dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/9] drm/i915: mark dmabuf objects as ALLOC_USER
@ 2021-10-18 17:45 Matthew Auld
  2021-10-18 17:45 ` [PATCH 2/9] drm/i915: mark userptr " Matthew Auld
                   ` (8 more replies)
  0 siblings, 9 replies; 19+ messages in thread
From: Matthew Auld @ 2021-10-18 17:45 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Thomas Hellström

These are userspace objects, so mark them as such. In a later patch it's
useful to determine how paranoid we need to be when managing cache
flushes. In theory no functional changes.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index afa34111de02..5be505ebbb7b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -301,7 +301,8 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
 	}
 
 	drm_gem_private_object_init(dev, &obj->base, dma_buf->size);
-	i915_gem_object_init(obj, &i915_gem_object_dmabuf_ops, &lock_class, 0);
+	i915_gem_object_init(obj, &i915_gem_object_dmabuf_ops, &lock_class,
+			     I915_BO_ALLOC_USER);
 	obj->base.import_attach = attach;
 	obj->base.resv = dma_buf->resv;
 
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 2/9] drm/i915: mark userptr objects as ALLOC_USER
  2021-10-18 17:45 [PATCH 1/9] drm/i915: mark dmabuf objects as ALLOC_USER Matthew Auld
@ 2021-10-18 17:45 ` Matthew Auld
  2021-10-20 14:36   ` Thomas Hellström
  2021-10-18 17:45 ` [PATCH 3/9] drm/i915: extract bypass-llc check into helper Matthew Auld
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Matthew Auld @ 2021-10-18 17:45 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Thomas Hellström

These are userspace objects, so mark them as such. In a later patch it's
useful to determine how paranoid we need to be when managing cache
flushes. In theory no functional changes.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
index 8ea0fa665e53..887aca9e8dd2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
@@ -546,7 +546,8 @@ i915_gem_userptr_ioctl(struct drm_device *dev,
 		return -ENOMEM;
 
 	drm_gem_private_object_init(dev, &obj->base, args->user_size);
-	i915_gem_object_init(obj, &i915_gem_userptr_ops, &lock_class, 0);
+	i915_gem_object_init(obj, &i915_gem_userptr_ops, &lock_class,
+			     I915_BO_ALLOC_USER);
 	obj->mem_flags = I915_BO_FLAG_STRUCT_PAGE;
 	obj->read_domains = I915_GEM_DOMAIN_CPU;
 	obj->write_domain = I915_GEM_DOMAIN_CPU;
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 3/9] drm/i915: extract bypass-llc check into helper
  2021-10-18 17:45 [PATCH 1/9] drm/i915: mark dmabuf objects as ALLOC_USER Matthew Auld
  2021-10-18 17:45 ` [PATCH 2/9] drm/i915: mark userptr " Matthew Auld
@ 2021-10-18 17:45 ` Matthew Auld
  2021-10-20 14:38   ` Thomas Hellström
  2021-10-18 17:45 ` [PATCH 4/9] drm/i915/dmabuf: add paranoid flush-on-acquire Matthew Auld
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Matthew Auld @ 2021-10-18 17:45 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Thomas Hellström

It looks like we will need this in some more places, so extract as a
helper.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_object.c | 26 ++++++++++++++++++++++
 drivers/gpu/drm/i915/gem/i915_gem_object.h |  1 +
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c  | 17 +-------------
 3 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 76ce6a1500bc..1e426a42a36c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -128,6 +128,32 @@ void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj,
 		!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE);
 }
 
+bool i915_gem_object_can_bypass_llc(struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+
+	/*
+	 * This is purely from a security perspective, so we simply don't care
+	 * about non-userspace objects being able to bypass the LLC.
+	 */
+	if (!(obj->flags & I915_BO_ALLOC_USER))
+		return false;
+
+	/*
+	 * EHL and JSL add the 'Bypass LLC' MOCS entry, which should make it
+	 * possible for userspace to bypass the GTT caching bits set by the
+	 * kernel, as per the given object cache_level. This is troublesome
+	 * since the heavy flush we apply when first gathering the pages is
+	 * skipped if the kernel thinks the object is coherent with the GPU. As
+	 * a result it might be possible to bypass the cache and read the
+	 * contents of the page directly, which could be stale data. If it's
+	 * just a case of userspace shooting themselves in the foot then so be
+	 * it, but since i915 takes the stance of always zeroing memory before
+	 * handing it to userspace, we need to prevent this.
+	 */
+	return IS_JSL_EHL(i915);
+}
+
 static void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file)
 {
 	struct drm_i915_gem_object *obj = to_intel_bo(gem);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 9df3ee60604e..59201801cec5 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -514,6 +514,7 @@ i915_gem_object_finish_access(struct drm_i915_gem_object *obj)
 
 void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj,
 					 unsigned int cache_level);
+bool i915_gem_object_can_bypass_llc(struct drm_i915_gem_object *obj);
 void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj);
 void i915_gem_object_flush_if_display_locked(struct drm_i915_gem_object *obj);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 11f072193f3b..cf11aa7e08a0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -182,22 +182,7 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
 	if (i915_gem_object_needs_bit17_swizzle(obj))
 		i915_gem_object_do_bit_17_swizzle(obj, st);
 
-	/*
-	 * EHL and JSL add the 'Bypass LLC' MOCS entry, which should make it
-	 * possible for userspace to bypass the GTT caching bits set by the
-	 * kernel, as per the given object cache_level. This is troublesome
-	 * since the heavy flush we apply when first gathering the pages is
-	 * skipped if the kernel thinks the object is coherent with the GPU. As
-	 * a result it might be possible to bypass the cache and read the
-	 * contents of the page directly, which could be stale data. If it's
-	 * just a case of userspace shooting themselves in the foot then so be
-	 * it, but since i915 takes the stance of always zeroing memory before
-	 * handing it to userspace, we need to prevent this.
-	 *
-	 * By setting cache_dirty here we make the clflush in set_pages
-	 * unconditional on such platforms.
-	 */
-	if (IS_JSL_EHL(i915) && obj->flags & I915_BO_ALLOC_USER)
+	if (i915_gem_object_can_bypass_llc(obj))
 		obj->cache_dirty = true;
 
 	__i915_gem_object_set_pages(obj, st, sg_page_sizes);
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 4/9] drm/i915/dmabuf: add paranoid flush-on-acquire
  2021-10-18 17:45 [PATCH 1/9] drm/i915: mark dmabuf objects as ALLOC_USER Matthew Auld
  2021-10-18 17:45 ` [PATCH 2/9] drm/i915: mark userptr " Matthew Auld
  2021-10-18 17:45 ` [PATCH 3/9] drm/i915: extract bypass-llc check into helper Matthew Auld
@ 2021-10-18 17:45 ` Matthew Auld
  2021-10-20 14:42   ` Thomas Hellström
  2021-10-26 13:44   ` Guenter Roeck
  2021-10-18 17:45 ` [PATCH 5/9] drm/i915/userptr: " Matthew Auld
                   ` (5 subsequent siblings)
  8 siblings, 2 replies; 19+ messages in thread
From: Matthew Auld @ 2021-10-18 17:45 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Thomas Hellström

As pointed out by Thomas, we likely need to flush the pages here if the
GPU can read the page contents directly from main memory. Underneath we
don't know what the sg_table is pointing to, so just add a
wbinvd_on_all_cpus() here, for now.

