diff --git a/Makefile b/Makefile
index 705eb9e38fce..b57ec79b4941 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 4
-SUBLEVEL = 36
+SUBLEVEL = 37
 EXTRAVERSION =
 NAME = Blurry Fish Butt
 
diff --git a/arch/arc/include/asm/delay.h b/arch/arc/include/asm/delay.h
index 08e7e2a16ac1..a36e8601114d 100644
--- a/arch/arc/include/asm/delay.h
+++ b/arch/arc/include/asm/delay.h
@@ -22,10 +22,11 @@
 static inline void __delay(unsigned long loops)
 {
        __asm__ __volatile__(
-       "       lp  1f  \n"
-       "       nop     \n"
-       "1:             \n"
-       : "+l"(loops));
+       "       mov lp_count, %0        \n"
+       "       lp  1f                  \n"
+       "       nop                     \n"
+       "1:                             \n"
+       : : "r"(loops));
 }
 
 extern void __bad_udelay(void);
diff --git a/arch/arm64/include/asm/cpufeature.h 
b/arch/arm64/include/asm/cpufeature.h
index 8136afc9df0d..8884b5d5f48c 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -77,7 +77,7 @@ struct arm64_cpu_capabilities {
        const char *desc;
        u16 capability;
        bool (*matches)(const struct arm64_cpu_capabilities *);
-       void (*enable)(void *);         /* Called on all active CPUs */
+       int (*enable)(void *);          /* Called on all active CPUs */
        union {
                struct {        /* To be used for erratum handling only */
                        u32 midr_model;
diff --git a/arch/arm64/include/asm/processor.h 
b/arch/arm64/include/asm/processor.h
index 4acb7ca94fcd..d08559528927 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -186,6 +186,6 @@ static inline void spin_lock_prefetch(const void *x)
 
 #endif
 
-void cpu_enable_pan(void *__unused);
+int cpu_enable_pan(void *__unused);
 
 #endif /* __ASM_PROCESSOR_H */
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 0669c63281ea..2735bf814592 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -19,7 +19,9 @@
 #define pr_fmt(fmt) "CPU features: " fmt
 
 #include <linux/bsearch.h>
+#include <linux/cpumask.h>
 #include <linux/sort.h>
+#include <linux/stop_machine.h>
 #include <linux/types.h>
 #include <asm/cpu.h>
 #include <asm/cpufeature.h>
@@ -764,7 +766,13 @@ static void enable_cpu_capabilities(const struct 
arm64_cpu_capabilities *caps)
 
        for (i = 0; caps[i].desc; i++)
                if (caps[i].enable && cpus_have_cap(caps[i].capability))
-                       on_each_cpu(caps[i].enable, NULL, true);
+                       /*
+                        * Use stop_machine() as it schedules the work allowing
+                        * us to modify PSTATE, instead of on_each_cpu() which
+                        * uses an IPI, giving us a PSTATE that disappears when
+                        * we return.
+                        */
+                       stop_machine(caps[i].enable, NULL, cpu_online_mask);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index 1095aa483a1c..00c1372bf57b 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -1,7 +1,9 @@
 #include <linux/ftrace.h>
 #include <linux/percpu.h>
 #include <linux/slab.h>
+#include <asm/alternative.h>
 #include <asm/cacheflush.h>
+#include <asm/cpufeature.h>
 #include <asm/debug-monitors.h>
 #include <asm/pgtable.h>
 #include <asm/memory.h>
@@ -111,6 +113,13 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned 
long))
                set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
 
                /*
+                * PSTATE was not saved over suspend/resume, re-enable any
+                * detected features that might not have been set correctly.
+                */
+               asm(ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN,
+                               CONFIG_ARM64_PAN));
+
+               /*
                 * Restore HW breakpoint registers to sane values
                 * before debug exceptions are possibly reenabled
                 * through local_dbg_restore.
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 4c1a118c1d09..247bae758e1e 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -29,7 +29,9 @@
 #include <linux/sched.h>
 #include <linux/highmem.h>
 #include <linux/perf_event.h>
+#include <linux/preempt.h>
 
+#include <asm/bug.h>
 #include <asm/cpufeature.h>
 #include <asm/exception.h>
 #include <asm/debug-monitors.h>
@@ -606,8 +608,16 @@ asmlinkage int __exception do_debug_exception(unsigned 
long addr,
 }
 
 #ifdef CONFIG_ARM64_PAN
-void cpu_enable_pan(void *__unused)
+int cpu_enable_pan(void *__unused)
 {
+       /*
+        * We modify PSTATE. This won't work from irq context as the PSTATE
+        * is discarded once we return from the exception.
+        */
+       WARN_ON_ONCE(in_interrupt());
+
        config_sctlr_el1(SCTLR_EL1_SPAN, 0);
