Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09548fda authored by Paul Mackerras's avatar Paul Mackerras Committed by Alexander Graf
Browse files

KVM: PPC: Use load_fp/vr_state rather than load_up_fpu/altivec



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: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
parent b1f0d94c
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -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);
+0 −2
Original line number Diff line number Diff line
@@ -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 *);
+0 −4
Original line number Diff line number Diff line
@@ -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
+12 −6
Original line number Diff line number Diff line
@@ -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;
}
+0 −47
Original line number Diff line number Diff line
@@ -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"
Loading