OSDN Git Service

KVM: PPC: booke: save/restore VRSAVE (a.k.a. USPRG0)
authorScott Wood <scottwood@freescale.com>
Wed, 27 Apr 2011 22:24:10 +0000 (17:24 -0500)
committerAvi Kivity <avi@redhat.com>
Sun, 22 May 2011 12:47:50 +0000 (08:47 -0400)
Linux doesn't use USPRG0 (now renamed VRSAVE in the architecture, even
when Altivec isn't involved), but a guest might.

Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kvm/booke_interrupts.S
arch/powerpc/kvm/powerpc.c

index 890897c..a168043 100644 (file)
@@ -223,6 +223,7 @@ struct kvm_vcpu_arch {
        ulong hflags;
        ulong guest_owned_ext;
 #endif
+       u32 vrsave; /* also USPRG0 */
        u32 mmucr;
        ulong sprg4;
        ulong sprg5;
index 23e6a93..cf0d822 100644 (file)
@@ -395,6 +395,7 @@ int main(void)
        DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack));
        DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid));
        DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr));
+       DEFINE(VCPU_VRSAVE, offsetof(struct kvm_vcpu, arch.vrsave));
        DEFINE(VCPU_SPRG4, offsetof(struct kvm_vcpu, arch.sprg4));
        DEFINE(VCPU_SPRG5, offsetof(struct kvm_vcpu, arch.sprg5));
        DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6));
index 1cc471f..b58ccae 100644 (file)
@@ -380,7 +380,6 @@ lightweight_exit:
         * because host interrupt handlers would get confused. */
        lwz     r1, VCPU_GPR(r1)(r4)
 
-       /* XXX handle USPRG0 */
        /* Host interrupt handlers may have clobbered these guest-readable
         * SPRGs, so we need to reload them here with the guest's values. */
        lwz     r3, VCPU_SPRG4(r4)
index ec3d2e7..9e6aa8b 100644 (file)
@@ -298,12 +298,25 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
 
 void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
+#ifdef CONFIG_BOOKE
+       /*
+        * vrsave (formerly usprg0) isn't used by Linux, but may
+        * be used by the guest.
+        *
+        * On non-booke this is associated with Altivec and
+        * is handled by code in book3s.c.
+        */
+       mtspr(SPRN_VRSAVE, vcpu->arch.vrsave);
+#endif
        kvmppc_core_vcpu_load(vcpu, cpu);
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
        kvmppc_core_vcpu_put(vcpu);
+#ifdef CONFIG_BOOKE
+       vcpu->arch.vrsave = mfspr(SPRN_VRSAVE);
+#endif
 }
 
 int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,