KVM: x86/xen: Fix potential deadlock in kvm_xen_update_runstate_guest()
authorDavid Woodhouse <dwmw@amazon.co.uk>
Wed, 11 Jan 2023 18:06:49 +0000 (18:06 +0000)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 11 Jan 2023 18:32:21 +0000 (13:32 -0500)
commitbbe17c625d6843e9cdf14d81fbece1b0f0c3fb2f
treeaba7b08f42d952a673d1ee91a1111bb620e44184
parent23e60258aeafb04e5dd813f03cb0c8ab7b01462a
KVM: x86/xen: Fix potential deadlock in kvm_xen_update_runstate_guest()

The kvm_xen_update_runstate_guest() function can be called when the vCPU
is being scheduled out, from a preempt notifier. It *opportunistically*
updates the runstate area in the guest memory, if the gfn_to_pfn_cache
which caches the appropriate address is still valid.

If there is *contention* when it attempts to obtain gpc->lock, then
locking inside the priority inheritance checks may cause a deadlock.
Lockdep reports:

[13890.148997] Chain exists of:
                 &gpc->lock --> &p->pi_lock --> &rq->__lock

[13890.149002]  Possible unsafe locking scenario:

[13890.149003]        CPU0                    CPU1
[13890.149004]        ----                    ----
[13890.149005]   lock(&rq->__lock);
[13890.149007]                                lock(&p->pi_lock);
[13890.149009]                                lock(&rq->__lock);
[13890.149011]   lock(&gpc->lock);
[13890.149013]
                *** DEADLOCK ***

In the general case, if there's contention for a read lock on gpc->lock,
that's going to be because something else is either invalidating or
revalidating the cache. Either way, we've raced with seeing it in an
invalid state, in which case we would have aborted the opportunistic
update anyway.

So in the 'atomic' case when called from the preempt notifier, just
switch to using read_trylock() and avoid the PI handling altogether.

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Message-Id: <20230111180651.14394-2-dwmw2@infradead.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/xen.c