KVM: arm64: Move hyp-init.S to nVHE
authorAndrew Scull <ascull@google.com>
Thu, 25 Jun 2020 13:14:12 +0000 (14:14 +0100)
committerMarc Zyngier <maz@kernel.org>
Sun, 5 Jul 2020 17:38:12 +0000 (18:38 +0100)
hyp-init.S contains the identity mapped initialisation code for the
non-VHE code that runs at EL2. It is only used for non-VHE.

Adjust code that calls into this to use the prefixed symbol name.

Signed-off-by: Andrew Scull <ascull@google.com>
Signed-off-by: David Brazdil <dbrazdil@google.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20200625131420.71444-8-dbrazdil@google.com
arch/arm64/include/asm/kvm_asm.h
arch/arm64/kernel/image-vars.h
arch/arm64/kvm/Makefile
arch/arm64/kvm/hyp-init.S [deleted file]
arch/arm64/kvm/hyp/nvhe/Makefile
arch/arm64/kvm/hyp/nvhe/hyp-init.S [new file with mode: 0644]

index 6026cbd..3476abb 100644 (file)
 struct kvm;
 struct kvm_vcpu;
 
-extern char __kvm_hyp_init[];
-extern char __kvm_hyp_init_end[];
-
+DECLARE_KVM_NVHE_SYM(__kvm_hyp_init);
 DECLARE_KVM_HYP_SYM(__kvm_hyp_vector);
+#define __kvm_hyp_init         CHOOSE_NVHE_SYM(__kvm_hyp_init)
 #define __kvm_hyp_vector       CHOOSE_HYP_SYM(__kvm_hyp_vector)
 
 #ifdef CONFIG_KVM_INDIRECT_VECTORS
index f28da48..63186c9 100644 (file)
@@ -71,9 +71,6 @@ KVM_NVHE_ALIAS(__guest_exit);
 KVM_NVHE_ALIAS(abort_guest_exit_end);
 KVM_NVHE_ALIAS(abort_guest_exit_start);
 
-/* Symbols defined in hyp-init.S (not yet compiled with nVHE build rules). */
-KVM_NVHE_ALIAS(__kvm_handle_stub_hvc);
-
 /* Symbols defined in switch.c (not yet compiled with nVHE build rules). */
 KVM_NVHE_ALIAS(__kvm_vcpu_run_nvhe);
 KVM_NVHE_ALIAS(hyp_panic);
@@ -113,6 +110,12 @@ KVM_NVHE_ALIAS(kimage_voffset);
 /* Kernel symbols used to call panic() from nVHE hyp code (via ERET). */
 KVM_NVHE_ALIAS(panic);
 
+/* Vectors installed by hyp-init on reset HVC. */
+KVM_NVHE_ALIAS(__hyp_stub_vectors);
+
+/* IDMAP TCR_EL1.T0SZ as computed by the EL1 init code */
+KVM_NVHE_ALIAS(idmap_t0sz);
+
 #endif /* CONFIG_KVM */
 
 #endif /* __ARM64_KERNEL_IMAGE_VARS_H */
index 8d3d951..152d884 100644 (file)
@@ -13,7 +13,7 @@ obj-$(CONFIG_KVM) += hyp/
 kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \
         $(KVM)/vfio.o $(KVM)/irqchip.o \
         arm.o mmu.o mmio.o psci.o perf.o hypercalls.o pvtime.o \
