commit:     3e05893dec2e2a2d507e8c22fff90e5a5abe452c
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Wed Feb 10 10:07:15 2021 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Wed Feb 10 10:07:27 2021 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=3e05893d

Linux patch 4.14.221

Signed-off-by: Alice Ferrazzi <alicef <AT> gentoo.org>

 0000_README               |   4 +
 1220_linux-4.14.221.patch | 972 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 976 insertions(+)

diff --git a/0000_README b/0000_README
index c5aa598..a3da73a 100644
--- a/0000_README
+++ b/0000_README
@@ -923,6 +923,10 @@ Patch:  1219_linux-4.14.220.patch
 From:   https://www.kernel.org
 Desc:   Linux 4.14.220
 
+Patch:  1220_linux-4.14.221.patch
+From:   https://www.kernel.org
+Desc:   Linux 4.14.221
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1220_linux-4.14.221.patch b/1220_linux-4.14.221.patch
new file mode 100644
index 0000000..45f0d80
--- /dev/null
+++ b/1220_linux-4.14.221.patch
@@ -0,0 +1,972 @@
+diff --git a/Makefile b/Makefile
+index 088dc5383dcf2..b25ce26c1cd71 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 4
+ PATCHLEVEL = 14
+-SUBLEVEL = 220
++SUBLEVEL = 221
+ EXTRAVERSION =
+ NAME = Petit Gorille
+ 
+@@ -844,12 +844,6 @@ KBUILD_CFLAGS   += $(call 
cc-option,-Werror=designated-init)
+ # change __FILE__ to the relative path from the srctree
+ KBUILD_CFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=)
+ 
+-# ensure -fcf-protection is disabled when using retpoline as it is
+-# incompatible with -mindirect-branch=thunk-extern
+-ifdef CONFIG_RETPOLINE
+-KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none)
+-endif
+-
+ # use the deterministic mode of AR if available
+ KBUILD_ARFLAGS := $(call ar-option,D)
+ 
+diff --git a/arch/arm/mach-footbridge/dc21285.c 
b/arch/arm/mach-footbridge/dc21285.c
+index 96a3d73ef4bf4..fd6c9169fa78e 100644
+--- a/arch/arm/mach-footbridge/dc21285.c
++++ b/arch/arm/mach-footbridge/dc21285.c
+@@ -69,15 +69,15 @@ dc21285_read_config(struct pci_bus *bus, unsigned int 
devfn, int where,
+       if (addr)
+               switch (size) {
+               case 1:
+-                      asm("ldrb       %0, [%1, %2]"
++                      asm volatile("ldrb      %0, [%1, %2]"
+                               : "=r" (v) : "r" (addr), "r" (where) : "cc");
+                       break;
+               case 2:
+-                      asm("ldrh       %0, [%1, %2]"
++                      asm volatile("ldrh      %0, [%1, %2]"
+                               : "=r" (v) : "r" (addr), "r" (where) : "cc");
+                       break;
+               case 4:
+-                      asm("ldr        %0, [%1, %2]"
++                      asm volatile("ldr       %0, [%1, %2]"
+                               : "=r" (v) : "r" (addr), "r" (where) : "cc");
+                       break;
+               }
+@@ -103,17 +103,17 @@ dc21285_write_config(struct pci_bus *bus, unsigned int 
devfn, int where,
+       if (addr)
+               switch (size) {
+               case 1:
+-                      asm("strb       %0, [%1, %2]"
++                      asm volatile("strb      %0, [%1, %2]"
+                               : : "r" (value), "r" (addr), "r" (where)
+                               : "cc");
+                       break;
+               case 2:
+-                      asm("strh       %0, [%1, %2]"
++                      asm volatile("strh      %0, [%1, %2]"
+                               : : "r" (value), "r" (addr), "r" (where)
+                               : "cc");
+                       break;
+               case 4:
+-                      asm("str        %0, [%1, %2]"
++                      asm volatile("str       %0, [%1, %2]"
+                               : : "r" (value), "r" (addr), "r" (where)
+                               : "cc");
+                       break;
+diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi 
b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+index c8ff0baddf1d0..cb49d21e317c0 100644
+--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
++++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+@@ -304,7 +304,7 @@
+ 
+               dcfg: dcfg@1ee0000 {
+                       compatible = "fsl,ls1046a-dcfg", "syscon";
+-                      reg = <0x0 0x1ee0000 0x0 0x10000>;
++                      reg = <0x0 0x1ee0000 0x0 0x1000>;
+                       big-endian;
+               };
+ 
+diff --git a/arch/x86/Makefile b/arch/x86/Makefile
+index 3dc54d2f79c4e..4c8e9f12b0c4d 100644
+--- a/arch/x86/Makefile
++++ b/arch/x86/Makefile
+@@ -138,6 +138,9 @@ else
+         KBUILD_CFLAGS += -mno-red-zone
+         KBUILD_CFLAGS += -mcmodel=kernel
+ 
++      # Intel CET isn't enabled in the kernel
++      KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none)
++
+         # -funit-at-a-time shrinks the kernel .text considerably
+         # unfortunately it makes reading oopses harder.
+         KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time)
+diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
+index 25a5a5c6ae90a..95f59f5dffb32 100644
+--- a/arch/x86/include/asm/apic.h
++++ b/arch/x86/include/asm/apic.h
+@@ -174,16 +174,6 @@ static inline void lapic_update_tsc_freq(void) { }
+ #endif /* !CONFIG_X86_LOCAL_APIC */
+ 
+ #ifdef CONFIG_X86_X2APIC
+-/*
+- * Make previous memory operations globally visible before
+- * sending the IPI through x2apic wrmsr. We need a serializing instruction or
+- * mfence for this.
+- */
+-static inline void x2apic_wrmsr_fence(void)
+-{
+-      asm volatile("mfence" : : : "memory");
+-}
+-
+ static inline void native_apic_msr_write(u32 reg, u32 v)
+ {
+       if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR ||
+diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h
+index bc88797cfa615..3895a7b6952bf 100644
+--- a/arch/x86/include/asm/barrier.h
++++ b/arch/x86/include/asm/barrier.h
+@@ -111,4 +111,22 @@ do {                                                      
                \
+ 
+ #include <asm-generic/barrier.h>
+ 
++/*
++ * Make previous memory operations globally visible before
++ * a WRMSR.
++ *
++ * MFENCE makes writes visible, but only affects load/store
++ * instructions.  WRMSR is unfortunately not a load/store
++ * instruction and is unaffected by MFENCE.  The LFENCE ensures
++ * that the WRMSR is not reordered.
++ *
++ * Most WRMSRs are full serializing instructions themselves and
++ * do not require this barrier.  This is only required for the
++ * IA32_TSC_DEADLINE and X2APIC MSRs.
++ */
++static inline void weak_wrmsr_fence(void)
++{
++      asm volatile("mfence; lfence" : : : "memory");
++}
++
+ #endif /* _ASM_X86_BARRIER_H */
+diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
+index ee33f09513223..76f2bbba92f98 100644
+--- a/arch/x86/kernel/apic/apic.c
++++ b/arch/x86/kernel/apic/apic.c
+@@ -42,6 +42,7 @@
+ #include <asm/x86_init.h>
+ #include <asm/pgalloc.h>
+ #include <linux/atomic.h>
++#include <asm/barrier.h>
+ #include <asm/mpspec.h>
+ #include <asm/i8259.h>
+ #include <asm/proto.h>
+@@ -473,6 +474,9 @@ static int lapic_next_deadline(unsigned long delta,
+ {
+       u64 tsc;
+ 
++      /* This MSR is special and need a special fence: */
++      weak_wrmsr_fence();
++
+       tsc = rdtsc();
+       wrmsrl(MSR_IA32_TSC_DEADLINE, tsc + (((u64) delta) * TSC_DIVISOR));
+       return 0;
+diff --git a/arch/x86/kernel/apic/x2apic_cluster.c 
b/arch/x86/kernel/apic/x2apic_cluster.c
+index e216cf3d64d2e..32c5dba6f1bbc 100644
+--- a/arch/x86/kernel/apic/x2apic_cluster.c
++++ b/arch/x86/kernel/apic/x2apic_cluster.c
+@@ -29,7 +29,8 @@ static void x2apic_send_IPI(int cpu, int vector)
+ {
+       u32 dest = per_cpu(x86_cpu_to_logical_apicid, cpu);
+ 
+-      x2apic_wrmsr_fence();
++      /* x2apic MSRs are special and need a special fence: */
++      weak_wrmsr_fence();
+       __x2apic_send_IPI_dest(dest, vector, APIC_DEST_LOGICAL);
+ }
+ 
+@@ -42,7 +43,8 @@ __x2apic_send_IPI_mask(const struct cpumask *mask, int 
vector, int apic_dest)
+       unsigned long flags;
+       u32 dest;
+ 
+-      x2apic_wrmsr_fence();
++      /* x2apic MSRs are special and need a special fence: */
++      weak_wrmsr_fence();
+ 
+       local_irq_save(flags);
+ 
+diff --git a/arch/x86/kernel/apic/x2apic_phys.c 
b/arch/x86/kernel/apic/x2apic_phys.c
+index b94d35320f85e..98716a4be0a7c 100644
+--- a/arch/x86/kernel/apic/x2apic_phys.c
++++ b/arch/x86/kernel/apic/x2apic_phys.c
+@@ -41,7 +41,8 @@ static void x2apic_send_IPI(int cpu, int vector)
+ {
+       u32 dest = per_cpu(x86_cpu_to_apicid, cpu);
+ 
+-      x2apic_wrmsr_fence();
++      /* x2apic MSRs are special and need a special fence: */
++      weak_wrmsr_fence();
+       __x2apic_send_IPI_dest(dest, vector, APIC_DEST_PHYSICAL);
+ }
+ 
+@@ -52,7 +53,8 @@ __x2apic_send_IPI_mask(const struct cpumask *mask, int 
vector, int apic_dest)
+       unsigned long this_cpu;
+       unsigned long flags;
+ 
+-      x2apic_wrmsr_fence();
++      /* x2apic MSRs are special and need a special fence: */
++      weak_wrmsr_fence();
+ 
+       local_irq_save(flags);
+ 
+diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
+index 637f1347cd13d..815b69d35722c 100644
+--- a/drivers/input/joystick/xpad.c
++++ b/drivers/input/joystick/xpad.c
+@@ -232,9 +232,17 @@ static const struct xpad_device {
+       { 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
+       { 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
+       { 0x0e6f, 0x0246, "Rock Candy Gamepad for Xbox One 2015", 0, 
XTYPE_XBOXONE },
+-      { 0x0e6f, 0x02ab, "PDP Controller for Xbox One", 0, XTYPE_XBOXONE },
++      { 0x0e6f, 0x02a0, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
++      { 0x0e6f, 0x02a1, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
++      { 0x0e6f, 0x02a2, "PDP Wired Controller for Xbox One - Crimson Red", 0, 
XTYPE_XBOXONE },
+       { 0x0e6f, 0x02a4, "PDP Wired Controller for Xbox One - Stealth Series", 
0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x02a6, "PDP Wired Controller for Xbox One - Camo Series", 0, 
XTYPE_XBOXONE },
++      { 0x0e6f, 0x02a7, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
++      { 0x0e6f, 0x02a8, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
++      { 0x0e6f, 0x02ab, "PDP Controller for Xbox One", 0, XTYPE_XBOXONE },
++      { 0x0e6f, 0x02ad, "PDP Wired Controller for Xbox One - Stealth Series", 
0, XTYPE_XBOXONE },
++      { 0x0e6f, 0x02b3, "Afterglow Prismatic Wired Controller", 0, 
XTYPE_XBOXONE },
++      { 0x0e6f, 0x02b8, "Afterglow Prismatic Wired Controller", 0, 
XTYPE_XBOXONE },
+       { 0x0e6f, 0x0301, "Logic3 Controller", 0, XTYPE_XBOX360 },
+       { 0x0e6f, 0x0346, "Rock Candy Gamepad for Xbox One 2016", 0, 
XTYPE_XBOXONE },
+       { 0x0e6f, 0x0401, "Logic3 Controller", 0, XTYPE_XBOX360 },
+@@ -313,6 +321,9 @@ static const struct xpad_device {
+       { 0x1bad, 0xfa01, "MadCatz GamePad", 0, XTYPE_XBOX360 },
+       { 0x1bad, 0xfd00, "Razer Onza TE", 0, XTYPE_XBOX360 },
+       { 0x1bad, 0xfd01, "Razer Onza", 0, XTYPE_XBOX360 },
++      { 0x20d6, 0x2001, "BDA Xbox Series X Wired Controller", 0, 
XTYPE_XBOXONE },
++      { 0x20d6, 0x281f, "PowerA Wired Controller For Xbox 360", 0, 
XTYPE_XBOX360 },
++      { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE },
+       { 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, 
XTYPE_XBOX360 },
+       { 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 },
+       { 0x24c6, 0x5303, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 },
+@@ -446,8 +457,12 @@ static const struct usb_device_id xpad_table[] = {
+       XPAD_XBOX360_VENDOR(0x162e),            /* Joytech X-Box 360 
controllers */
+       XPAD_XBOX360_VENDOR(0x1689),            /* Razer Onza */
+       XPAD_XBOX360_VENDOR(0x1bad),            /* Harminix Rock Band Guitar 
and Drums */
++      XPAD_XBOX360_VENDOR(0x20d6),            /* PowerA Controllers */
++      XPAD_XBOXONE_VENDOR(0x20d6),            /* PowerA Controllers */
+       XPAD_XBOX360_VENDOR(0x24c6),            /* PowerA Controllers */
+       XPAD_XBOXONE_VENDOR(0x24c6),            /* PowerA Controllers */
++      XPAD_XBOXONE_VENDOR(0x2e24),            /* Hyperkin Duke X-Box One pad 
*/
++      XPAD_XBOX360_VENDOR(0x2f24),            /* GameSir Controllers */
+       { }
+ };
+ 
+diff --git a/drivers/input/serio/i8042-x86ia64io.h 
b/drivers/input/serio/i8042-x86ia64io.h
+index b256e3006a6fb..844875df8cad7 100644
+--- a/drivers/input/serio/i8042-x86ia64io.h
++++ b/drivers/input/serio/i8042-x86ia64io.h
+@@ -223,6 +223,8 @@ static const struct dmi_system_id __initconst 
i8042_dmi_noloop_table[] = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "C15B"),
+               },
++      },
++      {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ByteSpeed LLC"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ByteSpeed Laptop C15B"),
+diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
+index db1b546134f59..74bfd7d293380 100644
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -3338,6 +3338,12 @@ static int __init init_dmars(void)
+ 
+               if (!ecap_pass_through(iommu->ecap))
+                       hw_pass_through = 0;
++
++              if (!intel_iommu_strict && cap_caching_mode(iommu->cap)) {
++                      pr_info("Disable batched IOTLB flush due to 
virtualization");
++                      intel_iommu_strict = 1;
++              }
++
+ #ifdef CONFIG_INTEL_IOMMU_SVM
+               if (pasid_enabled(iommu))
+                       intel_svm_alloc_pasid_tables(iommu);
+diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c
+index 2ca5cd79018b4..dca72444b3122 100644
+--- a/drivers/mmc/core/sdio_cis.c
++++ b/drivers/mmc/core/sdio_cis.c
+@@ -24,6 +24,8 @@
+ #include "sdio_cis.h"
+ #include "sdio_ops.h"
+ 
++#define SDIO_READ_CIS_TIMEOUT_MS  (10 * 1000) /* 10s */
++
+ static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func,
+                        const unsigned char *buf, unsigned size)
+ {
+@@ -270,6 +272,8 @@ static int sdio_read_cis(struct mmc_card *card, struct 
sdio_func *func)
+ 
+       do {
+               unsigned char tpl_code, tpl_link;
++              unsigned long timeout = jiffies +
++                      msecs_to_jiffies(SDIO_READ_CIS_TIMEOUT_MS);
+ 
+               ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_code);
+               if (ret)
+@@ -322,6 +326,8 @@ static int sdio_read_cis(struct mmc_card *card, struct 
sdio_func *func)
+                       prev = &this->next;
+ 
+                       if (ret == -ENOENT) {
++                              if (time_after(jiffies, timeout))
++                                      break;
+                               /* warn about unknown tuples */
+                               pr_warn_ratelimited("%s: queuing unknown"
+                                      " CIS tuple 0x%02x (%u bytes)\n",
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c 
b/drivers/net/dsa/mv88e6xxx/chip.c
+index f4268f0322663..7ab4cc0962ace 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -1364,7 +1364,11 @@ static int mv88e6xxx_port_db_load_purge(struct 
mv88e6xxx_chip *chip, int port,
+               if (!entry.portvec)
+                       entry.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED;
+       } else {
+-              entry.portvec |= BIT(port);
++              if (state == MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC)
++                      entry.portvec = BIT(port);
++              else
++                      entry.portvec |= BIT(port);
++
+               entry.state = state;
+       }
+ 
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 540fab9f850dd..92f269a0846c6 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -2588,6 +2588,8 @@ static const struct pci_device_id nvme_id_table[] = {
+       { PCI_DEVICE(0x1d1d, 0x2601),   /* CNEX Granby */
+               .driver_data = NVME_QUIRK_LIGHTNVM, },
+       { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
++      { PCI_DEVICE(0x2646, 0x2263),   /* KINGSTON A2000 NVMe SSD  */
++              .driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
+       { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) },
+       { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) },
+       { 0, }
+diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
+index 21a51a15893bb..f69a0a0b7266b 100644
+--- a/drivers/usb/class/usblp.c
++++ b/drivers/usb/class/usblp.c
+@@ -1340,14 +1340,17 @@ static int usblp_set_protocol(struct usblp *usblp, int 
protocol)
+       if (protocol < USBLP_FIRST_PROTOCOL || protocol > USBLP_LAST_PROTOCOL)
+               return -EINVAL;
+ 
+-      alts = usblp->protocol[protocol].alt_setting;
+-      if (alts < 0)
+-              return -EINVAL;
+-      r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
+-      if (r < 0) {
+-              printk(KERN_ERR "usblp: can't set desired altsetting %d on 
interface %d\n",
+-                      alts, usblp->ifnum);
+-              return r;
++      /* Don't unnecessarily set the interface if there's a single alt. */
++      if (usblp->intf->num_altsetting > 1) {
++              alts = usblp->protocol[protocol].alt_setting;
++              if (alts < 0)
++                      return -EINVAL;
++              r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
++              if (r < 0) {
++                      printk(KERN_ERR "usblp: can't set desired altsetting %d 
on interface %d\n",
++                              alts, usblp->ifnum);
++                      return r;
++              }
+       }
+ 
+       usblp->bidir = (usblp->protocol[protocol].epread != NULL);
+diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
+index d2d4067a1a5f4..aab2f6cbd524f 100644
+--- a/drivers/usb/dwc2/gadget.c
++++ b/drivers/usb/dwc2/gadget.c
+@@ -1470,7 +1470,6 @@ static void dwc2_hsotg_complete_oursetup(struct usb_ep 
*ep,
+ static struct dwc2_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg,
+                                           u32 windex)
+ {
+-      struct dwc2_hsotg_ep *ep;
+       int dir = (windex & USB_DIR_IN) ? 1 : 0;
+       int idx = windex & 0x7F;
+ 
+@@ -1480,12 +1479,7 @@ static struct dwc2_hsotg_ep *ep_from_windex(struct 
dwc2_hsotg *hsotg,
+       if (idx > hsotg->num_of_eps)
+               return NULL;
+ 
+-      ep = index_to_ep(hsotg, idx, dir);
+-
+-      if (idx && ep->dir_in != dir)
+-              return NULL;
+-
+-      return ep;
++      return index_to_ep(hsotg, idx, dir);
+ }
+ 
+ /**
+diff --git a/drivers/usb/gadget/legacy/ether.c 
b/drivers/usb/gadget/legacy/ether.c
+index 25a2c2e485920..3396e7193dba2 100644
+--- a/drivers/usb/gadget/legacy/ether.c
++++ b/drivers/usb/gadget/legacy/ether.c
+@@ -407,8 +407,10 @@ static int eth_bind(struct usb_composite_dev *cdev)
+               struct usb_descriptor_header *usb_desc;
+ 
+               usb_desc = usb_otg_descriptor_alloc(gadget);
+-              if (!usb_desc)
++              if (!usb_desc) {
++                      status = -ENOMEM;
+                       goto fail1;
++              }
+               usb_otg_descriptor_init(gadget, usb_desc);
+               otg_desc[0] = usb_desc;
+               otg_desc[1] = NULL;
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 0c5b2c75b8713..748d4c69cb28a 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -681,11 +681,16 @@ static void xhci_unmap_td_bounce_buffer(struct xhci_hcd 
*xhci,
+       dma_unmap_single(dev, seg->bounce_dma, ring->bounce_buf_len,
+                        DMA_FROM_DEVICE);
+       /* for in tranfers we need to copy the data from bounce to sg */
+-      len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, seg->bounce_buf,
+-                           seg->bounce_len, seg->bounce_offs);
+-      if (len != seg->bounce_len)
+-              xhci_warn(xhci, "WARN Wrong bounce buffer read length: %zu != 
%d\n",
+-                              len, seg->bounce_len);
++      if (urb->num_sgs) {
++              len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, 
seg->bounce_buf,
++                                         seg->bounce_len, seg->bounce_offs);
++              if (len != seg->bounce_len)
++                      xhci_warn(xhci, "WARN Wrong bounce buffer read length: 
%zu != %d\n",
++                                len, seg->bounce_len);
++      } else {
++              memcpy(urb->transfer_buffer + seg->bounce_offs, seg->bounce_buf,
++                     seg->bounce_len);
++      }
+       seg->bounce_len = 0;
+       seg->bounce_offs = 0;
+ }
+@@ -3252,12 +3257,16 @@ static int xhci_align_td(struct xhci_hcd *xhci, struct 
urb *urb, u32 enqd_len,
+ 
+       /* create a max max_pkt sized bounce buffer pointed to by last trb */
+       if (usb_urb_dir_out(urb)) {
+-              len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs,
+-                                 seg->bounce_buf, new_buff_len, enqd_len);
+-              if (len != new_buff_len)
+-                      xhci_warn(xhci,
+-                              "WARN Wrong bounce buffer write length: %zu != 
%d\n",
+-                              len, new_buff_len);
++              if (urb->num_sgs) {
++                      len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs,
++                                               seg->bounce_buf, new_buff_len, 
enqd_len);
++                      if (len != new_buff_len)
++                              xhci_warn(xhci, "WARN Wrong bounce buffer write 
length: %zu != %d\n",
++                                        len, new_buff_len);
++              } else {
++                      memcpy(seg->bounce_buf, urb->transfer_buffer + 
enqd_len, new_buff_len);
++              }
++
+               seg->bounce_dma = dma_map_single(dev, seg->bounce_buf,
+                                                max_pkt, DMA_TO_DEVICE);
+       } else {
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index 630c8338d7912..2d07364e93023 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -64,6 +64,7 @@ static const struct usb_device_id id_table[] = {
+       { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless 
smartcard reader */
+       { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC 
Device */
+       { USB_DEVICE(0x0908, 0x01FF) }, /* Siemens RUGGEDCOM USB Serial Console 
*/
++      { USB_DEVICE(0x0988, 0x0578) }, /* Teraoka AD2000 */
+       { USB_DEVICE(0x0B00, 0x3070) }, /* Ingenico 3070 */
+       { USB_DEVICE(0x0BED, 0x1100) }, /* MEI (TM) Cashflow-SC Bill/Voucher 
Acceptor */
+       { USB_DEVICE(0x0BED, 0x1101) }, /* MEI series 2000 Combo Acceptor */
+@@ -204,6 +205,7 @@ static const struct usb_device_id id_table[] = {
+       { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */
+       { USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART 
interface */
+       { USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */
++      { USB_DEVICE(0x199B, 0xBA30) }, /* LORD WSDA-200-USB */
+       { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
+       { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
+       { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 27549e80e0b16..22e119774cb3d 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -428,6 +428,8 @@ static void option_instat_callback(struct urb *urb);
+ #define CINTERION_PRODUCT_AHXX_2RMNET         0x0084
+ #define CINTERION_PRODUCT_AHXX_AUDIO          0x0085
+ #define CINTERION_PRODUCT_CLS8                        0x00b0
++#define CINTERION_PRODUCT_MV31_MBIM           0x00b3
++#define CINTERION_PRODUCT_MV31_RMNET          0x00b7
+ 
+ /* Olivetti products */
+ #define OLIVETTI_VENDOR_ID                    0x0b3c
+@@ -1917,6 +1919,10 @@ static const struct usb_device_id option_ids[] = {
+       { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) },
+       { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, /* HC28 
enumerates with Siemens or Cinterion VID depending on FW revision */
+       { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
++      { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, 
CINTERION_PRODUCT_MV31_MBIM, 0xff),
++        .driver_info = RSVD(3)},
++      { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, 
CINTERION_PRODUCT_MV31_RMNET, 0xff),
++        .driver_info = RSVD(0)},
+       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100),
+         .driver_info = RSVD(4) },
+       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120),
+diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
+index 03293e543c075..b92804ff3b333 100644
+--- a/fs/cifs/dir.c
++++ b/fs/cifs/dir.c
+@@ -841,6 +841,7 @@ static int
+ cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
+ {
+       struct inode *inode;
++      int rc;
+ 
+       if (flags & LOOKUP_RCU)
+               return -ECHILD;
+@@ -850,8 +851,25 @@ cifs_d_revalidate(struct dentry *direntry, unsigned int 
flags)
+               if ((flags & LOOKUP_REVAL) && !CIFS_CACHE_READ(CIFS_I(inode)))
+                       CIFS_I(inode)->time = 0; /* force reval */
+ 
+-              if (cifs_revalidate_dentry(direntry))
+-                      return 0;
++              rc = cifs_revalidate_dentry(direntry);
++              if (rc) {
++                      cifs_dbg(FYI, "cifs_revalidate_dentry failed with 
rc=%d", rc);
++                      switch (rc) {
++                      case -ENOENT:
++                      case -ESTALE:
++                              /*
++                               * Those errors mean the dentry is invalid
++                               * (file was deleted or recreated)
++                               */
++                              return 0;
++                      default:
++                              /*
++                               * Otherwise some unexpected error happened
++                               * report it as-is to VFS layer
++                               */
++                              return rc;
++                      }
++              }
+               else {
+                       /*
+                        * If the inode wasn't known to be a dfs entry when
+diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
+index f8baa54c83008..407425d31b2eb 100644
+--- a/fs/cifs/smb2pdu.h
++++ b/fs/cifs/smb2pdu.h
+@@ -206,7 +206,7 @@ struct smb2_negotiate_req {
+       __le32 NegotiateContextOffset; /* SMB3.1.1 only. MBZ earlier */
+       __le16 NegotiateContextCount;  /* SMB3.1.1 only. MBZ earlier */
+       __le16 Reserved2;
+-      __le16 Dialects[1]; /* One dialect (vers=) at a time for now */
++      __le16 Dialects[4]; /* BB expand this if autonegotiate > 4 dialects */
+ } __packed;
+ 
+ /* Dialects */
+diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
+index ba54a0e12bbd0..94fc833119e47 100644
+--- a/fs/hugetlbfs/inode.c
++++ b/fs/hugetlbfs/inode.c
+@@ -649,8 +649,9 @@ static long hugetlbfs_fallocate(struct file *file, int 
mode, loff_t offset,
+ 
+               mutex_unlock(&hugetlb_fault_mutex_table[hash]);
+ 
++              set_page_huge_active(page);
+               /*
+-               * page_put due to reference from alloc_huge_page()
++               * put_page() due to reference from alloc_huge_page()
+                * unlock_page because locked by add_to_page_cache()
+                */
+               put_page(page);
+diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
+index 8c561703275a5..5bdc85ad13a2f 100644
+--- a/fs/overlayfs/dir.c
++++ b/fs/overlayfs/dir.c
+@@ -850,8 +850,8 @@ static char *ovl_get_redirect(struct dentry *dentry, bool 
samedir)
+ 
+               buflen -= thislen;
+               memcpy(&buf[buflen], name, thislen);
+-              tmp = dget_dlock(d->d_parent);
+               spin_unlock(&d->d_lock);
++              tmp = dget_parent(d);
+ 
+               dput(d);
+               d = tmp;
+diff --git a/include/linux/elfcore.h b/include/linux/elfcore.h
+index 4cad0e784b286..b81f9e1d74b0a 100644
+--- a/include/linux/elfcore.h
++++ b/include/linux/elfcore.h
+@@ -58,6 +58,7 @@ static inline int elf_core_copy_task_xfpregs(struct 
task_struct *t, elf_fpxregse
+ }
+ #endif
+ 
++#if defined(CONFIG_UM) || defined(CONFIG_IA64)
+ /*
+  * These functions parameterize elf_core_dump in fs/binfmt_elf.c to write out
+  * extra segments containing the gate DSO contents.  Dumping its
+@@ -72,5 +73,26 @@ elf_core_write_extra_phdrs(struct coredump_params *cprm, 
loff_t offset);
+ extern int
+ elf_core_write_extra_data(struct coredump_params *cprm);
+ extern size_t elf_core_extra_data_size(void);
++#else
++static inline Elf_Half elf_core_extra_phdrs(void)
++{
++      return 0;
++}
++
++static inline int elf_core_write_extra_phdrs(struct coredump_params *cprm, 
loff_t offset)
++{
++      return 1;
++}
++
++static inline int elf_core_write_extra_data(struct coredump_params *cprm)
++{
++      return 1;
++}
++
++static inline size_t elf_core_extra_data_size(void)
++{
++      return 0;
++}
++#endif
+ 
+ #endif /* _LINUX_ELFCORE_H */
+diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
+index 50a07235032fd..7b152f9d63a48 100644
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -531,6 +531,9 @@ static inline void set_huge_swap_pte_at(struct mm_struct 
*mm, unsigned long addr
+       set_huge_pte_at(mm, addr, ptep, pte);
+ }
+ #endif
++
++void set_page_huge_active(struct page *page);
++
+ #else /* CONFIG_HUGETLB_PAGE */
+ struct hstate {};
+ #define alloc_huge_page(v, a, r) NULL
+diff --git a/kernel/Makefile b/kernel/Makefile
+index 43e92e3691ecc..38151285fca43 100644
+--- a/kernel/Makefile
++++ b/kernel/Makefile
+@@ -90,7 +90,6 @@ obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
+ obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
+ obj-$(CONFIG_TRACEPOINTS) += tracepoint.o
+ obj-$(CONFIG_LATENCYTOP) += latencytop.o
+-obj-$(CONFIG_ELFCORE) += elfcore.o
+ obj-$(CONFIG_FUNCTION_TRACER) += trace/
+ obj-$(CONFIG_TRACING) += trace/
+ obj-$(CONFIG_TRACE_CLOCK) += trace/
+diff --git a/kernel/elfcore.c b/kernel/elfcore.c
+deleted file mode 100644
+index 57fb4dcff4349..0000000000000
+--- a/kernel/elfcore.c
++++ /dev/null
+@@ -1,26 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-#include <linux/elf.h>
+-#include <linux/fs.h>
+-#include <linux/mm.h>
+-#include <linux/binfmts.h>
+-#include <linux/elfcore.h>
+-
+-Elf_Half __weak elf_core_extra_phdrs(void)
+-{
+-      return 0;
+-}
+-
+-int __weak elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t 
offset)
+-{
+-      return 1;
+-}
+-
+-int __weak elf_core_write_extra_data(struct coredump_params *cprm)
+-{
+-      return 1;
+-}
+-
+-size_t __weak elf_core_extra_data_size(void)
+-{
+-      return 0;
+-}
+diff --git a/kernel/kprobes.c b/kernel/kprobes.c
+index fdf6656cce292..d752c1df8f3fd 100644
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -1989,6 +1989,10 @@ int register_kretprobe(struct kretprobe *rp)
+       if (!kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, 
rp->kp.offset))
+               return -EINVAL;
+ 
++      /* If only rp->kp.addr is specified, check reregistering kprobes */
++      if (rp->kp.addr && check_kprobe_rereg(&rp->kp))
++              return -EINVAL;
++
+       if (kretprobe_blacklist_size) {
+               addr = kprobe_addr(&rp->kp);
+               if (IS_ERR(addr))
+diff --git a/mm/huge_memory.c b/mm/huge_memory.c
+index 5d9dd24d99c8b..9dbfa7286c611 100644
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -2198,7 +2198,7 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t 
*pmd,
+       spinlock_t *ptl;
+       struct mm_struct *mm = vma->vm_mm;
+       unsigned long haddr = address & HPAGE_PMD_MASK;
+-      bool was_locked = false;
++      bool do_unlock_page = false;
+       pmd_t _pmd;
+ 
+       mmu_notifier_invalidate_range_start(mm, haddr, haddr + HPAGE_PMD_SIZE);
+@@ -2211,7 +2211,6 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t 
*pmd,
+       VM_BUG_ON(freeze && !page);
+       if (page) {
+               VM_WARN_ON_ONCE(!PageLocked(page));
+-              was_locked = true;
+               if (page != pmd_page(*pmd))
+                       goto out;
+       }
+@@ -2220,19 +2219,29 @@ repeat:
+       if (pmd_trans_huge(*pmd)) {
+               if (!page) {
+                       page = pmd_page(*pmd);
+-                      if (unlikely(!trylock_page(page))) {
+-                              get_page(page);
+-                              _pmd = *pmd;
+-                              spin_unlock(ptl);
+-                              lock_page(page);
+-                              spin_lock(ptl);
+-                              if (unlikely(!pmd_same(*pmd, _pmd))) {
+-                                      unlock_page(page);
++                      /*
++                       * An anonymous page must be locked, to ensure that a
++                       * concurrent reuse_swap_page() sees stable mapcount;
++                       * but reuse_swap_page() is not used on shmem or file,
++                       * and page lock must not be taken when zap_pmd_range()
++                       * calls __split_huge_pmd() while i_mmap_lock is held.
++                       */
++                      if (PageAnon(page)) {
++                              if (unlikely(!trylock_page(page))) {
++                                      get_page(page);
++                                      _pmd = *pmd;
++                                      spin_unlock(ptl);
++                                      lock_page(page);
++                                      spin_lock(ptl);
++                                      if (unlikely(!pmd_same(*pmd, _pmd))) {
++                                              unlock_page(page);
++                                              put_page(page);
++                                              page = NULL;
++                                              goto repeat;
++                                      }
+                                       put_page(page);
+-                                      page = NULL;
+-                                      goto repeat;
+                               }
+-                              put_page(page);
++                              do_unlock_page = true;
+                       }
+               }
+               if (PageMlocked(page))
+@@ -2242,7 +2251,7 @@ repeat:
+       __split_huge_pmd_locked(vma, pmd, haddr, freeze);
+ out:
+       spin_unlock(ptl);
+-      if (!was_locked && page)
++      if (do_unlock_page)
+               unlock_page(page);
+       mmu_notifier_invalidate_range_end(mm, haddr, haddr + HPAGE_PMD_SIZE);
+ }
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 3623eb037eee8..5f0d0f92adbf8 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -1233,12 +1233,11 @@ struct hstate *size_to_hstate(unsigned long size)
+  */
+ bool page_huge_active(struct page *page)
+ {
+-      VM_BUG_ON_PAGE(!PageHuge(page), page);
+-      return PageHead(page) && PagePrivate(&page[1]);
++      return PageHeadHuge(page) && PagePrivate(&page[1]);
+ }
+ 
+ /* never called for tail page */
+-static void set_page_huge_active(struct page *page)
++void set_page_huge_active(struct page *page)
+ {
+       VM_BUG_ON_PAGE(!PageHeadHuge(page), page);
+       SetPagePrivate(&page[1]);
+@@ -4865,9 +4864,9 @@ bool isolate_huge_page(struct page *page, struct 
list_head *list)
+ {
+       bool ret = true;
+ 
+-      VM_BUG_ON_PAGE(!PageHead(page), page);
+       spin_lock(&hugetlb_lock);
+-      if (!page_huge_active(page) || !get_page_unless_zero(page)) {
++      if (!PageHeadHuge(page) || !page_huge_active(page) ||
++          !get_page_unless_zero(page)) {
+               ret = false;
+               goto unlock;
+       }
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index be7383d139c15..78d6bc61a1d87 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -1437,6 +1437,24 @@ static bool rt_bind_exception(struct rtable *rt, struct 
fib_nh_exception *fnhe,
+       return ret;
+ }
+ 
++struct uncached_list {
++      spinlock_t              lock;
++      struct list_head        head;
++};
++
++static DEFINE_PER_CPU_ALIGNED(struct uncached_list, rt_uncached_list);
++
++static void rt_add_uncached_list(struct rtable *rt)
++{
++      struct uncached_list *ul = raw_cpu_ptr(&rt_uncached_list);
++
++      rt->rt_uncached_list = ul;
++
++      spin_lock_bh(&ul->lock);
++      list_add_tail(&rt->rt_uncached, &ul->head);
++      spin_unlock_bh(&ul->lock);
++}
++
+ static bool rt_cache_route(struct fib_nh *nh, struct rtable *rt)
+ {
+       struct rtable *orig, *prev, **p;
+@@ -1456,7 +1474,7 @@ static bool rt_cache_route(struct fib_nh *nh, struct 
rtable *rt)
+       prev = cmpxchg(p, orig, rt);
+       if (prev == orig) {
+               if (orig) {
+-                      dst_dev_put(&orig->dst);
++                      rt_add_uncached_list(orig);
+                       dst_release(&orig->dst);
+               }
+       } else {
+@@ -1467,24 +1485,6 @@ static bool rt_cache_route(struct fib_nh *nh, struct 
rtable *rt)
+       return ret;
+ }
+ 
+-struct uncached_list {
+-      spinlock_t              lock;
+-      struct list_head        head;
+-};
+-
+-static DEFINE_PER_CPU_ALIGNED(struct uncached_list, rt_uncached_list);
+-
+-static void rt_add_uncached_list(struct rtable *rt)
+-{
+-      struct uncached_list *ul = raw_cpu_ptr(&rt_uncached_list);
+-
+-      rt->rt_uncached_list = ul;
+-
+-      spin_lock_bh(&ul->lock);
+-      list_add_tail(&rt->rt_uncached, &ul->head);
+-      spin_unlock_bh(&ul->lock);
+-}
+-
+ static void ipv4_dst_destroy(struct dst_entry *dst)
+ {
+       struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst);
+diff --git a/net/lapb/lapb_out.c b/net/lapb/lapb_out.c
+index eda726e22f645..621c66f001177 100644
+--- a/net/lapb/lapb_out.c
++++ b/net/lapb/lapb_out.c
+@@ -87,7 +87,8 @@ void lapb_kick(struct lapb_cb *lapb)
+               skb = skb_dequeue(&lapb->write_queue);
+ 
+               do {
+-                      if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
++                      skbn = skb_copy(skb, GFP_ATOMIC);
++                      if (!skbn) {
+                               skb_queue_head(&lapb->write_queue, skb);
+                               break;
+                       }
+diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c
+index f783d1377d9a8..9f0f437a09b95 100644
+--- a/net/mac80211/driver-ops.c
++++ b/net/mac80211/driver-ops.c
+@@ -128,8 +128,11 @@ int drv_sta_state(struct ieee80211_local *local,
+       } else if (old_state == IEEE80211_STA_AUTH &&
+                  new_state == IEEE80211_STA_ASSOC) {
+               ret = drv_sta_add(local, sdata, &sta->sta);
+-              if (ret == 0)
++              if (ret == 0) {
+                       sta->uploaded = true;
++                      if (rcu_access_pointer(sta->sta.rates))
++                              drv_sta_rate_tbl_update(local, sdata, 
&sta->sta);
++              }
+       } else if (old_state == IEEE80211_STA_ASSOC &&
+                  new_state == IEEE80211_STA_AUTH) {
+               drv_sta_remove(local, sdata, &sta->sta);
+diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
+index 76f303fda3eda..954b932fd7b86 100644
+--- a/net/mac80211/rate.c
++++ b/net/mac80211/rate.c
+@@ -941,7 +941,8 @@ int rate_control_set_rates(struct ieee80211_hw *hw,
+       if (old)
+               kfree_rcu(old, rcu_head);
+ 
+-      drv_sta_rate_tbl_update(hw_to_local(hw), sta->sdata, pubsta);
++      if (sta->uploaded)
++              drv_sta_rate_tbl_update(hw_to_local(hw), sta->sdata, pubsta);
+ 
+       ieee80211_sta_set_expected_throughput(pubsta, 
sta_get_expected_throughput(sta));
+ 
+diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c
+index 18384d9be4e17..32a343d6600da 100644
+--- a/tools/objtool/orc_gen.c
++++ b/tools/objtool/orc_gen.c
+@@ -98,11 +98,6 @@ static int create_orc_entry(struct section *u_sec, struct 
section *ip_relasec,
+       struct orc_entry *orc;
+       struct rela *rela;
+ 
+-      if (!insn_sec->sym) {
+-              WARN("missing symbol for section %s", insn_sec->name);
+-              return -1;
+-      }
+-
+       /* populate ORC data */
+       orc = (struct orc_entry *)u_sec->data->d_buf + idx;
+       memcpy(orc, o, sizeof(*orc));
+@@ -115,8 +110,32 @@ static int create_orc_entry(struct section *u_sec, struct 
section *ip_relasec,
+       }
+       memset(rela, 0, sizeof(*rela));
+ 
+-      rela->sym = insn_sec->sym;
+-      rela->addend = insn_off;
++      if (insn_sec->sym) {
++              rela->sym = insn_sec->sym;
++              rela->addend = insn_off;
++      } else {
++              /*
++               * The Clang assembler doesn't produce section symbols, so we
++               * have to reference the function symbol instead:
++               */
++              rela->sym = find_symbol_containing(insn_sec, insn_off);
++              if (!rela->sym) {
++                      /*
++                       * Hack alert.  This happens when we need to reference
++                       * the NOP pad insn immediately after the function.
++                       */
++                      rela->sym = find_symbol_containing(insn_sec,
++                                                         insn_off - 1);
++              }
++              if (!rela->sym) {
++                      WARN("missing symbol for insn at offset 0x%lx\n",
++                           insn_off);
++                      return -1;
++              }
++
++              rela->addend = insn_off - rela->sym->offset;
++      }
++
+       rela->type = R_X86_64_PC32;
+       rela->offset = idx * sizeof(int);
+ 

Reply via email to