Commit 0ca5565d authored by Marc Zyngier's avatar Marc Zyngier

ARM: KVM: Move VFP registers to a CPU context structure

In order to turn the WS code into something that looks a bit
more like the arm64 version, move the VFP registers into a
CPU context container for both the host and the guest.
Reviewed-by: default avatarChristoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent 42428525
...@@ -88,9 +88,15 @@ struct kvm_vcpu_fault_info { ...@@ -88,9 +88,15 @@ struct kvm_vcpu_fault_info {
u32 hyp_pc; /* PC when exception was taken from Hyp mode */ u32 hyp_pc; /* PC when exception was taken from Hyp mode */
}; };
typedef struct vfp_hard_struct kvm_cpu_context_t; struct kvm_cpu_context {
struct vfp_hard_struct vfp;
};
typedef struct kvm_cpu_context kvm_cpu_context_t;
struct kvm_vcpu_arch { struct kvm_vcpu_arch {
struct kvm_cpu_context ctxt;
struct kvm_regs regs; struct kvm_regs regs;
int target; /* Processor target */ int target; /* Processor target */
...@@ -111,9 +117,6 @@ struct kvm_vcpu_arch { ...@@ -111,9 +117,6 @@ struct kvm_vcpu_arch {
/* Exception Information */ /* Exception Information */
struct kvm_vcpu_fault_info fault; struct kvm_vcpu_fault_info fault;
/* Floating point registers (VFP and Advanced SIMD/NEON) */
struct vfp_hard_struct vfp_guest;
/* Host FP context */ /* Host FP context */
kvm_cpu_context_t *host_cpu_context; kvm_cpu_context_t *host_cpu_context;
......
...@@ -173,8 +173,9 @@ int main(void) ...@@ -173,8 +173,9 @@ int main(void)
DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm)); DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm));
DEFINE(VCPU_MIDR, offsetof(struct kvm_vcpu, arch.midr)); DEFINE(VCPU_MIDR, offsetof(struct kvm_vcpu, arch.midr));
DEFINE(VCPU_CP15, offsetof(struct kvm_vcpu, arch.cp15)); DEFINE(VCPU_CP15, offsetof(struct kvm_vcpu, arch.cp15));
DEFINE(VCPU_VFP_GUEST, offsetof(struct kvm_vcpu, arch.vfp_guest)); DEFINE(VCPU_GUEST_CTXT, offsetof(struct kvm_vcpu, arch.ctxt));
DEFINE(VCPU_VFP_HOST, offsetof(struct kvm_vcpu, arch.host_cpu_context)); DEFINE(VCPU_HOST_CTXT, offsetof(struct kvm_vcpu, arch.host_cpu_context));
DEFINE(CPU_CTXT_VFP, offsetof(struct kvm_cpu_context, vfp));
DEFINE(VCPU_REGS, offsetof(struct kvm_vcpu, arch.regs)); DEFINE(VCPU_REGS, offsetof(struct kvm_vcpu, arch.regs));
DEFINE(VCPU_USR_REGS, offsetof(struct kvm_vcpu, arch.regs.usr_regs)); DEFINE(VCPU_USR_REGS, offsetof(struct kvm_vcpu, arch.regs.usr_regs));
DEFINE(VCPU_SVC_REGS, offsetof(struct kvm_vcpu, arch.regs.svc_regs)); DEFINE(VCPU_SVC_REGS, offsetof(struct kvm_vcpu, arch.regs.svc_regs));
......
...@@ -901,7 +901,7 @@ static int vfp_get_reg(const struct kvm_vcpu *vcpu, u64 id, void __user *uaddr) ...@@ -901,7 +901,7 @@ static int vfp_get_reg(const struct kvm_vcpu *vcpu, u64 id, void __user *uaddr)
if (vfpid < num_fp_regs()) { if (vfpid < num_fp_regs()) {
if (KVM_REG_SIZE(id) != 8) if (KVM_REG_SIZE(id) != 8)
return -ENOENT; return -ENOENT;
return reg_to_user(uaddr, &vcpu->arch.vfp_guest.fpregs[vfpid], return reg_to_user(uaddr, &vcpu->arch.ctxt.vfp.fpregs[vfpid],
id); id);
} }
...@@ -911,13 +911,13 @@ static int vfp_get_reg(const struct kvm_vcpu *vcpu, u64 id, void __user *uaddr) ...@@ -911,13 +911,13 @@ static int vfp_get_reg(const struct kvm_vcpu *vcpu, u64 id, void __user *uaddr)
switch (vfpid) { switch (vfpid) {
case KVM_REG_ARM_VFP_FPEXC: case KVM_REG_ARM_VFP_FPEXC:
return reg_to_user(uaddr, &vcpu->arch.vfp_guest.fpexc, id); return reg_to_user(uaddr, &vcpu->arch.ctxt.vfp.fpexc, id);
case KVM_REG_ARM_VFP_FPSCR: case KVM_REG_ARM_VFP_FPSCR:
return reg_to_user(uaddr, &vcpu->arch.vfp_guest.fpscr, id); return reg_to_user(uaddr, &vcpu->arch.ctxt.vfp.fpscr, id);
case KVM_REG_ARM_VFP_FPINST: case KVM_REG_ARM_VFP_FPINST:
return reg_to_user(uaddr, &vcpu->arch.vfp_guest.fpinst, id); return reg_to_user(uaddr, &vcpu->arch.ctxt.vfp.fpinst, id);
case KVM_REG_ARM_VFP_FPINST2: case KVM_REG_ARM_VFP_FPINST2:
return reg_to_user(uaddr, &vcpu->arch.vfp_guest.fpinst2, id); return reg_to_user(uaddr, &vcpu->arch.ctxt.vfp.fpinst2, id);
case KVM_REG_ARM_VFP_MVFR0: case KVM_REG_ARM_VFP_MVFR0:
val = fmrx(MVFR0); val = fmrx(MVFR0);
return reg_to_user(uaddr, &val, id); return reg_to_user(uaddr, &val, id);
...@@ -945,7 +945,7 @@ static int vfp_set_reg(struct kvm_vcpu *vcpu, u64 id, const void __user *uaddr) ...@@ -945,7 +945,7 @@ static int vfp_set_reg(struct kvm_vcpu *vcpu, u64 id, const void __user *uaddr)
if (vfpid < num_fp_regs()) { if (vfpid < num_fp_regs()) {
if (KVM_REG_SIZE(id) != 8) if (KVM_REG_SIZE(id) != 8)
return -ENOENT; return -ENOENT;
return reg_from_user(&vcpu->arch.vfp_guest.fpregs[vfpid], return reg_from_user(&vcpu->arch.ctxt.vfp.fpregs[vfpid],
uaddr, id); uaddr, id);
} }
...@@ -955,13 +955,13 @@ static int vfp_set_reg(struct kvm_vcpu *vcpu, u64 id, const void __user *uaddr) ...@@ -955,13 +955,13 @@ static int vfp_set_reg(struct kvm_vcpu *vcpu, u64 id, const void __user *uaddr)
switch (vfpid) { switch (vfpid) {
case KVM_REG_ARM_VFP_FPEXC: case KVM_REG_ARM_VFP_FPEXC:
return reg_from_user(&vcpu->arch.vfp_guest.fpexc, uaddr, id); return reg_from_user(&vcpu->arch.ctxt.vfp.fpexc, uaddr, id);
case KVM_REG_ARM_VFP_FPSCR: case KVM_REG_ARM_VFP_FPSCR:
return reg_from_user(&vcpu->arch.vfp_guest.fpscr, uaddr, id); return reg_from_user(&vcpu->arch.ctxt.vfp.fpscr, uaddr, id);
case KVM_REG_ARM_VFP_FPINST: case KVM_REG_ARM_VFP_FPINST:
return reg_from_user(&vcpu->arch.vfp_guest.fpinst, uaddr, id); return reg_from_user(&vcpu->arch.ctxt.vfp.fpinst, uaddr, id);
case KVM_REG_ARM_VFP_FPINST2: case KVM_REG_ARM_VFP_FPINST2:
return reg_from_user(&vcpu->arch.vfp_guest.fpinst2, uaddr, id); return reg_from_user(&vcpu->arch.ctxt.vfp.fpinst2, uaddr, id);
/* These are invariant. */ /* These are invariant. */
case KVM_REG_ARM_VFP_MVFR0: case KVM_REG_ARM_VFP_MVFR0:
if (reg_from_user(&val, uaddr, id)) if (reg_from_user(&val, uaddr, id))
......
...@@ -172,10 +172,11 @@ __kvm_vcpu_return: ...@@ -172,10 +172,11 @@ __kvm_vcpu_return:
#ifdef CONFIG_VFPv3 #ifdef CONFIG_VFPv3
@ Switch VFP/NEON hardware state to the host's @ Switch VFP/NEON hardware state to the host's
add r7, vcpu, #VCPU_VFP_GUEST add r7, vcpu, #(VCPU_GUEST_CTXT + CPU_CTXT_VFP)
store_vfp_state r7 store_vfp_state r7
add r7, vcpu, #VCPU_VFP_HOST add r7, vcpu, #VCPU_HOST_CTXT
ldr r7, [r7] ldr r7, [r7]
add r7, r7, #CPU_CTXT_VFP
restore_vfp_state r7 restore_vfp_state r7
after_vfp_restore: after_vfp_restore:
...@@ -482,10 +483,11 @@ switch_to_guest_vfp: ...@@ -482,10 +483,11 @@ switch_to_guest_vfp:
set_hcptr vmtrap, (HCPTR_TCP(10) | HCPTR_TCP(11)) set_hcptr vmtrap, (HCPTR_TCP(10) | HCPTR_TCP(11))
@ Switch VFP/NEON hardware state to the guest's @ Switch VFP/NEON hardware state to the guest's
add r7, r0, #VCPU_VFP_HOST add r7, r0, #VCPU_HOST_CTXT
ldr r7, [r7] ldr r7, [r7]
add r7, r7, #CPU_CTXT_VFP
store_vfp_state r7 store_vfp_state r7
add r7, r0, #VCPU_VFP_GUEST add r7, r0, #(VCPU_GUEST_CTXT + CPU_CTXT_VFP)
restore_vfp_state r7 restore_vfp_state r7
pop {r3-r7} pop {r3-r7}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment