commit:     6e3d7d8964a084eaa37791cd4488b9a2289679d8
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Tue Jan 24 07:23:57 2023 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Tue Jan 24 07:24:44 2023 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=6e3d7d89

Linux patch 5.4.230

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

 0000_README              |    4 +
 1229_linux-5.4.230.patch | 1448 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1452 insertions(+)

diff --git a/0000_README b/0000_README
index bec9c24b..36bb199c 100644
--- a/0000_README
+++ b/0000_README
@@ -959,6 +959,10 @@ Patch:  1228_linux-5.4.229.patch
 From:   http://www.kernel.org
 Desc:   Linux 5.4.229
 
+Patch:  1229_linux-5.4.230.patch
+From:   http://www.kernel.org
+Desc:   Linux 5.4.230
+
 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/1229_linux-5.4.230.patch b/1229_linux-5.4.230.patch
new file mode 100644
index 00000000..9d4cde8a
--- /dev/null
+++ b/1229_linux-5.4.230.patch
@@ -0,0 +1,1448 @@
+diff --git 
a/Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml 
b/Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml
+new file mode 100644
+index 0000000000000..5407468a8dda0
+--- /dev/null
++++ b/Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml
+@@ -0,0 +1,57 @@
++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
++# Copyright 2019 BayLibre, SAS
++%YAML 1.2
++---
++$id: "http://devicetree.org/schemas/phy/amlogic,g12a-usb3-pcie-phy.yaml#";
++$schema: "http://devicetree.org/meta-schemas/core.yaml#";
++
++title: Amlogic G12A USB3 + PCIE Combo PHY
++
++maintainers:
++  - Neil Armstrong <[email protected]>
++
++properties:
++  compatible:
++    enum:
++      - amlogic,g12a-usb3-pcie-phy
++
++  reg:
++    maxItems: 1
++
++  clocks:
++    maxItems: 1
++
++  clock-names:
++    items:
++      - const: ref_clk
++
++  resets:
++    maxItems: 1
++
++  reset-names:
++    items:
++      - const: phy
++
++  "#phy-cells":
++    const: 1
++
++required:
++  - compatible
++  - reg
++  - clocks
++  - clock-names
++  - resets
++  - reset-names
++  - "#phy-cells"
++
++examples:
++  - |
++    phy@46000 {
++          compatible = "amlogic,g12a-usb3-pcie-phy";
++          reg = <0x46000 0x2000>;
++          clocks = <&ref_clk>;
++          clock-names = "ref_clk";
++          resets = <&phy_reset>;
++          reset-names = "phy";
++          #phy-cells = <1>;
++    };
+diff --git 
a/Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml 
b/Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml
+deleted file mode 100644
+index 346f9c35427ce..0000000000000
+--- 
a/Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml
++++ /dev/null
+@@ -1,57 +0,0 @@
+-# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+-# Copyright 2019 BayLibre, SAS
+-%YAML 1.2
+----
+-$id: 
"http://devicetree.org/schemas/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml#";
+-$schema: "http://devicetree.org/meta-schemas/core.yaml#";
+-
+-title: Amlogic G12A USB3 + PCIE Combo PHY
+-
+-maintainers:
+-  - Neil Armstrong <[email protected]>
+-
+-properties:
+-  compatible:
+-    enum:
+-      - amlogic,meson-g12a-usb3-pcie-phy
+-
+-  reg:
+-    maxItems: 1
+-
+-  clocks:
+-    maxItems: 1
+-
+-  clock-names:
+-    items:
+-      - const: ref_clk
+-
+-  resets:
+-    maxItems: 1
+-
+-  reset-names:
+-    items:
+-      - const: phy
+-
+-  "#phy-cells":
+-    const: 1
+-
+-required:
+-  - compatible
+-  - reg
+-  - clocks
+-  - clock-names
+-  - resets
+-  - reset-names
+-  - "#phy-cells"
+-
+-examples:
+-  - |
+-    phy@46000 {
+-          compatible = "amlogic,meson-g12a-usb3-pcie-phy";
+-          reg = <0x46000 0x2000>;
+-          clocks = <&ref_clk>;
+-          clock-names = "ref_clk";
+-          resets = <&phy_reset>;
+-          reset-names = "phy";
+-          #phy-cells = <1>;
+-    };
+diff --git a/Makefile b/Makefile
+index abe29e47198b9..6a947b4ed5dc4 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 5
+ PATCHLEVEL = 4
+-SUBLEVEL = 229
++SUBLEVEL = 230
+ EXTRAVERSION =
+ NAME = Kleptomaniac Octopus
+ 
+diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
+index b271da0fa2193..17d092eb1934c 100644
+--- a/arch/x86/kernel/fpu/init.c
++++ b/arch/x86/kernel/fpu/init.c
+@@ -139,9 +139,6 @@ static void __init fpu__init_system_generic(void)
+ unsigned int fpu_kernel_xstate_size;
+ EXPORT_SYMBOL_GPL(fpu_kernel_xstate_size);
+ 
+-/* Get alignment of the TYPE. */
+-#define TYPE_ALIGN(TYPE) offsetof(struct { char x; TYPE test; }, test)
+-
+ /*
+  * Enforce that 'MEMBER' is the last field of 'TYPE'.
+  *
+@@ -149,8 +146,8 @@ EXPORT_SYMBOL_GPL(fpu_kernel_xstate_size);
+  * because that's how C aligns structs.
+  */
+ #define CHECK_MEMBER_AT_END_OF(TYPE, MEMBER) \
+-      BUILD_BUG_ON(sizeof(TYPE) != ALIGN(offsetofend(TYPE, MEMBER), \
+-                                         TYPE_ALIGN(TYPE)))
++      BUILD_BUG_ON(sizeof(TYPE) !=         \
++                   ALIGN(offsetofend(TYPE, MEMBER), _Alignof(TYPE)))
+ 
+ /*
+  * We append the 'struct fpu' to the task_struct:
+diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c 
b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+index a1ce307c502fa..0b970b91750c5 100644
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -551,6 +551,11 @@ static noinline void axi_chan_handle_err(struct 
axi_dma_chan *chan, u32 status)
+ 
+       /* The bad descriptor currently is in the head of vc list */
+       vd = vchan_next_desc(&chan->vc);
++      if (!vd) {
++              dev_err(chan2dev(chan), "BUG: %s, IRQ with no descriptors\n",
++                      axi_chan_name(chan));
++              goto out;
++      }
+       /* Remove the completed descriptor from issued list */
+       list_del(&vd->node);
+ 
+@@ -565,6 +570,7 @@ static noinline void axi_chan_handle_err(struct 
axi_dma_chan *chan, u32 status)
+       /* Try to restart the controller */
+       axi_chan_start_first_queued(chan);
+ 
++out:
+       spin_unlock_irqrestore(&chan->vc.lock, flags);
+ }
+ 
+diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c
+index 9068591bd684b..d82c251387490 100644
+--- a/drivers/dma/tegra210-adma.c
++++ b/drivers/dma/tegra210-adma.c
+@@ -224,7 +224,7 @@ static int tegra_adma_init(struct tegra_adma *tdma)
+       int ret;
+ 
+       /* Clear any interrupts */
+-      tdma_write(tdma, tdma->cdata->global_int_clear, 0x1);
++      tdma_write(tdma, tdma->cdata->ch_base_offset + 
tdma->cdata->global_int_clear, 0x1);
+ 
+       /* Assert soft reset */
+       tdma_write(tdma, ADMA_GLOBAL_SOFT_RESET, 0x1);
+diff --git a/drivers/firmware/efi/runtime-wrappers.c 
b/drivers/firmware/efi/runtime-wrappers.c
+index 136b9c7f9ac95..a6735f1a16d14 100644
+--- a/drivers/firmware/efi/runtime-wrappers.c
++++ b/drivers/firmware/efi/runtime-wrappers.c
+@@ -62,6 +62,7 @@ struct efi_runtime_work efi_rts_work;
+                                                                       \
+       if (!efi_enabled(EFI_RUNTIME_SERVICES)) {                       \
+               pr_warn_once("EFI Runtime Services are disabled!\n");   \
++              efi_rts_work.status = EFI_DEVICE_ERROR;                 \
+               goto exit;                                              \
+       }                                                               \
+                                                                       \
+diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c
+index 517fb57d07d2e..94753ad18ca63 100644
+--- a/drivers/firmware/google/gsmi.c
++++ b/drivers/firmware/google/gsmi.c
+@@ -359,9 +359,10 @@ static efi_status_t gsmi_get_variable(efi_char16_t *name,
+               memcpy(data, gsmi_dev.data_buf->start, *data_size);
+ 
+               /* All variables are have the following attributes */
+-              *attr = EFI_VARIABLE_NON_VOLATILE |
+-                      EFI_VARIABLE_BOOTSERVICE_ACCESS |
+-                      EFI_VARIABLE_RUNTIME_ACCESS;
++              if (attr)
++                      *attr = EFI_VARIABLE_NON_VOLATILE |
++                              EFI_VARIABLE_BOOTSERVICE_ACCESS |
++                              EFI_VARIABLE_RUNTIME_ACCESS;
+       }
+ 
+       spin_unlock_irqrestore(&gsmi_dev.lock, flags);
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index fe9c135fee0e4..9fd711005c1f5 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -7409,8 +7409,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
+                       goto fail;
+               }
+ 
+-              if (dm_old_con_state->abm_level !=
+-                  dm_new_con_state->abm_level)
++              if (dm_old_con_state->abm_level != dm_new_con_state->abm_level 
||
++                  dm_old_con_state->scaling != dm_new_con_state->scaling)
+                       new_crtc_state->connectors_changed = true;
+       }
+ 
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+index c026b393f3c5f..940aa621485cc 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+@@ -92,8 +92,8 @@ static const struct out_csc_color_matrix_type 
output_csc_matrix[] = {
+               { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
+                               0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
+       { COLOR_SPACE_YCBCR2020_TYPE,
+-              { 0x1000, 0xF149, 0xFEB7, 0x0000, 0x0868, 0x15B2,
+-                              0x01E6, 0x0000, 0xFB88, 0xF478, 0x1000, 0x0000} 
},
++              { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868, 0x15B2,
++                              0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} 
},
+       { COLOR_SPACE_YCBCR709_BLACK_TYPE,
+               { 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000,
+                               0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x1000} 
},
+diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c 
b/drivers/gpu/drm/i915/gt/intel_reset.c
+index 8cea42379dd79..48aed34e19dfd 100644
+--- a/drivers/gpu/drm/i915/gt/intel_reset.c
++++ b/drivers/gpu/drm/i915/gt/intel_reset.c
+@@ -257,6 +257,7 @@ out:
+ static int gen6_hw_domain_reset(struct intel_gt *gt, u32 hw_domain_mask)
+ {
+       struct intel_uncore *uncore = gt->uncore;
++      int loops = 2;
+       int err;
+ 
+       /*
+@@ -264,17 +265,38 @@ static int gen6_hw_domain_reset(struct intel_gt *gt, u32 
hw_domain_mask)
+        * for fifo space for the write or forcewake the chip for
+        * the read
+        */
+-      intel_uncore_write_fw(uncore, GEN6_GDRST, hw_domain_mask);
++      do {
++              intel_uncore_write_fw(uncore, GEN6_GDRST, hw_domain_mask);
+ 
+-      /* Wait for the device to ack the reset requests */
+-      err = __intel_wait_for_register_fw(uncore,
+-                                         GEN6_GDRST, hw_domain_mask, 0,
+-                                         500, 0,
+-                                         NULL);
++              /*
++               * Wait for the device to ack the reset requests.
++               *
++               * On some platforms, e.g. Jasperlake, we see that the
++               * engine register state is not cleared until shortly after
++               * GDRST reports completion, causing a failure as we try
++               * to immediately resume while the internal state is still
++               * in flux. If we immediately repeat the reset, the second
++               * reset appears to serialise with the first, and since
++               * it is a no-op, the registers should retain their reset
++               * value. However, there is still a concern that upon
++               * leaving the second reset, the internal engine state
++               * is still in flux and not ready for resuming.
++               */
++              err = __intel_wait_for_register_fw(uncore, GEN6_GDRST,
++                                                 hw_domain_mask, 0,
++                                                 2000, 0,
++                                                 NULL);
++      } while (err == 0 && --loops);
+       if (err)
+               DRM_DEBUG_DRIVER("Wait for 0x%08x engines reset failed\n",
+                                hw_domain_mask);
+ 
++      /*
++       * As we have observed that the engine state is still volatile
++       * after GDRST is acked, impose a small delay to let everything settle.
++       */
++      udelay(50);
++
+       return err;
+ }
+ 
+diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
+index 1974e4c78a439..b3f0c20d5ba5d 100644
+--- a/drivers/gpu/drm/i915/i915_pci.c
++++ b/drivers/gpu/drm/i915/i915_pci.c
+@@ -418,7 +418,8 @@ static const struct intel_device_info 
intel_sandybridge_m_gt2_info = {
+       .has_coherent_ggtt = true, \
+       .has_llc = 1, \
+       .has_rc6 = 1, \
+-      .has_rc6p = 1, \
++      /* snb does support rc6p, but enabling it causes various issues */ \
++      .has_rc6p = 0, \
+       .has_rps = true, \
+       .ppgtt_type = INTEL_PPGTT_FULL, \
+       .ppgtt_size = 31, \
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.h 
b/drivers/infiniband/ulp/srp/ib_srp.h
+index b2861cd2087a9..3f17bfd33eb5f 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.h
++++ b/drivers/infiniband/ulp/srp/ib_srp.h
+@@ -63,9 +63,6 @@ enum {
+       SRP_DEFAULT_CMD_SQ_SIZE = SRP_DEFAULT_QUEUE_SIZE - SRP_RSP_SQ_SIZE -
+                                 SRP_TSK_MGMT_SQ_SIZE,
+ 
+-      SRP_TAG_NO_REQ          = ~0U,
+-      SRP_TAG_TSK_MGMT        = 1U << 31,
+-
+       SRP_MAX_PAGES_PER_MR    = 512,
+ 
+       SRP_MAX_ADD_CDB_LEN     = 16,
+@@ -80,6 +77,11 @@ enum {
+                                 sizeof(struct srp_imm_buf),
+ };
+ 
++enum {
++      SRP_TAG_NO_REQ          = ~0U,
++      SRP_TAG_TSK_MGMT        = BIT(31),
++};
++
+ enum srp_target_state {
+       SRP_TARGET_SCANNING,
+       SRP_TARGET_LIVE,
+diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
+index 5812ef3345feb..19840ad58a5fb 100644
+--- a/drivers/misc/fastrpc.c
++++ b/drivers/misc/fastrpc.c
+@@ -218,6 +218,13 @@ static void fastrpc_free_map(struct kref *ref)
+               dma_buf_put(map->buf);
+       }
+ 
++      if (map->fl) {
++              spin_lock(&map->fl->lock);
++              list_del(&map->node);
++              spin_unlock(&map->fl->lock);
++              map->fl = NULL;
++      }
++
+       kfree(map);
+ }
+ 
+@@ -227,10 +234,12 @@ static void fastrpc_map_put(struct fastrpc_map *map)
+               kref_put(&map->refcount, fastrpc_free_map);
+ }
+ 
+-static void fastrpc_map_get(struct fastrpc_map *map)
++static int fastrpc_map_get(struct fastrpc_map *map)
+ {
+-      if (map)
+-              kref_get(&map->refcount);
++      if (!map)
++              return -ENOENT;
++
++      return kref_get_unless_zero(&map->refcount) ? 0 : -ENOENT;
+ }
+ 
+ static int fastrpc_map_find(struct fastrpc_user *fl, int fd,
+@@ -1080,12 +1089,7 @@ err_invoke:
+       fl->init_mem = NULL;
+       fastrpc_buf_free(imem);
+ err_alloc:
+-      if (map) {
+-              spin_lock(&fl->lock);
+-              list_del(&map->node);
+-              spin_unlock(&fl->lock);
+-              fastrpc_map_put(map);
+-      }
++      fastrpc_map_put(map);
+ err:
+       kfree(args);
+ 
+@@ -1161,10 +1165,8 @@ static int fastrpc_device_release(struct inode *inode, 
struct file *file)
+               fastrpc_context_put(ctx);
+       }
+ 
+-      list_for_each_entry_safe(map, m, &fl->maps, node) {
+-              list_del(&map->node);
++      list_for_each_entry_safe(map, m, &fl->maps, node)
+               fastrpc_map_put(map);
+-      }
+ 
+       fastrpc_session_free(cctx, fl->sctx);
+       fastrpc_channel_ctx_put(cctx);
+diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
+index d577a6b0ceae2..519718bb246ce 100644
+--- a/drivers/mmc/host/sunxi-mmc.c
++++ b/drivers/mmc/host/sunxi-mmc.c
+@@ -1456,9 +1456,11 @@ static int sunxi_mmc_remove(struct platform_device 
*pdev)
+       struct sunxi_mmc_host *host = mmc_priv(mmc);
+ 
+       mmc_remove_host(mmc);
+-      pm_runtime_force_suspend(&pdev->dev);
+-      disable_irq(host->irq);
+-      sunxi_mmc_disable(host);
++      pm_runtime_disable(&pdev->dev);
++      if (!pm_runtime_status_suspended(&pdev->dev)) {
++              disable_irq(host->irq);
++              sunxi_mmc_disable(host);
++      }
+       dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
+       mmc_free_host(mmc);
+ 
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+index 092501eee9aa6..6aa175bdaddeb 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+@@ -1109,7 +1109,7 @@ static int brcmf_pcie_init_ringbuffers(struct 
brcmf_pciedev_info *devinfo)
+                               BRCMF_NROF_H2D_COMMON_MSGRINGS;
+               max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS;
+       }
+-      if (max_flowrings > 256) {
++      if (max_flowrings > 512) {
+               brcmf_err(bus, "invalid max_flowrings(%d)\n", max_flowrings);
+               return -EIO;
+       }
+diff --git a/drivers/staging/comedi/drivers/adv_pci1760.c 
b/drivers/staging/comedi/drivers/adv_pci1760.c
+index f460f21efb90c..0f6faf263c82c 100644
+--- a/drivers/staging/comedi/drivers/adv_pci1760.c
++++ b/drivers/staging/comedi/drivers/adv_pci1760.c
+@@ -59,7 +59,7 @@
+ #define PCI1760_CMD_CLR_IMB2          0x00    /* Clears IMB2 */
+ #define PCI1760_CMD_SET_DO            0x01    /* Set output state */
+ #define PCI1760_CMD_GET_DO            0x02    /* Read output status */
+-#define PCI1760_CMD_GET_STATUS                0x03    /* Read current status 
*/
++#define PCI1760_CMD_GET_STATUS                0x07    /* Read current status 
*/
+ #define PCI1760_CMD_GET_FW_VER                0x0e    /* Read firmware 
version */
+ #define PCI1760_CMD_GET_HW_VER                0x0f    /* Read hardware 
version */
+ #define PCI1760_CMD_SET_PWM_HI(x)     (0x10 + (x) * 2) /* Set "hi" period */
+diff --git a/drivers/tty/serial/atmel_serial.c 
b/drivers/tty/serial/atmel_serial.c
+index 3bd93558b4435..6c0628c58efd9 100644
+--- a/drivers/tty/serial/atmel_serial.c
++++ b/drivers/tty/serial/atmel_serial.c
+@@ -2642,13 +2642,7 @@ static void __init atmel_console_get_options(struct 
uart_port *port, int *baud,
+       else if (mr == ATMEL_US_PAR_ODD)
+               *parity = 'o';
+ 
+-      /*
+-       * The serial core only rounds down when matching this to a
+-       * supported baud rate. Make sure we don't end up slightly
+-       * lower than one of those, as it would make us fall through
+-       * to a much lower baud rate than we really want.
+-       */
+-      *baud = port->uartclk / (16 * (quot - 1));
++      *baud = port->uartclk / (16 * quot);
+ }
+ 
+ static int __init atmel_console_setup(struct console *co, char *options)
+diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
+index a8b6759140dd7..317067184bfa4 100644
+--- a/drivers/tty/serial/pch_uart.c
++++ b/drivers/tty/serial/pch_uart.c
+@@ -776,7 +776,7 @@ static void pch_dma_tx_complete(void *arg)
+       }
+       xmit->tail &= UART_XMIT_SIZE - 1;
+       async_tx_ack(priv->desc_tx);
+-      dma_unmap_sg(port->dev, sg, priv->orig_nent, DMA_TO_DEVICE);
++      dma_unmap_sg(port->dev, priv->sg_tx_p, priv->orig_nent, DMA_TO_DEVICE);
+       priv->tx_dma_use = 0;
+       priv->nent = 0;
+       priv->orig_nent = 0;
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 50c7df59f7e87..549bf04f29b27 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -41,6 +41,9 @@
+ #define USB_PRODUCT_USB5534B                  0x5534
+ #define USB_VENDOR_CYPRESS                    0x04b4
+ #define USB_PRODUCT_CY7C65632                 0x6570
++#define USB_VENDOR_TEXAS_INSTRUMENTS          0x0451
++#define USB_PRODUCT_TUSB8041_USB3             0x8140
++#define USB_PRODUCT_TUSB8041_USB2             0x8142
+ #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND      0x01
+ #define HUB_QUIRK_DISABLE_AUTOSUSPEND         0x02
+ 
+@@ -5587,6 +5590,16 @@ static const struct usb_device_id hub_id_table[] = {
+       .idVendor = USB_VENDOR_GENESYS_LOGIC,
+       .bInterfaceClass = USB_CLASS_HUB,
+       .driver_info = HUB_QUIRK_CHECK_PORT_AUTOSUSPEND},
++    { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
++                      | USB_DEVICE_ID_MATCH_PRODUCT,
++      .idVendor = USB_VENDOR_TEXAS_INSTRUMENTS,
++      .idProduct = USB_PRODUCT_TUSB8041_USB2,
++      .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND},
++    { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
++                      | USB_DEVICE_ID_MATCH_PRODUCT,
++      .idVendor = USB_VENDOR_TEXAS_INSTRUMENTS,
++      .idProduct = USB_PRODUCT_TUSB8041_USB3,
++      .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND},
+     { .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS,
+       .bDeviceClass = USB_CLASS_HUB},
+     { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
+diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
+index 9043d7242d67e..14274b60b47ba 100644
+--- a/drivers/usb/core/usb-acpi.c
++++ b/drivers/usb/core/usb-acpi.c
+@@ -37,6 +37,71 @@ bool usb_acpi_power_manageable(struct usb_device *hdev, int 
index)
+ }
+ EXPORT_SYMBOL_GPL(usb_acpi_power_manageable);
+ 
++#define UUID_USB_CONTROLLER_DSM "ce2ee385-00e6-48cb-9f05-2edb927c4899"
++#define USB_DSM_DISABLE_U1_U2_FOR_PORT        5
++
++/**
++ * usb_acpi_port_lpm_incapable - check if lpm should be disabled for a port.
++ * @hdev: USB device belonging to the usb hub
++ * @index: zero based port index
++ *
++ * Some USB3 ports may not support USB3 link power management U1/U2 states
++ * due to different retimer setup. ACPI provides _DSM method which returns 
0x01
++ * if U1 and U2 states should be disabled. Evaluate _DSM with:
++ * Arg0: UUID = ce2ee385-00e6-48cb-9f05-2edb927c4899
++ * Arg1: Revision ID = 0
++ * Arg2: Function Index = 5
++ * Arg3: (empty)
++ *
++ * Return 1 if USB3 port is LPM incapable, negative on error, otherwise 0
++ */
++
++int usb_acpi_port_lpm_incapable(struct usb_device *hdev, int index)
++{
++      union acpi_object *obj;
++      acpi_handle port_handle;
++      int port1 = index + 1;
++      guid_t guid;
++      int ret;
++
++      ret = guid_parse(UUID_USB_CONTROLLER_DSM, &guid);
++      if (ret)
++              return ret;
++
++      port_handle = usb_get_hub_port_acpi_handle(hdev, port1);
++      if (!port_handle) {
++              dev_dbg(&hdev->dev, "port-%d no acpi handle\n", port1);
++              return -ENODEV;
++      }
++
++      if (!acpi_check_dsm(port_handle, &guid, 0,
++                          BIT(USB_DSM_DISABLE_U1_U2_FOR_PORT))) {
++              dev_dbg(&hdev->dev, "port-%d no _DSM function %d\n",
++                      port1, USB_DSM_DISABLE_U1_U2_FOR_PORT);
++              return -ENODEV;
++      }
++
++      obj = acpi_evaluate_dsm(port_handle, &guid, 0,
++                              USB_DSM_DISABLE_U1_U2_FOR_PORT, NULL);
++
++      if (!obj)
++              return -ENODEV;
++
++      if (obj->type != ACPI_TYPE_INTEGER) {
++              dev_dbg(&hdev->dev, "evaluate port-%d _DSM failed\n", port1);
++              ACPI_FREE(obj);
++              return -EINVAL;
++      }
++
++      if (obj->integer.value == 0x01)
++              ret = 1;
++
++      ACPI_FREE(obj);
++
++      return ret;
++}
++EXPORT_SYMBOL_GPL(usb_acpi_port_lpm_incapable);
++
+ /**
+  * usb_acpi_set_power_state - control usb port's power via acpi power
+  * resource
+diff --git a/drivers/usb/gadget/function/f_ncm.c 
b/drivers/usb/gadget/function/f_ncm.c
+index 9b19d6935df99..5558ea5ac77af 100644
+--- a/drivers/usb/gadget/function/f_ncm.c
++++ b/drivers/usb/gadget/function/f_ncm.c
+@@ -85,7 +85,9 @@ static inline struct f_ncm *func_to_ncm(struct usb_function 
*f)
+ /* peak (theoretical) bulk transfer rate in bits-per-second */
+ static inline unsigned ncm_bitrate(struct usb_gadget *g)
+ {
+-      if (gadget_is_superspeed(g) && g->speed >= USB_SPEED_SUPER_PLUS)
++      if (!g)
++              return 0;
++      else if (gadget_is_superspeed(g) && g->speed >= USB_SPEED_SUPER_PLUS)
+               return 4250000000U;
+       else if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER)
+               return 3750000000U;
+diff --git a/drivers/usb/gadget/legacy/inode.c 
b/drivers/usb/gadget/legacy/inode.c
+index 97c73d610eeb4..dd72e75beb82e 100644
+--- a/drivers/usb/gadget/legacy/inode.c
++++ b/drivers/usb/gadget/legacy/inode.c
+@@ -229,6 +229,7 @@ static void put_ep (struct ep_data *data)
+  */
+ 
+ static const char *CHIP;
++static DEFINE_MUTEX(sb_mutex);                /* Serialize superblock 
operations */
+ 
+ /*----------------------------------------------------------------------*/
+ 
+@@ -2013,13 +2014,20 @@ gadgetfs_fill_super (struct super_block *sb, struct 
fs_context *fc)
+ {
+       struct inode    *inode;
+       struct dev_data *dev;
++      int             rc;
+ 
+-      if (the_device)
+-              return -ESRCH;
++      mutex_lock(&sb_mutex);
++
++      if (the_device) {
++              rc = -ESRCH;
++              goto Done;
++      }
+ 
+       CHIP = usb_get_gadget_udc_name();
+-      if (!CHIP)
+-              return -ENODEV;
++      if (!CHIP) {
++              rc = -ENODEV;
++              goto Done;
++      }
+ 
+       /* superblock */
+       sb->s_blocksize = PAGE_SIZE;
+@@ -2056,13 +2064,17 @@ gadgetfs_fill_super (struct super_block *sb, struct 
fs_context *fc)
+        * from binding to a controller.
+        */
+       the_device = dev;
+-      return 0;
++      rc = 0;
++      goto Done;
+ 
+-Enomem:
++ Enomem:
+       kfree(CHIP);
+       CHIP = NULL;
++      rc = -ENOMEM;
+ 
+-      return -ENOMEM;
++ Done:
++      mutex_unlock(&sb_mutex);
++      return rc;
+ }
+ 
+ /* "mount -t gadgetfs path /dev/gadget" ends up here */
+@@ -2084,6 +2096,7 @@ static int gadgetfs_init_fs_context(struct fs_context 
*fc)
+ static void
+ gadgetfs_kill_sb (struct super_block *sb)
+ {
++      mutex_lock(&sb_mutex);
+       kill_litter_super (sb);
+       if (the_device) {
+               put_dev (the_device);
+@@ -2091,6 +2104,7 @@ gadgetfs_kill_sb (struct super_block *sb)
+       }
+       kfree(CHIP);
+       CHIP = NULL;
++      mutex_unlock(&sb_mutex);
+ }
+ 
+ /*----------------------------------------------------------------------*/
+diff --git a/drivers/usb/gadget/legacy/webcam.c 
b/drivers/usb/gadget/legacy/webcam.c
+index 2c9eab2b863d2..ff970a9433479 100644
+--- a/drivers/usb/gadget/legacy/webcam.c
++++ b/drivers/usb/gadget/legacy/webcam.c
+@@ -293,6 +293,7 @@ static const struct uvc_descriptor_header * const 
uvc_fs_streaming_cls[] = {
+       (const struct uvc_descriptor_header *) &uvc_format_yuv,
+       (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
+       (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
++      (const struct uvc_descriptor_header *) &uvc_color_matching,
+       (const struct uvc_descriptor_header *) &uvc_format_mjpg,
+       (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
+       (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
+@@ -305,6 +306,7 @@ static const struct uvc_descriptor_header * const 
uvc_hs_streaming_cls[] = {
+       (const struct uvc_descriptor_header *) &uvc_format_yuv,
+       (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
+       (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
++      (const struct uvc_descriptor_header *) &uvc_color_matching,
+       (const struct uvc_descriptor_header *) &uvc_format_mjpg,
+       (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
+       (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
+@@ -317,6 +319,7 @@ static const struct uvc_descriptor_header * const 
uvc_ss_streaming_cls[] = {
+       (const struct uvc_descriptor_header *) &uvc_format_yuv,
+       (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
+       (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
++      (const struct uvc_descriptor_header *) &uvc_color_matching,
+       (const struct uvc_descriptor_header *) &uvc_format_mjpg,
+       (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
+       (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
+diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
+index 9e9c232e896fa..b66cc64f084c6 100644
+--- a/drivers/usb/host/ehci-fsl.c
++++ b/drivers/usb/host/ehci-fsl.c
+@@ -29,7 +29,7 @@
+ #include "ehci-fsl.h"
+ 
+ #define DRIVER_DESC "Freescale EHCI Host controller driver"
+-#define DRV_NAME "ehci-fsl"
++#define DRV_NAME "fsl-ehci"
+ 
+ static struct hc_driver __read_mostly fsl_ehci_hc_driver;
+ 
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
+index 8bd55e51ecfc5..aa4c21a12de71 100644
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -79,9 +79,12 @@ static const char hcd_name[] = "xhci_hcd";
+ static struct hc_driver __read_mostly xhci_pci_hc_driver;
+ 
+ static int xhci_pci_setup(struct usb_hcd *hcd);
++static int xhci_pci_update_hub_device(struct usb_hcd *hcd, struct usb_device 
*hdev,
++                                    struct usb_tt *tt, gfp_t mem_flags);
+ 
+ static const struct xhci_driver_overrides xhci_pci_overrides __initconst = {
+       .reset = xhci_pci_setup,
++      .update_hub_device = xhci_pci_update_hub_device,
+ };
+ 
+ /* called after powerup, by probe or system-pm "wakeup" */
+@@ -336,8 +339,38 @@ static void xhci_pme_acpi_rtd3_enable(struct pci_dev *dev)
+                               NULL);
+       ACPI_FREE(obj);
+ }
++
++static void xhci_find_lpm_incapable_ports(struct usb_hcd *hcd, struct 
usb_device *hdev)
++{
++      struct xhci_hcd *xhci = hcd_to_xhci(hcd);
++      struct xhci_hub *rhub = &xhci->usb3_rhub;
++      int ret;
++      int i;
++
++      /* This is not the usb3 roothub we are looking for */
++      if (hcd != rhub->hcd)
++              return;
++
++      if (hdev->maxchild > rhub->num_ports) {
++              dev_err(&hdev->dev, "USB3 roothub port number mismatch\n");
++              return;
++      }
++
++      for (i = 0; i < hdev->maxchild; i++) {
++              ret = usb_acpi_port_lpm_incapable(hdev, i);
++
++              dev_dbg(&hdev->dev, "port-%d disable U1/U2 _DSM: %d\n", i + 1, 
ret);
++
++              if (ret >= 0) {
++                      rhub->ports[i]->lpm_incapable = ret;
++                      continue;
++              }
++      }
++}
++
+ #else
+ static void xhci_pme_acpi_rtd3_enable(struct pci_dev *dev) { }
++static void xhci_find_lpm_incapable_ports(struct usb_hcd *hcd, struct 
usb_device *hdev) { }
+ #endif /* CONFIG_ACPI */
+ 
+ /* called during probe() after chip reset completes */
+@@ -370,6 +403,16 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
+       return xhci_pci_reinit(xhci, pdev);
+ }
+ 
++static int xhci_pci_update_hub_device(struct usb_hcd *hcd, struct usb_device 
*hdev,
++                                    struct usb_tt *tt, gfp_t mem_flags)
++{
++      /* Check if acpi claims some USB3 roothub ports are lpm incapable */
++      if (!hdev->parent)
++              xhci_find_lpm_incapable_ports(hcd, hdev);
++
++      return xhci_update_hub_device(hcd, hdev, tt, mem_flags);
++}
++
+ /*
+  * We need to register our own PCI probe function (instead of the USB core's
+  * function) in order to create a second roothub under xHCI.
+@@ -427,6 +470,8 @@ static int xhci_pci_probe(struct pci_dev *dev, const 
struct pci_device_id *id)
+       if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW)
+               pm_runtime_allow(&dev->dev);
+ 
++      dma_set_max_seg_size(&dev->dev, UINT_MAX);
++
+       return 0;
+ 
+ put_usb3_hcd:
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 6cedae902adf9..e6faabe65bd5d 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -921,7 +921,10 @@ static void xhci_kill_endpoint_urbs(struct xhci_hcd *xhci,
+       struct xhci_virt_ep *ep;
+       struct xhci_ring *ring;
+ 
+-      ep = &xhci->devs[slot_id]->eps[ep_index];
++      ep = xhci_get_virt_ep(xhci, slot_id, ep_index);
++      if (!ep)
++              return;
++
+       if ((ep->ep_state & EP_HAS_STREAMS) ||
+                       (ep->ep_state & EP_GETTING_NO_STREAMS)) {
+               int stream_id;
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index 3537113f006fa..35d96796854d6 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -3909,6 +3909,7 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct 
usb_device *udev)
+       struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+       struct xhci_virt_device *virt_dev;
+       struct xhci_slot_ctx *slot_ctx;
++      unsigned long flags;
+       int i, ret;
+ 
+       /*
+@@ -3937,7 +3938,11 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct 
usb_device *udev)
+       }
+       virt_dev->udev = NULL;
+       xhci_disable_slot(xhci, udev->slot_id);
++
++      spin_lock_irqsave(&xhci->lock, flags);
+       xhci_free_virt_device(xhci, udev->slot_id);
++      spin_unlock_irqrestore(&xhci->lock, flags);
++
+ }
+ 
+ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id)
+@@ -4994,6 +4999,7 @@ static int xhci_enable_usb3_lpm_timeout(struct usb_hcd 
*hcd,
+                       struct usb_device *udev, enum usb3_link_state state)
+ {
+       struct xhci_hcd *xhci;
++      struct xhci_port *port;
+       u16 hub_encoded_timeout;
+       int mel;
+       int ret;
+@@ -5007,6 +5013,13 @@ static int xhci_enable_usb3_lpm_timeout(struct usb_hcd 
*hcd,
+                       !xhci->devs[udev->slot_id])
+               return USB3_LPM_DISABLED;
+ 
++      /* If connected to root port then check port can handle lpm */
++      if (udev->parent && !udev->parent->parent) {
++              port = xhci->usb3_rhub.ports[udev->portnum - 1];
++              if (port->lpm_incapable)
++                      return USB3_LPM_DISABLED;
++      }
++
+       hub_encoded_timeout = xhci_calculate_lpm_timeout(hcd, udev, state);
+       mel = calculate_max_exit_latency(udev, state, hub_encoded_timeout);
+       if (mel < 0) {
+@@ -5066,7 +5079,7 @@ static int xhci_disable_usb3_lpm_timeout(struct usb_hcd 
*hcd,
+ /* Once a hub descriptor is fetched for a device, we need to update the xHC's
+  * internal data structures for the device.
+  */
+-static int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device 
*hdev,
++int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
+                       struct usb_tt *tt, gfp_t mem_flags)
+ {
+       struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+@@ -5166,6 +5179,7 @@ static int xhci_update_hub_device(struct usb_hcd *hcd, 
struct usb_device *hdev,
+       xhci_free_command(xhci, config_cmd);
+       return ret;
+ }
++EXPORT_SYMBOL_GPL(xhci_update_hub_device);
+ 
+ static int xhci_get_frame(struct usb_hcd *hcd)
+ {
+@@ -5435,6 +5449,8 @@ void xhci_init_driver(struct hc_driver *drv,
+                       drv->check_bandwidth = over->check_bandwidth;
+               if (over->reset_bandwidth)
+                       drv->reset_bandwidth = over->reset_bandwidth;
++              if (over->update_hub_device)
++                      drv->update_hub_device = over->update_hub_device;
+       }
+ }
+ EXPORT_SYMBOL_GPL(xhci_init_driver);
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 0dc448630197c..e696f1508318e 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1724,6 +1724,7 @@ struct xhci_port {
+       int                     hcd_portnum;
+       struct xhci_hub         *rhub;
+       struct xhci_port_cap    *port_cap;
++      unsigned int            lpm_incapable:1;
+ };
+ 
+ struct xhci_hub {
+@@ -1922,6 +1923,8 @@ struct xhci_driver_overrides {
+       int (*start)(struct usb_hcd *hcd);
+       int (*check_bandwidth)(struct usb_hcd *, struct usb_device *);
+       void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *);
++      int (*update_hub_device)(struct usb_hcd *hcd, struct usb_device *hdev,
++                          struct usb_tt *tt, gfp_t mem_flags);
+ };
+ 
+ #define       XHCI_CFC_DELAY          10
+@@ -2076,6 +2079,8 @@ void xhci_init_driver(struct hc_driver *drv,
+                     const struct xhci_driver_overrides *over);
+ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
+ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
++int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
++                         struct usb_tt *tt, gfp_t mem_flags);
+ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id);
+ int xhci_ext_cap_init(struct xhci_hcd *xhci);
+ 
+diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
+index 888defdea546f..c366a65fbd802 100644
+--- a/drivers/usb/misc/iowarrior.c
++++ b/drivers/usb/misc/iowarrior.c
+@@ -817,7 +817,7 @@ static int iowarrior_probe(struct usb_interface *interface,
+                       break;
+ 
+               case USB_DEVICE_ID_CODEMERCS_IOW100:
+-                      dev->report_size = 13;
++                      dev->report_size = 12;
+                       break;
+               }
+       }
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index 9992c5aa5ff47..4cd46fc9fcad4 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -61,6 +61,7 @@ static const struct usb_device_id id_table[] = {
+       { USB_DEVICE(0x0846, 0x1100) }, /* NetGear Managed Switch M4100 series, 
M5300 series, M7100 series */
+       { 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, 0x0070) }, /* Siemens SCALANCE LPE-9000 USB Serial 
Console */
+       { USB_DEVICE(0x0908, 0x01FF) }, /* Siemens RUGGEDCOM USB Serial Console 
*/
+       { USB_DEVICE(0x0988, 0x0578) }, /* Teraoka AD2000 */
+       { USB_DEVICE(0x0B00, 0x3070) }, /* Ingenico 3070 */
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 08a368a0f7457..159b01b9e1727 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -255,10 +255,16 @@ static void option_instat_callback(struct urb *urb);
+ #define QUECTEL_PRODUCT_EP06                  0x0306
+ #define QUECTEL_PRODUCT_EM05G                 0x030a
+ #define QUECTEL_PRODUCT_EM060K                        0x030b
++#define QUECTEL_PRODUCT_EM05G_CS              0x030c
++#define QUECTEL_PRODUCT_EM05CN_SG             0x0310
+ #define QUECTEL_PRODUCT_EM05G_SG              0x0311
++#define QUECTEL_PRODUCT_EM05CN                        0x0312
++#define QUECTEL_PRODUCT_EM05G_GR              0x0313
++#define QUECTEL_PRODUCT_EM05G_RS              0x0314
+ #define QUECTEL_PRODUCT_EM12                  0x0512
+ #define QUECTEL_PRODUCT_RM500Q                        0x0800
+ #define QUECTEL_PRODUCT_RM520N                        0x0801
++#define QUECTEL_PRODUCT_EC200U                        0x0901
+ #define QUECTEL_PRODUCT_EC200S_CN             0x6002
+ #define QUECTEL_PRODUCT_EC200T                        0x6026
+ #define QUECTEL_PRODUCT_RM500K                        0x7001
+@@ -1159,8 +1165,18 @@ static const struct usb_device_id option_ids[] = {
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff),
+         .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_EP06, 0xff, 0, 0) },
++      { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05CN, 
0xff),
++        .driver_info = RSVD(6) | ZLP },
++      { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_EM05CN_SG, 0xff),
++        .driver_info = RSVD(6) | ZLP },
+       { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G, 
0xff),
+         .driver_info = RSVD(6) | ZLP },
++      { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_EM05G_GR, 0xff),
++        .driver_info = RSVD(6) | ZLP },
++      { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_EM05G_CS, 0xff),
++        .driver_info = RSVD(6) | ZLP },
++      { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_EM05G_RS, 0xff),
++        .driver_info = RSVD(6) | ZLP },
+       { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_EM05G_SG, 0xff),
+         .driver_info = RSVD(6) | ZLP },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) },
+@@ -1180,6 +1196,7 @@ static const struct usb_device_id option_ids[] = {
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_RM520N, 0xff, 0xff, 0x30) },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_RM520N, 0xff, 0, 0x40) },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_RM520N, 0xff, 0, 0) },
++      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_EC200U, 0xff, 0, 0) },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 
QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) },
+diff --git a/drivers/usb/storage/uas-detect.h 
b/drivers/usb/storage/uas-detect.h
+index 3734a25e09e53..44f0b78be8a96 100644
+--- a/drivers/usb/storage/uas-detect.h
++++ b/drivers/usb/storage/uas-detect.h
+@@ -116,6 +116,19 @@ static int uas_use_uas_driver(struct usb_interface *intf,
+       if (le16_to_cpu(udev->descriptor.idVendor) == 0x0bc2)
+               flags |= US_FL_NO_ATA_1X;
+ 
++      /*
++       * RTL9210-based enclosure from HIKSEMI, MD202 reportedly have issues
++       * with UAS.  This isn't distinguishable with just idVendor and
++       * idProduct, use manufacturer and product too.
++       *
++       * Reported-by: Hongling Zeng <[email protected]>
++       */
++      if (le16_to_cpu(udev->descriptor.idVendor) == 0x0bda &&
++                      le16_to_cpu(udev->descriptor.idProduct) == 0x9210 &&
++                      (udev->manufacturer && !strcmp(udev->manufacturer, 
"HIKSEMI")) &&
++                      (udev->product && !strcmp(udev->product, "MD202")))
++              flags |= US_FL_IGNORE_UAS;
++
+       usb_stor_adjust_quirks(udev, &flags);
+ 
+       if (flags & US_FL_IGNORE_UAS) {
+diff --git a/drivers/usb/storage/unusual_uas.h 
b/drivers/usb/storage/unusual_uas.h
+index 92e9bd006622d..d4fa29b623ff9 100644
+--- a/drivers/usb/storage/unusual_uas.h
++++ b/drivers/usb/storage/unusual_uas.h
+@@ -83,13 +83,6 @@ UNUSUAL_DEV(0x0bc2, 0x331a, 0x0000, 0x9999,
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_NO_REPORT_LUNS),
+ 
+-/* Reported-by: Hongling Zeng <[email protected]> */
+-UNUSUAL_DEV(0x0bda, 0x9210, 0x0000, 0x9999,
+-              "Hiksemi",
+-              "External HDD",
+-              USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+-              US_FL_IGNORE_UAS),
+-
+ /* Reported-by: Benjamin Tissoires <[email protected]> */
+ UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999,
+               "Initio Corporation",
+diff --git a/drivers/usb/typec/altmodes/displayport.c 
b/drivers/usb/typec/altmodes/displayport.c
+index 0b5cbf5ed1ca6..1aa1bd991ef43 100644
+--- a/drivers/usb/typec/altmodes/displayport.c
++++ b/drivers/usb/typec/altmodes/displayport.c
+@@ -407,6 +407,18 @@ static const char * const pin_assignments[] = {
+       [DP_PIN_ASSIGN_F] = "F",
+ };
+ 
++/*
++ * Helper function to extract a peripheral's currently supported
++ * Pin Assignments from its DisplayPort alternate mode state.
++ */
++static u8 get_current_pin_assignments(struct dp_altmode *dp)
++{
++      if (DP_CONF_CURRENTLY(dp->data.conf) == DP_CONF_DFP_D)
++              return DP_CAP_PIN_ASSIGN_DFP_D(dp->alt->vdo);
++      else
++              return DP_CAP_PIN_ASSIGN_UFP_D(dp->alt->vdo);
++}
++
+ static ssize_t
+ pin_assignment_store(struct device *dev, struct device_attribute *attr,
+                    const char *buf, size_t size)
+@@ -433,10 +445,7 @@ pin_assignment_store(struct device *dev, struct 
device_attribute *attr,
+               goto out_unlock;
+       }
+ 
+-      if (DP_CONF_CURRENTLY(dp->data.conf) == DP_CONF_DFP_D)
+-              assignments = DP_CAP_UFP_D_PIN_ASSIGN(dp->alt->vdo);
+-      else
+-              assignments = DP_CAP_DFP_D_PIN_ASSIGN(dp->alt->vdo);
++      assignments = get_current_pin_assignments(dp);
+ 
+       if (!(DP_CONF_GET_PIN_ASSIGN(conf) & assignments)) {
+               ret = -EINVAL;
+@@ -473,10 +482,7 @@ static ssize_t pin_assignment_show(struct device *dev,
+ 
+       cur = get_count_order(DP_CONF_GET_PIN_ASSIGN(dp->data.conf));
+ 
+-      if (DP_CONF_CURRENTLY(dp->data.conf) == DP_CONF_DFP_D)
+-              assignments = DP_CAP_UFP_D_PIN_ASSIGN(dp->alt->vdo);
+-      else
+-              assignments = DP_CAP_DFP_D_PIN_ASSIGN(dp->alt->vdo);
++      assignments = get_current_pin_assignments(dp);
+ 
+       for (i = 0; assignments; assignments >>= 1, i++) {
+               if (assignments & 1) {
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index 5c8507e74bc17..353e89efdebf8 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -3209,6 +3209,7 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work 
*work)
+       int err = -ENOMEM;
+       int ret = 0;
+       bool stopped = false;
++      bool did_leaf_rescans = false;
+ 
+       path = btrfs_alloc_path();
+       if (!path)
+@@ -3229,6 +3230,7 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work 
*work)
+               }
+ 
+               err = qgroup_rescan_leaf(trans, path);
++              did_leaf_rescans = true;
+ 
+               if (err > 0)
+                       btrfs_commit_transaction(trans);
+@@ -3249,16 +3251,23 @@ out:
+       mutex_unlock(&fs_info->qgroup_rescan_lock);
+ 
+       /*
+-       * only update status, since the previous part has already updated the
+-       * qgroup info.
++       * Only update status, since the previous part has already updated the
++       * qgroup info, and only if we did any actual work. This also prevents
++       * race with a concurrent quota disable, which has already set
++       * fs_info->quota_root to NULL and cleared BTRFS_FS_QUOTA_ENABLED at
++       * btrfs_quota_disable().
+        */
+-      trans = btrfs_start_transaction(fs_info->quota_root, 1);
+-      if (IS_ERR(trans)) {
+-              err = PTR_ERR(trans);
++      if (did_leaf_rescans) {
++              trans = btrfs_start_transaction(fs_info->quota_root, 1);
++              if (IS_ERR(trans)) {
++                      err = PTR_ERR(trans);
++                      trans = NULL;
++                      btrfs_err(fs_info,
++                                "fail to start transaction for status update: 
%d",
++                                err);
++              }
++      } else {
+               trans = NULL;
+-              btrfs_err(fs_info,
+-                        "fail to start transaction for status update: %d",
+-                        err);
+       }
+ 
+       mutex_lock(&fs_info->qgroup_rescan_lock);
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index ec2dbb8df3d32..da1a1b531ca5e 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -3639,12 +3639,15 @@ smb2_readv_callback(struct mid_q_entry *mid)
+                               (struct smb2_sync_hdr *)rdata->iov[0].iov_base;
+       struct cifs_credits credits = { .value = 0, .instance = 0 };
+       struct smb_rqst rqst = { .rq_iov = &rdata->iov[1],
+-                               .rq_nvec = 1,
+-                               .rq_pages = rdata->pages,
+-                               .rq_offset = rdata->page_offset,
+-                               .rq_npages = rdata->nr_pages,
+-                               .rq_pagesz = rdata->pagesz,
+-                               .rq_tailsz = rdata->tailsz };
++                               .rq_nvec = 1, };
++
++      if (rdata->got_bytes) {
++              rqst.rq_pages = rdata->pages;
++              rqst.rq_offset = rdata->page_offset;
++              rqst.rq_npages = rdata->nr_pages;
++              rqst.rq_pagesz = rdata->pagesz;
++              rqst.rq_tailsz = rdata->tailsz;
++      }
+ 
+       cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
+                __func__, mid->mid, mid->mid_state, rdata->result,
+diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
+index 05b17a741ccc0..dd53c9294ad95 100644
+--- a/fs/f2fs/extent_cache.c
++++ b/fs/f2fs/extent_cache.c
+@@ -381,7 +381,8 @@ static bool f2fs_lookup_extent_tree(struct inode *inode, 
pgoff_t pgofs,
+       struct extent_node *en;
+       bool ret = false;
+ 
+-      f2fs_bug_on(sbi, !et);
++      if (!et)
++              return false;
+ 
+       trace_f2fs_lookup_extent_tree_start(inode, pgofs);
+ 
+diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c
+index 98b74cdabb99a..8c72718d9fe01 100644
+--- a/fs/nfs/filelayout/filelayout.c
++++ b/fs/nfs/filelayout/filelayout.c
+@@ -837,6 +837,12 @@ filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid,
+       return &fl->generic_hdr;
+ }
+ 
++static bool
++filelayout_lseg_is_striped(const struct nfs4_filelayout_segment *flseg)
++{
++      return flseg->num_fh > 1;
++}
++
+ /*
+  * filelayout_pg_test(). Called by nfs_can_coalesce_requests()
+  *
+@@ -857,6 +863,8 @@ filelayout_pg_test(struct nfs_pageio_descriptor *pgio, 
struct nfs_page *prev,
+       size = pnfs_generic_pg_test(pgio, prev, req);
+       if (!size)
+               return 0;
++      else if (!filelayout_lseg_is_striped(FILELAYOUT_LSEG(pgio->pg_lseg)))
++              return size;
+ 
+       /* see if req and prev are in the same stripe */
+       if (prev) {
+diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
+index 919d1238ce45f..a0e37530dcf30 100644
+--- a/fs/nilfs2/btree.c
++++ b/fs/nilfs2/btree.c
+@@ -480,9 +480,18 @@ static int __nilfs_btree_get_block(const struct 
nilfs_bmap *btree, __u64 ptr,
+       ret = nilfs_btnode_submit_block(btnc, ptr, 0, REQ_OP_READ, 0, &bh,
+                                       &submit_ptr);
+       if (ret) {
+-              if (ret != -EEXIST)
+-                      return ret;
+-              goto out_check;
++              if (likely(ret == -EEXIST))
++                      goto out_check;
++              if (ret == -ENOENT) {
++                      /*
++                       * Block address translation failed due to invalid
++                       * value of 'ptr'.  In this case, return internal code
++                       * -EINVAL (broken bmap) to notify bmap layer of fatal
++                       * metadata corruption.
++                       */
++                      ret = -EINVAL;
++              }
++              return ret;
+       }
+ 
+       if (ra) {
+diff --git a/include/linux/usb.h b/include/linux/usb.h
+index 703c7464d8957..c4e919cbbec7a 100644
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -751,11 +751,14 @@ extern void usb_queue_reset_device(struct usb_interface 
*dev);
+ extern int usb_acpi_set_power_state(struct usb_device *hdev, int index,
+       bool enable);
+ extern bool usb_acpi_power_manageable(struct usb_device *hdev, int index);
++extern int usb_acpi_port_lpm_incapable(struct usb_device *hdev, int index);
+ #else
+ static inline int usb_acpi_set_power_state(struct usb_device *hdev, int index,
+       bool enable) { return 0; }
+ static inline bool usb_acpi_power_manageable(struct usb_device *hdev, int 
index)
+       { return true; }
++static inline int usb_acpi_port_lpm_incapable(struct usb_device *hdev, int 
index)
++      { return 0; }
+ #endif
+ 
+ /* USB autosuspend and autoresume */
+diff --git a/kernel/sys.c b/kernel/sys.c
+index b075fe84eb5a5..f6d6ce8da3e4a 100644
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -1534,6 +1534,8 @@ int do_prlimit(struct task_struct *tsk, unsigned int 
resource,
+ 
+       if (resource >= RLIM_NLIMITS)
+               return -EINVAL;
++      resource = array_index_nospec(resource, RLIM_NLIMITS);
++
+       if (new_rlim) {
+               if (new_rlim->rlim_cur > new_rlim->rlim_max)
+                       return -EINVAL;
+diff --git a/mm/khugepaged.c b/mm/khugepaged.c
+index 8e67d2e5ff39c..f1f98305433e9 100644
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -1328,14 +1328,6 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, 
unsigned long addr)
+       if (!hugepage_vma_check(vma, vma->vm_flags | VM_HUGEPAGE))
+               return;
+ 
+-      /*
+-       * Symmetry with retract_page_tables(): Exclude MAP_PRIVATE mappings
+-       * that got written to. Without this, we'd have to also lock the
+-       * anon_vma if one exists.
+-       */
+-      if (vma->anon_vma)
+-              return;
+-
+       hpage = find_lock_page(vma->vm_file->f_mapping,
+                              linear_page_index(vma, haddr));
+       if (!hpage)
+@@ -1407,6 +1399,10 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, 
unsigned long addr)
+       }
+ 
+       /* step 4: collapse pmd */
++      /* we make no change to anon, but protect concurrent anon page lookup */
++      if (vma->anon_vma)
++              anon_vma_lock_write(vma->anon_vma);
++
+       mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, NULL, mm, haddr,
+                               haddr + HPAGE_PMD_SIZE);
+       mmu_notifier_invalidate_range_start(&range);
+@@ -1416,6 +1412,8 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, 
unsigned long addr)
+       mmu_notifier_invalidate_range_end(&range);
+       pte_free(mm, pmd_pgtable(_pmd));
+ 
++      if (vma->anon_vma)
++              anon_vma_unlock_write(vma->anon_vma);
+       i_mmap_unlock_write(vma->vm_file->f_mapping);
+ 
+ drop_hpage:
+diff --git a/net/core/ethtool.c b/net/core/ethtool.c
+index cbd1885f24592..9ae38c3e2bf0a 100644
+--- a/net/core/ethtool.c
++++ b/net/core/ethtool.c
+@@ -1947,7 +1947,8 @@ static int ethtool_get_phy_stats(struct net_device *dev, 
void __user *useraddr)
+               return n_stats;
+       if (n_stats > S32_MAX / sizeof(u64))
+               return -ENOMEM;
+-      WARN_ON_ONCE(!n_stats);
++      if (WARN_ON_ONCE(!n_stats))
++              return -EOPNOTSUPP;
+ 
+       if (copy_from_user(&stats, useraddr, sizeof(stats)))
+               return -EFAULT;
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index ee4f70cea76ef..413d4886f3d28 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -3503,6 +3503,15 @@ static void alc256_init(struct hda_codec *codec)
+       hda_nid_t hp_pin = alc_get_hp_pin(spec);
+       bool hp_pin_sense;
+ 
++      if (spec->ultra_low_power) {
++              alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1);
++              alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2);
++              alc_update_coef_idx(codec, 0x08, 7<<4, 0);
++              alc_update_coef_idx(codec, 0x3b, 1<<15, 0);
++              alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
++              msleep(30);
++      }
++
+       if (!hp_pin)
+               hp_pin = 0x21;
+ 
+@@ -3514,14 +3523,6 @@ static void alc256_init(struct hda_codec *codec)
+               msleep(2);
+ 
+       alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
+-      if (spec->ultra_low_power) {
+-              alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1);
+-              alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2);
+-              alc_update_coef_idx(codec, 0x08, 7<<4, 0);
+-              alc_update_coef_idx(codec, 0x3b, 1<<15, 0);
+-              alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
+-              msleep(30);
+-      }
+ 
+       snd_hda_codec_write(codec, hp_pin, 0,
+                           AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+@@ -3603,6 +3604,13 @@ static void alc225_init(struct hda_codec *codec)
+       hda_nid_t hp_pin = alc_get_hp_pin(spec);
+       bool hp1_pin_sense, hp2_pin_sense;
+ 
++      if (spec->ultra_low_power) {
++              alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
++              alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
++              alc_update_coef_idx(codec, 0x33, 1<<11, 0);
++              msleep(30);
++      }
++
+       if (!hp_pin)
+               hp_pin = 0x21;
+       msleep(30);
+@@ -3614,12 +3622,6 @@ static void alc225_init(struct hda_codec *codec)
+               msleep(2);
+ 
+       alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
+-      if (spec->ultra_low_power) {
+-              alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2);
+-              alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6);
+-              alc_update_coef_idx(codec, 0x33, 1<<11, 0);
+-              msleep(30);
+-      }
+ 
+       if (hp1_pin_sense || spec->ultra_low_power)
+               snd_hda_codec_write(codec, hp_pin, 0,
+diff --git a/tools/testing/selftests/bpf/prog_tests/jeq_infer_not_null.c 
b/tools/testing/selftests/bpf/prog_tests/jeq_infer_not_null.c
+new file mode 100644
+index 0000000000000..3add34df57678
+--- /dev/null
++++ b/tools/testing/selftests/bpf/prog_tests/jeq_infer_not_null.c
+@@ -0,0 +1,9 @@
++// SPDX-License-Identifier: GPL-2.0
++
++#include <test_progs.h>
++#include "jeq_infer_not_null_fail.skel.h"
++
++void test_jeq_infer_not_null(void)
++{
++      RUN_TESTS(jeq_infer_not_null_fail);
++}
+diff --git a/tools/testing/selftests/bpf/progs/jeq_infer_not_null_fail.c 
b/tools/testing/selftests/bpf/progs/jeq_infer_not_null_fail.c
+new file mode 100644
+index 0000000000000..f46965053acb2
+--- /dev/null
++++ b/tools/testing/selftests/bpf/progs/jeq_infer_not_null_fail.c
+@@ -0,0 +1,42 @@
++// SPDX-License-Identifier: GPL-2.0
++
++#include "vmlinux.h"
++#include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
++
++char _license[] SEC("license") = "GPL";
++
++struct {
++      __uint(type, BPF_MAP_TYPE_HASH);
++      __uint(max_entries, 1);
++      __type(key, u64);
++      __type(value, u64);
++} m_hash SEC(".maps");
++
++SEC("?raw_tp")
++__failure __msg("R8 invalid mem access 'map_value_or_null")
++int jeq_infer_not_null_ptr_to_btfid(void *ctx)
++{
++      struct bpf_map *map = (struct bpf_map *)&m_hash;
++      struct bpf_map *inner_map = map->inner_map_meta;
++      u64 key = 0, ret = 0, *val;
++
++      val = bpf_map_lookup_elem(map, &key);
++      /* Do not mark ptr as non-null if one of them is
++       * PTR_TO_BTF_ID (R9), reject because of invalid
++       * access to map value (R8).
++       *
++       * Here, we need to inline those insns to access
++       * R8 directly, since compiler may use other reg
++       * once it figures out val==inner_map.
++       */
++      asm volatile("r8 = %[val];\n"
++                   "r9 = %[inner_map];\n"
++                   "if r8 != r9 goto +1;\n"
++                   "%[ret] = *(u64 *)(r8 +0);\n"
++                   : [ret] "+r"(ret)
++                   : [inner_map] "r"(inner_map), [val] "r"(val)
++                   : "r8", "r9");
++
++      return ret;
++}

Reply via email to