Consolidate the wrapper functions to check for dma_fence
subclasses in the dma_fence header.
This makes it easier to document and also check the different
requirements for fence containers in the subclasses.
Signed-off-by: Christian König <christian.koenig(a)amd.com>
---
include/linux/dma-fence-array.h | 15 +------------
include/linux/dma-fence-chain.h | 3 +--
include/linux/dma-fence.h | 38 +++++++++++++++++++++++++++++++++
3 files changed, 40 insertions(+), 16 deletions(-)
diff --git a/include/linux/dma-fence-array.h b/include/linux/dma-fence-array.h
index 303dd712220f..fec374f69e12 100644
--- a/include/linux/dma-fence-array.h
+++ b/include/linux/dma-fence-array.h
@@ -45,19 +45,6 @@ struct dma_fence_array {
struct irq_work work;
};
-extern const struct dma_fence_ops dma_fence_array_ops;
-
-/**
- * dma_fence_is_array - check if a fence is from the array subsclass
- * @fence: fence to test
- *
- * Return true if it is a dma_fence_array and false otherwise.
- */
-static inline bool dma_fence_is_array(struct dma_fence *fence)
-{
- return fence->ops == &dma_fence_array_ops;
-}
-
/**
* to_dma_fence_array - cast a fence to a dma_fence_array
* @fence: fence to cast to a dma_fence_array
@@ -68,7 +55,7 @@ static inline bool dma_fence_is_array(struct dma_fence *fence)
static inline struct dma_fence_array *
to_dma_fence_array(struct dma_fence *fence)
{
- if (fence->ops != &dma_fence_array_ops)
+ if (!fence || !dma_fence_is_array(fence))
return NULL;
return container_of(fence, struct dma_fence_array, base);
diff --git a/include/linux/dma-fence-chain.h b/include/linux/dma-fence-chain.h
index 54fe3443fd2c..ee906b659694 100644
--- a/include/linux/dma-fence-chain.h
+++ b/include/linux/dma-fence-chain.h
@@ -49,7 +49,6 @@ struct dma_fence_chain {
spinlock_t lock;
};
-extern const struct dma_fence_ops dma_fence_chain_ops;
/**
* to_dma_fence_chain - cast a fence to a dma_fence_chain
@@ -61,7 +60,7 @@ extern const struct dma_fence_ops dma_fence_chain_ops;
static inline struct dma_fence_chain *
to_dma_fence_chain(struct dma_fence *fence)
{
- if (!fence || fence->ops != &dma_fence_chain_ops)
+ if (!fence || !dma_fence_is_chain(fence))
return NULL;
return container_of(fence, struct dma_fence_chain, base);
diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
index 1ea691753bd3..775cdc0b4f24 100644
--- a/include/linux/dma-fence.h
+++ b/include/linux/dma-fence.h
@@ -587,4 +587,42 @@ struct dma_fence *dma_fence_get_stub(void);
struct dma_fence *dma_fence_allocate_private_stub(void);
u64 dma_fence_context_alloc(unsigned num);
+extern const struct dma_fence_ops dma_fence_array_ops;
+extern const struct dma_fence_ops dma_fence_chain_ops;
+
+/**
+ * dma_fence_is_array - check if a fence is from the array subclass
+ * @fence: the fence to test
+ *
+ * Return true if it is a dma_fence_array and false otherwise.
+ */
+static inline bool dma_fence_is_array(struct dma_fence *fence)
+{
+ return fence->ops == &dma_fence_array_ops;
+}
+
+/**
+ * dma_fence_is_chain - check if a fence is from the chain subclass
+ * @fence: the fence to test
+ *
+ * Return true if it is a dma_fence_chain and false otherwise.
+ */
+static inline bool dma_fence_is_chain(struct dma_fence *fence)
+{
+ return fence->ops == &dma_fence_chain_ops;
+}
+
+/**
+ * dma_fence_is_container - check if a fence is a container for other fences
+ * @fence: the fence to test
+ *
+ * Return true if this fence is a container for other fences, false otherwise.
+ * This is important since we can't build up large fence structure or otherwise
+ * we run into recursion during operation on those fences.
+ */
+static inline bool dma_fence_is_container(struct dma_fence *fence)
+{
+ return dma_fence_is_array(fence) || dma_fence_is_chain(fence);
+}
+
#endif /* __LINUX_DMA_FENCE_H */
--
2.25.1
While porting i915 to arm64 we noticed some issues accessing lmem.
Some writes were getting corrupted and the final state of the buffer
didn't have exactly what we wrote. This became evident when enabling
GuC submission: depending on the number of engines the ADS struct was
being corrupted and GuC would reject it, refusin to initialize.
From Documentation/core-api/bus-virt-phys-mapping.rst:
This memory is called "PCI memory" or "shared memory" or "IO memory" or
whatever, and there is only one way to access it: the readb/writeb and
related functions. You should never take the address of such memory, because
there is really nothing you can do with such an address: it's not
conceptually in the same memory space as "real memory" at all, so you cannot
just dereference a pointer. (Sadly, on x86 it **is** in the same memory space,
so on x86 it actually works to just deference a pointer, but it's not
portable).
When reading or writing words directly to IO memory, in order to be portable
the Linux kernel provides the abstraction detailed in section "Differences
between I/O access functions" of Documentation/driver-api/device-io.rst.
This limits our ability to simply overlay our structs on top a buffer
and directly access it since that buffer may come from IO memory rather than
system memory. Hence the approach taken in intel_guc_ads.c needs to be
refactored. This is not the only place in i915 that neeed to be changed, but
the one causing the most problems, with a real reproducer. This first set of
patch focuses on fixing the gem object to pass the ADS
After the addition of a few helpers in the dma_buf_map API, most of
intel_guc_ads.c can be converted to use it. The exception is the regset
initialization: we'd incur into a lot of extra indirection when
reading/writting each register. So the regset is converted to use a
temporary buffer allocated on probe, which is then copied to its
final location when finishing the initialization or on gt reset.
Testing on some discrete cards, after this change we can correctly pass the
ADS struct to GuC and have it initialized correctly.
thanks
Lucas De Marchi
Cc: linux-media(a)vger.kernel.org
Cc: dri-devel(a)lists.freedesktop.org
Cc: linaro-mm-sig(a)lists.linaro.org
Cc: linux-kernel(a)vger.kernel.org
Cc: Christian König <christian.koenig(a)amd.com>
Cc: Daniel Vetter <daniel(a)ffwll.ch>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio(a)intel.com>
Cc: David Airlie <airlied(a)linux.ie>
Cc: John Harrison <John.C.Harrison(a)Intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen(a)linux.intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst(a)linux.intel.com>
Cc: Matt Roper <matthew.d.roper(a)intel.com>
Cc: Matthew Auld <matthew.auld(a)intel.com>
Cc: Matthew Brost <matthew.brost(a)intel.com>
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: Thomas Hellström <thomas.hellstrom(a)linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin(a)linux.intel.com>
Lucas De Marchi (19):
dma-buf-map: Add read/write helpers
dma-buf-map: Add helper to initialize second map
drm/i915/gt: Add helper for shmem copy to dma_buf_map
drm/i915/guc: Keep dma_buf_map of ads_blob around
drm/i915/guc: Add read/write helpers for ADS blob
drm/i915/guc: Convert golden context init to dma_buf_map
drm/i915/guc: Convert policies update to dma_buf_map
drm/i915/guc: Convert engine record to dma_buf_map
dma-buf-map: Add wrapper over memset
drm/i915/guc: Convert guc_ads_private_data_reset to dma_buf_map
drm/i915/guc: Convert golden context prep to dma_buf_map
drm/i915/guc: Replace check for golden context size
drm/i915/guc: Convert mapping table to dma_buf_map
drm/i915/guc: Convert capture list to dma_buf_map
drm/i915/guc: Prepare for error propagation
drm/i915/guc: Use a single pass to calculate regset
drm/i915/guc: Convert guc_mmio_reg_state_init to dma_buf_map
drm/i915/guc: Convert __guc_ads_init to dma_buf_map
drm/i915/guc: Remove plain ads_blob pointer
drivers/gpu/drm/i915/gt/shmem_utils.c | 32 ++
drivers/gpu/drm/i915/gt/shmem_utils.h | 3 +
drivers/gpu/drm/i915/gt/uc/intel_guc.h | 14 +-
drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 374 +++++++++++-------
drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h | 3 +-
.../gpu/drm/i915/gt/uc/intel_guc_submission.c | 11 +-
include/linux/dma-buf-map.h | 127 ++++++
7 files changed, 405 insertions(+), 159 deletions(-)
--
2.35.0
On Thu, Jan 27, 2022 at 02:24:29PM +0100, Greg Kroah-Hartman wrote:
> On Thu, Jan 27, 2022 at 02:02:18PM +0100, Mathias Krause wrote:
> > If the copy back to userland fails for the FASTRPC_IOCTL_ALLOC_DMA_BUFF
> > ioctl(), we shouldn't assume that 'buf->dmabuf' is still valid. In fact,
> > dma_buf_fd() called fd_install() before, i.e. "consumed" one reference,
> > leaving us with none.
> >
> > Calling dma_buf_put() will therefore put a reference we no longer own,
> > leading to a valid file descritor table entry for an already released
> > 'file' object which is a straight use-after-free.
> >
> > Simply avoid calling dma_buf_put() and rely on the process exit code to
> > do the necessary cleanup, if needed, i.e. if the file descriptor is
> > still valid.
> >
> > Fixes: 6cffd79504ce ("misc: fastrpc: Add support for dmabuf exporter")
> > Signed-off-by: Mathias Krause <minipli(a)grsecurity.net>
> > ---
> > drivers/misc/fastrpc.c | 9 ++++++++-
> > 1 file changed, 8 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
> > index 4ccbf43e6bfa..aa1682b94a23 100644
> > --- a/drivers/misc/fastrpc.c
> > +++ b/drivers/misc/fastrpc.c
> > @@ -1288,7 +1288,14 @@ static int fastrpc_dmabuf_alloc(struct fastrpc_user *fl, char __user *argp)
> > }
> >
> > if (copy_to_user(argp, &bp, sizeof(bp))) {
> > - dma_buf_put(buf->dmabuf);
> > + /*
> > + * The usercopy failed, but we can't do much about it, as
> > + * dma_buf_fd() already called fd_install() and made the
> > + * file descriptor accessible for the current process. It
> > + * might already be closed and dmabuf no longer valid when
> > + * we reach this point. Therefore "leak" the fd and rely on
> > + * the process exit path to do any required cleanup.
> > + */
> > return -EFAULT;
> > }
> >
>
> This feels wrong. How do all other dma buf users handle this?
>
> And you forgot to cc: the dmabuf developers, I think get_maintainers.pl
> should have caught them on this patch.
Odd, it didn't, not your fault, my apologies.
DMA BUFFER maintainers, what happened to the MAINTAINERS regex that
caused the above patch to not catch you all?
thanks,
greg k-h
This series make KFENCE to be more convenient to adjust parameters in
not only debug process but also production situations. In different
production and development stage, the demands of memory and CPU
limitations for KFENCE is quite different. In order to satisfy these
demands with a uniform kernel release, dynamically adjust KFENCE
parameters is needed.
Signed-off-by: Peng Liu <liupeng256(a)huawei.com>
Peng Liu (3):
kfence: Add a module parameter to adjust kfence objects
kfence: Optimize branches prediction when sample interval is zero
kfence: Make test case compatible with run time set sample interval
Documentation/dev-tools/kfence.rst | 14 ++--
include/linux/kfence.h | 10 ++-
mm/kfence/core.c | 113 ++++++++++++++++++++++++-----
mm/kfence/kfence.h | 2 +-
mm/kfence/kfence_test.c | 10 +--
5 files changed, 116 insertions(+), 33 deletions(-)
--
2.18.0.huawei.25
This is a note to let you know that I've just added the patch titled
dma_fence_array: Fix PENDING_ERROR leak in dma_fence_array_signaled()
to the 5.10-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
dma_fence_array-fix-pending_error-leak-in-dma_fence_array_signaled.patch
and it can be found in the queue-5.10 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
From 95d35838880fb040ccb9fe4a48816bd0c8b62df5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= <thomas.hellstrom(a)linux.intel.com>
Date: Mon, 29 Nov 2021 16:27:27 +0100
Subject: dma_fence_array: Fix PENDING_ERROR leak in dma_fence_array_signaled()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Thomas Hellström <thomas.hellstrom(a)linux.intel.com>
commit 95d35838880fb040ccb9fe4a48816bd0c8b62df5 upstream.
If a dma_fence_array is reported signaled by a call to
dma_fence_is_signaled(), it may leak the PENDING_ERROR status.
Fix this by clearing the PENDING_ERROR status if we return true in
dma_fence_array_signaled().
v2:
- Update Cc list, and add R-b.
Fixes: 1f70b8b812f3 ("dma-fence: Propagate errors to dma-fence-array container")
Cc: Chris Wilson <chris(a)chris-wilson.co.uk>
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: Gustavo Padovan <gustavo(a)padovan.org>
Cc: Christian König <christian.koenig(a)amd.com>
Cc: "Christian König" <christian.koenig(a)amd.com>
Cc: linux-media(a)vger.kernel.org
Cc: dri-devel(a)lists.freedesktop.org
Cc: linaro-mm-sig(a)lists.linaro.org
Cc: <stable(a)vger.kernel.org> # v5.4+
Signed-off-by: Thomas Hellström <thomas.hellstrom(a)linux.intel.com>
Reviewed-by: Christian König <christian.koenig(a)amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211129152727.448908-1-thoma…
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/dma-fence-array.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/dma-buf/dma-fence-array.c
+++ b/drivers/dma-buf/dma-fence-array.c
@@ -104,7 +104,11 @@ static bool dma_fence_array_signaled(str
{
struct dma_fence_array *array = to_dma_fence_array(fence);
- return atomic_read(&array->num_pending) <= 0;
+ if (atomic_read(&array->num_pending) > 0)
+ return false;
+
+ dma_fence_array_clear_pending_error(array);
+ return true;
}
static void dma_fence_array_release(struct dma_fence *fence)
Patches currently in stable-queue which might be from thomas.hellstrom(a)linux.intel.com are
queue-5.10/dma_fence_array-fix-pending_error-leak-in-dma_fence_array_signaled.patch