linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/9] 52-bit kernel + user VAs
@ 2019-02-18 17:02 Steve Capper
  2019-02-18 17:02 ` [PATCH 1/9] arm/arm64: KVM: Formalise end of direct linear map Steve Capper
                   ` (10 more replies)
  0 siblings, 11 replies; 29+ messages in thread
From: Steve Capper @ 2019-02-18 17:02 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: crecklin, Steve Capper, marc.zyngier, catalin.marinas,
	ard.biesheuvel, will.deacon

This patch series adds support for 52-bit kernel VAs using some of the
machinery already introduced by the 52-bit userspace VA code in 5.0.

As 52-bit virtual address support is an optional hardware feature,
software support for 52-bit kernel VAs needs to be deduced at early boot
time. If HW support is not available, the kernel falls back to 48-bit.

A significant proportion of this series focuses on "de-constifying"
VA_BITS related constants.

In order to allow for a KASAN shadow that changes size at boot time, one
must fix the KASAN_SHADOW_END for both 48 & 52-bit VAs and "grow" the
start address. Also, it is highly desirable to maintain the same
function addresses in the kernel .text between VA sizes. Both of these
requirements necessitate us to flip the kernel address space halves s.t.
the direct linear map occupies the lower addresses.

One obvious omission is 52-bit kernel VA + 48-bit userspace VA which I
can add with some more #ifdef'ery if needed.

Cheers,
-- 
Steve

Steve Capper (9):
  arm/arm64: KVM: Formalise end of direct linear map
  arm64: mm: Flip kernel VA space
  arm64: kasan: Switch to using KASAN_SHADOW_OFFSET
  arm64: mm: Replace fixed map BUILD_BUG_ON's with BUG_ON's
  arm64: dump: Make kernel page table dumper dynamic again
  arm64: mm: Introduce VA_BITS_MIN
  arm64: mm: Introduce VA_BITS_ACTUAL
  arm64: mm: Logic to make offset_ttbr1 conditional
  arm64: mm: Introduce 52-bit Kernel VAs

 Documentation/arm64/kasan-offsets.sh   | 27 ++++++++++++
 arch/arm/include/asm/memory.h          |  1 +
 arch/arm64/Kconfig                     | 46 +++++++++++++++++++-
 arch/arm64/Makefile                    |  8 ----
 arch/arm64/include/asm/assembler.h     | 17 +++++++-
 arch/arm64/include/asm/cpucaps.h       |  3 +-
 arch/arm64/include/asm/efi.h           |  4 +-
 arch/arm64/include/asm/kasan.h         | 11 ++---
 arch/arm64/include/asm/memory.h        | 33 +++++++++------
 arch/arm64/include/asm/mmu_context.h   |  4 +-
 arch/arm64/include/asm/pgtable-hwdef.h |  2 +-
 arch/arm64/include/asm/pgtable.h       |  2 +-
 arch/arm64/include/asm/processor.h     |  2 +-
 arch/arm64/kernel/cpufeature.c         | 18 ++++++++
 arch/arm64/kernel/head.S               | 25 +++++++++--
 arch/arm64/kernel/hibernate-asm.S      |  1 +
 arch/arm64/kernel/kaslr.c              |  6 +--
 arch/arm64/kvm/va_layout.c             | 14 +++----
 arch/arm64/mm/dump.c                   | 58 +++++++++++++++++++++-----
 arch/arm64/mm/fault.c                  |  4 +-
 arch/arm64/mm/init.c                   | 14 +++----
 arch/arm64/mm/kasan_init.c             | 11 +++--
 arch/arm64/mm/mmu.c                    | 13 +++---
 arch/arm64/mm/proc.S                   |  6 ++-
 virt/kvm/arm/mmu.c                     |  4 +-
 25 files changed, 247 insertions(+), 87 deletions(-)
 create mode 100644 Documentation/arm64/kasan-offsets.sh

-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 1/9] arm/arm64: KVM: Formalise end of direct linear map
  2019-02-18 17:02 [PATCH 0/9] 52-bit kernel + user VAs Steve Capper
@ 2019-02-18 17:02 ` Steve Capper
  2019-02-18 17:02 ` [PATCH 2/9] arm64: mm: Flip kernel VA space Steve Capper
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 29+ messages in thread
From: Steve Capper @ 2019-02-18 17:02 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: crecklin, Steve Capper, marc.zyngier, catalin.marinas,
	ard.biesheuvel, will.deacon

We assume that the direct linear map ends at ~0 in the KVM HYP map
intersection checking code. This assumption will become invalid later on
for arm64 when the address space of the kernel is re-arranged.

This patch introduces a new constant PAGE_OFFSET_END for both arm and
arm64 and defines it to be ~0UL

Signed-off-by: Steve Capper <steve.capper@arm.com>
---
 arch/arm/include/asm/memory.h   | 1 +
 arch/arm64/include/asm/memory.h | 1 +
 virt/kvm/arm/mmu.c              | 4 ++--
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index ed8fd0d19a3e..45c211fd50da 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -24,6 +24,7 @@
 
 /* PAGE_OFFSET - the virtual address of the start of the kernel image */
 #define PAGE_OFFSET		UL(CONFIG_PAGE_OFFSET)
+#define PAGE_OFFSET_END		(~0UL)
 
 #ifdef CONFIG_MMU
 
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 0c656850eeea..617071dbad06 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -52,6 +52,7 @@
 	(UL(1) << VA_BITS) + 1)
 #define PAGE_OFFSET		(UL(0xffffffffffffffff) - \
 	(UL(1) << (VA_BITS - 1)) + 1)
+#define PAGE_OFFSET_END		(~0UL)
 #define KIMAGE_VADDR		(MODULES_END)
 #define BPF_JIT_REGION_START	(VA_START + KASAN_SHADOW_SIZE)
 #define BPF_JIT_REGION_SIZE	(SZ_128M)
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index 30251e288629..94496bdffb49 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -2179,10 +2179,10 @@ int kvm_mmu_init(void)
 	kvm_debug("IDMAP page: %lx\n", hyp_idmap_start);
 	kvm_debug("HYP VA range: %lx:%lx\n",
 		  kern_hyp_va(PAGE_OFFSET),
-		  kern_hyp_va((unsigned long)high_memory - 1));
+		  kern_hyp_va(PAGE_OFFSET_END));
 
 	if (hyp_idmap_start >= kern_hyp_va(PAGE_OFFSET) &&
-	    hyp_idmap_start <  kern_hyp_va((unsigned long)high_memory - 1) &&
+	    hyp_idmap_start <  kern_hyp_va(PAGE_OFFSET_END) &&
 	    hyp_idmap_start != (unsigned long)__hyp_idmap_text_start) {
 		/*
 		 * The idmap page is intersecting with the VA space,
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 2/9] arm64: mm: Flip kernel VA space
  2019-02-18 17:02 [PATCH 0/9] 52-bit kernel + user VAs Steve Capper
  2019-02-18 17:02 ` [PATCH 1/9] arm/arm64: KVM: Formalise end of direct linear map Steve Capper
@ 2019-02-18 17:02 ` Steve Capper
  2019-04-03 11:44   ` Bhupesh Sharma
  2019-02-18 17:02 ` [PATCH 3/9] arm64: kasan: Switch to using KASAN_SHADOW_OFFSET Steve Capper
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 29+ messages in thread
From: Steve Capper @ 2019-02-18 17:02 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: crecklin, Steve Capper, marc.zyngier, catalin.marinas,
	ard.biesheuvel, will.deacon

Put the direct linear map in the lower addresses of the kernel VA range
and everything else in the higher ranges.

This allows us to make room for an inline KASAN shadow that operates
under both 48 and 52 bit kernel VA sizes. For example with a 52-bit VA,
if KASAN_SHADOW_END < 0xFFF8000000000000 (it is in the lower addresses
of the kernel VA range), this will be below the start of the minimum
48-bit kernel VA address of 0xFFFF000000000000.

We need to adjust:
 *) KASAN shadow region placement logic,
 *) KASAN_SHADOW_OFFSET computation logic,
 *) virt_to_phys, phys_to_virt checks,
 *) page table dumper.

These are all small changes, that need to take place atomically, so they
are bundled into this commit.

Signed-off-by: Steve Capper <steve.capper@arm.com>
---
 arch/arm64/Makefile              |  2 +-
 arch/arm64/include/asm/memory.h  | 10 +++++-----
 arch/arm64/include/asm/pgtable.h |  2 +-
 arch/arm64/mm/dump.c             |  8 ++++----
 arch/arm64/mm/init.c             |  9 +--------
 arch/arm64/mm/kasan_init.c       |  6 +++---
 arch/arm64/mm/mmu.c              |  4 ++--
 7 files changed, 17 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index b025304bde46..2dad2ae6b181 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -115,7 +115,7 @@ KBUILD_AFLAGS += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT)
 #				 - (1 << (64 - KASAN_SHADOW_SCALE_SHIFT))
 # in 32-bit arithmetic
 KASAN_SHADOW_OFFSET := $(shell printf "0x%08x00000000\n" $$(( \
-	(0xffffffff & (-1 << ($(CONFIG_ARM64_VA_BITS) - 32))) \
+	(0xffffffff & (-1 << ($(CONFIG_ARM64_VA_BITS) - 1 - 32))) \
 	+ (1 << ($(CONFIG_ARM64_VA_BITS) - 32 - $(KASAN_SHADOW_SCALE_SHIFT))) \
 	- (1 << (64 - 32 - $(KASAN_SHADOW_SCALE_SHIFT))) )) )
 
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 617071dbad06..46a7aba44e9b 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -49,10 +49,10 @@
  */
 #define VA_BITS			(CONFIG_ARM64_VA_BITS)
 #define VA_START		(UL(0xffffffffffffffff) - \
-	(UL(1) << VA_BITS) + 1)
-#define PAGE_OFFSET		(UL(0xffffffffffffffff) - \
 	(UL(1) << (VA_BITS - 1)) + 1)
-#define PAGE_OFFSET_END		(~0UL)
+#define PAGE_OFFSET		(UL(0xffffffffffffffff) - \
+	(UL(1) << VA_BITS) + 1)
+#define PAGE_OFFSET_END		(VA_START)
 #define KIMAGE_VADDR		(MODULES_END)
 #define BPF_JIT_REGION_START	(VA_START + KASAN_SHADOW_SIZE)
 #define BPF_JIT_REGION_SIZE	(SZ_128M)
@@ -60,7 +60,7 @@
 #define MODULES_END		(MODULES_VADDR + MODULES_VSIZE)
 #define MODULES_VADDR		(BPF_JIT_REGION_END)
 #define MODULES_VSIZE		(SZ_128M)
-#define VMEMMAP_START		(PAGE_OFFSET - VMEMMAP_SIZE)
+#define VMEMMAP_START		(-VMEMMAP_SIZE)
 #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)
@@ -243,7 +243,7 @@ extern u64			vabits_user;
  * space. Testing the top bit for the start of the region is a
  * sufficient check.
  */
-#define __is_lm_address(addr)	(!!((addr) & BIT(VA_BITS - 1)))
+#define __is_lm_address(addr)	(!((addr) & BIT(VA_BITS - 1)))
 
 #define __lm_to_phys(addr)	(((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)
 #define __kimg_to_phys(addr)	((addr) - kimage_voffset)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index de70c1eabf33..766def2ed788 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -32,7 +32,7 @@
  *	and fixed mappings
  */
 #define VMALLOC_START		(MODULES_END)
-#define VMALLOC_END		(PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
+#define VMALLOC_END		(- PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
 
 #define vmemmap			((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
 
diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c
index 99bb8facb5cb..3dd9b884bd39 100644
--- a/arch/arm64/mm/dump.c
+++ b/arch/arm64/mm/dump.c
@@ -30,6 +30,8 @@
 #include <asm/ptdump.h>
 
 static const struct addr_marker address_markers[] = {
+	{ PAGE_OFFSET,			"Linear Mapping start" },
+	{ VA_START,			"Linear Mapping end" },
 #ifdef CONFIG_KASAN
 	{ KASAN_SHADOW_START,		"Kasan shadow start" },
 	{ KASAN_SHADOW_END,		"Kasan shadow end" },
@@ -43,10 +45,8 @@ static const struct addr_marker address_markers[] = {
 	{ PCI_IO_START,			"PCI I/O start" },
 	{ PCI_IO_END,			"PCI I/O end" },
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
-	{ VMEMMAP_START,		"vmemmap start" },
-	{ VMEMMAP_START + VMEMMAP_SIZE,	"vmemmap end" },
+	{ VMEMMAP_START,		"vmemmap" },
 #endif
-	{ PAGE_OFFSET,			"Linear mapping" },
 	{ -1,				NULL },
 };
 
@@ -380,7 +380,7 @@ static void ptdump_initialize(void)
 static struct ptdump_info kernel_ptdump_info = {
 	.mm		= &init_mm,
 	.markers	= address_markers,
-	.base_addr	= VA_START,
+	.base_addr	= PAGE_OFFSET,
 };
 
 void ptdump_check_wx(void)
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 7205a9085b4d..0574e17fd28d 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -354,7 +354,7 @@ static void __init fdt_enforce_memory_region(void)
 
 void __init arm64_memblock_init(void)
 {
-	const s64 linear_region_size = -(s64)PAGE_OFFSET;
+	const s64 linear_region_size = BIT(VA_BITS - 1);
 
 	/* Handle linux,usable-memory-range property */
 	fdt_enforce_memory_region();
@@ -362,13 +362,6 @@ void __init arm64_memblock_init(void)
 	/* Remove memory above our supported physical address size */
 	memblock_remove(1ULL << PHYS_MASK_SHIFT, ULLONG_MAX);
 
-	/*
-	 * Ensure that the linear region takes up exactly half of the kernel
-	 * virtual address space. This way, we can distinguish a linear address
-	 * from a kernel/module/vmalloc address by testing a single bit.
-	 */
-	BUILD_BUG_ON(linear_region_size != BIT(VA_BITS - 1));
-
 	/*
 	 * Select a suitable value for the base of physical memory.
 	 */
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index 4b55b15707a3..ee5ec343d009 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -219,10 +219,10 @@ void __init kasan_init(void)
 	kasan_map_populate(kimg_shadow_start, kimg_shadow_end,
 			   early_pfn_to_nid(virt_to_pfn(lm_alias(_text))));
 
-	kasan_populate_early_shadow((void *)KASAN_SHADOW_START,
-				    (void *)mod_shadow_start);
+	kasan_populate_early_shadow(kasan_mem_to_shadow((void *) VA_START),
+				   (void *)mod_shadow_start);
 	kasan_populate_early_shadow((void *)kimg_shadow_end,
-				    kasan_mem_to_shadow((void *)PAGE_OFFSET));
+				   (void *)KASAN_SHADOW_END);
 
 	if (kimg_shadow_start > mod_shadow_end)
 		kasan_populate_early_shadow((void *)mod_shadow_end,
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index b6f5aa52ac67..7401a8481f78 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -389,7 +389,7 @@ static phys_addr_t pgd_pgtable_alloc(void)
 static void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt,
 				  phys_addr_t size, pgprot_t prot)
 {
-	if (virt < VMALLOC_START) {
+	if ((virt >= VA_START) && (virt < VMALLOC_START)) {
 		pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n",
 			&phys, virt);
 		return;
@@ -416,7 +416,7 @@ void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
 static void update_mapping_prot(phys_addr_t phys, unsigned long virt,
 				phys_addr_t size, pgprot_t prot)
 {
-	if (virt < VMALLOC_START) {
+	if ((virt >= VA_START) && (virt < VMALLOC_START)) {
 		pr_warn("BUG: not updating mapping for %pa at 0x%016lx - outside kernel range\n",
 			&phys, virt);
 		return;
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 3/9] arm64: kasan: Switch to using KASAN_SHADOW_OFFSET
  2019-02-18 17:02 [PATCH 0/9] 52-bit kernel + user VAs Steve Capper
  2019-02-18 17:02 ` [PATCH 1/9] arm/arm64: KVM: Formalise end of direct linear map Steve Capper
  2019-02-18 17:02 ` [PATCH 2/9] arm64: mm: Flip kernel VA space Steve Capper
@ 2019-02-18 17:02 ` Steve Capper
  2019-02-18 17:02 ` [PATCH 4/9] arm64: mm: Replace fixed map BUILD_BUG_ON's with BUG_ON's Steve Capper
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 29+ messages in thread
From: Steve Capper @ 2019-02-18 17:02 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: crecklin, Steve Capper, marc.zyngier, catalin.marinas,
	ard.biesheuvel, will.deacon

KASAN_SHADOW_OFFSET is a constant that is supplied to gcc as a command
line argument and affects the codegen of the inline address sanetiser.

Essentially, for an example memory access:
    *ptr1 = val;
The compiler will insert logic similar to the below:
    shadowValue = *(ptr1 >> KASAN_SHADOW_SCALE_SHIFT + KASAN_SHADOW_OFFSET)
    if (somethingWrong(shadowValue))
        flagAnError();

This code sequence is inserted into many places, thus
KASAN_SHADOW_OFFSET is essentially baked into many places in the kernel
text.

If we want to run a single kernel binary with multiple address spaces,
then we need to do this with KASAN_SHADOW_OFFSET fixed.

Thankfully, due to the way the KASAN_SHADOW_OFFSET is used to provide
shadow addresses we know that the end of the shadow region is constant
w.r.t. VA space size:
    KASAN_SHADOW_END = ~0 >> KASAN_SHADOW_SCALE_SHIFT + KASAN_SHADOW_OFFSET

This means that if we increase the size of the VA space, the start of
the KASAN region expands into lower addresses whilst the end of the
KASAN region is fixed.

Currently the arm64 code computes KASAN_SHADOW_OFFSET at build time via
build scripts with the VA size used as a parameter. (There are build
time checks in the C code too to ensure that expected values are being
derived). It is sufficient, and indeed is a simplification, to remove
the build scripts (and build time checks) entirely and instead provide
KASAN_SHADOW_OFFSET values.

This patch removes the logic to compute the KASAN_SHADOW_OFFSET in the
arm64 Makefile, and instead we adopt the approach used by x86 to supply
offset values in kConfig. To help debug/develop future VA space changes,
the Makefile logic has been preserved in a script file in the arm64
Documentation folder.

Signed-off-by: Steve Capper <steve.capper@arm.com>

---

Changed in V3, rebase to include KASAN_SHADOW_SCALE_SHIFT, wording
tidied up.
---
 Documentation/arm64/kasan-offsets.sh | 27 +++++++++++++++++++++++++++
 arch/arm64/Kconfig                   | 15 +++++++++++++++
 arch/arm64/Makefile                  |  8 --------
 arch/arm64/include/asm/kasan.h       | 11 ++++-------
 arch/arm64/include/asm/memory.h      |  8 +++++---
 arch/arm64/mm/kasan_init.c           |  2 --
 6 files changed, 51 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/arm64/kasan-offsets.sh

diff --git a/Documentation/arm64/kasan-offsets.sh b/Documentation/arm64/kasan-offsets.sh
new file mode 100644
index 000000000000..2b7a021db363
--- /dev/null
+++ b/Documentation/arm64/kasan-offsets.sh
@@ -0,0 +1,27 @@
+#!/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
+
+print_kasan_offset () {
+	printf "%02d\t" $1
+	printf "0x%08x00000000\n" $(( (0xffffffff & (-1 << ($1 - 1 - 32))) \
+			+ (1 << ($1 - 32 - $2)) \
+			- (1 << (64 - 32 - $2)) ))
+}
+
+echo KASAN_SHADOW_SCALE_SHIFT = 3
+printf "VABITS\tKASAN_SHADOW_OFFSET\n"
+print_kasan_offset 48 3
+print_kasan_offset 47 3
+print_kasan_offset 42 3
+print_kasan_offset 39 3
+print_kasan_offset 36 3
+echo
+echo KASAN_SHADOW_SCALE_SHIFT = 4
+printf "VABITS\tKASAN_SHADOW_OFFSET\n"
+print_kasan_offset 48 4
+print_kasan_offset 47 4
+print_kasan_offset 42 4
+print_kasan_offset 39 4
+print_kasan_offset 36 4
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index a4168d366127..db155ae86fed 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -291,6 +291,21 @@ config ARCH_SUPPORTS_UPROBES
 config ARCH_PROC_KCORE_TEXT
 	def_bool y
 
+config KASAN_SHADOW_OFFSET
+	hex
+	depends on KASAN
+	default 0xdfffa00000000000 if (ARM64_VA_BITS_48 || ARM64_USER_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_USER_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 0xffffffffffffffff
+
 source "arch/arm64/Kconfig.platforms"
 
 menu "Kernel Features"
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 2dad2ae6b181..764201c76d77 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -111,14 +111,6 @@ KBUILD_CFLAGS += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT)
 KBUILD_CPPFLAGS += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT)
 KBUILD_AFLAGS += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT)
 
-# KASAN_SHADOW_OFFSET = VA_START + (1 << (VA_BITS - KASAN_SHADOW_SCALE_SHIFT))
-#				 - (1 << (64 - KASAN_SHADOW_SCALE_SHIFT))
-# in 32-bit arithmetic
-KASAN_SHADOW_OFFSET := $(shell printf "0x%08x00000000\n" $$(( \
-	(0xffffffff & (-1 << ($(CONFIG_ARM64_VA_BITS) - 1 - 32))) \
-	+ (1 << ($(CONFIG_ARM64_VA_BITS) - 32 - $(KASAN_SHADOW_SCALE_SHIFT))) \
-	- (1 << (64 - 32 - $(KASAN_SHADOW_SCALE_SHIFT))) )) )
-
 export	TEXT_OFFSET GZFLAGS
 
 core-y		+= arch/arm64/kernel/ arch/arm64/mm/
diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h
index b52aacd2c526..10d2add842da 100644
--- a/arch/arm64/include/asm/kasan.h
+++ b/arch/arm64/include/asm/kasan.h
@@ -18,11 +18,8 @@
  * KASAN_SHADOW_START: beginning of the kernel virtual addresses.
  * KASAN_SHADOW_END: KASAN_SHADOW_START + 1/N of kernel virtual addresses,
  * where N = (1 << KASAN_SHADOW_SCALE_SHIFT).
- */
-#define KASAN_SHADOW_START      (VA_START)
-#define KASAN_SHADOW_END        (KASAN_SHADOW_START + KASAN_SHADOW_SIZE)
-
-/*
+ *
+ * KASAN_SHADOW_OFFSET:
  * This value is used to map an address to the corresponding shadow
  * address by the following formula:
  *     shadow_addr = (address >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET
@@ -33,8 +30,8 @@
  *      KASAN_SHADOW_OFFSET = KASAN_SHADOW_END -
  *				(1ULL << (64 - KASAN_SHADOW_SCALE_SHIFT))
  */
-#define KASAN_SHADOW_OFFSET     (KASAN_SHADOW_END - (1ULL << \
-					(64 - KASAN_SHADOW_SCALE_SHIFT)))
+#define _KASAN_SHADOW_START(va)	(KASAN_SHADOW_END - (1UL << ((va) - KASAN_SHADOW_SCALE_SHIFT)))
+#define KASAN_SHADOW_START      _KASAN_SHADOW_START(VA_BITS)
 
 void kasan_init(void);
 void kasan_copy_shadow(pgd_t *pgdir);
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 46a7aba44e9b..dde0b9b75b22 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -54,7 +54,7 @@
 	(UL(1) << VA_BITS) + 1)
 #define PAGE_OFFSET_END		(VA_START)
 #define KIMAGE_VADDR		(MODULES_END)
-#define BPF_JIT_REGION_START	(VA_START + KASAN_SHADOW_SIZE)
+#define BPF_JIT_REGION_START	(KASAN_SHADOW_END)
 #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)
@@ -80,15 +80,17 @@
  * significantly, so double the (minimum) stack size when they are in use.
  */
 #ifdef CONFIG_KASAN
-#define KASAN_SHADOW_SIZE	(UL(1) << (VA_BITS - KASAN_SHADOW_SCALE_SHIFT))
+#define KASAN_SHADOW_OFFSET	_AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
+#define KASAN_SHADOW_END	((UL(1) << (64 - KASAN_SHADOW_SCALE_SHIFT)) \
+					+ KASAN_SHADOW_OFFSET)
 #ifdef CONFIG_KASAN_EXTRA
 #define KASAN_THREAD_SHIFT	2
 #else
 #define KASAN_THREAD_SHIFT	1
 #endif /* CONFIG_KASAN_EXTRA */
 #else
-#define KASAN_SHADOW_SIZE	(0)
 #define KASAN_THREAD_SHIFT	0
+#define KASAN_SHADOW_END	(VA_START)
 #endif
 
 #define MIN_THREAD_SHIFT	(14 + KASAN_THREAD_SHIFT)
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index ee5ec343d009..66ea44568aa5 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -148,8 +148,6 @@ 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(KASAN_SHADOW_OFFSET !=
-		KASAN_SHADOW_END - (1UL << (64 - KASAN_SHADOW_SCALE_SHIFT)));
 	BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE));
 	BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE));
 	kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE,
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 4/9] arm64: mm: Replace fixed map BUILD_BUG_ON's with BUG_ON's
  2019-02-18 17:02 [PATCH 0/9] 52-bit kernel + user VAs Steve Capper
                   ` (2 preceding siblings ...)
  2019-02-18 17:02 ` [PATCH 3/9] arm64: kasan: Switch to using KASAN_SHADOW_OFFSET Steve Capper
@ 2019-02-18 17:02 ` Steve Capper
  2019-02-18 17:02 ` [PATCH 5/9] arm64: dump: Make kernel page table dumper dynamic again Steve Capper
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 29+ messages in thread
From: Steve Capper @ 2019-02-18 17:02 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: crecklin, Steve Capper, marc.zyngier, catalin.marinas,
	ard.biesheuvel, will.deacon

