linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Bhupesh Sharma <bhsharma@redhat.com>
To: Steve Capper <steve.capper@arm.com>,
	linux-arm-kernel@lists.infradead.org
Cc: crecklin@redhat.com, ard.biesheuvel@linaro.org,
	marc.zyngier@arm.com, Catalin Marinas <catalin.marinas@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	will.deacon@arm.com, Dave Anderson <anderson@redhat.com>,
	James Morse <james.morse@arm.com>,
	Bhupesh SHARMA <bhupesh.linux@gmail.com>,
	"kexec@lists.infradead.org" <kexec@lists.infradead.org>
Subject: Re: [PATCH 8/9] arm64: mm: Logic to make offset_ttbr1 conditional
Date: Wed, 3 Apr 2019 16:56:16 +0530	[thread overview]
Message-ID: <47e8dd37-fbcf-8b4f-0f95-b1e0b8efe0e4@redhat.com> (raw)
In-Reply-To: <20190218170245.14915-9-steve.capper@arm.com>

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

  reply	other threads:[~2019-04-03 11:26 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=47e8dd37-fbcf-8b4f-0f95-b1e0b8efe0e4@redhat.com \
    --to=bhsharma@redhat.com \
    --cc=anderson@redhat.com \
    --cc=ard.biesheuvel@linaro.org \
    --cc=bhupesh.linux@gmail.com \
    --cc=catalin.marinas@arm.com \
    --cc=crecklin@redhat.com \
    --cc=james.morse@arm.com \
    --cc=kexec@lists.infradead.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=marc.zyngier@arm.com \
    --cc=steve.capper@arm.com \
    --cc=suzuki.poulose@arm.com \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).