]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
KVM: arm64: Patch kimage_voffset instead of loading the EL1 value
authorMarc Zyngier <maz@kernel.org>
Sat, 24 Oct 2020 15:33:38 +0000 (16:33 +0100)
committerMarc Zyngier <maz@kernel.org>
Fri, 27 Nov 2020 11:32:43 +0000 (11:32 +0000)
Directly using the kimage_voffset variable is fine for now, but
will become more problematic as we start distrusting EL1.

Instead, patch the kimage_voffset into the HYP text, ensuring
we don't have to load an untrusted value later on.

Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/include/asm/kvm_mmu.h
arch/arm64/kernel/image-vars.h
arch/arm64/kvm/hyp/nvhe/host.S
arch/arm64/kvm/va_layout.c

index 608c3a83e740d38a4c8fe73e0fac295f8b8c9841..5633c5a27aad3547e9a504b412b4c1300b064458 100644 (file)
@@ -72,6 +72,28 @@ alternative_cb kvm_update_va_mask
 alternative_cb_end
 .endm
 
+/*
+ * Convert a kernel image address to a PA
+ * reg: kernel address to be converted in place
+ * tmp: temporary register
+ *
+ * The actual code generation takes place in kvm_get_kimage_voffset, and
+ * the instructions below are only there to reserve the space and
+ * perform the register allocation (kvm_get_kimage_voffset uses the
+ * specific registers encoded in the instructions).
+ */
+.macro kimg_pa reg, tmp
+alternative_cb kvm_get_kimage_voffset
+       movz    \tmp, #0
+       movk    \tmp, #0, lsl #16
+       movk    \tmp, #0, lsl #32
+       movk    \tmp, #0, lsl #48
+alternative_cb_end
+
+       /* reg = __pa(reg) */
+       sub     \reg, \reg, \tmp
+.endm
+
 #else
 
 #include <linux/pgtable.h>
index e8c194f8de88764e9e4711a3087faef5e3200009..4b32588918d9041189797a711f1d4a4230df3677 100644 (file)
@@ -65,13 +65,11 @@ __efistub__ctype            = _ctype;
 KVM_NVHE_ALIAS(kvm_patch_vector_branch);
 KVM_NVHE_ALIAS(kvm_update_va_mask);
 KVM_NVHE_ALIAS(kvm_update_kimg_phys_offset);
+KVM_NVHE_ALIAS(kvm_get_kimage_voffset);
 
 /* Global kernel state accessed by nVHE hyp code. */
 KVM_NVHE_ALIAS(kvm_vgic_global_state);
 
-/* Kernel constant needed to compute idmap addresses. */
-KVM_NVHE_ALIAS(kimage_voffset);
-
 /* Kernel symbols used to call panic() from nVHE hyp code (via ERET). */
 KVM_NVHE_ALIAS(__hyp_panic_string);
 KVM_NVHE_ALIAS(panic);
index ed27f06a31ba2bbb46db322525cc3bdb55e3f916..4e207c1c512674ca4152a4a7623d4003fdcd3e83 100644 (file)
@@ -115,10 +115,7 @@ SYM_FUNC_END(__hyp_do_panic)
         * Preserve x0-x4, which may contain stub parameters.
         */
        ldr     x5, =__kvm_handle_stub_hvc
-       ldr_l   x6, kimage_voffset
-
-       /* x5 = __pa(x5) */
-       sub     x5, x5, x6
+       kimg_pa x5, x6
        br      x5
 .L__vect_end\@:
 .if ((.L__vect_end\@ - .L__vect_start\@) > 0x80)
index 1d00d2cb93fd545a001d2f634fbe4a88240b9520..d61117805de06cf54b8bfff6690a59f7a30d7e02 100644 (file)
@@ -251,3 +251,9 @@ void kvm_update_kimg_phys_offset(struct alt_instr *alt,
 {
        generate_mov_q(kimage_voffset + PHYS_OFFSET, origptr, updptr, nr_inst);
 }
+
+void kvm_get_kimage_voffset(struct alt_instr *alt,
+                           __le32 *origptr, __le32 *updptr, int nr_inst)
+{
+       generate_mov_q(kimage_voffset, origptr, updptr, nr_inst);
+}