Reported-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 5be505ebbb7b..1adcd8e02d29 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -232,6 +232,7 @@ struct dma_buf *i915_gem_prime_export(struct drm_gem_object *gem_obj, int flags)
 
 static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
 {
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
 	struct sg_table *pages;
 	unsigned int sg_page_sizes;
 
@@ -242,8 +243,11 @@ static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
 	if (IS_ERR(pages))
 		return PTR_ERR(pages);
 
-	sg_page_sizes = i915_sg_dma_sizes(pages->sgl);
+	/* XXX: consider doing a vmap flush or something */
+	if (!HAS_LLC(i915) || i915_gem_object_can_bypass_llc(obj))
+		wbinvd_on_all_cpus();
 
+	sg_page_sizes = i915_sg_dma_sizes(pages->sgl);
 	__i915_gem_object_set_pages(obj, pages, sg_page_sizes);
 
 	return 0;
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 5/9] drm/i915/userptr: add paranoid flush-on-acquire
  2021-10-18 17:45 [PATCH 1/9] drm/i915: mark dmabuf objects as ALLOC_USER Matthew Auld
                   ` (2 preceding siblings ...)
  2021-10-18 17:45 ` [PATCH 4/9] drm/i915/dmabuf: add paranoid flush-on-acquire Matthew Auld
@ 2021-10-18 17:45 ` Matthew Auld
  2021-10-20 14:52   ` Thomas Hellström
  2021-10-18 17:45 ` [PATCH 6/9] drm/i915/shmem: ensure flush during swap-in on non-LLC Matthew Auld
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Matthew Auld @ 2021-10-18 17:45 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Thomas Hellström

Even though userptr objects are always coherent with the GPU, with no
way for userspace to change this with the set_caching ioctl, even on
non-LLC platforms, there is still the 'Bypass LCC' mocs setting, which
might permit reading the contents of main memory directly.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
index 887aca9e8dd2..3173c9f9a040 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
@@ -165,8 +165,11 @@ static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
 		goto err;
 	}
 
-	sg_page_sizes = i915_sg_dma_sizes(st->sgl);
+	WARN_ON_ONCE(!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE));
+	if (i915_gem_object_can_bypass_llc(obj))
+		obj->cache_dirty = true;
 
+	sg_page_sizes = i915_sg_dma_sizes(st->sgl);
 	__i915_gem_object_set_pages(obj, st, sg_page_sizes);
 
 	return 0;
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 6/9] drm/i915/shmem: ensure flush during swap-in on non-LLC
  2021-10-18 17:45 [PATCH 1/9] drm/i915: mark dmabuf objects as ALLOC_USER Matthew Auld
                   ` (3 preceding siblings ...)
  2021-10-18 17:45 ` [PATCH 5/9] drm/i915/userptr: " Matthew Auld
@ 2021-10-18 17:45 ` Matthew Auld
  2021-10-20 14:53   ` Thomas Hellström
  2021-10-18 17:45 ` [PATCH 7/9] drm/i915: expand on the kernel-doc for cache_dirty Matthew Auld
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Matthew Auld @ 2021-10-18 17:45 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Thomas Hellström

On non-LLC platforms, force the flush-on-acquire if this is ever
swapped-in. Our async flush path is not trust worthy enough yet(and
happens in the wrong order), and with some tricks it's conceivable for
userspace to change the cache-level to I915_CACHE_NONE after the pages
are swapped-in, and since execbuf binds the object before doing the
async flush, there is a potential race window.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index cf11aa7e08a0..d77da59fae04 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -286,6 +286,8 @@ __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj,
 				struct sg_table *pages,
 				bool needs_clflush)
 {
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+
 	GEM_BUG_ON(obj->mm.madv == __I915_MADV_PURGED);
 
 	if (obj->mm.madv == I915_MADV_DONTNEED)
@@ -297,6 +299,16 @@ __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj,
 		drm_clflush_sg(pages);
 
 	__start_cpu_write(obj);
+	/*
+	 * On non-LLC platforms, force the flush-on-acquire if this is ever
+	 * swapped-in. Our async flush path is not trust worthy enough yet(and
+	 * happens in the wrong order), and with some tricks it's conceivable
+	 * for userspace to change the cache-level to I915_CACHE_NONE after the
+	 * pages are swapped-in, and since execbuf binds the object before doing
+	 * the async flush, we have a race window.
+	 */
+	if (!HAS_LLC(i915))
+		obj->cache_dirty = true;
 }
 
 void i915_gem_object_put_pages_shmem(struct drm_i915_gem_object *obj, struct sg_table *pages)
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 7/9] drm/i915: expand on the kernel-doc for cache_dirty
  2021-10-18 17:45 [PATCH 1/9] drm/i915: mark dmabuf objects as ALLOC_USER Matthew Auld
                   ` (4 preceding siblings ...)
  2021-10-18 17:45 ` [PATCH 6/9] drm/i915/shmem: ensure flush during swap-in on non-LLC Matthew Auld
