diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 25afb1d594e3..2d121fbe5c93 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -677,7 +677,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
 	spin_lock_init(&dev_priv->cursor_lock);
 
 	for (i = vmw_res_context; i < vmw_res_max; ++i) {
-		idr_init(&dev_priv->res_idr[i]);
+		xa_init_flags(&dev_priv->resources[i], XA_FLAGS_ALLOC1);
 		INIT_LIST_HEAD(&dev_priv->res_lru[i]);
 	}
 
@@ -988,9 +988,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
 out_err4:
 	memunmap(dev_priv->mmio_virt);
 out_err0:
-	for (i = vmw_res_context; i < vmw_res_max; ++i)
-		idr_destroy(&dev_priv->res_idr[i]);
-
 	if (dev_priv->ctx.staged_bindings)
 		vmw_binding_state_free(dev_priv->ctx.staged_bindings);
 	kfree(dev_priv);
@@ -1000,7 +997,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
 static void vmw_driver_unload(struct drm_device *dev)
 {
 	struct vmw_private *dev_priv = vmw_priv(dev);
-	enum vmw_res_type i;
 
 	unregister_pm_notifier(&dev_priv->pm_nb);
 
@@ -1039,9 +1035,6 @@ static void vmw_driver_unload(struct drm_device *dev)
 	if (dev_priv->ctx.staged_bindings)
 		vmw_binding_state_free(dev_priv->ctx.staged_bindings);
 
-	for (i = vmw_res_context; i < vmw_res_max; ++i)
-		idr_destroy(&dev_priv->res_idr[i]);
-
 	kfree(dev_priv);
 }
 
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index cd607ba9c2fe..e7613a33a773 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -484,7 +484,8 @@ struct vmw_private {
 	 */
 
 	spinlock_t resource_lock;
-	struct idr res_idr[vmw_res_max];
+	struct xarray resources[vmw_res_max];
+
 	/*
 	 * Block lastclose from racing with firstopen.
 	 */
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 3025bfc001a1..d8cc329a9c0e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -56,13 +56,11 @@ vmw_resource_reference_unless_doomed(struct vmw_resource *res)
 void vmw_resource_release_id(struct vmw_resource *res)
 {
 	struct vmw_private *dev_priv = res->dev_priv;
-	struct idr *idr = &dev_priv->res_idr[res->func->res_type];
+	struct xarray *xa = &dev_priv->resources[res->func->res_type];
 
-	spin_lock(&dev_priv->resource_lock);
 	if (res->id != -1)
-		idr_remove(idr, res->id);
+		xa_erase(xa, res->id);
 	res->id = -1;
-	spin_unlock(&dev_priv->resource_lock);
 }
 
 static void vmw_resource_release(struct kref *kref)
@@ -70,8 +68,7 @@ static void vmw_resource_release(struct kref *kref)
 	struct vmw_resource *res =
 	    container_of(kref, struct vmw_resource, kref);
 	struct vmw_private *dev_priv = res->dev_priv;
-	int id;
-	struct idr *idr = &dev_priv->res_idr[res->func->res_type];
+	struct xarray *xa = &dev_priv->resources[res->func->res_type];
 
 	spin_lock(&dev_priv->resource_lock);
 	list_del_init(&res->lru_head);
@@ -101,16 +98,12 @@ static void vmw_resource_release(struct kref *kref)
 		res->hw_destroy(res);
 	}
 
-	id = res->id;
+	if (res->id != -1)
+		xa_erase(xa, res->id);
 	if (res->res_free != NULL)
 		res->res_free(res);
 	else
 		kfree(res);
-
-	spin_lock(&dev_priv->resource_lock);
-	if (id != -1)
-		idr_remove(idr, id);
-	spin_unlock(&dev_priv->resource_lock);
 }
 
 void vmw_resource_unreference(struct vmw_resource **p_res)
@@ -133,21 +126,11 @@ void vmw_resource_unreference(struct vmw_resource **p_res)
 int vmw_resource_alloc_id(struct vmw_resource *res)
 {
 	struct vmw_private *dev_priv = res->dev_priv;
-	int ret;
-	struct idr *idr = &dev_priv->res_idr[res->func->res_type];
+	struct xarray *xa = &dev_priv->resources[res->func->res_type];
 
 	BUG_ON(res->id != -1);
 
-	idr_preload(GFP_KERNEL);
-	spin_lock(&dev_priv->resource_lock);
-
-	ret = idr_alloc(idr, res, 1, 0, GFP_NOWAIT);
-	if (ret >= 0)
-		res->id = ret;
-
-	spin_unlock(&dev_priv->resource_lock);
-	idr_preload_end();
-	return ret < 0 ? ret : 0;
+	return xa_alloc(xa, &res->id, res, xa_limit_31b, GFP_NOWAIT);
 }
 
 /**
