]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
KVM: PPC: Add giveup_ext() hook to PPC KVM ops
authorSimon Guo <wei.guo.simon@gmail.com>
Mon, 21 May 2018 05:24:22 +0000 (13:24 +0800)
committerPaul Mackerras <paulus@ozlabs.org>
Tue, 22 May 2018 09:51:13 +0000 (19:51 +1000)
Currently HV will save math regs(FP/VEC/VSX) when trap into host. But
PR KVM will only save math regs when qemu task switch out of CPU, or
when returning from qemu code.

To emulate FP/VEC/VSX mmio load, PR KVM need to make sure that math
regs were flushed firstly and then be able to update saved VCPU
FPR/VEC/VSX area reasonably.

This patch adds giveup_ext() field to KVM ops. Only PR KVM has non-NULL
giveup_ext() ops. kvmppc_complete_mmio_load() can invoke that hook
(when not NULL) to flush math regs accordingly, before updating saved
register vals.

Math regs flush is also necessary for STORE, which will be covered
in later patch within this patch series.

Signed-off-by: Simon Guo <wei.guo.simon@gmail.com>
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
arch/powerpc/include/asm/kvm_ppc.h
arch/powerpc/kvm/book3s_pr.c
arch/powerpc/kvm/powerpc.c

index 139cdf0abf902474632cf33f82bcd1b59a5df888..1f087c4cb3866c044854bd6475b41b60c331397a 100644 (file)
@@ -324,6 +324,7 @@ struct kvmppc_ops {
        int (*get_rmmu_info)(struct kvm *kvm, struct kvm_ppc_rmmu_info *info);
        int (*set_smt_mode)(struct kvm *kvm, unsigned long mode,
                            unsigned long flags);
+       void (*giveup_ext)(struct kvm_vcpu *vcpu, ulong msr);
 };
 
 extern struct kvmppc_ops *kvmppc_hv_ops;
index 3d0251edc13c1778783b3d51896134372087a089..c74a8885427d6e0e2f6582add39cd507e538c2cf 100644 (file)
@@ -1789,6 +1789,7 @@ static struct kvmppc_ops kvm_ops_pr = {
 #ifdef CONFIG_PPC_BOOK3S_64
        .hcall_implemented = kvmppc_hcall_impl_pr,
 #endif
+       .giveup_ext = kvmppc_giveup_ext,
 };
 
 
index 45daf3b9d9d24f2db573db8e5a90ef4a5c9289b0..8ce9e7ba5fed37e39fb281135ff23e754574fb05 100644 (file)
@@ -1061,6 +1061,9 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu,
                kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr);
                break;
        case KVM_MMIO_REG_FPR:
+               if (vcpu->kvm->arch.kvm_ops->giveup_ext)
+                       vcpu->kvm->arch.kvm_ops->giveup_ext(vcpu, MSR_FP);
+
                VCPU_FPR(vcpu, vcpu->arch.io_gpr & KVM_MMIO_REG_MASK) = gpr;
                break;
 #ifdef CONFIG_PPC_BOOK3S
@@ -1074,6 +1077,9 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu,
 #endif
 #ifdef CONFIG_VSX
        case KVM_MMIO_REG_VSX:
+               if (vcpu->kvm->arch.kvm_ops->giveup_ext)
+                       vcpu->kvm->arch.kvm_ops->giveup_ext(vcpu, MSR_VSX);
+
                if (vcpu->arch.mmio_vsx_copy_type == KVMPPC_VSX_COPY_DWORD)
                        kvmppc_set_vsr_dword(vcpu, gpr);
                else if (vcpu->arch.mmio_vsx_copy_type == KVMPPC_VSX_COPY_WORD)
@@ -1088,6 +1094,9 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu,
 #endif
 #ifdef CONFIG_ALTIVEC
        case KVM_MMIO_REG_VMX:
+               if (vcpu->kvm->arch.kvm_ops->giveup_ext)
+                       vcpu->kvm->arch.kvm_ops->giveup_ext(vcpu, MSR_VEC);
+
                kvmppc_set_vmx_dword(vcpu, gpr);
                break;
 #endif