In order to prepare for a variable VA_BITS we need to account for a
variable size VMEMMAP which in turn means the position of the fixed map
is variable at compile time.

Thus, we need to replace the BUILD_BUG_ON's that check the fixed map
position with BUG_ON's.

Signed-off-by: Steve Capper <steve.capper@arm.com>
---
 arch/arm64/mm/mmu.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 7401a8481f78..c24bc447ed9c 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -830,7 +830,7 @@ void __init early_fixmap_init(void)
 	 * The boot-ioremap range spans multiple pmds, for which
 	 * we are not prepared:
 	 */
-	BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT)
+	BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT)
 		     != (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT));
 
 	if ((pmdp != fixmap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)))
@@ -898,9 +898,9 @@ void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
 	 * On 4k pages, we'll use section mappings for the FDT so we only
 	 * have to be in the same PUD.
 	 */
-	BUILD_BUG_ON(dt_virt_base % SZ_2M);
+	BUG_ON(dt_virt_base % SZ_2M);
 
-	BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> SWAPPER_TABLE_SHIFT !=
+	BUG_ON(__fix_to_virt(FIX_FDT_END) >> SWAPPER_TABLE_SHIFT !=
 		     __fix_to_virt(FIX_BTMAP_BEGIN) >> SWAPPER_TABLE_SHIFT);
 
 	offset = dt_phys % SWAPPER_BLOCK_SIZE;
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 5/9] arm64: dump: Make kernel page table dumper dynamic again
  2019-02-18 17:02 [PATCH 0/9] 52-bit kernel + user VAs Steve Capper
                   ` (3 preceding siblings ...)
  2019-02-18 17:02 ` [PATCH 4/9] arm64: mm: Replace fixed map BUILD_BUG_ON's with BUG_ON's Steve Capper
@ 2019-02-18 17:02 ` Steve Capper
  2019-02-18 17:02 ` [PATCH 6/9] arm64: mm: Introduce VA_BITS_MIN Steve Capper
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 29+ messages in thread
From: Steve Capper @ 2019-02-18 17:02 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: crecklin, Steve Capper, marc.zyngier, catalin.marinas,
	ard.biesheuvel, will.deacon

The kernel page table dumper assumes that the placement of VA regions is
constant and determined at compile time. As we are about to introduce
variable VA logic, we need to be able to determine certain regions at
boot time.

This patch adds logic to the kernel page table dumper s.t. these regions
can be computed at boot time.

Signed-off-by: Steve Capper <steve.capper@arm.com>
---
 arch/arm64/mm/dump.c | 58 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 47 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c
index 3dd9b884bd39..2196131b8e4f 100644
--- a/arch/arm64/mm/dump.c
+++ b/arch/arm64/mm/dump.c
@@ -29,23 +29,45 @@
 #include <asm/pgtable-hwdef.h>
 #include <asm/ptdump.h>
 
-static const struct addr_marker address_markers[] = {
-	{ PAGE_OFFSET,			"Linear Mapping start" },
-	{ VA_START,			"Linear Mapping end" },
+
+enum address_markers_idx {
+	PAGE_OFFSET_NR = 0,
+	VA_START_NR,
+#ifdef CONFIG_KASAN
+	KASAN_START_NR,
+	KASAN_END_NR,
+#endif
+	MODULES_START_NR,
+	MODULES_END_NR,
+	VMALLOC_START_NR,
+	VMALLOC_END_NR,
+	FIXADDR_START_NR,
+	FIXADDR_END_NR,
+	PCI_START_NR,
+	PCI_END_NR,
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+	VMEMMAP_START_NR,
+#endif
+	END_NR
+};
+
+static struct addr_marker address_markers[] = {
+	{ 0 /* PAGE_OFFSET */,		"Linear Mapping start" },
+	{ 0 /* VA_START */,		"Linear Mapping end" },
 #ifdef CONFIG_KASAN
-	{ KASAN_SHADOW_START,		"Kasan shadow start" },
+	{ 0 /* KASAN_SHADOW_START */,	"Kasan shadow start" },
 	{ KASAN_SHADOW_END,		"Kasan shadow end" },
 #endif
 	{ MODULES_VADDR,		"Modules start" },
 	{ MODULES_END,			"Modules end" },
 	{ VMALLOC_START,		"vmalloc() area" },
-	{ VMALLOC_END,			"vmalloc() end" },
-	{ FIXADDR_START,		"Fixmap start" },
-	{ FIXADDR_TOP,			"Fixmap end" },
-	{ PCI_IO_START,			"PCI I/O start" },
-	{ PCI_IO_END,			"PCI I/O end" },
+	{ 0 /* VMALLOC_END */,		"vmalloc() end" },
+	{ 0 /* FIXADDR_START */,	"Fixmap start" },
+	{ 0 /* FIXADDR_TOP */,		"Fixmap end" },
+	{ 0 /* PCI_IO_START */,		"PCI I/O start" },
+	{ 0 /* PCI_IO_END */,		"PCI I/O end" },
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
-	{ VMEMMAP_START,		"vmemmap" },
+	{ 0 /* VMEMMAP_START */,	"vmemmap" },
 #endif
 	{ -1,				NULL },
 };
@@ -380,7 +402,6 @@ static void ptdump_initialize(void)
 static struct ptdump_info kernel_ptdump_info = {
 	.mm		= &init_mm,
 	.markers	= address_markers,
-	.base_addr	= PAGE_OFFSET,
 };
 
 void ptdump_check_wx(void)
@@ -406,6 +427,21 @@ void ptdump_check_wx(void)
 static int ptdump_init(void)
 {
 	ptdump_initialize();
+	kernel_ptdump_info.base_addr = PAGE_OFFSET;
+	address_markers[PAGE_OFFSET_NR].start_address = PAGE_OFFSET;
+	address_markers[VA_START_NR].start_address = VA_START;
+#ifdef CONFIG_KASAN
+	address_markers[KASAN_START_NR].start_address = KASAN_SHADOW_START;
+#endif
+	address_markers[VMALLOC_END_NR].start_address = VMALLOC_END;
+	address_markers[FIXADDR_START_NR].start_address = FIXADDR_START;
+	address_markers[FIXADDR_END_NR].start_address = FIXADDR_TOP;
+	address_markers[PCI_START_NR].start_address = PCI_IO_START;
+	address_markers[PCI_END_NR].start_address = PCI_IO_END;
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+	address_markers[VMEMMAP_START_NR].start_address = VMEMMAP_START;
+#endif
+
 	return ptdump_debugfs_register(&kernel_ptdump_info,
 					"kernel_page_tables");
 }
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 6/9] arm64: mm: Introduce VA_BITS_MIN
  2019-02-18 17:02 [PATCH 0/9] 52-bit kernel + user VAs Steve Capper
                   ` (4 preceding siblings ...)
  2019-02-18 17:02 ` [PATCH 5/9] arm64: dump: Make kernel page table dumper dynamic again Steve Capper
@ 2019-02-18 17:02 ` Steve Capper
  2019-02-18 17:02 ` [PATCH 7/9] arm64: mm: Introduce VA_BITS_ACTUAL Steve Capper
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 29+ messages in thread
From: Steve Capper @ 2019-02-18 17:02 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: crecklin, Steve Capper, marc.zyngier, catalin.marinas,
	ard.biesheuvel, will.deacon

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(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index db155ae86fed..0f933d3a1614 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -756,6 +756,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 7ed320895d1f..4a84353bc9f7 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -68,7 +68,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
@@ -79,7 +79,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 dde0b9b75b22..03db258eb354 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -64,6 +64,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
@@ -90,7 +93,7 @@
 #endif /* CONFIG_KASAN_EXTRA */
 #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 f1a7ab18faf3..48e94a671234 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -53,7 +53,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 15d79a8e5e5e..b6c15b97ec9d 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -325,7 +325,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 b09b6f75f759..6f0075f983c7 100644
--- a/arch/arm64/kernel/kaslr.c
+++ b/arch/arm64/kernel/kaslr.c
@@ -119,15 +119,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 66ea44568aa5..3996d46b5d0e 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -148,7 +148,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);
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 7/9] arm64: mm: Introduce VA_BITS_ACTUAL
  2019-02-18 17:02 [PATCH 0/9] 52-bit kernel + user VAs Steve Capper
                   ` (5 preceding siblings ...)
  2019-02-18 17:02 ` [PATCH 6/9] arm64: mm: Introduce VA_BITS_MIN Steve Capper
@ 2019-02-18 17:02 ` Steve Capper
  2019-02-18 17:02 ` [PATCH 8/9] arm64: mm: Logic to make offset_ttbr1 conditional Steve Capper
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 29+ messages in thread
From: Steve Capper @ 2019-02-18 17:02 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: crecklin, Steve Capper, marc.zyngier, catalin.marinas,
	ard.biesheuvel, will.deacon

In order to support 52-bit kernel addresses detectable at boot time, one
needs to know the actual VA_BITS detected. A new variable VA_BITS_ACTUAL
is introduced in this commit and employed for the KVM hypervisor layout,
KASAN, fault handling and phys-to/from-virt translation where there
would normally be compile time constants.

In order to maintain performance in phys_to_virt, another variable
physvirt_offset is introduced.

Signed-off-by: Steve Capper <steve.capper@arm.com>
---
 arch/arm64/include/asm/kasan.h       |  2 +-
 arch/arm64/include/asm/memory.h      | 17 ++++++++++-------
 arch/arm64/include/asm/mmu_context.h |  2 +-
 arch/arm64/kernel/head.S             |  5 +++++
 arch/arm64/kvm/va_layout.c           | 14 +++++++-------
 arch/arm64/mm/fault.c                |  4 ++--
 arch/arm64/mm/init.c                 |  7 ++++++-
 arch/arm64/mm/mmu.c                  |  3 +++
 8 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h
index 10d2add842da..ff991dc86ae1 100644
--- a/arch/arm64/include/asm/kasan.h
+++ b/arch/arm64/include/asm/kasan.h
@@ -31,7 +31,7 @@
  *				(1ULL << (64 - KASAN_SHADOW_SCALE_SHIFT))
  */
 #define _KASAN_SHADOW_START(va)	(KASAN_SHADOW_END - (1UL << ((va) - KASAN_SHADOW_SCALE_SHIFT)))
-#define KASAN_SHADOW_START      _KASAN_SHADOW_START(VA_BITS)
+#define KASAN_SHADOW_START      _KASAN_SHADOW_START(VA_BITS_ACTUAL)
 
 void kasan_init(void);
 void kasan_copy_shadow(pgd_t *pgdir);
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 03db258eb354..a51056a157dd 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -48,10 +48,6 @@
  * VA_START - the first kernel virtual address.
  */
 #define VA_BITS			(CONFIG_ARM64_VA_BITS)
-#define VA_START		(UL(0xffffffffffffffff) - \
-	(UL(1) << (VA_BITS - 1)) + 1)
-#define PAGE_OFFSET		(UL(0xffffffffffffffff) - \
-	(UL(1) << VA_BITS) + 1)
 #define PAGE_OFFSET_END		(VA_START)
 #define KIMAGE_VADDR		(MODULES_END)
 #define BPF_JIT_REGION_START	(KASAN_SHADOW_END)
@@ -178,10 +174,17 @@
 #endif
 
 #ifndef __ASSEMBLY__
+extern u64			vabits_actual;
+#define VA_BITS_ACTUAL		({vabits_actual;})
+#define VA_START		(_VA_START(VA_BITS_ACTUAL))
+#define PAGE_OFFSET		(UL(0xffffffffffffffff) - \
+					(UL(1) << VA_BITS_ACTUAL) + 1)
+#define PAGE_OFFSET_END		(VA_START)
 
 #include <linux/bitops.h>
 #include <linux/mmdebug.h>
 
+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; })
@@ -248,9 +251,9 @@ extern u64			vabits_user;
  * space. Testing the top bit for the start of the region is a
  * sufficient check.
  */
-#define __is_lm_address(addr)	(!((addr) & BIT(VA_BITS - 1)))
+#define __is_lm_address(addr)	(!((addr) & BIT(VA_BITS_ACTUAL - 1)))
 
-#define __lm_to_phys(addr)	(((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)
+#define __lm_to_phys(addr)	(((addr) + physvirt_offset))
 #define __kimg_to_phys(addr)	((addr) - kimage_voffset)
 
 #define __virt_to_phys_nodebug(x) ({					\
@@ -269,7 +272,7 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x);
 #define __phys_addr_symbol(x)	__pa_symbol_nodebug(x)
 #endif
 
-#define __phys_to_virt(x)	((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET)
+#define __phys_to_virt(x)	((unsigned long)((x) - physvirt_offset))
 #define __phys_to_kimg(x)	((unsigned long)((x) + kimage_voffset))
 
 /*
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index 2da3e478fd8f..133ecb65b602 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -106,7 +106,7 @@ static inline void __cpu_set_tcr_t0sz(unsigned long t0sz)
 	isb();
 }
 
-#define cpu_set_default_tcr_t0sz()	__cpu_set_tcr_t0sz(TCR_T0SZ(VA_BITS))
+#define cpu_set_default_tcr_t0sz()	__cpu_set_tcr_t0sz(TCR_T0SZ(VA_BITS_ACTUAL))
 #define cpu_set_idmap_tcr_t0sz()	__cpu_set_tcr_t0sz(idmap_t0sz)
 
 /*
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index b6c15b97ec9d..68c391b26858 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -332,6 +332,11 @@ __create_page_tables:
 	dmb	sy
 	dc	ivac, x6		// Invalidate potentially stale cache line
 
+	adr_l	x6, vabits_actual
+	str	x5, [x6]
+	dmb	sy
+	dc	ivac, x6		// Invalidate potentially stale cache line
+
 	/*
 	 * VA_BITS may be too small to allow for an ID mapping to be created
 	 * that covers system RAM if that is located sufficiently high in the
diff --git a/arch/arm64/kvm/va_layout.c b/arch/arm64/kvm/va_layout.c
index c712a7376bc1..c9a1debb45bd 100644
--- a/arch/arm64/kvm/va_layout.c
+++ b/arch/arm64/kvm/va_layout.c
@@ -40,25 +40,25 @@ static void compute_layout(void)
 	int kva_msb;
 
 	/* Where is my RAM region? */
-	hyp_va_msb  = idmap_addr & BIT(VA_BITS - 1);
-	hyp_va_msb ^= BIT(VA_BITS - 1);
+	hyp_va_msb  = idmap_addr & BIT(VA_BITS_ACTUAL - 1);
+	hyp_va_msb ^= BIT(VA_BITS_ACTUAL - 1);
 
 	kva_msb = fls64((u64)phys_to_virt(memblock_start_of_DRAM()) ^
 			(u64)(high_memory - 1));
 
-	if (kva_msb == (VA_BITS - 1)) {
+	if (kva_msb == (VA_BITS_ACTUAL - 1)) {
 		/*
 		 * No space in the address, let's compute the mask so
-		 * that it covers (VA_BITS - 1) bits, and the region
+		 * that it covers (VA_BITS_ACTUAL - 1) bits, and the region
 		 * bit. The tag stays set to zero.
 		 */
-		va_mask  = BIT(VA_BITS - 1) - 1;
+		va_mask  = BIT(VA_BITS_ACTUAL - 1) - 1;
 		va_mask |= hyp_va_msb;
 	} else {
 		/*
 		 * We do have some free bits to insert a random tag.
 		 * Hyp VAs are now created from kernel linear map VAs
-		 * using the following formula (with V == VA_BITS):
+		 * using the following formula (with V == VA_BITS_ACTUAL):
 		 *
 		 *  63 ... V |     V-1    | V-2 .. tag_lsb | tag_lsb - 1 .. 0
 		 *  ---------------------------------------------------------
@@ -66,7 +66,7 @@ static void compute_layout(void)
 		 */
 		tag_lsb = kva_msb;
 		va_mask = GENMASK_ULL(tag_lsb - 1, 0);
-		tag_val = get_random_long() & GENMASK_ULL(VA_BITS - 2, tag_lsb);
+		tag_val = get_random_long() & GENMASK_ULL(VA_BITS_ACTUAL - 2, tag_lsb);
 		tag_val |= hyp_va_msb;
 		tag_val >>= tag_lsb;
 	}
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index efb7b2cbead5..15eca262f6e6 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -171,9 +171,9 @@ void show_pte(unsigned long addr)
 		return;
 	}
 
-	pr_alert("%s pgtable: %luk pages, %u-bit VAs, pgdp = %p\n",
+	pr_alert("%s pgtable: %luk pages, %llu-bit VAs, pgdp = %p\n",
 		 mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K,
-		 mm == &init_mm ? VA_BITS : (int) vabits_user, mm->pgd);
+		 mm == &init_mm ? VA_BITS_ACTUAL : (int) vabits_user, mm->pgd);
 	pgdp = pgd_offset(mm, addr);
 	pgd = READ_ONCE(*pgdp);
 	pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd));
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 0574e17fd28d..25bdb71c6c5a 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -61,6 +61,9 @@
 s64 memstart_addr __ro_after_init = -1;
 EXPORT_SYMBOL(memstart_addr);
 
+s64 physvirt_offset __ro_after_init;
+EXPORT_SYMBOL(physvirt_offset);
+
 phys_addr_t arm64_dma_phys_limit __ro_after_init;
 
 #ifdef CONFIG_KEXEC_CORE
@@ -354,7 +357,7 @@ static void __init fdt_enforce_memory_region(void)
 
 void __init arm64_memblock_init(void)
 {
-	const s64 linear_region_size = BIT(VA_BITS - 1);
+	const s64 linear_region_size = BIT(VA_BITS_ACTUAL - 1);
 
 	/* Handle linux,usable-memory-range property */
 	fdt_enforce_memory_region();
@@ -368,6 +371,8 @@ void __init arm64_memblock_init(void)
 	memstart_addr = round_down(memblock_start_of_DRAM(),
 				   ARM64_MEMSTART_ALIGN);
 
+	physvirt_offset = PHYS_OFFSET - PAGE_OFFSET;
+
 	/*
 	 * 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
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index c24bc447ed9c..50fe776ccb37 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -55,6 +55,9 @@ u64 idmap_ptrs_per_pgd = PTRS_PER_PGD;
 u64 vabits_user __ro_after_init;
 EXPORT_SYMBOL(vabits_user);
 
+u64 __section(".mmuoff.data.write") vabits_actual;
+EXPORT_SYMBOL(vabits_actual);
+
 u64 kimage_voffset __ro_after_init;
 EXPORT_SYMBOL(kimage_voffset);
 
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 8/9] arm64: mm: Logic to make offset_ttbr1 conditional
  2019-02-18 17:02 [PATCH 0/9] 52-bit kernel + user VAs Steve Capper
                   ` (6 preceding siblings ...)
  2019-02-18 17:02 ` [PATCH 7/9] arm64: mm: Introduce VA_BITS_ACTUAL Steve Capper
@ 2019-02-18 17:02 ` Steve Capper
  2019-04-03 11:26   ` Bhupesh Sharma
  2019-02-18 17:02 ` [PATCH 9/9] arm64: mm: Introduce 52-bit Kernel VAs Steve Capper
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 29+ messages in thread
From: Steve Capper @ 2019-02-18 17:02 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: crecklin, Steve Capper, marc.zyngier, catalin.marinas,
	ard.biesheuvel, will.deacon

When running with a 52-bit userspace VA and a 48-bit kernel VA we offset
ttbr1_el1 to allow the kernel pagetables with a 52-bit PTRS_PER_PGD to
be used for both userspace and kernel.

Moving on to a 52-bit kernel VA we no longer require this offset to
ttbr1_el1 should we be running on a system with HW support for 52-bit
VAs.

This patch introduces alternative logic to offset_ttbr1 and expands out
the very early case in head.S. We need to use the alternative framework
as offset_ttbr1 is used in places in the kernel where it is not possible
to safely adrp address kernel constants (such as the kpti paths); thus
code patching is the safer route.

Signed-off-by: Steve Capper <steve.capper@arm.com>
---
 arch/arm64/include/asm/assembler.h | 10 +++++++++-
 arch/arm64/include/asm/cpucaps.h   |  3 ++-
 arch/arm64/kernel/cpufeature.c     | 18 ++++++++++++++++++
 arch/arm64/kernel/head.S           | 14 +++++++++++++-
 arch/arm64/kernel/hibernate-asm.S  |  1 +
 5 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 4feb6119c3c9..58ed5d086e1e 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -551,6 +551,14 @@ USER(\label, ic	ivau, \tmp2)			// invalidate I line PoU
 	.macro	offset_ttbr1, ttbr
 #ifdef CONFIG_ARM64_USER_VA_BITS_52
 	orr	\ttbr, \ttbr, #TTBR1_BADDR_4852_OFFSET
+#endif
+
+#ifdef CONFIG_ARM64_USER_KERNEL_VA_BITS_52
+alternative_if_not ARM64_HAS_52BIT_VA
+	orr	\ttbr, \ttbr, #TTBR1_BADDR_4852_OFFSET
+alternative_else
+	nop
+alternative_endif
 #endif
 	.endm
 
@@ -560,7 +568,7 @@ USER(\label, ic	ivau, \tmp2)			// invalidate I line PoU
  * to be nop'ed out when dealing with 52-bit kernel VAs.
  */
 	.macro	restore_ttbr1, ttbr
-#ifdef CONFIG_ARM64_USER_VA_BITS_52
+#if defined(CONFIG_ARM64_USER_VA_BITS_52) || defined(CONFIG_ARM64_KERNEL_VA_BITS_52)
 	bic	\ttbr, \ttbr, #TTBR1_BADDR_4852_OFFSET
 #endif
 	.endm
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 82e9099834ae..d71aecb6d6db 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -60,7 +60,8 @@
 #define ARM64_HAS_ADDRESS_AUTH_IMP_DEF		39
 #define ARM64_HAS_GENERIC_AUTH_ARCH		40
 #define ARM64_HAS_GENERIC_AUTH_IMP_DEF		41
+#define ARM64_HAS_52BIT_VA			42
 
-#define ARM64_NCAPS				42
+#define ARM64_NCAPS				43
 
 #endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index f6d84e2c92fe..2e150c564f2a 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -944,6 +944,16 @@ has_useable_cnp(const struct arm64_cpu_capabilities *entry, int scope)
 	return has_cpuid_feature(entry, scope);
 }
 
+#ifdef CONFIG_ARM64_USER_KERNEL_VA_BITS_52
+extern u64 vabits_actual;
+static bool __maybe_unused
+has_52bit_kernel_va(const struct arm64_cpu_capabilities *entry, int scope)
+{
+	return vabits_actual == 52;
+}
+
+#endif /* CONFIG_ARM64_USER_KERNEL_VA_BITS_52 */
+
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
 static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */
 
@@ -1480,6 +1490,14 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 	},
 #endif /* CONFIG_ARM64_PTR_AUTH */
+#ifdef CONFIG_ARM64_USER_KERNEL_VA_BITS_52
+	{
+		.desc = "52-bit kernel VA",
+		.capability = ARM64_HAS_52BIT_VA,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_52bit_kernel_va,
+	},
+#endif /* CONFIG_ARM64_USER_KERNEL_VA_BITS_52 */
 	{},
 };
 
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 68c391b26858..4877b82d2091 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -789,7 +789,19 @@ ENTRY(__enable_mmu)
 	phys_to_ttbr x1, x1
 	phys_to_ttbr x2, x2
 	msr	ttbr0_el1, x2			// load TTBR0
-	offset_ttbr1 x1
+
+#if defined(CONFIG_ARM64_USER_VA_BITS_52)
+	orr     x1, x1, #TTBR1_BADDR_4852_OFFSET
+#endif
+
+#if defined(CONFIG_ARM64_USER_KERNEL_VA_BITS_52)
+	ldr_l	x3, vabits_actual
+	cmp	x3, #52
+	b.eq	1f
+	orr     x1, x1, #TTBR1_BADDR_4852_OFFSET
+1:
+#endif
+
 	msr	ttbr1_el1, x1			// load TTBR1
 	isb
 	msr	sctlr_el1, x0
diff --git a/arch/arm64/kernel/hibernate-asm.S b/arch/arm64/kernel/hibernate-asm.S
index fe36d85c60bd..d32725a2b77f 100644
--- a/arch/arm64/kernel/hibernate-asm.S
+++ b/arch/arm64/kernel/hibernate-asm.S
@@ -19,6 +19,7 @@
 #include <linux/linkage.h>
 #include <linux/errno.h>
 
+#include <asm/alternative.h>
 #include <asm/asm-offsets.h>
 #include <asm/assembler.h>
 #include <asm/cputype.h>
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 9/9] arm64: mm: Introduce 52-bit Kernel VAs
  2019-02-18 17:02 [PATCH 0/9] 52-bit kernel + user VAs Steve Capper
                   ` (7 preceding siblings ...)
  2019-02-18 17:02 ` [PATCH 8/9] arm64: mm: Logic to make offset_ttbr1 conditional Steve Capper
@ 2019-02-18 17:02 ` Steve Capper
  2019-03-25 18:17   ` Catalin Marinas
  2019-02-19 12:13 ` [PATCH 0/9] 52-bit kernel + user VAs Ard Biesheuvel
  2019-04-03  8:09 ` Bhupesh Sharma
  10 siblings, 1 reply; 29+ messages in thread
From: Steve Capper @ 2019-02-18 17:02 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: crecklin, Steve Capper, marc.zyngier, catalin.marinas,
	ard.biesheuvel, will.deacon

Most of the machinery is now in place to enable 52-bit kernel VAs that
are detectable at boot time.

