4.9.24-stable review
Subsystems (6)
Greg Kroah-Hartman
maintainercover 4.9.24-stable review
This is the start of the stable review cycle for the 4.9.24 release. There are 69 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Apr 21 14:16:02 UTC 2017. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.9.24-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.9.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.9.24-rc1
Marcelo Ricardo Leitner <[email protected]>
sctp: deny peeloff operation on asocs with threads sleeping on it
Mantas M <[email protected]>
net: ipv6: check route protocol when deleting routes
Omar Sandoval <[email protected]>
virtio-console: avoid DMA from stack
Stefan Brüns <[email protected]>
cxusb: Use a dma capable buffer also for reading
Stefan Brüns <[email protected]>
dvb-usb-firmware: don't do DMA on stack
Mauro Carvalho Chehab <[email protected]>
dvb-usb: don't use stack for firmware load
Kees Cook <[email protected]>
mm: Tighten x86 /dev/mem with zeroing reads
Thierry Reding <[email protected]>
rtc: tegra: Implement clock handling
Lv Zheng <[email protected]>
ACPI / EC: Use busy polling mode when GPE is not enabled
Mohit Gambhir <[email protected]>
x86/xen: Fix APIC id mismatch warning on Intel
Lee, Chun-Yi <[email protected]>
platform/x86: acer-wmi: setup accelerometer when machine has appropriate notify event
Andy Shevchenko <[email protected]>
ASoC: Intel: select DW_DMAC_CORE since it's mandatory
Jens Axboe <[email protected]>
nbd: fix 64-bit division
Josef Bacik <[email protected]>
nbd: use loff_t for blocksize and nbd_set_size args
Ben Skeggs <[email protected]>
drm/nouveau/disp/mcp7x: disable dptmds workaround
Vladimir Davydov <[email protected]>
mm: memcontrol: use special workqueue for creating per-memcg caches
Daeho Jeong <[email protected]>
ext4: fix inode checksum calculation problem if i_extra_size is small
Arnd Bergmann <[email protected]>
dvb-usb-v2: avoid use-after-free
Miaoqing Pan <[email protected]>
ath9k: fix NULL pointer dereference
Helge Deller <[email protected]>
parisc: Fix get_user() for 64-bit value on 32-bit kernel
Herbert Xu <[email protected]>
crypto: ahash - Fix EINPROGRESS notification callback
Herbert Xu <[email protected]>
crypto: algif_aead - Fix bogus request dereference in completion function
Namhyung Kim <[email protected]>
ftrace: Fix function pid filter on instances
Minchan Kim <[email protected]>
zram: do not use copy_page with non-page aligned address
Paolo Bonzini <[email protected]>
kvm: fix page struct leak in handle_vmon
Greg Kroah-Hartman <[email protected]>
Revert "MIPS: Lantiq: Fix cascaded IRQ setup"
Max Bires <[email protected]>
char: lack of bool string made CONFIG_DEVPORT always on
Steven Rostedt (VMware) <[email protected]>
ftrace: Fix removing of second function probe
Tyler Baker <[email protected]>
irqchip/irq-imx-gpcv2: Fix spinlock initialization
Chen Yu <[email protected]>
cpufreq: Bring CPUs up even if cpufreq_online() failed
David Wu <[email protected]>
pwm: rockchip: State of PWM clock should synchronize with PWM enabled state
Markus Marb <[email protected]>
can: ifi: use correct register to read rx status
Dan Williams <[email protected]>
libnvdimm: fix reconfig_mutex, mmap_sem, and jbd2_handle lockdep splat
Dan Williams <[email protected]>
libnvdimm: fix blk free space accounting
Al Viro <[email protected]>
make skb_copy_datagram_msg() et.al. preserve ->msg_iter on error
Al Viro <[email protected]>
new privimitive: iov_iter_revert()
Juergen Gross <[email protected]>
xen, fbfront: fix connecting to backend
Nicholas Bellinger <[email protected]>
target: Avoid mappedlun symlink creation during lun shutdown
Martin K. Petersen <[email protected]>
scsi: sd: Fix capacity calculation with 32-bit sector_t
Sawan Chandak <[email protected]>
scsi: qla2xxx: Add fix to read correct register value for ISP82xx.
Fam Zheng <[email protected]>
scsi: sd: Consider max_xfer_blocks if opt_xfer_blocks is unusable
Martin K. Petersen <[email protected]>
scsi: sr: Sanity check returned mode data
Nicholas Bellinger <[email protected]>
iscsi-target: Drop work-around for legacy GlobalSAN initiator
Nicholas Bellinger <[email protected]>
iscsi-target: Fix TMR reference leak during session shutdown
Ard Biesheuvel <[email protected]>
efi/fb: Avoid reconfiguration of BAR that covers the framebuffer
Cohen, Eugene <[email protected]>
efi/libstub: Skip GOP with PIXEL_BLT_ONLY format
Mikulas Patocka <[email protected]>
parisc: fix bugs in pa_memcpy
Rafael J. Wysocki <[email protected]>
ACPI / scan: Set the visited flag for all enumerated devices
Dan Williams <[email protected]>
acpi, nfit, libnvdimm: fix interleave set cookie calculation (64-bit comparison)
Thomas Gleixner <[email protected]>
x86/vdso: Plug race between mapping and ELF header setup
Mathias Krause <[email protected]>
x86/vdso: Ensure vdso32_enabled gets set to valid values only
Dan Williams <[email protected]>
x86, pmem: fix broken __copy_user_nocache cache-bypass assumptions
Joerg Roedel <[email protected]>
x86/signals: Fix lower/upper bound reporting in compat siginfo
Omar Sandoval <[email protected]>
x86/efi: Don't try to reserve runtime regions
Peter Zijlstra <[email protected]>
perf/x86: Avoid exposing wrong/stale data in intel_pmu_lbr_read_32()
Cameron Gutman <[email protected]>
Input: xpad - add support for Razer Wildcat gamepad
Germano Percossi <[email protected]>
CIFS: store results of cifs_reopen_file to avoid infinite wait
Germano Percossi <[email protected]>
CIFS: reconnect thread reschedule itself
Wei Yongjun <[email protected]>
drm/etnaviv: fix missing unlock on error in etnaviv_gpu_submit()
Ilia Mirkin <[email protected]>
drm/nouveau/mmu/nv4a: use nv04 mmu rather than the nv44 one
Ilia Mirkin <[email protected]>
drm/nouveau/mpeg: mthd returns true on success now
Martin Brandenburg <[email protected]>
orangefs: free superblock when mount fails
Minchan Kim <[email protected]>
zsmalloc: expand class bit
Kirill A. Shutemov <[email protected]>
thp: fix MADV_DONTNEED vs clear soft dirty race
Kirill A. Shutemov <[email protected]>
thp: fix MADV_DONTNEED vs. MADV_FREE race
Xiubo Li <[email protected]>
tcmu: Skip Data-Out blocks before gathering Data-In buffer for BIDI case
Xiubo Li <[email protected]>
tcmu: Fix wrongly calculating of the base_command_size
Xiubo Li <[email protected]>
tcmu: Fix possible overwrite of t_data_sg's last iov[]
Tejun Heo <[email protected]>
cgroup, kthread: close race window where new kthreads can be migrated to non-root cgroups
-------------
Diffstat:
Makefile | 4 +- arch/mips/lantiq/irq.c | 38 +++++----- arch/parisc/include/asm/uaccess.h | 86 +++++++++++++-------- arch/parisc/lib/lusercopy.S | 27 +++---- arch/x86/entry/vdso/vdso32-setup.c | 11 ++- arch/x86/events/intel/lbr.c | 3 + arch/x86/include/asm/elf.h | 2 +- arch/x86/include/asm/pmem.h | 42 ++++++++--- arch/x86/kernel/signal_compat.c | 4 +- arch/x86/kvm/vmx.c | 10 ++- arch/x86/mm/init.c | 41 +++++++--- arch/x86/platform/efi/quirks.c | 4 + arch/x86/xen/apic.c | 2 +- crypto/ahash.c | 79 ++++++++++++------- crypto/algif_aead.c | 12 +-- drivers/acpi/ec.c | 62 ++++++++------- drivers/acpi/internal.h | 4 +- drivers/acpi/nfit/core.c | 6 +- drivers/acpi/scan.c | 19 +++-- drivers/block/nbd.c | 10 +-- drivers/block/zram/zram_drv.c | 6 +- drivers/char/Kconfig | 5 +- drivers/char/mem.c | 82 ++++++++++++-------- drivers/char/virtio_console.c | 12 ++- drivers/cpufreq/cpufreq.c | 18 ++++- drivers/firmware/efi/libstub/gop.c | 6 +- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 3 +- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c | 2 - drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c | 2 +- drivers/input/joystick/xpad.c | 2 + drivers/irqchip/irq-imx-gpcv2.c | 2 + drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 9 ++- drivers/media/usb/dvb-usb/cxusb.c | 15 ++-- drivers/media/usb/dvb-usb/dvb-usb-firmware.c | 33 +++++--- drivers/net/can/ifi_canfd/ifi_canfd.c | 2 +- drivers/net/wireless/ath/ath9k/common-spectral.c | 8 +- drivers/nvdimm/bus.c | 6 ++ drivers/nvdimm/dimm_devs.c | 77 +++---------------- drivers/platform/x86/acer-wmi.c | 22 +++++- drivers/pwm/pwm-rockchip.c | 40 ++++++++-- drivers/rtc/rtc-tegra.c | 28 ++++++- drivers/scsi/qla2xxx/qla_os.c | 7 +- drivers/scsi/sd.c | 23 +++++- drivers/scsi/sr.c | 6 +- drivers/target/iscsi/iscsi_target_parameters.c | 16 ---- drivers/target/iscsi/iscsi_target_util.c | 12 +-- drivers/target/target_core_fabric_configfs.c | 5 ++ drivers/target/target_core_tpg.c | 4 + drivers/target/target_core_user.c | 92 ++++++++++++++++------- drivers/video/fbdev/efifb.c | 66 +++++++++++++++- drivers/video/fbdev/xen-fbfront.c | 4 +- fs/cifs/file.c | 6 +- fs/cifs/smb2pdu.c | 10 ++- fs/ext4/inode.c | 5 +- fs/orangefs/devorangefs-req.c | 9 ++- fs/orangefs/orangefs-kernel.h | 1 + fs/orangefs/super.c | 23 ++++-- fs/proc/task_mmu.c | 9 ++- include/crypto/internal/hash.h | 10 +++ include/linux/cgroup.h | 21 ++++++ include/linux/sched.h | 4 + include/linux/uio.h | 6 +- include/target/target_core_base.h | 1 + kernel/cgroup.c | 9 ++- kernel/kthread.c | 3 + kernel/trace/ftrace.c | 29 ++++++- kernel/trace/trace.c | 1 + kernel/trace/trace.h | 2 + lib/iov_iter.c | 63 ++++++++++++++++ mm/huge_memory.c | 3 +- mm/memcontrol.c | 15 +++- mm/zsmalloc.c | 2 +- net/core/datagram.c | 23 +++--- net/ipv6/route.c | 2 + net/sctp/socket.c | 8 +- sound/soc/intel/Kconfig | 31 ++++---- 78 files changed, 939 insertions(+), 442 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/69 cgroup, kthread: close race window where new kthreads can be migrated to non-root cgroups
4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejun Heo <[email protected]>
commit 77f88796cee819b9c4562b0b6b44691b3b7755b1 upstream.
Creation of a kthread goes through a couple interlocked stages between the kthread itself and its creator. Once the new kthread starts running, it initializes itself and wakes up the creator. The creator then can further configure the kthread and then let it start doing its job by waking it up.
In this configuration-by-creator stage, the creator is the only one that can wake it up but the kthread is visible to userland. When altering the kthread's attributes from userland is allowed, this is fine; however, for cases where CPU affinity is critical, kthread_bind() is used to first disable affinity changes from userland and then set the affinity. This also prevents the kthread from being migrated into non-root cgroups as that can affect the CPU affinity and many other things.
Unfortunately, the cgroup side of protection is racy. While the PF_NO_SETAFFINITY flag prevents further migrations, userland can win the race before the creator sets the flag with kthread_bind() and put the kthread in a non-root cgroup, which can lead to all sorts of problems including incorrect CPU affinity and starvation.
This bug got triggered by userland which periodically tries to migrate all processes in the root cpuset cgroup to a non-root one. Per-cpu workqueue workers got caught while being created and ended up with incorrected CPU affinity breaking concurrency management and sometimes stalling workqueue execution.
This patch adds task->no_cgroup_migration which disallows the task to be migrated by userland. kthreadd starts with the flag set making every child kthread start in the root cgroup with migration disallowed. The flag is cleared after the kthread finishes initialization by which time PF_NO_SETAFFINITY is set if the kthread should stay in the root cgroup.
It'd be better to wait for the initialization instead of failing but I couldn't think of a way of implementing that without adding either a new PF flag, or sleeping and retrying from waiting side. Even if userland depends on changing cgroup membership of a kthread, it either has to be synchronized with kthread_create() or periodically repeat, so it's unlikely that this would break anything.
v2: Switch to a simpler implementation using a new task_struct bit
field suggested by Oleg.
--- include/linux/cgroup.h | 21 +++++++++++++++++++++ include/linux/sched.h | 4 ++++ kernel/cgroup.c | 9 +++++---- kernel/kthread.c | 3 +++ 4 files changed, 33 insertions(+), 4 deletions(-)
include/linux/cgroup.h +21 -0
@@ -570,6 +570,25 @@ static inline void pr_cont_cgroup_path(s pr_cont_kernfs_path(cgrp->kn); } +static inline void cgroup_init_kthreadd (void ) +{ +/* +* kthreadd is inherited by all kthreads, keep it in the root so +* that the new kthreads are guaranteed to stay in the root until +* initialization is finished. +*/ + current->no_cgroup_migration =1 ; +} + +static inline void cgroup_kthread_ready (void ) +{ +/* +* This kthread finished initialization. The creator should have +* set PF_NO_SETAFFINITY if this kthread should stay in the root. +*/ + current->no_cgroup_migration =0 ; +} +#else /* !CONFIG_CGROUPS */ struct cgroup_subsys_state ;
@@ -590,6 +609,8 @@ static inline void cgroup_free(struct tastatic inline int cgroup_init_early (void ) {return 0 ; }static inline int cgroup_init (void ) {return 0 ; } +static inline void cgroup_init_kthreadd (void ) {} +static inline void cgroup_kthread_ready (void ) {}static inline bool task_under_cgroup_hierarchy (struct task_struct *task,struct cgroup *ancestor)
include/linux/sched.h +4 -0
@@ -1584,6 +1584,10 @@ struct task_struct {#ifdef CONFIG_COMPAT_BRK unsigned brk_randomized:1;#endif +#ifdef CONFIG_CGROUPS +/* disallow userland-initiated cgroup migration */ + unsigned no_cgroup_migration:1; +#endif unsigned long atomic_flags;/* Flags needing atomic access. */
kernel/cgroup.c +5 -4
@@ -2920,11 +2920,12 @@ static ssize_t __cgroup_procs_write(stru tsk = tsk->group_leader;/* -* Workqueue threads may acquire PF_NO_SETAFFINITY and become -* trapped in a cpuset, or RT worker may be born in a cgroup -* with no rt_runtime allocated. Just say no. +* kthreads may acquire PF_NO_SETAFFINITY during initialization. +* If userland migrates such a kthread to a non-root cgroup, it can +* become trapped in a cpuset, or RT kthread may be born in a +* cgroup with no rt_runtime allocated. Just say no. */ -if (tsk == kthreadd_task || (tsk->flags &PF_NO_SETAFFINITY )) { +if (tsk->no_cgroup_migration || (tsk->flags &PF_NO_SETAFFINITY )) { ret = -EINVAL ; goto out_unlock_rcu; }
kernel/kthread.c +3 -0
@@ -18,6 +18,7 @@#include <linux/freezer.h> #include <linux/ptrace.h> #include <linux/uaccess.h> +#include <linux/cgroup.h> #include <trace/events/sched.h> static DEFINE_SPINLOCK (kthread_create_lock);
@@ -205,6 +206,7 @@ static int kthread(void *_create) ret = -EINTR ;if (!test_bit (KTHREAD_SHOULD_STOP , &self.flags)) { +cgroup_kthread_ready ();__kthread_parkme (&self); ret =threadfn (data); }
@@ -530,6 +532,7 @@ int kthreadd(void *unused)set_mems_allowed (node_states[N_MEMORY ]); current->flags |=PF_NOFREEZE ; +cgroup_init_kthreadd ();for (;;) {set_current_state (TASK_INTERRUPTIBLE );
Greg Kroah-Hartman
maintainerPATCH 2/69 tcmu: Fix possible overwrite of t_data_sgs last iov[]
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiubo Li <[email protected]>
commit ab22d2604c86ceb01bb2725c9860b88a7dd383bb upstream.
If there has BIDI data, its first iov[] will overwrite the last iov[] for se_cmd->t_data_sg.
To fix this, we can just increase the iov pointer, but this may introuduce a new memory leakage bug: If the se_cmd->data_length and se_cmd->t_bidi_data_sg->length are all not aligned up to the DATA_BLOCK_SIZE, the actual length needed maybe larger than just sum of them.
So, this could be avoided by rounding all the data lengthes up to DATA_BLOCK_SIZE.
--- drivers/target/target_core_user.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-)
drivers/target/target_core_user.c +23 -11
@@ -389,6 +389,20 @@ static bool is_ring_space_avail(struct treturn true; } +static inline size_t tcmu_cmd_get_data_length (struct tcmu_cmd *tcmu_cmd) +{ +struct se_cmd *se_cmd = tcmu_cmd->se_cmd; +size_t data_length =round_up (se_cmd->data_length,DATA_BLOCK_SIZE ); + +if (se_cmd->se_cmd_flags &SCF_BIDI ) { +BUG_ON (!(se_cmd->t_bidi_data_sg && se_cmd->t_bidi_data_nents)); + data_length +=round_up (se_cmd->t_bidi_data_sg->length, +DATA_BLOCK_SIZE ); + } + +return data_length; +} +static sense_reason_t tcmu_queue_cmd_ring (struct tcmu_cmd *tcmu_cmd) {
@@ -402,7 +416,7 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmuint32_t cmd_head;uint64_t cdb_off;bool copy_to_data_area; -size_t data_length; +size_t data_length =tcmu_cmd_get_data_length (tcmu_cmd);DECLARE_BITMAP (old_bitmap,DATA_BLOCK_BITS );if (test_bit (TCMU_DEV_BIT_BROKEN , &udev->flags))
@@ -428,11 +442,6 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcm mb = udev->mb_addr; cmd_head = mb->cmd_head % udev->cmdr_size;/* UAM */ - data_length = se_cmd->data_length; -if (se_cmd->se_cmd_flags &SCF_BIDI ) { -BUG_ON (!(se_cmd->t_bidi_data_sg && se_cmd->t_bidi_data_nents)); - data_length += se_cmd->t_bidi_data_sg->length; - }if ((command_size > (udev->cmdr_size /2 )) || data_length > udev->data_size) { pr_warn("TCMU: Request of size %zu/%zu is too big for %u/%zu "
@@ -502,11 +511,14 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcm entry->req.iov_dif_cnt =0 ;/* Handle BIDI commands */ - iov_cnt =0 ; -alloc_and_scatter_data_area (udev, se_cmd->t_bidi_data_sg, - se_cmd->t_bidi_data_nents, &iov, &iov_cnt, false); - entry->req.iov_bidi_cnt = iov_cnt; - +if (se_cmd->se_cmd_flags &SCF_BIDI ) { + iov_cnt =0 ; + iov++; +alloc_and_scatter_data_area (udev, se_cmd->t_bidi_data_sg, + se_cmd->t_bidi_data_nents, &iov, &iov_cnt, + false); + entry->req.iov_bidi_cnt = iov_cnt; + }/* cmd's data_bitmap is what changed in process */ bitmap_xor (tcmu_cmd->data_bitmap, old_bitmap, udev->data_bitmap,DATA_BLOCK_BITS );
Greg Kroah-Hartman
maintainerPATCH 3/69 tcmu: Fix wrongly calculating of the base_command_size
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiubo Li <[email protected]>
commit abe342a5b4b5aa579f6bf40ba73447c699e6b579 upstream.
The t_data_nents and t_bidi_data_nents are the numbers of the segments, but it couldn't be sure the block size equals to size of the segment.
For the worst case, all the blocks are discontiguous and there will need the same number of iovecs, that's to say: blocks == iovs. So here just set the number of iovs to block count needed by tcmu cmd.
--- drivers/target/target_core_user.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/target/target_core_user.c +8 -2
@@ -403,6 +403,13 @@ static inline size_t tcmu_cmd_get_data_lreturn data_length; } +static inline uint32_t tcmu_cmd_get_block_cnt (struct tcmu_cmd *tcmu_cmd) +{ +size_t data_length =tcmu_cmd_get_data_length (tcmu_cmd); + +return data_length /DATA_BLOCK_SIZE ; +} +static sense_reason_t tcmu_queue_cmd_ring (struct tcmu_cmd *tcmu_cmd) {
@@ -430,8 +437,7 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcm* expensive to tell how many regions are freed in the bitmap */ base_command_size =max (offsetof(struct tcmu_cmd_entry , - req.iov[se_cmd->t_bidi_data_nents + - se_cmd->t_data_nents]), + req.iov[tcmu_cmd_get_block_cnt(tcmu_cmd)]), sizeof(struct tcmu_cmd_entry)); command_size = base_command_size +round_up (scsi_command_size (se_cmd->t_task_cdb),TCMU_OP_ALIGN_SIZE );
Greg Kroah-Hartman
maintainerPATCH 4/69 tcmu: Skip Data-Out blocks before gathering Data-In buffer for BIDI case
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiubo Li <[email protected]>
commit a5d68ba85801a78c892a0eb8efb711e293ed314b upstream.
For the bidirectional case, the Data-Out buffer blocks will always at the head of the tcmu_cmd's bitmap, and before gathering the Data-In buffer, first of all it should skip the Data-Out ones, or the device supporting BIDI commands won't work.
Fixed: 26418649eead ("target/user: Introduce data_bitmap, replace
data_length/data_head/data_tail")
--- drivers/target/target_core_user.c | 48 ++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 15 deletions(-)
drivers/target/target_core_user.c +33 -15
@@ -306,24 +306,50 @@ static void free_data_area(struct tcmu_d DATA_BLOCK_BITS); } -static void gather_data_area (struct tcmu_dev *udev,unsigned long *cmd_bitmap, -struct scatterlist *data_sg,unsigned int data_nents) +static void gather_data_area (struct tcmu_dev *udev,struct tcmu_cmd *cmd, +bool bidi) { +struct se_cmd *se_cmd = cmd->se_cmd;int i, block;int block_remaining =0 ;void *from, *to;size_t copy_bytes, from_offset; -struct scatterlist *sg; +struct scatterlist *sg, *data_sg; +unsigned int data_nents; +DECLARE_BITMAP (bitmap,DATA_BLOCK_BITS ); + +bitmap_copy (bitmap, cmd->data_bitmap,DATA_BLOCK_BITS ); + +if (!bidi) { + data_sg = se_cmd->t_data_sg; + data_nents = se_cmd->t_data_nents; + }else { +uint32_t count; + +/* +* For bidi case, the first count blocks are for Data-Out +* buffer blocks, and before gathering the Data-In buffer +* the Data-Out buffer blocks should be discarded. +*/ + count =DIV_ROUND_UP (se_cmd->data_length,DATA_BLOCK_SIZE ); +while (count--) { + block =find_first_bit (bitmap,DATA_BLOCK_BITS ); +clear_bit (block, bitmap); + } + + data_sg = se_cmd->t_bidi_data_sg; + data_nents = se_cmd->t_bidi_data_nents; + }for_each_sg (data_sg, sg, data_nents, i) {int sg_remaining = sg->length; to =kmap_atomic (sg_page (sg)) + sg->offset;while (sg_remaining >0 ) {if (block_remaining ==0 ) { - block =find_first_bit (cmd_bitmap, + block =find_first_bit (bitmap,DATA_BLOCK_BITS ); block_remaining =DATA_BLOCK_SIZE ; -clear_bit (block, cmd_bitmap); +clear_bit (block, bitmap); } copy_bytes =min_t (size_t, sg_remaining, block_remaining);
@@ -600,19 +626,11 @@ static void tcmu_handle_completion(struc se_cmd->scsi_sense_length);free_data_area (udev, cmd); }else if (se_cmd->se_cmd_flags &SCF_BIDI ) { -DECLARE_BITMAP (bitmap,DATA_BLOCK_BITS ); -/* Get Data-In buffer before clean up */ -bitmap_copy (bitmap, cmd->data_bitmap,DATA_BLOCK_BITS ); -gather_data_area (udev, bitmap, - se_cmd->t_bidi_data_sg, se_cmd->t_bidi_data_nents); +gather_data_area (udev, cmd, true);free_data_area (udev, cmd); }else if (se_cmd->data_direction ==DMA_FROM_DEVICE ) { -DECLARE_BITMAP (bitmap,DATA_BLOCK_BITS ); - -bitmap_copy (bitmap, cmd->data_bitmap,DATA_BLOCK_BITS ); -gather_data_area (udev, bitmap, - se_cmd->t_data_sg, se_cmd->t_data_nents); +gather_data_area (udev, cmd, false);free_data_area (udev, cmd); }else if (se_cmd->data_direction ==DMA_TO_DEVICE ) {free_data_area (udev, cmd);
Greg Kroah-Hartman
maintainerPATCH 5/69 thp: fix MADV_DONTNEED vs. MADV_FREE race
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kirill A. Shutemov <[email protected]>
commit 58ceeb6bec86d9140f9d91d71a710e963523d063 upstream.
Both MADV_DONTNEED and MADV_FREE handled with down_read(mmap_sem).
It's critical to not clear pmd intermittently while handling MADV_FREE to avoid race with MADV_DONTNEED:
CPU0: CPU1: madvise_free_huge_pmd() pmdp_huge_get_and_clear_full()
madvise_dontneed()
zap_pmd_range()
pmd_trans_huge(*pmd) == 0 (without ptl)
// skip the pmd
set_pmd_at(); // pmd is re-established
It results in MADV_DONTNEED skipping the pmd, leaving it not cleared. It violates MADV_DONTNEED interface and can result is userspace misbehaviour.
Basically it's the same race as with numa balancing in change_huge_pmd(), but a bit simpler to mitigate: we don't need to preserve dirty/young flags here due to MADV_FREE functionality.
--- mm/huge_memory.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
mm/huge_memory.c +1 -2
@@ -1380,8 +1380,7 @@ bool madvise_free_huge_pmd(struct mmu_gadeactivate_page (page);if (pmd_young (orig_pmd) ||pmd_dirty (orig_pmd)) { - orig_pmd =pmdp_huge_get_and_clear_full (tlb->mm, addr, pmd, - tlb->fullmm); +pmdp_invalidate (vma, addr, pmd); orig_pmd =pmd_mkold (orig_pmd); orig_pmd =pmd_mkclean (orig_pmd);
Greg Kroah-Hartman
maintainerPATCH 6/69 thp: fix MADV_DONTNEED vs clear soft dirty race
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kirill A. Shutemov <[email protected]>
commit 5b7abeae3af8c08c577e599dd0578b9e3ee6687b upstream.
Yet another instance of the same race.
Fix is identical to change_huge_pmd().
See "thp: fix MADV_DONTNEED vs. numa balancing race" for more details.
--- fs/proc/task_mmu.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
fs/proc/task_mmu.c +8 -1
@@ -899,7 +899,14 @@ static inline void clear_soft_dirty(strustatic inline void clear_soft_dirty_pmd (struct vm_area_struct *vma,unsigned long addr,pmd_t *pmdp) { -pmd_t pmd =pmdp_huge_get_and_clear (vma->vm_mm, addr, pmdp); +pmd_t pmd = *pmdp; + +/* See comment in change_huge_pmd() */ +pmdp_invalidate (vma, addr, pmdp); +if (pmd_dirty (*pmdp)) + pmd =pmd_mkdirty (pmd); +if (pmd_young (*pmdp)) + pmd =pmd_mkyoung (pmd); pmd =pmd_wrprotect (pmd); pmd =pmd_clear_soft_dirty (pmd);
Greg Kroah-Hartman
maintainerPATCH 7/69 zsmalloc: expand class bit
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Minchan Kim <[email protected]>
commit 85d492f28d056c40629fc25d79f54da618a29dc4 upstream.
Now 64K page system, zsamlloc has 257 classes so 8 class bit is not enough. With that, it corrupts the system when zsmalloc stores 65536byte data(ie, index number 256) so that this patch increases class bit for simple fix for stable backport. We should clean up this mess soon.
index size
0 32
1 288
..
..
204 52256
256 65536
--- mm/zsmalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/zsmalloc.c +1 -1
@@ -280,7 +280,7 @@ struct zs_pool {struct zspage {struct {unsigned int fullness:FULLNESS_BITS ; -unsigned int class:CLASS_BITS ; +unsigned int class:CLASS_BITS +1 ;unsigned int isolated:ISOLATED_BITS ;unsigned int magic:MAGIC_VAL_BITS ; };
Greg Kroah-Hartman
maintainerPATCH 8/69 orangefs: free superblock when mount fails
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Brandenburg <[email protected]>
commit 1ec1688c5360e14dde4094d6acbf7516bf6db37e upstream.
Otherwise lockdep says:
[ 1337.483798] ================================================
[ 1337.483999] [ BUG: lock held when returning to user space! ]
[ 1337.484252] 4.11.0-rc6 #19 Not tainted
[ 1337.484423] ------------------------------------------------
[ 1337.484626] mount/14766 is leaving the kernel with locks still held!
[ 1337.484841] 1 lock held by mount/14766:
[ 1337.485017] #0: (&type->s_umount_key#33/1){+.+.+.}, at: [<ffffffff8124171f>] sget_userns+0x2af/0x520Caught by xfstests generic/413 which tried to mount with the unsupported mount option dax. Then xfstests generic/422 ran sync which deadlocks.
--- fs/orangefs/devorangefs-req.c | 9 +++++++-- fs/orangefs/orangefs-kernel.h | 1 + fs/orangefs/super.c | 23 ++++++++++++++++------- 3 files changed, 24 insertions(+), 9 deletions(-)
fs/orangefs/devorangefs-req.c +7 -2
@@ -208,14 +208,19 @@ restart:continue ;/* * Skip ops whose filesystem we don't know about unless -* it is being mounted. +* it is being mounted or unmounted. It is possible for +* a filesystem we don't know about to be unmounted if +* it fails to mount in the kernel after userspace has +* been sent the mount request. */ /* XXX: is there a better way to detect this? */ }else if (ret ==-1 && !(op->upcall.type ==ORANGEFS_VFS_OP_FS_MOUNT || op->upcall.type == -ORANGEFS_VFS_OP_GETATTR )) { +ORANGEFS_VFS_OP_GETATTR || + op->upcall.type == +ORANGEFS_VFS_OP_FS_UMOUNT )) {gossip_debug (GOSSIP_DEV_DEBUG ,"orangefs: skipping op tag %llu %s\n" ,llu (op->tag),get_opname_string (op));
fs/orangefs/orangefs-kernel.h +1 -0
@@ -249,6 +249,7 @@ struct orangefs_sb_info_s {char devname[ORANGEFS_MAX_SERVER_ADDR_LEN ];struct super_block *sb;int mount_pending; +int no_list;struct list_head list; };
fs/orangefs/super.c +16 -7
@@ -493,7 +493,7 @@ struct dentry *orangefs_mount(struct filif (ret) { d =ERR_PTR (ret); - goto free_op; + goto free_sb_and_op; }/*
@@ -519,6 +519,9 @@ struct dentry *orangefs_mount(struct filspin_unlock (&orangefs_superblocks_lock);op_release (new_op); +/* Must be removed from the list now. */ +ORANGEFS_SB (sb)->no_list =0 ; +if (orangefs_userspace_version >=20906 ) { new_op =op_alloc (ORANGEFS_VFS_OP_FEATURES );if (!new_op)
@@ -533,6 +536,10 @@ struct dentry *orangefs_mount(struct filreturn dget (sb->s_root); +free_sb_and_op: +/* Will call orangefs_kill_sb with sb not in list. */ +ORANGEFS_SB (sb)->no_list =1 ; +deactivate_locked_super (sb); free_op:gossip_err ("orangefs_mount: mount request failed with %d\n" , ret);if (ret == -EINVAL ) {
@@ -558,12 +565,14 @@ void orangefs_kill_sb(struct super_block*/ orangefs_unmount_sb (sb); -/* remove the sb from our list of orangefs specific sb's */ - -spin_lock (&orangefs_superblocks_lock); -__list_del_entry (&ORANGEFS_SB (sb)->list);/* not list_del_init */ -ORANGEFS_SB (sb)->list.prev =NULL ; -spin_unlock (&orangefs_superblocks_lock); +if (!ORANGEFS_SB (sb)->no_list) { +/* remove the sb from our list of orangefs specific sb's */ +spin_lock (&orangefs_superblocks_lock); +/* not list_del_init */ +__list_del_entry (&ORANGEFS_SB (sb)->list); +ORANGEFS_SB (sb)->list.prev =NULL ; +spin_unlock (&orangefs_superblocks_lock); + }/* * make sure that ORANGEFS_DEV_REMOUNT_ALL loop that might've seen us
Greg Kroah-Hartman
maintainerPATCH 9/69 drm/nouveau/mpeg: mthd returns true on success now
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilia Mirkin <[email protected]>
commit 83bce9c2baa51e439480a713119a73d3c8b61083 upstream.
--- drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c +1 -1
@@ -198,7 +198,7 @@ nv31_mpeg_intr(struct nvkm_engine *engin }if (type ==0x00000010 ) { -if (!nv31_mpeg_mthd (mpeg, mthd, data)) +if (nv31_mpeg_mthd (mpeg, mthd, data)) show &= ~0x01000000 ; } }
drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c +1 -1
@@ -172,7 +172,7 @@ nv44_mpeg_intr(struct nvkm_engine *engin }if (type ==0x00000010 ) { -if (!nv44_mpeg_mthd (subdev->device, mthd, data)) +if (nv44_mpeg_mthd (subdev->device, mthd, data)) show &= ~0x01000000 ; } }
Greg Kroah-Hartman
maintainerPATCH 10/69 drm/nouveau/mmu/nv4a: use nv04 mmu rather than the nv44 one
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilia Mirkin <[email protected]>
commit f94773b9f5ecd1df7c88c2e921924dd41d2020cc upstream.
The NV4A (aka NV44A) is an oddity in the family. It only comes in AGP and PCI varieties, rather than a core PCIE chip with a bridge for AGP/PCI as necessary. As a result, it appears that the MMU is also non-functional. For AGP cards, the vast majority of the NV4A lineup, this worked out since we force AGP cards to use the nv04 mmu. However for PCI variants, this did not work.
Switching to the NV04 MMU makes it work like a charm. Thanks to mwk for the suggestion. This should be a no-op for NV4A AGP boards, as they were using it already.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70388
--- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +1 -1
@@ -714,7 +714,7 @@ nv4a_chipset = { .i2c = nv04_i2c_new, .imem = nv40_instmem_new, .mc = nv44_mc_new, - .mmu = nv44_mmu_new, + .mmu = nv04_mmu_new, .pci = nv40_pci_new, .therm = nv40_therm_new, .timer = nv41_timer_new,
Greg Kroah-Hartman
maintainerPATCH 11/69 drm/etnaviv: fix missing unlock on error in etnaviv_gpu_submit()
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Yongjun <[email protected]>
commit 45abdf35cf82e4270328c7237e7812de960ac560 upstream.
Add the missing unlock before return from function etnaviv_gpu_submit() in the error handling case.
lst: fixed label name.
--- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/etnaviv/etnaviv_gpu.c +2 -1
@@ -1305,7 +1305,7 @@ int etnaviv_gpu_submit(struct etnaviv_gpif (!fence) {event_free (gpu, event); ret = -ENOMEM ; - goto out_pm_put; + goto out_unlock; } gpu->event[event].fence = fence;
@@ -1345,6 +1345,7 @@ int etnaviv_gpu_submit(struct etnaviv_gphangcheck_timer_reset (gpu); ret =0 ; +out_unlock:mutex_unlock (&gpu->lock); out_pm_put:
Greg Kroah-Hartman
maintainerPATCH 12/69 CIFS: reconnect thread reschedule itself
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Germano Percossi <[email protected]>
commit 18ea43113f5b74a97dd4be9bddbac10d68b1a6ce upstream.
In case of error, smb2_reconnect_server reschedule itself with a delay, to avoid being too aggressive.
--- fs/cifs/smb2pdu.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
fs/cifs/smb2pdu.c +9 -1
@@ -1987,6 +1987,9 @@ void smb2_reconnect_server(struct work_sstruct cifs_tcon *tcon, *tcon2;struct list_head tmp_list;int tcon_exist = false; +int rc; +int resched = false; +/* Prevent simultaneous reconnects that can corrupt tcon->rlist list */ mutex_lock (&server->reconnect_mutex);
@@ -2014,13 +2017,18 @@ void smb2_reconnect_server(struct work_sspin_unlock (&cifs_tcp_ses_lock);list_for_each_entry_safe (tcon, tcon2, &tmp_list, rlist) { -if (!smb2_reconnect (SMB2_INTERNAL_CMD , tcon)) + rc =smb2_reconnect (SMB2_INTERNAL_CMD , tcon); +if (!rc)cifs_reopen_persistent_handles (tcon); +else + resched = true;list_del_init (&tcon->rlist);cifs_put_tcon (tcon); }cifs_dbg (FYI ,"Reconnecting tcons finished\n" ); +if (resched) +queue_delayed_work (cifsiod_wq, &server->reconnect,2 *HZ );mutex_unlock (&server->reconnect_mutex);/* now we can safely release srv struct */
Greg Kroah-Hartman
maintainerPATCH 13/69 CIFS: store results of cifs_reopen_file to avoid infinite wait
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Germano Percossi <[email protected]>
commit 1fa839b4986d648b907d117275869a0e46c324b9 upstream.
This fixes Continuous Availability when errors during file reopen are encountered.
cifs_user_readv and cifs_user_writev would wait for ever if results of cifs_reopen_file are not stored and for later inspection.
In fact, results are checked and, in case of errors, a chain of function calls leading to reads and writes to be scheduled in a separate thread is skipped.
These threads will wake up the corresponding waiters once reads and writes are done.
However, given the return value is not stored, when rc is checked for errors a previous one (always zero) is inspected instead. This leads to pending reads/writes added to the list, making cifs_user_readv and cifs_user_writev wait for ever.
--- fs/cifs/file.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/cifs/file.c +3 -3
@@ -2597,7 +2597,7 @@ cifs_write_from_iter(loff_t offset, size wdata->credits = credits;if (!wdata->cfile->invalidHandle || - !cifs_reopen_file (wdata->cfile, false)) + !(rc =cifs_reopen_file (wdata->cfile, false))) rc = server->ops->async_writev (wdata, cifs_uncached_writedata_release);if (rc) {
@@ -3002,7 +3002,7 @@ cifs_send_async_read(loff_t offset, size rdata->credits = credits;if (!rdata->cfile->invalidHandle || - !cifs_reopen_file (rdata->cfile, true)) + !(rc =cifs_reopen_file (rdata->cfile, true))) rc = server->ops->async_readv (rdata); error:if (rc) {
@@ -3577,7 +3577,7 @@ static int cifs_readpages(struct file *f }if (!rdata->cfile->invalidHandle || - !cifs_reopen_file (rdata->cfile, true)) + !(rc =cifs_reopen_file (rdata->cfile, true))) rc = server->ops->async_readv (rdata);if (rc) {add_credits_and_wake_if (server, rdata->credits,0 );
Greg Kroah-Hartman
maintainerPATCH 14/69 Input: xpad - add support for Razer Wildcat gamepad
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cameron Gutman <[email protected]>
commit 5376366886251e2f8f248704adb620a4bc4c0937 upstream.
--- drivers/input/joystick/xpad.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/input/joystick/xpad.c +2 -0
@@ -201,6 +201,7 @@ static const struct xpad_device { { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, { 0x1532, 0x0037, "Razer Sabertooth", 0, XTYPE_XBOX360 }, + { 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE }, { 0x15e4, 0x3f00, "Power A Mini Pro Elite", 0, XTYPE_XBOX360 }, { 0x15e4, 0x3f0a, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 }, { 0x15e4, 0x3f10, "Batarang Xbox 360 controller", 0, XTYPE_XBOX360 },
@@ -329,6 +330,7 @@ static struct usb_device_id xpad_table[]XPAD_XBOX360_VENDOR (0x24c6 ),/* PowerA Controllers */ XPAD_XBOXONE_VENDOR (0x24c6 ),/* PowerA Controllers */ XPAD_XBOX360_VENDOR (0x1532 ),/* Razer Sabertooth */ +XPAD_XBOXONE_VENDOR (0x1532 ),/* Razer Wildcat */ XPAD_XBOX360_VENDOR (0x15e4 ),/* Numark X-Box 360 controllers */ XPAD_XBOX360_VENDOR(0x162e), /* Joytech X-Box 360 controllers */ { }
Greg Kroah-Hartman
maintainerPATCH 15/69 perf/x86: Avoid exposing wrong/stale data in intel_pmu_lbr_read_32()
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
commit f2200ac311302fcdca6556fd0c5127eab6c65a3e upstream.
When the perf_branch_entry::{in_tx,abort,cycles} fields were added, intel_pmu_lbr_read_32() wasn't updated to initialize them.
--- arch/x86/events/intel/lbr.c | 3 +++ 1 file changed, 3 insertions(+)
arch/x86/events/intel/lbr.c +3 -0
@@ -507,6 +507,9 @@ static void intel_pmu_lbr_read_32(struct cpuc->lbr_entries[i].to = msr_lastbranch.to; cpuc->lbr_entries[i].mispred =0 ; cpuc->lbr_entries[i].predicted =0 ; + cpuc->lbr_entries[i].in_tx =0 ; + cpuc->lbr_entries[i].abort =0 ; + cpuc->lbr_entries[i].cycles =0 ; cpuc->lbr_entries[i].reserved =0 ; } cpuc->lbr_stack.nr = i;
Greg Kroah-Hartman
maintainerPATCH 16/69 x86/efi: Dont try to reserve runtime regions
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Omar Sandoval <[email protected]>
commit 6f6266a561306e206e0e31a5038f029b6a7b1d89 upstream.
Reserving a runtime region results in splitting the EFI memory descriptors for the runtime region. This results in runtime region descriptors with bogus memory mappings, leading to interesting crashes like the following during a kexec:
general protection fault: 0000 [#1] SMP Modules linked in: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.11.0-rc1 #53 Hardware name: Wiwynn Leopard-Orv2/Leopard-DDR BW, BIOS LBM05 09/30/2016 RIP: 0010:virt_efi_set_variable() ... Call Trace: efi_delete_dummy_variable() efi_enter_virtual_mode() start_kernel() ? set_init_arg() x86_64_start_reservations() x86_64_start_kernel() start_cpu() ... Kernel panic - not syncing: Fatal exception
Runtime regions will not be freed and do not need to be reserved, so skip the memmap modification in this case.
--- arch/x86/platform/efi/quirks.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/x86/platform/efi/quirks.c +4 -0
@@ -201,6 +201,10 @@ void __init efi_arch_mem_reserve(phys_adreturn ; } +/* No need to reserve regions that will never be freed. */ +if (md.attribute &EFI_MEMORY_RUNTIME ) +return ; + size += addr %EFI_PAGE_SIZE ; size =round_up (size,EFI_PAGE_SIZE ); addr =round_down (addr,EFI_PAGE_SIZE );
Greg Kroah-Hartman
maintainerPATCH 17/69 x86/signals: Fix lower/upper bound reporting in compat siginfo
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joerg Roedel <[email protected]>
commit cfac6dfa42bddfa9711b20d486e521d1a41ab09f upstream.
Put the right values from the original siginfo into the userspace compat-siginfo.
This fixes the 32-bit MPX "tabletest" testcase on 64-bit kernels.
--- arch/x86/kernel/signal_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kernel/signal_compat.c +2 -2
@@ -151,8 +151,8 @@ int __copy_siginfo_to_user32(compat_sigiif (from->si_signo ==SIGSEGV ) {if (from->si_code ==SEGV_BNDERR ) { -compat_uptr_t lower = (unsigned long )&to->si_lower; -compat_uptr_t upper = (unsigned long )&to->si_upper; +compat_uptr_t lower = (unsigned long )from->si_lower; +compat_uptr_t upper = (unsigned long )from->si_upper;put_user_ex (lower, &to->si_lower);put_user_ex (upper, &to->si_upper); }
Greg Kroah-Hartman
maintainerPATCH 18/69 x86, pmem: fix broken __copy_user_nocache cache-bypass assumptions
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams <[email protected]>
commit 11e63f6d920d6f2dfd3cd421e939a4aec9a58dcd upstream.
Before we rework the "pmem api" to stop abusing __copy_user_nocache() for memcpy_to_pmem() we need to fix cases where we may strand dirty data in the cpu cache. The problem occurs when copy_from_iter_pmem() is used for arbitrary data transfers from userspace. There is no guarantee that these transfers, performed by dax_iomap_actor(), will have aligned destinations or aligned transfer lengths. Backstop the usage __copy_user_nocache() with explicit cache management in these unaligned cases.
Yes, copy_from_iter_pmem() is now too big for an inline, but addressing that is saved for a later patch that moves the entirety of the "pmem api" into the pmem driver directly.
--- arch/x86/include/asm/pmem.h | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-)
arch/x86/include/asm/pmem.h +31 -11
@@ -55,7 +55,8 @@ static inline int arch_memcpy_from_pmem(* @size: number of bytes to write back * * Write back a cache range using the CLWB (cache line write back) -* instruction. +* instruction. Note that @size is internally rounded up to be cache +* line size aligned. */ static inline void arch_wb_cache_pmem (void *addr,size_t size) {
@@ -69,15 +70,6 @@ static inline void arch_wb_cache_pmem(voclwb (p); } -/* -* copy_from_iter_nocache() on x86 only uses non-temporal stores for iovec -* iterators, so for other types (bvec & kvec) we must do a cache write-back. -*/ -static inline bool __iter_needs_pmem_wb (struct iov_iter *i) -{ -return iter_is_iovec (i) == false; -} -/** * arch_copy_from_iter_pmem - copy data from an iterator to PMEM * @addr: PMEM destination address
@@ -94,7 +86,35 @@ static inline size_t arch_copy_from_iter/* TODO: skip the write-back by always using non-temporal stores */ len =copy_from_iter_nocache (addr, bytes, i); -if (__iter_needs_pmem_wb (i)) +/* +* In the iovec case on x86_64 copy_from_iter_nocache() uses +* non-temporal stores for the bulk of the transfer, but we need +* to manually flush if the transfer is unaligned. A cached +* memory copy is used when destination or size is not naturally +* aligned. That is: +* - Require 8-byte alignment when size is 8 bytes or larger. +* - Require 4-byte alignment when size is 4 bytes. +* +* In the non-iovec case the entire destination needs to be +* flushed. +*/ +if (iter_is_iovec (i)) { +unsigned long flushed, dest = (unsigned long ) addr; + +if (bytes <8 ) { +if (!IS_ALIGNED (dest,4 ) || (bytes !=4 )) +arch_wb_cache_pmem (addr,1 ); + }else { +if (!IS_ALIGNED (dest,8 )) { + dest =ALIGN (dest, boot_cpu_data.x86_clflush_size); +arch_wb_cache_pmem (addr,1 ); + } + + flushed = dest - (unsigned long ) addr; +if (bytes > flushed && !IS_ALIGNED (bytes - flushed,8 )) +arch_wb_cache_pmem (addr + bytes -1 ,1 ); + } + }else arch_wb_cache_pmem (addr, bytes);return len;
Greg Kroah-Hartman
maintainerPATCH 19/69 x86/vdso: Ensure vdso32_enabled gets set to valid values only
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Krause <[email protected]>
commit c06989da39cdb10604d572c8c7ea8c8c97f3c483 upstream.
vdso_enabled can be set to arbitrary integer values via the kernel command line 'vdso32=' parameter or via 'sysctl abi.vsyscall32'.
load_vdso32() only maps VDSO if vdso_enabled == 1, but ARCH_DLINFO_IA32 merily checks for vdso_enabled != 0. As a consequence the AT_SYSINFO_EHDR auxiliary vector for the VDSO_ENTRY is emitted with a NULL pointer which causes a segfault when the application tries to use the VDSO.
Restrict the valid arguments on the command line and the sysctl to 0 and 1.
--- arch/x86/entry/vdso/vdso32-setup.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
arch/x86/entry/vdso/vdso32-setup.c +9 -2
@@ -30,8 +30,10 @@ static int __init vdso32_setup(char *s) { vdso32_enabled =simple_strtoul (s,NULL ,0 ); -if (vdso32_enabled >1 ) +if (vdso32_enabled >1 ) {pr_warn ("vdso32 values other than 0 and 1 are no longer allowed; vdso disabled\n" ); + vdso32_enabled =0 ; + }return 1 ; }
@@ -62,13 +64,18 @@ subsys_initcall(sysenter_setup);/* Register vsyscall32 into the ABI table */ #include <linux/sysctl.h> +static const int zero; +static const int one =1 ; +static struct ctl_table abi_table2[] = { { .procname ="vsyscall32" , .data = &vdso32_enabled, .maxlen =sizeof (int ), .mode =0644 , - .proc_handler = proc_dointvec + .proc_handler = proc_dointvec_minmax, + .extra1 = (int *)&zero, + .extra2 = (int *)&one, }, {} };
Greg Kroah-Hartman
maintainerPATCH 20/69 x86/vdso: Plug race between mapping and ELF header setup
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
commit 6fdc6dd90272ce7e75d744f71535cfbd8d77da81 upstream.
The vsyscall32 sysctl can racy against a concurrent fork when it switches from disabled to enabled:
arch_setup_additional_pages()
if (vdso32_enabled)
--> No mapping
sysctl.vsysscall32()
--> vdso32_enabled = true
create_elf_tables()
ARCH_DLINFO_IA32
if (vdso32_enabled) {
--> Add VDSO entry with NULL pointerMake ARCH_DLINFO_IA32 check whether the VDSO mapping has been set up for the newly forked process or not.
--- arch/x86/include/asm/elf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/elf.h +1 -1
@@ -278,7 +278,7 @@ struct task_struct;#define ARCH_DLINFO_IA32 \ do { \ - if (vdso32_enabled) { \ + if (VDSO_CURRENT_BASE) { \ NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \ } \
Greg Kroah-Hartman
maintainerPATCH 21/69 acpi, nfit, libnvdimm: fix interleave set cookie calculation (64-bit comparison)
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams <[email protected]>
commit b03b99a329a14b7302f37c3ea6da3848db41c8c5 upstream.
While reviewing the -stable patch for commit 86ef58a4e35e "nfit,
libnvdimm: fix interleave set cookie calculation" Ben noted:
"This is returning an int, thus it's effectively doing a 32-bit
comparison and not the 64-bit comparison you say is needed."
Update the compare operation to be immune to this integer demotion problem.
--- drivers/acpi/nfit/core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/acpi/nfit/core.c +5 -1
@@ -1617,7 +1617,11 @@ static int cmp_map(const void *m0, constconst struct nfit_set_info_map *map0 = m0;const struct nfit_set_info_map *map1 = m1; -return map0->region_offset - map1->region_offset; +if (map0->region_offset < map1->region_offset) +return -1 ; +else if (map0->region_offset > map1->region_offset) +return 1 ; +return 0 ; }/* Retrieve the nth entry referencing this spa */
Greg Kroah-Hartman
maintainerPATCH 22/69 ACPI / scan: Set the visited flag for all enumerated devices
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
commit f406270bf73d71ea7b35ee3f7a08a44f6594c9b1 upstream.
Commit 10c7e20b2ff3 (ACPI / scan: fix enumeration (visited) flags for bus rescans) attempted to fix a problem with ACPI-based enumerateion of I2C/SPI devices, but it forgot to ensure that the visited flag will be set for all of the other enumerated devices, so fix that.
--- drivers/acpi/scan.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
drivers/acpi/scan.c +12 -7
@@ -1827,15 +1827,20 @@ static void acpi_bus_attach(struct acpi_return ; device->flags.match_driver = true; -if (!ret) { - ret =device_attach (&device->dev); -if (ret <0 ) -return ; - -if (!ret && device->pnp.type.platform_id) -acpi_default_enumeration (device); +if (ret >0 ) { +acpi_device_set_enumerated (device); + goto ok; } + ret =device_attach (&device->dev); +if (ret <0 ) +return ; + +if (ret >0 || !device->pnp.type.platform_id) +acpi_device_set_enumerated (device); +else +acpi_default_enumeration (device); + ok:list_for_each_entry (child, &device->children, node)acpi_bus_attach (child);
Greg Kroah-Hartman
maintainerPATCH 23/69 parisc: fix bugs in pa_memcpy
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
commit 409c1b250e30ad0e48b4d15d7319b4e18c046c4f upstream.
The patch 554bfeceb8a22d448cd986fc9efce25e833278a1 ("parisc: Fix access fault handling in pa_memcpy()") reimplements the pa_memcpy function. Unfortunatelly, it makes the kernel unbootable. The crash happens in the function ide_complete_cmd where memcpy is called with the same source and destination address.
This patch fixes a few bugs in pa_memcpy:
* When jumping to .Lcopy_loop_16 for the first time, don't skip the instruction "ldi 31,t0" (this bug made the kernel unbootable)
* Use the COND macro when comparing length, so that the comparison is 64-bit (a theoretical issue, in case the length is greater than 0xffffffff)
* Don't use the COND macro after the "extru" instruction (the PA-RISC specification says that the upper 32-bits of extru result are undefined, although they are set to zero in practice)
* Fix exception addresses in .Lcopy16_fault and .Lcopy8_fault
* Rename .Lcopy_loop_4 to .Lcopy_loop_8 (so that it is consistent with .Lcopy8_fault)
--- arch/parisc/lib/lusercopy.S | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-)
arch/parisc/lib/lusercopy.S +14 -13
@@ -201,7 +201,7 @@ ENTRY_CFI(pa_memcpy) add dst,len,end /* short copy with less than 16 bytes? */ - cmpib,>>=,n 15,len,.Lbyte_loop + cmpib,COND(>>=),n 15,len,.Lbyte_loop /* same alignment? */ xor src,dst,t0
@@ -216,7 +216,7 @@ ENTRY_CFI(pa_memcpy) /* loop until we are 64-bit aligned */ .Lalign_loop64: extru dst,31,3,t1 - cmpib,=,n 0,t1,.Lcopy_loop_16 + cmpib,=,n 0,t1,.Lcopy_loop_16_start 20: ldb,ma 1(srcspc,src),t1 21: stb,ma t1,1(dstspc,dst) b .Lalign_loop64
@@ -225,6 +225,7 @@ ENTRY_CFI(pa_memcpy) ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done) ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done) +.Lcopy_loop_16_start: ldi 31,t0 .Lcopy_loop_16: cmpb,COND(>>=),n t0,len,.Lword_loop
@@ -267,7 +268,7 @@ ENTRY_CFI(pa_memcpy) /* loop until we are 32-bit aligned */ .Lalign_loop32: extru dst,31,2,t1 - cmpib,=,n 0,t1,.Lcopy_loop_4 + cmpib,=,n 0,t1,.Lcopy_loop_8 20: ldb,ma 1(srcspc,src),t1 21: stb,ma t1,1(dstspc,dst) b .Lalign_loop32
@@ -277,7 +278,7 @@ ENTRY_CFI(pa_memcpy) ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done) -.Lcopy_loop_4: +.Lcopy_loop_8: cmpib,COND(>>=),n 15,len,.Lbyte_loop 10: ldw 0(srcspc,src),t1
@@ -299,7 +300,7 @@ ENTRY_CFI(pa_memcpy) ASM_EXCEPTIONTABLE_ENTRY(16b,.Lcopy_done) ASM_EXCEPTIONTABLE_ENTRY(17b,.Lcopy_done) - b .Lcopy_loop_4 + b .Lcopy_loop_8 ldo -16(len),len .Lbyte_loop:
@@ -324,7 +325,7 @@ ENTRY_CFI(pa_memcpy) .Lunaligned_copy: /* align until dst is 32bit-word-aligned */ extru dst,31,2,t1 - cmpib,COND(=),n 0,t1,.Lcopy_dstaligned + cmpib,=,n 0,t1,.Lcopy_dstaligned 20: ldb 0(srcspc,src),t1 ldo 1(src),src 21: stb,ma t1,1(dstspc,dst)
@@ -362,7 +363,7 @@ ENTRY_CFI(pa_memcpy) cmpiclr,<> 1,t0,%r0 b,n .Lcase1 .Lcase0: - cmpb,= %r0,len,.Lcda_finish + cmpb,COND(=) %r0,len,.Lcda_finish nop 1: ldw,ma 4(srcspc,src), a3
@@ -376,7 +377,7 @@ ENTRY_CFI(pa_memcpy) 1: ldw,ma 4(srcspc,src), a3 ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault) ldo -1(len),len - cmpb,=,n %r0,len,.Ldo0 + cmpb,COND(=),n %r0,len,.Ldo0 .Ldo4: 1: ldw,ma 4(srcspc,src), a0 ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
@@ -402,7 +403,7 @@ ENTRY_CFI(pa_memcpy) 1: stw,ma t0, 4(dstspc,dst) ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done) ldo -4(len),len - cmpb,<> %r0,len,.Ldo4 + cmpb,COND(<>) %r0,len,.Ldo4 nop .Ldo0: shrpw a2, a3, %sar, t0
@@ -436,14 +437,14 @@ ENTRY_CFI(pa_memcpy) /* fault exception fixup handlers: */ #ifdef CONFIG_64BIT .Lcopy16_fault: -10: b .Lcopy_done - std,ma t1,8(dstspc,dst) + b .Lcopy_done +10: std,ma t1,8(dstspc,dst) ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done) #endif .Lcopy8_fault: -10: b .Lcopy_done - stw,ma t1,4(dstspc,dst) + b .Lcopy_done +10: stw,ma t1,4(dstspc,dst) ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done) .exit
Greg Kroah-Hartman
maintainerPATCH 24/69 efi/libstub: Skip GOP with PIXEL_BLT_ONLY format
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cohen, Eugene <[email protected]>
commit 540f4c0e894f7e46a66dfa424b16424cbdc12c38 upstream.
The UEFI Specification permits Graphics Output Protocol (GOP) instances without direct framebuffer access. This is indicated in the Mode structure with a PixelFormat enumeration value of PIXEL_BLT_ONLY. Given that the kernel does not know how to drive a Blt() only framebuffer (which is only permitted before ExitBootServices() anyway), we should disregard such framebuffers when looking for a GOP instance that is suitable for use as the boot console.
So modify the EFI GOP initialization to not use a PIXEL_BLT_ONLY instance, preventing attempts later in boot to use an invalid screen_info.lfb_base address.
--- drivers/firmware/efi/libstub/gop.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/firmware/efi/libstub/gop.c +4 -2
@@ -149,7 +149,8 @@ setup_gop32(efi_system_table_t *sys_tabl status =__gop_query32 (sys_table_arg, gop32, &info, &size, ¤t_fb_base); -if (status ==EFI_SUCCESS && (!first_gop || conout_found)) { +if (status ==EFI_SUCCESS && (!first_gop || conout_found) && + info->pixel_format !=PIXEL_BLT_ONLY ) {/* * Systems that use the UEFI Console Splitter may * provide multiple GOP devices, not all of which are
@@ -266,7 +267,8 @@ setup_gop64(efi_system_table_t *sys_tabl status =__gop_query64 (sys_table_arg, gop64, &info, &size, ¤t_fb_base); -if (status ==EFI_SUCCESS && (!first_gop || conout_found)) { +if (status ==EFI_SUCCESS && (!first_gop || conout_found) && + info->pixel_format !=PIXEL_BLT_ONLY ) {/* * Systems that use the UEFI Console Splitter may * provide multiple GOP devices, not all of which are
Greg Kroah-Hartman
maintainerPATCH 25/69 efi/fb: Avoid reconfiguration of BAR that covers the framebuffer
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ard Biesheuvel <[email protected]>
commit 55d728a40d368ba80443be85c02e641fc9082a3f upstream.
On UEFI systems, the PCI subsystem is enumerated by the firmware, and if a graphical framebuffer is exposed via a PCI device, its base address and size are exposed to the OS via the Graphics Output Protocol (GOP).
On arm64 PCI systems, the entire PCI hierarchy is reconfigured from scratch at boot. This may result in the GOP framebuffer address to become stale, if the BAR covering the framebuffer is modified. This will cause the framebuffer to become unresponsive, and may in some cases result in unpredictable behavior if the range is reassigned to another device.
So add a non-x86 quirk to the EFI fb driver to find the BAR associated with the GOP base address, and claim the BAR resource so that the PCI core will not move it.
--- drivers/video/fbdev/efifb.c | 66 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-)
drivers/video/fbdev/efifb.c +65 -1
@@ -10,6 +10,7 @@#include <linux/efi.h> #include <linux/errno.h> #include <linux/fb.h> +#include <linux/pci.h> #include <linux/platform_device.h> #include <linux/screen_info.h> #include <video/vga.h>
@@ -118,6 +119,8 @@ static inline bool fb_base_is_valid(voidreturn false; } +static bool pci_dev_disabled;/* FB base matches BAR of a disabled device */ +static int efifb_probe (struct platform_device *dev) {struct fb_info *info;
@@ -127,7 +130,7 @@ static int efifb_probe(struct platform_dunsigned int size_total;char *option =NULL ; -if (screen_info.orig_video_isVGA !=VIDEO_TYPE_EFI ) +if (screen_info.orig_video_isVGA !=VIDEO_TYPE_EFI || pci_dev_disabled)return -ENODEV ;if (fb_get_options ("efifb" , &option))
@@ -327,3 +330,64 @@ static struct platform_driver efifb_driv };builtin_platform_driver (efifb_driver); + +#if defined(CONFIG_PCI ) && !defined(CONFIG_X86 ) + +static bool pci_bar_found;/* did we find a BAR matching the efifb base? */ + +static void claim_efifb_bar (struct pci_dev *dev,int idx) +{ +u16 word; + + pci_bar_found = true; + +pci_read_config_word (dev,PCI_COMMAND , &word); +if (!(word &PCI_COMMAND_MEMORY )) { + pci_dev_disabled = true; +dev_err (&dev->dev, +"BAR %d: assigned to efifb but device is disabled!\n" , + idx); +return ; + } + +if (pci_claim_resource (dev, idx)) { + pci_dev_disabled = true; +dev_err (&dev->dev, +"BAR %d: failed to claim resource for efifb!\n" , idx); +return ; + } + +dev_info (&dev->dev,"BAR %d: assigned to efifb\n" , idx); +} + +static void efifb_fixup_resources (struct pci_dev *dev) +{ +u64 base = screen_info.lfb_base; +u64 size = screen_info.lfb_size; +int i; + +if (pci_bar_found || screen_info.orig_video_isVGA !=VIDEO_TYPE_EFI ) +return ; + +if (screen_info.capabilities &VIDEO_CAPABILITY_64BIT_BASE ) + base |= (u64 )screen_info.ext_lfb_base <<32 ; + +if (!base) +return ; + +for (i =0 ; i <PCI_STD_RESOURCE_END ; i++) { +struct resource *res = &dev->resource[i]; + +if (!(res->flags &IORESOURCE_MEM )) +continue ; + +if (res->start <= base && res->end >= base + size -1 ) { +claim_efifb_bar (dev, i); +break ; + } + } +} +DECLARE_PCI_FIXUP_CLASS_HEADER (PCI_ANY_ID ,PCI_ANY_ID ,PCI_BASE_CLASS_DISPLAY , +16 , efifb_fixup_resources); + +#endif
Greg Kroah-Hartman
maintainerPATCH 26/69 iscsi-target: Fix TMR reference leak during session shutdown
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Bellinger <[email protected]>
commit efb2ea770bb3b0f40007530bc8b0c22f36e1c5eb upstream.
This patch fixes a iscsi-target specific TMR reference leak during session shutdown, that could occur when a TMR was quiesced before the hand-off back to iscsi-target code via transport_cmd_check_stop_to_fabric().
The reference leak happens because iscsit_free_cmd() was incorrectly skipping the final target_put_sess_cmd() for TMRs when transport_generic_free_cmd() returned zero because the se_cmd->cmd_kref did not reach zero, due to the missing se_cmd assignment in original code.
The result was iscsi_cmd and it's associated se_cmd memory would be freed once se_sess->sess_cmd_map where released, but the associated se_tmr_req was leaked and remained part of se_device->dev_tmr_list.
This bug would manfiest itself as kernel paging request OOPsen in core_tmr_lun_reset(), when a left-over se_tmr_req attempted to dereference it's se_cmd pointer that had already been released during normal session shutdown.
To address this bug, go ahead and treat ISCSI_OP_SCSI_CMD and ISCSI_OP_SCSI_TMFUNC the same when there is an extra se_cmd->cmd_kref to drop in iscsit_free_cmd(), and use op_scsi to signal __iscsit_free_cmd() when the former needs to clear any further iscsi related I/O state.
--- drivers/target/iscsi/iscsi_target_util.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/target/iscsi/iscsi_target_util.c +7 -5
@@ -735,21 +735,23 @@ void iscsit_free_cmd(struct iscsi_cmd *c {struct se_cmd *se_cmd =NULL ;int rc; +bool op_scsi = false;/* * Determine if a struct se_cmd is associated with * this struct iscsi_cmd. */ switch (cmd->iscsi_opcode) {case ISCSI_OP_SCSI_CMD : - se_cmd = &cmd->se_cmd; -__iscsit_free_cmd (cmd, true, shutdown); + op_scsi = true;/* * Fallthrough */ case ISCSI_OP_SCSI_TMFUNC : - rc =transport_generic_free_cmd (&cmd->se_cmd, shutdown); -if (!rc && shutdown && se_cmd && se_cmd->se_sess) { -__iscsit_free_cmd (cmd, true, shutdown); + se_cmd = &cmd->se_cmd; +__iscsit_free_cmd (cmd, op_scsi, shutdown); + rc =transport_generic_free_cmd (se_cmd, shutdown); +if (!rc && shutdown && se_cmd->se_sess) { +__iscsit_free_cmd (cmd, op_scsi, shutdown);target_put_sess_cmd (se_cmd); }break ;
Greg Kroah-Hartman
maintainerPATCH 27/69 iscsi-target: Drop work-around for legacy GlobalSAN initiator
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Bellinger <[email protected]>
commit 1c99de981f30b3e7868b8d20ce5479fa1c0fea46 upstream.
Once upon a time back in 2009, a work-around was added to support the GlobalSAN iSCSI initiator v3.3 for MacOSX, which during login did not propose nor respond to MaxBurstLength, FirstBurstLength, DefaultTime2Wait and DefaultTime2Retain keys.
The work-around in iscsi_check_proposer_for_optional_reply() allowed the missing keys to be proposed, but did not require waiting for a response before moving to full feature phase operation. This allowed GlobalSAN v3.3 to work out-of-the box, and for many years we didn't run into login interopt issues with any other initiators..
Until recently, when Martin tried a QLogic 57840S iSCSI Offload HBA on Windows 2016 which completed login, but subsequently failed with:
Got unknown iSCSI OpCode: 0x43
The issue was QLogic MSFT side did not propose DefaultTime2Wait + DefaultTime2Retain, so LIO proposes them itself, and immediately transitions to full feature phase because of the GlobalSAN hack. However, the QLogic MSFT side still attempts to respond to DefaultTime2Retain + DefaultTime2Wait, even though LIO has set ISCSI_FLAG_LOGIN_NEXT_STAGE3 + ISCSI_FLAG_LOGIN_TRANSIT in last login response.
So while the QLogic MSFT side should have been proposing these two keys to start, it was doing the correct thing per RFC-3720 attempting to respond to proposed keys before transitioning to full feature phase.
All that said, recent versions of GlobalSAN iSCSI (v5.3.0.541) does correctly propose the four keys during login, making the original work-around moot.
So in order to allow QLogic MSFT to run unmodified as-is, go ahead and drop this long standing work-around.
--- drivers/target/iscsi/iscsi_target_parameters.c | 16 ---------------- 1 file changed, 16 deletions(-)
drivers/target/iscsi/iscsi_target_parameters.c +0 -16
@@ -782,22 +782,6 @@ static void iscsi_check_proposer_for_optif (!strcmp (param->name,MAXRECVDATASEGMENTLENGTH ))SET_PSTATE_REPLY_OPTIONAL (param);/* -* The GlobalSAN iSCSI Initiator for MacOSX does -* not respond to MaxBurstLength, FirstBurstLength, -* DefaultTime2Wait or DefaultTime2Retain parameter keys. -* So, we set them to 'reply optional' here, and assume the -* the defaults from iscsi_parameters.h if the initiator -* is not RFC compliant and the keys are not negotiated. -*/ -if (!strcmp (param->name,MAXBURSTLENGTH )) -SET_PSTATE_REPLY_OPTIONAL (param); -if (!strcmp (param->name,FIRSTBURSTLENGTH )) -SET_PSTATE_REPLY_OPTIONAL (param); -if (!strcmp (param->name,DEFAULTTIME2WAIT )) -SET_PSTATE_REPLY_OPTIONAL (param); -if (!strcmp (param->name,DEFAULTTIME2RETAIN )) -SET_PSTATE_REPLY_OPTIONAL (param); -/* * Required for gPXE iSCSI boot client */ if (!strcmp (param->name,MAXCONNECTIONS ))
Greg Kroah-Hartman
maintainerPATCH 28/69 scsi: sr: Sanity check returned mode data
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin K. Petersen <[email protected]>
commit a00a7862513089f17209b732f230922f1942e0b9 upstream.
Kefeng Wang discovered that old versions of the QEMU CD driver would return mangled mode data causing us to walk off the end of the buffer in an attempt to parse it. Sanity check the returned mode sense data.
--- drivers/scsi/sr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/scsi/sr.c +4 -2
@@ -833,6 +833,7 @@ static void get_capabilities(struct scsiunsigned char *buffer;struct scsi_mode_data data;struct scsi_sense_hdr sshdr; +unsigned int ms_len =128 ;int rc, n; static const char *loadmech[] =
@@ -859,10 +860,11 @@ static void get_capabilities(struct scsiscsi_test_unit_ready (cd->device,SR_TIMEOUT ,MAX_RETRIES , &sshdr);/* ask for mode page 0x2a */ - rc =scsi_mode_sense (cd->device,0 ,0x2a , buffer,128 , + rc =scsi_mode_sense (cd->device,0 ,0x2a , buffer, ms_len,SR_TIMEOUT ,3 , &data,NULL ); -if (!scsi_status_is_good (rc)) { +if (!scsi_status_is_good (rc) || data.length > ms_len || + data.header_length + data.block_descriptor_length > data.length) {/* failed, drive doesn't have capabilities mode page */ cd->cdi.speed =1 ; cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |
Greg Kroah-Hartman
maintainerPATCH 29/69 scsi: sd: Consider max_xfer_blocks if opt_xfer_blocks is unusable
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fam Zheng <[email protected]>
commit 6780414519f91c2a84da9baa963a940ac916f803 upstream.
If device reports a small max_xfer_blocks and a zero opt_xfer_blocks, we end up using BLK_DEF_MAX_SECTORS, which is wrong and r/w of that size may get error.
[mkp: tweaked to avoid setting rw_max twice and added typecast]
--- drivers/scsi/sd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/scsi/sd.c +2 -1
@@ -2877,7 +2877,8 @@ static int sd_revalidate_disk(struct gen q->limits.io_opt =logical_to_bytes (sdp, sdkp->opt_xfer_blocks); rw_max =logical_to_sectors (sdp, sdkp->opt_xfer_blocks); }else - rw_max =BLK_DEF_MAX_SECTORS ; + rw_max =min_not_zero (logical_to_sectors (sdp, dev_max), + (sector_t )BLK_DEF_MAX_SECTORS );/* Combine with controller limits */ q->limits.max_sectors =min (rw_max,queue_max_hw_sectors (q));
Greg Kroah-Hartman
maintainerPATCH 30/69 scsi: qla2xxx: Add fix to read correct register value for ISP82xx.
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sawan Chandak <[email protected]>
commit bf6061b17a8d47ef0d9344d3ef576a4ff0edf793 upstream.
Add fix to read correct register value for ISP82xx, during check for register disconnect.ISP82xx has different base register.
--- drivers/scsi/qla2xxx/qla_os.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/scsi/qla2xxx/qla_os.c +6 -1
@@ -968,8 +968,13 @@ static inlineuint32_t qla2x00_isp_reg_stat (struct qla_hw_data *ha) {struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; +struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82; -return ((RD_REG_DWORD (®->host_status)) ==ISP_REG_DISCONNECT ); +if (IS_P3P_TYPE (ha)) +return ((RD_REG_DWORD (®82->host_int)) ==ISP_REG_DISCONNECT ); +else +return ((RD_REG_DWORD (®->host_status)) == +ISP_REG_DISCONNECT ); }/**************************************************************************
Greg Kroah-Hartman
maintainerPATCH 31/69 scsi: sd: Fix capacity calculation with 32-bit sector_t
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin K. Petersen <[email protected]>
commit 7c856152cb92f8eee2df29ef325a1b1f43161aff upstream.
We previously made sure that the reported disk capacity was less than 0xffffffff blocks when the kernel was not compiled with large sector_t support (CONFIG_LBDAF). However, this check assumed that the capacity was reported in units of 512 bytes.
Add a sanity check function to ensure that we only enable disks if the entire reported capacity can be expressed in terms of sector_t.
--- drivers/scsi/sd.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
drivers/scsi/sd.c +18 -2
@@ -2057,6 +2057,22 @@ static void read_capacity_error(struct s#define READ_CAPACITY_RETRIES_ON_RESET 10 +/* +* Ensure that we don't overflow sector_t when CONFIG_LBDAF is not set +* and the reported logical block size is bigger than 512 bytes. Note +* that last_sector is a u64 and therefore logical_to_sectors() is not +* applicable. +*/ +static bool sd_addressable_capacity (u64 lba,unsigned int sector_size) +{ +u64 last_sector = (lba +1ULL ) << (ilog2 (sector_size) -9 ); + +if (sizeof (sector_t) ==4 && last_sector >U32_MAX ) +return false; + +return true; +} +static int read_capacity_16 (struct scsi_disk *sdkp,struct scsi_device *sdp,unsigned char *buffer) {
@@ -2122,7 +2138,7 @@ static int read_capacity_16(struct scsi_return -ENODEV ; } -if ((sizeof (sdkp->capacity) ==4 ) && (lba >=0xffffffffULL )) { +if (!sd_addressable_capacity (lba, sector_size)) {sd_printk (KERN_ERR , sdkp,"Too big for this kernel. Use a " "kernel compiled with support for large block " "devices.\n" );
@@ -2208,7 +2224,7 @@ static int read_capacity_10(struct scsi_return sector_size; } -if ((sizeof (sdkp->capacity) ==4 ) && (lba ==0xffffffff )) { +if (!sd_addressable_capacity (lba, sector_size)) {sd_printk (KERN_ERR , sdkp,"Too big for this kernel. Use a " "kernel compiled with support for large block " "devices.\n" );
Greg Kroah-Hartman
maintainerPATCH 32/69 target: Avoid mappedlun symlink creation during lun shutdown
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Bellinger <[email protected]>
commit 49cb77e297dc611a1b795cfeb79452b3002bd331 upstream.
This patch closes a race between se_lun deletion during configfs unlink in target_fabric_port_unlink() -> core_dev_del_lun() -> core_tpg_remove_lun(), when transport_clear_lun_ref() blocks waiting for percpu_ref RCU grace period to finish, but a new NodeACL mappedlun is added before the RCU grace period has completed.
This can happen in target_fabric_mappedlun_link() because it only checks for se_lun->lun_se_dev, which is not cleared until after transport_clear_lun_ref() percpu_ref RCU grace period finishes.
This bug originally manifested as NULL pointer dereference OOPsen in target_stat_scsi_att_intr_port_show_attr_dev() on v4.1.y code, because it dereferences lun->lun_se_dev without a explicit NULL pointer check.
In post v4.1 code with target-core RCU conversion, the code in target_stat_scsi_att_intr_port_show_attr_dev() no longer uses se_lun->lun_se_dev, but the same race still exists.
To address the bug, go ahead and set se_lun>lun_shutdown as early as possible in core_tpg_remove_lun(), and ensure new NodeACL mappedlun creation in target_fabric_mappedlun_link() fails during se_lun shutdown.
--- drivers/target/target_core_fabric_configfs.c | 5 +++++ drivers/target/target_core_tpg.c | 4 ++++ include/target/target_core_base.h | 1 + 3 files changed, 10 insertions(+)
drivers/target/target_core_fabric_configfs.c +5 -0
@@ -92,6 +92,11 @@ static int target_fabric_mappedlun_link(pr_err ("Source se_lun->lun_se_dev does not exist\n" );return -EINVAL ; } +if (lun->lun_shutdown) { +pr_err ("Unable to create mappedlun symlink because" +" lun->lun_shutdown=true\n" ); +return -EINVAL ; + } se_tpg = lun->lun_tpg; nacl_ci = &lun_acl_ci->ci_parent->ci_group->cg_item;
drivers/target/target_core_tpg.c +4 -0
@@ -640,6 +640,8 @@ void core_tpg_remove_lun(*/ struct se_device *dev =rcu_dereference_raw (lun->lun_se_dev); + lun->lun_shutdown = true; +core_clear_lun_from_tpg (lun, tpg);/* * Wait for any active I/O references to percpu se_lun->lun_ref to
@@ -661,6 +663,8 @@ void core_tpg_remove_lun( }if (!(dev->se_hba->hba_flags &HBA_FLAGS_INTERNAL_USE ))hlist_del_rcu (&lun->link); + + lun->lun_shutdown = false;mutex_unlock (&tpg->tpg_lun_mutex);percpu_ref_exit (&lun->lun_ref);
include/target/target_core_base.h +1 -0
@@ -705,6 +705,7 @@ struct se_lun {u64 unpacked_lun;#define SE_LUN_LINK_MAGIC 0xffff7771u32 lun_link_magic; +bool lun_shutdown;bool lun_access_ro;u32 lun_index;
Greg Kroah-Hartman
maintainerPATCH 33/69 xen, fbfront: fix connecting to backend
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juergen Gross <[email protected]>
commit 9121b15b5628b38b4695282dc18c553440e0f79b upstream.
Connecting to the backend isn't working reliably in xen-fbfront: in case XenbusStateInitWait of the backend has been missed the backend transition to XenbusStateConnected will trigger the connected state only without doing the actions required when the backend has connected.
--- drivers/video/fbdev/xen-fbfront.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/video/fbdev/xen-fbfront.c +2 -2
@@ -644,7 +644,6 @@ static void xenfb_backend_changed(structbreak ;case XenbusStateInitWait: -InitWait:xenbus_switch_state (dev, XenbusStateConnected);break ;
@@ -655,7 +654,8 @@ InitWait:* get Connected twice here. */ if (dev->state != XenbusStateConnected) - goto InitWait;/* no InitWait seen yet, fudge it */ +/* no InitWait seen yet, fudge it */ +xenbus_switch_state (dev, XenbusStateConnected);if (xenbus_scanf (XBT_NIL , info->xbdev->otherend,"request-update" ,"%d" , &val) <0 )
Greg Kroah-Hartman
maintainerPATCH 34/69 new privimitive: iov_iter_revert()
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 27c0e3748e41ca79171ffa3e97415a20af6facd0 upstream.
opposite to iov_iter_advance(); the caller is responsible for never using it to move back past the initial position.
--- include/linux/uio.h | 6 ++++ lib/iov_iter.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-)
include/linux/uio.h +5 -1
@@ -39,7 +39,10 @@ struct iov_iter { };union {unsigned long nr_segs; -int idx; +struct { +int idx; +int start_idx; + }; }; };
@@ -81,6 +84,7 @@ unsigned long iov_shorten(struct iovec *size_t iov_iter_copy_from_user_atomic (struct page *page,struct iov_iter *i,unsigned long offset,size_t bytes);void iov_iter_advance (struct iov_iter *i,size_t bytes); +void iov_iter_revert (struct iov_iter *i,size_t bytes);int iov_iter_fault_in_readable (struct iov_iter *i,size_t bytes);size_t iov_iter_single_seg_count (const struct iov_iter *i); size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
lib/iov_iter.c +63 -0
75 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 35/69 make skb_copy_datagram_msg() et.al. preserve ->msg_iter on error
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 3278682123811dd8ef07de5eb701fc4548fcebf2 upstream.
Fixes the mess observed in e.g. rsync over a noisy link we'd been seeing since last Summer. What happens is that we copy part of a datagram before noticing a checksum mismatch. Datagram will be resent, all right, but we want the next try go into the same place, not after it...
All this family of primitives (copy/checksum and copy a datagram into destination) is "all or nothing" sort of interface - either we get 0 (meaning that copy had been successful) or we get an error (and no way to tell how much had been copied before we ran into whatever error it had been). Make all of them leave iterator unadvanced in case of errors - all callers must be able to cope with that (an error might've been caught before the iterator had been advanced), it costs very little to arrange, it's safer for callers and actually fixes at least one bug in said callers.
--- net/core/datagram.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
net/core/datagram.c +14 -9
@@ -378,7 +378,7 @@ int skb_copy_datagram_iter(const struct struct iov_iter *to, int len) { int start = skb_headlen(skb); -int i, copy = start - offset; +int i, copy = start - offset, start_off = offset, n;struct sk_buff *frag_iter;trace_skb_copy_datagram_iovec (skb, len);
@@ -387,11 +387,12 @@ int skb_copy_datagram_iter(const structif (copy >0 ) {if (copy > len) copy = len; -if (copy_to_iter (skb->data + offset, copy, to) != copy) + n =copy_to_iter (skb->data + offset, copy, to); + offset += n; +if (n != copy) goto short_copy;if ((len -= copy) ==0 )return 0 ; - offset += copy; }/* Copy paged appendix. Hmm... why does this look so complicated? */
@@ -405,13 +406,14 @@ int skb_copy_datagram_iter(const structif ((copy = end - offset) >0 ) {if (copy > len) copy = len; -if (copy_page_to_iter (skb_frag_page (frag), + n =copy_page_to_iter (skb_frag_page (frag), frag->page_offset + offset - - start, copy, to) != copy) + start, copy, to); + offset += n; +if (n != copy) goto short_copy;if (!(len -= copy))return 0 ; - offset += copy; } start = end; }
@@ -443,6 +445,7 @@ int skb_copy_datagram_iter(const struct*/ fault: +iov_iter_revert (to, offset - start_off);return -EFAULT ; short_copy:
@@ -593,7 +596,7 @@ static int skb_copy_and_csum_datagram(co __wsum *csump) {int start =skb_headlen (skb); -int i, copy = start - offset; +int i, copy = start - offset, start_off = offset;struct sk_buff *frag_iter;int pos =0 ;int n;
@@ -603,11 +606,11 @@ static int skb_copy_and_csum_datagram(coif (copy > len) copy = len; n =csum_and_copy_to_iter (skb->data + offset, copy, csump, to); + offset += n;if (n != copy) goto fault;if ((len -= copy) ==0 )return 0 ; - offset += copy; pos = copy; }
@@ -629,12 +632,12 @@ static int skb_copy_and_csum_datagram(co offset - start, copy, &csum2, to);kunmap (page); + offset += n;if (n != copy) goto fault; *csump =csum_block_add (*csump, csum2, pos);if (!(len -= copy))return 0 ; - offset += copy; pos += copy; } start = end;
@@ -667,6 +670,7 @@ static int skb_copy_and_csum_datagram(coreturn 0 ; fault: +iov_iter_revert (to, offset - start_off);return -EFAULT ; }
@@ -751,6 +755,7 @@ int skb_copy_and_csum_datagram_msg(struc }return 0 ; csum_error: +iov_iter_revert (&msg->msg_iter, chunk);return -EINVAL ; fault:return -EFAULT ;
Greg Kroah-Hartman
maintainerPATCH 36/69 libnvdimm: fix blk free space accounting
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams <[email protected]>
commit fe514739d8538783749d3ce72f78e5a999ea5668 upstream.
Commit a1f3e4d6a0c3 "libnvdimm, region: update nd_region_available_dpa() for multi-pmem support" reworked blk dpa (DIMM Physical Address) accounting to comprehend multiple pmem namespace allocations aliasing with a given blk-dpa range.
The following call trace is a result of failing to account for allocated blk capacity.
WARNING: CPU: 1 PID: 2433 at tools/testing/nvdimm/../../../drivers/nvdimm/names 4 size_store+0x6f3/0x930 [libnvdimm] nd_region region5: allocation underrun: 0x0 of 0x1000000 bytes [..] Call Trace: dump_stack+0x86/0xc3 __warn+0xcb/0xf0 warn_slowpath_fmt+0x5f/0x80 size_store+0x6f3/0x930 [libnvdimm] dev_attr_store+0x18/0x30
If a given blk-dpa allocation does not alias with any pmem ranges then the full allocation should be accounted as busy space, not the size of the current pmem contribution to the region.
The thinkos that led to this confusion was not realizing that the struct resource management is already guaranteeing no collisions between pmem allocations and blk allocations on the same dimm. Also, we do not try to support blk allocations in aliased pmem holes.
This patch also fixes a case where the available blk goes negative.
--- drivers/nvdimm/dimm_devs.c | 77 ++++++--------------------------------------- 1 file changed, 11 insertions(+), 66 deletions(-)
drivers/nvdimm/dimm_devs.c +11 -66
@@ -388,7 +388,7 @@ EXPORT_SYMBOL_GPL(nvdimm_create);int alias_dpa_busy (struct device *dev,void *data) { -resource_size_t map_end, blk_start, new, busy; +resource_size_t map_end, blk_start, new;struct blk_alloc_info *info = data;struct nd_mapping *nd_mapping;struct nd_region *nd_region;
@@ -429,29 +429,19 @@ int alias_dpa_busy(struct device *dev, v retry:/* * Find the free dpa from the end of the last pmem allocation to -* the end of the interleave-set mapping that is not already -* covered by a blk allocation. +* the end of the interleave-set mapping. */ - busy =0 ;for_each_dpa_resource (ndd, res) { +if (strncmp (res->name,"pmem" ,4 ) !=0 ) +continue ;if ((res->start >= blk_start && res->start < map_end) || (res->end >= blk_start && res->end <= map_end)) { -if (strncmp (res->name,"pmem" ,4 ) ==0 ) { - new =max (blk_start,min (map_end +1 , - res->end +1 )); -if (new != blk_start) { - blk_start = new; - goto retry; - } - }else - busy +=min (map_end, res->end) - -max (nd_mapping->start, res->start) +1 ; - }else if (nd_mapping->start > res->start - && map_end < res->end) { -/* total eclipse of the PMEM region mapping */ - busy += nd_mapping->size; -break ; + new =max (blk_start,min (map_end +1 , res->end +1 )); +if (new != blk_start) { + blk_start = new; + goto retry; + } } }
@@ -463,52 +453,11 @@ int alias_dpa_busy(struct device *dev, vreturn 1 ; } - info->available -= blk_start - nd_mapping->start + busy; + info->available -= blk_start - nd_mapping->start;return 0 ; } -static int blk_dpa_busy (struct device *dev,void *data) -{ -struct blk_alloc_info *info = data; -struct nd_mapping *nd_mapping; -struct nd_region *nd_region; -resource_size_t map_end; -int i; - -if (!is_nd_pmem (dev)) -return 0 ; - - nd_region =to_nd_region (dev); -for (i =0 ; i < nd_region->ndr_mappings; i++) { - nd_mapping = &nd_region->mapping[i]; -if (nd_mapping->nvdimm == info->nd_mapping->nvdimm) -break ; - } - -if (i >= nd_region->ndr_mappings) -return 0 ; - - map_end = nd_mapping->start + nd_mapping->size -1 ; -if (info->res->start >= nd_mapping->start - && info->res->start < map_end) { -if (info->res->end <= map_end) { - info->busy =0 ; -return 1 ; - }else { - info->busy -= info->res->end - map_end; -return 0 ; - } - }else if (info->res->end >= nd_mapping->start - && info->res->end <= map_end) { - info->busy -= nd_mapping->start - info->res->start; -return 0 ; - }else { - info->busy -= nd_mapping->size; -return 0 ; - } -} -/** * nd_blk_available_dpa - account the unused dpa of BLK region * @nd_mapping: container of dpa-resource-root + labels
@@ -538,11 +487,7 @@ resource_size_t nd_blk_available_dpa(strfor_each_dpa_resource (ndd, res) {if (strncmp (res->name,"blk" ,3 ) !=0 )continue ; - - info.res = res; - info.busy =resource_size (res); -device_for_each_child (&nvdimm_bus->dev, &info, blk_dpa_busy); - info.available -= info.busy; + info.available -=resource_size (res); }return info.available;
Greg Kroah-Hartman
maintainerPATCH 37/69 libnvdimm: fix reconfig_mutex, mmap_sem, and jbd2_handle lockdep splat
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams <[email protected]>
commit 0beb2012a1722633515c8aaa263c73449636c893 upstream.
Holding the reconfig_mutex over a potential userspace fault sets up a lockdep dependency chain between filesystem-DAX and the libnvdimm ioctl path. Move the user access outside of the lock.
[ INFO: possible circular locking dependency detected ]
4.11.0-rc3+ #13 Tainted: G W O
-------------------------------------------------------
fallocate/16656 is trying to acquire lock:
(&nvdimm_bus->reconfig_mutex){+.+.+.}, at: [<ffffffffa00080b1>] nvdimm_bus_lock+0x21/0x30 [libnvdimm]
but task is already holding lock:
(jbd2_handle){++++..}, at: [<ffffffff813b4944>] start_this_handle+0x104/0x460
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (jbd2_handle){++++..}:
lock_acquire+0xbd/0x200
start_this_handle+0x16a/0x460
jbd2__journal_start+0xe9/0x2d0
__ext4_journal_start_sb+0x89/0x1c0
ext4_dirty_inode+0x32/0x70
__mark_inode_dirty+0x235/0x670
generic_update_time+0x87/0xd0
touch_atime+0xa9/0xd0
ext4_file_mmap+0x90/0xb0
mmap_region+0x370/0x5b0
do_mmap+0x415/0x4f0
vm_mmap_pgoff+0xd7/0x120
SyS_mmap_pgoff+0x1c5/0x290
SyS_mmap+0x22/0x30
entry_SYSCALL_64_fastpath+0x1f/0xc2
-> #1 (&mm->mmap_sem){++++++}:
lock_acquire+0xbd/0x200
__might_fault+0x70/0xa0
__nd_ioctl+0x683/0x720 [libnvdimm]
nvdimm_ioctl+0x8b/0xe0 [libnvdimm]
do_vfs_ioctl+0xa8/0x740
SyS_ioctl+0x79/0x90
do_syscall_64+0x6c/0x200
return_from_SYSCALL_64+0x0/0x7a
-> #0 (&nvdimm_bus->reconfig_mutex){+.+.+.}:
__lock_acquire+0x16b6/0x1730
lock_acquire+0xbd/0x200
__mutex_lock+0x88/0x9b0
mutex_lock_nested+0x1b/0x20
nvdimm_bus_lock+0x21/0x30 [libnvdimm]
nvdimm_forget_poison+0x25/0x50 [libnvdimm]
nvdimm_clear_poison+0x106/0x140 [libnvdimm]
pmem_do_bvec+0x1c2/0x2b0 [nd_pmem]
pmem_make_request+0xf9/0x270 [nd_pmem]
generic_make_request+0x118/0x3b0
submit_bio+0x75/0x150--- drivers/nvdimm/bus.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/nvdimm/bus.c +6 -0
@@ -934,8 +934,14 @@ static int __nd_ioctl(struct nvdimm_bus rc = nd_desc->ndctl (nd_desc, nvdimm, cmd, buf, buf_len,NULL );if (rc <0 ) goto out_unlock; +nvdimm_bus_unlock (&nvdimm_bus->dev); +if (copy_to_user (p, buf, buf_len)) rc = -EFAULT ; + +vfree (buf); +return rc; + out_unlock:nvdimm_bus_unlock (&nvdimm_bus->dev); out:
Greg Kroah-Hartman
maintainerPATCH 38/69 can: ifi: use correct register to read rx status
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Markus Marb <[email protected]>
commit 57c1d4c33e8f7ec90976d79127059c1919cc0651 upstream.
The incorrect offset was used when trying to read the RXSTCMD register.
--- drivers/net/can/ifi_canfd/ifi_canfd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/can/ifi_canfd/ifi_canfd.c +1 -1
@@ -557,7 +557,7 @@ static int ifi_canfd_poll(struct napi_stint work_done =0 ;u32 stcmd =readl (priv->base +IFI_CANFD_STCMD ); -u32 rxstcmd =readl (priv->base +IFI_CANFD_STCMD ); +u32 rxstcmd =readl (priv->base +IFI_CANFD_RXSTCMD );u32 errctr =readl (priv->base +IFI_CANFD_ERROR_CTR );/* Handle bus state changes */
Greg Kroah-Hartman
maintainerPATCH 39/69 pwm: rockchip: State of PWM clock should synchronize with PWM enabled state
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Wu <[email protected]>
commit a900152b5c29aea8134cc7a4c5db25552b3cd8f7 upstream.
If the PWM was not enabled at U-Boot loader, PWM could not work for clock always disabled at PWM driver. The PWM clock is enabled at beginning of pwm_apply(), but disabled at end of pwm_apply().
If the PWM was enabled at U-Boot loader, PWM clock is always enabled unless closed by ATF. The pwm-backlight might turn off the power at early suspend, should disable PWM clock for saving power consume.
It is important to provide opportunity to enable/disable clock at PWM driver, the PWM consumer should ensure correct order to call PWM enable and disable, and PWM driver ensure state of PWM clock synchronized with PWM enabled state.
--- drivers/pwm/pwm-rockchip.c | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-)
drivers/pwm/pwm-rockchip.c +33 -7
@@ -191,6 +191,28 @@ static int rockchip_pwm_config(struct pwreturn 0 ; } +static int rockchip_pwm_enable (struct pwm_chip *chip, +struct pwm_device *pwm, +bool enable, +enum pwm_polarity polarity) +{ +struct rockchip_pwm_chip *pc =to_rockchip_pwm_chip (chip); +int ret; + +if (enable) { + ret =clk_enable (pc->clk); +if (ret) +return ret; + } + + pc->data->set_enable (chip, pwm, enable, polarity); + +if (!enable) +clk_disable (pc->clk); + +return 0 ; +} +static int rockchip_pwm_apply (struct pwm_chip *chip,struct pwm_device *pwm,struct pwm_state *state) {
@@ -207,22 +229,26 @@ static int rockchip_pwm_apply(struct pwmreturn ret;if (state->polarity != curstate.polarity && enabled) { - pc->data->set_enable (chip, pwm, false, state->polarity); + ret =rockchip_pwm_enable (chip, pwm, false, state->polarity); +if (ret) + goto out; enabled = false; } ret =rockchip_pwm_config (chip, pwm, state->duty_cycle, state->period);if (ret) {if (enabled != curstate.enabled) - pc->data->set_enable (chip, pwm, !enabled, - state->polarity); - +rockchip_pwm_enable (chip, pwm, !enabled, + state->polarity); goto out; } -if (state->enabled != enabled) - pc->data->set_enable (chip, pwm, state->enabled, - state->polarity); +if (state->enabled != enabled) { + ret =rockchip_pwm_enable (chip, pwm, state->enabled, + state->polarity); +if (ret) + goto out; + }/* * Update the state with the real hardware, which can differ a bit
Greg Kroah-Hartman
maintainerPATCH 40/69 cpufreq: Bring CPUs up even if cpufreq_online() failed
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Yu <[email protected]>
commit c4a3fa261b16858416f1fd7db03a33d7ef5fc0b3 upstream.
There is a report that after commit 27622b061eb4 ("cpufreq: Convert to hotplug state machine"), the normal CPU offline/online cycle fails on some platforms.
According to the ftrace result, this problem was triggered on platforms using acpi-cpufreq as the default cpufreq driver, and due to the lack of some ACPI freq method (eg. _PCT), cpufreq_online() failed and returned a negative value, so the CPU hotplug state machine rolled back the CPU online process. Actually, from the user's perspective, the failure of cpufreq_online() should not prevent that CPU from being brought up, although cpufreq might not work on that CPU.
BTW, during system startup cpufreq_online() is not invoked via CPU online but by the cpufreq device creation process, so the APs can be brought up even though cpufreq_online() fails in that stage.
This patch ignores the return value of cpufreq_online/offline() and lets the cpufreq framework deal with the failure. cpufreq_online() itself will do a proper rollback in that case and if _PCT is missing, the ACPI cpufreq driver will print a warning if the corresponding debug options have been enabled.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=194581
--- drivers/cpufreq/cpufreq.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
drivers/cpufreq/cpufreq.c +16 -2
@@ -2404,6 +2404,20 @@ EXPORT_SYMBOL_GPL(cpufreq_boost_enabled)*********************************************************************/ static enum cpuhp_state hp_online; +static int cpuhp_cpufreq_online (unsigned int cpu) +{ +cpufreq_online (cpu); + +return 0 ; +} + +static int cpuhp_cpufreq_offline (unsigned int cpu) +{ +cpufreq_offline (cpu); + +return 0 ; +} +/** * cpufreq_register_driver - register a CPU Frequency driver * @driver_data: A struct cpufreq_driver containing the values#
@@ -2466,8 +2480,8 @@ int cpufreq_register_driver(struct cpufr } ret =cpuhp_setup_state_nocalls (CPUHP_AP_ONLINE_DYN ,"cpufreq:online" , - cpufreq_online, - cpufreq_offline); + cpuhp_cpufreq_online, + cpuhp_cpufreq_offline);if (ret <0 ) goto err_if_unreg; hp_online = ret;
Greg Kroah-Hartman
maintainerPATCH 41/69 irqchip/irq-imx-gpcv2: Fix spinlock initialization
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tyler Baker <[email protected]>
commit 75eb5e1e7b4edbc8e8f930de59004d21cb46961f upstream.
The raw_spinlock in the IMX GPCV2 interupt chip is not initialized before usage. That results in a lockdep splat:
INFO: trying to register non-static key.
the code is fine but needs lockdep annotation.
turning off the locking correctness validator.
Add the missing raw_spin_lock_init() to the setup code.
--- drivers/irqchip/irq-imx-gpcv2.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/irqchip/irq-imx-gpcv2.c +2 -0
@@ -230,6 +230,8 @@ static int __init imx_gpcv2_irqchip_initreturn -ENOMEM ; } +raw_spin_lock_init (&cd->rlock); + cd->gpc_base =of_iomap (node,0 );if (!cd->gpc_base) {pr_err ("fsl-gpcv2: unable to map gpc registers\n" );
Greg Kroah-Hartman
maintainerPATCH 42/69 ftrace: Fix removing of second function probe
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (VMware) <[email protected]>
commit 82cc4fc2e70ec5baeff8f776f2773abc8b2cc0ae upstream.
When two function probes are added to set_ftrace_filter, and then one of them is removed, the update to the function locations is not performed, and the record keeping of the function states are corrupted, and causes an ftrace_bug() to occur.
This is easily reproducable by adding two probes, removing one, and then adding it back again.
# cd /sys/kernel/debug/tracing # echo schedule:traceoff > set_ftrace_filter # echo do_IRQ:traceoff > set_ftrace_filter # echo \!do_IRQ:traceoff > /debug/tracing/set_ftrace_filter # echo do_IRQ:traceoff > set_ftrace_filter
Causes:
------------[ cut here ]------------ WARNING: CPU: 2 PID: 1098 at kernel/trace/ftrace.c:2369 ftrace_get_addr_curr+0x143/0x220 Modules linked in: [...] CPU: 2 PID: 1098 Comm: bash Not tainted 4.10.0-test+ #405 Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01 v02.05 05/07/2012 Call Trace: dump_stack+0x68/0x9f __warn+0x111/0x130 ? trace_irq_work_interrupt+0xa0/0xa0 warn_slowpath_null+0x1d/0x20 ftrace_get_addr_curr+0x143/0x220 ? __fentry__+0x10/0x10 ftrace_replace_code+0xe3/0x4f0 ? ftrace_int3_handler+0x90/0x90 ? printk+0x99/0xb5 ? 0xffffffff81000000 ftrace_modify_all_code+0x97/0x110 arch_ftrace_update_code+0x10/0x20 ftrace_run_update_code+0x1c/0x60 ftrace_run_modify_code.isra.48.constprop.62+0x8e/0xd0 register_ftrace_function_probe+0x4b6/0x590 ? ftrace_startup+0x310/0x310 ? debug_lockdep_rcu_enabled.part.4+0x1a/0x30 ? update_stack_state+0x88/0x110 ? ftrace_regex_write.isra.43.part.44+0x1d3/0x320 ? preempt_count_sub+0x18/0xd0 ? mutex_lock_nested+0x104/0x800 ? ftrace_regex_write.isra.43.part.44+0x1d3/0x320 ? __unwind_start+0x1c0/0x1c0 ? _mutex_lock_nest_lock+0x800/0x800 ftrace_trace_probe_callback.isra.3+0xc0/0x130 ? func_set_flag+0xe0/0xe0 ? __lock_acquire+0x642/0x1790 ? __might_fault+0x1e/0x20 ? trace_get_user+0x398/0x470 ? strcmp+0x35/0x60 ftrace_trace_onoff_callback+0x48/0x70 ftrace_regex_write.isra.43.part.44+0x251/0x320 ? match_records+0x420/0x420 ftrace_filter_write+0x2b/0x30 __vfs_write+0xd7/0x330 ? do_loop_readv_writev+0x120/0x120 ? locks_remove_posix+0x90/0x2f0 ? do_lock_file_wait+0x160/0x160 ? __lock_is_held+0x93/0x100 ? rcu_read_lock_sched_held+0x5c/0xb0 ? preempt_count_sub+0x18/0xd0 ? __sb_start_write+0x10a/0x230 ? vfs_write+0x222/0x240 vfs_write+0xef/0x240 SyS_write+0xab/0x130 ? SyS_read+0x130/0x130 ? trace_hardirqs_on_caller+0x182/0x280 ? trace_hardirqs_on_thunk+0x1a/0x1c entry_SYSCALL_64_fastpath+0x18/0xad RIP: 0033:0x7fe61c157c30 RSP: 002b:00007ffe87890258 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: ffffffff8114a410 RCX: 00007fe61c157c30 RDX: 0000000000000010 RSI: 000055814798f5e0 RDI: 0000000000000001 RBP: ffff8800c9027f98 R08: 00007fe61c422740 R09: 00007fe61ca53700 R10: 0000000000000073 R11: 0000000000000246 R12: 0000558147a36400 R13: 00007ffe8788f160 R14: 0000000000000024 R15: 00007ffe8788f15c ? trace_hardirqs_off_caller+0xc0/0x110 ---[ end trace 99fa09b3d9869c2c ]--- Bad trampoline accounting at: ffffffff81cc3b00 (do_IRQ+0x0/0x150)
--- kernel/trace/ftrace.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
kernel/trace/ftrace.c +16 -4
@@ -3736,23 +3736,24 @@ static void __enable_ftrace_function_pro ftrace_probe_registered =1 ; } -static void __disable_ftrace_function_probe (void ) +static bool __disable_ftrace_function_probe (void ) {int i;if (!ftrace_probe_registered) -return ; +return false;for (i =0 ; i <FTRACE_FUNC_HASHSIZE ; i++) {struct hlist_head *hhd = &ftrace_func_hash[i];if (hhd->first) -return ; +return false; }/* no more funcs left */ ftrace_shutdown (&trace_probe_ops,0 ); ftrace_probe_registered =0 ; +return true; }
@@ -3882,6 +3883,7 @@ static void __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, void *data, int flags) { +struct ftrace_ops_hash old_hash_ops;struct ftrace_func_entry *rec_entry;struct ftrace_func_probe *entry;struct ftrace_func_probe *p;
@@ -3893,6 +3895,7 @@ __unregister_ftrace_function_probe(charstruct hlist_node *tmp;char str[KSYM_SYMBOL_LEN ];int i, ret; +bool disabled;if (glob && (strcmp (glob,"*" ) ==0 || !strlen (glob))) func_g.search =NULL ;
@@ -3911,6 +3914,10 @@ __unregister_ftrace_function_probe(charmutex_lock (&trace_probe_ops.func_hash->regex_lock); + old_hash_ops.filter_hash = old_hash; +/* Probes only have filters */ + old_hash_ops.notrace_hash =NULL ; + hash =alloc_and_copy_ftrace_hash (FTRACE_HASH_DEFAULT_BITS , *orig_hash);if (!hash)/* Hmm, should report this somehow */
@@ -3948,12 +3955,17 @@ __unregister_ftrace_function_probe(char } }mutex_lock (&ftrace_lock); -__disable_ftrace_function_probe (); + disabled =__disable_ftrace_function_probe ();/* * Remove after the disable is called. Otherwise, if the last * probe is removed, a null hash means *all enabled*. */ ret =ftrace_hash_move (&trace_probe_ops,1 , orig_hash, hash); + +/* still need to update the function call sites */ +if (ftrace_enabled && !disabled) +ftrace_run_modify_code (&trace_probe_ops,FTRACE_UPDATE_CALLS , + &old_hash_ops);synchronize_sched ();if (!ret)free_ftrace_hash_rcu (old_hash);
Greg Kroah-Hartman
maintainerPATCH 43/69 char: lack of bool string made CONFIG_DEVPORT always on
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Max Bires <[email protected]>
commit f2cfa58b136e4b06a9b9db7af5ef62fbb5992f62 upstream.
Without a bool string present, using "# CONFIG_DEVPORT is not set" in defconfig files would not actually unset devport. This esnured that /dev/port was always on, but there are reasons a user may wish to disable it (smaller kernel, attack surface reduction) if it's not being used. Adding a message here in order to make this user visible.
--- drivers/char/Kconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/char/Kconfig +4 -1
@@ -571,9 +571,12 @@ config TELCLOCK controlling the behavior of this hardware. config DEVPORT - bool + bool "/dev/port character device" depends on ISA || PCI default y + help + Say Y here if you want to support the /dev/port device. The /dev/port + device is similar to /dev/mem, but for I/O ports. source "drivers/s390/char/Kconfig"
Greg Kroah-Hartman
maintainerPATCH 44/69 Revert "MIPS: Lantiq: Fix cascaded IRQ setup"
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Kroah-Hartman <[email protected]>
This reverts commit 362721c4957dcda7b1fbd45380e7a6617a1d077c which is commit 6c356eda225e3ee134ed4176b9ae3a76f793f4dd upstream.
It shouldn't have been included in a stable release.
--- arch/mips/lantiq/irq.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-)
arch/mips/lantiq/irq.c +20 -16
@@ -269,11 +269,6 @@ static void ltq_hw5_irqdispatch(void) DEFINE_HWx_IRQDISPATCH(5)#endif -static void ltq_hw_irq_handler (struct irq_desc *desc) -{ -ltq_hw_irqdispatch (irq_desc_get_irq (desc) -2 ); -} -#ifdef CONFIG_MIPS_MT_SMP void __init arch_init_ipiirq (int irq,struct irqaction *action) {
@@ -318,19 +313,23 @@ static struct irqaction irq_call = { asmlinkage void plat_irq_dispatch(void) {unsigned int pending =read_c0_status () &read_c0_cause () &ST0_IM ; -int irq; +unsigned int i; -if (!pending) { -spurious_interrupt (); -return ; +if ((MIPS_CPU_TIMER_IRQ ==7 ) && (pending &CAUSEF_IP7 )) { +do_IRQ (MIPS_CPU_TIMER_IRQ ); + goto out; + }else { +for (i =0 ; i <MAX_IM ; i++) { +if (pending & (CAUSEF_IP2 << i)) { +ltq_hw_irqdispatch (i); + goto out; + } + } } +pr_alert ("Spurious IRQ: CAUSE=0x%08x\n" ,read_c0_status ()); - pending >>=CAUSEB_IP ; -while (pending) { - irq =fls (pending) -1 ; -do_IRQ (MIPS_CPU_IRQ_BASE + irq); - pending &= ~BIT (irq); - } +out: +return ; }static int icu_map (struct irq_domain *d,unsigned int irq,irq_hw_number_t hw)
@@ -355,6 +354,11 @@ static const struct irq_domain_ops irq_d .map = icu_map, }; +static struct irqaction cascade = { + .handler = no_action, + .name ="cascade" , +}; +int __init icu_of_init (struct device_node *node,struct device_node *parent) {struct device_node *eiu_node;
@@ -386,7 +390,7 @@ int __init icu_of_init(struct device_nodmips_cpu_irq_init ();for (i =0 ; i <MAX_IM ; i++) -irq_set_chained_handler (i +2 , ltq_hw_irq_handler); +setup_irq (i +2 , &cascade);if (cpu_has_vint) {pr_info ("Setting up vectored interrupts\n" );
Greg Kroah-Hartman
maintainerPATCH 45/69 kvm: fix page struct leak in handle_vmon
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Bonzini <[email protected]>
commit 06ce521af9558814b8606c0476c54497cf83a653 upstream.
handle_vmon gets a reference on VMXON region page, but does not release it. Release the reference.
Found by syzkaller; based on a patch by Dmitry.
--- arch/x86/kvm/vmx.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx.c +8 -2
@@ -6925,14 +6925,20 @@ static int nested_vmx_check_vmptr(struct } page =nested_get_page (vcpu, vmptr); -if (page ==NULL || - *(u32 *)kmap (page) !=VMCS12_REVISION ) { +if (page ==NULL ) {nested_vmx_failInvalid (vcpu); +skip_emulated_instruction (vcpu); +return 1 ; + } +if (*(u32 *)kmap (page) !=VMCS12_REVISION ) {kunmap (page); +nested_release_page_clean (page); +nested_vmx_failInvalid (vcpu);skip_emulated_instruction (vcpu);return 1 ; }kunmap (page); +nested_release_page_clean (page); vmx->nested.vmxon_ptr = vmptr;break ;case EXIT_REASON_VMCLEAR :
Greg Kroah-Hartman
maintainerPATCH 46/69 zram: do not use copy_page with non-page aligned address
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Minchan Kim <[email protected]>
commit d72e9a7a93e4f8e9e52491921d99e0c8aa89eb4e upstream.
The copy_page is optimized memcpy for page-alinged address. If it is used with non-page aligned address, it can corrupt memory which means system corruption. With zram, it can happen with
1. 64K architecture
2. partial IO
3. slub debug
Partial IO need to allocate a page and zram allocates it via kmalloc. With slub debug, kmalloc(PAGE_SIZE) doesn't return page-size aligned address. And finally, copy_page(mem, cmem) corrupts memory.
So, this patch changes it to memcpy.
Actuaully, we don't need to change zram_bvec_write part because zsmalloc returns page-aligned address in case of PAGE_SIZE class but it's not good to rely on the internal of zsmalloc.
Note:
When this patch is merged to stable, clear_page should be fixed, too. Unfortunately, recent zram removes it by "same page merge" feature so it's hard to backport this patch to -stable tree.
I will handle it when I receive the mail from stable tree maintainer to merge this patch to backport.
--- drivers/block/zram/zram_drv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/block/zram/zram_drv.c +3 -3
@@ -582,13 +582,13 @@ static int zram_decompress_page(struct zif (!handle ||zram_test_flag (meta, index,ZRAM_ZERO )) {bit_spin_unlock (ZRAM_ACCESS , &meta->table[index].value); -clear_page (mem); +memset (mem,0 ,PAGE_SIZE );return 0 ; } cmem =zs_map_object (meta->mem_pool, handle,ZS_MM_RO );if (size ==PAGE_SIZE ) { -copy_page (mem, cmem); +memcpy (mem, cmem,PAGE_SIZE ); }else {struct zcomp_strm *zstrm =zcomp_stream_get (zram->comp);
@@ -780,7 +780,7 @@ compress_again:if ((clen ==PAGE_SIZE ) && !is_partial_io (bvec)) { src =kmap_atomic (page); -copy_page (cmem, src); +memcpy (cmem, src,PAGE_SIZE );kunmap_atomic (src); }else {memcpy (cmem, src, clen);
Greg Kroah-Hartman
maintainerPATCH 47/69 ftrace: Fix function pid filter on instances
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
commit d879d0b8c183aabeb9a65eba91f3f9e3c7e7b905 upstream.
When function tracer has a pid filter, it adds a probe to sched_switch to track if current task can be ignored. The probe checks the ftrace_ignore_pid from current tr to filter tasks. But it misses to delete the probe when removing an instance so that it can cause a crash due to the invalid tr pointer (use-after-free).
This is easily reproducible with the following:
# cd /sys/kernel/debug/tracing # mkdir instances/buggy # echo $$ > instances/buggy/set_ftrace_pid # rmdir instances/buggy
============================================================================
BUG: KASAN: use-after-free in ftrace_filter_pid_sched_switch_probe+0x3d/0x90 Read of size 8 by task kworker/0:1/17 CPU: 0 PID: 17 Comm: kworker/0:1 Tainted: G B 4.11.0-rc3 #198 Call Trace: dump_stack+0x68/0x9f kasan_object_err+0x21/0x70 kasan_report.part.1+0x22b/0x500 ? ftrace_filter_pid_sched_switch_probe+0x3d/0x90 kasan_report+0x25/0x30 __asan_load8+0x5e/0x70 ftrace_filter_pid_sched_switch_probe+0x3d/0x90 ? fpid_start+0x130/0x130 __schedule+0x571/0xce0 ...
To fix it, use ftrace_clear_pids() to unregister the probe. As instance_rmdir() already updated ftrace codes, it can just free the filter safely.
--- kernel/trace/ftrace.c | 9 +++++++++ kernel/trace/trace.c | 1 + kernel/trace/trace.h | 2 ++ 3 files changed, 12 insertions(+)
kernel/trace/ftrace.c +9 -0
@@ -5401,6 +5401,15 @@ static void clear_ftrace_pids(struct tratrace_free_pid_list (pid_list); } +void ftrace_clear_pids (struct trace_array *tr) +{ +mutex_lock (&ftrace_lock); + +clear_ftrace_pids (tr); + +mutex_unlock (&ftrace_lock); +} +static void ftrace_pid_reset (struct trace_array *tr) {mutex_lock (&ftrace_lock);
kernel/trace/trace.c +1 -0
@@ -7150,6 +7150,7 @@ static int instance_rmdir(const char *natracing_set_nop (tr);event_trace_del_tracer (tr); +ftrace_clear_pids (tr);ftrace_destroy_function_files (tr);tracefs_remove_recursive (tr->dir);free_trace_buffers (tr);
kernel/trace/trace.h +2 -0
@@ -870,6 +870,7 @@ int using_ftrace_ops_list_func(void);void ftrace_init_tracefs (struct trace_array *tr,struct dentry *d_tracer);void ftrace_init_tracefs_toplevel (struct trace_array *tr,struct dentry *d_tracer); +void ftrace_clear_pids (struct trace_array *tr);#else static inline int ftrace_trace_task (struct trace_array *tr) {
@@ -888,6 +889,7 @@ ftrace_init_global_array_ops(struct tracstatic inline void ftrace_reset_array_ops (struct trace_array *tr) { }static inline void ftrace_init_tracefs (struct trace_array *tr,struct dentry *d) { }static inline void ftrace_init_tracefs_toplevel (struct trace_array *tr,struct dentry *d) { } +static inline void ftrace_clear_pids (struct trace_array *tr) { }/* ftace_func_t type is not defined, use macro instead of static inline */ #define ftrace_init_array_ops (tr, func) do { } while (0)#endif /* CONFIG_FUNCTION_TRACER */
Greg Kroah-Hartman
maintainerPATCH 48/69 crypto: algif_aead - Fix bogus request dereference in completion function
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
commit e6534aebb26e32fbab14df9c713c65e8507d17e4 upstream.
The algif_aead completion function tries to deduce the aead_request from the crypto_async_request argument. This is broken because the API does not guarantee that the same request will be pased to the completion function. Only the value of req->data can be used in the completion function.
This patch fixes it by storing a pointer to sk in areq and using that instead of passing in sk through req->data.
--- crypto/algif_aead.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
crypto/algif_aead.c +6 -6
@@ -39,6 +39,7 @@ struct aead_async_req {struct aead_async_rsgl first_rsgl;struct list_head list;struct kiocb *iocb; +struct sock *sk;unsigned int tsgls;char iv[]; };
@@ -379,12 +380,10 @@ unlock:static void aead_async_cb (struct crypto_async_request *_req,int err) { -struct sock *sk = _req->data; -struct alg_sock *ask =alg_sk (sk); -struct aead_ctx *ctx = ask->private; -struct crypto_aead *tfm =crypto_aead_reqtfm (&ctx->aead_req); -struct aead_request *req =aead_request_cast (_req); +struct aead_request *req = _req->data; +struct crypto_aead *tfm =crypto_aead_reqtfm (req);struct aead_async_req *areq =GET_ASYM_REQ (req, tfm); +struct sock *sk = areq->sk;struct scatterlist *sg = areq->tsgl;struct aead_async_rsgl *rsgl;struct kiocb *iocb = areq->iocb;
@@ -447,11 +446,12 @@ static int aead_recvmsg_async(struct socmemset (&areq->first_rsgl,'\0' ,sizeof (areq->first_rsgl));INIT_LIST_HEAD (&areq->list); areq->iocb = msg->msg_iocb; + areq->sk = sk;memcpy (areq->iv, ctx->iv,crypto_aead_ivsize (tfm));aead_request_set_tfm (req, tfm);aead_request_set_ad (req, ctx->aead_assoclen);aead_request_set_callback (req,CRYPTO_TFM_REQ_MAY_BACKLOG , - aead_async_cb, sk); + aead_async_cb, req); used -= ctx->aead_assoclen;/* take over all tx sgls from ctx */
Greg Kroah-Hartman
maintainerPATCH 49/69 crypto: ahash - Fix EINPROGRESS notification callback
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
commit ef0579b64e93188710d48667cb5e014926af9f1b upstream.
The ahash API modifies the request's callback function in order to clean up after itself in some corner cases (unaligned final and missing finup).
When the request is complete ahash will restore the original callback and everything is fine. However, when the request gets an EBUSY on a full queue, an EINPROGRESS callback is made while the request is still ongoing.
In this case the ahash API will incorrectly call its own callback.
This patch fixes the problem by creating a temporary request object on the stack which is used to relay EINPROGRESS back to the original completion function.
This patch also adds code to preserve the original flags value.
--- crypto/ahash.c | 79 +++++++++++++++++++++++++---------------- include/crypto/internal/hash.h | 10 +++++ 2 files changed, 60 insertions(+), 29 deletions(-)
crypto/ahash.c +50 -29
@@ -31,6 +31,7 @@ struct ahash_request_priv {crypto_completion_t complete;void *data;u8 *result; +u32 flags; void *ubuf[] CRYPTO_MINALIGN_ATTR; };
@@ -252,6 +253,8 @@ static int ahash_save_req(struct ahash_r priv->result = req->result; priv->complete = req->base.complete; priv->data = req->base.data; + priv->flags = req->base.flags; +/* * WARNING: We do not backup req->priv here! The req->priv * is for internal use of the Crypto API and the
@@ -266,38 +269,44 @@ static int ahash_save_req(struct ahash_rreturn 0 ; } -static void ahash_restore_req (struct ahash_request *req) +static void ahash_restore_req (struct ahash_request *req,int err) {struct ahash_request_priv *priv = req->priv; +if (!err) +memcpy (priv->result, req->result, +crypto_ahash_digestsize (crypto_ahash_reqtfm (req))); +/* Restore the original crypto request. */ req->result = priv->result; - req->base.complete = priv->complete; - req->base.data = priv->data; + +ahash_request_set_callback (req, priv->flags, + priv->complete, priv->data); req->priv =NULL ;/* Free the req->priv.priv from the ADJUSTED request. */ kzfree (priv); } -static void ahash_op_unaligned_finish (struct ahash_request *req,int err) +static void ahash_notify_einprogress (struct ahash_request *req) {struct ahash_request_priv *priv = req->priv; +struct crypto_async_request oreq; -if (err == -EINPROGRESS ) -return ; - -if (!err) -memcpy (priv->result, req->result, -crypto_ahash_digestsize (crypto_ahash_reqtfm (req))); + oreq.data = priv->data; -ahash_restore_req (req); + priv->complete (&oreq, -EINPROGRESS ); }static void ahash_op_unaligned_done (struct crypto_async_request *req,int err) {struct ahash_request *areq = req->data; +if (err == -EINPROGRESS ) { +ahash_notify_einprogress (areq); +return ; + } +/* * Restore the original request, see ahash_op_unaligned() for what * goes where.
@@ -308,7 +317,7 @@ static void ahash_op_unaligned_done(stru*/ /* First copy req->result into req->priv.result */ -ahash_op_unaligned_finish (areq, err); +ahash_restore_req (areq, err);/* Complete the ORIGINAL request. */ areq->base.complete (&areq->base, err);
@@ -324,7 +333,12 @@ static int ahash_op_unaligned(struct ahareturn err; err =op (req); -ahash_op_unaligned_finish (req, err); +if (err == -EINPROGRESS || + (err == -EBUSY && (ahash_request_flags (req) & +CRYPTO_TFM_REQ_MAY_BACKLOG ))) +return err; + +ahash_restore_req (req, err);return err; }
@@ -359,25 +373,14 @@ int crypto_ahash_digest(struct ahash_req }EXPORT_SYMBOL_GPL (crypto_ahash_digest); -static void ahash_def_finup_finish2 (struct ahash_request *req,int err) +static void ahash_def_finup_done2 (struct crypto_async_request *req,int err) { -struct ahash_request_priv *priv = req->priv; +struct ahash_request *areq = req->data;if (err == -EINPROGRESS )return ; -if (!err) -memcpy (priv->result, req->result, -crypto_ahash_digestsize (crypto_ahash_reqtfm (req))); - -ahash_restore_req (req); -} - -static void ahash_def_finup_done2 (struct crypto_async_request *req,int err) -{ -struct ahash_request *areq = req->data; - -ahash_def_finup_finish2 (areq, err); +ahash_restore_req (areq, err); areq->base.complete (&areq->base, err); }
@@ -388,11 +391,15 @@ static int ahash_def_finup_finish1(struc goto out; req->base.complete = ahash_def_finup_done2; - req->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP ; + err =crypto_ahash_reqtfm (req)->final (req); +if (err == -EINPROGRESS || + (err == -EBUSY && (ahash_request_flags (req) & +CRYPTO_TFM_REQ_MAY_BACKLOG ))) +return err; out: -ahash_def_finup_finish2 (req, err); +ahash_restore_req (req, err);return err; }
@@ -400,7 +407,16 @@ static void ahash_def_finup_done1(struct {struct ahash_request *areq = req->data; +if (err == -EINPROGRESS ) { +ahash_notify_einprogress (areq); +return ; + } + + areq->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP ; + err =ahash_def_finup_finish1 (areq, err); +if (areq->priv) +return ; areq->base.complete (&areq->base, err); }
@@ -415,6 +431,11 @@ static int ahash_def_finup(struct ahash_return err; err = tfm->update (req); +if (err == -EINPROGRESS || + (err == -EBUSY && (ahash_request_flags (req) & +CRYPTO_TFM_REQ_MAY_BACKLOG ))) +return err; +return ahash_def_finup_finish1 (req, err); }
include/crypto/internal/hash.h +10 -0
@@ -166,6 +166,16 @@ static inline struct ahash_instance *ahareturn crypto_alloc_instance2 (name, alg,ahash_instance_headroom ()); } +static inline void ahash_request_complete (struct ahash_request *req,int err) +{ + req->base.complete (&req->base, err); +} + +static inline u32 ahash_request_flags (struct ahash_request *req) +{ +return req->base.flags; +} +static inline struct crypto_ahash *crypto_spawn_ahash (struct crypto_ahash_spawn *spawn) {
Greg Kroah-Hartman
maintainerPATCH 50/69 parisc: Fix get_user() for 64-bit value on 32-bit kernel
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit 3f795cef0ecdf9bc980dd058d49bdab4b19af1d3 upstream.
This fixes a bug in which the upper 32-bits of a 64-bit value which is read by get_user() was lost on a 32-bit kernel.
While touching this code, split out pre-loading of %sr2 space register and clean up code indent.
--- arch/parisc/include/asm/uaccess.h | 86 ++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 31 deletions(-)
arch/parisc/include/asm/uaccess.h +55 -31
@@ -42,10 +42,10 @@ static inline long access_ok(int type, c#define get_user __get_user#if !defined(CONFIG_64BIT ) -#define LDD_USER (ptr) __get_user_asm64(ptr) +#define LDD_USER (val, ptr) __get_user_asm64(val, ptr)#define STD_USER (x, ptr) __put_user_asm64(x, ptr)#else -#define LDD_USER (ptr) __get_user_asm("ldd", ptr) +#define LDD_USER (val, ptr) __get_user_asm(val, "ldd", ptr)#define STD_USER (x, ptr) __put_user_asm("std", x, ptr)#endif
@@ -100,63 +100,87 @@ struct exception_data { " mtsp %0,%%sr2\n\t" \ : : "r"(get_fs()) : ) -#define __get_user (x, ptr) \ -({ \ - register long __gu_err __asm__ ("r8") = 0; \ - register long __gu_val; \ - \ - load_sr2(); \ - switch (sizeof(*(ptr))) { \ - case 1: __get_user_asm("ldb", ptr); break; \ - case 2: __get_user_asm("ldh", ptr); break; \ - case 4: __get_user_asm("ldw", ptr); break; \ - case 8: LDD_USER(ptr); break; \ - default: BUILD_BUG(); break; \ - } \ - \ - (x) = (__force __typeof__(*(ptr))) __gu_val; \ - __gu_err; \ +#define __get_user_internal (val, ptr) \ +({ \ + register long __gu_err __asm__ ("r8") = 0; \ + \ + switch (sizeof(*(ptr))) { \ + case 1: __get_user_asm(val, "ldb", ptr); break; \ + case 2: __get_user_asm(val, "ldh", ptr); break; \ + case 4: __get_user_asm(val, "ldw", ptr); break; \ + case 8: LDD_USER(val, ptr); break; \ + default: BUILD_BUG(); \ + } \ + \ + __gu_err; \ }) -#define __get_user_asm (ldx, ptr) \ +#define __get_user (val, ptr) \ +({ \ + load_sr2(); \ + __get_user_internal(val, ptr); \ +}) + +#define __get_user_asm (val, ldx, ptr) \ +{ \ + register long __gu_val; \ + \ __asm__("1: " ldx " 0(%%sr2,%2),%0\n" \ "9:\n" \ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ : "=r"(__gu_val), "=r"(__gu_err) \ - : "r"(ptr), "1"(__gu_err)); + : "r"(ptr), "1"(__gu_err)); \ + \ + (val) = (__force __typeof__(*(ptr))) __gu_val; \ +}#if !defined(CONFIG_64BIT ) -#define __get_user_asm64 (ptr) \ +#define __get_user_asm64 (val, ptr) \ +{ \ + union { \ + unsigned long long l; \ + __typeof__(*(ptr)) t; \ + } __gu_tmp; \ + \ __asm__(" copy %%r0,%R0\n" \ "1: ldw 0(%%sr2,%2),%0\n" \ "2: ldw 4(%%sr2,%2),%R0\n" \ "9:\n" \ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \ - : "=r"(__gu_val), "=r"(__gu_err) \ - : "r"(ptr), "1"(__gu_err)); + : "=&r"(__gu_tmp.l), "=r"(__gu_err) \ + : "r"(ptr), "1"(__gu_err)); \ + \ + (val) = __gu_tmp.t; \ +}#endif /* !defined(CONFIG_64BIT) */ -#define __put_user (x, ptr) \ +#define __put_user_internal (x, ptr) \ ({ \ register long __pu_err __asm__ ("r8") = 0; \ __typeof__(*(ptr)) __x = (__typeof__(*(ptr)))(x); \ \ - load_sr2(); \ switch (sizeof(*(ptr))) { \ - case 1: __put_user_asm("stb", __x, ptr); break; \ - case 2: __put_user_asm("sth", __x, ptr); break; \ - case 4: __put_user_asm("stw", __x, ptr); break; \ - case 8: STD_USER(__x, ptr); break; \ - default: BUILD_BUG(); break; \ - } \ + case 1: __put_user_asm("stb", __x, ptr); break; \ + case 2: __put_user_asm("sth", __x, ptr); break; \ + case 4: __put_user_asm("stw", __x, ptr); break; \ + case 8: STD_USER(__x, ptr); break; \ + default: BUILD_BUG(); \ + } \ \ __pu_err; \ }) +#define __put_user (x, ptr) \ +({ \ + load_sr2(); \ + __put_user_internal(x, ptr); \ +}) + +/* * The "__put_user/kernel_asm()" macros tell gcc they read from memory * instead of writing. This is because they do not write to any memory
Greg Kroah-Hartman
maintainerPATCH 51/69 ath9k: fix NULL pointer dereference
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaoqing Pan <[email protected]>
commit 40bea976c72b9ee60f8d097852deb53ccbeaffbe upstream.
relay_open() may return NULL, check the return value to avoid the crash.
BUG: unable to handle kernel NULL pointer dereference at 0000000000000040 IP: [<ffffffffa01a95c5>] ath_cmn_process_fft+0xd5/0x700 [ath9k_common] PGD 41cf28067 PUD 41be92067 PMD 0 Oops: 0000 [#1] SMP CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.8.6+ #35 Hardware name: Hewlett-Packard h8-1080t/2A86, BIOS 6.15 07/04/2011 task: ffffffff81e0c4c0 task.stack: ffffffff81e00000 RIP: 0010:[<ffffffffa01a95c5>] [<ffffffffa01a95c5>] ath_cmn_process_fft+0xd5/0x700 [ath9k_common] RSP: 0018:ffff88041f203ca0 EFLAGS: 00010293 RAX: 0000000000000000 RBX: 000000000000059f RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000040 RDI: ffffffff81f0ca98 RBP: ffff88041f203dc8 R08: ffffffffffffffff R09: 00000000000000ff R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 R13: ffffffff81f0ca98 R14: 0000000000000000 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff88041f200000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000040 CR3: 000000041b6ec000 CR4: 00000000000006f0 Stack:
0000000000000363 00000000000003f3 00000000000003f3 00000000000001f9 000000000000049a 0000000001252c04 ffff88041f203e44 ffff880417b4bfd0 0000000000000008 ffff88041785b9c0 0000000000000002 ffff88041613dc60
Call Trace: <IRQ> [<ffffffffa01b6441>] ath9k_tasklet+0x1b1/0x220 [ath9k] [<ffffffff8105d8dd>] tasklet_action+0x4d/0xf0 [<ffffffff8105dde2>] __do_softirq+0x92/0x2a0
--- drivers/net/wireless/ath/ath9k/common-spectral.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/ath9k/common-spectral.c +7 -1
@@ -528,6 +528,9 @@ int ath_cmn_process_fft(struct ath_spec_if (!(radar_info->pulse_bw_info &SPECTRAL_SCAN_BITMASK ))return 0 ; +if (!spec_priv->rfs_chan_spec_scan) +return 1 ; +/* Output buffers are full, no need to process anything * since there is no space to put the result anyway */
@@ -1072,7 +1075,7 @@ static struct rchan_callbacks rfs_spec_svoid ath9k_cmn_spectral_deinit_debug (struct ath_spec_scan_priv *spec_priv) { -if (IS_ENABLED (CONFIG_ATH9K_DEBUGFS )) { +if (IS_ENABLED (CONFIG_ATH9K_DEBUGFS ) && spec_priv->rfs_chan_spec_scan) {relay_close (spec_priv->rfs_chan_spec_scan); spec_priv->rfs_chan_spec_scan =NULL ; }
@@ -1086,6 +1089,9 @@ void ath9k_cmn_spectral_init_debug(struc debugfs_phy,1024 ,256 , &rfs_spec_scan_cb, NULL); +if (!spec_priv->rfs_chan_spec_scan) +return ; + debugfs_create_file("spectral_scan_ctl", S_IRUSR | S_IWUSR, debugfs_phy, spec_priv,
Greg Kroah-Hartman
maintainerPATCH 52/69 dvb-usb-v2: avoid use-after-free
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit 005145378c9ad7575a01b6ce1ba118fb427f583a upstream.
I ran into a stack frame size warning because of the on-stack copy of the USB device structure:
drivers/media/usb/dvb-usb-v2/dvb_usb_core.c: In function 'dvb_usbv2_disconnect':drivers/media/usb/dvb-usb-v2/dvb_usb_core.c:1029:1: error: the frame size of 1104 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
Copying a device structure like this is wrong for a number of other reasons too aside from the possible stack overflow. One of them is that the dev_info() call will print the name of the device later, but AFAICT we have only copied a pointer to the name earlier and the actual name has been freed by the time it gets printed.
This removes the on-stack copy of the device and instead copies the device name using kstrdup(). I'm ignoring the possible failure here as both printk() and kfree() are able to deal with NULL pointers.
--- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +5 -4
@@ -1013,8 +1013,8 @@ EXPORT_SYMBOL(dvb_usbv2_probe);void dvb_usbv2_disconnect (struct usb_interface *intf) {struct dvb_usb_device *d =usb_get_intfdata (intf); -const char *name = d->name; -struct device dev = d->udev->dev; +const char *devname =kstrdup (dev_name (&d->udev->dev),GFP_KERNEL ); +const char *drvname = d->name;dev_dbg (&d->udev->dev,"%s: bInterfaceNumber=%d\n" , __func__, intf->cur_altsetting->desc.bInterfaceNumber);
@@ -1024,8 +1024,9 @@ void dvb_usbv2_disconnect(struct usb_intdvb_usbv2_exit (d); -dev_info (&dev,"%s: '%s' successfully deinitialized and disconnected\n" , -KBUILD_MODNAME , name); +pr_info ("%s: '%s:%s' successfully deinitialized and disconnected\n" , +KBUILD_MODNAME , drvname, devname); +kfree (devname); }EXPORT_SYMBOL (dvb_usbv2_disconnect);
Greg Kroah-Hartman
maintainerPATCH 53/69 ext4: fix inode checksum calculation problem if i_extra_size is small
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daeho Jeong <[email protected]>
commit 05ac5aa18abd7db341e54df4ae2b4c98ea0e43b7 upstream.
We've fixed the race condition problem in calculating ext4 checksum value in commit b47820edd163 ("ext4: avoid modifying checksum fields directly during checksum veficationon"). However, by this change, when calculating the checksum value of inode whose i_extra_size is less than 4, we couldn't calculate the checksum value in a proper way. This problem was found and reported by Nix, Thank you.
--- fs/ext4/inode.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
fs/ext4/inode.c +2 -3
@@ -71,10 +71,9 @@ static __u32 ext4_inode_csum(struct inod csum =ext4_chksum (sbi, csum, (__u8 *)&dummy_csum, csum_size); offset += csum_size; - csum =ext4_chksum (sbi, csum, (__u8 *)raw + offset, -EXT4_INODE_SIZE (inode->i_sb) - - offset); } + csum =ext4_chksum (sbi, csum, (__u8 *)raw + offset, +EXT4_INODE_SIZE (inode->i_sb) - offset); }return csum;
Greg Kroah-Hartman
maintainerPATCH 54/69 mm: memcontrol: use special workqueue for creating per-memcg caches
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Davydov <[email protected]>
commit 13583c3d3224508582ec03d881d0b68dd3ee8e10 upstream.
Creating a lot of cgroups at the same time might stall all worker threads with kmem cache creation works, because kmem cache creation is done with the slab_mutex held. The problem was amplified by commits 801faf0db894 ("mm/slab: lockless decision to grow cache") in case of SLAB and 81ae6d03952c ("mm/slub.c: replace kick_all_cpus_sync() with synchronize_sched() in kmem_cache_shrink()") in case of SLUB, which increased the maximal time the slab_mutex can be held.
To prevent that from happening, let's use a special ordered single threaded workqueue for kmem cache creation. This shouldn't introduce any functional changes regarding how kmem caches are created, as the work function holds the global slab_mutex during its whole runtime anyway, making it impossible to run more than one work at a time. By using a single threaded workqueue, we just avoid creating a thread per each work. Ordering is required to avoid a situation when a cgroup's work is put off indefinitely because there are other cgroups to serve, in other words to guarantee fairness.
--- mm/memcontrol.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
mm/memcontrol.c +14 -1
@@ -2152,6 +2152,8 @@ struct memcg_kmem_cache_create_work {struct work_struct work; }; +static struct workqueue_struct *memcg_kmem_cache_create_wq; +static void memcg_kmem_cache_create_func (struct work_struct *w) { struct memcg_kmem_cache_create_work *cw =
@@ -2183,7 +2185,7 @@ static void __memcg_schedule_kmem_cache_ cw->cachep = cachep;INIT_WORK (&cw->work, memcg_kmem_cache_create_func); -schedule_work (&cw->work); +queue_work (memcg_kmem_cache_create_wq, &cw->work); } static void memcg_schedule_kmem_cache_create(struct mem_cgroup *memcg,
@@ -5786,6 +5788,17 @@ static int __init mem_cgroup_init(void) {int cpu, node; +#ifndef CONFIG_SLOB +/* +* Kmem cache creation is mostly done with the slab_mutex held, +* so use a special workqueue to avoid stalling all worker +* threads in case lots of cgroups are created simultaneously. +*/ + memcg_kmem_cache_create_wq = +alloc_ordered_workqueue ("memcg_kmem_cache_create" ,0 ); +BUG_ON (!memcg_kmem_cache_create_wq); +#endif +hotcpu_notifier (memcg_cpu_hotplug_callback,0 );for_each_possible_cpu (cpu)
Greg Kroah-Hartman
maintainerPATCH 55/69 drm/nouveau/disp/mcp7x: disable dptmds workaround
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Skeggs <[email protected]>
commit 7dfee6827780d4228148263545af936d0cae8930 upstream.
The workaround appears to cause regressions on these boards, and from inspection of RM traces, NVIDIA don't appear to do it on them either.
--- drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c | 2 -- 1 file changed, 2 deletions(-)
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c +0 -2
@@ -433,8 +433,6 @@ nv50_disp_dptmds_war(struct nvkm_devicecase 0x94 :case 0x96 :case 0x98 : -case 0xaa : -case 0xac :return true;default :break ;
Greg Kroah-Hartman
maintainerPATCH 56/69 nbd: use loff_t for blocksize and nbd_set_size args
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
commit ef77b515243b3499d62cf446eda6ca7e0a0b079c upstream.
If we have large devices (say like the 40t drive I was trying to test with) we will end up overflowing the int arguments to nbd_set_size and not get the right size for our device. Fix this by using loff_t everywhere so I don't have to think about this again. Thanks,
--- drivers/block/nbd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/block/nbd.c +4 -4
@@ -54,7 +54,7 @@ struct nbd_device {struct mutex tx_lock;struct gendisk *disk; -int blksize; +loff_t blksize;loff_t bytesize;/* protects initialization and shutdown of the socket */
@@ -126,7 +126,7 @@ static void nbd_size_update(struct nbd_d }static int nbd_size_set (struct nbd_device *nbd,struct block_device *bdev, -int blocksize,int nr_blocks) +loff_t blocksize,loff_t nr_blocks) {int ret;
@@ -135,7 +135,7 @@ static int nbd_size_set(struct nbd_devicreturn ret; nbd->blksize = blocksize; - nbd->bytesize = (loff_t )blocksize * (loff_t )nr_blocks; + nbd->bytesize = blocksize * nr_blocks;nbd_size_update (nbd, bdev);
@@ -817,7 +817,7 @@ static int nbd_dev_dbg_init(struct nbd_ddebugfs_create_file ("tasks" ,0444 , dir, nbd, &nbd_dbg_tasks_ops);debugfs_create_u64 ("size_bytes" ,0444 , dir, &nbd->bytesize);debugfs_create_u32 ("timeout" ,0444 , dir, &nbd->tag_set.timeout); -debugfs_create_u32 ("blocksize" ,0444 , dir, &nbd->blksize); +debugfs_create_u64 ("blocksize" ,0444 , dir, &nbd->blksize);debugfs_create_file ("flags" ,0444 , dir, nbd, &nbd_dbg_flags_ops);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 57/69 nbd: fix 64-bit division
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
commit e88f72cb9f54f6d244e55f629fe5e2f34ca6f9ed upstream.
We have this:
ERROR: "__aeabi_ldivmod" [drivers/block/nbd.ko] undefined!
ERROR: "__divdi3" [drivers/block/nbd.ko] undefined! nbd.c:(.text+0x247c72): undefined reference to `__divdi3'
due to a recent commit, that did 64-bit division. Use the proper divider function so that 32-bit compiles don't break.
--- drivers/block/nbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/nbd.c +1 -1
@@ -648,7 +648,7 @@ static int __nbd_ioctl(struct block_devicase NBD_SET_SIZE :return nbd_size_set (nbd, bdev, nbd->blksize, - arg / nbd->blksize); +div_s64 (arg, nbd->blksize));case NBD_SET_SIZE_BLOCKS :return nbd_size_set (nbd, bdev, nbd->blksize, arg);
Greg Kroah-Hartman
maintainerPATCH 58/69 ASoC: Intel: select DW_DMAC_CORE since its mandatory
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
commit ebf79091bf85d9b2270ab29191de9cd3aaf888c5 upstream.
Select DW_DMAC_CORE like the rest of glue drivers do, e.g. drivers/dma/dw/Kconfig.
While here group selectors under SND_SOC_INTEL_HASWELL and SND_SOC_INTEL_BAYTRAIL.
Make platforms, which are using a common SST firmware driver, to be dependent on DMADEVICES.
--- sound/soc/intel/Kconfig | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-)
sound/soc/intel/Kconfig +13 -18
@@ -33,11 +33,9 @@ config SND_SOC_INTEL_SST select SND_SOC_INTEL_SST_MATCH if ACPI depends on (X86 || COMPILE_TEST) -# firmware stuff depends DW_DMAC_CORE; since there is no depends-on from -# the reverse selection, each machine driver needs to select -# SND_SOC_INTEL_SST_FIRMWARE carefully depending on DW_DMAC_CORE config SND_SOC_INTEL_SST_FIRMWARE tristate + select DW_DMAC_CORE config SND_SOC_INTEL_SST_ACPI tristate
@@ -47,16 +45,18 @@ config SND_SOC_INTEL_SST_MATCH config SND_SOC_INTEL_HASWELL tristate + select SND_SOC_INTEL_SST select SND_SOC_INTEL_SST_FIRMWARE config SND_SOC_INTEL_BAYTRAIL tristate + select SND_SOC_INTEL_SST + select SND_SOC_INTEL_SST_FIRMWARE config SND_SOC_INTEL_HASWELL_MACH tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint" depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM - depends on DW_DMAC_CORE - select SND_SOC_INTEL_SST + depends on DMADEVICES select SND_SOC_INTEL_HASWELL select SND_SOC_RT5640 help
@@ -99,9 +99,8 @@ config SND_SOC_INTEL_BXT_RT298_MACH config SND_SOC_INTEL_BYT_RT5640_MACH tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec" depends on X86_INTEL_LPSS && I2C - depends on DW_DMAC_CORE && (SND_SST_IPC_ACPI = n) - select SND_SOC_INTEL_SST - select SND_SOC_INTEL_SST_FIRMWARE + depends on DMADEVICES + depends on SND_SST_IPC_ACPI = n select SND_SOC_INTEL_BAYTRAIL select SND_SOC_RT5640 help
@@ -112,9 +111,8 @@ config SND_SOC_INTEL_BYT_RT5640_MACH config SND_SOC_INTEL_BYT_MAX98090_MACH tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec" depends on X86_INTEL_LPSS && I2C - depends on DW_DMAC_CORE && (SND_SST_IPC_ACPI = n) - select SND_SOC_INTEL_SST - select SND_SOC_INTEL_SST_FIRMWARE + depends on DMADEVICES + depends on SND_SST_IPC_ACPI = n select SND_SOC_INTEL_BAYTRAIL select SND_SOC_MAX98090 help
@@ -123,9 +121,8 @@ config SND_SOC_INTEL_BYT_MAX98090_MACH config SND_SOC_INTEL_BDW_RT5677_MACH tristate "ASoC Audio driver for Intel Broadwell with RT5677 codec" - depends on X86_INTEL_LPSS && GPIOLIB && I2C && DW_DMAC - depends on DW_DMAC_CORE=y - select SND_SOC_INTEL_SST + depends on X86_INTEL_LPSS && GPIOLIB && I2C + depends on DMADEVICES select SND_SOC_INTEL_HASWELL select SND_SOC_RT5677 help
@@ -134,10 +131,8 @@ config SND_SOC_INTEL_BDW_RT5677_MACH config SND_SOC_INTEL_BROADWELL_MACH tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" - depends on X86_INTEL_LPSS && I2C && DW_DMAC && \ - I2C_DESIGNWARE_PLATFORM - depends on DW_DMAC_CORE - select SND_SOC_INTEL_SST + depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM + depends on DMADEVICES select SND_SOC_INTEL_HASWELL select SND_SOC_RT286 help
Greg Kroah-Hartman
maintainerPATCH 60/69 x86/xen: Fix APIC id mismatch warning on Intel
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mohit Gambhir <[email protected]>
commit cc272163ea554a97dac180fa8dd6cd54c2810bd1 upstream.
This patch fixes the following warning message seen when booting the kernel as Dom0 with Xen on Intel machines.
[0.003000] [Firmware Bug]: CPU1: APIC id mismatch. Firmware: 0 APIC: 1]
The code generating the warning in validate_apic_and_package_id() matches cpu_data(cpu).apicid (initialized in init_intel()-> detect_extended_topology() using cpuid) against the apicid returned from xen_apic_read(). Now, xen_apic_read() makes a hypercall to retrieve apicid for the boot cpu but returns 0 otherwise. Hence the warning gets thrown for all but the boot cpu.
The idea behind xen_apic_read() returning 0 for apicid is that the guests (even Dom0) should not need to know what physical processor their vcpus are running on. This is because we currently do not have topology information in Xen and also because xen allows more vcpus than physical processors. However, boot cpu's apicid is required for loading xen-acpi-processor driver on AMD machines. Look at following patch for details:
commit 558daa289a40 ("xen/apic: Return the APIC ID (and version) for CPU 0.")
So to get rid of the warning, this patch modifies xen_cpu_present_to_apicid() to return cpu_data(cpu).apicid instead of calling xen_apic_read().
The warning is not seen on AMD machines because init_amd() populates cpu_data(cpu).apicid by calling hard_smp_processor_id()->xen_apic_read() as opposed to using apicid from cpuid as is done on Intel machines.
--- arch/x86/xen/apic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/xen/apic.c +1 -1
@@ -145,7 +145,7 @@ static void xen_silent_inquire(int apicistatic int xen_cpu_present_to_apicid (int cpu) {if (cpu_present (cpu)) -return xen_get_apic_id (xen_apic_read (APIC_ID )); +return cpu_data (cpu).apicid;else return BAD_APICID ; }
Greg Kroah-Hartman
maintainerPATCH 61/69 ACPI / EC: Use busy polling mode when GPE is not enabled
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lv Zheng <[email protected]>
commit c3a696b6e8f8f75f9f75e556a9f9f6472eae2655 upstream.
When GPE is not enabled, it is not efficient to use the wait polling mode as it introduces an unexpected scheduler delay.
So before the GPE handler is installed, this patch uses busy polling mode for all EC(s) and the logic can be applied to non boot EC(s) during the suspend/resume process.
--- drivers/acpi/ec.c | 62 +++++++++++++++++++++++------------------------- drivers/acpi/internal.h | 4 +-- 2 files changed, 32 insertions(+), 34 deletions(-)
drivers/acpi/ec.c +30 -32
@@ -729,12 +729,12 @@ static void start_transaction(struct acpstatic int ec_guard (struct acpi_ec *ec) { -unsigned long guard =usecs_to_jiffies (ec_polling_guard); +unsigned long guard =usecs_to_jiffies (ec->polling_guard);unsigned long timeout = ec->timestamp + guard;/* Ensure guarding period before polling EC status */ do { - if (ec_busy_polling) { + if (ec->busy_polling) { /* Perform busy polling */ if (ec_transaction_completed(ec)) return 0;
@@ -998,6 +998,28 @@ static void acpi_ec_stop(struct acpi_ecspin_unlock_irqrestore (&ec->lock, flags); } +static void acpi_ec_enter_noirq (struct acpi_ec *ec) +{ +unsigned long flags; + +spin_lock_irqsave (&ec->lock, flags); + ec->busy_polling = true; + ec->polling_guard =0 ; +ec_log_drv ("interrupt blocked" ); +spin_unlock_irqrestore (&ec->lock, flags); +} + +static void acpi_ec_leave_noirq (struct acpi_ec *ec) +{ +unsigned long flags; + +spin_lock_irqsave (&ec->lock, flags); + ec->busy_polling = ec_busy_polling; + ec->polling_guard = ec_polling_guard; +ec_log_drv ("interrupt unblocked" ); +spin_unlock_irqrestore (&ec->lock, flags); +} +void acpi_ec_block_transactions (void ) {struct acpi_ec *ec = first_ec;
@@ -1278,7 +1300,7 @@ acpi_ec_space_handler(u32 function, acpiif (function !=ACPI_READ && function !=ACPI_WRITE )return AE_BAD_PARAMETER ; -if (ec_busy_polling || bits >8 ) +if (ec->busy_polling || bits >8 )acpi_ec_burst_enable (ec);for (i =0 ; i < bytes; ++i, ++address, ++value)
@@ -1286,7 +1308,7 @@ acpi_ec_space_handler(u32 function, acpi acpi_ec_read(ec, address, value) :acpi_ec_write (ec, address, *value); -if (ec_busy_polling || bits >8 ) +if (ec->busy_polling || bits >8 )acpi_ec_burst_disable (ec);switch (result) {
@@ -1329,6 +1351,8 @@ static struct acpi_ec *acpi_ec_alloc(voispin_lock_init (&ec->lock);INIT_WORK (&ec->work, acpi_ec_event_handler); ec->timestamp = jiffies; + ec->busy_polling = true; + ec->polling_guard =0 ;return ec; }
@@ -1390,6 +1414,7 @@ static int ec_install_handlers(struct acacpi_ec_start (ec, false);if (!test_bit (EC_FLAGS_EC_HANDLER_INSTALLED , &ec->flags)) { +acpi_ec_enter_noirq (ec); status = acpi_install_address_space_handler(ec->handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
@@ -1429,6 +1454,7 @@ static int ec_install_handlers(struct ac/* This is not fatal as we can poll EC events */ if (ACPI_SUCCESS (status)) {set_bit (EC_FLAGS_GPE_HANDLER_INSTALLED , &ec->flags); +acpi_ec_leave_noirq (ec);if (test_bit (EC_FLAGS_STARTED , &ec->flags) && ec->reference_count >=1 )acpi_ec_enable_gpe (ec, true);
@@ -1839,34 +1865,6 @@ error: }#ifdef CONFIG_PM_SLEEP -static void acpi_ec_enter_noirq (struct acpi_ec *ec) -{ -unsigned long flags; - -if (ec == first_ec) { -spin_lock_irqsave (&ec->lock, flags); - ec->saved_busy_polling = ec_busy_polling; - ec->saved_polling_guard = ec_polling_guard; - ec_busy_polling = true; - ec_polling_guard =0 ; -ec_log_drv ("interrupt blocked" ); -spin_unlock_irqrestore (&ec->lock, flags); - } -} - -static void acpi_ec_leave_noirq (struct acpi_ec *ec) -{ -unsigned long flags; - -if (ec == first_ec) { -spin_lock_irqsave (&ec->lock, flags); - ec_busy_polling = ec->saved_busy_polling; - ec_polling_guard = ec->saved_polling_guard; -ec_log_drv ("interrupt unblocked" ); -spin_unlock_irqrestore (&ec->lock, flags); - } -} -static int acpi_ec_suspend_noirq (struct device *dev) { struct acpi_ec *ec =
drivers/acpi/internal.h +2 -2
@@ -172,8 +172,8 @@ struct acpi_ec {struct work_struct work;unsigned long timestamp;unsigned long nr_pending_queries; -bool saved_busy_polling; -unsigned int saved_polling_guard; +bool busy_polling; +unsigned int polling_guard; };extern struct acpi_ec *first_ec;
Greg Kroah-Hartman
maintainerPATCH 62/69 rtc: tegra: Implement clock handling
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thierry Reding <[email protected]>
commit 5fa4086987506b2ab8c92f8f99f2295db9918856 upstream.
Accessing the registers of the RTC block on Tegra requires the module clock to be enabled. This only works because the RTC module clock will be enabled by default during early boot. However, because the clock is unused, the CCF will disable it at late_init time. This causes the RTC to become unusable afterwards. This can easily be reproduced by trying to use the RTC:
$ hwclock --rtc /dev/rtc1
This will hang the system. I ran into this by following up on a report by Martin Michlmayr that reboot wasn't working on Tegra210 systems. It turns out that the rtc-tegra driver's ->shutdown() implementation will hang the CPU, because of the disabled clock, before the system can be rebooted.
What confused me for a while is that the same driver is used on prior Tegra generations where the hang can not be observed. However, as Peter De Schrijver pointed out, this is because on 32-bit Tegra chips the RTC clock is enabled by the tegra20_timer.c clocksource driver, which uses the RTC to provide a persistent clock. This code is never enabled on 64-bit Tegra because the persistent clock infrastructure does not exist on 64-bit ARM.
The proper fix for this is to add proper clock handling to the RTC driver in order to ensure that the clock is enabled when the driver requires it. All device trees contain the clock already, therefore no additional changes are required.
Acked-By Peter De Schrijver <[email protected]>
--- drivers/rtc/rtc-tegra.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-)
drivers/rtc/rtc-tegra.c +26 -2
@@ -18,6 +18,7 @@* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include <linux/kernel.h> +#include <linux/clk.h> #include <linux/init.h> #include <linux/module.h> #include <linux/slab.h>
@@ -59,6 +60,7 @@ struct tegra_rtc_info {struct platform_device *pdev;struct rtc_device *rtc_dev;void __iomem *rtc_base;/* NULL if not initialized. */ +struct clk *clk;int tegra_rtc_irq;/* alarm and periodic irq */ spinlock_t tegra_rtc_lock; };
@@ -326,6 +328,14 @@ static int __init tegra_rtc_probe(structif (info->tegra_rtc_irq <=0 )return -EBUSY ; + info->clk =devm_clk_get (&pdev->dev,NULL ); +if (IS_ERR (info->clk)) +return PTR_ERR (info->clk); + + ret =clk_prepare_enable (info->clk); +if (ret <0 ) +return ret; +/* set context info. */ info->pdev = pdev;spin_lock_init (&info->tegra_rtc_lock);
@@ -346,7 +356,7 @@ static int __init tegra_rtc_probe(struct ret =PTR_ERR (info->rtc_dev);dev_err (&pdev->dev,"Unable to register device (err=%d).\n" , ret); -return ret; + goto disable_clk; } ret = devm_request_irq(&pdev->dev, info->tegra_rtc_irq,
@@ -356,12 +366,25 @@ static int __init tegra_rtc_probe(structdev_err (&pdev->dev,"Unable to request interrupt for device (err=%d).\n" , ret); -return ret; + goto disable_clk; }dev_notice (&pdev->dev,"Tegra internal Real Time Clock\n" );return 0 ; + +disable_clk: +clk_disable_unprepare (info->clk); +return ret; +} + +static int tegra_rtc_remove (struct platform_device *pdev) +{ +struct tegra_rtc_info *info =platform_get_drvdata (pdev); + +clk_disable_unprepare (info->clk); + +return 0 ; }#ifdef CONFIG_PM_SLEEP
@@ -413,6 +436,7 @@ static void tegra_rtc_shutdown(struct plMODULE_ALIAS ("platform:tegra_rtc" );static struct platform_driver tegra_rtc_driver = { + .remove = tegra_rtc_remove, .shutdown = tegra_rtc_shutdown, .driver = { .name ="tegra_rtc" ,
Greg Kroah-Hartman
maintainerPATCH 63/69 mm: Tighten x86 /dev/mem with zeroing reads
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
commit a4866aa812518ed1a37d8ea0c881dc946409de94 upstream.
Under CONFIG_STRICT_DEVMEM, reading System RAM through /dev/mem is disallowed. However, on x86, the first 1MB was always allowed for BIOS and similar things, regardless of it actually being System RAM. It was possible for heap to end up getting allocated in low 1MB RAM, and then read by things like x86info or dd, which would trip hardened usercopy:
usercopy: kernel memory exposure attempt detected from ffff880000090000 (dma-kmalloc-256) (4096 bytes)
This changes the x86 exception for the low 1MB by reading back zeros for System RAM areas instead of blindly allowing them. More work is needed to extend this to mmap, but currently mmap doesn't go through usercopy, so hardened usercopy won't Oops the kernel.
--- arch/x86/mm/init.c | 41 +++++++++++++++++++------- drivers/char/mem.c | 82 +++++++++++++++++++++++++++++++++-------------------- 2 files changed, 82 insertions(+), 41 deletions(-)
arch/x86/mm/init.c +30 -11
@@ -643,21 +643,40 @@ void __init init_mem_mapping(void)* devmem_is_allowed() checks to see if /dev/mem access to a certain address * is valid. The argument is a physical page number. * -* -* On x86, access has to be given to the first megabyte of ram because that area -* contains BIOS code and data regions used by X and dosemu and similar apps. -* Access has to be given to non-kernel-ram areas as well, these contain the PCI -* mmio resources as well as potential bios/acpi data regions. +* On x86, access has to be given to the first megabyte of RAM because that +* area traditionally contains BIOS code and data regions used by X, dosemu, +* and similar apps. Since they map the entire memory range, the whole range +* must be allowed (for mapping), but any areas that would otherwise be +* disallowed are flagged as being "zero filled" instead of rejected. +* Access has to be given to non-kernel-ram areas as well, these contain the +* PCI mmio resources as well as potential bios/acpi data regions. */ int devmem_is_allowed (unsigned long pagenr) { -if (pagenr <256 ) -return 1 ; -if (iomem_is_exclusive (pagenr <<PAGE_SHIFT )) +if (page_is_ram (pagenr)) { +/* +* For disallowed memory regions in the low 1MB range, +* request that the page be shown as all zeros. +*/ +if (pagenr <256 ) +return 2 ; + +return 0 ; + } + +/* +* This must follow RAM test, since System RAM is considered a +* restricted resource under CONFIG_STRICT_IOMEM. +*/ +if (iomem_is_exclusive (pagenr <<PAGE_SHIFT )) { +/* Low 1MB bypasses iomem restrictions. */ +if (pagenr <256 ) +return 1 ; +return 0 ; -if (!page_is_ram (pagenr)) -return 1 ; -return 0 ; + } + +return 1 ; }void free_init_pages (char *what,unsigned long begin,unsigned long end)
drivers/char/mem.c +52 -30
117 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 64/69 dvb-usb: dont use stack for firmware load
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mauro Carvalho Chehab <[email protected]>
commit 43fab9793c1f44e665b4f98035a14942edf03ddc upstream.
As reported by Marc Duponcheel <[email protected]>, firmware load on dvb-usb is using the stack, with is not allowed anymore on default Kernel configurations:
[ 1025.958836] dvb-usb: found a 'WideView WT-220U PenType Receiver (based on ZL353)' in cold state, will try to load a firmware [ 1025.958853] dvb-usb: downloading firmware from file 'dvb-usb-wt220u-zl0353-01.fw' [ 1025.958855] dvb-usb: could not stop the USB controller CPU. [ 1025.958856] dvb-usb: error while transferring firmware (transferred size: -11, block size: 3) [ 1025.958856] dvb-usb: firmware download failed at 8 with -22 [ 1025.958867] usbcore: registered new interface driver dvb_usb_dtt200u
[ 2.789902] dvb-usb: downloading firmware from file 'dvb-usb-wt220u-zl0353-01.fw' [ 2.789905] ------------[ cut here ]------------ [ 2.789911] WARNING: CPU: 3 PID: 2196 at drivers/usb/core/hcd.c:1584 usb_hcd_map_urb_for_dma+0x430/0x560 [usbcore] [ 2.789912] transfer buffer not dma capable [ 2.789912] Modules linked in: btusb dvb_usb_dtt200u(+) dvb_usb_af9035(+) btrtl btbcm dvb_usb dvb_usb_v2 btintel dvb_core bluetooth rc_core rfkill x86_pkg_temp_thermal intel_powerclamp coretemp crc32_pclmul aesni_intel aes_x86_64 glue_helper lrw gf128mul ablk_helper cryptd drm_kms_helper syscopyarea sysfillrect pcspkr i2c_i801 sysimgblt fb_sys_fops drm i2c_smbus i2c_core r8169 lpc_ich mfd_core mii thermal fan rtc_cmos video button acpi_cpufreq processor snd_hda_codec_realtek snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd crc32c_intel ahci libahci libata xhci_pci ehci_pci xhci_hcd ehci_hcd usbcore usb_common dm_mirror dm_region_hash dm_log dm_mod [ 2.789936] CPU: 3 PID: 2196 Comm: systemd-udevd Not tainted 4.9.0-gentoo #1 [ 2.789937] Hardware name: ASUS All Series/H81I-PLUS, BIOS 0401 07/23/2013 [ 2.789938] ffffc9000339b690 ffffffff812bd397 ffffc9000339b6e0 0000000000000000 [ 2.789939] ffffc9000339b6d0 ffffffff81055c86 000006300339b6a0 ffff880116c0c000 [ 2.789941] 0000000000000000 0000000000000000 0000000000000001 ffff880116c08000 [ 2.789942] Call Trace: [ 2.789945] [<ffffffff812bd397>] dump_stack+0x4d/0x66 [ 2.789947] [<ffffffff81055c86>] __warn+0xc6/0xe0 [ 2.789948] [<ffffffff81055cea>] warn_slowpath_fmt+0x4a/0x50 [ 2.789952] [<ffffffffa006d460>] usb_hcd_map_urb_for_dma+0x430/0x560 [usbcore] [ 2.789954] [<ffffffff814ed5a8>] ? io_schedule_timeout+0xd8/0x110 [ 2.789956] [<ffffffffa006e09c>] usb_hcd_submit_urb+0x9c/0x980 [usbcore] [ 2.789958] [<ffffffff812d0ebf>] ? copy_page_to_iter+0x14f/0x2b0 [ 2.789960] [<ffffffff81126818>] ? pagecache_get_page+0x28/0x240 [ 2.789962] [<ffffffff8118c2a0>] ? touch_atime+0x20/0xa0 [ 2.789964] [<ffffffffa006f7c4>] usb_submit_urb+0x2c4/0x520 [usbcore] [ 2.789967] [<ffffffffa006feca>] usb_start_wait_urb+0x5a/0xe0 [usbcore] [ 2.789969] [<ffffffffa007000c>] usb_control_msg+0xbc/0xf0 [usbcore] [ 2.789970] [<ffffffffa067903d>] usb_cypress_writemem+0x3d/0x40 [dvb_usb] [ 2.789972] [<ffffffffa06791cf>] usb_cypress_load_firmware+0x4f/0x130 [dvb_usb] [ 2.789973] [<ffffffff8109dbbe>] ? console_unlock+0x2fe/0x5d0 [ 2.789974] [<ffffffff8109e10c>] ? vprintk_emit+0x27c/0x410 [ 2.789975] [<ffffffff8109e40a>] ? vprintk_default+0x1a/0x20 [ 2.789976] [<ffffffff81124d76>] ? printk+0x43/0x4b [ 2.789977] [<ffffffffa0679310>] dvb_usb_download_firmware+0x60/0xd0 [dvb_usb] [ 2.789979] [<ffffffffa0679898>] dvb_usb_device_init+0x3d8/0x610 [dvb_usb] [ 2.789981] [<ffffffffa069e302>] dtt200u_usb_probe+0x92/0xd0 [dvb_usb_dtt200u] [ 2.789984] [<ffffffffa007420c>] usb_probe_interface+0xfc/0x270 [usbcore] [ 2.789985] [<ffffffff8138bf95>] driver_probe_device+0x215/0x2d0 [ 2.789986] [<ffffffff8138c0e6>] __driver_attach+0x96/0xa0 [ 2.789987] [<ffffffff8138c050>] ? driver_probe_device+0x2d0/0x2d0 [ 2.789988] [<ffffffff81389ffb>] bus_for_each_dev+0x5b/0x90 [ 2.789989] [<ffffffff8138b7b9>] driver_attach+0x19/0x20 [ 2.789990] [<ffffffff8138b33c>] bus_add_driver+0x11c/0x220 [ 2.789991] [<ffffffff8138c91b>] driver_register+0x5b/0xd0 [ 2.789994] [<ffffffffa0072f6c>] usb_register_driver+0x7c/0x130 [usbcore] [ 2.789994] [<ffffffffa06a5000>] ? 0xffffffffa06a5000 [ 2.789996] [<ffffffffa06a501e>] dtt200u_usb_driver_init+0x1e/0x20 [dvb_usb_dtt200u] [ 2.789997] [<ffffffff81000408>] do_one_initcall+0x38/0x140 [ 2.789998] [<ffffffff8116001c>] ? __vunmap+0x7c/0xc0 [ 2.789999] [<ffffffff81124fb0>] ? do_init_module+0x22/0x1d2 [ 2.790000] [<ffffffff81124fe8>] do_init_module+0x5a/0x1d2 [ 2.790002] [<ffffffff810c96b1>] load_module+0x1e11/0x2580 [ 2.790003] [<ffffffff810c68b0>] ? show_taint+0x30/0x30 [ 2.790004] [<ffffffff81177250>] ? kernel_read_file+0x100/0x190 [ 2.790005] [<ffffffff810c9ffa>] SyS_finit_module+0xba/0xc0 [ 2.790007] [<ffffffff814f13e0>] entry_SYSCALL_64_fastpath+0x13/0x94 [ 2.790008] ---[ end trace c78a74e78baec6fc ]---
So, allocate the structure dynamically.
--- drivers/media/usb/dvb-usb/dvb-usb-firmware.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
drivers/media/usb/dvb-usb/dvb-usb-firmware.c +13 -6
@@ -35,29 +35,34 @@ static int usb_cypress_writemem(struct uint usb_cypress_load_firmware (struct usb_device *udev,const struct firmware *fw,int type) { -struct hexline hx; +struct hexline *hx;u8 reset;int ret,pos=0 ; + hx =kmalloc (sizeof (*hx),GFP_KERNEL ); +if (!hx) +return -ENOMEM ; +/* stop the CPU */ reset =1 ;if ((ret =usb_cypress_writemem (udev,cypress[type].cpu_cs_register,&reset,1 )) !=1 )err ("could not stop the USB controller CPU." ); -while ((ret =dvb_usb_get_hexline (fw,&hx,&pos)) >0 ) { -deb_fw ("writing to address 0x%04x (buffer: 0x%02x %02x)\n" ,hx.addr,hx.len,hx.chk); - ret =usb_cypress_writemem (udev,hx.addr,hx.data,hx.len); +while ((ret =dvb_usb_get_hexline (fw, hx, &pos)) >0 ) { +deb_fw ("writing to address 0x%04x (buffer: 0x%02x %02x)\n" , hx->addr, hx->len, hx->chk); + ret =usb_cypress_writemem (udev, hx->addr, hx->data, hx->len); -if (ret != hx.len) { +if (ret != hx->len) {err ("error while transferring firmware " "(transferred size: %d, block size: %d)" , - ret,hx.len); + ret, hx->len); ret = -EINVAL ;break ; } }if (ret <0 ) {err ("firmware download failed at %d with %d" ,pos,ret); +kfree (hx);return ret; }
@@ -71,6 +76,8 @@ int usb_cypress_load_firmware(struct usb }else ret = -EIO ; +kfree (hx); +return ret; }EXPORT_SYMBOL (usb_cypress_load_firmware);
Greg Kroah-Hartman
maintainerPATCH 67/69 virtio-console: avoid DMA from stack
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Omar Sandoval <[email protected]>
commit c4baad50297d84bde1a7ad45e50c73adae4a2192 upstream.
put_chars() stuffs the buffer it gets into an sg, but that buffer may be on the stack. This breaks with CONFIG_VMAP_STACK=y (for me, it manifested as printks getting turned into NUL bytes).
--- drivers/char/virtio_console.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/char/virtio_console.c +10 -2
@@ -1136,6 +1136,8 @@ static int put_chars(u32 vtermno, const {struct port *port;struct scatterlist sg[1 ]; +void *data; +int ret;if (unlikely (early_put_chars))return early_put_chars (vtermno, buf, count);
@@ -1144,8 +1146,14 @@ static int put_chars(u32 vtermno, constif (!port)return -EPIPE ; -sg_init_one (sg, buf, count); -return __send_to_port (port, sg,1 , count, (void *)buf, false); + data =kmemdup (buf, count,GFP_ATOMIC ); +if (!data) +return -ENOMEM ; + +sg_init_one (sg, data, count); + ret =__send_to_port (port, sg,1 , count, data, false); +kfree (data); +return ret; }/*
Greg Kroah-Hartman
maintainerPATCH 69/69 sctp: deny peeloff operation on asocs with threads sleeping on it
In reply to Greg Kroah-Hartman4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marcelo Ricardo Leitner <[email protected]>
commit dfcb9f4f99f1e9a49e43398a7bfbf56927544af1 upstream.
commit 2dcab5984841 ("sctp: avoid BUG_ON on sctp_wait_for_sndbuf") attempted to avoid a BUG_ON call when the association being used for a sendmsg() is blocked waiting for more sndbuf and another thread did a peeloff operation on such asoc, moving it to another socket.
As Ben Hutchings noticed, then in such case it would return without locking back the socket and would cause two unlocks in a row.
Further analysis also revealed that it could allow a double free if the application managed to peeloff the asoc that is created during the sendmsg call, because then sctp_sendmsg() would try to free the asoc that was created only for that call.
This patch takes another approach. It will deny the peeloff operation if there is a thread sleeping on the asoc, so this situation doesn't exist anymore. This avoids the issues described above and also honors the syscalls that are already being handled (it can be multiple sendmsg calls).
Joint work with Xin Long.
--- net/sctp/socket.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
net/sctp/socket.c +6 -2
@@ -4735,6 +4735,12 @@ int sctp_do_peeloff(struct sock *sk, sctif (!asoc)return -EINVAL ; +/* If there is a thread waiting on more sndbuf space for +* sending on this asoc, it cannot be peeled. +*/ +if (waitqueue_active (&asoc->wait)) +return -EBUSY ; +/* An association cannot be branched off from an already peeled-off * socket, nor is this supported for tcp style sockets. */
@@ -7427,8 +7433,6 @@ static int sctp_wait_for_sndbuf(struct s*/ release_sock (sk); current_timeo =schedule_timeout (current_timeo); -if (sk != asoc->base.sk) - goto do_error;lock_sock (sk); *timeo_p = current_timeo;
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.9.24 release. There are 69 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Apr 21 14:16:02 UTC 2017. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.9.24-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.9.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.9.24 release. There are 69 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Apr 21 14:16:02 UTC 2017. Anything received after that time might be too late.
Build results:
total: 149 pass: 149 fail: 0 Qemu test results: total: 122 pass: 122 fail: 0
Details are available at http://kerneltests.org/builders.
Guenter