MIPS: Fix race condition in module relocation code.
The relocation code was essentially taken from the 2.4 modutils which perform relocation in userspace. In 2.6 relocation of multiple modules may be performed in parallel by the in-kernel loader so the global variable mips_hi16_list won't fly anymore. Fix race by moving it into mod_arch_specific. [ralf@linux-mips.org: folded in Tony's followup fix. Thanks Tony!] Signed-off-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: Tony Wu <tung7970@gmail.com> Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/4189/
This commit is contained in:
Родитель
d3cac35cd0
Коммит
861667dc82
|
@ -10,6 +10,7 @@ struct mod_arch_specific {
|
|||
struct list_head dbe_list;
|
||||
const struct exception_table_entry *dbe_start;
|
||||
const struct exception_table_entry *dbe_end;
|
||||
struct mips_hi16 *r_mips_hi16_list;
|
||||
};
|
||||
|
||||
typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */
|
||||
|
|
|
@ -39,8 +39,6 @@ struct mips_hi16 {
|
|||
Elf_Addr value;
|
||||
};
|
||||
|
||||
static struct mips_hi16 *mips_hi16_list;
|
||||
|
||||
static LIST_HEAD(dbe_list);
|
||||
static DEFINE_SPINLOCK(dbe_lock);
|
||||
|
||||
|
@ -128,8 +126,8 @@ static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)
|
|||
|
||||
n->addr = (Elf_Addr *)location;
|
||||
n->value = v;
|
||||
n->next = mips_hi16_list;
|
||||
mips_hi16_list = n;
|
||||
n->next = me->arch.r_mips_hi16_list;
|
||||
me->arch.r_mips_hi16_list = n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -151,9 +149,9 @@ static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v)
|
|||
/* Sign extend the addend we extract from the lo insn. */
|
||||
vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
|
||||
|
||||
if (mips_hi16_list != NULL) {
|
||||
if (me->arch.r_mips_hi16_list != NULL) {
|
||||
|
||||
l = mips_hi16_list;
|
||||
l = me->arch.r_mips_hi16_list;
|
||||
while (l != NULL) {
|
||||
unsigned long insn;
|
||||
|
||||
|
@ -187,7 +185,7 @@ static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v)
|
|||
l = next;
|
||||
}
|
||||
|
||||
mips_hi16_list = NULL;
|
||||
me->arch.r_mips_hi16_list = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -278,6 +276,7 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
|
|||
pr_debug("Applying relocate section %u to %u\n", relsec,
|
||||
sechdrs[relsec].sh_info);
|
||||
|
||||
me->arch.r_mips_hi16_list = NULL;
|
||||
for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
|
||||
/* This is where to make the change */
|
||||
location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
|
||||
|
|
Загрузка…
Ссылка в новой задаче