Patch "KVM: PPC: Book3S HV: Drop locks before reading guest memory" has been added to the 4.15-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
KVM: PPC: Book3S HV: Drop locks before reading guest memory
to the 4.15-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
kvm-ppc-book3s-hv-drop-locks-before-reading-guest-memory.patch
and it can be found in the queue-4.15 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
36ee41d161c67a6fcf696d4817a0da31f778938cMon Sep 17 00:00:00 2001
From: Paul Mackerras <[email protected]>
Date: Tue, 30 Jan 2018 10:51:32 +1100
Subject: KVM: PPC: Book3S HV: Drop locks before reading guest memory
From: Paul Mackerras <[email protected]>
commit 36ee41d161c67a6fcf696d4817a0da31f778938c upstream.
Running with CONFIG_DEBUG_ATOMIC_SLEEP reveals that HV KVM tries to read guest memory, in order to emulate guest instructions, while preempt is disabled and a vcore lock is held. This occurs in kvmppc_handle_exit_hv(), called from post_guest_process(), when emulating guest doorbell instructions on POWER9 systems, and also when checking whether we have hit a hypervisor breakpoint. Reading guest memory can cause a page fault and thus cause the task to sleep, so we need to avoid reading guest memory while holding a spinlock or when preempt is disabled.
To fix this, we move the preempt_enable() in kvmppc_run_core() to before the loop that calls post_guest_process() for each vcore that has just run, and we drop and re-take the vcore lock around the calls to kvmppc_emulate_debug_inst() and kvmppc_emulate_doorbell_instr().
Dropping the lock is safe with respect to the iteration over the runnable vcpus in post_guest_process(); for_each_runnable_thread is actually safe to use locklessly. It is possible for a vcpu to become runnable and add itself to the runnable_threads array (code near the beginning of kvmppc_run_vcpu()) and then get included in the iteration in post_guest_process despite the fact that it has not just run. This is benign because vcpu->arch.trap and vcpu->arch.ceded will be zero.
--- arch/powerpc/kvm/book3s_hv.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
arch/powerpc/kvm/book3s_hv.c +12 -4
@@ -1005,8 +1005,6 @@ static int kvmppc_emulate_doorbell_instrstruct kvm *kvm = vcpu->kvm;struct kvm_vcpu *tvcpu; -if (!cpu_has_feature (CPU_FTR_ARCH_300 )) -return EMULATE_FAIL ;if (kvmppc_get_last_inst (vcpu,INST_GENERIC , &inst) !=EMULATE_DONE )return RESUME_GUEST ;if (get_op (inst) !=31 )
@@ -1056,6 +1054,7 @@ static int kvmppc_emulate_doorbell_instrreturn RESUME_GUEST ; } +/* Called with vcpu->arch.vcore->lock held */ static int kvmppc_handle_exit_hv (struct kvm_run *run,struct kvm_vcpu *vcpu,struct task_struct *tsk) {
@@ -1176,7 +1175,10 @@ static int kvmppc_handle_exit_hv(struct swab32(vcpu->arch.emul_inst) : vcpu->arch.emul_inst;if (vcpu->guest_debug &KVM_GUESTDBG_USE_SW_BP ) { +/* Need vcore unlocked to call kvmppc_get_last_inst */ +spin_unlock (&vcpu->arch.vcore->lock); r =kvmppc_emulate_debug_inst (run, vcpu); +spin_lock (&vcpu->arch.vcore->lock); }else {kvmppc_core_queue_program (vcpu,SRR1_PROGILL ); r =RESUME_GUEST ;
@@ -1191,8 +1193,13 @@ static int kvmppc_handle_exit_hv(struct*/ case BOOK3S_INTERRUPT_H_FAC_UNAVAIL : r =EMULATE_FAIL ; -if ((vcpu->arch.hfscr >>56 ) ==FSCR_MSGP_LG ) +if (((vcpu->arch.hfscr >>56 ) ==FSCR_MSGP_LG ) && +cpu_has_feature (CPU_FTR_ARCH_300 )) { +/* Need vcore unlocked to call kvmppc_get_last_inst */ +spin_unlock (&vcpu->arch.vcore->lock); r =kvmppc_emulate_doorbell_instr (vcpu); +spin_lock (&vcpu->arch.vcore->lock); + }if (r ==EMULATE_FAIL ) {kvmppc_core_queue_program (vcpu,SRR1_PROGILL ); r =RESUME_GUEST ;
@@ -2934,13 +2941,14 @@ static noinline void kvmppc_run_core(str/* make sure updates to secondary vcpu structs are visible now */ smp_mb (); +preempt_enable (); +for (sub =0 ; sub < core_info.n_subcores; ++sub) { pvc = core_info.vc[sub];post_guest_process (pvc, pvc == vc); }spin_lock (&vc->lock); -preempt_enable (); out: vc->vcore_state =VCORE_INACTIVE ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.15/kvm-ppc-book3s-hv-make-sure-we-don-t-re-enter-guest-without-xive-loaded.patch queue-4.15/kvm-ppc-book3s-hv-drop-locks-before-reading-guest-memory.patch queue-4.15/kvm-ppc-book3s-pr-fix-broken-select-due-to-misspelling.patch