-        inject_fault.o regmap.o va_layout.o hyp.o hyp-init.o handle_exit.o \
+        inject_fault.o regmap.o va_layout.o hyp.o handle_exit.o \
         guest.o debug.o reset.o sys_regs.o sys_regs_generic_v8.o \
         vgic-sys-reg-v3.o fpsimd.o pmu.o \
         aarch32.o arch_timer.o \
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
deleted file mode 100644 (file)
index 6e6ed55..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2012,2013 - ARM Ltd
- * Author: Marc Zyngier <marc.zyngier@arm.com>
- */
-
-#include <linux/linkage.h>
-
-#include <asm/assembler.h>
-#include <asm/kvm_arm.h>
-#include <asm/kvm_mmu.h>
-#include <asm/pgtable-hwdef.h>
-#include <asm/sysreg.h>
-#include <asm/virt.h>
-
-       .text
-       .pushsection    .hyp.idmap.text, "ax"
-
-       .align  11
-
-SYM_CODE_START(__kvm_hyp_init)
-       ventry  __invalid               // Synchronous EL2t
-       ventry  __invalid               // IRQ EL2t
-       ventry  __invalid               // FIQ EL2t
-       ventry  __invalid               // Error EL2t
-
-       ventry  __invalid               // Synchronous EL2h
-       ventry  __invalid               // IRQ EL2h
-       ventry  __invalid               // FIQ EL2h
-       ventry  __invalid               // Error EL2h
-
-       ventry  __do_hyp_init           // Synchronous 64-bit EL1
-       ventry  __invalid               // IRQ 64-bit EL1
-       ventry  __invalid               // FIQ 64-bit EL1
-       ventry  __invalid               // Error 64-bit EL1
-
-       ventry  __invalid               // Synchronous 32-bit EL1
-       ventry  __invalid               // IRQ 32-bit EL1
-       ventry  __invalid               // FIQ 32-bit EL1
-       ventry  __invalid               // Error 32-bit EL1
-
-__invalid:
-       b       .
-
-       /*
-        * x0: HYP pgd
-        * x1: HYP stack
-        * x2: HYP vectors
-        * x3: per-CPU offset
-        */
-__do_hyp_init:
-       /* Check for a stub HVC call */
-       cmp     x0, #HVC_STUB_HCALL_NR
-       b.lo    __kvm_handle_stub_hvc
-
-       phys_to_ttbr x4, x0
-alternative_if ARM64_HAS_CNP
-       orr     x4, x4, #TTBR_CNP_BIT
-alternative_else_nop_endif
-       msr     ttbr0_el2, x4
-
-       mrs     x4, tcr_el1
-       mov_q   x5, TCR_EL2_MASK
-       and     x4, x4, x5
-       mov     x5, #TCR_EL2_RES1
-       orr     x4, x4, x5
-
-       /*
-        * The ID map may be configured to use an extended virtual address
-        * range. This is only the case if system RAM is out of range for the
-        * currently configured page size and VA_BITS, in which case we will
-        * also need the extended virtual range for the HYP ID map, or we won't
-        * be able to enable the EL2 MMU.
-        *
-        * However, at EL2, there is only one TTBR register, and we can't switch
-        * between translation tables *and* update TCR_EL2.T0SZ at the same
-        * time. Bottom line: we need to use the extended range with *both* our
-        * translation tables.
-        *
-        * So use the same T0SZ value we use for the ID map.
-        */
-       ldr_l   x5, idmap_t0sz
-       bfi     x4, x5, TCR_T0SZ_OFFSET, TCR_TxSZ_WIDTH
-
-       /*
-        * Set the PS bits in TCR_EL2.
-        */
-       tcr_compute_pa_size x4, #TCR_EL2_PS_SHIFT, x5, x6
-
-       msr     tcr_el2, x4
-
-       mrs     x4, mair_el1
-       msr     mair_el2, x4
-       isb
-
-       /* Invalidate the stale TLBs from Bootloader */
-       tlbi    alle2
-       dsb     sy
-
-       /*
-        * Preserve all the RES1 bits while setting the default flags,
-        * as well as the EE bit on BE. Drop the A flag since the compiler
-        * is allowed to generate unaligned accesses.
-        */
-       mov_q   x4, (SCTLR_EL2_RES1 | (SCTLR_ELx_FLAGS & ~SCTLR_ELx_A))
-CPU_BE(        orr     x4, x4, #SCTLR_ELx_EE)
-       msr     sctlr_el2, x4
-       isb
-
-       /* Set the stack and new vectors */
-       kern_hyp_va     x1
-       mov     sp, x1
-       msr     vbar_el2, x2
-
-       /* Set tpidr_el2 for use by HYP */
-       msr     tpidr_el2, x3
-
-       /* Hello, World! */
-       eret
-SYM_CODE_END(__kvm_hyp_init)
-
-SYM_CODE_START(__kvm_handle_stub_hvc)
-       cmp     x0, #HVC_SOFT_RESTART
-       b.ne    1f
-
-       /* This is where we're about to jump, staying at EL2 */
-       msr     elr_el2, x1
-       mov     x0, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT | PSR_MODE_EL2h)
-       msr     spsr_el2, x0
-
-       /* Shuffle the arguments, and don't come back */
-       mov     x0, x2
-       mov     x1, x3
-       mov     x2, x4
-       b       reset
-
-1:     cmp     x0, #HVC_RESET_VECTORS
-       b.ne    1f
-reset:
-       /*
-        * Reset kvm back to the hyp stub. Do not clobber x0-x4 in
-        * case we coming via HVC_SOFT_RESTART.
-        */
-       mrs     x5, sctlr_el2
-       mov_q   x6, SCTLR_ELx_FLAGS
-       bic     x5, x5, x6              // Clear SCTL_M and etc
-       pre_disable_mmu_workaround
-       msr     sctlr_el2, x5
-       isb
-
-       /* Install stub vectors */
-       adr_l   x5, __hyp_stub_vectors
-       msr     vbar_el2, x5
-       mov     x0, xzr
-       eret
-
-1:     /* Bad stub call */
-       mov_q   x0, HVC_STUB_ERR
-       eret
-
-SYM_CODE_END(__kvm_handle_stub_hvc)
-
-       .popsection
index 79eb8ee..bf2d8de 100644 (file)
@@ -6,7 +6,7 @@
 asflags-y := -D__KVM_NVHE_HYPERVISOR__
 ccflags-y := -D__KVM_NVHE_HYPERVISOR__
 