This patch adds a Kconfig option for 52-bit user and kernel addresses
and plumbs in the requisite CONFIG_ macros as well as sets TCR.T1SZ at
early boot.

Signed-off-by: Steve Capper <steve.capper@arm.com>
---
 arch/arm64/Kconfig                     | 31 ++++++++++++++++++++++----
 arch/arm64/include/asm/assembler.h     |  9 +++++++-
 arch/arm64/include/asm/memory.h        |  2 +-
 arch/arm64/include/asm/mmu_context.h   |  2 +-
 arch/arm64/include/asm/pgtable-hwdef.h |  2 +-
 arch/arm64/kernel/head.S               |  4 ++--
 arch/arm64/mm/proc.S                   |  6 ++++-
 7 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 0f933d3a1614..1a673a7d0a9b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -276,11 +276,14 @@ config KERNEL_MODE_NEON
 config FIX_EARLYCON_MEM
 	def_bool y
 
+config HAS_VA_BITS_52
+	def_bool n
+
 config PGTABLE_LEVELS
 	int
 	default 2 if ARM64_16K_PAGES && ARM64_VA_BITS_36
 	default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42
-	default 3 if ARM64_64K_PAGES && (ARM64_VA_BITS_48 || ARM64_USER_VA_BITS_52)
+	default 3 if ARM64_64K_PAGES && (ARM64_VA_BITS_48 || HAS_VA_BITS_52)
 	default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39
 	default 3 if ARM64_16K_PAGES && ARM64_VA_BITS_47
 	default 4 if !ARM64_64K_PAGES && ARM64_VA_BITS_48
@@ -294,12 +297,12 @@ config ARCH_PROC_KCORE_TEXT
 config KASAN_SHADOW_OFFSET
 	hex
 	depends on KASAN
-	default 0xdfffa00000000000 if (ARM64_VA_BITS_48 || ARM64_USER_VA_BITS_52) && !KASAN_SW_TAGS
+	default 0xdfffa00000000000 if (ARM64_VA_BITS_48 || HAS_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_USER_VA_BITS_52) && KASAN_SW_TAGS
+	default 0xefff900000000000 if (ARM64_VA_BITS_48 || HAS_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
@@ -721,6 +724,7 @@ config ARM64_VA_BITS_48
 config ARM64_USER_VA_BITS_52
 	bool "52-bit (user)"
 	depends on ARM64_64K_PAGES && (ARM64_PAN || !ARM64_SW_TTBR0_PAN)
+	select HAS_VA_BITS_52
 	help
 	  Enable 52-bit virtual addressing for userspace when explicitly
 	  requested via a hint to mmap(). The kernel will continue to
@@ -733,11 +737,28 @@ config ARM64_USER_VA_BITS_52
 
 	  If unsure, select 48-bit virtual addressing instead.
 
+config ARM64_USER_KERNEL_VA_BITS_52
+	bool "52-bit (user & kernel)"
+	depends on ARM64_64K_PAGES && (ARM64_PAN || !ARM64_SW_TTBR0_PAN)
+	select HAS_VA_BITS_52
+	help
+	  Enable 52-bit virtual addressing for userspace when explicitly
+	  requested via a hint to mmap(). The kernel will also use 52-bit
+	  virtual addresses for its own mappings (provided HW support for
+	  this feature is available, otherwise it reverts to 48-bit).
+
+	  NOTE: Enabling 52-bit virtual addressing in conjunction with
+	  ARMv8.3 Pointer Authentication will result in the PAC being
+	  reduced from 7 bits to 3 bits, which may have a significant
+	  impact on its susceptibility to brute-force attacks.
+
+	  If unsure, select 48-bit virtual addressing instead.
+
 endchoice
 
 config ARM64_FORCE_52BIT
 	bool "Force 52-bit virtual addresses for userspace"
-	depends on ARM64_USER_VA_BITS_52 && EXPERT
+	depends on HAS_VA_BITS_52 && EXPERT
 	help
 	  For systems with 52-bit userspace VAs enabled, the kernel will attempt
 	  to maintain compatibility with older software by providing 48-bit VAs
@@ -755,9 +776,11 @@ config ARM64_VA_BITS
 	default 42 if ARM64_VA_BITS_42
 	default 47 if ARM64_VA_BITS_47
 	default 48 if ARM64_VA_BITS_48 || ARM64_USER_VA_BITS_52
+	default 52 if ARM64_USER_KERNEL_VA_BITS_52
 
 config ARM64_VA_BITS_MIN
 	int
+	default 48 if ARM64_USER_KERNEL_VA_BITS_52
 	default ARM64_VA_BITS
 
 choice
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 58ed5d086e1e..c7c3ca2d70f8 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -363,6 +363,13 @@ alternative_endif
 	bfi	\valreg, \t0sz, #TCR_T0SZ_OFFSET, #TCR_TxSZ_WIDTH
 	.endm
 
+/*
+ * tcr_set_t1sz - update TCR.T1SZ
+ */
+	.macro	tcr_set_t1sz, valreg, t1sz
+	bfi	\valreg, \t1sz, #TCR_T1SZ_OFFSET, #TCR_TxSZ_WIDTH
+	.endm
+
 /*
  * tcr_compute_pa_size - set TCR.(I)PS to the highest supported
  * ID_AA64MMFR0_EL1.PARange value
@@ -568,7 +575,7 @@ alternative_endif
  * to be nop'ed out when dealing with 52-bit kernel VAs.
  */
 	.macro	restore_ttbr1, ttbr
-#if defined(CONFIG_ARM64_USER_VA_BITS_52) || defined(CONFIG_ARM64_KERNEL_VA_BITS_52)
+#ifdef CONFIG_HAS_VA_BITS_52
 	bic	\ttbr, \ttbr, #TTBR1_BADDR_4852_OFFSET
 #endif
 	.endm
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index a51056a157dd..f17777f4272c 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -67,7 +67,7 @@
 #define KERNEL_START      _text
 #define KERNEL_END        _end
 
-#ifdef CONFIG_ARM64_USER_VA_BITS_52
+#ifdef CONFIG_HAS_VA_BITS_52
 #define MAX_USER_VA_BITS	52
 #else
 #define MAX_USER_VA_BITS	VA_BITS
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index 133ecb65b602..1ae26b357e1e 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -74,7 +74,7 @@ extern u64 idmap_ptrs_per_pgd;
 
 static inline bool __cpu_uses_extended_idmap(void)
 {
-	if (IS_ENABLED(CONFIG_ARM64_USER_VA_BITS_52))
+	if (IS_ENABLED(CONFIG_HAS_VA_BITS_52))
 		return false;
 
 	return unlikely(idmap_t0sz != TCR_T0SZ(VA_BITS));
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index e9b0a7d75184..15379996ffe2 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -315,7 +315,7 @@
 #define TTBR_BADDR_MASK_52	(((UL(1) << 46) - 1) << 2)
 #endif
 
-#ifdef CONFIG_ARM64_USER_VA_BITS_52
+#ifdef CONFIG_HAS_VA_BITS_52
 /* Must be at least 64-byte aligned to prevent corruption of the TTBR */
 #define TTBR1_BADDR_4852_OFFSET	(((UL(1) << (52 - PGDIR_SHIFT)) - \
 				 (UL(1) << (48 - PGDIR_SHIFT))) * 8)
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 4877b82d2091..c486e66a9ba6 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -319,7 +319,7 @@ __create_page_tables:
 	adrp	x0, idmap_pg_dir
 	adrp	x3, __idmap_text_start		// __pa(__idmap_text_start)
 
-#ifdef CONFIG_ARM64_USER_VA_BITS_52
+#ifdef CONFIG_HAS_VA_BITS_52
 	mrs_s	x6, SYS_ID_AA64MMFR2_EL1
 	and	x6, x6, #(0xf << ID_AA64MMFR2_LVA_SHIFT)
 	mov	x5, #52
@@ -818,7 +818,7 @@ ENTRY(__enable_mmu)
 ENDPROC(__enable_mmu)
 
 ENTRY(__cpu_secondary_check52bitva)
-#ifdef CONFIG_ARM64_USER_VA_BITS_52
+#ifdef CONFIG_HAS_VA_BITS_52
 	ldr_l	x0, vabits_user
 	cmp	x0, #52
 	b.ne	2f
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 73886a5f1f30..e85500dfe89a 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -457,7 +457,7 @@ ENTRY(__cpu_setup)
 			TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \
 			TCR_TBI0 | TCR_A1 | TCR_KASAN_FLAGS
 
-#ifdef CONFIG_ARM64_USER_VA_BITS_52
+#ifdef CONFIG_HAS_VA_BITS_52
 	ldr_l		x9, vabits_user
 	sub		x9, xzr, x9
 	add		x9, x9, #64
@@ -466,6 +466,10 @@ ENTRY(__cpu_setup)
 #endif
 	tcr_set_t0sz	x10, x9
 
+#ifdef CONFIG_ARM64_USER_KERNEL_VA_BITS_52
+	tcr_set_t1sz	x10, x9
+#endif
+
 	/*
 	 * Set the IPS bits in TCR_EL1.
 	 */
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-02-18 17:02 [PATCH 0/9] 52-bit kernel + user VAs Steve Capper
                   ` (8 preceding siblings ...)
  2019-02-18 17:02 ` [PATCH 9/9] arm64: mm: Introduce 52-bit Kernel VAs Steve Capper
@ 2019-02-19 12:13 ` Ard Biesheuvel
  2019-02-19 12:48   ` Will Deacon
  2019-04-03  8:09 ` Bhupesh Sharma
  10 siblings, 1 reply; 29+ messages in thread
From: Ard Biesheuvel @ 2019-02-19 12:13 UTC (permalink / raw)
  To: Steve Capper
  Cc: Marc Zyngier, Catalin Marinas, crecklin, Will Deacon, linux-arm-kernel

On Mon, 18 Feb 2019 at 18:05, Steve Capper <steve.capper@arm.com> wrote:
>
> This patch series adds support for 52-bit kernel VAs using some of the
> machinery already introduced by the 52-bit userspace VA code in 5.0.
>
> As 52-bit virtual address support is an optional hardware feature,
> software support for 52-bit kernel VAs needs to be deduced at early boot
> time. If HW support is not available, the kernel falls back to 48-bit.
>
> A significant proportion of this series focuses on "de-constifying"
> VA_BITS related constants.
>
> In order to allow for a KASAN shadow that changes size at boot time, one
> must fix the KASAN_SHADOW_END for both 48 & 52-bit VAs and "grow" the
> start address. Also, it is highly desirable to maintain the same
> function addresses in the kernel .text between VA sizes. Both of these
> requirements necessitate us to flip the kernel address space halves s.t.
> the direct linear map occupies the lower addresses.
>
> One obvious omission is 52-bit kernel VA + 48-bit userspace VA which I
> can add with some more #ifdef'ery if needed.
>

Hi Steve,

Apologies if I am bringing up things that have been addressed
internally already. We discussed the 52-bit kernel VA work at
plumber's at some point, and IIUC, KASAN is the complicating factor
when it comes to having compile time constants for VA_BITS_MIN,
VA_BITS_MAX and PAGE_OFFSET, right?

To clarify what I mean, please refer to the diagram below, which
describes a hybrid 48/52 kernel VA arrangement that does not rely on
runtime variable quantities. (VA_BITS_MIN == 48, VA_BITS_MAX == 52)

+------------------- (~0) -------------------------+
|                                                |
|            PCI IO / fixmap spaces              |
|                                                |
+------------------------------------------------+
|                                                |
|             kernel/vmalloc space               |
|                                                |
+------------------------------------------------+
|                                                |
|                module space                    |
|                                                |
+------------------------------------------------+
|                                                |
|                BPF space                       |
|                                                |
+------------------------------------------------+
|                                                |
|                                                |
|   vmemmap space (size based on VA_BITS_MAX)    |
|                                                |
|                                                |
+-- linear/vmalloc split based on VA_BITS_MIN -- +
|                                                |
|    linear mapping (48 bit addressable region)  |
|                                                |
+------------------------------------------------+
|                                                |
|    linear mapping (52 bit addressable region)  |
|                                                |
+------ PAGE_OFFSET based on VA_BITS_MAX --------+

Since KASAN is what is preventing this, would it be acceptable for
KASAN to only be supported when you use a true 48 bit or a true 52 bit
configuration, and disable it for the 48/52 hybrid configuration?

Just thinking out loud (and in ASCII art :-))

-- 
Ard.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-02-19 12:13 ` [PATCH 0/9] 52-bit kernel + user VAs Ard Biesheuvel
@ 2019-02-19 12:48   ` Will Deacon
  2019-02-19 12:51     ` Ard Biesheuvel
  0 siblings, 1 reply; 29+ messages in thread
From: Will Deacon @ 2019-02-19 12:48 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Marc Zyngier, Catalin Marinas, crecklin, linux-arm-kernel, Steve Capper

On Tue, Feb 19, 2019 at 01:13:32PM +0100, Ard Biesheuvel wrote:
> On Mon, 18 Feb 2019 at 18:05, Steve Capper <steve.capper@arm.com> wrote:
> >
> > This patch series adds support for 52-bit kernel VAs using some of the
> > machinery already introduced by the 52-bit userspace VA code in 5.0.
> >
> > As 52-bit virtual address support is an optional hardware feature,
> > software support for 52-bit kernel VAs needs to be deduced at early boot
> > time. If HW support is not available, the kernel falls back to 48-bit.
> >
> > A significant proportion of this series focuses on "de-constifying"
> > VA_BITS related constants.
> >
> > In order to allow for a KASAN shadow that changes size at boot time, one
> > must fix the KASAN_SHADOW_END for both 48 & 52-bit VAs and "grow" the
> > start address. Also, it is highly desirable to maintain the same
> > function addresses in the kernel .text between VA sizes. Both of these
> > requirements necessitate us to flip the kernel address space halves s.t.
> > the direct linear map occupies the lower addresses.
> >
> > One obvious omission is 52-bit kernel VA + 48-bit userspace VA which I
> > can add with some more #ifdef'ery if needed.
> >
> 
> Hi Steve,
> 
> Apologies if I am bringing up things that have been addressed
> internally already. We discussed the 52-bit kernel VA work at
> plumber's at some point, and IIUC, KASAN is the complicating factor
> when it comes to having compile time constants for VA_BITS_MIN,
> VA_BITS_MAX and PAGE_OFFSET, right?
> 
> To clarify what I mean, please refer to the diagram below, which
> describes a hybrid 48/52 kernel VA arrangement that does not rely on
> runtime variable quantities. (VA_BITS_MIN == 48, VA_BITS_MAX == 52)
> 
> +------------------- (~0) -------------------------+
> |                                                |
> |            PCI IO / fixmap spaces              |
> |                                                |
> +------------------------------------------------+
> |                                                |
> |             kernel/vmalloc space               |
> |                                                |
> +------------------------------------------------+
> |                                                |
> |                module space                    |
> |                                                |
> +------------------------------------------------+
> |                                                |
> |                BPF space                       |
> |                                                |
> +------------------------------------------------+
> |                                                |
> |                                                |
> |   vmemmap space (size based on VA_BITS_MAX)    |
> |                                                |
> |                                                |
> +-- linear/vmalloc split based on VA_BITS_MIN -- +
> |                                                |
> |    linear mapping (48 bit addressable region)  |
> |                                                |
> +------------------------------------------------+
> |                                                |
> |    linear mapping (52 bit addressable region)  |
> |                                                |
> +------ PAGE_OFFSET based on VA_BITS_MAX --------+
> 
> Since KASAN is what is preventing this, would it be acceptable for
> KASAN to only be supported when you use a true 48 bit or a true 52 bit
> configuration, and disable it for the 48/52 hybrid configuration?
> 
> Just thinking out loud (and in ASCII art :-))

TBH, if we end up having support for 52-bit kernel VA, I'd be inclined to
drop the 48/52 configuration altogether. But Catalin's on holiday at the
moment, and may have a different opinion ;)

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-02-19 12:48   ` Will Deacon
@ 2019-02-19 12:51     ` Ard Biesheuvel
  2019-02-19 13:01       ` Will Deacon
  0 siblings, 1 reply; 29+ messages in thread
From: Ard Biesheuvel @ 2019-02-19 12:51 UTC (permalink / raw)
  To: Will Deacon
  Cc: Marc Zyngier, Catalin Marinas, crecklin, linux-arm-kernel, Steve Capper

On Tue, 19 Feb 2019 at 13:48, Will Deacon <will.deacon@arm.com> wrote:
>
> On Tue, Feb 19, 2019 at 01:13:32PM +0100, Ard Biesheuvel wrote:
> > On Mon, 18 Feb 2019 at 18:05, Steve Capper <steve.capper@arm.com> wrote:
> > >
> > > This patch series adds support for 52-bit kernel VAs using some of the
> > > machinery already introduced by the 52-bit userspace VA code in 5.0.
> > >
> > > As 52-bit virtual address support is an optional hardware feature,
> > > software support for 52-bit kernel VAs needs to be deduced at early boot
> > > time. If HW support is not available, the kernel falls back to 48-bit.
> > >
> > > A significant proportion of this series focuses on "de-constifying"
> > > VA_BITS related constants.
> > >
> > > In order to allow for a KASAN shadow that changes size at boot time, one
> > > must fix the KASAN_SHADOW_END for both 48 & 52-bit VAs and "grow" the
> > > start address. Also, it is highly desirable to maintain the same
> > > function addresses in the kernel .text between VA sizes. Both of these
> > > requirements necessitate us to flip the kernel address space halves s.t.
> > > the direct linear map occupies the lower addresses.
> > >
> > > One obvious omission is 52-bit kernel VA + 48-bit userspace VA which I
> > > can add with some more #ifdef'ery if needed.
> > >
> >
> > Hi Steve,
> >
> > Apologies if I am bringing up things that have been addressed
> > internally already. We discussed the 52-bit kernel VA work at
> > plumber's at some point, and IIUC, KASAN is the complicating factor
> > when it comes to having compile time constants for VA_BITS_MIN,
> > VA_BITS_MAX and PAGE_OFFSET, right?
> >
> > To clarify what I mean, please refer to the diagram below, which
> > describes a hybrid 48/52 kernel VA arrangement that does not rely on
> > runtime variable quantities. (VA_BITS_MIN == 48, VA_BITS_MAX == 52)
> >
> > +------------------- (~0) -------------------------+
> > |                                                |
> > |            PCI IO / fixmap spaces              |
> > |                                                |
> > +------------------------------------------------+
> > |                                                |
> > |             kernel/vmalloc space               |
> > |                                                |
> > +------------------------------------------------+
> > |                                                |
> > |                module space                    |
> > |                                                |
> > +------------------------------------------------+
> > |                                                |
> > |                BPF space                       |
> > |                                                |
> > +------------------------------------------------+
> > |                                                |
> > |                                                |
> > |   vmemmap space (size based on VA_BITS_MAX)    |
> > |                                                |
> > |                                                |
> > +-- linear/vmalloc split based on VA_BITS_MIN -- +
> > |                                                |
> > |    linear mapping (48 bit addressable region)  |
> > |                                                |
> > +------------------------------------------------+
> > |                                                |
> > |    linear mapping (52 bit addressable region)  |
> > |                                                |
> > +------ PAGE_OFFSET based on VA_BITS_MAX --------+
> >
> > Since KASAN is what is preventing this, would it be acceptable for
> > KASAN to only be supported when you use a true 48 bit or a true 52 bit
> > configuration, and disable it for the 48/52 hybrid configuration?
> >
> > Just thinking out loud (and in ASCII art :-))
>
> TBH, if we end up having support for 52-bit kernel VA, I'd be inclined to
> drop the 48/52 configuration altogether. But Catalin's on holiday at the
> moment, and may have a different opinion ;)
>

But that implies that you cannot have an image that supports 52-bit
kernel VAs but can still boot on hardware that does not implement
support for it. If that is acceptable, then none of this hoop jumping
that Steve is doing in these patches is necessary to begin with,
right?

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-02-19 12:51     ` Ard Biesheuvel
@ 2019-02-19 13:01       ` Will Deacon
  2019-02-19 13:15         ` Ard Biesheuvel
  0 siblings, 1 reply; 29+ messages in thread
From: Will Deacon @ 2019-02-19 13:01 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Marc Zyngier, Catalin Marinas, crecklin, linux-arm-kernel, Steve Capper

On Tue, Feb 19, 2019 at 01:51:51PM +0100, Ard Biesheuvel wrote:
> On Tue, 19 Feb 2019 at 13:48, Will Deacon <will.deacon@arm.com> wrote:
> >
> > On Tue, Feb 19, 2019 at 01:13:32PM +0100, Ard Biesheuvel wrote:
> > > On Mon, 18 Feb 2019 at 18:05, Steve Capper <steve.capper@arm.com> wrote:
> > > >
> > > > This patch series adds support for 52-bit kernel VAs using some of the
> > > > machinery already introduced by the 52-bit userspace VA code in 5.0.
> > > >
> > > > As 52-bit virtual address support is an optional hardware feature,
> > > > software support for 52-bit kernel VAs needs to be deduced at early boot
> > > > time. If HW support is not available, the kernel falls back to 48-bit.
> > > >
> > > > A significant proportion of this series focuses on "de-constifying"
> > > > VA_BITS related constants.
> > > >
> > > > In order to allow for a KASAN shadow that changes size at boot time, one
> > > > must fix the KASAN_SHADOW_END for both 48 & 52-bit VAs and "grow" the
> > > > start address. Also, it is highly desirable to maintain the same
> > > > function addresses in the kernel .text between VA sizes. Both of these
> > > > requirements necessitate us to flip the kernel address space halves s.t.
> > > > the direct linear map occupies the lower addresses.
> > > >
> > > > One obvious omission is 52-bit kernel VA + 48-bit userspace VA which I
> > > > can add with some more #ifdef'ery if needed.
> > > >
> > >
> > > Hi Steve,
> > >
> > > Apologies if I am bringing up things that have been addressed
> > > internally already. We discussed the 52-bit kernel VA work at
> > > plumber's at some point, and IIUC, KASAN is the complicating factor
> > > when it comes to having compile time constants for VA_BITS_MIN,
> > > VA_BITS_MAX and PAGE_OFFSET, right?
> > >
> > > To clarify what I mean, please refer to the diagram below, which
> > > describes a hybrid 48/52 kernel VA arrangement that does not rely on
> > > runtime variable quantities. (VA_BITS_MIN == 48, VA_BITS_MAX == 52)
> > >
> > > +------------------- (~0) -------------------------+
> > > |                                                |
> > > |            PCI IO / fixmap spaces              |
> > > |                                                |
> > > +------------------------------------------------+
> > > |                                                |
> > > |             kernel/vmalloc space               |
> > > |                                                |
> > > +------------------------------------------------+
> > > |                                                |
> > > |                module space                    |
> > > |                                                |
> > > +------------------------------------------------+
> > > |                                                |
> > > |                BPF space                       |
> > > |                                                |
> > > +------------------------------------------------+
> > > |                                                |
> > > |                                                |
> > > |   vmemmap space (size based on VA_BITS_MAX)    |
> > > |                                                |
> > > |                                                |
> > > +-- linear/vmalloc split based on VA_BITS_MIN -- +
> > > |                                                |
> > > |    linear mapping (48 bit addressable region)  |
> > > |                                                |
> > > +------------------------------------------------+
> > > |                                                |
> > > |    linear mapping (52 bit addressable region)  |
> > > |                                                |
> > > +------ PAGE_OFFSET based on VA_BITS_MAX --------+
> > >
> > > Since KASAN is what is preventing this, would it be acceptable for
> > > KASAN to only be supported when you use a true 48 bit or a true 52 bit
> > > configuration, and disable it for the 48/52 hybrid configuration?
> > >
> > > Just thinking out loud (and in ASCII art :-))
> >
> > TBH, if we end up having support for 52-bit kernel VA, I'd be inclined to
> > drop the 48/52 configuration altogether. But Catalin's on holiday at the
> > moment, and may have a different opinion ;)
> >
> 
> But that implies that you cannot have an image that supports 52-bit
> kernel VAs but can still boot on hardware that does not implement
> support for it. If that is acceptable, then none of this hoop jumping
> that Steve is doing in these patches is necessary to begin with,
> right?

Sorry, I misunderstood what you meant by a "48/52 hybrid configuration". I
thought you were referring to the configuration where userspace is 52-bit
and the kernel is 48-bit, which is something I think we can drop if we gain
support for 52-bit kernel.

