Skip to content

Commit

Permalink
x86-64: Allow alternative patching in the vDSO
Browse files Browse the repository at this point in the history
This code is short enough and different enough from the module
loader that it's not worth trying to share anything.

Signed-off-by: Andy Lutomirski <[email protected]>
Link: http://lkml.kernel.org/r/e73112e4381fff29e31b882c2d0856822edaea53.1310563276.git.luto@mit.edu
Signed-off-by: H. Peter Anvin <[email protected]>
  • Loading branch information
amluto authored and H. Peter Anvin committed Jul 13, 2011
1 parent 59e97e4 commit 1b3f2a7
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions arch/x86/vdso/vma.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,44 @@ extern unsigned short vdso_sync_cpuid;
static struct page **vdso_pages;
static unsigned vdso_size;

static void __init patch_vdso(void *vdso, size_t len)
{
Elf64_Ehdr *hdr = vdso;
Elf64_Shdr *sechdrs, *alt_sec = 0;
char *secstrings;
void *alt_data;
int i;

BUG_ON(len < sizeof(Elf64_Ehdr));
BUG_ON(memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0);

sechdrs = (void *)hdr + hdr->e_shoff;
secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;

for (i = 1; i < hdr->e_shnum; i++) {
Elf64_Shdr *shdr = &sechdrs[i];
if (!strcmp(secstrings + shdr->sh_name, ".altinstructions")) {
alt_sec = shdr;
goto found;
}
}

/* If we get here, it's probably a bug. */
pr_warning("patch_vdso: .altinstructions not found\n");
return; /* nothing to patch */

found:
alt_data = (void *)hdr + alt_sec->sh_offset;
apply_alternatives(alt_data, alt_data + alt_sec->sh_size);
}

static int __init init_vdso_vars(void)
{
int npages = (vdso_end - vdso_start + PAGE_SIZE - 1) / PAGE_SIZE;
int i;

patch_vdso(vdso_start, vdso_end - vdso_start);

vdso_size = npages << PAGE_SHIFT;
vdso_pages = kmalloc(sizeof(struct page *) * npages, GFP_KERNEL);
if (!vdso_pages)
Expand Down

0 comments on commit 1b3f2a7

Please sign in to comment.