arm64: mm: optimize VA space organization for 52-bit
Subsystems (2)
v2 cover arm64: mm: optimize VA space organization for 52-bit
This series reorganizes the kernel VA space slightly so that 52-bit VA configurations can use more virtual address space, i.e., the usable linear address space almost doubles, from 2^51 to 2^52-2^47.
Patch #1 merges the physvirt_offset and memstart_addr variables, both of which represent translations between the physical address space and the linear region, and there is no need for having both. This fixes a bug too, as the two values were not properly kept in sync when booting with KASLR enabled.
Patch #2 updates the definitions for the boundaries of the linear space, so that 52-bit VA builds use all available space for the linear region.
Patches #3 and #4 simplify the way the vmemmap region is configured, and unify the 48-bit/4k and 52-bit/64k layouts.
Changes since v1:
- drop incorrect use of untagged_addr() from #2
- add patches #3 and #4
Not boot tested yet on a 52-bit VA capable system.
Ard Biesheuvel (4):
arm64: mm: use single quantity to represent the PA to VA translation
arm64: mm: extend linear region for 52-bit VA configurations
arm64: mm: make vmemmap region a projection of the linear region
arm64: mm: tidy up top of kernel VA space
Documentation/arm64/kasan-offsets.sh | 3 +- Documentation/arm64/memory.rst | 45 +++++++++----------- arch/arm64/Kconfig | 20 ++++----- arch/arm64/include/asm/memory.h | 35 +++++++-------- arch/arm64/include/asm/pgtable.h | 6 +-- arch/arm64/mm/init.c | 34 ++++++--------- 6 files changed, 63 insertions(+), 80 deletions(-)
Signature · 7 lines
2.17.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v2 1/4 arm64: mm: use single quantity to represent the PA to VA translation
On arm64, the global variable memstart_addr represents the physical address of PAGE_OFFSET, and so physical to virtual translations or vice versa used to come down to simple additions or subtractions involving the values of PAGE_OFFSET and memstart_addr.
When support for 52-bit virtual addressing was introduced, we had to deal with PAGE_OFFSET potentially being outside of the region that can be covered by the virtual range (as the 52-bit VA capable build needs to be able to run on systems that are only 48-bit VA capable), and for this reason, another translation was introduced, and recorded in the global variable physvirt_offset.
However, if we go back to the original definition of memstart_addr, i.e., the physical address of PAGE_OFFSET, it turns out that there is no need for two separate translations: instead, we can simply subtract the size of the unaddressable VA space from memstart_addr to make the available physical memory appear in the 48-bit addressable VA region.
This simplifies things, but also fixes a bug on KASLR builds, which may update memstart_addr later on in arm64_memblock_init(), but fails to update vmemmap and physvirt_offset accordingly.
--- arch/arm64/include/asm/memory.h | 5 ++-- arch/arm64/include/asm/pgtable.h | 4 +-- arch/arm64/mm/init.c | 30 +++++++------------- 3 files changed, 14 insertions(+), 25 deletions(-)
arch/arm64/include/asm/memory.h +2 -3
@@ -164,7 +164,6 @@extern u64 vabits_actual;#define PAGE_END (_PAGE_END(vabits_actual)) -extern s64 physvirt_offset;extern s64 memstart_addr;/* PHYS_OFFSET - the physical address of the start of memory. */ #define PHYS_OFFSET ({ VM_BUG_ON(memstart_addr & 1); memstart_addr; })
@@ -240,7 +239,7 @@ static inline const void *__tag_set(const void *addr, u8 tag)*/ #define __is_lm_address (addr) (!(((u64)addr) & BIT(vabits_actual - 1))) -#define __lm_to_phys (addr) (((addr) + physvirt_offset)) +#define __lm_to_phys (addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)#define __kimg_to_phys (addr) ((addr) - kimage_voffset)#define __virt_to_phys_nodebug (x) ({ \
@@ -258,7 +257,7 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x);#define __phys_addr_symbol (x) __pa_symbol_nodebug(x)#endif /* CONFIG_DEBUG_VIRTUAL */ -#define __phys_to_virt (x) ((unsigned long)((x) - physvirt_offset)) +#define __phys_to_virt (x) ((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET)#define __phys_to_kimg (x) ((unsigned long)((x) + kimage_voffset))/*
arch/arm64/include/asm/pgtable.h +2 -2
@@ -23,6 +23,8 @@#define VMALLOC_START (MODULES_END)#define VMALLOC_END (- PUD_SIZE - VMEMMAP_SIZE - SZ_64K) +#define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT)) +#define FIRST_USER_ADDRESS 0UL#ifndef __ASSEMBLY__
@@ -33,8 +35,6 @@#include <linux/mm_types.h> #include <linux/sched.h> -extern struct page *vmemmap; -extern void __pte_error (const char *file,int line,unsigned long val);extern void __pmd_error (const char *file,int line,unsigned long val);extern void __pud_error (const char *file,int line,unsigned long val);
arch/arm64/mm/init.c +10 -20
@@ -54,12 +54,6 @@s64 memstart_addr__ro_after_init =-1 ;EXPORT_SYMBOL (memstart_addr); -s64 physvirt_offset__ro_after_init ; -EXPORT_SYMBOL (physvirt_offset); - -struct page *vmemmap__ro_after_init ; -EXPORT_SYMBOL (vmemmap); -/* * We create both ZONE_DMA and ZONE_DMA32. ZONE_DMA covers the first 1G of * memory as some devices, namely the Raspberry Pi 4, have peripherals with
@@ -290,20 +284,6 @@ void __init arm64_memblock_init(void) memstart_addr =round_down (memblock_start_of_DRAM (),ARM64_MEMSTART_ALIGN ); - physvirt_offset =PHYS_OFFSET -PAGE_OFFSET ; - - vmemmap = ((struct page *)VMEMMAP_START - (memstart_addr >>PAGE_SHIFT )); - -/* -* If we are running with a 52-bit kernel VA config on a system that -* does not support it, we have to offset our vmemmap and physvirt_offset -* s.t. we avoid the 52-bit portion of the direct linear map -*/ -if (IS_ENABLED (CONFIG_ARM64_VA_BITS_52 ) && (vabits_actual !=52 )) { - vmemmap += (_PAGE_OFFSET (48 ) -_PAGE_OFFSET (52 )) >>PAGE_SHIFT ; - physvirt_offset =PHYS_OFFSET -_PAGE_OFFSET (48 ); - } -/* * Remove the memory that we will not be able to cover with the * linear mapping. Take care not to clip the kernel which may be
@@ -318,6 +298,16 @@ void __init arm64_memblock_init(void)memblock_remove (0 , memstart_addr); } +/* +* If we are running with a 52-bit kernel VA config on a system that +* does not support it, we have to place the available physical +* memory in the 48-bit addressable part of the linear region, i.e., +* we have to move it upward. Since memstart_addr represents the +* physical address of PAGE_OFFSET, we have to *subtract* from it. +*/ +if (IS_ENABLED (CONFIG_ARM64_VA_BITS_52 ) && (vabits_actual !=52 )) + memstart_addr -=_PAGE_OFFSET (48 ) -_PAGE_OFFSET (52 ); +/* * Apply the memory limit if it was set. Since the kernel may be loaded * high up in memory, add back the kernel region that must be accessible
Signature · 7 lines
2.17.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
RE: [PATCH v2 1/4] arm64: mm: use single quantity to represent the PA to VA translation
Hi Ard,
Quoted 18 lines · Ard Biesheuvel
On arm64, the global variable
memstart_addrrepresents the physical address ofPAGE_OFFSET, and so physical to virtual translations or vice versa used to come down to simple additions or subtractions involving the values ofPAGE_OFFSETandmemstart_addr.When support for 52-bit virtual addressing was introduced, we had to deal with
PAGE_OFFSETpotentially being outside of the region that can be covered by the virtual range (as the 52-bit VA capable build needs to be able to run on systems that are only 48-bit VA capable), and for this reason, another translation was introduced, and recorded in the global variablephysvirt_offset.However, if we go back to the original definition of
memstart_addr, i.e., the physical address ofPAGE_OFFSET, it turns out that there is no need for two separate translations: instead, we can simply subtract the size of the unaddressable VA space frommemstart_addrto make the available physical memory appear in the 48-bit addressable VA region.
Quoted 4 lines
This simplifies things, but also fixes a bug on KASLR builds, which may update
memstart_addrlater on inarm64_memblock_init(), but fails to update vmemmap andphysvirt_offsetaccordingly.
Apologies, I didn't spot that before.
Quoted 2 lines
Fixes 5383cc6efed13 ("arm64: mm: Introduce vabits_actual")Signed-off-by Ard Biesheuvel <[email protected]>
Thanks for this. It is much better to modify memstart_addr rather than introducing needless complexity.
Cheers,
--
Steve
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH v2 1/4] arm64: mm: use single quantity to represent the PA to VA translation
In reply to Ard BiesheuvelHi Ard,
Quoted 18 lines · Ard Biesheuvel
On arm64, the global variable
memstart_addrrepresents the physical address ofPAGE_OFFSET, and so physical to virtual translations or vice versa used to come down to simple additions or subtractions involving the values ofPAGE_OFFSETandmemstart_addr.When support for 52-bit virtual addressing was introduced, we had to deal with
PAGE_OFFSETpotentially being outside of the region that can be covered by the virtual range (as the 52-bit VA capable build needs to be able to run on systems that are only 48-bit VA capable), and for this reason, another translation was introduced, and recorded in the global variablephysvirt_offset.However, if we go back to the original definition of
memstart_addr, i.e., the physical address ofPAGE_OFFSET, it turns out that there is no need for two separate translations: instead, we can simply subtract the size of the unaddressable VA space frommemstart_addrto make the available physical memory appear in the 48-bit addressable VA region.
Quoted 4 lines
This simplifies things, but also fixes a bug on KASLR builds, which may update
memstart_addrlater on inarm64_memblock_init(), but fails to update vmemmap andphysvirt_offsetaccordingly.
Apologies, I didn't spot that before.
Quoted 2 lines
Fixes 5383cc6efed13 ("arm64: mm: Introduce vabits_actual")Signed-off-by Ard Biesheuvel <[email protected]>
Thanks for this. It is much better to modify memstart_addr rather than introducing needless complexity.
Cheers,
--
Steve
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerRe: [PATCH v2 1/4] arm64: mm: use single quantity to represent the PA to VA translation
In reply to Ard BiesheuvelQuoted 22 lines · Ard Biesheuvel
On arm64, the global variable
memstart_addrrepresents the physical address ofPAGE_OFFSET, and so physical to virtual translations or vice versa used to come down to simple additions or subtractions involving the values ofPAGE_OFFSETandmemstart_addr.When support for 52-bit virtual addressing was introduced, we had to deal with
PAGE_OFFSETpotentially being outside of the region that can be covered by the virtual range (as the 52-bit VA capable build needs to be able to run on systems that are only 48-bit VA capable), and for this reason, another translation was introduced, and recorded in the global variablephysvirt_offset.However, if we go back to the original definition of
memstart_addr, i.e., the physical address ofPAGE_OFFSET, it turns out that there is no need for two separate translations: instead, we can simply subtract the size of the unaddressable VA space frommemstart_addrto make the available physical memory appear in the 48-bit addressable VA region.This simplifies things, but also fixes a bug on KASLR builds, which may update
memstart_addrlater on inarm64_memblock_init(), but fails to update vmemmap andphysvirt_offsetaccordingly.
Quoted 7 lines
Fixes 5383cc6efed13 ("arm64: mm: Introduce vabits_actual")Signed-off-by Ard Biesheuvel <[email protected]>--- arch/arm64/include/asm/memory.h | 5 ++-- arch/arm64/include/asm/pgtable.h | 4 +-- arch/arm64/mm/init.c | 30 +++++++------------- 3 files changed, 14 insertions(+), 25 deletions(-)
I'll pick this one patch up for 5.10, thanks.
Will
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v2 2/4 arm64: mm: extend linear region for 52-bit VA configurations
In reply to Ard BiesheuvelFor historical reasons, the arm64 kernel VA space is configured as two equally sized halves, i.e., on a 48-bit VA build, the VA space is split into a 47-bit vmalloc region and a 47-bit linear region.
When support for 52-bit virtual addressing was added, this equal split was kept, resulting in a substantial waste of virtual address space in the linear region:
48-bit VA 52-bit VA
0xffff_ffff_ffff_ffff +-------------+ +-------------+
| vmalloc | | vmalloc |
0xffff_8000_0000_0000 +-------------+ _PAGE_END(48) +-------------+
| linear | : :
0xffff_0000_0000_0000 +-------------+ : :
: : : :
: : : :
: : : :
: : : currently :
: unusable : : :
: : : unused :
: by : : :
: : : :
: hardware : : :
: : : :
0xfff8_0000_0000_0000 : : _PAGE_END(52) +-------------+
: : | |
: : | |
: : | |
: : | |
: : | |
: unusable : | |
: : | linear |
: by : | |
: : | region |
: hardware : | |
: : | |
: : | |
: : | |
: : | |
: : | |
: : | |
0xfff0_0000_0000_0000 +-------------+ PAGE_OFFSET +-------------+As illustrated above, the 52-bit VA kernel uses 47 bits for the vmalloc space (as before), to ensure that a single 64k granule kernel image can support any 64k granule capable system, regardless of whether it supports the 52-bit virtual addressing extension. However, due to the fact that the VA space is still split in equal halves, the linear region is only 2^51 bytes in size, wasting almost half of the 52-bit VA space.
Let's fix this, by abandoning the equal split, and simply assigning all VA space outside of the vmalloc region to the linear region.
The KASAN shadow region is reconfigured so that it ends at the start of the vmalloc region, and grows downwards. That way, the arrangement of the vmalloc space (which contains kernel mappings, modules, BPF region, the vmemmap array etc) is identical between non-KASAN and KASAN builds, which aids debugging.
--- Documentation/arm64/kasan-offsets.sh | 3 +-- Documentation/arm64/memory.rst | 19 +++++++++---------- arch/arm64/Kconfig | 20 ++++++++++---------- arch/arm64/include/asm/memory.h | 12 +++++------- arch/arm64/mm/init.c | 2 +- 5 files changed, 26 insertions(+), 30 deletions(-)
Documentation/arm64/kasan-offsets.sh +1 -2
@@ -1,12 +1,11 @@ #!/bin/sh # Print out the KASAN_SHADOW_OFFSETS required to place the KASAN SHADOW -# start address at the mid-point of the kernel VA space +# start address at the top of the linear region print_kasan_offset () { printf "%02d\t" $1 printf "0x%08x00000000\n" $(( (0xffffffff & (-1 << ($1 - 1 - 32))) \ - + (1 << ($1 - 32 - $2)) \ - (1 << (64 - 32 - $2)) )) }
Documentation/arm64/memory.rst +9 -10
@@ -32,10 +32,10 @@ AArch64 Linux memory layout with 4KB pages + 4 levels (48-bit):: ----------------------------------------------------------------------- 0000000000000000 0000ffffffffffff 256TB user ffff000000000000 ffff7fffffffffff 128TB kernel logical memory map - ffff800000000000 ffff9fffffffffff 32TB kasan shadow region - ffffa00000000000 ffffa00007ffffff 128MB bpf jit region - ffffa00008000000 ffffa0000fffffff 128MB modules - ffffa00010000000 fffffdffbffeffff ~93TB vmalloc +[ ffff600000000000 ffff7fffffffffff ] 32TB [ kasan shadow region ] + ffff800000000000 ffff800007ffffff 128MB bpf jit region + ffff800008000000 ffff80000fffffff 128MB modules + ffff800010000000 fffffdffbffeffff 125TB vmalloc fffffdffbfff0000 fffffdfffe5f8fff ~998MB [guard region] fffffdfffe5f9000 fffffdfffe9fffff 4124KB fixed mappings fffffdfffea00000 fffffdfffebfffff 2MB [guard region]
@@ -50,12 +50,11 @@ AArch64 Linux memory layout with 64KB pages + 3 levels (52-bit with HW support): Start End Size Use ----------------------------------------------------------------------- 0000000000000000 000fffffffffffff 4PB user - fff0000000000000 fff7ffffffffffff 2PB kernel logical memory map - fff8000000000000 fffd9fffffffffff 1440TB [gap] - fffda00000000000 ffff9fffffffffff 512TB kasan shadow region - ffffa00000000000 ffffa00007ffffff 128MB bpf jit region - ffffa00008000000 ffffa0000fffffff 128MB modules - ffffa00010000000 fffff81ffffeffff ~88TB vmalloc + fff0000000000000 ffff7fffffffffff ~4PB kernel logical memory map +[ fffd800000000000 ffff7fffffffffff ] 512TB [ kasan shadow region ] + ffff800000000000 ffff800007ffffff 128MB bpf jit region + ffff800008000000 ffff80000fffffff 128MB modules + ffff800010000000 fffff81ffffeffff 120TB vmalloc fffff81fffff0000 fffffc1ffe58ffff ~3TB [guard region] fffffc1ffe590000 fffffc1ffe9fffff 4544KB fixed mappings fffffc1ffea00000 fffffc1ffebfffff 2MB [guard region]
arch/arm64/Kconfig +10 -10
@@ -321,16 +321,16 @@ config BROKEN_GAS_INST config KASAN_SHADOW_OFFSET hex depends on KASAN - default 0xdfffa00000000000 if (ARM64_VA_BITS_48 || ARM64_VA_BITS_52) && !KASAN_SW_TAGS - default 0xdfffd00000000000 if ARM64_VA_BITS_47 && !KASAN_SW_TAGS - default 0xdffffe8000000000 if ARM64_VA_BITS_42 && !KASAN_SW_TAGS - default 0xdfffffd000000000 if ARM64_VA_BITS_39 && !KASAN_SW_TAGS - default 0xdffffffa00000000 if ARM64_VA_BITS_36 && !KASAN_SW_TAGS - default 0xefff900000000000 if (ARM64_VA_BITS_48 || ARM64_VA_BITS_52) && KASAN_SW_TAGS - default 0xefffc80000000000 if ARM64_VA_BITS_47 && KASAN_SW_TAGS - default 0xeffffe4000000000 if ARM64_VA_BITS_42 && KASAN_SW_TAGS - default 0xefffffc800000000 if ARM64_VA_BITS_39 && KASAN_SW_TAGS - default 0xeffffff900000000 if ARM64_VA_BITS_36 && KASAN_SW_TAGS + default 0xdfff800000000000 if (ARM64_VA_BITS_48 || ARM64_VA_BITS_52) && !KASAN_SW_TAGS + default 0xdfffc00000000000 if ARM64_VA_BITS_47 && !KASAN_SW_TAGS + default 0xdffffe0000000000 if ARM64_VA_BITS_42 && !KASAN_SW_TAGS + default 0xdfffffc000000000 if ARM64_VA_BITS_39 && !KASAN_SW_TAGS + default 0xdffffff800000000 if ARM64_VA_BITS_36 && !KASAN_SW_TAGS + default 0xefff800000000000 if (ARM64_VA_BITS_48 || ARM64_VA_BITS_52) && KASAN_SW_TAGS + default 0xefffc00000000000 if ARM64_VA_BITS_47 && KASAN_SW_TAGS + default 0xeffffe0000000000 if ARM64_VA_BITS_42 && KASAN_SW_TAGS + default 0xefffffc000000000 if ARM64_VA_BITS_39 && KASAN_SW_TAGS + default 0xeffffff800000000 if ARM64_VA_BITS_36 && KASAN_SW_TAGS default 0xffffffffffffffff source "arch/arm64/Kconfig.platforms"
arch/arm64/include/asm/memory.h +5 -7
@@ -44,7 +44,7 @@#define _PAGE_OFFSET (va) (-(UL(1) << (va)))#define PAGE_OFFSET (_PAGE_OFFSET(VA_BITS))#define KIMAGE_VADDR (MODULES_END) -#define BPF_JIT_REGION_START (KASAN_SHADOW_END) +#define BPF_JIT_REGION_START (_PAGE_END(VA_BITS_MIN))#define BPF_JIT_REGION_SIZE (SZ_128M)#define BPF_JIT_REGION_END (BPF_JIT_REGION_START + BPF_JIT_REGION_SIZE)#define MODULES_END (MODULES_VADDR + MODULES_VSIZE)
@@ -76,10 +76,11 @@#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)#define KASAN_SHADOW_END ((UL(1) << (64 - KASAN_SHADOW_SCALE_SHIFT)) \ + KASAN_SHADOW_OFFSET) +#define PAGE_END (KASAN_SHADOW_END - (1UL << (vabits_actual - KASAN_SHADOW_SCALE_SHIFT)))#define KASAN_THREAD_SHIFT 1#else #define KASAN_THREAD_SHIFT 0 -#define KASAN_SHADOW_END (_PAGE_END(VA_BITS_MIN)) +#define PAGE_END (_PAGE_END(VA_BITS_MIN))#endif /* CONFIG_KASAN */ #define MIN_THREAD_SHIFT (14 + KASAN_THREAD_SHIFT)
@@ -162,7 +163,6 @@#include <asm/bug.h> extern u64 vabits_actual; -#define PAGE_END (_PAGE_END(vabits_actual))extern s64 memstart_addr;/* PHYS_OFFSET - the physical address of the start of memory. */
@@ -233,11 +233,9 @@ static inline const void *__tag_set(const void *addr, u8 tag)/* -* The linear kernel range starts at the bottom of the virtual address -* space. Testing the top bit for the start of the region is a -* sufficient check and avoids having to worry about the tag. +* The linear kernel range starts at the bottom of the virtual address space. */ -#define __is_lm_address (addr) (!(((u64)addr) & BIT(vabits_actual - 1))) +#define __is_lm_address (addr) (((u64)(addr) & ~PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET))#define __lm_to_phys (addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)#define __kimg_to_phys (addr) ((addr) - kimage_voffset)
arch/arm64/mm/init.c +1 -1
@@ -270,7 +270,7 @@ static void __init fdt_enforce_memory_region(void)void __init arm64_memblock_init (void ) { -const s64 linear_region_size =BIT (vabits_actual -1 ); +const s64 linear_region_size =PAGE_END -_PAGE_OFFSET (vabits_actual);/* Handle linux,usable-memory-range property */ fdt_enforce_memory_region ();
Signature · 7 lines
2.17.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH v2 2/4] arm64: mm: extend linear region for 52-bit VA configurations
Hi Ard,
One comment below...
Quoted 68 lines · Ard Biesheuvel
For historical reasons, the arm64 kernel VA space is configured as two equally sized halves, i.e., on a 48-bit VA build, the VA space is split into a 47-bit vmalloc region and a 47-bit linear region.
When support for 52-bit virtual addressing was added, this equal split was kept, resulting in a substantial waste of virtual address space in the linear region:
48-bit VA 52-bit VA
0xffff_ffff_ffff_ffff +-------------+ +-------------+
| vmalloc | | vmalloc |
0xffff_8000_0000_0000 +-------------+_PAGE_END(48)+-------------+| linear | : : 0xffff_0000_0000_0000 +-------------+ : : : : : : : : : : : : : : : : : currently : : unusable : : : : : : unused : : by : : : : : : : : hardware : : : : : : : 0xfff8_0000_0000_0000 : : _PAGE_END(52) +-------------+ : : | | : : | | : : | | : : | | : : | | : unusable : | | : : | linear | : by : | | : : | region | : hardware : | | : : | | : : | | : : | | : : | | : : | | : : | | 0xfff0_0000_0000_0000 +-------------+ PAGE_OFFSET +-------------+As illustrated above, the 52-bit VA kernel uses 47 bits for the vmalloc space (as before), to ensure that a single 64k granule kernel image can support any 64k granule capable system, regardless of whether it supports the 52-bit virtual addressing extension. However, due to the fact that the VA space is still split in equal halves, the linear region is only 2^51 bytes in size, wasting almost half of the 52-bit VA space.
Let's fix this, by abandoning the equal split, and simply assigning all VA space outside of the vmalloc region to the linear region.
The KASAN shadow region is reconfigured so that it ends at the start of the vmalloc region, and grows downwards. That way, the arrangement of the vmalloc space (which contains kernel mappings, modules, BPF region, the vmemmap array etc) is identical between non-KASAN and KASAN builds, which aids debugging.
Signed-off-by Ard Biesheuvel <[email protected]>--- Documentation/arm64/kasan-offsets.sh | 3 +-- Documentation/arm64/memory.rst | 19 +++++++++---------- arch/arm64/Kconfig | 20 ++++++++++---------- arch/arm64/include/asm/memory.h | 12 +++++------- arch/arm64/mm/init.c | 2 +- 5 files changed, 26 insertions(+), 30 deletions(-)
[...]
Documentation/arm64/memory.rst AArch64 Linux memory layout with 4KB pages + 4 levels (48-bit):: · line 35
Quoted 13 lines
Documentation/arm64/memory.rst +1
-4@@ -32,10 +32,10 @@ AArch64 Linux memory layout with 4KB pages + 4 levels (48-bit):: ----------------------------------------------------------------------- 0000000000000000 0000ffffffffffff 256TB user ffff000000000000 ffff7fffffffffff 128TB kernel logical memory map - ffff800000000000 ffff9fffffffffff 32TB kasan shadow region - ffffa00000000000 ffffa00007ffffff 128MB bpf jit region - ffffa00008000000 ffffa0000fffffff 128MB modules - ffffa00010000000 fffffdffbffeffff ~93TB vmalloc +[ ffff600000000000 ffff7fffffffffff ] 32TB [ kasan shadow region ]
We have the KASAN shadow region intersecting with the kernel logical memory map now. Could this present a problem if both the KASAN and phys_to_virt paths land on the same VA? Or is that not possible? (Also what about smaller VA sizes?)
If it is a problem, could carving out the appropriate memblocks (and warning the user) be a way forward?
Cheers,
--
Steve
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH v2 2/4] arm64: mm: extend linear region for 52-bit VA configurations
Quoted 96 lines · Steve Capper
Hi Ard,
One comment below...
Quoted 68 lines · Ard Biesheuvel
For historical reasons, the arm64 kernel VA space is configured as two equally sized halves, i.e., on a 48-bit VA build, the VA space is split into a 47-bit vmalloc region and a 47-bit linear region.
When support for 52-bit virtual addressing was added, this equal split was kept, resulting in a substantial waste of virtual address space in the linear region:
48-bit VA 52-bit VA
0xffff_ffff_ffff_ffff +-------------+ +-------------+
| vmalloc | | vmalloc |
0xffff_8000_0000_0000 +-------------+_PAGE_END(48)+-------------+| linear | : : 0xffff_0000_0000_0000 +-------------+ : : : : : : : : : : : : : : : : : currently : : unusable : : : : : : unused : : by : : : : : : : : hardware : : : : : : : 0xfff8_0000_0000_0000 : : _PAGE_END(52) +-------------+ : : | | : : | | : : | | : : | | : : | | : unusable : | | : : | linear | : by : | | : : | region | : hardware : | | : : | | : : | | : : | | : : | | : : | | : : | | 0xfff0_0000_0000_0000 +-------------+ PAGE_OFFSET +-------------+As illustrated above, the 52-bit VA kernel uses 47 bits for the vmalloc space (as before), to ensure that a single 64k granule kernel image can support any 64k granule capable system, regardless of whether it supports the 52-bit virtual addressing extension. However, due to the fact that the VA space is still split in equal halves, the linear region is only 2^51 bytes in size, wasting almost half of the 52-bit VA space.
Let's fix this, by abandoning the equal split, and simply assigning all VA space outside of the vmalloc region to the linear region.
The KASAN shadow region is reconfigured so that it ends at the start of the vmalloc region, and grows downwards. That way, the arrangement of the vmalloc space (which contains kernel mappings, modules, BPF region, the vmemmap array etc) is identical between non-KASAN and KASAN builds, which aids debugging.
Signed-off-by Ard Biesheuvel <[email protected]>--- Documentation/arm64/kasan-offsets.sh | 3 +-- Documentation/arm64/memory.rst | 19 +++++++++---------- arch/arm64/Kconfig | 20 ++++++++++---------- arch/arm64/include/asm/memory.h | 12 +++++------- arch/arm64/mm/init.c | 2 +- 5 files changed, 26 insertions(+), 30 deletions(-)[...]
Documentation/arm64/memory.rst AArch64 Linux memory layout with 4KB pages + 4 levels (48-bit):: · line 35
Quoted 13 lines
Documentation/arm64/memory.rst +1
-4@@ -32,10 +32,10 @@ AArch64 Linux memory layout with 4KB pages + 4 levels (48-bit):: ----------------------------------------------------------------------- 0000000000000000 0000ffffffffffff 256TB user ffff000000000000 ffff7fffffffffff 128TB kernel logical memory map - ffff800000000000 ffff9fffffffffff 32TB kasan shadow region - ffffa00000000000 ffffa00007ffffff 128MB bpf jit region - ffffa00008000000 ffffa0000fffffff 128MB modules - ffffa00010000000 fffffdffbffeffff ~93TB vmalloc +[ ffff600000000000 ffff7fffffffffff ] 32TB [ kasan shadow region ]We have the KASAN shadow region intersecting with the kernel logical memory map now. Could this present a problem if both the KASAN and
phys_to_virtpaths land on the same VA? Or is that not possible? (Also what about smaller VA sizes?)
Quoted 3 lines
If it is a problem, could carving out the appropriate memblocks (and warning the user) be a way forward?
Hi Steve,
This is currently taken into account in arm64_memblock_init():
const s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
When CONFIG_KASAN=y, PAGE_END is #defined as
(KASAN_SHADOW_END - (1UL << (vabits_actual - KASAN_SHADOW_SCALE_SHIFT)))
and so the linear region ends where the KASAN shadow region starts. So even if the static definitions overlap, the shared region will not be used for mapping memory if it is needed for allocating shadow pages.
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Steve Capper
Reviewed-byRe: [PATCH v2 2/4] arm64: mm: extend linear region for 52-bit VA configurations
Quoted 107 lines · Ard Biesheuvel
Quoted 96 lines · Steve Capper
Hi Ard,
One comment below...
Quoted 68 lines · Ard Biesheuvel
For historical reasons, the arm64 kernel VA space is configured as two equally sized halves, i.e., on a 48-bit VA build, the VA space is split into a 47-bit vmalloc region and a 47-bit linear region.
When support for 52-bit virtual addressing was added, this equal split was kept, resulting in a substantial waste of virtual address space in the linear region:
48-bit VA 52-bit VA
0xffff_ffff_ffff_ffff +-------------+ +-------------+
| vmalloc | | vmalloc |
0xffff_8000_0000_0000 +-------------+_PAGE_END(48)+-------------+
| linear | : :
0xffff_0000_0000_0000 +-------------+ : :
: : : :
: : : :
: : : :
: : : currently :
: unusable : : :
: : : unused :
: by : : :
: : : :
: hardware : : :
: : : :
0xfff8_0000_0000_0000 : :_PAGE_END(52)+-------------+
: : | |
: : | |
: : | |
: : | |
: : | |
: unusable : | |
: : | linear |
: by : | |
: : | region |
: hardware : | |
: : | |
: : | |
: : | |
: : | |
: : | |
: : | |
0xfff0_0000_0000_0000 +-------------+PAGE_OFFSET+-------------+As illustrated above, the 52-bit VA kernel uses 47 bits for the vmalloc space (as before), to ensure that a single 64k granule kernel image can support any 64k granule capable system, regardless of whether it supports the 52-bit virtual addressing extension. However, due to the fact that the VA space is still split in equal halves, the linear region is only 2^51 bytes in size, wasting almost half of the 52-bit VA space.
Let's fix this, by abandoning the equal split, and simply assigning all VA space outside of the vmalloc region to the linear region.
The KASAN shadow region is reconfigured so that it ends at the start of the vmalloc region, and grows downwards. That way, the arrangement of the vmalloc space (which contains kernel mappings, modules, BPF region, the vmemmap array etc) is identical between non-KASAN and KASAN builds, which aids debugging.
Signed-off-by Ard Biesheuvel <[email protected]>--- Documentation/arm64/kasan-offsets.sh | 3 +-- Documentation/arm64/memory.rst | 19 +++++++++---------- arch/arm64/Kconfig | 20 ++++++++++---------- arch/arm64/include/asm/memory.h | 12 +++++------- arch/arm64/mm/init.c | 2 +- 5 files changed, 26 insertions(+), 30 deletions(-)[...]
Documentation/arm64/memory.rst AArch64 Linux memory layout with 4KB pages + 4 levels (48-bit):: · line 35
Quoted 13 lines
Documentation/arm64/memory.rst +1
-4@@ -32,10 +32,10 @@ AArch64 Linux memory layout with 4KB pages + 4 levels (48-bit):: ----------------------------------------------------------------------- 0000000000000000 0000ffffffffffff 256TB user ffff000000000000 ffff7fffffffffff 128TB kernel logical memory map - ffff800000000000 ffff9fffffffffff 32TB kasan shadow region - ffffa00000000000 ffffa00007ffffff 128MB bpf jit region - ffffa00008000000 ffffa0000fffffff 128MB modules - ffffa00010000000 fffffdffbffeffff ~93TB vmalloc +[ ffff600000000000 ffff7fffffffffff ] 32TB [ kasan shadow region ]We have the KASAN shadow region intersecting with the kernel logical memory map now. Could this present a problem if both the KASAN and
phys_to_virtpaths land on the same VA? Or is that not possible? (Also what about smaller VA sizes?)Quoted 3 lines
If it is a problem, could carving out the appropriate memblocks (and warning the user) be a way forward?
Hi Steve,
This is currently taken into account in
arm64_memblock_init():const s64
linear_region_size=PAGE_END-_PAGE_OFFSET(vabits_actual);
Quoted 8 lines
When
CONFIG_KASAN=y,PAGE_ENDis #defined as(
KASAN_SHADOW_END- (1UL << (vabits_actual-KASAN_SHADOW_SCALE_SHIFT)))and so the linear region ends where the KASAN shadow region starts. So even if the static definitions overlap, the shared region will not be used for mapping memory if it is needed for allocating shadow pages.
Ahhh, yes, thanks that will prevent the intersection from occurring.
This looks good to me, feel free to add:
Cheers,
--
Steve
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH v2 2/4] arm64: mm: extend linear region for 52-bit VA configurations
In reply to Ard BiesheuvelQuoted 43 lines · Ard Biesheuvel
For historical reasons, the arm64 kernel VA space is configured as two equally sized halves, i.e., on a 48-bit VA build, the VA space is split into a 47-bit vmalloc region and a 47-bit linear region.
When support for 52-bit virtual addressing was added, this equal split was kept, resulting in a substantial waste of virtual address space in the linear region:
48-bit VA 52-bit VA
0xffff_ffff_ffff_ffff +-------------+ +-------------+
| vmalloc | | vmalloc |
0xffff_8000_0000_0000 +-------------+_PAGE_END(48)+-------------+| linear | : : 0xffff_0000_0000_0000 +-------------+ : : : : : : : : : : : : : : : : : currently : : unusable : : : : : : unused : : by : : : : : : : : hardware : : : : : : : 0xfff8_0000_0000_0000 : : _PAGE_END(52) +-------------+ : : | | : : | | : : | | : : | | : : | | : unusable : | | : : | linear | : by : | | : : | region | : hardware : | | : : | | : : | | : : | | : : | | : : | | : : | | 0xfff0_0000_0000_0000 +-------------+ PAGE_OFFSET +-------------+
Quoted 6 lines
As illustrated above, the 52-bit VA kernel uses 47 bits for the vmalloc space (as before), to ensure that a single 64k granule kernel image can support any 64k granule capable system, regardless of whether it supports the 52-bit virtual addressing extension. However, due to the fact that the VA space is still split in equal halves, the linear region is only 2^51 bytes in size, wasting almost half of the 52-bit VA space.
Right, that is a huge wastage. Increasing the linear mapping will definitely help in getting more memory used on the system. But now do we have enough vmemmap range to support this enlarged linear mapping ?
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH v2 2/4] arm64: mm: extend linear region for 52-bit VA configurations
Quoted 54 lines · Anshuman Khandual
Quoted 43 lines · Ard Biesheuvel
For historical reasons, the arm64 kernel VA space is configured as two equally sized halves, i.e., on a 48-bit VA build, the VA space is split into a 47-bit vmalloc region and a 47-bit linear region.
When support for 52-bit virtual addressing was added, this equal split was kept, resulting in a substantial waste of virtual address space in the linear region:
48-bit VA 52-bit VA
0xffff_ffff_ffff_ffff +-------------+ +-------------+
| vmalloc | | vmalloc |
0xffff_8000_0000_0000 +-------------+_PAGE_END(48)+-------------+| linear | : : 0xffff_0000_0000_0000 +-------------+ : : : : : : : : : : : : : : : : : currently : : unusable : : : : : : unused : : by : : : : : : : : hardware : : : : : : : 0xfff8_0000_0000_0000 : : _PAGE_END(52) +-------------+ : : | | : : | | : : | | : : | | : : | | : unusable : | | : : | linear | : by : | | : : | region | : hardware : | | : : | | : : | | : : | | : : | | : : | | : : | | 0xfff0_0000_0000_0000 +-------------+ PAGE_OFFSET +-------------+Quoted 6 lines
As illustrated above, the 52-bit VA kernel uses 47 bits for the vmalloc space (as before), to ensure that a single 64k granule kernel image can support any 64k granule capable system, regardless of whether it supports the 52-bit virtual addressing extension. However, due to the fact that the VA space is still split in equal halves, the linear region is only 2^51 bytes in size, wasting almost half of the 52-bit VA space.
Quoted 3 lines
Right, that is a huge wastage. Increasing the linear mapping will definitely help in getting more memory used on the system. But now do we have enough vmemmap range to support this enlarged linear mapping ?
Yes.
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v2 3/4 arm64: mm: make vmemmap region a projection of the linear region
In reply to Ard BiesheuvelNow that we have reverted the introduction of the vmemmap struct page pointer and the separate physvirt_offset, we can simplify things further, and place the vmemmap region in the VA space in such a way that virtual to page translations and vice versa can be implemented using a single arithmetic shift.
One happy coincidence resulting from this is that the 48-bit/4k and 52-bit/64k configurations (which are assumed to be the two most prevalent) end up with the same placement of the vmemmap region. In a subsequent patch, we will take advantage of this, and unify the memory maps even more.
--- Documentation/arm64/memory.rst | 30 ++++++++++---------- arch/arm64/include/asm/memory.h | 14 ++++----- arch/arm64/mm/init.c | 2 ++ 3 files changed, 23 insertions(+), 23 deletions(-)
Documentation/arm64/memory.rst +15 -15
@@ -35,14 +35,14 @@ AArch64 Linux memory layout with 4KB pages + 4 levels (48-bit):: [ ffff600000000000 ffff7fffffffffff ] 32TB [ kasan shadow region ] ffff800000000000 ffff800007ffffff 128MB bpf jit region ffff800008000000 ffff80000fffffff 128MB modules - ffff800010000000 fffffdffbffeffff 125TB vmalloc - fffffdffbfff0000 fffffdfffe5f8fff ~998MB [guard region] - fffffdfffe5f9000 fffffdfffe9fffff 4124KB fixed mappings - fffffdfffea00000 fffffdfffebfffff 2MB [guard region] - fffffdfffec00000 fffffdffffbfffff 16MB PCI I/O space - fffffdffffc00000 fffffdffffdfffff 2MB [guard region] - fffffdffffe00000 ffffffffffdfffff 2TB vmemmap - ffffffffffe00000 ffffffffffffffff 2MB [guard region] + ffff800010000000 fffffbffbffeffff 123TB vmalloc + fffffbffbfff0000 fffffbfffe7f8fff ~998MB [guard region] + fffffbfffe7f9000 fffffbfffebfffff 4124KB fixed mappings + fffffbfffec00000 fffffbfffedfffff 2MB [guard region] + fffffbfffee00000 fffffbffffdfffff 16MB PCI I/O space + fffffbffffe00000 fffffbffffffffff 2MB [guard region] + fffffc0000000000 fffffdffffffffff 2TB vmemmap + fffffe0000000000 ffffffffffffffff 2TB [guard region] AArch64 Linux memory layout with 64KB pages + 3 levels (52-bit with HW support)::
@@ -55,13 +55,13 @@ AArch64 Linux memory layout with 64KB pages + 3 levels (52-bit with HW support): ffff800000000000 ffff800007ffffff 128MB bpf jit region ffff800008000000 ffff80000fffffff 128MB modules ffff800010000000 fffff81ffffeffff 120TB vmalloc - fffff81fffff0000 fffffc1ffe58ffff ~3TB [guard region] - fffffc1ffe590000 fffffc1ffe9fffff 4544KB fixed mappings - fffffc1ffea00000 fffffc1ffebfffff 2MB [guard region] - fffffc1ffec00000 fffffc1fffbfffff 16MB PCI I/O space - fffffc1fffc00000 fffffc1fffdfffff 2MB [guard region] - fffffc1fffe00000 ffffffffffdfffff 3968GB vmemmap - ffffffffffe00000 ffffffffffffffff 2MB [guard region] + fffff81fffff0000 fffffbfffe38ffff ~3TB [guard region] + fffffbfffe390000 fffffbfffebfffff 4544KB fixed mappings + fffffbfffec00000 fffffbfffedfffff 2MB [guard region] + fffffbfffee00000 fffffbffffdfffff 16MB PCI I/O space + fffffbffffe00000 fffffbffffffffff 2MB [guard region] + fffffc0000000000 ffffffdfffffffff ~4TB vmemmap + ffffffe000000000 ffffffffffffffff 128GB [guard region] Translation table lookup with 4KB pages::
arch/arm64/include/asm/memory.h +6 -8
@@ -30,8 +30,8 @@* keep a constant PAGE_OFFSET and "fallback" to using the higher end * of the VMEMMAP where 52-bit support is not available in hardware. */ -#define VMEMMAP_SIZE ((_PAGE_END(VA_BITS_MIN) - PAGE_OFFSET) \ - >> (PAGE_SHIFT - STRUCT_PAGE_MAX_SHIFT)) +#define VMEMMAP_SHIFT (PAGE_SHIFT - STRUCT_PAGE_MAX_SHIFT) +#define VMEMMAP_SIZE ((_PAGE_END(VA_BITS_MIN) - PAGE_OFFSET) >> VMEMMAP_SHIFT)/* * PAGE_OFFSET - the virtual address of the start of the linear map, at the
@@ -50,7 +50,7 @@#define MODULES_END (MODULES_VADDR + MODULES_VSIZE)#define MODULES_VADDR (BPF_JIT_REGION_END)#define MODULES_VSIZE (SZ_128M) -#define VMEMMAP_START (-VMEMMAP_SIZE - SZ_2M) +#define VMEMMAP_START (-(UL(1) << (VA_BITS - VMEMMAP_SHIFT)))#define VMEMMAP_END (VMEMMAP_START + VMEMMAP_SIZE)#define PCI_IO_END (VMEMMAP_START - SZ_2M)#define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE)
@@ -303,15 +303,13 @@ static inline void *phys_to_virt(phys_addr_t x)#else #define page_to_virt (x) ({ \ __typeof__(x) __page = x; \ - u64 __idx = ((u64)__page - VMEMMAP_START) / sizeof(struct page);\ - u64 __addr = PAGE_OFFSET + (__idx * PAGE_SIZE); \ + u64 __addr = (u64)__page << VMEMMAP_SHIFT; \ (void *)__tag_set((const void *)__addr, page_kasan_tag(__page));\ })#define virt_to_page (x) ({ \ - u64 __idx = (__tag_reset((u64)x) - PAGE_OFFSET) / PAGE_SIZE; \ - u64 __addr = VMEMMAP_START + (__idx * sizeof(struct page)); \ - (struct page *)__addr; \ + u64 __addr = __tag_reset((u64)(x)) & PAGE_MASK; \ + (struct page *)((s64)__addr >> VMEMMAP_SHIFT); \ })#endif /* !CONFIG_SPARSEMEM_VMEMMAP || CONFIG_DEBUG_VIRTUAL */
arch/arm64/mm/init.c +2 -0
@@ -504,6 +504,8 @@ static void __init free_unused_memmap(void)*/ void __init mem_init (void ) { +BUILD_BUG_ON (!is_power_of_2 (sizeof (struct page ))); +if (swiotlb_force ==SWIOTLB_FORCE || max_pfn >PFN_DOWN (arm64_dma_phys_limit ? : arm64_dma32_phys_limit))swiotlb_init (1 );
Signature · 7 lines
2.17.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH v2 3/4] arm64: mm: make vmemmap region a projection of the linear region
Quoted 6 lines · Ard Biesheuvel
Now that we have reverted the introduction of the vmemmap struct page pointer and the separate
physvirt_offset, we can simplify things further, and place the vmemmap region in the VA space in such a way that virtual to page translations and vice versa can be implemented using a single arithmetic shift.
Quoted 7 lines
One happy coincidence resulting from this is that the 48-bit/4k and 52-bit/64k configurations (which are assumed to be the two most prevalent) end up with the same placement of the vmemmap region. In a subsequent patch, we will take advantage of this, and unify the memory maps even more.
Signed-off-by Ard Biesheuvel <[email protected]>
Cheers,
--
Steve
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH v2 3/4] arm64: mm: make vmemmap region a projection of the linear region
In reply to Ard BiesheuvelHi Ard,
Quoted 6 lines · Ard Biesheuvel
Now that we have reverted the introduction of the vmemmap struct page pointer and the separate
physvirt_offset, we can simplify things further, and place the vmemmap region in the VA space in such a way that virtual to page translations and vice versa can be implemented using a single arithmetic shift.
Quoted 7 lines
One happy coincidence resulting from this is that the 48-bit/4k and 52-bit/64k configurations (which are assumed to be the two most prevalent) end up with the same placement of the vmemmap region. In a subsequent patch, we will take advantage of this, and unify the memory maps even more.
Signed-off-by Ard Biesheuvel <[email protected]>
This is now commit 8c96400d6a39be76 ("arm64: mm: make vmemmap region a projection of the linear region") in arm64/for-next/core.
arch/arm64/mm/init.c static void __init free_unused_memmap(void) · line 507
Quoted 7 lines
arch/arm64/mm/init.c +1
-0@@ -504,6 +504,8 @@ static void __init free_unused_memmap(void)*/ void __init mem_init (void ) { +BUILD_BUG_ON (!is_power_of_2 (sizeof (struct page )));
This check is triggering for me.
If CONFIG_MEMCG=n, sizeof(struct page) = 56.
If CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y, this is mitigated by the explicit alignment:
#ifdef CONFIG_HAVE_ALIGNED_STRUCT_PAGE
#define _struct_page_alignment __aligned(2 * sizeof(unsigned long))
#else
#define _struct_page_alignment
#endif
struct page { ... } _struct_page_alignment;However, HAVE_ALIGNED_STRUCT_PAGE is selected only if SLUB, while my .config is using SLAB.
Gr{oetje,eeting}s,
Geert
Signature · 10 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH v2 3/4] arm64: mm: make vmemmap region a projection of the linear region
Quoted 44 lines · Geert Uytterhoeven
Hi Ard,
Quoted 6 lines · Ard Biesheuvel
Now that we have reverted the introduction of the vmemmap struct page pointer and the separate
physvirt_offset, we can simplify things further, and place the vmemmap region in the VA space in such a way that virtual to page translations and vice versa can be implemented using a single arithmetic shift.Quoted 7 lines
One happy coincidence resulting from this is that the 48-bit/4k and 52-bit/64k configurations (which are assumed to be the two most prevalent) end up with the same placement of the vmemmap region. In a subsequent patch, we will take advantage of this, and unify the memory maps even more.
Signed-off-by Ard Biesheuvel <[email protected]>This is now commit
8c96400d6a39be76("arm64: mm: make vmemmap region a projection of the linear region") in arm64/for-next/core.arch/arm64/mm/init.c static void __init free_unused_memmap(void) · line 507
Quoted 7 lines
arch/arm64/mm/init.c +1
-0@@ -504,6 +504,8 @@ static void __init free_unused_memmap(void)*/ void __init mem_init (void ) { +BUILD_BUG_ON (!is_power_of_2 (sizeof (struct page )));This check is triggering for me.
If
CONFIG_MEMCG=n, sizeof(struct page) = 56.If
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y, this is mitigated by the explicit alignment:#ifdef CONFIG_HAVE_ALIGNED_STRUCT_PAGE #define _struct_page_alignment __aligned(2 * sizeof(unsigned long)) #else #define _struct_page_alignment #endif struct page { ... } _struct_page_alignment;
Quoted 3 lines
However,
HAVE_ALIGNED_STRUCT_PAGEis selected only if SLUB, while my .config is using SLAB.
Thanks for the report. I will look into this.
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH v2 3/4] arm64: mm: make vmemmap region a projection of the linear region
Quoted 44 lines · Ard Biesheuvel
Quoted 42 lines · Geert Uytterhoeven
Hi Ard,
Quoted 6 lines · Ard Biesheuvel
Now that we have reverted the introduction of the vmemmap struct page pointer and the separate
physvirt_offset, we can simplify things further, and place the vmemmap region in the VA space in such a way that virtual to page translations and vice versa can be implemented using a single arithmetic shift.Quoted 7 lines
One happy coincidence resulting from this is that the 48-bit/4k and 52-bit/64k configurations (which are assumed to be the two most prevalent) end up with the same placement of the vmemmap region. In a subsequent patch, we will take advantage of this, and unify the memory maps even more.
Signed-off-by Ard Biesheuvel <[email protected]>This is now commit
8c96400d6a39be76("arm64: mm: make vmemmap region a projection of the linear region") in arm64/for-next/core.arch/arm64/mm/init.c static void __init free_unused_memmap(void) · line 507
Quoted 7 lines
arch/arm64/mm/init.c +1
-0@@ -504,6 +504,8 @@ static void __init free_unused_memmap(void)*/ void __init mem_init (void ) { +BUILD_BUG_ON (!is_power_of_2 (sizeof (struct page )));This check is triggering for me.
If
CONFIG_MEMCG=n, sizeof(struct page) = 56.If
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y, this is mitigated by the explicit alignment:#ifdef CONFIG_HAVE_ALIGNED_STRUCT_PAGE #define _struct_page_alignment __aligned(2 * sizeof(unsigned long)) #else #define _struct_page_alignment #endif
Quoted 7 lines
Quoted 5 lines
struct page { ... } _struct_page_alignment;However,
HAVE_ALIGNED_STRUCT_PAGEis selected only if SLUB, while my .config is using SLAB.Thanks for the report. I will look into this.
OK, so we can obviously fix this easily by setting CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y unconditionally instead of only 'if SLUB'. The question is whether that is likely to lead to any performance regressions.
So first of all, having a smaller struct page means we can fit more of them into memory. On a 4k pages config with SPARSEMEM_VMEMMAP enabled (which allocates struct pages in 2M blocks), every 2M block can cover 146 MB of DRAM instead of 128 MB. I'm not sure what kind of DRAM arrangement would be needed to take advantage of this in practice, though.
Another aspect is D-cache utilization: cache lines are typically 64 bytes on arm64, and while we can improve Dcache utilization in theory (by virtue of the smaller size), the random access nature of struct pages may well result in the opposite, given that 3 out of 4 struct pages now straddle two cachelines.
Given the above, and given the purpose of this patch series, which was to tidy up and unify different configurations, in order to reduce the size of the validation matrix, I think it would be reasonable to simply set CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y for arm64 in all cases.
Signature · 6 lines
Ard. _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH v2 3/4] arm64: mm: make vmemmap region a projection of the linear region
Hi Ard,
Quoted 54 lines · Ard Biesheuvel
Quoted 40 lines · Ard Biesheuvel
Quoted 39 lines · Geert Uytterhoeven
Quoted 6 lines · Ard Biesheuvel
Now that we have reverted the introduction of the vmemmap struct page pointer and the separate
physvirt_offset, we can simplify things further, and place the vmemmap region in the VA space in such a way that virtual to page translations and vice versa can be implemented using a single arithmetic shift.Quoted 7 lines
One happy coincidence resulting from this is that the 48-bit/4k and 52-bit/64k configurations (which are assumed to be the two most prevalent) end up with the same placement of the vmemmap region. In a subsequent patch, we will take advantage of this, and unify the memory maps even more.
Signed-off-by Ard Biesheuvel <[email protected]>This is now commit
8c96400d6a39be76("arm64: mm: make vmemmap region a projection of the linear region") in arm64/for-next/core.arch/arm64/mm/init.c static void __init free_unused_memmap(void) · line 507
Quoted 7 lines
arch/arm64/mm/init.c +1
-0@@ -504,6 +504,8 @@ static void __init free_unused_memmap(void)*/ void __init mem_init (void ) { +BUILD_BUG_ON (!is_power_of_2 (sizeof (struct page )));This check is triggering for me.
If
CONFIG_MEMCG=n, sizeof(struct page) = 56.If
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y, this is mitigated by the explicit alignment:#ifdef CONFIG_HAVE_ALIGNED_STRUCT_PAGE #define _struct_page_alignment __aligned(2 * sizeof(unsigned long)) #else #define _struct_page_alignment #endifQuoted 7 lines
Quoted 5 lines
struct page { ... } _struct_page_alignment;However,
HAVE_ALIGNED_STRUCT_PAGEis selected only if SLUB, while my .config is using SLAB.Thanks for the report. I will look into this.
OK, so we can obviously fix this easily by setting
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=yunconditionally instead of only 'if SLUB'. The question is whether that is likely to lead to any performance regressions.
Quoted 6 lines
So first of all, having a smaller struct page means we can fit more of them into memory. On a 4k pages config with
SPARSEMEM_VMEMMAPenabled (which allocates struct pages in 2M blocks), every 2M block can cover 146 MB of DRAM instead of 128 MB. I'm not sure what kind of DRAM arrangement would be needed to take advantage of this in practice, though.
So this starts making a difference only for systems with more than 1 GiB RAM, where we can probably afford losing 2 MiB.
Quoted 10 lines
Another aspect is D-cache utilization: cache lines are typically 64 bytes on arm64, and while we can improve Dcache utilization in theory (by virtue of the smaller size), the random access nature of struct pages may well result in the opposite, given that 3 out of 4 struct pages now straddle two cachelines.
Given the above, and given the purpose of this patch series, which was to tidy up and unify different configurations, in order to reduce the size of the validation matrix, I think it would be reasonable to simply set
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=yfor arm64 in all cases.
Thanks, sounds reasonable to me.
Gr{oetje,eeting}s,
Geert
Signature · 10 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Catalin Marinas
maintainerRe: [PATCH v2 3/4] arm64: mm: make vmemmap region a projection of the linear region
In reply to Ard BiesheuvelQuoted 47 lines · Ard Biesheuvel
Quoted 46 lines · Ard Biesheuvel
Quoted 44 lines · Geert Uytterhoeven
Quoted 6 lines · Ard Biesheuvel
Now that we have reverted the introduction of the vmemmap struct page pointer and the separate
physvirt_offset, we can simplify things further, and place the vmemmap region in the VA space in such a way that virtual to page translations and vice versa can be implemented using a single arithmetic shift.Quoted 7 lines
One happy coincidence resulting from this is that the 48-bit/4k and 52-bit/64k configurations (which are assumed to be the two most prevalent) end up with the same placement of the vmemmap region. In a subsequent patch, we will take advantage of this, and unify the memory maps even more.
Signed-off-by Ard Biesheuvel <[email protected]>This is now commit
8c96400d6a39be76("arm64: mm: make vmemmap region a projection of the linear region") in arm64/for-next/core.arch/arm64/mm/init.c static void __init free_unused_memmap(void) · line 507
Quoted 7 lines
arch/arm64/mm/init.c +1
-0@@ -504,6 +504,8 @@ static void __init free_unused_memmap(void)*/ void __init mem_init (void ) { +BUILD_BUG_ON (!is_power_of_2 (sizeof (struct page )));This check is triggering for me.
If
CONFIG_MEMCG=n, sizeof(struct page) = 56.If
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y, this is mitigated by the explicit alignment:#ifdef CONFIG_HAVE_ALIGNED_STRUCT_PAGE #define _struct_page_alignment __aligned(2 * sizeof(unsigned long)) #else #define _struct_page_alignment #endif struct page { ... } _struct_page_alignment;However,
HAVE_ALIGNED_STRUCT_PAGEis selected only if SLUB, while my .config is using SLAB.
Quoted 6 lines
Quoted 1 line
Thanks for the report. I will look into this.
OK, so we can obviously fix this easily by setting
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=yunconditionally instead of only 'if SLUB'. The question is whether that is likely to lead to any performance regressions.
I'm not sure I understand. The mem_init() bug triggers if sizeof(struct page) is not a power of 2. HAVE_ALIGNED_STRUCT_PAGE forces the page alignment to 16 bytes but, for example, a 48-byte structure is not a power of 2.
Signature · 6 lines
Catalin _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH v2 3/4] arm64: mm: make vmemmap region a projection of the linear region
Quoted 56 lines · Catalin Marinas
Quoted 47 lines · Ard Biesheuvel
Quoted 46 lines · Ard Biesheuvel
Quoted 44 lines · Geert Uytterhoeven
Quoted 6 lines · Ard Biesheuvel
Now that we have reverted the introduction of the vmemmap struct page pointer and the separate
physvirt_offset, we can simplify things further, and place the vmemmap region in the VA space in such a way that virtual to page translations and vice versa can be implemented using a single arithmetic shift.Quoted 7 lines
One happy coincidence resulting from this is that the 48-bit/4k and 52-bit/64k configurations (which are assumed to be the two most prevalent) end up with the same placement of the vmemmap region. In a subsequent patch, we will take advantage of this, and unify the memory maps even more.
Signed-off-by Ard Biesheuvel <[email protected]>This is now commit
8c96400d6a39be76("arm64: mm: make vmemmap region a projection of the linear region") in arm64/for-next/core.arch/arm64/mm/init.c static void __init free_unused_memmap(void) · line 507
Quoted 7 lines
arch/arm64/mm/init.c +1
-0@@ -504,6 +504,8 @@ static void __init free_unused_memmap(void)*/ void __init mem_init (void ) { +BUILD_BUG_ON (!is_power_of_2 (sizeof (struct page )));This check is triggering for me.
If
CONFIG_MEMCG=n, sizeof(struct page) = 56.If
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y, this is mitigated by the explicit alignment:#ifdef CONFIG_HAVE_ALIGNED_STRUCT_PAGE #define _struct_page_alignment __aligned(2 * sizeof(unsigned long)) #else #define _struct_page_alignment #endif struct page { ... } _struct_page_alignment;However,
HAVE_ALIGNED_STRUCT_PAGEis selected only if SLUB, while my .config is using SLAB.Quoted 6 lines
Quoted 1 line
Thanks for the report. I will look into this.
OK, so we can obviously fix this easily by setting
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=yunconditionally instead of only 'if SLUB'. The question is whether that is likely to lead to any performance regressions.
Quoted 5 lines
I'm not sure I understand. The
mem_init()bug triggers if sizeof(struct page) is not a power of 2.HAVE_ALIGNED_STRUCT_PAGEforces the page alignment to 16 bytes but, for example, a 48-byte structure is not a power of 2.
True, but looking at include/linux/mm_types.h, I don't see how that would happen.
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Catalin Marinas
maintainerRe: [PATCH v2 3/4] arm64: mm: make vmemmap region a projection of the linear region
Quoted 39 lines · Ard Biesheuvel
Quoted 38 lines · Catalin Marinas
Quoted 36 lines · Ard Biesheuvel
Quoted 23 lines · Ard Biesheuvel
Quoted 22 lines · Geert Uytterhoeven
arch/arm64/mm/init.c static void __init free_unused_memmap(void) · line 507
Quoted 7 lines · Ard Biesheuvel
arch/arm64/mm/init.c +1
-0@@ -504,6 +504,8 @@ static void __init free_unused_memmap(void)*/ void __init mem_init (void ) { +BUILD_BUG_ON (!is_power_of_2 (sizeof (struct page )));This check is triggering for me.
If
CONFIG_MEMCG=n, sizeof(struct page) = 56.If
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y, this is mitigated by the explicit alignment:#ifdef CONFIG_HAVE_ALIGNED_STRUCT_PAGE #define _struct_page_alignment __aligned(2 * sizeof(unsigned long)) #else #define _struct_page_alignment #endifQuoted 7 lines
Quoted 5 lines
struct page { ... } _struct_page_alignment;However,
HAVE_ALIGNED_STRUCT_PAGEis selected only if SLUB, while my .config is using SLAB.Thanks for the report. I will look into this.
OK, so we can obviously fix this easily by setting
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=yunconditionally instead of only 'if SLUB'. The question is whether that is likely to lead to any performance regressions.
Quoted 7 lines
Quoted 4 lines
I'm not sure I understand. The
mem_init()bug triggers if sizeof(struct page) is not a power of 2.HAVE_ALIGNED_STRUCT_PAGEforces the page alignment to 16 bytes but, for example, a 48-byte structure is not a power of 2.True, but looking at
include/linux/mm_types.h, I don't see how that would happen.
Not with 48 and probably won't ever go beyond 64 for "production" builds. But say someone wants to experiment with some debug data in struct page and adds a long. The structure (I think 64 now with MEMCG=y) becomes 72, force-aligned to 80. That triggers the build-bug.
Anyway, I don't mind the forced alignment, only that the build-bug you added has a different requirement than what HAVE_ALIGNED_STRUCT_PAGE provides (power of 2 vs 16-byte aligned).
AFAICT, VMEMMAP_START is a compile-time value, PAGE_OFFSET is also compile-time, so can we not revert to the original virt_to_page and page_to_virt macros? They'd not be as efficient but it may not matter much (and if the struct size is a power of 2, the compiler should change the division/multiplication by shifts).
Signature · 6 lines
Catalin _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH v2 3/4] arm64: mm: make vmemmap region a projection of the linear region
Quoted 58 lines · Catalin Marinas
Quoted 39 lines · Ard Biesheuvel
Quoted 38 lines · Catalin Marinas
Quoted 36 lines · Ard Biesheuvel
Quoted 23 lines · Ard Biesheuvel
Quoted 22 lines · Geert Uytterhoeven
arch/arm64/mm/init.c static void __init free_unused_memmap(void) · line 507
Quoted 7 lines · Ard Biesheuvel
arch/arm64/mm/init.c +1
-0@@ -504,6 +504,8 @@ static void __init free_unused_memmap(void)*/ void __init mem_init (void ) { +BUILD_BUG_ON (!is_power_of_2 (sizeof (struct page )));This check is triggering for me.
If
CONFIG_MEMCG=n, sizeof(struct page) = 56.If
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y, this is mitigated by the explicit alignment:#ifdef CONFIG_HAVE_ALIGNED_STRUCT_PAGE #define _struct_page_alignment __aligned(2 * sizeof(unsigned long)) #else #define _struct_page_alignment #endifQuoted 7 lines
Quoted 5 lines
struct page { ... } _struct_page_alignment;However,
HAVE_ALIGNED_STRUCT_PAGEis selected only if SLUB, while my .config is using SLAB.Thanks for the report. I will look into this.
OK, so we can obviously fix this easily by setting
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=yunconditionally instead of only 'if SLUB'. The question is whether that is likely to lead to any performance regressions.Quoted 7 lines
Quoted 4 lines
I'm not sure I understand. The
mem_init()bug triggers if sizeof(struct page) is not a power of 2.HAVE_ALIGNED_STRUCT_PAGEforces the page alignment to 16 bytes but, for example, a 48-byte structure is not a power of 2.True, but looking at
include/linux/mm_types.h, I don't see how that would happen.Not with 48 and probably won't ever go beyond 64 for "production" builds. But say someone wants to experiment with some debug data in struct page and adds a long. The structure (I think 64 now with MEMCG=y) becomes 72, force-aligned to 80. That triggers the build-bug.
Anyway, I don't mind the forced alignment, only that the build-bug you added has a different requirement than what
HAVE_ALIGNED_STRUCT_PAGEprovides (power of 2 vs 16-byte aligned).
Quoted 6 lines
AFAICT,
VMEMMAP_STARTis a compile-time value,PAGE_OFFSETis also compile-time, so can we not revert to the originalvirt_to_pageandpage_to_virtmacros? They'd not be as efficient but it may not matter much (and if the struct size is a power of 2, the compiler should change the division/multiplication by shifts).
Works for me. I'll go and code that up.
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v2 4/4 arm64: mm: tidy up top of kernel VA space
In reply to Ard BiesheuvelTidy up the way the top of the kernel VA space is organized, by mirroring the 256 MB region we have below the vmalloc space, and populating it top down with the PCI I/O space, some guard regions, and the fixmap region. The latter region is itself populated top down, and today only covers about 4 MB, and so 224 MB is ample, and no guard region is therefore required.
The resulting layout is identical between 48-bit/4k and 52-bit/64k configurations.
--- Documentation/arm64/memory.rst | 22 +++++++++----------- arch/arm64/include/asm/memory.h | 4 ++-- arch/arm64/include/asm/pgtable.h | 2 +- 3 files changed, 13 insertions(+), 15 deletions(-)
Documentation/arm64/memory.rst +10 -12
@@ -35,12 +35,11 @@ AArch64 Linux memory layout with 4KB pages + 4 levels (48-bit):: [ ffff600000000000 ffff7fffffffffff ] 32TB [ kasan shadow region ] ffff800000000000 ffff800007ffffff 128MB bpf jit region ffff800008000000 ffff80000fffffff 128MB modules - ffff800010000000 fffffbffbffeffff 123TB vmalloc - fffffbffbfff0000 fffffbfffe7f8fff ~998MB [guard region] - fffffbfffe7f9000 fffffbfffebfffff 4124KB fixed mappings - fffffbfffec00000 fffffbfffedfffff 2MB [guard region] - fffffbfffee00000 fffffbffffdfffff 16MB PCI I/O space - fffffbffffe00000 fffffbffffffffff 2MB [guard region] + ffff800010000000 fffffbffefffffff 124TB vmalloc + fffffbfff0000000 fffffbfffdffffff 224MB fixed mappings (top down) + fffffbfffe000000 fffffbfffe7fffff 8MB [guard region] + fffffbfffe800000 fffffbffff7fffff 16MB PCI I/O space + fffffbffff800000 fffffbffffffffff 8MB [guard region] fffffc0000000000 fffffdffffffffff 2TB vmemmap fffffe0000000000 ffffffffffffffff 2TB [guard region]
@@ -54,12 +53,11 @@ AArch64 Linux memory layout with 64KB pages + 3 levels (52-bit with HW support): [ fffd800000000000 ffff7fffffffffff ] 512TB [ kasan shadow region ] ffff800000000000 ffff800007ffffff 128MB bpf jit region ffff800008000000 ffff80000fffffff 128MB modules - ffff800010000000 fffff81ffffeffff 120TB vmalloc - fffff81fffff0000 fffffbfffe38ffff ~3TB [guard region] - fffffbfffe390000 fffffbfffebfffff 4544KB fixed mappings - fffffbfffec00000 fffffbfffedfffff 2MB [guard region] - fffffbfffee00000 fffffbffffdfffff 16MB PCI I/O space - fffffbffffe00000 fffffbffffffffff 2MB [guard region] + ffff800010000000 fffffbffefffffff 124TB vmalloc + fffffbfff0000000 fffffbfffdffffff 224MB fixed mappings (top down) + fffffbfffe000000 fffffbfffe7fffff 8MB [guard region] + fffffbfffe800000 fffffbffff7fffff 16MB PCI I/O space + fffffbffff800000 fffffbffffffffff 8MB [guard region] fffffc0000000000 ffffffdfffffffff ~4TB vmemmap ffffffe000000000 ffffffffffffffff 128GB [guard region]
arch/arm64/include/asm/memory.h +2 -2
@@ -52,9 +52,9 @@#define MODULES_VSIZE (SZ_128M)#define VMEMMAP_START (-(UL(1) << (VA_BITS - VMEMMAP_SHIFT)))#define VMEMMAP_END (VMEMMAP_START + VMEMMAP_SIZE) -#define PCI_IO_END (VMEMMAP_START - SZ_2M) +#define PCI_IO_END (VMEMMAP_START - SZ_8M)#define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE) -#define FIXADDR_TOP (PCI_IO_START - SZ_2M) +#define FIXADDR_TOP (VMEMMAP_START - SZ_32M)#if VA_BITS >48 #define VA_BITS_MIN (48)
arch/arm64/include/asm/pgtable.h +1 -1
@@ -21,7 +21,7 @@* and fixed mappings */ #define VMALLOC_START (MODULES_END) -#define VMALLOC_END (- PUD_SIZE - VMEMMAP_SIZE - SZ_64K) +#define VMALLOC_END (VMEMMAP_START - SZ_256M)#define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
Signature · 7 lines
2.17.1 _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Re: [PATCH v2 4/4] arm64: mm: tidy up top of kernel VA space
Quoted 9 lines · Ard Biesheuvel
Tidy up the way the top of the kernel VA space is organized, by mirroring the 256 MB region we have below the vmalloc space, and populating it top down with the PCI I/O space, some guard regions, and the fixmap region. The latter region is itself populated top down, and today only covers about 4 MB, and so 224 MB is ample, and no guard region is therefore required.
The resulting layout is identical between 48-bit/4k and 52-bit/64k configurations.
Nice! :-)
Quoted 2 lines
Signed-off-by Ard Biesheuvel <[email protected]>
Cheers,
--
Steve
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Quoted 14 lines · Ard Biesheuvel
This series reorganizes the kernel VA space slightly so that 52-bit VA configurations can use more virtual address space, i.e., the usable linear address space almost doubles, from 2^51 to 2^52-2^47.
Patch #1 merges the
physvirt_offsetandmemstart_addrvariables, both of which represent translations between the physical address space and the linear region, and there is no need for having both. This fixes a bug too, as the two values were not properly kept in sync when booting with KASLR enabled.Patch #2 updates the definitions for the boundaries of the linear space, so that 52-bit VA builds use all available space for the linear region.
Quoted 9 lines
Patches #3 and #4 simplify the way the vmemmap region is configured, and unify the 48-bit/4k and 52-bit/64k layouts.
Changes since v1:
- drop incorrect use ofuntagged_addr()from #2
- add patches #3 and #4Not boot tested yet on a 52-bit VA capable system.
Boot tested now on FVP Base with and without LVA support enabled.
Quoted 17 lines
Cc Steve Capper <[email protected]>Cc Anshuman Khandual <[email protected]>Ard Biesheuvel (4):
arm64: mm: use single quantity to represent the PA to VA translation
arm64: mm: extend linear region for 52-bit VA configurations
arm64: mm: make vmemmap region a projection of the linear region
arm64: mm: tidy up top of kernel VA spaceDocumentation/arm64/kasan-offsets.sh | 3 +- Documentation/arm64/memory.rst | 45 +++++++++----------- arch/arm64/Kconfig | 20 ++++----- arch/arm64/include/asm/memory.h | 35 +++++++-------- arch/arm64/include/asm/pgtable.h | 6 +-- arch/arm64/mm/init.c | 34 ++++++--------- 6 files changed, 63 insertions(+), 80 deletions(-)
Quoted 3 lines
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerQuoted 11 lines · Ard Biesheuvel
This series reorganizes the kernel VA space slightly so that 52-bit VA configurations can use more virtual address space, i.e., the usable linear address space almost doubles, from 2^51 to 2^52-2^47.
Patch #1 merges the
physvirt_offsetandmemstart_addrvariables, both of which represent translations between the physical address space and the linear region, and there is no need for having both. This fixes a bug too, as the two values were not properly kept in sync when booting with KASLR enabled.[...]
Applied the first patch to arm64 (for-next/core), thanks!
[1/1] arm64: mm: use single quantity to represent the PA to VA translation
https://git.kernel.org/arm64/c/7bc1a0f9e176
Cheers,
Signature · 10 lines
Will https://fixes.arm64.dev https://next.arm64.dev https://will.arm64.dev _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Quoted 11 lines · Ard Biesheuvel
This series reorganizes the kernel VA space slightly so that 52-bit VA configurations can use more virtual address space, i.e., the usable linear address space almost doubles, from 2^51 to 2^52-2^47.
Patch #1 merges the
physvirt_offsetandmemstart_addrvariables, both of which represent translations between the physical address space and the linear region, and there is no need for having both. This fixes a bug too, as the two values were not properly kept in sync when booting with KASLR enabled.[...]
Applied to arm64 (for-next/va-refactor), thanks!
[2/4] arm64: mm: extend linear region for 52-bit VA configurations
https://git.kernel.org/arm64/c/f4693c2716b3 [3/4] arm64: mm: make vmemmap region a projection of the linear region https://git.kernel.org/arm64/c/8c96400d6a39 [4/4] arm64: mm: tidy up top of kernel VA space https://git.kernel.org/arm64/c/9ad7c6d5e75b
Signature · 7 lines
Catalin _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel