Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 21c4ff80 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Paul Mackerras
Browse files

[POWERPC] Support feature fixups in modules



This patch adds support for feature fixups in modules. This involves
adding support for R_PPC64_REL64 relocs to the 64 bits module loader.
It also modifies modpost.c to ignore the powerpc fixup sections (or it
would warn when used in .init.text).

Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: default avatarOlof Johansson <olof@lixom.net>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 0909c8c2
Loading
Loading
Loading
Loading
+29 −10
Original line number Original line Diff line number Diff line
@@ -24,6 +24,8 @@
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/cache.h>
#include <linux/cache.h>


#include "setup.h"

#if 0
#if 0
#define DEBUGP printk
#define DEBUGP printk
#else
#else
@@ -269,24 +271,34 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
	return 0;
	return 0;
}
}


int module_finalize(const Elf_Ehdr *hdr,
static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
				    const Elf_Shdr *sechdrs,
				    const Elf_Shdr *sechdrs,
		    struct module *me)
				    const char *name)
{
{
	char *secstrings;
	char *secstrings;
	unsigned int i;
	unsigned int i;


	secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
	for (i = 1; i < hdr->e_shnum; i++)
		if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
			return &sechdrs[i];
	return NULL;
}

int module_finalize(const Elf_Ehdr *hdr,
		    const Elf_Shdr *sechdrs,
		    struct module *me)
{
	const Elf_Shdr *sect;

	me->arch.bug_table = NULL;
	me->arch.bug_table = NULL;
	me->arch.num_bugs = 0;
	me->arch.num_bugs = 0;


	/* Find the __bug_table section, if present */
	/* Find the __bug_table section, if present */
	secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
	sect = find_section(hdr, sechdrs, "__bug_table");
	for (i = 1; i < hdr->e_shnum; i++) {
	if (sect != NULL) {
		if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table"))
		me->arch.bug_table = (void *) sect->sh_addr;
			continue;
		me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry);
		me->arch.bug_table = (void *) sechdrs[i].sh_addr;
		me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry);
		break;
	}
	}


 	/*
 	/*
@@ -296,6 +308,13 @@ int module_finalize(const Elf_Ehdr *hdr,
	 */
	 */
	list_add(&me->arch.bug_list, &module_bug_list);
	list_add(&me->arch.bug_list, &module_bug_list);


	/* Apply feature fixups */
	sect = find_section(hdr, sechdrs, "__ftr_fixup");
	if (sect != NULL)
		do_feature_fixups(cur_cpu_spec->cpu_features,
				  (void *)sect->sh_addr,
				  (void *)sect->sh_addr + sect->sh_size);

	return 0;
	return 0;
}
}


+40 −9
Original line number Original line Diff line number Diff line
@@ -22,6 +22,9 @@
#include <linux/vmalloc.h>
#include <linux/vmalloc.h>
#include <asm/module.h>
#include <asm/module.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <asm/firmware.h>

#include "setup.h"


/* FIXME: We don't do .init separately.  To do this, we'd need to have
/* FIXME: We don't do .init separately.  To do this, we'd need to have
   a separate r2 value in the init and core section, and stub between
   a separate r2 value in the init and core section, and stub between
@@ -400,6 +403,11 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
				| (value & 0x03fffffc);
				| (value & 0x03fffffc);
			break;
			break;


		case R_PPC64_REL64:
			/* 64 bits relative (used by features fixups) */
			*location = value - (unsigned long)location;
			break;

		default:
		default:
			printk("%s: Unknown ADD relocation: %lu\n",
			printk("%s: Unknown ADD relocation: %lu\n",
			       me->name,
			       me->name,
@@ -413,23 +421,33 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,


LIST_HEAD(module_bug_list);
LIST_HEAD(module_bug_list);


int module_finalize(const Elf_Ehdr *hdr,
static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
		const Elf_Shdr *sechdrs, struct module *me)
				    const Elf_Shdr *sechdrs,
				    const char *name)
{
{
	char *secstrings;
	char *secstrings;
	unsigned int i;
	unsigned int i;


	secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
	for (i = 1; i < hdr->e_shnum; i++)
		if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
			return &sechdrs[i];
	return NULL;
}

int module_finalize(const Elf_Ehdr *hdr,
		const Elf_Shdr *sechdrs, struct module *me)
{
	const Elf_Shdr *sect;

	me->arch.bug_table = NULL;
	me->arch.bug_table = NULL;
	me->arch.num_bugs = 0;
	me->arch.num_bugs = 0;


	/* Find the __bug_table section, if present */
	/* Find the __bug_table section, if present */
	secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
	sect = find_section(hdr, sechdrs, "__bug_table");
	for (i = 1; i < hdr->e_shnum; i++) {
	if (sect != NULL) {
		if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table"))
		me->arch.bug_table = (void *) sect->sh_addr;
			continue;
		me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry);
		me->arch.bug_table = (void *) sechdrs[i].sh_addr;
		me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry);
		break;
	}
	}


	/*
	/*
@@ -439,6 +457,19 @@ int module_finalize(const Elf_Ehdr *hdr,
	 */
	 */
	list_add(&me->arch.bug_list, &module_bug_list);
	list_add(&me->arch.bug_list, &module_bug_list);


	/* Apply feature fixups */
	sect = find_section(hdr, sechdrs, "__ftr_fixup");
	if (sect != NULL)
		do_feature_fixups(cur_cpu_spec->cpu_features,
				  (void *)sect->sh_addr,
				  (void *)sect->sh_addr + sect->sh_size);

	sect = find_section(hdr, sechdrs, "__fw_ftr_fixup");
	if (sect != NULL)
		do_feature_fixups(powerpc_firmware_features,
				  (void *)sect->sh_addr,
				  (void *)sect->sh_addr + sect->sh_size);

	return 0;
	return 0;
}
}


+2 −0
Original line number Original line Diff line number Diff line
@@ -921,6 +921,8 @@ static int init_section_ref_ok(const char *name)
		".fixup",
		".fixup",
		".smp_locks",
		".smp_locks",
		".plt",  /* seen on ARCH=um build on x86_64. Harmless */
		".plt",  /* seen on ARCH=um build on x86_64. Harmless */
		"__ftr_fixup",		/* powerpc cpu feature fixup */
		"__fw_ftr_fixup",	/* powerpc firmware feature fixup */
		NULL
		NULL
	};
	};
	/* Start of section names */
	/* Start of section names */