Now that I understand what you mean, I think disabling KASAN would be fine
as long as it's a runtime thing and the kernel continues to work in every
other respect.

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-02-19 13:01       ` Will Deacon
@ 2019-02-19 13:15         ` Ard Biesheuvel
  2019-02-19 13:56           ` Steve Capper
  0 siblings, 1 reply; 29+ messages in thread
From: Ard Biesheuvel @ 2019-02-19 13:15 UTC (permalink / raw)
  To: Will Deacon
  Cc: Marc Zyngier, Catalin Marinas, crecklin, linux-arm-kernel, Steve Capper

On Tue, 19 Feb 2019 at 14:01, Will Deacon <will.deacon@arm.com> wrote:
>
> On Tue, Feb 19, 2019 at 01:51:51PM +0100, Ard Biesheuvel wrote:
> > On Tue, 19 Feb 2019 at 13:48, Will Deacon <will.deacon@arm.com> wrote:
> > >
> > > On Tue, Feb 19, 2019 at 01:13:32PM +0100, Ard Biesheuvel wrote:
> > > > On Mon, 18 Feb 2019 at 18:05, Steve Capper <steve.capper@arm.com> wrote:
> > > > >
> > > > > This patch series adds support for 52-bit kernel VAs using some of the
> > > > > machinery already introduced by the 52-bit userspace VA code in 5.0.
> > > > >
> > > > > As 52-bit virtual address support is an optional hardware feature,
> > > > > software support for 52-bit kernel VAs needs to be deduced at early boot
> > > > > time. If HW support is not available, the kernel falls back to 48-bit.
> > > > >
> > > > > A significant proportion of this series focuses on "de-constifying"
> > > > > VA_BITS related constants.
> > > > >
> > > > > In order to allow for a KASAN shadow that changes size at boot time, one
> > > > > must fix the KASAN_SHADOW_END for both 48 & 52-bit VAs and "grow" the
> > > > > start address. Also, it is highly desirable to maintain the same
> > > > > function addresses in the kernel .text between VA sizes. Both of these
> > > > > requirements necessitate us to flip the kernel address space halves s.t.
> > > > > the direct linear map occupies the lower addresses.
> > > > >
> > > > > One obvious omission is 52-bit kernel VA + 48-bit userspace VA which I
> > > > > can add with some more #ifdef'ery if needed.
> > > > >
> > > >
> > > > Hi Steve,
> > > >
> > > > Apologies if I am bringing up things that have been addressed
> > > > internally already. We discussed the 52-bit kernel VA work at
> > > > plumber's at some point, and IIUC, KASAN is the complicating factor
> > > > when it comes to having compile time constants for VA_BITS_MIN,
> > > > VA_BITS_MAX and PAGE_OFFSET, right?
> > > >
> > > > To clarify what I mean, please refer to the diagram below, which
> > > > describes a hybrid 48/52 kernel VA arrangement that does not rely on
> > > > runtime variable quantities. (VA_BITS_MIN == 48, VA_BITS_MAX == 52)
> > > >
> > > > +------------------- (~0) -------------------------+
> > > > |                                                |
> > > > |            PCI IO / fixmap spaces              |
> > > > |                                                |
> > > > +------------------------------------------------+
> > > > |                                                |
> > > > |             kernel/vmalloc space               |
> > > > |                                                |
> > > > +------------------------------------------------+
> > > > |                                                |
> > > > |                module space                    |
> > > > |                                                |
> > > > +------------------------------------------------+
> > > > |                                                |
> > > > |                BPF space                       |
> > > > |                                                |
> > > > +------------------------------------------------+
> > > > |                                                |
> > > > |                                                |
> > > > |   vmemmap space (size based on VA_BITS_MAX)    |
> > > > |                                                |
> > > > |                                                |
> > > > +-- linear/vmalloc split based on VA_BITS_MIN -- +
> > > > |                                                |
> > > > |    linear mapping (48 bit addressable region)  |
> > > > |                                                |
> > > > +------------------------------------------------+
> > > > |                                                |
> > > > |    linear mapping (52 bit addressable region)  |
> > > > |                                                |
> > > > +------ PAGE_OFFSET based on VA_BITS_MAX --------+
> > > >
> > > > Since KASAN is what is preventing this, would it be acceptable for
> > > > KASAN to only be supported when you use a true 48 bit or a true 52 bit
> > > > configuration, and disable it for the 48/52 hybrid configuration?
> > > >
> > > > Just thinking out loud (and in ASCII art :-))
> > >
> > > TBH, if we end up having support for 52-bit kernel VA, I'd be inclined to
> > > drop the 48/52 configuration altogether. But Catalin's on holiday at the
> > > moment, and may have a different opinion ;)
> > >
> >
> > But that implies that you cannot have an image that supports 52-bit
> > kernel VAs but can still boot on hardware that does not implement
> > support for it. If that is acceptable, then none of this hoop jumping
> > that Steve is doing in these patches is necessary to begin with,
> > right?
>
> Sorry, I misunderstood what you meant by a "48/52 hybrid configuration". I
> thought you were referring to the configuration where userspace is 52-bit
> and the kernel is 48-bit, which is something I think we can drop if we gain
> support for 52-bit kernel.
>
> Now that I understand what you mean, I think disabling KASAN would be fine
> as long as it's a runtime thing and the kernel continues to work in every
> other respect.
>

No, it would be a limitation of the 52-bit config which also supports
48-bit-VA-only-h/w that the address space is laid out in such a way
that there is simply no room for the KASAN shadow region, since it
would have to live in the 48-bit addressable area, but be big enough
to cover 52 bits of VA, which is impossible.

For the vmemmap space, we could live with sizing it statically to
cover a 52-bit VA linear region, but the KASAN shadow region is simply
too big.

So if KASAN support in that configuration is a requirement, then I
agree with Steve's approach, but it does imply that quite a number of
formerly compile-time constants now get turned into runtime variables.

Steve, do you have any idea what the impact of that is?

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-02-19 13:15         ` Ard Biesheuvel
@ 2019-02-19 13:56           ` Steve Capper
  2019-02-19 16:18             ` Ard Biesheuvel
  0 siblings, 1 reply; 29+ messages in thread
From: Steve Capper @ 2019-02-19 13:56 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: crecklin, Marc Zyngier, Catalin Marinas, Will Deacon, nd,
	linux-arm-kernel

On Tue, Feb 19, 2019 at 02:15:26PM +0100, Ard Biesheuvel wrote:
> On Tue, 19 Feb 2019 at 14:01, Will Deacon <will.deacon@arm.com> wrote:
> >
> > On Tue, Feb 19, 2019 at 01:51:51PM +0100, Ard Biesheuvel wrote:
> > > On Tue, 19 Feb 2019 at 13:48, Will Deacon <will.deacon@arm.com> wrote:
> > > >
> > > > On Tue, Feb 19, 2019 at 01:13:32PM +0100, Ard Biesheuvel wrote:
> > > > > On Mon, 18 Feb 2019 at 18:05, Steve Capper <steve.capper@arm.com> wrote:
> > > > > >
> > > > > > This patch series adds support for 52-bit kernel VAs using some of the
> > > > > > machinery already introduced by the 52-bit userspace VA code in 5.0.
> > > > > >
> > > > > > As 52-bit virtual address support is an optional hardware feature,
> > > > > > software support for 52-bit kernel VAs needs to be deduced at early boot
> > > > > > time. If HW support is not available, the kernel falls back to 48-bit.
> > > > > >
> > > > > > A significant proportion of this series focuses on "de-constifying"
> > > > > > VA_BITS related constants.
> > > > > >
> > > > > > In order to allow for a KASAN shadow that changes size at boot time, one
> > > > > > must fix the KASAN_SHADOW_END for both 48 & 52-bit VAs and "grow" the
> > > > > > start address. Also, it is highly desirable to maintain the same
> > > > > > function addresses in the kernel .text between VA sizes. Both of these
> > > > > > requirements necessitate us to flip the kernel address space halves s.t.
> > > > > > the direct linear map occupies the lower addresses.
> > > > > >
> > > > > > One obvious omission is 52-bit kernel VA + 48-bit userspace VA which I
> > > > > > can add with some more #ifdef'ery if needed.
> > > > > >
> > > > >
> > > > > Hi Steve,
> > > > >
> > > > > Apologies if I am bringing up things that have been addressed
> > > > > internally already. We discussed the 52-bit kernel VA work at
> > > > > plumber's at some point, and IIUC, KASAN is the complicating factor
> > > > > when it comes to having compile time constants for VA_BITS_MIN,
> > > > > VA_BITS_MAX and PAGE_OFFSET, right?
> > > > >
> > > > > To clarify what I mean, please refer to the diagram below, which
> > > > > describes a hybrid 48/52 kernel VA arrangement that does not rely on
> > > > > runtime variable quantities. (VA_BITS_MIN == 48, VA_BITS_MAX == 52)
> > > > >
> > > > > +------------------- (~0) -------------------------+
> > > > > |                                                |
> > > > > |            PCI IO / fixmap spaces              |
> > > > > |                                                |
> > > > > +------------------------------------------------+
> > > > > |                                                |
> > > > > |             kernel/vmalloc space               |
> > > > > |                                                |
> > > > > +------------------------------------------------+
> > > > > |                                                |
> > > > > |                module space                    |
> > > > > |                                                |
> > > > > +------------------------------------------------+
> > > > > |                                                |
> > > > > |                BPF space                       |
> > > > > |                                                |
> > > > > +------------------------------------------------+
> > > > > |                                                |
> > > > > |                                                |
> > > > > |   vmemmap space (size based on VA_BITS_MAX)    |
> > > > > |                                                |
> > > > > |                                                |
> > > > > +-- linear/vmalloc split based on VA_BITS_MIN -- +
> > > > > |                                                |
> > > > > |    linear mapping (48 bit addressable region)  |
> > > > > |                                                |
> > > > > +------------------------------------------------+
> > > > > |                                                |
> > > > > |    linear mapping (52 bit addressable region)  |
> > > > > |                                                |
> > > > > +------ PAGE_OFFSET based on VA_BITS_MAX --------+
> > > > >
> > > > > Since KASAN is what is preventing this, would it be acceptable for
> > > > > KASAN to only be supported when you use a true 48 bit or a true 52 bit
> > > > > configuration, and disable it for the 48/52 hybrid configuration?
> > > > >
> > > > > Just thinking out loud (and in ASCII art :-))
> > > >
> > > > TBH, if we end up having support for 52-bit kernel VA, I'd be inclined to
> > > > drop the 48/52 configuration altogether. But Catalin's on holiday at the
> > > > moment, and may have a different opinion ;)
> > > >
> > >
> > > But that implies that you cannot have an image that supports 52-bit
> > > kernel VAs but can still boot on hardware that does not implement
> > > support for it. If that is acceptable, then none of this hoop jumping
> > > that Steve is doing in these patches is necessary to begin with,
> > > right?
> >
> > Sorry, I misunderstood what you meant by a "48/52 hybrid configuration". I
> > thought you were referring to the configuration where userspace is 52-bit
> > and the kernel is 48-bit, which is something I think we can drop if we gain
> > support for 52-bit kernel.
> >
> > Now that I understand what you mean, I think disabling KASAN would be fine
> > as long as it's a runtime thing and the kernel continues to work in every
> > other respect.
> >
> 
> No, it would be a limitation of the 52-bit config which also supports
> 48-bit-VA-only-h/w that the address space is laid out in such a way
> that there is simply no room for the KASAN shadow region, since it
> would have to live in the 48-bit addressable area, but be big enough
> to cover 52 bits of VA, which is impossible.
> 
> For the vmemmap space, we could live with sizing it statically to
> cover a 52-bit VA linear region, but the KASAN shadow region is simply
> too big.
> 
> So if KASAN support in that configuration is a requirement, then I
> agree with Steve's approach, but it does imply that quite a number of
> formerly compile-time constants now get turned into runtime variables.
> 
> Steve, do you have any idea what the impact of that is?

Hi Guys,

The KASAN region only really necessitates two things: 1) that we think
about the end address of the region (which is invariant) rather than the
start address; and that 2) we flip the kernel VA space. IIUC both these
changes have a neglible perf impact.

As for VA_BITS_ACTUAL, we need this in a few places: KVM mapping
support, and the big one phys_to/from_virt. For phys_to/from_virt the
logic is changed s.t. we use a variable lookup for translation but this
is folded into a new variable physvirt_offset (before the patch we used
a single variable read too).

Again IIUC there should be a minimal perf impact (unless one tries to do
cat /sys/kernel/debug/kernel_page_tables with KASAN enabled - but that
can be optimised later).

I didn't have the patience for ASCII art ;-), but I have a picture of
what I think it looks like here:
https://s3.amazonaws.com/connect.linaro.org/yvr18/presentations/yvr18-119.pdf
What I've tried to do is have most parts of the kernel VA space
invariant between 48/52 bits. If it's helpful I can type this up into a
document/commit log message?

For this series I have tried to introduce VA_BITS_MIN in its own patch
and also VA_BITS_ACTUAL into its own patch to make it easier to follow.

If I've overlooked something, please let me know.

Cheers,
-- 
Steve

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-02-19 13:56           ` Steve Capper
@ 2019-02-19 16:18             ` Ard Biesheuvel
  2019-02-26 17:30               ` Steve Capper
  0 siblings, 1 reply; 29+ messages in thread
From: Ard Biesheuvel @ 2019-02-19 16:18 UTC (permalink / raw)
  To: Steve Capper
  Cc: crecklin, Marc Zyngier, Catalin Marinas, Will Deacon, nd,
	linux-arm-kernel

On Tue, 19 Feb 2019 at 14:56, Steve Capper <Steve.Capper@arm.com> wrote:
>
> On Tue, Feb 19, 2019 at 02:15:26PM +0100, Ard Biesheuvel wrote:
> > On Tue, 19 Feb 2019 at 14:01, Will Deacon <will.deacon@arm.com> wrote:
> > >
> > > On Tue, Feb 19, 2019 at 01:51:51PM +0100, Ard Biesheuvel wrote:
> > > > On Tue, 19 Feb 2019 at 13:48, Will Deacon <will.deacon@arm.com> wrote:
> > > > >
> > > > > On Tue, Feb 19, 2019 at 01:13:32PM +0100, Ard Biesheuvel wrote:
> > > > > > On Mon, 18 Feb 2019 at 18:05, Steve Capper <steve.capper@arm.com> wrote:
> > > > > > >
> > > > > > > This patch series adds support for 52-bit kernel VAs using some of the
> > > > > > > machinery already introduced by the 52-bit userspace VA code in 5.0.
> > > > > > >
> > > > > > > As 52-bit virtual address support is an optional hardware feature,
> > > > > > > software support for 52-bit kernel VAs needs to be deduced at early boot
> > > > > > > time. If HW support is not available, the kernel falls back to 48-bit.
> > > > > > >
> > > > > > > A significant proportion of this series focuses on "de-constifying"
> > > > > > > VA_BITS related constants.
> > > > > > >
> > > > > > > In order to allow for a KASAN shadow that changes size at boot time, one
> > > > > > > must fix the KASAN_SHADOW_END for both 48 & 52-bit VAs and "grow" the
> > > > > > > start address. Also, it is highly desirable to maintain the same
> > > > > > > function addresses in the kernel .text between VA sizes. Both of these
> > > > > > > requirements necessitate us to flip the kernel address space halves s.t.
> > > > > > > the direct linear map occupies the lower addresses.
> > > > > > >
> > > > > > > One obvious omission is 52-bit kernel VA + 48-bit userspace VA which I
> > > > > > > can add with some more #ifdef'ery if needed.
> > > > > > >
> > > > > >
> > > > > > Hi Steve,
> > > > > >
> > > > > > Apologies if I am bringing up things that have been addressed
> > > > > > internally already. We discussed the 52-bit kernel VA work at
> > > > > > plumber's at some point, and IIUC, KASAN is the complicating factor
> > > > > > when it comes to having compile time constants for VA_BITS_MIN,
> > > > > > VA_BITS_MAX and PAGE_OFFSET, right?
> > > > > >
> > > > > > To clarify what I mean, please refer to the diagram below, which
> > > > > > describes a hybrid 48/52 kernel VA arrangement that does not rely on
> > > > > > runtime variable quantities. (VA_BITS_MIN == 48, VA_BITS_MAX == 52)
> > > > > >
> > > > > > +------------------- (~0) -------------------------+
> > > > > > |                                                |
> > > > > > |            PCI IO / fixmap spaces              |
> > > > > > |                                                |
> > > > > > +------------------------------------------------+
> > > > > > |                                                |
> > > > > > |             kernel/vmalloc space               |
> > > > > > |                                                |
> > > > > > +------------------------------------------------+
> > > > > > |                                                |
> > > > > > |                module space                    |
> > > > > > |                                                |
> > > > > > +------------------------------------------------+
> > > > > > |                                                |
> > > > > > |                BPF space                       |
> > > > > > |                                                |
> > > > > > +------------------------------------------------+
> > > > > > |                                                |
> > > > > > |                                                |
> > > > > > |   vmemmap space (size based on VA_BITS_MAX)    |
> > > > > > |                                                |
> > > > > > |                                                |
> > > > > > +-- linear/vmalloc split based on VA_BITS_MIN -- +
> > > > > > |                                                |
> > > > > > |    linear mapping (48 bit addressable region)  |
> > > > > > |                                                |
> > > > > > +------------------------------------------------+
> > > > > > |                                                |
> > > > > > |    linear mapping (52 bit addressable region)  |
> > > > > > |                                                |
> > > > > > +------ PAGE_OFFSET based on VA_BITS_MAX --------+
> > > > > >
> > > > > > Since KASAN is what is preventing this, would it be acceptable for
> > > > > > KASAN to only be supported when you use a true 48 bit or a true 52 bit
> > > > > > configuration, and disable it for the 48/52 hybrid configuration?
> > > > > >
> > > > > > Just thinking out loud (and in ASCII art :-))
> > > > >
> > > > > TBH, if we end up having support for 52-bit kernel VA, I'd be inclined to
> > > > > drop the 48/52 configuration altogether. But Catalin's on holiday at the
> > > > > moment, and may have a different opinion ;)
> > > > >
> > > >
> > > > But that implies that you cannot have an image that supports 52-bit
> > > > kernel VAs but can still boot on hardware that does not implement
> > > > support for it. If that is acceptable, then none of this hoop jumping
> > > > that Steve is doing in these patches is necessary to begin with,
> > > > right?
> > >
> > > Sorry, I misunderstood what you meant by a "48/52 hybrid configuration". I
> > > thought you were referring to the configuration where userspace is 52-bit
> > > and the kernel is 48-bit, which is something I think we can drop if we gain
> > > support for 52-bit kernel.
> > >
> > > Now that I understand what you mean, I think disabling KASAN would be fine
> > > as long as it's a runtime thing and the kernel continues to work in every
> > > other respect.
> > >
> >
> > No, it would be a limitation of the 52-bit config which also supports
> > 48-bit-VA-only-h/w that the address space is laid out in such a way
> > that there is simply no room for the KASAN shadow region, since it
> > would have to live in the 48-bit addressable area, but be big enough
> > to cover 52 bits of VA, which is impossible.
> >
> > For the vmemmap space, we could live with sizing it statically to
> > cover a 52-bit VA linear region, but the KASAN shadow region is simply
> > too big.
> >
> > So if KASAN support in that configuration is a requirement, then I
> > agree with Steve's approach, but it does imply that quite a number of
> > formerly compile-time constants now get turned into runtime variables.
> >
> > Steve, do you have any idea what the impact of that is?
>
> Hi Guys,
>
> The KASAN region only really necessitates two things: 1) that we think
> about the end address of the region (which is invariant) rather than the
> start address; and that 2) we flip the kernel VA space. IIUC both these
> changes have a neglible perf impact.
>
> As for VA_BITS_ACTUAL, we need this in a few places: KVM mapping
> support, and the big one phys_to/from_virt. For phys_to/from_virt the
> logic is changed s.t. we use a variable lookup for translation but this
> is folded into a new variable physvirt_offset (before the patch we used
> a single variable read too).
>
> Again IIUC there should be a minimal perf impact (unless one tries to do
> cat /sys/kernel/debug/kernel_page_tables with KASAN enabled - but that
> can be optimised later).
>
> I didn't have the patience for ASCII art ;-), but I have a picture of
> what I think it looks like here:
> https://s3.amazonaws.com/connect.linaro.org/yvr18/presentations/yvr18-119.pdf
> What I've tried to do is have most parts of the kernel VA space
> invariant between 48/52 bits. If it's helpful I can type this up into a
> document/commit log message?
>
> For this series I have tried to introduce VA_BITS_MIN in its own patch
> and also VA_BITS_ACTUAL into its own patch to make it easier to follow.
>

OK, perhaps I am just rephrasing what you essentially implemented
already, but let me try to explain a bit better what I mean:

- we flip the VA space in the way you suggest
- we limit the size of the top half of the address space to 47 bits
- KASAN region growns downwards from (~0) << 47
- we define PAGE_OFFSET as (~0) << 52, regardless of whether the h/w
supports LVA or not
- however, we tweak the phys/virt translation so that memory appears
in the 48-bit addressable part of the linear region on non-LVA
hardware

The latter basically means that the KASAN shadow region will intersect
the linear region, but whether we map memory or shadow pages there
depends on the h/w config at runtime.

The heart of the matter is probably the different placement of the
memory inside the linear region, depending on whether the h/w is LVA
capable or not, which is also reflected in your physvirt_offset. I am
just trying to figure out why we need VA_BITS_ACTUAL to be a runtime
variable.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-02-19 16:18             ` Ard Biesheuvel
@ 2019-02-26 17:30               ` Steve Capper
  2019-02-26 20:17                 ` Ard Biesheuvel
  0 siblings, 1 reply; 29+ messages in thread
From: Steve Capper @ 2019-02-26 17:30 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: crecklin, Marc Zyngier, Catalin Marinas, Will Deacon, nd,
	linux-arm-kernel

On Tue, Feb 19, 2019 at 05:18:18PM +0100, Ard Biesheuvel wrote:
> On Tue, 19 Feb 2019 at 14:56, Steve Capper <Steve.Capper@arm.com> wrote:
> >
> > On Tue, Feb 19, 2019 at 02:15:26PM +0100, Ard Biesheuvel wrote:
> > > On Tue, 19 Feb 2019 at 14:01, Will Deacon <will.deacon@arm.com> wrote:
> > > >
> > > > On Tue, Feb 19, 2019 at 01:51:51PM +0100, Ard Biesheuvel wrote:
> > > > > On Tue, 19 Feb 2019 at 13:48, Will Deacon <will.deacon@arm.com> wrote:
> > > > > >
> > > > > > On Tue, Feb 19, 2019 at 01:13:32PM +0100, Ard Biesheuvel wrote:
> > > > > > > On Mon, 18 Feb 2019 at 18:05, Steve Capper <steve.capper@arm.com> wrote:
> > > > > > > >
> > > > > > > > This patch series adds support for 52-bit kernel VAs using some of the
> > > > > > > > machinery already introduced by the 52-bit userspace VA code in 5.0.
> > > > > > > >
> > > > > > > > As 52-bit virtual address support is an optional hardware feature,
> > > > > > > > software support for 52-bit kernel VAs needs to be deduced at early boot
> > > > > > > > time. If HW support is not available, the kernel falls back to 48-bit.
> > > > > > > >
> > > > > > > > A significant proportion of this series focuses on "de-constifying"
> > > > > > > > VA_BITS related constants.
> > > > > > > >
> > > > > > > > In order to allow for a KASAN shadow that changes size at boot time, one
> > > > > > > > must fix the KASAN_SHADOW_END for both 48 & 52-bit VAs and "grow" the
> > > > > > > > start address. Also, it is highly desirable to maintain the same
> > > > > > > > function addresses in the kernel .text between VA sizes. Both of these
> > > > > > > > requirements necessitate us to flip the kernel address space halves s.t.
> > > > > > > > the direct linear map occupies the lower addresses.
> > > > > > > >
> > > > > > > > One obvious omission is 52-bit kernel VA + 48-bit userspace VA which I
> > > > > > > > can add with some more #ifdef'ery if needed.
> > > > > > > >
> > > > > > >
> > > > > > > Hi Steve,
> > > > > > >
> > > > > > > Apologies if I am bringing up things that have been addressed
> > > > > > > internally already. We discussed the 52-bit kernel VA work at
> > > > > > > plumber's at some point, and IIUC, KASAN is the complicating factor
> > > > > > > when it comes to having compile time constants for VA_BITS_MIN,
> > > > > > > VA_BITS_MAX and PAGE_OFFSET, right?
> > > > > > >
> > > > > > > To clarify what I mean, please refer to the diagram below, which
> > > > > > > describes a hybrid 48/52 kernel VA arrangement that does not rely on
> > > > > > > runtime variable quantities. (VA_BITS_MIN == 48, VA_BITS_MAX == 52)
> > > > > > >
> > > > > > > +------------------- (~0) -------------------------+
> > > > > > > |                                                |
> > > > > > > |            PCI IO / fixmap spaces              |
> > > > > > > |                                                |
> > > > > > > +------------------------------------------------+
> > > > > > > |                                                |
> > > > > > > |             kernel/vmalloc space               |
> > > > > > > |                                                |
> > > > > > > +------------------------------------------------+
> > > > > > > |                                                |
> > > > > > > |                module space                    |
> > > > > > > |                                                |
> > > > > > > +------------------------------------------------+
> > > > > > > |                                                |
> > > > > > > |                BPF space                       |
> > > > > > > |                                                |
> > > > > > > +------------------------------------------------+
> > > > > > > |                                                |
> > > > > > > |                                                |
> > > > > > > |   vmemmap space (size based on VA_BITS_MAX)    |
> > > > > > > |                                                |
> > > > > > > |                                                |
> > > > > > > +-- linear/vmalloc split based on VA_BITS_MIN -- +
> > > > > > > |                                                |
> > > > > > > |    linear mapping (48 bit addressable region)  |
> > > > > > > |                                                |
> > > > > > > +------------------------------------------------+
> > > > > > > |                                                |
> > > > > > > |    linear mapping (52 bit addressable region)  |
> > > > > > > |                                                |
> > > > > > > +------ PAGE_OFFSET based on VA_BITS_MAX --------+
> > > > > > >
> > > > > > > Since KASAN is what is preventing this, would it be acceptable for
> > > > > > > KASAN to only be supported when you use a true 48 bit or a true 52 bit
> > > > > > > configuration, and disable it for the 48/52 hybrid configuration?
> > > > > > >
> > > > > > > Just thinking out loud (and in ASCII art :-))
> > > > > >
> > > > > > TBH, if we end up having support for 52-bit kernel VA, I'd be inclined to
> > > > > > drop the 48/52 configuration altogether. But Catalin's on holiday at the
> > > > > > moment, and may have a different opinion ;)
> > > > > >
> > > > >
> > > > > But that implies that you cannot have an image that supports 52-bit
> > > > > kernel VAs but can still boot on hardware that does not implement
> > > > > support for it. If that is acceptable, then none of this hoop jumping
> > > > > that Steve is doing in these patches is necessary to begin with,
> > > > > right?
> > > >
> > > > Sorry, I misunderstood what you meant by a "48/52 hybrid configuration". I
> > > > thought you were referring to the configuration where userspace is 52-bit
> > > > and the kernel is 48-bit, which is something I think we can drop if we gain
> > > > support for 52-bit kernel.
> > > >
> > > > Now that I understand what you mean, I think disabling KASAN would be fine
> > > > as long as it's a runtime thing and the kernel continues to work in every
> > > > other respect.
> > > >
> > >
> > > No, it would be a limitation of the 52-bit config which also supports
> > > 48-bit-VA-only-h/w that the address space is laid out in such a way
> > > that there is simply no room for the KASAN shadow region, since it
> > > would have to live in the 48-bit addressable area, but be big enough
> > > to cover 52 bits of VA, which is impossible.
> > >
> > > For the vmemmap space, we could live with sizing it statically to
> > > cover a 52-bit VA linear region, but the KASAN shadow region is simply
> > > too big.
> > >
> > > So if KASAN support in that configuration is a requirement, then I
> > > agree with Steve's approach, but it does imply that quite a number of
> > > formerly compile-time constants now get turned into runtime variables.
> > >
> > > Steve, do you have any idea what the impact of that is?
> >
> > Hi Guys,
> >
> > The KASAN region only really necessitates two things: 1) that we think
> > about the end address of the region (which is invariant) rather than the
> > start address; and that 2) we flip the kernel VA space. IIUC both these
> > changes have a neglible perf impact.
> >
> > As for VA_BITS_ACTUAL, we need this in a few places: KVM mapping
> > support, and the big one phys_to/from_virt. For phys_to/from_virt the
> > logic is changed s.t. we use a variable lookup for translation but this
> > is folded into a new variable physvirt_offset (before the patch we used
> > a single variable read too).
> >
> > Again IIUC there should be a minimal perf impact (unless one tries to do
> > cat /sys/kernel/debug/kernel_page_tables with KASAN enabled - but that
> > can be optimised later).
> >
> > I didn't have the patience for ASCII art ;-), but I have a picture of
> > what I think it looks like here:
> > https://s3.amazonaws.com/connect.linaro.org/yvr18/presentations/yvr18-119.pdf
> > What I've tried to do is have most parts of the kernel VA space
> > invariant between 48/52 bits. If it's helpful I can type this up into a
> > document/commit log message?
> >
> > For this series I have tried to introduce VA_BITS_MIN in its own patch
> > and also VA_BITS_ACTUAL into its own patch to make it easier to follow.
> >

