arm64: vdso: clean up vdso_pagelist initialization

Remove some unnecessary bits that were apparently carried over from
another architecture's implementation:

- No need to get_page() the vdso text/data - these are part of the
  kernel image.
- No need for ClearPageReserved on the vdso text.
- No need to vmap the first text page to check the ELF header - this
  can be done through &vdso_start.

Also some minor cleanup:
- Use kcalloc for vdso_pagelist array allocation.
- Don't print on allocation failure, slab/slub will do that for us.

Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
Nathan Lynch 2014-02-11 22:28:42 +00:00 committed by Catalin Marinas
parent bb10eb7b4d
commit 16fb1a9bec
1 changed files with 12 additions and 30 deletions

View File

@ -106,49 +106,31 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
static int __init vdso_init(void) static int __init vdso_init(void)
{ {
struct page *pg; int i;
char *vbase;
int i, ret = 0; if (memcmp(&vdso_start, "\177ELF", 4)) {
pr_err("vDSO is not a valid ELF object!\n");
return -EINVAL;
}
vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT; vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
pr_info("vdso: %ld pages (%ld code, %ld data) at base %p\n", pr_info("vdso: %ld pages (%ld code, %ld data) at base %p\n",
vdso_pages + 1, vdso_pages, 1L, &vdso_start); vdso_pages + 1, vdso_pages, 1L, &vdso_start);
/* Allocate the vDSO pagelist, plus a page for the data. */ /* Allocate the vDSO pagelist, plus a page for the data. */
vdso_pagelist = kzalloc(sizeof(struct page *) * (vdso_pages + 1), vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
GFP_KERNEL); GFP_KERNEL);
if (vdso_pagelist == NULL) { if (vdso_pagelist == NULL)
pr_err("Failed to allocate vDSO pagelist!\n");
return -ENOMEM; return -ENOMEM;
}
/* Grab the vDSO code pages. */ /* Grab the vDSO code pages. */
for (i = 0; i < vdso_pages; i++) { for (i = 0; i < vdso_pages; i++)
pg = virt_to_page(&vdso_start + i*PAGE_SIZE); vdso_pagelist[i] = virt_to_page(&vdso_start + i * PAGE_SIZE);
ClearPageReserved(pg);
get_page(pg);
vdso_pagelist[i] = pg;
}
/* Sanity check the shared object header. */
vbase = vmap(vdso_pagelist, 1, 0, PAGE_KERNEL);
if (vbase == NULL) {
pr_err("Failed to map vDSO pagelist!\n");
return -ENOMEM;
} else if (memcmp(vbase, "\177ELF", 4)) {
pr_err("vDSO is not a valid ELF object!\n");
ret = -EINVAL;
goto unmap;
}
/* Grab the vDSO data page. */ /* Grab the vDSO data page. */
pg = virt_to_page(vdso_data); vdso_pagelist[i] = virt_to_page(vdso_data);
get_page(pg);
vdso_pagelist[i] = pg;
unmap: return 0;
vunmap(vbase);
return ret;
} }
arch_initcall(vdso_init); arch_initcall(vdso_init);