* [PATCH v1 2/9] powerpc/vdso: Remove get_page() in vdso_pagelist initialization
2020-08-25 13:53 [PATCH v1 1/9] powerpc/vdso: Remove BUG_ON() in vdso_init() Christophe Leroy
@ 2020-08-25 13:54 ` Christophe Leroy
2020-08-25 13:54 ` [PATCH v1 3/9] powerpc/vdso: Remove NULL termination element in vdso_pagelist Christophe Leroy
` (6 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: Christophe Leroy @ 2020-08-25 13:54 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linux-kernel, linuxppc-dev
Partly copied from commit 16fb1a9bec61 ("arm64: vdso: clean up
vdso_pagelist initialization").
No need to get_page() the vdso text/data - these are part of the
kernel image.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/vdso.c | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 88a4a02ed4c4..3bc4d5b1980b 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -757,11 +757,9 @@ static int __init vdso_init(void)
if (!vdso32_pagelist)
goto alloc_failed;
- for (i = 0; i < vdso32_pages; i++) {
- struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE);
- get_page(pg);
- vdso32_pagelist[i] = pg;
- }
+ for (i = 0; i < vdso32_pages; i++)
+ vdso32_pagelist[i] = virt_to_page(vdso32_kbase + i * PAGE_SIZE);
+
vdso32_pagelist[i++] = virt_to_page(vdso_data);
vdso32_pagelist[i] = NULL;
#endif
@@ -772,17 +770,13 @@ static int __init vdso_init(void)
if (!vdso64_pagelist)
goto alloc_failed;
- for (i = 0; i < vdso64_pages; i++) {
- struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE);
- get_page(pg);
- vdso64_pagelist[i] = pg;
- }
+ for (i = 0; i < vdso64_pages; i++)
+ vdso64_pagelist[i] = virt_to_page(vdso64_kbase + i * PAGE_SIZE);
+
vdso64_pagelist[i++] = virt_to_page(vdso_data);
vdso64_pagelist[i] = NULL;
#endif /* CONFIG_PPC64 */
- get_page(virt_to_page(vdso_data));
-
smp_wmb();
vdso_ready = 1;
--
2.25.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 3/9] powerpc/vdso: Remove NULL termination element in vdso_pagelist
2020-08-25 13:53 [PATCH v1 1/9] powerpc/vdso: Remove BUG_ON() in vdso_init() Christophe Leroy
2020-08-25 13:54 ` [PATCH v1 2/9] powerpc/vdso: Remove get_page() in vdso_pagelist initialization Christophe Leroy
@ 2020-08-25 13:54 ` Christophe Leroy
2020-08-25 13:54 ` [PATCH v1 4/9] powerpc/vdso: Remove unnecessary ifdefs in vdso_pagelist initialization Christophe Leroy
` (5 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: Christophe Leroy @ 2020-08-25 13:54 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linux-kernel, linuxppc-dev
No need of a NULL last element in pagelists, install_special_mapping()
knows how long the list is.
Remove that element.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/vdso.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 3bc4d5b1980b..daef14a284a3 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -752,7 +752,7 @@ static int __init vdso_init(void)
#ifdef CONFIG_VDSO32
/* Make sure pages are in the correct state */
- vdso32_pagelist = kcalloc(vdso32_pages + 2, sizeof(struct page *),
+ vdso32_pagelist = kcalloc(vdso32_pages + 1, sizeof(struct page *),
GFP_KERNEL);
if (!vdso32_pagelist)
goto alloc_failed;
@@ -760,12 +760,11 @@ static int __init vdso_init(void)
for (i = 0; i < vdso32_pages; i++)
vdso32_pagelist[i] = virt_to_page(vdso32_kbase + i * PAGE_SIZE);
- vdso32_pagelist[i++] = virt_to_page(vdso_data);
- vdso32_pagelist[i] = NULL;
+ vdso32_pagelist[i] = virt_to_page(vdso_data);
#endif
#ifdef CONFIG_PPC64
- vdso64_pagelist = kcalloc(vdso64_pages + 2, sizeof(struct page *),
+ vdso64_pagelist = kcalloc(vdso64_pages + 1, sizeof(struct page *),
GFP_KERNEL);
if (!vdso64_pagelist)
goto alloc_failed;
@@ -773,8 +772,7 @@ static int __init vdso_init(void)
for (i = 0; i < vdso64_pages; i++)
vdso64_pagelist[i] = virt_to_page(vdso64_kbase + i * PAGE_SIZE);
- vdso64_pagelist[i++] = virt_to_page(vdso_data);
- vdso64_pagelist[i] = NULL;
+ vdso64_pagelist[i] = virt_to_page(vdso_data);
#endif /* CONFIG_PPC64 */
smp_wmb();
--
2.25.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 4/9] powerpc/vdso: Remove unnecessary ifdefs in vdso_pagelist initialization
2020-08-25 13:53 [PATCH v1 1/9] powerpc/vdso: Remove BUG_ON() in vdso_init() Christophe Leroy
2020-08-25 13:54 ` [PATCH v1 2/9] powerpc/vdso: Remove get_page() in vdso_pagelist initialization Christophe Leroy
2020-08-25 13:54 ` [PATCH v1 3/9] powerpc/vdso: Remove NULL termination element in vdso_pagelist Christophe Leroy
@ 2020-08-25 13:54 ` Christophe Leroy
2020-08-26 14:58 ` Michael Ellerman
2020-08-25 13:54 ` [PATCH v1 5/9] powerpc/vdso: move to _install_special_mapping() and remove arch_vma_name() Christophe Leroy
` (4 subsequent siblings)
7 siblings, 1 reply; 15+ messages in thread
From: Christophe Leroy @ 2020-08-25 13:54 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linux-kernel, linuxppc-dev
No need of all those #ifdefs around the pagelist initialisation,
use IS_ENABLED(), GCC will kick out unused static variables.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/vdso.c | 57 +++++++++++++++-----------------------
1 file changed, 22 insertions(+), 35 deletions(-)
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index daef14a284a3..bbb69832fd46 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -51,15 +51,13 @@ static struct page **vdso32_pagelist;
unsigned long vdso32_sigtramp;
unsigned long vdso32_rt_sigtramp;
-#ifdef CONFIG_VDSO32
extern char vdso32_start, vdso32_end;
-#endif
-#ifdef CONFIG_PPC64
extern char vdso64_start, vdso64_end;
static void *vdso64_kbase = &vdso64_start;
static unsigned int vdso64_pages;
static struct page **vdso64_pagelist;
+#ifdef CONFIG_PPC64
unsigned long vdso64_rt_sigtramp;
#endif /* CONFIG_PPC64 */
@@ -134,7 +132,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
if (!vdso_ready)
return 0;
-#ifdef CONFIG_PPC64
if (is_32bit_task()) {
vdso_pagelist = vdso32_pagelist;
vdso_pages = vdso32_pages;
@@ -149,11 +146,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
*/
vdso_base = 0;
}
-#else
- vdso_pagelist = vdso32_pagelist;
- vdso_pages = vdso32_pages;
- vdso_base = VDSO32_MBASE;
-#endif
current->mm->context.vdso_base = 0;
@@ -718,16 +710,14 @@ static int __init vdso_init(void)
vdso_data->icache_block_size = ppc64_caches.l1i.block_size;
vdso_data->dcache_log_block_size = ppc64_caches.l1d.log_block_size;
vdso_data->icache_log_block_size = ppc64_caches.l1i.log_block_size;
+#endif /* CONFIG_PPC64 */
/*
* Calculate the size of the 64 bits vDSO
*/
vdso64_pages = (&vdso64_end - &vdso64_start) >> PAGE_SHIFT;
DBG("vdso64_kbase: %p, 0x%x pages\n", vdso64_kbase, vdso64_pages);
-#endif /* CONFIG_PPC64 */
-
-#ifdef CONFIG_VDSO32
vdso32_kbase = &vdso32_start;
/*
@@ -735,8 +725,6 @@ static int __init vdso_init(void)
*/
vdso32_pages = (&vdso32_end - &vdso32_start) >> PAGE_SHIFT;
DBG("vdso32_kbase: %p, 0x%x pages\n", vdso32_kbase, vdso32_pages);
-#endif
-
/*
* Setup the syscall map in the vDOS
@@ -750,30 +738,30 @@ static int __init vdso_init(void)
if (vdso_setup())
goto setup_failed;
-#ifdef CONFIG_VDSO32
- /* Make sure pages are in the correct state */
- vdso32_pagelist = kcalloc(vdso32_pages + 1, sizeof(struct page *),
- GFP_KERNEL);
- if (!vdso32_pagelist)
- goto alloc_failed;
+ if (IS_ENABLED(CONFIG_VDSO32)) {
+ /* Make sure pages are in the correct state */
+ vdso32_pagelist = kcalloc(vdso32_pages + 1, sizeof(struct page *),
+ GFP_KERNEL);
+ if (!vdso32_pagelist)
+ goto alloc_failed;
- for (i = 0; i < vdso32_pages; i++)
- vdso32_pagelist[i] = virt_to_page(vdso32_kbase + i * PAGE_SIZE);
+ for (i = 0; i < vdso32_pages; i++)
+ vdso32_pagelist[i] = virt_to_page(vdso32_kbase + i * PAGE_SIZE);
- vdso32_pagelist[i] = virt_to_page(vdso_data);
-#endif
+ vdso32_pagelist[i] = virt_to_page(vdso_data);
+ }
-#ifdef CONFIG_PPC64
- vdso64_pagelist = kcalloc(vdso64_pages + 1, sizeof(struct page *),
- GFP_KERNEL);
- if (!vdso64_pagelist)
- goto alloc_failed;
+ if (IS_ENABLED(CONFIG_PPC64)) {
+ vdso64_pagelist = kcalloc(vdso64_pages + 1, sizeof(struct page *),
+ GFP_KERNEL);
+ if (!vdso64_pagelist)
+ goto alloc_failed;
- for (i = 0; i < vdso64_pages; i++)
- vdso64_pagelist[i] = virt_to_page(vdso64_kbase + i * PAGE_SIZE);
+ for (i = 0; i < vdso64_pages; i++)
+ vdso64_pagelist[i] = virt_to_page(vdso64_kbase + i * PAGE_SIZE);
- vdso64_pagelist[i] = virt_to_page(vdso_data);
-#endif /* CONFIG_PPC64 */
+ vdso64_pagelist[i] = virt_to_page(vdso_data);
+ }
smp_wmb();
vdso_ready = 1;
@@ -784,9 +772,8 @@ static int __init vdso_init(void)
pr_err("vDSO setup failure, not enabled !\n");
alloc_failed:
vdso32_pages = 0;
-#ifdef CONFIG_PPC64
vdso64_pages = 0;
-#endif
+
return 0;
}
arch_initcall(vdso_init);
--
2.25.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v1 4/9] powerpc/vdso: Remove unnecessary ifdefs in vdso_pagelist initialization
2020-08-25 13:54 ` [PATCH v1 4/9] powerpc/vdso: Remove unnecessary ifdefs in vdso_pagelist initialization Christophe Leroy
@ 2020-08-26 14:58 ` Michael Ellerman
2020-08-26 15:21 ` Christophe Leroy
2020-08-27 6:47 ` Christophe Leroy
0 siblings, 2 replies; 15+ messages in thread
From: Michael Ellerman @ 2020-08-26 14:58 UTC (permalink / raw)
To: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras
Cc: linux-kernel, linuxppc-dev
Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
> index daef14a284a3..bbb69832fd46 100644
> --- a/arch/powerpc/kernel/vdso.c
> +++ b/arch/powerpc/kernel/vdso.c
> @@ -718,16 +710,14 @@ static int __init vdso_init(void)
...
>
> -
> -#ifdef CONFIG_VDSO32
> vdso32_kbase = &vdso32_start;
>
> /*
> @@ -735,8 +725,6 @@ static int __init vdso_init(void)
> */
> vdso32_pages = (&vdso32_end - &vdso32_start) >> PAGE_SHIFT;
> DBG("vdso32_kbase: %p, 0x%x pages\n", vdso32_kbase, vdso32_pages);
> -#endif
This didn't build for ppc64le:
/opt/cross/gcc-8.20_binutils-2.32/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-ld: arch/powerpc/kernel/vdso.o:(.toc+0x0): undefined reference to `vdso32_end'
/opt/cross/gcc-8.20_binutils-2.32/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-ld: arch/powerpc/kernel/vdso.o:(.toc+0x8): undefined reference to `vdso32_start'
make[1]: *** [/scratch/michael/build/maint/Makefile:1166: vmlinux] Error 1
make: *** [Makefile:185: __sub-make] Error 2
So I just put that ifdef back.
cheers
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v1 4/9] powerpc/vdso: Remove unnecessary ifdefs in vdso_pagelist initialization
2020-08-26 14:58 ` Michael Ellerman
@ 2020-08-26 15:21 ` Christophe Leroy
2020-08-27 6:47 ` Christophe Leroy
1 sibling, 0 replies; 15+ messages in thread
From: Christophe Leroy @ 2020-08-26 15:21 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras
Cc: linux-kernel, linuxppc-dev
Le 26/08/2020 à 16:58, Michael Ellerman a écrit :
> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>> diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
>> index daef14a284a3..bbb69832fd46 100644
>> --- a/arch/powerpc/kernel/vdso.c
>> +++ b/arch/powerpc/kernel/vdso.c
>> @@ -718,16 +710,14 @@ static int __init vdso_init(void)
> ...
>>
>> -
>> -#ifdef CONFIG_VDSO32
>> vdso32_kbase = &vdso32_start;
>>
>> /*
>> @@ -735,8 +725,6 @@ static int __init vdso_init(void)
>> */
>> vdso32_pages = (&vdso32_end - &vdso32_start) >> PAGE_SHIFT;
>> DBG("vdso32_kbase: %p, 0x%x pages\n", vdso32_kbase, vdso32_pages);
>> -#endif
>
> This didn't build for ppc64le:
>
> /opt/cross/gcc-8.20_binutils-2.32/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-ld: arch/powerpc/kernel/vdso.o:(.toc+0x0): undefined reference to `vdso32_end'
> /opt/cross/gcc-8.20_binutils-2.32/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-ld: arch/powerpc/kernel/vdso.o:(.toc+0x8): undefined reference to `vdso32_start'
> make[1]: *** [/scratch/michael/build/maint/Makefile:1166: vmlinux] Error 1
> make: *** [Makefile:185: __sub-make] Error 2
>
> So I just put that ifdef back.
>
Argh. I guess that's the DBG() that hurts. I'll think about it.
Christophe
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v1 4/9] powerpc/vdso: Remove unnecessary ifdefs in vdso_pagelist initialization
2020-08-26 14:58 ` Michael Ellerman
2020-08-26 15:21 ` Christophe Leroy
@ 2020-08-27 6:47 ` Christophe Leroy
2020-08-27 13:19 ` Michael Ellerman
1 sibling, 1 reply; 15+ messages in thread
From: Christophe Leroy @ 2020-08-27 6:47 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras
Cc: linux-kernel, linuxppc-dev
On 08/26/2020 02:58 PM, Michael Ellerman wrote:
> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>> diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
>> index daef14a284a3..bbb69832fd46 100644
>> --- a/arch/powerpc/kernel/vdso.c
>> +++ b/arch/powerpc/kernel/vdso.c
>> @@ -718,16 +710,14 @@ static int __init vdso_init(void)
> ...
>>
>> -
>> -#ifdef CONFIG_VDSO32
>> vdso32_kbase = &vdso32_start;
>>
>> /*
>> @@ -735,8 +725,6 @@ static int __init vdso_init(void)
>> */
>> vdso32_pages = (&vdso32_end - &vdso32_start) >> PAGE_SHIFT;
>> DBG("vdso32_kbase: %p, 0x%x pages\n", vdso32_kbase, vdso32_pages);
>> -#endif
>
> This didn't build for ppc64le:
>
> /opt/cross/gcc-8.20_binutils-2.32/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-ld: arch/powerpc/kernel/vdso.o:(.toc+0x0): undefined reference to `vdso32_end'
> /opt/cross/gcc-8.20_binutils-2.32/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-ld: arch/powerpc/kernel/vdso.o:(.toc+0x8): undefined reference to `vdso32_start'
> make[1]: *** [/scratch/michael/build/maint/Makefile:1166: vmlinux] Error 1
> make: *** [Makefile:185: __sub-make] Error 2
>
> So I just put that ifdef back.
>
The problem is because is_32bit() can still return true even when
CONFIG_VDSO32 is not set.
The change below fixes the problem:
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index bbb69832fd46..38abff60cbe2 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -132,11 +132,7 @@ int arch_setup_additional_pages(struct linux_binprm
*bprm, int uses_interp)
if (!vdso_ready)
return 0;
- if (is_32bit_task()) {
- vdso_pagelist = vdso32_pagelist;
- vdso_pages = vdso32_pages;
- vdso_base = VDSO32_MBASE;
- } else {
+ if (!is_32bit_task()) {
vdso_pagelist = vdso64_pagelist;
vdso_pages = vdso64_pages;
/*
@@ -145,6 +141,12 @@ int arch_setup_additional_pages(struct linux_binprm
*bprm, int uses_interp)
* and most likely share a SLB entry.
*/
vdso_base = 0;
+ } else if (IS_ENABLED(CONFIG_VDSO32)) {
+ vdso_pagelist = vdso32_pagelist;
+ vdso_pages = vdso32_pages;
+ vdso_base = VDSO32_MBASE;
+ } else {
+ vdso_pages = 0;
}
current->mm->context.vdso_base = 0;
With this change all vdso32 static objects (functions and vars) go away
as expected.
We get a simple conflict with the following patch.
Do you prefer an updated series or a follow up patch, or you take the
above change yourself ?
Christophe
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v1 4/9] powerpc/vdso: Remove unnecessary ifdefs in vdso_pagelist initialization
2020-08-27 6:47 ` Christophe Leroy
@ 2020-08-27 13:19 ` Michael Ellerman
2020-08-28 5:40 ` Christophe Leroy
0 siblings, 1 reply; 15+ messages in thread
From: Michael Ellerman @ 2020-08-27 13:19 UTC (permalink / raw)
To: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras
Cc: linux-kernel, linuxppc-dev
Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> On 08/26/2020 02:58 PM, Michael Ellerman wrote:
>> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>>> diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
>>> index daef14a284a3..bbb69832fd46 100644
>>> --- a/arch/powerpc/kernel/vdso.c
>>> +++ b/arch/powerpc/kernel/vdso.c
>>> @@ -718,16 +710,14 @@ static int __init vdso_init(void)
>> ...
>>>
>>> -
>>> -#ifdef CONFIG_VDSO32
>>> vdso32_kbase = &vdso32_start;
>>>
>>> /*
>>> @@ -735,8 +725,6 @@ static int __init vdso_init(void)
>>> */
>>> vdso32_pages = (&vdso32_end - &vdso32_start) >> PAGE_SHIFT;
>>> DBG("vdso32_kbase: %p, 0x%x pages\n", vdso32_kbase, vdso32_pages);
>>> -#endif
>>
>> This didn't build for ppc64le:
>>
>> /opt/cross/gcc-8.20_binutils-2.32/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-ld: arch/powerpc/kernel/vdso.o:(.toc+0x0): undefined reference to `vdso32_end'
>> /opt/cross/gcc-8.20_binutils-2.32/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-ld: arch/powerpc/kernel/vdso.o:(.toc+0x8): undefined reference to `vdso32_start'
>> make[1]: *** [/scratch/michael/build/maint/Makefile:1166: vmlinux] Error 1
>> make: *** [Makefile:185: __sub-make] Error 2
>>
>> So I just put that ifdef back.
>>
>
> The problem is because is_32bit() can still return true even when
> CONFIG_VDSO32 is not set.
Hmm, you're right. My config had CONFIG_COMPAT enabled.
But that seems like a bug, if someone enables COMPAT on ppc64le they are
almost certainly going to want VDSO32 as well.
So I think I'll do a lead up patch as below.
cheers
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index d4fd109f177e..cf2da1e401ef 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -501,13 +501,12 @@ endmenu
config VDSO32
def_bool y
- depends on PPC32 || CPU_BIG_ENDIAN
+ depends on PPC32 || COMPAT
help
This symbol controls whether we build the 32-bit VDSO. We obviously
want to do that if we're building a 32-bit kernel. If we're building
- a 64-bit kernel then we only want a 32-bit VDSO if we're building for
- big endian. That is because the only little endian configuration we
- support is ppc64le which is 64-bit only.
+ a 64-bit kernel then we only want a 32-bit VDSO if we're also enabling
+ COMPAT.
choice
prompt "Endianness selection"
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v1 4/9] powerpc/vdso: Remove unnecessary ifdefs in vdso_pagelist initialization
2020-08-27 13:19 ` Michael Ellerman
@ 2020-08-28 5:40 ` Christophe Leroy
2020-08-28 5:46 ` Christophe Leroy
0 siblings, 1 reply; 15+ messages in thread
From: Christophe Leroy @ 2020-08-28 5:40 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras
Cc: linux-kernel, linuxppc-dev
Le 27/08/2020 à 15:19, Michael Ellerman a écrit :
> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>> On 08/26/2020 02:58 PM, Michael Ellerman wrote:
>>> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>>>> diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
>>>> index daef14a284a3..bbb69832fd46 100644
>>>> --- a/arch/powerpc/kernel/vdso.c
>>>> +++ b/arch/powerpc/kernel/vdso.c
>>>> @@ -718,16 +710,14 @@ static int __init vdso_init(void)
>>> ...
>>>>
>>>> -
>>>> -#ifdef CONFIG_VDSO32
>>>> vdso32_kbase = &vdso32_start;
>>>>
>>>> /*
>>>> @@ -735,8 +725,6 @@ static int __init vdso_init(void)
>>>> */
>>>> vdso32_pages = (&vdso32_end - &vdso32_start) >> PAGE_SHIFT;
>>>> DBG("vdso32_kbase: %p, 0x%x pages\n", vdso32_kbase, vdso32_pages);
>>>> -#endif
>>>
>>> This didn't build for ppc64le:
>>>
>>> /opt/cross/gcc-8.20_binutils-2.32/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-ld: arch/powerpc/kernel/vdso.o:(.toc+0x0): undefined reference to `vdso32_end'
>>> /opt/cross/gcc-8.20_binutils-2.32/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-ld: arch/powerpc/kernel/vdso.o:(.toc+0x8): undefined reference to `vdso32_start'
>>> make[1]: *** [/scratch/michael/build/maint/Makefile:1166: vmlinux] Error 1
>>> make: *** [Makefile:185: __sub-make] Error 2
>>>
>>> So I just put that ifdef back.
>>>
>>
>> The problem is because is_32bit() can still return true even when
>> CONFIG_VDSO32 is not set.
>
> Hmm, you're right. My config had CONFIG_COMPAT enabled.
>
> But that seems like a bug, if someone enables COMPAT on ppc64le they are
> almost certainly going to want VDSO32 as well.
>
> So I think I'll do a lead up patch as below.
Ah yes, and with that then no need to consider the case where
is_32bit_task() is true and CONFIG_VDSO32 is not selected.
I'll update my leading series accordingly.
Christophe
>
> cheers
>
> diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
> index d4fd109f177e..cf2da1e401ef 100644
> --- a/arch/powerpc/platforms/Kconfig.cputype
> +++ b/arch/powerpc/platforms/Kconfig.cputype
> @@ -501,13 +501,12 @@ endmenu
>
> config VDSO32
> def_bool y
> - depends on PPC32 || CPU_BIG_ENDIAN
> + depends on PPC32 || COMPAT
> help
> This symbol controls whether we build the 32-bit VDSO. We obviously
> want to do that if we're building a 32-bit kernel. If we're building
> - a 64-bit kernel then we only want a 32-bit VDSO if we're building for
> - big endian. That is because the only little endian configuration we
> - support is ppc64le which is 64-bit only.
> + a 64-bit kernel then we only want a 32-bit VDSO if we're also enabling
> + COMPAT.
>
> choice
> prompt "Endianness selection"
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v1 4/9] powerpc/vdso: Remove unnecessary ifdefs in vdso_pagelist initialization
2020-08-28 5:40 ` Christophe Leroy
@ 2020-08-28 5:46 ` Christophe Leroy
0 siblings, 0 replies; 15+ messages in thread
From: Christophe Leroy @ 2020-08-28 5:46 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras
Cc: linux-kernel, linuxppc-dev
Le 28/08/2020 à 07:40, Christophe Leroy a écrit :
>
>
> Le 27/08/2020 à 15:19, Michael Ellerman a écrit :
>> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>>> On 08/26/2020 02:58 PM, Michael Ellerman wrote:
>>>> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>>>>> diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
>>>>> index daef14a284a3..bbb69832fd46 100644
>>>>> --- a/arch/powerpc/kernel/vdso.c
>>>>> +++ b/arch/powerpc/kernel/vdso.c
>>>>> @@ -718,16 +710,14 @@ static int __init vdso_init(void)
>>>> ...
>>>>> -
>>>>> -#ifdef CONFIG_VDSO32
>>>>> vdso32_kbase = &vdso32_start;
>>>>> /*
>>>>> @@ -735,8 +725,6 @@ static int __init vdso_init(void)
>>>>> */
>>>>> vdso32_pages = (&vdso32_end - &vdso32_start) >> PAGE_SHIFT;
>>>>> DBG("vdso32_kbase: %p, 0x%x pages\n", vdso32_kbase,
>>>>> vdso32_pages);
>>>>> -#endif
>>>>
>>>> This didn't build for ppc64le:
>>>>
>>>>
>>>> /opt/cross/gcc-8.20_binutils-2.32/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-ld:
>>>> arch/powerpc/kernel/vdso.o:(.toc+0x0): undefined reference to
>>>> `vdso32_end'
>>>>
>>>> /opt/cross/gcc-8.20_binutils-2.32/powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux-gnu-ld:
>>>> arch/powerpc/kernel/vdso.o:(.toc+0x8): undefined reference to
>>>> `vdso32_start'
>>>> make[1]: *** [/scratch/michael/build/maint/Makefile:1166:
>>>> vmlinux] Error 1
>>>> make: *** [Makefile:185: __sub-make] Error 2
>>>>
>>>> So I just put that ifdef back.
>>>>
>>>
>>> The problem is because is_32bit() can still return true even when
>>> CONFIG_VDSO32 is not set.
>>
>> Hmm, you're right. My config had CONFIG_COMPAT enabled.
>>
>> But that seems like a bug, if someone enables COMPAT on ppc64le they are
>> almost certainly going to want VDSO32 as well.
>>
>> So I think I'll do a lead up patch as below.
>
> Ah yes, and with that then no need to consider the case where
> is_32bit_task() is true and CONFIG_VDSO32 is not selected.
>
> I'll update my leading series accordingly.
I meant follow up series.
Christophe
>
> Christophe
>
>>
>> cheers
>>
>> diff --git a/arch/powerpc/platforms/Kconfig.cputype
>> b/arch/powerpc/platforms/Kconfig.cputype
>> index d4fd109f177e..cf2da1e401ef 100644
>> --- a/arch/powerpc/platforms/Kconfig.cputype
>> +++ b/arch/powerpc/platforms/Kconfig.cputype
>> @@ -501,13 +501,12 @@ endmenu
>> config VDSO32
>> def_bool y
>> - depends on PPC32 || CPU_BIG_ENDIAN
>> + depends on PPC32 || COMPAT
>> help
>> This symbol controls whether we build the 32-bit VDSO. We
>> obviously
>> want to do that if we're building a 32-bit kernel. If we're
>> building
>> - a 64-bit kernel then we only want a 32-bit VDSO if we're
>> building for
>> - big endian. That is because the only little endian
>> configuration we
>> - support is ppc64le which is 64-bit only.
>> + a 64-bit kernel then we only want a 32-bit VDSO if we're also
>> enabling
>> + COMPAT.
>> choice
>> prompt "Endianness selection"
>>
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v1 5/9] powerpc/vdso: move to _install_special_mapping() and remove arch_vma_name()
2020-08-25 13:53 [PATCH v1 1/9] powerpc/vdso: Remove BUG_ON() in vdso_init() Christophe Leroy
` (2 preceding siblings ...)
2020-08-25 13:54 ` [PATCH v1 4/9] powerpc/vdso: Remove unnecessary ifdefs in vdso_pagelist initialization Christophe Leroy
@ 2020-08-25 13:54 ` Christophe Leroy
2020-08-25 13:54 ` [PATCH v1 6/9] powerpc/vdso: Provide vdso_remap() Christophe Leroy
` (3 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: Christophe Leroy @ 2020-08-25 13:54 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linux-kernel, linuxppc-dev
From commit 2fea7f6c98f5 ("arm64: vdso: move to
_install_special_mapping and remove arch_vma_name").
Use the new _install_special_mapping() API added by
commit a62c34bd2a8a ("x86, mm: Improve _install_special_mapping
and fix x86 vdso naming") which obsolete install_special_mapping().
And remove arch_vma_name() as the name is handled by the new API.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/vdso.c | 59 +++++++++++++++++++-------------------
1 file changed, 30 insertions(+), 29 deletions(-)
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index bbb69832fd46..4ccfc0dc96b5 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -47,7 +47,6 @@
static unsigned int vdso32_pages;
static void *vdso32_kbase;
-static struct page **vdso32_pagelist;
unsigned long vdso32_sigtramp;
unsigned long vdso32_rt_sigtramp;
@@ -56,7 +55,6 @@ extern char vdso32_start, vdso32_end;
extern char vdso64_start, vdso64_end;
static void *vdso64_kbase = &vdso64_start;
static unsigned int vdso64_pages;
-static struct page **vdso64_pagelist;
#ifdef CONFIG_PPC64
unsigned long vdso64_rt_sigtramp;
#endif /* CONFIG_PPC64 */
@@ -117,6 +115,14 @@ struct lib64_elfinfo
};
+static struct vm_special_mapping vdso32_spec __ro_after_init = {
+ .name = "[vdso]",
+};
+
+static struct vm_special_mapping vdso64_spec __ro_after_init = {
+ .name = "[vdso]",
+};
+
/*
* This is called from binfmt_elf, we create the special vma for the
* vDSO and insert it into the mm struct tree
@@ -124,7 +130,8 @@ struct lib64_elfinfo
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{
struct mm_struct *mm = current->mm;
- struct page **vdso_pagelist;
+ struct vm_special_mapping *vdso_spec;
+ struct vm_area_struct *vma;
unsigned long vdso_pages;
unsigned long vdso_base;
int rc;
@@ -133,11 +140,11 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
return 0;
if (is_32bit_task()) {
- vdso_pagelist = vdso32_pagelist;
+ vdso_spec = &vdso32_spec;
vdso_pages = vdso32_pages;
vdso_base = VDSO32_MBASE;
} else {
- vdso_pagelist = vdso64_pagelist;
+ vdso_spec = &vdso64_spec;
vdso_pages = vdso64_pages;
/*
* On 64bit we don't have a preferred map address. This
@@ -194,12 +201,12 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
* It's fine to use that for setting breakpoints in the vDSO code
* pages though.
*/
- rc = install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT,
- VM_READ|VM_EXEC|
- VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
- vdso_pagelist);
- if (rc) {
+ vma = _install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT,
+ VM_READ | VM_EXEC | VM_MAYREAD |
+ VM_MAYWRITE | VM_MAYEXEC, vdso_spec);
+ if (IS_ERR(vma)) {
current->mm->context.vdso_base = 0;
+ rc = PTR_ERR(vma);
goto fail_mmapsem;
}
@@ -211,15 +218,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
return rc;
}
-const char *arch_vma_name(struct vm_area_struct *vma)
-{
- if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso_base)
- return "[vdso]";
- return NULL;
-}
-
-
-
#ifdef CONFIG_VDSO32
static void * __init find_section32(Elf32_Ehdr *ehdr, const char *secname,
unsigned long *size)
@@ -685,6 +683,7 @@ early_initcall(vdso_getcpu_init);
static int __init vdso_init(void)
{
int i;
+ struct page **pagelist;
#ifdef CONFIG_PPC64
/*
@@ -740,27 +739,29 @@ static int __init vdso_init(void)
if (IS_ENABLED(CONFIG_VDSO32)) {
/* Make sure pages are in the correct state */
- vdso32_pagelist = kcalloc(vdso32_pages + 1, sizeof(struct page *),
- GFP_KERNEL);
- if (!vdso32_pagelist)
+ pagelist = kcalloc(vdso32_pages + 1, sizeof(struct page *), GFP_KERNEL);
+ if (!pagelist)
goto alloc_failed;
for (i = 0; i < vdso32_pages; i++)
- vdso32_pagelist[i] = virt_to_page(vdso32_kbase + i * PAGE_SIZE);
+ pagelist[i] = virt_to_page(vdso32_kbase + i * PAGE_SIZE);
+
+ pagelist[i++] = virt_to_page(vdso_data);
- vdso32_pagelist[i] = virt_to_page(vdso_data);
+ vdso32_spec.pages = pagelist;
}
if (IS_ENABLED(CONFIG_PPC64)) {
- vdso64_pagelist = kcalloc(vdso64_pages + 1, sizeof(struct page *),
- GFP_KERNEL);
- if (!vdso64_pagelist)
+ pagelist = kcalloc(vdso64_pages + 1, sizeof(struct page *), GFP_KERNEL);
+ if (!pagelist)
goto alloc_failed;
for (i = 0; i < vdso64_pages; i++)
- vdso64_pagelist[i] = virt_to_page(vdso64_kbase + i * PAGE_SIZE);
+ pagelist[i] = virt_to_page(vdso64_kbase + i * PAGE_SIZE);
+
+ pagelist[i++] = virt_to_page(vdso_data);
- vdso64_pagelist[i] = virt_to_page(vdso_data);
+ vdso64_spec.pages = pagelist;
}
smp_wmb();
--
2.25.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 6/9] powerpc/vdso: Provide vdso_remap()
2020-08-25 13:53 [PATCH v1 1/9] powerpc/vdso: Remove BUG_ON() in vdso_init() Christophe Leroy
` (3 preceding siblings ...)
2020-08-25 13:54 ` [PATCH v1 5/9] powerpc/vdso: move to _install_special_mapping() and remove arch_vma_name() Christophe Leroy
@ 2020-08-25 13:54 ` Christophe Leroy
2020-08-25 13:54 ` [PATCH v1 7/9] powerpc/vdso: Move vdso datapage up front Christophe Leroy
` (2 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: Christophe Leroy @ 2020-08-25 13:54 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linux-kernel, linuxppc-dev
Provide vdso_remap() through _install_special_mapping() and
drop arch_remap().
This adds a test of the size and returns -EINVAL if the size
is not correct.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/mm-arch-hooks.h | 25 ---------------------
arch/powerpc/kernel/vdso.c | 28 ++++++++++++++++++++++++
2 files changed, 28 insertions(+), 25 deletions(-)
delete mode 100644 arch/powerpc/include/asm/mm-arch-hooks.h
diff --git a/arch/powerpc/include/asm/mm-arch-hooks.h b/arch/powerpc/include/asm/mm-arch-hooks.h
deleted file mode 100644
index dce274be824a..000000000000
--- a/arch/powerpc/include/asm/mm-arch-hooks.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Architecture specific mm hooks
- *
- * Copyright (C) 2015, IBM Corporation
- * Author: Laurent Dufour <ldufour@linux.vnet.ibm.com>
- */
-
-#ifndef _ASM_POWERPC_MM_ARCH_HOOKS_H
-#define _ASM_POWERPC_MM_ARCH_HOOKS_H
-
-static inline void arch_remap(struct mm_struct *mm,
- unsigned long old_start, unsigned long old_end,
- unsigned long new_start, unsigned long new_end)
-{
- /*
- * mremap() doesn't allow moving multiple vmas so we can limit the
- * check to old_start == vdso_base.
- */
- if (old_start == mm->context.vdso_base)
- mm->context.vdso_base = new_start;
-}
-#define arch_remap arch_remap
-
-#endif /* _ASM_POWERPC_MM_ARCH_HOOKS_H */
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 4ccfc0dc96b5..b9270923452e 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -114,13 +114,41 @@ struct lib64_elfinfo
unsigned long text;
};
+static int vdso_mremap(unsigned long vdso_pages,
+ const struct vm_special_mapping *sm,
+ struct vm_area_struct *new_vma)
+{
+ unsigned long new_size = new_vma->vm_end - new_vma->vm_start;
+ unsigned long vdso_size = (vdso_pages + 1) << PAGE_SHIFT;
+
+ if (new_size != vdso_size)
+ return -EINVAL;
+
+ current->mm->context.vdso_base = (unsigned long)new_vma->vm_start;
+
+ return 0;
+}
+
+static int vdso32_mremap(const struct vm_special_mapping *sm,
+ struct vm_area_struct *new_vma)
+{
+ return vdso_mremap(vdso32_pages, sm, new_vma);
+}
+
+static int vdso64_mremap(const struct vm_special_mapping *sm,
+ struct vm_area_struct *new_vma)
+{
+ return vdso_mremap(vdso64_pages, sm, new_vma);
+}
static struct vm_special_mapping vdso32_spec __ro_after_init = {
.name = "[vdso]",
+ .mremap = vdso32_mremap,
};
static struct vm_special_mapping vdso64_spec __ro_after_init = {
.name = "[vdso]",
+ .mremap = vdso64_mremap,
};
/*
--
2.25.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 7/9] powerpc/vdso: Move vdso datapage up front
2020-08-25 13:53 [PATCH v1 1/9] powerpc/vdso: Remove BUG_ON() in vdso_init() Christophe Leroy
` (4 preceding siblings ...)
2020-08-25 13:54 ` [PATCH v1 6/9] powerpc/vdso: Provide vdso_remap() Christophe Leroy
@ 2020-08-25 13:54 ` Christophe Leroy
2020-08-25 13:54 ` [PATCH v1 8/9] powerpc/vdso: Remove __kernel_datapage_offset and simplify __get_datapage() Christophe Leroy
2020-08-25 13:54 ` [PATCH v1 9/9] powerpc/vdso: Remove unused \tmp param in __get_datapage() Christophe Leroy
7 siblings, 0 replies; 15+ messages in thread
From: Christophe Leroy @ 2020-08-25 13:54 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linux-kernel, linuxppc-dev
Move the vdso datapage in front of the VDSO area,
before vdso test.
This will allow to remove the __kernel_datapage_offset symbol
and simplify __get_datapage() in the following patch.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/mmu_context.h | 4 +++-
arch/powerpc/kernel/vdso.c | 22 ++++++++++------------
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
index 7f3658a97384..be18ad12bb54 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -262,7 +262,9 @@ extern void arch_exit_mmap(struct mm_struct *mm);
static inline void arch_unmap(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
- if (start <= mm->context.vdso_base && mm->context.vdso_base < end)
+ unsigned long vdso_base = mm->context.vdso_base - PAGE_SIZE;
+
+ if (start <= vdso_base && vdso_base < end)
mm->context.vdso_base = 0;
}
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index b9270923452e..1d72c4b7672f 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -124,7 +124,7 @@ static int vdso_mremap(unsigned long vdso_pages,
if (new_size != vdso_size)
return -EINVAL;
- current->mm->context.vdso_base = (unsigned long)new_vma->vm_start;
+ current->mm->context.vdso_base = (unsigned long)new_vma->vm_start + PAGE_SIZE;
return 0;
}
@@ -217,7 +217,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
* install_special_mapping or the perf counter mmap tracking code
* will fail to recognise it as a vDSO (since arch_vma_name fails).
*/
- current->mm->context.vdso_base = vdso_base;
+ current->mm->context.vdso_base = vdso_base + PAGE_SIZE;
/*
* our vma flags don't have VM_WRITE so by default, the process isn't
@@ -516,8 +516,7 @@ static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32,
return -1;
}
*((int *)(vdso64_kbase + sym64->st_value - VDSO64_LBASE)) =
- (vdso64_pages << PAGE_SHIFT) -
- (sym64->st_value - VDSO64_LBASE);
+ (sym64->st_value - VDSO64_LBASE) - PAGE_SIZE;
#endif /* CONFIG_PPC64 */
#ifdef CONFIG_VDSO32
@@ -528,8 +527,7 @@ static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32,
return -1;
}
*((int *)(vdso32_kbase + (sym32->st_value - VDSO32_LBASE))) =
- (vdso32_pages << PAGE_SHIFT) -
- (sym32->st_value - VDSO32_LBASE);
+ (sym32->st_value - VDSO32_LBASE) - PAGE_SIZE;
#endif
return 0;
@@ -771,10 +769,10 @@ static int __init vdso_init(void)
if (!pagelist)
goto alloc_failed;
- for (i = 0; i < vdso32_pages; i++)
- pagelist[i] = virt_to_page(vdso32_kbase + i * PAGE_SIZE);
+ pagelist[0] = virt_to_page(vdso_data);
- pagelist[i++] = virt_to_page(vdso_data);
+ for (i = 0; i < vdso32_pages; i++)
+ pagelist[i + 1] = virt_to_page(vdso32_kbase + i * PAGE_SIZE);
vdso32_spec.pages = pagelist;
}
@@ -784,10 +782,10 @@ static int __init vdso_init(void)
if (!pagelist)
goto alloc_failed;
- for (i = 0; i < vdso64_pages; i++)
- pagelist[i] = virt_to_page(vdso64_kbase + i * PAGE_SIZE);
+ pagelist[0] = virt_to_page(vdso_data);
- pagelist[i++] = virt_to_page(vdso_data);
+ for (i = 0; i < vdso64_pages; i++)
+ pagelist[i + 1] = virt_to_page(vdso64_kbase + i * PAGE_SIZE);
vdso64_spec.pages = pagelist;
}
--
2.25.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 8/9] powerpc/vdso: Remove __kernel_datapage_offset and simplify __get_datapage()
2020-08-25 13:53 [PATCH v1 1/9] powerpc/vdso: Remove BUG_ON() in vdso_init() Christophe Leroy
` (5 preceding siblings ...)
2020-08-25 13:54 ` [PATCH v1 7/9] powerpc/vdso: Move vdso datapage up front Christophe Leroy
@ 2020-08-25 13:54 ` Christophe Leroy
2020-08-25 13:54 ` [PATCH v1 9/9] powerpc/vdso: Remove unused \tmp param in __get_datapage() Christophe Leroy
7 siblings, 0 replies; 15+ messages in thread
From: Christophe Leroy @ 2020-08-25 13:54 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linux-kernel, linuxppc-dev
The VDSO datapage and the text pages are always located immediately
next to each other, so it can be hardcoded without an indirection
through __kernel_datapage_offset
Before:
clock-getres-realtime-coarse: vdso: 714 nsec/call
clock-gettime-realtime-coarse: vdso: 792 nsec/call
clock-gettime-realtime: vdso: 1243 nsec/call
After:
clock-getres-realtime-coarse: vdso: 699 nsec/call
clock-gettime-realtime-coarse: vdso: 784 nsec/call
clock-gettime-realtime: vdso: 1231 nsec/call
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/vdso_datapage.h | 8 +++--
arch/powerpc/kernel/vdso.c | 37 ------------------------
arch/powerpc/kernel/vdso32/datapage.S | 3 --
arch/powerpc/kernel/vdso32/vdso32.lds.S | 7 ++---
arch/powerpc/kernel/vdso64/datapage.S | 3 --
arch/powerpc/kernel/vdso64/vdso64.lds.S | 7 ++---
6 files changed, 9 insertions(+), 56 deletions(-)
diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h
index c4d320504d26..2bc415f7714c 100644
--- a/arch/powerpc/include/asm/vdso_datapage.h
+++ b/arch/powerpc/include/asm/vdso_datapage.h
@@ -104,10 +104,12 @@ extern struct vdso_arch_data *vdso_data;
.macro get_datapage ptr, tmp
bcl 20, 31, .+4
+999:
mflr \ptr
- addi \ptr, \ptr, (__kernel_datapage_offset - (.-4))@l
- lwz \tmp, 0(\ptr)
- add \ptr, \tmp, \ptr
+#if CONFIG_PPC_PAGE_SHIFT > 14
+ addis \ptr, \ptr, (_vdso_datapage - 999b)@ha
+#endif
+ addi \ptr, \ptr, (_vdso_datapage - 999b)@l
.endm
#endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 1d72c4b7672f..e2568d9ecdff 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -500,40 +500,6 @@ static __init void vdso_setup_trampolines(struct lib32_elfinfo *v32,
vdso32_rt_sigtramp = find_function32(v32, "__kernel_sigtramp_rt32");
}
-static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32,
- struct lib64_elfinfo *v64)
-{
-#ifdef CONFIG_VDSO32
- Elf32_Sym *sym32;
-#endif
-#ifdef CONFIG_PPC64
- Elf64_Sym *sym64;
-
- sym64 = find_symbol64(v64, "__kernel_datapage_offset");
- if (sym64 == NULL) {
- printk(KERN_ERR "vDSO64: Can't find symbol "
- "__kernel_datapage_offset !\n");
- return -1;
- }
- *((int *)(vdso64_kbase + sym64->st_value - VDSO64_LBASE)) =
- (sym64->st_value - VDSO64_LBASE) - PAGE_SIZE;
-#endif /* CONFIG_PPC64 */
-
-#ifdef CONFIG_VDSO32
- sym32 = find_symbol32(v32, "__kernel_datapage_offset");
- if (sym32 == NULL) {
- printk(KERN_ERR "vDSO32: Can't find symbol "
- "__kernel_datapage_offset !\n");
- return -1;
- }
- *((int *)(vdso32_kbase + (sym32->st_value - VDSO32_LBASE))) =
- (sym32->st_value - VDSO32_LBASE) - PAGE_SIZE;
-#endif
-
- return 0;
-}
-
-
static __init int vdso_fixup_features(struct lib32_elfinfo *v32,
struct lib64_elfinfo *v64)
{
@@ -634,9 +600,6 @@ static __init int vdso_setup(void)
if (vdso_do_find_sections(&v32, &v64))
return -1;
- if (vdso_fixup_datapage(&v32, &v64))
- return -1;
-
if (vdso_fixup_features(&v32, &v64))
return -1;
diff --git a/arch/powerpc/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S
index 217bb630f8f9..5513a4f8253e 100644
--- a/arch/powerpc/kernel/vdso32/datapage.S
+++ b/arch/powerpc/kernel/vdso32/datapage.S
@@ -13,9 +13,6 @@
#include <asm/vdso_datapage.h>
.text
- .global __kernel_datapage_offset;
-__kernel_datapage_offset:
- .long 0
/*
* void *__kernel_get_syscall_map(unsigned int *syscall_count) ;
diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S
index 582c5b046cc9..25be27b47a9f 100644
--- a/arch/powerpc/kernel/vdso32/vdso32.lds.S
+++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S
@@ -4,6 +4,7 @@
* library
*/
#include <asm/vdso.h>
+#include <asm/page.h>
#ifdef __LITTLE_ENDIAN__
OUTPUT_FORMAT("elf32-powerpcle", "elf32-powerpcle", "elf32-powerpcle")
@@ -15,6 +16,7 @@ ENTRY(_start)
SECTIONS
{
+ PROVIDE(_vdso_datapage = . - PAGE_SIZE);
. = VDSO32_LBASE + SIZEOF_HEADERS;
.hash : { *(.hash) } :text
@@ -139,11 +141,6 @@ VERSION
{
VDSO_VERSION_STRING {
global:
- /*
- * Has to be there for the kernel to find
- */
- __kernel_datapage_offset;
-
__kernel_get_syscall_map;
#ifndef CONFIG_PPC_BOOK3S_601
__kernel_gettimeofday;
diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S
index 067247d3efb9..03bb72c440dc 100644
--- a/arch/powerpc/kernel/vdso64/datapage.S
+++ b/arch/powerpc/kernel/vdso64/datapage.S
@@ -13,9 +13,6 @@
#include <asm/vdso_datapage.h>
.text
-.global __kernel_datapage_offset;
-__kernel_datapage_offset:
- .long 0
/*
* void *__kernel_get_syscall_map(unsigned int *syscall_count) ;
diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S
index 4e3a8d4ee614..aaa5acf6d1b9 100644
--- a/arch/powerpc/kernel/vdso64/vdso64.lds.S
+++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S
@@ -4,6 +4,7 @@
* library
*/
#include <asm/vdso.h>
+#include <asm/page.h>
#ifdef __LITTLE_ENDIAN__
OUTPUT_FORMAT("elf64-powerpcle", "elf64-powerpcle", "elf64-powerpcle")
@@ -15,6 +16,7 @@ ENTRY(_start)
SECTIONS
{
+ PROVIDE(_vdso_datapage = . - PAGE_SIZE);
. = VDSO64_LBASE + SIZEOF_HEADERS;
.hash : { *(.hash) } :text
@@ -139,11 +141,6 @@ VERSION
{
VDSO_VERSION_STRING {
global:
- /*
- * Has to be there for the kernel to find
- */
- __kernel_datapage_offset;
-
__kernel_get_syscall_map;
__kernel_gettimeofday;
__kernel_clock_gettime;
--
2.25.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v1 9/9] powerpc/vdso: Remove unused \tmp param in __get_datapage()
2020-08-25 13:53 [PATCH v1 1/9] powerpc/vdso: Remove BUG_ON() in vdso_init() Christophe Leroy
` (6 preceding siblings ...)
2020-08-25 13:54 ` [PATCH v1 8/9] powerpc/vdso: Remove __kernel_datapage_offset and simplify __get_datapage() Christophe Leroy
@ 2020-08-25 13:54 ` Christophe Leroy
7 siblings, 0 replies; 15+ messages in thread
From: Christophe Leroy @ 2020-08-25 13:54 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linux-kernel, linuxppc-dev
The \tmp param is not used anymore, remove it.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/vdso/gettimeofday.h | 4 ++--
arch/powerpc/include/asm/vdso_datapage.h | 2 +-
arch/powerpc/kernel/vdso32/cacheflush.S | 2 +-
arch/powerpc/kernel/vdso32/datapage.S | 4 ++--
arch/powerpc/kernel/vdso64/cacheflush.S | 2 +-
arch/powerpc/kernel/vdso64/datapage.S | 4 ++--
6 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/include/asm/vdso/gettimeofday.h b/arch/powerpc/include/asm/vdso/gettimeofday.h
index 59a609a48b63..8602f1243e8d 100644
--- a/arch/powerpc/include/asm/vdso/gettimeofday.h
+++ b/arch/powerpc/include/asm/vdso/gettimeofday.h
@@ -22,7 +22,7 @@
#ifdef CONFIG_PPC64
PPC_STL r2, STACK_FRAME_OVERHEAD + STK_GOT(r1)
#endif
- get_datapage r5, r0
+ get_datapage r5
addi r5, r5, VDSO_DATA_OFFSET
bl \funct
PPC_LL r0, STACK_FRAME_OVERHEAD + PPC_LR_STKOFF(r1)
@@ -51,7 +51,7 @@
#ifdef CONFIG_PPC64
PPC_STL r2, STACK_FRAME_OVERHEAD + STK_GOT(r1)
#endif
- get_datapage r4, r0
+ get_datapage r4
addi r4, r4, VDSO_DATA_OFFSET
bl \funct
PPC_LL r0, STACK_FRAME_OVERHEAD + PPC_LR_STKOFF(r1)
diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h
index 2bc415f7714c..71f44598f392 100644
--- a/arch/powerpc/include/asm/vdso_datapage.h
+++ b/arch/powerpc/include/asm/vdso_datapage.h
@@ -102,7 +102,7 @@ extern struct vdso_arch_data *vdso_data;
#else /* __ASSEMBLY__ */
-.macro get_datapage ptr, tmp
+.macro get_datapage ptr
bcl 20, 31, .+4
999:
mflr \ptr
diff --git a/arch/powerpc/kernel/vdso32/cacheflush.S b/arch/powerpc/kernel/vdso32/cacheflush.S
index 3440ddf21c8b..017843bf5382 100644
--- a/arch/powerpc/kernel/vdso32/cacheflush.S
+++ b/arch/powerpc/kernel/vdso32/cacheflush.S
@@ -27,7 +27,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache)
#ifdef CONFIG_PPC64
mflr r12
.cfi_register lr,r12
- get_datapage r10, r0
+ get_datapage r10
mtlr r12
#endif
diff --git a/arch/powerpc/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S
index 5513a4f8253e..0513a2eabec8 100644
--- a/arch/powerpc/kernel/vdso32/datapage.S
+++ b/arch/powerpc/kernel/vdso32/datapage.S
@@ -28,7 +28,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
mflr r12
.cfi_register lr,r12
mr. r4,r3
- get_datapage r3, r0
+ get_datapage r3
mtlr r12
addi r3,r3,CFG_SYSCALL_MAP32
beqlr
@@ -49,7 +49,7 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
.cfi_startproc
mflr r12
.cfi_register lr,r12
- get_datapage r3, r0
+ get_datapage r3
lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3)
lwz r3,CFG_TB_TICKS_PER_SEC(r3)
mtlr r12
diff --git a/arch/powerpc/kernel/vdso64/cacheflush.S b/arch/powerpc/kernel/vdso64/cacheflush.S
index cab14324242b..61985de5758f 100644
--- a/arch/powerpc/kernel/vdso64/cacheflush.S
+++ b/arch/powerpc/kernel/vdso64/cacheflush.S
@@ -25,7 +25,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache)
.cfi_startproc
mflr r12
.cfi_register lr,r12
- get_datapage r10, r0
+ get_datapage r10
mtlr r12
lwz r7,CFG_DCACHE_BLOCKSZ(r10)
diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S
index 03bb72c440dc..00760dc69d68 100644
--- a/arch/powerpc/kernel/vdso64/datapage.S
+++ b/arch/powerpc/kernel/vdso64/datapage.S
@@ -28,7 +28,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
mflr r12
.cfi_register lr,r12
mr r4,r3
- get_datapage r3, r0
+ get_datapage r3
mtlr r12
addi r3,r3,CFG_SYSCALL_MAP64
cmpldi cr0,r4,0
@@ -50,7 +50,7 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
.cfi_startproc
mflr r12
.cfi_register lr,r12
- get_datapage r3, r0
+ get_datapage r3
ld r3,CFG_TB_TICKS_PER_SEC(r3)
mtlr r12
crclr cr0*4+so
--
2.25.0
^ permalink raw reply related [flat|nested] 15+ messages in thread