Commit aeeaf9ba authored by Jon Bloomfield's avatar Jon Bloomfield Committed by Stefan Bader

UBUNTU: SAUCE: i915_bpo: drm/i915/gtt: Read-only pages for insert_entries on bdw+

Hook up the flags to allow read-only ppGTT mappings for gen8+

v2: Include a selftest to check that writes to a readonly PTE are
dropped
v3: Don't duplicate cpu_check() as we can just reuse it, and even worse
don't wholesale copy the theory-of-operation comment from igt_ctx_exec
without changing it to explain the intention behind the new test!
v4: Joonas really likes magic mystery values
Signed-off-by: default avatarJon Bloomfield <jon.bloomfield@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Matthew Auld <matthew.william.auld@gmail.com>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: default avatarMatthew Auld <matthew.william.auld@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180712185315.3288-2-chris@chris-wilson.co.uk
(backported from commit 250f8c81)

CVE-2019-0155

[tjaalton: backport to i915_bpo
 - ggtt_vm doesn't exist, use ggtt->base
 - dev_priv doesn't have gtt, use ggtt instead]
Signed-off-by: default avatarTimo Aaltonen <timo.aaltonen@canonical.com>
Signed-off-by: default avatarStefan Bader <stefan.bader@canonical.com>
parent 46761351
......@@ -159,7 +159,8 @@ static int ppgtt_bind_vma(struct i915_vma *vma,
{
u32 pte_flags = 0;
/* Currently applicable only to VLV */
/* Applicable to VLV, and gen8+ */
pte_flags = 0;
if (vma->obj->gt_ro)
pte_flags |= PTE_READ_ONLY;
......@@ -787,7 +788,8 @@ gen8_ppgtt_insert_pte_entries(struct i915_address_space *vm,
struct i915_page_directory_pointer *pdp,
struct sg_page_iter *sg_iter,
uint64_t start,
enum i915_cache_level cache_level)
enum i915_cache_level cache_level,
u32 flags)
{
struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
gen8_pte_t *pt_vaddr;
......@@ -806,7 +808,7 @@ gen8_ppgtt_insert_pte_entries(struct i915_address_space *vm,
pt_vaddr[pte] =
gen8_pte_encode(sg_page_iter_dma_address(sg_iter),
cache_level, true, 0);
cache_level, true, flags);
if (++pte == GEN8_PTES) {
kunmap_px(ppgtt, pt_vaddr);
pt_vaddr = NULL;
......@@ -827,7 +829,7 @@ static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
struct sg_table *pages,
uint64_t start,
enum i915_cache_level cache_level,
u32 unused)
u32 flags)
{
struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
struct sg_page_iter sg_iter;
......@@ -836,7 +838,7 @@ static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
if (!USES_FULL_48BIT_PPGTT(vm->dev)) {
gen8_ppgtt_insert_pte_entries(vm, &ppgtt->pdp, &sg_iter, start,
cache_level);
cache_level, flags);
} else {
struct i915_page_directory_pointer *pdp;
uint64_t pml4e;
......@@ -844,7 +846,7 @@ static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
gen8_for_each_pml4e(pdp, &ppgtt->pml4, start, length, pml4e) {
gen8_ppgtt_insert_pte_entries(vm, pdp, &sg_iter,
start, cache_level);
start, cache_level, flags);
}
}
}
......@@ -1510,6 +1512,10 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
ppgtt->base.clear_range = gen8_ppgtt_clear_range;
ppgtt->base.unbind_vma = ppgtt_unbind_vma;
ppgtt->base.bind_vma = ppgtt_bind_vma;
/* From bdw, there is support for read-only pages in the PPGTT */
ppgtt->base.has_read_only = true;
ppgtt->debug_dump = gen8_dump_ppgtt;
if (USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
......@@ -2358,7 +2364,7 @@ static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte)
static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
struct sg_table *st,
uint64_t start,
enum i915_cache_level level, u32 unused)
enum i915_cache_level level, u32 flags)
{
struct drm_i915_private *dev_priv = to_i915(vm->dev);
struct i915_ggtt *ggtt = &dev_priv->ggtt;
......@@ -2376,7 +2382,7 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
addr = sg_dma_address(sg_iter.sg) +
(sg_iter.sg_pgoffset << PAGE_SHIFT);
gen8_set_pte(&gtt_entries[i],
gen8_pte_encode(addr, level, true, 0));
gen8_pte_encode(addr, level, true, flags));
i++;
}
......@@ -2389,7 +2395,7 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
*/
if (i != 0)
WARN_ON(readq(&gtt_entries[i-1])
!= gen8_pte_encode(addr, level, true, 0));
!= gen8_pte_encode(addr, level, true, flags));
/* This next bit makes the above posting read even more important. We
* want to flush the TLBs only after we're certain all the PTE updates
......@@ -2588,7 +2594,8 @@ static int ggtt_bind_vma(struct i915_vma *vma,
if (ret)
return ret;
/* Currently applicable only to VLV */
/* Applicable to VLV (gen8+ do not support RO in the GGTT) */
pte_flags = 0;
if (obj->gt_ro)
pte_flags |= PTE_READ_ONLY;
......@@ -2730,6 +2737,9 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
i915_address_space_init(&ggtt->base, dev_priv);
ggtt->base.total += PAGE_SIZE;
/* Only VLV supports read-only GGTT mappings */
ggtt->base.has_read_only = IS_VALLEYVIEW(dev_priv);
if (intel_vgpu_active(dev)) {
ret = intel_vgt_balloon(dev);
if (ret)
......
......@@ -303,6 +303,9 @@ struct i915_address_space {
*/
struct list_head inactive_list;
/* Some systems support read-only mappings for GGTT and/or PPGTT */
bool has_read_only:1;
/* FIXME: Need a more generic return type */
gen6_pte_t (*pte_encode)(dma_addr_t addr,
enum i915_cache_level level,
......
......@@ -2232,6 +2232,8 @@ static void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf)
static int intel_alloc_ringbuffer_obj(struct drm_device *dev,
struct intel_ringbuffer *ringbuf)
{
struct drm_i915_private *dev_priv = to_i915(dev);
struct i915_address_space *vm = &dev_priv->ggtt.base;
struct drm_i915_gem_object *obj;
obj = NULL;
......@@ -2242,7 +2244,11 @@ static int intel_alloc_ringbuffer_obj(struct drm_device *dev,
if (obj == NULL)
return -ENOMEM;
/* mark ring buffers as read-only from GPU side by default */
/*
* Mark ring buffers as read-only from GPU side (so no stray overwrites)
* if supported by the platform's GGTT.
*/
if (vm->has_read_only)
obj->gt_ro = 1;
ringbuf->obj = obj;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment