aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-02-12 13:31:08 +1100
committerPaul Mackerras <paulus@samba.org>2007-02-13 15:35:52 +1100
commit7ac9a13717c10c5ee074a6b23096c8d277fa5712 (patch)
treead4fde87891f3d4c9f04412c4a33d80b2bd6b445 /arch/powerpc
parenta334bdbdda9659b8f50a8620a11249fde62ccfde (diff)
[POWERPC] Fix vDSO page count calculation
The recent vDSO consolidation patches broke powerpc due to a mistake in the definition of MAXPAGES constants. This fixes it by moving to a dynamically allocated array of pages instead as I don't like much hard coded size limits. Also move the vdso initialisation to an initcall since it doesn't really need to be done -that- early. Applogies for not catching the breakage earlier, Roland _did_ CC me on his patches a while ago, I got busy with other things and forgot to test them. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/kernel/vdso.c34
-rw-r--r--arch/powerpc/mm/mem.c3
2 files changed, 23 insertions, 14 deletions
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 50149ec6efa..e46c31b3664 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -49,24 +49,23 @@
/* Max supported size for symbol names */
#define MAX_SYMNAME 64
-#define VDSO32_MAXPAGES (((0x3000 + PAGE_MASK) >> PAGE_SHIFT) + 2)
-#define VDSO64_MAXPAGES (((0x3000 + PAGE_MASK) >> PAGE_SHIFT) + 2)
-
extern char vdso32_start, vdso32_end;
static void *vdso32_kbase = &vdso32_start;
-unsigned int vdso32_pages;
-static struct page *vdso32_pagelist[VDSO32_MAXPAGES];
+static unsigned int vdso32_pages;
+static struct page **vdso32_pagelist;
unsigned long vdso32_sigtramp;
unsigned long vdso32_rt_sigtramp;
#ifdef CONFIG_PPC64
extern char vdso64_start, vdso64_end;
static void *vdso64_kbase = &vdso64_start;
-unsigned int vdso64_pages;
-static struct page *vdso64_pagelist[VDSO64_MAXPAGES];
+static unsigned int vdso64_pages;
+static struct page **vdso64_pagelist;
unsigned long vdso64_rt_sigtramp;
#endif /* CONFIG_PPC64 */
+static int vdso_ready;
+
/*
* The vdso data page (aka. systemcfg for old ppc64 fans) is here.
* Once the early boot kernel code no longer needs to muck around
@@ -182,6 +181,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
unsigned long vdso_base;
int rc;
+ if (!vdso_ready)
+ return 0;
+
#ifdef CONFIG_PPC64
if (test_thread_flag(TIF_32BIT)) {
vdso_pagelist = vdso32_pagelist;
@@ -661,7 +663,7 @@ static void __init vdso_setup_syscall_map(void)
}
-void __init vdso_init(void)
+static int __init vdso_init(void)
{
int i;
@@ -716,11 +718,13 @@ void __init vdso_init(void)
#ifdef CONFIG_PPC64
vdso64_pages = 0;
#endif
- return;
+ return 0;
}
/* Make sure pages are in the correct state */
- BUG_ON(vdso32_pages + 2 > VDSO32_MAXPAGES);
+ vdso32_pagelist = kzalloc(sizeof(struct page *) * (vdso32_pages + 2),
+ GFP_KERNEL);
+ BUG_ON(vdso32_pagelist == NULL);
for (i = 0; i < vdso32_pages; i++) {
struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE);
ClearPageReserved(pg);
@@ -731,7 +735,9 @@ void __init vdso_init(void)
vdso32_pagelist[i] = NULL;
#ifdef CONFIG_PPC64
- BUG_ON(vdso64_pages + 2 > VDSO64_MAXPAGES);
+ vdso64_pagelist = kzalloc(sizeof(struct page *) * (vdso64_pages + 2),
+ GFP_KERNEL);
+ BUG_ON(vdso64_pagelist == NULL);
for (i = 0; i < vdso64_pages; i++) {
struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE);
ClearPageReserved(pg);
@@ -743,7 +749,13 @@ void __init vdso_init(void)
#endif /* CONFIG_PPC64 */
get_page(virt_to_page(vdso_data));
+
+ smp_wmb();
+ vdso_ready = 1;
+
+ return 0;
}
+arch_initcall(vdso_init);
int in_gate_area_no_task(unsigned long addr)
{
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 77b4637097e..52f397c108a 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -384,9 +384,6 @@ void __init mem_init(void)
initsize >> 10);
mem_init_done = 1;
-
- /* Initialize the vDSO */
- vdso_init();
}
/*