Commit f69956f7 authored by Yizhen Fan's avatar Yizhen Fan Committed by fanyizhen1995
Browse files

ub: uburma add cmd register/unregister segment implementation.



driver inclusion
category: feature
bugzilla: NA
CVE: NA

--------------------------------

Uburma add implementations of handling register/unregister segment cmd from
user layer.

This will make kernel possible to handle urma_register_seg and
urma_unregister_seg api in user-layer urma.

Register_seg will finally call ubcore_register_seg. The created segment
will be related to a uobj.
Unregister seg will delete the seg-related uobj. In uobj destroy function,
it will call ubcore_unregister_seg.

Signed-off-by: default avatarGuoxin Qian <qianguoxin@huawei.com>
Signed-off-by: default avatarYizhen Fan <fanyizhen@huawei.com>
parent 4a40c421
Loading
Loading
Loading
Loading
+94 −0
Original line number Diff line number Diff line
@@ -125,6 +125,15 @@ static int uburma_cmd_destroy_ctx(struct ubcore_device *ubc_dev, struct uburma_f
	return 0;
}

static void uburma_fill_attr(struct ubcore_seg_cfg *cfg, struct uburma_cmd_register_seg *arg)
{
	cfg->va = arg->in.va;
	cfg->len = arg->in.len;
	cfg->flag.value = arg->in.flag;
	cfg->ukey.key = arg->in.key;
	cfg->iova = arg->in.va;
}

static int uburma_cmd_alloc_key_id(struct ubcore_device *ubc_dev, struct uburma_file *file,
				   struct uburma_cmd_hdr *hdr)
{
@@ -194,6 +203,89 @@ static int uburma_cmd_free_key_id(struct ubcore_device *ubc_dev, struct uburma_f
	return ret;
}

static int uburma_cmd_register_seg(struct ubcore_device *ubc_dev, struct uburma_file *file,
				   struct uburma_cmd_hdr *hdr)
{
	struct uburma_cmd_register_seg arg;
	struct ubcore_seg_cfg cfg = { 0 };
	struct ubcore_target_seg *seg;
	struct ubcore_udata udata = { 0 };
	struct uburma_uobj *uobj;
	struct uburma_uobj *keyid_uobj;
	int ret;

	ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr,
				    sizeof(struct uburma_cmd_register_seg));
	if (ret != 0)
		return ret;

	keyid_uobj = uobj_get_read(UOBJ_CLASS_KEY, (int)arg.in.keyid_handle, file);
	if (!IS_ERR(keyid_uobj))
		cfg.keyid = (struct ubcore_key_id *)keyid_uobj->object;

	uburma_fill_attr(&cfg, &arg);
	fill_udata(&udata, file->ucontext, &arg.udata);

	uobj = uobj_alloc(UOBJ_CLASS_SEG, file);
	if (IS_ERR(uobj)) {
		uburma_log_err("UOBJ_CLASS_SEG alloc fail!\n");
		ret = -ENOMEM;
		goto err_put_keyid;
	}

	seg = ubcore_register_seg(ubc_dev, &cfg, &udata);
	if (IS_ERR_OR_NULL(seg)) {
		uburma_log_err("ubcore_register_seg failed.\n");
		ret = -EPERM;
		goto err_free_uobj;
	}
	uobj->object = seg;
	arg.out.key_id = seg->seg.key_id;
	arg.out.handle = uobj->id;

	ret = uburma_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg,
				  sizeof(struct uburma_cmd_register_seg));
	if (ret != 0)
		goto err_delete_seg;

	if (!IS_ERR(keyid_uobj))
		uobj_put_read(keyid_uobj);
	uobj_alloc_commit(uobj);
	return 0;

err_delete_seg:
	ubcore_unregister_seg(seg);
err_free_uobj:
	uobj_alloc_abort(uobj);
err_put_keyid:
	if (!IS_ERR(keyid_uobj))
		uobj_put_read(keyid_uobj);
	return ret;
}

static int uburma_cmd_unregister_seg(struct ubcore_device *ubc_dev, struct uburma_file *file,
				     struct uburma_cmd_hdr *hdr)
{
	struct uburma_cmd_unregister_seg arg;
	struct uburma_uobj *uobj;
	int ret;

	ret = uburma_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr,
				    sizeof(struct uburma_cmd_unregister_seg));
	if (ret != 0)
		return ret;

	uobj = uobj_get_del(UOBJ_CLASS_SEG, arg.in.handle, file);
	if (IS_ERR(uobj)) {
		uburma_log_err("failed to find registered seg.\n");
		return -EINVAL;
	}
	ret = uobj_remove_commit(uobj);
	if (ret != 0)
		uburma_log_err("ubcore_unregister_seg failed.\n");
	return ret;
}

