This is a note to let you know that I've just added the patch titled
dmaengine: virt-dma: Support for race free transfer termination
to the 4.15-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:
dmaengine-virt-dma-support-for-race-free-transfer-termination.patch
and it can be found in the queue-4.15 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 1c7f072d94e8b697fd9b70cdb268622a18faf522 Mon Sep 17 00:00:00 2001
From: Peter Ujfalusi <peter.ujfalusi(a)ti.com>
Date: Tue, 14 Nov 2017 16:32:04 +0200
Subject: dmaengine: virt-dma: Support for race free transfer termination
From: Peter Ujfalusi <peter.ujfalusi(a)ti.com>
commit 1c7f072d94e8b697fd9b70cdb268622a18faf522 upstream.
Even with the introduced vchan_synchronize() we can face race when
terminating a cyclic transfer.
If the terminate_all is called after the interrupt handler called
vchan_cyclic_callback(), but before the vchan_complete tasklet is called:
vc->cyclic is set to the cyclic descriptor, but the descriptor itself was
freed up in the driver's terminate_all() callback.
When the vhan_complete() is executed it will try to fetch the vc->cyclic
vdesc, but the pointer is pointing now to uninitialized memory leading to
(hard to reproduce) kernel crash.
In order to fix this, drivers should:
- call vchan_terminate_vdesc() from their terminate_all callback instead
calling their free_desc function to free up the descriptor.
- implement device_synchronize callback and call vchan_synchronize().
This way we can make sure that the descriptor is only going to be freed up
after the vchan_callback was executed in a safe manner.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi(a)ti.com>
Reviewed-by: Linus Walleij <linus.walleij(a)linaro.org>
Signed-off-by: Vinod Koul <vinod.koul(a)intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma/virt-dma.h | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
--- a/drivers/dma/virt-dma.h
+++ b/drivers/dma/virt-dma.h
@@ -35,6 +35,7 @@ struct virt_dma_chan {
struct list_head desc_completed;
struct virt_dma_desc *cyclic;
+ struct virt_dma_desc *vd_terminated;
};
static inline struct virt_dma_chan *to_virt_chan(struct dma_chan *chan)
@@ -116,6 +117,25 @@ static inline void vchan_cyclic_callback
}
/**
+ * vchan_terminate_vdesc - Disable pending cyclic callback
+ * @vd: virtual descriptor to be terminated
+ *
+ * vc.lock must be held by caller
+ */
+static inline void vchan_terminate_vdesc(struct virt_dma_desc *vd)
+{
+ struct virt_dma_chan *vc = to_virt_chan(vd->tx.chan);
+
+ /* free up stuck descriptor */
+ if (vc->vd_terminated)
+ vchan_vdesc_fini(vc->vd_terminated);
+
+ vc->vd_terminated = vd;
+ if (vc->cyclic == vd)
+ vc->cyclic = NULL;
+}
+
+/**
* vchan_next_desc - peek at the next descriptor to be processed
* @vc: virtual channel to obtain descriptor from
*
@@ -168,10 +188,20 @@ static inline void vchan_free_chan_resou
* Makes sure that all scheduled or active callbacks have finished running. For
* proper operation the caller has to ensure that no new callbacks are scheduled
* after the invocation of this function started.
+ * Free up the terminated cyclic descriptor to prevent memory leakage.
*/
static inline void vchan_synchronize(struct virt_dma_chan *vc)
{
+ unsigned long flags;
+
tasklet_kill(&vc->task);
+
+ spin_lock_irqsave(&vc->lock, flags);
+ if (vc->vd_terminated) {
+ vchan_vdesc_fini(vc->vd_terminated);
+ vc->vd_terminated = NULL;
+ }
+ spin_unlock_irqrestore(&vc->lock, flags);
}
#endif
Patches currently in stable-queue which might be from peter.ujfalusi(a)ti.com are
queue-4.15/dmaengine-bcm2835-dma-use-vchan_terminate_vdesc-instead-of-desc_free.patch
queue-4.15/dmaengine-virt-dma-support-for-race-free-transfer-termination.patch
queue-4.15/dmaengine-amba-pl08x-use-vchan_terminate_vdesc-instead-of-desc_free.patch
This is a note to let you know that I've just added the patch titled
dmaengine: virt-dma: Support for race free transfer termination
to the 4.14-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:
dmaengine-virt-dma-support-for-race-free-transfer-termination.patch
and it can be found in the queue-4.14 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 1c7f072d94e8b697fd9b70cdb268622a18faf522 Mon Sep 17 00:00:00 2001
From: Peter Ujfalusi <peter.ujfalusi(a)ti.com>
Date: Tue, 14 Nov 2017 16:32:04 +0200
Subject: dmaengine: virt-dma: Support for race free transfer termination
From: Peter Ujfalusi <peter.ujfalusi(a)ti.com>
commit 1c7f072d94e8b697fd9b70cdb268622a18faf522 upstream.
Even with the introduced vchan_synchronize() we can face race when
terminating a cyclic transfer.
If the terminate_all is called after the interrupt handler called
vchan_cyclic_callback(), but before the vchan_complete tasklet is called:
vc->cyclic is set to the cyclic descriptor, but the descriptor itself was
freed up in the driver's terminate_all() callback.
When the vhan_complete() is executed it will try to fetch the vc->cyclic
vdesc, but the pointer is pointing now to uninitialized memory leading to
(hard to reproduce) kernel crash.
In order to fix this, drivers should:
- call vchan_terminate_vdesc() from their terminate_all callback instead
calling their free_desc function to free up the descriptor.
- implement device_synchronize callback and call vchan_synchronize().
This way we can make sure that the descriptor is only going to be freed up
after the vchan_callback was executed in a safe manner.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi(a)ti.com>
Reviewed-by: Linus Walleij <linus.walleij(a)linaro.org>
Signed-off-by: Vinod Koul <vinod.koul(a)intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma/virt-dma.h | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
--- a/drivers/dma/virt-dma.h
+++ b/drivers/dma/virt-dma.h
@@ -35,6 +35,7 @@ struct virt_dma_chan {
struct list_head desc_completed;
struct virt_dma_desc *cyclic;
+ struct virt_dma_desc *vd_terminated;
};
static inline struct virt_dma_chan *to_virt_chan(struct dma_chan *chan)
@@ -116,6 +117,25 @@ static inline void vchan_cyclic_callback
}
/**
+ * vchan_terminate_vdesc - Disable pending cyclic callback
+ * @vd: virtual descriptor to be terminated
+ *
+ * vc.lock must be held by caller
+ */
+static inline void vchan_terminate_vdesc(struct virt_dma_desc *vd)
+{
+ struct virt_dma_chan *vc = to_virt_chan(vd->tx.chan);
+
+ /* free up stuck descriptor */
+ if (vc->vd_terminated)
+ vchan_vdesc_fini(vc->vd_terminated);
+
+ vc->vd_terminated = vd;
+ if (vc->cyclic == vd)
+ vc->cyclic = NULL;
+}
+
+/**
* vchan_next_desc - peek at the next descriptor to be processed
* @vc: virtual channel to obtain descriptor from
*
@@ -168,10 +188,20 @@ static inline void vchan_free_chan_resou
* Makes sure that all scheduled or active callbacks have finished running. For
* proper operation the caller has to ensure that no new callbacks are scheduled
* after the invocation of this function started.
+ * Free up the terminated cyclic descriptor to prevent memory leakage.
*/
static inline void vchan_synchronize(struct virt_dma_chan *vc)
{
+ unsigned long flags;
+
tasklet_kill(&vc->task);
+
+ spin_lock_irqsave(&vc->lock, flags);
+ if (vc->vd_terminated) {
+ vchan_vdesc_fini(vc->vd_terminated);
+ vc->vd_terminated = NULL;
+ }
+ spin_unlock_irqrestore(&vc->lock, flags);
}
#endif
Patches currently in stable-queue which might be from peter.ujfalusi(a)ti.com are
queue-4.14/dmaengine-bcm2835-dma-use-vchan_terminate_vdesc-instead-of-desc_free.patch
queue-4.14/dmaengine-virt-dma-support-for-race-free-transfer-termination.patch
queue-4.14/dmaengine-amba-pl08x-use-vchan_terminate_vdesc-instead-of-desc_free.patch
On Fri, Mar 16, 2018 at 07:21:53PM +0000, Harsh Shandilya wrote:
> On Fri, 16 Mar, 2018, 8:53 PM Greg Kroah-Hartman, <
> gregkh(a)linuxfoundation.org> wrote:
>
> > This is the start of the stable review cycle for the 3.18.100 release.
> > There are 25 patches in this series, all will be posted as a response
> > to this one. If anyone has any issues with these being applied, please
> > let me know.
> >
> > Responses should be made by Sun Mar 18 15:22:18 UTC 2018.
> > Anything received after that time might be too late.
> >
> > The whole patch series can be found in one patch at:
> >
> > https://www.kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.18.100-r…
> > or in the git tree and branch at:
> > git://
> > git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
> > linux-3.18.y
> > and the diffstat can be found below.
> >
>
> Builds and boots on the OnePlus 3T, no immediate issues noticed. Thanks for
> the update.
Thanks for testing and letting me know.
greg k-h
glibc keeps getting cleverer, and my version now turns raise() into
more than one syscall. Since the test relies on ptrace seeing an
exact set of syscalls, this breaks the test. Replace raise(SIGSTOP)
with syscall(SYS_tgkill, ...) to force glibc to get out of our way.
Cc: stable(a)vger.kernel.org
Signed-off-by: Andy Lutomirski <luto(a)kernel.org>
---
tools/testing/selftests/x86/ptrace_syscall.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/x86/ptrace_syscall.c b/tools/testing/selftests/x86/ptrace_syscall.c
index 1ae1c5a7392e..6f22238f3217 100644
--- a/tools/testing/selftests/x86/ptrace_syscall.c
+++ b/tools/testing/selftests/x86/ptrace_syscall.c
@@ -183,8 +183,10 @@ static void test_ptrace_syscall_restart(void)
if (ptrace(PTRACE_TRACEME, 0, 0, 0) != 0)
err(1, "PTRACE_TRACEME");
+ pid_t pid = getpid(), tid = syscall(SYS_gettid);
+
printf("\tChild will make one syscall\n");
- raise(SIGSTOP);
+ syscall(SYS_tgkill, pid, tid, SIGSTOP);
syscall(SYS_gettid, 10, 11, 12, 13, 14, 15);
_exit(0);
@@ -301,9 +303,11 @@ static void test_restart_under_ptrace(void)
if (ptrace(PTRACE_TRACEME, 0, 0, 0) != 0)
err(1, "PTRACE_TRACEME");
+ pid_t pid = getpid(), tid = syscall(SYS_gettid);
+
printf("\tChild will take a nap until signaled\n");
setsigign(SIGUSR1, SA_RESTART);
- raise(SIGSTOP);
+ syscall(SYS_tgkill, pid, tid, SIGSTOP);
syscall(SYS_pause, 0, 0, 0, 0, 0, 0);
_exit(0);
--
2.14.3
This is the start of the stable review cycle for the 3.18.100 release.
There are 25 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Sun Mar 18 15:22:18 UTC 2018.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.18.100-r…
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-3.18.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Linux 3.18.100-rc1
Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
fixup: sctp: verify size of a new chunk in _sctp_make_chunk()
Nikola Ciprich <nikola.ciprich(a)linuxbox.cz>
serial: 8250_pci: Add Brainboxes UC-260 4 port serial device
Pete Zaitcev <zaitcev(a)kotori.zaitcev.us>
usb: usbmon: Read text within supplied buffer size
Julia Lawall <Julia.Lawall(a)lip6.fr>
USB: usbmon: remove assignment from IS_ERR argument
Danilo Krummrich <danilokrummrich(a)dk-develop.de>
usb: quirks: add control message delay for 1b1c:1b20
Joel Fernandes <joelaf(a)google.com>
staging: android: ashmem: Fix lockdep issue during llseek
Oliver Neukum <oneukum(a)suse.com>
uas: fix comparison for error code
Jonas Danielsson <jonas(a)orbital-systems.com>
tty/serial: atmel: add new version check for usart
Ulrich Hecht <ulrich.hecht+renesas(a)gmail.com>
serial: sh-sci: prevent lockup on full TTY buffers
H.J. Lu <hjl.tools(a)gmail.com>
x86: Treat R_X86_64_PLT32 as R_X86_64_PC32
Josh Poimboeuf <jpoimboe(a)redhat.com>
x86/module: Detect and skip invalid relocations
Russell King <rmk+kernel(a)arm.linux.org.uk>
scripts: recordmcount: break hardlinks
Clay McClure <clay(a)daemons.net>
ubi: Fix race condition between ubi volume creation and udev
Florian Westphal <fw(a)strlen.de>
netfilter: ipv6: fix use-after-free Write in nf_nat_ipv6_manip_pkt
Florian Westphal <fw(a)strlen.de>
netfilter: bridge: ebt_among: add missing match size checks
Florian Westphal <fw(a)strlen.de>
netfilter: ebtables: CONFIG_COMPAT: don't trust userland offsets
Eric Dumazet <edumazet(a)google.com>
netfilter: IDLETIMER: be syzkaller friendly
Paolo Abeni <pabeni(a)redhat.com>
netfilter: nat: cope with negative port range
Paolo Abeni <pabeni(a)redhat.com>
netfilter: x_tables: fix missing timer initialization in xt_LED
Takashi Iwai <tiwai(a)suse.de>
ALSA: seq: More protection for concurrent write and ioctl races
Takashi Iwai <tiwai(a)suse.de>
ALSA: seq: Don't allow resizing pool in use
Seunghun Han <kkamagui(a)gmail.com>
x86/MCE: Serialize sysfs changes
Zhang Bo <zbsdta(a)126.com>
Input: matrix_keypad - fix race when disabling interrupts
Justin Chen <justinpopo6(a)gmail.com>
MIPS: BMIPS: Do not mask IPIs during suspend
himanshu.madhani(a)cavium.com <himanshu.madhani(a)cavium.com>
scsi: qla2xxx: Fix NULL pointer crash due to active timer for ABTS
-------------
Diffstat:
Makefile | 4 +-
arch/mips/kernel/smp-bmips.c | 8 +-
arch/x86/kernel/cpu/mcheck/mce.c | 22 +++++-
arch/x86/kernel/machine_kexec_64.c | 1 +
arch/x86/kernel/module.c | 14 ++++
arch/x86/tools/relocs.c | 3 +
drivers/input/keyboard/matrix_keypad.c | 4 +-
drivers/mtd/ubi/vmt.c | 15 ++--
drivers/scsi/qla2xxx/qla_init.c | 1 +
drivers/staging/android/ashmem.c | 15 ++--
drivers/tty/serial/8250/8250_pci.c | 11 +++
drivers/tty/serial/atmel_serial.c | 1 +
drivers/tty/serial/sh-sci.c | 2 +
drivers/usb/core/message.c | 4 +
drivers/usb/core/quirks.c | 3 +-
drivers/usb/mon/mon_text.c | 124 +++++++++++++++++++------------
drivers/usb/storage/uas.c | 2 +-
include/linux/usb/quirks.h | 3 +
net/bridge/netfilter/ebt_among.c | 21 +++++-
net/bridge/netfilter/ebtables.c | 13 +++-
net/ipv6/netfilter/nf_nat_l3proto_ipv6.c | 4 +
net/netfilter/nf_nat_proto_common.c | 7 +-
net/netfilter/xt_IDLETIMER.c | 9 ++-
net/netfilter/xt_LED.c | 12 +--
net/sctp/sm_make_chunk.c | 2 +-
scripts/recordmcount.c | 14 ++++
sound/core/seq/seq_clientmgr.c | 21 ++++--
sound/core/seq/seq_fifo.c | 2 +-
sound/core/seq/seq_memory.c | 14 +++-
sound/core/seq/seq_memory.h | 3 +-
30 files changed, 262 insertions(+), 97 deletions(-)