diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-08-10 14:30:12 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-08-10 14:30:12 +0200 |
commit | c84136446aa5d0b3b7ca489808cf8c69dcbd65ba (patch) | |
tree | f78ddff85b6a8ce380c22c8ba0b9a024eb9d96b6 | |
parent | 374455f081ca3aac16960d99f8b02b3580499b18 (diff) | |
download | patches-c84136446aa5d0b3b7ca489808cf8c69dcbd65ba.tar.gz |
update all patches
24 files changed, 133 insertions, 2605 deletions
diff --git a/0001-moxart-fix-potential-use-after-free-on-remove-path.patch b/0001-moxart-fix-potential-use-after-free-on-remove-path.patch deleted file mode 100644 index 40b099df459821..00000000000000 --- a/0001-moxart-fix-potential-use-after-free-on-remove-path.patch +++ /dev/null @@ -1,40 +0,0 @@ -From b927353f1bc0ab6887727fb34145637998141123 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Fri, 14 Jan 2022 08:50:22 +0100 -Subject: [PATCH] moxart: fix potential use-after-free on remove path - -It was reported that the mmc host structure could be accessed after it -was freed in moxart_remove(), so fix this by saving the base register of -the device and using it instead of the pointer dereference. - -Reported-by: whitehat002 <hackyzh002@gmail.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/mmc/host/moxart-mmc.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - ---- a/drivers/mmc/host/moxart-mmc.c -+++ b/drivers/mmc/host/moxart-mmc.c -@@ -697,6 +697,7 @@ static int moxart_remove(struct platform - { - struct mmc_host *mmc = dev_get_drvdata(&pdev->dev); - struct moxart_host *host = mmc_priv(mmc); -+ void __iomem *base = host->base; - - dev_set_drvdata(&pdev->dev, NULL); - -@@ -707,10 +708,10 @@ static int moxart_remove(struct platform - mmc_remove_host(mmc); - mmc_free_host(mmc); - -- writel(0, host->base + REG_INTERRUPT_MASK); -- writel(0, host->base + REG_POWER_CONTROL); -- writel(readl(host->base + REG_CLOCK_CONTROL) | CLK_OFF, -- host->base + REG_CLOCK_CONTROL); -+ writel(0, base + REG_INTERRUPT_MASK); -+ writel(0, base + REG_POWER_CONTROL); -+ writel(readl(base + REG_CLOCK_CONTROL) | CLK_OFF, -+ base + REG_CLOCK_CONTROL); - - return 0; - } diff --git a/0001-paride-fix-up-build-warning-on-mips-platforms.patch b/0001-paride-fix-up-build-warning-on-mips-platforms.patch deleted file mode 100644 index 7859aced900982..00000000000000 --- a/0001-paride-fix-up-build-warning-on-mips-platforms.patch +++ /dev/null @@ -1,39 +0,0 @@ -From bb8680382c187daabd36f51f7dae105584dca0e8 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Tue, 30 Nov 2021 09:43:34 +0100 -Subject: [PATCH] paride: fix up build warning on mips platforms -X-Developer-Signature: v=1; a=openpgp-sha256; l=861; h=from:subject; - bh=sKKgJm4IeJL19jVxGxafCC/+cpVZuuY5RM3ezPC40jo=; - b=owGbwMvMwCRo6H6F97bub03G02pJDIlLn9yPO6wUdO3CzAl3q6Rqbr15tVinImOj+ndVvUU1LFV3 - P75V6IhlYRBkYpAVU2T5so3n6P6KQ4pehranYeawMoEMYeDiFICJhEYyzNM51+y9RyBk3u6ARzf8q8 - 8Vr727zI1hnkFDjPZ2/jvxpe90PE92HvzakeuWBgA= -X-Developer-Key: i=gregkh@linuxfoundation.org; a=openpgp; - fpr=F4B60CC5BF78C2214A313DCB3147D40DDB2DFB29 - -MIPS include files define "PC" so when building the paride driver the -following build warning shows up: - - rivers/block/paride/bpck.c:32: warning: "PC" redefined - -Fix this by undefining PC before redefining it as is done for other -defines in this driver. - -Cc: Tim Waugh <tim@cyberelk.net> -Cc: Jens Axboe <axboe@kernel.dk> -Cc: linux-block@vger.kernel.org -Cc: linux-kernel@vger.kernel.org -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/block/paride/bpck.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/block/paride/bpck.c -+++ b/drivers/block/paride/bpck.c -@@ -28,6 +28,7 @@ - - #undef r2 - #undef w2 -+#undef PC - - #define PC pi->private - #define r2() (PC=(in_p(2) & 0xff)) diff --git a/0001-readfile-implement-readfile-syscall.patch b/0001-readfile-implement-readfile-syscall.patch index 88cf996b382e11..20523621604c1b 100644 --- a/0001-readfile-implement-readfile-syscall.patch +++ b/0001-readfile-implement-readfile-syscall.patch @@ -1,4 +1,4 @@ -From c28d7cedda47e7f1575fb58d12cc892a12093c22 Mon Sep 17 00:00:00 2001 +From 0ebe2101d6920e27137ac6706bf97803f78ce415 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Date: Sun, 24 May 2020 12:37:15 +0200 Subject: [PATCH 1/4] readfile: implement readfile syscall @@ -20,7 +20,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- a/fs/open.c +++ b/fs/open.c -@@ -1400,3 +1400,53 @@ int stream_open(struct inode *inode, str +@@ -1526,3 +1526,53 @@ int stream_open(struct inode *inode, str } EXPORT_SYMBOL(stream_open); diff --git a/0001-tty-n_r3964-locking-fixups.patch b/0001-tty-n_r3964-locking-fixups.patch deleted file mode 100644 index 678565cff8abf7..00000000000000 --- a/0001-tty-n_r3964-locking-fixups.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 51d25226b066ddeff053d36a74af38e53472520b Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Wed, 23 Jan 2019 11:00:42 +0100 -Subject: [PATCH 01/15] tty: n_r3964: locking fixups - -The n_r3964 line discipline has an "interesting" concept of locking. The -list of client's are not always properly accessed under a lock, which -can cause problems with some multi-threaded systems. - -To resolve this, do two different things: - - serialize ioctl and read accesses. - Right now ioctls can mess with the structures that a read call wants - to also touch, so serialze them to make it simpler. Note, this - _might_ break some userspace applications, as one thread could be - waiting in a read while another one wanted to make an ioctl call. - In reality, the ioctls mess with things so much that any outstanding - read might be really confused, so this is not a good thing for - userspace to be doing anyway. - - properly protect the client list - The list of clients could be accessed by different threads at the - same time without any locking. Well, there was some attempt at - locking, but the main access, findClient(), was not locked at all. - Also fix this up in a few other places. - -This line discipline needs a major overhaul. It was written at a time -there was not any SMP machines, and it shows. Rewriting some of the -object handling logic will allow the read/ioctl serialization to be -removed again. - -Reported-by: Jann Horn <jannh@google.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 54 ++++++++++++++++++++++++++++++++++++------------ - include/linux/n_r3964.h | 2 - - 2 files changed, 42 insertions(+), 14 deletions(-) - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -484,6 +484,7 @@ static void on_receive_block(struct r396 - unsigned int length; - struct r3964_client_info *pClient; - struct r3964_block_header *pBlock; -+ unsigned long flags; - - length = pInfo->rx_position; - -@@ -541,12 +542,14 @@ static void on_receive_block(struct r396 - add_rx_queue(pInfo, pBlock); - - /* notify attached client processes: */ -+ spin_lock_irqsave(&pInfo->lock, flags); - for (pClient = pInfo->firstClient; pClient; pClient = pClient->next) { - if (pClient->sig_flags & R3964_SIG_DATA) { - add_msg(pClient, R3964_MSG_DATA, length, R3964_OK, - pBlock); - } - } -+ spin_unlock_irqrestore(&pInfo->lock, flags); - wake_up_interruptible(&pInfo->tty->read_wait); - - pInfo->state = R3964_IDLE; -@@ -742,13 +745,17 @@ static struct r3964_client_info *findCli - struct pid *pid) - { - struct r3964_client_info *pClient; -+ unsigned long flags; - -+ spin_lock_irqsave(&pInfo->lock, flags); - for (pClient = pInfo->firstClient; pClient; pClient = pClient->next) { - if (pClient->pid == pid) { -- return pClient; -+ goto exit; - } - } -- return NULL; -+exit: -+ spin_unlock_irqrestore(&pInfo->lock, flags); -+ return pClient; - } - - static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg) -@@ -756,8 +763,11 @@ static int enable_signals(struct r3964_i - struct r3964_client_info *pClient; - struct r3964_client_info **ppClient; - struct r3964_message *pMsg; -+ unsigned long flags; - - if ((arg & R3964_SIG_ALL) == 0) { -+ spin_lock_irqsave(&pInfo->lock, flags); -+ - /* Remove client from client list */ - for (ppClient = &pInfo->firstClient; *ppClient; - ppClient = &(*ppClient)->next) { -@@ -778,9 +788,11 @@ static int enable_signals(struct r3964_i - put_pid(pClient->pid); - kfree(pClient); - TRACE_M("enable_signals - kfree %p", pClient); -+ spin_unlock_irqrestore(&pInfo->lock, flags); - return 0; - } - } -+ spin_unlock_irqrestore(&pInfo->lock, flags); - return -EINVAL; - } else { - pClient = findClient(pInfo, pid); -@@ -795,6 +807,7 @@ static int enable_signals(struct r3964_i - if (pClient == NULL) - return -ENOMEM; - -+ spin_lock_irqsave(&pInfo->lock, flags); - TRACE_PS("add client %d to client list", pid_nr(pid)); - spin_lock_init(&pClient->lock); - pClient->sig_flags = arg; -@@ -805,6 +818,7 @@ static int enable_signals(struct r3964_i - pClient->next_block_to_read = NULL; - pClient->msg_count = 0; - pInfo->firstClient = pClient; -+ spin_unlock_irqrestore(&pInfo->lock, flags); - } - } - -@@ -849,8 +863,7 @@ static void add_msg(struct r3964_client_ - if (pClient->msg_count < R3964_MAX_MSG_COUNT - 1) { - queue_the_message: - -- pMsg = kmalloc(sizeof(struct r3964_message), -- error_code ? GFP_ATOMIC : GFP_KERNEL); -+ pMsg = kmalloc(sizeof(*pMsg), GFP_ATOMIC); - TRACE_M("add_msg - kmalloc %p", pMsg); - if (pMsg == NULL) { - return; -@@ -1069,9 +1082,7 @@ static ssize_t r3964_read(struct tty_str - - TRACE_L("read()"); - -- /* -- * Internal serialization of reads. -- */ -+ /* Internal serialization of reads and ioctls. */ - if (file->f_flags & O_NONBLOCK) { - if (!mutex_trylock(&pInfo->read_lock)) - return -EAGAIN; -@@ -1190,28 +1201,45 @@ static int r3964_ioctl(struct tty_struct - unsigned int cmd, unsigned long arg) - { - struct r3964_info *pInfo = tty->disc_data; -+ int retval = 0; -+ - if (pInfo == NULL) - return -EINVAL; -+ /* Internal serialization of reads and ioctls */ -+ if (file->f_flags & O_NONBLOCK) { -+ if (!mutex_trylock(&pInfo->read_lock)) -+ return -EAGAIN; -+ } else { -+ if (mutex_lock_interruptible(&pInfo->read_lock)) -+ return -ERESTARTSYS; -+ } -+ - switch (cmd) { - case R3964_ENABLE_SIGNALS: -- return enable_signals(pInfo, task_pid(current), arg); -+ retval = enable_signals(pInfo, task_pid(current), arg); -+ break; - case R3964_SETPRIORITY: - if (arg < R3964_MASTER || arg > R3964_SLAVE) - return -EINVAL; - pInfo->priority = arg & 0xff; -- return 0; -+ break; - case R3964_USE_BCC: - if (arg) - pInfo->flags |= R3964_BCC; - else - pInfo->flags &= ~R3964_BCC; -- return 0; -+ break; - case R3964_READ_TELEGRAM: -- return read_telegram(pInfo, task_pid(current), -- (unsigned char __user *)arg); -+ retval = read_telegram(pInfo, task_pid(current), -+ (unsigned char __user *)arg); -+ break; - default: -- return -ENOIOCTLCMD; -+ retval = -ENOIOCTLCMD; -+ break; - } -+ -+ mutex_unlock(&pInfo->read_lock); -+ return retval; - } - - #ifdef CONFIG_COMPAT ---- a/include/linux/n_r3964.h -+++ b/include/linux/n_r3964.h -@@ -162,7 +162,7 @@ struct r3964_info { - unsigned char bcc; - unsigned int blocks_in_rx_queue; - -- struct mutex read_lock; /* serialize r3964_read */ -+ struct mutex read_lock; /* serialize read and ioctl */ - - struct r3964_client_info *firstClient; - unsigned int state; diff --git a/0002-arch-wire-up-the-readfile-syscall.patch b/0002-arch-wire-up-the-readfile-syscall.patch index 340fdf9729f0fe..76a5c67bb57b9c 100644 --- a/0002-arch-wire-up-the-readfile-syscall.patch +++ b/0002-arch-wire-up-the-readfile-syscall.patch @@ -1,6 +1,6 @@ -From 9723d438992d0c11d5d3e886198674ef28213edc Mon Sep 17 00:00:00 2001 +From b1c4dc1ba255fb1eac6f11532bdb8d41173624df Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Sun, 24 May 2020 12:36:21 +0200 +Date: Wed, 10 Aug 2022 13:07:37 +0200 Subject: [PATCH 2/4] arch: wire up the readfile syscall This wires up the readfile syscall for all architectures @@ -26,152 +26,152 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> arch/x86/entry/syscalls/syscall_64.tbl | 1 + arch/xtensa/kernel/syscalls/syscall.tbl | 1 + include/linux/syscalls.h | 2 ++ - include/uapi/asm-generic/unistd.h | 4 +++- - 20 files changed, 24 insertions(+), 2 deletions(-) + include/uapi/asm-generic/unistd.h | 5 ++++- + 20 files changed, 25 insertions(+), 2 deletions(-) --- a/arch/alpha/kernel/syscalls/syscall.tbl +++ b/arch/alpha/kernel/syscalls/syscall.tbl -@@ -482,3 +482,4 @@ - 550 common process_madvise sys_process_madvise - 551 common epoll_pwait2 sys_epoll_pwait2 - 552 common mount_setattr sys_mount_setattr -+553 common readfile sys_readfile +@@ -490,3 +490,4 @@ + 558 common process_mrelease sys_process_mrelease + 559 common futex_waitv sys_futex_waitv + 560 common set_mempolicy_home_node sys_ni_syscall ++561 common readfile sys_readfile --- a/arch/arm/tools/syscall.tbl +++ b/arch/arm/tools/syscall.tbl -@@ -456,3 +456,4 @@ - 440 common process_madvise sys_process_madvise - 441 common epoll_pwait2 sys_epoll_pwait2 - 442 common mount_setattr sys_mount_setattr -+443 common readfile sys_readfile +@@ -464,3 +464,4 @@ + 448 common process_mrelease sys_process_mrelease + 449 common futex_waitv sys_futex_waitv + 450 common set_mempolicy_home_node sys_set_mempolicy_home_node ++451 common readfile sys_readfile --- a/arch/arm64/include/asm/unistd.h +++ b/arch/arm64/include/asm/unistd.h -@@ -38,7 +38,7 @@ +@@ -39,7 +39,7 @@ #define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE + 5) #define __ARM_NR_COMPAT_END (__ARM_NR_COMPAT_BASE + 0x800) --#define __NR_compat_syscalls 443 -+#define __NR_compat_syscalls 444 +-#define __NR_compat_syscalls 451 ++#define __NR_compat_syscalls 452 #endif #define __ARCH_WANT_SYS_CLONE --- a/arch/arm64/include/asm/unistd32.h +++ b/arch/arm64/include/asm/unistd32.h -@@ -893,6 +893,8 @@ __SYSCALL(__NR_process_madvise, sys_proc - __SYSCALL(__NR_epoll_pwait2, compat_sys_epoll_pwait2) - #define __NR_mount_setattr 442 - __SYSCALL(__NR_mount_setattr, sys_mount_setattr) -+#define __NR_readfile 443 +@@ -907,6 +907,8 @@ __SYSCALL(__NR_process_mrelease, sys_pro + __SYSCALL(__NR_futex_waitv, sys_futex_waitv) + #define __NR_set_mempolicy_home_node 450 + __SYSCALL(__NR_set_mempolicy_home_node, sys_set_mempolicy_home_node) ++#define __NR_readfile 451 +__SYSCALL(__NR_readfile, sys_readfile) /* * Please add new compat syscalls above this comment and update --- a/arch/ia64/kernel/syscalls/syscall.tbl +++ b/arch/ia64/kernel/syscalls/syscall.tbl -@@ -363,3 +363,4 @@ - 440 common process_madvise sys_process_madvise - 441 common epoll_pwait2 sys_epoll_pwait2 - 442 common mount_setattr sys_mount_setattr -+443 common readfile sys_readfile +@@ -371,3 +371,4 @@ + 448 common process_mrelease sys_process_mrelease + 449 common futex_waitv sys_futex_waitv + 450 common set_mempolicy_home_node sys_set_mempolicy_home_node ++451 common readfile sys_readfile --- a/arch/m68k/kernel/syscalls/syscall.tbl +++ b/arch/m68k/kernel/syscalls/syscall.tbl -@@ -442,3 +442,4 @@ - 440 common process_madvise sys_process_madvise - 441 common epoll_pwait2 sys_epoll_pwait2 - 442 common mount_setattr sys_mount_setattr -+443 common readfile sys_readfile +@@ -450,3 +450,4 @@ + 448 common process_mrelease sys_process_mrelease + 449 common futex_waitv sys_futex_waitv + 450 common set_mempolicy_home_node sys_set_mempolicy_home_node ++451 common readfile sys_readfile --- a/arch/microblaze/kernel/syscalls/syscall.tbl +++ b/arch/microblaze/kernel/syscalls/syscall.tbl -@@ -448,3 +448,4 @@ - 440 common process_madvise sys_process_madvise - 441 common epoll_pwait2 sys_epoll_pwait2 - 442 common mount_setattr sys_mount_setattr -+443 common readfile sys_readfile +@@ -456,3 +456,4 @@ + 448 common process_mrelease sys_process_mrelease + 449 common futex_waitv sys_futex_waitv + 450 common set_mempolicy_home_node sys_set_mempolicy_home_node ++451 common readfile sys_readfile --- a/arch/mips/kernel/syscalls/syscall_n32.tbl +++ b/arch/mips/kernel/syscalls/syscall_n32.tbl -@@ -381,3 +381,4 @@ - 440 n32 process_madvise sys_process_madvise - 441 n32 epoll_pwait2 compat_sys_epoll_pwait2 - 442 n32 mount_setattr sys_mount_setattr -+443 n32 readfile sys_readfile +@@ -389,3 +389,4 @@ + 448 n32 process_mrelease sys_process_mrelease + 449 n32 futex_waitv sys_futex_waitv + 450 n32 set_mempolicy_home_node sys_set_mempolicy_home_node ++451 n32 readfile sys_readfile --- a/arch/mips/kernel/syscalls/syscall_n64.tbl +++ b/arch/mips/kernel/syscalls/syscall_n64.tbl -@@ -357,3 +357,4 @@ - 440 n64 process_madvise sys_process_madvise - 441 n64 epoll_pwait2 sys_epoll_pwait2 - 442 n64 mount_setattr sys_mount_setattr -+443 n64 readfile sys_readfile +@@ -365,3 +365,4 @@ + 448 n64 process_mrelease sys_process_mrelease + 449 n64 futex_waitv sys_futex_waitv + 450 common set_mempolicy_home_node sys_set_mempolicy_home_node ++451 n64 readfile sys_readfile --- a/arch/mips/kernel/syscalls/syscall_o32.tbl +++ b/arch/mips/kernel/syscalls/syscall_o32.tbl -@@ -430,3 +430,4 @@ - 440 o32 process_madvise sys_process_madvise - 441 o32 epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 - 442 o32 mount_setattr sys_mount_setattr -+443 o32 readfile sys_readfile +@@ -438,3 +438,4 @@ + 448 o32 process_mrelease sys_process_mrelease + 449 o32 futex_waitv sys_futex_waitv + 450 o32 set_mempolicy_home_node sys_set_mempolicy_home_node ++451 o32 readfile sys_readfile --- a/arch/parisc/kernel/syscalls/syscall.tbl +++ b/arch/parisc/kernel/syscalls/syscall.tbl -@@ -440,3 +440,4 @@ - 440 common process_madvise sys_process_madvise - 441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 - 442 common mount_setattr sys_mount_setattr -+443 common readfile sys_readfile +@@ -448,3 +448,4 @@ + 448 common process_mrelease sys_process_mrelease + 449 common futex_waitv sys_futex_waitv + 450 common set_mempolicy_home_node sys_set_mempolicy_home_node ++451 common readfile sys_readfile --- a/arch/powerpc/kernel/syscalls/syscall.tbl +++ b/arch/powerpc/kernel/syscalls/syscall.tbl -@@ -522,3 +522,4 @@ - 440 common process_madvise sys_process_madvise - 441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 - 442 common mount_setattr sys_mount_setattr -+443 common readfile sys_readfile +@@ -530,3 +530,4 @@ + 448 common process_mrelease sys_process_mrelease + 449 common futex_waitv sys_futex_waitv + 450 nospu set_mempolicy_home_node sys_set_mempolicy_home_node ++451 common readfile sys_readfile --- a/arch/s390/kernel/syscalls/syscall.tbl +++ b/arch/s390/kernel/syscalls/syscall.tbl -@@ -445,3 +445,4 @@ - 440 common process_madvise sys_process_madvise sys_process_madvise - 441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 - 442 common mount_setattr sys_mount_setattr sys_mount_setattr -+443 common readfile sys_readfile sys_readfile +@@ -453,3 +453,4 @@ + 448 common process_mrelease sys_process_mrelease sys_process_mrelease + 449 common futex_waitv sys_futex_waitv sys_futex_waitv + 450 common set_mempolicy_home_node sys_set_mempolicy_home_node sys_set_mempolicy_home_node ++451 common readfile sys_readfile sys_readfile --- a/arch/sh/kernel/syscalls/syscall.tbl +++ b/arch/sh/kernel/syscalls/syscall.tbl -@@ -445,3 +445,4 @@ - 440 common process_madvise sys_process_madvise - 441 common epoll_pwait2 sys_epoll_pwait2 - 442 common mount_setattr sys_mount_setattr -+443 common readfile sys_readfile +@@ -453,3 +453,4 @@ + 448 common process_mrelease sys_process_mrelease + 449 common futex_waitv sys_futex_waitv + 450 common set_mempolicy_home_node sys_set_mempolicy_home_node ++451 common readfile sys_readfile --- a/arch/sparc/kernel/syscalls/syscall.tbl +++ b/arch/sparc/kernel/syscalls/syscall.tbl -@@ -488,3 +488,4 @@ - 440 common process_madvise sys_process_madvise - 441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 - 442 common mount_setattr sys_mount_setattr -+443 common readfile sys_readfile +@@ -496,3 +496,4 @@ + 448 common process_mrelease sys_process_mrelease + 449 common futex_waitv sys_futex_waitv + 450 common set_mempolicy_home_node sys_set_mempolicy_home_node ++451 common readfile sys_readfile --- a/arch/x86/entry/syscalls/syscall_32.tbl +++ b/arch/x86/entry/syscalls/syscall_32.tbl -@@ -447,3 +447,4 @@ - 440 i386 process_madvise sys_process_madvise - 441 i386 epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 - 442 i386 mount_setattr sys_mount_setattr -+443 i386 readfile sys_readfile +@@ -455,3 +455,4 @@ + 448 i386 process_mrelease sys_process_mrelease + 449 i386 futex_waitv sys_futex_waitv + 450 i386 set_mempolicy_home_node sys_set_mempolicy_home_node ++451 i386 readfile sys_readfile --- a/arch/x86/entry/syscalls/syscall_64.tbl +++ b/arch/x86/entry/syscalls/syscall_64.tbl -@@ -364,6 +364,7 @@ - 440 common process_madvise sys_process_madvise - 441 common epoll_pwait2 sys_epoll_pwait2 - 442 common mount_setattr sys_mount_setattr -+443 common readfile sys_readfile +@@ -372,6 +372,7 @@ + 448 common process_mrelease sys_process_mrelease + 449 common futex_waitv sys_futex_waitv + 450 common set_mempolicy_home_node sys_set_mempolicy_home_node ++451 common readfile sys_readfile # # Due to a historical design error, certain syscalls are numbered differently --- a/arch/xtensa/kernel/syscalls/syscall.tbl +++ b/arch/xtensa/kernel/syscalls/syscall.tbl -@@ -413,3 +413,4 @@ - 440 common process_madvise sys_process_madvise - 441 common epoll_pwait2 sys_epoll_pwait2 - 442 common mount_setattr sys_mount_setattr -+443 common readfile sys_readfile +@@ -421,3 +421,4 @@ + 448 common process_mrelease sys_process_mrelease + 449 common futex_waitv sys_futex_waitv + 450 common set_mempolicy_home_node sys_set_mempolicy_home_node ++451 common readfile sys_readfile --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h -@@ -1041,6 +1041,8 @@ asmlinkage long sys_pidfd_send_signal(in - siginfo_t __user *info, - unsigned int flags); - asmlinkage long sys_pidfd_getfd(int pidfd, int fd, unsigned int flags); +@@ -1056,6 +1056,8 @@ asmlinkage long sys_memfd_secret(unsigne + asmlinkage long sys_set_mempolicy_home_node(unsigned long start, unsigned long len, + unsigned long home_node, + unsigned long flags); +asmlinkage long sys_readfile(int dfd, const char __user *filename, + char __user *buffer, size_t bufsize, int flags); @@ -179,16 +179,16 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> * Architecture-specific system calls --- a/include/uapi/asm-generic/unistd.h +++ b/include/uapi/asm-generic/unistd.h -@@ -863,9 +863,11 @@ __SYSCALL(__NR_process_madvise, sys_proc - __SC_COMP(__NR_epoll_pwait2, sys_epoll_pwait2, compat_sys_epoll_pwait2) - #define __NR_mount_setattr 442 - __SYSCALL(__NR_mount_setattr, sys_mount_setattr) -+#define __NR_readfile 443 -+__SYSCALL(__NR_readfile, sys_readfile) +@@ -886,8 +886,11 @@ __SYSCALL(__NR_futex_waitv, sys_futex_wa + #define __NR_set_mempolicy_home_node 450 + __SYSCALL(__NR_set_mempolicy_home_node, sys_set_mempolicy_home_node) ++#define __NR_readfile 451 ++__SYSCALL(__NR_readfile, sys_readfile) ++ #undef __NR_syscalls --#define __NR_syscalls 443 -+#define __NR_syscalls 444 +-#define __NR_syscalls 451 ++#define __NR_syscalls 452 /* * 32 bit systems traditionally used different diff --git a/0002-tty-n_r3964-fix-poll-return-value.patch b/0002-tty-n_r3964-fix-poll-return-value.patch deleted file mode 100644 index f4f0b79115cb15..00000000000000 --- a/0002-tty-n_r3964-fix-poll-return-value.patch +++ /dev/null @@ -1,25 +0,0 @@ -From f93faa310cf3da0d54ee2232a76729b2063cc551 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Fri, 25 Jan 2019 15:13:58 +0100 -Subject: [PATCH 02/15] tty: n_r3964: fix poll return value - --EINVAL is not a valid __poll_t return value for when an error happens. -Instead, set return EPOLLNVAL | EPOLLERR to tell userspace that what it -wanted to have happen did not. - -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -1283,7 +1283,7 @@ static __poll_t r3964_poll(struct tty_st - if (pMsg) - result |= EPOLLIN | EPOLLRDNORM; - } else { -- result = -EINVAL; -+ result = EPOLLNVAL | EPOLLERR; - } - return result; - } diff --git a/0003-selftests-add-readfile-2-selftests.patch b/0003-selftests-add-readfile-2-selftests.patch index 881ab3f7443a4d..a2b4c8951cca75 100644 --- a/0003-selftests-add-readfile-2-selftests.patch +++ b/0003-selftests-add-readfile-2-selftests.patch @@ -1,4 +1,4 @@ -From 3c2a46d3834f782c4154fb5c7749dd45246e1885 Mon Sep 17 00:00:00 2001 +From ed08facb51f6119546948eeb2bf5c6a9c7ffe7e3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Date: Sun, 8 Mar 2020 09:54:45 +0100 Subject: [PATCH 3/4] selftests: add readfile(2) selftests @@ -25,8 +25,8 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile -@@ -50,6 +50,7 @@ TARGETS += ptrace - TARGETS += openat2 +@@ -59,6 +59,7 @@ TARGETS += resctrl + TARGETS += rlimits TARGETS += rseq TARGETS += rtc +TARGETS += readfile @@ -343,7 +343,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +//#define __NR_readfile -1 +//#endif + -+#define __NR_readfile 443 ++#define __NR_readfile 451 + +static inline int sys_readfile(int fd, const char *filename, + unsigned char *buffer, size_t bufsize, int flags) diff --git a/0003-tty-n_r3964-remove-n_r3964.h.patch b/0003-tty-n_r3964-remove-n_r3964.h.patch deleted file mode 100644 index ebcd9ce5a42c81..00000000000000 --- a/0003-tty-n_r3964-remove-n_r3964.h.patch +++ /dev/null @@ -1,329 +0,0 @@ -From 3383e7c9df4908b5f3ac97e5ac0492775d0a4b35 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Wed, 23 Jan 2019 20:28:46 +0100 -Subject: [PATCH 03/15] tty: n_r3964: remove n_r3964.h - -No need to have a .h file in include/linux/ for a line discipline where -the only things in it are needed by a single c file. - -So move the contents (and fix the formatting at the same time) into -drivers/tty/n_r3964.c - -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 114 ++++++++++++++++++++++++++++++- - include/linux/n_r3964.h | 175 ------------------------------------------------ - 2 files changed, 113 insertions(+), 176 deletions(-) - delete mode 100644 include/linux/n_r3964.h - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -60,10 +60,11 @@ - #include <linux/string.h> /* used in new tty drivers */ - #include <linux/signal.h> /* used in new tty drivers */ - #include <linux/ioctl.h> --#include <linux/n_r3964.h> -+#include <linux/param.h> - #include <linux/poll.h> - #include <linux/init.h> - #include <linux/uaccess.h> -+#include <uapi/linux/n_r3964.h> - - /*#define DEBUG_QUEUE*/ - -@@ -107,6 +108,117 @@ - #else - #define TRACE_Q(fmt, arg...) do {} while (0) - #endif -+ -+/* Common ascii handshake characters: */ -+#define STX 0x02 -+#define ETX 0x03 -+#define DLE 0x10 -+#define NAK 0x15 -+ -+/* Timeouts (from milliseconds to jiffies) */ -+#define R3964_TO_QVZ ((550)*HZ/1000) -+#define R3964_TO_ZVZ ((220)*HZ/1000) -+#define R3964_TO_NO_BUF ((400)*HZ/1000) -+#define R3964_NO_TX_ROOM ((100)*HZ/1000) -+#define R3964_TO_RX_PANIC ((4000)*HZ/1000) -+#define R3964_MAX_RETRIES 5 -+ -+enum { -+ R3964_IDLE, -+ R3964_TX_REQUEST, -+ R3964_TRANSMITTING, -+ R3964_WAIT_ZVZ_BEFORE_TX_RETRY, -+ R3964_WAIT_FOR_TX_ACK, -+ R3964_WAIT_FOR_RX_BUF, -+ R3964_RECEIVING, -+ R3964_WAIT_FOR_BCC, -+ R3964_WAIT_FOR_RX_REPEAT -+}; -+ -+/* All open file-handles are 'clients' and are stored in a linked list: */ -+ -+struct r3964_message; -+ -+struct r3964_client_info { -+ spinlock_t lock; -+ struct pid *pid; -+ unsigned int sig_flags; -+ -+ struct r3964_client_info *next; -+ -+ struct r3964_message *first_msg; -+ struct r3964_message *last_msg; -+ struct r3964_block_header *next_block_to_read; -+ int msg_count; -+}; -+ -+struct r3964_block_header; -+ -+/* internal version of client_message: */ -+struct r3964_message { -+ int msg_id; -+ int arg; -+ int error_code; -+ struct r3964_block_header *block; -+ struct r3964_message *next; -+}; -+ -+/* Header of received block in rx_buf/tx_buf: */ -+struct r3964_block_header { -+ unsigned int length; /* length in chars without header */ -+ unsigned char *data; /* usually data is located immediately -+ * behind this struct */ -+ unsigned int locks; /* only used in rx_buffer */ -+ -+ struct r3964_block_header *next; -+ struct r3964_client_info *owner; /* =NULL in rx_buffer */ -+}; -+ -+/* -+ * If rx_buf hasn't enough space to store R3964_MTU chars, -+ * we will reject all incoming STX-requests by sending NAK. -+ */ -+#define RX_BUF_SIZE 4000 -+#define TX_BUF_SIZE 4000 -+#define R3964_MAX_BLOCKS_IN_RX_QUEUE 100 -+ -+#define R3964_PARITY 0x0001 -+#define R3964_FRAME 0x0002 -+#define R3964_OVERRUN 0x0004 -+#define R3964_UNKNOWN 0x0008 -+#define R3964_BREAK 0x0010 -+#define R3964_CHECKSUM 0x0020 -+#define R3964_ERROR 0x003f -+#define R3964_BCC 0x4000 -+#define R3964_DEBUG 0x8000 -+ -+struct r3964_info { -+ spinlock_t lock; -+ struct tty_struct *tty; -+ unsigned char priority; -+ unsigned char *rx_buf; /* ring buffer */ -+ unsigned char *tx_buf; -+ -+ struct r3964_block_header *rx_first; -+ struct r3964_block_header *rx_last; -+ struct r3964_block_header *tx_first; -+ struct r3964_block_header *tx_last; -+ unsigned int tx_position; -+ unsigned int rx_position; -+ unsigned char last_rx; -+ unsigned char bcc; -+ unsigned int blocks_in_rx_queue; -+ -+ struct mutex read_lock; /* serialize read and ioctl */ -+ -+ struct r3964_client_info *firstClient; -+ unsigned int state; -+ unsigned int flags; -+ -+ struct timer_list tmr; -+ int nRetry; -+}; -+ - static void add_tx_queue(struct r3964_info *, struct r3964_block_header *); - static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code); - static void put_char(struct r3964_info *pInfo, unsigned char ch); ---- a/include/linux/n_r3964.h -+++ /dev/null -@@ -1,175 +0,0 @@ --/* r3964 linediscipline for linux -- * -- * ----------------------------------------------------------- -- * Copyright by -- * Philips Automation Projects -- * Kassel (Germany) -- * ----------------------------------------------------------- -- * This software may be used and distributed according to the terms of -- * the GNU General Public License, incorporated herein by reference. -- * -- * Author: -- * L. Haag -- * -- * $Log: r3964.h,v $ -- * Revision 1.4 2005/12/21 19:54:24 Kurt Huwig <kurt huwig de> -- * Fixed HZ usage on 2.6 kernels -- * Removed unnecessary include -- * -- * Revision 1.3 2001/03/18 13:02:24 dwmw2 -- * Fix timer usage, use spinlocks properly. -- * -- * Revision 1.2 2001/03/18 12:53:15 dwmw2 -- * Merge changes in 2.4.2 -- * -- * Revision 1.1.1.1 1998/10/13 16:43:14 dwmw2 -- * This'll screw the version control -- * -- * Revision 1.6 1998/09/30 00:40:38 dwmw2 -- * Updated to use kernel's N_R3964 if available -- * -- * Revision 1.4 1998/04/02 20:29:44 lhaag -- * select, blocking, ... -- * -- * Revision 1.3 1998/02/12 18:58:43 root -- * fixed some memory leaks -- * calculation of checksum characters -- * -- * Revision 1.2 1998/02/07 13:03:17 root -- * ioctl read_telegram -- * -- * Revision 1.1 1998/02/06 19:19:43 root -- * Initial revision -- * -- * -- */ --#ifndef __LINUX_N_R3964_H__ --#define __LINUX_N_R3964_H__ -- -- --#include <linux/param.h> --#include <uapi/linux/n_r3964.h> -- --/* -- * Common ascii handshake characters: -- */ -- --#define STX 0x02 --#define ETX 0x03 --#define DLE 0x10 --#define NAK 0x15 -- --/* -- * Timeouts (from milliseconds to jiffies) -- */ -- --#define R3964_TO_QVZ ((550)*HZ/1000) --#define R3964_TO_ZVZ ((220)*HZ/1000) --#define R3964_TO_NO_BUF ((400)*HZ/1000) --#define R3964_NO_TX_ROOM ((100)*HZ/1000) --#define R3964_TO_RX_PANIC ((4000)*HZ/1000) --#define R3964_MAX_RETRIES 5 -- -- --enum { R3964_IDLE, -- R3964_TX_REQUEST, R3964_TRANSMITTING, -- R3964_WAIT_ZVZ_BEFORE_TX_RETRY, R3964_WAIT_FOR_TX_ACK, -- R3964_WAIT_FOR_RX_BUF, -- R3964_RECEIVING, R3964_WAIT_FOR_BCC, R3964_WAIT_FOR_RX_REPEAT -- }; -- --/* -- * All open file-handles are 'clients' and are stored in a linked list: -- */ -- --struct r3964_message; -- --struct r3964_client_info { -- spinlock_t lock; -- struct pid *pid; -- unsigned int sig_flags; -- -- struct r3964_client_info *next; -- -- struct r3964_message *first_msg; -- struct r3964_message *last_msg; -- struct r3964_block_header *next_block_to_read; -- int msg_count; --}; -- -- -- --struct r3964_block_header; -- --/* internal version of client_message: */ --struct r3964_message { -- int msg_id; -- int arg; -- int error_code; -- struct r3964_block_header *block; -- struct r3964_message *next; --}; -- --/* -- * Header of received block in rx_buf/tx_buf: -- */ -- --struct r3964_block_header --{ -- unsigned int length; /* length in chars without header */ -- unsigned char *data; /* usually data is located -- immediately behind this struct */ -- unsigned int locks; /* only used in rx_buffer */ -- -- struct r3964_block_header *next; -- struct r3964_client_info *owner; /* =NULL in rx_buffer */ --}; -- --/* -- * If rx_buf hasn't enough space to store R3964_MTU chars, -- * we will reject all incoming STX-requests by sending NAK. -- */ -- --#define RX_BUF_SIZE 4000 --#define TX_BUF_SIZE 4000 --#define R3964_MAX_BLOCKS_IN_RX_QUEUE 100 -- --#define R3964_PARITY 0x0001 --#define R3964_FRAME 0x0002 --#define R3964_OVERRUN 0x0004 --#define R3964_UNKNOWN 0x0008 --#define R3964_BREAK 0x0010 --#define R3964_CHECKSUM 0x0020 --#define R3964_ERROR 0x003f --#define R3964_BCC 0x4000 --#define R3964_DEBUG 0x8000 -- -- --struct r3964_info { -- spinlock_t lock; -- struct tty_struct *tty; -- unsigned char priority; -- unsigned char *rx_buf; /* ring buffer */ -- unsigned char *tx_buf; -- -- struct r3964_block_header *rx_first; -- struct r3964_block_header *rx_last; -- struct r3964_block_header *tx_first; -- struct r3964_block_header *tx_last; -- unsigned int tx_position; -- unsigned int rx_position; -- unsigned char last_rx; -- unsigned char bcc; -- unsigned int blocks_in_rx_queue; -- -- struct mutex read_lock; /* serialize read and ioctl */ -- -- struct r3964_client_info *firstClient; -- unsigned int state; -- unsigned int flags; -- -- struct timer_list tmr; -- int nRetry; --}; -- --#endif diff --git a/0004-readfile.2-new-page-describing-readfile-2.patch b/0004-readfile.2-new-page-describing-readfile-2.patch index 7603c0dbef876e..5a18923787f543 100644 --- a/0004-readfile.2-new-page-describing-readfile-2.patch +++ b/0004-readfile.2-new-page-describing-readfile-2.patch @@ -1,4 +1,4 @@ -From 988a63edfccc64b73f380e60a3769a8775ae050e Mon Sep 17 00:00:00 2001 +From 8d58e2dad8eb7d6fc1cf689adcf0a88e033ea109 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Date: Fri, 12 Jun 2020 12:11:39 +0200 Subject: [PATCH 4/4] readfile.2: new page describing readfile(2) diff --git a/0004-tty-n_r3964-drop-ancient-header-changelog-text.patch b/0004-tty-n_r3964-drop-ancient-header-changelog-text.patch deleted file mode 100644 index 5a08eaee47ca39..00000000000000 --- a/0004-tty-n_r3964-drop-ancient-header-changelog-text.patch +++ /dev/null @@ -1,69 +0,0 @@ -From d01e4fbee328ad33555c740d7881129fe6d15175 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Wed, 23 Jan 2019 20:31:02 +0100 -Subject: [PATCH 04/15] tty: n_r3964: drop ancient header changelog text - -No need to keep changelog text from 2001 and earlier in the file itself, -drop it all. This keeps the original copyright and author information -in the file. - -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 45 ++++----------------------------------------- - 1 file changed, 4 insertions(+), 41 deletions(-) - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -1,48 +1,11 @@ - // SPDX-License-Identifier: GPL-1.0+ --/* r3964 linediscipline for linux -+/* -+ * r3964 line discipline - * -- * ----------------------------------------------------------- -- * Copyright by -- * Philips Automation Projects -+ * Copyright by Philips Automation Projects - * Kassel (Germany) -- * ----------------------------------------------------------- -- * Author: -- * L. Haag -- * -- * $Log: n_r3964.c,v $ -- * Revision 1.10 2001/03/18 13:02:24 dwmw2 -- * Fix timer usage, use spinlocks properly. -- * -- * Revision 1.9 2001/03/18 12:52:14 dwmw2 -- * Merge changes in 2.4.2 -- * -- * Revision 1.8 2000/03/23 14:14:54 dwmw2 -- * Fix race in sleeping in r3964_read() -- * -- * Revision 1.7 1999/28/08 11:41:50 dwmw2 -- * Port to 2.3 kernel -- * -- * Revision 1.6 1998/09/30 00:40:40 dwmw2 -- * Fixed compilation on 2.0.x kernels -- * Updated to newly registered tty-ldisc number 9 -- * -- * Revision 1.5 1998/09/04 21:57:36 dwmw2 -- * Signal handling bug fixes, port to 2.1.x. -- * -- * Revision 1.4 1998/04/02 20:26:59 lhaag -- * select, blocking, ... -- * -- * Revision 1.3 1998/02/12 18:58:43 root -- * fixed some memory leaks -- * calculation of checksum characters -- * -- * Revision 1.2 1998/02/07 13:03:34 root -- * ioctl read_telegram -- * -- * Revision 1.1 1998/02/06 19:21:03 root -- * Initial revision -- * - * -+ * Author: L. Haag - */ - - #include <linux/module.h> diff --git a/0005-tty-n_r3964-split-rx-and-tx-header-structures.patch b/0005-tty-n_r3964-split-rx-and-tx-header-structures.patch deleted file mode 100644 index 6f41d34f2f0003..00000000000000 --- a/0005-tty-n_r3964-split-rx-and-tx-header-structures.patch +++ /dev/null @@ -1,260 +0,0 @@ -From b717816885270bfe80ed184cb894b14c10c3f48f Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Thu, 24 Jan 2019 12:32:05 +0100 -Subject: [PATCH 05/15] tty: n_r3964: split rx and tx header structures - -It's really confusing to try to figure out what structure is what type -of header when both the tx and rx queues are using the same header -structure, but not all of the fields in it. - -So split this into two different structures. That makes it much more -obvious what variable and queue and type of message is being kept track -of where. - -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 78 +++++++++++++++++++++++++------------------------- - 1 file changed, 39 insertions(+), 39 deletions(-) - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -101,6 +101,8 @@ enum { - /* All open file-handles are 'clients' and are stored in a linked list: */ - - struct r3964_message; -+struct rx_block_header; -+struct tx_block_header; - - struct r3964_client_info { - spinlock_t lock; -@@ -111,30 +113,35 @@ struct r3964_client_info { - - struct r3964_message *first_msg; - struct r3964_message *last_msg; -- struct r3964_block_header *next_block_to_read; -+ struct rx_block_header *next_block_to_read; - int msg_count; - }; - --struct r3964_block_header; -- - /* internal version of client_message: */ - struct r3964_message { - int msg_id; - int arg; - int error_code; -- struct r3964_block_header *block; -+ struct rx_block_header *block; - struct r3964_message *next; - }; - --/* Header of received block in rx_buf/tx_buf: */ --struct r3964_block_header { -+/* Header of received block in rx_buf: */ -+struct rx_block_header { - unsigned int length; /* length in chars without header */ - unsigned char *data; /* usually data is located immediately - * behind this struct */ - unsigned int locks; /* only used in rx_buffer */ - -- struct r3964_block_header *next; -- struct r3964_client_info *owner; /* =NULL in rx_buffer */ -+ struct rx_block_header *next; -+}; -+ -+/* Header of received block in tx_buf: */ -+struct tx_block_header { -+ unsigned int length; /* length in chars without header */ -+ unsigned char *data; -+ struct tx_block_header *next; -+ struct r3964_client_info *owner; - }; - - /* -@@ -162,10 +169,10 @@ struct r3964_info { - unsigned char *rx_buf; /* ring buffer */ - unsigned char *tx_buf; - -- struct r3964_block_header *rx_first; -- struct r3964_block_header *rx_last; -- struct r3964_block_header *tx_first; -- struct r3964_block_header *tx_last; -+ struct rx_block_header *rx_first; -+ struct rx_block_header *rx_last; -+ struct tx_block_header *tx_first; -+ struct tx_block_header *tx_last; - unsigned int tx_position; - unsigned int rx_position; - unsigned char last_rx; -@@ -182,8 +189,6 @@ struct r3964_info { - int nRetry; - }; - --static void add_tx_queue(struct r3964_info *, struct r3964_block_header *); --static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code); - static void put_char(struct r3964_info *pInfo, unsigned char ch); - static void trigger_transmit(struct r3964_info *pInfo); - static void retry_transmit(struct r3964_info *pInfo); -@@ -195,7 +200,7 @@ static int enable_signals(struct r3964_i - static int read_telegram(struct r3964_info *pInfo, struct pid *pid, - unsigned char __user * buf); - static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg, -- int error_code, struct r3964_block_header *pBlock); -+ int error_code, struct rx_block_header *pBlock); - static struct r3964_message *remove_msg(struct r3964_info *pInfo, - struct r3964_client_info *pClient); - static void remove_client_block(struct r3964_info *pInfo, -@@ -306,7 +311,7 @@ module_exit(r3964_exit); - *************************************************************/ - - static void add_tx_queue(struct r3964_info *pInfo, -- struct r3964_block_header *pHeader) -+ struct tx_block_header *pHeader) - { - unsigned long flags; - -@@ -329,10 +334,10 @@ static void add_tx_queue(struct r3964_in - - static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code) - { -- struct r3964_block_header *pHeader; -+ struct tx_block_header *pHeader; - unsigned long flags; - #ifdef DEBUG_QUEUE -- struct r3964_block_header *pDump; -+ struct tx_block_header *pDump; - #endif - - pHeader = pInfo->tx_first; -@@ -376,7 +381,7 @@ static void remove_from_tx_queue(struct - } - - static void add_rx_queue(struct r3964_info *pInfo, -- struct r3964_block_header *pHeader) -+ struct rx_block_header *pHeader) - { - unsigned long flags; - -@@ -400,10 +405,10 @@ static void add_rx_queue(struct r3964_in - } - - static void remove_from_rx_queue(struct r3964_info *pInfo, -- struct r3964_block_header *pHeader) -+ struct rx_block_header *pHeader) - { - unsigned long flags; -- struct r3964_block_header *pFind; -+ struct rx_block_header *pFind; - - if (pHeader == NULL) - return; -@@ -517,7 +522,7 @@ static void retry_transmit(struct r3964_ - static void transmit_block(struct r3964_info *pInfo) - { - struct tty_struct *tty = pInfo->tty; -- struct r3964_block_header *pBlock = pInfo->tx_first; -+ struct tx_block_header *pBlock = pInfo->tx_first; - int room = 0; - - if (tty == NULL || pBlock == NULL) { -@@ -558,7 +563,7 @@ static void on_receive_block(struct r396 - { - unsigned int length; - struct r3964_client_info *pClient; -- struct r3964_block_header *pBlock; -+ struct rx_block_header *pBlock; - unsigned long flags; - - length = pInfo->rx_position; -@@ -596,20 +601,17 @@ static void on_receive_block(struct r396 - del_timer_sync(&pInfo->tmr); - TRACE_PS(" rx success: got %d chars", length); - -- /* prepare struct r3964_block_header: */ -- pBlock = kmalloc(length + sizeof(struct r3964_block_header), -- GFP_KERNEL); -+ /* prepare struct rx_block_header: */ -+ pBlock = kmalloc(length + sizeof(*pBlock), GFP_KERNEL); - TRACE_M("on_receive_block - kmalloc %p", pBlock); - - if (pBlock == NULL) - return; - - pBlock->length = length; -- pBlock->data = ((unsigned char *)pBlock) + -- sizeof(struct r3964_block_header); -+ pBlock->data = ((unsigned char *)pBlock) + sizeof(*pBlock); - pBlock->locks = 0; - pBlock->next = NULL; -- pBlock->owner = NULL; - - memcpy(pBlock->data, pInfo->rx_buf, length); - -@@ -904,7 +906,7 @@ static int read_telegram(struct r3964_in - unsigned char __user * buf) - { - struct r3964_client_info *pClient; -- struct r3964_block_header *block; -+ struct rx_block_header *block; - - if (!buf) { - return -EINVAL; -@@ -930,7 +932,7 @@ static int read_telegram(struct r3964_in - } - - static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg, -- int error_code, struct r3964_block_header *pBlock) -+ int error_code, struct rx_block_header *pBlock) - { - struct r3964_message *pMsg; - unsigned long flags; -@@ -1013,7 +1015,7 @@ static struct r3964_message *remove_msg( - static void remove_client_block(struct r3964_info *pInfo, - struct r3964_client_info *pClient) - { -- struct r3964_block_header *block; -+ struct rx_block_header *block; - - TRACE_PS("remove_client_block PID %d", pid_nr(pClient->pid)); - -@@ -1097,7 +1099,7 @@ static void r3964_close(struct tty_struc - struct r3964_info *pInfo = tty->disc_data; - struct r3964_client_info *pClient, *pNext; - struct r3964_message *pMsg; -- struct r3964_block_header *pHeader, *pNextHeader; -+ struct tx_block_header *pHeader, *pNextHeader; - unsigned long flags; - - TRACE_L("close"); -@@ -1211,7 +1213,7 @@ static ssize_t r3964_write(struct tty_st - const unsigned char *data, size_t count) - { - struct r3964_info *pInfo = tty->disc_data; -- struct r3964_block_header *pHeader; -+ struct tx_block_header *pHeader; - struct r3964_client_info *pClient; - unsigned char *new_data; - -@@ -1236,8 +1238,7 @@ static ssize_t r3964_write(struct tty_st - /* - * Allocate a buffer for the data and copy it from the buffer with header prepended - */ -- new_data = kmalloc(count + sizeof(struct r3964_block_header), -- GFP_KERNEL); -+ new_data = kmalloc(count + sizeof(*pHeader), GFP_KERNEL); - TRACE_M("r3964_write - kmalloc %p", new_data); - if (new_data == NULL) { - if (pInfo->flags & R3964_DEBUG) { -@@ -1246,10 +1247,9 @@ static ssize_t r3964_write(struct tty_st - return -ENOSPC; - } - -- pHeader = (struct r3964_block_header *)new_data; -- pHeader->data = new_data + sizeof(struct r3964_block_header); -+ pHeader = (struct tx_block_header *)new_data; -+ pHeader->data = new_data + sizeof(*pHeader); - pHeader->length = count; -- pHeader->locks = 0; - pHeader->owner = NULL; - - pClient = findClient(pInfo, task_pid(current)); diff --git a/0006-tty-n_r3964-for-tx_blocks-use-a-real-kernel-list.patch b/0006-tty-n_r3964-for-tx_blocks-use-a-real-kernel-list.patch deleted file mode 100644 index 7363811ee053a4..00000000000000 --- a/0006-tty-n_r3964-for-tx_blocks-use-a-real-kernel-list.patch +++ /dev/null @@ -1,182 +0,0 @@ -From 55124901b0e4b05999669830cf6e0b240f8cb2fd Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Thu, 24 Jan 2019 13:35:36 +0100 -Subject: [PATCH 06/15] tty: n_r3964: for tx_blocks, use a real kernel list - -The tx blocks have a hand-rolled linked list structure, use a "normal" -kernel list structure instead, making the code smaller and easier to -understand and verify that it really does what we think it should be -doing. - -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 85 +++++++++++++++----------------------------------- - 1 file changed, 26 insertions(+), 59 deletions(-) - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -140,7 +140,7 @@ struct rx_block_header { - struct tx_block_header { - unsigned int length; /* length in chars without header */ - unsigned char *data; -- struct tx_block_header *next; -+ struct list_head node; - struct r3964_client_info *owner; - }; - -@@ -171,8 +171,7 @@ struct r3964_info { - - struct rx_block_header *rx_first; - struct rx_block_header *rx_last; -- struct tx_block_header *tx_first; -- struct tx_block_header *tx_last; -+ struct list_head tx_blocks; - unsigned int tx_position; - unsigned int rx_position; - unsigned char last_rx; -@@ -316,42 +315,25 @@ static void add_tx_queue(struct r3964_in - unsigned long flags; - - spin_lock_irqsave(&pInfo->lock, flags); -- -- pHeader->next = NULL; -- -- if (pInfo->tx_last == NULL) { -- pInfo->tx_first = pInfo->tx_last = pHeader; -- } else { -- pInfo->tx_last->next = pHeader; -- pInfo->tx_last = pHeader; -- } -- -+ list_add_tail(&pHeader->node, &pInfo->tx_blocks); - spin_unlock_irqrestore(&pInfo->lock, flags); -- -- TRACE_Q("add_tx_queue %p, length %d, tx_first = %p", -- pHeader, pHeader->length, pInfo->tx_first); - } - - static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code) - { - struct tx_block_header *pHeader; - unsigned long flags; --#ifdef DEBUG_QUEUE -- struct tx_block_header *pDump; --#endif - -- pHeader = pInfo->tx_first; -- -- if (pHeader == NULL) -+ spin_lock_irqsave(&pInfo->lock, flags); -+ if (list_empty(&pInfo->tx_blocks)) { -+ spin_unlock_irqrestore(&pInfo->lock, flags); - return; -+ } - --#ifdef DEBUG_QUEUE -- printk("r3964: remove_from_tx_queue: %p, length %u - ", -- pHeader, pHeader->length); -- for (pDump = pHeader; pDump; pDump = pDump->next) -- printk("%p ", pDump); -- printk("\n"); --#endif -+ pHeader = list_first_entry(&pInfo->tx_blocks, struct tx_block_header, -+ node); -+ list_del(&pHeader->node); -+ spin_unlock_irqrestore(&pInfo->lock, flags); - - if (pHeader->owner) { - if (error_code) { -@@ -364,20 +346,7 @@ static void remove_from_tx_queue(struct - wake_up_interruptible(&pInfo->tty->read_wait); - } - -- spin_lock_irqsave(&pInfo->lock, flags); -- -- pInfo->tx_first = pHeader->next; -- if (pInfo->tx_first == NULL) { -- pInfo->tx_last = NULL; -- } -- -- spin_unlock_irqrestore(&pInfo->lock, flags); -- - kfree(pHeader); -- TRACE_M("remove_from_tx_queue - kfree %p", pHeader); -- -- TRACE_Q("remove_from_tx_queue: tx_first = %p, tx_last = %p", -- pInfo->tx_first, pInfo->tx_last); - } - - static void add_rx_queue(struct r3964_info *pInfo, -@@ -476,7 +445,7 @@ static void trigger_transmit(struct r396 - - spin_lock_irqsave(&pInfo->lock, flags); - -- if ((pInfo->state == R3964_IDLE) && (pInfo->tx_first != NULL)) { -+ if ((pInfo->state == R3964_IDLE) && (!list_empty(&pInfo->tx_blocks))) { - pInfo->state = R3964_TX_REQUEST; - pInfo->nRetry = 0; - pInfo->flags &= ~R3964_ERROR; -@@ -522,17 +491,19 @@ static void retry_transmit(struct r3964_ - static void transmit_block(struct r3964_info *pInfo) - { - struct tty_struct *tty = pInfo->tty; -- struct tx_block_header *pBlock = pInfo->tx_first; -- int room = 0; -+ struct tx_block_header *pBlock; -+ int room; - -- if (tty == NULL || pBlock == NULL) { -+ if (!tty) - return; -- } - -- room = tty_write_room(tty); -+ if (list_empty(&pInfo->tx_blocks)) -+ return; - -- TRACE_PS("transmit_block %p, room %d, length %d", -- pBlock, room, pBlock->length); -+ pBlock = list_first_entry(&pInfo->tx_blocks, struct tx_block_header, -+ node); -+ -+ room = tty_write_room(tty); - - while (pInfo->tx_position < pBlock->length) { - if (room < 2) -@@ -1076,7 +1047,7 @@ static int r3964_open(struct tty_struct - pInfo->tty = tty; - pInfo->priority = R3964_MASTER; - pInfo->rx_first = pInfo->rx_last = NULL; -- pInfo->tx_first = pInfo->tx_last = NULL; -+ INIT_LIST_HEAD(&pInfo->tx_blocks); - pInfo->rx_position = 0; - pInfo->tx_position = 0; - pInfo->last_rx = 0; -@@ -1099,7 +1070,7 @@ static void r3964_close(struct tty_struc - struct r3964_info *pInfo = tty->disc_data; - struct r3964_client_info *pClient, *pNext; - struct r3964_message *pMsg; -- struct tx_block_header *pHeader, *pNextHeader; -+ struct tx_block_header *pHeader, *tmp; - unsigned long flags; - - TRACE_L("close"); -@@ -1128,15 +1099,11 @@ static void r3964_close(struct tty_struc - } - /* Remove jobs from tx_queue: */ - spin_lock_irqsave(&pInfo->lock, flags); -- pHeader = pInfo->tx_first; -- pInfo->tx_first = pInfo->tx_last = NULL; -- spin_unlock_irqrestore(&pInfo->lock, flags); -- -- while (pHeader) { -- pNextHeader = pHeader->next; -+ list_for_each_entry_safe(pHeader, tmp, &pInfo->tx_blocks, node) { -+ list_del(&pHeader->node); - kfree(pHeader); -- pHeader = pNextHeader; - } -+ spin_unlock_irqrestore(&pInfo->lock, flags); - - /* Free buffers: */ - kfree(pInfo->rx_buf); diff --git a/0007-tty-n_r3964-for-rx_blocks-use-a-real-kernel-list.patch b/0007-tty-n_r3964-for-rx_blocks-use-a-real-kernel-list.patch deleted file mode 100644 index 7e00cf063d8327..00000000000000 --- a/0007-tty-n_r3964-for-rx_blocks-use-a-real-kernel-list.patch +++ /dev/null @@ -1,136 +0,0 @@ -From c711e9d95e2fbc99dc88c0797f58194ade169258 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Thu, 24 Jan 2019 16:04:54 +0100 -Subject: [PATCH 07/15] tty: n_r3964: for rx_blocks, use a real kernel list - -The rx blocks have a hand-rolled linked list structure, use a "normal" -kernel list structure instead, making the code smaller and easier to -understand and verify that it really does what we think it should be -doing. - -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 67 +++++++++----------------------------------------- - 1 file changed, 13 insertions(+), 54 deletions(-) - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -132,8 +132,7 @@ struct rx_block_header { - unsigned char *data; /* usually data is located immediately - * behind this struct */ - unsigned int locks; /* only used in rx_buffer */ -- -- struct rx_block_header *next; -+ struct list_head node; - }; - - /* Header of received block in tx_buf: */ -@@ -169,8 +168,7 @@ struct r3964_info { - unsigned char *rx_buf; /* ring buffer */ - unsigned char *tx_buf; - -- struct rx_block_header *rx_first; -- struct rx_block_header *rx_last; -+ struct list_head rx_blocks; - struct list_head tx_blocks; - unsigned int tx_position; - unsigned int rx_position; -@@ -355,71 +353,32 @@ static void add_rx_queue(struct r3964_in - unsigned long flags; - - spin_lock_irqsave(&pInfo->lock, flags); -- -- pHeader->next = NULL; -- -- if (pInfo->rx_last == NULL) { -- pInfo->rx_first = pInfo->rx_last = pHeader; -- } else { -- pInfo->rx_last->next = pHeader; -- pInfo->rx_last = pHeader; -- } -- pInfo->blocks_in_rx_queue++; -- -+ list_add_tail(&pHeader->node, &pInfo->rx_blocks); - spin_unlock_irqrestore(&pInfo->lock, flags); -- -- TRACE_Q("add_rx_queue: %p, length = %d, rx_first = %p, count = %d", -- pHeader, pHeader->length, -- pInfo->rx_first, pInfo->blocks_in_rx_queue); - } - - static void remove_from_rx_queue(struct r3964_info *pInfo, - struct rx_block_header *pHeader) - { -+ struct rx_block_header *pFind, *tmp; - unsigned long flags; -- struct rx_block_header *pFind; - - if (pHeader == NULL) - return; - -- TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d", -- pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue); -- TRACE_Q("remove_from_rx_queue: %p, length %u", -- pHeader, pHeader->length); -- - spin_lock_irqsave(&pInfo->lock, flags); -- -- if (pInfo->rx_first == pHeader) { -- /* Remove the first block in the linked list: */ -- pInfo->rx_first = pHeader->next; -- -- if (pInfo->rx_first == NULL) { -- pInfo->rx_last = NULL; -- } -- pInfo->blocks_in_rx_queue--; -- } else { -- /* Find block to remove: */ -- for (pFind = pInfo->rx_first; pFind; pFind = pFind->next) { -- if (pFind->next == pHeader) { -- /* Got it. */ -- pFind->next = pHeader->next; -- pInfo->blocks_in_rx_queue--; -- if (pFind->next == NULL) { -- /* Oh, removed the last one! */ -- pInfo->rx_last = pFind; -- } -- break; -- } -+ list_for_each_entry_safe(pFind, tmp, &pInfo->rx_blocks, node) { -+ if (pFind == pHeader) { -+ /* Got it. */ -+ list_del(&pFind->node); -+ pInfo->blocks_in_rx_queue--; -+ goto exit; - } - } -- -+exit: - spin_unlock_irqrestore(&pInfo->lock, flags); - - kfree(pHeader); -- TRACE_M("remove_from_rx_queue - kfree %p", pHeader); -- -- TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d", -- pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue); - } - - static void put_char(struct r3964_info *pInfo, unsigned char ch) -@@ -582,7 +541,7 @@ static void on_receive_block(struct r396 - pBlock->length = length; - pBlock->data = ((unsigned char *)pBlock) + sizeof(*pBlock); - pBlock->locks = 0; -- pBlock->next = NULL; -+ INIT_LIST_HEAD(&pBlock->node); - - memcpy(pBlock->data, pInfo->rx_buf, length); - -@@ -1046,7 +1005,7 @@ static int r3964_open(struct tty_struct - mutex_init(&pInfo->read_lock); - pInfo->tty = tty; - pInfo->priority = R3964_MASTER; -- pInfo->rx_first = pInfo->rx_last = NULL; -+ INIT_LIST_HEAD(&pInfo->rx_blocks); - INIT_LIST_HEAD(&pInfo->tx_blocks); - pInfo->rx_position = 0; - pInfo->tx_position = 0; diff --git a/0008-tty-n_r3964-don-t-hand-roll-a-reference-count.patch b/0008-tty-n_r3964-don-t-hand-roll-a-reference-count.patch deleted file mode 100644 index 883505b548a82d..00000000000000 --- a/0008-tty-n_r3964-don-t-hand-roll-a-reference-count.patch +++ /dev/null @@ -1,155 +0,0 @@ -From 6e885d94ba582aec3e689d94b3b2deb3570a5e06 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Thu, 24 Jan 2019 16:44:28 +0100 -Subject: [PATCH 08/15] tty: n_r3964: don't hand-roll a reference count - -rx_block_header had a "locks" variable that was trying to be a reference -count on the header. When it would drop to zero, the memory would be -freed. Convert this to be a kref instead to handle the housekeeping for -doing reference counting properly. - -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 61 ++++++++++++++++++++++---------------------------- - 1 file changed, 28 insertions(+), 33 deletions(-) - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -26,6 +26,7 @@ - #include <linux/param.h> - #include <linux/poll.h> - #include <linux/init.h> -+#include <linux/kref.h> - #include <linux/uaccess.h> - #include <uapi/linux/n_r3964.h> - -@@ -131,8 +132,9 @@ struct rx_block_header { - unsigned int length; /* length in chars without header */ - unsigned char *data; /* usually data is located immediately - * behind this struct */ -- unsigned int locks; /* only used in rx_buffer */ - struct list_head node; -+ struct kref kref; -+ struct r3964_info *info; - }; - - /* Header of received block in tx_buf: */ -@@ -200,8 +202,7 @@ static void add_msg(struct r3964_client_ - int error_code, struct rx_block_header *pBlock); - static struct r3964_message *remove_msg(struct r3964_info *pInfo, - struct r3964_client_info *pClient); --static void remove_client_block(struct r3964_info *pInfo, -- struct r3964_client_info *pClient); -+static void remove_client_block(struct r3964_client_info *pClient); - - static int r3964_open(struct tty_struct *tty); - static void r3964_close(struct tty_struct *tty); -@@ -357,28 +358,28 @@ static void add_rx_queue(struct r3964_in - spin_unlock_irqrestore(&pInfo->lock, flags); - } - --static void remove_from_rx_queue(struct r3964_info *pInfo, -- struct rx_block_header *pHeader) -+static void remove_from_rx_queue(struct kref *kref) - { -- struct rx_block_header *pFind, *tmp; -+ struct rx_block_header *header, *find; -+ struct r3964_info *info; - unsigned long flags; - -- if (pHeader == NULL) -- return; -+ header = container_of(kref, struct rx_block_header, kref); -+ info = header->info; - -- spin_lock_irqsave(&pInfo->lock, flags); -- list_for_each_entry_safe(pFind, tmp, &pInfo->rx_blocks, node) { -- if (pFind == pHeader) { -+ spin_lock_irqsave(&info->lock, flags); -+ list_for_each_entry(find, &info->rx_blocks, node) { -+ if (find == header) { - /* Got it. */ -- list_del(&pFind->node); -- pInfo->blocks_in_rx_queue--; -+ list_del(&find->node); -+ info->blocks_in_rx_queue--; - goto exit; - } - } - exit: -- spin_unlock_irqrestore(&pInfo->lock, flags); -+ spin_unlock_irqrestore(&info->lock, flags); - -- kfree(pHeader); -+ kfree(header); - } - - static void put_char(struct r3964_info *pInfo, unsigned char ch) -@@ -540,7 +541,8 @@ static void on_receive_block(struct r396 - - pBlock->length = length; - pBlock->data = ((unsigned char *)pBlock) + sizeof(*pBlock); -- pBlock->locks = 0; -+ pBlock->info = pInfo; -+ kref_init(&pBlock->kref); - INIT_LIST_HEAD(&pBlock->node); - - memcpy(pBlock->data, pInfo->rx_buf, length); -@@ -854,7 +856,7 @@ static int read_telegram(struct r3964_in - if (copy_to_user(buf, block->data, block->length)) - return -EFAULT; - -- remove_client_block(pInfo, pClient); -+ remove_client_block(pClient); - return block->length; - } - -@@ -893,9 +895,9 @@ queue_the_message: - - pClient->msg_count++; - -- if (pBlock != NULL) { -- pBlock->locks++; -- } -+ if (pBlock != NULL) -+ kref_get(&pBlock->kref); -+ - spin_unlock_irqrestore(&pClient->lock, flags); - } else { - if ((pClient->last_msg->msg_id == R3964_MSG_ACK) -@@ -934,7 +936,7 @@ static struct r3964_message *remove_msg( - - pClient->msg_count--; - if (pMsg->block) { -- remove_client_block(pInfo, pClient); -+ remove_client_block(pClient); - pClient->next_block_to_read = pMsg->block; - } - spin_unlock_irqrestore(&pClient->lock, flags); -@@ -942,21 +944,14 @@ static struct r3964_message *remove_msg( - return pMsg; - } - --static void remove_client_block(struct r3964_info *pInfo, -- struct r3964_client_info *pClient) -+static void remove_client_block(struct r3964_client_info *client) - { - struct rx_block_header *block; - -- TRACE_PS("remove_client_block PID %d", pid_nr(pClient->pid)); -- -- block = pClient->next_block_to_read; -- if (block) { -- block->locks--; -- if (block->locks == 0) { -- remove_from_rx_queue(pInfo, block); -- } -- } -- pClient->next_block_to_read = NULL; -+ block = client->next_block_to_read; -+ if (block) -+ kref_put(&block->kref, remove_from_rx_queue); -+ client->next_block_to_read = NULL; - } - - /************************************************************* diff --git a/0009-tty-n_r3964-for-messages-use-a-real-kernel-list.patch b/0009-tty-n_r3964-for-messages-use-a-real-kernel-list.patch deleted file mode 100644 index 02042fadda9567..00000000000000 --- a/0009-tty-n_r3964-for-messages-use-a-real-kernel-list.patch +++ /dev/null @@ -1,265 +0,0 @@ -From df04ddde6d9577c3cf230e725f36ae2480908040 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Thu, 24 Jan 2019 17:43:52 +0100 -Subject: [PATCH 09/15] tty: n_r3964: for messages, use a real kernel list - -The message list associated with a client was a hand-rolled linked list -structure, so use a "normal" kernel list structure instead. This makes -the code smaller and simpler to understand. - -In doing so, fix up a number of locking mistakes where the proper lock -was not being held for every time the client message list was being -accessed. - -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 136 +++++++++++++++++++++++--------------------------- - 1 file changed, 64 insertions(+), 72 deletions(-) - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -101,7 +101,6 @@ enum { - - /* All open file-handles are 'clients' and are stored in a linked list: */ - --struct r3964_message; - struct rx_block_header; - struct tx_block_header; - -@@ -112,8 +111,7 @@ struct r3964_client_info { - - struct r3964_client_info *next; - -- struct r3964_message *first_msg; -- struct r3964_message *last_msg; -+ struct list_head msgs; - struct rx_block_header *next_block_to_read; - int msg_count; - }; -@@ -124,7 +122,7 @@ struct r3964_message { - int arg; - int error_code; - struct rx_block_header *block; -- struct r3964_message *next; -+ struct list_head node; - }; - - /* Header of received block in rx_buf: */ -@@ -200,8 +198,7 @@ static int read_telegram(struct r3964_in - unsigned char __user * buf); - static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg, - int error_code, struct rx_block_header *pBlock); --static struct r3964_message *remove_msg(struct r3964_info *pInfo, -- struct r3964_client_info *pClient); -+static struct r3964_message *remove_msg(struct r3964_client_info *client); - static void remove_client_block(struct r3964_client_info *pClient); - - static int r3964_open(struct tty_struct *tty); -@@ -787,7 +784,7 @@ static int enable_signals(struct r3964_i - pid_nr(pid)); - *ppClient = pClient->next; - while (pClient->msg_count) { -- pMsg = remove_msg(pInfo, pClient); -+ pMsg = remove_msg(pClient); - if (pMsg) { - kfree(pMsg); - TRACE_M("enable_signals - msg " -@@ -822,8 +819,7 @@ static int enable_signals(struct r3964_i - pClient->sig_flags = arg; - pClient->pid = get_pid(pid); - pClient->next = pInfo->firstClient; -- pClient->first_msg = NULL; -- pClient->last_msg = NULL; -+ INIT_LIST_HEAD(&pClient->msgs); - pClient->next_block_to_read = NULL; - pClient->msg_count = 0; - pInfo->firstClient = pClient; -@@ -863,85 +859,83 @@ static int read_telegram(struct r3964_in - return -EINVAL; - } - --static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg, -- int error_code, struct rx_block_header *pBlock) -+static void __add_msg(struct r3964_client_info *pClient, int msg_id, int arg, -+ int error_code, struct rx_block_header *pBlock) -+ __must_hold(&pClient->lock) - { - struct r3964_message *pMsg; -- unsigned long flags; -- -- if (pClient->msg_count < R3964_MAX_MSG_COUNT - 1) { --queue_the_message: - -- pMsg = kmalloc(sizeof(*pMsg), GFP_ATOMIC); -- TRACE_M("add_msg - kmalloc %p", pMsg); -- if (pMsg == NULL) { -- return; -- } -+ pMsg = kmalloc(sizeof(*pMsg), GFP_ATOMIC); -+ if (pMsg == NULL) -+ return; - -- spin_lock_irqsave(&pClient->lock, flags); -+ pMsg->msg_id = msg_id; -+ pMsg->arg = arg; -+ pMsg->error_code = error_code; -+ pMsg->block = pBlock; -+ INIT_LIST_HEAD(&pMsg->node); - -- pMsg->msg_id = msg_id; -- pMsg->arg = arg; -- pMsg->error_code = error_code; -- pMsg->block = pBlock; -- pMsg->next = NULL; -+ list_add_tail(&pMsg->node, &pClient->msgs); -+ pClient->msg_count++; - -- if (pClient->last_msg == NULL) { -- pClient->first_msg = pClient->last_msg = pMsg; -- } else { -- pClient->last_msg->next = pMsg; -- pClient->last_msg = pMsg; -- } -+ if (pBlock != NULL) -+ kref_get(&pBlock->kref); -+} - -- pClient->msg_count++; -+static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg, -+ int error_code, struct rx_block_header *pBlock) -+{ -+ struct r3964_message *pMsg; -+ unsigned long flags; - -- if (pBlock != NULL) -- kref_get(&pBlock->kref); -+ spin_lock_irqsave(&pClient->lock, flags); - -- spin_unlock_irqrestore(&pClient->lock, flags); -+ if (pClient->msg_count < R3964_MAX_MSG_COUNT - 1) { -+ __add_msg(pClient, msg_id, arg, error_code, pBlock); - } else { -- if ((pClient->last_msg->msg_id == R3964_MSG_ACK) -- && (pClient->last_msg->error_code == R3964_OVERFLOW)) { -- pClient->last_msg->arg++; -- TRACE_PE("add_msg - inc prev OVERFLOW-msg"); -+ if (!list_empty(&pClient->msgs)) { -+ pMsg = list_last_entry(&pClient->msgs, -+ struct r3964_message, node); -+ if ((pMsg->msg_id == R3964_MSG_ACK) && -+ (pMsg->error_code == R3964_OVERFLOW)) { -+ pMsg->arg++; -+ TRACE_PE("add_msg - inc prev OVERFLOW-msg"); -+ } - } else { -- msg_id = R3964_MSG_ACK; -- arg = 0; -- error_code = R3964_OVERFLOW; -- pBlock = NULL; -+ __add_msg(pClient, R3964_MSG_ACK, 0, R3964_OVERFLOW, -+ pBlock); - TRACE_PE("add_msg - queue OVERFLOW-msg"); -- goto queue_the_message; - } - } -+ spin_unlock_irqrestore(&pClient->lock, flags); -+ - /* Send SIGIO signal to client process: */ - if (pClient->sig_flags & R3964_USE_SIGIO) { - kill_pid(pClient->pid, SIGIO, 1); - } - } - --static struct r3964_message *remove_msg(struct r3964_info *pInfo, -- struct r3964_client_info *pClient) -+static struct r3964_message *remove_msg(struct r3964_client_info *client) - { -- struct r3964_message *pMsg = NULL; -+ struct r3964_message *msg = NULL; - unsigned long flags; - -- if (pClient->first_msg) { -- spin_lock_irqsave(&pClient->lock, flags); -- -- pMsg = pClient->first_msg; -- pClient->first_msg = pMsg->next; -- if (pClient->first_msg == NULL) { -- pClient->last_msg = NULL; -- } -- -- pClient->msg_count--; -- if (pMsg->block) { -- remove_client_block(pClient); -- pClient->next_block_to_read = pMsg->block; -- } -- spin_unlock_irqrestore(&pClient->lock, flags); -+ spin_lock_irqsave(&client->lock, flags); -+ if (list_empty(&client->msgs)) { -+ spin_unlock_irqrestore(&client->lock, flags); -+ return NULL; -+ } -+ -+ msg = list_first_entry(&client->msgs, struct r3964_message, node); -+ list_del(&msg->node); -+ -+ client->msg_count--; -+ if (msg->block) { -+ remove_client_block(client); -+ client->next_block_to_read = msg->block; - } -- return pMsg; -+ spin_unlock_irqrestore(&client->lock, flags); -+ return msg; - } - - static void remove_client_block(struct r3964_client_info *client) -@@ -1040,7 +1034,7 @@ static void r3964_close(struct tty_struc - while (pClient) { - pNext = pClient->next; - while (pClient->msg_count) { -- pMsg = remove_msg(pInfo, pClient); -+ pMsg = remove_msg(pClient); - if (pMsg) { - kfree(pMsg); - TRACE_M("r3964_close - msg kfree %p", pMsg); -@@ -1091,7 +1085,7 @@ static ssize_t r3964_read(struct tty_str - - pClient = findClient(pInfo, task_pid(current)); - if (pClient) { -- pMsg = remove_msg(pInfo, pClient); -+ pMsg = remove_msg(pClient); - if (pMsg == NULL) { - /* no messages available. */ - if (tty_io_nonblock(tty, file)) { -@@ -1100,7 +1094,7 @@ static ssize_t r3964_read(struct tty_str - } - /* block until there is a message: */ - wait_event_interruptible(tty->read_wait, -- (pMsg = remove_msg(pInfo, pClient))); -+ (pMsg = remove_msg(pClient))); - } - - /* If we still haven't got a message, we must have been signalled */ -@@ -1264,7 +1258,6 @@ static __poll_t r3964_poll(struct tty_st - { - struct r3964_info *pInfo = tty->disc_data; - struct r3964_client_info *pClient; -- struct r3964_message *pMsg = NULL; - unsigned long flags; - __poll_t result = EPOLLOUT; - -@@ -1273,11 +1266,10 @@ static __poll_t r3964_poll(struct tty_st - pClient = findClient(pInfo, task_pid(current)); - if (pClient) { - poll_wait(file, &tty->read_wait, wait); -- spin_lock_irqsave(&pInfo->lock, flags); -- pMsg = pClient->first_msg; -- spin_unlock_irqrestore(&pInfo->lock, flags); -- if (pMsg) -+ spin_lock_irqsave(&pClient->lock, flags); -+ if (!list_empty(&pClient->msgs)) - result |= EPOLLIN | EPOLLRDNORM; -+ spin_unlock_irqrestore(&pClient->lock, flags); - } else { - result = EPOLLNVAL | EPOLLERR; - } diff --git a/0010-tty-n_r3964-for-clients-use-a-real-kernel-list.patch b/0010-tty-n_r3964-for-clients-use-a-real-kernel-list.patch deleted file mode 100644 index ada55bb6e6aec1..00000000000000 --- a/0010-tty-n_r3964-for-clients-use-a-real-kernel-list.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 336b06e9db65482b6146e112670cff7e4e52c7ef Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Fri, 25 Jan 2019 09:35:45 +0100 -Subject: [PATCH 10/15] tty: n_r3964: for clients, use a real kernel list - -The "info" structure had a hand-rolled linked list of all of the clients -associated with it. Convert that over to a kernel list structure, -making the logic a lot simpler and easier to understand. - -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 31 ++++++++++++------------------- - 1 file changed, 12 insertions(+), 19 deletions(-) - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -109,8 +109,7 @@ struct r3964_client_info { - struct pid *pid; - unsigned int sig_flags; - -- struct r3964_client_info *next; -- -+ struct list_head node; - struct list_head msgs; - struct rx_block_header *next_block_to_read; - int msg_count; -@@ -178,7 +177,7 @@ struct r3964_info { - - struct mutex read_lock; /* serialize read and ioctl */ - -- struct r3964_client_info *firstClient; -+ struct list_head clients; - unsigned int state; - unsigned int flags; - -@@ -549,7 +548,7 @@ static void on_receive_block(struct r396 - - /* notify attached client processes: */ - spin_lock_irqsave(&pInfo->lock, flags); -- for (pClient = pInfo->firstClient; pClient; pClient = pClient->next) { -+ list_for_each_entry(pClient, &pInfo->clients, node) { - if (pClient->sig_flags & R3964_SIG_DATA) { - add_msg(pClient, R3964_MSG_DATA, length, R3964_OK, - pBlock); -@@ -754,11 +753,12 @@ static struct r3964_client_info *findCli - unsigned long flags; - - spin_lock_irqsave(&pInfo->lock, flags); -- for (pClient = pInfo->firstClient; pClient; pClient = pClient->next) { -+ list_for_each_entry(pClient, &pInfo->clients, node) { - if (pClient->pid == pid) { - goto exit; - } - } -+ pClient = NULL; - exit: - spin_unlock_irqrestore(&pInfo->lock, flags); - return pClient; -@@ -767,7 +767,6 @@ exit: - static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg) - { - struct r3964_client_info *pClient; -- struct r3964_client_info **ppClient; - struct r3964_message *pMsg; - unsigned long flags; - -@@ -775,14 +774,10 @@ static int enable_signals(struct r3964_i - spin_lock_irqsave(&pInfo->lock, flags); - - /* Remove client from client list */ -- for (ppClient = &pInfo->firstClient; *ppClient; -- ppClient = &(*ppClient)->next) { -- pClient = *ppClient; -- -+ list_for_each_entry(pClient, &pInfo->clients, node) { - if (pClient->pid == pid) { - TRACE_PS("removing client %d from client list", - pid_nr(pid)); -- *ppClient = pClient->next; - while (pClient->msg_count) { - pMsg = remove_msg(pClient); - if (pMsg) { -@@ -792,6 +787,7 @@ static int enable_signals(struct r3964_i - } - } - put_pid(pClient->pid); -+ list_del(&pClient->node); - kfree(pClient); - TRACE_M("enable_signals - kfree %p", pClient); - spin_unlock_irqrestore(&pInfo->lock, flags); -@@ -818,11 +814,10 @@ static int enable_signals(struct r3964_i - spin_lock_init(&pClient->lock); - pClient->sig_flags = arg; - pClient->pid = get_pid(pid); -- pClient->next = pInfo->firstClient; - INIT_LIST_HEAD(&pClient->msgs); - pClient->next_block_to_read = NULL; - pClient->msg_count = 0; -- pInfo->firstClient = pClient; -+ list_add(&pClient->node, &pInfo->clients); - spin_unlock_irqrestore(&pInfo->lock, flags); - } - } -@@ -1000,7 +995,7 @@ static int r3964_open(struct tty_struct - pInfo->tx_position = 0; - pInfo->last_rx = 0; - pInfo->blocks_in_rx_queue = 0; -- pInfo->firstClient = NULL; -+ INIT_LIST_HEAD(&pInfo->clients); - pInfo->state = R3964_IDLE; - pInfo->flags = R3964_DEBUG; - pInfo->nRetry = 0; -@@ -1016,7 +1011,7 @@ static int r3964_open(struct tty_struct - static void r3964_close(struct tty_struct *tty) - { - struct r3964_info *pInfo = tty->disc_data; -- struct r3964_client_info *pClient, *pNext; -+ struct r3964_client_info *pClient, *tmp_client; - struct r3964_message *pMsg; - struct tx_block_header *pHeader, *tmp; - unsigned long flags; -@@ -1030,9 +1025,7 @@ static void r3964_close(struct tty_struc - del_timer_sync(&pInfo->tmr); - - /* Remove client-structs and message queues: */ -- pClient = pInfo->firstClient; -- while (pClient) { -- pNext = pClient->next; -+ list_for_each_entry_safe(pClient, tmp_client, &pInfo->clients, node) { - while (pClient->msg_count) { - pMsg = remove_msg(pClient); - if (pMsg) { -@@ -1041,9 +1034,9 @@ static void r3964_close(struct tty_struc - } - } - put_pid(pClient->pid); -+ list_del(&pClient->node); - kfree(pClient); - TRACE_M("r3964_close - client kfree %p", pClient); -- pClient = pNext; - } - /* Remove jobs from tx_queue: */ - spin_lock_irqsave(&pInfo->lock, flags); diff --git a/0011-tty-n_r3964-fix-race-with-add_msg-and-read_telegram.patch b/0011-tty-n_r3964-fix-race-with-add_msg-and-read_telegram.patch deleted file mode 100644 index a035acb550c9c0..00000000000000 --- a/0011-tty-n_r3964-fix-race-with-add_msg-and-read_telegram.patch +++ /dev/null @@ -1,108 +0,0 @@ -From b54481aa9fb9cab7a0ca3257c4a6ba6082ef9652 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Fri, 25 Jan 2019 15:03:15 +0100 -Subject: [PATCH 11/15] tty: n_r3964: fix race with add_msg() and read_telegram - -read_telegram() could race with the client block access code that can be -called through add_msg() as it did not hold any locks. - -Fix that up by properly holding the client->lock when touching the next -message to be read structures. Gyrations ensue due to the data having -to be copied to userspace, but the potential corruption problem is now -gone, to be replaced with a possible race where we free a block that no -one sent to userspace yet. Given that no one has reported this problem -in the 20+ years of this code, I'll take the potential race condition -over a known corruption problems. - -Reported-by: Jann Horn <jannh@google.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 52 ++++++++++++++++++++++++++++++++++++++++---------- - 1 file changed, 42 insertions(+), 10 deletions(-) - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -193,8 +193,6 @@ static void receive_char(struct r3964_in - static void receive_error(struct r3964_info *pInfo, const char flag); - static void on_timeout(struct timer_list *t); - static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg); --static int read_telegram(struct r3964_info *pInfo, struct pid *pid, -- unsigned char __user * buf); - static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg, - int error_code, struct rx_block_header *pBlock); - static struct r3964_message *remove_msg(struct r3964_client_info *client); -@@ -830,6 +828,10 @@ static int read_telegram(struct r3964_in - { - struct r3964_client_info *pClient; - struct rx_block_header *block; -+ unsigned long flags; -+ unsigned int length; -+ int retval = 0; -+ u8 *data; - - if (!buf) { - return -EINVAL; -@@ -840,18 +842,47 @@ static int read_telegram(struct r3964_in - return -EINVAL; - } - -+ spin_lock_irqsave(&pClient->lock, flags); -+ - block = pClient->next_block_to_read; -- if (!block) { -- return 0; -- } else { -- if (copy_to_user(buf, block->data, block->length)) -- return -EFAULT; -+ if (!block) -+ goto exit; -+ -+ /* -+ * Duplicate the data so we can release the lock while we copy to -+ * userspace -+ */ -+ length = block->length; -+ data = kmemdup(block->data, length, GFP_ATOMIC); -+ if (!data) { -+ retval = -ENOMEM; -+ goto exit; -+ } -+ -+ spin_unlock_irqrestore(&pClient->lock, flags); - -- remove_client_block(pClient); -- return block->length; -+ if (copy_to_user(buf, data, length)) { -+ kfree(data); -+ return -EFAULT; - } -+ kfree(data); - -- return -EINVAL; -+ /* -+ * Copy succeeded, so grab the lock again, and then drop the buffer, as -+ * remove_client_block() has to have the lock held. -+ * -+ * Note, the client's next_block_to_read could have changed here, so -+ * worst case, we just dropped a buffer that wasn't read. But, nothing -+ * was corrupted or accidentally freed, so we are doing better than we -+ * used to. Ideally the whole issue of "read_telegram" would be handled -+ * some other way as this races with the add_msg() path in a bad manner -+ */ -+ spin_lock_irqsave(&pClient->lock, flags); -+ remove_client_block(pClient); -+ -+exit: -+ spin_unlock_irqrestore(&pClient->lock, flags); -+ return retval; - } - - static void __add_msg(struct r3964_client_info *pClient, int msg_id, int arg, -@@ -934,6 +965,7 @@ static struct r3964_message *remove_msg( - } - - static void remove_client_block(struct r3964_client_info *client) -+ __must_hold(&client->lock) - { - struct rx_block_header *block; - diff --git a/0012-tty-n_r3964-remove-read_lock-from-some-ioctls.patch b/0012-tty-n_r3964-remove-read_lock-from-some-ioctls.patch deleted file mode 100644 index 71c6b33bba2de3..00000000000000 --- a/0012-tty-n_r3964-remove-read_lock-from-some-ioctls.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 3e1d022e31e12398690f4f8638453b3929fa73d4 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Fri, 25 Jan 2019 15:20:31 +0100 -Subject: [PATCH 12/15] tty: n_r3964: remove read_lock from some ioctls - -Now that read_telegram() properly grabs the needed locks for its -operation, we can move the "heavy" read lock away from all ioctls except -one, the R3964_ENABLE_SIGNALS lock. - -When we move this lock away, properly grab the info->lock for the other -ioctls that need it so that they will not have any problems. - -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 28 ++++++++++++++++++---------- - 1 file changed, 18 insertions(+), 10 deletions(-) - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -175,7 +175,8 @@ struct r3964_info { - unsigned char bcc; - unsigned int blocks_in_rx_queue; - -- struct mutex read_lock; /* serialize read and ioctl */ -+ /* serialize read and R3964_ENABLE_SIGNALS ioctl */ -+ struct mutex read_lock; - - struct list_head clients; - unsigned int state; -@@ -1216,33 +1217,41 @@ static int r3964_ioctl(struct tty_struct - unsigned int cmd, unsigned long arg) - { - struct r3964_info *pInfo = tty->disc_data; -+ unsigned long flags; - int retval = 0; - - if (pInfo == NULL) - return -EINVAL; -- /* Internal serialization of reads and ioctls */ -- if (file->f_flags & O_NONBLOCK) { -- if (!mutex_trylock(&pInfo->read_lock)) -- return -EAGAIN; -- } else { -- if (mutex_lock_interruptible(&pInfo->read_lock)) -- return -ERESTARTSYS; -- } - - switch (cmd) { - case R3964_ENABLE_SIGNALS: -+ /* Internal serialization of reads and this ioctl */ -+ if (file->f_flags & O_NONBLOCK) { -+ if (!mutex_trylock(&pInfo->read_lock)) -+ return -EAGAIN; -+ } else { -+ if (mutex_lock_interruptible(&pInfo->read_lock)) -+ return -ERESTARTSYS; -+ } -+ - retval = enable_signals(pInfo, task_pid(current), arg); -+ -+ mutex_unlock(&pInfo->read_lock); - break; - case R3964_SETPRIORITY: - if (arg < R3964_MASTER || arg > R3964_SLAVE) - return -EINVAL; -+ spin_lock_irqsave(&pInfo->lock, flags); - pInfo->priority = arg & 0xff; -+ spin_unlock_irqrestore(&pInfo->lock, flags); - break; - case R3964_USE_BCC: -+ spin_lock_irqsave(&pInfo->lock, flags); - if (arg) - pInfo->flags |= R3964_BCC; - else - pInfo->flags &= ~R3964_BCC; -+ spin_unlock_irqrestore(&pInfo->lock, flags); - break; - case R3964_READ_TELEGRAM: - retval = read_telegram(pInfo, task_pid(current), -@@ -1253,7 +1262,6 @@ static int r3964_ioctl(struct tty_struct - break; - } - -- mutex_unlock(&pInfo->read_lock); - return retval; - } - diff --git a/0013-tty-n_r3964-properly-protect-sig_flags-of-client-str.patch b/0013-tty-n_r3964-properly-protect-sig_flags-of-client-str.patch deleted file mode 100644 index 5bbcd6030d1c9a..00000000000000 --- a/0013-tty-n_r3964-properly-protect-sig_flags-of-client-str.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 7105eeab4aa73032fe40f5e72f51601da0cd7c4f Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Fri, 25 Jan 2019 16:35:57 +0100 -Subject: [PATCH 13/15] tty: n_r3964: properly protect sig_flags of client - structure - -This cleans up the remaining users of the sig_flags field in the client -structure to allways access it under the client structure's lock. - -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 20 ++++++++++++++++---- - 1 file changed, 16 insertions(+), 4 deletions(-) - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -193,7 +193,6 @@ static void transmit_block(struct r3964_ - static void receive_char(struct r3964_info *pInfo, const unsigned char c); - static void receive_error(struct r3964_info *pInfo, const char flag); - static void on_timeout(struct timer_list *t); --static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg); - static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg, - int error_code, struct rx_block_header *pBlock); - static struct r3964_message *remove_msg(struct r3964_client_info *client); -@@ -548,7 +547,14 @@ static void on_receive_block(struct r396 - /* notify attached client processes: */ - spin_lock_irqsave(&pInfo->lock, flags); - list_for_each_entry(pClient, &pInfo->clients, node) { -- if (pClient->sig_flags & R3964_SIG_DATA) { -+ unsigned long client_flags; -+ unsigned int sig_flags; -+ -+ spin_lock_irqsave(&pClient->lock, client_flags); -+ sig_flags = pClient->sig_flags; -+ spin_unlock_irqrestore(&pClient->lock, client_flags); -+ -+ if (sig_flags & R3964_SIG_DATA) { - add_msg(pClient, R3964_MSG_DATA, length, R3964_OK, - pBlock); - } -@@ -798,8 +804,12 @@ static int enable_signals(struct r3964_i - } else { - pClient = findClient(pInfo, pid); - if (pClient) { -+ unsigned long client_flags; -+ - /* update signal options */ -+ spin_lock_irqsave(&pClient->lock, client_flags); - pClient->sig_flags = arg; -+ spin_unlock_irqrestore(&pClient->lock, client_flags); - } else { - /* add client to client list */ - pClient = kmalloc(sizeof(struct r3964_client_info), -@@ -914,6 +924,7 @@ static void add_msg(struct r3964_client_ - { - struct r3964_message *pMsg; - unsigned long flags; -+ unsigned int sig_flags; - - spin_lock_irqsave(&pClient->lock, flags); - -@@ -934,12 +945,13 @@ static void add_msg(struct r3964_client_ - TRACE_PE("add_msg - queue OVERFLOW-msg"); - } - } -+ -+ sig_flags = pClient->sig_flags; - spin_unlock_irqrestore(&pClient->lock, flags); - - /* Send SIGIO signal to client process: */ -- if (pClient->sig_flags & R3964_USE_SIGIO) { -+ if (sig_flags & R3964_USE_SIGIO) - kill_pid(pClient->pid, SIGIO, 1); -- } - } - - static struct r3964_message *remove_msg(struct r3964_client_info *client) diff --git a/0014-tty-n_r3964-properly-reference-count-pids.patch b/0014-tty-n_r3964-properly-reference-count-pids.patch deleted file mode 100644 index 9587d275eb18e2..00000000000000 --- a/0014-tty-n_r3964-properly-reference-count-pids.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 4607af3f8237114c8c679e5d976ef00fe7053123 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Fri, 25 Jan 2019 16:47:16 +0100 -Subject: [PATCH 14/15] tty: n_r3964: properly reference count pids - -The driver likes to look up things based on the current pid, yet the -structure is never properly reference counted when passing around the -pointer. Luckily when it is saved off it is correct, but for all other -usages, we need to handle the reference properly. - -The function find_client_current() is created to handle some of the -common housekeeping when trying to lookup a structure on the current -pid. - -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 28 ++++++++++++++++++++++------ - 1 file changed, 22 insertions(+), 6 deletions(-) - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -769,6 +769,18 @@ exit: - return pClient; - } - -+/* Find a client that refers to the pid of the current task */ -+static struct r3964_client_info *find_client_current(struct r3964_info *info) -+{ -+ struct r3964_client_info *client; -+ struct pid *pid; -+ -+ pid = get_pid(task_pid(current)); -+ client = findClient(info, pid); -+ put_pid(pid); -+ return client; -+} -+ - static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg) - { - struct r3964_client_info *pClient; -@@ -1121,7 +1133,7 @@ static ssize_t r3964_read(struct tty_str - return -ERESTARTSYS; - } - -- pClient = findClient(pInfo, task_pid(current)); -+ pClient = find_client_current(pInfo); - if (pClient) { - pMsg = remove_msg(pClient); - if (pMsg == NULL) { -@@ -1205,7 +1217,7 @@ static ssize_t r3964_write(struct tty_st - pHeader->length = count; - pHeader->owner = NULL; - -- pClient = findClient(pInfo, task_pid(current)); -+ pClient = find_client_current(pInfo); - if (pClient) { - pHeader->owner = pClient; - } -@@ -1229,6 +1241,7 @@ static int r3964_ioctl(struct tty_struct - unsigned int cmd, unsigned long arg) - { - struct r3964_info *pInfo = tty->disc_data; -+ struct pid *pid; - unsigned long flags; - int retval = 0; - -@@ -1246,7 +1259,9 @@ static int r3964_ioctl(struct tty_struct - return -ERESTARTSYS; - } - -- retval = enable_signals(pInfo, task_pid(current), arg); -+ pid = get_pid(task_pid(current)); -+ retval = enable_signals(pInfo, pid, arg); -+ put_pid(pid); - - mutex_unlock(&pInfo->read_lock); - break; -@@ -1266,8 +1281,9 @@ static int r3964_ioctl(struct tty_struct - spin_unlock_irqrestore(&pInfo->lock, flags); - break; - case R3964_READ_TELEGRAM: -- retval = read_telegram(pInfo, task_pid(current), -- (unsigned char __user *)arg); -+ pid = get_pid(task_pid(current)); -+ retval = read_telegram(pInfo, pid, (unsigned char __user *)arg); -+ put_pid(pid); - break; - default: - retval = -ENOIOCTLCMD; -@@ -1308,7 +1324,7 @@ static __poll_t r3964_poll(struct tty_st - - TRACE_L("POLL"); - -- pClient = findClient(pInfo, task_pid(current)); -+ pClient = find_client_current(pInfo); - if (pClient) { - poll_wait(file, &tty->read_wait, wait); - spin_lock_irqsave(&pClient->lock, flags); diff --git a/0015-tty-n_r3964-add-reference-counting-to-the-client-str.patch b/0015-tty-n_r3964-add-reference-counting-to-the-client-str.patch deleted file mode 100644 index 862be5f5310f93..00000000000000 --- a/0015-tty-n_r3964-add-reference-counting-to-the-client-str.patch +++ /dev/null @@ -1,245 +0,0 @@ -From da04c3926a73304489a320796045814ac48f2e37 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Fri, 1 Feb 2019 10:44:55 +0100 -Subject: [PATCH 15/15] tty: n_r3964: add reference counting to the client - structure - -The client structure pointer is thrown around a lot, and trying to keep -track of who has, and does not have, a valid pointer is almost -impossible to audit properly, especially when looking up client -structures from the lists. So add a kref to the structure so that it -will be automatically reference counted and no one can access a stale -pointer and memory will be freed when everything is finished. - -This should resolve the problem with the client structure pointer beging -able to be accessed when it was removed by someone else at the same -time. - -Reported-by: Jann Horn <jannh@google.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_r3964.c | 82 +++++++++++++++++++++++++++++++++++++++----------- - 1 file changed, 64 insertions(+), 18 deletions(-) - ---- a/drivers/tty/n_r3964.c -+++ b/drivers/tty/n_r3964.c -@@ -106,6 +106,7 @@ struct tx_block_header; - - struct r3964_client_info { - spinlock_t lock; -+ struct kref kref; - struct pid *pid; - unsigned int sig_flags; - -@@ -298,6 +299,30 @@ static int __init r3964_init(void) - module_init(r3964_init); - module_exit(r3964_exit); - -+static struct r3964_client_info *client_get(struct r3964_client_info *client) -+{ -+ if (client) -+ kref_get(&client->kref); -+ return client; -+} -+ -+static void client_free(struct kref *kref) -+{ -+ struct r3964_client_info *client; -+ -+ client = container_of(kref, struct r3964_client_info, kref); -+ -+ put_pid(client->pid); -+ list_del(&client->node); -+ kfree(client); -+} -+ -+static void client_put(struct r3964_client_info *client) -+{ -+ if (client) -+ kref_put(&client->kref, client_free); -+} -+ - /************************************************************* - * Protocol implementation routines - *************************************************************/ -@@ -339,6 +364,7 @@ static void remove_from_tx_queue(struct - wake_up_interruptible(&pInfo->tty->read_wait); - } - -+ client_put(pHeader->owner); - kfree(pHeader); - } - -@@ -550,6 +576,7 @@ static void on_receive_block(struct r396 - unsigned long client_flags; - unsigned int sig_flags; - -+ client_get(pClient); - spin_lock_irqsave(&pClient->lock, client_flags); - sig_flags = pClient->sig_flags; - spin_unlock_irqrestore(&pClient->lock, client_flags); -@@ -558,6 +585,7 @@ static void on_receive_block(struct r396 - add_msg(pClient, R3964_MSG_DATA, length, R3964_OK, - pBlock); - } -+ client_put(pClient); - } - spin_unlock_irqrestore(&pInfo->lock, flags); - wake_up_interruptible(&pInfo->tty->read_wait); -@@ -751,25 +779,40 @@ static void on_timeout(struct timer_list - } - } - -+/* -+ * The reference count of the pointer returned will be incremented -+ * (if it is not NULL) so client_put() must be called on it when the -+ * caller is finished with it. -+ */ - static struct r3964_client_info *findClient(struct r3964_info *pInfo, - struct pid *pid) - { - struct r3964_client_info *pClient; -- unsigned long flags; -+ unsigned long client_flags; -+ unsigned long info_flags; - -- spin_lock_irqsave(&pInfo->lock, flags); -+ spin_lock_irqsave(&pInfo->lock, info_flags); - list_for_each_entry(pClient, &pInfo->clients, node) { -+ client_get(pClient); -+ spin_lock_irqsave(&pClient->lock, client_flags); - if (pClient->pid == pid) { -+ spin_unlock_irqrestore(&pClient->lock, client_flags); - goto exit; - } -+ spin_unlock_irqrestore(&pClient->lock, client_flags); -+ client_put(pClient); - } - pClient = NULL; - exit: -- spin_unlock_irqrestore(&pInfo->lock, flags); -+ spin_unlock_irqrestore(&pInfo->lock, info_flags); - return pClient; - } - --/* Find a client that refers to the pid of the current task */ -+/* -+ * Find a client that refers to the pid of the current task -+ * The reference count of the pointer will be incremented so -+ * client_put() must be called when the caller is finished with it -+ */ - static struct r3964_client_info *find_client_current(struct r3964_info *info) - { - struct r3964_client_info *client; -@@ -792,6 +835,7 @@ static int enable_signals(struct r3964_i - - /* Remove client from client list */ - list_for_each_entry(pClient, &pInfo->clients, node) { -+ client_get(pClient); - if (pClient->pid == pid) { - TRACE_PS("removing client %d from client list", - pid_nr(pid)); -@@ -803,13 +847,13 @@ static int enable_signals(struct r3964_i - "kfree %p", pMsg); - } - } -- put_pid(pClient->pid); -- list_del(&pClient->node); -- kfree(pClient); -- TRACE_M("enable_signals - kfree %p", pClient); -+ /* Second put will free the structure */ -+ client_put(pClient); -+ client_put(pClient); - spin_unlock_irqrestore(&pInfo->lock, flags); - return 0; - } -+ client_put(pClient); - } - spin_unlock_irqrestore(&pInfo->lock, flags); - return -EINVAL; -@@ -822,6 +866,7 @@ static int enable_signals(struct r3964_i - spin_lock_irqsave(&pClient->lock, client_flags); - pClient->sig_flags = arg; - spin_unlock_irqrestore(&pClient->lock, client_flags); -+ client_put(pClient); - } else { - /* add client to client list */ - pClient = kmalloc(sizeof(struct r3964_client_info), -@@ -833,6 +878,7 @@ static int enable_signals(struct r3964_i - spin_lock_irqsave(&pInfo->lock, flags); - TRACE_PS("add client %d to client list", pid_nr(pid)); - spin_lock_init(&pClient->lock); -+ kref_init(&pClient->kref); - pClient->sig_flags = arg; - pClient->pid = get_pid(pid); - INIT_LIST_HEAD(&pClient->msgs); -@@ -886,6 +932,7 @@ static int read_telegram(struct r3964_in - - if (copy_to_user(buf, data, length)) { - kfree(data); -+ client_put(pClient); - return -EFAULT; - } - kfree(data); -@@ -905,6 +952,7 @@ static int read_telegram(struct r3964_in - - exit: - spin_unlock_irqrestore(&pClient->lock, flags); -+ client_put(pClient); - return retval; - } - -@@ -1090,10 +1138,7 @@ static void r3964_close(struct tty_struc - TRACE_M("r3964_close - msg kfree %p", pMsg); - } - } -- put_pid(pClient->pid); -- list_del(&pClient->node); -- kfree(pClient); -- TRACE_M("r3964_close - client kfree %p", pClient); -+ client_put(pClient); - } - /* Remove jobs from tx_queue: */ - spin_lock_irqsave(&pInfo->lock, flags); -@@ -1171,6 +1216,7 @@ static ssize_t r3964_read(struct tty_str - ret = -EPERM; - unlock: - mutex_unlock(&pInfo->read_lock); -+ client_put(pClient); - return ret; - } - -@@ -1179,7 +1225,6 @@ static ssize_t r3964_write(struct tty_st - { - struct r3964_info *pInfo = tty->disc_data; - struct tx_block_header *pHeader; -- struct r3964_client_info *pClient; - unsigned char *new_data; - - TRACE_L("write request, %d characters", count); -@@ -1215,12 +1260,12 @@ static ssize_t r3964_write(struct tty_st - pHeader = (struct tx_block_header *)new_data; - pHeader->data = new_data + sizeof(*pHeader); - pHeader->length = count; -- pHeader->owner = NULL; - -- pClient = find_client_current(pInfo); -- if (pClient) { -- pHeader->owner = pClient; -- } -+ /* -+ * The reference count is left incremented as the last user of -+ * this pointer will drop it when needed -+ */ -+ pHeader->owner = find_client_current(pInfo); - - memcpy(pHeader->data, data, count); /* We already verified this */ - -@@ -1331,6 +1376,7 @@ static __poll_t r3964_poll(struct tty_st - if (!list_empty(&pClient->msgs)) - result |= EPOLLIN | EPOLLRDNORM; - spin_unlock_irqrestore(&pClient->lock, flags); -+ client_put(pClient); - } else { - result = EPOLLNVAL | EPOLLERR; - } @@ -1,7 +1,4 @@ # -0001-moxart-fix-potential-use-after-free-on-remove-path.patch -0001-paride-fix-up-build-warning-on-mips-platforms.patch -0001-Kbuild-provide-a-common-kernel-installation-script.patch 0001-driver-core-aux-test-code.patch copying.patch 0001-readfile-implement-readfile-syscall.patch @@ -10,23 +7,10 @@ copying.patch 0004-readfile.2-new-page-describing-readfile-2.patch spdxcheck-print-out-files-without-any-spdx-lines.patch -0001-tty-n_r3964-locking-fixups.patch -0002-tty-n_r3964-fix-poll-return-value.patch -0003-tty-n_r3964-remove-n_r3964.h.patch -0004-tty-n_r3964-drop-ancient-header-changelog-text.patch -0005-tty-n_r3964-split-rx-and-tx-header-structures.patch -0006-tty-n_r3964-for-tx_blocks-use-a-real-kernel-list.patch -0007-tty-n_r3964-for-rx_blocks-use-a-real-kernel-list.patch -0008-tty-n_r3964-don-t-hand-roll-a-reference-count.patch -0009-tty-n_r3964-for-messages-use-a-real-kernel-list.patch -0010-tty-n_r3964-for-clients-use-a-real-kernel-list.patch -0011-tty-n_r3964-fix-race-with-add_msg-and-read_telegram.patch -0012-tty-n_r3964-remove-read_lock-from-some-ioctls.patch -0013-tty-n_r3964-properly-protect-sig_flags-of-client-str.patch -0014-tty-n_r3964-properly-reference-count-pids.patch -0015-tty-n_r3964-add-reference-counting-to-the-client-str.patch + usb_DEVICE_ATTR.patch +0001-Kbuild-provide-a-common-kernel-installation-script.patch ## broken patch! diff --git a/spdxcheck-print-out-files-without-any-spdx-lines.patch b/spdxcheck-print-out-files-without-any-spdx-lines.patch index 681db818c4f978..2bb7bbd5c6cb9c 100644 --- a/spdxcheck-print-out-files-without-any-spdx-lines.patch +++ b/spdxcheck-print-out-files-without-any-spdx-lines.patch @@ -14,8 +14,8 @@ Just a hack to make it easy to see what still needs to be converted. --- a/scripts/spdxcheck.py +++ b/scripts/spdxcheck.py -@@ -214,7 +214,10 @@ def scan_git_tree(tree): - if not os.path.isfile(el.path): +@@ -298,7 +298,10 @@ def scan_git_tree(tree, basedir, dirdept + parser.excluded += 1 continue with open(el.path, 'rb') as fd: + i = parser.spdx_valid @@ -23,5 +23,5 @@ Just a hack to make it easy to see what still needs to be converted. + if i == parser.spdx_valid: + sys.stdout.write('%s\n' %el.path) - def scan_git_subtree(tree, path): + def scan_git_subtree(tree, path, dirdepth): for p in path.strip('/').split('/'): diff --git a/usb_DEVICE_ATTR.patch b/usb_DEVICE_ATTR.patch index 6bcb207f0926e9..d59eb0d0ab0168 100644 --- a/usb_DEVICE_ATTR.patch +++ b/usb_DEVICE_ATTR.patch @@ -2,30 +2,37 @@ From foo@baz Fri Nov 30 11:15:46 CET 2018 Date: Fri, 30 Nov 2018 11:15:46 +0100 To: Greg KH <gregkh@linuxfoundation.org> From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Subject: [PATCH] USB: get rid of DEVICE_ATTR() usage +Subject: [PATCH] USB: gadget: f_mass_storage: get rid of DEVICE_ATTR() usage -Drivers should be using DEVICE_ATTR_RO() and friends, not a "raw" -DEVICE_ATTR(). Convert the remaining drivers/usb/ code to use a -specific DEVICE_ATTR_* macro instead, making it easier to audit the -correct mode on sysfs files and to make it harder to get wrong in the -future. +The last holdout in the drivers/usb/* tree using DEVICE_ATTR() is the +f_mass_storage driver, so move it to use DEVICE_ATTR_RW() instead. The +mode is overridden in the is_visible callback to set it properly +depending on if this is a cdrom or removable device. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- - drivers/usb/gadget/function/f_mass_storage.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) + drivers/usb/gadget/function/f_mass_storage.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c -@@ -2553,9 +2553,8 @@ static ssize_t file_store(struct device +@@ -2662,11 +2662,16 @@ static ssize_t forced_eject_store(struct } static DEVICE_ATTR_RW(nofua); -/* mode wil be set in fsg_lun_attr_is_visible() */ -static DEVICE_ATTR(ro, 0, ro_show, ro_store); -static DEVICE_ATTR(file, 0, file_show, file_store); + static DEVICE_ATTR_WO(forced_eject); + ++/* ++ * Mode of the ro and file attribute files will be overridden in ++ * fsg_lun_dev_is_visible() depending on if this is a cdrom, or if it is a ++ * removable device. ++ */ +static DEVICE_ATTR_RW(ro); +static DEVICE_ATTR_RW(file); - ++ /****************************** FSG COMMON ******************************/ + static void fsg_lun_release(struct device *dev) |