Hi Ard,

Apologies for my late reply, I had been staring at this for a while.

> 
> OK, perhaps I am just rephrasing what you essentially implemented
> already, but let me try to explain a bit better what I mean:
> 
> - we flip the VA space in the way you suggest
> - we limit the size of the top half of the address space to 47 bits
> - KASAN region growns downwards from (~0) << 47
> - we define PAGE_OFFSET as (~0) << 52, regardless of whether the h/w
> supports LVA or not
> - however, we tweak the phys/virt translation so that memory appears
> in the 48-bit addressable part of the linear region on non-LVA
> hardware
> 
> The latter basically means that the KASAN shadow region will intersect
> the linear region, but whether we map memory or shadow pages there
> depends on the h/w config at runtime.
> 
> The heart of the matter is probably the different placement of the
> memory inside the linear region, depending on whether the h/w is LVA
> capable or not, which is also reflected in your physvirt_offset. I am
> just trying to figure out why we need VA_BITS_ACTUAL to be a runtime
> variable.

Currently the direct linear map between configurations does not overlap,
we have:

FFF00000_00000000 - Direct linear map start (52-bit)
FFF80000_00000000 - Direct linear map end (52-bit)
FFFF0000_00000000 - Direct linear map start (48-bit)
FFFF8000_00000000 - Direct linear map end (48-bit)

We *can* make PAGE_OFFSET a constant for both 48/52 bit VA_BITS, if we
offset it. vmemmap can then be adjusted on early boot to ensure that
everything points to the right place. However we will get overlap for
52-bit configurations between KASAN and the direct linear map.

The question is: are we okay with quite a large overlap?

The KASAN region begins on 0xFFFDA000_00000000 for 52-bit. If we wish to
employ a "full" 47-bit direct linear map on 48-bit systems we need a
PAGE_OFFSET of 0xFFF78000_00000000 in order to make the direct linear
map end addresses "match up" between 48/52 bit configurations.

This doesn't leave us with a lot of room for 52-bit configurations
though, if KASAN is enabled.

Cheers,
-- 
Steve

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-02-26 17:30               ` Steve Capper
@ 2019-02-26 20:17                 ` Ard Biesheuvel
  2019-02-28 10:35                   ` Steve Capper
  0 siblings, 1 reply; 29+ messages in thread
From: Ard Biesheuvel @ 2019-02-26 20:17 UTC (permalink / raw)
  To: Steve Capper
  Cc: crecklin, Marc Zyngier, Catalin Marinas, Will Deacon, nd,
	linux-arm-kernel

On Tue, 26 Feb 2019 at 18:30, Steve Capper <Steve.Capper@arm.com> wrote:
>
> On Tue, Feb 19, 2019 at 05:18:18PM +0100, Ard Biesheuvel wrote:
> > On Tue, 19 Feb 2019 at 14:56, Steve Capper <Steve.Capper@arm.com> wrote:
> > >
> > > On Tue, Feb 19, 2019 at 02:15:26PM +0100, Ard Biesheuvel wrote:
> > > > On Tue, 19 Feb 2019 at 14:01, Will Deacon <will.deacon@arm.com> wrote:
> > > > >
> > > > > On Tue, Feb 19, 2019 at 01:51:51PM +0100, Ard Biesheuvel wrote:
> > > > > > On Tue, 19 Feb 2019 at 13:48, Will Deacon <will.deacon@arm.com> wrote:
> > > > > > >
> > > > > > > On Tue, Feb 19, 2019 at 01:13:32PM +0100, Ard Biesheuvel wrote:
> > > > > > > > On Mon, 18 Feb 2019 at 18:05, Steve Capper <steve.capper@arm.com> wrote:
> > > > > > > > >
> > > > > > > > > This patch series adds support for 52-bit kernel VAs using some of the
> > > > > > > > > machinery already introduced by the 52-bit userspace VA code in 5.0.
> > > > > > > > >
> > > > > > > > > As 52-bit virtual address support is an optional hardware feature,
> > > > > > > > > software support for 52-bit kernel VAs needs to be deduced at early boot
> > > > > > > > > time. If HW support is not available, the kernel falls back to 48-bit.
> > > > > > > > >
> > > > > > > > > A significant proportion of this series focuses on "de-constifying"
> > > > > > > > > VA_BITS related constants.
> > > > > > > > >
> > > > > > > > > In order to allow for a KASAN shadow that changes size at boot time, one
> > > > > > > > > must fix the KASAN_SHADOW_END for both 48 & 52-bit VAs and "grow" the
> > > > > > > > > start address. Also, it is highly desirable to maintain the same
> > > > > > > > > function addresses in the kernel .text between VA sizes. Both of these
> > > > > > > > > requirements necessitate us to flip the kernel address space halves s.t.
> > > > > > > > > the direct linear map occupies the lower addresses.
> > > > > > > > >
> > > > > > > > > One obvious omission is 52-bit kernel VA + 48-bit userspace VA which I
> > > > > > > > > can add with some more #ifdef'ery if needed.
> > > > > > > > >
> > > > > > > >
> > > > > > > > Hi Steve,
> > > > > > > >
> > > > > > > > Apologies if I am bringing up things that have been addressed
> > > > > > > > internally already. We discussed the 52-bit kernel VA work at
> > > > > > > > plumber's at some point, and IIUC, KASAN is the complicating factor
> > > > > > > > when it comes to having compile time constants for VA_BITS_MIN,
> > > > > > > > VA_BITS_MAX and PAGE_OFFSET, right?
> > > > > > > >
> > > > > > > > To clarify what I mean, please refer to the diagram below, which
> > > > > > > > describes a hybrid 48/52 kernel VA arrangement that does not rely on
> > > > > > > > runtime variable quantities. (VA_BITS_MIN == 48, VA_BITS_MAX == 52)
> > > > > > > >
> > > > > > > > +------------------- (~0) -------------------------+
> > > > > > > > |                                                |
> > > > > > > > |            PCI IO / fixmap spaces              |
> > > > > > > > |                                                |
> > > > > > > > +------------------------------------------------+
> > > > > > > > |                                                |
> > > > > > > > |             kernel/vmalloc space               |
> > > > > > > > |                                                |
> > > > > > > > +------------------------------------------------+
> > > > > > > > |                                                |
> > > > > > > > |                module space                    |
> > > > > > > > |                                                |
> > > > > > > > +------------------------------------------------+
> > > > > > > > |                                                |
> > > > > > > > |                BPF space                       |
> > > > > > > > |                                                |
> > > > > > > > +------------------------------------------------+
> > > > > > > > |                                                |
> > > > > > > > |                                                |
> > > > > > > > |   vmemmap space (size based on VA_BITS_MAX)    |
> > > > > > > > |                                                |
> > > > > > > > |                                                |
> > > > > > > > +-- linear/vmalloc split based on VA_BITS_MIN -- +
> > > > > > > > |                                                |
> > > > > > > > |    linear mapping (48 bit addressable region)  |
> > > > > > > > |                                                |
> > > > > > > > +------------------------------------------------+
> > > > > > > > |                                                |
> > > > > > > > |    linear mapping (52 bit addressable region)  |
> > > > > > > > |                                                |
> > > > > > > > +------ PAGE_OFFSET based on VA_BITS_MAX --------+
> > > > > > > >
> > > > > > > > Since KASAN is what is preventing this, would it be acceptable for
> > > > > > > > KASAN to only be supported when you use a true 48 bit or a true 52 bit
> > > > > > > > configuration, and disable it for the 48/52 hybrid configuration?
> > > > > > > >
> > > > > > > > Just thinking out loud (and in ASCII art :-))
> > > > > > >
> > > > > > > TBH, if we end up having support for 52-bit kernel VA, I'd be inclined to
> > > > > > > drop the 48/52 configuration altogether. But Catalin's on holiday at the
> > > > > > > moment, and may have a different opinion ;)
> > > > > > >
> > > > > >
> > > > > > But that implies that you cannot have an image that supports 52-bit
> > > > > > kernel VAs but can still boot on hardware that does not implement
> > > > > > support for it. If that is acceptable, then none of this hoop jumping
> > > > > > that Steve is doing in these patches is necessary to begin with,
> > > > > > right?
> > > > >
> > > > > Sorry, I misunderstood what you meant by a "48/52 hybrid configuration". I
> > > > > thought you were referring to the configuration where userspace is 52-bit
> > > > > and the kernel is 48-bit, which is something I think we can drop if we gain
> > > > > support for 52-bit kernel.
> > > > >
> > > > > Now that I understand what you mean, I think disabling KASAN would be fine
> > > > > as long as it's a runtime thing and the kernel continues to work in every
> > > > > other respect.
> > > > >
> > > >
> > > > No, it would be a limitation of the 52-bit config which also supports
> > > > 48-bit-VA-only-h/w that the address space is laid out in such a way
> > > > that there is simply no room for the KASAN shadow region, since it
> > > > would have to live in the 48-bit addressable area, but be big enough
> > > > to cover 52 bits of VA, which is impossible.
> > > >
> > > > For the vmemmap space, we could live with sizing it statically to
> > > > cover a 52-bit VA linear region, but the KASAN shadow region is simply
> > > > too big.
> > > >
> > > > So if KASAN support in that configuration is a requirement, then I
> > > > agree with Steve's approach, but it does imply that quite a number of
> > > > formerly compile-time constants now get turned into runtime variables.
> > > >
> > > > Steve, do you have any idea what the impact of that is?
> > >
> > > Hi Guys,
> > >
> > > The KASAN region only really necessitates two things: 1) that we think
> > > about the end address of the region (which is invariant) rather than the
> > > start address; and that 2) we flip the kernel VA space. IIUC both these
> > > changes have a neglible perf impact.
> > >
> > > As for VA_BITS_ACTUAL, we need this in a few places: KVM mapping
> > > support, and the big one phys_to/from_virt. For phys_to/from_virt the
> > > logic is changed s.t. we use a variable lookup for translation but this
> > > is folded into a new variable physvirt_offset (before the patch we used
> > > a single variable read too).
> > >
> > > Again IIUC there should be a minimal perf impact (unless one tries to do
> > > cat /sys/kernel/debug/kernel_page_tables with KASAN enabled - but that
> > > can be optimised later).
> > >
> > > I didn't have the patience for ASCII art ;-), but I have a picture of
> > > what I think it looks like here:
> > > https://s3.amazonaws.com/connect.linaro.org/yvr18/presentations/yvr18-119.pdf
> > > What I've tried to do is have most parts of the kernel VA space
> > > invariant between 48/52 bits. If it's helpful I can type this up into a
> > > document/commit log message?
> > >
> > > For this series I have tried to introduce VA_BITS_MIN in its own patch
> > > and also VA_BITS_ACTUAL into its own patch to make it easier to follow.
> > >
>
> Hi Ard,
>
> Apologies for my late reply, I had been staring at this for a while.
>
> >
> > OK, perhaps I am just rephrasing what you essentially implemented
> > already, but let me try to explain a bit better what I mean:
> >
> > - we flip the VA space in the way you suggest
> > - we limit the size of the top half of the address space to 47 bits
> > - KASAN region growns downwards from (~0) << 47
> > - we define PAGE_OFFSET as (~0) << 52, regardless of whether the h/w
> > supports LVA or not
> > - however, we tweak the phys/virt translation so that memory appears
> > in the 48-bit addressable part of the linear region on non-LVA
> > hardware
> >
> > The latter basically means that the KASAN shadow region will intersect
> > the linear region, but whether we map memory or shadow pages there
> > depends on the h/w config at runtime.
> >
> > The heart of the matter is probably the different placement of the
> > memory inside the linear region, depending on whether the h/w is LVA
> > capable or not, which is also reflected in your physvirt_offset. I am
> > just trying to figure out why we need VA_BITS_ACTUAL to be a runtime
> > variable.
>
> Currently the direct linear map between configurations does not overlap,
> we have:
>
> FFF00000_00000000 - Direct linear map start (52-bit)
> FFF80000_00000000 - Direct linear map end (52-bit)
> FFFF0000_00000000 - Direct linear map start (48-bit)
> FFFF8000_00000000 - Direct linear map end (48-bit)
>
> We *can* make PAGE_OFFSET a constant for both 48/52 bit VA_BITS, if we
> offset it. vmemmap can then be adjusted on early boot to ensure that
> everything points to the right place. However we will get overlap for
> 52-bit configurations between KASAN and the direct linear map.
>
> The question is: are we okay with quite a large overlap?
>
> The KASAN region begins on 0xFFFDA000_00000000 for 52-bit. If we wish to
> employ a "full" 47-bit direct linear map on 48-bit systems we need a
> PAGE_OFFSET of 0xFFF78000_00000000 in order to make the direct linear
> map end addresses "match up" between 48/52 bit configurations.
>
> This doesn't leave us with a lot of room for 52-bit configurations
> though, if KASAN is enabled.
>

OK, so with actual numbers, what I had in mind was


FFF00000_00000000  start of 52-bit addressable linear region | PAGE_OFFSET

FFFD8000_00000000  start of KASAN shadow region | KASAN_SHADOW_OFFSET

FFFF0000_00000000  start of 48-bit addressable linear region

FFFF6000_00000000  start of used KASAN shadow region (48-bit VA)
                   (KASAN_SHADOW_OFFSET + F0000_00000000 >> 3)

FFFF8000_00000000  start of vmemmap area - end of KASAN shadow region

FFFF8200_00000000  end of vmemmap area - start of bpf/module/etc area


The trick is that the full (52 - 3) bits KASAN shadow space overlaps
with the 48-bit linear region, but since you don't need KASAN shadow
pages for memory that does not exist, the region FFFF0000_00000000 -
FFFF6000_00000000 can be used for mapping the memory in case the h/w
is 48-bit only.

So in this case, PAGE_OFFSET and KASAN_SHADOW_OFFSET remain compile
time constants, and as long as we don't attempt to map anything
outside of the 48-bit addressable area on h/w that does not support
it, the fact that those quantities are outside the 48-bit range does
not really matter.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-02-26 20:17                 ` Ard Biesheuvel
@ 2019-02-28 10:35                   ` Steve Capper
  2019-02-28 11:22                     ` Ard Biesheuvel
  0 siblings, 1 reply; 29+ messages in thread
From: Steve Capper @ 2019-02-28 10:35 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: crecklin, Marc Zyngier, Catalin Marinas, Will Deacon, nd,
	linux-arm-kernel

On Tue, Feb 26, 2019 at 09:17:49PM +0100, Ard Biesheuvel wrote:
> On Tue, 26 Feb 2019 at 18:30, Steve Capper <Steve.Capper@arm.com> wrote:
> >
> > On Tue, Feb 19, 2019 at 05:18:18PM +0100, Ard Biesheuvel wrote:
> > > On Tue, 19 Feb 2019 at 14:56, Steve Capper <Steve.Capper@arm.com> wrote:
> > > >
> > > > On Tue, Feb 19, 2019 at 02:15:26PM +0100, Ard Biesheuvel wrote:
> > > > > On Tue, 19 Feb 2019 at 14:01, Will Deacon <will.deacon@arm.com> wrote:
> > > > > >
> > > > > > On Tue, Feb 19, 2019 at 01:51:51PM +0100, Ard Biesheuvel wrote:
> > > > > > > On Tue, 19 Feb 2019 at 13:48, Will Deacon <will.deacon@arm.com> wrote:
> > > > > > > >
> > > > > > > > On Tue, Feb 19, 2019 at 01:13:32PM +0100, Ard Biesheuvel wrote:
> > > > > > > > > On Mon, 18 Feb 2019 at 18:05, Steve Capper <steve.capper@arm.com> wrote:
> > > > > > > > > >
> > > > > > > > > > This patch series adds support for 52-bit kernel VAs using some of the
> > > > > > > > > > machinery already introduced by the 52-bit userspace VA code in 5.0.
> > > > > > > > > >
> > > > > > > > > > As 52-bit virtual address support is an optional hardware feature,
> > > > > > > > > > software support for 52-bit kernel VAs needs to be deduced at early boot
> > > > > > > > > > time. If HW support is not available, the kernel falls back to 48-bit.
> > > > > > > > > >
> > > > > > > > > > A significant proportion of this series focuses on "de-constifying"
> > > > > > > > > > VA_BITS related constants.
> > > > > > > > > >
> > > > > > > > > > In order to allow for a KASAN shadow that changes size at boot time, one
> > > > > > > > > > must fix the KASAN_SHADOW_END for both 48 & 52-bit VAs and "grow" the
> > > > > > > > > > start address. Also, it is highly desirable to maintain the same
> > > > > > > > > > function addresses in the kernel .text between VA sizes. Both of these
> > > > > > > > > > requirements necessitate us to flip the kernel address space halves s.t.
> > > > > > > > > > the direct linear map occupies the lower addresses.
> > > > > > > > > >
> > > > > > > > > > One obvious omission is 52-bit kernel VA + 48-bit userspace VA which I
> > > > > > > > > > can add with some more #ifdef'ery if needed.
> > > > > > > > > >
> > > > > > > > >
> > > > > > > > > Hi Steve,
> > > > > > > > >
> > > > > > > > > Apologies if I am bringing up things that have been addressed
> > > > > > > > > internally already. We discussed the 52-bit kernel VA work at
> > > > > > > > > plumber's at some point, and IIUC, KASAN is the complicating factor
> > > > > > > > > when it comes to having compile time constants for VA_BITS_MIN,
> > > > > > > > > VA_BITS_MAX and PAGE_OFFSET, right?
> > > > > > > > >
> > > > > > > > > To clarify what I mean, please refer to the diagram below, which
> > > > > > > > > describes a hybrid 48/52 kernel VA arrangement that does not rely on
> > > > > > > > > runtime variable quantities. (VA_BITS_MIN == 48, VA_BITS_MAX == 52)
> > > > > > > > >
> > > > > > > > > +------------------- (~0) -------------------------+
> > > > > > > > > |                                                |
> > > > > > > > > |            PCI IO / fixmap spaces              |
> > > > > > > > > |                                                |
> > > > > > > > > +------------------------------------------------+
> > > > > > > > > |                                                |
> > > > > > > > > |             kernel/vmalloc space               |
> > > > > > > > > |                                                |
> > > > > > > > > +------------------------------------------------+
> > > > > > > > > |                                                |
> > > > > > > > > |                module space                    |
> > > > > > > > > |                                                |
> > > > > > > > > +------------------------------------------------+
> > > > > > > > > |                                                |
> > > > > > > > > |                BPF space                       |
> > > > > > > > > |                                                |
> > > > > > > > > +------------------------------------------------+
> > > > > > > > > |                                                |
> > > > > > > > > |                                                |
> > > > > > > > > |   vmemmap space (size based on VA_BITS_MAX)    |
> > > > > > > > > |                                                |
> > > > > > > > > |                                                |
> > > > > > > > > +-- linear/vmalloc split based on VA_BITS_MIN -- +
> > > > > > > > > |                                                |
> > > > > > > > > |    linear mapping (48 bit addressable region)  |
> > > > > > > > > |                                                |
> > > > > > > > > +------------------------------------------------+
> > > > > > > > > |                                                |
> > > > > > > > > |    linear mapping (52 bit addressable region)  |
> > > > > > > > > |                                                |
> > > > > > > > > +------ PAGE_OFFSET based on VA_BITS_MAX --------+
> > > > > > > > >
> > > > > > > > > Since KASAN is what is preventing this, would it be acceptable for
> > > > > > > > > KASAN to only be supported when you use a true 48 bit or a true 52 bit
> > > > > > > > > configuration, and disable it for the 48/52 hybrid configuration?
> > > > > > > > >
> > > > > > > > > Just thinking out loud (and in ASCII art :-))
> > > > > > > >
> > > > > > > > TBH, if we end up having support for 52-bit kernel VA, I'd be inclined to
> > > > > > > > drop the 48/52 configuration altogether. But Catalin's on holiday at the
> > > > > > > > moment, and may have a different opinion ;)
> > > > > > > >
> > > > > > >
> > > > > > > But that implies that you cannot have an image that supports 52-bit
> > > > > > > kernel VAs but can still boot on hardware that does not implement
> > > > > > > support for it. If that is acceptable, then none of this hoop jumping
> > > > > > > that Steve is doing in these patches is necessary to begin with,
> > > > > > > right?
> > > > > >
> > > > > > Sorry, I misunderstood what you meant by a "48/52 hybrid configuration". I
> > > > > > thought you were referring to the configuration where userspace is 52-bit
> > > > > > and the kernel is 48-bit, which is something I think we can drop if we gain
> > > > > > support for 52-bit kernel.
> > > > > >
> > > > > > Now that I understand what you mean, I think disabling KASAN would be fine
> > > > > > as long as it's a runtime thing and the kernel continues to work in every
> > > > > > other respect.
> > > > > >
> > > > >
> > > > > No, it would be a limitation of the 52-bit config which also supports
> > > > > 48-bit-VA-only-h/w that the address space is laid out in such a way
> > > > > that there is simply no room for the KASAN shadow region, since it
> > > > > would have to live in the 48-bit addressable area, but be big enough
> > > > > to cover 52 bits of VA, which is impossible.
> > > > >
> > > > > For the vmemmap space, we could live with sizing it statically to
> > > > > cover a 52-bit VA linear region, but the KASAN shadow region is simply
> > > > > too big.
> > > > >
> > > > > So if KASAN support in that configuration is a requirement, then I
> > > > > agree with Steve's approach, but it does imply that quite a number of
> > > > > formerly compile-time constants now get turned into runtime variables.
> > > > >
> > > > > Steve, do you have any idea what the impact of that is?
> > > >
> > > > Hi Guys,
> > > >
> > > > The KASAN region only really necessitates two things: 1) that we think
> > > > about the end address of the region (which is invariant) rather than the
> > > > start address; and that 2) we flip the kernel VA space. IIUC both these
> > > > changes have a neglible perf impact.
> > > >
> > > > As for VA_BITS_ACTUAL, we need this in a few places: KVM mapping
> > > > support, and the big one phys_to/from_virt. For phys_to/from_virt the
> > > > logic is changed s.t. we use a variable lookup for translation but this
> > > > is folded into a new variable physvirt_offset (before the patch we used
> > > > a single variable read too).
> > > >
> > > > Again IIUC there should be a minimal perf impact (unless one tries to do
> > > > cat /sys/kernel/debug/kernel_page_tables with KASAN enabled - but that
> > > > can be optimised later).
> > > >
> > > > I didn't have the patience for ASCII art ;-), but I have a picture of
> > > > what I think it looks like here:
> > > > https://s3.amazonaws.com/connect.linaro.org/yvr18/presentations/yvr18-119.pdf
> > > > What I've tried to do is have most parts of the kernel VA space
> > > > invariant between 48/52 bits. If it's helpful I can type this up into a
> > > > document/commit log message?
> > > >
> > > > For this series I have tried to introduce VA_BITS_MIN in its own patch
> > > > and also VA_BITS_ACTUAL into its own patch to make it easier to follow.
> > > >
> >
> > Hi Ard,
> >
> > Apologies for my late reply, I had been staring at this for a while.
> >
> > >
> > > OK, perhaps I am just rephrasing what you essentially implemented
> > > already, but let me try to explain a bit better what I mean:
> > >
> > > - we flip the VA space in the way you suggest
> > > - we limit the size of the top half of the address space to 47 bits
> > > - KASAN region growns downwards from (~0) << 47
> > > - we define PAGE_OFFSET as (~0) << 52, regardless of whether the h/w
> > > supports LVA or not
> > > - however, we tweak the phys/virt translation so that memory appears
> > > in the 48-bit addressable part of the linear region on non-LVA
> > > hardware
> > >
> > > The latter basically means that the KASAN shadow region will intersect
> > > the linear region, but whether we map memory or shadow pages there
> > > depends on the h/w config at runtime.
> > >
> > > The heart of the matter is probably the different placement of the
> > > memory inside the linear region, depending on whether the h/w is LVA
> > > capable or not, which is also reflected in your physvirt_offset. I am
> > > just trying to figure out why we need VA_BITS_ACTUAL to be a runtime
> > > variable.
> >
> > Currently the direct linear map between configurations does not overlap,
> > we have:
> >
> > FFF00000_00000000 - Direct linear map start (52-bit)
> > FFF80000_00000000 - Direct linear map end (52-bit)
> > FFFF0000_00000000 - Direct linear map start (48-bit)
> > FFFF8000_00000000 - Direct linear map end (48-bit)
> >
> > We *can* make PAGE_OFFSET a constant for both 48/52 bit VA_BITS, if we
> > offset it. vmemmap can then be adjusted on early boot to ensure that
> > everything points to the right place. However we will get overlap for
> > 52-bit configurations between KASAN and the direct linear map.
> >
> > The question is: are we okay with quite a large overlap?
> >
> > The KASAN region begins on 0xFFFDA000_00000000 for 52-bit. If we wish to
> > employ a "full" 47-bit direct linear map on 48-bit systems we need a
> > PAGE_OFFSET of 0xFFF78000_00000000 in order to make the direct linear
> > map end addresses "match up" between 48/52 bit configurations.
> >
> > This doesn't leave us with a lot of room for 52-bit configurations
> > though, if KASAN is enabled.
> >
> 
> OK, so with actual numbers, what I had in mind was
> 
> 
> FFF00000_00000000  start of 52-bit addressable linear region | PAGE_OFFSET
> 
> FFFD8000_00000000  start of KASAN shadow region | KASAN_SHADOW_OFFSET
> 
> FFFF0000_00000000  start of 48-bit addressable linear region
> 
> FFFF6000_00000000  start of used KASAN shadow region (48-bit VA)
>                    (KASAN_SHADOW_OFFSET + F0000_00000000 >> 3)
> 
> FFFF8000_00000000  start of vmemmap area - end of KASAN shadow region
> 
> FFFF8200_00000000  end of vmemmap area - start of bpf/module/etc area
> 
> 
> The trick is that the full (52 - 3) bits KASAN shadow space overlaps
> with the 48-bit linear region, but since you don't need KASAN shadow
> pages for memory that does not exist, the region FFFF0000_00000000 -
> FFFF6000_00000000 can be used for mapping the memory in case the h/w
> is 48-bit only.
> 
> So in this case, PAGE_OFFSET and KASAN_SHADOW_OFFSET remain compile
> time constants, and as long as we don't attempt to map anything
> outside of the 48-bit addressable area on h/w that does not support
> it, the fact that those quantities are outside the 48-bit range does
> not really matter.

