@@ -127,19 +127,34 @@ static inline void vcpu_set_vsesr(struct kvm_vcpu *vcpu, u64 vsesr)
vcpu->arch.vsesr_el2 = vsesr;
}
+static __always_inline unsigned long *ctxt_pc(const struct kvm_cpu_context *ctxt)
+{
+ return (unsigned long *)&ctxt_gp_regs(ctxt)->pc;
+}
+
static __always_inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu)
{
- return (unsigned long *)&vcpu_gp_regs(vcpu)->pc;
+ return ctxt_pc(&vcpu_ctxt(vcpu));
+}
+
+static __always_inline unsigned long *ctxt_cpsr(const struct kvm_cpu_context *ctxt)
+{
+ return (unsigned long *)&ctxt_gp_regs(ctxt)->pstate;
}
static __always_inline unsigned long *vcpu_cpsr(const struct kvm_vcpu *vcpu)
{
- return (unsigned long *)&vcpu_gp_regs(vcpu)->pstate;
+ return ctxt_cpsr(&vcpu_ctxt(vcpu));
+}
+
+static __always_inline bool ctxt_mode_is_32bit(const struct kvm_cpu_context *ctxt)
+{
+ return !!(*ctxt_cpsr(ctxt) & PSR_MODE32_BIT);
}
static __always_inline bool vcpu_mode_is_32bit(const struct kvm_vcpu *vcpu)
{
- return !!(*vcpu_cpsr(vcpu) & PSR_MODE32_BIT);
+ return ctxt_mode_is_32bit(&vcpu_ctxt(vcpu));
}
static __always_inline bool kvm_condition_valid(const struct kvm_vcpu *vcpu)
@@ -150,27 +165,45 @@ static __always_inline bool kvm_condition_valid(const struct kvm_vcpu *vcpu)
return true;
}
+static inline void ctxt_set_thumb(struct kvm_cpu_context *ctxt)
+{
+ *ctxt_cpsr(ctxt) |= PSR_AA32_T_BIT;
+}
+
static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
{
- *vcpu_cpsr(vcpu) |= PSR_AA32_T_BIT;
+ ctxt_set_thumb(&vcpu_ctxt(vcpu));
}
/*
- * vcpu_get_reg and vcpu_set_reg should always be passed a register number
- * coming from a read of ESR_EL2. Otherwise, it may give the wrong result on
- * AArch32 with banked registers.
+ * vcpu/ctxt_get_reg and vcpu/ctxt_set_reg should always be passed a register
+ * number coming from a read of ESR_EL2. Otherwise, it may give the wrong result
+ * on AArch32 with banked registers.
*/
+static __always_inline unsigned long
+ctxt_get_reg(const struct kvm_cpu_context *ctxt, u8 reg_num)
+{
+ return (reg_num == 31) ? 0 : ctxt_gp_regs(ctxt)->regs[reg_num];
+}
+
+static __always_inline void
+ctxt_set_reg(struct kvm_cpu_context *ctxt, u8 reg_num, unsigned long val)
+{
+ if (reg_num != 31)
+ ctxt_gp_regs(ctxt)->regs[reg_num] = val;
+}
+
static __always_inline unsigned long vcpu_get_reg(const struct kvm_vcpu *vcpu,
u8 reg_num)
{
- return (reg_num == 31) ? 0 : vcpu_gp_regs(vcpu)->regs[reg_num];
+ return ctxt_get_reg(&vcpu_ctxt(vcpu), reg_num);
+
}
static __always_inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num,
unsigned long val)
{
- if (reg_num != 31)
- vcpu_gp_regs(vcpu)->regs[reg_num] = val;
+ ctxt_set_reg(&vcpu_ctxt(vcpu), reg_num, val);
}
/*
@@ -446,7 +446,23 @@ struct kvm_vcpu_arch {
#define vcpu_has_ptrauth(vcpu) false
#endif
-#define vcpu_gp_regs(v) (&(v)->arch.ctxt.regs)
+#define vcpu_ctxt(vcpu) ((vcpu)->arch.ctxt)
+
+/* VCPU Context accessors (direct) */
+#define ctxt_gp_regs(c) (&(c)->regs)
+#define ctxt_spsr_abt(c) (&(c)->spsr_abt)
+#define ctxt_spsr_und(c) (&(c)->spsr_und)
+#define ctxt_spsr_irq(c) (&(c)->spsr_irq)
+#define ctxt_spsr_fiq(c) (&(c)->spsr_fiq)
+#define ctxt_fp_regs(c) (&(c)->fp_regs)
+
+/* VCPU Context accessors */
+#define vcpu_gp_regs(v) ctxt_gp_regs(&vcpu_ctxt(v))
+#define vcpu_spsr_abt(v) ctxt_spsr_abt(&vcpu_ctxt(v))
+#define vcpu_spsr_und(v) ctxt_spsr_und(&vcpu_ctxt(v))
+#define vcpu_spsr_irq(v) ctxt_spsr_irq(&vcpu_ctxt(v))
+#define vcpu_spsr_fiq(v) ctxt_spsr_fiq(&vcpu_ctxt(v))
+#define vcpu_fp_regs(v) ctxt_fp_regs(&vcpu_ctxt(v))
/*
* Only use __vcpu_sys_reg/ctxt_sys_reg if you know you want the
@@ -18,43 +18,68 @@
#error Hypervisor code only!
#endif
-static inline u64 __vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
+static inline u64 __ctxt_read_sys_reg(const struct kvm_cpu_context *vcpu_ctxt, int reg)
{
u64 val;
if (__vcpu_read_sys_reg_from_cpu(reg, &val))
return val;
- return __vcpu_sys_reg(vcpu, reg);
+ return ctxt_sys_reg(vcpu_ctxt, reg);
}
-static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
+static inline void __ctxt_write_sys_reg(struct kvm_cpu_context *vcpu_ctxt, u64 val, int reg)
{
if (__vcpu_write_sys_reg_to_cpu(val, reg))
return;
- __vcpu_sys_reg(vcpu, reg) = val;
+ ctxt_sys_reg(vcpu_ctxt, reg) = val;
}
-static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, u64 val)
+static void __ctxt_write_spsr(struct kvm_cpu_context *vcpu_ctxt, u64 val)
{
write_sysreg_el1(val, SYS_SPSR);
}
-static void __vcpu_write_spsr_abt(struct kvm_vcpu *vcpu, u64 val)
+static void __ctxt_write_spsr_abt(struct kvm_cpu_context *vcpu_ctxt, u64 val)
{
if (has_vhe())
write_sysreg(val, spsr_abt);
else
- vcpu->arch.ctxt.spsr_abt = val;
+ *ctxt_spsr_abt(vcpu_ctxt) = val;
}
-static void __vcpu_write_spsr_und(struct kvm_vcpu *vcpu, u64 val)
+static void __ctxt_write_spsr_und(struct kvm_cpu_context *vcpu_ctxt, u64 val)
{
if (has_vhe())
write_sysreg(val, spsr_und);
else
- vcpu->arch.ctxt.spsr_und = val;
+ *ctxt_spsr_und(vcpu_ctxt) = val;
+}
+
+static inline u64 __vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
+{
+ return __ctxt_read_sys_reg(&vcpu_ctxt(vcpu), reg);
+}
+
+static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
+{
+ __ctxt_write_sys_reg(&vcpu_ctxt(vcpu), val, reg);
+}
+
+static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, u64 val)
+{
+ __ctxt_write_spsr(&vcpu_ctxt(vcpu), val);
+}
+
+static void __vcpu_write_spsr_abt(struct kvm_vcpu *vcpu, u64 val)
+{
+ __ctxt_write_spsr_abt(&vcpu_ctxt(vcpu), val);
+}
+
+static void __vcpu_write_spsr_und(struct kvm_vcpu *vcpu, u64 val)
+{
+ __ctxt_write_spsr_und(&vcpu_ctxt(vcpu), val);
}
/*
Add accessors to get/set elements of struct kvm_cpu_context. Simplifies future refactoring, and makes the code more consistent. Signed-off-by: Fuad Tabba <tabba@google.com> --- arch/arm64/include/asm/kvm_emulate.h | 53 ++++++++++++++++++++++------ arch/arm64/include/asm/kvm_host.h | 18 +++++++++- arch/arm64/kvm/hyp/exception.c | 43 +++++++++++++++++----- 3 files changed, 94 insertions(+), 20 deletions(-)