From 960042345866ff4ab7d76b56e4af60e800c60a36 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Mon, 31 Mar 2008 21:50:02 +0200 Subject: radeon_ms: small fix & cleanup to command checking --- shared-core/radeon_ms_exec.c | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) (limited to 'shared-core/radeon_ms_exec.c') diff --git a/shared-core/radeon_ms_exec.c b/shared-core/radeon_ms_exec.c index 574e5a06..32b55eaf 100644 --- a/shared-core/radeon_ms_exec.c +++ b/shared-core/radeon_ms_exec.c @@ -220,47 +220,40 @@ static int amd_cbuffer_packet3_check(struct drm_device *dev, break; case PACKET3_OPCODE_BITBLT: case PACKET3_OPCODE_BITBLT_MULTI: - DRM_INFO("[radeon_ms] exec step - [05][P3]00.00\n"); /* we only alow simple blit */ if (count != 5) { return -EINVAL; } - DRM_INFO("[radeon_ms] exec step - [05][P3]01.00\n"); s_mask = 0xf; s_auth = 0x3; if ((cbuffer->cbuffer[dw_id + 1] & s_mask) != s_auth) { return -EINVAL; } - DRM_INFO("[radeon_ms] exec step - [05][P3]02.00\n"); arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, dw_id+2); if (arg == NULL) { return -EINVAL; } - DRM_INFO("[radeon_ms] exec step - [05][P3]03.00\n"); ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, &gpu_addr); if (ret) { return ret; } - DRM_INFO("[radeon_ms] exec step - [05][P3]04.00\n"); gpu_addr = (gpu_addr >> 10) & 0x003FFFFF; cbuffer->cbuffer[dw_id + 2] &= 0xFFC00000; cbuffer->cbuffer[dw_id + 2] |= gpu_addr; + arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, dw_id+3); if (arg == NULL) { return -EINVAL; } - DRM_INFO("[radeon_ms] exec step - [05][P3]05.00\n"); ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, &gpu_addr); if (ret) { return ret; } - DRM_INFO("[radeon_ms] exec step - [05][P3]06.00\n"); gpu_addr = (gpu_addr >> 10) & 0x003FFFFF; cbuffer->cbuffer[dw_id + 3] &= 0xFFC00000; cbuffer->cbuffer[dw_id + 3] |= gpu_addr; - DRM_INFO("[radeon_ms] exec step - [05][P3]07.00\n"); /* FIXME: check that source & destination are big enough * for requested blit */ break; @@ -279,14 +272,12 @@ static int amd_cbuffer_check(struct drm_device *dev, int ret; for (i = 0; i < cbuffer->cbuffer_dw_count;) { - DRM_INFO("[radeon_ms] exec step - [05]00.00 %d 0x%08X\n", - i, cbuffer->cbuffer[i]); switch (PACKET_HEADER_GET(cbuffer->cbuffer[i])) { case 0: ret = amd_cbuffer_packet0_check(dev, file_priv, cbuffer, i, _r3xx_register_right); - if (ret) { + if (ret <= 0) { return ret; } /* advance to next packet */ @@ -302,7 +293,7 @@ static int amd_cbuffer_check(struct drm_device *dev, case 3: ret = amd_cbuffer_packet3_check(dev, file_priv, cbuffer, i); - if (ret) { + if (ret <= 0) { return ret; } /* advance to next packet */ @@ -331,13 +322,11 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, /* FIXME: Lock buffer manager, is this really needed ? */ - DRM_INFO("[radeon_ms] exec step - 00.00\n"); ret = drm_bo_read_lock(&dev->bm.bm_lock); if (ret) { return ret; } - DRM_INFO("[radeon_ms] exec step - 01.00\n"); cbuffer.args = drm_calloc(execbuffer->args_count, sizeof(struct amd_cbuffer_arg), DRM_MEM_DRIVER); @@ -350,7 +339,6 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, INIT_LIST_HEAD(&cbuffer.arg_used.list); /* process arguments */ - DRM_INFO("[radeon_ms] exec step - 02.00\n"); ret = radeon_ms_execbuffer_args(dev, file_priv, execbuffer, &cbuffer); if (ret) { DRM_ERROR("[radeon_ms] execbuffer wrong arguments\n"); @@ -358,14 +346,12 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, } /* map command buffer */ - DRM_INFO("[radeon_ms] exec step - 03.00\n"); cbuffer.cbuffer_dw_count = (cbuffer.args[0].buffer->mem.num_pages * PAGE_SIZE) >> 2; if (execbuffer->cmd_size > cbuffer.cbuffer_dw_count) { ret = -EINVAL; goto out_free_release; } - DRM_INFO("[radeon_ms] exec step - 04.00\n"); cbuffer.cbuffer_dw_count = execbuffer->cmd_size; memset(&cmd_kmap, 0, sizeof(struct drm_bo_kmap_obj)); ret = drm_bo_kmap(cbuffer.args[0].buffer, 0, @@ -374,13 +360,9 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, DRM_ERROR("[radeon_ms] error mapping ring buffer: %d\n", ret); goto out_free_release; } - DRM_INFO("[radeon_ms] exec step - 05.00\n"); cbuffer.cbuffer = drm_bmo_virtual(&cmd_kmap, &cmd_is_iomem); - DRM_INFO("[radeon_ms] exec step - 05.01\n"); list_del(&cbuffer.args[0].list); - DRM_INFO("[radeon_ms] exec step - 05.02\n"); list_add_tail(&cbuffer.args[0].list , &cbuffer.arg_used.list); - DRM_INFO("[radeon_ms] exec step - 05.03\n"); /* do cmd checking & relocations */ ret = amd_cbuffer_check(dev, file_priv, &cbuffer); @@ -388,7 +370,6 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, drm_putback_buffer_objects(dev); goto out_free_release; } - DRM_INFO("[radeon_ms] exec step - 06.00\n"); ret = radeon_ms_ring_emit(dev, cbuffer.cbuffer, cbuffer.cbuffer_dw_count); @@ -396,7 +377,6 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, drm_putback_buffer_objects(dev); goto out_free_release; } - DRM_INFO("[radeon_ms] exec step - 07.00\n"); /* fence */ ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence); @@ -418,16 +398,13 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, } } drm_fence_usage_deref_unlocked(&fence); - DRM_INFO("[radeon_ms] exec step - 08.00\n"); out_free_release: drm_bo_kunmap(&cmd_kmap); radeon_ms_execbuffer_args_clean(dev, &cbuffer, execbuffer->args_count); - DRM_INFO("[radeon_ms] exec step - 09.00\n"); out_free: drm_free(cbuffer.args, (execbuffer->args_count * sizeof(struct amd_cbuffer_arg)), DRM_MEM_DRIVER); drm_bo_read_unlock(&dev->bm.bm_lock); - DRM_INFO("[radeon_ms] exec step - 10.00\n"); return ret; } -- cgit v1.2.3 From 779e826c1e2c127f4950c78a56cc314c43b7eb56 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Tue, 8 Apr 2008 02:18:14 +0200 Subject: radeon_ms: command buffer validation use array of function pointer --- shared-core/radeon_ms_exec.c | 195 ++++++++++++++----------------------------- 1 file changed, 63 insertions(+), 132 deletions(-) (limited to 'shared-core/radeon_ms_exec.c') diff --git a/shared-core/radeon_ms_exec.c b/shared-core/radeon_ms_exec.c index 32b55eaf..28fcc180 100644 --- a/shared-core/radeon_ms_exec.c +++ b/shared-core/radeon_ms_exec.c @@ -25,7 +25,7 @@ * Jerome Glisse */ #include "radeon_ms.h" -#include "amd_cbuffer.h" +#include "amd.h" static void radeon_ms_execbuffer_args_clean(struct drm_device *dev, struct amd_cbuffer *cbuffer, @@ -118,155 +118,69 @@ out_err: return ret; } -enum { - REGISTER_FORBIDDEN = 0, - REGISTER_SAFE, - REGISTER_SET_OFFSET, -}; -static uint8_t _r3xx_register_right[0x5000 >> 2]; - -static int amd_cbuffer_packet0_set_offset(struct drm_device *dev, - struct amd_cbuffer *cbuffer, - uint32_t reg, int dw_id, - struct amd_cbuffer_arg *arg) -{ - uint32_t gpu_addr; - int ret; - - ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, &gpu_addr); - if (ret) { - return ret; - } - switch (reg) { - default: - return -EINVAL; - } - return 0; -} - -static struct amd_cbuffer_arg * -amd_cbuffer_arg_from_dw_id(struct amd_cbuffer_arg *head, uint32_t dw_id) +static int cbuffer_packet0_check(struct drm_device *dev, + struct amd_cbuffer *cbuffer, + int dw_id) { - struct amd_cbuffer_arg *arg; - - list_for_each_entry(arg, &head->list, list) { - if (arg->dw_id == dw_id) { - return arg; - } - } - /* no buffer at this dw index */ - return NULL; -} - -static int amd_cbuffer_packet0_check(struct drm_device *dev, - struct drm_file *file_priv, - struct amd_cbuffer *cbuffer, - int dw_id, - uint8_t *register_right) -{ - struct amd_cbuffer_arg *arg; + struct drm_radeon_private *dev_priv = dev->dev_private; uint32_t reg, count, r, i; int ret; reg = cbuffer->cbuffer[dw_id] & PACKET0_REG_MASK; count = (cbuffer->cbuffer[dw_id] & PACKET0_COUNT_MASK) >> PACKET0_COUNT_SHIFT; + if (reg + count > dev_priv->cbuffer_checker.numof_p0_checkers) { + return -EINVAL; + } for (r = reg, i = 0; i <= count; i++, r++) { - switch (register_right[i]) { - case REGISTER_FORBIDDEN: + if (dev_priv->cbuffer_checker.check_p0[r] == NULL) { + continue; + } + if (dev_priv->cbuffer_checker.check_p0[r] == (void *)-1) { + DRM_INFO("[radeon_ms] check_f: %d %d -1 checker\n", + r, r << 2); + return -EINVAL; + } + ret = dev_priv->cbuffer_checker.check_p0[r](dev, cbuffer, + dw_id + i + 1, reg); + if (ret) { + DRM_INFO("[radeon_ms] check_f: %d %d checker ret=%d\n", + r, r << 2, ret); return -EINVAL; - case REGISTER_SAFE: - break; - case REGISTER_SET_OFFSET: - arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, - dw_id + i +1); - if (arg == NULL) { - return -EINVAL; - } - /* remove from unparsed list */ - list_del(&arg->list); - list_add_tail(&arg->list, &cbuffer->arg_used.list); - /* set the offset */ - ret = amd_cbuffer_packet0_set_offset(dev, cbuffer, - r, dw_id + i + 1, - arg); - if (ret) { - return ret; - } - break; } } /* header + N + 1 dword passed test */ return count + 2; } -static int amd_cbuffer_packet3_check(struct drm_device *dev, - struct drm_file *file_priv, - struct amd_cbuffer *cbuffer, - int dw_id) +static int cbuffer_packet3_check(struct drm_device *dev, + struct amd_cbuffer *cbuffer, + int dw_id) { - struct amd_cbuffer_arg *arg; + struct drm_radeon_private *dev_priv = dev->dev_private; uint32_t opcode, count; - uint32_t s_auth, s_mask; - uint32_t gpu_addr; int ret; opcode = (cbuffer->cbuffer[dw_id] & PACKET3_OPCODE_MASK) >> PACKET3_OPCODE_SHIFT; + if (opcode > dev_priv->cbuffer_checker.numof_p3_checkers) { + return -EINVAL; + } count = (cbuffer->cbuffer[dw_id] & PACKET3_COUNT_MASK) >> PACKET3_COUNT_SHIFT; - switch (opcode) { - case PACKET3_OPCODE_NOP: - break; - case PACKET3_OPCODE_BITBLT: - case PACKET3_OPCODE_BITBLT_MULTI: - /* we only alow simple blit */ - if (count != 5) { - return -EINVAL; - } - s_mask = 0xf; - s_auth = 0x3; - if ((cbuffer->cbuffer[dw_id + 1] & s_mask) != s_auth) { - return -EINVAL; - } - arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, dw_id+2); - if (arg == NULL) { - return -EINVAL; - } - ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, - &gpu_addr); - if (ret) { - return ret; - } - gpu_addr = (gpu_addr >> 10) & 0x003FFFFF; - cbuffer->cbuffer[dw_id + 2] &= 0xFFC00000; - cbuffer->cbuffer[dw_id + 2] |= gpu_addr; - - arg = amd_cbuffer_arg_from_dw_id(&cbuffer->arg_unused, dw_id+3); - if (arg == NULL) { - return -EINVAL; - } - ret = radeon_ms_bo_get_gpu_addr(dev, &arg->buffer->mem, - &gpu_addr); - if (ret) { - return ret; - } - gpu_addr = (gpu_addr >> 10) & 0x003FFFFF; - cbuffer->cbuffer[dw_id + 3] &= 0xFFC00000; - cbuffer->cbuffer[dw_id + 3] |= gpu_addr; - /* FIXME: check that source & destination are big enough - * for requested blit */ - break; - default: + if (dev_priv->cbuffer_checker.check_p3[opcode] == NULL) { + return -EINVAL; + } + ret = dev_priv->cbuffer_checker.check_p3[opcode](dev, cbuffer, + dw_id + 1, opcode, + count); + if (ret) { return -EINVAL; } - /* header + N + 1 dword passed test */ return count + 2; } -static int amd_cbuffer_check(struct drm_device *dev, - struct drm_file *file_priv, - struct amd_cbuffer *cbuffer) +int amd_cbuffer_check(struct drm_device *dev, struct amd_cbuffer *cbuffer) { uint32_t i; int ret; @@ -274,9 +188,7 @@ static int amd_cbuffer_check(struct drm_device *dev, for (i = 0; i < cbuffer->cbuffer_dw_count;) { switch (PACKET_HEADER_GET(cbuffer->cbuffer[i])) { case 0: - ret = amd_cbuffer_packet0_check(dev, file_priv, - cbuffer, i, - _r3xx_register_right); + ret = cbuffer_packet0_check(dev, cbuffer, i); if (ret <= 0) { return ret; } @@ -287,12 +199,10 @@ static int amd_cbuffer_check(struct drm_device *dev, /* we don't accept packet 1 */ return -EINVAL; case 2: - /* packet 2 */ - i += 1; - break; + /* FIXME: accept packet 2 */ + return -EINVAL; case 3: - ret = amd_cbuffer_packet3_check(dev, file_priv, - cbuffer, i); + ret = cbuffer_packet3_check(dev, cbuffer, i); if (ret <= 0) { return ret; } @@ -304,9 +214,25 @@ static int amd_cbuffer_check(struct drm_device *dev, return 0; } +struct amd_cbuffer_arg * +amd_cbuffer_arg_from_dw_id(struct amd_cbuffer_arg *head, uint32_t dw_id) +{ + struct amd_cbuffer_arg *arg; + + list_for_each_entry(arg, &head->list, list) { + if (arg->dw_id == dw_id) { + return arg; + } + } + /* no buffer at this dw index */ + return NULL; +} + + int radeon_ms_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct drm_radeon_private *dev_priv = dev->dev_private; struct drm_radeon_execbuffer *execbuffer = data; struct drm_fence_arg *fence_arg = &execbuffer->fence_arg; struct drm_bo_kmap_obj cmd_kmap; @@ -365,8 +291,13 @@ int radeon_ms_execbuffer(struct drm_device *dev, void *data, list_add_tail(&cbuffer.args[0].list , &cbuffer.arg_used.list); /* do cmd checking & relocations */ - ret = amd_cbuffer_check(dev, file_priv, &cbuffer); - if (ret) { + if (dev_priv->cbuffer_checker.check) { + ret = dev_priv->cbuffer_checker.check(dev, &cbuffer); + if (ret) { + drm_putback_buffer_objects(dev); + goto out_free_release; + } + } else { drm_putback_buffer_objects(dev); goto out_free_release; } -- cgit v1.2.3