ARM: KVM: Move VFP registers to a CPU context structure
authorMarc Zyngier <marc.zyngier@arm.com>
Sun, 3 Jan 2016 11:01:49 +0000 (11:01 +0000)
committerMarc Zyngier <marc.zyngier@arm.com>
Mon, 29 Feb 2016 18:34:12 +0000 (18:34 +0000)
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: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
arch/arm/include/asm/kvm_host.h
arch/arm/kernel/asm-offsets.c
arch/arm/kvm/coproc.c
arch/arm/kvm/interrupts.S

index f1e86f1eb2e527e8417d182f7024e01d74f77c2b..b64ac8e4adaa250bdb48fac42928abe1c466b668 100644 (file)
@@ -88,9 +88,15 @@ struct kvm_vcpu_fault_info {
        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_cpu_context ctxt;
+
        struct kvm_regs regs;
 
        int target; /* Processor target */
@@ -111,9 +117,6 @@ struct kvm_vcpu_arch {
        /* Exception Information */
        struct kvm_vcpu_fault_info fault;
 
-       /* Floating point registers (VFP and Advanced SIMD/NEON) */
-       struct vfp_hard_struct vfp_guest;
-
        /* Host FP context */
        kvm_cpu_context_t *host_cpu_context;
 
index 871b8267d211af0e5eaf9d5fb9f8329ae33696e1..346bfca29720d30dd981ac8994d7adacdf5a95a1 100644 (file)
@@ -173,8 +173,9 @@ int main(void)
   DEFINE(VCPU_KVM,             offsetof(struct kvm_vcpu, kvm));
   DEFINE(VCPU_MIDR,            offsetof(struct kvm_vcpu, arch.midr));
   DEFINE(VCPU_CP15,            offsetof(struct kvm_vcpu, arch.cp15));
-  DEFINE(VCPU_VFP_GUEST,       offsetof(struct kvm_vcpu, arch.vfp_guest));
-  DEFINE(VCPU_VFP_HOST,                offsetof(struct kvm_vcpu, arch.host_cpu_context));
+  DEFINE(VCPU_GUEST_CTXT,      offsetof(struct kvm_vcpu, arch.ctxt));
+  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_USR_REGS,                offsetof(struct kvm_vcpu, arch.regs.usr_regs));
   DEFINE(VCPU_SVC_REGS,                offsetof(struct kvm_vcpu, arch.regs.svc_regs));
index f3d88dc388bc560778d49dacfded70aebde44a89..1a643f38031d90fa10f9c87486bdec83d1f87732 100644 (file)
@@ -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 (KVM_REG_SIZE(id) != 8)
                        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);
        }
 
@@ -911,13 +911,13 @@ static int vfp_get_reg(const struct kvm_vcpu *vcpu, u64 id, void __user *uaddr)
 
        switch (vfpid) {
        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:
-               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:
-               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:
-               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:
                val = fmrx(MVFR0);
                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)
        if (vfpid < num_fp_regs()) {
                if (KVM_REG_SIZE(id) != 8)
                        return -ENOENT;
-               return reg_from_user(&vcpu->arch.vfp_guest.fpregs[vfpid],
+               return reg_from_user(&vcpu->arch.ctxt.vfp.fpregs[vfpid],
                                     uaddr, id);
        }
 
@@ -955,13 +955,13 @@ static int vfp_set_reg(struct kvm_vcpu *vcpu, u64 id, const void __user *uaddr)
 
        switch (vfpid) {
        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:
-               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:
-               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:
-               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. */
        case KVM_REG_ARM_VFP_MVFR0:
                if (reg_from_user(&val, uaddr, id))
index 9d9cb71df449242a27afc7c143f01186bb0a9f0b..7bfb2893691441a3dded5476025b76b8d95fc261 100644 (file)
@@ -172,10 +172,11 @@ __kvm_vcpu_return:
 
 #ifdef CONFIG_VFPv3
        @ 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
-       add     r7, vcpu, #VCPU_VFP_HOST
+       add     r7, vcpu, #VCPU_HOST_CTXT
        ldr     r7, [r7]
+       add     r7, r7, #CPU_CTXT_VFP
        restore_vfp_state r7
 
 after_vfp_restore:
@@ -482,10 +483,11 @@ switch_to_guest_vfp:
        set_hcptr vmtrap, (HCPTR_TCP(10) | HCPTR_TCP(11))
 
        @ Switch VFP/NEON hardware state to the guest's
-       add     r7, r0, #VCPU_VFP_HOST
+       add     r7, r0, #VCPU_HOST_CTXT
        ldr     r7, [r7]
+       add     r7, r7, #CPU_CTXT_VFP
        store_vfp_state r7
-       add     r7, r0, #VCPU_VFP_GUEST
+       add     r7, r0, #(VCPU_GUEST_CTXT + CPU_CTXT_VFP)
        restore_vfp_state r7
 
        pop     {r3-r7}