static void uburma_write_async_event(struct ubcore_ucontext *ctx, uint64_t event_data,
				     uint32_t event_type, struct list_head *obj_event_list,
				     uint32_t *counter)
@@ -1299,6 +1391,8 @@ static uburma_cmd_handler g_uburma_cmd_handlers[] = {
	[UBURMA_CMD_DESTROY_CTX] = uburma_cmd_destroy_ctx,
	[UBURMA_CMD_ALLOC_KEY_ID] = uburma_cmd_alloc_key_id,
	[UBURMA_CMD_FREE_KEY_ID] = uburma_cmd_free_key_id,
	[UBURMA_CMD_REGISTER_SEG] = uburma_cmd_register_seg,
	[UBURMA_CMD_UNREGISTER_SEG] = uburma_cmd_unregister_seg,
	[UBURMA_CMD_CREATE_JFR] = uburma_cmd_create_jfr,
	[UBURMA_CMD_MODIFY_JFR] = uburma_cmd_modify_jfr,
	[UBURMA_CMD_DELETE_JFR] = uburma_cmd_delete_jfr,
+24 −0
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ enum uburma_cmd {
	UBURMA_CMD_DESTROY_CTX,
	UBURMA_CMD_ALLOC_KEY_ID,
	UBURMA_CMD_FREE_KEY_ID,
	UBURMA_CMD_REGISTER_SEG,
	UBURMA_CMD_UNREGISTER_SEG,
	UBURMA_CMD_CREATE_JFS,
	UBURMA_CMD_DELETE_JFS,
	UBURMA_CMD_CREATE_JFR,
@@ -98,6 +100,28 @@ struct uburma_cmd_free_key_id {
	} in;
};

struct uburma_cmd_register_seg {
	struct {
		uint64_t va;
		uint64_t len;
		uint32_t key_id;
		uint64_t keyid_handle;
		uint32_t key;
		uint32_t flag;
	} in;
	struct {
		uint32_t key_id;
		uint64_t handle; /* handle of the allocated seg obj in kernel */
	} out;
	struct uburma_cmd_udrv_priv udata;
};

struct uburma_cmd_unregister_seg {
	struct {
		uint64_t handle; /* handle of seg, used to find seg obj in kernel */
	} in;
};

struct uburma_cmd_create_jfr {
	struct {
		uint32_t depth; /* in terms of WQEBB */
+7 −0
Original line number Diff line number Diff line
@@ -509,6 +509,11 @@ static int uburma_free_key(struct uburma_uobj *uobj, enum uburma_remove_reason w
	return ubcore_free_key_id((struct ubcore_key_id *)uobj->object);
}

static int uburma_free_seg(struct uburma_uobj *uobj, enum uburma_remove_reason why)
{
	return ubcore_unregister_seg((struct ubcore_target_seg *)uobj->object);
}

static int uburma_free_jfc(struct uburma_uobj *uobj, enum uburma_remove_reason why)
{
	struct uburma_jfc_uobj *jfc_uobj = container_of(uobj, struct uburma_jfc_uobj, uobj);
@@ -674,6 +679,8 @@ declare_uobj_class(UOBJ_CLASS_JFC,
		   &uobj_type_alloc_idr(sizeof(struct uburma_jfc_uobj), 2, uburma_free_jfc));
declare_uobj_class(UOBJ_CLASS_KEY,
		   &uobj_type_alloc_idr(sizeof(struct uburma_uobj), 1, uburma_free_key));
declare_uobj_class(UOBJ_CLASS_SEG,
		   &uobj_type_alloc_idr(sizeof(struct uburma_uobj), 1, uburma_free_seg));
declare_uobj_class(UOBJ_CLASS_JFS,
		   &uobj_type_alloc_idr(sizeof(struct uburma_jfs_uobj), 1, uburma_free_jfs));
declare_uobj_class(UOBJ_CLASS_JFR,
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
enum UOBJ_CLASS_ID {
	UOBJ_CLASS_ROOT, /* used by framework */
	UOBJ_CLASS_KEY,
	UOBJ_CLASS_SEG,
	UOBJ_CLASS_JFR,
	UOBJ_CLASS_JFS,
	UOBJ_CLASS_JFC,
@@ -214,6 +215,7 @@ static inline bool uobj_type_is_fd(const struct uburma_uobj *uobj)
	uobj_lookup_get(uobj_get_type(class_id), ufile, _id, UOBJ_ACCESS_NOLOCK)

extern const struct uobj_class_def uobj_class_UOBJ_CLASS_KEY;
extern const struct uobj_class_def uobj_class_UOBJ_CLASS_SEG;
extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFCE;
extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFAE;
extern const struct uobj_class_def uobj_class_UOBJ_CLASS_JFC;