drm/radeon/si: add VM CS checker support for CP DMA
authorAlex Deucher <alexander.deucher@amd.com>
Tue, 4 Dec 2012 00:42:37 +0000 (19:42 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 12 Dec 2012 22:16:50 +0000 (17:16 -0500)
Need to verify for copies involving registers.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/radeon/si.c

index f6e7815e18608d0da251cc00ac46d2f8db2d387c..7e835d94df4ab70e7a667cb8102cffeff2fc48ca 100644 (file)
@@ -2550,6 +2550,7 @@ static int si_vm_packet3_gfx_check(struct radeon_device *rdev,
        u32 idx = pkt->idx + 1;
        u32 idx_value = ib[idx];
        u32 start_reg, end_reg, reg, i;
+       u32 command, info;
 
        switch (pkt->opcode) {
        case PACKET3_NOP:
@@ -2649,6 +2650,52 @@ static int si_vm_packet3_gfx_check(struct radeon_device *rdev,
                                return -EINVAL;
                }
                break;
+       case PACKET3_CP_DMA:
+               command = ib[idx + 4];
+               info = ib[idx + 1];
+               if (command & PACKET3_CP_DMA_CMD_SAS) {
+                       /* src address space is register */
+                       if (((info & 0x60000000) >> 29) == 0) {
+                               start_reg = idx_value << 2;
+                               if (command & PACKET3_CP_DMA_CMD_SAIC) {
+                                       reg = start_reg;
+                                       if (!si_vm_reg_valid(reg)) {
+                                               DRM_ERROR("CP DMA Bad SRC register\n");
+                                               return -EINVAL;
+                                       }
+                               } else {
+                                       for (i = 0; i < (command & 0x1fffff); i++) {
+                                               reg = start_reg + (4 * i);
+                                               if (!si_vm_reg_valid(reg)) {
+                                                       DRM_ERROR("CP DMA Bad SRC register\n");
+                                                       return -EINVAL;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               if (command & PACKET3_CP_DMA_CMD_DAS) {
+                       /* dst address space is register */
+                       if (((info & 0x00300000) >> 20) == 0) {
+                               start_reg = ib[idx + 2];
+                               if (command & PACKET3_CP_DMA_CMD_DAIC) {
+                                       reg = start_reg;
+                                       if (!si_vm_reg_valid(reg)) {
+                                               DRM_ERROR("CP DMA Bad DST register\n");
+                                               return -EINVAL;
+                                       }
+                               } else {
+                                       for (i = 0; i < (command & 0x1fffff); i++) {
+                                               reg = start_reg + (4 * i);
+                                               if (!si_vm_reg_valid(reg)) {
+                                                       DRM_ERROR("CP DMA Bad DST register\n");
+                                                       return -EINVAL;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               break;
        default:
                DRM_ERROR("Invalid GFX packet3: 0x%x\n", pkt->opcode);
                return -EINVAL;