summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bloomfield <jon.bloomfield@intel.com>2018-05-22 16:59:06 -0400
committerJon Bloomfield <jon.bloomfield@intel.com>2019-11-05 14:37:54 -0500
commit4f7af1948abcb18b4772fe1bcd84d7d27d96258c (patch)
tree6342740201512113cb4c17be219eef5a8039c59e
parent311a50e76a33d1e029563c24b2ff6db0c02b5afe (diff)
drm/i915: Support ro ppgtt mapped cmdparser shadow buffers
For Gen7, the original cmdparser motive was to permit limited use of register read/write instructions in unprivileged BB's. This worked by copying the user supplied bb to a kmd owned bb, and running it in secure mode, from the ggtt, only if the scanner finds no unsafe commands or registers. For Gen8+ we can't use this same technique because running bb's from the ggtt also disables access to ppgtt space. But we also do not actually require 'secure' execution since we are only trying to reduce the available command/register set. Instead we will copy the user buffer to a kmd owned read-only bb in ppgtt, and run in the usual non-secure mode. Note that ro pages are only supported by ppgtt (not ggtt), but luckily that's exactly what we need. Add the required paths to map the shadow buffer to ppgtt ro for Gen8+ v2: IS_GEN7/IS_GEN (Mika) v3: rebase v4: rebase v5: rebase Signed-off-by: Jon Bloomfield <jon.bloomfield@intel.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Dave Airlie <airlied@redhat.com> Cc: Takashi Iwai <tiwai@suse.de> Cc: Tyler Hicks <tyhicks@canonical.com> Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com> Reviewed-by: Chris Wilson <chris.p.wilson@intel.com>
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c58
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h14
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c16
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
1959static struct i915_vma *
1960shadow_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
1959static struct i915_vma *eb_parse(struct i915_execbuffer *eb) 1987static 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
2294struct i915_vma * __must_check
2295i915_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
2288void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv); 2302void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv);
2289 2303
2290static inline int __must_check 2304static 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
972struct i915_vma *
973i915_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