summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2007-10-17 10:55:21 +0200
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2007-10-17 10:59:48 +0200
commit086c058a417317491320129d2cbeb68d1cfcfefe (patch)
treeb206708018ddc58bed9179e44b77c899dc3dc81b
parent0d1926d36e59ddfc34d8c9c0cdef10b71a49ecf1 (diff)
Remove the op ioctl, and replace it with a setuser ioctl.
Remove need for lock for now. May create races when we clean memory areas or on takedown. Needs to be fixed. Really do a validate on buffer creation in order to avoid problems with fixed memory buffers.
-rw-r--r--libdrm/xf86drm.c65
-rw-r--r--linux-core/drm_bo.c146
-rw-r--r--linux-core/drm_drv.c2
-rw-r--r--linux-core/drm_objects.h4
-rw-r--r--shared-core/drm.h27
5 files changed, 77 insertions, 167 deletions
diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c
index b8f3b986..78cbb099 100644
--- a/libdrm/xf86drm.c
+++ b/libdrm/xf86drm.c
@@ -2695,62 +2695,37 @@ int drmBOUnmap(int fd, drmBO *buf)
return 0;
}
-int drmBOValidate(int fd, drmBO *buf, uint32_t fence_class,
- uint64_t flags, uint64_t mask,
- unsigned hint)
+int drmBOSetStatus(int fd, drmBO *buf, uint32_t fence_class,
+ uint64_t flags, uint64_t mask,
+ unsigned int hint,
+ unsigned int desired_tile_stride,
+ unsigned int tile_info)
{
- struct drm_bo_op_arg arg;
- struct drm_bo_op_req *req = &arg.d.req;
- struct drm_bo_arg_rep *rep = &arg.d.rep;
+ struct drm_bo_map_wait_idle_arg arg;
+ struct drm_bo_info_req *req = &arg.d.req;
+ struct drm_bo_info_rep *rep = &arg.d.rep;
int ret = 0;
memset(&arg, 0, sizeof(arg));
- req->bo_req.handle = buf->handle;
- req->bo_req.flags = flags;
- req->bo_req.mask = mask;
- req->bo_req.hint = hint;
- req->bo_req.fence_class = fence_class;
- req->op = drm_bo_validate;
-
- do{
- ret = ioctl(fd, DRM_IOCTL_BO_OP, &arg);
+ req->mask = mask;
+ req->flags = flags;
+ req->handle = buf->handle;
+ req->hint = hint;
+ req->fence_class = fence_class;
+ req->desired_tile_stride = desired_tile_stride;
+ req->tile_info = tile_info;
+
+ do {
+ ret = ioctl(fd, DRM_IOCTL_BO_SETSTATUS, &arg);
} while (ret && errno == EAGAIN);
if (ret)
- return -errno;
- if (!arg.handled)
- return -EFAULT;
- if (rep->ret)
- return rep->ret;
+ return -errno;
- drmBOCopyReply(&rep->bo_info, buf);
- return 0;
+ drmBOCopyReply(rep, buf);
}
-int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle)
-{
- struct drm_bo_op_arg arg;
- struct drm_bo_op_req *req = &arg.d.req;
- struct drm_bo_arg_rep *rep = &arg.d.rep;
- int ret = 0;
-
- memset(&arg, 0, sizeof(arg));
- req->bo_req.handle = buf->handle;
- req->bo_req.flags = flags;
- req->arg_handle = fenceHandle;
- req->op = drm_bo_fence;
-
- ret = ioctl(fd, DRM_IOCTL_BO_OP, &arg);
- if (ret)
- return -errno;
- if (!arg.handled)
- return -EFAULT;
- if (rep->ret)
- return rep->ret;
- return 0;
-}
-
int drmBOInfo(int fd, drmBO *buf)
{
struct drm_bo_reference_info_arg arg;
diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c
index 7335d258..bdeefec2 100644
--- a/linux-core/drm_bo.c
+++ b/linux-core/drm_bo.c
@@ -929,11 +929,6 @@ static int drm_bo_new_mask(struct drm_buffer_object * bo,
DRM_ERROR("User buffers are not supported yet\n");
return -EINVAL;
}
- if (bo->type == drm_bo_type_fake &&
- !(new_mask & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT))) {
- DRM_ERROR("Fake buffers must be pinned.\n");
- return -EINVAL;
- }
if ((new_mask & DRM_BO_FLAG_NO_EVICT) && !DRM_SUSER(DRM_CURPROC)) {
DRM_ERROR
@@ -942,6 +937,12 @@ static int drm_bo_new_mask(struct drm_buffer_object * bo,
return -EPERM;
}
+ if ((new_mask & DRM_BO_FLAG_NO_MOVE)) {
+ DRM_ERROR
+ ("DRM_BO_FLAG_NO_MOVE is not properly implemented yet.\n");
+ return -EPERM;
+ }
+
new_props = new_mask & (DRM_BO_FLAG_EXE | DRM_BO_FLAG_WRITE |
DRM_BO_FLAG_READ);
@@ -1160,11 +1161,9 @@ static int drm_buffer_object_map(struct drm_file *file_priv, uint32_t handle,
return -EINVAL;
mutex_lock(&bo->mutex);
- if (!(hint & DRM_BO_HINT_ALLOW_UNFENCED_MAP)) {
- ret = drm_bo_wait_unfenced(bo, no_wait, 0);
- if (ret)
- goto out;
- }
+ ret = drm_bo_wait_unfenced(bo, no_wait, 0);
+ if (ret)
+ goto out;
/*
* If this returns true, we are currently unmapped.
@@ -1542,6 +1541,7 @@ int drm_bo_handle_validate(struct drm_file * file_priv, uint32_t handle,
return -EINVAL;
}
+
ret = drm_bo_do_validate(bo, flags, mask, hint, fence_class,
no_wait, rep);
@@ -1663,8 +1663,10 @@ int drm_buffer_object_create(struct drm_device *dev,
bo->mem.page_alignment = page_alignment;
bo->buffer_start = buffer_start;
bo->priv_flags = 0;
- bo->mem.flags = 0ULL;
- bo->mem.mask = 0ULL;
+ bo->mem.flags = DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED |
+ DRM_BO_FLAG_MAPPABLE;
+ bo->mem.mask = DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED |
+ DRM_BO_FLAG_MAPPABLE;
atomic_inc(&bm->count);
ret = drm_bo_new_mask(bo, mask, hint);
@@ -1678,18 +1680,8 @@ int drm_buffer_object_create(struct drm_device *dev,
if (ret)
goto out_err;
}
-#if 0
- bo->fence_class = 0;
- ret = driver->fence_type(bo, &bo->fence_class, &bo->fence_type);
- if (ret) {
- DRM_ERROR("Driver did not support given buffer permissions\n");
- goto out_err;
- }
- ret = drm_bo_add_ttm(bo);
-#else
ret = drm_buffer_object_validate(bo, 0, 0, hint & DRM_BO_HINT_DONT_BLOCK);
-#endif
if (ret)
goto out_err;
@@ -1705,6 +1697,7 @@ int drm_buffer_object_create(struct drm_device *dev,
}
EXPORT_SYMBOL(drm_buffer_object_create);
+
static int drm_bo_add_user_object(struct drm_file *file_priv,
struct drm_buffer_object *bo, int shareable)
{
@@ -1726,86 +1719,6 @@ static int drm_bo_add_user_object(struct drm_file *file_priv,
return ret;
}
-static int drm_bo_lock_test(struct drm_device * dev, struct drm_file *file_priv)
-{
- LOCK_TEST_WITH_RETURN(dev, file_priv);
- return 0;
-}
-
-int drm_bo_op_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_bo_op_arg curarg;
- struct drm_bo_op_arg *arg = data;
- struct drm_bo_op_req *req = &arg->d.req;
- struct drm_bo_info_rep rep;
- unsigned long next = 0;
- void __user *curuserarg = NULL;
- int ret;
-
- if (!dev->bm.initialized) {
- DRM_ERROR("Buffer object manager is not initialized.\n");
- return -EINVAL;
- }
-
- do {
- if (next != 0) {
- curuserarg = (void __user *)next;
- if (copy_from_user(&curarg, curuserarg,
- sizeof(curarg)) != 0)
- return -EFAULT;
- arg = &curarg;
- }
-
- if (arg->handled) {
- next = arg->next;
- continue;
- }
- req = &arg->d.req;
- ret = 0;
- switch (req->op) {
- case drm_bo_validate:
- ret = drm_bo_lock_test(dev, file_priv);
- if (ret)
- break;
- ret = drm_bo_handle_validate(file_priv, req->bo_req.handle,
- req->bo_req.fence_class,
- req->bo_req.flags,
- req->bo_req.mask,
- req->bo_req.hint,
- &rep, NULL);
- break;
- case drm_bo_fence:
- ret = -EINVAL;
- DRM_ERROR("Function is not implemented yet.\n");
- break;
- case drm_bo_ref_fence:
- ret = -EINVAL;
- DRM_ERROR("Function is not implemented yet.\n");
- break;
- default:
- ret = -EINVAL;
- }
- next = arg->next;
-
- /*
- * A signal interrupted us. Make sure the ioctl is restartable.
- */
-
- if (ret == -EAGAIN)
- return -EAGAIN;
-
- arg->handled = 1;
- arg->d.rep.ret = ret;
- arg->d.rep.bo_info = rep;
- if (arg != data) {
- if (copy_to_user(curuserarg, &curarg,
- sizeof(curarg)) != 0)
- return -EFAULT;
- }
- } while (next != 0);
- return 0;
-}
-
int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
struct drm_bo_create_arg *arg = data;
@@ -1821,11 +1734,6 @@ int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
DRM_ERROR("Buffer object manager is not initialized.\n");
return -EINVAL;
}
-#if 0
- ret = drm_bo_lock_test(dev, file_priv);
- if (ret)
- goto out;
-#endif
ret = drm_buffer_object_create(file_priv->head->dev,
req->size, drm_bo_type_dc, req->mask,
@@ -1849,6 +1757,30 @@ out:
return ret;
}
+int drm_bo_setstatus_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ struct drm_bo_map_wait_idle_arg *arg = data;
+ struct drm_bo_info_req *req = &arg->d.req;
+ struct drm_bo_info_rep *rep = &arg->d.rep;
+ int ret;
+ if (!dev->bm.initialized) {
+ DRM_ERROR("Buffer object manager is not initialized.\n");
+ return -EINVAL;
+ }
+
+ ret = drm_bo_handle_validate(file_priv, req->handle, req->fence_class,
+ req->flags,
+ req->mask,
+ req->hint | DRM_BO_HINT_DONT_FENCE,
+ rep, NULL);
+
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
int drm_bo_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
struct drm_bo_map_wait_idle_arg *arg = data;
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index 80e56938..9c867f1b 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -142,7 +142,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_BO_UNMAP, drm_bo_unmap_ioctl, DRM_AUTH),
DRM_IOCTL_DEF(DRM_IOCTL_BO_REFERENCE, drm_bo_reference_ioctl, DRM_AUTH),
DRM_IOCTL_DEF(DRM_IOCTL_BO_UNREFERENCE, drm_bo_unreference_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_BO_OP, drm_bo_op_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_BO_SETSTATUS, drm_bo_setstatus_ioctl, DRM_AUTH),
DRM_IOCTL_DEF(DRM_IOCTL_BO_INFO, drm_bo_info_ioctl, DRM_AUTH),
DRM_IOCTL_DEF(DRM_IOCTL_BO_WAIT_IDLE, drm_bo_wait_idle_ioctl, DRM_AUTH),
};
diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h
index 91378b8a..4d1ec993 100644
--- a/linux-core/drm_objects.h
+++ b/linux-core/drm_objects.h
@@ -470,9 +470,7 @@ extern int drm_bo_reference_ioctl(struct drm_device *dev, void *data, struct drm
extern int drm_bo_unreference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int drm_bo_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int drm_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int drm_bo_op_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
-
-
+extern int drm_bo_setstatus_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
diff --git a/shared-core/drm.h b/shared-core/drm.h
index 021a52e6..0ffd0ad5 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -723,6 +723,7 @@ struct drm_fence_arg {
* Flags: Acknowledge.
*/
#define DRM_BO_FLAG_FORCE_MAPPABLE (1ULL << 14)
+#define DRM_BO_FLAG_TILE (1ULL << 15)
/*
* Memory type flags that can be or'ed together in the mask, but only
@@ -755,7 +756,6 @@ struct drm_fence_arg {
/* Don't place this buffer on the unfenced list.*/
#define DRM_BO_HINT_DONT_FENCE 0x00000004
#define DRM_BO_HINT_WAIT_LAZY 0x00000008
-#define DRM_BO_HINT_ALLOW_UNFENCED_MAP 0x00000010
#define DRM_BO_INIT_MAGIC 0xfe769812
#define DRM_BO_INIT_MAJOR 0
@@ -768,6 +768,8 @@ struct drm_bo_info_req {
unsigned int handle;
unsigned int hint;
unsigned int fence_class;
+ unsigned int desired_tile_stride;
+ unsigned int tile_info;
unsigned int pad64;
};
@@ -779,15 +781,6 @@ struct drm_bo_create_req {
unsigned int page_alignment;
};
-struct drm_bo_op_req {
- enum {
- drm_bo_validate,
- drm_bo_fence,
- drm_bo_ref_fence,
- } op;
- unsigned int arg_handle;
- struct drm_bo_info_req bo_req;
-};
/*
* Reply flags
@@ -844,6 +837,17 @@ struct drm_bo_map_wait_idle_arg {
} d;
};
+struct drm_bo_op_req {
+ enum {
+ drm_bo_validate,
+ drm_bo_fence,
+ drm_bo_ref_fence,
+ } op;
+ unsigned int arg_handle;
+ struct drm_bo_info_req bo_req;
+};
+
+
struct drm_bo_op_arg {
uint64_t next;
union {
@@ -854,6 +858,7 @@ struct drm_bo_op_arg {
unsigned int pad64;
};
+
#define DRM_BO_MEM_LOCAL 0
#define DRM_BO_MEM_TT 1
#define DRM_BO_MEM_VRAM 2
@@ -964,7 +969,7 @@ struct drm_mm_init_arg {
#define DRM_IOCTL_BO_UNMAP DRM_IOWR(0xd0, struct drm_bo_handle_arg)
#define DRM_IOCTL_BO_REFERENCE DRM_IOWR(0xd1, struct drm_bo_reference_info_arg)
#define DRM_IOCTL_BO_UNREFERENCE DRM_IOWR(0xd2, struct drm_bo_handle_arg)
-#define DRM_IOCTL_BO_OP DRM_IOWR(0xd3, struct drm_bo_op_arg)
+#define DRM_IOCTL_BO_SETSTATUS DRM_IOWR(0xd3, struct drm_bo_map_wait_idle_arg)
#define DRM_IOCTL_BO_INFO DRM_IOWR(0xd4, struct drm_bo_reference_info_arg)
#define DRM_IOCTL_BO_WAIT_IDLE DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_arg)