-obj-y := ../hyp-entry.o
+obj-y := hyp-init.o ../hyp-entry.o
 
 obj-y := $(patsubst %.o,%.hyp.o,$(obj-y))
 extra-y := $(patsubst %.hyp.o,%.hyp.tmp.o,$(obj-y))
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-init.S b/arch/arm64/kvm/hyp/nvhe/hyp-init.S
new file mode 100644 (file)
index 0000000..6e6ed55
--- /dev/null
@@ -0,0 +1,163 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ */
+
+#include <linux/linkage.h>
+
+#include <asm/assembler.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_mmu.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/sysreg.h>
+#include <asm/virt.h>
+
+       .text
+       .pushsection    .hyp.idmap.text, "ax"
+
+       .align  11
+
+SYM_CODE_START(__kvm_hyp_init)
+       ventry  __invalid               // Synchronous EL2t
+       ventry  __invalid               // IRQ EL2t
+       ventry  __invalid               // FIQ EL2t
+       ventry  __invalid               // Error EL2t
+
+       ventry  __invalid               // Synchronous EL2h
+       ventry  __invalid               // IRQ EL2h
+       ventry  __invalid               // FIQ EL2h
+       ventry  __invalid               // Error EL2h
+
+       ventry  __do_hyp_init           // Synchronous 64-bit EL1
+       ventry  __invalid               // IRQ 64-bit EL1
+       ventry  __invalid               // FIQ 64-bit EL1
+       ventry  __invalid               // Error 64-bit EL1
+
+       ventry  __invalid               // Synchronous 32-bit EL1
+       ventry  __invalid               // IRQ 32-bit EL1
+       ventry  __invalid               // FIQ 32-bit EL1
+       ventry  __invalid               // Error 32-bit EL1
+
+__invalid:
+       b       .
+
+       /*
+        * x0: HYP pgd
+        * x1: HYP stack
+        * x2: HYP vectors
+        * x3: per-CPU offset
+        */
+__do_hyp_init:
+       /* Check for a stub HVC call */
+       cmp     x0, #HVC_STUB_HCALL_NR
+       b.lo    __kvm_handle_stub_hvc
+
+       phys_to_ttbr x4, x0
+alternative_if ARM64_HAS_CNP
+       orr     x4, x4, #TTBR_CNP_BIT
+alternative_else_nop_endif
+       msr     ttbr0_el2, x4
+
+       mrs     x4, tcr_el1
+       mov_q   x5, TCR_EL2_MASK
+       and     x4, x4, x5
+       mov     x5, #TCR_EL2_RES1
+       orr     x4, x4, x5
+
+       /*
+        * The ID map may be configured to use an extended virtual address
+        * range. This is only the case if system RAM is out of range for the
+        * currently configured page size and VA_BITS, in which case we will
+        * also need the extended virtual range for the HYP ID map, or we won't
+        * be able to enable the EL2 MMU.
+        *
+        * However, at EL2, there is only one TTBR register, and we can't switch
+        * between translation tables *and* update TCR_EL2.T0SZ at the same
+        * time. Bottom line: we need to use the extended range with *both* our
+        * translation tables.
+        *
+        * So use the same T0SZ value we use for the ID map.
+        */
+       ldr_l   x5, idmap_t0sz
+       bfi     x4, x5, TCR_T0SZ_OFFSET, TCR_TxSZ_WIDTH
+
+       /*
+        * Set the PS bits in TCR_EL2.
+        */
+       tcr_compute_pa_size x4, #TCR_EL2_PS_SHIFT, x5, x6
+
+       msr     tcr_el2, x4
+
+       mrs     x4, mair_el1
+       msr     mair_el2, x4
+       isb
+
+       /* Invalidate the stale TLBs from Bootloader */
+       tlbi    alle2
+       dsb     sy
+
+       /*
+        * Preserve all the RES1 bits while setting the default flags,
+        * as well as the EE bit on BE. Drop the A flag since the compiler
+        * is allowed to generate unaligned accesses.
+        */
+       mov_q   x4, (SCTLR_EL2_RES1 | (SCTLR_ELx_FLAGS & ~SCTLR_ELx_A))
+CPU_BE(        orr     x4, x4, #SCTLR_ELx_EE)
+       msr     sctlr_el2, x4
+       isb
+
+       /* Set the stack and new vectors */
+       kern_hyp_va     x1
+       mov     sp, x1
+       msr     vbar_el2, x2
+
+       /* Set tpidr_el2 for use by HYP */
+       msr     tpidr_el2, x3
+
+       /* Hello, World! */
+       eret
+SYM_CODE_END(__kvm_hyp_init)
+
+SYM_CODE_START(__kvm_handle_stub_hvc)
+       cmp     x0, #HVC_SOFT_RESTART
+       b.ne    1f
+
+       /* This is where we're about to jump, staying at EL2 */
+       msr     elr_el2, x1
+       mov     x0, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT | PSR_MODE_EL2h)
+       msr     spsr_el2, x0
+
+       /* Shuffle the arguments, and don't come back */
+       mov     x0, x2
+       mov     x1, x3
+       mov     x2, x4
+       b       reset
+
+1:     cmp     x0, #HVC_RESET_VECTORS
+       b.ne    1f
+reset:
+       /*
+        * Reset kvm back to the hyp stub. Do not clobber x0-x4 in
+        * case we coming via HVC_SOFT_RESTART.
+        */
+       mrs     x5, sctlr_el2
+       mov_q   x6, SCTLR_ELx_FLAGS
+       bic     x5, x5, x6              // Clear SCTL_M and etc
+       pre_disable_mmu_workaround
+       msr     sctlr_el2, x5
+       isb
+
+       /* Install stub vectors */
+       adr_l   x5, __hyp_stub_vectors
+       msr     vbar_el2, x5
+       mov     x0, xzr
+       eret
+
+1:     /* Bad stub call */
+       mov_q   x0, HVC_STUB_ERR
+       eret
+
+SYM_CODE_END(__kvm_handle_stub_hvc)
+
+       .popsection