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 <luto@mit.edu>
Link: http://lkml.kernel.org/r/e73112e4381fff29e31b882c2d0856822edaea53.1310563276.git.luto@mit.edu
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
  • Loading branch information
Andy Lutomirski 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
@@ -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)

0 comments on commit 1b3f2a7

Please sign in to comment.