+       asm(SET_PSTATE_PAN(1));
+       return 0;
 }
 #endif /* CONFIG_ARM64_PAN */
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 6bc9ae24b6d2..8f1a3f443f7d 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -571,7 +571,7 @@ early_idt_handler_common:
        movl %eax,%ds
        movl %eax,%es
 
-       cmpl $(__KERNEL_CS),32(%esp)
+       cmpw $(__KERNEL_CS),32(%esp)
        jne 10f
 
        leal 28(%esp),%eax      # Pointer to %eip
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 370c2f76016d..1770c455dfdd 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -1368,7 +1368,8 @@ static ssize_t hot_remove_store(struct class *class,
        zram = idr_find(&zram_index_idr, dev_id);
        if (zram) {
                ret = zram_remove(zram);
-               idr_remove(&zram_index_idr, dev_id);
+               if (!ret)
+                       idr_remove(&zram_index_idr, dev_id);
        } else {
                ret = -ENODEV;
        }
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c 
b/drivers/net/wireless/mwifiex/cfg80211.c
index 4073116e6e9f..c3331d6201c3 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2144,8 +2144,9 @@ done:
                        is_scanning_required = 1;
                } else {
                        mwifiex_dbg(priv->adapter, MSG,
-                                   "info: trying to associate to '%s' bssid 
%pM\n",
-                                   (char *)req_ssid.ssid, bss->bssid);
+                                   "info: trying to associate to '%.*s' bssid 
%pM\n",
+                                   req_ssid.ssid_len, (char *)req_ssid.ssid,
+                                   bss->bssid);
                        memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN);
                        break;
                }
@@ -2202,8 +2203,8 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct 
net_device *dev,
        }
 
        mwifiex_dbg(adapter, INFO,
-                   "info: Trying to associate to %s and bssid %pM\n",
-                   (char *)sme->ssid, sme->bssid);
+                   "info: Trying to associate to %.*s and bssid %pM\n",
+                   (int)sme->ssid_len, (char *)sme->ssid, sme->bssid);
 
        ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
                                     priv->bss_mode, sme->channel, sme, 0);
@@ -2333,8 +2334,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct 
net_device *dev,
        }
 
        mwifiex_dbg(priv->adapter, MSG,
-                   "info: trying to join to %s and bssid %pM\n",
-                   (char *)params->ssid, params->bssid);
+                   "info: trying to join to %.*s and bssid %pM\n",
+                   params->ssid_len, (char *)params->ssid, params->bssid);
 
        mwifiex_set_ibss_params(priv, params);
 
diff --git a/drivers/pci/pcie/aer/aer_inject.c 
b/drivers/pci/pcie/aer/aer_inject.c
index 182224acedbe..58f1419a68ae 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -283,20 +283,6 @@ out:
        return 0;
 }
 
-static struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
-{
-       while (1) {
-               if (!pci_is_pcie(dev))
-                       break;
-               if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
-                       return dev;
-               if (!dev->bus->self)
-                       break;
-               dev = dev->bus->self;
-       }
-       return NULL;
-}
-
 static int find_aer_device_iter(struct device *device, void *data)
 {
        struct pcie_device **result = data;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 9757cf9037a2..b5843c255263 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1415,6 +1415,21 @@ static void program_hpp_type1(struct pci_dev *dev, 
struct hpp_type1 *hpp)
                dev_warn(&dev->dev, "PCI-X settings not supported\n");
 }
 
