Merge tag 'clk-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / iommu / iommufd / driver.c
blob2d98b04ff1cb7edd382064f1bcedd10afe0a5b77
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES
3 */
4 #include "iommufd_private.h"
6 struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
7 size_t size,
8 enum iommufd_object_type type)
10 struct iommufd_object *obj;
11 int rc;
13 obj = kzalloc(size, GFP_KERNEL_ACCOUNT);
14 if (!obj)
15 return ERR_PTR(-ENOMEM);
16 obj->type = type;
17 /* Starts out bias'd by 1 until it is removed from the xarray */
18 refcount_set(&obj->shortterm_users, 1);
19 refcount_set(&obj->users, 1);
22 * Reserve an ID in the xarray but do not publish the pointer yet since
23 * the caller hasn't initialized it yet. Once the pointer is published
24 * in the xarray and visible to other threads we can't reliably destroy
25 * it anymore, so the caller must complete all errorable operations
26 * before calling iommufd_object_finalize().
28 rc = xa_alloc(&ictx->objects, &obj->id, XA_ZERO_ENTRY, xa_limit_31b,
29 GFP_KERNEL_ACCOUNT);
30 if (rc)
31 goto out_free;
32 return obj;
33 out_free:
34 kfree(obj);
35 return ERR_PTR(rc);
37 EXPORT_SYMBOL_NS_GPL(_iommufd_object_alloc, "IOMMUFD");
39 /* Caller should xa_lock(&viommu->vdevs) to protect the return value */
40 struct device *iommufd_viommu_find_dev(struct iommufd_viommu *viommu,
41 unsigned long vdev_id)
43 struct iommufd_vdevice *vdev;
45 lockdep_assert_held(&viommu->vdevs.xa_lock);
47 vdev = xa_load(&viommu->vdevs, vdev_id);
48 return vdev ? vdev->dev : NULL;
50 EXPORT_SYMBOL_NS_GPL(iommufd_viommu_find_dev, "IOMMUFD");
52 MODULE_DESCRIPTION("iommufd code shared with builtin modules");
53 MODULE_LICENSE("GPL");