It's the default.
Also so much for "we're not going to tell the graphics people how to
review their code", dma_fence is a pretty core piece of gpu driver
infrastructure. And it's very much uapi relevant, including piles of
corresponding userspace protocols and libraries for how to pass these
around.
Would be great if habanalabs would not use this (from a quick look
it's not needed at all), since open source the userspace and playing
by the usual rules isn't on the table. If that's not possible (because
it's actually using the uapi part of dma_fence to interact with gpu
drivers) then we have exactly what everyone promised we'd want to
avoid.
Signed-off-by: Daniel Vetter <daniel.vetter(a)intel.com>
Cc: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Cc: Olof Johansson <olof(a)lixom.net>
Cc: Oded Gabbay <oded.gabbay(a)gmail.com>
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: linux-media(a)vger.kernel.org
Cc: linaro-mm-sig(a)lists.linaro.org
---
drivers/misc/habanalabs/command_submission.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/misc/habanalabs/command_submission.c b/drivers/misc/habanalabs/command_submission.c
index 409276b6374d..cc3ce759b6c3 100644
--- a/drivers/misc/habanalabs/command_submission.c
+++ b/drivers/misc/habanalabs/command_submission.c
@@ -46,7 +46,6 @@ static const struct dma_fence_ops hl_fence_ops = {
.get_driver_name = hl_fence_get_driver_name,
.get_timeline_name = hl_fence_get_timeline_name,
.enable_signaling = hl_fence_enable_signaling,
- .wait = dma_fence_default_wait,
.release = hl_fence_release
};
--
2.26.2
On Wed, May 06, 2020 at 02:00:10PM +0530, Charan Teja Kalla wrote:
> Thank you Greg for the reply.
>
> On 5/5/2020 3:38 PM, Greg KH wrote:
> > On Tue, Apr 28, 2020 at 01:24:02PM +0530, Charan Teja Reddy wrote:
> > > The following race occurs while accessing the dmabuf object exported as
> > > file:
> > > P1 P2
> > > dma_buf_release() dmabuffs_dname()
> > > [say lsof reading /proc/<P1 pid>/fd/<num>]
> > >
> > > read dmabuf stored in dentry->fsdata
> > > Free the dmabuf object
> > > Start accessing the dmabuf structure
> > >
> > > In the above description, the dmabuf object freed in P1 is being
> > > accessed from P2 which is resulting into the use-after-free. Below is
> > > the dump stack reported.
> > >
> > > Call Trace:
> > > kasan_report+0x12/0x20
> > > __asan_report_load8_noabort+0x14/0x20
> > > dmabuffs_dname+0x4f4/0x560
> > > tomoyo_realpath_from_path+0x165/0x660
> > > tomoyo_get_realpath
> > > tomoyo_check_open_permission+0x2a3/0x3e0
> > > tomoyo_file_open
> > > tomoyo_file_open+0xa9/0xd0
> > > security_file_open+0x71/0x300
> > > do_dentry_open+0x37a/0x1380
> > > vfs_open+0xa0/0xd0
> > > path_openat+0x12ee/0x3490
> > > do_filp_open+0x192/0x260
> > > do_sys_openat2+0x5eb/0x7e0
> > > do_sys_open+0xf2/0x180
> > >
> > > Fixes: bb2bb90 ("dma-buf: add DMA_BUF_SET_NAME ioctls")
> > Nit, please read the documentation for how to do a Fixes: line properly,
> > you need more digits:
> > Fixes: bb2bb9030425 ("dma-buf: add DMA_BUF_SET_NAME ioctls")
>
>
> Will update the patch
>
>
> > > Reported-by:syzbot+3643a18836bce555bff6@syzkaller.appspotmail.com
> > > Signed-off-by: Charan Teja Reddy<charante(a)codeaurora.org>
> > Also, any reason you didn't include the other mailing lists that
> > get_maintainer.pl said to?
>
>
> Really sorry for not sending to complete list. Added now.
>
>
> > And finally, no cc: stable in the s-o-b area for an issue that needs to
> > be backported to older kernels?
>
>
> Will update the patch.
>
>
> >
> > > ---
> > > drivers/dma-buf/dma-buf.c | 25 +++++++++++++++++++++++--
> > > include/linux/dma-buf.h | 1 +
> > > 2 files changed, 24 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> > > index 570c923..069d8f78 100644
> > > --- a/drivers/dma-buf/dma-buf.c
> > > +++ b/drivers/dma-buf/dma-buf.c
> > > @@ -25,6 +25,7 @@
> > > #include <linux/mm.h>
> > > #include <linux/mount.h>
> > > #include <linux/pseudo_fs.h>
> > > +#include <linux/dcache.h>
> > > #include <uapi/linux/dma-buf.h>
> > > #include <uapi/linux/magic.h>
> > > @@ -38,18 +39,34 @@ struct dma_buf_list {
> > > static struct dma_buf_list db_list;
> > > +static void dmabuf_dent_put(struct dma_buf *dmabuf)
> > > +{
> > > + if (atomic_dec_and_test(&dmabuf->dent_count)) {
> > > + kfree(dmabuf->name);
> > > + kfree(dmabuf);
> > > + }
> > Why not just use a kref instead of an open-coded atomic value?
>
>
> Kref approach looks cleaner. will update the patch accordingly.
>
>
> > > +}
> > > +
> > > static char *dmabuffs_dname(struct dentry *dentry, char *buffer, int buflen)
> > > {
> > > struct dma_buf *dmabuf;
> > > char name[DMA_BUF_NAME_LEN];
> > > size_t ret = 0;
> > > + spin_lock(&dentry->d_lock);
> > > dmabuf = dentry->d_fsdata;
> > > + if (!dmabuf || !atomic_add_unless(&dmabuf->dent_count, 1, 0)) {
> > > + spin_unlock(&dentry->d_lock);
> > > + goto out;
> > How can dmabuf not be valid here?
> >
> > And isn't there already a usecount for the buffer?
>
>
> dmabuf exported as file simply relies on that file's refcount, thus fput()
> releases the dmabuf.
>
> We are storing the dmabuf in the dentry->d_fsdata but there is no binding
> between the dentry and the dmabuf. So, flow will be like
>
> 1) P1 calls fput(dmabuf_fd)
>
> 2) P2 trying to access the file information of P1.
> Eg: lsof command trying to list out the dmabuf_fd information using
> /proc/<P1 pid>/fd/dmabuf_fd
>
> 3) P1 calls the file->f_op->release(dmabuf_fd_file)(ends up in calling
> dma_buf_release()), thus frees up the dmabuf buffer.
>
> 4) P2 access the dmabuf stored in the dentry->d_fsdata which was freed in
> step 3.
>
> So we need to have some refcount mechanism to avoid the use-after-free in
> step 4.
Ok, but watch out, now you have 2 different reference counts for the
same structure. Keeping them coordinated is almost always an impossible
task so you need to only rely on one. If you can't use the file api,
just drop all of the reference counting logic in there and only use the
kref one.
good luck!
greg k-h
From: Daniel Vetter <daniel.vetter(a)intel.com>
commit a5bff92eaac45bdf6221badf9505c26792fdf99e upstream.
The uapi is the same on 32 and 64 bit, but the number isn't. Everyone
who botched this please re-read:
https://www.kernel.org/doc/html/v5.4-preprc-cpu/ioctl/botching-up-ioctls.ht…
Also, the type argument for the ioctl macros is for the type the void
__user *arg pointer points at, which in this case would be the
variable-sized char[] of a 0 terminated string. So this was botched in
more than just the usual ways.
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: Chenbo Feng <fengc(a)google.com>
Cc: Greg Hackmann <ghackmann(a)google.com>
Cc: Daniel Vetter <daniel.vetter(a)ffwll.ch>
Cc: linux-media(a)vger.kernel.org
Cc: linaro-mm-sig(a)lists.linaro.org
Cc: minchan(a)kernel.org
Cc: surenb(a)google.com
Cc: jenhaochen(a)google.com
Cc: Martin Liu <liumartin(a)google.com>
Signed-off-by: Daniel Vetter <daniel.vetter(a)intel.com>
Tested-by: Martin Liu <liumartin(a)google.com>
Reviewed-by: Martin Liu <liumartin(a)google.com>
Signed-off-by: Sumit Semwal <sumit.semwal(a)linaro.org>
[sumits: updated some checkpatch fixes, corrected author email]
Link: https://patchwork.freedesktop.org/patch/msgid/20200407133002.3486387-1-dani…
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/dma-buf.c | 3 ++-
include/uapi/linux/dma-buf.h | 6 ++++++
2 files changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -388,7 +388,8 @@ static long dma_buf_ioctl(struct file *f
return ret;
- case DMA_BUF_SET_NAME:
+ case DMA_BUF_SET_NAME_A:
+ case DMA_BUF_SET_NAME_B:
return dma_buf_set_name(dmabuf, (const char __user *)arg);
default:
--- a/include/uapi/linux/dma-buf.h
+++ b/include/uapi/linux/dma-buf.h
@@ -39,6 +39,12 @@ struct dma_buf_sync {
#define DMA_BUF_BASE 'b'
#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
+
+/* 32/64bitness of this uapi was botched in android, there's no difference
+ * between them in actual uapi, they're just different numbers.
+ */
#define DMA_BUF_SET_NAME _IOW(DMA_BUF_BASE, 1, const char *)
+#define DMA_BUF_SET_NAME_A _IOW(DMA_BUF_BASE, 1, u32)
+#define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, u64)
#endif
From: Daniel Vetter <daniel.vetter(a)intel.com>
commit a5bff92eaac45bdf6221badf9505c26792fdf99e upstream.
The uapi is the same on 32 and 64 bit, but the number isn't. Everyone
who botched this please re-read:
https://www.kernel.org/doc/html/v5.4-preprc-cpu/ioctl/botching-up-ioctls.ht…
Also, the type argument for the ioctl macros is for the type the void
__user *arg pointer points at, which in this case would be the
variable-sized char[] of a 0 terminated string. So this was botched in
more than just the usual ways.
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: Chenbo Feng <fengc(a)google.com>
Cc: Greg Hackmann <ghackmann(a)google.com>
Cc: Daniel Vetter <daniel.vetter(a)ffwll.ch>
Cc: linux-media(a)vger.kernel.org
Cc: linaro-mm-sig(a)lists.linaro.org
Cc: minchan(a)kernel.org
Cc: surenb(a)google.com
Cc: jenhaochen(a)google.com
Cc: Martin Liu <liumartin(a)google.com>
Signed-off-by: Daniel Vetter <daniel.vetter(a)intel.com>
Tested-by: Martin Liu <liumartin(a)google.com>
Reviewed-by: Martin Liu <liumartin(a)google.com>
Signed-off-by: Sumit Semwal <sumit.semwal(a)linaro.org>
[sumits: updated some checkpatch fixes, corrected author email]
Link: https://patchwork.freedesktop.org/patch/msgid/20200407133002.3486387-1-dani…
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/dma-buf.c | 3 ++-
include/uapi/linux/dma-buf.h | 6 ++++++
2 files changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -388,7 +388,8 @@ static long dma_buf_ioctl(struct file *f
return ret;
- case DMA_BUF_SET_NAME:
+ case DMA_BUF_SET_NAME_A:
+ case DMA_BUF_SET_NAME_B:
return dma_buf_set_name(dmabuf, (const char __user *)arg);
default:
--- a/include/uapi/linux/dma-buf.h
+++ b/include/uapi/linux/dma-buf.h
@@ -39,6 +39,12 @@ struct dma_buf_sync {
#define DMA_BUF_BASE 'b'
#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
+
+/* 32/64bitness of this uapi was botched in android, there's no difference
+ * between them in actual uapi, they're just different numbers.
+ */
#define DMA_BUF_SET_NAME _IOW(DMA_BUF_BASE, 1, const char *)
+#define DMA_BUF_SET_NAME_A _IOW(DMA_BUF_BASE, 1, u32)
+#define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, u64)
#endif
Dear All,
During the Exynos DRM GEM rework and fixing the issues in the
drm_prime_sg_to_page_addr_arrays() function [1] I've noticed that most
drivers in DRM framework incorrectly use nents and orig_nents entries of
the struct sg_table.
In case of the most DMA-mapping implementations exchanging those two
entries or using nents for all loops on the scatterlist is harmless,
because they both have the same value. There exists however a DMA-mapping
implementations, for which such incorrect usage breaks things. The nents
returned by dma_map_sg() might be lower than the nents passed as its
parameter and this is perfectly fine. DMA framework or IOMMU is allowed
to join consecutive chunks while mapping if such operation is supported
by the underlying HW (bus, bridge, IOMMU, etc). Example of the case
where dma_map_sg() might return 1 'DMA' chunk for the 4 'physical' pages
is described here [2]
The DMA-mapping framework documentation [3] states that dma_map_sg()
returns the numer of the created entries in the DMA address space.
However the subsequent calls to dma_sync_sg_for_{device,cpu} and
dma_unmap_sg must be called with the original number of entries passed to
dma_map_sg. The common pattern in DRM drivers were to assign the
dma_map_sg() return value to sg_table->nents and use that value for
the subsequent calls to dma_sync_sg_* or dma_unmap_sg functions. Also
the code iterated over nents times to access the pages stored in the
processed scatterlist, while it should use orig_nents as the numer of
the page entries.
I've tried to identify all such incorrect usage of sg_table->nents and
this is a result of my research. It looks that the incorrect pattern has
been copied over the many drivers mainly in the DRM subsystem. Too bad in
most cases it even worked correctly if the system used simple,
linear DMA-mapping implementation, for which swapping nents and
orig_nents doesn't make any difference.
The biggest TODO is DRM/i915 driver and I don't feel brave enough to fix
it fully. The driver creatively uses sg_table->orig_nents to store the
size of the allocate scatterlist and ignores the number of the entries
returned by dma_map_sg function. In this patchset I only fixed the
sg_table objects exported by dmabuf related functions. I hope that I
didn't break anything there.
As a follow-up for this patchset I will prepare a common
dma_{map,sync,unmap}_sgtable() wrappers, which will use a proper sg_table
entries and call respective DMA-mapping functions. I hope this will help
to avoid issue like this in the future.
Patches are based on top of Linux next-20200504.
Best regards,
Marek Szyprowski
References:
[1] https://lkml.org/lkml/2020/3/27/555
[2] https://lkml.org/lkml/2020/3/29/65
[3] Documentation/DMA-API-HOWTO.txt
Changelog:
v2:
- dropped most of the changes to drm/i915
- added fixes for rcar-du, xen, media and ion
- fixed a few issues pointed by kbuild test robot
- added wide cc: list for each patch
v1: https://lore.kernel.org/linux-iommu/c01c9766-9778-fd1f-f36e-2dc7bd376ba4@ar…
- initial version
Patch summary:
Marek Szyprowski (21):
drm: core: fix sg_table nents vs. orig_nents misuse
drm: amdgpu: fix sg_table nents vs. orig_nents misuse
drm: armada: fix sg_table nents vs. orig_nents misuse
drm: etnaviv: fix sg_table nents vs. orig_nents misuse
drm: exynos: fix sg_table nents vs. orig_nents misuse
drm: i915: fix sg_table nents vs. orig_nents misuse for dmabuf objects
drm: lima: fix sg_table nents vs. orig_nents misuse
drm: msm: fix sg_table nents vs. orig_nents misuse
drm: panfrost: fix sg_table nents vs. orig_nents misuse
drm: radeon: fix sg_table nents vs. orig_nents misuse
drm: rockchip: fix sg_table nents vs. orig_nents misuse
drm: tegra: fix sg_table nents vs. orig_nents misuse
drm: virtio: fix sg_table nents vs. orig_nents misuse
drm: vmwgfx: fix sg_table nents vs. orig_nents misuse
drm: xen: fix sg_table nents vs. orig_nents misuse
drm: host1x: fix sg_table nents vs. orig_nents misuse
drm: rcar-du: fix sg_table nents vs. orig_nents misuse
xen: gntdev: fix sg_table nents vs. orig_nents misuse
dmabuf: fix sg_table nents vs. orig_nents misuse
media: pci: fix common ALSA DMA-mapping related code
staging: ion: fix sg_table nents vs. orig_nents misuse
drivers/dma-buf/heaps/heap-helpers.c | 7 ++++---
drivers/dma-buf/udmabuf.c | 5 +++--
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 7 ++++---
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 8 ++++----
drivers/gpu/drm/armada/armada_gem.c | 14 ++++++++-----
drivers/gpu/drm/drm_cache.c | 2 +-
drivers/gpu/drm/drm_gem_shmem_helper.c | 7 ++++---
drivers/gpu/drm/drm_prime.c | 9 +++++----
drivers/gpu/drm/etnaviv/etnaviv_gem.c | 10 ++++++----
drivers/gpu/drm/exynos/exynos_drm_g2d.c | 7 ++++---
drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 9 +++++----
drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c | 5 +++--
drivers/gpu/drm/lima/lima_gem.c | 4 ++--
drivers/gpu/drm/msm/msm_gem.c | 8 ++++----
drivers/gpu/drm/msm/msm_iommu.c | 3 ++-
drivers/gpu/drm/panfrost/panfrost_gem.c | 3 ++-
drivers/gpu/drm/panfrost/panfrost_mmu.c | 4 +++-
drivers/gpu/drm/radeon/radeon_ttm.c | 11 ++++++-----
drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 15 +++++++-------
drivers/gpu/drm/tegra/gem.c | 25 ++++++++++++------------
drivers/gpu/drm/tegra/plane.c | 13 ++++++------
drivers/gpu/drm/virtio/virtgpu_object.c | 11 ++++++-----
drivers/gpu/drm/virtio/virtgpu_vq.c | 8 ++++----
drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 6 +++---
drivers/gpu/drm/xen/xen_drm_front_gem.c | 2 +-
drivers/gpu/host1x/job.c | 17 ++++++++--------
drivers/media/pci/cx23885/cx23885-alsa.c | 2 +-
drivers/media/pci/cx25821/cx25821-alsa.c | 2 +-
drivers/media/pci/cx88/cx88-alsa.c | 2 +-
drivers/media/pci/saa7134/saa7134-alsa.c | 2 +-
drivers/media/platform/vsp1/vsp1_drm.c | 7 ++++---
drivers/staging/android/ion/ion.c | 17 ++++++++--------
drivers/staging/android/ion/ion_heap.c | 6 +++---
drivers/staging/android/ion/ion_system_heap.c | 2 +-
drivers/xen/gntdev-dmabuf.c | 10 ++++++----
35 files changed, 149 insertions(+), 121 deletions(-)
--
1.9.1
This is a note to let you know that I've just added the patch titled
dma-buf: Fix SET_NAME ioctl uapi
to the 5.6-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-buf-fix-set_name-ioctl-uapi.patch
and it can be found in the queue-5.6 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 a5bff92eaac45bdf6221badf9505c26792fdf99e Mon Sep 17 00:00:00 2001
From: Daniel Vetter <daniel.vetter(a)intel.com>
Date: Tue, 7 Apr 2020 15:30:02 +0200
Subject: dma-buf: Fix SET_NAME ioctl uapi
From: Daniel Vetter <daniel.vetter(a)intel.com>
commit a5bff92eaac45bdf6221badf9505c26792fdf99e upstream.
The uapi is the same on 32 and 64 bit, but the number isn't. Everyone
who botched this please re-read:
https://www.kernel.org/doc/html/v5.4-preprc-cpu/ioctl/botching-up-ioctls.ht…
Also, the type argument for the ioctl macros is for the type the void
__user *arg pointer points at, which in this case would be the
variable-sized char[] of a 0 terminated string. So this was botched in
more than just the usual ways.
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: Chenbo Feng <fengc(a)google.com>
Cc: Greg Hackmann <ghackmann(a)google.com>
Cc: Daniel Vetter <daniel.vetter(a)ffwll.ch>
Cc: linux-media(a)vger.kernel.org
Cc: linaro-mm-sig(a)lists.linaro.org
Cc: minchan(a)kernel.org
Cc: surenb(a)google.com
Cc: jenhaochen(a)google.com
Cc: Martin Liu <liumartin(a)google.com>
Signed-off-by: Daniel Vetter <daniel.vetter(a)intel.com>
Tested-by: Martin Liu <liumartin(a)google.com>
Reviewed-by: Martin Liu <liumartin(a)google.com>
Signed-off-by: Sumit Semwal <sumit.semwal(a)linaro.org>
[sumits: updated some checkpatch fixes, corrected author email]
Link: https://patchwork.freedesktop.org/patch/msgid/20200407133002.3486387-1-dani…
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/dma-buf.c | 3 ++-
include/uapi/linux/dma-buf.h | 6 ++++++
2 files changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -388,7 +388,8 @@ static long dma_buf_ioctl(struct file *f
return ret;
- case DMA_BUF_SET_NAME:
+ case DMA_BUF_SET_NAME_A:
+ case DMA_BUF_SET_NAME_B:
return dma_buf_set_name(dmabuf, (const char __user *)arg);
default:
--- a/include/uapi/linux/dma-buf.h
+++ b/include/uapi/linux/dma-buf.h
@@ -39,6 +39,12 @@ struct dma_buf_sync {
#define DMA_BUF_BASE 'b'
#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
+
+/* 32/64bitness of this uapi was botched in android, there's no difference
+ * between them in actual uapi, they're just different numbers.
+ */
#define DMA_BUF_SET_NAME _IOW(DMA_BUF_BASE, 1, const char *)
+#define DMA_BUF_SET_NAME_A _IOW(DMA_BUF_BASE, 1, u32)
+#define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, u64)
#endif
Patches currently in stable-queue which might be from daniel.vetter(a)intel.com are
queue-5.6/dma-buf-fix-set_name-ioctl-uapi.patch
This is a note to let you know that I've just added the patch titled
dma-buf: Fix SET_NAME ioctl uapi
to the 5.4-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-buf-fix-set_name-ioctl-uapi.patch
and it can be found in the queue-5.4 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 a5bff92eaac45bdf6221badf9505c26792fdf99e Mon Sep 17 00:00:00 2001
From: Daniel Vetter <daniel.vetter(a)intel.com>
Date: Tue, 7 Apr 2020 15:30:02 +0200
Subject: dma-buf: Fix SET_NAME ioctl uapi
From: Daniel Vetter <daniel.vetter(a)intel.com>
commit a5bff92eaac45bdf6221badf9505c26792fdf99e upstream.
The uapi is the same on 32 and 64 bit, but the number isn't. Everyone
who botched this please re-read:
https://www.kernel.org/doc/html/v5.4-preprc-cpu/ioctl/botching-up-ioctls.ht…
Also, the type argument for the ioctl macros is for the type the void
__user *arg pointer points at, which in this case would be the
variable-sized char[] of a 0 terminated string. So this was botched in
more than just the usual ways.
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: Chenbo Feng <fengc(a)google.com>
Cc: Greg Hackmann <ghackmann(a)google.com>
Cc: Daniel Vetter <daniel.vetter(a)ffwll.ch>
Cc: linux-media(a)vger.kernel.org
Cc: linaro-mm-sig(a)lists.linaro.org
Cc: minchan(a)kernel.org
Cc: surenb(a)google.com
Cc: jenhaochen(a)google.com
Cc: Martin Liu <liumartin(a)google.com>
Signed-off-by: Daniel Vetter <daniel.vetter(a)intel.com>
Tested-by: Martin Liu <liumartin(a)google.com>
Reviewed-by: Martin Liu <liumartin(a)google.com>
Signed-off-by: Sumit Semwal <sumit.semwal(a)linaro.org>
[sumits: updated some checkpatch fixes, corrected author email]
Link: https://patchwork.freedesktop.org/patch/msgid/20200407133002.3486387-1-dani…
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/dma-buf.c | 3 ++-
include/uapi/linux/dma-buf.h | 6 ++++++
2 files changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -388,7 +388,8 @@ static long dma_buf_ioctl(struct file *f
return ret;
- case DMA_BUF_SET_NAME:
+ case DMA_BUF_SET_NAME_A:
+ case DMA_BUF_SET_NAME_B:
return dma_buf_set_name(dmabuf, (const char __user *)arg);
default:
--- a/include/uapi/linux/dma-buf.h
+++ b/include/uapi/linux/dma-buf.h
@@ -39,6 +39,12 @@ struct dma_buf_sync {
#define DMA_BUF_BASE 'b'
#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
+
+/* 32/64bitness of this uapi was botched in android, there's no difference
+ * between them in actual uapi, they're just different numbers.
+ */
#define DMA_BUF_SET_NAME _IOW(DMA_BUF_BASE, 1, const char *)
+#define DMA_BUF_SET_NAME_A _IOW(DMA_BUF_BASE, 1, u32)
+#define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, u64)
#endif
Patches currently in stable-queue which might be from daniel.vetter(a)intel.com are
queue-5.4/dma-buf-fix-set_name-ioctl-uapi.patch
On 4/29/20 6:59 PM, Vitor Massaru Iha wrote:
> Add missed ":" on kernel-doc function parameter.
>
> This patch fixes this warnings from `make htmldocs`:
> ./drivers/dma-buf/dma-buf.c:678: warning: Function parameter or member 'importer_ops' not described in 'dma_buf_dynamic_attach'
> ./drivers/dma-buf/dma-buf.c:678: warning: Function parameter or member 'importer_priv' not described in 'dma_buf_dynamic_attach'
>
> Signed-off-by: Vitor Massaru Iha <vitor(a)massaru.org>
> ---
> drivers/dma-buf/dma-buf.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index ccc9eda1bc28..0756d2155745 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c
> @@ -655,8 +655,8 @@ EXPORT_SYMBOL_GPL(dma_buf_put);
> * calls attach() of dma_buf_ops to allow device-specific attach functionality
> * @dmabuf: [in] buffer to attach device to.
> * @dev: [in] device to be attached.
> - * @importer_ops [in] importer operations for the attachment
> - * @importer_priv [in] importer private pointer for the attachment
> + * @importer_ops: [in] importer operations for the attachment
> + * @importer_priv: [in] importer private pointer for the attachment
> *
> * Returns struct dma_buf_attachment pointer for this attachment. Attachments
> * must be cleaned up by calling dma_buf_detach().
>
Sumit said that he would be applying my patch from April 7:
https://lore.kernel.org/linux-media/7bcbe6fe-0b4b-87da-d003-b68a26eb4cf0@in…
thanks.
--
~Randy
Dear All,
During the Exynos DRM GEM rework and fixing the issues in the
drm_prime_sg_to_page_addr_arrays() function [1] I've noticed that most
drivers in DRM framework incorrectly use nents and orig_nents entries of
the struct sg_table.
In case of the most DMA-mapping implementations exchanging those two
entries or using nents for all loops on the scatterlist is harmless,
because they both have the same value. There exists however a DMA-mapping
implementations, for which such incorrect usage breaks things. The nents
returned by dma_map_sg() might be lower than the nents passed as its
parameter and this is perfectly fine. DMA framework or IOMMU is allowed
to join consecutive chunks while mapping if such operation is supported
by the underlying HW (bus, bridge, IOMMU, etc). Example of the case
where dma_map_sg() might return 1 'DMA' chunk for the 4 'physical' pages
is described here [2]
The DMA-mapping framework documentation [3] states that dma_map_sg()
returns the numer of the created entries in the DMA address space.
However the subsequent calls to dma_sync_sg_for_{device,cpu} and
dma_unmap_sg must be called with the original number of entries passed to
dma_map_sg. The common pattern in DRM drivers were to assign the
dma_map_sg() return value to sg_table->nents and use that value for
the subsequent calls to dma_sync_sg_* or dma_unmap_sg functions. Also
the code iterated over nents times to access the pages stored in the
processed scatterlist, while it should use orig_nents as the numer of
the page entries.
I've tried to identify all such incorrect usage of sg_table->nents in the
DRM subsystem and this is a result of my research. It looks that the
incorrect pattern has been copied over the many drivers. Too bad in most
cases it even worked correctly if the system used simple, linear
DMA-mapping implementation, for which swapping nents and orig_nents
doesn't make any difference.
I wonder what to do to avoid such misuse in the future, as this case
clearly shows that the current sg_table structure is a bit hard to
understand. I have the following ideas and I would like to know your
opinion before I prepare more patches and check sg_table usage all over
the kernel:
1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
a proper sg_table entries and call respective DMA-mapping functions
and adapt current code to it
2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
which one refers to which part of the scatterlist; I'm open for
other names for those entries
I will appreciate your comments.
Patches are based on top of Linux next-20200428. I've reduced the
recipients list mainly to mailing lists, the next version I will try to
send to the maintainers of the respective drivers.
Best regards,
Marek Szyprowski
References:
[1] https://lkml.org/lkml/2020/3/27/555
[2] https://lkml.org/lkml/2020/3/29/65
[3] Documentation/DMA-API-HOWTO.txt
Patch summary:
Marek Szyprowski (17):
drm: core: fix sg_table nents vs. orig_nents usage
drm: amdgpu: fix sg_table nents vs. orig_nents usage
drm: armada: fix sg_table nents vs. orig_nents usage
drm: etnaviv: fix sg_table nents vs. orig_nents usage
drm: exynos: fix sg_table nents vs. orig_nents usage
drm: i915: fix sg_table nents vs. orig_nents usage
drm: lima: fix sg_table nents vs. orig_nents usage
drm: msm: fix sg_table nents vs. orig_nents usage
drm: panfrost: fix sg_table nents vs. orig_nents usage
drm: radeon: fix sg_table nents vs. orig_nents usage
drm: rockchip: fix sg_table nents vs. orig_nents usage
drm: tegra: fix sg_table nents vs. orig_nents usage
drm: virtio: fix sg_table nents vs. orig_nents usage
drm: vmwgfx: fix sg_table nents vs. orig_nents usage
drm: xen: fix sg_table nents vs. orig_nents usage
drm: host1x: fix sg_table nents vs. orig_nents usage
dmabuf: fix sg_table nents vs. orig_nents usage
drivers/dma-buf/heaps/heap-helpers.c | 7 ++++---
drivers/dma-buf/udmabuf.c | 5 +++--
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 7 ++++---
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 8 ++++----
drivers/gpu/drm/armada/armada_gem.c | 14 ++++++++-----
drivers/gpu/drm/drm_cache.c | 2 +-
drivers/gpu/drm/drm_gem_shmem_helper.c | 7 ++++---
drivers/gpu/drm/drm_prime.c | 9 +++++----
drivers/gpu/drm/etnaviv/etnaviv_gem.c | 10 ++++++----
drivers/gpu/drm/exynos/exynos_drm_g2d.c | 7 ++++---
drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 13 ++++++------
drivers/gpu/drm/i915/gem/i915_gem_internal.c | 4 ++--
drivers/gpu/drm/i915/gem/i915_gem_region.c | 4 ++--
drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 5 +++--
drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 10 +++++-----
drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c | 5 +++--
drivers/gpu/drm/i915/gt/intel_ggtt.c | 12 ++++++------
drivers/gpu/drm/i915/i915_gem_gtt.c | 12 +++++++-----
drivers/gpu/drm/i915/i915_scatterlist.c | 4 ++--
drivers/gpu/drm/i915/selftests/scatterlist.c | 8 ++++----
drivers/gpu/drm/lima/lima_gem.c | 4 ++--
drivers/gpu/drm/msm/msm_gem.c | 8 ++++----
drivers/gpu/drm/msm/msm_iommu.c | 3 ++-
drivers/gpu/drm/panfrost/panfrost_gem.c | 3 ++-
drivers/gpu/drm/panfrost/panfrost_mmu.c | 4 +++-
drivers/gpu/drm/radeon/radeon_ttm.c | 10 +++++-----
drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 15 +++++++-------
drivers/gpu/drm/tegra/gem.c | 25 ++++++++++++------------
drivers/gpu/drm/tegra/plane.c | 13 ++++++------
drivers/gpu/drm/virtio/virtgpu_object.c | 11 ++++++-----
drivers/gpu/drm/virtio/virtgpu_vq.c | 8 ++++----
drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 6 +++---
drivers/gpu/drm/xen/xen_drm_front_gem.c | 2 +-
drivers/gpu/host1x/job.c | 17 ++++++++--------
34 files changed, 154 insertions(+), 128 deletions(-)
--
1.9.1
The uapi is the same on 32 and 64 bit, but the number isnt. Everyone
who botched this please re-read:
https://www.kernel.org/doc/html/v5.4-preprc-cpu/ioctl/botching-up-ioctls.ht…
Also, the type argument for the ioctl macros is for the type the void
__user *arg pointer points at, which in this case would be the
variable-sized char[] of a 0 terminated string. So this was botched in
more than just the usual ways.
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: Chenbo Feng <fengc(a)google.com>
Cc: Greg Hackmann <ghackmann(a)google.com>
Cc: Daniel Vetter <daniel.vetter(a)ffwll.ch>
Cc: linux-media(a)vger.kernel.org
Cc: linaro-mm-sig(a)lists.linaro.org
Cc: minchan(a)kernel.org
Cc: surenb(a)google.com
Cc: jenhaochen(a)google.com
Cc: Martin Liu <liumartin(a)google.com>
Signed-off-by: Daniel Vetter <daniel.vetter(a)intel.com>
---
drivers/dma-buf/dma-buf.c | 3 ++-
include/uapi/linux/dma-buf.h | 4 ++++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 570c923023e6..1d923b8e4c59 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -388,7 +388,8 @@ static long dma_buf_ioctl(struct file *file,
return ret;
- case DMA_BUF_SET_NAME:
+ case DMA_BUF_SET_NAME_A:
+ case DMA_BUF_SET_NAME_B:
return dma_buf_set_name(dmabuf, (const char __user *)arg);
default:
diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h
index dbc7092e04b5..21dfac815dc0 100644
--- a/include/uapi/linux/dma-buf.h
+++ b/include/uapi/linux/dma-buf.h
@@ -39,6 +39,10 @@ struct dma_buf_sync {
#define DMA_BUF_BASE 'b'
#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
+/* 32/64bitness of this uapi was botched in android, there's no difference
+ * between them in actual uapi, they're just different numbers. */
#define DMA_BUF_SET_NAME _IOW(DMA_BUF_BASE, 1, const char *)
+#define DMA_BUF_SET_NAME_A _IOW(DMA_BUF_BASE, 1, u32)
+#define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, u64)
#endif
--
2.25.1
On Fri, Apr 24, 2020 at 3:18 PM Andrew F. Davis <afd(a)ti.com> wrote:
>
> Some clients of DMA-Heaps probe earlier than subsys_initcall(), this
> can cause issues when these clients call dma_heap_add() before the
> core DMA-Heaps framework has initialized. DMA-Heaps should initialize
> during core startup to get ahead of all users.
>
> Signed-off-by: Andrew F. Davis <afd(a)ti.com>
No objection from me right off.
Acked-by: John Stultz <john.stultz(a)linaro.org>
thanks
-john
Hi all,
Peter noticed that with some dumb luck you can toast the kernel address
space with exported vmalloc symbols.
I used this as an opportunity to decruft the vmalloc.c API and make it
much more systematic. This also removes any chance to create vmalloc
mappings outside the designated areas or using executable permissions
from modules. Besides that it removes more than 300 lines of code.
A git tree is also available here:
git://git.infradead.org/users/hch/misc.git sanitize-vmalloc-api.2
Gitweb:
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/sanitize-vm…
Changes since v1:
- implement pgprot_nx for arm64 (Mark Rutland)
- fix a patch description
- properly pass pgprot to vmap in ion
- add a new patch to fix vmap() API misuse
- fix a vmap argument in x86
- two more vmalloc cleanups
- cleanup use of the unmap_kernel_range API
- rename ioremap_pbh to ioremap_phb
Only sync the sg-list of an Ion dma-buf attachment when the attachment
is actually mapped on the device.
dma-bufs may be synced at any time. It can be reached from user space
via DMA_BUF_IOCTL_SYNC, so there are no guarantees from callers on when
syncs may be attempted, and dma_buf_end_cpu_access() and
dma_buf_begin_cpu_access() may not be paired.
Since the sg_list's dma_address isn't set up until the buffer is used
on the device, and dma_map_sg() is called on it, the dma_address will be
NULL if sync is attempted on the dma-buf before it's mapped on a device.
Before v5.0 (commit 55897af63091 ("dma-direct: merge swiotlb_dma_ops
into the dma_direct code")) this was a problem as the dma-api (at least
the swiotlb_dma_ops on arm64) would use the potentially invalid
dma_address. How that failed depended on how the device handled physical
address 0. If 0 was a valid address to physical ram, that page would get
flushed a lot, while the actual pages in the buffer would not get synced
correctly. While if 0 is an invalid physical address it may cause a
fault and trigger a crash.
In v5.0 this was incidentally fixed by commit 55897af63091 ("dma-direct:
merge swiotlb_dma_ops into the dma_direct code"), as this moved the
dma-api to use the page pointer in the sg_list, and (for Ion buffers at
least) this will always be valid if the sg_list exists at all.
But, this issue is re-introduced in v5.3 with
commit 449fa54d6815 ("dma-direct: correct the physical addr in
dma_direct_sync_sg_for_cpu/device") moves the dma-api back to the old
behaviour and picks the dma_address that may be invalid.
dma-buf core doesn't ensure that the buffer is mapped on the device, and
thus have a valid sg_list, before calling the exporter's
begin_cpu_access.
Signed-off-by: Ørjan Eide <orjan.eide(a)arm.com>
---
drivers/staging/android/ion/ion.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
This seems to be part of a bigger issue where dma-buf exporters assume
that their dma-buf begin_cpu_access and end_cpu_access callbacks have a
certain guaranteed behavior, which isn't ensured by dma-buf core.
This patch fixes this in ion only, but it also needs to be fixed for
other exporters, either handled like this in each exporter, or in
dma-buf core before calling into the exporters.
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 38b51eace4f9..7b752ba0cb6d 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -173,6 +173,7 @@ struct ion_dma_buf_attachment {
struct device *dev;
struct sg_table *table;
struct list_head list;
+ bool mapped:1;
};
static int ion_dma_buf_attach(struct dma_buf *dmabuf,
@@ -195,6 +196,7 @@ static int ion_dma_buf_attach(struct dma_buf *dmabuf,
a->table = table;
a->dev = attachment->dev;
INIT_LIST_HEAD(&a->list);
+ a->mapped = false;
attachment->priv = a;
@@ -231,6 +233,8 @@ static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment,
direction))
return ERR_PTR(-ENOMEM);
+ a->mapped = true;
+
return table;
}
@@ -238,6 +242,10 @@ static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment,
struct sg_table *table,
enum dma_data_direction direction)
{
+ struct ion_dma_buf_attachment *a = attachment->priv;
+
+ a->mapped = false;
+
dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction);
}
@@ -297,6 +305,8 @@ static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
mutex_lock(&buffer->lock);
list_for_each_entry(a, &buffer->attachments, list) {
+ if (!a->mapped)
+ continue;
dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents,
direction);
}
@@ -320,6 +330,8 @@ static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
mutex_lock(&buffer->lock);
list_for_each_entry(a, &buffer->attachments, list) {
+ if (!a->mapped)
+ continue;
dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents,
direction);
}
--
2.17.1
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
Hi Sergey,
On Fri, Apr 10, 2020 at 11:38:45AM +0900, Sergey Senozhatsky wrote:
> On (20/04/09 10:08), Minchan Kim wrote:
> > > > Even though I don't know how many usecase we have using zsmalloc as
> > > > module(I heard only once by dumb reason), it could affect existing
> > > > users. Thus, please include concrete explanation in the patch to
> > > > justify when the complain occurs.
> > >
> > > The justification is 'we can unexport functions that have no sane reason
> > > of being exported in the first place'.
> > >
> > > The Changelog pretty much says that.
> >
> > Okay, I hope there is no affected user since this patch.
> > If there are someone, they need to provide sane reason why they want
> > to have zsmalloc as module.
>
> I'm one of those who use zsmalloc as a module - mainly because I use zram
> as a compressing general purpose block device, not as a swap device.
> I create zram0, mkfs, mount, checkout and compile code, once done -
> umount, rmmod. This reduces the number of writes to SSD. Some people use
> tmpfs, but zram device(-s) can be much larger in size. That's a niche use
> case and I'm not against the patch.
It doesn't mean we couldn't use zsmalloc as module any longer. It means
we couldn't use zsmalloc as module with pgtable mapping whcih was little
bit faster on microbenchmark in some architecutre(However, I usually temped
to remove it since it had several problems). However, we could still use
zsmalloc as module as copy way instead of pgtable mapping. Thus, if someone
really want to rollback the feature, they should provide reasonable reason
why it doesn't work for them. "A little fast" wouldn't be enough to exports
deep internal to the module.
Thanks.
Hi all,
Peter noticed that with some dumb luck you can toast the kernel address
space with exported vmalloc symbols.
I used this as an opportunity to decruft the vmalloc.c API and make it
much more systematic. This also removes any chance to create vmalloc
mappings outside the designated areas or using executable permissions
from modules. Besides that it removes more than 300 lines of code.
A git tree is also available here:
git://git.infradead.org/users/hch/misc.git sanitize-vmalloc-api
Gitweb:
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/sanitize-vm…