]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 30 Aug 2018 17:03:56 +0000 (10:03 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 30 Aug 2018 17:03:56 +0000 (10:03 -0700)
added patches:
arm64-dts-rockchip-corrected-uart1-clock-names-for-rk3328.patch
arm64-mm-check-for-upper-page_shift-bits-in-pfn_valid.patch
ext4-check-for-nul-characters-in-extended-attribute-s-name.patch
ext4-reset-error-code-in-ext4_find_entry-in-fallback.patch
ext4-sysfs-print-ext4_super_block-fields-as-little-endian.patch
iommu-arm-smmu-error-out-only-if-not-enough-context-interrupts.patch
kprobes-arm64-fix-p-uses-in-error-messages.patch
kvm-arm-arm64-skip-updating-pmd-entry-if-no-change.patch
kvm-arm-arm64-skip-updating-pte-entry-if-no-change.patch
printk-nmi-prevent-deadlock-when-accessing-the-main-log-buffer-in-nmi.patch
s390-kvm-fix-deadlock-when-killed-by-oom.patch
stop_machine-atomically-queue-and-wake-stopper-threads.patch
stop_machine-reflow-cpu_stop_queue_two_works.patch

14 files changed:
queue-4.14/arm64-dts-rockchip-corrected-uart1-clock-names-for-rk3328.patch [new file with mode: 0644]
queue-4.14/arm64-mm-check-for-upper-page_shift-bits-in-pfn_valid.patch [new file with mode: 0644]
queue-4.14/ext4-check-for-nul-characters-in-extended-attribute-s-name.patch [new file with mode: 0644]
queue-4.14/ext4-reset-error-code-in-ext4_find_entry-in-fallback.patch [new file with mode: 0644]
queue-4.14/ext4-sysfs-print-ext4_super_block-fields-as-little-endian.patch [new file with mode: 0644]
queue-4.14/iommu-arm-smmu-error-out-only-if-not-enough-context-interrupts.patch [new file with mode: 0644]
queue-4.14/kprobes-arm64-fix-p-uses-in-error-messages.patch [new file with mode: 0644]
queue-4.14/kvm-arm-arm64-skip-updating-pmd-entry-if-no-change.patch [new file with mode: 0644]
queue-4.14/kvm-arm-arm64-skip-updating-pte-entry-if-no-change.patch [new file with mode: 0644]
queue-4.14/printk-nmi-prevent-deadlock-when-accessing-the-main-log-buffer-in-nmi.patch [new file with mode: 0644]
queue-4.14/s390-kvm-fix-deadlock-when-killed-by-oom.patch [new file with mode: 0644]
queue-4.14/series
queue-4.14/stop_machine-atomically-queue-and-wake-stopper-threads.patch [new file with mode: 0644]
queue-4.14/stop_machine-reflow-cpu_stop_queue_two_works.patch [new file with mode: 0644]

diff --git a/queue-4.14/arm64-dts-rockchip-corrected-uart1-clock-names-for-rk3328.patch b/queue-4.14/arm64-dts-rockchip-corrected-uart1-clock-names-for-rk3328.patch
new file mode 100644 (file)
index 0000000..699e844
--- /dev/null
@@ -0,0 +1,32 @@
+From d0414fdd58eb51ffd6528280fd66705123663964 Mon Sep 17 00:00:00 2001
+From: Huibin Hong <huibin.hong@rock-chips.com>
+Date: Fri, 6 Jul 2018 16:03:57 +0800
+Subject: arm64: dts: rockchip: corrected uart1 clock-names for rk3328
+
+From: Huibin Hong <huibin.hong@rock-chips.com>
+
+commit d0414fdd58eb51ffd6528280fd66705123663964 upstream.
+
+Corrected the uart clock-names or the uart driver might fail.
+
+Fixes: 52e02d377a72 ("arm64: dts: rockchip: add core dtsi file for RK3328 SoCs")
+Cc: stable@vger.kernel.org
+Signed-off-by: Huibin Hong <huibin.hong@rock-chips.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/boot/dts/rockchip/rk3328.dtsi |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+@@ -331,7 +331,7 @@
+               reg = <0x0 0xff120000 0x0 0x100>;
+               interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+-              clock-names = "sclk_uart", "pclk_uart";
++              clock-names = "baudclk", "apb_pclk";
+               dmas = <&dmac 4>, <&dmac 5>;
+               #dma-cells = <2>;
+               pinctrl-names = "default";
diff --git a/queue-4.14/arm64-mm-check-for-upper-page_shift-bits-in-pfn_valid.patch b/queue-4.14/arm64-mm-check-for-upper-page_shift-bits-in-pfn_valid.patch
new file mode 100644 (file)
index 0000000..c4fe5b5
--- /dev/null
@@ -0,0 +1,59 @@
+From 5ad356eabc47d26a92140a0c4b20eba471c10de3 Mon Sep 17 00:00:00 2001
+From: Greg Hackmann <ghackmann@android.com>
+Date: Wed, 15 Aug 2018 12:51:21 -0700
+Subject: arm64: mm: check for upper PAGE_SHIFT bits in pfn_valid()
+
+From: Greg Hackmann <ghackmann@android.com>
+
+commit 5ad356eabc47d26a92140a0c4b20eba471c10de3 upstream.
+
+ARM64's pfn_valid() shifts away the upper PAGE_SHIFT bits of the input
+before seeing if the PFN is valid.  This leads to false positives when
+some of the upper bits are set, but the lower bits match a valid PFN.
+
+For example, the following userspace code looks up a bogus entry in
+/proc/kpageflags:
+
+    int pagemap = open("/proc/self/pagemap", O_RDONLY);
+    int pageflags = open("/proc/kpageflags", O_RDONLY);
+    uint64_t pfn, val;
+
+    lseek64(pagemap, [...], SEEK_SET);
+    read(pagemap, &pfn, sizeof(pfn));
+    if (pfn & (1UL << 63)) {        /* valid PFN */
+        pfn &= ((1UL << 55) - 1);   /* clear flag bits */
+        pfn |= (1UL << 55);
+        lseek64(pageflags, pfn * sizeof(uint64_t), SEEK_SET);
+        read(pageflags, &val, sizeof(val));
+    }
+
+On ARM64 this causes the userspace process to crash with SIGSEGV rather
+than reading (1 << KPF_NOPAGE).  kpageflags_read() treats the offset as
+valid, and stable_page_flags() will try to access an address between the
+user and kernel address ranges.
+
+Fixes: c1cc1552616d ("arm64: MMU initialisation")
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Hackmann <ghackmann@google.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/mm/init.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/mm/init.c
++++ b/arch/arm64/mm/init.c
+@@ -287,7 +287,11 @@ static void __init zone_sizes_init(unsig
+ #ifdef CONFIG_HAVE_ARCH_PFN_VALID
+ int pfn_valid(unsigned long pfn)
+ {
+-      return memblock_is_map_memory(pfn << PAGE_SHIFT);
++      phys_addr_t addr = pfn << PAGE_SHIFT;
++
++      if ((addr >> PAGE_SHIFT) != pfn)
++              return 0;
++      return memblock_is_map_memory(addr);
+ }
+ EXPORT_SYMBOL(pfn_valid);
+ #endif
diff --git a/queue-4.14/ext4-check-for-nul-characters-in-extended-attribute-s-name.patch b/queue-4.14/ext4-check-for-nul-characters-in-extended-attribute-s-name.patch
new file mode 100644 (file)
index 0000000..ee1f9ac
--- /dev/null
@@ -0,0 +1,38 @@
+From 7d95178c77014dbd8dce36ee40bbbc5e6c121ff5 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 1 Aug 2018 12:36:52 -0400
+Subject: ext4: check for NUL characters in extended attribute's name
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 7d95178c77014dbd8dce36ee40bbbc5e6c121ff5 upstream.
+
+Extended attribute names are defined to be NUL-terminated, so the name
+must not contain a NUL character.  This is important because there are
+places when remove extended attribute, the code uses strlen to
+determine the length of the entry.  That should probably be fixed at
+some point, but code is currently really messy, so the simplest fix
+for now is to simply validate that the extended attributes are sane.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=200401
+
+Reported-by: Wen Xu <wen.xu@gatech.edu>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/xattr.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -189,6 +189,8 @@ ext4_xattr_check_entries(struct ext4_xat
+               struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e);
+               if ((void *)next >= end)
+                       return -EFSCORRUPTED;
++              if (strnlen(e->e_name, e->e_name_len) != e->e_name_len)
++                      return -EFSCORRUPTED;
+               e = next;
+       }
diff --git a/queue-4.14/ext4-reset-error-code-in-ext4_find_entry-in-fallback.patch b/queue-4.14/ext4-reset-error-code-in-ext4_find_entry-in-fallback.patch
new file mode 100644 (file)
index 0000000..b2eef54
--- /dev/null
@@ -0,0 +1,37 @@
+From f39b3f45dbcb0343822cce31ea7636ad66e60bc2 Mon Sep 17 00:00:00 2001
+From: Eric Sandeen <sandeen@redhat.com>
+Date: Sun, 29 Jul 2018 17:13:42 -0400
+Subject: ext4: reset error code in ext4_find_entry in fallback
+
+From: Eric Sandeen <sandeen@redhat.com>
+
+commit f39b3f45dbcb0343822cce31ea7636ad66e60bc2 upstream.
+
+When ext4_find_entry() falls back to "searching the old fashioned
+way" due to a corrupt dx dir, it needs to reset the error code
+to NULL so that the nonstandard ERR_BAD_DX_DIR code isn't returned
+to userspace.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=199947
+
+Reported-by: Anatoly Trosinenko <anatoly.trosinenko@yandex.com>
+Reviewed-by: Andreas Dilger <adilger@dilger.ca>
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/namei.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -1397,6 +1397,7 @@ static struct buffer_head * ext4_find_en
+                       goto cleanup_and_exit;
+               dxtrace(printk(KERN_DEBUG "ext4_find_entry: dx failed, "
+                              "falling back\n"));
++              ret = NULL;
+       }
+       nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb);
+       if (!nblocks) {
diff --git a/queue-4.14/ext4-sysfs-print-ext4_super_block-fields-as-little-endian.patch b/queue-4.14/ext4-sysfs-print-ext4_super_block-fields-as-little-endian.patch
new file mode 100644 (file)
index 0000000..b7998e4
--- /dev/null
@@ -0,0 +1,59 @@
+From a4d2aadca184ece182418950d45ba4ffc7b652d2 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Sun, 29 Jul 2018 15:48:00 -0400
+Subject: ext4: sysfs: print ext4_super_block fields as little-endian
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit a4d2aadca184ece182418950d45ba4ffc7b652d2 upstream.
+
+While working on extended rand for last_error/first_error timestamps,
+I noticed that the endianess is wrong; we access the little-endian
+fields in struct ext4_super_block as native-endian when we print them.
+
+This adds a special case in ext4_attr_show() and ext4_attr_store()
+to byteswap the superblock fields if needed.
+
+In older kernels, this code was part of super.c, it got moved to
+sysfs.c in linux-4.4.
+
+Cc: stable@vger.kernel.org
+Fixes: 52c198c6820f ("ext4: add sysfs entry showing whether the fs contains errors")
+Reviewed-by: Andreas Dilger <adilger@dilger.ca>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/sysfs.c |   13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- a/fs/ext4/sysfs.c
++++ b/fs/ext4/sysfs.c
+@@ -278,8 +278,12 @@ static ssize_t ext4_attr_show(struct kob
+       case attr_pointer_ui:
+               if (!ptr)
+                       return 0;
+-              return snprintf(buf, PAGE_SIZE, "%u\n",
+-                              *((unsigned int *) ptr));
++              if (a->attr_ptr == ptr_ext4_super_block_offset)
++                      return snprintf(buf, PAGE_SIZE, "%u\n",
++                                      le32_to_cpup(ptr));
++              else
++                      return snprintf(buf, PAGE_SIZE, "%u\n",
++                                      *((unsigned int *) ptr));
+       case attr_pointer_atomic:
+               if (!ptr)
+                       return 0;
+@@ -312,7 +316,10 @@ static ssize_t ext4_attr_store(struct ko
+               ret = kstrtoul(skip_spaces(buf), 0, &t);
+               if (ret)
+                       return ret;
+-              *((unsigned int *) ptr) = t;
++              if (a->attr_ptr == ptr_ext4_super_block_offset)
++                      *((__le32 *) ptr) = cpu_to_le32(t);
++              else
++                      *((unsigned int *) ptr) = t;
+               return len;
+       case attr_inode_readahead:
+               return inode_readahead_blks_store(a, sbi, buf, len);
diff --git a/queue-4.14/iommu-arm-smmu-error-out-only-if-not-enough-context-interrupts.patch b/queue-4.14/iommu-arm-smmu-error-out-only-if-not-enough-context-interrupts.patch
new file mode 100644 (file)
index 0000000..639d2a2
--- /dev/null
@@ -0,0 +1,57 @@
+From d1e20222d5372e951bbb2fd3f6489ec4a6ea9b11 Mon Sep 17 00:00:00 2001
+From: Vivek Gautam <vivek.gautam@codeaurora.org>
+Date: Thu, 19 Jul 2018 23:23:56 +0530
+Subject: iommu/arm-smmu: Error out only if not enough context interrupts
+
+From: Vivek Gautam <vivek.gautam@codeaurora.org>
+
+commit d1e20222d5372e951bbb2fd3f6489ec4a6ea9b11 upstream.
+
+Currently we check if the number of context banks is not equal to
+num_context_interrupts. However, there are booloaders such as, one
+on sdm845 that reserves few context banks and thus kernel views
+less than the total available context banks.
+So, although the hardware definition in device tree would mention
+the correct number of context interrupts, this number can be
+greater than the number of context banks visible to smmu in kernel.
+We should therefore error out only when the number of context banks
+is greater than the available number of context interrupts.
+
+Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
+Suggested-by: Tomasz Figa <tfiga@chromium.org>
+Cc: Robin Murphy <robin.murphy@arm.com>
+Cc: Will Deacon <will.deacon@arm.com>
+[will: drop useless printk]
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Cc: Jitendra Bhivare <jitendra.bhivare@broadcom.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/arm-smmu.c |   16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/drivers/iommu/arm-smmu.c
++++ b/drivers/iommu/arm-smmu.c
+@@ -2100,12 +2100,16 @@ static int arm_smmu_device_probe(struct
+       if (err)
+               return err;
+-      if (smmu->version == ARM_SMMU_V2 &&
+-          smmu->num_context_banks != smmu->num_context_irqs) {
+-              dev_err(dev,
+-                      "found only %d context interrupt(s) but %d required\n",
+-                      smmu->num_context_irqs, smmu->num_context_banks);
+-              return -ENODEV;
++      if (smmu->version == ARM_SMMU_V2) {
++              if (smmu->num_context_banks > smmu->num_context_irqs) {
++                      dev_err(dev,
++                            "found only %d context irq(s) but %d required\n",
++                            smmu->num_context_irqs, smmu->num_context_banks);
++                      return -ENODEV;
++              }
++
++              /* Ignore superfluous interrupts */
++              smmu->num_context_irqs = smmu->num_context_banks;
+       }
+       for (i = 0; i < smmu->num_global_irqs; ++i) {
diff --git a/queue-4.14/kprobes-arm64-fix-p-uses-in-error-messages.patch b/queue-4.14/kprobes-arm64-fix-p-uses-in-error-messages.patch
new file mode 100644 (file)
index 0000000..81b404f
--- /dev/null
@@ -0,0 +1,52 @@
+From 0722867dcbc28cc9b269b57acd847c7c1aa638d6 Mon Sep 17 00:00:00 2001
+From: Masami Hiramatsu <mhiramat@kernel.org>
+Date: Sat, 28 Apr 2018 21:38:04 +0900
+Subject: kprobes/arm64: Fix %p uses in error messages
+
+From: Masami Hiramatsu <mhiramat@kernel.org>
+
+commit 0722867dcbc28cc9b269b57acd847c7c1aa638d6 upstream.
+
+Fix %p uses in error messages by removing it because
+those are redundant or meaningless.
+
+Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
+Acked-by: Will Deacon <will.deacon@arm.com>
+Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
+Cc: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: David Howells <dhowells@redhat.com>
+Cc: David S . Miller <davem@davemloft.net>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Jon Medhurst <tixy@linaro.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Thomas Richter <tmricht@linux.ibm.com>
+Cc: Tobin C . Harding <me@tobin.cc>
+Cc: acme@kernel.org
+Cc: akpm@linux-foundation.org
+Cc: brueckner@linux.vnet.ibm.com
+Cc: linux-arch@vger.kernel.org
+Cc: rostedt@goodmis.org
+Cc: schwidefsky@de.ibm.com
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/lkml/152491908405.9916.12425053035317241111.stgit@devbox
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/kernel/probes/kprobes.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/kernel/probes/kprobes.c
++++ b/arch/arm64/kernel/probes/kprobes.c
+@@ -275,7 +275,7 @@ static int __kprobes reenter_kprobe(stru
+               break;
+       case KPROBE_HIT_SS:
+       case KPROBE_REENTER:
+-              pr_warn("Unrecoverable kprobe detected at %p.\n", p->addr);
++              pr_warn("Unrecoverable kprobe detected.\n");
+               dump_kprobe(p);
+               BUG();
+               break;
diff --git a/queue-4.14/kvm-arm-arm64-skip-updating-pmd-entry-if-no-change.patch b/queue-4.14/kvm-arm-arm64-skip-updating-pmd-entry-if-no-change.patch
new file mode 100644 (file)
index 0000000..b30d857
--- /dev/null
@@ -0,0 +1,86 @@
+From 86658b819cd0a9aa584cd84453ed268a6f013770 Mon Sep 17 00:00:00 2001
+From: Punit Agrawal <punit.agrawal@arm.com>
+Date: Mon, 13 Aug 2018 11:43:50 +0100
+Subject: KVM: arm/arm64: Skip updating PMD entry if no change
+
+From: Punit Agrawal <punit.agrawal@arm.com>
+
+commit 86658b819cd0a9aa584cd84453ed268a6f013770 upstream.
+
+Contention on updating a PMD entry by a large number of vcpus can lead
+to duplicate work when handling stage 2 page faults. As the page table
+update follows the break-before-make requirement of the architecture,
+it can lead to repeated refaults due to clearing the entry and
+flushing the tlbs.
+
+This problem is more likely when -
+
+* there are large number of vcpus
+* the mapping is large block mapping
+
+such as when using PMD hugepages (512MB) with 64k pages.
+
+Fix this by skipping the page table update if there is no change in
+the entry being updated.
+
+Cc: stable@vger.kernel.org
+Fixes: ad361f093c1e ("KVM: ARM: Support hugetlbfs backed huge pages")
+Reviewed-by: Suzuki Poulose <suzuki.poulose@arm.com>
+Acked-by: Christoffer Dall <christoffer.dall@arm.com>
+Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ virt/kvm/arm/mmu.c |   38 +++++++++++++++++++++++++++-----------
+ 1 file changed, 27 insertions(+), 11 deletions(-)
+
+--- a/virt/kvm/arm/mmu.c
++++ b/virt/kvm/arm/mmu.c
+@@ -901,19 +901,35 @@ static int stage2_set_pmd_huge(struct kv
+       pmd = stage2_get_pmd(kvm, cache, addr);
+       VM_BUG_ON(!pmd);
+-      /*
+-       * Mapping in huge pages should only happen through a fault.  If a
+-       * page is merged into a transparent huge page, the individual
+-       * subpages of that huge page should be unmapped through MMU
+-       * notifiers before we get here.
+-       *
+-       * Merging of CompoundPages is not supported; they should become
+-       * splitting first, unmapped, merged, and mapped back in on-demand.
+-       */
+-      VM_BUG_ON(pmd_present(*pmd) && pmd_pfn(*pmd) != pmd_pfn(*new_pmd));
+-
+       old_pmd = *pmd;
+       if (pmd_present(old_pmd)) {
++              /*
++               * Multiple vcpus faulting on the same PMD entry, can
++               * lead to them sequentially updating the PMD with the
++               * same value. Following the break-before-make
++               * (pmd_clear() followed by tlb_flush()) process can
++               * hinder forward progress due to refaults generated
++               * on missing translations.
++               *
++               * Skip updating the page table if the entry is
++               * unchanged.
++               */
++              if (pmd_val(old_pmd) == pmd_val(*new_pmd))
++                      return 0;
++
++              /*
++               * Mapping in huge pages should only happen through a
++               * fault.  If a page is merged into a transparent huge
++               * page, the individual subpages of that huge page
++               * should be unmapped through MMU notifiers before we
++               * get here.
++               *
++               * Merging of CompoundPages is not supported; they
++               * should become splitting first, unmapped, merged,
++               * and mapped back in on-demand.
++               */
++              VM_BUG_ON(pmd_pfn(old_pmd) != pmd_pfn(*new_pmd));
++
+               pmd_clear(pmd);
+               kvm_tlb_flush_vmid_ipa(kvm, addr);
+       } else {
diff --git a/queue-4.14/kvm-arm-arm64-skip-updating-pte-entry-if-no-change.patch b/queue-4.14/kvm-arm-arm64-skip-updating-pte-entry-if-no-change.patch
new file mode 100644 (file)
index 0000000..14b30d7
--- /dev/null
@@ -0,0 +1,41 @@
+From 976d34e2dab10ece5ea8fe7090b7692913f89084 Mon Sep 17 00:00:00 2001
+From: Punit Agrawal <punit.agrawal@arm.com>
+Date: Mon, 13 Aug 2018 11:43:51 +0100
+Subject: KVM: arm/arm64: Skip updating PTE entry if no change
+
+From: Punit Agrawal <punit.agrawal@arm.com>
+
+commit 976d34e2dab10ece5ea8fe7090b7692913f89084 upstream.
+
+When there is contention on faulting in a particular page table entry
+at stage 2, the break-before-make requirement of the architecture can
+lead to additional refaulting due to TLB invalidation.
+
+Avoid this by skipping a page table update if the new value of the PTE
+matches the previous value.
+
+Cc: stable@vger.kernel.org
+Fixes: d5d8184d35c9 ("KVM: ARM: Memory virtualization setup")
+Reviewed-by: Suzuki Poulose <suzuki.poulose@arm.com>
+Acked-by: Christoffer Dall <christoffer.dall@arm.com>
+Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ virt/kvm/arm/mmu.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/virt/kvm/arm/mmu.c
++++ b/virt/kvm/arm/mmu.c
+@@ -985,6 +985,10 @@ static int stage2_set_pte(struct kvm *kv
+       /* Create 2nd stage page table mapping - Level 3 */
+       old_pte = *pte;
+       if (pte_present(old_pte)) {
++              /* Skip page table update if there is no change */
++              if (pte_val(old_pte) == pte_val(*new_pte))
++                      return 0;
++
+               kvm_set_pte(pte, __pte(0));
+               kvm_tlb_flush_vmid_ipa(kvm, addr);
+       } else {
diff --git a/queue-4.14/printk-nmi-prevent-deadlock-when-accessing-the-main-log-buffer-in-nmi.patch b/queue-4.14/printk-nmi-prevent-deadlock-when-accessing-the-main-log-buffer-in-nmi.patch
new file mode 100644 (file)
index 0000000..3518dfb
--- /dev/null
@@ -0,0 +1,232 @@
+From 03fc7f9c99c1e7ae2925d459e8487f1a6f199f79 Mon Sep 17 00:00:00 2001
+From: Petr Mladek <pmladek@suse.com>
+Date: Wed, 27 Jun 2018 16:20:28 +0200
+Subject: printk/nmi: Prevent deadlock when accessing the main log buffer in NMI
+
+From: Petr Mladek <pmladek@suse.com>
+
+commit 03fc7f9c99c1e7ae2925d459e8487f1a6f199f79 upstream.
+
+The commit 719f6a7040f1bdaf96 ("printk: Use the main logbuf in NMI
+when logbuf_lock is available") brought back the possible deadlocks
+in printk() and NMI.
+
+The check of logbuf_lock is done only in printk_nmi_enter() to prevent
+mixed output. But another CPU might take the lock later, enter NMI, and:
+
+      + Both NMIs might be serialized by yet another lock, for example,
+       the one in nmi_cpu_backtrace().
+
+      + The other CPU might get stopped in NMI, see smp_send_stop()
+       in panic().
+
+The only safe solution is to use trylock when storing the message
+into the main log-buffer. It might cause reordering when some lines
+go to the main lock buffer directly and others are delayed via
+the per-CPU buffer. It means that it is not useful in general.
+
+This patch replaces the problematic NMI deferred context with NMI
+direct context. It can be used to mark a code that might produce
+many messages in NMI and the risk of losing them is more critical
+than problems with eventual reordering.
+
+The context is then used when dumping trace buffers on oops. It was
+the primary motivation for the original fix. Also the reordering is
+even smaller issue there because some traces have their own time stamps.
+
+Finally, nmi_cpu_backtrace() need not longer be serialized because
+it will always us the per-CPU buffers again.
+
+Fixes: 719f6a7040f1bdaf96 ("printk: Use the main logbuf in NMI when logbuf_lock is available")
+Cc: stable@vger.kernel.org
+Link: http://lkml.kernel.org/r/20180627142028.11259-1-pmladek@suse.com
+To: Steven Rostedt <rostedt@goodmis.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
+Cc: linux-kernel@vger.kernel.org
+Cc: stable@vger.kernel.org
+Acked-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/printk.h      |    4 +++
+ kernel/printk/internal.h    |    9 ++++++
+ kernel/printk/printk_safe.c |   58 ++++++++++++++++++++++++++++----------------
+ kernel/trace/trace.c        |    4 ++-
+ lib/nmi_backtrace.c         |    3 --
+ 5 files changed, 52 insertions(+), 26 deletions(-)
+
+--- a/include/linux/printk.h
++++ b/include/linux/printk.h
+@@ -150,9 +150,13 @@ void early_printk(const char *s, ...) {
+ #ifdef CONFIG_PRINTK_NMI
+ extern void printk_nmi_enter(void);
+ extern void printk_nmi_exit(void);
++extern void printk_nmi_direct_enter(void);
++extern void printk_nmi_direct_exit(void);
+ #else
+ static inline void printk_nmi_enter(void) { }
+ static inline void printk_nmi_exit(void) { }
++static inline void printk_nmi_direct_enter(void) { }
++static inline void printk_nmi_direct_exit(void) { }
+ #endif /* PRINTK_NMI */
+ #ifdef CONFIG_PRINTK
+--- a/kernel/printk/internal.h
++++ b/kernel/printk/internal.h
+@@ -19,11 +19,16 @@
+ #ifdef CONFIG_PRINTK
+ #define PRINTK_SAFE_CONTEXT_MASK       0x3fffffff
+-#define PRINTK_NMI_DEFERRED_CONTEXT_MASK 0x40000000
++#define PRINTK_NMI_DIRECT_CONTEXT_MASK         0x40000000
+ #define PRINTK_NMI_CONTEXT_MASK                0x80000000
+ extern raw_spinlock_t logbuf_lock;
++__printf(5, 0)
++int vprintk_store(int facility, int level,
++                const char *dict, size_t dictlen,
++                const char *fmt, va_list args);
++
+ __printf(1, 0) int vprintk_default(const char *fmt, va_list args);
+ __printf(1, 0) int vprintk_deferred(const char *fmt, va_list args);
+ __printf(1, 0) int vprintk_func(const char *fmt, va_list args);
+@@ -54,6 +59,8 @@ void __printk_safe_exit(void);
+               local_irq_enable();             \
+       } while (0)
++void defer_console_output(void);
++
+ #else
+ __printf(1, 0) int vprintk_func(const char *fmt, va_list args) { return 0; }
+--- a/kernel/printk/printk_safe.c
++++ b/kernel/printk/printk_safe.c
+@@ -311,24 +311,33 @@ static __printf(1, 0) int vprintk_nmi(co
+ void printk_nmi_enter(void)
+ {
+-      /*
+-       * The size of the extra per-CPU buffer is limited. Use it only when
+-       * the main one is locked. If this CPU is not in the safe context,
+-       * the lock must be taken on another CPU and we could wait for it.
+-       */
+-      if ((this_cpu_read(printk_context) & PRINTK_SAFE_CONTEXT_MASK) &&
+-          raw_spin_is_locked(&logbuf_lock)) {
+-              this_cpu_or(printk_context, PRINTK_NMI_CONTEXT_MASK);
+-      } else {
+-              this_cpu_or(printk_context, PRINTK_NMI_DEFERRED_CONTEXT_MASK);
+-      }
++      this_cpu_or(printk_context, PRINTK_NMI_CONTEXT_MASK);
+ }
+ void printk_nmi_exit(void)
+ {
+-      this_cpu_and(printk_context,
+-                   ~(PRINTK_NMI_CONTEXT_MASK |
+-                     PRINTK_NMI_DEFERRED_CONTEXT_MASK));
++      this_cpu_and(printk_context, ~PRINTK_NMI_CONTEXT_MASK);
++}
++
++/*
++ * Marks a code that might produce many messages in NMI context
++ * and the risk of losing them is more critical than eventual
++ * reordering.
++ *
++ * It has effect only when called in NMI context. Then printk()
++ * will try to store the messages into the main logbuf directly
++ * and use the per-CPU buffers only as a fallback when the lock
++ * is not available.
++ */
++void printk_nmi_direct_enter(void)
++{
++      if (this_cpu_read(printk_context) & PRINTK_NMI_CONTEXT_MASK)
++              this_cpu_or(printk_context, PRINTK_NMI_DIRECT_CONTEXT_MASK);
++}
++
++void printk_nmi_direct_exit(void)
++{
++      this_cpu_and(printk_context, ~PRINTK_NMI_DIRECT_CONTEXT_MASK);
+ }
+ #else
+@@ -366,6 +375,20 @@ void __printk_safe_exit(void)
+ __printf(1, 0) int vprintk_func(const char *fmt, va_list args)
+ {
++      /*
++       * Try to use the main logbuf even in NMI. But avoid calling console
++       * drivers that might have their own locks.
++       */
++      if ((this_cpu_read(printk_context) & PRINTK_NMI_DIRECT_CONTEXT_MASK) &&
++          raw_spin_trylock(&logbuf_lock)) {
++              int len;
++
++              len = vprintk_store(0, LOGLEVEL_DEFAULT, NULL, 0, fmt, args);
++              raw_spin_unlock(&logbuf_lock);
++              defer_console_output();
++              return len;
++      }
++
+       /* Use extra buffer in NMI when logbuf_lock is taken or in safe mode. */
+       if (this_cpu_read(printk_context) & PRINTK_NMI_CONTEXT_MASK)
+               return vprintk_nmi(fmt, args);
+@@ -374,13 +397,6 @@ __printf(1, 0) int vprintk_func(const ch
+       if (this_cpu_read(printk_context) & PRINTK_SAFE_CONTEXT_MASK)
+               return vprintk_safe(fmt, args);
+-      /*
+-       * Use the main logbuf when logbuf_lock is available in NMI.
+-       * But avoid calling console drivers that might have their own locks.
+-       */
+-      if (this_cpu_read(printk_context) & PRINTK_NMI_DEFERRED_CONTEXT_MASK)
+-              return vprintk_deferred(fmt, args);
+-
+       /* No obstacles. */
+       return vprintk_default(fmt, args);
+ }
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -8187,6 +8187,7 @@ void ftrace_dump(enum ftrace_dump_mode o
+       tracing_off();
+       local_irq_save(flags);
++      printk_nmi_direct_enter();
+       /* Simulate the iterator */
+       trace_init_global_iter(&iter);
+@@ -8266,7 +8267,8 @@ void ftrace_dump(enum ftrace_dump_mode o
+       for_each_tracing_cpu(cpu) {
+               atomic_dec(&per_cpu_ptr(iter.trace_buffer->data, cpu)->disabled);
+       }
+-      atomic_dec(&dump_running);
++      atomic_dec(&dump_running);
++      printk_nmi_direct_exit();
+       local_irq_restore(flags);
+ }
+ EXPORT_SYMBOL_GPL(ftrace_dump);
+--- a/lib/nmi_backtrace.c
++++ b/lib/nmi_backtrace.c
+@@ -87,11 +87,9 @@ void nmi_trigger_cpumask_backtrace(const
+ bool nmi_cpu_backtrace(struct pt_regs *regs)
+ {
+-      static arch_spinlock_t lock = __ARCH_SPIN_LOCK_UNLOCKED;
+       int cpu = smp_processor_id();
+       if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) {
+-              arch_spin_lock(&lock);
+               if (regs && cpu_in_idle(instruction_pointer(regs))) {
+                       pr_warn("NMI backtrace for cpu %d skipped: idling at pc %#lx\n",
+                               cpu, instruction_pointer(regs));
+@@ -102,7 +100,6 @@ bool nmi_cpu_backtrace(struct pt_regs *r
+                       else
+                               dump_stack();
+               }
+-              arch_spin_unlock(&lock);
+               cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
+               return true;
+       }
diff --git a/queue-4.14/s390-kvm-fix-deadlock-when-killed-by-oom.patch b/queue-4.14/s390-kvm-fix-deadlock-when-killed-by-oom.patch
new file mode 100644 (file)
index 0000000..9bb0088
--- /dev/null
@@ -0,0 +1,40 @@
+From 306d6c49ac9ded11114cb53b0925da52f2c2ada1 Mon Sep 17 00:00:00 2001
+From: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
+Date: Mon, 16 Jul 2018 10:38:57 +0200
+Subject: s390/kvm: fix deadlock when killed by oom
+
+From: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
+
+commit 306d6c49ac9ded11114cb53b0925da52f2c2ada1 upstream.
+
+When the oom killer kills a userspace process in the page fault handler
+while in guest context, the fault handler fails to release the mm_sem
+if the FAULT_FLAG_RETRY_NOWAIT option is set. This leads to a deadlock
+when tearing down the mm when the process terminates. This bug can only
+happen when pfault is enabled, so only KVM clients are affected.
+
+The problem arises in the rare cases in which handle_mm_fault does not
+release the mm_sem. This patch fixes the issue by manually releasing
+the mm_sem when needed.
+
+Fixes: 24eb3a824c4f3 ("KVM: s390: Add FAULT_FLAG_RETRY_NOWAIT for guest fault")
+Cc: <stable@vger.kernel.org> # 3.15+
+Signed-off-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/mm/fault.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/s390/mm/fault.c
++++ b/arch/s390/mm/fault.c
+@@ -486,6 +486,8 @@ retry:
+       /* No reason to continue if interrupted by SIGKILL. */
+       if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) {
+               fault = VM_FAULT_SIGNAL;
++              if (flags & FAULT_FLAG_RETRY_NOWAIT)
++                      goto out_up;
+               goto out;
+       }
+       if (unlikely(fault & VM_FAULT_ERROR))
index e2a4dd4e8ee58077d8c9f04ffb2ec3a23e620cc4..27559239615efc7b4844191bd30352f2d67d3c9e 100644 (file)
@@ -90,3 +90,16 @@ smb3-fill-in-statfs-fsid-and-correct-namelen.patch
 btrfs-use-correct-compare-function-of-dirty_metadata_bytes.patch
 btrfs-don-t-leak-ret-from-do_chunk_alloc.patch
 btrfs-fix-btrfs_write_inode-vs-delayed-iput-deadlock.patch
+iommu-arm-smmu-error-out-only-if-not-enough-context-interrupts.patch
+printk-nmi-prevent-deadlock-when-accessing-the-main-log-buffer-in-nmi.patch
+kprobes-arm64-fix-p-uses-in-error-messages.patch
+arm64-mm-check-for-upper-page_shift-bits-in-pfn_valid.patch
+arm64-dts-rockchip-corrected-uart1-clock-names-for-rk3328.patch
+kvm-arm-arm64-skip-updating-pmd-entry-if-no-change.patch
+kvm-arm-arm64-skip-updating-pte-entry-if-no-change.patch
+s390-kvm-fix-deadlock-when-killed-by-oom.patch
+stop_machine-reflow-cpu_stop_queue_two_works.patch
+stop_machine-atomically-queue-and-wake-stopper-threads.patch
+ext4-check-for-nul-characters-in-extended-attribute-s-name.patch
+ext4-sysfs-print-ext4_super_block-fields-as-little-endian.patch
+ext4-reset-error-code-in-ext4_find_entry-in-fallback.patch
diff --git a/queue-4.14/stop_machine-atomically-queue-and-wake-stopper-threads.patch b/queue-4.14/stop_machine-atomically-queue-and-wake-stopper-threads.patch
new file mode 100644 (file)
index 0000000..97690f0
--- /dev/null
@@ -0,0 +1,97 @@
+From cfd355145c32bb7ccb65fccbe2d67280dc2119e1 Mon Sep 17 00:00:00 2001
+From: Prasad Sodagudi <psodagud@codeaurora.org>
+Date: Fri, 3 Aug 2018 13:56:06 -0700
+Subject: stop_machine: Atomically queue and wake stopper threads
+
+From: Prasad Sodagudi <psodagud@codeaurora.org>
+
+commit cfd355145c32bb7ccb65fccbe2d67280dc2119e1 upstream.
+
+When cpu_stop_queue_work() releases the lock for the stopper
+thread that was queued into its wake queue, preemption is
+enabled, which leads to the following deadlock:
+
+CPU0                              CPU1
+sched_setaffinity(0, ...)
+__set_cpus_allowed_ptr()
+stop_one_cpu(0, ...)              stop_two_cpus(0, 1, ...)
+cpu_stop_queue_work(0, ...)       cpu_stop_queue_two_works(0, ..., 1, ...)
+
+-grabs lock for migration/0-
+                                  -spins with preemption disabled,
+                                   waiting for migration/0's lock to be
+                                   released-
+
+-adds work items for migration/0
+and queues migration/0 to its
+wake_q-
+
+-releases lock for migration/0
+ and preemption is enabled-
+
+-current thread is preempted,
+and __set_cpus_allowed_ptr
+has changed the thread's
+cpu allowed mask to CPU1 only-
+
+                                  -acquires migration/0 and migration/1's
+                                   locks-
+
+                                  -adds work for migration/0 but does not
+                                   add migration/0 to wake_q, since it is
+                                   already in a wake_q-
+
+                                  -adds work for migration/1 and adds
+                                   migration/1 to its wake_q-
+
+                                  -releases migration/0 and migration/1's
+                                   locks, wakes migration/1, and enables
+                                   preemption-
+
+                                  -since migration/1 is requested to run,
+                                   migration/1 begins to run and waits on
+                                   migration/0, but migration/0 will never
+                                   be able to run, since the thread that
+                                   can wake it is affine to CPU1-
+
+Disable preemption in cpu_stop_queue_work() before queueing works for
+stopper threads, and queueing the stopper thread in the wake queue, to
+ensure that the operation of queueing the works and waking the stopper
+threads is atomic.
+
+Fixes: 0b26351b910f ("stop_machine, sched: Fix migrate_swap() vs. active_balance() deadlock")
+Signed-off-by: Prasad Sodagudi <psodagud@codeaurora.org>
+Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: peterz@infradead.org
+Cc: matt@codeblueprint.co.uk
+Cc: bigeasy@linutronix.de
+Cc: gregkh@linuxfoundation.org
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/1533329766-4856-1-git-send-email-isaacm@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+Co-Developed-by: Isaac J. Manjarres <isaacm@codeaurora.org>
+
+---
+ kernel/stop_machine.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/kernel/stop_machine.c
++++ b/kernel/stop_machine.c
+@@ -81,6 +81,7 @@ static bool cpu_stop_queue_work(unsigned
+       unsigned long flags;
+       bool enabled;
++      preempt_disable();
+       raw_spin_lock_irqsave(&stopper->lock, flags);
+       enabled = stopper->enabled;
+       if (enabled)
+@@ -90,6 +91,7 @@ static bool cpu_stop_queue_work(unsigned
+       raw_spin_unlock_irqrestore(&stopper->lock, flags);
+       wake_up_q(&wakeq);
++      preempt_enable();
+       return enabled;
+ }
diff --git a/queue-4.14/stop_machine-reflow-cpu_stop_queue_two_works.patch b/queue-4.14/stop_machine-reflow-cpu_stop_queue_two_works.patch
new file mode 100644 (file)
index 0000000..4b8a1b2
--- /dev/null
@@ -0,0 +1,110 @@
+From b80a2bfce85e1051056d98d04ecb2d0b55cbbc1c Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Mon, 30 Jul 2018 13:21:40 +0200
+Subject: stop_machine: Reflow cpu_stop_queue_two_works()
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+commit b80a2bfce85e1051056d98d04ecb2d0b55cbbc1c upstream.
+
+The code flow in cpu_stop_queue_two_works() is a little arcane; fix this by
+lifting the preempt_disable() to the top to create more natural nesting wrt
+the spinlocks and make the wake_up_q() and preempt_enable() unconditional
+at the end.
+
+Furthermore, enable preemption in the -EDEADLK case, such that we spin-wait
+with preemption enabled.
+
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Cc: isaacm@codeaurora.org
+Cc: matt@codeblueprint.co.uk
+Cc: psodagud@codeaurora.org
+Cc: gregkh@linuxfoundation.org
+Cc: pkondeti@codeaurora.org
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20180730112140.GH2494@hirez.programming.kicks-ass.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/stop_machine.c |   41 +++++++++++++++++++++++------------------
+ 1 file changed, 23 insertions(+), 18 deletions(-)
+
+--- a/kernel/stop_machine.c
++++ b/kernel/stop_machine.c
+@@ -236,13 +236,24 @@ static int cpu_stop_queue_two_works(int
+       struct cpu_stopper *stopper2 = per_cpu_ptr(&cpu_stopper, cpu2);
+       DEFINE_WAKE_Q(wakeq);
+       int err;
++
+ retry:
++      /*
++       * The waking up of stopper threads has to happen in the same
++       * scheduling context as the queueing.  Otherwise, there is a
++       * possibility of one of the above stoppers being woken up by another
++       * CPU, and preempting us. This will cause us to not wake up the other
++       * stopper forever.
++       */
++      preempt_disable();
+       raw_spin_lock_irq(&stopper1->lock);
+       raw_spin_lock_nested(&stopper2->lock, SINGLE_DEPTH_NESTING);
+-      err = -ENOENT;
+-      if (!stopper1->enabled || !stopper2->enabled)
++      if (!stopper1->enabled || !stopper2->enabled) {
++              err = -ENOENT;
+               goto unlock;
++      }
++
+       /*
+        * Ensure that if we race with __stop_cpus() the stoppers won't get
+        * queued up in reverse order leading to system deadlock.
+@@ -253,36 +264,30 @@ retry:
+        * It can be falsely true but it is safe to spin until it is cleared,
+        * queue_stop_cpus_work() does everything under preempt_disable().
+        */
+-      err = -EDEADLK;
+-      if (unlikely(stop_cpus_in_progress))
+-                      goto unlock;
++      if (unlikely(stop_cpus_in_progress)) {
++              err = -EDEADLK;
++              goto unlock;
++      }
+       err = 0;
+       __cpu_stop_queue_work(stopper1, work1, &wakeq);
+       __cpu_stop_queue_work(stopper2, work2, &wakeq);
+-      /*
+-       * The waking up of stopper threads has to happen
+-       * in the same scheduling context as the queueing.
+-       * Otherwise, there is a possibility of one of the
+-       * above stoppers being woken up by another CPU,
+-       * and preempting us. This will cause us to n ot
+-       * wake up the other stopper forever.
+-       */
+-      preempt_disable();
++
+ unlock:
+       raw_spin_unlock(&stopper2->lock);
+       raw_spin_unlock_irq(&stopper1->lock);
+       if (unlikely(err == -EDEADLK)) {
++              preempt_enable();
++
+               while (stop_cpus_in_progress)
+                       cpu_relax();
++
+               goto retry;
+       }
+-      if (!err) {
+-              wake_up_q(&wakeq);
+-              preempt_enable();
+-      }
++      wake_up_q(&wakeq);
++      preempt_enable();
+       return err;
+ }