Commit 7ac9a13717c10c5ee074a6b23096c8d277fa5712

Authored by Benjamin Herrenschmidt
Committed by Paul Mackerras
1 parent a334bdbdda

[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>

Showing 3 changed files with 23 additions and 19 deletions Side-by-side Diff

arch/powerpc/kernel/vdso.c
... ... @@ -49,24 +49,23 @@
49 49 /* Max supported size for symbol names */
50 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   -
55 52 extern char vdso32_start, vdso32_end;
56 53 static void *vdso32_kbase = &vdso32_start;
57   -unsigned int vdso32_pages;
58   -static struct page *vdso32_pagelist[VDSO32_MAXPAGES];
  54 +static unsigned int vdso32_pages;
  55 +static struct page **vdso32_pagelist;
59 56 unsigned long vdso32_sigtramp;
60 57 unsigned long vdso32_rt_sigtramp;
61 58  
62 59 #ifdef CONFIG_PPC64
63 60 extern char vdso64_start, vdso64_end;
64 61 static void *vdso64_kbase = &vdso64_start;
65   -unsigned int vdso64_pages;
66   -static struct page *vdso64_pagelist[VDSO64_MAXPAGES];
  62 +static unsigned int vdso64_pages;
  63 +static struct page **vdso64_pagelist;
67 64 unsigned long vdso64_rt_sigtramp;
68 65 #endif /* CONFIG_PPC64 */
69 66  
  67 +static int vdso_ready;
  68 +
70 69 /*
71 70 * The vdso data page (aka. systemcfg for old ppc64 fans) is here.
72 71 * Once the early boot kernel code no longer needs to muck around
... ... @@ -182,6 +181,9 @@
182 181 unsigned long vdso_base;
183 182 int rc;
184 183  
  184 + if (!vdso_ready)
  185 + return 0;
  186 +
185 187 #ifdef CONFIG_PPC64
186 188 if (test_thread_flag(TIF_32BIT)) {
187 189 vdso_pagelist = vdso32_pagelist;
... ... @@ -661,7 +663,7 @@
661 663 }
662 664  
663 665  
664   -void __init vdso_init(void)
  666 +static int __init vdso_init(void)
665 667 {
666 668 int i;
667 669  
668 670  
... ... @@ -716,11 +718,13 @@
716 718 #ifdef CONFIG_PPC64
717 719 vdso64_pages = 0;
718 720 #endif
719   - return;
  721 + return 0;
720 722 }
721 723  
722 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 728 for (i = 0; i < vdso32_pages; i++) {
725 729 struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE);
726 730 ClearPageReserved(pg);
... ... @@ -731,7 +735,9 @@
731 735 vdso32_pagelist[i] = NULL;
732 736  
733 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 741 for (i = 0; i < vdso64_pages; i++) {
736 742 struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE);
737 743 ClearPageReserved(pg);
738 744  
... ... @@ -743,7 +749,13 @@
743 749 #endif /* CONFIG_PPC64 */
744 750  
745 751 get_page(virt_to_page(vdso_data));
  752 +
  753 + smp_wmb();
  754 + vdso_ready = 1;
  755 +
  756 + return 0;
746 757 }
  758 +arch_initcall(vdso_init);
747 759  
748 760 int in_gate_area_no_task(unsigned long addr)
749 761 {
arch/powerpc/mm/mem.c
... ... @@ -384,9 +384,6 @@
384 384 initsize >> 10);
385 385  
386 386 mem_init_done = 1;
387   -
388   - /* Initialize the vDSO */
389   - vdso_init();
390 387 }
391 388  
392 389 /*
include/asm-powerpc/vdso.h
... ... @@ -18,15 +18,10 @@
18 18  
19 19 #ifndef __ASSEMBLY__
20 20  
21   -extern unsigned int vdso64_pages;
22   -extern unsigned int vdso32_pages;
23   -
24 21 /* Offsets relative to thread->vdso_base */
25 22 extern unsigned long vdso64_rt_sigtramp;
26 23 extern unsigned long vdso32_sigtramp;
27 24 extern unsigned long vdso32_rt_sigtramp;
28   -
29   -extern void vdso_init(void);
30 25  
31 26 #else /* __ASSEMBLY__ */
32 27