Skip to content

Commit dfce902

Browse files
committed
Backmerge i915 security patches from commit 'ea0b163b13ff' into drm-next
This backmerges the branch that ended up in Linus' tree. It removes all the changes for the rc6 patches from Linus' tree in favour of a patch that is based on a large refactor that occured. Otherwise it all looks good. Signed-off-by: Dave Airlie <[email protected]>
2 parents 2248a28 + ea0b163 commit dfce902

File tree

10 files changed

+460
-168
lines changed

10 files changed

+460
-168
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ static void i915_gem_context_free(struct i915_gem_context *ctx)
236236
free_engines(rcu_access_pointer(ctx->engines));
237237
mutex_destroy(&ctx->engines_mutex);
238238

239+
kfree(ctx->jump_whitelist);
240+
239241
if (ctx->timeline)
240242
intel_timeline_put(ctx->timeline);
241243

@@ -527,6 +529,9 @@ __create_context(struct drm_i915_private *i915)
527529
for (i = 0; i < ARRAY_SIZE(ctx->hang_timestamp); i++)
528530
ctx->hang_timestamp[i] = jiffies - CONTEXT_FAST_HANG_JIFFIES;
529531

532+
ctx->jump_whitelist = NULL;
533+
ctx->jump_whitelist_cmds = 0;
534+
530535
spin_lock(&i915->gem.contexts.lock);
531536
list_add_tail(&ctx->link, &i915->gem.contexts.list);
532537
spin_unlock(&i915->gem.contexts.lock);

drivers/gpu/drm/i915/gem/i915_gem_context_types.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,13 @@ struct i915_gem_context {
176176
* per vm, which may be one per context or shared with the global GTT)
177177
*/
178178
struct radix_tree_root handles_vma;
179+
180+
/** jump_whitelist: Bit array for tracking cmds during cmdparsing
181+
* Guarded by struct_mutex
182+
*/
183+
unsigned long *jump_whitelist;
184+
/** jump_whitelist_cmds: No of cmd slots available */
185+
u32 jump_whitelist_cmds;
179186
};
180187

181188
#endif /* __I915_GEM_CONTEXT_TYPES_H__ */

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

Lines changed: 80 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,9 @@ static inline u64 gen8_noncanonical_addr(u64 address)
298298

299299
static inline bool eb_use_cmdparser(const struct i915_execbuffer *eb)
300300
{
301-
return intel_engine_needs_cmd_parser(eb->engine) && eb->batch_len;
301+
return intel_engine_requires_cmd_parser(eb->engine) ||
302+
(intel_engine_using_cmd_parser(eb->engine) &&
303+
eb->args->batch_len);
302304
}
303305

304306
static int eb_create(struct i915_execbuffer *eb)
@@ -1990,40 +1992,94 @@ static int i915_reset_gen7_sol_offsets(struct i915_request *rq)
19901992
return 0;
19911993
}
19921994

