Skip to content

Commit

Permalink
MIPS: Fix race condition in module relocation code.
Browse files Browse the repository at this point in the history
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/
  • Loading branch information
Ralf Baechle committed Aug 17, 2012
1 parent d3cac35 commit 861667d
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 7 deletions.
1 change: 1 addition & 0 deletions arch/mips/include/asm/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
13 changes: 6 additions & 7 deletions arch/mips/kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
}
Expand All @@ -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;

Expand Down Expand Up @@ -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;
}

/*
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 861667d

Please sign in to comment.