aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/vdso.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-02-11 21:31:08 -0500
committerPaul Mackerras <paulus@samba.org>2007-02-12 23:35:52 -0500
commit7ac9a13717c10c5ee074a6b23096c8d277fa5712 (patch)
treead4fde87891f3d4c9f04412c4a33d80b2bd6b445 /arch/powerpc/kernel/vdso.c
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/kernel/vdso.c')
-rw-r--r--arch/powerpc/kernel/vdso.c34
1 files changed, 23 insertions, 11 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 @@
49/* Max supported size for symbol names */ 49/* Max supported size for symbol names */
50#define MAX_SYMNAME 64 50#define MAX_SYMNAME 64
51 51
52#define VDSO32_MAXPAGES (((0x3000 + PAGE_MASK) >> PAGE_SHIFT) + 2)
53#define VDSO64_MAXPAGES (((0x3000 + PAGE_MASK) >> PAGE_SHIFT) + 2)
54
55extern char vdso32_start, vdso32_end; 52extern char vdso32_start, vdso32_end;
56static void *vdso32_kbase = &vdso32_start; 53static void *vdso32_kbase = &vdso32_start;
57unsigned int vdso32_pages; 54static unsigned int vdso32_pages;
58static struct page *vdso32_pagelist[VDSO32_MAXPAGES]; 55static struct page **vdso32_pagelist;
59unsigned long vdso32_sigtramp; 56unsigned long vdso32_sigtramp;
60unsigned long vdso32_rt_sigtramp; 57unsigned long vdso32_rt_sigtramp;
61 58
62#ifdef CONFIG_PPC64 59#ifdef CONFIG_PPC64
63extern char vdso64_start, vdso64_end; 60extern char vdso64_start, vdso64_end;
64static void *vdso64_kbase = &vdso64_start; 61static void *vdso64_kbase = &vdso64_start;
65unsigned int vdso64_pages; 62static unsigned int vdso64_pages;
66static struct page *vdso64_pagelist[VDSO64_MAXPAGES]; 63static struct page **vdso64_pagelist;
67unsigned long vdso64_rt_sigtramp; 64unsigned long vdso64_rt_sigtramp;
68#endif /* CONFIG_PPC64 */ 65#endif /* CONFIG_PPC64 */
69 66
67static int vdso_ready;
68
70/* 69/*
71 * The vdso data page (aka. systemcfg for old ppc64 fans) is here. 70 * The vdso data page (aka. systemcfg for old ppc64 fans) is here.
72 * Once the early boot kernel code no longer needs to muck around 71 * 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,
182 unsigned long vdso_base; 181 unsigned long vdso_base;
183 int rc; 182 int rc;
184 183
184 if (!vdso_ready)
185 return 0;
186
185#ifdef CONFIG_PPC64 187#ifdef CONFIG_PPC64
186 if (test_thread_flag(TIF_32BIT)) { 188 if (test_thread_flag(TIF_32BIT)) {
187 vdso_pagelist = vdso32_pagelist; 189 vdso_pagelist = vdso32_pagelist;
@@ -661,7 +663,7 @@ static void __init vdso_setup_syscall_map(void)
661} 663}
662 664
663 665
664void __init vdso_init(void) 666static int __init vdso_init(void)
665{ 667{
666 int i; 668 int i;
667 669
@@ -716,11 +718,13 @@ void __init vdso_init(void)
716#ifdef CONFIG_PPC64 718#ifdef CONFIG_PPC64
717 vdso64_pages = 0; 719 vdso64_pages = 0;
718#endif 720#endif
719 return; 721 return 0;
720 } 722 }
721 723
722 /* Make sure pages are in the correct state */ 724 /* Make sure pages are in the correct state */
723 BUG_ON(vdso32_pages + 2 > VDSO32_MAXPAGES); 725 vdso32_pagelist = kzalloc(sizeof(struct page *) * (vdso32_pages + 2),
726 GFP_KERNEL);
727 BUG_ON(vdso32_pagelist == NULL);
724 for (i = 0; i < vdso32_pages; i++) { 728 for (i = 0; i < vdso32_pages; i++) {
725 struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE); 729 struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE);
726 ClearPageReserved(pg); 730 ClearPageReserved(pg);
@@ -731,7 +735,9 @@ void __init vdso_init(void)
731 vdso32_pagelist[i] = NULL; 735 vdso32_pagelist[i] = NULL;
732 736
733#ifdef CONFIG_PPC64 737#ifdef CONFIG_PPC64
734 BUG_ON(vdso64_pages + 2 > VDSO64_MAXPAGES); 738 vdso64_pagelist = kzalloc(sizeof(struct page *) * (vdso64_pages + 2),
739 GFP_KERNEL);
740 BUG_ON(vdso64_pagelist == NULL);
735 for (i = 0; i < vdso64_pages; i++) { 741 for (i = 0; i < vdso64_pages; i++) {
736 struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE); 742 struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE);
737 ClearPageReserved(pg); 743 ClearPageReserved(pg);
@@ -743,7 +749,13 @@ void __init vdso_init(void)
743#endif /* CONFIG_PPC64 */ 749#endif /* CONFIG_PPC64 */
744 750
745 get_page(virt_to_page(vdso_data)); 751 get_page(virt_to_page(vdso_data));
752
753 smp_wmb();
754 vdso_ready = 1;
755
756 return 0;
746} 757}
758arch_initcall(vdso_init);
747 759
748int in_gate_area_no_task(unsigned long addr) 760int in_gate_area_no_task(unsigned long addr)
749{ 761{