forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
iommufd: File descriptor, context, kconfig and makefiles
This is the basic infrastructure of a new miscdevice to hold the iommufd IOCTL API. It provides: - A miscdevice to create file descriptors to run the IOCTL interface over - A table based ioctl dispatch and centralized extendable pre-validation step - An xarray mapping userspace ID's to kernel objects. The design has multiple inter-related objects held within in a single IOMMUFD fd - A simple usage count to build a graph of object relations and protect against hostile userspace racing ioctls The only IOCTL provided in this patch is the generic 'destroy any object by handle' operation. Link: https://lore.kernel.org/r/6-v6-a196d26f289e+11787-iommufd_jgg@nvidia.com Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Tested-by: Yi Liu <yi.l.liu@intel.com> Tested-by: Lixiao Yang <lixiao.yang@intel.com> Tested-by: Matthew Rosato <mjrosato@linux.ibm.com> Signed-off-by: Yi Liu <yi.l.liu@intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
- Loading branch information
1 parent
658234d
commit 2ff4bed
Showing
10 changed files
with
571 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# SPDX-License-Identifier: GPL-2.0-only | ||
config IOMMUFD | ||
tristate "IOMMU Userspace API" | ||
select INTERVAL_TREE | ||
select INTERVAL_TREE_SPAN_ITER | ||
select IOMMU_API | ||
default n | ||
help | ||
Provides /dev/iommu, the user API to control the IOMMU subsystem as | ||
it relates to managing IO page tables that point at user space memory. | ||
|
||
If you don't know what to do here, say N. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# SPDX-License-Identifier: GPL-2.0-only | ||
iommufd-y := \ | ||
main.o | ||
|
||
obj-$(CONFIG_IOMMUFD) += iommufd.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-only */ | ||
/* Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES | ||
*/ | ||
#ifndef __IOMMUFD_PRIVATE_H | ||
#define __IOMMUFD_PRIVATE_H | ||
|
||
#include <linux/rwsem.h> | ||
#include <linux/xarray.h> | ||
#include <linux/refcount.h> | ||
#include <linux/uaccess.h> | ||
|
||
struct iommufd_ctx { | ||
struct file *file; | ||
struct xarray objects; | ||
}; | ||
|
||
struct iommufd_ucmd { | ||
struct iommufd_ctx *ictx; | ||
void __user *ubuffer; | ||
u32 user_size; | ||
void *cmd; | ||
}; | ||
|
||
/* Copy the response in ucmd->cmd back to userspace. */ | ||
static inline int iommufd_ucmd_respond(struct iommufd_ucmd *ucmd, | ||
size_t cmd_len) | ||
{ | ||
if (copy_to_user(ucmd->ubuffer, ucmd->cmd, | ||
min_t(size_t, ucmd->user_size, cmd_len))) | ||
return -EFAULT; | ||
return 0; | ||
} | ||
|
||
enum iommufd_object_type { | ||
IOMMUFD_OBJ_NONE, | ||
IOMMUFD_OBJ_ANY = IOMMUFD_OBJ_NONE, | ||
}; | ||
|
||
/* Base struct for all objects with a userspace ID handle. */ | ||
struct iommufd_object { | ||
struct rw_semaphore destroy_rwsem; | ||
refcount_t users; | ||
enum iommufd_object_type type; | ||
unsigned int id; | ||
}; | ||
|
||
static inline bool iommufd_lock_obj(struct iommufd_object *obj) | ||
{ | ||
if (!down_read_trylock(&obj->destroy_rwsem)) | ||
return false; | ||
if (!refcount_inc_not_zero(&obj->users)) { | ||
up_read(&obj->destroy_rwsem); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
struct iommufd_object *iommufd_get_object(struct iommufd_ctx *ictx, u32 id, | ||
enum iommufd_object_type type); | ||
static inline void iommufd_put_object(struct iommufd_object *obj) | ||
{ | ||
refcount_dec(&obj->users); | ||
up_read(&obj->destroy_rwsem); | ||
} | ||
|
||
/** | ||
* iommufd_ref_to_users() - Switch from destroy_rwsem to users refcount | ||
* protection | ||
* @obj - Object to release | ||
* | ||
* Objects have two refcount protections (destroy_rwsem and the refcount_t | ||
* users). Holding either of these will prevent the object from being destroyed. | ||
* | ||
* Depending on the use case, one protection or the other is appropriate. In | ||
* most cases references are being protected by the destroy_rwsem. This allows | ||
* orderly destruction of the object because iommufd_object_destroy_user() will | ||
* wait for it to become unlocked. However, as a rwsem, it cannot be held across | ||
* a system call return. So cases that have longer term needs must switch | ||
* to the weaker users refcount_t. | ||
* | ||
* With users protection iommufd_object_destroy_user() will return false, | ||
* refusing to destroy the object, causing -EBUSY to userspace. | ||
*/ | ||
static inline void iommufd_ref_to_users(struct iommufd_object *obj) | ||
{ | ||
up_read(&obj->destroy_rwsem); | ||
/* iommufd_lock_obj() obtains users as well */ | ||
} | ||
void iommufd_object_abort(struct iommufd_ctx *ictx, struct iommufd_object *obj); | ||
void iommufd_object_abort_and_destroy(struct iommufd_ctx *ictx, | ||
struct iommufd_object *obj); | ||
void iommufd_object_finalize(struct iommufd_ctx *ictx, | ||
struct iommufd_object *obj); | ||
bool iommufd_object_destroy_user(struct iommufd_ctx *ictx, | ||
struct iommufd_object *obj); | ||
struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx, | ||
size_t size, | ||
enum iommufd_object_type type); | ||
|
||
#define iommufd_object_alloc(ictx, ptr, type) \ | ||
container_of(_iommufd_object_alloc( \ | ||
ictx, \ | ||
sizeof(*(ptr)) + BUILD_BUG_ON_ZERO( \ | ||
offsetof(typeof(*(ptr)), \ | ||
obj) != 0), \ | ||
type), \ | ||
typeof(*(ptr)), obj) | ||
|
||
#endif |
Oops, something went wrong.