Thanks Ard,
I'll elaborate more on what I'm worrying about :-).

The 48/52 bit linear regions above do not overlap and this creates the
following issue.

To go from a struct page * to a linear address we do the following:
lva = (page - VMEMMAP_START) * PAGE_SIZE / sizeof(struct page) + PAGE_OFFSET

(Before my series) all the constants are fixed at compile time and thus
translation is very quick. My understanding is that you would like
PAGE_OFFSET to be constant to preserve the optimised nature of this
transform? (if not, please shout :-) )

The problem is that a 52-bit PAGE_OFFSET = 0xFFF00000_00000000 will
never be able to give us an lva within a 48-bit addressable range. At
best we will get an lva of FFF80000_00000000.

We can get around this by adding a variable to the above transform, but
this is essentially what my series does by making PAGE_OFFSET variable.

Cheers,
-- 
Steve

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-02-28 10:35                   ` Steve Capper
@ 2019-02-28 11:22                     ` Ard Biesheuvel
  2019-02-28 11:45                       ` Steve Capper
  2019-03-25 18:38                       ` Catalin Marinas
  0 siblings, 2 replies; 29+ messages in thread
From: Ard Biesheuvel @ 2019-02-28 11:22 UTC (permalink / raw)
  To: Steve Capper
  Cc: crecklin, Marc Zyngier, Catalin Marinas, Will Deacon, nd,
	linux-arm-kernel

On Thu, 28 Feb 2019 at 11:36, Steve Capper <Steve.Capper@arm.com> wrote:
>
> On Tue, Feb 26, 2019 at 09:17:49PM +0100, Ard Biesheuvel wrote:
> > On Tue, 26 Feb 2019 at 18:30, Steve Capper <Steve.Capper@arm.com> wrote:
> > >
> > > On Tue, Feb 19, 2019 at 05:18:18PM +0100, Ard Biesheuvel wrote:
> > > > On Tue, 19 Feb 2019 at 14:56, Steve Capper <Steve.Capper@arm.com> wrote:
> > > > >
> > > > > On Tue, Feb 19, 2019 at 02:15:26PM +0100, Ard Biesheuvel wrote:
> > > > > > On Tue, 19 Feb 2019 at 14:01, Will Deacon <will.deacon@arm.com> wrote:
> > > > > > >
> > > > > > > On Tue, Feb 19, 2019 at 01:51:51PM +0100, Ard Biesheuvel wrote:
> > > > > > > > On Tue, 19 Feb 2019 at 13:48, Will Deacon <will.deacon@arm.com> wrote:
> > > > > > > > >
> > > > > > > > > On Tue, Feb 19, 2019 at 01:13:32PM +0100, Ard Biesheuvel wrote:
> > > > > > > > > > On Mon, 18 Feb 2019 at 18:05, Steve Capper <steve.capper@arm.com> wrote:
> > > > > > > > > > >
> > > > > > > > > > > This patch series adds support for 52-bit kernel VAs using some of the
> > > > > > > > > > > machinery already introduced by the 52-bit userspace VA code in 5.0.
> > > > > > > > > > >
> > > > > > > > > > > As 52-bit virtual address support is an optional hardware feature,
> > > > > > > > > > > software support for 52-bit kernel VAs needs to be deduced at early boot
> > > > > > > > > > > time. If HW support is not available, the kernel falls back to 48-bit.
> > > > > > > > > > >
> > > > > > > > > > > A significant proportion of this series focuses on "de-constifying"
> > > > > > > > > > > VA_BITS related constants.
> > > > > > > > > > >
> > > > > > > > > > > In order to allow for a KASAN shadow that changes size at boot time, one
> > > > > > > > > > > must fix the KASAN_SHADOW_END for both 48 & 52-bit VAs and "grow" the
> > > > > > > > > > > start address. Also, it is highly desirable to maintain the same
> > > > > > > > > > > function addresses in the kernel .text between VA sizes. Both of these
> > > > > > > > > > > requirements necessitate us to flip the kernel address space halves s.t.
> > > > > > > > > > > the direct linear map occupies the lower addresses.
> > > > > > > > > > >
> > > > > > > > > > > One obvious omission is 52-bit kernel VA + 48-bit userspace VA which I
> > > > > > > > > > > can add with some more #ifdef'ery if needed.
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > Hi Steve,
> > > > > > > > > >
> > > > > > > > > > Apologies if I am bringing up things that have been addressed
> > > > > > > > > > internally already. We discussed the 52-bit kernel VA work at
> > > > > > > > > > plumber's at some point, and IIUC, KASAN is the complicating factor
> > > > > > > > > > when it comes to having compile time constants for VA_BITS_MIN,
> > > > > > > > > > VA_BITS_MAX and PAGE_OFFSET, right?
> > > > > > > > > >
> > > > > > > > > > To clarify what I mean, please refer to the diagram below, which
> > > > > > > > > > describes a hybrid 48/52 kernel VA arrangement that does not rely on
> > > > > > > > > > runtime variable quantities. (VA_BITS_MIN == 48, VA_BITS_MAX == 52)
> > > > > > > > > >
> > > > > > > > > > +------------------- (~0) -------------------------+
> > > > > > > > > > |                                                |
> > > > > > > > > > |            PCI IO / fixmap spaces              |
> > > > > > > > > > |                                                |
> > > > > > > > > > +------------------------------------------------+
> > > > > > > > > > |                                                |
> > > > > > > > > > |             kernel/vmalloc space               |
> > > > > > > > > > |                                                |
> > > > > > > > > > +------------------------------------------------+
> > > > > > > > > > |                                                |
> > > > > > > > > > |                module space                    |
> > > > > > > > > > |                                                |
> > > > > > > > > > +------------------------------------------------+
> > > > > > > > > > |                                                |
> > > > > > > > > > |                BPF space                       |
> > > > > > > > > > |                                                |
> > > > > > > > > > +------------------------------------------------+
> > > > > > > > > > |                                                |
> > > > > > > > > > |                                                |
> > > > > > > > > > |   vmemmap space (size based on VA_BITS_MAX)    |
> > > > > > > > > > |                                                |
> > > > > > > > > > |                                                |
> > > > > > > > > > +-- linear/vmalloc split based on VA_BITS_MIN -- +
> > > > > > > > > > |                                                |
> > > > > > > > > > |    linear mapping (48 bit addressable region)  |
> > > > > > > > > > |                                                |
> > > > > > > > > > +------------------------------------------------+
> > > > > > > > > > |                                                |
> > > > > > > > > > |    linear mapping (52 bit addressable region)  |
> > > > > > > > > > |                                                |
> > > > > > > > > > +------ PAGE_OFFSET based on VA_BITS_MAX --------+
> > > > > > > > > >
> > > > > > > > > > Since KASAN is what is preventing this, would it be acceptable for
> > > > > > > > > > KASAN to only be supported when you use a true 48 bit or a true 52 bit
> > > > > > > > > > configuration, and disable it for the 48/52 hybrid configuration?
> > > > > > > > > >
> > > > > > > > > > Just thinking out loud (and in ASCII art :-))
> > > > > > > > >
> > > > > > > > > TBH, if we end up having support for 52-bit kernel VA, I'd be inclined to
> > > > > > > > > drop the 48/52 configuration altogether. But Catalin's on holiday at the
> > > > > > > > > moment, and may have a different opinion ;)
> > > > > > > > >
> > > > > > > >
> > > > > > > > But that implies that you cannot have an image that supports 52-bit
> > > > > > > > kernel VAs but can still boot on hardware that does not implement
> > > > > > > > support for it. If that is acceptable, then none of this hoop jumping
> > > > > > > > that Steve is doing in these patches is necessary to begin with,
> > > > > > > > right?
> > > > > > >
> > > > > > > Sorry, I misunderstood what you meant by a "48/52 hybrid configuration". I
> > > > > > > thought you were referring to the configuration where userspace is 52-bit
> > > > > > > and the kernel is 48-bit, which is something I think we can drop if we gain
> > > > > > > support for 52-bit kernel.
> > > > > > >
> > > > > > > Now that I understand what you mean, I think disabling KASAN would be fine
> > > > > > > as long as it's a runtime thing and the kernel continues to work in every
> > > > > > > other respect.
> > > > > > >
> > > > > >
> > > > > > No, it would be a limitation of the 52-bit config which also supports
> > > > > > 48-bit-VA-only-h/w that the address space is laid out in such a way
> > > > > > that there is simply no room for the KASAN shadow region, since it
> > > > > > would have to live in the 48-bit addressable area, but be big enough
> > > > > > to cover 52 bits of VA, which is impossible.
> > > > > >
> > > > > > For the vmemmap space, we could live with sizing it statically to
> > > > > > cover a 52-bit VA linear region, but the KASAN shadow region is simply
> > > > > > too big.
> > > > > >
> > > > > > So if KASAN support in that configuration is a requirement, then I
> > > > > > agree with Steve's approach, but it does imply that quite a number of
> > > > > > formerly compile-time constants now get turned into runtime variables.
> > > > > >
> > > > > > Steve, do you have any idea what the impact of that is?
> > > > >
> > > > > Hi Guys,
> > > > >
> > > > > The KASAN region only really necessitates two things: 1) that we think
> > > > > about the end address of the region (which is invariant) rather than the
> > > > > start address; and that 2) we flip the kernel VA space. IIUC both these
> > > > > changes have a neglible perf impact.
> > > > >
> > > > > As for VA_BITS_ACTUAL, we need this in a few places: KVM mapping
> > > > > support, and the big one phys_to/from_virt. For phys_to/from_virt the
> > > > > logic is changed s.t. we use a variable lookup for translation but this
> > > > > is folded into a new variable physvirt_offset (before the patch we used
> > > > > a single variable read too).
> > > > >
> > > > > Again IIUC there should be a minimal perf impact (unless one tries to do
> > > > > cat /sys/kernel/debug/kernel_page_tables with KASAN enabled - but that
> > > > > can be optimised later).
> > > > >
> > > > > I didn't have the patience for ASCII art ;-), but I have a picture of
> > > > > what I think it looks like here:
> > > > > https://s3.amazonaws.com/connect.linaro.org/yvr18/presentations/yvr18-119.pdf
> > > > > What I've tried to do is have most parts of the kernel VA space
> > > > > invariant between 48/52 bits. If it's helpful I can type this up into a
> > > > > document/commit log message?
> > > > >
> > > > > For this series I have tried to introduce VA_BITS_MIN in its own patch
> > > > > and also VA_BITS_ACTUAL into its own patch to make it easier to follow.
> > > > >
> > >
> > > Hi Ard,
> > >
> > > Apologies for my late reply, I had been staring at this for a while.
> > >
> > > >
> > > > OK, perhaps I am just rephrasing what you essentially implemented
> > > > already, but let me try to explain a bit better what I mean:
> > > >
> > > > - we flip the VA space in the way you suggest
> > > > - we limit the size of the top half of the address space to 47 bits
> > > > - KASAN region growns downwards from (~0) << 47
> > > > - we define PAGE_OFFSET as (~0) << 52, regardless of whether the h/w
> > > > supports LVA or not
> > > > - however, we tweak the phys/virt translation so that memory appears
> > > > in the 48-bit addressable part of the linear region on non-LVA
> > > > hardware
> > > >
> > > > The latter basically means that the KASAN shadow region will intersect
> > > > the linear region, but whether we map memory or shadow pages there
> > > > depends on the h/w config at runtime.
> > > >
> > > > The heart of the matter is probably the different placement of the
> > > > memory inside the linear region, depending on whether the h/w is LVA
> > > > capable or not, which is also reflected in your physvirt_offset. I am
> > > > just trying to figure out why we need VA_BITS_ACTUAL to be a runtime
> > > > variable.
> > >
> > > Currently the direct linear map between configurations does not overlap,
> > > we have:
> > >
> > > FFF00000_00000000 - Direct linear map start (52-bit)
> > > FFF80000_00000000 - Direct linear map end (52-bit)
> > > FFFF0000_00000000 - Direct linear map start (48-bit)
> > > FFFF8000_00000000 - Direct linear map end (48-bit)
> > >
> > > We *can* make PAGE_OFFSET a constant for both 48/52 bit VA_BITS, if we
> > > offset it. vmemmap can then be adjusted on early boot to ensure that
> > > everything points to the right place. However we will get overlap for
> > > 52-bit configurations between KASAN and the direct linear map.
> > >
> > > The question is: are we okay with quite a large overlap?
> > >
> > > The KASAN region begins on 0xFFFDA000_00000000 for 52-bit. If we wish to
> > > employ a "full" 47-bit direct linear map on 48-bit systems we need a
> > > PAGE_OFFSET of 0xFFF78000_00000000 in order to make the direct linear
> > > map end addresses "match up" between 48/52 bit configurations.
> > >
> > > This doesn't leave us with a lot of room for 52-bit configurations
> > > though, if KASAN is enabled.
> > >
> >
> > OK, so with actual numbers, what I had in mind was
> >
> >
> > FFF00000_00000000  start of 52-bit addressable linear region | PAGE_OFFSET
> >
> > FFFD8000_00000000  start of KASAN shadow region | KASAN_SHADOW_OFFSET
> >
> > FFFF0000_00000000  start of 48-bit addressable linear region
> >
> > FFFF6000_00000000  start of used KASAN shadow region (48-bit VA)
> >                    (KASAN_SHADOW_OFFSET + F0000_00000000 >> 3)
> >
> > FFFF8000_00000000  start of vmemmap area - end of KASAN shadow region
> >
> > FFFF8200_00000000  end of vmemmap area - start of bpf/module/etc area
> >
> >
> > The trick is that the full (52 - 3) bits KASAN shadow space overlaps
> > with the 48-bit linear region, but since you don't need KASAN shadow
> > pages for memory that does not exist, the region FFFF0000_00000000 -
> > FFFF6000_00000000 can be used for mapping the memory in case the h/w
> > is 48-bit only.
> >
> > So in this case, PAGE_OFFSET and KASAN_SHADOW_OFFSET remain compile
> > time constants, and as long as we don't attempt to map anything
> > outside of the 48-bit addressable area on h/w that does not support
> > it, the fact that those quantities are outside the 48-bit range does
> > not really matter.
>
> Thanks Ard,
> I'll elaborate more on what I'm worrying about :-).
>
> The 48/52 bit linear regions above do not overlap and this creates the
> following issue.
>

OK, I see what you mean (I think). In my proposal, the linear regions
*do* overlap.

In my example, the vmemmap region is only sized to cover 51 bits of
linear region, but this is not sufficient, since the 52-bit linear
region is actually bigger than that.

So based on a linear region that goes from

FFF0_0000_0000_0000 ... FFFF_8000_0000_0000

we would end up with a vmemmap region

FFFF_8000_0000_0000 ... FFFF_83E0_0000_0000

covering the entire combined linear region.  This is a fair chunk of
the vmalloc space for 48-bit configuration, but I don't think that is
anything to worry about.

> To go from a struct page * to a linear address we do the following:
> lva = (page - VMEMMAP_START) * PAGE_SIZE / sizeof(struct page) + PAGE_OFFSET
>

OK, so given the above correction, we can take

VMEMMAP_START := FFFF_8000_0000_0000
PAGE_OFFSET := FFF0_0000_0000_0000

and everything still adds up afaict, and struct pages in the 48-bit VA
region are covered from FFFF_83C0_0000_0000 and up.

> (Before my series) all the constants are fixed at compile time and thus
> translation is very quick. My understanding is that you would like
> PAGE_OFFSET to be constant to preserve the optimised nature of this
> transform? (if not, please shout :-) )
>

Yes, the main idea is to have compile time constants for PAGE_OFFSET,
VA_BITS, etc

> The problem is that a 52-bit PAGE_OFFSET = 0xFFF00000_00000000 will
> never be able to give us an lva within a 48-bit addressable range. At
> best we will get an lva of FFF80000_00000000.
>

You are assuming that we have to split the address space down the
middle, but I don't think that is necessary at all.

