KVM: PPC: Book3S HV: Fix trap number return from __kvmppc_vcore_entry
commit a8b48a4dccea77e29462e59f1dbf0d5aa1ff167c upstream. This fixes a bug where the trap number that is returned by __kvmppc_vcore_entry gets corrupted. The effect of the corruption is that IPIs get ignored on POWER9 systems when the IPI is sent via a doorbell interrupt to a CPU which is executing in a KVM guest. The effect of the IPI being ignored is often that another CPU locks up inside smp_call_function_many() (and if that CPU is holding a spinlock, other CPUs then lock up inside raw_spin_lock()). The trap number is currently held in register r12 for most of the assembly-language part of the guest exit path. In that path, we call kvmppc_subcore_exit_guest(), which is a C function, without restoring r12 afterwards. Depending on the kernel config and the compiler, it may modify r12 or it may not, so some config/compiler combinations see the bug and others don't. To fix this, we arrange for the trap number to be stored on the stack from the 'guest_bypass:' label until the end of the function, then the trap number is loaded and returned in r12 as before. Cc: stable@vger.kernel.org # v4.8+ Fixes: fd7bacbca47a ("KVM: PPC: Book3S HV: Fix TB corruption in guest exit path on HMI interrupt") Signed-off-by: Paul Mackerras <paulus@ozlabs.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
683b4520d0
commit
c51eb7379d
@ -308,7 +308,6 @@ kvm_novcpu_exit:
|
||||
stw r12, STACK_SLOT_TRAP(r1)
|
||||
bl kvmhv_commence_exit
|
||||
nop
|
||||
lwz r12, STACK_SLOT_TRAP(r1)
|
||||
b kvmhv_switch_to_host
|
||||
|
||||
/*
|
||||
@ -1136,6 +1135,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
|
||||
|
||||
secondary_too_late:
|
||||
li r12, 0
|
||||
stw r12, STACK_SLOT_TRAP(r1)
|
||||
cmpdi r4, 0
|
||||
beq 11f
|
||||
stw r12, VCPU_TRAP(r4)
|
||||
@ -1445,12 +1445,12 @@ mc_cont:
|
||||
1:
|
||||
#endif /* CONFIG_KVM_XICS */
|
||||
|
||||
stw r12, STACK_SLOT_TRAP(r1)
|
||||
mr r3, r12
|
||||
/* Increment exit count, poke other threads to exit */
|
||||
bl kvmhv_commence_exit
|
||||
nop
|
||||
ld r9, HSTATE_KVM_VCPU(r13)
|
||||
lwz r12, VCPU_TRAP(r9)
|
||||
|
||||
/* Stop others sending VCPU interrupts to this physical CPU */
|
||||
li r0, -1
|
||||
@ -1816,6 +1816,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_POWER9_DD1)
|
||||
* POWER7/POWER8 guest -> host partition switch code.
|
||||
* We don't have to lock against tlbies but we do
|
||||
* have to coordinate the hardware threads.
|
||||
* Here STACK_SLOT_TRAP(r1) contains the trap number.
|
||||
*/
|
||||
kvmhv_switch_to_host:
|
||||
/* Secondary threads wait for primary to do partition switch */
|
||||
@ -1868,11 +1869,11 @@ BEGIN_FTR_SECTION
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
|
||||
|
||||
/* If HMI, call kvmppc_realmode_hmi_handler() */
|
||||
lwz r12, STACK_SLOT_TRAP(r1)
|
||||
cmpwi r12, BOOK3S_INTERRUPT_HMI
|
||||
bne 27f
|
||||
bl kvmppc_realmode_hmi_handler
|
||||
nop
|
||||
li r12, BOOK3S_INTERRUPT_HMI
|
||||
/*
|
||||
* At this point kvmppc_realmode_hmi_handler would have resync-ed
|
||||
* the TB. Hence it is not required to subtract guest timebase
|
||||
@ -1950,6 +1951,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX)
|
||||
li r0, KVM_GUEST_MODE_NONE
|
||||
stb r0, HSTATE_IN_GUEST(r13)
|
||||
|
||||
lwz r12, STACK_SLOT_TRAP(r1) /* return trap # in r12 */
|
||||
ld r0, SFS+PPC_LR_STKOFF(r1)
|
||||
addi r1, r1, SFS
|
||||
mtlr r0
|
||||
|
Loading…
x
Reference in New Issue
Block a user