Hi James,
On 2020-10-27 17:41, James Morse wrote:
Hi Marc,
On 26/10/2020 13:34, Marc Zyngier wrote:
Move the AArch64 exception injection code from EL1 to HYP, leaving
only the ESR_EL1 updates to EL1. In order to come with the differences
(cope with the differences?)
Yes, much better!
between VHE and nVHE, two set of system register accessors are
provided.
SPSR, ELR, PC and PSTATE are now completely handled in the hypervisor.
diff --git a/arch/arm64/kvm/hyp/exception.c
b/arch/arm64/kvm/hyp/exception.c
index 6533a9270850..cd6e643639e8 100644
--- a/arch/arm64/kvm/hyp/exception.c
+++ b/arch/arm64/kvm/hyp/exception.c
@@ -11,7 +11,167 @@
*/
#include <hyp/adjust_pc.h>
+#include <linux/kvm_host.h>
+#include <asm/kvm_emulate.h>
+
+#if defined (__KVM_NVHE_HYPERVISOR__)
+/*
+ * System registers are never loaded on the CPU until we actually
+ * restore them.
+ */
+static inline u64 __vcpu_read_sys_reg(const struct kvm_vcpu *vcpu,
int reg)
+{
+ return __vcpu_sys_reg(vcpu, reg);
+}
+
+static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64
val, int reg)
+{
+ __vcpu_sys_reg(vcpu, reg) = val;
+}
+
+static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, u64 val)
+{
+ write_sysreg_el1(val, SYS_SPSR);
+}
+#elif defined (__KVM_VHE_HYPERVISOR__)
+/* On VHE, all the registers are already loaded on the CPU */
+static inline u64 __vcpu_read_sys_reg(const struct kvm_vcpu *vcpu,
int reg)
+{
+ u64 val;
+ if (__vcpu_read_sys_reg_from_cpu(reg, &val))
+ return val;
As has_vhe()'s behaviour changes based on these KVM preprocessor
symbols, would:
| if (has_vhe() && __vcpu_read_sys_reg_from_cpu(reg, &val))
| return val;
let you do both of these with only one copy of the function?
Indeed that's better. Even better, let's move the has_vhe() into
__vcpu_read_sys_reg_from_cpu(), as that's the only case this is
used for.
Further cleanup could involve a new helper that would gate the
test of vcpu->sysregs_loaded_on_cpu with has_vhe() too, as this
definitely is a VHE-only feature.
+ return __vcpu_sys_reg(vcpu, reg);
+}
+
+static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64
val, int reg)
+{
+ if (__vcpu_write_sys_reg_to_cpu(val, reg))
+ return;
+
+ __vcpu_sys_reg(vcpu, reg) = val;
+}
+static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, u64 val)
+{
+ write_sysreg_el1(val, SYS_SPSR);
+}
This one doesn't look like it needs duplicating.
Spot on again, thanks!
M.
--
Jazz is not dead. It just smells funny...