From: Steve Capper <steve.capper@arm.com>
To: linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu
Cc: catalin.marinas@arm.com, ard.biesheuvel@linaro.org
Subject: [PATCH 11/12] arm64: KVM: Add support for an alternative VA space
Date: Mon, 4 Dec 2017 14:13:12 +0000 [thread overview]
Message-ID: <20171204141313.31604-12-steve.capper@arm.com> (raw)
In-Reply-To: <20171204141313.31604-1-steve.capper@arm.com>
This patch adjusts the alternative patching logic for kern_hyp_va to
take into account a change in virtual address space size on boot.
Because the instructions in the alternatives regions have to be fixed at
compile time, in order to make the logic depend on a dynamic VA size
the predicates have to be adjusted.
The predicates used, follow the corresponding logic:
- ARM64_HAS_VIRT_HOST_EXTN, true if running with VHE
- ARM64_HYP_MAP_FLIP, true if !VHE and idmap is high and VA size is small.
- ARM64_HYP_RUNNING_ALT_VA, true if !VHE and VA size is big.
- ARM64_HYP_MAP_FLIP_ALT, true if !VHE and idmap is high and VA size is big.
Using the above predicates means we have to add two instructions to
kern_hyp_va.
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
arch/arm64/Kconfig | 4 ++++
arch/arm64/include/asm/cpucaps.h | 4 +++-
arch/arm64/include/asm/kvm_mmu.h | 47 ++++++++++++++++++++++++++++++++++++++++
arch/arm64/kernel/cpufeature.c | 39 ++++++++++++++++++++++++++++++++-
4 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 0fa430326825..143c453b06f1 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -656,6 +656,10 @@ config ARM64_VA_BITS
default 47 if ARM64_VA_BITS_47
default 48 if ARM64_VA_BITS_48
+config ARM64_VA_BITS_ALT
+ bool
+ default n
+
config CPU_BIG_ENDIAN
bool "Build big-endian kernel"
help
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 3de31a1010ee..955936adcf7a 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -41,7 +41,9 @@
#define ARM64_WORKAROUND_CAVIUM_30115 20
#define ARM64_HAS_DCPOP 21
#define ARM64_SVE 22
+#define ARM64_HYP_RUNNING_ALT_VA 23
+#define ARM64_HYP_MAP_FLIP_ALT 24
-#define ARM64_NCAPS 23
+#define ARM64_NCAPS 25
#endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 5174fd7e5196..8de396764a11 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -73,6 +73,11 @@
#define _HYP_MAP_HIGH_BIT(va) (UL(1) << ((va) - 1))
#define HYP_MAP_KERNEL_BITS _HYP_MAP_KERNEL_BITS(VA_BITS_MIN)
#define HYP_MAP_HIGH_BIT _HYP_MAP_HIGH_BIT(VA_BITS_MIN)
+#ifdef CONFIG_ARM64_VA_BITS_ALT
+#define HYP_MAP_KERNEL_BITS_ALT (_HYP_MAP_KERNEL_BITS(VA_BITS_ALT) \
+ ^ _HYP_MAP_KERNEL_BITS(VA_BITS_MIN))
+#define HYP_MAP_HIGH_BIT_ALT _HYP_MAP_HIGH_BIT(VA_BITS_ALT)
+#endif
#ifdef __ASSEMBLY__
@@ -95,6 +100,27 @@
* - VHE:
* nop
* nop
+ *
+ * For cases where we are running with a variable address space size,
+ * two extra instructions are added, and the logic changes thusly:
+ *
+ * - Flip the kernel bits for the new VA:
+ * eor x0, x0, #HYP_MAP_KERNEL_BITS
+ * nop
+ * eor x0, x0, #HYP_MAP_KERNEL_BITS_ALT
+ * eor
+ *
+ * - Flip the kernel bits and upper HYP bit for new VA:
+ * eor x0, x0, #HYP_MAP_KERNEL_BITS
+ * nop
+ * eor x0, x0, #HYP_MAP_KERNEL_BITS_ALT
+ * eor x0, x0, #HYP_MAP_HIGH_BIT_ALT
+ *
+ * - VHE:
+ * nop
+ * nop
+ * nop
+ * nop
*/
.macro kern_hyp_va reg
alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
@@ -103,6 +129,14 @@ alternative_else_nop_endif
alternative_if ARM64_HYP_MAP_FLIP
eor \reg, \reg, #HYP_MAP_HIGH_BIT
alternative_else_nop_endif
+#ifdef CONFIG_ARM64_VA_BITS_ALT
+alternative_if ARM64_HYP_RUNNING_ALT_VA
+ eor \reg, \reg, #HYP_MAP_KERNEL_BITS_ALT
+alternative_else_nop_endif
+alternative_if ARM64_HYP_MAP_FLIP_ALT
+ eor \reg, \reg, #HYP_MAP_HIGH_BIT_ALT
+alternative_else_nop_endif
+#endif
.endm
#else
@@ -125,6 +159,19 @@ static inline unsigned long __kern_hyp_va(unsigned long v)
ARM64_HYP_MAP_FLIP)
: "+r" (v)
: "i" (HYP_MAP_HIGH_BIT));
+#ifdef CONFIG_ARM64_VA_BITS_ALT
+ asm volatile(ALTERNATIVE("nop",
+ "eor %0, %0, %1",
+ ARM64_HYP_RUNNING_ALT_VA)
+ : "+r" (v)
+ : "i" (HYP_MAP_KERNEL_BITS_ALT));
+ asm volatile(ALTERNATIVE("nop",
+ "eor %0, %0, %1",
+ ARM64_HYP_MAP_FLIP_ALT)
+ : "+r" (v)
+ : "i" (HYP_MAP_HIGH_BIT_ALT));
+#endif
+
return v;
}
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 31cfffa79fee..cd4bcd2d0942 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -834,7 +834,8 @@ static bool hyp_flip_space(const struct arm64_cpu_capabilities *entry,
* - the idmap doesn't clash with it,
* - the kernel is not running at EL2.
*/
- return idmap_addr <= GENMASK(VA_BITS_MIN - 2, 0) && !is_kernel_in_hyp_mode();
+ return (VA_BITS == VA_BITS_MIN) &&
+ idmap_addr <= GENMASK(VA_BITS_MIN - 2, 0) && !is_kernel_in_hyp_mode();
}
static bool has_no_fpsimd(const struct arm64_cpu_capabilities *entry, int __unused)
@@ -845,6 +846,28 @@ static bool has_no_fpsimd(const struct arm64_cpu_capabilities *entry, int __unus
ID_AA64PFR0_FP_SHIFT) < 0;
}
+#ifdef CONFIG_ARM64_VA_BITS_ALT
+static bool hyp_using_large_va(const struct arm64_cpu_capabilities *entry,
+ int __unused)
+{
+ return (VA_BITS > VA_BITS_MIN) && !is_kernel_in_hyp_mode();
+}
+
+static bool hyp_flip_space_alt(const struct arm64_cpu_capabilities *entry,
+ int __unused)
+{
+ phys_addr_t idmap_addr = __pa_symbol(__hyp_idmap_text_start);
+
+ /*
+ * Activate the lower HYP offset only if:
+ * - the idmap doesn't clash with it,
+ * - the kernel is not running at EL2.
+ */
+ return (VA_BITS > VA_BITS_MIN) &&
+ idmap_addr <= GENMASK(VA_BITS - 2, 0) && !is_kernel_in_hyp_mode();
+}
+#endif
+
static const struct arm64_cpu_capabilities arm64_features[] = {
{
.desc = "GIC system register CPU interface",
@@ -931,6 +954,20 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.def_scope = SCOPE_SYSTEM,
.matches = hyp_flip_space,
},
+#ifdef CONFIG_ARM64_VA_BITS_ALT
+ {
+ .desc = "HYP mapping using larger VA space",
+ .capability = ARM64_HYP_RUNNING_ALT_VA,
+ .def_scope = SCOPE_SYSTEM,
+ .matches = hyp_using_large_va,
+ },
+ {
+ .desc = "HYP mapping using flipped, larger VA space",
+ .capability = ARM64_HYP_MAP_FLIP_ALT,
+ .def_scope = SCOPE_SYSTEM,
+ .matches = hyp_flip_space_alt,
+ },
+#endif
{
/* FP/SIMD is not implemented */
.capability = ARM64_HAS_NO_FPSIMD,
--
2.11.0
next prev parent reply other threads:[~2017-12-04 14:10 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-04 14:13 [PATCH 00/12] 52-bit kernel VAs for arm64 Steve Capper
2017-12-04 14:13 ` [PATCH 01/12] KVM: arm/arm64: vgic: Remove spurious call to kern_hyp_va Steve Capper
2017-12-04 14:30 ` Suzuki K Poulose
2017-12-12 11:53 ` Steve Capper
2017-12-04 14:13 ` [PATCH 02/12] arm64: KVM: Enforce injective kern_hyp_va mappings Steve Capper
2017-12-04 14:13 ` [PATCH 03/12] arm/arm64: KVM: Formalise end of direct linear map Steve Capper
2017-12-04 14:13 ` [PATCH 04/12] arm64: Initialise high_memory global variable earlier Steve Capper
2017-12-11 12:00 ` Catalin Marinas
2017-12-12 10:56 ` Steve Capper
2017-12-04 14:13 ` [PATCH 05/12] arm64: mm: Remove VMALLOC checks from update_mapping_prot(.) Steve Capper
2017-12-04 16:01 ` Ard Biesheuvel
2017-12-12 15:39 ` Steve Capper
2017-12-13 16:04 ` Catalin Marinas
2017-12-04 14:13 ` [PATCH 06/12] arm64: mm: Flip kernel VA space Steve Capper
2017-12-04 14:13 ` [PATCH 07/12] arm64: mm: Place kImage at bottom of " Steve Capper
2017-12-04 16:25 ` Ard Biesheuvel
2017-12-04 17:18 ` Steve Capper
2017-12-04 17:21 ` Steve Capper
2017-12-04 17:27 ` Ard Biesheuvel
2017-12-04 18:12 ` Steve Capper
2017-12-12 11:03 ` Steve Capper
2017-12-04 14:13 ` [PATCH 08/12] arm64: kasan: Switch to using KASAN_SHADOW_OFFSET Steve Capper
2017-12-04 14:13 ` [PATCH 09/12] arm64: dump: Make kernel page table dumper dynamic again Steve Capper
2017-12-04 14:13 ` [PATCH 10/12] arm64: mm: Make VA_BITS variable, introduce VA_BITS_MIN Steve Capper
2017-12-04 14:13 ` Steve Capper [this message]
2017-12-04 14:13 ` [PATCH 12/12] arm64: mm: Add 48/52-bit kernel VA support 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=20171204141313.31604-12-steve.capper@arm.com \
--to=steve.capper@arm.com \
--cc=ard.biesheuvel@linaro.org \
--cc=catalin.marinas@arm.com \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=linux-arm-kernel@lists.infradead.org \
/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