@ 2021-10-18 17:45 ` Matthew Auld
  2021-10-20 14:58   ` Thomas Hellström
  2021-10-18 17:45 ` [PATCH 8/9] drm/i915: mark up internal objects with start_cpu_write Matthew Auld
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Matthew Auld @ 2021-10-18 17:45 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Thomas Hellström, Daniel Vetter

Add some details around non-LLC platforms and cflushing, when dealing
with the flush-on-acquire, which is potentially security sensitive.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 11 ++++++++
 .../gpu/drm/i915/gem/i915_gem_object_types.h  | 27 +++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 1231224728e4..9c323666bd7c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -1933,6 +1933,17 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
 		 *   !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)
 		 * but gcc's optimiser doesn't handle that as well and emits
 		 * two jumps instead of one. Maybe one day...
+		 *
+		 * FIXME: There is also sync flushing in set_pages(), which
+		 * serves a different purpose(some of the time at least).
+		 *
+		 * We should consider:
+		 *
+		 *   1. Rip out the async flush code.
+		 *
+		 *   2. Or make the sync flushing use the async clflush path
+		 *   using mandatory fences underneath. Currently the below
+		 *   async flush happens after we bind the object.
 		 */
 		if (unlikely(obj->cache_dirty & ~obj->cache_coherent)) {
 			if (i915_gem_clflush_object(obj, 0))
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 7c3da4e3e737..da85169006d4 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -427,6 +427,33 @@ struct drm_i915_gem_object {
 	 * can freely bypass the CPU cache when touching the pages with the GPU,
 	 * where the kernel is completely unaware. On such platform we need
 	 * apply the sledgehammer-on-acquire regardless of the @cache_coherent.
+	 *
+	 * Special care is taken on non-LLC platforms, to prevent potential
+	 * information leak. The driver currently ensures:
+	 *
+	 *   1. All userspace objects, by default, have @cache_level set as
+	 *   I915_CACHE_NONE. The only exception is userptr objects, where we
+	 *   instead force I915_CACHE_LLC, but we also don't allow userspace to
+	 *   ever change the @cache_level for such objects. Another special case
+	 *   is dma-buf, which doesn't rely on @cache_dirty,  but there we
+	 *   always do a forced flush when acquiring the pages, if there is a
+	 *   chance that the pages can be read directly from main memory with
+	 *   the GPU.
+	 *
+	 *   2. All I915_CACHE_NONE objects have @cache_dirty initially true.
+	 *
+	 *   3. All swapped-out objects(i.e shmem) have @cache_dirty set to
+	 *   true.
+	 *
+	 *   4. The @cache_dirty is never freely reset before the initial
+	 *   flush, even if userspace adjusts the @cache_level through the
+	 *   i915_gem_set_caching_ioctl.
+	 *
+	 *   5. All @cache_dirty objects(including swapped-in) are initially
+	 *   flushed with a synchronous call to drm_clflush_sg in
+	 *   __i915_gem_object_set_pages. The @cache_dirty can be freely reset
+	 *   at this point. All further asynchronous clfushes are never security
+	 *   critical, i.e userspace is free to race against itself.
 	 */
 	unsigned int cache_dirty:1;
 
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 8/9] drm/i915: mark up internal objects with start_cpu_write
  2021-10-18 17:45 [PATCH 1/9] drm/i915: mark dmabuf objects as ALLOC_USER Matthew Auld
                   ` (5 preceding siblings ...)
  2021-10-18 17:45 ` [PATCH 7/9] drm/i915: expand on the kernel-doc for cache_dirty Matthew Auld
@ 2021-10-18 17:45 ` Matthew Auld
  2021-10-20 15:11   ` Thomas Hellström
  2021-10-18 17:45 ` [PATCH 9/9] drm/i915/selftests: mark up hugepages object " Matthew Auld
  2021-10-20 14:34 ` [PATCH 1/9] drm/i915: mark dmabuf objects as ALLOC_USER Thomas Hellström
  8 siblings, 1 reply; 19+ messages in thread
From: Matthew Auld @ 2021-10-18 17:45 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Thomas Hellström

While the pages can't be swapped out, they can be discarded by the shrinker.
Normally such objects are marked with __I915_MADV_PURGED, which can't be
unset, and therefore requires a new object. For kernel internal objects
this is not true, since the madv hint is reset for our special volatile
objects, such that we can re-acquire new pages, if so desired, without
needing a new object. As a result we should probably be paranoid here
and put the object back into the CPU domain when discarding the pages,
and also correctly set cache_dirty, if required.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_internal.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
index e5ae9c06510c..a57a6b7013c2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
@@ -134,6 +134,8 @@ static void i915_gem_object_put_pages_internal(struct drm_i915_gem_object *obj,
 	internal_free_pages(pages);
 
 	obj->mm.dirty = false;
+
+	__start_cpu_write(obj);
 }
 
 static const struct drm_i915_gem_object_ops i915_gem_object_internal_ops = {
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 9/9] drm/i915/selftests: mark up hugepages object with start_cpu_write
  2021-10-18 17:45 [PATCH 1/9] drm/i915: mark dmabuf objects as ALLOC_USER Matthew Auld
                   ` (6 preceding siblings ...)
  2021-10-18 17:45 ` [PATCH 8/9] drm/i915: mark up internal objects with start_cpu_write Matthew Auld
@ 2021-10-18 17:45 ` Matthew Auld
  2021-10-20 15:12   ` Thomas Hellström
  2021-10-20 14:34 ` [PATCH 1/9] drm/i915: mark dmabuf objects as ALLOC_USER Thomas Hellström
  8 siblings, 1 reply; 19+ messages in thread
