diff options
-rw-r--r-- | drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 58 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 16 |
3 files changed, 70 insertions, 18 deletions
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 2426efc05c09..1f423bb2d644 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | |||
@@ -1956,6 +1956,34 @@ static int i915_reset_gen7_sol_offsets(struct i915_request *rq) | |||
1956 | return 0; | 1956 | return 0; |
1957 | } | 1957 | } |
1958 | 1958 | ||
1959 | static struct i915_vma * | ||
1960 | shadow_batch_pin(struct i915_execbuffer *eb, struct drm_i915_gem_object *obj) | ||
1961 | { | ||
1962 | struct drm_i915_private *dev_priv = eb->i915; | ||
1963 | struct i915_vma * const vma = *eb->vma; | ||
1964 | struct i915_address_space *vm; | ||
1965 | u64 flags; | ||
1966 | |||
1967 | /* | ||
1968 | * PPGTT backed shadow buffers must be mapped RO, to prevent | ||
1969 | * post-scan tampering | ||
1970 | */ | ||
1971 | if (CMDPARSER_USES_GGTT(dev_priv)) { | ||
1972 | flags = PIN_GLOBAL; | ||
1973 | vm = &dev_priv->ggtt.vm; | ||
1974 | eb->batch_flags |= I915_DISPATCH_SECURE; | ||
1975 | } else if (vma->vm->has_read_only) { | ||
1976 | flags = PIN_USER; | ||
1977 | vm = vma->vm; | ||
1978 | i915_gem_object_set_readonly(obj); | ||
1979 | } else { | ||
1980 | DRM_DEBUG("Cannot prevent post-scan tampering without RO capable vm\n"); | ||
1981 | return ERR_PTR(-EINVAL); | ||
1982 | } | ||
1983 | |||
1984 | return i915_gem_object_pin(obj, vm, NULL, 0, 0, flags); | ||
1985 | } | ||
1986 | |||
1959 | static struct i915_vma *eb_parse(struct i915_execbuffer *eb) | 1987 | static struct i915_vma *eb_parse(struct i915_execbuffer *eb) |
1960 | { | 1988 | { |
1961 | struct intel_engine_pool_node *pool; | 1989 | struct intel_engine_pool_node *pool; |
@@ -1972,14 +2000,21 @@ static struct i915_vma *eb_parse(struct i915_execbuffer *eb) | |||
1972 | eb->batch_start_offset, | 2000 | eb->batch_start_offset, |
1973 | eb->batch_len); | 2001 | eb->batch_len); |
1974 | if (err) { | 2002 | if (err) { |
1975 | if (err == -EACCES) /* unhandled chained batch */ | 2003 | /* |
2004 | * Unsafe GGTT-backed buffers can still be submitted safely | ||
2005 | * as non-secure. | ||
2006 | * For PPGTT backing however, we have no choice but to forcibly | ||
2007 | * reject unsafe buffers | ||
2008 | */ | ||
2009 | if (CMDPARSER_USES_GGTT(eb->i915) && (err == -EACCES)) | ||
2010 | /* Execute original buffer non-secure */ | ||
1976 | vma = NULL; | 2011 | vma = NULL; |
1977 | else | 2012 | else |
1978 | vma = ERR_PTR(err); | 2013 | vma = ERR_PTR(err); |
1979 | goto err; | 2014 | goto err; |
1980 | } | 2015 | } |
1981 | 2016 | ||
1982 | vma = i915_gem_object_ggtt_pin(pool->obj, NULL, 0, 0, 0); | 2017 | vma = shadow_batch_pin(eb, pool->obj); |
1983 | if (IS_ERR(vma)) | 2018 | if (IS_ERR(vma)) |
1984 | goto err; | 2019 | goto err; |
1985 | 2020 | ||
@@ -1989,6 +2024,10 @@ static struct i915_vma *eb_parse(struct i915_execbuffer *eb) | |||
1989 | vma->exec_flags = &eb->flags[eb->buffer_count]; | 2024 | vma->exec_flags = &eb->flags[eb->buffer_count]; |
1990 | eb->buffer_count++; | 2025 | eb->buffer_count++; |
1991 | 2026 | ||
2027 | eb->batch_start_offset = 0; | ||
2028 | eb->batch = vma; | ||
2029 | /* eb->batch_len unchanged */ | ||
2030 | |||
1992 | vma->private = pool; | 2031 | vma->private = pool; |
1993 | return vma; | 2032 | return vma; |
1994 | 2033 | ||
@@ -2546,21 +2585,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, | |||
2546 | err = PTR_ERR(vma); | 2585 | err = PTR_ERR(vma); |
2547 | goto err_vma; | 2586 | goto err_vma; |
2548 | } | 2587 | } |
2549 | |||
2550 | if (vma) { | ||
2551 | /* | ||
2552 | * Batch parsed and accepted: | ||
2553 | * | ||
2554 | * Set the DISPATCH_SECURE bit to remove the NON_SECURE | ||
2555 | * bit from MI_BATCH_BUFFER_START commands issued in | ||
2556 | * the dispatch_execbuffer implementations. We | ||
2557 | * specifically don't want that set on batches the | ||
2558 | * command parser has accepted. | ||
2559 | */ | ||
2560 | eb.batch_flags |= I915_DISPATCH_SECURE; | ||
2561 | eb.batch_start_offset = 0; | ||
2562 | eb.batch = vma; | ||
2563 | } | ||
2564 | } | 2588 | } |
2565 | 2589 | ||
2566 | if (eb.batch_len == 0) | 2590 | if (eb.batch_len == 0) |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5a16abea3465..5b338e1b79fd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -2075,6 +2075,12 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, | |||
2075 | #define VEBOX_MASK(dev_priv) \ | 2075 | #define VEBOX_MASK(dev_priv) \ |
2076 | ENGINE_INSTANCES_MASK(dev_priv, VECS0, I915_MAX_VECS) | 2076 | ENGINE_INSTANCES_MASK(dev_priv, VECS0, I915_MAX_VECS) |
2077 | 2077 | ||
2078 | /* | ||
2079 | * The Gen7 cmdparser copies the scanned buffer to the ggtt for execution | ||
2080 | * All later gens can run the final buffer from the ppgtt | ||
2081 | */ | ||
2082 | #define CMDPARSER_USES_GGTT(dev_priv) IS_GEN(dev_priv, 7) | ||
2083 | |||
2078 | #define HAS_LLC(dev_priv) (INTEL_INFO(dev_priv)->has_llc) | 2084 | #define HAS_LLC(dev_priv) (INTEL_INFO(dev_priv)->has_llc) |
2079 | #define HAS_SNOOP(dev_priv) (INTEL_INFO(dev_priv)->has_snoop) | 2085 | #define HAS_SNOOP(dev_priv) (INTEL_INFO(dev_priv)->has_snoop) |
2080 | #define HAS_EDRAM(dev_priv) ((dev_priv)->edram_size_mb) | 2086 | #define HAS_EDRAM(dev_priv) ((dev_priv)->edram_size_mb) |
@@ -2285,6 +2291,14 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj, | |||
2285 | unsigned long flags); | 2291 | unsigned long flags); |
2286 | #define I915_GEM_OBJECT_UNBIND_ACTIVE BIT(0) | 2292 | #define I915_GEM_OBJECT_UNBIND_ACTIVE BIT(0) |
2287 | 2293 | ||
2294 | struct i915_vma * __must_check | ||
2295 | i915_gem_object_pin(struct drm_i915_gem_object *obj, | ||
2296 | struct i915_address_space *vm, | ||
2297 | const struct i915_ggtt_view *view, | ||
2298 | u64 size, | ||
2299 | u64 alignment, | ||
2300 | u64 flags); | ||
2301 | |||
2288 | void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv); | 2302 | void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv); |
2289 | 2303 | ||
2290 | static inline int __must_check | 2304 | static inline int __must_check |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d0f94f239919..98305d987ac1 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -964,6 +964,20 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj, | |||
964 | { | 964 | { |
965 | struct drm_i915_private *dev_priv = to_i915(obj->base.dev); | 965 | struct drm_i915_private *dev_priv = to_i915(obj->base.dev); |
966 | struct i915_address_space *vm = &dev_priv->ggtt.vm; | 966 | struct i915_address_space *vm = &dev_priv->ggtt.vm; |
967 | |||
968 | return i915_gem_object_pin(obj, vm, view, size, alignment, | ||
969 | flags | PIN_GLOBAL); | ||
970 | } | ||
971 | |||
972 | struct i915_vma * | ||
973 | i915_gem_object_pin(struct drm_i915_gem_object *obj, | ||
974 | struct i915_address_space *vm, | ||
975 | const struct i915_ggtt_view *view, | ||
976 | u64 size, | ||
977 | u64 alignment, | ||
978 | u64 flags) | ||
979 | { | ||
980 | struct drm_i915_private *dev_priv = to_i915(obj->base.dev); | ||
967 | struct i915_vma *vma; | 981 | struct i915_vma *vma; |
968 | int ret; | 982 | int ret; |
969 | 983 | ||
@@ -1038,7 +1052,7 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj, | |||
1038 | return ERR_PTR(ret); | 1052 | return ERR_PTR(ret); |
1039 | } | 1053 | } |
1040 | 1054 | ||
1041 | ret = i915_vma_pin(vma, size, alignment, flags | PIN_GLOBAL); | 1055 | ret = i915_vma_pin(vma, size, alignment, flags); |
1042 | if (ret) | 1056 | if (ret) |
1043 | return ERR_PTR(ret); | 1057 | return ERR_PTR(ret); |
1044 | 1058 | ||