KVM: PPC: Book3S HV P9: implement kvmppc_xive_pull_vcpu in C
This is more symmetric with kvmppc_xive_push_vcpu, and has the advantage that it runs with the MMU on. The extra test added to the asm will go away with a future change. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Reviewed-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20210528090752.3542186-9-npiggin@gmail.com
This commit is contained in:
Родитель
e2762743c6
Коммит
023c3c96ca
|
@ -671,6 +671,7 @@ extern int kvmppc_xive_set_icp(struct kvm_vcpu *vcpu, u64 icpval);
|
|||
extern int kvmppc_xive_set_irq(struct kvm *kvm, int irq_source_id, u32 irq,
|
||||
int level, bool line_status);
|
||||
extern void kvmppc_xive_push_vcpu(struct kvm_vcpu *vcpu);
|
||||
extern void kvmppc_xive_pull_vcpu(struct kvm_vcpu *vcpu);
|
||||
|
||||
static inline int kvmppc_xive_enabled(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
|
@ -711,6 +712,7 @@ static inline int kvmppc_xive_set_icp(struct kvm_vcpu *vcpu, u64 icpval) { retur
|
|||
static inline int kvmppc_xive_set_irq(struct kvm *kvm, int irq_source_id, u32 irq,
|
||||
int level, bool line_status) { return -ENODEV; }
|
||||
static inline void kvmppc_xive_push_vcpu(struct kvm_vcpu *vcpu) { }
|
||||
static inline void kvmppc_xive_pull_vcpu(struct kvm_vcpu *vcpu) { }
|
||||
|
||||
static inline int kvmppc_xive_enabled(struct kvm_vcpu *vcpu)
|
||||
{ return 0; }
|
||||
|
|
|
@ -3570,6 +3570,8 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu *vcpu, u64 time_limit,
|
|||
|
||||
trap = __kvmhv_vcpu_entry_p9(vcpu);
|
||||
|
||||
kvmppc_xive_pull_vcpu(vcpu);
|
||||
|
||||
/* Advance host PURR/SPURR by the amount used by guest */
|
||||
purr = mfspr(SPRN_PURR);
|
||||
spurr = mfspr(SPRN_SPURR);
|
||||
|
|
|
@ -1445,6 +1445,11 @@ guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */
|
|||
bl kvmhv_accumulate_time
|
||||
#endif
|
||||
#ifdef CONFIG_KVM_XICS
|
||||
/* If we came in through the P9 short path, xive pull is done in C */
|
||||
lwz r0, STACK_SLOT_SHORT_PATH(r1)
|
||||
cmpwi r0, 0
|
||||
bne 1f
|
||||
|
||||
/* We are exiting, pull the VP from the XIVE */
|
||||
lbz r0, VCPU_XIVE_PUSHED(r9)
|
||||
cmpwi cr0, r0, 0
|
||||
|
|
|
@ -127,6 +127,37 @@ void kvmppc_xive_push_vcpu(struct kvm_vcpu *vcpu)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(kvmppc_xive_push_vcpu);
|
||||
|
||||
/*
|
||||
* Pull a vcpu's context from the XIVE on guest exit.
|
||||
* This assumes we are in virtual mode (MMU on)
|
||||
*/
|
||||
void kvmppc_xive_pull_vcpu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
void __iomem *tima = local_paca->kvm_hstate.xive_tima_virt;
|
||||
|
||||
if (!vcpu->arch.xive_pushed)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Should not have been pushed if there is no tima
|
||||
*/
|
||||
if (WARN_ON(!tima))
|
||||
return;
|
||||
|
||||
eieio();
|
||||
/* First load to pull the context, we ignore the value */
|
||||
__raw_readl(tima + TM_SPC_PULL_OS_CTX);
|
||||
/* Second load to recover the context state (Words 0 and 1) */
|
||||
vcpu->arch.xive_saved_state.w01 = __raw_readq(tima + TM_QW1_OS);
|
||||
|
||||
/* Fixup some of the state for the next load */
|
||||
vcpu->arch.xive_saved_state.lsmfb = 0;
|
||||
vcpu->arch.xive_saved_state.ack = 0xff;
|
||||
vcpu->arch.xive_pushed = 0;
|
||||
eieio();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvmppc_xive_pull_vcpu);
|
||||
|
||||
/*
|
||||
* This is a simple trigger for a generic XIVE IRQ. This must
|
||||
* only be called for interrupts that support a trigger page
|
||||
|
|
Загрузка…
Ссылка в новой задаче