From: Matthew Auld @ 2021-10-18 17:45 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Thomas Hellström

Just like we do for internal objects. Also just use
i915_gem_object_set_cache_coherency() here. No need for over-flushing on
LLC platforms.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index 41d0680f3bd7..b2003133deaf 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -136,6 +136,8 @@ static void put_huge_pages(struct drm_i915_gem_object *obj,
 	huge_pages_free_pages(pages);
 
 	obj->mm.dirty = false;
+
+	__start_cpu_write(obj);
 }
 
 static const struct drm_i915_gem_object_ops huge_page_ops = {
@@ -152,6 +154,7 @@ huge_pages_object(struct drm_i915_private *i915,
 {
 	static struct lock_class_key lock_class;
 	struct drm_i915_gem_object *obj;
+	unsigned int cache_level;
 
 	GEM_BUG_ON(!size);
 	GEM_BUG_ON(!IS_ALIGNED(size, BIT(__ffs(page_mask))));
@@ -173,7 +176,9 @@ huge_pages_object(struct drm_i915_private *i915,
 
 	obj->write_domain = I915_GEM_DOMAIN_CPU;
 	obj->read_domains = I915_GEM_DOMAIN_CPU;
-	obj->cache_level = I915_CACHE_NONE;
+
+	cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
+	i915_gem_object_set_cache_coherency(obj, cache_level);
 
 	obj->mm.page_mask = page_mask;
 
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/9] drm/i915: mark dmabuf objects as ALLOC_USER
  2021-10-18 17:45 [PATCH 1/9] drm/i915: mark dmabuf objects as ALLOC_USER Matthew Auld
                   ` (7 preceding siblings ...)
  2021-10-18 17:45 ` [PATCH 9/9] drm/i915/selftests: mark up hugepages object " Matthew Auld
@ 2021-10-20 14:34 ` Thomas Hellström
  8 siblings, 0 replies; 19+ messages in thread
From: Thomas Hellström @ 2021-10-20 14:34 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx; +Cc: dri-devel

On Mon, 2021-10-18 at 18:45 +0100, Matthew Auld wrote:
> These are userspace objects, so mark them as such. In a later patch
> it's
> useful to determine how paranoid we need to be when managing cache
> flushes. In theory no functional changes.
> 
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> 
Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/9] drm/i915: mark userptr objects as ALLOC_USER
  2021-10-18 17:45 ` [PATCH 2/9] drm/i915: mark userptr " Matthew Auld
@ 2021-10-20 14:36   ` Thomas Hellström
  0 siblings, 0 replies; 19+ messages in thread
From: Thomas Hellström @ 2021-10-20 14:36 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx; +Cc: dri-devel

On Mon, 2021-10-18 at 18:45 +0100, Matthew Auld wrote:
> These are userspace objects, so mark them as such. In a later patch
> it's
> useful to determine how paranoid we need to be when managing cache
> flushes. In theory no functional changes.
> 
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/9] drm/i915: extract bypass-llc check into helper
  2021-10-18 17:45 ` [PATCH 3/9] drm/i915: extract bypass-llc check into helper Matthew Auld
@ 2021-10-20 14:38   ` Thomas Hellström
  0 siblings, 0 replies; 19+ messages in thread
From: Thomas Hellström @ 2021-10-20 14:38 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx; +Cc: dri-devel

On Mon, 2021-10-18 at 18:45 +0100, Matthew Auld wrote:
> It looks like we will need this in some more places, so extract as a
> helper.
> 
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_object.c | 26
> ++++++++++++++++++++++
>  drivers/gpu/drm/i915/gem/i915_gem_object.h |  1 +
>  drivers/gpu/drm/i915/gem/i915_gem_shmem.c  | 17 +-------------
>  3 files changed, 28 insertions(+), 16 deletions(-)
> 
Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 4/9] drm/i915/dmabuf: add paranoid flush-on-acquire
  2021-10-18 17:45 ` [PATCH 4/9] drm/i915/dmabuf: add paranoid flush-on-acquire Matthew Auld
@ 2021-10-20 14:42   ` Thomas Hellström
  2021-10-26 13:44   ` Guenter Roeck
  1 sibling, 0 replies; 19+ messages in thread
From: Thomas Hellström @ 2021-10-20 14:42 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx; +Cc: dri-devel

On Mon, 2021-10-18 at 18:45 +0100, Matthew Auld wrote:
> As pointed out by Thomas, we likely need to flush the pages here if
> the
> GPU can read the page contents directly from main memory. Underneath
> we
> don't know what the sg_table is pointing to, so just add a
> wbinvd_on_all_cpus() here, for now.
> 
> Reported-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>

Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 5/9] drm/i915/userptr: add paranoid flush-on-acquire
  2021-10-18 17:45 ` [PATCH 5/9] drm/i915/userptr: " Matthew Auld
@ 2021-10-20 14:52   ` Thomas Hellström
  0 siblings, 0 replies; 19+ messages in thread
From: Thomas Hellström @ 2021-10-20 14:52 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx; +Cc: dri-devel


On 10/18/21 19:45, Matthew Auld wrote:
> Even though userptr objects are always coherent with the GPU, with no
> way for userspace to change this with the set_caching ioctl, even on
> non-LLC platforms, there is still the 'Bypass LCC' mocs setting, which
> might permit reading the contents of main memory directly.
>
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> ---
>   drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)

Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>


> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
> index 887aca9e8dd2..3173c9f9a040 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
> @@ -165,8 +165,11 @@ static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
>   		goto err;
>   	}
>   
> -	sg_page_sizes = i915_sg_dma_sizes(st->sgl);
> +	WARN_ON_ONCE(!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE));
> +	if (i915_gem_object_can_bypass_llc(obj))
> +		obj->cache_dirty = true;
>   
> +	sg_page_sizes = i915_sg_dma_sizes(st->sgl);
>   	__i915_gem_object_set_pages(obj, st, sg_page_sizes);
>   
>   	return 0;

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 6/9] drm/i915/shmem: ensure flush during swap-in on non-LLC
  2021-10-18 17:45 ` [PATCH 6/9] drm/i915/shmem: ensure flush during swap-in on non-LLC Matthew Auld
@ 2021-10-20 14:53   ` Thomas Hellström
  0 siblings, 0 replies; 19+ messages in thread
