[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>
This commit is contained in:
parent
a334bdbdda
commit
7ac9a13717
|
@ -49,24 +49,23 @@
|
||||||
/* Max supported size for symbol names */
|
/* Max supported size for symbol names */
|
||||||
#define MAX_SYMNAME 64
|
#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;
|
extern char vdso32_start, vdso32_end;
|
||||||
static void *vdso32_kbase = &vdso32_start;
|
static void *vdso32_kbase = &vdso32_start;
|
||||||
unsigned int vdso32_pages;
|
static unsigned int vdso32_pages;
|
||||||
static struct page *vdso32_pagelist[VDSO32_MAXPAGES];
|
static struct page **vdso32_pagelist;
|
||||||
unsigned long vdso32_sigtramp;
|
unsigned long vdso32_sigtramp;
|
||||||
unsigned long vdso32_rt_sigtramp;
|
unsigned long vdso32_rt_sigtramp;
|
||||||
|
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
extern char vdso64_start, vdso64_end;
|
extern char vdso64_start, vdso64_end;
|
||||||
static void *vdso64_kbase = &vdso64_start;
|
static void *vdso64_kbase = &vdso64_start;
|
||||||
unsigned int vdso64_pages;
|
static unsigned int vdso64_pages;
|
||||||
static struct page *vdso64_pagelist[VDSO64_MAXPAGES];
|
static struct page **vdso64_pagelist;
|
||||||
unsigned long vdso64_rt_sigtramp;
|
unsigned long vdso64_rt_sigtramp;
|
||||||
#endif /* CONFIG_PPC64 */
|
#endif /* CONFIG_PPC64 */
|
||||||
|
|
||||||
|
static int vdso_ready;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The vdso data page (aka. systemcfg for old ppc64 fans) is here.
|
* The vdso data page (aka. systemcfg for old ppc64 fans) is here.
|
||||||
* Once the early boot kernel code no longer needs to muck around
|
* 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;
|
unsigned long vdso_base;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (!vdso_ready)
|
||||||
|
return 0;
|
||||||
|
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
if (test_thread_flag(TIF_32BIT)) {
|
if (test_thread_flag(TIF_32BIT)) {
|
||||||
vdso_pagelist = vdso32_pagelist;
|
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;
|
int i;
|
||||||
|
|
||||||
|
@ -716,11 +718,13 @@ void __init vdso_init(void)
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
vdso64_pages = 0;
|
vdso64_pages = 0;
|
||||||
#endif
|
#endif
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure pages are in the correct state */
|
/* 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++) {
|
for (i = 0; i < vdso32_pages; i++) {
|
||||||
struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE);
|
struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE);
|
||||||
ClearPageReserved(pg);
|
ClearPageReserved(pg);
|
||||||
|
@ -731,7 +735,9 @@ void __init vdso_init(void)
|
||||||
vdso32_pagelist[i] = NULL;
|
vdso32_pagelist[i] = NULL;
|
||||||
|
|
||||||
#ifdef CONFIG_PPC64
|
#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++) {
|
for (i = 0; i < vdso64_pages; i++) {
|
||||||
struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE);
|
struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE);
|
||||||
ClearPageReserved(pg);
|
ClearPageReserved(pg);
|
||||||
|
@ -743,7 +749,13 @@ void __init vdso_init(void)
|
||||||
#endif /* CONFIG_PPC64 */
|
#endif /* CONFIG_PPC64 */
|
||||||
|
|
||||||
get_page(virt_to_page(vdso_data));
|
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)
|
int in_gate_area_no_task(unsigned long addr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -384,9 +384,6 @@ void __init mem_init(void)
|
||||||
initsize >> 10);
|
initsize >> 10);
|
||||||
|
|
||||||
mem_init_done = 1;
|
mem_init_done = 1;
|
||||||
|
|
||||||
/* Initialize the vDSO */
|
|
||||||
vdso_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -18,16 +18,11 @@
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
extern unsigned int vdso64_pages;
|
|
||||||
extern unsigned int vdso32_pages;
|
|
||||||
|
|
||||||
/* Offsets relative to thread->vdso_base */
|
/* Offsets relative to thread->vdso_base */
|
||||||
extern unsigned long vdso64_rt_sigtramp;
|
extern unsigned long vdso64_rt_sigtramp;
|
||||||
extern unsigned long vdso32_sigtramp;
|
extern unsigned long vdso32_sigtramp;
|
||||||
extern unsigned long vdso32_rt_sigtramp;
|
extern unsigned long vdso32_rt_sigtramp;
|
||||||
|
|
||||||
extern void vdso_init(void);
|
|
||||||
|
|
||||||
#else /* __ASSEMBLY__ */
|
#else /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#ifdef __VDSO64__
|
#ifdef __VDSO64__
|
||||||
|
|
Loading…
Reference in a new issue