1993-
static struct i915_vma *eb_parse(struct i915_execbuffer *eb, bool is_master)
1995+
static struct i915_vma *
1996+
shadow_batch_pin(struct i915_execbuffer *eb, struct drm_i915_gem_object *obj)
1997+
{
1998+
struct drm_i915_private *dev_priv = eb->i915;
1999+
struct i915_vma * const vma = *eb->vma;
2000+
struct i915_address_space *vm;
2001+
u64 flags;
2002+
2003+
/*
2004+
* PPGTT backed shadow buffers must be mapped RO, to prevent
2005+
* post-scan tampering
2006+
*/
2007+
if (CMDPARSER_USES_GGTT(dev_priv)) {
2008+
flags = PIN_GLOBAL;
2009+
vm = &dev_priv->ggtt.vm;
2010+
} else if (vma->vm->has_read_only) {
2011+
flags = PIN_USER;
2012+
vm = vma->vm;
2013+
i915_gem_object_set_readonly(obj);
2014+
} else {
2015+
DRM_DEBUG("Cannot prevent post-scan tampering without RO capable vm\n");
2016+
return ERR_PTR(-EINVAL);
2017+
}
2018+
2019+
return i915_gem_object_pin(obj, vm, NULL, 0, 0, flags);
2020+
}
2021+
2022+
static struct i915_vma *eb_parse(struct i915_execbuffer *eb)
19942023
{
19952024
struct intel_engine_pool_node *pool;
19962025
struct i915_vma *vma;
2026+
u64 batch_start;
2027+
u64 shadow_batch_start;
19972028
int err;
19982029

19992030
pool = intel_engine_get_pool(eb->engine, eb->batch_len);
20002031
if (IS_ERR(pool))
20012032
return ERR_CAST(pool);
20022033

2003-
err = intel_engine_cmd_parser(eb->engine,
2034+
vma = shadow_batch_pin(eb, pool->obj);
2035+
if (IS_ERR(vma))
2036+
goto err;
2037+
2038+
batch_start = gen8_canonical_addr(eb->batch->node.start) +
2039+
eb->batch_start_offset;
2040+
2041+
shadow_batch_start = gen8_canonical_addr(vma->node.start);
2042+
2043+
err = intel_engine_cmd_parser(eb->gem_context,
2044+
eb->engine,
20042045
eb->batch->obj,
2005-
pool->obj,
2046+
batch_start,
20062047
eb->batch_start_offset,
20072048
eb->batch_len,
2008-
is_master);
2049+
pool->obj,
2050+
shadow_batch_start);
2051+
20092052
if (err) {
2010-
if (err == -EACCES) /* unhandled chained batch */
2053+
i915_vma_unpin(vma);
2054+
2055+
/*
2056+
* Unsafe GGTT-backed buffers can still be submitted safely
2057+
* as non-secure.
2058+
* For PPGTT backing however, we have no choice but to forcibly
2059+
* reject unsafe buffers
2060+
*/
2061+
if (CMDPARSER_USES_GGTT(eb->i915) && (err == -EACCES))
2062+
/* Execute original buffer non-secure */
20112063
vma = NULL;
20122064
else
20132065
vma = ERR_PTR(err);
20142066
goto err;
20152067
}
20162068

2017-
vma = i915_gem_object_ggtt_pin(pool->obj, NULL, 0, 0, 0);
2018-
if (IS_ERR(vma))
2019-
goto err;
2020-
20212069
eb->vma[eb->buffer_count] = i915_vma_get(vma);
20222070
eb->flags[eb->buffer_count] =
20232071
__EXEC_OBJECT_HAS_PIN | __EXEC_OBJECT_HAS_REF;
20242072
vma->exec_flags = &eb->flags[eb->buffer_count];
20252073
eb->buffer_count++;
20262074

2075+
eb->batch_start_offset = 0;
2076+
eb->batch = vma;
2077+
2078+
if (CMDPARSER_USES_GGTT(eb->i915))
2079+
eb->batch_flags |= I915_DISPATCH_SECURE;
2080+
2081+
/* eb->batch_len unchanged */
2082+
20272083
vma->private = pool;
20282084
return vma;
20292085

@@ -2430,6 +2486,7 @@ i915_gem_do_execbuffer(struct drm_device *dev,
24302486
struct drm_i915_gem_exec_object2 *exec,
24312487
struct drm_syncobj **fences)
24322488
{
2489+
struct drm_i915_private *i915 = to_i915(dev);
24332490
struct i915_execbuffer eb;
24342491
struct dma_fence *in_fence = NULL;
24352492
struct dma_fence *exec_fence = NULL;
@@ -2441,7 +2498,7 @@ i915_gem_do_execbuffer(struct drm_device *dev,
24412498
BUILD_BUG_ON(__EXEC_OBJECT_INTERNAL_FLAGS &
24422499
~__EXEC_OBJECT_UNKNOWN_FLAGS);
24432500

2444-
eb.i915 = to_i915(dev);
2501+
eb.i915 = i915;
24452502
eb.file = file;
24462503
eb.args = args;
24472504
if (DBG_FORCE_RELOC || !(args->flags & I915_EXEC_NO_RELOC))
@@ -2461,8 +2518,15 @@ i915_gem_do_execbuffer(struct drm_device *dev,
24612518

24622519
eb.batch_flags = 0;
24632520
if (args->flags & I915_EXEC_SECURE) {
2521+
if (INTEL_GEN(i915) >= 11)
2522+
return -ENODEV;
2523+
2524+
/* Return -EPERM to trigger fallback code on old binaries. */
2525+
if (!HAS_SECURE_BATCHES(i915))
2526+
return -EPERM;
2527+
24642528
if (!drm_is_current_master(file) || !capable(CAP_SYS_ADMIN))
2465-
return -EPERM;
2529+
return -EPERM;
24662530

24672531
eb.batch_flags |= I915_DISPATCH_SECURE;
24682532
}
@@ -2539,34 +2603,19 @@ i915_gem_do_execbuffer(struct drm_device *dev,
25392603
goto err_vma;
25402604
}
25412605

2606+
if (eb.batch_len == 0)
2607+
eb.batch_len = eb.batch->size - eb.batch_start_offset;
2608+
25422609
if (eb_use_cmdparser(&eb)) {
25432610
struct i915_vma *vma;
25442611

2545-
vma = eb_parse(&eb, drm_is_current_master(file));
2612+
vma = eb_parse(&eb);
25462613
if (IS_ERR(vma)) {
25472614
err = PTR_ERR(vma);
25482615
goto err_vma;
25492616
}
2550-
2551-
if (vma) {
2552-
/*
2553-
* Batch parsed and accepted:
2554-
*
2555-
* Set the DISPATCH_SECURE bit to remove the NON_SECURE
2556-
* bit from MI_BATCH_BUFFER_START commands issued in
2557-
* the dispatch_execbuffer implementations. We
2558-
* specifically don't want that set on batches the
2559-
* command parser has accepted.
2560-
*/
2561-
eb.batch_flags |= I915_DISPATCH_SECURE;
2562-
eb.batch_start_offset = 0;
2563-
eb.batch = vma;
2564-
}
25652617
}
25662618

2567-
if (eb.batch_len == 0)
2568-
eb.batch_len = eb.batch->size - eb.batch_start_offset;
2569-
25702619
/*
25712620
* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure
25722621
* batch" bit. Hence we need to pin secure batches into the global gtt.

drivers/gpu/drm/i915/gt/intel_engine_types.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -454,13 +454,14 @@ struct intel_engine_cs {
454454
/* status_notifier: list of callbacks for context-switch changes */
455455
struct atomic_notifier_head context_status_notifier;
456456

457-
#define I915_ENGINE_NEEDS_CMD_PARSER BIT(0)
457+
#define I915_ENGINE_USING_CMD_PARSER BIT(0)
458458
#define I915_ENGINE_SUPPORTS_STATS BIT(1)
459459
#define I915_ENGINE_HAS_PREEMPTION BIT(2)
460460
#define I915_ENGINE_HAS_SEMAPHORES BIT(3)
461461
#define I915_ENGINE_NEEDS_BREADCRUMB_TASKLET BIT(4)
462462
#define I915_ENGINE_IS_VIRTUAL BIT(5)
463463
#define I915_ENGINE_HAS_RELATIVE_MMIO BIT(6)
464+
#define I915_ENGINE_REQUIRES_CMD_PARSER BIT(7)
464465
unsigned int flags;
465466

466467
/*
@@ -528,9 +529,15 @@ struct intel_engine_cs {
528529
};
529530

530531
static inline bool
531-
intel_engine_needs_cmd_parser(const struct intel_engine_cs *engine)
532+
intel_engine_using_cmd_parser(const struct intel_engine_cs *engine)
532533
{
533-
return engine->flags & I915_ENGINE_NEEDS_CMD_PARSER;
534+
return engine->flags & I915_ENGINE_USING_CMD_PARSER;
535+
}
536+
537+
static inline bool
538+
intel_engine_requires_cmd_parser(const struct intel_engine_cs *engine)
539+
{
540+
return engine->flags & I915_ENGINE_REQUIRES_CMD_PARSER;
534541
}
535542

536543
static inline bool

0 commit comments

Comments
 (0)