From: Thomas Hellström @ 2021-10-20 14:53 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx; +Cc: dri-devel


On 10/18/21 19:45, Matthew Auld wrote:
> On non-LLC platforms, force the flush-on-acquire if this is ever
> swapped-in. Our async flush path is not trust worthy enough yet(and
> happens in the wrong order), and with some tricks it's conceivable for
> userspace to change the cache-level to I915_CACHE_NONE after the pages
> are swapped-in, and since execbuf binds the object before doing the
> async flush, there is a potential race window.

Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 7/9] drm/i915: expand on the kernel-doc for cache_dirty
  2021-10-18 17:45 ` [PATCH 7/9] drm/i915: expand on the kernel-doc for cache_dirty Matthew Auld
@ 2021-10-20 14:58   ` Thomas Hellström
  0 siblings, 0 replies; 19+ messages in thread
From: Thomas Hellström @ 2021-10-20 14:58 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx; +Cc: dri-devel, Daniel Vetter


On 10/18/21 19:45, Matthew Auld wrote:
> Add some details around non-LLC platforms and cflushing, when dealing
> with the flush-on-acquire, which is potentially security sensitive.
>
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> ---
>   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 11 ++++++++
>   .../gpu/drm/i915/gem/i915_gem_object_types.h  | 27 +++++++++++++++++++
>   2 files changed, 38 insertions(+)