+static bool pcie_root_rcb_set(struct pci_dev *dev)
+{
+       struct pci_dev *rp = pcie_find_root_port(dev);
+       u16 lnkctl;
+
+       if (!rp)
+               return false;
+
+       pcie_capability_read_word(rp, PCI_EXP_LNKCTL, &lnkctl);
+       if (lnkctl & PCI_EXP_LNKCTL_RCB)
+               return true;
+
+       return false;
+}
+
 static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
 {
        int pos;
@@ -1444,9 +1459,20 @@ static void program_hpp_type2(struct pci_dev *dev, 
struct hpp_type2 *hpp)
                        ~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or);
 
        /* Initialize Link Control Register */
-       if (pcie_cap_has_lnkctl(dev))
+       if (pcie_cap_has_lnkctl(dev)) {
+
+               /*
+                * If the Root Port supports Read Completion Boundary of
+                * 128, set RCB to 128.  Otherwise, clear it.
+                */
+               hpp->pci_exp_lnkctl_and |= PCI_EXP_LNKCTL_RCB;
+               hpp->pci_exp_lnkctl_or &= ~PCI_EXP_LNKCTL_RCB;
+               if (pcie_root_rcb_set(dev))
+                       hpp->pci_exp_lnkctl_or |= PCI_EXP_LNKCTL_RCB;
+
                pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
                        ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or);
+       }
 
        /* Find Advanced Error Reporting Enhanced Capability */
        pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
index c20163b92991..375008e2be20 100644
--- a/drivers/pwm/sysfs.c
+++ b/drivers/pwm/sysfs.c
@@ -366,6 +366,8 @@ void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
                if (test_bit(PWMF_EXPORTED, &pwm->flags))
                        pwm_unexport_child(parent, pwm);
        }
+
+       put_device(parent);
 }
 
 static int __init pwm_sysfs_init(void)
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index eeae401a2412..287e698c28de 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -251,7 +251,9 @@
 #endif
 #endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
 
-#if GCC_VERSION >= 50000
+#if GCC_VERSION >= 70000
+#define KASAN_ABI_VERSION 5
+#elif GCC_VERSION >= 50000
 #define KASAN_ABI_VERSION 4
 #elif GCC_VERSION >= 40902
 #define KASAN_ABI_VERSION 3
diff --git a/include/linux/pci.h b/include/linux/pci.h
index e89c7ee7e803..5f37614f2451 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1802,6 +1802,20 @@ static inline int pci_pcie_type(const struct pci_dev 
*dev)
        return (pcie_caps_reg(dev) & PCI_EXP_FLAGS_TYPE) >> 4;
 }
 
+static inline struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
+{
+       while (1) {
+               if (!pci_is_pcie(dev))
+                       break;
+               if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
+                       return dev;
+               if (!dev->bus->self)
+                       break;
+               dev = dev->bus->self;
+       }
+       return NULL;
+}
+
 void pci_request_acs(void);
 bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags);
 bool pci_acs_path_enabled(struct pci_dev *start,
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 630c19772630..32cbe72bf545 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -2275,6 +2275,7 @@ static int rcu_nocb_kthread(void *arg)
                                cl++;
                        c++;
                        local_bh_enable();
+                       cond_resched_rcu_qs();
                        list = next;
                }
                trace_rcu_batch_end(rdp->rsp->name, c, !!list, 0, 0, 1);
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index 4f6c62e5c21e..37ff0ab6a8ff 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -52,6 +52,9 @@ struct kasan_global {
 #if KASAN_ABI_VERSION >= 4
        struct kasan_source_location *location;
 #endif
+#if KASAN_ABI_VERSION >= 5
+       char *odr_indicator;
+#endif
 };
 
 static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 3a9b66c6e09c..0aca39762ed0 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1886,8 +1886,8 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream 
*substream)
                snd_timer_interrupt(substream->timer, 1);
 #endif
  _end:
-       snd_pcm_stream_unlock_irqrestore(substream, flags);
        kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
+       snd_pcm_stream_unlock_irqrestore(substream, flags);
 }
 
 EXPORT_SYMBOL(snd_pcm_period_elapsed);

Reply via email to