From: Greg Kroah-Hartman Date: Tue, 18 Apr 2017 12:50:05 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v4.4.63~39 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=82785807d9034aa5ae528a8047d9a9ea91160979;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: cifs-reconnect-thread-reschedule-itself.patch cifs-store-results-of-cifs_reopen_file-to-avoid-infinite-wait.patch drm-etnaviv-fix-missing-unlock-on-error-in-etnaviv_gpu_submit.patch drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch drm-nouveau-mpeg-mthd-returns-true-on-success-now.patch input-xpad-add-support-for-razer-wildcat-gamepad.patch orangefs-free-superblock-when-mount-fails.patch perf-x86-avoid-exposing-wrong-stale-data-in-intel_pmu_lbr_read_32.patch tcmu-fix-possible-overwrite-of-t_data_sg-s-last-iov.patch tcmu-fix-wrongly-calculating-of-the-base_command_size.patch tcmu-skip-data-out-blocks-before-gathering-data-in-buffer-for-bidi-case.patch thp-fix-madv_dontneed-vs-clear-soft-dirty-race.patch thp-fix-madv_dontneed-vs.-madv_free-race.patch x86-efi-don-t-try-to-reserve-runtime-regions.patch x86-pmem-fix-broken-__copy_user_nocache-cache-bypass-assumptions.patch x86-signals-fix-lower-upper-bound-reporting-in-compat-siginfo.patch x86-vdso-ensure-vdso32_enabled-gets-set-to-valid-values-only.patch x86-vdso-plug-race-between-mapping-and-elf-header-setup.patch zram-do-not-use-copy_page-with-non-page-aligned-address.patch zram-fix-operator-precedence-to-get-offset.patch zsmalloc-expand-class-bit.patch --- diff --git a/queue-4.9/cifs-reconnect-thread-reschedule-itself.patch b/queue-4.9/cifs-reconnect-thread-reschedule-itself.patch new file mode 100644 index 00000000000..c27f067bfc8 --- /dev/null +++ b/queue-4.9/cifs-reconnect-thread-reschedule-itself.patch @@ -0,0 +1,53 @@ +From 18ea43113f5b74a97dd4be9bddbac10d68b1a6ce Mon Sep 17 00:00:00 2001 +From: Germano Percossi +Date: Fri, 7 Apr 2017 12:29:36 +0100 +Subject: CIFS: reconnect thread reschedule itself + +From: Germano Percossi + +commit 18ea43113f5b74a97dd4be9bddbac10d68b1a6ce upstream. + +In case of error, smb2_reconnect_server reschedule itself +with a delay, to avoid being too aggressive. + +Signed-off-by: Germano Percossi +Reviewed-by: Pavel Shilovsky +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/smb2pdu.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -1987,6 +1987,9 @@ void smb2_reconnect_server(struct work_s + struct 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_s + spin_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 */ diff --git a/queue-4.9/cifs-store-results-of-cifs_reopen_file-to-avoid-infinite-wait.patch b/queue-4.9/cifs-store-results-of-cifs_reopen_file-to-avoid-infinite-wait.patch new file mode 100644 index 00000000000..b9a98580714 --- /dev/null +++ b/queue-4.9/cifs-store-results-of-cifs_reopen_file-to-avoid-infinite-wait.patch @@ -0,0 +1,64 @@ +From 1fa839b4986d648b907d117275869a0e46c324b9 Mon Sep 17 00:00:00 2001 +From: Germano Percossi +Date: Fri, 7 Apr 2017 12:29:38 +0100 +Subject: CIFS: store results of cifs_reopen_file to avoid infinite wait + +From: Germano Percossi + +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. + +Signed-off-by: Germano Percossi +Reviewed-by: Pavel Shilovsky +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/file.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -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); diff --git a/queue-4.9/drm-etnaviv-fix-missing-unlock-on-error-in-etnaviv_gpu_submit.patch b/queue-4.9/drm-etnaviv-fix-missing-unlock-on-error-in-etnaviv_gpu_submit.patch new file mode 100644 index 00000000000..5a9df6b82af --- /dev/null +++ b/queue-4.9/drm-etnaviv-fix-missing-unlock-on-error-in-etnaviv_gpu_submit.patch @@ -0,0 +1,42 @@ +From 45abdf35cf82e4270328c7237e7812de960ac560 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Wed, 12 Apr 2017 00:31:16 +0000 +Subject: drm/etnaviv: fix missing unlock on error in etnaviv_gpu_submit() + +From: Wei Yongjun + +commit 45abdf35cf82e4270328c7237e7812de960ac560 upstream. + +Add the missing unlock before return from function etnaviv_gpu_submit() +in the error handling case. + +lst: fixed label name. + +Fixes: f3cd1b064f11 ("drm/etnaviv: (re-)protect fence allocation with GPU mutex") +Signed-off-by: Wei Yongjun +Signed-off-by: Lucas Stach +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c ++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +@@ -1305,7 +1305,7 @@ int etnaviv_gpu_submit(struct etnaviv_gp + if (!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_gp + hangcheck_timer_reset(gpu); + ret = 0; + ++out_unlock: + mutex_unlock(&gpu->lock); + + out_pm_put: diff --git a/queue-4.9/drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch b/queue-4.9/drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch new file mode 100644 index 00000000000..9faabe84cf3 --- /dev/null +++ b/queue-4.9/drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch @@ -0,0 +1,40 @@ +From f94773b9f5ecd1df7c88c2e921924dd41d2020cc Mon Sep 17 00:00:00 2001 +From: Ilia Mirkin +Date: Sat, 18 Mar 2017 16:23:10 -0400 +Subject: drm/nouveau/mmu/nv4a: use nv04 mmu rather than the nv44 one + +From: Ilia Mirkin + +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 +Signed-off-by: Ilia Mirkin +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +@@ -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, diff --git a/queue-4.9/drm-nouveau-mpeg-mthd-returns-true-on-success-now.patch b/queue-4.9/drm-nouveau-mpeg-mthd-returns-true-on-success-now.patch new file mode 100644 index 00000000000..6146be453d5 --- /dev/null +++ b/queue-4.9/drm-nouveau-mpeg-mthd-returns-true-on-success-now.patch @@ -0,0 +1,41 @@ +From 83bce9c2baa51e439480a713119a73d3c8b61083 Mon Sep 17 00:00:00 2001 +From: Ilia Mirkin +Date: Sat, 18 Mar 2017 21:53:05 -0400 +Subject: drm/nouveau/mpeg: mthd returns true on success now + +From: Ilia Mirkin + +commit 83bce9c2baa51e439480a713119a73d3c8b61083 upstream. + +Signed-off-by: Ilia Mirkin +Fixes: 590801c1a3 ("drm/nouveau/mpeg: remove dependence on namedb/engctx lookup") +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + 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(-) + +--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c +@@ -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; + } + } +--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c +@@ -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; + } + } diff --git a/queue-4.9/input-xpad-add-support-for-razer-wildcat-gamepad.patch b/queue-4.9/input-xpad-add-support-for-razer-wildcat-gamepad.patch new file mode 100644 index 00000000000..b7d13a5f28b --- /dev/null +++ b/queue-4.9/input-xpad-add-support-for-razer-wildcat-gamepad.patch @@ -0,0 +1,35 @@ +From 5376366886251e2f8f248704adb620a4bc4c0937 Mon Sep 17 00:00:00 2001 +From: Cameron Gutman +Date: Mon, 10 Apr 2017 20:44:25 -0700 +Subject: Input: xpad - add support for Razer Wildcat gamepad + +From: Cameron Gutman + +commit 5376366886251e2f8f248704adb620a4bc4c0937 upstream. + +Signed-off-by: Cameron Gutman +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/joystick/xpad.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -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 */ + { } diff --git a/queue-4.9/orangefs-free-superblock-when-mount-fails.patch b/queue-4.9/orangefs-free-superblock-when-mount-fails.patch new file mode 100644 index 00000000000..8135f5ec864 --- /dev/null +++ b/queue-4.9/orangefs-free-superblock-when-mount-fails.patch @@ -0,0 +1,120 @@ +From 1ec1688c5360e14dde4094d6acbf7516bf6db37e Mon Sep 17 00:00:00 2001 +From: Martin Brandenburg +Date: Fri, 14 Apr 2017 14:22:41 -0400 +Subject: orangefs: free superblock when mount fails + +From: Martin Brandenburg + +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: [] sget_userns+0x2af/0x520 + +Caught by xfstests generic/413 which tried to mount with the unsupported +mount option dax. Then xfstests generic/422 ran sync which deadlocks. + +Signed-off-by: Martin Brandenburg +Acked-by: Mike Marshall +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/orangefs/devorangefs-req.c | 9 +++++++-- + fs/orangefs/orangefs-kernel.h | 1 + + fs/orangefs/super.c | 23 ++++++++++++++++------- + 3 files changed, 24 insertions(+), 9 deletions(-) + +--- a/fs/orangefs/devorangefs-req.c ++++ b/fs/orangefs/devorangefs-req.c +@@ -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)); +--- a/fs/orangefs/orangefs-kernel.h ++++ b/fs/orangefs/orangefs-kernel.h +@@ -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; + }; + +--- a/fs/orangefs/super.c ++++ b/fs/orangefs/super.c +@@ -493,7 +493,7 @@ struct dentry *orangefs_mount(struct fil + + if (ret) { + d = ERR_PTR(ret); +- goto free_op; ++ goto free_sb_and_op; + } + + /* +@@ -519,6 +519,9 @@ struct dentry *orangefs_mount(struct fil + spin_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 fil + + return 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 diff --git a/queue-4.9/perf-x86-avoid-exposing-wrong-stale-data-in-intel_pmu_lbr_read_32.patch b/queue-4.9/perf-x86-avoid-exposing-wrong-stale-data-in-intel_pmu_lbr_read_32.patch new file mode 100644 index 00000000000..a8411490987 --- /dev/null +++ b/queue-4.9/perf-x86-avoid-exposing-wrong-stale-data-in-intel_pmu_lbr_read_32.patch @@ -0,0 +1,37 @@ +From f2200ac311302fcdca6556fd0c5127eab6c65a3e Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Tue, 11 Apr 2017 10:10:28 +0200 +Subject: perf/x86: Avoid exposing wrong/stale data in intel_pmu_lbr_read_32() + +From: Peter Zijlstra + +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. + +Signed-off-by: Peter Zijlstra (Intel) +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: linux-kernel@vger.kernel.org +Fixes: 135c5612c460 ("perf/x86/intel: Support Haswell/v4 LBR format") +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/events/intel/lbr.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/x86/events/intel/lbr.c ++++ b/arch/x86/events/intel/lbr.c +@@ -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; diff --git a/queue-4.9/series b/queue-4.9/series index fb7089adbbd..7598871a129 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -1,2 +1,23 @@ cgroup-avoid-attaching-a-cgroup-root-to-two-different-superblocks.patch cgroup-kthread-close-race-window-where-new-kthreads-can-be-migrated-to-non-root-cgroups.patch +tcmu-fix-possible-overwrite-of-t_data_sg-s-last-iov.patch +tcmu-fix-wrongly-calculating-of-the-base_command_size.patch +tcmu-skip-data-out-blocks-before-gathering-data-in-buffer-for-bidi-case.patch +thp-fix-madv_dontneed-vs.-madv_free-race.patch +thp-fix-madv_dontneed-vs-clear-soft-dirty-race.patch +zram-fix-operator-precedence-to-get-offset.patch +zram-do-not-use-copy_page-with-non-page-aligned-address.patch +zsmalloc-expand-class-bit.patch +orangefs-free-superblock-when-mount-fails.patch +drm-nouveau-mpeg-mthd-returns-true-on-success-now.patch +drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch +drm-etnaviv-fix-missing-unlock-on-error-in-etnaviv_gpu_submit.patch +cifs-reconnect-thread-reschedule-itself.patch +cifs-store-results-of-cifs_reopen_file-to-avoid-infinite-wait.patch +input-xpad-add-support-for-razer-wildcat-gamepad.patch +perf-x86-avoid-exposing-wrong-stale-data-in-intel_pmu_lbr_read_32.patch +x86-efi-don-t-try-to-reserve-runtime-regions.patch +x86-signals-fix-lower-upper-bound-reporting-in-compat-siginfo.patch +x86-pmem-fix-broken-__copy_user_nocache-cache-bypass-assumptions.patch +x86-vdso-ensure-vdso32_enabled-gets-set-to-valid-values-only.patch +x86-vdso-plug-race-between-mapping-and-elf-header-setup.patch diff --git a/queue-4.9/tcmu-fix-possible-overwrite-of-t_data_sg-s-last-iov.patch b/queue-4.9/tcmu-fix-possible-overwrite-of-t_data_sg-s-last-iov.patch new file mode 100644 index 00000000000..c6de40ada50 --- /dev/null +++ b/queue-4.9/tcmu-fix-possible-overwrite-of-t_data_sg-s-last-iov.patch @@ -0,0 +1,96 @@ +From ab22d2604c86ceb01bb2725c9860b88a7dd383bb Mon Sep 17 00:00:00 2001 +From: Xiubo Li +Date: Mon, 27 Mar 2017 17:07:40 +0800 +Subject: tcmu: Fix possible overwrite of t_data_sg's last iov[] + +From: Xiubo Li + +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. + +Reviewed-by: Mike Christie +Tested-by: Ilias Tsitsimpis +Reviewed-by: Bryant G. Ly +Signed-off-by: Xiubo Li +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_user.c | 34 +++++++++++++++++++++++----------- + 1 file changed, 23 insertions(+), 11 deletions(-) + +--- a/drivers/target/target_core_user.c ++++ b/drivers/target/target_core_user.c +@@ -389,6 +389,20 @@ static bool is_ring_space_avail(struct t + return 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 *tcm + uint32_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); diff --git a/queue-4.9/tcmu-fix-wrongly-calculating-of-the-base_command_size.patch b/queue-4.9/tcmu-fix-wrongly-calculating-of-the-base_command_size.patch new file mode 100644 index 00000000000..91a8dda1070 --- /dev/null +++ b/queue-4.9/tcmu-fix-wrongly-calculating-of-the-base_command_size.patch @@ -0,0 +1,54 @@ +From abe342a5b4b5aa579f6bf40ba73447c699e6b579 Mon Sep 17 00:00:00 2001 +From: Xiubo Li +Date: Mon, 27 Mar 2017 17:07:41 +0800 +Subject: tcmu: Fix wrongly calculating of the base_command_size + +From: Xiubo Li + +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. + +Tested-by: Ilias Tsitsimpis +Reviewed-by: Mike Christie +Signed-off-by: Xiubo Li +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_user.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/target/target_core_user.c ++++ b/drivers/target/target_core_user.c +@@ -403,6 +403,13 @@ static inline size_t tcmu_cmd_get_data_l + return 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); diff --git a/queue-4.9/tcmu-skip-data-out-blocks-before-gathering-data-in-buffer-for-bidi-case.patch b/queue-4.9/tcmu-skip-data-out-blocks-before-gathering-data-in-buffer-for-bidi-case.patch new file mode 100644 index 00000000000..7d1e1c09d99 --- /dev/null +++ b/queue-4.9/tcmu-skip-data-out-blocks-before-gathering-data-in-buffer-for-bidi-case.patch @@ -0,0 +1,106 @@ +From a5d68ba85801a78c892a0eb8efb711e293ed314b Mon Sep 17 00:00:00 2001 +From: Xiubo Li +Date: Fri, 31 Mar 2017 10:35:25 +0800 +Subject: tcmu: Skip Data-Out blocks before gathering Data-In buffer for BIDI case + +From: Xiubo Li + +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") +Reported-by: Ilias Tsitsimpis +Tested-by: Ilias Tsitsimpis +Signed-off-by: Xiubo Li +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_user.c | 48 ++++++++++++++++++++++++++------------ + 1 file changed, 33 insertions(+), 15 deletions(-) + +--- a/drivers/target/target_core_user.c ++++ b/drivers/target/target_core_user.c +@@ -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); diff --git a/queue-4.9/thp-fix-madv_dontneed-vs-clear-soft-dirty-race.patch b/queue-4.9/thp-fix-madv_dontneed-vs-clear-soft-dirty-race.patch new file mode 100644 index 00000000000..b49804b4359 --- /dev/null +++ b/queue-4.9/thp-fix-madv_dontneed-vs-clear-soft-dirty-race.patch @@ -0,0 +1,45 @@ +From 5b7abeae3af8c08c577e599dd0578b9e3ee6687b Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" +Date: Thu, 13 Apr 2017 14:56:28 -0700 +Subject: thp: fix MADV_DONTNEED vs clear soft dirty race + +From: Kirill A. Shutemov + +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. + +Link: http://lkml.kernel.org/r/20170302151034.27829-5-kirill.shutemov@linux.intel.com +Signed-off-by: Kirill A. Shutemov +Cc: Andrea Arcangeli +Cc: Hillf Danton +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/proc/task_mmu.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/fs/proc/task_mmu.c ++++ b/fs/proc/task_mmu.c +@@ -899,7 +899,14 @@ static inline void clear_soft_dirty(stru + static 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); diff --git a/queue-4.9/thp-fix-madv_dontneed-vs.-madv_free-race.patch b/queue-4.9/thp-fix-madv_dontneed-vs.-madv_free-race.patch new file mode 100644 index 00000000000..0ffc1539d6d --- /dev/null +++ b/queue-4.9/thp-fix-madv_dontneed-vs.-madv_free-race.patch @@ -0,0 +1,60 @@ +From 58ceeb6bec86d9140f9d91d71a710e963523d063 Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" +Date: Thu, 13 Apr 2017 14:56:26 -0700 +Subject: thp: fix MADV_DONTNEED vs. MADV_FREE race + +From: Kirill A. Shutemov + +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. + +[kirill.shutemov@linux.intel.com: Urgh... Power is special again] + Link: http://lkml.kernel.org/r/20170303102636.bhd2zhtpds4mt62a@black.fi.intel.com +Link: http://lkml.kernel.org/r/20170302151034.27829-4-kirill.shutemov@linux.intel.com +Signed-off-by: Kirill A. Shutemov +Acked-by: Minchan Kim +Cc: Minchan Kim +Cc: Andrea Arcangeli +Cc: Hillf Danton +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/huge_memory.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -1380,8 +1380,7 @@ bool madvise_free_huge_pmd(struct mmu_ga + deactivate_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); + diff --git a/queue-4.9/x86-efi-don-t-try-to-reserve-runtime-regions.patch b/queue-4.9/x86-efi-don-t-try-to-reserve-runtime-regions.patch new file mode 100644 index 00000000000..4012d4108f2 --- /dev/null +++ b/queue-4.9/x86-efi-don-t-try-to-reserve-runtime-regions.patch @@ -0,0 +1,65 @@ +From 6f6266a561306e206e0e31a5038f029b6a7b1d89 Mon Sep 17 00:00:00 2001 +From: Omar Sandoval +Date: Wed, 12 Apr 2017 16:27:19 +0100 +Subject: x86/efi: Don't try to reserve runtime regions + +From: Omar Sandoval + +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. + +Signed-off-by: Omar Sandoval +Signed-off-by: Matt Fleming +Cc: Ard Biesheuvel +Cc: Dave Young +Cc: Linus Torvalds +Cc: Peter Jones +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: linux-efi@vger.kernel.org +Fixes: 8e80632fb23f ("efi/esrt: Use efi_mem_reserve() and avoid a kmalloc()") +Link: http://lkml.kernel.org/r/20170412152719.9779-2-matt@codeblueprint.co.uk +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/platform/efi/quirks.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/x86/platform/efi/quirks.c ++++ b/arch/x86/platform/efi/quirks.c +@@ -201,6 +201,10 @@ void __init efi_arch_mem_reserve(phys_ad + return; + } + ++ /* 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); diff --git a/queue-4.9/x86-pmem-fix-broken-__copy_user_nocache-cache-bypass-assumptions.patch b/queue-4.9/x86-pmem-fix-broken-__copy_user_nocache-cache-bypass-assumptions.patch new file mode 100644 index 00000000000..6a655eea722 --- /dev/null +++ b/queue-4.9/x86-pmem-fix-broken-__copy_user_nocache-cache-bypass-assumptions.patch @@ -0,0 +1,106 @@ +From 11e63f6d920d6f2dfd3cd421e939a4aec9a58dcd Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Thu, 6 Apr 2017 09:04:31 -0700 +Subject: x86, pmem: fix broken __copy_user_nocache cache-bypass assumptions + +From: Dan Williams + +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. + +Fixes: 5de490daec8b ("pmem: add copy_from_iter_pmem() and clear_pmem()") +Cc: +Cc: Jan Kara +Cc: Jeff Moyer +Cc: Ingo Molnar +Cc: Christoph Hellwig +Cc: "H. Peter Anvin" +Cc: Al Viro +Cc: Thomas Gleixner +Cc: Matthew Wilcox +Reviewed-by: Ross Zwisler +Signed-off-by: Toshi Kani +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/pmem.h | 42 +++++++++++++++++++++++++++++++----------- + 1 file changed, 31 insertions(+), 11 deletions(-) + +--- a/arch/x86/include/asm/pmem.h ++++ b/arch/x86/include/asm/pmem.h +@@ -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(vo + clwb(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; diff --git a/queue-4.9/x86-signals-fix-lower-upper-bound-reporting-in-compat-siginfo.patch b/queue-4.9/x86-signals-fix-lower-upper-bound-reporting-in-compat-siginfo.patch new file mode 100644 index 00000000000..bd9a9b5a835 --- /dev/null +++ b/queue-4.9/x86-signals-fix-lower-upper-bound-reporting-in-compat-siginfo.patch @@ -0,0 +1,49 @@ +From cfac6dfa42bddfa9711b20d486e521d1a41ab09f Mon Sep 17 00:00:00 2001 +From: Joerg Roedel +Date: Tue, 4 Apr 2017 18:15:01 +0200 +Subject: x86/signals: Fix lower/upper bound reporting in compat siginfo + +From: Joerg Roedel + +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. + +Signed-off-by: Joerg Roedel +Acked-by: Dave Hansen +Cc: Andy Lutomirski +Cc: Borislav Petkov +Cc: Borislav Petkov +Cc: Brian Gerst +Cc: Denys Vlasenko +Cc: Dmitry Safonov <0x7f454c46@gmail.com> +Cc: H. Peter Anvin +Cc: Josh Poimboeuf +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Fixes: a4455082dc6f0 ('x86/signals: Add missing signal_compat code for x86 features') +Link: http://lkml.kernel.org/r/1491322501-5054-1-git-send-email-joro@8bytes.org +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/signal_compat.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/x86/kernel/signal_compat.c ++++ b/arch/x86/kernel/signal_compat.c +@@ -151,8 +151,8 @@ int __copy_siginfo_to_user32(compat_sigi + + if (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); + } diff --git a/queue-4.9/x86-vdso-ensure-vdso32_enabled-gets-set-to-valid-values-only.patch b/queue-4.9/x86-vdso-ensure-vdso32_enabled-gets-set-to-valid-values-only.patch new file mode 100644 index 00000000000..18469652c6d --- /dev/null +++ b/queue-4.9/x86-vdso-ensure-vdso32_enabled-gets-set-to-valid-values-only.patch @@ -0,0 +1,67 @@ +From c06989da39cdb10604d572c8c7ea8c8c97f3c483 Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Mon, 10 Apr 2017 17:14:27 +0200 +Subject: x86/vdso: Ensure vdso32_enabled gets set to valid values only + +From: Mathias Krause + +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. + +Fixes: b0b49f2673f0 ("x86, vdso: Remove compat vdso support") +Signed-off-by: Mathias Krause +Acked-by: Andy Lutomirski +Cc: Peter Zijlstra +Cc: Roland McGrath +Link: http://lkml.kernel.org/r/1491424561-7187-1-git-send-email-minipli@googlemail.com +Link: http://lkml.kernel.org/r/20170410151723.518412863@linutronix.de +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/entry/vdso/vdso32-setup.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/arch/x86/entry/vdso/vdso32-setup.c ++++ b/arch/x86/entry/vdso/vdso32-setup.c +@@ -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 + ++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, + }, + {} + }; diff --git a/queue-4.9/x86-vdso-plug-race-between-mapping-and-elf-header-setup.patch b/queue-4.9/x86-vdso-plug-race-between-mapping-and-elf-header-setup.patch new file mode 100644 index 00000000000..88cf88ddb72 --- /dev/null +++ b/queue-4.9/x86-vdso-plug-race-between-mapping-and-elf-header-setup.patch @@ -0,0 +1,48 @@ +From 6fdc6dd90272ce7e75d744f71535cfbd8d77da81 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Mon, 10 Apr 2017 17:14:28 +0200 +Subject: x86/vdso: Plug race between mapping and ELF header setup + +From: Thomas Gleixner + +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 pointer + +Make ARCH_DLINFO_IA32 check whether the VDSO mapping has been set up for +the newly forked process or not. + +Signed-off-by: Thomas Gleixner +Acked-by: Andy Lutomirski +Cc: Peter Zijlstra +Cc: Mathias Krause +Link: http://lkml.kernel.org/r/20170410151723.602367196@linutronix.de +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/elf.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/include/asm/elf.h ++++ b/arch/x86/include/asm/elf.h +@@ -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); \ + } \ diff --git a/queue-4.9/zram-do-not-use-copy_page-with-non-page-aligned-address.patch b/queue-4.9/zram-do-not-use-copy_page-with-non-page-aligned-address.patch new file mode 100644 index 00000000000..508042636ec --- /dev/null +++ b/queue-4.9/zram-do-not-use-copy_page-with-non-page-aligned-address.patch @@ -0,0 +1,67 @@ +From d72e9a7a93e4f8e9e52491921d99e0c8aa89eb4e Mon Sep 17 00:00:00 2001 +From: Minchan Kim +Date: Thu, 13 Apr 2017 14:56:37 -0700 +Subject: zram: do not use copy_page with non-page aligned address + +From: Minchan Kim + +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. + +Fixes: 42e99bd ("zram: optimize memory operations with clear_page()/copy_page()") +Link: http://lkml.kernel.org/r/1492042622-12074-2-git-send-email-minchan@kernel.org +Signed-off-by: Minchan Kim +Cc: Sergey Senozhatsky +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/zram/zram_drv.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/block/zram/zram_drv.c ++++ b/drivers/block/zram/zram_drv.c +@@ -588,7 +588,7 @@ static int zram_decompress_page(struct z + + 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); diff --git a/queue-4.9/zram-fix-operator-precedence-to-get-offset.patch b/queue-4.9/zram-fix-operator-precedence-to-get-offset.patch new file mode 100644 index 00000000000..306d00ec81f --- /dev/null +++ b/queue-4.9/zram-fix-operator-precedence-to-get-offset.patch @@ -0,0 +1,36 @@ +From 4ca82dabc9fbf7bc5322aa54d802cb3cb7b125c5 Mon Sep 17 00:00:00 2001 +From: Minchan Kim +Date: Thu, 13 Apr 2017 14:56:35 -0700 +Subject: zram: fix operator precedence to get offset + +From: Minchan Kim + +commit 4ca82dabc9fbf7bc5322aa54d802cb3cb7b125c5 upstream. + +In zram_rw_page, the logic to get offset is wrong by operator precedence +(i.e., "<<" is higher than "&"). With wrong offset, zram can corrupt +the user's data. This patch fixes it. + +Fixes: 8c7f01025 ("zram: implement rw_page operation of zram") +Link: http://lkml.kernel.org/r/1492042622-12074-1-git-send-email-minchan@kernel.org +Signed-off-by: Minchan Kim +Cc: Sergey Senozhatsky +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/zram/zram_drv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/block/zram/zram_drv.c ++++ b/drivers/block/zram/zram_drv.c +@@ -998,7 +998,7 @@ static int zram_rw_page(struct block_dev + } + + index = sector >> SECTORS_PER_PAGE_SHIFT; +- offset = sector & (SECTORS_PER_PAGE - 1) << SECTOR_SHIFT; ++ offset = (sector & (SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT; + + bv.bv_page = page; + bv.bv_len = PAGE_SIZE; diff --git a/queue-4.9/zsmalloc-expand-class-bit.patch b/queue-4.9/zsmalloc-expand-class-bit.patch new file mode 100644 index 00000000000..fa1e8f16e02 --- /dev/null +++ b/queue-4.9/zsmalloc-expand-class-bit.patch @@ -0,0 +1,46 @@ +From 85d492f28d056c40629fc25d79f54da618a29dc4 Mon Sep 17 00:00:00 2001 +From: Minchan Kim +Date: Thu, 13 Apr 2017 14:56:40 -0700 +Subject: zsmalloc: expand class bit + +From: Minchan Kim + +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 + +Fixes: 3783689a1 ("zsmalloc: introduce zspage structure") +Link: http://lkml.kernel.org/r/1492042622-12074-3-git-send-email-minchan@kernel.org +Signed-off-by: Minchan Kim +Cc: Sergey Senozhatsky +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/zsmalloc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/zsmalloc.c ++++ b/mm/zsmalloc.c +@@ -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; + };