162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/* Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES
362306a36Sopenharmony_ci */
462306a36Sopenharmony_ci#ifndef __IOMMUFD_PRIVATE_H
562306a36Sopenharmony_ci#define __IOMMUFD_PRIVATE_H
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/rwsem.h>
862306a36Sopenharmony_ci#include <linux/xarray.h>
962306a36Sopenharmony_ci#include <linux/refcount.h>
1062306a36Sopenharmony_ci#include <linux/uaccess.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_cistruct iommu_domain;
1362306a36Sopenharmony_cistruct iommu_group;
1462306a36Sopenharmony_cistruct iommu_option;
1562306a36Sopenharmony_cistruct iommufd_device;
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cistruct iommufd_ctx {
1862306a36Sopenharmony_ci	struct file *file;
1962306a36Sopenharmony_ci	struct xarray objects;
2062306a36Sopenharmony_ci	struct xarray groups;
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci	u8 account_mode;
2362306a36Sopenharmony_ci	/* Compatibility with VFIO no iommu */
2462306a36Sopenharmony_ci	u8 no_iommu_mode;
2562306a36Sopenharmony_ci	struct iommufd_ioas *vfio_ioas;
2662306a36Sopenharmony_ci};
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/*
2962306a36Sopenharmony_ci * The IOVA to PFN map. The map automatically copies the PFNs into multiple
3062306a36Sopenharmony_ci * domains and permits sharing of PFNs between io_pagetable instances. This
3162306a36Sopenharmony_ci * supports both a design where IOAS's are 1:1 with a domain (eg because the
3262306a36Sopenharmony_ci * domain is HW customized), or where the IOAS is 1:N with multiple generic
3362306a36Sopenharmony_ci * domains.  The io_pagetable holds an interval tree of iopt_areas which point
3462306a36Sopenharmony_ci * to shared iopt_pages which hold the pfns mapped to the page table.
3562306a36Sopenharmony_ci *
3662306a36Sopenharmony_ci * The locking order is domains_rwsem -> iova_rwsem -> pages::mutex
3762306a36Sopenharmony_ci */
3862306a36Sopenharmony_cistruct io_pagetable {
3962306a36Sopenharmony_ci	struct rw_semaphore domains_rwsem;
4062306a36Sopenharmony_ci	struct xarray domains;
4162306a36Sopenharmony_ci	struct xarray access_list;
4262306a36Sopenharmony_ci	unsigned int next_domain_id;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	struct rw_semaphore iova_rwsem;
4562306a36Sopenharmony_ci	struct rb_root_cached area_itree;
4662306a36Sopenharmony_ci	/* IOVA that cannot become reserved, struct iopt_allowed */
4762306a36Sopenharmony_ci	struct rb_root_cached allowed_itree;
4862306a36Sopenharmony_ci	/* IOVA that cannot be allocated, struct iopt_reserved */
4962306a36Sopenharmony_ci	struct rb_root_cached reserved_itree;
5062306a36Sopenharmony_ci	u8 disable_large_pages;
5162306a36Sopenharmony_ci	unsigned long iova_alignment;
5262306a36Sopenharmony_ci};
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_civoid iopt_init_table(struct io_pagetable *iopt);
5562306a36Sopenharmony_civoid iopt_destroy_table(struct io_pagetable *iopt);
5662306a36Sopenharmony_ciint iopt_get_pages(struct io_pagetable *iopt, unsigned long iova,
5762306a36Sopenharmony_ci		   unsigned long length, struct list_head *pages_list);
5862306a36Sopenharmony_civoid iopt_free_pages_list(struct list_head *pages_list);
5962306a36Sopenharmony_cienum {
6062306a36Sopenharmony_ci	IOPT_ALLOC_IOVA = 1 << 0,
6162306a36Sopenharmony_ci};
6262306a36Sopenharmony_ciint iopt_map_user_pages(struct iommufd_ctx *ictx, struct io_pagetable *iopt,
6362306a36Sopenharmony_ci			unsigned long *iova, void __user *uptr,
6462306a36Sopenharmony_ci			unsigned long length, int iommu_prot,
6562306a36Sopenharmony_ci			unsigned int flags);
6662306a36Sopenharmony_ciint iopt_map_pages(struct io_pagetable *iopt, struct list_head *pages_list,
6762306a36Sopenharmony_ci		   unsigned long length, unsigned long *dst_iova,
6862306a36Sopenharmony_ci		   int iommu_prot, unsigned int flags);
6962306a36Sopenharmony_ciint iopt_unmap_iova(struct io_pagetable *iopt, unsigned long iova,
7062306a36Sopenharmony_ci		    unsigned long length, unsigned long *unmapped);
7162306a36Sopenharmony_ciint iopt_unmap_all(struct io_pagetable *iopt, unsigned long *unmapped);
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_civoid iommufd_access_notify_unmap(struct io_pagetable *iopt, unsigned long iova,
7462306a36Sopenharmony_ci				 unsigned long length);
7562306a36Sopenharmony_ciint iopt_table_add_domain(struct io_pagetable *iopt,
7662306a36Sopenharmony_ci			  struct iommu_domain *domain);
7762306a36Sopenharmony_civoid iopt_table_remove_domain(struct io_pagetable *iopt,
7862306a36Sopenharmony_ci			      struct iommu_domain *domain);
7962306a36Sopenharmony_ciint iopt_table_enforce_dev_resv_regions(struct io_pagetable *iopt,
8062306a36Sopenharmony_ci					struct device *dev,
8162306a36Sopenharmony_ci					phys_addr_t *sw_msi_start);
8262306a36Sopenharmony_ciint iopt_set_allow_iova(struct io_pagetable *iopt,
8362306a36Sopenharmony_ci			struct rb_root_cached *allowed_iova);
8462306a36Sopenharmony_ciint iopt_reserve_iova(struct io_pagetable *iopt, unsigned long start,
8562306a36Sopenharmony_ci		      unsigned long last, void *owner);
8662306a36Sopenharmony_civoid iopt_remove_reserved_iova(struct io_pagetable *iopt, void *owner);
8762306a36Sopenharmony_ciint iopt_cut_iova(struct io_pagetable *iopt, unsigned long *iovas,
8862306a36Sopenharmony_ci		  size_t num_iovas);
8962306a36Sopenharmony_civoid iopt_enable_large_pages(struct io_pagetable *iopt);
9062306a36Sopenharmony_ciint iopt_disable_large_pages(struct io_pagetable *iopt);
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_cistruct iommufd_ucmd {
9362306a36Sopenharmony_ci	struct iommufd_ctx *ictx;
9462306a36Sopenharmony_ci	void __user *ubuffer;
9562306a36Sopenharmony_ci	u32 user_size;
9662306a36Sopenharmony_ci	void *cmd;
9762306a36Sopenharmony_ci};
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ciint iommufd_vfio_ioctl(struct iommufd_ctx *ictx, unsigned int cmd,
10062306a36Sopenharmony_ci		       unsigned long arg);
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci/* Copy the response in ucmd->cmd back to userspace. */
10362306a36Sopenharmony_cistatic inline int iommufd_ucmd_respond(struct iommufd_ucmd *ucmd,
10462306a36Sopenharmony_ci				       size_t cmd_len)
10562306a36Sopenharmony_ci{
10662306a36Sopenharmony_ci	if (copy_to_user(ucmd->ubuffer, ucmd->cmd,
10762306a36Sopenharmony_ci			 min_t(size_t, ucmd->user_size, cmd_len)))
10862306a36Sopenharmony_ci		return -EFAULT;
10962306a36Sopenharmony_ci	return 0;
11062306a36Sopenharmony_ci}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_cienum iommufd_object_type {
11362306a36Sopenharmony_ci	IOMMUFD_OBJ_NONE,
11462306a36Sopenharmony_ci	IOMMUFD_OBJ_ANY = IOMMUFD_OBJ_NONE,
11562306a36Sopenharmony_ci	IOMMUFD_OBJ_DEVICE,
11662306a36Sopenharmony_ci	IOMMUFD_OBJ_HW_PAGETABLE,
11762306a36Sopenharmony_ci	IOMMUFD_OBJ_IOAS,
11862306a36Sopenharmony_ci	IOMMUFD_OBJ_ACCESS,
11962306a36Sopenharmony_ci#ifdef CONFIG_IOMMUFD_TEST
12062306a36Sopenharmony_ci	IOMMUFD_OBJ_SELFTEST,
12162306a36Sopenharmony_ci#endif
12262306a36Sopenharmony_ci	IOMMUFD_OBJ_MAX,
12362306a36Sopenharmony_ci};
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci/* Base struct for all objects with a userspace ID handle. */
12662306a36Sopenharmony_cistruct iommufd_object {
12762306a36Sopenharmony_ci	struct rw_semaphore destroy_rwsem;
12862306a36Sopenharmony_ci	refcount_t users;
12962306a36Sopenharmony_ci	enum iommufd_object_type type;
13062306a36Sopenharmony_ci	unsigned int id;
13162306a36Sopenharmony_ci};
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_cistatic inline bool iommufd_lock_obj(struct iommufd_object *obj)
13462306a36Sopenharmony_ci{
13562306a36Sopenharmony_ci	if (!down_read_trylock(&obj->destroy_rwsem))
13662306a36Sopenharmony_ci		return false;
13762306a36Sopenharmony_ci	if (!refcount_inc_not_zero(&obj->users)) {
13862306a36Sopenharmony_ci		up_read(&obj->destroy_rwsem);
13962306a36Sopenharmony_ci		return false;
14062306a36Sopenharmony_ci	}
14162306a36Sopenharmony_ci	return true;
14262306a36Sopenharmony_ci}
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_cistruct iommufd_object *iommufd_get_object(struct iommufd_ctx *ictx, u32 id,
14562306a36Sopenharmony_ci					  enum iommufd_object_type type);
14662306a36Sopenharmony_cistatic inline void iommufd_put_object(struct iommufd_object *obj)
14762306a36Sopenharmony_ci{
14862306a36Sopenharmony_ci	refcount_dec(&obj->users);
14962306a36Sopenharmony_ci	up_read(&obj->destroy_rwsem);
15062306a36Sopenharmony_ci}
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_civoid iommufd_object_abort(struct iommufd_ctx *ictx, struct iommufd_object *obj);
15362306a36Sopenharmony_civoid iommufd_object_abort_and_destroy(struct iommufd_ctx *ictx,
15462306a36Sopenharmony_ci				      struct iommufd_object *obj);
15562306a36Sopenharmony_civoid iommufd_object_finalize(struct iommufd_ctx *ictx,
15662306a36Sopenharmony_ci			     struct iommufd_object *obj);
15762306a36Sopenharmony_civoid __iommufd_object_destroy_user(struct iommufd_ctx *ictx,
15862306a36Sopenharmony_ci				   struct iommufd_object *obj, bool allow_fail);
15962306a36Sopenharmony_cistatic inline void iommufd_object_destroy_user(struct iommufd_ctx *ictx,
16062306a36Sopenharmony_ci					       struct iommufd_object *obj)
16162306a36Sopenharmony_ci{
16262306a36Sopenharmony_ci	__iommufd_object_destroy_user(ictx, obj, false);
16362306a36Sopenharmony_ci}
16462306a36Sopenharmony_cistatic inline void iommufd_object_deref_user(struct iommufd_ctx *ictx,
16562306a36Sopenharmony_ci					     struct iommufd_object *obj)
16662306a36Sopenharmony_ci{
16762306a36Sopenharmony_ci	__iommufd_object_destroy_user(ictx, obj, true);
16862306a36Sopenharmony_ci}
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_cistruct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
17162306a36Sopenharmony_ci					     size_t size,
17262306a36Sopenharmony_ci					     enum iommufd_object_type type);
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci#define iommufd_object_alloc(ictx, ptr, type)                                  \
17562306a36Sopenharmony_ci	container_of(_iommufd_object_alloc(                                    \
17662306a36Sopenharmony_ci			     ictx,                                             \
17762306a36Sopenharmony_ci			     sizeof(*(ptr)) + BUILD_BUG_ON_ZERO(               \
17862306a36Sopenharmony_ci						      offsetof(typeof(*(ptr)), \
17962306a36Sopenharmony_ci							       obj) != 0),     \
18062306a36Sopenharmony_ci			     type),                                            \
18162306a36Sopenharmony_ci		     typeof(*(ptr)), obj)
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci/*
18462306a36Sopenharmony_ci * The IO Address Space (IOAS) pagetable is a virtual page table backed by the
18562306a36Sopenharmony_ci * io_pagetable object. It is a user controlled mapping of IOVA -> PFNs. The
18662306a36Sopenharmony_ci * mapping is copied into all of the associated domains and made available to
18762306a36Sopenharmony_ci * in-kernel users.
18862306a36Sopenharmony_ci *
18962306a36Sopenharmony_ci * Every iommu_domain that is created is wrapped in a iommufd_hw_pagetable
19062306a36Sopenharmony_ci * object. When we go to attach a device to an IOAS we need to get an
19162306a36Sopenharmony_ci * iommu_domain and wrapping iommufd_hw_pagetable for it.
19262306a36Sopenharmony_ci *
19362306a36Sopenharmony_ci * An iommu_domain & iommfd_hw_pagetable will be automatically selected
19462306a36Sopenharmony_ci * for a device based on the hwpt_list. If no suitable iommu_domain
19562306a36Sopenharmony_ci * is found a new iommu_domain will be created.
19662306a36Sopenharmony_ci */
19762306a36Sopenharmony_cistruct iommufd_ioas {
19862306a36Sopenharmony_ci	struct iommufd_object obj;
19962306a36Sopenharmony_ci	struct io_pagetable iopt;
20062306a36Sopenharmony_ci	struct mutex mutex;
20162306a36Sopenharmony_ci	struct list_head hwpt_list;
20262306a36Sopenharmony_ci};
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_cistatic inline struct iommufd_ioas *iommufd_get_ioas(struct iommufd_ctx *ictx,
20562306a36Sopenharmony_ci						    u32 id)
20662306a36Sopenharmony_ci{
20762306a36Sopenharmony_ci	return container_of(iommufd_get_object(ictx, id,
20862306a36Sopenharmony_ci					       IOMMUFD_OBJ_IOAS),
20962306a36Sopenharmony_ci			    struct iommufd_ioas, obj);
21062306a36Sopenharmony_ci}
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_cistruct iommufd_ioas *iommufd_ioas_alloc(struct iommufd_ctx *ictx);
21362306a36Sopenharmony_ciint iommufd_ioas_alloc_ioctl(struct iommufd_ucmd *ucmd);
21462306a36Sopenharmony_civoid iommufd_ioas_destroy(struct iommufd_object *obj);
21562306a36Sopenharmony_ciint iommufd_ioas_iova_ranges(struct iommufd_ucmd *ucmd);
21662306a36Sopenharmony_ciint iommufd_ioas_allow_iovas(struct iommufd_ucmd *ucmd);
21762306a36Sopenharmony_ciint iommufd_ioas_map(struct iommufd_ucmd *ucmd);
21862306a36Sopenharmony_ciint iommufd_ioas_copy(struct iommufd_ucmd *ucmd);
21962306a36Sopenharmony_ciint iommufd_ioas_unmap(struct iommufd_ucmd *ucmd);
22062306a36Sopenharmony_ciint iommufd_ioas_option(struct iommufd_ucmd *ucmd);
22162306a36Sopenharmony_ciint iommufd_option_rlimit_mode(struct iommu_option *cmd,
22262306a36Sopenharmony_ci			       struct iommufd_ctx *ictx);
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ciint iommufd_vfio_ioas(struct iommufd_ucmd *ucmd);
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci/*
22762306a36Sopenharmony_ci * A HW pagetable is called an iommu_domain inside the kernel. This user object
22862306a36Sopenharmony_ci * allows directly creating and inspecting the domains. Domains that have kernel
22962306a36Sopenharmony_ci * owned page tables will be associated with an iommufd_ioas that provides the
23062306a36Sopenharmony_ci * IOVA to PFN map.
23162306a36Sopenharmony_ci */
23262306a36Sopenharmony_cistruct iommufd_hw_pagetable {
23362306a36Sopenharmony_ci	struct iommufd_object obj;
23462306a36Sopenharmony_ci	struct iommufd_ioas *ioas;
23562306a36Sopenharmony_ci	struct iommu_domain *domain;
23662306a36Sopenharmony_ci	bool auto_domain : 1;
23762306a36Sopenharmony_ci	bool enforce_cache_coherency : 1;
23862306a36Sopenharmony_ci	bool msi_cookie : 1;
23962306a36Sopenharmony_ci	/* Head at iommufd_ioas::hwpt_list */
24062306a36Sopenharmony_ci	struct list_head hwpt_item;
24162306a36Sopenharmony_ci};
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_cistruct iommufd_hw_pagetable *
24462306a36Sopenharmony_ciiommufd_hw_pagetable_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
24562306a36Sopenharmony_ci			   struct iommufd_device *idev, bool immediate_attach);
24662306a36Sopenharmony_ciint iommufd_hw_pagetable_enforce_cc(struct iommufd_hw_pagetable *hwpt);
24762306a36Sopenharmony_ciint iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
24862306a36Sopenharmony_ci				struct iommufd_device *idev);
24962306a36Sopenharmony_cistruct iommufd_hw_pagetable *
25062306a36Sopenharmony_ciiommufd_hw_pagetable_detach(struct iommufd_device *idev);
25162306a36Sopenharmony_civoid iommufd_hw_pagetable_destroy(struct iommufd_object *obj);
25262306a36Sopenharmony_civoid iommufd_hw_pagetable_abort(struct iommufd_object *obj);
25362306a36Sopenharmony_ciint iommufd_hwpt_alloc(struct iommufd_ucmd *ucmd);
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_cistatic inline void iommufd_hw_pagetable_put(struct iommufd_ctx *ictx,
25662306a36Sopenharmony_ci					    struct iommufd_hw_pagetable *hwpt)
25762306a36Sopenharmony_ci{
25862306a36Sopenharmony_ci	lockdep_assert_not_held(&hwpt->ioas->mutex);
25962306a36Sopenharmony_ci	if (hwpt->auto_domain)
26062306a36Sopenharmony_ci		iommufd_object_deref_user(ictx, &hwpt->obj);
26162306a36Sopenharmony_ci	else
26262306a36Sopenharmony_ci		refcount_dec(&hwpt->obj.users);
26362306a36Sopenharmony_ci}
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_cistruct iommufd_group {
26662306a36Sopenharmony_ci	struct kref ref;
26762306a36Sopenharmony_ci	struct mutex lock;
26862306a36Sopenharmony_ci	struct iommufd_ctx *ictx;
26962306a36Sopenharmony_ci	struct iommu_group *group;
27062306a36Sopenharmony_ci	struct iommufd_hw_pagetable *hwpt;
27162306a36Sopenharmony_ci	struct list_head device_list;
27262306a36Sopenharmony_ci	phys_addr_t sw_msi_start;
27362306a36Sopenharmony_ci};
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci/*
27662306a36Sopenharmony_ci * A iommufd_device object represents the binding relationship between a
27762306a36Sopenharmony_ci * consuming driver and the iommufd. These objects are created/destroyed by
27862306a36Sopenharmony_ci * external drivers, not by userspace.
27962306a36Sopenharmony_ci */
28062306a36Sopenharmony_cistruct iommufd_device {
28162306a36Sopenharmony_ci	struct iommufd_object obj;
28262306a36Sopenharmony_ci	struct iommufd_ctx *ictx;
28362306a36Sopenharmony_ci	struct iommufd_group *igroup;
28462306a36Sopenharmony_ci	struct list_head group_item;
28562306a36Sopenharmony_ci	/* always the physical device */
28662306a36Sopenharmony_ci	struct device *dev;
28762306a36Sopenharmony_ci	bool enforce_cache_coherency;
28862306a36Sopenharmony_ci};
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_cistatic inline struct iommufd_device *
29162306a36Sopenharmony_ciiommufd_get_device(struct iommufd_ucmd *ucmd, u32 id)
29262306a36Sopenharmony_ci{
29362306a36Sopenharmony_ci	return container_of(iommufd_get_object(ucmd->ictx, id,
29462306a36Sopenharmony_ci					       IOMMUFD_OBJ_DEVICE),
29562306a36Sopenharmony_ci			    struct iommufd_device, obj);
29662306a36Sopenharmony_ci}
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_civoid iommufd_device_destroy(struct iommufd_object *obj);
29962306a36Sopenharmony_ciint iommufd_get_hw_info(struct iommufd_ucmd *ucmd);
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_cistruct iommufd_access {
30262306a36Sopenharmony_ci	struct iommufd_object obj;
30362306a36Sopenharmony_ci	struct iommufd_ctx *ictx;
30462306a36Sopenharmony_ci	struct iommufd_ioas *ioas;
30562306a36Sopenharmony_ci	struct iommufd_ioas *ioas_unpin;
30662306a36Sopenharmony_ci	struct mutex ioas_lock;
30762306a36Sopenharmony_ci	const struct iommufd_access_ops *ops;
30862306a36Sopenharmony_ci	void *data;
30962306a36Sopenharmony_ci	unsigned long iova_alignment;
31062306a36Sopenharmony_ci	u32 iopt_access_list_id;
31162306a36Sopenharmony_ci};
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ciint iopt_add_access(struct io_pagetable *iopt, struct iommufd_access *access);
31462306a36Sopenharmony_civoid iopt_remove_access(struct io_pagetable *iopt,
31562306a36Sopenharmony_ci			struct iommufd_access *access,
31662306a36Sopenharmony_ci			u32 iopt_access_list_id);
31762306a36Sopenharmony_civoid iommufd_access_destroy_object(struct iommufd_object *obj);
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci#ifdef CONFIG_IOMMUFD_TEST
32062306a36Sopenharmony_ciint iommufd_test(struct iommufd_ucmd *ucmd);
32162306a36Sopenharmony_civoid iommufd_selftest_destroy(struct iommufd_object *obj);
32262306a36Sopenharmony_ciextern size_t iommufd_test_memory_limit;
32362306a36Sopenharmony_civoid iommufd_test_syz_conv_iova_id(struct iommufd_ucmd *ucmd,
32462306a36Sopenharmony_ci				   unsigned int ioas_id, u64 *iova, u32 *flags);
32562306a36Sopenharmony_cibool iommufd_should_fail(void);
32662306a36Sopenharmony_ciint __init iommufd_test_init(void);
32762306a36Sopenharmony_civoid iommufd_test_exit(void);
32862306a36Sopenharmony_cibool iommufd_selftest_is_mock_dev(struct device *dev);
32962306a36Sopenharmony_ci#else
33062306a36Sopenharmony_cistatic inline void iommufd_test_syz_conv_iova_id(struct iommufd_ucmd *ucmd,
33162306a36Sopenharmony_ci						 unsigned int ioas_id,
33262306a36Sopenharmony_ci						 u64 *iova, u32 *flags)
33362306a36Sopenharmony_ci{
33462306a36Sopenharmony_ci}
33562306a36Sopenharmony_cistatic inline bool iommufd_should_fail(void)
33662306a36Sopenharmony_ci{
33762306a36Sopenharmony_ci	return false;
33862306a36Sopenharmony_ci}
33962306a36Sopenharmony_cistatic inline int __init iommufd_test_init(void)
34062306a36Sopenharmony_ci{
34162306a36Sopenharmony_ci	return 0;
34262306a36Sopenharmony_ci}
34362306a36Sopenharmony_cistatic inline void iommufd_test_exit(void)
34462306a36Sopenharmony_ci{
34562306a36Sopenharmony_ci}
34662306a36Sopenharmony_cistatic inline bool iommufd_selftest_is_mock_dev(struct device *dev)
34762306a36Sopenharmony_ci{
34862306a36Sopenharmony_ci	return false;
34962306a36Sopenharmony_ci}
35062306a36Sopenharmony_ci#endif
35162306a36Sopenharmony_ci#endif
352