Skip to content

Commit 4f7af19

Browse files
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 <[email protected]> Cc: Tony Luck <[email protected]> Cc: Dave Airlie <[email protected]> Cc: Takashi Iwai <[email protected]> Cc: Tyler Hicks <[email protected]> Signed-off-by: Mika Kuoppala <[email protected]> Reviewed-by: Chris Wilson <[email protected]>
1 parent 311a50e commit 4f7af19

File tree

3 files changed

+70
-18
lines changed

3 files changed

+70
-18
lines changed

drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1956,6 +1956,34 @@ static int i915_reset_gen7_sol_offsets(struct i915_request *rq)
19561956
return 0;
19571957
}
19581958

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+
19591987
static struct i915_vma *eb_parse(struct i915_execbuffer *eb)
19601988
{
19611989
struct intel_engine_pool_node *pool;
@@ -1972,14 +2000,21 @@ static struct i915_vma *eb_parse(struct i915_execbuffer *eb)
19722000
eb->batch_start_offset,
19732001
eb->batch_len);
19742002
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 */
19762011
vma = NULL;
19772012
else
19782013
vma = ERR_PTR(err);
19792014
goto err;
19802015
}
19812016

1982-
vma = i915_gem_object_ggtt_pin(pool->obj, NULL, 0, 0, 0);
2017+
vma = shadow_batch_pin(eb, pool->obj);
19832018
if (IS_ERR(vma))
19842019
goto err;
19852020

@@ -1989,6 +2024,10 @@ static struct i915_vma *eb_parse(struct i915_execbuffer *eb)
19892024
vma->exec_flags = &eb->flags[eb->buffer_count];
19902025
eb->buffer_count++;
19912026

2027+
eb->batch_start_offset = 0;
2028+
eb->batch = vma;
2029+
/* eb->batch_len unchanged */
2030+
19922031
vma->private = pool;
19932032
return vma;
19942033

@@ -2546,21 +2585,6 @@ i915_gem_do_execbuffer(struct drm_device *dev,
25462585
err = PTR_ERR(vma);
25472586
goto err_vma;
25482587
}
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-
}
25642588
}
25652589

25662590
if (eb.batch_len == 0)

drivers/gpu/drm/i915/i915_drv.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2075,6 +2075,12 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
20752075
#define VEBOX_MASK(dev_priv) \
20762076
ENGINE_INSTANCES_MASK(dev_priv, VECS0, I915_MAX_VECS)
20772077

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+
20782084
#define HAS_LLC(dev_priv) (INTEL_INFO(dev_priv)->has_llc)
20792085
#define HAS_SNOOP(dev_priv) (INTEL_INFO(dev_priv)->has_snoop)
20802086
#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,
22852291
unsigned long flags);
22862292
#define I915_GEM_OBJECT_UNBIND_ACTIVE BIT(0)
22872293

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+
22882302
void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv);
22892303

22902304
static inline int __must_check

drivers/gpu/drm/i915/i915_gem.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,20 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
964964
{
965965
struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
966966
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);
967981
struct i915_vma *vma;
968982
int ret;
969983

@@ -1038,7 +1052,7 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
10381052
return ERR_PTR(ret);
10391053
}
10401054

1041-
ret = i915_vma_pin(vma, size, alignment, flags | PIN_GLOBAL);
1055+
ret = i915_vma_pin(vma, size, alignment, flags);
10421056
if (ret)
10431057
return ERR_PTR(ret);
10441058

0 commit comments

Comments
 (0)