• Paul Mackerras's avatar
    KVM: PPC: Book3S HV: Drop locks before reading guest memory · 36ee41d1
    Paul Mackerras authored
    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.
    
    Cc: stable@vger.kernel.org # v4.13+
    Fixes: 57900694 ("KVM: PPC: Book3S HV: Virtualize doorbell facility on POWER9")
    Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
    36ee41d1
book3s_hv.c 115 KB