> We can get around this by adding a variable to the above transform, but
> this is essentially what my series does by making PAGE_OFFSET variable.
>
> Cheers,
> --
> Steve

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-02-28 11:22                     ` Ard Biesheuvel
@ 2019-02-28 11:45                       ` Steve Capper
  2019-03-25 18:38                       ` Catalin Marinas
  1 sibling, 0 replies; 29+ messages in thread
From: Steve Capper @ 2019-02-28 11:45 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: crecklin, Marc Zyngier, Catalin Marinas, Will Deacon, nd,
	linux-arm-kernel

On Thu, Feb 28, 2019 at 12:22:09PM +0100, Ard Biesheuvel wrote:
> On Thu, 28 Feb 2019 at 11:36, Steve Capper <Steve.Capper@arm.com> wrote:
> >
> > On Tue, Feb 26, 2019 at 09:17:49PM +0100, Ard Biesheuvel wrote:
> > > On Tue, 26 Feb 2019 at 18:30, Steve Capper <Steve.Capper@arm.com> wrote:
> > > >
> > > > On Tue, Feb 19, 2019 at 05:18:18PM +0100, Ard Biesheuvel wrote:
> > > > > On Tue, 19 Feb 2019 at 14:56, Steve Capper <Steve.Capper@arm.com> wrote:
> > > > > >
> > > > > > On Tue, Feb 19, 2019 at 02:15:26PM +0100, Ard Biesheuvel wrote:
> > > > > > > On Tue, 19 Feb 2019 at 14:01, Will Deacon <will.deacon@arm.com> wrote:
> > > > > > > >
> > > > > > > > On Tue, Feb 19, 2019 at 01:51:51PM +0100, Ard Biesheuvel wrote:
> > > > > > > > > On Tue, 19 Feb 2019 at 13:48, Will Deacon <will.deacon@arm.com> wrote:
> > > > > > > > > >
> > > > > > > > > > On Tue, Feb 19, 2019 at 01:13:32PM +0100, Ard Biesheuvel wrote:
> > > > > > > > > > > On Mon, 18 Feb 2019 at 18:05, Steve Capper <steve.capper@arm.com> wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > This patch series adds support for 52-bit kernel VAs using some of the
> > > > > > > > > > > > machinery already introduced by the 52-bit userspace VA code in 5.0.
> > > > > > > > > > > >
> > > > > > > > > > > > As 52-bit virtual address support is an optional hardware feature,
> > > > > > > > > > > > software support for 52-bit kernel VAs needs to be deduced at early boot
> > > > > > > > > > > > time. If HW support is not available, the kernel falls back to 48-bit.
> > > > > > > > > > > >
> > > > > > > > > > > > A significant proportion of this series focuses on "de-constifying"
> > > > > > > > > > > > VA_BITS related constants.
> > > > > > > > > > > >
> > > > > > > > > > > > In order to allow for a KASAN shadow that changes size at boot time, one
> > > > > > > > > > > > must fix the KASAN_SHADOW_END for both 48 & 52-bit VAs and "grow" the
> > > > > > > > > > > > start address. Also, it is highly desirable to maintain the same
> > > > > > > > > > > > function addresses in the kernel .text between VA sizes. Both of these
> > > > > > > > > > > > requirements necessitate us to flip the kernel address space halves s.t.
> > > > > > > > > > > > the direct linear map occupies the lower addresses.
> > > > > > > > > > > >
> > > > > > > > > > > > One obvious omission is 52-bit kernel VA + 48-bit userspace VA which I
> > > > > > > > > > > > can add with some more #ifdef'ery if needed.
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > Hi Steve,
> > > > > > > > > > >
> > > > > > > > > > > Apologies if I am bringing up things that have been addressed
> > > > > > > > > > > internally already. We discussed the 52-bit kernel VA work at
> > > > > > > > > > > plumber's at some point, and IIUC, KASAN is the complicating factor
> > > > > > > > > > > when it comes to having compile time constants for VA_BITS_MIN,
> > > > > > > > > > > VA_BITS_MAX and PAGE_OFFSET, right?
> > > > > > > > > > >
> > > > > > > > > > > To clarify what I mean, please refer to the diagram below, which
> > > > > > > > > > > describes a hybrid 48/52 kernel VA arrangement that does not rely on
> > > > > > > > > > > runtime variable quantities. (VA_BITS_MIN == 48, VA_BITS_MAX == 52)
> > > > > > > > > > >
> > > > > > > > > > > +------------------- (~0) -------------------------+
> > > > > > > > > > > |                                                |
> > > > > > > > > > > |            PCI IO / fixmap spaces              |
> > > > > > > > > > > |                                                |
> > > > > > > > > > > +------------------------------------------------+
> > > > > > > > > > > |                                                |
> > > > > > > > > > > |             kernel/vmalloc space               |
> > > > > > > > > > > |                                                |
> > > > > > > > > > > +------------------------------------------------+
> > > > > > > > > > > |                                                |
> > > > > > > > > > > |                module space                    |
> > > > > > > > > > > |                                                |
> > > > > > > > > > > +------------------------------------------------+
> > > > > > > > > > > |                                                |
> > > > > > > > > > > |                BPF space                       |
> > > > > > > > > > > |                                                |
> > > > > > > > > > > +------------------------------------------------+
> > > > > > > > > > > |                                                |
> > > > > > > > > > > |                                                |
> > > > > > > > > > > |   vmemmap space (size based on VA_BITS_MAX)    |
> > > > > > > > > > > |                                                |
> > > > > > > > > > > |                                                |
> > > > > > > > > > > +-- linear/vmalloc split based on VA_BITS_MIN -- +
> > > > > > > > > > > |                                                |
> > > > > > > > > > > |    linear mapping (48 bit addressable region)  |
> > > > > > > > > > > |                                                |
> > > > > > > > > > > +------------------------------------------------+
> > > > > > > > > > > |                                                |
> > > > > > > > > > > |    linear mapping (52 bit addressable region)  |
> > > > > > > > > > > |                                                |
> > > > > > > > > > > +------ PAGE_OFFSET based on VA_BITS_MAX --------+
> > > > > > > > > > >
> > > > > > > > > > > Since KASAN is what is preventing this, would it be acceptable for
> > > > > > > > > > > KASAN to only be supported when you use a true 48 bit or a true 52 bit
> > > > > > > > > > > configuration, and disable it for the 48/52 hybrid configuration?
> > > > > > > > > > >
> > > > > > > > > > > Just thinking out loud (and in ASCII art :-))
> > > > > > > > > >
> > > > > > > > > > TBH, if we end up having support for 52-bit kernel VA, I'd be inclined to
> > > > > > > > > > drop the 48/52 configuration altogether. But Catalin's on holiday at the
> > > > > > > > > > moment, and may have a different opinion ;)
> > > > > > > > > >
> > > > > > > > >
> > > > > > > > > But that implies that you cannot have an image that supports 52-bit
> > > > > > > > > kernel VAs but can still boot on hardware that does not implement
> > > > > > > > > support for it. If that is acceptable, then none of this hoop jumping
> > > > > > > > > that Steve is doing in these patches is necessary to begin with,
> > > > > > > > > right?
> > > > > > > >
> > > > > > > > Sorry, I misunderstood what you meant by a "48/52 hybrid configuration". I
> > > > > > > > thought you were referring to the configuration where userspace is 52-bit
> > > > > > > > and the kernel is 48-bit, which is something I think we can drop if we gain
> > > > > > > > support for 52-bit kernel.
> > > > > > > >
> > > > > > > > Now that I understand what you mean, I think disabling KASAN would be fine
> > > > > > > > as long as it's a runtime thing and the kernel continues to work in every
> > > > > > > > other respect.
> > > > > > > >
> > > > > > >
> > > > > > > No, it would be a limitation of the 52-bit config which also supports
> > > > > > > 48-bit-VA-only-h/w that the address space is laid out in such a way
> > > > > > > that there is simply no room for the KASAN shadow region, since it
> > > > > > > would have to live in the 48-bit addressable area, but be big enough
> > > > > > > to cover 52 bits of VA, which is impossible.
> > > > > > >
> > > > > > > For the vmemmap space, we could live with sizing it statically to
> > > > > > > cover a 52-bit VA linear region, but the KASAN shadow region is simply
> > > > > > > too big.
> > > > > > >
> > > > > > > So if KASAN support in that configuration is a requirement, then I
> > > > > > > agree with Steve's approach, but it does imply that quite a number of
> > > > > > > formerly compile-time constants now get turned into runtime variables.
> > > > > > >
> > > > > > > Steve, do you have any idea what the impact of that is?
> > > > > >
> > > > > > Hi Guys,
> > > > > >
> > > > > > The KASAN region only really necessitates two things: 1) that we think
> > > > > > about the end address of the region (which is invariant) rather than the
> > > > > > start address; and that 2) we flip the kernel VA space. IIUC both these
> > > > > > changes have a neglible perf impact.
> > > > > >
> > > > > > As for VA_BITS_ACTUAL, we need this in a few places: KVM mapping
> > > > > > support, and the big one phys_to/from_virt. For phys_to/from_virt the
> > > > > > logic is changed s.t. we use a variable lookup for translation but this
> > > > > > is folded into a new variable physvirt_offset (before the patch we used
> > > > > > a single variable read too).
> > > > > >
> > > > > > Again IIUC there should be a minimal perf impact (unless one tries to do
> > > > > > cat /sys/kernel/debug/kernel_page_tables with KASAN enabled - but that
> > > > > > can be optimised later).
> > > > > >
> > > > > > I didn't have the patience for ASCII art ;-), but I have a picture of
> > > > > > what I think it looks like here:
> > > > > > https://s3.amazonaws.com/connect.linaro.org/yvr18/presentations/yvr18-119.pdf
> > > > > > What I've tried to do is have most parts of the kernel VA space
> > > > > > invariant between 48/52 bits. If it's helpful I can type this up into a
> > > > > > document/commit log message?
> > > > > >
> > > > > > For this series I have tried to introduce VA_BITS_MIN in its own patch
> > > > > > and also VA_BITS_ACTUAL into its own patch to make it easier to follow.
> > > > > >
> > > >
> > > > Hi Ard,
> > > >
> > > > Apologies for my late reply, I had been staring at this for a while.
> > > >
> > > > >
> > > > > OK, perhaps I am just rephrasing what you essentially implemented
> > > > > already, but let me try to explain a bit better what I mean:
> > > > >
> > > > > - we flip the VA space in the way you suggest
> > > > > - we limit the size of the top half of the address space to 47 bits
> > > > > - KASAN region growns downwards from (~0) << 47
> > > > > - we define PAGE_OFFSET as (~0) << 52, regardless of whether the h/w
> > > > > supports LVA or not
> > > > > - however, we tweak the phys/virt translation so that memory appears
> > > > > in the 48-bit addressable part of the linear region on non-LVA
> > > > > hardware
> > > > >
> > > > > The latter basically means that the KASAN shadow region will intersect
> > > > > the linear region, but whether we map memory or shadow pages there
> > > > > depends on the h/w config at runtime.
> > > > >
> > > > > The heart of the matter is probably the different placement of the
> > > > > memory inside the linear region, depending on whether the h/w is LVA
> > > > > capable or not, which is also reflected in your physvirt_offset. I am
> > > > > just trying to figure out why we need VA_BITS_ACTUAL to be a runtime
> > > > > variable.
> > > >
> > > > Currently the direct linear map between configurations does not overlap,
> > > > we have:
> > > >
> > > > FFF00000_00000000 - Direct linear map start (52-bit)
> > > > FFF80000_00000000 - Direct linear map end (52-bit)
> > > > FFFF0000_00000000 - Direct linear map start (48-bit)
> > > > FFFF8000_00000000 - Direct linear map end (48-bit)
> > > >
> > > > We *can* make PAGE_OFFSET a constant for both 48/52 bit VA_BITS, if we
> > > > offset it. vmemmap can then be adjusted on early boot to ensure that
> > > > everything points to the right place. However we will get overlap for
> > > > 52-bit configurations between KASAN and the direct linear map.
> > > >
> > > > The question is: are we okay with quite a large overlap?
> > > >
> > > > The KASAN region begins on 0xFFFDA000_00000000 for 52-bit. If we wish to
> > > > employ a "full" 47-bit direct linear map on 48-bit systems we need a
> > > > PAGE_OFFSET of 0xFFF78000_00000000 in order to make the direct linear
> > > > map end addresses "match up" between 48/52 bit configurations.
> > > >
> > > > This doesn't leave us with a lot of room for 52-bit configurations
> > > > though, if KASAN is enabled.
> > > >
> > >
> > > OK, so with actual numbers, what I had in mind was
> > >
> > >
> > > FFF00000_00000000  start of 52-bit addressable linear region | PAGE_OFFSET
> > >
> > > FFFD8000_00000000  start of KASAN shadow region | KASAN_SHADOW_OFFSET
> > >
> > > FFFF0000_00000000  start of 48-bit addressable linear region
> > >
> > > FFFF6000_00000000  start of used KASAN shadow region (48-bit VA)
> > >                    (KASAN_SHADOW_OFFSET + F0000_00000000 >> 3)
> > >
> > > FFFF8000_00000000  start of vmemmap area - end of KASAN shadow region
> > >
> > > FFFF8200_00000000  end of vmemmap area - start of bpf/module/etc area
> > >
> > >
> > > The trick is that the full (52 - 3) bits KASAN shadow space overlaps
> > > with the 48-bit linear region, but since you don't need KASAN shadow
> > > pages for memory that does not exist, the region FFFF0000_00000000 -
> > > FFFF6000_00000000 can be used for mapping the memory in case the h/w
> > > is 48-bit only.
> > >
> > > So in this case, PAGE_OFFSET and KASAN_SHADOW_OFFSET remain compile
> > > time constants, and as long as we don't attempt to map anything
> > > outside of the 48-bit addressable area on h/w that does not support
> > > it, the fact that those quantities are outside the 48-bit range does
> > > not really matter.
> >
> > Thanks Ard,
> > I'll elaborate more on what I'm worrying about :-).
> >
> > The 48/52 bit linear regions above do not overlap and this creates the
> > following issue.
> >
> 
> OK, I see what you mean (I think). In my proposal, the linear regions
> *do* overlap.
> 
> In my example, the vmemmap region is only sized to cover 51 bits of
> linear region, but this is not sufficient, since the 52-bit linear
> region is actually bigger than that.
> 

Ahhhh, okay, nice (sorry I didn't parse your numbers correctly before).

> So based on a linear region that goes from
> 
> FFF0_0000_0000_0000 ... FFFF_8000_0000_0000
> 
> we would end up with a vmemmap region
> 
> FFFF_8000_0000_0000 ... FFFF_83E0_0000_0000
> 
> covering the entire combined linear region.  This is a fair chunk of
> the vmalloc space for 48-bit configuration, but I don't think that is
> anything to worry about.
> 
> > To go from a struct page * to a linear address we do the following:
> > lva = (page - VMEMMAP_START) * PAGE_SIZE / sizeof(struct page) + PAGE_OFFSET
> >
> 
> OK, so given the above correction, we can take
> 
> VMEMMAP_START := FFFF_8000_0000_0000
> PAGE_OFFSET := FFF0_0000_0000_0000
> 
> and everything still adds up afaict, and struct pages in the 48-bit VA
> region are covered from FFFF_83C0_0000_0000 and up.
> 
> > (Before my series) all the constants are fixed at compile time and thus
> > translation is very quick. My understanding is that you would like
> > PAGE_OFFSET to be constant to preserve the optimised nature of this
> > transform? (if not, please shout :-) )
> >
> 
> Yes, the main idea is to have compile time constants for PAGE_OFFSET,
> VA_BITS, etc
> 
> > The problem is that a 52-bit PAGE_OFFSET = 0xFFF00000_00000000 will
> > never be able to give us an lva within a 48-bit addressable range. At
> > best we will get an lva of FFF80000_00000000.
> >
> 
> You are assuming that we have to split the address space down the
> middle, but I don't think that is necessary at all.
> 

Agreed, some minor tweaks are needed to some helper functions to allow
for this.

Many thanks Ard, I'll give this a go.

Cheers,
-- 
Steve

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 9/9] arm64: mm: Introduce 52-bit Kernel VAs
  2019-02-18 17:02 ` [PATCH 9/9] arm64: mm: Introduce 52-bit Kernel VAs Steve Capper
@ 2019-03-25 18:17   ` Catalin Marinas
  0 siblings, 0 replies; 29+ messages in thread
From: Catalin Marinas @ 2019-03-25 18:17 UTC (permalink / raw)
  To: Steve Capper
  Cc: marc.zyngier, crecklin, will.deacon, linux-arm-kernel, ard.biesheuvel

On Mon, Feb 18, 2019 at 05:02:45PM +0000, Steve Capper wrote:
> @@ -721,6 +724,7 @@ config ARM64_VA_BITS_48
>  config ARM64_USER_VA_BITS_52
>  	bool "52-bit (user)"
>  	depends on ARM64_64K_PAGES && (ARM64_PAN || !ARM64_SW_TTBR0_PAN)
> +	select HAS_VA_BITS_52
>  	help
>  	  Enable 52-bit virtual addressing for userspace when explicitly
>  	  requested via a hint to mmap(). The kernel will continue to
> @@ -733,11 +737,28 @@ config ARM64_USER_VA_BITS_52
>  
>  	  If unsure, select 48-bit virtual addressing instead.
>  
> +config ARM64_USER_KERNEL_VA_BITS_52
> +	bool "52-bit (user & kernel)"
> +	depends on ARM64_64K_PAGES && (ARM64_PAN || !ARM64_SW_TTBR0_PAN)
> +	select HAS_VA_BITS_52
> +	help
> +	  Enable 52-bit virtual addressing for userspace when explicitly
> +	  requested via a hint to mmap(). The kernel will also use 52-bit
> +	  virtual addresses for its own mappings (provided HW support for
> +	  this feature is available, otherwise it reverts to 48-bit).
> +
> +	  NOTE: Enabling 52-bit virtual addressing in conjunction with
> +	  ARMv8.3 Pointer Authentication will result in the PAC being
> +	  reduced from 7 bits to 3 bits, which may have a significant
> +	  impact on its susceptibility to brute-force attacks.
> +
> +	  If unsure, select 48-bit virtual addressing instead.
> +
>  endchoice

Is there any value in having separate USER_VA_BITS_52? I'd rather squash
both kernel and user into a single ARM64_VA_BITS_52

-- 
Catalin

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-02-28 11:22                     ` Ard Biesheuvel
  2019-02-28 11:45                       ` Steve Capper
@ 2019-03-25 18:38                       ` Catalin Marinas
  2019-03-25 20:32                         ` Ard Biesheuvel
  1 sibling, 1 reply; 29+ messages in thread
From: Catalin Marinas @ 2019-03-25 18:38 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: crecklin, Steve Capper, Marc Zyngier, Will Deacon, nd, linux-arm-kernel

On Thu, Feb 28, 2019 at 12:22:09PM +0100, Ard Biesheuvel wrote:
> On Thu, 28 Feb 2019 at 11:36, Steve Capper <Steve.Capper@arm.com> wrote:
> > The 48/52 bit linear regions above do not overlap and this creates the
> > following issue.
> 
> OK, I see what you mean (I think). In my proposal, the linear regions
> *do* overlap.
> 
> In my example, the vmemmap region is only sized to cover 51 bits of
> linear region, but this is not sufficient, since the 52-bit linear
> region is actually bigger than that.
> 
> So based on a linear region that goes from
> 
> FFF0_0000_0000_0000 ... FFFF_8000_0000_0000
> 
> we would end up with a vmemmap region
> 
> FFFF_8000_0000_0000 ... FFFF_83E0_0000_0000
> 
> covering the entire combined linear region.  This is a fair chunk of
> the vmalloc space for 48-bit configuration, but I don't think that is
> anything to worry about.

So that's about 42-bit for vmemmap (my calculations were 2^(52-16+6),
assuming a 64 byte sizeof(page)), so 1/64 of the 48-bit va space. I
don't think that's a problem.

> > To go from a struct page * to a linear address we do the following:
> > lva = (page - VMEMMAP_START) * PAGE_SIZE / sizeof(struct page) + PAGE_OFFSET
> 
> OK, so given the above correction, we can take
> 
> VMEMMAP_START := FFFF_8000_0000_0000
> PAGE_OFFSET := FFF0_0000_0000_0000
> 
> and everything still adds up afaict, and struct pages in the 48-bit VA
> region are covered from FFFF_83C0_0000_0000 and up.
> 
> > (Before my series) all the constants are fixed at compile time and thus
> > translation is very quick. My understanding is that you would like
> > PAGE_OFFSET to be constant to preserve the optimised nature of this
> > transform? (if not, please shout :-) )
> 
> Yes, the main idea is to have compile time constants for PAGE_OFFSET,
> VA_BITS, etc

If we can have all of the constant, it would be great (we managed from
the early versions of the patch to have VA_BITS constant).

I have to figure out the KASan story with this (still parsing this
thread). Can we still get KASan and single-image in the 52-bit VA
configuration? Or, at least, not have the kernel fall apart if a 52-bit
image is booted on 48-bit hw with KASan enabled, whether KASan still
works or not (to get the chance to print some warning)?

-- 
Catalin

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-03-25 18:38                       ` Catalin Marinas
@ 2019-03-25 20:32                         ` Ard Biesheuvel
  0 siblings, 0 replies; 29+ messages in thread
From: Ard Biesheuvel @ 2019-03-25 20:32 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: crecklin, Steve Capper, Marc Zyngier, Will Deacon, nd, linux-arm-kernel

On Mon, 25 Mar 2019 at 19:38, Catalin Marinas <catalin.marinas@arm.com> wrote:
>
> On Thu, Feb 28, 2019 at 12:22:09PM +0100, Ard Biesheuvel wrote:
> > On Thu, 28 Feb 2019 at 11:36, Steve Capper <Steve.Capper@arm.com> wrote:
> > > The 48/52 bit linear regions above do not overlap and this creates the
> > > following issue.
> >
> > OK, I see what you mean (I think). In my proposal, the linear regions
> > *do* overlap.
> >
> > In my example, the vmemmap region is only sized to cover 51 bits of
> > linear region, but this is not sufficient, since the 52-bit linear
> > region is actually bigger than that.
> >
> > So based on a linear region that goes from
> >
> > FFF0_0000_0000_0000 ... FFFF_8000_0000_0000
> >
> > we would end up with a vmemmap region
> >
> > FFFF_8000_0000_0000 ... FFFF_83E0_0000_0000
> >
> > covering the entire combined linear region.  This is a fair chunk of
> > the vmalloc space for 48-bit configuration, but I don't think that is
> > anything to worry about.
>
> So that's about 42-bit for vmemmap (my calculations were 2^(52-16+6),
> assuming a 64 byte sizeof(page)), so 1/64 of the 48-bit va space. I
> don't think that's a problem.
>
> > > To go from a struct page * to a linear address we do the following:
> > > lva = (page - VMEMMAP_START) * PAGE_SIZE / sizeof(struct page) + PAGE_OFFSET
> >
> > OK, so given the above correction, we can take
> >
> > VMEMMAP_START := FFFF_8000_0000_0000
> > PAGE_OFFSET := FFF0_0000_0000_0000
> >
> > and everything still adds up afaict, and struct pages in the 48-bit VA
> > region are covered from FFFF_83C0_0000_0000 and up.
> >
> > > (Before my series) all the constants are fixed at compile time and thus
> > > translation is very quick. My understanding is that you would like
> > > PAGE_OFFSET to be constant to preserve the optimised nature of this
> > > transform? (if not, please shout :-) )
> >
> > Yes, the main idea is to have compile time constants for PAGE_OFFSET,
> > VA_BITS, etc
>
> If we can have all of the constant, it would be great (we managed from
> the early versions of the patch to have VA_BITS constant).
>
> I have to figure out the KASan story with this (still parsing this
> thread). Can we still get KASan and single-image in the 52-bit VA
> configuration? Or, at least, not have the kernel fall apart if a 52-bit
> image is booted on 48-bit hw with KASan enabled, whether KASan still
> works or not (to get the chance to print some warning)?
>

It should work in both cases, but there will be a part of the linear
region that is used as KASAN shadow on 52-bit hardware, and as a
linear mapping on 48-bit hardware. I'm pretty sure this shouldn't be a
problem, but someone has to double check (and perhaps some boundary
definition macros for KASAN need to be turned into runtime variables)

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-02-18 17:02 [PATCH 0/9] 52-bit kernel + user VAs Steve Capper
                   ` (9 preceding siblings ...)
  2019-02-19 12:13 ` [PATCH 0/9] 52-bit kernel + user VAs Ard Biesheuvel
@ 2019-04-03  8:09 ` Bhupesh Sharma
  2019-05-03 14:57   ` Steve Capper
  10 siblings, 1 reply; 29+ messages in thread
From: Bhupesh Sharma @ 2019-04-03  8:09 UTC (permalink / raw)
  To: Steve Capper, linux-arm-kernel
  Cc: crecklin, Ard Biesheuvel, marc.zyngier, Catalin Marinas,
	Suzuki K Poulose, will.deacon, Dave Anderson, James Morse,
	Bhupesh SHARMA

Hi Steve,

On 02/18/2019 10:32 PM, Steve Capper wrote:
> This patch series adds support for 52-bit kernel VAs using some of the
> machinery already introduced by the 52-bit userspace VA code in 5.0.
> 
> As 52-bit virtual address support is an optional hardware feature,
> software support for 52-bit kernel VAs needs to be deduced at early boot
> time. If HW support is not available, the kernel falls back to 48-bit.
> 
> A significant proportion of this series focuses on "de-constifying"
> VA_BITS related constants.
> 
> In order to allow for a KASAN shadow that changes size at boot time, one
> must fix the KASAN_SHADOW_END for both 48 & 52-bit VAs and "grow" the
> start address. Also, it is highly desirable to maintain the same
> function addresses in the kernel .text between VA sizes. Both of these
> requirements necessitate us to flip the kernel address space halves s.t.
> the direct linear map occupies the lower addresses.
> 
> One obvious omission is 52-bit kernel VA + 48-bit userspace VA which I
> can add with some more #ifdef'ery if needed.

Thanks for the patchset.

I did some work on the user-space side to see how user-space tools like 
makedumpfile and kexec-tools are affected by these changes. I see that 
Dave Anderson (in Cc) also did some work on crash-utility side [0] to 
have the basic framework in place to have the user-space tools work with 
the inverted memory map.

I have a couple of concerns regarding:

1. VA_BITS_ACTUAL, and how user-space gets to know its value.

2. Overall bits that we need to be aware in user-space now to address 
the following combinations of address space (phew ..):

a) 48-bit Kernel VA + 48-bit User-space VA + 48-bit PA
b) 48-bit Kernel VA + 48-bit User-space VA + 52-bit PA
c) 48-bit Kernel VA + 52-bit User-space VA + 52-bit PA
d) 52-bit Kernel VA + 52-bit User-space VA + 52-bit PA
e) 52-bit Kernel VA + 48-bit User-space VA + 52-bit PA (is this even 
used-somewhere? Not sure but James [in Cc] had some queries on this [1]. 
Personally, I am not aware of any users of this combination).

I have added detailed comments/concerns in individual patches in mails 
to follow regarding the above points.

[0]. 
https://github.com/crash-utility/crash/commit/b0b3ef2eda543413762b32710b8a63dd9ed55de5
[1]. http://lists.infradead.org/pipermail/kexec/2019-April/022729.html

Thanks,
Bhupesh


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 8/9] arm64: mm: Logic to make offset_ttbr1 conditional
  2019-02-18 17:02 ` [PATCH 8/9] arm64: mm: Logic to make offset_ttbr1 conditional Steve Capper
