Since commit 511157ab641e ("powerpc/vdso: Move vdso datapage up front")
VVAR page is in front of the VDSO area. In result it breaks CRIU
(Checkpoint Restore In Userspace) [1], where CRIU expects that "[vdso]"
from /proc/../maps points at ELF/vdso image, rather than at VVAR data page.
Laurent made a patch to keep CRIU working (by reading aux vector).
But I think it still makes sence to separate two mappings into different
VMAs. It will also make ppc64 less "special" for userspace and as
a side-bonus will make VVAR page un-writable by debugger (which previously
would COW page and can be unexpected).
I opportunistically Cc stable on it: I understand that usually such
stuff isn't a stable material, but that will allow us in CRIU have
one workaround less that is needed just for one release (v5.11) on
one platform (ppc64), which we otherwise have to maintain.
I wouldn't go as far as to say that the commit 511157ab641e is ABI
regression as no other userspace got broken, but I'd really appreciate
if it gets backported to v5.11 after v5.12 is released, so as not
to complicate already non-simple CRIU-vdso code. Thanks!
Cc: Andrei Vagin <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Christophe Leroy <redacted>
Cc: Laurent Dufour <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <redacted>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: stable@vger.kernel.org # v5.11
[1]: https://github.com/checkpoint-restore/criu/issues/1417
Signed-off-by: Dmitry Safonov <redacted>
Tested-by: Christophe Leroy <redacted>
---
arch/powerpc/include/asm/mmu_context.h | 2 +-
arch/powerpc/kernel/vdso.c | 54 +++++++++++++++++++-------
2 files changed, 40 insertions(+), 16 deletions(-)
@@ -110,8 +114,8 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_intvdso_base=0;}-/* Add a page to the vdso size for the data page */-vdso_size+=PAGE_SIZE;+mappings_size=vdso_size+vvar_size;+mappings_size+=(VDSO_ALIGNMENT-1)&PAGE_MASK;/**pickabaseaddressforthevDSOinprocessspace.Wetrytoputit
@@ -119,9 +123,7 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int*andendupputtingitelsewhere.*Addenoughtothesizesothattheresultcanbealigned.*/-vdso_base=get_unmapped_area(NULL,vdso_base,-vdso_size+((VDSO_ALIGNMENT-1)&PAGE_MASK),-0,0);+vdso_base=get_unmapped_area(NULL,vdso_base,mappings_size,0,0);if(IS_ERR_VALUE(vdso_base))returnvdso_base;
@@ -133,7 +135,13 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int*install_special_mappingortheperfcountermmaptrackingcode*willfailtorecogniseitasavDSO.*/-mm->context.vdso=(void__user*)vdso_base+PAGE_SIZE;+mm->context.vdso=(void__user*)vdso_base+vvar_size;++vma=_install_special_mapping(mm,vdso_base,vvar_size,+VM_READ|VM_MAYREAD|VM_IO|+VM_DONTDUMP|VM_PFNMAP,&vvar_spec);+if(IS_ERR(vma))+returnPTR_ERR(vma);/**ourvmaflagsdon'thaveVM_WRITEsobydefault,theprocessisn't
@@ -145,9 +153,12 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int*It'sfinetousethatforsettingbreakpointsinthevDSOcode*pagesthough.*/-vma=_install_special_mapping(mm,vdso_base,vdso_size,+vma=_install_special_mapping(mm,vdso_base+vvar_size,vdso_size,VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,vdso_spec);+if(IS_ERR(vma))+do_munmap(mm,vdso_base,vvar_size,NULL);+returnPTR_ERR_OR_ZERO(vma);}
@@ -249,11 +260,22 @@ static struct page ** __init vdso_setup_pages(void *start, void *end)if(!pagelist)panic("%s: Cannot allocate page list for VDSO",__func__);-pagelist[0]=virt_to_page(vdso_data);-for(i=0;i<pages;i++)-pagelist[i+1]=virt_to_page(start+i*PAGE_SIZE);+pagelist[i]=virt_to_page(start+i*PAGE_SIZE);++returnpagelist;+}++staticstructpage**__initvvar_setup_pages(void)+{+structpage**pagelist;+/* .pages is NULL-terminated */+pagelist=kcalloc(2,sizeof(structpage*),GFP_KERNEL);+if(!pagelist)+panic("%s: Cannot allocate page list for VVAR",__func__);++pagelist[0]=virt_to_page(vdso_data);returnpagelist;}
@@ -295,6 +317,8 @@ static int __init vdso_init(void)if(IS_ENABLED(CONFIG_PPC64))vdso64_spec.pages=vdso_setup_pages(&vdso64_start,&vdso64_end);+vvar_spec.pages=vvar_setup_pages();+smp_wmb();return0;
Since commit 511157ab641e ("powerpc/vdso: Move vdso datapage up front")
VVAR page is in front of the VDSO area. In result it breaks CRIU
(Checkpoint Restore In Userspace) [1], where CRIU expects that "[vdso]"
from /proc/../maps points at ELF/vdso image, rather than at VVAR data page.
Laurent made a patch to keep CRIU working (by reading aux vector).
But I think it still makes sence to separate two mappings into different
VMAs. It will also make ppc64 less "special" for userspace and as
a side-bonus will make VVAR page un-writable by debugger (which previously
would COW page and can be unexpected).
I opportunistically Cc stable on it: I understand that usually such
stuff isn't a stable material, but that will allow us in CRIU have
one workaround less that is needed just for one release (v5.11) on
one platform (ppc64), which we otherwise have to maintain.
Why is that a workaround, and why for one release only ? I think the solution proposed by Laurentto
use the aux vector AT_SYSINFO_EHDR should work with any past and future release.
I wouldn't go as far as to say that the commit 511157ab641e is ABI
regression as no other userspace got broken, but I'd really appreciate
if it gets backported to v5.11 after v5.12 is released, so as not
to complicate already non-simple CRIU-vdso code. Thanks!
Cc: Andrei Vagin <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Christophe Leroy <redacted>
Cc: Laurent Dufour <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <redacted>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: stable@vger.kernel.org # v5.11
[1]: https://github.com/checkpoint-restore/criu/issues/1417
Signed-off-by: Dmitry Safonov <redacted>
Tested-by: Christophe Leroy <redacted>
I tested it with sifreturn_vdso selftest and it worked, because that selftest doesn't involve VDSO data.
But if I do a mremap() on the VDSO text vma without remapping VVAR to keep the same distance between
the two vmas, gettimeofday() crashes. The reason is that the code obtains the address of the data by
calculating a fix difference from its own address with the below macro, the delta being resolved at
link time:
.macro get_datapage ptr
bcl 20, 31, .+4
999:
mflr \ptr
#if CONFIG_PPC_PAGE_SHIFT > 14
addis \ptr, \ptr, (_vdso_datapage - 999b)@ha
#endif
addi \ptr, \ptr, (_vdso_datapage - 999b)@l
.endm
So the datapage needs to remain at the same distance from the code at all time.
Wondering how the other architectures do to have two independant VMAs and be able to move one
independantly of the other.
Christophe
Hi Christophe,
On 3/27/21 5:19 PM, Christophe Leroy wrote:
[..]
quoted
I opportunistically Cc stable on it: I understand that usually such
stuff isn't a stable material, but that will allow us in CRIU have
one workaround less that is needed just for one release (v5.11) on
one platform (ppc64), which we otherwise have to maintain.
Why is that a workaround, and why for one release only ? I think the
solution proposed by Laurentto use the aux vector AT_SYSINFO_EHDR should
work with any past and future release.
Yeah, I guess.
Previously, (before v5.11/power) all kernels had ELF start at "[vdso]"
VMA start, now we'll have to carry the offset in the VMA. Probably, not
the worst thing, but as it will be only for v5.11 release it can break,
so needs separate testing.
Kinda life was a bit easier without this additional code.
quoted
I wouldn't go as far as to say that the commit 511157ab641e is ABI
regression as no other userspace got broken, but I'd really appreciate
if it gets backported to v5.11 after v5.12 is released, so as not
to complicate already non-simple CRIU-vdso code. Thanks!
Cc: Andrei Vagin <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Christophe Leroy <redacted>
Cc: Laurent Dufour <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <redacted>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: stable@vger.kernel.org # v5.11
[1]: https://github.com/checkpoint-restore/criu/issues/1417
Signed-off-by: Dmitry Safonov <redacted>
Tested-by: Christophe Leroy <redacted>
I tested it with sifreturn_vdso selftest and it worked, because that
selftest doesn't involve VDSO data.
Thanks again on helping with testing it, I appreciate it!
But if I do a mremap() on the VDSO text vma without remapping VVAR to
keep the same distance between the two vmas, gettimeofday() crashes. The
reason is that the code obtains the address of the data by calculating a
fix difference from its own address with the below macro, the delta
being resolved at link time:
.macro get_datapage ptr
bcl 20, 31, .+4
999:
mflr \ptr
#if CONFIG_PPC_PAGE_SHIFT > 14
addis \ptr, \ptr, (_vdso_datapage - 999b)@ha
#endif
addi \ptr, \ptr, (_vdso_datapage - 999b)@l
.endm
So the datapage needs to remain at the same distance from the code at
all time.
Wondering how the other architectures do to have two independent VMAs
and be able to move one independently of the other.
It's alright as far as I know. If userspace remaps vdso/vvar it should
be aware of this (CRIU keeps this in mind, also old vdso image is dumped
to compare on restore with the one that the host has).
Thanks,
Dmitry
Hi Christophe and Dimitry,
Le 27/03/2021 à 18:43, Dmitry Safonov a écrit :
Hi Christophe,
On 3/27/21 5:19 PM, Christophe Leroy wrote:
[..]
quoted
quoted
I opportunistically Cc stable on it: I understand that usually such
stuff isn't a stable material, but that will allow us in CRIU have
one workaround less that is needed just for one release (v5.11) on
one platform (ppc64), which we otherwise have to maintain.
Why is that a workaround, and why for one release only ? I think the
solution proposed by Laurentto use the aux vector AT_SYSINFO_EHDR should
work with any past and future release.
Yeah, I guess.
Previously, (before v5.11/power) all kernels had ELF start at "[vdso]"
VMA start, now we'll have to carry the offset in the VMA. Probably, not
the worst thing, but as it will be only for v5.11 release it can break,
so needs separate testing.
Kinda life was a bit easier without this additional code.
The assumption that ELF header is at the start of "[vdso]" is perhaps not a good
one, but using a "[vvar]" section looks more conventional and allows to clearly
identify the data part. I'd argue for this option.
quoted
quoted
I wouldn't go as far as to say that the commit 511157ab641e is ABI
regression as no other userspace got broken, but I'd really appreciate
if it gets backported to v5.11 after v5.12 is released, so as not
to complicate already non-simple CRIU-vdso code. Thanks!
Cc: Andrei Vagin <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Christophe Leroy <redacted>
Cc: Laurent Dufour <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <redacted>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: stable@vger.kernel.org # v5.11
[1]: https://github.com/checkpoint-restore/criu/issues/1417
Signed-off-by: Dmitry Safonov <redacted>
Tested-by: Christophe Leroy <redacted>
I tested it with sifreturn_vdso selftest and it worked, because that
selftest doesn't involve VDSO data.
Thanks again on helping with testing it, I appreciate it!
quoted
But if I do a mremap() on the VDSO text vma without remapping VVAR to
keep the same distance between the two vmas, gettimeofday() crashes. The
reason is that the code obtains the address of the data by calculating a
fix difference from its own address with the below macro, the delta
being resolved at link time:
.macro get_datapage ptr
bcl 20, 31, .+4
999:
mflr \ptr
#if CONFIG_PPC_PAGE_SHIFT > 14
addis \ptr, \ptr, (_vdso_datapage - 999b)@ha
#endif
addi \ptr, \ptr, (_vdso_datapage - 999b)@l
.endm
So the datapage needs to remain at the same distance from the code at
all time.
Wondering how the other architectures do to have two independent VMAs
and be able to move one independently of the other.
It's alright as far as I know. If userspace remaps vdso/vvar it should
be aware of this (CRIU keeps this in mind, also old vdso image is dumped
to compare on restore with the one that the host has).
I do agree, playing with the VDSO mapping needs the application to be aware of
the mapping details, and prior to 83d3f0e90c6c "powerpc/mm: tracking vDSO
remap", remapping the VDSO was not working on PowerPC and nobody complained...
Laurent.
Since commit 511157ab641e ("powerpc/vdso: Move vdso datapage up front")
VVAR page is in front of the VDSO area. In result it breaks CRIU
(Checkpoint Restore In Userspace) [1], where CRIU expects that "[vdso]"
from /proc/../maps points at ELF/vdso image, rather than at VVAR data page.
Laurent made a patch to keep CRIU working (by reading aux vector).
But I think it still makes sence to separate two mappings into different
VMAs. It will also make ppc64 less "special" for userspace and as
a side-bonus will make VVAR page un-writable by debugger (which previously
would COW page and can be unexpected).
I opportunistically Cc stable on it: I understand that usually such
stuff isn't a stable material, but that will allow us in CRIU have
one workaround less that is needed just for one release (v5.11) on
one platform (ppc64), which we otherwise have to maintain.
I wouldn't go as far as to say that the commit 511157ab641e is ABI
regression as no other userspace got broken, but I'd really appreciate
if it gets backported to v5.11 after v5.12 is released, so as not
to complicate already non-simple CRIU-vdso code. Thanks!
Cc: Andrei Vagin <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Christophe Leroy <redacted>
Cc: Laurent Dufour <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <redacted>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: stable@vger.kernel.org # v5.11
[1]: https://github.com/checkpoint-restore/criu/issues/1417
Signed-off-by: Dmitry Safonov <redacted>
Tested-by: Christophe Leroy <redacted>
I run the CRIU's test suite and except the usual suspects, all the tests passed.
Tested-by: Laurent Dufour <redacted>
@@ -110,8 +114,8 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_intvdso_base=0;}-/* Add a page to the vdso size for the data page */-vdso_size+=PAGE_SIZE;+mappings_size=vdso_size+vvar_size;+mappings_size+=(VDSO_ALIGNMENT-1)&PAGE_MASK;/**pickabaseaddressforthevDSOinprocessspace.Wetrytoputit
@@ -119,9 +123,7 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int*andendupputtingitelsewhere.*Addenoughtothesizesothattheresultcanbealigned.*/-vdso_base=get_unmapped_area(NULL,vdso_base,-vdso_size+((VDSO_ALIGNMENT-1)&PAGE_MASK),-0,0);+vdso_base=get_unmapped_area(NULL,vdso_base,mappings_size,0,0);if(IS_ERR_VALUE(vdso_base))returnvdso_base;
@@ -133,7 +135,13 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int*install_special_mappingortheperfcountermmaptrackingcode*willfailtorecogniseitasavDSO.*/-mm->context.vdso=(void__user*)vdso_base+PAGE_SIZE;+mm->context.vdso=(void__user*)vdso_base+vvar_size;++vma=_install_special_mapping(mm,vdso_base,vvar_size,+VM_READ|VM_MAYREAD|VM_IO|+VM_DONTDUMP|VM_PFNMAP,&vvar_spec);+if(IS_ERR(vma))+returnPTR_ERR(vma);/**ourvmaflagsdon'thaveVM_WRITEsobydefault,theprocessisn't
@@ -145,9 +153,12 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int*It'sfinetousethatforsettingbreakpointsinthevDSOcode*pagesthough.*/-vma=_install_special_mapping(mm,vdso_base,vdso_size,+vma=_install_special_mapping(mm,vdso_base+vvar_size,vdso_size,VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,vdso_spec);+if(IS_ERR(vma))+do_munmap(mm,vdso_base,vvar_size,NULL);+returnPTR_ERR_OR_ZERO(vma);}
@@ -249,11 +260,22 @@ static struct page ** __init vdso_setup_pages(void *start, void *end)if(!pagelist)panic("%s: Cannot allocate page list for VDSO",__func__);-pagelist[0]=virt_to_page(vdso_data);-for(i=0;i<pages;i++)-pagelist[i+1]=virt_to_page(start+i*PAGE_SIZE);+pagelist[i]=virt_to_page(start+i*PAGE_SIZE);++returnpagelist;+}++staticstructpage**__initvvar_setup_pages(void)+{+structpage**pagelist;+/* .pages is NULL-terminated */+pagelist=kcalloc(2,sizeof(structpage*),GFP_KERNEL);+if(!pagelist)+panic("%s: Cannot allocate page list for VVAR",__func__);++pagelist[0]=virt_to_page(vdso_data);returnpagelist;}
@@ -295,6 +317,8 @@ static int __init vdso_init(void)if(IS_ENABLED(CONFIG_PPC64))vdso64_spec.pages=vdso_setup_pages(&vdso64_start,&vdso64_end);+vvar_spec.pages=vvar_setup_pages();+smp_wmb();return0;
Since commit 511157ab641e ("powerpc/vdso: Move vdso datapage up front")
VVAR page is in front of the VDSO area. In result it breaks CRIU
(Checkpoint Restore In Userspace) [1], where CRIU expects that "[vdso]"
from /proc/../maps points at ELF/vdso image, rather than at VVAR data
page.
Laurent made a patch to keep CRIU working (by reading aux vector).
But I think it still makes sence to separate two mappings into different
VMAs. It will also make ppc64 less "special" for userspace and as
a side-bonus will make VVAR page un-writable by debugger (which
previously
would COW page and can be unexpected).
I opportunistically Cc stable on it: I understand that usually such
stuff isn't a stable material, but that will allow us in CRIU have
one workaround less that is needed just for one release (v5.11) on
one platform (ppc64), which we otherwise have to maintain.
I wouldn't go as far as to say that the commit 511157ab641e is ABI
regression as no other userspace got broken, but I'd really appreciate
if it gets backported to v5.11 after v5.12 is released, so as not
to complicate already non-simple CRIU-vdso code. Thanks!
Cc: Andrei Vagin <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Christophe Leroy <redacted>
Cc: Laurent Dufour <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <redacted>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: stable@vger.kernel.org # v5.11
[1]: https://github.com/checkpoint-restore/criu/issues/1417
Signed-off-by: Dmitry Safonov <redacted>
Tested-by: Christophe Leroy <redacted>
I run the CRIU's test suite and except the usual suspects, all the tests
passed.
Tested-by: Laurent Dufour <redacted>
Since commit 511157ab641e ("powerpc/vdso: Move vdso datapage up front")
VVAR page is in front of the VDSO area. In result it breaks CRIU
(Checkpoint Restore In Userspace) [1], where CRIU expects that "[vdso]"
from /proc/../maps points at ELF/vdso image, rather than at VVAR data page.
Laurent made a patch to keep CRIU working (by reading aux vector).
But I think it still makes sence to separate two mappings into different
VMAs. It will also make ppc64 less "special" for userspace and as
a side-bonus will make VVAR page un-writable by debugger (which previously
would COW page and can be unexpected).
I opportunistically Cc stable on it: I understand that usually such
stuff isn't a stable material, but that will allow us in CRIU have
one workaround less that is needed just for one release (v5.11) on
one platform (ppc64), which we otherwise have to maintain.
I wouldn't go as far as to say that the commit 511157ab641e is ABI
regression as no other userspace got broken, but I'd really appreciate
if it gets backported to v5.11 after v5.12 is released, so as not
to complicate already non-simple CRIU-vdso code. Thanks!
Cc: Andrei Vagin <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Christophe Leroy <redacted>
Cc: Laurent Dufour <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <redacted>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: stable@vger.kernel.org # v5.11
[1]: https://github.com/checkpoint-restore/criu/issues/1417
Signed-off-by: Dmitry Safonov <redacted>
Tested-by: Christophe Leroy <redacted>
---
arch/powerpc/include/asm/mmu_context.h | 2 +-
arch/powerpc/kernel/vdso.c | 54 +++++++++++++++++++-------
2 files changed, 40 insertions(+), 16 deletions(-)
quoted hunk
@@ -133,7 +135,13 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int * install_special_mapping or the perf counter mmap tracking code * will fail to recognise it as a vDSO. */- mm->context.vdso = (void __user *)vdso_base + PAGE_SIZE;+ mm->context.vdso = (void __user *)vdso_base + vvar_size;++ vma = _install_special_mapping(mm, vdso_base, vvar_size,+ VM_READ | VM_MAYREAD | VM_IO |+ VM_DONTDUMP | VM_PFNMAP, &vvar_spec);+ if (IS_ERR(vma))+ return PTR_ERR(vma); /* * our vma flags don't have VM_WRITE so by default, the process isn't
IIUC, VM_PFNMAP is for when we have a vvar_fault handler.
Allthough we will soon have one for handle TIME_NS, at the moment powerpc doesn't have that handler.
Isn't it dangerous to set VM_PFNMAP then ?
Christophe
Since commit 511157ab641e ("powerpc/vdso: Move vdso datapage up front")
VVAR page is in front of the VDSO area. In result it breaks CRIU
(Checkpoint Restore In Userspace) [1], where CRIU expects that "[vdso]"
from /proc/../maps points at ELF/vdso image, rather than at VVAR data page.
Laurent made a patch to keep CRIU working (by reading aux vector).
But I think it still makes sence to separate two mappings into different
VMAs. It will also make ppc64 less "special" for userspace and as
a side-bonus will make VVAR page un-writable by debugger (which previously
would COW page and can be unexpected).
I opportunistically Cc stable on it: I understand that usually such
stuff isn't a stable material, but that will allow us in CRIU have
one workaround less that is needed just for one release (v5.11) on
one platform (ppc64), which we otherwise have to maintain.
I wouldn't go as far as to say that the commit 511157ab641e is ABI
regression as no other userspace got broken, but I'd really appreciate
if it gets backported to v5.11 after v5.12 is released, so as not
to complicate already non-simple CRIU-vdso code. Thanks!
Cc: Andrei Vagin <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Christophe Leroy <redacted>
Cc: Laurent Dufour <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <redacted>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: stable@vger.kernel.org # v5.11
[1]: https://github.com/checkpoint-restore/criu/issues/1417
Signed-off-by: Dmitry Safonov <redacted>
Tested-by: Christophe Leroy <redacted>
---
arch/powerpc/include/asm/mmu_context.h | 2 +-
arch/powerpc/kernel/vdso.c | 54 +++++++++++++++++++-------
2 files changed, 40 insertions(+), 16 deletions(-)
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2021-03-31 10:00:21
Christophe Leroy [off-list ref] writes:
Le 26/03/2021 à 20:17, Dmitry Safonov a écrit :
quoted
Since commit 511157ab641e ("powerpc/vdso: Move vdso datapage up front")
VVAR page is in front of the VDSO area. In result it breaks CRIU
(Checkpoint Restore In Userspace) [1], where CRIU expects that "[vdso]"
from /proc/../maps points at ELF/vdso image, rather than at VVAR data page.
Laurent made a patch to keep CRIU working (by reading aux vector).
But I think it still makes sence to separate two mappings into different
VMAs. It will also make ppc64 less "special" for userspace and as
a side-bonus will make VVAR page un-writable by debugger (which previously
would COW page and can be unexpected).
I opportunistically Cc stable on it: I understand that usually such
stuff isn't a stable material, but that will allow us in CRIU have
one workaround less that is needed just for one release (v5.11) on
one platform (ppc64), which we otherwise have to maintain.
I wouldn't go as far as to say that the commit 511157ab641e is ABI
regression as no other userspace got broken, but I'd really appreciate
if it gets backported to v5.11 after v5.12 is released, so as not
to complicate already non-simple CRIU-vdso code. Thanks!
Cc: Andrei Vagin <redacted>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Christophe Leroy <redacted>
Cc: Laurent Dufour <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <redacted>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: stable@vger.kernel.org # v5.11
[1]: https://github.com/checkpoint-restore/criu/issues/1417
Signed-off-by: Dmitry Safonov <redacted>
Tested-by: Christophe Leroy <redacted>
---
arch/powerpc/include/asm/mmu_context.h | 2 +-
arch/powerpc/kernel/vdso.c | 54 +++++++++++++++++++-------
2 files changed, 40 insertions(+), 16 deletions(-)
quoted
@@ -133,7 +135,13 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int * install_special_mapping or the perf counter mmap tracking code * will fail to recognise it as a vDSO. */- mm->context.vdso = (void __user *)vdso_base + PAGE_SIZE;+ mm->context.vdso = (void __user *)vdso_base + vvar_size;++ vma = _install_special_mapping(mm, vdso_base, vvar_size,+ VM_READ | VM_MAYREAD | VM_IO |+ VM_DONTDUMP | VM_PFNMAP, &vvar_spec);+ if (IS_ERR(vma))+ return PTR_ERR(vma); /* * our vma flags don't have VM_WRITE so by default, the process isn't
IIUC, VM_PFNMAP is for when we have a vvar_fault handler.
Some of the other flags seem odd too.
eg. VM_IO ? VM_DONTDUMP ?
cheers
@@ -133,7 +135,13 @@ static int __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_int * install_special_mapping or the perf counter mmap tracking code * will fail to recognise it as a vDSO. */- mm->context.vdso = (void __user *)vdso_base + PAGE_SIZE;+ mm->context.vdso = (void __user *)vdso_base + vvar_size;++ vma = _install_special_mapping(mm, vdso_base, vvar_size,+ VM_READ | VM_MAYREAD | VM_IO |+ VM_DONTDUMP | VM_PFNMAP, &vvar_spec);+ if (IS_ERR(vma))+ return PTR_ERR(vma); /* * our vma flags don't have VM_WRITE so by default, the process isn't
IIUC, VM_PFNMAP is for when we have a vvar_fault handler.
Allthough we will soon have one for handle TIME_NS, at the moment
powerpc doesn't have that handler.
Isn't it dangerous to set VM_PFNMAP then ?
I believe, it's fine, special_mapping_fault() does:
: if (sm->fault)
: return sm->fault(sm, vmf->vma, vmf);
Some of the other flags seem odd too.
eg. VM_IO ? VM_DONTDUMP ?
From: Michael Ellerman <hidden> Date: 2021-04-19 04:05:01
On Fri, 26 Mar 2021 19:17:20 +0000, Dmitry Safonov wrote:
Since commit 511157ab641e ("powerpc/vdso: Move vdso datapage up front")
VVAR page is in front of the VDSO area. In result it breaks CRIU
(Checkpoint Restore In Userspace) [1], where CRIU expects that "[vdso]"
from /proc/../maps points at ELF/vdso image, rather than at VVAR data page.
Laurent made a patch to keep CRIU working (by reading aux vector).
But I think it still makes sence to separate two mappings into different
VMAs. It will also make ppc64 less "special" for userspace and as
a side-bonus will make VVAR page un-writable by debugger (which previously
would COW page and can be unexpected).
[...]