Lgtm.

Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 8/9] drm/i915: mark up internal objects with start_cpu_write
  2021-10-18 17:45 ` [PATCH 8/9] drm/i915: mark up internal objects with start_cpu_write Matthew Auld
@ 2021-10-20 15:11   ` Thomas Hellström
  0 siblings, 0 replies; 19+ messages in thread
From: Thomas Hellström @ 2021-10-20 15:11 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx; +Cc: dri-devel

On Mon, 2021-10-18 at 18:45 +0100, Matthew Auld wrote:
> While the pages can't be swapped out, they can be discarded by the
> shrinker.
> Normally such objects are marked with __I915_MADV_PURGED, which can't
> be
> unset, and therefore requires a new object. For kernel internal
> objects
> this is not true, since the madv hint is reset for our special
> volatile
> objects, such that we can re-acquire new pages, if so desired,
> without
> needing a new object. As a result we should probably be paranoid here
> and put the object back into the CPU domain when discarding the
> pages,
> and also correctly set cache_dirty, if required.
> 
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_internal.c | 2 ++
>  1 file changed, 2 insertions(+)

Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 9/9] drm/i915/selftests: mark up hugepages object with start_cpu_write
  2021-10-18 17:45 ` [PATCH 9/9] drm/i915/selftests: mark up hugepages object " Matthew Auld
@ 2021-10-20 15:12   ` Thomas Hellström
  0 siblings, 0 replies; 19+ messages in thread
From: Thomas Hellström @ 2021-10-20 15:12 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx; +Cc: dri-devel

On Mon, 2021-10-18 at 18:45 +0100, Matthew Auld wrote:
> Just like we do for internal objects. Also just use
> i915_gem_object_set_cache_coherency() here. No need for over-flushing
> on
> LLC platforms.
> 
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
Reivewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 4/9] drm/i915/dmabuf: add paranoid flush-on-acquire
  2021-10-18 17:45 ` [PATCH 4/9] drm/i915/dmabuf: add paranoid flush-on-acquire Matthew Auld
  2021-10-20 14:42   ` Thomas Hellström