@ 2019-04-03 11:26   ` Bhupesh Sharma
  0 siblings, 0 replies; 29+ messages in thread
From: Bhupesh Sharma @ 2019-04-03 11:26 UTC (permalink / raw)
  To: Steve Capper, linux-arm-kernel
  Cc: crecklin, ard.biesheuvel, marc.zyngier, Catalin Marinas,
	Suzuki K Poulose, will.deacon, Dave Anderson, James Morse,
	Bhupesh SHARMA, kexec

Hi Steve,

On 02/18/2019 10:32 PM, Steve Capper wrote:
> When running with a 52-bit userspace VA and a 48-bit kernel VA we offset
> ttbr1_el1 to allow the kernel pagetables with a 52-bit PTRS_PER_PGD to
> be used for both userspace and kernel.
> 
> Moving on to a 52-bit kernel VA we no longer require this offset to
> ttbr1_el1 should we be running on a system with HW support for 52-bit
> VAs.
> 
> This patch introduces alternative logic to offset_ttbr1 and expands out
> the very early case in head.S. We need to use the alternative framework
> as offset_ttbr1 is used in places in the kernel where it is not possible
> to safely adrp address kernel constants (such as the kpti paths); thus
> code patching is the safer route.
> 
> Signed-off-by: Steve Capper <steve.capper@arm.com>
> ---
>   arch/arm64/include/asm/assembler.h | 10 +++++++++-
>   arch/arm64/include/asm/cpucaps.h   |  3 ++-
>   arch/arm64/kernel/cpufeature.c     | 18 ++++++++++++++++++
>   arch/arm64/kernel/head.S           | 14 +++++++++++++-
>   arch/arm64/kernel/hibernate-asm.S  |  1 +
>   5 files changed, 43 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
> index 4feb6119c3c9..58ed5d086e1e 100644
> --- a/arch/arm64/include/asm/assembler.h
> +++ b/arch/arm64/include/asm/assembler.h
> @@ -551,6 +551,14 @@ USER(\label, ic	ivau, \tmp2)			// invalidate I line PoU
>   	.macro	offset_ttbr1, ttbr
>   #ifdef CONFIG_ARM64_USER_VA_BITS_52
>   	orr	\ttbr, \ttbr, #TTBR1_BADDR_4852_OFFSET
> +#endif
> +
> +#ifdef CONFIG_ARM64_USER_KERNEL_VA_BITS_52
> +alternative_if_not ARM64_HAS_52BIT_VA
> +	orr	\ttbr, \ttbr, #TTBR1_BADDR_4852_OFFSET
> +alternative_else
> +	nop
> +alternative_endif
>   #endif
>   	.endm
>   
> @@ -560,7 +568,7 @@ USER(\label, ic	ivau, \tmp2)			// invalidate I line PoU
>    * to be nop'ed out when dealing with 52-bit kernel VAs.
>    */
>   	.macro	restore_ttbr1, ttbr
> -#ifdef CONFIG_ARM64_USER_VA_BITS_52
> +#if defined(CONFIG_ARM64_USER_VA_BITS_52) || defined(CONFIG_ARM64_KERNEL_VA_BITS_52)
>   	bic	\ttbr, \ttbr, #TTBR1_BADDR_4852_OFFSET
>   #endif
>   	.endm
> diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
> index 82e9099834ae..d71aecb6d6db 100644
> --- a/arch/arm64/include/asm/cpucaps.h
> +++ b/arch/arm64/include/asm/cpucaps.h
> @@ -60,7 +60,8 @@
>   #define ARM64_HAS_ADDRESS_AUTH_IMP_DEF		39
>   #define ARM64_HAS_GENERIC_AUTH_ARCH		40
>   #define ARM64_HAS_GENERIC_AUTH_IMP_DEF		41
> +#define ARM64_HAS_52BIT_VA			42
>   
> -#define ARM64_NCAPS				42
> +#define ARM64_NCAPS				43
>   
>   #endif /* __ASM_CPUCAPS_H */
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index f6d84e2c92fe..2e150c564f2a 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -944,6 +944,16 @@ has_useable_cnp(const struct arm64_cpu_capabilities *entry, int scope)
>   	return has_cpuid_feature(entry, scope);
>   }
>   
> +#ifdef CONFIG_ARM64_USER_KERNEL_VA_BITS_52
> +extern u64 vabits_actual;
> +static bool __maybe_unused
> +has_52bit_kernel_va(const struct arm64_cpu_capabilities *entry, int scope)
> +{
> +	return vabits_actual == 52;
> +}
> +
> +#endif /* CONFIG_ARM64_USER_KERNEL_VA_BITS_52 */
> +
>   #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
>   static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */
>   
> @@ -1480,6 +1490,14 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
>   		.matches = has_cpuid_feature,
>   	},
>   #endif /* CONFIG_ARM64_PTR_AUTH */
> +#ifdef CONFIG_ARM64_USER_KERNEL_VA_BITS_52
> +	{
> +		.desc = "52-bit kernel VA",
> +		.capability = ARM64_HAS_52BIT_VA,
> +		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
> +		.matches = has_52bit_kernel_va,
> +	},
> +#endif /* CONFIG_ARM64_USER_KERNEL_VA_BITS_52 */
>   	{},
>   };

Right, so now the question is how do we export the 52-bit VA properties 
(that we select in the kernel) to user-space. There are two things to 
consider:

a). CPUs which support ARMv8.2-LVA + newer kernels which export 52-bit 
address capabilities:

- Right now, neither the cpu-feature-registers interface (see [1]) nor 
the HWCAPS interface (see [2]), provide a mechanism to export these 
properties to the user-space.

- I had shared a patch in the past for enabling atleast LVA and LPA 
extension bits to be exported via the cpu-feature-registers interface 
(See: 
http://lists.infradead.org/pipermail/kexec/2019-January/022371.html), 
but we didn't make much progress on the same.

May be Suzuki (in Cc), will have more comments on the same.

[1]. 
https://www.kernel.org/doc/Documentation/arm64/cpu-feature-registers.txt
[2]. https://www.kernel.org/doc/Documentation/arm64/elf_hwcaps.txt

b). CPUs which do not support ARMv8.2-LVA + newer kernels which export 
52-bit address capabilities:

- Right now, for older CPUs running with kernels with 
CONFIG_ARM64_USER_KERNEL_VA_BITS_52=y, if we have:

VA_BITS = 52,
VA_BITS_ACTUAL = vabits_actual = 48,
VA_BITS_MIN = min (48, VA_BITS) = 48.

Now, we need to make user-space aware of the VA_BITS_ACTUAL value, so 
that it can process virtual addresses. Let's consider two different 
use-cases which are normally used to debug live-kernel or debug crashes 
(via kdump):

- Calculating 'vaddr_to_paddr' for a given vaddr (provided to user-space 
for e.g from /proc/kcore file).

A). An essential part of the calculation is to know if the provided 
vaddr lies in the linear map range. In kernel, we use the following 
computation to determine whether an address lies in the linear map range:

#define __is_lm_address(addr)	(!((addr) & BIT(VA_BITS_ACTUAL - 1)))

A similar check is performed in user-space utilities while performing 
live debugging to determine paddr value for a given vaddr (for 
performing a page-table walk).

So, we need a mechanism to have the VA_BITS_ACTUAL value in user-space.
Reading kernel CONFIG flags, vmlinux information and /proc/kallsyms is 
not a portable approach for all user-space use-cases, hence we need a 
standard method of exporting this information to user-space.

May be something like a 
'/sys/devices/system/cpu/addressing-capabilities' node? (similar to 
'/sys/devices/system/cpu/vulnerabilities' we added for sideband 
vulnerabilities).

I understand that it may be difficult to standardize a 'sysfs' 
placeholder for different archs for addressing ranges, but I am just 
thinking out loud here.

May be something like:

+ssize_t cpu_show_address_capabilities(struct device *dev, struct 
device_attribute *attr,
+			    char *buf)
+{
+	return sprintf(buf, "va_bits_actual: %ld\n", vabits_actual);
+}

and more..

See 
<https://github.com/torvalds/linux/blob/master/arch/x86/kernel/cpu/bugs.c#L1188> 
for an example.

B). Debugging a crash dump obtained on one arm64 system (say a 
reporter's machine with VA_BITS_ACTUAL = 48) on another arm64 system 
(say the maintainer's machine with VA_BITS_ACTUAL = 52)

So, we again need a mechanism to have the VA_BITS_ACTUAL value in crash 
vmcore dump'ed on the reporter's machine.

Note, that reading kernel CONFIG flags, vmlinux information or 
/proc/kallsyms on the maintainer's machine will not help in such cases 
as they can be different from the configuration on the reporter's machine.

In such case, it is _mandatory_ to have VA_BITS_ACTUAL information 
exported in vmcoreinfo. Also since commit 23c85094fe18 ("proc/kcore: add 
vmcoreinfo note to /proc/kcore"), we have the same information available 
in kcore.

So, it would make sense to have the following patch for exporting 
VA_BITS_ACTUAL information in vmcoreinfo. I would suggest that we have 
the same added in the re-worked version v2 of the patchset so that the 
user-space works as expected:

----------------------------x

 From 0a4f30357932bf2addd1dda66acde8c26ecd3f75 Mon Sep 17 00:00:00 2001
From: Bhupesh Sharma <bhsharma@redhat.com>
Date: Wed, 3 Apr 2019 16:27:10 +0530
Subject: [PATCH] arm64/crash_core: Export VA_BITS_ACTUAL in vmcoreinfo

VA_BITS_ACTUAL indicates the actual VA_BITS detected at boot time which
is required for determining 52-bit kernel address support at boot time.

User-space utilities like makedumpfile and crash-utility, need to
read/write this value from/to vmcoreinfo for determining if a virtual
address lies in the linear map range.

The user-space computation for determining whether an address lies in
the linear map range is the same as we have in kernel-space:

   #define __is_lm_address(addr)	(!((addr) & BIT(VA_BITS_ACTUAL - 1)))

Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
---
  Documentation/kdump/vmcoreinfo.txt | 7 +++++++
  arch/arm64/kernel/crash_core.c     | 1 +
  2 files changed, 8 insertions(+)

diff --git a/Documentation/kdump/vmcoreinfo.txt 
b/Documentation/kdump/vmcoreinfo.txt
index bb94a4bd597a..a23ae95e3a93 100644
--- a/Documentation/kdump/vmcoreinfo.txt
+++ b/Documentation/kdump/vmcoreinfo.txt
@@ -376,6 +376,13 @@ VA_BITS
  The maximum number of bits for virtual addresses. Used to compute the
  virtual memory ranges.

+VA_BITS_ACTUAL
+--------------
+
+Indicates the actual VA_BITS detected at boot time, i.e. the maximum
+number of bits for virtual addresses. Required for determing 52-bit kernel
+address support at boot time.
+
  kimage_voffset
  --------------

diff --git a/arch/arm64/kernel/crash_core.c b/arch/arm64/kernel/crash_core.c
index ca4c3e12d8c5..1cde442ce8b2 100644
--- a/arch/arm64/kernel/crash_core.c
+++ b/arch/arm64/kernel/crash_core.c
@@ -10,6 +10,7 @@
  void arch_crash_save_vmcoreinfo(void)
  {
  	VMCOREINFO_NUMBER(VA_BITS);
+	VMCOREINFO_NUMBER(VA_BITS_ACTUAL);
  	/* Please note VMCOREINFO_NUMBER() uses "%d", not "%x" */
  	vmcoreinfo_append_str("NUMBER(kimage_voffset)=0x%llx\n",
  						kimage_voffset);
-- 
2.7.4


Please let me know your views.

Thanks,
Bhupesh

> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index 68c391b26858..4877b82d2091 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -789,7 +789,19 @@ ENTRY(__enable_mmu)
>   	phys_to_ttbr x1, x1
>   	phys_to_ttbr x2, x2
>   	msr	ttbr0_el1, x2			// load TTBR0
> -	offset_ttbr1 x1
> +
> +#if defined(CONFIG_ARM64_USER_VA_BITS_52)
> +	orr     x1, x1, #TTBR1_BADDR_4852_OFFSET
> +#endif
> +
> +#if defined(CONFIG_ARM64_USER_KERNEL_VA_BITS_52)
> +	ldr_l	x3, vabits_actual
> +	cmp	x3, #52
> +	b.eq	1f
> +	orr     x1, x1, #TTBR1_BADDR_4852_OFFSET
> +1:
> +#endif
> +
>   	msr	ttbr1_el1, x1			// load TTBR1
>   	isb
>   	msr	sctlr_el1, x0
> diff --git a/arch/arm64/kernel/hibernate-asm.S b/arch/arm64/kernel/hibernate-asm.S
> index fe36d85c60bd..d32725a2b77f 100644
> --- a/arch/arm64/kernel/hibernate-asm.S
> +++ b/arch/arm64/kernel/hibernate-asm.S
> @@ -19,6 +19,7 @@
>   #include <linux/linkage.h>
>   #include <linux/errno.h>
>   
> +#include <asm/alternative.h>
>   #include <asm/asm-offsets.h>
>   #include <asm/assembler.h>
>   #include <asm/cputype.h>
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/9] arm64: mm: Flip kernel VA space
  2019-02-18 17:02 ` [PATCH 2/9] arm64: mm: Flip kernel VA space Steve Capper
@ 2019-04-03 11:44   ` Bhupesh Sharma
  0 siblings, 0 replies; 29+ messages in thread
From: Bhupesh Sharma @ 2019-04-03 11:44 UTC (permalink / raw)
  To: Steve Capper, linux-arm-kernel
  Cc: crecklin, ard.biesheuvel, marc.zyngier, catalin.marinas,
	will.deacon, James Morse, Bhupesh SHARMA, kexec

Hi Steve,

On 02/18/2019 10:32 PM, Steve Capper wrote:
> Put the direct linear map in the lower addresses of the kernel VA range
> and everything else in the higher ranges.
> 
> This allows us to make room for an inline KASAN shadow that operates
> under both 48 and 52 bit kernel VA sizes. For example with a 52-bit VA,
> if KASAN_SHADOW_END < 0xFFF8000000000000 (it is in the lower addresses
> of the kernel VA range), this will be below the start of the minimum
> 48-bit kernel VA address of 0xFFFF000000000000.
> 
> We need to adjust:
>   *) KASAN shadow region placement logic,
>   *) KASAN_SHADOW_OFFSET computation logic,
>   *) virt_to_phys, phys_to_virt checks,
>   *) page table dumper.
> 
> These are all small changes, that need to take place atomically, so they
> are bundled into this commit.

May be its a good opportunity to update the memory layout documentation 
(see [0]) with this patch, where we say:

AArch64 Linux memory layout with 64KB pages + 3 levels:

Start			End			Size		Use
-----------------------------------------------------------------------
0000000000000000	0000ffffffffffff	 256TB		user
ffff000000000000	ffffffffffffffff	 256TB		kernel

Now, with 52-bit addressing capabilities the kernel space would start 
from 0xFFF0_0000_0000_0000 and go all the way up to 0xFFFF_FFFF_FFFF_FFFF.

Also the 'Translation table lookup with 64KB pages:' section needs an 
update to indicate increased bits for 52-bit PA changes.

Alternatively we may want to have a doc dedicated to 52-bit address 
space details on arm64, similar to what we have currently for x86 (see 
[1a] and [1b]) where we can capture some of the details already 
available in your excellent talk on this subject (see [2]).

If you need any help with the same, do let me know.

[0]. https://www.kernel.org/doc/Documentation/arm64/memory.txt
[1a]. 
https://github.com/torvalds/linux/blob/master/Documentation/x86/x86_64/5level-paging.txt
[1b]. 
https://github.com/torvalds/linux/blob/master/Documentation/x86/x86_64/mm.txt
[2]. https://connect.linaro.org/resources/yvr18/sessions/yvr18-119/

Thanks,
Bhupesh

> Signed-off-by: Steve Capper <steve.capper@arm.com>
> ---
>   arch/arm64/Makefile              |  2 +-
>   arch/arm64/include/asm/memory.h  | 10 +++++-----
>   arch/arm64/include/asm/pgtable.h |  2 +-
>   arch/arm64/mm/dump.c             |  8 ++++----
>   arch/arm64/mm/init.c             |  9 +--------
>   arch/arm64/mm/kasan_init.c       |  6 +++---
>   arch/arm64/mm/mmu.c              |  4 ++--
>   7 files changed, 17 insertions(+), 24 deletions(-)
> 
> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> index b025304bde46..2dad2ae6b181 100644
> --- a/arch/arm64/Makefile
> +++ b/arch/arm64/Makefile
> @@ -115,7 +115,7 @@ KBUILD_AFLAGS += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT)
>   #				 - (1 << (64 - KASAN_SHADOW_SCALE_SHIFT))
>   # in 32-bit arithmetic
>   KASAN_SHADOW_OFFSET := $(shell printf "0x%08x00000000\n" $$(( \
> -	(0xffffffff & (-1 << ($(CONFIG_ARM64_VA_BITS) - 32))) \
> +	(0xffffffff & (-1 << ($(CONFIG_ARM64_VA_BITS) - 1 - 32))) \
>   	+ (1 << ($(CONFIG_ARM64_VA_BITS) - 32 - $(KASAN_SHADOW_SCALE_SHIFT))) \
>   	- (1 << (64 - 32 - $(KASAN_SHADOW_SCALE_SHIFT))) )) )
>   
> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index 617071dbad06..46a7aba44e9b 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -49,10 +49,10 @@
>    */
>   #define VA_BITS			(CONFIG_ARM64_VA_BITS)
>   #define VA_START		(UL(0xffffffffffffffff) - \
> -	(UL(1) << VA_BITS) + 1)
> -#define PAGE_OFFSET		(UL(0xffffffffffffffff) - \
>   	(UL(1) << (VA_BITS - 1)) + 1)
> -#define PAGE_OFFSET_END		(~0UL)
> +#define PAGE_OFFSET		(UL(0xffffffffffffffff) - \
> +	(UL(1) << VA_BITS) + 1)
> +#define PAGE_OFFSET_END		(VA_START)
>   #define KIMAGE_VADDR		(MODULES_END)
>   #define BPF_JIT_REGION_START	(VA_START + KASAN_SHADOW_SIZE)
>   #define BPF_JIT_REGION_SIZE	(SZ_128M)
> @@ -60,7 +60,7 @@
>   #define MODULES_END		(MODULES_VADDR + MODULES_VSIZE)
>   #define MODULES_VADDR		(BPF_JIT_REGION_END)
>   #define MODULES_VSIZE		(SZ_128M)
> -#define VMEMMAP_START		(PAGE_OFFSET - VMEMMAP_SIZE)
> +#define VMEMMAP_START		(-VMEMMAP_SIZE)
>   #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)
> @@ -243,7 +243,7 @@ extern u64			vabits_user;
>    * space. Testing the top bit for the start of the region is a
>    * sufficient check.
>    */
> -#define __is_lm_address(addr)	(!!((addr) & BIT(VA_BITS - 1)))
> +#define __is_lm_address(addr)	(!((addr) & BIT(VA_BITS - 1)))
>   
>   #define __lm_to_phys(addr)	(((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)
>   #define __kimg_to_phys(addr)	((addr) - kimage_voffset)
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index de70c1eabf33..766def2ed788 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -32,7 +32,7 @@
>    *	and fixed mappings
>    */
>   #define VMALLOC_START		(MODULES_END)
> -#define VMALLOC_END		(PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
> +#define VMALLOC_END		(- PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
>   
>   #define vmemmap			((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
>   
> diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c
> index 99bb8facb5cb..3dd9b884bd39 100644
> --- a/arch/arm64/mm/dump.c
> +++ b/arch/arm64/mm/dump.c
> @@ -30,6 +30,8 @@
>   #include <asm/ptdump.h>
>   
>   static const struct addr_marker address_markers[] = {
> +	{ PAGE_OFFSET,			"Linear Mapping start" },
> +	{ VA_START,			"Linear Mapping end" },
>   #ifdef CONFIG_KASAN
>   	{ KASAN_SHADOW_START,		"Kasan shadow start" },
>   	{ KASAN_SHADOW_END,		"Kasan shadow end" },
> @@ -43,10 +45,8 @@ static const struct addr_marker address_markers[] = {
>   	{ PCI_IO_START,			"PCI I/O start" },
>   	{ PCI_IO_END,			"PCI I/O end" },
>   #ifdef CONFIG_SPARSEMEM_VMEMMAP
> -	{ VMEMMAP_START,		"vmemmap start" },
> -	{ VMEMMAP_START + VMEMMAP_SIZE,	"vmemmap end" },
> +	{ VMEMMAP_START,		"vmemmap" },
>   #endif
> -	{ PAGE_OFFSET,			"Linear mapping" },
>   	{ -1,				NULL },
>   };
>   
> @@ -380,7 +380,7 @@ static void ptdump_initialize(void)
>   static struct ptdump_info kernel_ptdump_info = {
>   	.mm		= &init_mm,
>   	.markers	= address_markers,
> -	.base_addr	= VA_START,
> +	.base_addr	= PAGE_OFFSET,
>   };
>   
>   void ptdump_check_wx(void)
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 7205a9085b4d..0574e17fd28d 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -354,7 +354,7 @@ static void __init fdt_enforce_memory_region(void)
>   
>   void __init arm64_memblock_init(void)
>   {
> -	const s64 linear_region_size = -(s64)PAGE_OFFSET;
> +	const s64 linear_region_size = BIT(VA_BITS - 1);
>   
>   	/* Handle linux,usable-memory-range property */
>   	fdt_enforce_memory_region();
> @@ -362,13 +362,6 @@ void __init arm64_memblock_init(void)
>   	/* Remove memory above our supported physical address size */
>   	memblock_remove(1ULL << PHYS_MASK_SHIFT, ULLONG_MAX);
>   
> -	/*
> -	 * Ensure that the linear region takes up exactly half of the kernel
> -	 * virtual address space. This way, we can distinguish a linear address
> -	 * from a kernel/module/vmalloc address by testing a single bit.
> -	 */
> -	BUILD_BUG_ON(linear_region_size != BIT(VA_BITS - 1));
> -
>   	/*
>   	 * Select a suitable value for the base of physical memory.
>   	 */
> diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
> index 4b55b15707a3..ee5ec343d009 100644
> --- a/arch/arm64/mm/kasan_init.c
> +++ b/arch/arm64/mm/kasan_init.c
> @@ -219,10 +219,10 @@ void __init kasan_init(void)
>   	kasan_map_populate(kimg_shadow_start, kimg_shadow_end,
>   			   early_pfn_to_nid(virt_to_pfn(lm_alias(_text))));
>   
> -	kasan_populate_early_shadow((void *)KASAN_SHADOW_START,
> -				    (void *)mod_shadow_start);
> +	kasan_populate_early_shadow(kasan_mem_to_shadow((void *) VA_START),
> +				   (void *)mod_shadow_start);
>   	kasan_populate_early_shadow((void *)kimg_shadow_end,
> -				    kasan_mem_to_shadow((void *)PAGE_OFFSET));
> +				   (void *)KASAN_SHADOW_END);
>   
>   	if (kimg_shadow_start > mod_shadow_end)
>   		kasan_populate_early_shadow((void *)mod_shadow_end,
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index b6f5aa52ac67..7401a8481f78 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -389,7 +389,7 @@ static phys_addr_t pgd_pgtable_alloc(void)
>   static void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt,
>   				  phys_addr_t size, pgprot_t prot)
>   {
> -	if (virt < VMALLOC_START) {
> +	if ((virt >= VA_START) && (virt < VMALLOC_START)) {
>   		pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n",
>   			&phys, virt);
>   		return;
> @@ -416,7 +416,7 @@ void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
>   static void update_mapping_prot(phys_addr_t phys, unsigned long virt,
>   				phys_addr_t size, pgprot_t prot)
>   {
> -	if (virt < VMALLOC_START) {
> +	if ((virt >= VA_START) && (virt < VMALLOC_START)) {
>   		pr_warn("BUG: not updating mapping for %pa at 0x%016lx - outside kernel range\n",
>   			&phys, virt);
>   		return;
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] 52-bit kernel + user VAs
  2019-04-03  8:09 ` Bhupesh Sharma
@ 2019-05-03 14:57   ` Steve Capper
  0 siblings, 0 replies; 29+ messages in thread
From: Steve Capper @ 2019-05-03 14:57 UTC (permalink / raw)
  To: Bhupesh Sharma
  Cc: nd, crecklin, ard.biesheuvel, Marc Zyngier, Catalin Marinas,
	Suzuki Poulose, Will Deacon, Dave Anderson, James Morse,
	Bhupesh SHARMA, linux-arm-kernel

On Wed, Apr 03, 2019 at 01:39:36PM +0530, Bhupesh Sharma wrote:
> Hi Steve,
> 
> On 02/18/2019 10:32 PM, Steve Capper wrote:
> > This patch series adds support for 52-bit kernel VAs using some of the
> > machinery already introduced by the 52-bit userspace VA code in 5.0.
> > 
> > As 52-bit virtual address support is an optional hardware feature,
> > software support for 52-bit kernel VAs needs to be deduced at early boot
> > time. If HW support is not available, the kernel falls back to 48-bit.
> > 
> > A significant proportion of this series focuses on "de-constifying"
> > VA_BITS related constants.
> > 
> > In order to allow for a KASAN shadow that changes size at boot time, one
> > must fix the KASAN_SHADOW_END for both 48 & 52-bit VAs and "grow" the
> > start address. Also, it is highly desirable to maintain the same
> > function addresses in the kernel .text between VA sizes. Both of these
> > requirements necessitate us to flip the kernel address space halves s.t.
> > the direct linear map occupies the lower addresses.
> > 
> > One obvious omission is 52-bit kernel VA + 48-bit userspace VA which I
> > can add with some more #ifdef'ery if needed.
> 
> Thanks for the patchset.
> 
> I did some work on the user-space side to see how user-space tools like
> makedumpfile and kexec-tools are affected by these changes. I see that Dave
> Anderson (in Cc) also did some work on crash-utility side [0] to have the
> basic framework in place to have the user-space tools work with the inverted
> memory map.
> 
> I have a couple of concerns regarding:
> 
> 1. VA_BITS_ACTUAL, and how user-space gets to know its value.
> 
> 2. Overall bits that we need to be aware in user-space now to address the
> following combinations of address space (phew ..):
> 
> a) 48-bit Kernel VA + 48-bit User-space VA + 48-bit PA
> b) 48-bit Kernel VA + 48-bit User-space VA + 52-bit PA
> c) 48-bit Kernel VA + 52-bit User-space VA + 52-bit PA
> d) 52-bit Kernel VA + 52-bit User-space VA + 52-bit PA
> e) 52-bit Kernel VA + 48-bit User-space VA + 52-bit PA (is this even
> used-somewhere? Not sure but James [in Cc] had some queries on this [1].
> Personally, I am not aware of any users of this combination).
> 
> I have added detailed comments/concerns in individual patches in mails to
> follow regarding the above points.
> 
> [0]. https://github.com/crash-utility/crash/commit/b0b3ef2eda543413762b32710b8a63dd9ed55de5
> [1]. http://lists.infradead.org/pipermail/kexec/2019-April/022729.html
> 
>

Thanks Bhupesh, Ard,
As an update to this series, I have got the constant PAGE_OFFSET working
(basically got back to it after a while away and also caught a silly typo
that I made) and am tidying things up. And figuring out whether or not I
can just keep the vmemmap in the same place and just expand it.

I don't think we'll see a 52-bit kernel VA and 48-bit user VA unless
anyone wants it?

Cheers,
-- 
Steve

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2019-05-03 14:57 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-18 17:02 [PATCH 0/9] 52-bit kernel + user VAs Steve Capper
2019-02-18 17:02 ` [PATCH 1/9] arm/arm64: KVM: Formalise end of direct linear map Steve Capper
2019-02-18 17:02 ` [PATCH 2/9] arm64: mm: Flip kernel VA space Steve Capper
2019-04-03 11:44   ` Bhupesh Sharma
2019-02-18 17:02 ` [PATCH 3/9] arm64: kasan: Switch to using KASAN_SHADOW_OFFSET Steve Capper
2019-02-18 17:02 ` [PATCH 4/9] arm64: mm: Replace fixed map BUILD_BUG_ON's with BUG_ON's Steve Capper
2019-02-18 17:02 ` [PATCH 5/9] arm64: dump: Make kernel page table dumper dynamic again Steve Capper
2019-02-18 17:02 ` [PATCH 6/9] arm64: mm: Introduce VA_BITS_MIN Steve Capper
2019-02-18 17:02 ` [PATCH 7/9] arm64: mm: Introduce VA_BITS_ACTUAL Steve Capper
2019-02-18 17:02 ` [PATCH 8/9] arm64: mm: Logic to make offset_ttbr1 conditional Steve Capper
2019-04-03 11:26   ` Bhupesh Sharma
2019-02-18 17:02 ` [PATCH 9/9] arm64: mm: Introduce 52-bit Kernel VAs Steve Capper
2019-03-25 18:17   ` Catalin Marinas
2019-02-19 12:13 ` [PATCH 0/9] 52-bit kernel + user VAs Ard Biesheuvel
2019-02-19 12:48   ` Will Deacon
2019-02-19 12:51     ` Ard Biesheuvel
2019-02-19 13:01       ` Will Deacon
2019-02-19 13:15         ` Ard Biesheuvel
2019-02-19 13:56           ` Steve Capper
2019-02-19 16:18             ` Ard Biesheuvel
2019-02-26 17:30               ` Steve Capper
2019-02-26 20:17                 ` Ard Biesheuvel
2019-02-28 10:35                   ` Steve Capper
2019-02-28 11:22                     ` Ard Biesheuvel
2019-02-28 11:45                       ` Steve Capper
2019-03-25 18:38                       ` Catalin Marinas
2019-03-25 20:32                         ` Ard Biesheuvel
2019-04-03  8:09 ` Bhupesh Sharma
2019-05-03 14:57   ` Steve Capper

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).