#include <linux/clocksource.h>
#include <linux/irqbypass.h>
#include <linux/hyperv.h>
+#include <linux/xarray.h>
#include <asm/apic.h>
#include <asm/pvclock-abi.h>
HV_REFERENCE_TSC_PAGE tsc_ref;
- struct idr conn_to_evt;
+ struct xarray conn_to_evt;
u64 hv_reenlightenment_control;
u64 hv_tsc_emulation_control;
if (param & ~KVM_HYPERV_CONN_ID_MASK)
return HV_STATUS_INVALID_HYPERCALL_INPUT;
- /* the eventfd is protected by vcpu->kvm->srcu, but conn_to_evt isn't */
- rcu_read_lock();
- eventfd = idr_find(&vcpu->kvm->arch.hyperv.conn_to_evt, param);
- rcu_read_unlock();
+ eventfd = xa_load(&vcpu->kvm->arch.hyperv.conn_to_evt, param);
if (!eventfd)
return HV_STATUS_INVALID_PORT_ID;
void kvm_hv_init_vm(struct kvm *kvm)
{
mutex_init(&kvm->arch.hyperv.hv_lock);
- idr_init(&kvm->arch.hyperv.conn_to_evt);
+ xa_init(&kvm->arch.hyperv.conn_to_evt);
}
void kvm_hv_destroy_vm(struct kvm *kvm)
{
struct eventfd_ctx *eventfd;
- int i;
+ unsigned long i;
- idr_for_each_entry(&kvm->arch.hyperv.conn_to_evt, eventfd, i)
+ xa_for_each(&kvm->arch.hyperv.conn_to_evt, i, eventfd)
eventfd_ctx_put(eventfd);
- idr_destroy(&kvm->arch.hyperv.conn_to_evt);
+ xa_destroy(&kvm->arch.hyperv.conn_to_evt);
}
static int kvm_hv_eventfd_assign(struct kvm *kvm, u32 conn_id, int fd)
if (IS_ERR(eventfd))
return PTR_ERR(eventfd);
- mutex_lock(&hv->hv_lock);
- ret = idr_alloc(&hv->conn_to_evt, eventfd, conn_id, conn_id + 1,
- GFP_KERNEL_ACCOUNT);
- mutex_unlock(&hv->hv_lock);
-
- if (ret >= 0)
- return 0;
+ ret = xa_insert(&hv->conn_to_evt, conn_id, eventfd, GFP_KERNEL_ACCOUNT);
+ if (ret < 0)
+ eventfd_ctx_put(eventfd);
- if (ret == -ENOSPC)
- ret = -EEXIST;
- eventfd_ctx_put(eventfd);
return ret;
}
struct kvm_hv *hv = &kvm->arch.hyperv;
struct eventfd_ctx *eventfd;
- mutex_lock(&hv->hv_lock);
- eventfd = idr_remove(&hv->conn_to_evt, conn_id);
- mutex_unlock(&hv->hv_lock);
-
+ eventfd = xa_erase(&hv->conn_to_evt, conn_id);
if (!eventfd)
return -ENOENT;