Message ID | 20190729162117.832-6-steve.capper@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | 52-bit kernel + user VAs | expand |
On Mon, Jul 29, 2019 at 05:21:11PM +0100, Steve Capper wrote: > In order to support 52-bit kernel addresses detectable at boot time, the > kernel needs to know the most conservative VA_BITS possible should it > need to fall back to this quantity due to lack of hardware support. > > A new compile time constant VA_BITS_MIN is introduced in this patch and > it is employed in the KASAN end address, KASLR, and EFI stub. > > For Arm, if 52-bit VA support is unavailable the fallback is to 48-bits. > > In other words: VA_BITS_MIN = min (48, VA_BITS) > > Signed-off-by: Steve Capper <steve.capper@arm.com> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
On Mon, Jul 29, 2019 at 05:21:11PM +0100, Steve Capper wrote: > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig > index f7f23e47c28f..0206804b0868 100644 > --- a/arch/arm64/Kconfig > +++ b/arch/arm64/Kconfig > @@ -797,6 +797,10 @@ config ARM64_VA_BITS > default 47 if ARM64_VA_BITS_47 > default 48 if ARM64_VA_BITS_48 || ARM64_USER_VA_BITS_52 > > +config ARM64_VA_BITS_MIN > + int > + default ARM64_VA_BITS > + > choice > prompt "Physical address space size" > default ARM64_PA_BITS_48 [...] > diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h > index 8b0f1599b2d1..a8a91a573bff 100644 > --- a/arch/arm64/include/asm/memory.h > +++ b/arch/arm64/include/asm/memory.h > @@ -52,6 +52,9 @@ > #define PCI_IO_END (VMEMMAP_START - SZ_2M) > #define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE) > #define FIXADDR_TOP (PCI_IO_START - SZ_2M) > +#define VA_BITS_MIN (CONFIG_ARM64_VA_BITS_MIN) Thinking about it, do we actually need a Kconfig option for VA_BITS_MIN? Can we not just generated it here based on VA_BITS as min(48, VA_BITS)?
On Mon, Aug 05, 2019 at 06:20:01PM +0100, Catalin Marinas wrote: > On Mon, Jul 29, 2019 at 05:21:11PM +0100, Steve Capper wrote: > > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig > > index f7f23e47c28f..0206804b0868 100644 > > --- a/arch/arm64/Kconfig > > +++ b/arch/arm64/Kconfig > > @@ -797,6 +797,10 @@ config ARM64_VA_BITS > > default 47 if ARM64_VA_BITS_47 > > default 48 if ARM64_VA_BITS_48 || ARM64_USER_VA_BITS_52 > > > > +config ARM64_VA_BITS_MIN > > + int > > + default ARM64_VA_BITS > > + > > choice > > prompt "Physical address space size" > > default ARM64_PA_BITS_48 > [...] > > diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h > > index 8b0f1599b2d1..a8a91a573bff 100644 > > --- a/arch/arm64/include/asm/memory.h > > +++ b/arch/arm64/include/asm/memory.h > > @@ -52,6 +52,9 @@ > > #define PCI_IO_END (VMEMMAP_START - SZ_2M) > > #define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE) > > #define FIXADDR_TOP (PCI_IO_START - SZ_2M) > > +#define VA_BITS_MIN (CONFIG_ARM64_VA_BITS_MIN) > > Thinking about it, do we actually need a Kconfig option for VA_BITS_MIN? > Can we not just generated it here based on VA_BITS as min(48, VA_BITS)? > Thanks Catalin, I'll get rid of the Kconfig option. Cheers,
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index f7f23e47c28f..0206804b0868 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -797,6 +797,10 @@ config ARM64_VA_BITS default 47 if ARM64_VA_BITS_47 default 48 if ARM64_VA_BITS_48 || ARM64_USER_VA_BITS_52 +config ARM64_VA_BITS_MIN + int + default ARM64_VA_BITS + choice prompt "Physical address space size" default ARM64_PA_BITS_48 diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index 8e79ce9c3f5c..f6dbc0149dae 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -79,7 +79,7 @@ static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base) /* * On arm64, we have to ensure that the initrd ends up in the linear region, - * which is a 1 GB aligned region of size '1UL << (VA_BITS - 1)' that is + * which is a 1 GB aligned region of size '1UL << (VA_BITS_MIN - 1)' that is * guaranteed to cover the kernel Image. * * Since the EFI stub is part of the kernel Image, we can relax the @@ -90,7 +90,7 @@ static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base) static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base, unsigned long image_addr) { - return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS - 1)); + return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS_MIN - 1)); } #define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__) diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index 8b0f1599b2d1..a8a91a573bff 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -52,6 +52,9 @@ #define PCI_IO_END (VMEMMAP_START - SZ_2M) #define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE) #define FIXADDR_TOP (PCI_IO_START - SZ_2M) +#define VA_BITS_MIN (CONFIG_ARM64_VA_BITS_MIN) +#define _VA_START(va) (UL(0xffffffffffffffff) - \ + (UL(1) << ((va) - 1)) + 1) #define KERNEL_START _text #define KERNEL_END _end @@ -78,7 +81,7 @@ #endif #else #define KASAN_THREAD_SHIFT 0 -#define KASAN_SHADOW_END (VA_START) +#define KASAN_SHADOW_END (_VA_START(VA_BITS_MIN)) #endif #define MIN_THREAD_SHIFT (14 + KASAN_THREAD_SHIFT) diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 844e2964b0f5..0e1f2770192a 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -42,7 +42,7 @@ * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area. */ -#define DEFAULT_MAP_WINDOW_64 (UL(1) << VA_BITS) +#define DEFAULT_MAP_WINDOW_64 (UL(1) << VA_BITS_MIN) #define TASK_SIZE_64 (UL(1) << vabits_user) #ifdef CONFIG_COMPAT diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 2cdacd1c141b..ac58c69993ec 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -314,7 +314,7 @@ __create_page_tables: mov x5, #52 cbnz x6, 1f #endif - mov x5, #VA_BITS + mov x5, #VA_BITS_MIN 1: adr_l x6, vabits_user str x5, [x6] diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c index 708051655ad9..5a59f7567f9c 100644 --- a/arch/arm64/kernel/kaslr.c +++ b/arch/arm64/kernel/kaslr.c @@ -116,15 +116,15 @@ u64 __init kaslr_early_init(u64 dt_phys) /* * OK, so we are proceeding with KASLR enabled. Calculate a suitable * kernel image offset from the seed. Let's place the kernel in the - * middle half of the VMALLOC area (VA_BITS - 2), and stay clear of + * middle half of the VMALLOC area (VA_BITS_MIN - 2), and stay clear of * the lower and upper quarters to avoid colliding with other * allocations. * Even if we could randomize at page granularity for 16k and 64k pages, * let's always round to 2 MB so we don't interfere with the ability to * map using contiguous PTEs */ - mask = ((1UL << (VA_BITS - 2)) - 1) & ~(SZ_2M - 1); - offset = BIT(VA_BITS - 3) + (seed & mask); + mask = ((1UL << (VA_BITS_MIN - 2)) - 1) & ~(SZ_2M - 1); + offset = BIT(VA_BITS_MIN - 3) + (seed & mask); /* use the top 16 bits to randomize the linear region */ memstart_offset_seed = seed >> 48; diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c index 9e68e3d12956..881d545d252a 100644 --- a/arch/arm64/mm/kasan_init.c +++ b/arch/arm64/mm/kasan_init.c @@ -154,7 +154,8 @@ static void __init kasan_pgd_populate(unsigned long addr, unsigned long end, /* The early shadow maps everything to a single page of zeroes */ asmlinkage void __init kasan_early_init(void) { - BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE)); + BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS), PGDIR_SIZE)); + BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS_MIN), PGDIR_SIZE)); BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE)); kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE, true);
In order to support 52-bit kernel addresses detectable at boot time, the kernel needs to know the most conservative VA_BITS possible should it need to fall back to this quantity due to lack of hardware support. A new compile time constant VA_BITS_MIN is introduced in this patch and it is employed in the KASAN end address, KASLR, and EFI stub. For Arm, if 52-bit VA support is unavailable the fallback is to 48-bits. In other words: VA_BITS_MIN = min (48, VA_BITS) Signed-off-by: Steve Capper <steve.capper@arm.com> --- arch/arm64/Kconfig | 4 ++++ arch/arm64/include/asm/efi.h | 4 ++-- arch/arm64/include/asm/memory.h | 5 ++++- arch/arm64/include/asm/processor.h | 2 +- arch/arm64/kernel/head.S | 2 +- arch/arm64/kernel/kaslr.c | 6 +++--- arch/arm64/mm/kasan_init.c | 3 ++- 7 files changed, 17 insertions(+), 9 deletions(-)