i915_gem_execbuffer.c (282199) | i915_gem_execbuffer.c (290454) |
---|---|
1/* 2 * Copyright �� 2008,2010 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the --- 13 unchanged lines hidden (view full) --- 22 * 23 * Authors: 24 * Eric Anholt <eric@anholt.net> 25 * Chris Wilson <chris@chris-wilson.co.uk> 26 * 27 */ 28 29#include <sys/cdefs.h> | 1/* 2 * Copyright �� 2008,2010 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the --- 13 unchanged lines hidden (view full) --- 22 * 23 * Authors: 24 * Eric Anholt <eric@anholt.net> 25 * Chris Wilson <chris@chris-wilson.co.uk> 26 * 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: stable/10/sys/dev/drm2/i915/i915_gem_execbuffer.c 282199 2015-04-28 19:35:05Z dumbbell $"); | 30__FBSDID("$FreeBSD: stable/10/sys/dev/drm2/i915/i915_gem_execbuffer.c 290454 2015-11-06 16:48:33Z jhb $"); |
31 32#include <dev/drm2/drmP.h> 33#include <dev/drm2/drm.h> 34#include <dev/drm2/i915/i915_drm.h> 35#include <dev/drm2/i915/i915_drv.h> 36#include <dev/drm2/i915/intel_drv.h> 37#include <sys/limits.h> 38#include <sys/sf_buf.h> --- 895 unchanged lines hidden (view full) --- 934static bool 935i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec) 936{ 937 return ((exec->batch_start_offset | exec->batch_len) & 0x7) == 0; 938} 939 940static int 941validate_exec_list(struct drm_i915_gem_exec_object2 *exec, int count, | 31 32#include <dev/drm2/drmP.h> 33#include <dev/drm2/drm.h> 34#include <dev/drm2/i915/i915_drm.h> 35#include <dev/drm2/i915/i915_drv.h> 36#include <dev/drm2/i915/intel_drv.h> 37#include <sys/limits.h> 38#include <sys/sf_buf.h> --- 895 unchanged lines hidden (view full) --- 934static bool 935i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec) 936{ 937 return ((exec->batch_start_offset | exec->batch_len) & 0x7) == 0; 938} 939 940static int 941validate_exec_list(struct drm_i915_gem_exec_object2 *exec, int count, |
942 vm_page_t ***map) | 942 vm_page_t ***map, int **maplen) |
943{ 944 vm_page_t *ma; 945 int i, length, page_count; 946 947 /* XXXKIB various limits checking is missing there */ 948 *map = malloc(count * sizeof(*ma), DRM_I915_GEM, M_WAITOK | M_ZERO); | 943{ 944 vm_page_t *ma; 945 int i, length, page_count; 946 947 /* XXXKIB various limits checking is missing there */ 948 *map = malloc(count * sizeof(*ma), DRM_I915_GEM, M_WAITOK | M_ZERO); |
949 *maplen = malloc(count * sizeof(*maplen), DRM_I915_GEM, M_WAITOK | 950 M_ZERO); |
|
949 for (i = 0; i < count; i++) { 950 /* First check for malicious input causing overflow */ 951 if (exec[i].relocation_count > 952 INT_MAX / sizeof(struct drm_i915_gem_relocation_entry)) 953 return -EINVAL; 954 955 length = exec[i].relocation_count * 956 sizeof(struct drm_i915_gem_relocation_entry); --- 5 unchanged lines hidden (view full) --- 962 * Since both start and end of the relocation region 963 * may be not aligned on the page boundary, be 964 * conservative and request a page slot for each 965 * partial page. Thus +2. 966 */ 967 page_count = howmany(length, PAGE_SIZE) + 2; 968 ma = (*map)[i] = malloc(page_count * sizeof(vm_page_t), 969 DRM_I915_GEM, M_WAITOK | M_ZERO); | 951 for (i = 0; i < count; i++) { 952 /* First check for malicious input causing overflow */ 953 if (exec[i].relocation_count > 954 INT_MAX / sizeof(struct drm_i915_gem_relocation_entry)) 955 return -EINVAL; 956 957 length = exec[i].relocation_count * 958 sizeof(struct drm_i915_gem_relocation_entry); --- 5 unchanged lines hidden (view full) --- 964 * Since both start and end of the relocation region 965 * may be not aligned on the page boundary, be 966 * conservative and request a page slot for each 967 * partial page. Thus +2. 968 */ 969 page_count = howmany(length, PAGE_SIZE) + 2; 970 ma = (*map)[i] = malloc(page_count * sizeof(vm_page_t), 971 DRM_I915_GEM, M_WAITOK | M_ZERO); |
970 if (vm_fault_quick_hold_pages(&curproc->p_vmspace->vm_map, 971 exec[i].relocs_ptr, length, VM_PROT_READ | VM_PROT_WRITE, 972 ma, page_count) == -1) { | 972 (*maplen)[i] = vm_fault_quick_hold_pages( 973 &curproc->p_vmspace->vm_map, exec[i].relocs_ptr, length, 974 VM_PROT_READ | VM_PROT_WRITE, ma, page_count); 975 if ((*maplen)[i] == -1) { |
973 free(ma, DRM_I915_GEM); 974 (*map)[i] = NULL; 975 return (-EFAULT); 976 } 977 } 978 979 return 0; 980} --- 135 unchanged lines hidden (view full) --- 1116{ 1117 drm_i915_private_t *dev_priv = dev->dev_private; 1118 struct list_head objects; 1119 struct eb_objects *eb; 1120 struct drm_i915_gem_object *batch_obj; 1121 struct drm_clip_rect *cliprects = NULL; 1122 struct intel_ring_buffer *ring; 1123 vm_page_t **relocs_ma; | 976 free(ma, DRM_I915_GEM); 977 (*map)[i] = NULL; 978 return (-EFAULT); 979 } 980 } 981 982 return 0; 983} --- 135 unchanged lines hidden (view full) --- 1119{ 1120 drm_i915_private_t *dev_priv = dev->dev_private; 1121 struct list_head objects; 1122 struct eb_objects *eb; 1123 struct drm_i915_gem_object *batch_obj; 1124 struct drm_clip_rect *cliprects = NULL; 1125 struct intel_ring_buffer *ring; 1126 vm_page_t **relocs_ma; |
1127 int *relocs_len; |
|
1124 u32 ctx_id = i915_execbuffer2_get_context_id(*args); 1125 u32 exec_start, exec_len; 1126 u32 seqno; 1127 u32 mask; 1128 int ret, mode, i; 1129 1130 if (!i915_gem_check_execbuffer(args)) { 1131 DRM_DEBUG("execbuf with invalid offset/length\n"); 1132 return -EINVAL; 1133 } 1134 1135 if (args->batch_len == 0) 1136 return (0); 1137 | 1128 u32 ctx_id = i915_execbuffer2_get_context_id(*args); 1129 u32 exec_start, exec_len; 1130 u32 seqno; 1131 u32 mask; 1132 int ret, mode, i; 1133 1134 if (!i915_gem_check_execbuffer(args)) { 1135 DRM_DEBUG("execbuf with invalid offset/length\n"); 1136 return -EINVAL; 1137 } 1138 1139 if (args->batch_len == 0) 1140 return (0); 1141 |
1138 ret = validate_exec_list(exec, args->buffer_count, &relocs_ma); | 1142 ret = validate_exec_list(exec, args->buffer_count, &relocs_ma, 1143 &relocs_len); |
1139 if (ret != 0) 1140 goto pre_struct_lock_err; 1141 1142 switch (args->flags & I915_EXEC_RING_MASK) { 1143 case I915_EXEC_DEFAULT: 1144 case I915_EXEC_RENDER: 1145 ring = &dev_priv->rings[RCS]; 1146 break; 1147 case I915_EXEC_BSD: 1148 ring = &dev_priv->rings[VCS]; 1149 if (ctx_id != 0) { 1150 DRM_DEBUG("Ring %s doesn't support contexts\n", 1151 ring->name); | 1144 if (ret != 0) 1145 goto pre_struct_lock_err; 1146 1147 switch (args->flags & I915_EXEC_RING_MASK) { 1148 case I915_EXEC_DEFAULT: 1149 case I915_EXEC_RENDER: 1150 ring = &dev_priv->rings[RCS]; 1151 break; 1152 case I915_EXEC_BSD: 1153 ring = &dev_priv->rings[VCS]; 1154 if (ctx_id != 0) { 1155 DRM_DEBUG("Ring %s doesn't support contexts\n", 1156 ring->name); |
1152 return -EPERM; | 1157 ret = -EPERM; 1158 goto pre_struct_lock_err; |
1153 } 1154 break; 1155 case I915_EXEC_BLT: 1156 ring = &dev_priv->rings[BCS]; 1157 if (ctx_id != 0) { 1158 DRM_DEBUG("Ring %s doesn't support contexts\n", 1159 ring->name); | 1159 } 1160 break; 1161 case I915_EXEC_BLT: 1162 ring = &dev_priv->rings[BCS]; 1163 if (ctx_id != 0) { 1164 DRM_DEBUG("Ring %s doesn't support contexts\n", 1165 ring->name); |
1160 return -EPERM; | 1166 ret = -EPERM; 1167 goto pre_struct_lock_err; |
1161 } 1162 break; 1163 default: 1164 DRM_DEBUG("execbuf with unknown ring: %d\n", 1165 (int)(args->flags & I915_EXEC_RING_MASK)); 1166 ret = -EINVAL; 1167 goto pre_struct_lock_err; 1168 } 1169 if (!intel_ring_initialized(ring)) { 1170 DRM_DEBUG("execbuf with invalid ring: %d\n", 1171 (int)(args->flags & I915_EXEC_RING_MASK)); | 1168 } 1169 break; 1170 default: 1171 DRM_DEBUG("execbuf with unknown ring: %d\n", 1172 (int)(args->flags & I915_EXEC_RING_MASK)); 1173 ret = -EINVAL; 1174 goto pre_struct_lock_err; 1175 } 1176 if (!intel_ring_initialized(ring)) { 1177 DRM_DEBUG("execbuf with invalid ring: %d\n", 1178 (int)(args->flags & I915_EXEC_RING_MASK)); |
1172 return -EINVAL; | 1179 ret = -EINVAL; 1180 goto pre_struct_lock_err; |
1173 } 1174 1175 mode = args->flags & I915_EXEC_CONSTANTS_MASK; 1176 mask = I915_EXEC_CONSTANTS_MASK; 1177 switch (mode) { 1178 case I915_EXEC_CONSTANTS_REL_GENERAL: 1179 case I915_EXEC_CONSTANTS_ABSOLUTE: 1180 case I915_EXEC_CONSTANTS_REL_SURFACE: --- 215 unchanged lines hidden (view full) --- 1396 list_del_init(&obj->exec_list); 1397 drm_gem_object_unreference(&obj->base); 1398 } 1399 DRM_UNLOCK(dev); 1400 1401pre_struct_lock_err: 1402 for (i = 0; i < args->buffer_count; i++) { 1403 if (relocs_ma[i] != NULL) { | 1181 } 1182 1183 mode = args->flags & I915_EXEC_CONSTANTS_MASK; 1184 mask = I915_EXEC_CONSTANTS_MASK; 1185 switch (mode) { 1186 case I915_EXEC_CONSTANTS_REL_GENERAL: 1187 case I915_EXEC_CONSTANTS_ABSOLUTE: 1188 case I915_EXEC_CONSTANTS_REL_SURFACE: --- 215 unchanged lines hidden (view full) --- 1404 list_del_init(&obj->exec_list); 1405 drm_gem_object_unreference(&obj->base); 1406 } 1407 DRM_UNLOCK(dev); 1408 1409pre_struct_lock_err: 1410 for (i = 0; i < args->buffer_count; i++) { 1411 if (relocs_ma[i] != NULL) { |
1404 vm_page_unhold_pages(relocs_ma[i], howmany( 1405 exec[i].relocation_count * 1406 sizeof(struct drm_i915_gem_relocation_entry), 1407 PAGE_SIZE)); | 1412 vm_page_unhold_pages(relocs_ma[i], relocs_len[i]); |
1408 free(relocs_ma[i], DRM_I915_GEM); 1409 } 1410 } | 1413 free(relocs_ma[i], DRM_I915_GEM); 1414 } 1415 } |
1416 free(relocs_len, DRM_I915_GEM); |
|
1411 free(relocs_ma, DRM_I915_GEM); 1412 free(cliprects, DRM_I915_GEM); 1413 return ret; 1414} 1415 1416/* 1417 * Legacy execbuffer just creates an exec2 list from the original exec object 1418 * list array and passes it to the real function. --- 122 unchanged lines hidden --- | 1417 free(relocs_ma, DRM_I915_GEM); 1418 free(cliprects, DRM_I915_GEM); 1419 return ret; 1420} 1421 1422/* 1423 * Legacy execbuffer just creates an exec2 list from the original exec object 1424 * list array and passes it to the real function. --- 122 unchanged lines hidden --- |