@ 2021-10-26 13:44   ` Guenter Roeck
  1 sibling, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2021-10-26 13:44 UTC (permalink / raw)
  To: Matthew Auld; +Cc: intel-gfx, dri-devel, Thomas Hellström

On Mon, Oct 18, 2021 at 06:45:03PM +0100, Matthew Auld wrote:
> As pointed out by Thomas, we likely need to flush the pages here if the
> GPU can read the page contents directly from main memory. Underneath we
> don't know what the sg_table is pointing to, so just add a
> wbinvd_on_all_cpus() here, for now.
> 
> Reported-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>

With nosmp builds:

Error log:
drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c: In function 'i915_gem_object_get_pages_dmabuf':
drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c:248:17: error: implicit declaration of function 'wbinvd_on_all_cpus' [-Werror=implicit-function-declaration]
  248 |                 wbinvd_on_all_cpus();
      |                 ^~~~~~~~~~~~~~~~~~

Guenter

> ---
>  drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> index 5be505ebbb7b..1adcd8e02d29 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> @@ -232,6 +232,7 @@ struct dma_buf *i915_gem_prime_export(struct drm_gem_object *gem_obj, int flags)
>  
>  static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
>  {
> +	struct drm_i915_private *i915 = to_i915(obj->base.dev);
>  	struct sg_table *pages;
>  	unsigned int sg_page_sizes;
>  
> @@ -242,8 +243,11 @@ static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
>  	if (IS_ERR(pages))
>  		return PTR_ERR(pages);
>  
> -	sg_page_sizes = i915_sg_dma_sizes(pages->sgl);
> +	/* XXX: consider doing a vmap flush or something */
> +	if (!HAS_LLC(i915) || i915_gem_object_can_bypass_llc(obj))
> +		wbinvd_on_all_cpus();
>  
> +	sg_page_sizes = i915_sg_dma_sizes(pages->sgl);
>  	__i915_gem_object_set_pages(obj, pages, sg_page_sizes);
>  
>  	return 0;
> -- 
> 2.26.3
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2021-10-26 13:44 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-18 17:45 [PATCH 1/9] drm/i915: mark dmabuf objects as ALLOC_USER Matthew Auld
2021-10-18 17:45 ` [PATCH 2/9] drm/i915: mark userptr " Matthew Auld
2021-10-20 14:36   ` Thomas Hellström
2021-10-18 17:45 ` [PATCH 3/9] drm/i915: extract bypass-llc check into helper Matthew Auld
2021-10-20 14:38   ` Thomas Hellström
2021-10-18 17:45 ` [PATCH 4/9] drm/i915/dmabuf: add paranoid flush-on-acquire Matthew Auld
2021-10-20 14:42   ` Thomas Hellström
2021-10-26 13:44   ` Guenter Roeck
2021-10-18 17:45 ` [PATCH 5/9] drm/i915/userptr: " Matthew Auld
2021-10-20 14:52   ` Thomas Hellström
2021-10-18 17:45 ` [PATCH 6/9] drm/i915/shmem: ensure flush during swap-in on non-LLC Matthew Auld
2021-10-20 14:53   ` Thomas Hellström
2021-10-18 17:45 ` [PATCH 7/9] drm/i915: expand on the kernel-doc for cache_dirty Matthew Auld
2021-10-20 14:58   ` Thomas Hellström
2021-10-18 17:45 ` [PATCH 8/9] drm/i915: mark up internal objects with start_cpu_write Matthew Auld
2021-10-20 15:11   ` Thomas Hellström
2021-10-18 17:45 ` [PATCH 9/9] drm/i915/selftests: mark up hugepages object " Matthew Auld
2021-10-20 15:12   ` Thomas Hellström
2021-10-20 14:34 ` [PATCH 1/9] drm/i915: mark dmabuf objects as ALLOC_USER Thomas Hellström

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).