162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2012 Red Hat, Inc.  All rights reserved.
462306a36Sopenharmony_ci *     Author: Alex Williamson <alex.williamson@redhat.com>
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci#ifndef __VFIO_VFIO_H__
762306a36Sopenharmony_ci#define __VFIO_VFIO_H__
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/file.h>
1062306a36Sopenharmony_ci#include <linux/device.h>
1162306a36Sopenharmony_ci#include <linux/cdev.h>
1262306a36Sopenharmony_ci#include <linux/module.h>
1362306a36Sopenharmony_ci#include <linux/vfio.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cistruct iommufd_ctx;
1662306a36Sopenharmony_cistruct iommu_group;
1762306a36Sopenharmony_cistruct vfio_container;
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistruct vfio_device_file {
2062306a36Sopenharmony_ci	struct vfio_device *device;
2162306a36Sopenharmony_ci	struct vfio_group *group;
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci	u8 access_granted;
2462306a36Sopenharmony_ci	u32 devid; /* only valid when iommufd is valid */
2562306a36Sopenharmony_ci	spinlock_t kvm_ref_lock; /* protect kvm field */
2662306a36Sopenharmony_ci	struct kvm *kvm;
2762306a36Sopenharmony_ci	struct iommufd_ctx *iommufd; /* protected by struct vfio_device_set::lock */
2862306a36Sopenharmony_ci};
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_civoid vfio_device_put_registration(struct vfio_device *device);
3162306a36Sopenharmony_cibool vfio_device_try_get_registration(struct vfio_device *device);
3262306a36Sopenharmony_ciint vfio_df_open(struct vfio_device_file *df);
3362306a36Sopenharmony_civoid vfio_df_close(struct vfio_device_file *df);
3462306a36Sopenharmony_cistruct vfio_device_file *
3562306a36Sopenharmony_civfio_allocate_device_file(struct vfio_device *device);
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ciextern const struct file_operations vfio_device_fops;
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#ifdef CONFIG_VFIO_NOIOMMU
4062306a36Sopenharmony_ciextern bool vfio_noiommu __read_mostly;
4162306a36Sopenharmony_ci#else
4262306a36Sopenharmony_cienum { vfio_noiommu = false };
4362306a36Sopenharmony_ci#endif
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cienum vfio_group_type {
4662306a36Sopenharmony_ci	/*
4762306a36Sopenharmony_ci	 * Physical device with IOMMU backing.
4862306a36Sopenharmony_ci	 */
4962306a36Sopenharmony_ci	VFIO_IOMMU,
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	/*
5262306a36Sopenharmony_ci	 * Virtual device without IOMMU backing. The VFIO core fakes up an
5362306a36Sopenharmony_ci	 * iommu_group as the iommu_group sysfs interface is part of the
5462306a36Sopenharmony_ci	 * userspace ABI.  The user of these devices must not be able to
5562306a36Sopenharmony_ci	 * directly trigger unmediated DMA.
5662306a36Sopenharmony_ci	 */
5762306a36Sopenharmony_ci	VFIO_EMULATED_IOMMU,
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	/*
6062306a36Sopenharmony_ci	 * Physical device without IOMMU backing. The VFIO core fakes up an
6162306a36Sopenharmony_ci	 * iommu_group as the iommu_group sysfs interface is part of the
6262306a36Sopenharmony_ci	 * userspace ABI.  Users can trigger unmediated DMA by the device,
6362306a36Sopenharmony_ci	 * usage is highly dangerous, requires an explicit opt-in and will
6462306a36Sopenharmony_ci	 * taint the kernel.
6562306a36Sopenharmony_ci	 */
6662306a36Sopenharmony_ci	VFIO_NO_IOMMU,
6762306a36Sopenharmony_ci};
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_VFIO_GROUP)
7062306a36Sopenharmony_cistruct vfio_group {
7162306a36Sopenharmony_ci	struct device 			dev;
7262306a36Sopenharmony_ci	struct cdev			cdev;
7362306a36Sopenharmony_ci	/*
7462306a36Sopenharmony_ci	 * When drivers is non-zero a driver is attached to the struct device
7562306a36Sopenharmony_ci	 * that provided the iommu_group and thus the iommu_group is a valid
7662306a36Sopenharmony_ci	 * pointer. When drivers is 0 the driver is being detached. Once users
7762306a36Sopenharmony_ci	 * reaches 0 then the iommu_group is invalid.
7862306a36Sopenharmony_ci	 */
7962306a36Sopenharmony_ci	refcount_t			drivers;
8062306a36Sopenharmony_ci	unsigned int			container_users;
8162306a36Sopenharmony_ci	struct iommu_group		*iommu_group;
8262306a36Sopenharmony_ci	struct vfio_container		*container;
8362306a36Sopenharmony_ci	struct list_head		device_list;
8462306a36Sopenharmony_ci	struct mutex			device_lock;
8562306a36Sopenharmony_ci	struct list_head		vfio_next;
8662306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_VFIO_CONTAINER)
8762306a36Sopenharmony_ci	struct list_head		container_next;
8862306a36Sopenharmony_ci#endif
8962306a36Sopenharmony_ci	enum vfio_group_type		type;
9062306a36Sopenharmony_ci	struct mutex			group_lock;
9162306a36Sopenharmony_ci	struct kvm			*kvm;
9262306a36Sopenharmony_ci	struct file			*opened_file;
9362306a36Sopenharmony_ci	struct blocking_notifier_head	notifier;
9462306a36Sopenharmony_ci	struct iommufd_ctx		*iommufd;
9562306a36Sopenharmony_ci	spinlock_t			kvm_ref_lock;
9662306a36Sopenharmony_ci	unsigned int			cdev_device_open_cnt;
9762306a36Sopenharmony_ci};
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ciint vfio_device_block_group(struct vfio_device *device);
10062306a36Sopenharmony_civoid vfio_device_unblock_group(struct vfio_device *device);
10162306a36Sopenharmony_ciint vfio_device_set_group(struct vfio_device *device,
10262306a36Sopenharmony_ci			  enum vfio_group_type type);
10362306a36Sopenharmony_civoid vfio_device_remove_group(struct vfio_device *device);
10462306a36Sopenharmony_civoid vfio_device_group_register(struct vfio_device *device);
10562306a36Sopenharmony_civoid vfio_device_group_unregister(struct vfio_device *device);
10662306a36Sopenharmony_ciint vfio_device_group_use_iommu(struct vfio_device *device);
10762306a36Sopenharmony_civoid vfio_device_group_unuse_iommu(struct vfio_device *device);
10862306a36Sopenharmony_civoid vfio_df_group_close(struct vfio_device_file *df);
10962306a36Sopenharmony_cistruct vfio_group *vfio_group_from_file(struct file *file);
11062306a36Sopenharmony_cibool vfio_group_enforced_coherent(struct vfio_group *group);
11162306a36Sopenharmony_civoid vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm);
11262306a36Sopenharmony_cibool vfio_device_has_container(struct vfio_device *device);
11362306a36Sopenharmony_ciint __init vfio_group_init(void);
11462306a36Sopenharmony_civoid vfio_group_cleanup(void);
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_cistatic inline bool vfio_device_is_noiommu(struct vfio_device *vdev)
11762306a36Sopenharmony_ci{
11862306a36Sopenharmony_ci	return IS_ENABLED(CONFIG_VFIO_NOIOMMU) &&
11962306a36Sopenharmony_ci	       vdev->group->type == VFIO_NO_IOMMU;
12062306a36Sopenharmony_ci}
12162306a36Sopenharmony_ci#else
12262306a36Sopenharmony_cistruct vfio_group;
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_cistatic inline int vfio_device_block_group(struct vfio_device *device)
12562306a36Sopenharmony_ci{
12662306a36Sopenharmony_ci	return 0;
12762306a36Sopenharmony_ci}
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_cistatic inline void vfio_device_unblock_group(struct vfio_device *device)
13062306a36Sopenharmony_ci{
13162306a36Sopenharmony_ci}
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_cistatic inline int vfio_device_set_group(struct vfio_device *device,
13462306a36Sopenharmony_ci					enum vfio_group_type type)
13562306a36Sopenharmony_ci{
13662306a36Sopenharmony_ci	return 0;
13762306a36Sopenharmony_ci}
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_cistatic inline void vfio_device_remove_group(struct vfio_device *device)
14062306a36Sopenharmony_ci{
14162306a36Sopenharmony_ci}
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_cistatic inline void vfio_device_group_register(struct vfio_device *device)
14462306a36Sopenharmony_ci{
14562306a36Sopenharmony_ci}
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_cistatic inline void vfio_device_group_unregister(struct vfio_device *device)
14862306a36Sopenharmony_ci{
14962306a36Sopenharmony_ci}
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_cistatic inline int vfio_device_group_use_iommu(struct vfio_device *device)
15262306a36Sopenharmony_ci{
15362306a36Sopenharmony_ci	return -EOPNOTSUPP;
15462306a36Sopenharmony_ci}
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_cistatic inline void vfio_device_group_unuse_iommu(struct vfio_device *device)
15762306a36Sopenharmony_ci{
15862306a36Sopenharmony_ci}
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_cistatic inline void vfio_df_group_close(struct vfio_device_file *df)
16162306a36Sopenharmony_ci{
16262306a36Sopenharmony_ci}
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_cistatic inline struct vfio_group *vfio_group_from_file(struct file *file)
16562306a36Sopenharmony_ci{
16662306a36Sopenharmony_ci	return NULL;
16762306a36Sopenharmony_ci}
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_cistatic inline bool vfio_group_enforced_coherent(struct vfio_group *group)
17062306a36Sopenharmony_ci{
17162306a36Sopenharmony_ci	return true;
17262306a36Sopenharmony_ci}
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_cistatic inline void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm)
17562306a36Sopenharmony_ci{
17662306a36Sopenharmony_ci}
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_cistatic inline bool vfio_device_has_container(struct vfio_device *device)
17962306a36Sopenharmony_ci{
18062306a36Sopenharmony_ci	return false;
18162306a36Sopenharmony_ci}
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_cistatic inline int __init vfio_group_init(void)
18462306a36Sopenharmony_ci{
18562306a36Sopenharmony_ci	return 0;
18662306a36Sopenharmony_ci}
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_cistatic inline void vfio_group_cleanup(void)
18962306a36Sopenharmony_ci{
19062306a36Sopenharmony_ci}
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_cistatic inline bool vfio_device_is_noiommu(struct vfio_device *vdev)
19362306a36Sopenharmony_ci{
19462306a36Sopenharmony_ci	return false;
19562306a36Sopenharmony_ci}
19662306a36Sopenharmony_ci#endif /* CONFIG_VFIO_GROUP */
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_VFIO_CONTAINER)
19962306a36Sopenharmony_ci/**
20062306a36Sopenharmony_ci * struct vfio_iommu_driver_ops - VFIO IOMMU driver callbacks
20162306a36Sopenharmony_ci */
20262306a36Sopenharmony_cistruct vfio_iommu_driver_ops {
20362306a36Sopenharmony_ci	char		*name;
20462306a36Sopenharmony_ci	struct module	*owner;
20562306a36Sopenharmony_ci	void		*(*open)(unsigned long arg);
20662306a36Sopenharmony_ci	void		(*release)(void *iommu_data);
20762306a36Sopenharmony_ci	long		(*ioctl)(void *iommu_data, unsigned int cmd,
20862306a36Sopenharmony_ci				 unsigned long arg);
20962306a36Sopenharmony_ci	int		(*attach_group)(void *iommu_data,
21062306a36Sopenharmony_ci					struct iommu_group *group,
21162306a36Sopenharmony_ci					enum vfio_group_type);
21262306a36Sopenharmony_ci	void		(*detach_group)(void *iommu_data,
21362306a36Sopenharmony_ci					struct iommu_group *group);
21462306a36Sopenharmony_ci	int		(*pin_pages)(void *iommu_data,
21562306a36Sopenharmony_ci				     struct iommu_group *group,
21662306a36Sopenharmony_ci				     dma_addr_t user_iova,
21762306a36Sopenharmony_ci				     int npage, int prot,
21862306a36Sopenharmony_ci				     struct page **pages);
21962306a36Sopenharmony_ci	void		(*unpin_pages)(void *iommu_data,
22062306a36Sopenharmony_ci				       dma_addr_t user_iova, int npage);
22162306a36Sopenharmony_ci	void		(*register_device)(void *iommu_data,
22262306a36Sopenharmony_ci					   struct vfio_device *vdev);
22362306a36Sopenharmony_ci	void		(*unregister_device)(void *iommu_data,
22462306a36Sopenharmony_ci					     struct vfio_device *vdev);
22562306a36Sopenharmony_ci	int		(*dma_rw)(void *iommu_data, dma_addr_t user_iova,
22662306a36Sopenharmony_ci				  void *data, size_t count, bool write);
22762306a36Sopenharmony_ci	struct iommu_domain *(*group_iommu_domain)(void *iommu_data,
22862306a36Sopenharmony_ci						   struct iommu_group *group);
22962306a36Sopenharmony_ci};
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_cistruct vfio_iommu_driver {
23262306a36Sopenharmony_ci	const struct vfio_iommu_driver_ops	*ops;
23362306a36Sopenharmony_ci	struct list_head			vfio_next;
23462306a36Sopenharmony_ci};
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ciint vfio_register_iommu_driver(const struct vfio_iommu_driver_ops *ops);
23762306a36Sopenharmony_civoid vfio_unregister_iommu_driver(const struct vfio_iommu_driver_ops *ops);
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_cistruct vfio_container *vfio_container_from_file(struct file *filep);
24062306a36Sopenharmony_ciint vfio_group_use_container(struct vfio_group *group);
24162306a36Sopenharmony_civoid vfio_group_unuse_container(struct vfio_group *group);
24262306a36Sopenharmony_ciint vfio_container_attach_group(struct vfio_container *container,
24362306a36Sopenharmony_ci				struct vfio_group *group);
24462306a36Sopenharmony_civoid vfio_group_detach_container(struct vfio_group *group);
24562306a36Sopenharmony_civoid vfio_device_container_register(struct vfio_device *device);
24662306a36Sopenharmony_civoid vfio_device_container_unregister(struct vfio_device *device);
24762306a36Sopenharmony_ciint vfio_device_container_pin_pages(struct vfio_device *device,
24862306a36Sopenharmony_ci				    dma_addr_t iova, int npage,
24962306a36Sopenharmony_ci				    int prot, struct page **pages);
25062306a36Sopenharmony_civoid vfio_device_container_unpin_pages(struct vfio_device *device,
25162306a36Sopenharmony_ci				       dma_addr_t iova, int npage);
25262306a36Sopenharmony_ciint vfio_device_container_dma_rw(struct vfio_device *device,
25362306a36Sopenharmony_ci				 dma_addr_t iova, void *data,
25462306a36Sopenharmony_ci				 size_t len, bool write);
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ciint __init vfio_container_init(void);
25762306a36Sopenharmony_civoid vfio_container_cleanup(void);
25862306a36Sopenharmony_ci#else
25962306a36Sopenharmony_cistatic inline struct vfio_container *
26062306a36Sopenharmony_civfio_container_from_file(struct file *filep)
26162306a36Sopenharmony_ci{
26262306a36Sopenharmony_ci	return NULL;
26362306a36Sopenharmony_ci}
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_cistatic inline int vfio_group_use_container(struct vfio_group *group)
26662306a36Sopenharmony_ci{
26762306a36Sopenharmony_ci	return -EOPNOTSUPP;
26862306a36Sopenharmony_ci}
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_cistatic inline void vfio_group_unuse_container(struct vfio_group *group)
27162306a36Sopenharmony_ci{
27262306a36Sopenharmony_ci}
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_cistatic inline int vfio_container_attach_group(struct vfio_container *container,
27562306a36Sopenharmony_ci					      struct vfio_group *group)
27662306a36Sopenharmony_ci{
27762306a36Sopenharmony_ci	return -EOPNOTSUPP;
27862306a36Sopenharmony_ci}
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_cistatic inline void vfio_group_detach_container(struct vfio_group *group)
28162306a36Sopenharmony_ci{
28262306a36Sopenharmony_ci}
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_cistatic inline void vfio_device_container_register(struct vfio_device *device)
28562306a36Sopenharmony_ci{
28662306a36Sopenharmony_ci}
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_cistatic inline void vfio_device_container_unregister(struct vfio_device *device)
28962306a36Sopenharmony_ci{
29062306a36Sopenharmony_ci}
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_cistatic inline int vfio_device_container_pin_pages(struct vfio_device *device,
29362306a36Sopenharmony_ci						  dma_addr_t iova, int npage,
29462306a36Sopenharmony_ci						  int prot, struct page **pages)
29562306a36Sopenharmony_ci{
29662306a36Sopenharmony_ci	return -EOPNOTSUPP;
29762306a36Sopenharmony_ci}
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_cistatic inline void vfio_device_container_unpin_pages(struct vfio_device *device,
30062306a36Sopenharmony_ci						     dma_addr_t iova, int npage)
30162306a36Sopenharmony_ci{
30262306a36Sopenharmony_ci}
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_cistatic inline int vfio_device_container_dma_rw(struct vfio_device *device,
30562306a36Sopenharmony_ci					       dma_addr_t iova, void *data,
30662306a36Sopenharmony_ci					       size_t len, bool write)
30762306a36Sopenharmony_ci{
30862306a36Sopenharmony_ci	return -EOPNOTSUPP;
30962306a36Sopenharmony_ci}
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_cistatic inline int vfio_container_init(void)
31262306a36Sopenharmony_ci{
31362306a36Sopenharmony_ci	return 0;
31462306a36Sopenharmony_ci}
31562306a36Sopenharmony_cistatic inline void vfio_container_cleanup(void)
31662306a36Sopenharmony_ci{
31762306a36Sopenharmony_ci}
31862306a36Sopenharmony_ci#endif
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IOMMUFD)
32162306a36Sopenharmony_cibool vfio_iommufd_device_has_compat_ioas(struct vfio_device *vdev,
32262306a36Sopenharmony_ci					 struct iommufd_ctx *ictx);
32362306a36Sopenharmony_ciint vfio_df_iommufd_bind(struct vfio_device_file *df);
32462306a36Sopenharmony_civoid vfio_df_iommufd_unbind(struct vfio_device_file *df);
32562306a36Sopenharmony_ciint vfio_iommufd_compat_attach_ioas(struct vfio_device *device,
32662306a36Sopenharmony_ci				    struct iommufd_ctx *ictx);
32762306a36Sopenharmony_ci#else
32862306a36Sopenharmony_cistatic inline bool
32962306a36Sopenharmony_civfio_iommufd_device_has_compat_ioas(struct vfio_device *vdev,
33062306a36Sopenharmony_ci				    struct iommufd_ctx *ictx)
33162306a36Sopenharmony_ci{
33262306a36Sopenharmony_ci	return false;
33362306a36Sopenharmony_ci}
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_cistatic inline int vfio_df_iommufd_bind(struct vfio_device_file *fd)
33662306a36Sopenharmony_ci{
33762306a36Sopenharmony_ci	return -EOPNOTSUPP;
33862306a36Sopenharmony_ci}
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_cistatic inline void vfio_df_iommufd_unbind(struct vfio_device_file *df)
34162306a36Sopenharmony_ci{
34262306a36Sopenharmony_ci}
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_cistatic inline int
34562306a36Sopenharmony_civfio_iommufd_compat_attach_ioas(struct vfio_device *device,
34662306a36Sopenharmony_ci				struct iommufd_ctx *ictx)
34762306a36Sopenharmony_ci{
34862306a36Sopenharmony_ci	return -EOPNOTSUPP;
34962306a36Sopenharmony_ci}
35062306a36Sopenharmony_ci#endif
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ciint vfio_df_ioctl_attach_pt(struct vfio_device_file *df,
35362306a36Sopenharmony_ci			    struct vfio_device_attach_iommufd_pt __user *arg);
35462306a36Sopenharmony_ciint vfio_df_ioctl_detach_pt(struct vfio_device_file *df,
35562306a36Sopenharmony_ci			    struct vfio_device_detach_iommufd_pt __user *arg);
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_VFIO_DEVICE_CDEV)
35862306a36Sopenharmony_civoid vfio_init_device_cdev(struct vfio_device *device);
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_cistatic inline int vfio_device_add(struct vfio_device *device)
36162306a36Sopenharmony_ci{
36262306a36Sopenharmony_ci	/* cdev does not support noiommu device */
36362306a36Sopenharmony_ci	if (vfio_device_is_noiommu(device))
36462306a36Sopenharmony_ci		return device_add(&device->device);
36562306a36Sopenharmony_ci	vfio_init_device_cdev(device);
36662306a36Sopenharmony_ci	return cdev_device_add(&device->cdev, &device->device);
36762306a36Sopenharmony_ci}
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_cistatic inline void vfio_device_del(struct vfio_device *device)
37062306a36Sopenharmony_ci{
37162306a36Sopenharmony_ci	if (vfio_device_is_noiommu(device))
37262306a36Sopenharmony_ci		device_del(&device->device);
37362306a36Sopenharmony_ci	else
37462306a36Sopenharmony_ci		cdev_device_del(&device->cdev, &device->device);
37562306a36Sopenharmony_ci}
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ciint vfio_device_fops_cdev_open(struct inode *inode, struct file *filep);
37862306a36Sopenharmony_cilong vfio_df_ioctl_bind_iommufd(struct vfio_device_file *df,
37962306a36Sopenharmony_ci				struct vfio_device_bind_iommufd __user *arg);
38062306a36Sopenharmony_civoid vfio_df_unbind_iommufd(struct vfio_device_file *df);
38162306a36Sopenharmony_ciint vfio_cdev_init(struct class *device_class);
38262306a36Sopenharmony_civoid vfio_cdev_cleanup(void);
38362306a36Sopenharmony_ci#else
38462306a36Sopenharmony_cistatic inline void vfio_init_device_cdev(struct vfio_device *device)
38562306a36Sopenharmony_ci{
38662306a36Sopenharmony_ci}
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_cistatic inline int vfio_device_add(struct vfio_device *device)
38962306a36Sopenharmony_ci{
39062306a36Sopenharmony_ci	return device_add(&device->device);
39162306a36Sopenharmony_ci}
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_cistatic inline void vfio_device_del(struct vfio_device *device)
39462306a36Sopenharmony_ci{
39562306a36Sopenharmony_ci	device_del(&device->device);
39662306a36Sopenharmony_ci}
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_cistatic inline int vfio_device_fops_cdev_open(struct inode *inode,
39962306a36Sopenharmony_ci					     struct file *filep)
40062306a36Sopenharmony_ci{
40162306a36Sopenharmony_ci	return 0;
40262306a36Sopenharmony_ci}
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_cistatic inline long vfio_df_ioctl_bind_iommufd(struct vfio_device_file *df,
40562306a36Sopenharmony_ci					      struct vfio_device_bind_iommufd __user *arg)
40662306a36Sopenharmony_ci{
40762306a36Sopenharmony_ci	return -ENOTTY;
40862306a36Sopenharmony_ci}
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_cistatic inline void vfio_df_unbind_iommufd(struct vfio_device_file *df)
41162306a36Sopenharmony_ci{
41262306a36Sopenharmony_ci}
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_cistatic inline int vfio_cdev_init(struct class *device_class)
41562306a36Sopenharmony_ci{
41662306a36Sopenharmony_ci	return 0;
41762306a36Sopenharmony_ci}
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_cistatic inline void vfio_cdev_cleanup(void)
42062306a36Sopenharmony_ci{
42162306a36Sopenharmony_ci}
42262306a36Sopenharmony_ci#endif /* CONFIG_VFIO_DEVICE_CDEV */
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_VFIO_VIRQFD)
42562306a36Sopenharmony_ciint __init vfio_virqfd_init(void);
42662306a36Sopenharmony_civoid vfio_virqfd_exit(void);
42762306a36Sopenharmony_ci#else
42862306a36Sopenharmony_cistatic inline int __init vfio_virqfd_init(void)
42962306a36Sopenharmony_ci{
43062306a36Sopenharmony_ci	return 0;
43162306a36Sopenharmony_ci}
43262306a36Sopenharmony_cistatic inline void vfio_virqfd_exit(void)
43362306a36Sopenharmony_ci{
43462306a36Sopenharmony_ci}
43562306a36Sopenharmony_ci#endif
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci#ifdef CONFIG_HAVE_KVM
43862306a36Sopenharmony_civoid vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm);
43962306a36Sopenharmony_civoid vfio_device_put_kvm(struct vfio_device *device);
44062306a36Sopenharmony_ci#else
44162306a36Sopenharmony_cistatic inline void vfio_device_get_kvm_safe(struct vfio_device *device,
44262306a36Sopenharmony_ci					    struct kvm *kvm)
44362306a36Sopenharmony_ci{
44462306a36Sopenharmony_ci}
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_cistatic inline void vfio_device_put_kvm(struct vfio_device *device)
44762306a36Sopenharmony_ci{
44862306a36Sopenharmony_ci}
44962306a36Sopenharmony_ci#endif
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci#endif
452