Le 26/02/2024 à 20:09, Rick Edgecombe a écrit : > Future changes will need to add a field to struct vm_unmapped_area_info. > This would cause trouble for any archs that don't initialize the > struct. Currently every user sets each field, so if new fields are > added, the core code parsing the struct will see garbage in the new > field. > > It could be possible to initialize the new field for each arch to 0, but > instead simply inialize the field with a C99 struct inializing syntax. Why doing a full init of the struct when all fields are re-written a few lines after ? If I take the exemple of powerpc function slice_find_area_bottomup(): struct vm_unmapped_area_info info; info.flags = 0; info.length = len; info.align_mask = PAGE_MASK & ((1ul << pshift) - 1); info.align_offset = 0; For me it looks better to just add: info.new_field = 0; /* or whatever value it needs to have */ Christophe > > Cc: linux-mm@xxxxxxxxx > Cc: linux-alpha@xxxxxxxxxxxxxxx > Cc: linux-snps-arc@xxxxxxxxxxxxxxxxxxx > Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx > Cc: linux-csky@xxxxxxxxxxxxxxx > Cc: loongarch@xxxxxxxxxxxxxxx > Cc: linux-mips@xxxxxxxxxxxxxxx > Cc: linux-parisc@xxxxxxxxxxxxxxx > Cc: linuxppc-dev@xxxxxxxxxxxxxxxx > Cc: linux-s390@xxxxxxxxxxxxxxx > Cc: linux-sh@xxxxxxxxxxxxxxx > Cc: sparclinux@xxxxxxxxxxxxxxx > Cc: x86@xxxxxxxxxx > Suggested-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> > Signed-off-by: Rick Edgecombe <rick.p.edgecombe@xxxxxxxxx> > Link: https://lore.kernel.org/lkml/3ynogxcgokc6i6xojbxzzwqectg472laes24u7jmtktlxcch5e@dfytra3ia3zc/#t > --- > Hi archs, > > For some context, this is part of a larger series to improve shadow stack > guard gaps. It involves plumbing a new field via > struct vm_unmapped_area_info. The first user is x86, but arm and riscv may > likely use it as well. The change is compile tested only for non-x86 but > seems like a relatively safe one. > > Thanks, > > Rick > > v2: > - New patch > --- > arch/alpha/kernel/osf_sys.c | 2 +- > arch/arc/mm/mmap.c | 2 +- > arch/arm/mm/mmap.c | 4 ++-- > arch/csky/abiv1/mmap.c | 2 +- > arch/loongarch/mm/mmap.c | 2 +- > arch/mips/mm/mmap.c | 2 +- > arch/parisc/kernel/sys_parisc.c | 2 +- > arch/powerpc/mm/book3s64/slice.c | 4 ++-- > arch/s390/mm/hugetlbpage.c | 4 ++-- > arch/s390/mm/mmap.c | 4 ++-- > arch/sh/mm/mmap.c | 4 ++-- > arch/sparc/kernel/sys_sparc_32.c | 2 +- > arch/sparc/kernel/sys_sparc_64.c | 4 ++-- > arch/sparc/mm/hugetlbpage.c | 4 ++-- > arch/x86/kernel/sys_x86_64.c | 4 ++-- > arch/x86/mm/hugetlbpage.c | 4 ++-- > fs/hugetlbfs/inode.c | 4 ++-- > mm/mmap.c | 4 ++-- > 18 files changed, 29 insertions(+), 29 deletions(-) > > diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c > index 5db88b627439..dd6801bb9240 100644 > --- a/arch/alpha/kernel/osf_sys.c > +++ b/arch/alpha/kernel/osf_sys.c > @@ -1218,7 +1218,7 @@ static unsigned long > arch_get_unmapped_area_1(unsigned long addr, unsigned long len, > unsigned long limit) > { > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > info.flags = 0; > info.length = len; > diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c > index 3c1c7ae73292..6549b3375f54 100644 > --- a/arch/arc/mm/mmap.c > +++ b/arch/arc/mm/mmap.c > @@ -27,7 +27,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, > { > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > /* > * We enforce the MAP_FIXED case. > diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c > index a0f8a0ca0788..525795578c29 100644 > --- a/arch/arm/mm/mmap.c > +++ b/arch/arm/mm/mmap.c > @@ -34,7 +34,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, > struct vm_area_struct *vma; > int do_align = 0; > int aliasing = cache_is_vipt_aliasing(); > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > /* > * We only need to do colour alignment if either the I or D > @@ -87,7 +87,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, > unsigned long addr = addr0; > int do_align = 0; > int aliasing = cache_is_vipt_aliasing(); > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > /* > * We only need to do colour alignment if either the I or D > diff --git a/arch/csky/abiv1/mmap.c b/arch/csky/abiv1/mmap.c > index 6792aca49999..726659d41fa9 100644 > --- a/arch/csky/abiv1/mmap.c > +++ b/arch/csky/abiv1/mmap.c > @@ -28,7 +28,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma; > int do_align = 0; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > /* > * We only need to do colour alignment if either the I or D > diff --git a/arch/loongarch/mm/mmap.c b/arch/loongarch/mm/mmap.c > index a9630a81b38a..664bf4abfdcf 100644 > --- a/arch/loongarch/mm/mmap.c > +++ b/arch/loongarch/mm/mmap.c > @@ -24,7 +24,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp, > struct vm_area_struct *vma; > unsigned long addr = addr0; > int do_color_align; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > if (unlikely(len > TASK_SIZE)) > return -ENOMEM; > diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c > index 00fe90c6db3e..6321b53dc995 100644 > --- a/arch/mips/mm/mmap.c > +++ b/arch/mips/mm/mmap.c > @@ -34,7 +34,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp, > struct vm_area_struct *vma; > unsigned long addr = addr0; > int do_color_align; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > if (unlikely(len > TASK_SIZE)) > return -ENOMEM; > diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c > index 98af719d5f85..e87c0e325abf 100644 > --- a/arch/parisc/kernel/sys_parisc.c > +++ b/arch/parisc/kernel/sys_parisc.c > @@ -104,7 +104,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp, > struct vm_area_struct *vma, *prev; > unsigned long filp_pgoff; > int do_color_align; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > if (unlikely(len > TASK_SIZE)) > return -ENOMEM; > diff --git a/arch/powerpc/mm/book3s64/slice.c b/arch/powerpc/mm/book3s64/slice.c > index c0b58afb9a47..5884f384866f 100644 > --- a/arch/powerpc/mm/book3s64/slice.c > +++ b/arch/powerpc/mm/book3s64/slice.c > @@ -282,7 +282,7 @@ static unsigned long slice_find_area_bottomup(struct mm_struct *mm, > { > int pshift = max_t(int, mmu_psize_defs[psize].shift, PAGE_SHIFT); > unsigned long found, next_end; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > info.flags = 0; > info.length = len; > @@ -326,7 +326,7 @@ static unsigned long slice_find_area_topdown(struct mm_struct *mm, > { > int pshift = max_t(int, mmu_psize_defs[psize].shift, PAGE_SHIFT); > unsigned long found, prev; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > unsigned long min_addr = max(PAGE_SIZE, mmap_min_addr); > > info.flags = VM_UNMAPPED_AREA_TOPDOWN; > diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c > index c2d2850ec8d5..7f68485feea0 100644 > --- a/arch/s390/mm/hugetlbpage.c > +++ b/arch/s390/mm/hugetlbpage.c > @@ -258,7 +258,7 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file, > unsigned long pgoff, unsigned long flags) > { > struct hstate *h = hstate_file(file); > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > info.flags = 0; > info.length = len; > @@ -274,7 +274,7 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file, > unsigned long pgoff, unsigned long flags) > { > struct hstate *h = hstate_file(file); > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > unsigned long addr; > > info.flags = VM_UNMAPPED_AREA_TOPDOWN; > diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c > index cd52d72b59cf..df88496e2903 100644 > --- a/arch/s390/mm/mmap.c > +++ b/arch/s390/mm/mmap.c > @@ -77,7 +77,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > { > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > if (len > TASK_SIZE - mmap_min_addr) > return -ENOMEM; > @@ -116,7 +116,7 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long ad > { > struct vm_area_struct *vma; > struct mm_struct *mm = current->mm; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > /* requested length too big for entire address space */ > if (len > TASK_SIZE - mmap_min_addr) > diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c > index b82199878b45..6aee5f761e08 100644 > --- a/arch/sh/mm/mmap.c > +++ b/arch/sh/mm/mmap.c > @@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma; > int do_colour_align; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > if (flags & MAP_FIXED) { > /* We do not accept a shared mapping if it would violate > @@ -106,7 +106,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, > struct mm_struct *mm = current->mm; > unsigned long addr = addr0; > int do_colour_align; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > if (flags & MAP_FIXED) { > /* We do not accept a shared mapping if it would violate > diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c > index 082a551897ed..7e781dbfd052 100644 > --- a/arch/sparc/kernel/sys_sparc_32.c > +++ b/arch/sparc/kernel/sys_sparc_32.c > @@ -41,7 +41,7 @@ SYSCALL_DEFINE0(getpagesize) > > unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) > { > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > if (flags & MAP_FIXED) { > /* We do not accept a shared mapping if it would violate > diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c > index 1dbf7211666e..fc48ab3f83af 100644 > --- a/arch/sparc/kernel/sys_sparc_64.c > +++ b/arch/sparc/kernel/sys_sparc_64.c > @@ -93,7 +93,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi > struct vm_area_struct * vma; > unsigned long task_size = TASK_SIZE; > int do_color_align; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > if (flags & MAP_FIXED) { > /* We do not accept a shared mapping if it would violate > @@ -154,7 +154,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, > unsigned long task_size = STACK_TOP32; > unsigned long addr = addr0; > int do_color_align; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > /* This should only ever run for 32-bit processes. */ > BUG_ON(!test_thread_flag(TIF_32BIT)); > diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c > index 38a1bef47efb..614e2c46d781 100644 > --- a/arch/sparc/mm/hugetlbpage.c > +++ b/arch/sparc/mm/hugetlbpage.c > @@ -31,7 +31,7 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp, > { > struct hstate *h = hstate_file(filp); > unsigned long task_size = TASK_SIZE; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > if (test_thread_flag(TIF_32BIT)) > task_size = STACK_TOP32; > @@ -63,7 +63,7 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, > struct hstate *h = hstate_file(filp); > struct mm_struct *mm = current->mm; > unsigned long addr = addr0; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > /* This should only ever run for 32-bit processes. */ > BUG_ON(!test_thread_flag(TIF_32BIT)); > diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c > index c783aeb37dce..6e5d4fa5fc42 100644 > --- a/arch/x86/kernel/sys_x86_64.c > +++ b/arch/x86/kernel/sys_x86_64.c > @@ -125,7 +125,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, > { > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > unsigned long begin, end; > > if (flags & MAP_FIXED) > @@ -165,7 +165,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, > struct vm_area_struct *vma; > struct mm_struct *mm = current->mm; > unsigned long addr = addr0; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > /* requested length too big for entire address space */ > if (len > TASK_SIZE) > diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c > index 6d77c0039617..88726bd1f72d 100644 > --- a/arch/x86/mm/hugetlbpage.c > +++ b/arch/x86/mm/hugetlbpage.c > @@ -51,7 +51,7 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file, > unsigned long pgoff, unsigned long flags) > { > struct hstate *h = hstate_file(file); > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > info.flags = 0; > info.length = len; > @@ -74,7 +74,7 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file, > unsigned long pgoff, unsigned long flags) > { > struct hstate *h = hstate_file(file); > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > info.flags = VM_UNMAPPED_AREA_TOPDOWN; > info.length = len; > diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c > index a63d2eee086f..848b2239a215 100644 > --- a/fs/hugetlbfs/inode.c > +++ b/fs/hugetlbfs/inode.c > @@ -165,7 +165,7 @@ hugetlb_get_unmapped_area_bottomup(struct file *file, unsigned long addr, > unsigned long len, unsigned long pgoff, unsigned long flags) > { > struct hstate *h = hstate_file(file); > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > info.flags = 0; > info.length = len; > @@ -181,7 +181,7 @@ hugetlb_get_unmapped_area_topdown(struct file *file, unsigned long addr, > unsigned long len, unsigned long pgoff, unsigned long flags) > { > struct hstate *h = hstate_file(file); > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > > info.flags = VM_UNMAPPED_AREA_TOPDOWN; > info.length = len; > diff --git a/mm/mmap.c b/mm/mmap.c > index e02bb17fef5b..33af683a643f 100644 > --- a/mm/mmap.c > +++ b/mm/mmap.c > @@ -1699,7 +1699,7 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr, > { > struct mm_struct *mm = current->mm; > struct vm_area_struct *vma, *prev; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags); > > if (len > mmap_end - mmap_min_addr) > @@ -1747,7 +1747,7 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr, > { > struct vm_area_struct *vma, *prev; > struct mm_struct *mm = current->mm; > - struct vm_unmapped_area_info info; > + struct vm_unmapped_area_info info = {}; > const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags); > > /* requested length too big for entire address space */