Deleted Added
full compact
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 ---