]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 24 Jul 2016 23:05:10 +0000 (16:05 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 24 Jul 2016 23:05:10 +0000 (16:05 -0700)
added patches:
apparmor-fix-oops-validate-buffer-size-in-apparmor_setprocattr.patch
arm64-fix-dump_instr-when-pan-and-uao-are-in-use.patch
arm64-kernel-save-and-restore-uao-and-addr_limit-on-exception-entry.patch
arm64-mm-remove-page_mapping-check-in-__sync_icache_dcache.patch
base-make-module_create_drivers_dir-race-free.patch
drm-fsl-dcu-use-flat-regmap-cache.patch
drm-mgag200-black-screen-fix-for-g200e-rev-4.patch
drm-nouveau-revert-drm-nouveau-device-pci-set-as-non-cpu-coherent-on-arm64.patch
hid-elo-kill-not-flush-the-work.patch
hid-hiddev-validate-num_values-for-hidiocgusages-hidiocsusages-commands.patch
hid-multitouch-enable-palm-rejection-for-windows-precision-touchpad.patch
iommu-amd-fix-unity-mapping-initialization-race.patch
iommu-arm-smmu-wire-up-map_sg-for-arm-smmu-v3.patch
iommu-rockchip-fix-zap-cache-during-device-attach.patch
iommu-vt-d-enable-qi-on-all-iommus-before-setting-root-entry.patch
ipmi-remove-smi_msg-from-waiting_rcv_msgs-list-before-handle_one_recv_msg.patch
keys-potential-uninitialized-variable.patch
kvm-arm-arm64-stop-leaking-vcpu-pid-references.patch
kvm-fix-irq-route-entries-exceeding-kvm_max_irq_routes.patch
kvm-nvmx-vmx-instructions-fix-segment-checks-when-l1-is-in-long-mode.patch
kvm-s390-mm-fix-cmma-reset-during-reboot.patch
kvm-vmx-check-apicv-is-active-before-using-vt-d-posted-interrupt.patch
revert-hid-multitouch-enable-palm-rejection-if-device-implements-confidence-usage.patch
tracing-handle-null-formats-in-hold_module_trace_bprintk_format.patch

25 files changed:
queue-4.6/apparmor-fix-oops-validate-buffer-size-in-apparmor_setprocattr.patch [new file with mode: 0644]
queue-4.6/arm64-fix-dump_instr-when-pan-and-uao-are-in-use.patch [new file with mode: 0644]
queue-4.6/arm64-kernel-save-and-restore-uao-and-addr_limit-on-exception-entry.patch [new file with mode: 0644]
queue-4.6/arm64-mm-remove-page_mapping-check-in-__sync_icache_dcache.patch [new file with mode: 0644]
queue-4.6/base-make-module_create_drivers_dir-race-free.patch [new file with mode: 0644]
queue-4.6/drm-fsl-dcu-use-flat-regmap-cache.patch [new file with mode: 0644]
queue-4.6/drm-mgag200-black-screen-fix-for-g200e-rev-4.patch [new file with mode: 0644]
queue-4.6/drm-nouveau-revert-drm-nouveau-device-pci-set-as-non-cpu-coherent-on-arm64.patch [new file with mode: 0644]
queue-4.6/hid-elo-kill-not-flush-the-work.patch [new file with mode: 0644]
queue-4.6/hid-hiddev-validate-num_values-for-hidiocgusages-hidiocsusages-commands.patch [new file with mode: 0644]
queue-4.6/hid-multitouch-enable-palm-rejection-for-windows-precision-touchpad.patch [new file with mode: 0644]
queue-4.6/iommu-amd-fix-unity-mapping-initialization-race.patch [new file with mode: 0644]
queue-4.6/iommu-arm-smmu-wire-up-map_sg-for-arm-smmu-v3.patch [new file with mode: 0644]
queue-4.6/iommu-rockchip-fix-zap-cache-during-device-attach.patch [new file with mode: 0644]
queue-4.6/iommu-vt-d-enable-qi-on-all-iommus-before-setting-root-entry.patch [new file with mode: 0644]
queue-4.6/ipmi-remove-smi_msg-from-waiting_rcv_msgs-list-before-handle_one_recv_msg.patch [new file with mode: 0644]
queue-4.6/keys-potential-uninitialized-variable.patch [new file with mode: 0644]
queue-4.6/kvm-arm-arm64-stop-leaking-vcpu-pid-references.patch [new file with mode: 0644]
queue-4.6/kvm-fix-irq-route-entries-exceeding-kvm_max_irq_routes.patch [new file with mode: 0644]
queue-4.6/kvm-nvmx-vmx-instructions-fix-segment-checks-when-l1-is-in-long-mode.patch [new file with mode: 0644]
queue-4.6/kvm-s390-mm-fix-cmma-reset-during-reboot.patch [new file with mode: 0644]
queue-4.6/kvm-vmx-check-apicv-is-active-before-using-vt-d-posted-interrupt.patch [new file with mode: 0644]
queue-4.6/revert-hid-multitouch-enable-palm-rejection-if-device-implements-confidence-usage.patch [new file with mode: 0644]
queue-4.6/series
queue-4.6/tracing-handle-null-formats-in-hold_module_trace_bprintk_format.patch [new file with mode: 0644]

diff --git a/queue-4.6/apparmor-fix-oops-validate-buffer-size-in-apparmor_setprocattr.patch b/queue-4.6/apparmor-fix-oops-validate-buffer-size-in-apparmor_setprocattr.patch
new file mode 100644 (file)
index 0000000..d1ef483
--- /dev/null
@@ -0,0 +1,117 @@
+From 30a46a4647fd1df9cf52e43bf467f0d9265096ca Mon Sep 17 00:00:00 2001
+From: Vegard Nossum <vegard.nossum@oracle.com>
+Date: Thu, 7 Jul 2016 13:41:11 -0700
+Subject: apparmor: fix oops, validate buffer size in apparmor_setprocattr()
+
+From: Vegard Nossum <vegard.nossum@oracle.com>
+
+commit 30a46a4647fd1df9cf52e43bf467f0d9265096ca upstream.
+
+When proc_pid_attr_write() was changed to use memdup_user apparmor's
+(interface violating) assumption that the setprocattr buffer was always
+a single page was violated.
+
+The size test is not strictly speaking needed as proc_pid_attr_write()
+will reject anything larger, but for the sake of robustness we can keep
+it in.
+
+SMACK and SELinux look safe to me, but somebody else should probably
+have a look just in case.
+
+Based on original patch from Vegard Nossum <vegard.nossum@oracle.com>
+modified for the case that apparmor provides null termination.
+
+Fixes: bb646cdb12e75d82258c2f2e7746d5952d3e321a
+Reported-by: Vegard Nossum <vegard.nossum@oracle.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: John Johansen <john.johansen@canonical.com>
+Cc: Paul Moore <paul@paul-moore.com>
+Cc: Stephen Smalley <sds@tycho.nsa.gov>
+Cc: Eric Paris <eparis@parisplace.org>
+Cc: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Reviewed-by: Tyler Hicks <tyhicks@canonical.com>
+Signed-off-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/apparmor/lsm.c |   36 +++++++++++++++++++-----------------
+ 1 file changed, 19 insertions(+), 17 deletions(-)
+
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -523,34 +523,34 @@ static int apparmor_setprocattr(struct t
+ {
+       struct common_audit_data sa;
+       struct apparmor_audit_data aad = {0,};
+-      char *command, *args = value;
++      char *command, *largs = NULL, *args = value;
+       size_t arg_size;
+       int error;
+       if (size == 0)
+               return -EINVAL;
+-      /* args points to a PAGE_SIZE buffer, AppArmor requires that
+-       * the buffer must be null terminated or have size <= PAGE_SIZE -1
+-       * so that AppArmor can null terminate them
+-       */
+-      if (args[size - 1] != '\0') {
+-              if (size == PAGE_SIZE)
+-                      return -EINVAL;
+-              args[size] = '\0';
+-      }
+-
+       /* task can only write its own attributes */
+       if (current != task)
+               return -EACCES;
+-      args = value;
++      /* AppArmor requires that the buffer must be null terminated atm */
++      if (args[size - 1] != '\0') {
++              /* null terminate */
++              largs = args = kmalloc(size + 1, GFP_KERNEL);
++              if (!args)
++                      return -ENOMEM;
++              memcpy(args, value, size);
++              args[size] = '\0';
++      }
++
++      error = -EINVAL;
+       args = strim(args);
+       command = strsep(&args, " ");
+       if (!args)
+-              return -EINVAL;
++              goto out;
+       args = skip_spaces(args);
+       if (!*args)
+-              return -EINVAL;
++              goto out;
+       arg_size = size - (args - (char *) value);
+       if (strcmp(name, "current") == 0) {
+@@ -576,10 +576,12 @@ static int apparmor_setprocattr(struct t
+                       goto fail;
+       } else
+               /* only support the "current" and "exec" process attributes */
+-              return -EINVAL;
++              goto fail;
+       if (!error)
+               error = size;
++out:
++      kfree(largs);
+       return error;
+ fail:
+@@ -588,9 +590,9 @@ fail:
+       aad.profile = aa_current_profile();
+       aad.op = OP_SETPROCATTR;
+       aad.info = name;
+-      aad.error = -EINVAL;
++      aad.error = error = -EINVAL;
+       aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
+-      return -EINVAL;
++      goto out;
+ }
+ static int apparmor_task_setrlimit(struct task_struct *task,
diff --git a/queue-4.6/arm64-fix-dump_instr-when-pan-and-uao-are-in-use.patch b/queue-4.6/arm64-fix-dump_instr-when-pan-and-uao-are-in-use.patch
new file mode 100644 (file)
index 0000000..c14074c
--- /dev/null
@@ -0,0 +1,95 @@
+From c5cea06be060f38e5400d796e61cfc8c36e52924 Mon Sep 17 00:00:00 2001
+From: Mark Rutland <mark.rutland@arm.com>
+Date: Mon, 13 Jun 2016 11:15:14 +0100
+Subject: arm64: fix dump_instr when PAN and UAO are in use
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+commit c5cea06be060f38e5400d796e61cfc8c36e52924 upstream.
+
+If the kernel is set to show unhandled signals, and a user task does not
+handle a SIGILL as a result of an instruction abort, we will attempt to
+log the offending instruction with dump_instr before killing the task.
+
+We use dump_instr to log the encoding of the offending userspace
+instruction. However, dump_instr is also used to dump instructions from
+kernel space, and internally always switches to KERNEL_DS before dumping
+the instruction with get_user. When both PAN and UAO are in use, reading
+a user instruction via get_user while in KERNEL_DS will result in a
+permission fault, which leads to an Oops.
+
+As we have regs corresponding to the context of the original instruction
+abort, we can inspect this and only flip to KERNEL_DS if the original
+abort was taken from the kernel, avoiding this issue. At the same time,
+remove the redundant (and incorrect) comments regarding the order
+dump_mem and dump_instr are called in.
+
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: James Morse <james.morse@arm.com>
+Cc: Robin Murphy <robin.murphy@arm.com>
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Reported-by: Vladimir Murzin <vladimir.murzin@arm.com>
+Tested-by: Vladimir Murzin <vladimir.murzin@arm.com>
+Fixes: 57f4959bad0a154a ("arm64: kernel: Add support for User Access Override")
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/kernel/traps.c |   26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+--- a/arch/arm64/kernel/traps.c
++++ b/arch/arm64/kernel/traps.c
+@@ -64,8 +64,7 @@ static void dump_mem(const char *lvl, co
+       /*
+        * We need to switch to kernel mode so that we can use __get_user
+-       * to safely read from kernel space.  Note that we now dump the
+-       * code first, just in case the backtrace kills us.
++       * to safely read from kernel space.
+        */
+       fs = get_fs();
+       set_fs(KERNEL_DS);
+@@ -111,21 +110,12 @@ static void dump_backtrace_entry(unsigne
+       print_ip_sym(where);
+ }
+-static void dump_instr(const char *lvl, struct pt_regs *regs)
++static void __dump_instr(const char *lvl, struct pt_regs *regs)
+ {
+       unsigned long addr = instruction_pointer(regs);
+-      mm_segment_t fs;
+       char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
+       int i;
+-      /*
+-       * We need to switch to kernel mode so that we can use __get_user
+-       * to safely read from kernel space.  Note that we now dump the
+-       * code first, just in case the backtrace kills us.
+-       */
+-      fs = get_fs();
+-      set_fs(KERNEL_DS);
+-
+       for (i = -4; i < 1; i++) {
+               unsigned int val, bad;
+@@ -139,8 +129,18 @@ static void dump_instr(const char *lvl,
+               }
+       }
+       printk("%sCode: %s\n", lvl, str);
++}
+-      set_fs(fs);
++static void dump_instr(const char *lvl, struct pt_regs *regs)
++{
++      if (!user_mode(regs)) {
++              mm_segment_t fs = get_fs();
++              set_fs(KERNEL_DS);
++              __dump_instr(lvl, regs);
++              set_fs(fs);
++      } else {
++              __dump_instr(lvl, regs);
++      }
+ }
+ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
diff --git a/queue-4.6/arm64-kernel-save-and-restore-uao-and-addr_limit-on-exception-entry.patch b/queue-4.6/arm64-kernel-save-and-restore-uao-and-addr_limit-on-exception-entry.patch
new file mode 100644 (file)
index 0000000..8bd6dd3
--- /dev/null
@@ -0,0 +1,111 @@
+From e19a6ee2460bdd0d0055a6029383422773f9999a Mon Sep 17 00:00:00 2001
+From: James Morse <james.morse@arm.com>
+Date: Mon, 20 Jun 2016 18:28:01 +0100
+Subject: arm64: kernel: Save and restore UAO and addr_limit on exception entry
+
+From: James Morse <james.morse@arm.com>
+
+commit e19a6ee2460bdd0d0055a6029383422773f9999a upstream.
+
+If we take an exception while at EL1, the exception handler inherits
+the original context's addr_limit and PSTATE.UAO values. To be consistent
+always reset addr_limit and PSTATE.UAO on (re-)entry to EL1. This
+prevents accidental re-use of the original context's addr_limit.
+
+Based on a similar patch for arm from Russell King.
+
+Acked-by: Will Deacon <will.deacon@arm.com>
+Reviewed-by: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: James Morse <james.morse@arm.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/include/asm/ptrace.h |    2 ++
+ arch/arm64/kernel/asm-offsets.c |    1 +
+ arch/arm64/kernel/entry.S       |   19 +++++++++++++++++--
+ arch/arm64/mm/fault.c           |    3 ++-
+ 4 files changed, 22 insertions(+), 3 deletions(-)
+
+--- a/arch/arm64/include/asm/ptrace.h
++++ b/arch/arm64/include/asm/ptrace.h
+@@ -117,6 +117,8 @@ struct pt_regs {
+       };
+       u64 orig_x0;
+       u64 syscallno;
++      u64 orig_addr_limit;
++      u64 unused;     // maintain 16 byte alignment
+ };
+ #define arch_has_single_step()        (1)
+--- a/arch/arm64/kernel/asm-offsets.c
++++ b/arch/arm64/kernel/asm-offsets.c
+@@ -59,6 +59,7 @@ int main(void)
+   DEFINE(S_PC,                        offsetof(struct pt_regs, pc));
+   DEFINE(S_ORIG_X0,           offsetof(struct pt_regs, orig_x0));
+   DEFINE(S_SYSCALLNO,         offsetof(struct pt_regs, syscallno));
++  DEFINE(S_ORIG_ADDR_LIMIT,   offsetof(struct pt_regs, orig_addr_limit));
+   DEFINE(S_FRAME_SIZE,                sizeof(struct pt_regs));
+   BLANK();
+   DEFINE(MM_CONTEXT_ID,               offsetof(struct mm_struct, context.id.counter));
+--- a/arch/arm64/kernel/entry.S
++++ b/arch/arm64/kernel/entry.S
+@@ -28,6 +28,7 @@
+ #include <asm/errno.h>
+ #include <asm/esr.h>
+ #include <asm/irq.h>
++#include <asm/memory.h>
+ #include <asm/thread_info.h>
+ #include <asm/unistd.h>
+@@ -97,7 +98,14 @@
+       mov     x29, xzr                        // fp pointed to user-space
+       .else
+       add     x21, sp, #S_FRAME_SIZE
+-      .endif
++      get_thread_info tsk
++      /* Save the task's original addr_limit and set USER_DS (TASK_SIZE_64) */
++      ldr     x20, [tsk, #TI_ADDR_LIMIT]
++      str     x20, [sp, #S_ORIG_ADDR_LIMIT]
++      mov     x20, #TASK_SIZE_64
++      str     x20, [tsk, #TI_ADDR_LIMIT]
++      ALTERNATIVE(nop, SET_PSTATE_UAO(0), ARM64_HAS_UAO, CONFIG_ARM64_UAO)
++      .endif /* \el == 0 */
+       mrs     x22, elr_el1
+       mrs     x23, spsr_el1
+       stp     lr, x21, [sp, #S_LR]
+@@ -128,6 +136,14 @@
+       .endm
+       .macro  kernel_exit, el
++      .if     \el != 0
++      /* Restore the task's original addr_limit. */
++      ldr     x20, [sp, #S_ORIG_ADDR_LIMIT]
++      str     x20, [tsk, #TI_ADDR_LIMIT]
++
++      /* No need to restore UAO, it will be restored from SPSR_EL1 */
++      .endif
++
+       ldp     x21, x22, [sp, #S_PC]           // load ELR, SPSR
+       .if     \el == 0
+       ct_user_enter
+@@ -406,7 +422,6 @@ el1_irq:
+       bl      trace_hardirqs_off
+ #endif
+-      get_thread_info tsk
+       irq_handler
+ #ifdef CONFIG_PREEMPT
+--- a/arch/arm64/mm/fault.c
++++ b/arch/arm64/mm/fault.c
+@@ -284,7 +284,8 @@ static int __kprobes do_page_fault(unsig
+       }
+       if (permission_fault(esr) && (addr < USER_DS)) {
+-              if (get_fs() == KERNEL_DS)
++              /* regs->orig_addr_limit may be 0 if we entered from EL0 */
++              if (regs->orig_addr_limit == KERNEL_DS)
+                       die("Accessing user space memory with fs=KERNEL_DS", regs, esr);
+               if (!search_exception_tables(regs->pc))
diff --git a/queue-4.6/arm64-mm-remove-page_mapping-check-in-__sync_icache_dcache.patch b/queue-4.6/arm64-mm-remove-page_mapping-check-in-__sync_icache_dcache.patch
new file mode 100644 (file)
index 0000000..32d53ca
--- /dev/null
@@ -0,0 +1,47 @@
+From 20c27a4270c775d7ed661491af8ac03264d60fc6 Mon Sep 17 00:00:00 2001
+From: Shaokun Zhang <zhangshaokun@hisilicon.com>
+Date: Tue, 21 Jun 2016 15:32:57 +0800
+Subject: arm64: mm: remove page_mapping check in __sync_icache_dcache
+
+From: Shaokun Zhang <zhangshaokun@hisilicon.com>
+
+commit 20c27a4270c775d7ed661491af8ac03264d60fc6 upstream.
+
+__sync_icache_dcache unconditionally skips the cache maintenance for
+anonymous pages, under the assumption that flushing is only required in
+the presence of D-side aliases [see 7249b79f6b4cc ("arm64: Do not flush
+the D-cache for anonymous pages")].
+
+Unfortunately, this breaks migration of anonymous pages holding
+self-modifying code, where userspace cannot be reasonably expected to
+reissue maintenance instructions in response to a migration.
+
+This patch fixes the problem by removing the broken page_mapping(page)
+check from the cache syncing code, otherwise we may end up fetching and
+executing stale instructions from the PoU.
+
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will.deacon@arm.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/mm/flush.c |    4 ----
+ 1 file changed, 4 deletions(-)
+
+--- a/arch/arm64/mm/flush.c
++++ b/arch/arm64/mm/flush.c
+@@ -71,10 +71,6 @@ void __sync_icache_dcache(pte_t pte, uns
+ {
+       struct page *page = pte_page(pte);
+-      /* no flushing needed for anonymous pages */
+-      if (!page_mapping(page))
+-              return;
+-
+       if (!test_and_set_bit(PG_dcache_clean, &page->flags))
+               sync_icache_aliases(page_address(page),
+                                   PAGE_SIZE << compound_order(page));
diff --git a/queue-4.6/base-make-module_create_drivers_dir-race-free.patch b/queue-4.6/base-make-module_create_drivers_dir-race-free.patch
new file mode 100644 (file)
index 0000000..20c31c6
--- /dev/null
@@ -0,0 +1,83 @@
+From 7e1b1fc4dabd6ec8e28baa0708866e13fa93c9b3 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Fri, 10 Jun 2016 10:54:32 +0200
+Subject: base: make module_create_drivers_dir race-free
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit 7e1b1fc4dabd6ec8e28baa0708866e13fa93c9b3 upstream.
+
+Modules which register drivers via standard path (driver_register) in
+parallel can cause a warning:
+WARNING: CPU: 2 PID: 3492 at ../fs/sysfs/dir.c:31 sysfs_warn_dup+0x62/0x80
+sysfs: cannot create duplicate filename '/module/saa7146/drivers'
+Modules linked in: hexium_gemini(+) mxb(+) ...
+...
+Call Trace:
+...
+ [<ffffffff812e63a2>] sysfs_warn_dup+0x62/0x80
+ [<ffffffff812e6487>] sysfs_create_dir_ns+0x77/0x90
+ [<ffffffff8140f2c4>] kobject_add_internal+0xb4/0x340
+ [<ffffffff8140f5b8>] kobject_add+0x68/0xb0
+ [<ffffffff8140f631>] kobject_create_and_add+0x31/0x70
+ [<ffffffff8157a703>] module_add_driver+0xc3/0xd0
+ [<ffffffff8155e5d4>] bus_add_driver+0x154/0x280
+ [<ffffffff815604c0>] driver_register+0x60/0xe0
+ [<ffffffff8145bed0>] __pci_register_driver+0x60/0x70
+ [<ffffffffa0273e14>] saa7146_register_extension+0x64/0x90 [saa7146]
+ [<ffffffffa0033011>] hexium_init_module+0x11/0x1000 [hexium_gemini]
+...
+
+As can be (mostly) seen, driver_register causes this call sequence:
+  -> bus_add_driver
+    -> module_add_driver
+      -> module_create_drivers_dir
+The last one creates "drivers" directory in /sys/module/<...>. When
+this is done in parallel, the directory is attempted to be created
+twice at the same time.
+
+This can be easily reproduced by loading mxb and hexium_gemini in
+parallel:
+while :; do
+  modprobe mxb &
+  modprobe hexium_gemini
+  wait
+  rmmod mxb hexium_gemini saa7146_vv saa7146
+done
+
+saa7146 calls pci_register_driver for both mxb and hexium_gemini,
+which means /sys/module/saa7146/drivers is to be created for both of
+them.
+
+Fix this by a new mutex in module_create_drivers_dir which makes the
+test-and-create "drivers" dir atomic.
+
+I inverted the condition and removed 'return' to avoid multiple
+unlocks or a goto.
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Fixes: fe480a2675ed (Modules: only add drivers/ direcory if needed)
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/module.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/base/module.c
++++ b/drivers/base/module.c
+@@ -24,10 +24,12 @@ static char *make_driver_name(struct dev
+ static void module_create_drivers_dir(struct module_kobject *mk)
+ {
+-      if (!mk || mk->drivers_dir)
+-              return;
++      static DEFINE_MUTEX(drivers_dir_mutex);
+-      mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
++      mutex_lock(&drivers_dir_mutex);
++      if (mk && !mk->drivers_dir)
++              mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
++      mutex_unlock(&drivers_dir_mutex);
+ }
+ void module_add_driver(struct module *mod, struct device_driver *drv)
diff --git a/queue-4.6/drm-fsl-dcu-use-flat-regmap-cache.patch b/queue-4.6/drm-fsl-dcu-use-flat-regmap-cache.patch
new file mode 100644 (file)
index 0000000..be392f8
--- /dev/null
@@ -0,0 +1,47 @@
+From ce492b3b8f99cf9d2f807ec22d8805c996a09503 Mon Sep 17 00:00:00 2001
+From: Stefan Agner <stefan@agner.ch>
+Date: Fri, 3 Jun 2016 14:21:34 -0700
+Subject: drm/fsl-dcu: use flat regmap cache
+
+From: Stefan Agner <stefan@agner.ch>
+
+commit ce492b3b8f99cf9d2f807ec22d8805c996a09503 upstream.
+
+Using flat regmap cache instead of RB-tree to avoid the following
+lockdep warning on driver load:
+WARNING: CPU: 0 PID: 1 at kernel/locking/lockdep.c:2755 lockdep_trace_alloc+0x15c/0x160()
+DEBUG_LOCKS_WARN_ON(irqs_disabled_flags(flags))
+
+The RB-tree regmap cache needs to allocate new space on first
+writes. However, allocations in an atomic context (e.g. when a
+spinlock is held) are not allowed. The function regmap_write
+calls map->lock, which acquires a spinlock in the fast_io case.
+Since the FSL DCU driver uses MMIO, the regmap bus of type
+regmap_mmio is being used which has fast_io set to true.
+
+Use flat regmap cache and specify max register to be large
+enouth to cover all registers available in LS1021a and Vybrids
+register space.
+
+Signed-off-by: Stefan Agner <stefan@agner.ch>
+Cc: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+@@ -40,9 +40,10 @@ static const struct regmap_config fsl_dc
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+-      .cache_type = REGCACHE_RBTREE,
++      .cache_type = REGCACHE_FLAT,
+       .volatile_reg = fsl_dcu_drm_is_volatile_reg,
++      .max_register = 0x11fc,
+ };
+ static int fsl_dcu_drm_irq_init(struct drm_device *dev)
diff --git a/queue-4.6/drm-mgag200-black-screen-fix-for-g200e-rev-4.patch b/queue-4.6/drm-mgag200-black-screen-fix-for-g200e-rev-4.patch
new file mode 100644 (file)
index 0000000..182eb08
--- /dev/null
@@ -0,0 +1,48 @@
+From d3922b69617b62bb2509936b68301f837229d9f0 Mon Sep 17 00:00:00 2001
+From: Mathieu Larouche <mathieu.larouche@matrox.com>
+Date: Fri, 27 May 2016 15:12:50 -0400
+Subject: drm/mgag200: Black screen fix for G200e rev 4
+
+From: Mathieu Larouche <mathieu.larouche@matrox.com>
+
+commit d3922b69617b62bb2509936b68301f837229d9f0 upstream.
+
+- Fixed black screen for some resolutions of G200e rev4
+- Fixed testm & testn which had predetermined value.
+
+Reported-by: Jan Beulich <jbeulich@suse.com>
+
+Signed-off-by: Mathieu Larouche <mathieu.larouche@matrox.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/mgag200/mgag200_mode.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
++++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
+@@ -182,7 +182,7 @@ static int mga_g200se_set_plls(struct mg
+                       }
+               }
+-              fvv = pllreffreq * testn / testm;
++              fvv = pllreffreq * (n + 1) / (m + 1);
+               fvv = (fvv - 800000) / 50000;
+               if (fvv > 15)
+@@ -202,6 +202,14 @@ static int mga_g200se_set_plls(struct mg
+       WREG_DAC(MGA1064_PIX_PLLC_M, m);
+       WREG_DAC(MGA1064_PIX_PLLC_N, n);
+       WREG_DAC(MGA1064_PIX_PLLC_P, p);
++
++      if (mdev->unique_rev_id >= 0x04) {
++              WREG_DAC(0x1a, 0x09);
++              msleep(20);
++              WREG_DAC(0x1a, 0x01);
++
++      }
++
+       return 0;
+ }
diff --git a/queue-4.6/drm-nouveau-revert-drm-nouveau-device-pci-set-as-non-cpu-coherent-on-arm64.patch b/queue-4.6/drm-nouveau-revert-drm-nouveau-device-pci-set-as-non-cpu-coherent-on-arm64.patch
new file mode 100644 (file)
index 0000000..04e401d
--- /dev/null
@@ -0,0 +1,131 @@
+From 539aae6e3af97c7ec1602ff23e805f2852c2611c Mon Sep 17 00:00:00 2001
+From: Robin Murphy <robin.murphy@arm.com>
+Date: Mon, 6 Jun 2016 16:11:52 +0900
+Subject: drm/nouveau/Revert "drm/nouveau/device/pci: set as non-CPU-coherent on ARM64"
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+commit 539aae6e3af97c7ec1602ff23e805f2852c2611c upstream.
+
+This reverts commit 1733a2ad36741b1812cf8b3f3037c28d0af53f50.
+
+There is apparently something amiss with the way the TTM code handles
+DMA buffers, which the above commit was attempting to work around for
+arm64 systems with non-coherent PCI. Unfortunately, this completely
+breaks systems *with* coherent PCI (which appear to be the majority).
+
+Booting a plain arm64 defconfig + CONFIG_DRM + CONFIG_DRM_NOUVEAU on
+a machine with a PCI GPU having coherent dma_map_ops (in this case a
+7600GT card plugged into an ARM Juno board) results in a fatal crash:
+
+[    2.803438] nouveau 0000:06:00.0: DRM: allocated 1024x768 fb: 0x9000, bo ffffffc976141c00
+[    2.897662] Unable to handle kernel NULL pointer dereference at virtual address 000001ac
+[    2.897666] pgd = ffffff8008e00000
+[    2.897675] [000001ac] *pgd=00000009ffffe003, *pud=00000009ffffe003, *pmd=0000000000000000
+[    2.897680] Internal error: Oops: 96000045 [#1] PREEMPT SMP
+[    2.897685] Modules linked in:
+[    2.897692] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.6.0-rc5+ #543
+[    2.897694] Hardware name: ARM Juno development board (r1) (DT)
+[    2.897699] task: ffffffc9768a0000 ti: ffffffc9768a8000 task.ti: ffffffc9768a8000
+[    2.897711] PC is at __memcpy+0x7c/0x180
+[    2.897719] LR is at OUT_RINGp+0x34/0x70
+[    2.897724] pc : [<ffffff80083465fc>] lr : [<ffffff800854248c>] pstate: 80000045
+[    2.897726] sp : ffffffc9768ab360
+[    2.897732] x29: ffffffc9768ab360 x28: 0000000000000001
+[    2.897738] x27: ffffffc97624c000 x26: 0000000000000000
+[    2.897744] x25: 0000000000000080 x24: 0000000000006c00
+[    2.897749] x23: 0000000000000005 x22: ffffffc97624c010
+[    2.897755] x21: 0000000000000004 x20: 0000000000000004
+[    2.897761] x19: ffffffc9763da000 x18: ffffffc976b2491c
+[    2.897766] x17: 0000000000000007 x16: 0000000000000006
+[    2.897771] x15: 0000000000000001 x14: 0000000000000001
+[    2.897777] x13: 0000000000e31b70 x12: ffffffc9768a0080
+[    2.897783] x11: 0000000000000000 x10: fffffffffffffb00
+[    2.897788] x9 : 0000000000000000 x8 : 0000000000000000
+[    2.897793] x7 : 0000000000000000 x6 : 00000000000001ac
+[    2.897799] x5 : 00000000ffffffff x4 : 0000000000000000
+[    2.897804] x3 : 0000000000000010 x2 : 0000000000000010
+[    2.897810] x1 : ffffffc97624c010 x0 : 00000000000001ac
+...
+[    2.898494] Call trace:
+[    2.898499] Exception stack(0xffffffc9768ab1a0 to 0xffffffc9768ab2c0)
+[    2.898506] b1a0: ffffffc9763da000 0000000000000004 ffffffc9768ab360 ffffff80083465fc
+[    2.898513] b1c0: ffffffc976801e00 ffffffc9762b8000 ffffffc9768ab1f0 ffffff80080ec158
+[    2.898520] b1e0: ffffffc9768ab230 ffffff8008496d04 ffffffc975ce6d80 ffffffc9768ab36e
+[    2.898527] b200: ffffffc9768ab36f ffffffc9768ab29d ffffffc9768ab29e ffffffc9768a0000
+[    2.898533] b220: ffffffc9768ab250 ffffff80080e70c0 ffffffc9768ab270 ffffff8008496e44
+[    2.898540] b240: 00000000000001ac ffffffc97624c010 0000000000000010 0000000000000010
+[    2.898546] b260: 0000000000000000 00000000ffffffff 00000000000001ac 0000000000000000
+[    2.898552] b280: 0000000000000000 0000000000000000 fffffffffffffb00 0000000000000000
+[    2.898558] b2a0: ffffffc9768a0080 0000000000e31b70 0000000000000001 0000000000000001
+[    2.898566] [<ffffff80083465fc>] __memcpy+0x7c/0x180
+[    2.898574] [<ffffff800853e164>] nv04_fbcon_imageblit+0x1d4/0x2e8
+[    2.898582] [<ffffff800853d6d0>] nouveau_fbcon_imageblit+0xd8/0xe0
+[    2.898591] [<ffffff80083c4db4>] soft_cursor+0x154/0x1d8
+[    2.898598] [<ffffff80083c47b4>] bit_cursor+0x4fc/0x538
+[    2.898605] [<ffffff80083c0cfc>] fbcon_cursor+0x134/0x1a8
+[    2.898613] [<ffffff800841c280>] hide_cursor+0x38/0xa0
+[    2.898620] [<ffffff800841d420>] redraw_screen+0x120/0x228
+[    2.898628] [<ffffff80083bf268>] fbcon_prepare_logo+0x370/0x3f8
+[    2.898635] [<ffffff80083bf640>] fbcon_init+0x350/0x560
+[    2.898641] [<ffffff800841c634>] visual_init+0xac/0x108
+[    2.898648] [<ffffff800841df14>] do_bind_con_driver+0x1c4/0x3a8
+[    2.898655] [<ffffff800841e4f4>] do_take_over_console+0x174/0x1e8
+[    2.898662] [<ffffff80083bf8c4>] do_fbcon_takeover+0x74/0x100
+[    2.898669] [<ffffff80083c3e44>] fbcon_event_notify+0x8cc/0x920
+[    2.898680] [<ffffff80080d7e38>] notifier_call_chain+0x50/0x90
+[    2.898685] [<ffffff80080d8214>] __blocking_notifier_call_chain+0x4c/0x90
+[    2.898691] [<ffffff80080d826c>] blocking_notifier_call_chain+0x14/0x20
+[    2.898696] [<ffffff80083c5e1c>] fb_notifier_call_chain+0x1c/0x28
+[    2.898703] [<ffffff80083c81ac>] register_framebuffer+0x1cc/0x2e0
+[    2.898712] [<ffffff800845da80>] drm_fb_helper_initial_config+0x288/0x3e8
+[    2.898719] [<ffffff800853da20>] nouveau_fbcon_init+0xe0/0x118
+[    2.898727] [<ffffff800852d2f8>] nouveau_drm_load+0x268/0x890
+[    2.898734] [<ffffff8008466e24>] drm_dev_register+0xbc/0xc8
+[    2.898740] [<ffffff8008468a88>] drm_get_pci_dev+0xa0/0x180
+[    2.898747] [<ffffff800852cb28>] nouveau_drm_probe+0x1a0/0x1e0
+[    2.898755] [<ffffff80083a32e0>] pci_device_probe+0x98/0x110
+[    2.898763] [<ffffff800858e434>] driver_probe_device+0x204/0x2b0
+[    2.898770] [<ffffff800858e58c>] __driver_attach+0xac/0xb0
+[    2.898777] [<ffffff800858c3e0>] bus_for_each_dev+0x60/0xa0
+[    2.898783] [<ffffff800858dbc0>] driver_attach+0x20/0x28
+[    2.898789] [<ffffff800858d7b0>] bus_add_driver+0x1d0/0x238
+[    2.898796] [<ffffff800858ed50>] driver_register+0x60/0xf8
+[    2.898802] [<ffffff80083a20dc>] __pci_register_driver+0x3c/0x48
+[    2.898809] [<ffffff8008468eb4>] drm_pci_init+0xf4/0x120
+[    2.898818] [<ffffff8008c56fc0>] nouveau_drm_init+0x21c/0x230
+[    2.898825] [<ffffff80080829d4>] do_one_initcall+0x8c/0x190
+[    2.898832] [<ffffff8008c31af4>] kernel_init_freeable+0x14c/0x1f0
+[    2.898839] [<ffffff80088a0c20>] kernel_init+0x10/0x100
+[    2.898845] [<ffffff8008085e10>] ret_from_fork+0x10/0x40
+[    2.898853] Code: a88120c7 a8c12027 a88120c7 a8c12027 (a88120c7)
+[    2.898871] ---[ end trace d5713dcad023ee04 ]---
+[    2.898888] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
+
+In a toss-up between the GPU seeing stale data artefacts on some systems
+vs. catastrophic kernel crashes on other systems, the latter would seem
+to take precedence, so revert this change until the real underlying
+problem can be fixed.
+
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Acked-by: Alexandre Courbot <acourbot@nvidia.com>
+[acourbot@nvidia.com: port to Nouveau tree, remove bits in lib/]
+Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
+@@ -1614,7 +1614,7 @@ nvkm_device_pci_func = {
+       .fini = nvkm_device_pci_fini,
+       .resource_addr = nvkm_device_pci_resource_addr,
+       .resource_size = nvkm_device_pci_resource_size,
+-      .cpu_coherent = !IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_ARM64),
++      .cpu_coherent = !IS_ENABLED(CONFIG_ARM),
+ };
+ int
diff --git a/queue-4.6/hid-elo-kill-not-flush-the-work.patch b/queue-4.6/hid-elo-kill-not-flush-the-work.patch
new file mode 100644 (file)
index 0000000..fac2de5
--- /dev/null
@@ -0,0 +1,32 @@
+From ed596a4a88bd161f868ccba078557ee7ede8a6ef Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Tue, 31 May 2016 14:48:15 +0200
+Subject: HID: elo: kill not flush the work
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit ed596a4a88bd161f868ccba078557ee7ede8a6ef upstream.
+
+Flushing a work that reschedules itself is not a sensible operation. It needs
+to be killed. Failure to do so leads to a kernel panic in the timer code.
+
+Signed-off-by: Oliver Neukum <ONeukum@suse.com>
+Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-elo.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/hid/hid-elo.c
++++ b/drivers/hid/hid-elo.c
+@@ -261,7 +261,7 @@ static void elo_remove(struct hid_device
+       struct elo_priv *priv = hid_get_drvdata(hdev);
+       hid_hw_stop(hdev);
+-      flush_workqueue(wq);
++      cancel_delayed_work_sync(&priv->work);
+       kfree(priv);
+ }
diff --git a/queue-4.6/hid-hiddev-validate-num_values-for-hidiocgusages-hidiocsusages-commands.patch b/queue-4.6/hid-hiddev-validate-num_values-for-hidiocgusages-hidiocsusages-commands.patch
new file mode 100644 (file)
index 0000000..69d045d
--- /dev/null
@@ -0,0 +1,43 @@
+From 93a2001bdfd5376c3dc2158653034c20392d15c5 Mon Sep 17 00:00:00 2001
+From: Scott Bauer <sbauer@plzdonthack.me>
+Date: Thu, 23 Jun 2016 08:59:47 -0600
+Subject: HID: hiddev: validate num_values for HIDIOCGUSAGES, HIDIOCSUSAGES commands
+
+From: Scott Bauer <sbauer@plzdonthack.me>
+
+commit 93a2001bdfd5376c3dc2158653034c20392d15c5 upstream.
+
+This patch validates the num_values parameter from userland during the
+HIDIOCGUSAGES and HIDIOCSUSAGES commands. Previously, if the report id was set
+to HID_REPORT_ID_UNKNOWN, we would fail to validate the num_values parameter
+leading to a heap overflow.
+
+Signed-off-by: Scott Bauer <sbauer@plzdonthack.me>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/usbhid/hiddev.c |   10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/hid/usbhid/hiddev.c
++++ b/drivers/hid/usbhid/hiddev.c
+@@ -516,13 +516,13 @@ static noinline int hiddev_ioctl_usage(s
+                                       goto inval;
+                       } else if (uref->usage_index >= field->report_count)
+                               goto inval;
+-
+-                      else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
+-                               (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
+-                                uref->usage_index + uref_multi->num_values > field->report_count))
+-                              goto inval;
+               }
++              if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
++                  (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
++                   uref->usage_index + uref_multi->num_values > field->report_count))
++                      goto inval;
++
+               switch (cmd) {
+               case HIDIOCGUSAGE:
+                       uref->value = field->value[uref->usage_index];
diff --git a/queue-4.6/hid-multitouch-enable-palm-rejection-for-windows-precision-touchpad.patch b/queue-4.6/hid-multitouch-enable-palm-rejection-for-windows-precision-touchpad.patch
new file mode 100644 (file)
index 0000000..2fb2186
--- /dev/null
@@ -0,0 +1,90 @@
+From 6dd2e27a103d716921cc4a1a96a9adc0a8e3ab57 Mon Sep 17 00:00:00 2001
+From: Allen Hung <allen_hung@dell.com>
+Date: Thu, 23 Jun 2016 16:31:30 +0800
+Subject: HID: multitouch: enable palm rejection for Windows Precision Touchpad
+
+From: Allen Hung <allen_hung@dell.com>
+
+commit 6dd2e27a103d716921cc4a1a96a9adc0a8e3ab57 upstream.
+
+The usage Confidence is mandary to Windows Precision Touchpad devices. If
+it is examined in input_mapping on a WIndows Precision Touchpad, a new add
+quirk MT_QUIRK_CONFIDENCE desgned for such devices will be applied to the
+device. A touch with the confidence bit is not set is determined as
+invalid.
+
+Tested on Dell XPS13 9343
+
+Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Tested-by: Andy Lutomirski <luto@kernel.org> # XPS 13 9350, BIOS 1.4.3
+Signed-off-by: Allen Hung <allen_hung@dell.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-multitouch.c |   18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -61,6 +61,7 @@ MODULE_LICENSE("GPL");
+ #define MT_QUIRK_ALWAYS_VALID         (1 << 4)
+ #define MT_QUIRK_VALID_IS_INRANGE     (1 << 5)
+ #define MT_QUIRK_VALID_IS_CONFIDENCE  (1 << 6)
++#define MT_QUIRK_CONFIDENCE           (1 << 7)
+ #define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE  (1 << 8)
+ #define MT_QUIRK_NO_AREA              (1 << 9)
+ #define MT_QUIRK_IGNORE_DUPLICATES    (1 << 10)
+@@ -78,6 +79,7 @@ struct mt_slot {
+       __s32 contactid;        /* the device ContactID assigned to this slot */
+       bool touch_state;       /* is the touch valid? */
+       bool inrange_state;     /* is the finger in proximity of the sensor? */
++      bool confidence_state;  /* is the touch made by a finger? */
+ };
+ struct mt_class {
+@@ -502,6 +504,9 @@ static int mt_touch_input_mapping(struct
+                       mt_store_field(usage, td, hi);
+                       return 1;
+               case HID_DG_CONFIDENCE:
++                      if (cls->name == MT_CLS_WIN_8 &&
++                              field->application == HID_DG_TOUCHPAD)
++                              cls->quirks |= MT_QUIRK_CONFIDENCE;
+                       mt_store_field(usage, td, hi);
+                       return 1;
+               case HID_DG_TIPSWITCH:
+@@ -614,6 +619,7 @@ static void mt_complete_slot(struct mt_d
+               return;
+       if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) {
++              int active;
+               int slotnum = mt_compute_slot(td, input);
+               struct mt_slot *s = &td->curdata;
+               struct input_mt *mt = input->mt;
+@@ -628,10 +634,14 @@ static void mt_complete_slot(struct mt_d
+                               return;
+               }
++              if (!(td->mtclass.quirks & MT_QUIRK_CONFIDENCE))
++                      s->confidence_state = 1;
++              active = (s->touch_state || s->inrange_state) &&
++                                                      s->confidence_state;
++
+               input_mt_slot(input, slotnum);
+-              input_mt_report_slot_state(input, MT_TOOL_FINGER,
+-                      s->touch_state || s->inrange_state);
+-              if (s->touch_state || s->inrange_state) {
++              input_mt_report_slot_state(input, MT_TOOL_FINGER, active);
++              if (active) {
+                       /* this finger is in proximity of the sensor */
+                       int wide = (s->w > s->h);
+                       /* divided by two to match visual scale of touch */
+@@ -696,6 +706,8 @@ static void mt_process_mt_event(struct h
+                       td->curdata.touch_state = value;
+                       break;
+               case HID_DG_CONFIDENCE:
++                      if (quirks & MT_QUIRK_CONFIDENCE)
++                              td->curdata.confidence_state = value;
+                       if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE)
+                               td->curvalid = value;
+                       break;
diff --git a/queue-4.6/iommu-amd-fix-unity-mapping-initialization-race.patch b/queue-4.6/iommu-amd-fix-unity-mapping-initialization-race.patch
new file mode 100644 (file)
index 0000000..bd5945e
--- /dev/null
@@ -0,0 +1,53 @@
+From 522e5cb76d0663c88f96b6a8301451c8efa37207 Mon Sep 17 00:00:00 2001
+From: Joerg Roedel <jroedel@suse.de>
+Date: Fri, 1 Jul 2016 16:42:55 +0200
+Subject: iommu/amd: Fix unity mapping initialization race
+
+From: Joerg Roedel <jroedel@suse.de>
+
+commit 522e5cb76d0663c88f96b6a8301451c8efa37207 upstream.
+
+There is a race condition in the AMD IOMMU init code that
+causes requested unity mappings to be blocked by the IOMMU
+for a short period of time. This results on boot failures
+and IO_PAGE_FAULTs on some machines.
+
+Fix this by making sure the unity mappings are installed
+before all other DMA is blocked.
+
+Fixes: aafd8ba0ca74 ('iommu/amd: Implement add_device and remove_device')
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/amd_iommu_init.c |   14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+--- a/drivers/iommu/amd_iommu_init.c
++++ b/drivers/iommu/amd_iommu_init.c
+@@ -1363,13 +1363,23 @@ static int __init amd_iommu_init_pci(voi
+                       break;
+       }
++      /*
++       * Order is important here to make sure any unity map requirements are
++       * fulfilled. The unity mappings are created and written to the device
++       * table during the amd_iommu_init_api() call.
++       *
++       * After that we call init_device_table_dma() to make sure any
++       * uninitialized DTE will block DMA, and in the end we flush the caches
++       * of all IOMMUs to make sure the changes to the device table are
++       * active.
++       */
++      ret = amd_iommu_init_api();
++
+       init_device_table_dma();
+       for_each_iommu(iommu)
+               iommu_flush_all_caches(iommu);
+-      ret = amd_iommu_init_api();
+-
+       if (!ret)
+               print_iommu_info();
diff --git a/queue-4.6/iommu-arm-smmu-wire-up-map_sg-for-arm-smmu-v3.patch b/queue-4.6/iommu-arm-smmu-wire-up-map_sg-for-arm-smmu-v3.patch
new file mode 100644 (file)
index 0000000..aa4aece
--- /dev/null
@@ -0,0 +1,32 @@
+From 9aeb26cfc2abc96be42b9df2d0f2dc5d805084ff Mon Sep 17 00:00:00 2001
+From: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
+Date: Fri, 3 Jun 2016 11:50:30 +0100
+Subject: iommu/arm-smmu: Wire up map_sg for arm-smmu-v3
+
+From: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
+
+commit 9aeb26cfc2abc96be42b9df2d0f2dc5d805084ff upstream.
+
+The map_sg callback is missing from arm_smmu_ops, but is required by
+iommu.h. Similarly to most other IOMMU drivers, connect it to
+default_iommu_map_sg.
+
+Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/arm-smmu-v3.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/iommu/arm-smmu-v3.c
++++ b/drivers/iommu/arm-smmu-v3.c
+@@ -1942,6 +1942,7 @@ static struct iommu_ops arm_smmu_ops = {
+       .attach_dev             = arm_smmu_attach_dev,
+       .map                    = arm_smmu_map,
+       .unmap                  = arm_smmu_unmap,
++      .map_sg                 = default_iommu_map_sg,
+       .iova_to_phys           = arm_smmu_iova_to_phys,
+       .add_device             = arm_smmu_add_device,
+       .remove_device          = arm_smmu_remove_device,
diff --git a/queue-4.6/iommu-rockchip-fix-zap-cache-during-device-attach.patch b/queue-4.6/iommu-rockchip-fix-zap-cache-during-device-attach.patch
new file mode 100644 (file)
index 0000000..784cc03
--- /dev/null
@@ -0,0 +1,35 @@
+From ae8a7910fb0568531033bd6ebe65590f7a4fa6e2 Mon Sep 17 00:00:00 2001
+From: John Keeping <john@metanate.com>
+Date: Wed, 1 Jun 2016 16:46:10 +0100
+Subject: iommu/rockchip: Fix zap cache during device attach
+
+From: John Keeping <john@metanate.com>
+
+commit ae8a7910fb0568531033bd6ebe65590f7a4fa6e2 upstream.
+
+rk_iommu_command() takes a struct rk_iommu and iterates over the slave
+MMUs, so this is doubly wrong in that we're passing in the wrong pointer
+and talking to MMUs that we shouldn't be.
+
+Fixes: cd6438c5f844 ("iommu/rockchip: Reconstruct to support multi slaves")
+Signed-off-by: John Keeping <john@metanate.com>
+Tested-by: Heiko Stuebner <heiko@sntech.de>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/rockchip-iommu.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iommu/rockchip-iommu.c
++++ b/drivers/iommu/rockchip-iommu.c
+@@ -815,7 +815,7 @@ static int rk_iommu_attach_device(struct
+       dte_addr = virt_to_phys(rk_domain->dt);
+       for (i = 0; i < iommu->num_mmu; i++) {
+               rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, dte_addr);
+-              rk_iommu_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
++              rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
+               rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK);
+       }
diff --git a/queue-4.6/iommu-vt-d-enable-qi-on-all-iommus-before-setting-root-entry.patch b/queue-4.6/iommu-vt-d-enable-qi-on-all-iommus-before-setting-root-entry.patch
new file mode 100644 (file)
index 0000000..57684ab
--- /dev/null
@@ -0,0 +1,56 @@
+From a4c34ff1c029e90e7d5f8dd8d29b0a93b31c3cb2 Mon Sep 17 00:00:00 2001
+From: Joerg Roedel <jroedel@suse.de>
+Date: Fri, 17 Jun 2016 11:29:48 +0200
+Subject: iommu/vt-d: Enable QI on all IOMMUs before setting root entry
+
+From: Joerg Roedel <jroedel@suse.de>
+
+commit a4c34ff1c029e90e7d5f8dd8d29b0a93b31c3cb2 upstream.
+
+This seems to be required on some X58 chipsets on systems
+with more than one IOMMU. QI does not work until it is
+enabled on all IOMMUs in the system.
+
+Reported-by: Dheeraj CVR <cvr.dheeraj@gmail.com>
+Tested-by: Dheeraj CVR <cvr.dheeraj@gmail.com>
+Fixes: 5f0a7f7614a9 ('iommu/vt-d: Make root entry visible for hardware right after allocation')
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/intel-iommu.c |   17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -3169,11 +3169,6 @@ static int __init init_dmars(void)
+                       }
+               }
+-              iommu_flush_write_buffer(iommu);
+-              iommu_set_root_entry(iommu);
+-              iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
+-              iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
+-
+               if (!ecap_pass_through(iommu->ecap))
+                       hw_pass_through = 0;
+ #ifdef CONFIG_INTEL_IOMMU_SVM
+@@ -3182,6 +3177,18 @@ static int __init init_dmars(void)
+ #endif
+       }
++      /*
++       * Now that qi is enabled on all iommus, set the root entry and flush
++       * caches. This is required on some Intel X58 chipsets, otherwise the
++       * flush_context function will loop forever and the boot hangs.
++       */
++      for_each_active_iommu(iommu, drhd) {
++              iommu_flush_write_buffer(iommu);
++              iommu_set_root_entry(iommu);
++              iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
++              iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
++      }
++
+       if (iommu_pass_through)
+               iommu_identity_mapping |= IDENTMAP_ALL;
diff --git a/queue-4.6/ipmi-remove-smi_msg-from-waiting_rcv_msgs-list-before-handle_one_recv_msg.patch b/queue-4.6/ipmi-remove-smi_msg-from-waiting_rcv_msgs-list-before-handle_one_recv_msg.patch
new file mode 100644 (file)
index 0000000..dec829a
--- /dev/null
@@ -0,0 +1,88 @@
+From ae4ea9a2460c7fee2ae8feeb4dfe96f5f6c3e562 Mon Sep 17 00:00:00 2001
+From: Junichi Nomura <j-nomura@ce.jp.nec.com>
+Date: Fri, 10 Jun 2016 04:31:52 +0000
+Subject: ipmi: Remove smi_msg from waiting_rcv_msgs list before handle_one_recv_msg()
+
+From: Junichi Nomura <j-nomura@ce.jp.nec.com>
+
+commit ae4ea9a2460c7fee2ae8feeb4dfe96f5f6c3e562 upstream.
+
+Commit 7ea0ed2b5be8 ("ipmi: Make the message handler easier to use for
+SMI interfaces") changed handle_new_recv_msgs() to call handle_one_recv_msg()
+for a smi_msg while the smi_msg is still connected to waiting_rcv_msgs list.
+That could lead to following list corruption problems:
+
+1) low-level function treats smi_msg as not connected to list
+
+  handle_one_recv_msg() could end up calling smi_send(), which
+  assumes the msg is not connected to list.
+
+  For example, the following sequence could corrupt list by
+  doing list_add_tail() for the entry still connected to other list.
+
+    handle_new_recv_msgs()
+      msg = list_entry(waiting_rcv_msgs)
+      handle_one_recv_msg(msg)
+        handle_ipmb_get_msg_cmd(msg)
+          smi_send(msg)
+            spin_lock(xmit_msgs_lock)
+            list_add_tail(msg)
+            spin_unlock(xmit_msgs_lock)
+
+2) race between multiple handle_new_recv_msgs() instances
+
+  handle_new_recv_msgs() once releases waiting_rcv_msgs_lock before calling
+  handle_one_recv_msg() then retakes the lock and list_del() it.
+
+  If others call handle_new_recv_msgs() during the window shown below
+  list_del() will be done twice for the same smi_msg.
+
+  handle_new_recv_msgs()
+    spin_lock(waiting_rcv_msgs_lock)
+    msg = list_entry(waiting_rcv_msgs)
+    spin_unlock(waiting_rcv_msgs_lock)
+  |
+  | handle_one_recv_msg(msg)
+  |
+    spin_lock(waiting_rcv_msgs_lock)
+    list_del(msg)
+    spin_unlock(waiting_rcv_msgs_lock)
+
+Fixes: 7ea0ed2b5be8 ("ipmi: Make the message handler easier to use for SMI interfaces")
+Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
+[Added a comment to describe why this works.]
+Signed-off-by: Corey Minyard <cminyard@mvista.com>
+Tested-by: Ye Feng <yefeng.yl@alibaba-inc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/ipmi/ipmi_msghandler.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -3820,6 +3820,7 @@ static void handle_new_recv_msgs(ipmi_sm
+       while (!list_empty(&intf->waiting_rcv_msgs)) {
+               smi_msg = list_entry(intf->waiting_rcv_msgs.next,
+                                    struct ipmi_smi_msg, link);
++              list_del(&smi_msg->link);
+               if (!run_to_completion)
+                       spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock,
+                                              flags);
+@@ -3829,11 +3830,14 @@ static void handle_new_recv_msgs(ipmi_sm
+               if (rv > 0) {
+                       /*
+                        * To preserve message order, quit if we
+-                       * can't handle a message.
++                       * can't handle a message.  Add the message
++                       * back at the head, this is safe because this
++                       * tasklet is the only thing that pulls the
++                       * messages.
+                        */
++                      list_add(&smi_msg->link, &intf->waiting_rcv_msgs);
+                       break;
+               } else {
+-                      list_del(&smi_msg->link);
+                       if (rv == 0)
+                               /* Message handled */
+                               ipmi_free_smi_msg(smi_msg);
diff --git a/queue-4.6/keys-potential-uninitialized-variable.patch b/queue-4.6/keys-potential-uninitialized-variable.patch
new file mode 100644 (file)
index 0000000..9b64554
--- /dev/null
@@ -0,0 +1,91 @@
+From 38327424b40bcebe2de92d07312c89360ac9229a Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Thu, 16 Jun 2016 15:48:57 +0100
+Subject: KEYS: potential uninitialized variable
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit 38327424b40bcebe2de92d07312c89360ac9229a upstream.
+
+If __key_link_begin() failed then "edit" would be uninitialized.  I've
+added a check to fix that.
+
+This allows a random user to crash the kernel, though it's quite
+difficult to achieve.  There are three ways it can be done as the user
+would have to cause an error to occur in __key_link():
+
+ (1) Cause the kernel to run out of memory.  In practice, this is difficult
+     to achieve without ENOMEM cropping up elsewhere and aborting the
+     attempt.
+
+ (2) Revoke the destination keyring between the keyring ID being looked up
+     and it being tested for revocation.  In practice, this is difficult to
+     time correctly because the KEYCTL_REJECT function can only be used
+     from the request-key upcall process.  Further, users can only make use
+     of what's in /sbin/request-key.conf, though this does including a
+     rejection debugging test - which means that the destination keyring
+     has to be the caller's session keyring in practice.
+
+ (3) Have just enough key quota available to create a key, a new session
+     keyring for the upcall and a link in the session keyring, but not then
+     sufficient quota to create a link in the nominated destination keyring
+     so that it fails with EDQUOT.
+
+The bug can be triggered using option (3) above using something like the
+following:
+
+       echo 80 >/proc/sys/kernel/keys/root_maxbytes
+       keyctl request2 user debug:fred negate @t
+
+The above sets the quota to something much lower (80) to make the bug
+easier to trigger, but this is dependent on the system.  Note also that
+the name of the keyring created contains a random number that may be
+between 1 and 10 characters in size, so may throw the test off by
+changing the amount of quota used.
+
+Assuming the failure occurs, something like the following will be seen:
+
+       kfree_debugcheck: out of range ptr 6b6b6b6b6b6b6b68h
+       ------------[ cut here ]------------
+       kernel BUG at ../mm/slab.c:2821!
+       ...
+       RIP: 0010:[<ffffffff811600f9>] kfree_debugcheck+0x20/0x25
+       RSP: 0018:ffff8804014a7de8  EFLAGS: 00010092
+       RAX: 0000000000000034 RBX: 6b6b6b6b6b6b6b68 RCX: 0000000000000000
+       RDX: 0000000000040001 RSI: 00000000000000f6 RDI: 0000000000000300
+       RBP: ffff8804014a7df0 R08: 0000000000000001 R09: 0000000000000000
+       R10: ffff8804014a7e68 R11: 0000000000000054 R12: 0000000000000202
+       R13: ffffffff81318a66 R14: 0000000000000000 R15: 0000000000000001
+       ...
+       Call Trace:
+         kfree+0xde/0x1bc
+         assoc_array_cancel_edit+0x1f/0x36
+         __key_link_end+0x55/0x63
+         key_reject_and_link+0x124/0x155
+         keyctl_reject_key+0xb6/0xe0
+         keyctl_negate_key+0x10/0x12
+         SyS_keyctl+0x9f/0xe7
+         do_syscall_64+0x63/0x13a
+         entry_SYSCALL64_slow_path+0x25/0x25
+
+Fixes: f70e2e06196a ('KEYS: Do preallocation for __key_link()')
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/keys/key.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/security/keys/key.c
++++ b/security/keys/key.c
+@@ -584,7 +584,7 @@ int key_reject_and_link(struct key *key,
+       mutex_unlock(&key_construction_mutex);
+-      if (keyring)
++      if (keyring && link_ret == 0)
+               __key_link_end(keyring, &key->index_key, edit);
+       /* wake up anyone waiting for a key to be constructed */
diff --git a/queue-4.6/kvm-arm-arm64-stop-leaking-vcpu-pid-references.patch b/queue-4.6/kvm-arm-arm64-stop-leaking-vcpu-pid-references.patch
new file mode 100644 (file)
index 0000000..513c79e
--- /dev/null
@@ -0,0 +1,54 @@
+From 591d215afcc2f94e8e2c69a63c924c044677eb31 Mon Sep 17 00:00:00 2001
+From: James Morse <james.morse@arm.com>
+Date: Wed, 8 Jun 2016 17:24:45 +0100
+Subject: KVM: arm/arm64: Stop leaking vcpu pid references
+
+From: James Morse <james.morse@arm.com>
+
+commit 591d215afcc2f94e8e2c69a63c924c044677eb31 upstream.
+
+kvm provides kvm_vcpu_uninit(), which amongst other things, releases the
+last reference to the struct pid of the task that was last running the vcpu.
+
+On arm64 built with CONFIG_DEBUG_KMEMLEAK, starting a guest with kvmtool,
+then killing it with SIGKILL results (after some considerable time) in:
+> cat /sys/kernel/debug/kmemleak
+> unreferenced object 0xffff80007d5ea080 (size 128):
+>  comm "lkvm", pid 2025, jiffies 4294942645 (age 1107.776s)
+>  hex dump (first 32 bytes):
+>    01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+>    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+>  backtrace:
+>    [<ffff8000001b30ec>] create_object+0xfc/0x278
+>    [<ffff80000071da34>] kmemleak_alloc+0x34/0x70
+>    [<ffff80000019fa2c>] kmem_cache_alloc+0x16c/0x1d8
+>    [<ffff8000000d0474>] alloc_pid+0x34/0x4d0
+>    [<ffff8000000b5674>] copy_process.isra.6+0x79c/0x1338
+>    [<ffff8000000b633c>] _do_fork+0x74/0x320
+>    [<ffff8000000b66b0>] SyS_clone+0x18/0x20
+>    [<ffff800000085cb0>] el0_svc_naked+0x24/0x28
+>    [<ffffffffffffffff>] 0xffffffffffffffff
+
+On x86 kvm_vcpu_uninit() is called on the path from kvm_arch_destroy_vm(),
+on arm no equivalent call is made. Add the call to kvm_arch_vcpu_free().
+
+Signed-off-by: James Morse <james.morse@arm.com>
+Fixes: 749cf76c5a36 ("KVM: ARM: Initial skeleton to compile KVM support")
+Acked-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/kvm/arm.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm/kvm/arm.c
++++ b/arch/arm/kvm/arm.c
+@@ -267,6 +267,7 @@ void kvm_arch_vcpu_free(struct kvm_vcpu
+       kvm_timer_vcpu_terminate(vcpu);
+       kvm_vgic_vcpu_destroy(vcpu);
+       kvm_pmu_vcpu_destroy(vcpu);
++      kvm_vcpu_uninit(vcpu);
+       kmem_cache_free(kvm_vcpu_cache, vcpu);
+ }
diff --git a/queue-4.6/kvm-fix-irq-route-entries-exceeding-kvm_max_irq_routes.patch b/queue-4.6/kvm-fix-irq-route-entries-exceeding-kvm_max_irq_routes.patch
new file mode 100644 (file)
index 0000000..33e1fc3
--- /dev/null
@@ -0,0 +1,72 @@
+From caf1ff26e1aa178133df68ac3d40815fed2187d9 Mon Sep 17 00:00:00 2001
+From: Xiubo Li <lixiubo@cmss.chinamobile.com>
+Date: Wed, 15 Jun 2016 18:00:33 +0800
+Subject: kvm: Fix irq route entries exceeding KVM_MAX_IRQ_ROUTES
+
+From: Xiubo Li <lixiubo@cmss.chinamobile.com>
+
+commit caf1ff26e1aa178133df68ac3d40815fed2187d9 upstream.
+
+These days, we experienced one guest crash with 8 cores and 3 disks,
+with qemu error logs as bellow:
+
+qemu-system-x86_64: /build/qemu-2.0.0/kvm-all.c:984:
+kvm_irqchip_commit_routes: Assertion `ret == 0' failed.
+
+And then we found one patch(bdf026317d) in qemu tree, which said
+could fix this bug.
+
+Execute the following script will reproduce the BUG quickly:
+
+irq_affinity.sh
+========================================================================
+
+vda_irq_num=25
+vdb_irq_num=27
+while [ 1 ]
+do
+    for irq in {1,2,4,8,10,20,40,80}
+        do
+            echo $irq > /proc/irq/$vda_irq_num/smp_affinity
+            echo $irq > /proc/irq/$vdb_irq_num/smp_affinity
+            dd if=/dev/vda of=/dev/zero bs=4K count=100 iflag=direct
+            dd if=/dev/vdb of=/dev/zero bs=4K count=100 iflag=direct
+        done
+done
+========================================================================
+
+The following qemu log is added in the qemu code and is displayed when
+this bug reproduced:
+
+kvm_irqchip_commit_routes: max gsi: 1008, nr_allocated_irq_routes: 1024,
+irq_routes->nr: 1024, gsi_count: 1024.
+
+That's to say when irq_routes->nr == 1024, there are 1024 routing entries,
+but in the kernel code when routes->nr >= 1024, will just return -EINVAL;
+
+The nr is the number of the routing entries which is in of
+[1 ~ KVM_MAX_IRQ_ROUTES], not the index in [0 ~ KVM_MAX_IRQ_ROUTES - 1].
+
+This patch fix the BUG above.
+
+Signed-off-by: Xiubo Li <lixiubo@cmss.chinamobile.com>
+Signed-off-by: Wei Tang <tangwei@cmss.chinamobile.com>
+Signed-off-by: Zhang Zhuoyu <zhangzhuoyu@cmss.chinamobile.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ virt/kvm/kvm_main.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -2868,7 +2868,7 @@ static long kvm_vm_ioctl(struct file *fi
+               if (copy_from_user(&routing, argp, sizeof(routing)))
+                       goto out;
+               r = -EINVAL;
+-              if (routing.nr >= KVM_MAX_IRQ_ROUTES)
++              if (routing.nr > KVM_MAX_IRQ_ROUTES)
+                       goto out;
+               if (routing.flags)
+                       goto out;
diff --git a/queue-4.6/kvm-nvmx-vmx-instructions-fix-segment-checks-when-l1-is-in-long-mode.patch b/queue-4.6/kvm-nvmx-vmx-instructions-fix-segment-checks-when-l1-is-in-long-mode.patch
new file mode 100644 (file)
index 0000000..3e289c5
--- /dev/null
@@ -0,0 +1,155 @@
+From ff30ef40deca4658e27b0c596e7baf39115e858f Mon Sep 17 00:00:00 2001
+From: Quentin Casasnovas <quentin.casasnovas@oracle.com>
+Date: Sat, 18 Jun 2016 11:01:05 +0200
+Subject: KVM: nVMX: VMX instructions: fix segment checks when L1 is in long mode.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Quentin Casasnovas <quentin.casasnovas@oracle.com>
+
+commit ff30ef40deca4658e27b0c596e7baf39115e858f upstream.
+
+I couldn't get Xen to boot a L2 HVM when it was nested under KVM - it was
+getting a GP(0) on a rather unspecial vmread from Xen:
+
+     (XEN) ----[ Xen-4.7.0-rc  x86_64  debug=n  Not tainted ]----
+     (XEN) CPU:    1
+     (XEN) RIP:    e008:[<ffff82d0801e629e>] vmx_get_segment_register+0x14e/0x450
+     (XEN) RFLAGS: 0000000000010202   CONTEXT: hypervisor (d1v0)
+     (XEN) rax: ffff82d0801e6288   rbx: ffff83003ffbfb7c   rcx: fffffffffffab928
+     (XEN) rdx: 0000000000000000   rsi: 0000000000000000   rdi: ffff83000bdd0000
+     (XEN) rbp: ffff83000bdd0000   rsp: ffff83003ffbfab0   r8:  ffff830038813910
+     (XEN) r9:  ffff83003faf3958   r10: 0000000a3b9f7640   r11: ffff83003f82d418
+     (XEN) r12: 0000000000000000   r13: ffff83003ffbffff   r14: 0000000000004802
+     (XEN) r15: 0000000000000008   cr0: 0000000080050033   cr4: 00000000001526e0
+     (XEN) cr3: 000000003fc79000   cr2: 0000000000000000
+     (XEN) ds: 0000   es: 0000   fs: 0000   gs: 0000   ss: 0000   cs: e008
+     (XEN) Xen code around <ffff82d0801e629e> (vmx_get_segment_register+0x14e/0x450):
+     (XEN)  00 00 41 be 02 48 00 00 <44> 0f 78 74 24 08 0f 86 38 56 00 00 b8 08 68 00
+     (XEN) Xen stack trace from rsp=ffff83003ffbfab0:
+
+     ...
+
+     (XEN) Xen call trace:
+     (XEN)    [<ffff82d0801e629e>] vmx_get_segment_register+0x14e/0x450
+     (XEN)    [<ffff82d0801f3695>] get_page_from_gfn_p2m+0x165/0x300
+     (XEN)    [<ffff82d0801bfe32>] hvmemul_get_seg_reg+0x52/0x60
+     (XEN)    [<ffff82d0801bfe93>] hvm_emulate_prepare+0x53/0x70
+     (XEN)    [<ffff82d0801ccacb>] handle_mmio+0x2b/0xd0
+     (XEN)    [<ffff82d0801be591>] emulate.c#_hvm_emulate_one+0x111/0x2c0
+     (XEN)    [<ffff82d0801cd6a4>] handle_hvm_io_completion+0x274/0x2a0
+     (XEN)    [<ffff82d0801f334a>] __get_gfn_type_access+0xfa/0x270
+     (XEN)    [<ffff82d08012f3bb>] timer.c#add_entry+0x4b/0xb0
+     (XEN)    [<ffff82d08012f80c>] timer.c#remove_entry+0x7c/0x90
+     (XEN)    [<ffff82d0801c8433>] hvm_do_resume+0x23/0x140
+     (XEN)    [<ffff82d0801e4fe7>] vmx_do_resume+0xa7/0x140
+     (XEN)    [<ffff82d080164aeb>] context_switch+0x13b/0xe40
+     (XEN)    [<ffff82d080128e6e>] schedule.c#schedule+0x22e/0x570
+     (XEN)    [<ffff82d08012c0cc>] softirq.c#__do_softirq+0x5c/0x90
+     (XEN)    [<ffff82d0801602c5>] domain.c#idle_loop+0x25/0x50
+     (XEN)
+     (XEN)
+     (XEN) ****************************************
+     (XEN) Panic on CPU 1:
+     (XEN) GENERAL PROTECTION FAULT
+     (XEN) [error_code=0000]
+     (XEN) ****************************************
+
+Tracing my host KVM showed it was the one injecting the GP(0) when
+emulating the VMREAD and checking the destination segment permissions in
+get_vmx_mem_address():
+
+     3)               |    vmx_handle_exit() {
+     3)               |      handle_vmread() {
+     3)               |        nested_vmx_check_permission() {
+     3)               |          vmx_get_segment() {
+     3)   0.074 us    |            vmx_read_guest_seg_base();
+     3)   0.065 us    |            vmx_read_guest_seg_selector();
+     3)   0.066 us    |            vmx_read_guest_seg_ar();
+     3)   1.636 us    |          }
+     3)   0.058 us    |          vmx_get_rflags();
+     3)   0.062 us    |          vmx_read_guest_seg_ar();
+     3)   3.469 us    |        }
+     3)               |        vmx_get_cs_db_l_bits() {
+     3)   0.058 us    |          vmx_read_guest_seg_ar();
+     3)   0.662 us    |        }
+     3)               |        get_vmx_mem_address() {
+     3)   0.068 us    |          vmx_cache_reg();
+     3)               |          vmx_get_segment() {
+     3)   0.074 us    |            vmx_read_guest_seg_base();
+     3)   0.068 us    |            vmx_read_guest_seg_selector();
+     3)   0.071 us    |            vmx_read_guest_seg_ar();
+     3)   1.756 us    |          }
+     3)               |          kvm_queue_exception_e() {
+     3)   0.066 us    |            kvm_multiple_exception();
+     3)   0.684 us    |          }
+     3)   4.085 us    |        }
+     3)   9.833 us    |      }
+     3) + 10.366 us   |    }
+
+Cross-checking the KVM/VMX VMREAD emulation code with the Intel Software
+Developper Manual Volume 3C - "VMREAD - Read Field from Virtual-Machine
+Control Structure", I found that we're enforcing that the destination
+operand is NOT located in a read-only data segment or any code segment when
+the L1 is in long mode - BUT that check should only happen when it is in
+protected mode.
+
+Shuffling the code a bit to make our emulation follow the specification
+allows me to boot a Xen dom0 in a nested KVM and start HVM L2 guests
+without problems.
+
+Fixes: f9eb4af67c9d ("KVM: nVMX: VMX instructions: add checks for #GP/#SS exceptions")
+Signed-off-by: Quentin Casasnovas <quentin.casasnovas@oracle.com>
+Cc: Eugene Korenevsky <ekorenevsky@gmail.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Radim Krčmář <rkrcmar@redhat.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/vmx.c |   23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -6659,7 +6659,13 @@ static int get_vmx_mem_address(struct kv
+       /* Checks for #GP/#SS exceptions. */
+       exn = false;
+-      if (is_protmode(vcpu)) {
++      if (is_long_mode(vcpu)) {
++              /* Long mode: #GP(0)/#SS(0) if the memory address is in a
++               * non-canonical form. This is the only check on the memory
++               * destination for long mode!
++               */
++              exn = is_noncanonical_address(*ret);
++      } else if (is_protmode(vcpu)) {
+               /* Protected mode: apply checks for segment validity in the
+                * following order:
+                * - segment type check (#GP(0) may be thrown)
+@@ -6676,17 +6682,10 @@ static int get_vmx_mem_address(struct kv
+                        * execute-only code segment
+                        */
+                       exn = ((s.type & 0xa) == 8);
+-      }
+-      if (exn) {
+-              kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
+-              return 1;
+-      }
+-      if (is_long_mode(vcpu)) {
+-              /* Long mode: #GP(0)/#SS(0) if the memory address is in a
+-               * non-canonical form. This is an only check for long mode.
+-               */
+-              exn = is_noncanonical_address(*ret);
+-      } else if (is_protmode(vcpu)) {
++              if (exn) {
++                      kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
++                      return 1;
++              }
+               /* Protected mode: #GP(0)/#SS(0) if the segment is unusable.
+                */
+               exn = (s.unusable != 0);
diff --git a/queue-4.6/kvm-s390-mm-fix-cmma-reset-during-reboot.patch b/queue-4.6/kvm-s390-mm-fix-cmma-reset-during-reboot.patch
new file mode 100644 (file)
index 0000000..3534c63
--- /dev/null
@@ -0,0 +1,40 @@
+From 1c343f7b0e177e8ca7f4d4a5dd1fa790f85abbcc Mon Sep 17 00:00:00 2001
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+Date: Mon, 13 Jun 2016 13:14:56 +0200
+Subject: KVM: s390/mm: Fix CMMA reset during reboot
+
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+
+commit 1c343f7b0e177e8ca7f4d4a5dd1fa790f85abbcc upstream.
+
+commit 1e133ab296f ("s390/mm: split arch/s390/mm/pgtable.c") factored
+out the page table handling code from __gmap_zap and  __s390_reset_cmma
+into ptep_zap_unused and added a simple flag that tells which one of the
+function (reset or not) is to be made. This also changed the behaviour,
+as it also zaps unused page table entries on reset.
+Turns out that this is wrong as s390_reset_cmma uses the page walker,
+which DOES NOT take the ptl lock.
+
+The most simple fix is to not do the zapping part on reset (which uses
+the walker)
+
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Fixes: 1e133ab296f ("s390/mm: split arch/s390/mm/pgtable.c")
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/mm/pgtable.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/s390/mm/pgtable.c
++++ b/arch/s390/mm/pgtable.c
+@@ -437,7 +437,7 @@ void ptep_zap_unused(struct mm_struct *m
+       pgste = pgste_get_lock(ptep);
+       pgstev = pgste_val(pgste);
+       pte = *ptep;
+-      if (pte_swap(pte) &&
++      if (!reset && pte_swap(pte) &&
+           ((pgstev & _PGSTE_GPS_USAGE_MASK) == _PGSTE_GPS_USAGE_UNUSED ||
+            (pgstev & _PGSTE_GPS_ZERO))) {
+               ptep_zap_swap_entry(mm, pte_to_swp_entry(pte));
diff --git a/queue-4.6/kvm-vmx-check-apicv-is-active-before-using-vt-d-posted-interrupt.patch b/queue-4.6/kvm-vmx-check-apicv-is-active-before-using-vt-d-posted-interrupt.patch
new file mode 100644 (file)
index 0000000..2cdb55c
--- /dev/null
@@ -0,0 +1,75 @@
+From a0052191624e9bf8a8f9dc41b92ab5f252566c3c Mon Sep 17 00:00:00 2001
+From: Yang Zhang <yang.zhang.wz@gmail.com>
+Date: Mon, 13 Jun 2016 09:56:56 +0800
+Subject: kvm: vmx: check apicv is active before using VT-d posted interrupt
+
+From: Yang Zhang <yang.zhang.wz@gmail.com>
+
+commit a0052191624e9bf8a8f9dc41b92ab5f252566c3c upstream.
+
+VT-d posted interrupt is relying on the CPU side's posted interrupt.
+Need to check whether VCPU's APICv is active before enabing VT-d
+posted interrupt.
+
+Fixes: d62caabb41f33d96333f9ef15e09cd26e1c12760
+Signed-off-by: Yang Zhang <yang.zhang.wz@gmail.com>
+Signed-off-by: Shengge Ding <shengge.dsg@alibaba-inc.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/vmx.c |   15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -2072,7 +2072,8 @@ static void vmx_vcpu_pi_load(struct kvm_
+       unsigned int dest;
+       if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
+-              !irq_remapping_cap(IRQ_POSTING_CAP))
++              !irq_remapping_cap(IRQ_POSTING_CAP)  ||
++              !kvm_vcpu_apicv_active(vcpu))
+               return;
+       do {
+@@ -2180,7 +2181,8 @@ static void vmx_vcpu_pi_put(struct kvm_v
+       struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
+       if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
+-              !irq_remapping_cap(IRQ_POSTING_CAP))
++              !irq_remapping_cap(IRQ_POSTING_CAP)  ||
++              !kvm_vcpu_apicv_active(vcpu))
+               return;
+       /* Set SN when the vCPU is preempted */
+@@ -10702,7 +10704,8 @@ static int vmx_pre_block(struct kvm_vcpu
+       struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
+       if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
+-              !irq_remapping_cap(IRQ_POSTING_CAP))
++              !irq_remapping_cap(IRQ_POSTING_CAP)  ||
++              !kvm_vcpu_apicv_active(vcpu))
+               return 0;
+       vcpu->pre_pcpu = vcpu->cpu;
+@@ -10768,7 +10771,8 @@ static void vmx_post_block(struct kvm_vc
+       unsigned long flags;
+       if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
+-              !irq_remapping_cap(IRQ_POSTING_CAP))
++              !irq_remapping_cap(IRQ_POSTING_CAP)  ||
++              !kvm_vcpu_apicv_active(vcpu))
+               return;
+       do {
+@@ -10821,7 +10825,8 @@ static int vmx_update_pi_irte(struct kvm
+       int idx, ret = -EINVAL;
+       if (!kvm_arch_has_assigned_device(kvm) ||
+-              !irq_remapping_cap(IRQ_POSTING_CAP))
++              !irq_remapping_cap(IRQ_POSTING_CAP) ||
++              !kvm_vcpu_apicv_active(kvm->vcpus[0]))
+               return 0;
+       idx = srcu_read_lock(&kvm->irq_srcu);
diff --git a/queue-4.6/revert-hid-multitouch-enable-palm-rejection-if-device-implements-confidence-usage.patch b/queue-4.6/revert-hid-multitouch-enable-palm-rejection-if-device-implements-confidence-usage.patch
new file mode 100644 (file)
index 0000000..c64a456
--- /dev/null
@@ -0,0 +1,42 @@
+From 62630ea768869beeb1e514b0bf5607a0c9b93d12 Mon Sep 17 00:00:00 2001
+From: Allen Hung <allen_hung@dell.com>
+Date: Thu, 23 Jun 2016 16:31:29 +0800
+Subject: Revert "HID: multitouch: enable palm rejection if device implements confidence usage"
+
+From: Allen Hung <allen_hung@dell.com>
+
+commit 62630ea768869beeb1e514b0bf5607a0c9b93d12 upstream.
+
+This reverts commit 25a84db15b3f ("HID: multitouch: enable palm rejection
+if device implements confidence usage")
+
+The commit enables palm rejection for Win8 Precision Touchpad devices but
+the quirk MT_QUIRK_VALID_IS_CONFIDENCE it is using is not working very
+properly. This quirk is originally designed for some WIn7 touchscreens. Use
+of this for a Win8 Precision Touchpad will cause unexpected pointer jumping
+problem.
+
+Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Tested-by: Andy Lutomirski <luto@kernel.org> # XPS 13 9350, BIOS 1.4.3
+Signed-off-by: Allen Hung <allen_hung@dell.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-multitouch.c |    5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -502,11 +502,6 @@ static int mt_touch_input_mapping(struct
+                       mt_store_field(usage, td, hi);
+                       return 1;
+               case HID_DG_CONFIDENCE:
+-                      if (cls->name == MT_CLS_WIN_8 &&
+-                              field->application == HID_DG_TOUCHPAD) {
+-                              cls->quirks &= ~MT_QUIRK_ALWAYS_VALID;
+-                              cls->quirks |= MT_QUIRK_VALID_IS_CONFIDENCE;
+-                      }
+                       mt_store_field(usage, td, hi);
+                       return 1;
+               case HID_DG_TIPSWITCH:
index 620fc473c96b85ba185575f74a15d173f178be2e..94067c0ad1779133132f4cd92690851100849132 100644 (file)
@@ -73,3 +73,27 @@ macsec-set-actual-real-device-for-xmit-when-protect_frames.patch
 geneve-fix-max_mtu-setting.patch
 cdc_ncm-workaround-for-em7455-silent-data-interface.patch
 ipv6-fix-mem-leak-in-rt6i_pcpu.patch
+keys-potential-uninitialized-variable.patch
+kvm-vmx-check-apicv-is-active-before-using-vt-d-posted-interrupt.patch
+kvm-fix-irq-route-entries-exceeding-kvm_max_irq_routes.patch
+kvm-s390-mm-fix-cmma-reset-during-reboot.patch
+kvm-arm-arm64-stop-leaking-vcpu-pid-references.patch
+kvm-nvmx-vmx-instructions-fix-segment-checks-when-l1-is-in-long-mode.patch
+hid-elo-kill-not-flush-the-work.patch
+hid-hiddev-validate-num_values-for-hidiocgusages-hidiocsusages-commands.patch
+revert-hid-multitouch-enable-palm-rejection-if-device-implements-confidence-usage.patch
+hid-multitouch-enable-palm-rejection-for-windows-precision-touchpad.patch
+tracing-handle-null-formats-in-hold_module_trace_bprintk_format.patch
+base-make-module_create_drivers_dir-race-free.patch
+iommu-rockchip-fix-zap-cache-during-device-attach.patch
+iommu-arm-smmu-wire-up-map_sg-for-arm-smmu-v3.patch
+iommu-vt-d-enable-qi-on-all-iommus-before-setting-root-entry.patch
+iommu-amd-fix-unity-mapping-initialization-race.patch
+apparmor-fix-oops-validate-buffer-size-in-apparmor_setprocattr.patch
+drm-mgag200-black-screen-fix-for-g200e-rev-4.patch
+drm-fsl-dcu-use-flat-regmap-cache.patch
+ipmi-remove-smi_msg-from-waiting_rcv_msgs-list-before-handle_one_recv_msg.patch
+drm-nouveau-revert-drm-nouveau-device-pci-set-as-non-cpu-coherent-on-arm64.patch
+arm64-fix-dump_instr-when-pan-and-uao-are-in-use.patch
+arm64-mm-remove-page_mapping-check-in-__sync_icache_dcache.patch
+arm64-kernel-save-and-restore-uao-and-addr_limit-on-exception-entry.patch
diff --git a/queue-4.6/tracing-handle-null-formats-in-hold_module_trace_bprintk_format.patch b/queue-4.6/tracing-handle-null-formats-in-hold_module_trace_bprintk_format.patch
new file mode 100644 (file)
index 0000000..8e2542c
--- /dev/null
@@ -0,0 +1,61 @@
+From 70c8217acd4383e069fe1898bbad36ea4fcdbdcc Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
+Date: Fri, 17 Jun 2016 16:10:42 -0400
+Subject: tracing: Handle NULL formats in hold_module_trace_bprintk_format()
+
+From: Steven Rostedt (Red Hat) <rostedt@goodmis.org>
+
+commit 70c8217acd4383e069fe1898bbad36ea4fcdbdcc upstream.
+
+If a task uses a non constant string for the format parameter in
+trace_printk(), then the trace_printk_fmt variable is set to NULL. This
+variable is then saved in the __trace_printk_fmt section.
+
+The function hold_module_trace_bprintk_format() checks to see if duplicate
+formats are used by modules, and reuses them if so (saves them to the list
+if it is new). But this function calls lookup_format() that does a strcmp()
+to the value (which is now NULL) and can cause a kernel oops.
+
+This wasn't an issue till 3debb0a9ddb ("tracing: Fix trace_printk() to print
+when not using bprintk()") which added "__used" to the trace_printk_fmt
+variable, and before that, the kernel simply optimized it out (no NULL value
+was saved).
+
+The fix is simply to handle the NULL pointer in lookup_format() and have the
+caller ignore the value if it was NULL.
+
+Link: http://lkml.kernel.org/r/1464769870-18344-1-git-send-email-zhengjun.xing@intel.com
+
+Reported-by: xingzhen <zhengjun.xing@intel.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Fixes: 3debb0a9ddb ("tracing: Fix trace_printk() to print when not using bprintk()")
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/trace_printk.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/kernel/trace/trace_printk.c
++++ b/kernel/trace/trace_printk.c
+@@ -36,6 +36,10 @@ struct trace_bprintk_fmt {
+ static inline struct trace_bprintk_fmt *lookup_format(const char *fmt)
+ {
+       struct trace_bprintk_fmt *pos;
++
++      if (!fmt)
++              return ERR_PTR(-EINVAL);
++
+       list_for_each_entry(pos, &trace_bprintk_fmt_list, list) {
+               if (!strcmp(pos->fmt, fmt))
+                       return pos;
+@@ -57,7 +61,8 @@ void hold_module_trace_bprintk_format(co
+       for (iter = start; iter < end; iter++) {
+               struct trace_bprintk_fmt *tb_fmt = lookup_format(*iter);
+               if (tb_fmt) {
+-                      *iter = tb_fmt->fmt;
++                      if (!IS_ERR(tb_fmt))
++                              *iter = tb_fmt->fmt;
+                       continue;
+               }