|
|
27a0ef |
From c2dd834b3e366fff19a868fa446643f7f30201c7 Mon Sep 17 00:00:00 2001
|
|
|
27a0ef |
From: Yannick Cote <ycote@redhat.com>
|
|
|
27a0ef |
Date: Tue, 8 Feb 2022 17:10:45 -0500
|
|
|
27a0ef |
Subject: [KPATCH CVE-2022-0330] drm/i915: kpatch fixes for CVE-2022-0330
|
|
|
27a0ef |
|
|
|
27a0ef |
Kernels:
|
|
|
27a0ef |
3.10.0-1160.21.1.el7
|
|
|
27a0ef |
3.10.0-1160.24.1.el7
|
|
|
27a0ef |
3.10.0-1160.25.1.el7
|
|
|
27a0ef |
3.10.0-1160.31.1.el7
|
|
|
27a0ef |
3.10.0-1160.36.2.el7
|
|
|
27a0ef |
3.10.0-1160.41.1.el7
|
|
|
27a0ef |
3.10.0-1160.42.2.el7
|
|
|
27a0ef |
3.10.0-1160.45.1.el7
|
|
|
27a0ef |
3.10.0-1160.49.1.el7
|
|
|
27a0ef |
3.10.0-1160.53.1.el7
|
|
|
27a0ef |
|
|
|
27a0ef |
Changes since last build:
|
|
|
27a0ef |
arches: x86_64
|
|
|
27a0ef |
i915_drv.o: changed function: i915_driver_destroy
|
|
|
27a0ef |
i915_gem.o: changed function: __i915_gem_object_unset_pages
|
|
|
27a0ef |
i915_gem.o: changed function: i915_gem_fault
|
|
|
27a0ef |
i915_gem.o: new function: assert_rpm_wakelock_held.part.56
|
|
|
27a0ef |
i915_gem.o: new function: tlb_invalidate_lock_ctor
|
|
|
27a0ef |
i915_vma.o: changed function: i915_vma_bind
|
|
|
27a0ef |
---------------------------
|
|
|
27a0ef |
|
|
|
27a0ef |
Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-7/-/merge_requests/24
|
|
|
27a0ef |
Kernels:
|
|
|
27a0ef |
3.10.0-1160.21.1.el7
|
|
|
27a0ef |
3.10.0-1160.24.1.el7
|
|
|
27a0ef |
3.10.0-1160.25.1.el7
|
|
|
27a0ef |
3.10.0-1160.31.1.el7
|
|
|
27a0ef |
3.10.0-1160.36.2.el7
|
|
|
27a0ef |
3.10.0-1160.41.1.el7
|
|
|
27a0ef |
3.10.0-1160.42.2.el7
|
|
|
27a0ef |
3.10.0-1160.45.1.el7
|
|
|
27a0ef |
3.10.0-1160.49.1.el7
|
|
|
27a0ef |
3.10.0-1160.53.1.el7
|
|
|
27a0ef |
|
|
|
27a0ef |
Modifications:
|
|
|
27a0ef |
- Move new bit definition to .c files avoiding changes to .h files.
|
|
|
27a0ef |
- Redefine tlb_invalidate_lock as a klp shadow variable and avoid
|
|
|
27a0ef |
changes to global structure definition (struct drm_i915_private).
|
|
|
27a0ef |
|
|
|
27a0ef |
commit c96aee1f92b3a81d8a36efd91cfc5ff33ca3ac80
|
|
|
27a0ef |
Author: Dave Airlie <airlied@redhat.com>
|
|
|
27a0ef |
Date: Tue Jan 25 18:19:06 2022 -0500
|
|
|
27a0ef |
|
|
|
27a0ef |
drm/i915: Flush TLBs before releasing backing store
|
|
|
27a0ef |
|
|
|
27a0ef |
Bugzilla: http://bugzilla.redhat.com/2044319
|
|
|
27a0ef |
CVE: CVE-2022-0330
|
|
|
27a0ef |
|
|
|
27a0ef |
commit 7938d61591d33394a21bdd7797a245b65428f44c
|
|
|
27a0ef |
Author: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
|
|
|
27a0ef |
Date: Tue Oct 19 13:27:10 2021 +0100
|
|
|
27a0ef |
|
|
|
27a0ef |
drm/i915: Flush TLBs before releasing backing store
|
|
|
27a0ef |
|
|
|
27a0ef |
We need to flush TLBs before releasing backing store otherwise userspace
|
|
|
27a0ef |
is able to encounter stale entries if a) it is not declaring access to
|
|
|
27a0ef |
certain buffers and b) it races with the backing store release from a
|
|
|
27a0ef |
such undeclared execution already executing on the GPU in parallel.
|
|
|
27a0ef |
|
|
|
27a0ef |
The approach taken is to mark any buffer objects which were ever bound
|
|
|
27a0ef |
to the GPU and to trigger a serialized TLB flush when their backing
|
|
|
27a0ef |
store is released.
|
|
|
27a0ef |
|
|
|
27a0ef |
Alternatively the flushing could be done on VMA unbind, at which point
|
|
|
27a0ef |
we would be able to ascertain whether there is potential a parallel GPU
|
|
|
27a0ef |
execution (which could race), but essentially it boils down to paying
|
|
|
27a0ef |
the cost of TLB flushes potentially needlessly at VMA unbind time (when
|
|
|
27a0ef |
the backing store is not known to be going away so not needed for
|
|
|
27a0ef |
safety), versus potentially needlessly at backing store relase time
|
|
|
27a0ef |
(since we at that point cannot tell whether there is anything executing
|
|
|
27a0ef |
on the GPU which uses that object).
|
|
|
27a0ef |
|
|
|
27a0ef |
Thereforce simplicity of implementation has been chosen for now with
|
|
|
27a0ef |
scope to benchmark and refine later as required.
|
|
|
27a0ef |
|
|
|
27a0ef |
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
|
|
|
27a0ef |
Reported-by: Sushma Venkatesh Reddy <sushma.venkatesh.reddy@intel.com>
|
|
|
27a0ef |
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
|
|
|
27a0ef |
Acked-by: Dave Airlie <airlied@redhat.com>
|
|
|
27a0ef |
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
|
|
|
27a0ef |
Cc: Jon Bloomfield <jon.bloomfield@intel.com>
|
|
|
27a0ef |
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
|
|
|
27a0ef |
Cc: Jani Nikula <jani.nikula@intel.com>
|
|
|
27a0ef |
Cc: stable@vger.kernel.org
|
|
|
27a0ef |
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
|
27a0ef |
|
|
|
27a0ef |
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
|
|
27a0ef |
|
|
|
27a0ef |
Signed-off-by: Yannick Cote <ycote@redhat.com>
|
|
|
27a0ef |
---
|
|
|
27a0ef |
drivers/gpu/drm/i915/i915_drv.c | 4 ++
|
|
|
27a0ef |
drivers/gpu/drm/i915/i915_gem.c | 104 ++++++++++++++++++++++++++++++++
|
|
|
27a0ef |
drivers/gpu/drm/i915/i915_vma.c | 6 ++
|
|
|
27a0ef |
3 files changed, 114 insertions(+)
|
|
|
27a0ef |
|
|
|
27a0ef |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
|
|
|
27a0ef |
index db8a0e6d2f2f..9c12def30f4b 100644
|
|
|
27a0ef |
--- a/drivers/gpu/drm/i915/i915_drv.c
|
|
|
27a0ef |
+++ b/drivers/gpu/drm/i915/i915_drv.c
|
|
|
27a0ef |
@@ -1683,11 +1683,15 @@ i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
27a0ef |
return i915;
|
|
|
27a0ef |
}
|
|
|
27a0ef |
|
|
|
27a0ef |
+#include <linux/livepatch.h>
|
|
|
27a0ef |
+#define KLP_CVE_2022_0330_MUTEX 0x2022033000000001
|
|
|
27a0ef |
+
|
|
|
27a0ef |
static void i915_driver_destroy(struct drm_i915_private *i915)
|
|
|
27a0ef |
{
|
|
|
27a0ef |
struct pci_dev *pdev = i915->drm.pdev;
|
|
|
27a0ef |
|
|
|
27a0ef |
drm_dev_fini(&i915->drm);
|
|
|
27a0ef |
+ klp_shadow_free(i915, KLP_CVE_2022_0330_MUTEX, NULL);
|
|
|
27a0ef |
kfree(i915);
|
|
|
27a0ef |
|
|
|
27a0ef |
/* And make sure we never chase our dangling pointer from pci_dev */
|
|
|
27a0ef |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
|
|
|
27a0ef |
index c96ccd9001bf..b882a08b32f9 100644
|
|
|
27a0ef |
--- a/drivers/gpu/drm/i915/i915_gem.c
|
|
|
27a0ef |
+++ b/drivers/gpu/drm/i915/i915_gem.c
|
|
|
27a0ef |
@@ -2464,6 +2464,101 @@ static void __i915_gem_object_reset_page_iter(struct drm_i915_gem_object *obj)
|
|
|
27a0ef |
rcu_read_unlock();
|
|
|
27a0ef |
}
|
|
|
27a0ef |
|
|
|
27a0ef |
+struct reg_and_bit {
|
|
|
27a0ef |
+ i915_reg_t reg;
|
|
|
27a0ef |
+ u32 bit;
|
|
|
27a0ef |
+};
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+static struct reg_and_bit
|
|
|
27a0ef |
+get_reg_and_bit(const struct intel_engine_cs *engine,
|
|
|
27a0ef |
+ const i915_reg_t *regs, const unsigned int num)
|
|
|
27a0ef |
+{
|
|
|
27a0ef |
+ const unsigned int class = engine->class;
|
|
|
27a0ef |
+ struct reg_and_bit rb = { .bit = 1 };
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+ if (WARN_ON_ONCE(class >= num || !regs[class].reg))
|
|
|
27a0ef |
+ return rb;
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+ rb.reg = regs[class];
|
|
|
27a0ef |
+ if (class == VIDEO_DECODE_CLASS)
|
|
|
27a0ef |
+ rb.reg.reg += 4 * engine->instance; /* GEN8_M2TCR */
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+ return rb;
|
|
|
27a0ef |
+}
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+#include <linux/livepatch.h>
|
|
|
27a0ef |
+#define KLP_CVE_2022_0330_MUTEX 0x2022033000000001
|
|
|
27a0ef |
+#define I915_BO_WAS_BOUND_BIT 1
|
|
|
27a0ef |
+#define GEN8_RTCR _MMIO(0x4260)
|
|
|
27a0ef |
+#define GEN8_M1TCR _MMIO(0x4264)
|
|
|
27a0ef |
+#define GEN8_M2TCR _MMIO(0x4268)
|
|
|
27a0ef |
+#define GEN8_BTCR _MMIO(0x426c)
|
|
|
27a0ef |
+#define GEN8_VTCR _MMIO(0x4270)
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+static int tlb_invalidate_lock_ctor(void *obj, void *shadow_data, void *ctor_data)
|
|
|
27a0ef |
+{
|
|
|
27a0ef |
+ struct mutex *m = shadow_data;
|
|
|
27a0ef |
+ mutex_init(m);
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+ return 0;
|
|
|
27a0ef |
+}
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+static void invalidate_tlbs(struct drm_i915_private *dev_priv)
|
|
|
27a0ef |
+{
|
|
|
27a0ef |
+ static const i915_reg_t gen8_regs[] = {
|
|
|
27a0ef |
+ [RENDER_CLASS] = GEN8_RTCR,
|
|
|
27a0ef |
+ [VIDEO_DECODE_CLASS] = GEN8_M1TCR, /* , GEN8_M2TCR */
|
|
|
27a0ef |
+ [VIDEO_ENHANCEMENT_CLASS] = GEN8_VTCR,
|
|
|
27a0ef |
+ [COPY_ENGINE_CLASS] = GEN8_BTCR,
|
|
|
27a0ef |
+ };
|
|
|
27a0ef |
+ const unsigned int num = ARRAY_SIZE(gen8_regs);
|
|
|
27a0ef |
+ const i915_reg_t *regs = gen8_regs;
|
|
|
27a0ef |
+ struct intel_engine_cs *engine;
|
|
|
27a0ef |
+ enum intel_engine_id id;
|
|
|
27a0ef |
+ struct mutex *tlb_invalidate_lock;
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+ if (INTEL_GEN(dev_priv) < 8)
|
|
|
27a0ef |
+ return;
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+ GEM_TRACE("\n");
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+ assert_rpm_wakelock_held(dev_priv);
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+ tlb_invalidate_lock = klp_shadow_get_or_alloc(dev_priv, KLP_CVE_2022_0330_MUTEX,
|
|
|
27a0ef |
+ sizeof(*tlb_invalidate_lock), GFP_KERNEL,
|
|
|
27a0ef |
+ tlb_invalidate_lock_ctor, NULL);
|
|
|
27a0ef |
+ if (tlb_invalidate_lock) {
|
|
|
27a0ef |
+ mutex_lock(tlb_invalidate_lock);
|
|
|
27a0ef |
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+ for_each_engine(engine, dev_priv, id) {
|
|
|
27a0ef |
+ /*
|
|
|
27a0ef |
+ * HW architecture suggest typical invalidation time at 40us,
|
|
|
27a0ef |
+ * with pessimistic cases up to 100us and a recommendation to
|
|
|
27a0ef |
+ * cap at 1ms. We go a bit higher just in case.
|
|
|
27a0ef |
+ */
|
|
|
27a0ef |
+ const unsigned int timeout_us = 100;
|
|
|
27a0ef |
+ const unsigned int timeout_ms = 4;
|
|
|
27a0ef |
+ struct reg_and_bit rb;
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+ rb = get_reg_and_bit(engine, regs, num);
|
|
|
27a0ef |
+ if (!i915_mmio_reg_offset(rb.reg))
|
|
|
27a0ef |
+ continue;
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+ I915_WRITE_FW(rb.reg, rb.bit);
|
|
|
27a0ef |
+ if (__intel_wait_for_register_fw(dev_priv,
|
|
|
27a0ef |
+ rb.reg, rb.bit, 0,
|
|
|
27a0ef |
+ timeout_us, timeout_ms,
|
|
|
27a0ef |
+ NULL))
|
|
|
27a0ef |
+ DRM_ERROR_RATELIMITED("%s TLB invalidation did not complete in %ums!\n",
|
|
|
27a0ef |
+ engine->name, timeout_ms);
|
|
|
27a0ef |
+ }
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
|
|
|
27a0ef |
+ mutex_unlock(tlb_invalidate_lock);
|
|
|
27a0ef |
+ }
|
|
|
27a0ef |
+}
|
|
|
27a0ef |
+
|
|
|
27a0ef |
static struct sg_table *
|
|
|
27a0ef |
__i915_gem_object_unset_pages(struct drm_i915_gem_object *obj)
|
|
|
27a0ef |
{
|
|
|
27a0ef |
@@ -2493,6 +2588,15 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj)
|
|
|
27a0ef |
__i915_gem_object_reset_page_iter(obj);
|
|
|
27a0ef |
obj->mm.page_sizes.phys = obj->mm.page_sizes.sg = 0;
|
|
|
27a0ef |
|
|
|
27a0ef |
+ if (test_and_clear_bit(I915_BO_WAS_BOUND_BIT, &obj->flags)) {
|
|
|
27a0ef |
+ struct drm_i915_private *i915 = to_i915(obj->base.dev);
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+ if (intel_runtime_pm_get_if_in_use(i915)) {
|
|
|
27a0ef |
+ invalidate_tlbs(i915);
|
|
|
27a0ef |
+ intel_runtime_pm_put(i915);
|
|
|
27a0ef |
+ }
|
|
|
27a0ef |
+ }
|
|
|
27a0ef |
+
|
|
|
27a0ef |
return pages;
|
|
|
27a0ef |
}
|
|
|
27a0ef |
|
|
|
27a0ef |
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
|
|
|
27a0ef |
index 5b4d78cdb4ca..906e6321ad77 100644
|
|
|
27a0ef |
--- a/drivers/gpu/drm/i915/i915_vma.c
|
|
|
27a0ef |
+++ b/drivers/gpu/drm/i915/i915_vma.c
|
|
|
27a0ef |
@@ -285,6 +285,8 @@ i915_vma_instance(struct drm_i915_gem_object *obj,
|
|
|
27a0ef |
return vma;
|
|
|
27a0ef |
}
|
|
|
27a0ef |
|
|
|
27a0ef |
+#define I915_BO_WAS_BOUND_BIT 1
|
|
|
27a0ef |
+
|
|
|
27a0ef |
/**
|
|
|
27a0ef |
* i915_vma_bind - Sets up PTEs for an VMA in it's corresponding address space.
|
|
|
27a0ef |
* @vma: VMA to map
|
|
|
27a0ef |
@@ -335,6 +337,10 @@ int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
|
|
|
27a0ef |
return ret;
|
|
|
27a0ef |
|
|
|
27a0ef |
vma->flags |= bind_flags;
|
|
|
27a0ef |
+
|
|
|
27a0ef |
+ if (vma->obj)
|
|
|
27a0ef |
+ set_bit(I915_BO_WAS_BOUND_BIT, &vma->obj->flags);
|
|
|
27a0ef |
+
|
|
|
27a0ef |
return 0;
|
|
|
27a0ef |
}
|
|
|
27a0ef |
|
|
|
27a0ef |
--
|
|
|
27a0ef |
2.26.3
|
|
|
27a0ef |
|
|
|
27a0ef |
|