Commit f01c4e68 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/nvif: modify nvif_unvers/nvif_unpack macros to be more obvious



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 13db6d6e
Loading
Loading
Loading
Loading
+19 −15
Original line number Diff line number Diff line
#ifndef __NVIF_UNPACK_H__
#define __NVIF_UNPACK_H__

#define nvif_unvers(d) ({                                                      \
	ret = (size == sizeof(d)) ? 0 : -ENOSYS;                               \
	(ret == 0);                                                            \
#define nvif_unvers(r,d,s,m) ({                                                \
	void **_data = (d); __u32 *_size = (s); int _ret = (r);                \
	if (_ret == -ENOSYS && *_size == sizeof(m)) {                          \
		*_data = NULL;                                                 \
		*_size = _ret = 0;                                             \
	}                                                                      \
	_ret;                                                                  \
})

#define nvif_unpack(d,vl,vh,m) ({                                              \
	if ((vl) == 0 || ret == -ENOSYS) {                                     \
		int _size = sizeof(d);                                         \
		if (_size <= size && (d).version >= (vl) &&                    \
				     (d).version <= (vh)) {                    \
			data = (u8 *)data + _size;                             \
			size = size - _size;                                   \
			ret = ((m) || !size) ? 0 : -E2BIG;                     \
		} else {                                                       \
			ret = -ENOSYS;                                         \
#define nvif_unpack(r,d,s,m,vl,vh,x) ({                                        \
	void **_data = (d); __u32 *_size = (s);                                \
	int _ret = (r), _vl = (vl), _vh = (vh);                                \
	if (_ret == -ENOSYS && *_size >= sizeof(m) &&                          \
	    (m).version >= _vl && (m).version <= _vh) {                        \
		*_data = (__u8 *)*_data + sizeof(m);                           \
		*_size = *_size - sizeof(m);                                   \
		if (_ret = 0, !(x)) {                                          \
			_ret = *_size ? -E2BIG : 0;                            \
			*_data = NULL;                                         \
			*_size = 0;                                            \
		}                                                              \
	}                                                                      \
	(ret == 0);                                                            \
	_ret;                                                                  \
})

#endif
+2 −2
Original line number Diff line number Diff line
@@ -357,9 +357,9 @@ nouveau_abi16_usif(struct drm_file *file_priv, void *data, u32 size)
	} *args = data;
	struct nouveau_abi16_chan *chan;
	struct nouveau_abi16 *abi16;
	int ret;
	int ret = -ENOSYS;

	if (nvif_unpack(args->v0, 0, 0, true)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		switch (args->v0.type) {
		case NVIF_IOCTL_V0_NEW:
		case NVIF_IOCTL_V0_MTHD:
+13 −12
Original line number Diff line number Diff line
@@ -130,20 +130,21 @@ usif_notify_new(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
		struct nvif_notify_req_v0 v0;
	} *req;
	struct usif_notify *ntfy;
	int ret;
	int ret = -ENOSYS;

	if (nvif_unpack(args->v0, 0, 0, true)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		if (usif_notify_find(f, args->v0.index))
			return -EEXIST;
	} else
		return ret;
	req = data;
	ret = -ENOSYS;

	if (!(ntfy = kmalloc(sizeof(*ntfy), GFP_KERNEL)))
		return -ENOMEM;
	atomic_set(&ntfy->enabled, 0);

	if (nvif_unpack(req->v0, 0, 0, true)) {
	if (!(ret = nvif_unpack(ret, &data, &size, req->v0, 0, 0, true))) {
		ntfy->reply = sizeof(struct nvif_notify_rep_v0) + req->v0.reply;
		ntfy->route = req->v0.route;
		ntfy->token = req->v0.token;
@@ -171,9 +172,9 @@ usif_notify_del(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
		struct nvif_ioctl_ntfy_del_v0 v0;
	} *args = data;
	struct usif_notify *ntfy;
	int ret;
	int ret = -ENOSYS;

	if (nvif_unpack(args->v0, 0, 0, true)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		if (!(ntfy = usif_notify_find(f, args->v0.index)))
			return -ENOENT;
	} else
@@ -194,9 +195,9 @@ usif_notify_get(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
		struct nvif_ioctl_ntfy_del_v0 v0;
	} *args = data;
	struct usif_notify *ntfy;
	int ret;
	int ret = -ENOSYS;

	if (nvif_unpack(args->v0, 0, 0, true)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		if (!(ntfy = usif_notify_find(f, args->v0.index)))
			return -ENOENT;
	} else
@@ -233,9 +234,9 @@ usif_notify_put(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
		struct nvif_ioctl_ntfy_put_v0 v0;
	} *args = data;
	struct usif_notify *ntfy;
	int ret;
	int ret = -ENOSYS;

	if (nvif_unpack(args->v0, 0, 0, true)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		if (!(ntfy = usif_notify_find(f, args->v0.index)))
			return -ENOENT;
	} else
@@ -270,13 +271,13 @@ usif_object_new(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
		struct nvif_ioctl_new_v0 v0;
	} *args = data;
	struct usif_object *object;
	int ret;
	int ret = -ENOSYS;

	if (!(object = kmalloc(sizeof(*object), GFP_KERNEL)))
		return -ENOMEM;
	list_add(&object->head, &cli->objects);

	if (nvif_unpack(args->v0, 0, 0, true)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		object->route = args->v0.route;
		object->token = args->v0.token;
		args->v0.route = NVDRM_OBJECT_USIF;
@@ -310,7 +311,7 @@ usif_ioctl(struct drm_file *filp, void __user *user, u32 argc)
	if (ret = -EFAULT, copy_from_user(argv, user, size))
		goto done;

	if (nvif_unpack(argv->v0, 0, 0, true)) {
	if (!(ret = nvif_unpack(-ENOSYS, &data, &size, argv->v0, 0, 0, true))) {
		/* block access to objects not created via this interface */
		owner = argv->v0.owner;
		if (argv->v0.object == 0ULL)
+4 −4
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ nvkm_client_notify_new(struct nvkm_object *object,
		struct nvif_notify_req_v0 v0;
	} *req = data;
	u8  index, reply;
	int ret;
	int ret = -ENOSYS;

	for (index = 0; index < ARRAY_SIZE(client->notify); index++) {
		if (!client->notify[index])
@@ -112,7 +112,7 @@ nvkm_client_notify_new(struct nvkm_object *object,
		return -ENOMEM;

	nvif_ioctl(object, "notify new size %d\n", size);
	if (nvif_unpack(req->v0, 0, 0, true)) {
	if (!(ret = nvif_unpack(ret, &data, &size, req->v0, 0, 0, true))) {
		nvif_ioctl(object, "notify new vers %d reply %d route %02x "
				   "token %llx\n", req->v0.version,
			   req->v0.reply, req->v0.route, req->v0.token);
@@ -144,10 +144,10 @@ nvkm_client_mthd_devlist(struct nvkm_object *object, void *data, u32 size)
	union {
		struct nv_client_devlist_v0 v0;
	} *args = data;
	int ret;
	int ret = -ENOSYS;

	nvif_ioctl(object, "client devlist size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, true)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		nvif_ioctl(object, "client devlist vers %d count %d\n",
			   args->v0.version, args->v0.count);
		if (size == sizeof(args->v0.device[0]) * args->v0.count) {
+28 −28
Original line number Diff line number Diff line
@@ -34,10 +34,10 @@ nvkm_ioctl_nop(struct nvkm_object *object, void *data, u32 size)
	union {
		struct nvif_ioctl_nop_v0 v0;
	} *args = data;
	int ret;
	int ret = -ENOSYS;

	nvif_ioctl(object, "nop size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, false)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
		nvif_ioctl(object, "nop vers %lld\n", args->v0.version);
		args->v0.version = NVIF_VERSION_LATEST;
	}
@@ -52,10 +52,10 @@ nvkm_ioctl_sclass(struct nvkm_object *object, void *data, u32 size)
		struct nvif_ioctl_sclass_v0 v0;
	} *args = data;
	struct nvkm_oclass oclass;
	int ret, i = 0;
	int ret = -ENOSYS, i = 0;

	nvif_ioctl(object, "sclass size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, true)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		nvif_ioctl(object, "sclass vers %d count %d\n",
			   args->v0.version, args->v0.count);
		if (size != args->v0.count * sizeof(args->v0.oclass[0]))
@@ -86,10 +86,10 @@ nvkm_ioctl_new(struct nvkm_object *parent, void *data, u32 size)
	struct nvkm_client *client = parent->client;
	struct nvkm_object *object = NULL;
	struct nvkm_oclass oclass;
	int ret, i = 0;
	int ret = -ENOSYS, i = 0;

	nvif_ioctl(parent, "new size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, true)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		nvif_ioctl(parent, "new vers %d handle %08x class %08x "
				   "route %02x token %llx object %016llx\n",
			   args->v0.version, args->v0.handle, args->v0.oclass,
@@ -147,10 +147,10 @@ nvkm_ioctl_del(struct nvkm_object *object, void *data, u32 size)
	union {
		struct nvif_ioctl_del none;
	} *args = data;
	int ret;
	int ret = -ENOSYS;

	nvif_ioctl(object, "delete size %d\n", size);
	if (nvif_unvers(args->none)) {
	if (!(ret = nvif_unvers(ret, &data, &size, args->none))) {
		nvif_ioctl(object, "delete\n");
		nvkm_object_fini(object, false);
		nvkm_object_del(&object);
@@ -165,10 +165,10 @@ nvkm_ioctl_mthd(struct nvkm_object *object, void *data, u32 size)
	union {
		struct nvif_ioctl_mthd_v0 v0;
	} *args = data;
	int ret;
	int ret = -ENOSYS;

	nvif_ioctl(object, "mthd size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, true)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		nvif_ioctl(object, "mthd vers %d mthd %02x\n",
			   args->v0.version, args->v0.method);
		ret = nvkm_object_mthd(object, args->v0.method, data, size);
@@ -189,10 +189,10 @@ nvkm_ioctl_rd(struct nvkm_object *object, void *data, u32 size)
		u16 b16;
		u32 b32;
	} v;
	int ret;
	int ret = -ENOSYS;

	nvif_ioctl(object, "rd size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, false)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
		nvif_ioctl(object, "rd vers %d size %d addr %016llx\n",
			   args->v0.version, args->v0.size, args->v0.addr);
		switch (args->v0.size) {
@@ -223,10 +223,10 @@ nvkm_ioctl_wr(struct nvkm_object *object, void *data, u32 size)
	union {
		struct nvif_ioctl_wr_v0 v0;
	} *args = data;
	int ret;
	int ret = -ENOSYS;

	nvif_ioctl(object, "wr size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, false)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
		nvif_ioctl(object,
			   "wr vers %d size %d addr %016llx data %08x\n",
			   args->v0.version, args->v0.size, args->v0.addr,
@@ -251,10 +251,10 @@ nvkm_ioctl_map(struct nvkm_object *object, void *data, u32 size)
	union {
		struct nvif_ioctl_map_v0 v0;
	} *args = data;
	int ret;
	int ret = -ENOSYS;

	nvif_ioctl(object, "map size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, false)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
		nvif_ioctl(object, "map vers %d\n", args->v0.version);
		ret = nvkm_object_map(object, &args->v0.handle,
					      &args->v0.length);
@@ -269,10 +269,10 @@ nvkm_ioctl_unmap(struct nvkm_object *object, void *data, u32 size)
	union {
		struct nvif_ioctl_unmap none;
	} *args = data;
	int ret;
	int ret = -ENOSYS;

	nvif_ioctl(object, "unmap size %d\n", size);
	if (nvif_unvers(args->none)) {
	if (!(ret = nvif_unvers(ret, &data, &size, args->none))) {
		nvif_ioctl(object, "unmap\n");
	}

@@ -286,10 +286,10 @@ nvkm_ioctl_ntfy_new(struct nvkm_object *object, void *data, u32 size)
		struct nvif_ioctl_ntfy_new_v0 v0;
	} *args = data;
	struct nvkm_event *event;
	int ret;
	int ret = -ENOSYS;

	nvif_ioctl(object, "ntfy new size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, true)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		nvif_ioctl(object, "ntfy new vers %d event %02x\n",
			   args->v0.version, args->v0.event);
		ret = nvkm_object_ntfy(object, args->v0.event, &event);
@@ -312,10 +312,10 @@ nvkm_ioctl_ntfy_del(struct nvkm_object *object, void *data, u32 size)
	union {
		struct nvif_ioctl_ntfy_del_v0 v0;
	} *args = data;
	int ret;
	int ret = -ENOSYS;

	nvif_ioctl(object, "ntfy del size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, false)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
		nvif_ioctl(object, "ntfy del vers %d index %d\n",
			   args->v0.version, args->v0.index);
		ret = nvkm_client_notify_del(client, args->v0.index);
@@ -331,10 +331,10 @@ nvkm_ioctl_ntfy_get(struct nvkm_object *object, void *data, u32 size)
	union {
		struct nvif_ioctl_ntfy_get_v0 v0;
	} *args = data;
	int ret;
	int ret = -ENOSYS;

	nvif_ioctl(object, "ntfy get size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, false)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
		nvif_ioctl(object, "ntfy get vers %d index %d\n",
			   args->v0.version, args->v0.index);
		ret = nvkm_client_notify_get(client, args->v0.index);
@@ -350,10 +350,10 @@ nvkm_ioctl_ntfy_put(struct nvkm_object *object, void *data, u32 size)
	union {
		struct nvif_ioctl_ntfy_put_v0 v0;
	} *args = data;
	int ret;
	int ret = -ENOSYS;

	nvif_ioctl(object, "ntfy put size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, false)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
		nvif_ioctl(object, "ntfy put vers %d index %d\n",
			   args->v0.version, args->v0.index);
		ret = nvkm_client_notify_put(client, args->v0.index);
@@ -421,12 +421,12 @@ nvkm_ioctl(struct nvkm_client *client, bool supervisor,
	union {
		struct nvif_ioctl_v0 v0;
	} *args = data;
	int ret;
	int ret = -ENOSYS;

	client->super = supervisor;
	nvif_ioctl(object, "size %d\n", size);

	if (nvif_unpack(args->v0, 0, 0, true)) {
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		nvif_ioctl(object,
			   "vers %d type %02x object %016llx owner %02x\n",
			   args->v0.version, args->v0.type, args->v0.object,
Loading