Protect `evtchnfd` by entering SRCU critical section. Signed-off-by: Michal Luczaj <mhal@xxxxxxx> --- arch/x86/kvm/xen.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c index d7af40240248..8e17629e5665 100644 --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -1825,20 +1825,26 @@ static int kvm_xen_eventfd_update(struct kvm *kvm, { u32 port = data->u.evtchn.send_port; struct evtchnfd *evtchnfd; + int ret = -EINVAL; + int idx; if (!port || port >= max_evtchn_port(kvm)) return -EINVAL; + idx = srcu_read_lock(&kvm->srcu); + mutex_lock(&kvm->lock); evtchnfd = idr_find(&kvm->arch.xen.evtchn_ports, port); mutex_unlock(&kvm->lock); - if (!evtchnfd) - return -ENOENT; + if (!evtchnfd) { + ret = -ENOENT; + goto out_rcu; + } /* For an UPDATE, nothing may change except the priority/vcpu */ if (evtchnfd->type != data->u.evtchn.type) - return -EINVAL; + goto out_rcu; /* -EINVAL */ /* * Port cannot change, and if it's zero that was an eventfd @@ -1846,11 +1852,11 @@ static int kvm_xen_eventfd_update(struct kvm *kvm, */ if (!evtchnfd->deliver.port.port || evtchnfd->deliver.port.port != data->u.evtchn.deliver.port.port) - return -EINVAL; + goto out_rcu; /* -EINVAL */ /* We only support 2 level event channels for now */ if (data->u.evtchn.deliver.port.priority != KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL) - return -EINVAL; + goto out_rcu; /* -EINVAL */ mutex_lock(&kvm->lock); evtchnfd->deliver.port.priority = data->u.evtchn.deliver.port.priority; @@ -1859,7 +1865,10 @@ static int kvm_xen_eventfd_update(struct kvm *kvm, evtchnfd->deliver.port.vcpu_idx = -1; } mutex_unlock(&kvm->lock); - return 0; + ret = 0; +out_rcu: + srcu_read_unlock(&kvm->srcu, idx); + return ret; } /* -- 2.39.0