KVM: PPC: Use load_fp/vr_state rather than load_up_fpu/altivec
authorPaul Mackerras <paulus@samba.org>
Tue, 15 Oct 2013 09:43:01 +0000 (20:43 +1100)
committerAlexander Graf <agraf@suse.de>
Thu, 9 Jan 2014 09:14:59 +0000 (10:14 +0100)
The load_up_fpu and load_up_altivec functions were never intended to
be called from C, and do things like modifying the MSR value in their
callers' stack frames, which are assumed to be interrupt frames.  In
addition, on 32-bit Book S they require the MMU to be off.

This makes KVM use the new load_fp_state() and load_vr_state() functions
instead of load_up_fpu/altivec.  This means we can remove the assembler
glue in book3s_rmhandlers.S, and potentially fixes a bug on Book E,
where load_up_fpu was called directly from C.

Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
arch/powerpc/include/asm/kvm_book3s.h
arch/powerpc/include/asm/switch_to.h
arch/powerpc/kvm/book3s_exports.c
arch/powerpc/kvm/book3s_pr.c
arch/powerpc/kvm/book3s_rmhandlers.S
arch/powerpc/kvm/booke.h

index 4a594b76674d4e536ce714b40c183f598bf380d6..8bb8706946162764eca13a346c3920bcf903fcc8 100644 (file)
@@ -186,9 +186,6 @@ extern void kvmppc_update_lpcr(struct kvm *kvm, unsigned long lpcr,
 
 extern void kvmppc_entry_trampoline(void);
 extern void kvmppc_hv_entry_trampoline(void);
-extern void kvmppc_load_up_fpu(void);
-extern void kvmppc_load_up_altivec(void);
-extern void kvmppc_load_up_vsx(void);
 extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst);
 extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst);
 extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd);
index 9ee12610af02bdca7fd61b9b7f6b16f2c74d36d0..971ca336f451c6b4e6537354a21321d27d499efa 100644 (file)
@@ -25,10 +25,8 @@ static inline void save_tar(struct thread_struct *prev)
 static inline void save_tar(struct thread_struct *prev) {}
 #endif
 
-extern void load_up_fpu(void);
 extern void enable_kernel_fp(void);
 extern void enable_kernel_altivec(void);
-extern void load_up_altivec(struct task_struct *);
 extern int emulate_altivec(struct pt_regs *);
 extern void __giveup_vsx(struct task_struct *);
 extern void giveup_vsx(struct task_struct *);
index 852989a9bad3040751d39a32c81b28bf28d864e4..20d4ea8e656d3eacf3202ef42f806168d44841f4 100644 (file)
@@ -25,9 +25,5 @@ EXPORT_SYMBOL_GPL(kvmppc_hv_entry_trampoline);
 #endif
 #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
 EXPORT_SYMBOL_GPL(kvmppc_entry_trampoline);
-EXPORT_SYMBOL_GPL(kvmppc_load_up_fpu);
-#ifdef CONFIG_ALTIVEC
-EXPORT_SYMBOL_GPL(kvmppc_load_up_altivec);
-#endif
 #endif
 
index 21bf7c5c9545651f9235cd98ecc9ae4894e1ffdc..d63a91f825d39f5ea4c06b3876c1264d161aedde 100644 (file)
@@ -691,7 +691,8 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
 #endif
                t->fp_state.fpscr = vcpu->arch.fpscr;
                t->fpexc_mode = 0;
-               kvmppc_load_up_fpu();
+               enable_kernel_fp();
+               load_fp_state(&t->fp_state);
        }
 
        if (msr & MSR_VEC) {
@@ -699,7 +700,8 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
                memcpy(t->vr_state.vr, vcpu->arch.vr, sizeof(vcpu->arch.vr));
                t->vr_state.vscr = vcpu->arch.vscr;
                t->vrsave = -1;
-               kvmppc_load_up_altivec();
+               enable_kernel_altivec();
+               load_vr_state(&t->vr_state);
 #endif
        }
 
@@ -722,11 +724,15 @@ static void kvmppc_handle_lost_ext(struct kvm_vcpu *vcpu)
        if (!lost_ext)
                return;
 
-       if (lost_ext & MSR_FP)
-               kvmppc_load_up_fpu();
+       if (lost_ext & MSR_FP) {
+               enable_kernel_fp();
+               load_fp_state(&current->thread.fp_state);
+       }
 #ifdef CONFIG_ALTIVEC
-       if (lost_ext & MSR_VEC)
-               kvmppc_load_up_altivec();
+       if (lost_ext & MSR_VEC) {
+               enable_kernel_altivec();
+               load_vr_state(&current->thread.vr_state);
+       }
 #endif
        current->thread.regs->msr |= lost_ext;
 }
index a38c4c9edab87aca16929b5e96377368b5016fbd..c78ffbc371a566aea92dd2d4aa172c70faba1101 100644 (file)
@@ -166,51 +166,4 @@ _GLOBAL(kvmppc_entry_trampoline)
        mtsrr1  r6
        RFI
 
-#if defined(CONFIG_PPC_BOOK3S_32)
-#define STACK_LR       INT_FRAME_SIZE+4
-
-/* load_up_xxx have to run with MSR_DR=0 on Book3S_32 */
-#define MSR_EXT_START                                          \
-       PPC_STL r20, _NIP(r1);                                  \
-       mfmsr   r20;                                            \
-       LOAD_REG_IMMEDIATE(r3, MSR_DR|MSR_EE);                  \
-       andc    r3,r20,r3;              /* Disable DR,EE */     \
-       mtmsr   r3;                                             \
-       sync
-
-#define MSR_EXT_END                                            \
-       mtmsr   r20;                    /* Enable DR,EE */      \
-       sync;                                                   \
-       PPC_LL  r20, _NIP(r1)
-
-#elif defined(CONFIG_PPC_BOOK3S_64)
-#define STACK_LR       _LINK
-#define MSR_EXT_START
-#define MSR_EXT_END
-#endif
-
-/*
- * Activate current's external feature (FPU/Altivec/VSX)
- */
-#define define_load_up(what)                                   \
-                                                               \
-_GLOBAL(kvmppc_load_up_ ## what);                              \
-       PPC_STLU r1, -INT_FRAME_SIZE(r1);                       \
-       mflr    r3;                                             \
-       PPC_STL r3, STACK_LR(r1);                               \
-       MSR_EXT_START;                                          \
-                                                               \
-       bl      FUNC(load_up_ ## what);                         \
-                                                               \
-       MSR_EXT_END;                                            \
-       PPC_LL  r3, STACK_LR(r1);                               \
-       mtlr    r3;                                             \
-       addi    r1, r1, INT_FRAME_SIZE;                         \
-       blr
-
-define_load_up(fpu)
-#ifdef CONFIG_ALTIVEC
-define_load_up(altivec)
-#endif
-
 #include "book3s_segment.S"
index 09bfd9bc7cf8d9b1db12a9afc1956ec2fa9fc5e3..fe59f225327fb03b68c58288289f5ef6ecf9bee8 100644 (file)
@@ -136,7 +136,8 @@ static inline void kvmppc_load_guest_fp(struct kvm_vcpu *vcpu)
 {
 #ifdef CONFIG_PPC_FPU
        if (vcpu->fpu_active && !(current->thread.regs->msr & MSR_FP)) {
-               load_up_fpu();
+               enable_kernel_fp();
+               load_fp_state(&current->thread.fp_state);
                current->thread.regs->msr |= MSR_FP;
        }
 #endif