]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.1
authorSasha Levin <sashal@kernel.org>
Thu, 11 May 2023 15:48:34 +0000 (11:48 -0400)
committerSasha Levin <sashal@kernel.org>
Thu, 11 May 2023 15:48:34 +0000 (11:48 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
18 files changed:
queue-6.1/crypto-ccp-clear-psp-interrupt-status-register-befor.patch [new file with mode: 0644]
queue-6.1/drm-vmwgfx-fix-legacy-display-unit-atomic-drm-suppor.patch [new file with mode: 0644]
queue-6.1/drm-vmwgfx-remove-explicit-and-broken-vblank-handlin.patch [new file with mode: 0644]
queue-6.1/kvm-x86-pmu-disallow-legacy-lbrs-if-architectural-lb.patch [new file with mode: 0644]
queue-6.1/kvm-x86-track-supported-perf_capabilities-in-kvm_cap.patch [new file with mode: 0644]
queue-6.1/mailbox-zynq-switch-to-flexible-array-to-simplify-co.patch [new file with mode: 0644]
queue-6.1/mailbox-zynqmp-fix-counts-of-child-nodes.patch [new file with mode: 0644]
queue-6.1/mtd-spi-nor-add-a-rww-flag.patch [new file with mode: 0644]
queue-6.1/mtd-spi-nor-add-sfdp-fixups-for-quad-page-program.patch [new file with mode: 0644]
queue-6.1/mtd-spi-nor-spansion-enable-jffs2-write-buffer-for-i.patch [new file with mode: 0644]
queue-6.1/mtd-spi-nor-spansion-enable-jffs2-write-buffer-for-i.patch-26314 [new file with mode: 0644]
queue-6.1/mtd-spi-nor-spansion-remove-no_sfdp_flags-from-s28hs.patch [new file with mode: 0644]
queue-6.1/perf-x86-core-zero-lbr-instead-of-returning-1-in-x86.patch [new file with mode: 0644]
queue-6.1/qcom-llcc-edac-support-polling-mode-for-ecc-handling.patch [new file with mode: 0644]
queue-6.1/series [new file with mode: 0644]
queue-6.1/soc-qcom-llcc-do-not-create-edac-platform-device-on-.patch [new file with mode: 0644]
queue-6.1/usb-dwc3-gadget-drop-dead-hibernation-code.patch [new file with mode: 0644]
queue-6.1/usb-dwc3-gadget-execute-gadget-stop-after-halting-th.patch [new file with mode: 0644]

diff --git a/queue-6.1/crypto-ccp-clear-psp-interrupt-status-register-befor.patch b/queue-6.1/crypto-ccp-clear-psp-interrupt-status-register-befor.patch
new file mode 100644 (file)
index 0000000..01ef92f
--- /dev/null
@@ -0,0 +1,74 @@
+From b4d711d2447121e41781503c515c77576747c77a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Mar 2023 15:16:36 +0000
+Subject: crypto: ccp - Clear PSP interrupt status register before calling
+ handler
+
+From: Jeremi Piotrowski <jpiotrowski@linux.microsoft.com>
+
+[ Upstream commit 45121ad4a1750ca47ce3f32bd434bdb0cdbf0043 ]
+
+The PSP IRQ is edge-triggered (MSI or MSI-X) in all cases supported by
+the psp module so clear the interrupt status register early in the
+handler to prevent missed interrupts. sev_irq_handler() calls wake_up()
+on a wait queue, which can result in a new command being submitted from
+a different CPU. This then races with the clearing of isr and can result
+in missed interrupts. A missed interrupt results in a command waiting
+until it times out, which results in the psp being declared dead.
+
+This is unlikely on bare metal, but has been observed when running
+virtualized. In the cases where this is observed, sev->cmdresp_reg has
+PSP_CMDRESP_RESP set which indicates that the command was processed
+correctly but no interrupt was asserted.
+
+The full sequence of events looks like this:
+
+CPU 1: submits SEV cmd #1
+CPU 1: calls wait_event_timeout()
+CPU 0: enters psp_irq_handler()
+CPU 0: calls sev_handler()->wake_up()
+CPU 1: wakes up; finishes processing cmd #1
+CPU 1: submits SEV cmd #2
+CPU 1: calls wait_event_timeout()
+PSP:   finishes processing cmd #2; interrupt status is still set; no interrupt
+CPU 0: clears intsts
+CPU 0: exits psp_irq_handler()
+CPU 1: wait_event_timeout() times out; psp_dead=true
+
+Fixes: 200664d5237f ("crypto: ccp: Add Secure Encrypted Virtualization (SEV) command support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jeremi Piotrowski <jpiotrowski@linux.microsoft.com>
+Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ccp/psp-dev.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
+index c9c741ac84421..949a3fa0b94a9 100644
+--- a/drivers/crypto/ccp/psp-dev.c
++++ b/drivers/crypto/ccp/psp-dev.c
+@@ -42,6 +42,9 @@ static irqreturn_t psp_irq_handler(int irq, void *data)
+       /* Read the interrupt status: */
+       status = ioread32(psp->io_regs + psp->vdata->intsts_reg);
++      /* Clear the interrupt status by writing the same value we read. */
++      iowrite32(status, psp->io_regs + psp->vdata->intsts_reg);
++
+       /* invoke subdevice interrupt handlers */
+       if (status) {
+               if (psp->sev_irq_handler)
+@@ -51,9 +54,6 @@ static irqreturn_t psp_irq_handler(int irq, void *data)
+                       psp->tee_irq_handler(irq, psp->tee_irq_data, status);
+       }
+-      /* Clear the interrupt status by writing the same value we read. */
+-      iowrite32(status, psp->io_regs + psp->vdata->intsts_reg);
+-
+       return IRQ_HANDLED;
+ }
+-- 
+2.39.2
+
diff --git a/queue-6.1/drm-vmwgfx-fix-legacy-display-unit-atomic-drm-suppor.patch b/queue-6.1/drm-vmwgfx-fix-legacy-display-unit-atomic-drm-suppor.patch
new file mode 100644 (file)
index 0000000..e68d3e1
--- /dev/null
@@ -0,0 +1,217 @@
+From b801ba48e2fb48318b2ea43cac0dc2b7d2806366 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Mar 2023 22:09:49 -0400
+Subject: drm/vmwgfx: Fix Legacy Display Unit atomic drm support
+
+From: Martin Krastev <krastevm@vmware.com>
+
+[ Upstream commit a37a512db3fa1b65fe9087003e5b2072cefb3667 ]
+
+Legacy Display Unit (LDU) fb dirty support used a custom fb dirty callback. Latter
+handled only the DIRTYFB IOCTL presentation path but not the ADDFB2/PAGE_FLIP/RMFB
+IOCTL path, common for Wayland compositors.
+
+Get rid of the custom callback in favor of drm_atomic_helper_dirtyfb and unify the
+handling of the presentation paths inside of vmw_ldu_primary_plane_atomic_update.
+This also homogenizes the fb dirty callbacks across all DUs: LDU, SOU and STDU.
+
+Signed-off-by: Martin Krastev <krastevm@vmware.com>
+Reviewed-by: Maaz Mombasawala <mombasawalam@vmware.com>
+Fixes: 2f5544ff0300 ("drm/vmwgfx: Use atomic helper function for dirty fb IOCTL")
+Cc: <stable@vger.kernel.org> # v5.0+
+Signed-off-by: Zack Rusin <zackr@vmware.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230321020949.335012-3-zack@kde.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 62 +----------------------------
+ drivers/gpu/drm/vmwgfx/vmwgfx_kms.h |  5 ---
+ drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 45 +++++++++++++++++----
+ 3 files changed, 38 insertions(+), 74 deletions(-)
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+index d5c4da2b05b1a..aab6389cb4aab 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+@@ -1264,70 +1264,10 @@ static void vmw_framebuffer_bo_destroy(struct drm_framebuffer *framebuffer)
+       kfree(vfbd);
+ }
+-static int vmw_framebuffer_bo_dirty(struct drm_framebuffer *framebuffer,
+-                                  struct drm_file *file_priv,
+-                                  unsigned int flags, unsigned int color,
+-                                  struct drm_clip_rect *clips,
+-                                  unsigned int num_clips)
+-{
+-      struct vmw_private *dev_priv = vmw_priv(framebuffer->dev);
+-      struct vmw_framebuffer_bo *vfbd =
+-              vmw_framebuffer_to_vfbd(framebuffer);
+-      struct drm_clip_rect norect;
+-      int ret, increment = 1;
+-
+-      drm_modeset_lock_all(&dev_priv->drm);
+-
+-      if (!num_clips) {
+-              num_clips = 1;
+-              clips = &norect;
+-              norect.x1 = norect.y1 = 0;
+-              norect.x2 = framebuffer->width;
+-              norect.y2 = framebuffer->height;
+-      } else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) {
+-              num_clips /= 2;
+-              increment = 2;
+-      }
+-
+-      switch (dev_priv->active_display_unit) {
+-      case vmw_du_legacy:
+-              ret = vmw_kms_ldu_do_bo_dirty(dev_priv, &vfbd->base, 0, 0,
+-                                            clips, num_clips, increment);
+-              break;
+-      default:
+-              ret = -EINVAL;
+-              WARN_ONCE(true, "Dirty called with invalid display system.\n");
+-              break;
+-      }
+-
+-      vmw_cmd_flush(dev_priv, false);
+-
+-      drm_modeset_unlock_all(&dev_priv->drm);
+-
+-      return ret;
+-}
+-
+-static int vmw_framebuffer_bo_dirty_ext(struct drm_framebuffer *framebuffer,
+-                                      struct drm_file *file_priv,
+-                                      unsigned int flags, unsigned int color,
+-                                      struct drm_clip_rect *clips,
+-                                      unsigned int num_clips)
+-{
+-      struct vmw_private *dev_priv = vmw_priv(framebuffer->dev);
+-
+-      if (dev_priv->active_display_unit == vmw_du_legacy &&
+-          vmw_cmd_supported(dev_priv))
+-              return vmw_framebuffer_bo_dirty(framebuffer, file_priv, flags,
+-                                              color, clips, num_clips);
+-
+-      return drm_atomic_helper_dirtyfb(framebuffer, file_priv, flags, color,
+-                                       clips, num_clips);
+-}
+-
+ static const struct drm_framebuffer_funcs vmw_framebuffer_bo_funcs = {
+       .create_handle = vmw_framebuffer_bo_create_handle,
+       .destroy = vmw_framebuffer_bo_destroy,
+-      .dirty = vmw_framebuffer_bo_dirty_ext,
++      .dirty = drm_atomic_helper_dirtyfb,
+ };
+ /*
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+index 85f86faa32439..b02d2793659f9 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+@@ -517,11 +517,6 @@ void vmw_du_connector_destroy_state(struct drm_connector *connector,
+  */
+ int vmw_kms_ldu_init_display(struct vmw_private *dev_priv);
+ int vmw_kms_ldu_close_display(struct vmw_private *dev_priv);
+-int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv,
+-                          struct vmw_framebuffer *framebuffer,
+-                          unsigned int flags, unsigned int color,
+-                          struct drm_clip_rect *clips,
+-                          unsigned int num_clips, int increment);
+ int vmw_kms_update_proxy(struct vmw_resource *res,
+                        const struct drm_clip_rect *clips,
+                        unsigned num_clips,
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+index a56e5d0ca3c65..ac72c20715f32 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+@@ -234,6 +234,7 @@ static const struct drm_crtc_funcs vmw_legacy_crtc_funcs = {
+       .atomic_duplicate_state = vmw_du_crtc_duplicate_state,
+       .atomic_destroy_state = vmw_du_crtc_destroy_state,
+       .set_config = drm_atomic_helper_set_config,
++      .page_flip = drm_atomic_helper_page_flip,
+ };
+@@ -273,6 +274,12 @@ static const struct
+ drm_connector_helper_funcs vmw_ldu_connector_helper_funcs = {
+ };
++static int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv,
++                                 struct vmw_framebuffer *framebuffer,
++                                 unsigned int flags, unsigned int color,
++                                 struct drm_mode_rect *clips,
++                                 unsigned int num_clips);
++
+ /*
+  * Legacy Display Plane Functions
+  */
+@@ -291,7 +298,6 @@ vmw_ldu_primary_plane_atomic_update(struct drm_plane *plane,
+       struct drm_framebuffer *fb;
+       struct drm_crtc *crtc = new_state->crtc ?: old_state->crtc;
+-
+       ldu = vmw_crtc_to_ldu(crtc);
+       dev_priv = vmw_priv(plane->dev);
+       fb       = new_state->fb;
+@@ -304,8 +310,31 @@ vmw_ldu_primary_plane_atomic_update(struct drm_plane *plane,
+               vmw_ldu_del_active(dev_priv, ldu);
+       vmw_ldu_commit_list(dev_priv);
+-}
++      if (vfb && vmw_cmd_supported(dev_priv)) {
++              struct drm_mode_rect fb_rect = {
++                      .x1 = 0,
++                      .y1 = 0,
++                      .x2 = vfb->base.width,
++                      .y2 = vfb->base.height
++              };
++              struct drm_mode_rect *damage_rects = drm_plane_get_damage_clips(new_state);
++              u32 rect_count = drm_plane_get_damage_clips_count(new_state);
++              int ret;
++
++              if (!damage_rects) {
++                      damage_rects = &fb_rect;
++                      rect_count = 1;
++              }
++
++              ret = vmw_kms_ldu_do_bo_dirty(dev_priv, vfb, 0, 0, damage_rects, rect_count);
++
++              drm_WARN_ONCE(plane->dev, ret,
++                      "vmw_kms_ldu_do_bo_dirty failed with: ret=%d\n", ret);
++
++              vmw_cmd_flush(dev_priv, false);
++      }
++}
+ static const struct drm_plane_funcs vmw_ldu_plane_funcs = {
+       .update_plane = drm_atomic_helper_update_plane,
+@@ -536,11 +565,11 @@ int vmw_kms_ldu_close_display(struct vmw_private *dev_priv)
+ }
+-int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv,
+-                          struct vmw_framebuffer *framebuffer,
+-                          unsigned int flags, unsigned int color,
+-                          struct drm_clip_rect *clips,
+-                          unsigned int num_clips, int increment)
++static int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv,
++                                 struct vmw_framebuffer *framebuffer,
++                                 unsigned int flags, unsigned int color,
++                                 struct drm_mode_rect *clips,
++                                 unsigned int num_clips)
+ {
+       size_t fifo_size;
+       int i;
+@@ -556,7 +585,7 @@ int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv,
+               return -ENOMEM;
+       memset(cmd, 0, fifo_size);
+-      for (i = 0; i < num_clips; i++, clips += increment) {
++      for (i = 0; i < num_clips; i++, clips++) {
+               cmd[i].header = SVGA_CMD_UPDATE;
+               cmd[i].body.x = clips->x1;
+               cmd[i].body.y = clips->y1;
+-- 
+2.39.2
+
diff --git a/queue-6.1/drm-vmwgfx-remove-explicit-and-broken-vblank-handlin.patch b/queue-6.1/drm-vmwgfx-remove-explicit-and-broken-vblank-handlin.patch
new file mode 100644 (file)
index 0000000..ab5ead1
--- /dev/null
@@ -0,0 +1,286 @@
+From 90ec1e7f8cb094ff0fa39823e5487b53beb0cc6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Oct 2022 00:02:33 -0400
+Subject: drm/vmwgfx: Remove explicit and broken vblank handling
+
+From: Zack Rusin <zackr@vmware.com>
+
+[ Upstream commit 2e10cdc6e85de5998b0b140deff01765ceb92f64 ]
+
+The explicit vblank handling was never finished. The driver never had
+the full implementation of vblank and what was there is emulated
+by DRM when the driver doesn't pretend to be implementing it itself.
+
+Let DRM handle the vblank emulation and stop pretending the driver is
+doing anything special with vblank. In the future it would make sense
+to implement helpers for full vblank handling because vkms and
+amdgpu_vkms already have that code. Exporting it to common helpers and
+having all three drivers share it would make sense (that would be largely
+just to allow more of igt to run).
+
+Signed-off-by: Zack Rusin <zackr@vmware.com>
+Reviewed-by: Maaz Mombasawala <mombasawalam@vmware.com>
+Reviewed-by: Martin Krastev <krastevm@vmware.com>
+Reviewed-by: Michael Banack <banackm@vmware.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221022040236.616490-15-zack@kde.org
+Stable-dep-of: a37a512db3fa ("drm/vmwgfx: Fix Legacy Display Unit atomic drm support")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_drv.h  |  3 ---
+ drivers/gpu/drm/vmwgfx/vmwgfx_kms.c  | 34 ----------------------------
+ drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c  |  8 -------
+ drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 31 +------------------------
+ drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 26 ---------------------
+ 5 files changed, 1 insertion(+), 101 deletions(-)
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+index 0bc1ebc43002b..1ec9c53a7bf43 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+@@ -1221,9 +1221,6 @@ int vmw_kms_write_svga(struct vmw_private *vmw_priv,
+ bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
+                               uint32_t pitch,
+                               uint32_t height);
+-u32 vmw_get_vblank_counter(struct drm_crtc *crtc);
+-int vmw_enable_vblank(struct drm_crtc *crtc);
+-void vmw_disable_vblank(struct drm_crtc *crtc);
+ int vmw_kms_present(struct vmw_private *dev_priv,
+                   struct drm_file *file_priv,
+                   struct vmw_framebuffer *vfb,
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+index 13721bcf047c0..d5c4da2b05b1a 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+@@ -31,7 +31,6 @@
+ #include <drm/drm_fourcc.h>
+ #include <drm/drm_rect.h>
+ #include <drm/drm_sysfs.h>
+-#include <drm/drm_vblank.h>
+ #include "vmwgfx_kms.h"
+@@ -832,15 +831,6 @@ void vmw_du_crtc_atomic_begin(struct drm_crtc *crtc,
+ void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc,
+                             struct drm_atomic_state *state)
+ {
+-      struct drm_pending_vblank_event *event = crtc->state->event;
+-
+-      if (event) {
+-              crtc->state->event = NULL;
+-
+-              spin_lock_irq(&crtc->dev->event_lock);
+-              drm_crtc_send_vblank_event(crtc, event);
+-              spin_unlock_irq(&crtc->dev->event_lock);
+-      }
+ }
+@@ -2158,30 +2148,6 @@ bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
+                dev_priv->max_primary_mem : dev_priv->vram_size);
+ }
+-
+-/*
+- * Function called by DRM code called with vbl_lock held.
+- */
+-u32 vmw_get_vblank_counter(struct drm_crtc *crtc)
+-{
+-      return 0;
+-}
+-
+-/*
+- * Function called by DRM code called with vbl_lock held.
+- */
+-int vmw_enable_vblank(struct drm_crtc *crtc)
+-{
+-      return -EINVAL;
+-}
+-
+-/*
+- * Function called by DRM code called with vbl_lock held.
+- */
+-void vmw_disable_vblank(struct drm_crtc *crtc)
+-{
+-}
+-
+ /**
+  * vmw_du_update_layout - Update the display unit with topology from resolution
+  * plugin and generate DRM uevent
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+index b8761f16dd785..a56e5d0ca3c65 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+@@ -28,7 +28,6 @@
+ #include <drm/drm_atomic.h>
+ #include <drm/drm_atomic_helper.h>
+ #include <drm/drm_fourcc.h>
+-#include <drm/drm_vblank.h>
+ #include "vmwgfx_kms.h"
+@@ -235,9 +234,6 @@ static const struct drm_crtc_funcs vmw_legacy_crtc_funcs = {
+       .atomic_duplicate_state = vmw_du_crtc_duplicate_state,
+       .atomic_destroy_state = vmw_du_crtc_destroy_state,
+       .set_config = drm_atomic_helper_set_config,
+-      .get_vblank_counter = vmw_get_vblank_counter,
+-      .enable_vblank = vmw_enable_vblank,
+-      .disable_vblank = vmw_disable_vblank,
+ };
+@@ -507,10 +503,6 @@ int vmw_kms_ldu_init_display(struct vmw_private *dev_priv)
+       dev_priv->ldu_priv->last_num_active = 0;
+       dev_priv->ldu_priv->fb = NULL;
+-      ret = drm_vblank_init(dev, num_display_units);
+-      if (ret != 0)
+-              goto err_free;
+-
+       vmw_kms_create_implicit_placement_property(dev_priv);
+       for (i = 0; i < num_display_units; ++i) {
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+index 9c79873f62f06..e1f36a09c59c1 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+@@ -29,7 +29,6 @@
+ #include <drm/drm_atomic_helper.h>
+ #include <drm/drm_damage_helper.h>
+ #include <drm/drm_fourcc.h>
+-#include <drm/drm_vblank.h>
+ #include "vmwgfx_kms.h"
+@@ -320,9 +319,6 @@ static const struct drm_crtc_funcs vmw_screen_object_crtc_funcs = {
+       .atomic_destroy_state = vmw_du_crtc_destroy_state,
+       .set_config = drm_atomic_helper_set_config,
+       .page_flip = drm_atomic_helper_page_flip,
+-      .get_vblank_counter = vmw_get_vblank_counter,
+-      .enable_vblank = vmw_enable_vblank,
+-      .disable_vblank = vmw_disable_vblank,
+ };
+ /*
+@@ -730,7 +726,6 @@ vmw_sou_primary_plane_atomic_update(struct drm_plane *plane,
+       struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, plane);
+       struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane);
+       struct drm_crtc *crtc = new_state->crtc;
+-      struct drm_pending_vblank_event *event = NULL;
+       struct vmw_fence_obj *fence = NULL;
+       int ret;
+@@ -754,24 +749,6 @@ vmw_sou_primary_plane_atomic_update(struct drm_plane *plane,
+               return;
+       }
+-      /* For error case vblank event is send from vmw_du_crtc_atomic_flush */
+-      event = crtc->state->event;
+-      if (event && fence) {
+-              struct drm_file *file_priv = event->base.file_priv;
+-
+-              ret = vmw_event_fence_action_queue(file_priv,
+-                                                 fence,
+-                                                 &event->base,
+-                                                 &event->event.vbl.tv_sec,
+-                                                 &event->event.vbl.tv_usec,
+-                                                 true);
+-
+-              if (unlikely(ret != 0))
+-                      DRM_ERROR("Failed to queue event on fence.\n");
+-              else
+-                      crtc->state->event = NULL;
+-      }
+-
+       if (fence)
+               vmw_fence_obj_unreference(&fence);
+ }
+@@ -947,7 +924,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
+ int vmw_kms_sou_init_display(struct vmw_private *dev_priv)
+ {
+       struct drm_device *dev = &dev_priv->drm;
+-      int i, ret;
++      int i;
+       /* Screen objects won't work if GMR's aren't available */
+       if (!dev_priv->has_gmr)
+@@ -957,12 +934,6 @@ int vmw_kms_sou_init_display(struct vmw_private *dev_priv)
+               return -ENOSYS;
+       }
+-      ret = -ENOMEM;
+-
+-      ret = drm_vblank_init(dev, VMWGFX_NUM_DISPLAY_UNITS);
+-      if (unlikely(ret != 0))
+-              return ret;
+-
+       for (i = 0; i < VMWGFX_NUM_DISPLAY_UNITS; ++i)
+               vmw_sou_init(dev_priv, i);
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+index 8650c3aea8f0a..0090abe892548 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+@@ -29,7 +29,6 @@
+ #include <drm/drm_atomic_helper.h>
+ #include <drm/drm_damage_helper.h>
+ #include <drm/drm_fourcc.h>
+-#include <drm/drm_vblank.h>
+ #include "vmwgfx_kms.h"
+ #include "vmw_surface_cache.h"
+@@ -925,9 +924,6 @@ static const struct drm_crtc_funcs vmw_stdu_crtc_funcs = {
+       .atomic_destroy_state = vmw_du_crtc_destroy_state,
+       .set_config = drm_atomic_helper_set_config,
+       .page_flip = drm_atomic_helper_page_flip,
+-      .get_vblank_counter = vmw_get_vblank_counter,
+-      .enable_vblank = vmw_enable_vblank,
+-      .disable_vblank = vmw_disable_vblank,
+ };
+@@ -1591,7 +1587,6 @@ vmw_stdu_primary_plane_atomic_update(struct drm_plane *plane,
+       struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state);
+       struct drm_crtc *crtc = new_state->crtc;
+       struct vmw_screen_target_display_unit *stdu;
+-      struct drm_pending_vblank_event *event;
+       struct vmw_fence_obj *fence = NULL;
+       struct vmw_private *dev_priv;
+       int ret;
+@@ -1640,23 +1635,6 @@ vmw_stdu_primary_plane_atomic_update(struct drm_plane *plane,
+               return;
+       }
+-      /* In case of error, vblank event is send in vmw_du_crtc_atomic_flush */
+-      event = crtc->state->event;
+-      if (event && fence) {
+-              struct drm_file *file_priv = event->base.file_priv;
+-
+-              ret = vmw_event_fence_action_queue(file_priv,
+-                                                 fence,
+-                                                 &event->base,
+-                                                 &event->event.vbl.tv_sec,
+-                                                 &event->event.vbl.tv_usec,
+-                                                 true);
+-              if (ret)
+-                      DRM_ERROR("Failed to queue event on fence.\n");
+-              else
+-                      crtc->state->event = NULL;
+-      }
+-
+       if (fence)
+               vmw_fence_obj_unreference(&fence);
+ }
+@@ -1883,10 +1861,6 @@ int vmw_kms_stdu_init_display(struct vmw_private *dev_priv)
+       if (!(dev_priv->capabilities & SVGA_CAP_GBOBJECTS))
+               return -ENOSYS;
+-      ret = drm_vblank_init(dev, VMWGFX_NUM_DISPLAY_UNITS);
+-      if (unlikely(ret != 0))
+-              return ret;
+-
+       dev_priv->active_display_unit = vmw_du_screen_target;
+       for (i = 0; i < VMWGFX_NUM_DISPLAY_UNITS; ++i) {
+-- 
+2.39.2
+
diff --git a/queue-6.1/kvm-x86-pmu-disallow-legacy-lbrs-if-architectural-lb.patch b/queue-6.1/kvm-x86-pmu-disallow-legacy-lbrs-if-architectural-lb.patch
new file mode 100644 (file)
index 0000000..2d0682b
--- /dev/null
@@ -0,0 +1,50 @@
+From fbed41939b41f759cbea3f2042a01afca42d6fe9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 28 Jan 2023 00:14:27 +0000
+Subject: KVM: x86/pmu: Disallow legacy LBRs if architectural LBRs are
+ available
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 098f4c061ea10b777033b71c10bd9fd706820ee9 ]
+
+Disallow enabling LBR support if the CPU supports architectural LBRs.
+Traditional LBR support is absent on CPU models that have architectural
+LBRs, and KVM doesn't yet support arch LBRs, i.e. KVM will pass through
+non-existent MSRs if userspace enables LBRs for the guest.
+
+Cc: stable@vger.kernel.org
+Cc: Yang Weijiang <weijiang.yang@intel.com>
+Cc: Like Xu <like.xu.linux@gmail.com>
+Reported-by: Paolo Bonzini <pbonzini@redhat.com>
+Fixes: be635e34c284 ("KVM: vmx/pmu: Expose LBR_FMT in the MSR_IA32_PERF_CAPABILITIES")
+Tested-by: Like Xu <likexu@tencent.com>
+Link: https://lore.kernel.org/r/20230128001427.2548858-1-seanjc@google.com
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/vmx/vmx.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
+index 8ad5992f61340..5db21d9ef6710 100644
+--- a/arch/x86/kvm/vmx/vmx.c
++++ b/arch/x86/kvm/vmx/vmx.c
+@@ -7714,9 +7714,11 @@ static u64 vmx_get_perf_capabilities(void)
+       if (boot_cpu_has(X86_FEATURE_PDCM))
+               rdmsrl(MSR_IA32_PERF_CAPABILITIES, host_perf_cap);
+-      x86_perf_get_lbr(&lbr);
+-      if (lbr.nr)
+-              perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT;
++      if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR)) {
++              x86_perf_get_lbr(&lbr);
++              if (lbr.nr)
++                      perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT;
++      }
+       if (vmx_pebs_supported()) {
+               perf_cap |= host_perf_cap & PERF_CAP_PEBS_MASK;
+-- 
+2.39.2
+
diff --git a/queue-6.1/kvm-x86-track-supported-perf_capabilities-in-kvm_cap.patch b/queue-6.1/kvm-x86-track-supported-perf_capabilities-in-kvm_cap.patch
new file mode 100644 (file)
index 0000000..2a10b03
--- /dev/null
@@ -0,0 +1,191 @@
+From 231fd45b949ebb4460a53a7f252ab462c02600b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Oct 2022 00:03:11 +0000
+Subject: KVM: x86: Track supported PERF_CAPABILITIES in kvm_caps
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit bec46859fb9d797a21c983100b1f425bebe89747 ]
+
+Track KVM's supported PERF_CAPABILITIES in kvm_caps instead of computing
+the supported capabilities on the fly every time.  Using kvm_caps will
+also allow for future cleanups as the kvm_caps values can be used
+directly in common x86 code.
+
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Acked-by: Like Xu <likexu@tencent.com>
+Message-Id: <20221006000314.73240-6-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Stable-dep-of: 098f4c061ea1 ("KVM: x86/pmu: Disallow legacy LBRs if architectural LBRs are available")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/svm/svm.c          |  2 ++
+ arch/x86/kvm/vmx/capabilities.h | 25 ------------------------
+ arch/x86/kvm/vmx/pmu_intel.c    |  2 +-
+ arch/x86/kvm/vmx/vmx.c          | 34 +++++++++++++++++++++++++++++----
+ arch/x86/kvm/x86.h              |  1 +
+ 5 files changed, 34 insertions(+), 30 deletions(-)
+
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index 9599931c7d572..fc1649b5931a4 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -2709,6 +2709,7 @@ static int svm_get_msr_feature(struct kvm_msr_entry *msr)
+                       msr->data |= MSR_AMD64_DE_CFG_LFENCE_SERIALIZE;
+               break;
+       case MSR_IA32_PERF_CAPABILITIES:
++              msr->data = kvm_caps.supported_perf_cap;
+               return 0;
+       default:
+               return KVM_MSR_RET_INVALID;
+@@ -4888,6 +4889,7 @@ static __init void svm_set_cpu_caps(void)
+ {
+       kvm_set_cpu_caps();
++      kvm_caps.supported_perf_cap = 0;
+       kvm_caps.supported_xss = 0;
+       /* CPUID 0x80000001 and 0x8000000A (SVM features) */
+diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h
+index 479124e49bbda..cd2ac9536c998 100644
+--- a/arch/x86/kvm/vmx/capabilities.h
++++ b/arch/x86/kvm/vmx/capabilities.h
+@@ -395,31 +395,6 @@ static inline bool vmx_pebs_supported(void)
+       return boot_cpu_has(X86_FEATURE_PEBS) && kvm_pmu_cap.pebs_ept;
+ }
+-static inline u64 vmx_get_perf_capabilities(void)
+-{
+-      u64 perf_cap = PMU_CAP_FW_WRITES;
+-      struct x86_pmu_lbr lbr;
+-      u64 host_perf_cap = 0;
+-
+-      if (!enable_pmu)
+-              return 0;
+-
+-      if (boot_cpu_has(X86_FEATURE_PDCM))
+-              rdmsrl(MSR_IA32_PERF_CAPABILITIES, host_perf_cap);
+-
+-      x86_perf_get_lbr(&lbr);
+-      if (lbr.nr)
+-              perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT;
+-
+-      if (vmx_pebs_supported()) {
+-              perf_cap |= host_perf_cap & PERF_CAP_PEBS_MASK;
+-              if ((perf_cap & PERF_CAP_PEBS_FORMAT) < 4)
+-                      perf_cap &= ~PERF_CAP_PEBS_BASELINE;
+-      }
+-
+-      return perf_cap;
+-}
+-
+ static inline bool cpu_has_notify_vmexit(void)
+ {
+       return vmcs_config.cpu_based_2nd_exec_ctrl &
+diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
+index 10b33da9bd058..9fabfe71fd879 100644
+--- a/arch/x86/kvm/vmx/pmu_intel.c
++++ b/arch/x86/kvm/vmx/pmu_intel.c
+@@ -631,7 +631,7 @@ static void intel_pmu_init(struct kvm_vcpu *vcpu)
+               pmu->fixed_counters[i].current_config = 0;
+       }
+-      vcpu->arch.perf_capabilities = vmx_get_perf_capabilities();
++      vcpu->arch.perf_capabilities = kvm_caps.supported_perf_cap;
+       lbr_desc->records.nr = 0;
+       lbr_desc->event = NULL;
+       lbr_desc->msr_passthrough = false;
+diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
+index 4c9116d223df5..8ad5992f61340 100644
+--- a/arch/x86/kvm/vmx/vmx.c
++++ b/arch/x86/kvm/vmx/vmx.c
+@@ -1879,7 +1879,7 @@ static int vmx_get_msr_feature(struct kvm_msr_entry *msr)
+                       return 1;
+               return vmx_get_vmx_msr(&vmcs_config.nested, msr->index, &msr->data);
+       case MSR_IA32_PERF_CAPABILITIES:
+-              msr->data = vmx_get_perf_capabilities();
++              msr->data = kvm_caps.supported_perf_cap;
+               return 0;
+       default:
+               return KVM_MSR_RET_INVALID;
+@@ -2058,7 +2058,7 @@ static u64 vmx_get_supported_debugctl(struct kvm_vcpu *vcpu, bool host_initiated
+           (host_initiated || guest_cpuid_has(vcpu, X86_FEATURE_BUS_LOCK_DETECT)))
+               debugctl |= DEBUGCTLMSR_BUS_LOCK_DETECT;
+-      if ((vmx_get_perf_capabilities() & PMU_CAP_LBR_FMT) &&
++      if ((kvm_caps.supported_perf_cap & PMU_CAP_LBR_FMT) &&
+           (host_initiated || intel_pmu_lbr_is_enabled(vcpu)))
+               debugctl |= DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI;
+@@ -2371,14 +2371,14 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+                       return 1;
+               if (data & PMU_CAP_LBR_FMT) {
+                       if ((data & PMU_CAP_LBR_FMT) !=
+-                          (vmx_get_perf_capabilities() & PMU_CAP_LBR_FMT))
++                          (kvm_caps.supported_perf_cap & PMU_CAP_LBR_FMT))
+                               return 1;
+                       if (!cpuid_model_is_consistent(vcpu))
+                               return 1;
+               }
+               if (data & PERF_CAP_PEBS_FORMAT) {
+                       if ((data & PERF_CAP_PEBS_MASK) !=
+-                          (vmx_get_perf_capabilities() & PERF_CAP_PEBS_MASK))
++                          (kvm_caps.supported_perf_cap & PERF_CAP_PEBS_MASK))
+                               return 1;
+                       if (!guest_cpuid_has(vcpu, X86_FEATURE_DS))
+                               return 1;
+@@ -7702,6 +7702,31 @@ static void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
+       vmx_update_exception_bitmap(vcpu);
+ }
++static u64 vmx_get_perf_capabilities(void)
++{
++      u64 perf_cap = PMU_CAP_FW_WRITES;
++      struct x86_pmu_lbr lbr;
++      u64 host_perf_cap = 0;
++
++      if (!enable_pmu)
++              return 0;
++
++      if (boot_cpu_has(X86_FEATURE_PDCM))
++              rdmsrl(MSR_IA32_PERF_CAPABILITIES, host_perf_cap);
++
++      x86_perf_get_lbr(&lbr);
++      if (lbr.nr)
++              perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT;
++
++      if (vmx_pebs_supported()) {
++              perf_cap |= host_perf_cap & PERF_CAP_PEBS_MASK;
++              if ((perf_cap & PERF_CAP_PEBS_FORMAT) < 4)
++                      perf_cap &= ~PERF_CAP_PEBS_BASELINE;
++      }
++
++      return perf_cap;
++}
++
+ static __init void vmx_set_cpu_caps(void)
+ {
+       kvm_set_cpu_caps();
+@@ -7724,6 +7749,7 @@ static __init void vmx_set_cpu_caps(void)
+       if (!enable_pmu)
+               kvm_cpu_cap_clear(X86_FEATURE_PDCM);
++      kvm_caps.supported_perf_cap = vmx_get_perf_capabilities();
+       if (!enable_sgx) {
+               kvm_cpu_cap_clear(X86_FEATURE_SGX);
+diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
+index 829d3134c1eb0..9de72586f4065 100644
+--- a/arch/x86/kvm/x86.h
++++ b/arch/x86/kvm/x86.h
+@@ -27,6 +27,7 @@ struct kvm_caps {
+       u64 supported_mce_cap;
+       u64 supported_xcr0;
+       u64 supported_xss;
++      u64 supported_perf_cap;
+ };
+ void kvm_spurious_fault(void);
+-- 
+2.39.2
+
diff --git a/queue-6.1/mailbox-zynq-switch-to-flexible-array-to-simplify-co.patch b/queue-6.1/mailbox-zynq-switch-to-flexible-array-to-simplify-co.patch
new file mode 100644 (file)
index 0000000..a17d838
--- /dev/null
@@ -0,0 +1,56 @@
+From e2fcaee6852f373687d69f2e3aae4d9d2530305c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Nov 2022 09:25:54 +0100
+Subject: mailbox: zynq: Switch to flexible array to simplify code
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 043f85ce81cb1714e14d31c322c5646513dde3fb ]
+
+Using flexible array is more straight forward. It
+  - saves 1 pointer in the 'zynqmp_ipi_pdata' structure
+  - saves an indirection when using this array
+  - saves some LoC and avoids some always spurious pointer arithmetic
+
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
+Stable-dep-of: f72f805e7288 ("mailbox: zynqmp: Fix counts of child nodes")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/zynqmp-ipi-mailbox.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
+index e02a4a18e8c29..29f09ded6e739 100644
+--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
++++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
+@@ -110,7 +110,7 @@ struct zynqmp_ipi_pdata {
+       unsigned int method;
+       u32 local_id;
+       int num_mboxes;
+-      struct zynqmp_ipi_mbox *ipi_mboxes;
++      struct zynqmp_ipi_mbox ipi_mboxes[];
+ };
+ static struct device_driver zynqmp_ipi_mbox_driver = {
+@@ -635,7 +635,7 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
+       int num_mboxes, ret = -EINVAL;
+       num_mboxes = of_get_child_count(np);
+-      pdata = devm_kzalloc(dev, sizeof(*pdata) + (num_mboxes * sizeof(*mbox)),
++      pdata = devm_kzalloc(dev, struct_size(pdata, ipi_mboxes, num_mboxes),
+                            GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
+@@ -649,8 +649,6 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
+       }
+       pdata->num_mboxes = num_mboxes;
+-      pdata->ipi_mboxes = (struct zynqmp_ipi_mbox *)
+-                          ((char *)pdata + sizeof(*pdata));
+       mbox = pdata->ipi_mboxes;
+       for_each_available_child_of_node(np, nc) {
+-- 
+2.39.2
+
diff --git a/queue-6.1/mailbox-zynqmp-fix-counts-of-child-nodes.patch b/queue-6.1/mailbox-zynqmp-fix-counts-of-child-nodes.patch
new file mode 100644 (file)
index 0000000..e297b9f
--- /dev/null
@@ -0,0 +1,45 @@
+From d7abfa634e44dfb587cbf172f37eddb6cf66774b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Mar 2023 17:24:04 -0800
+Subject: mailbox: zynqmp: Fix counts of child nodes
+
+From: Tanmay Shah <tanmay.shah@amd.com>
+
+[ Upstream commit f72f805e72882c361e2a612c64a6e549f3da7152 ]
+
+If child mailbox node status is disabled it causes
+crash in interrupt handler. Fix this by assigning
+only available child node during driver probe.
+
+Fixes: 4981b82ba2ff ("mailbox: ZynqMP IPI mailbox controller")
+Signed-off-by: Tanmay Shah <tanmay.shah@amd.com>
+Acked-by: Michal Simek <michal.simek@amd.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20230311012407.1292118-2-tanmay.shah@amd.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mailbox/zynqmp-ipi-mailbox.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
+index 29f09ded6e739..d097f45b0e5f5 100644
+--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
++++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
+@@ -634,7 +634,12 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
+       struct zynqmp_ipi_mbox *mbox;
+       int num_mboxes, ret = -EINVAL;
+-      num_mboxes = of_get_child_count(np);
++      num_mboxes = of_get_available_child_count(np);
++      if (num_mboxes == 0) {
++              dev_err(dev, "mailbox nodes not available\n");
++              return -EINVAL;
++      }
++
+       pdata = devm_kzalloc(dev, struct_size(pdata, ipi_mboxes, num_mboxes),
+                            GFP_KERNEL);
+       if (!pdata)
+-- 
+2.39.2
+
diff --git a/queue-6.1/mtd-spi-nor-add-a-rww-flag.patch b/queue-6.1/mtd-spi-nor-add-a-rww-flag.patch
new file mode 100644 (file)
index 0000000..522d96a
--- /dev/null
@@ -0,0 +1,83 @@
+From 271ca13cefb1361b133db56e0cfc5e3bf39a3eb2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Mar 2023 17:41:03 +0200
+Subject: mtd: spi-nor: Add a RWW flag
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+[ Upstream commit 4eddee70140b3ae183398b246a609756546c51f1 ]
+
+Introduce a new (no SFDP) flag for the feature that we are about to
+support: Read While Write. This means, if the chip has several banks and
+supports RWW, once a page of data to write has been transferred into the
+chip's internal SRAM, another read operation happening on a different
+bank can be performed during the tPROG delay.
+
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/r/20230328154105.448540-7-miquel.raynal@bootlin.com
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Stable-dep-of: 9fd0945fe6fa ("mtd: spi-nor: spansion: Enable JFFS2 write buffer for Infineon s28hx SEMPER flash")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/spi-nor/core.c    | 3 +++
+ drivers/mtd/spi-nor/core.h    | 3 +++
+ drivers/mtd/spi-nor/debugfs.c | 1 +
+ 3 files changed, 7 insertions(+)
+
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index 88da4a125c743..621e9ad4bcc39 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -2440,6 +2440,9 @@ static void spi_nor_init_flags(struct spi_nor *nor)
+       if (flags & NO_CHIP_ERASE)
+               nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
++
++      if (flags & SPI_NOR_RWW)
++              nor->flags |= SNOR_F_RWW;
+ }
+ /**
+diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
+index 8a846ad86d298..f23d1e77199e5 100644
+--- a/drivers/mtd/spi-nor/core.h
++++ b/drivers/mtd/spi-nor/core.h
+@@ -130,6 +130,7 @@ enum spi_nor_option_flags {
+       SNOR_F_IO_MODE_EN_VOLATILE = BIT(11),
+       SNOR_F_SOFT_RESET       = BIT(12),
+       SNOR_F_SWP_IS_VOLATILE  = BIT(13),
++      SNOR_F_RWW              = BIT(14),
+ };
+ struct spi_nor_read_command {
+@@ -459,6 +460,7 @@ struct spi_nor_fixups {
+  *   NO_CHIP_ERASE:           chip does not support chip erase.
+  *   SPI_NOR_NO_FR:           can't do fastread.
+  *   SPI_NOR_QUAD_PP:         flash supports Quad Input Page Program.
++ *   SPI_NOR_RWW:             flash supports reads while write.
+  *
+  * @no_sfdp_flags:  flags that indicate support that can be discovered via SFDP.
+  *                  Used when SFDP tables are not defined in the flash. These
+@@ -509,6 +511,7 @@ struct flash_info {
+ #define NO_CHIP_ERASE                 BIT(7)
+ #define SPI_NOR_NO_FR                 BIT(8)
+ #define SPI_NOR_QUAD_PP                       BIT(9)
++#define SPI_NOR_RWW                   BIT(10)
+       u8 no_sfdp_flags;
+ #define SPI_NOR_SKIP_SFDP             BIT(0)
+diff --git a/drivers/mtd/spi-nor/debugfs.c b/drivers/mtd/spi-nor/debugfs.c
+index 5f56b23205d8b..8b4922a1aafb9 100644
+--- a/drivers/mtd/spi-nor/debugfs.c
++++ b/drivers/mtd/spi-nor/debugfs.c
+@@ -25,6 +25,7 @@ static const char *const snor_f_names[] = {
+       SNOR_F_NAME(IO_MODE_EN_VOLATILE),
+       SNOR_F_NAME(SOFT_RESET),
+       SNOR_F_NAME(SWP_IS_VOLATILE),
++      SNOR_F_NAME(RWW),
+ };
+ #undef SNOR_F_NAME
+-- 
+2.39.2
+
diff --git a/queue-6.1/mtd-spi-nor-add-sfdp-fixups-for-quad-page-program.patch b/queue-6.1/mtd-spi-nor-add-sfdp-fixups-for-quad-page-program.patch
new file mode 100644 (file)
index 0000000..b26df25
--- /dev/null
@@ -0,0 +1,77 @@
+From cc39c4e1cf6a815403a0f4222f88c4a2dac7e8bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Sep 2022 19:48:08 +0100
+Subject: mtd: spi-nor: add SFDP fixups for Quad Page Program
+
+From: Sudip Mukherjee <sudip.mukherjee@sifive.com>
+
+[ Upstream commit 1799cd8540b67b88514c82f5fae1c75b986bcbd8 ]
+
+SFDP table of some flash chips do not advertise support of Quad Input
+Page Program even though it has support. Use flags and add hardware
+cap for these chips.
+
+Signed-off-by: Sudip Mukherjee <sudip.mukherjee@sifive.com>
+[tudor.ambarus@microchip.com: move pp setting in spi_nor_init_default_params]
+Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
+Link: https://lore.kernel.org/r/20220920184808.44876-2-sudip.mukherjee@sifive.com
+Stable-dep-of: 9fd0945fe6fa ("mtd: spi-nor: spansion: Enable JFFS2 write buffer for Infineon s28hx SEMPER flash")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/spi-nor/core.c | 6 ++++++
+ drivers/mtd/spi-nor/core.h | 2 ++
+ drivers/mtd/spi-nor/issi.c | 1 +
+ 3 files changed, 9 insertions(+)
+
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index 9a7bea365acb7..88da4a125c743 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -2578,6 +2578,12 @@ static void spi_nor_init_default_params(struct spi_nor *nor)
+       params->hwcaps.mask |= SNOR_HWCAPS_PP;
+       spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP],
+                               SPINOR_OP_PP, SNOR_PROTO_1_1_1);
++
++      if (info->flags & SPI_NOR_QUAD_PP) {
++              params->hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4;
++              spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_1_1_4],
++                                      SPINOR_OP_PP_1_1_4, SNOR_PROTO_1_1_4);
++      }
+ }
+ /**
+diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
+index 00bf0d0e955a0..8a846ad86d298 100644
+--- a/drivers/mtd/spi-nor/core.h
++++ b/drivers/mtd/spi-nor/core.h
+@@ -458,6 +458,7 @@ struct spi_nor_fixups {
+  *   SPI_NOR_NO_ERASE:        no erase command needed.
+  *   NO_CHIP_ERASE:           chip does not support chip erase.
+  *   SPI_NOR_NO_FR:           can't do fastread.
++ *   SPI_NOR_QUAD_PP:         flash supports Quad Input Page Program.
+  *
+  * @no_sfdp_flags:  flags that indicate support that can be discovered via SFDP.
+  *                  Used when SFDP tables are not defined in the flash. These
+@@ -507,6 +508,7 @@ struct flash_info {
+ #define SPI_NOR_NO_ERASE              BIT(6)
+ #define NO_CHIP_ERASE                 BIT(7)
+ #define SPI_NOR_NO_FR                 BIT(8)
++#define SPI_NOR_QUAD_PP                       BIT(9)
+       u8 no_sfdp_flags;
+ #define SPI_NOR_SKIP_SFDP             BIT(0)
+diff --git a/drivers/mtd/spi-nor/issi.c b/drivers/mtd/spi-nor/issi.c
+index 89a66a19d754f..7c8eee808dda6 100644
+--- a/drivers/mtd/spi-nor/issi.c
++++ b/drivers/mtd/spi-nor/issi.c
+@@ -73,6 +73,7 @@ static const struct flash_info issi_nor_parts[] = {
+       { "is25wp256", INFO(0x9d7019, 0, 64 * 1024, 512)
+               NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+               FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
++              FLAGS(SPI_NOR_QUAD_PP)
+               .fixups = &is25lp256_fixups },
+       /* PMC */
+-- 
+2.39.2
+
diff --git a/queue-6.1/mtd-spi-nor-spansion-enable-jffs2-write-buffer-for-i.patch b/queue-6.1/mtd-spi-nor-spansion-enable-jffs2-write-buffer-for-i.patch
new file mode 100644 (file)
index 0000000..ef621e2
--- /dev/null
@@ -0,0 +1,108 @@
+From fcae9d741ef75cb2385744e8ff566bea7c8a2515 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Apr 2023 15:17:44 +0900
+Subject: mtd: spi-nor: spansion: Enable JFFS2 write buffer for Infineon s28hx
+ SEMPER flash
+
+From: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
+
+[ Upstream commit 9fd0945fe6fadfb6b54a9cd73be101c02b3e8134 ]
+
+Infineon(Cypress) SEMPER NOR flash family has on-die ECC and its program
+granularity is 16-byte ECC data unit size. JFFS2 supports write buffer
+mode for ECC'd NOR flash. Provide a way to clear the MTD_BIT_WRITEABLE
+flag in order to enable JFFS2 write buffer mode support.
+
+A new SNOR_F_ECC flag is introduced to determine if the part has on-die
+ECC and if it has, MTD_BIT_WRITEABLE is unset.
+
+In vendor specific driver, a common cypress_nor_ecc_init() helper is
+added. This helper takes care for ECC related initialization for SEMPER
+flash family by setting up params->writesize and SNOR_F_ECC.
+
+Fixes: c3266af101f2 ("mtd: spi-nor: spansion: add support for Cypress Semper flash")
+Suggested-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/d586723f6f12aaff44fbcd7b51e674b47ed554ed.1680760742.git.Takahiro.Kuwano@infineon.com
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/spi-nor/core.c     |  3 +++
+ drivers/mtd/spi-nor/core.h     |  1 +
+ drivers/mtd/spi-nor/debugfs.c  |  1 +
+ drivers/mtd/spi-nor/spansion.c | 13 ++++++++++++-
+ 4 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index 621e9ad4bcc39..dc4d86ceee447 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -2942,6 +2942,9 @@ static void spi_nor_set_mtd_info(struct spi_nor *nor)
+               mtd->name = dev_name(dev);
+       mtd->type = MTD_NORFLASH;
+       mtd->flags = MTD_CAP_NORFLASH;
++      /* Unset BIT_WRITEABLE to enable JFFS2 write buffer for ECC'd NOR */
++      if (nor->flags & SNOR_F_ECC)
++              mtd->flags &= ~MTD_BIT_WRITEABLE;
+       if (nor->info->flags & SPI_NOR_NO_ERASE)
+               mtd->flags |= MTD_NO_ERASE;
+       else
+diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
+index f23d1e77199e5..290613fd63ae7 100644
+--- a/drivers/mtd/spi-nor/core.h
++++ b/drivers/mtd/spi-nor/core.h
+@@ -131,6 +131,7 @@ enum spi_nor_option_flags {
+       SNOR_F_SOFT_RESET       = BIT(12),
+       SNOR_F_SWP_IS_VOLATILE  = BIT(13),
+       SNOR_F_RWW              = BIT(14),
++      SNOR_F_ECC              = BIT(15),
+ };
+ struct spi_nor_read_command {
+diff --git a/drivers/mtd/spi-nor/debugfs.c b/drivers/mtd/spi-nor/debugfs.c
+index 8b4922a1aafb9..6d6bd559db8fd 100644
+--- a/drivers/mtd/spi-nor/debugfs.c
++++ b/drivers/mtd/spi-nor/debugfs.c
+@@ -26,6 +26,7 @@ static const char *const snor_f_names[] = {
+       SNOR_F_NAME(SOFT_RESET),
+       SNOR_F_NAME(SWP_IS_VOLATILE),
+       SNOR_F_NAME(RWW),
++      SNOR_F_NAME(ECC),
+ };
+ #undef SNOR_F_NAME
+diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
+index 6bbbfc9c215b8..581f209c27347 100644
+--- a/drivers/mtd/spi-nor/spansion.c
++++ b/drivers/mtd/spi-nor/spansion.c
+@@ -212,6 +212,17 @@ static int cypress_nor_set_page_size(struct spi_nor *nor)
+       return 0;
+ }
++static void cypress_nor_ecc_init(struct spi_nor *nor)
++{
++      /*
++       * Programming is supported only in 16-byte ECC data unit granularity.
++       * Byte-programming, bit-walking, or multiple program operations to the
++       * same ECC data unit without an erase are not allowed.
++       */
++      nor->params->writesize = 16;
++      nor->flags |= SNOR_F_ECC;
++}
++
+ static int
+ s25hx_t_post_bfpt_fixup(struct spi_nor *nor,
+                       const struct sfdp_parameter_header *bfpt_header,
+@@ -318,7 +329,7 @@ static int s28hs512t_post_bfpt_fixup(struct spi_nor *nor,
+ static void s28hs512t_late_init(struct spi_nor *nor)
+ {
+       nor->params->octal_dtr_enable = cypress_nor_octal_dtr_enable;
+-      nor->params->writesize = 16;
++      cypress_nor_ecc_init(nor);
+ }
+ static const struct spi_nor_fixups s28hs512t_fixups = {
+-- 
+2.39.2
+
diff --git a/queue-6.1/mtd-spi-nor-spansion-enable-jffs2-write-buffer-for-i.patch-26314 b/queue-6.1/mtd-spi-nor-spansion-enable-jffs2-write-buffer-for-i.patch-26314
new file mode 100644 (file)
index 0000000..d19c0a2
--- /dev/null
@@ -0,0 +1,49 @@
+From 74149d4095a982008918b7e1ea6f19e625d1fb6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Apr 2023 15:17:45 +0900
+Subject: mtd: spi-nor: spansion: Enable JFFS2 write buffer for Infineon s25hx
+ SEMPER flash
+
+From: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
+
+[ Upstream commit 4199c1719e24e73be0acc8b0146fc31ad8af9771 ]
+
+Infineon(Cypress) SEMPER NOR flash family has on-die ECC and its program
+granularity is 16-byte ECC data unit size. JFFS2 supports write buffer
+mode for ECC'd NOR flash. Provide a way to clear the MTD_BIT_WRITEABLE
+flag in order to enable JFFS2 write buffer mode support.
+
+Fixes: b6b23833fc42 ("mtd: spi-nor: spansion: Add s25hl-t/s25hs-t IDs and fixups")
+Suggested-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/a1cc128e094db4ec141f85bd380127598dfef17e.1680760742.git.Takahiro.Kuwano@infineon.com
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/spi-nor/spansion.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
+index 581f209c27347..7e7c68fc7776d 100644
+--- a/drivers/mtd/spi-nor/spansion.c
++++ b/drivers/mtd/spi-nor/spansion.c
+@@ -260,13 +260,10 @@ static void s25hx_t_post_sfdp_fixup(struct spi_nor *nor)
+ static void s25hx_t_late_init(struct spi_nor *nor)
+ {
+-      struct spi_nor_flash_parameter *params = nor->params;
+-
+       /* Fast Read 4B requires mode cycles */
+-      params->reads[SNOR_CMD_READ_FAST].num_mode_clocks = 8;
++      nor->params->reads[SNOR_CMD_READ_FAST].num_mode_clocks = 8;
+-      /* The writesize should be ECC data unit size */
+-      params->writesize = 16;
++      cypress_nor_ecc_init(nor);
+ }
+ static struct spi_nor_fixups s25hx_t_fixups = {
+-- 
+2.39.2
+
diff --git a/queue-6.1/mtd-spi-nor-spansion-remove-no_sfdp_flags-from-s28hs.patch b/queue-6.1/mtd-spi-nor-spansion-remove-no_sfdp_flags-from-s28hs.patch
new file mode 100644 (file)
index 0000000..6baa94d
--- /dev/null
@@ -0,0 +1,71 @@
+From 169676c426e3a8a1d5d4a3c312378b7e95367aed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Aug 2022 13:59:04 +0900
+Subject: mtd: spi-nor: spansion: Remove NO_SFDP_FLAGS from s28hs512t info
+
+From: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
+
+[ Upstream commit db391efe765cc6cfc0ffc8d8ef146dc8e6816a7e ]
+
+Read, Page Program, and Sector Erase settings are done in SFDP so we can
+remove NO_SFDP_FLAGS from s28hs512t info. Since the default_init() is no
+longer called after removing NO_SFDP_FLAGS, the initialization in the
+default_init() is moved to late_init().
+
+Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
+Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
+Link: https://lore.kernel.org/r/12e468992f5d0cbd474abff3203100cc8163d4e5.1661915569.git.Takahiro.Kuwano@infineon.com
+Stable-dep-of: 9fd0945fe6fa ("mtd: spi-nor: spansion: Enable JFFS2 write buffer for Infineon s28hx SEMPER flash")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/spi-nor/spansion.c | 17 ++++++++---------
+ 1 file changed, 8 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
+index 7ac2ad1a8d576..6bbbfc9c215b8 100644
+--- a/drivers/mtd/spi-nor/spansion.c
++++ b/drivers/mtd/spi-nor/spansion.c
+@@ -280,12 +280,6 @@ static int cypress_nor_octal_dtr_enable(struct spi_nor *nor, bool enable)
+                       cypress_nor_octal_dtr_dis(nor);
+ }
+-static void s28hs512t_default_init(struct spi_nor *nor)
+-{
+-      nor->params->octal_dtr_enable = cypress_nor_octal_dtr_enable;
+-      nor->params->writesize = 16;
+-}
+-
+ static void s28hs512t_post_sfdp_fixup(struct spi_nor *nor)
+ {
+       /*
+@@ -321,10 +315,16 @@ static int s28hs512t_post_bfpt_fixup(struct spi_nor *nor,
+       return cypress_nor_set_page_size(nor);
+ }
++static void s28hs512t_late_init(struct spi_nor *nor)
++{
++      nor->params->octal_dtr_enable = cypress_nor_octal_dtr_enable;
++      nor->params->writesize = 16;
++}
++
+ static const struct spi_nor_fixups s28hs512t_fixups = {
+-      .default_init = s28hs512t_default_init,
+       .post_sfdp = s28hs512t_post_sfdp_fixup,
+       .post_bfpt = s28hs512t_post_bfpt_fixup,
++      .late_init = s28hs512t_late_init,
+ };
+ static int
+@@ -459,8 +459,7 @@ static const struct flash_info spansion_nor_parts[] = {
+       { "cy15x104q",  INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1)
+               FLAGS(SPI_NOR_NO_ERASE) },
+       { "s28hs512t",   INFO(0x345b1a,      0, 256 * 1024, 256)
+-              NO_SFDP_FLAGS(SECT_4K | SPI_NOR_OCTAL_DTR_READ |
+-                            SPI_NOR_OCTAL_DTR_PP)
++              PARSE_SFDP
+               .fixups = &s28hs512t_fixups,
+       },
+ };
+-- 
+2.39.2
+
diff --git a/queue-6.1/perf-x86-core-zero-lbr-instead-of-returning-1-in-x86.patch b/queue-6.1/perf-x86-core-zero-lbr-instead-of-returning-1-in-x86.patch
new file mode 100644 (file)
index 0000000..fc06776
--- /dev/null
@@ -0,0 +1,96 @@
+From 56a0ad9c19f4b41e9d680010c2d2505aa7f2ff9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Oct 2022 00:03:07 +0000
+Subject: perf/x86/core: Zero @lbr instead of returning -1 in
+ x86_perf_get_lbr() stub
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 0b9ca98b722969660ad98b39f766a561ccb39f5f ]
+
+Drop the return value from x86_perf_get_lbr() and have the stub zero out
+the @lbr structure instead of returning -1 to indicate "no LBR support".
+KVM doesn't actually check the return value, and instead subtly relies on
+zeroing the number of LBRs in intel_pmu_init().
+
+Formalize "nr=0 means unsupported" so that KVM doesn't need to add a
+pointless check on the return value to fix KVM's benign bug.
+
+Note, the stub is necessary even though KVM x86 selects PERF_EVENTS and
+the caller exists only when CONFIG_KVM_INTEL=y.  Despite the name,
+KVM_INTEL doesn't strictly require CPU_SUP_INTEL, it can be built with
+any of INTEL || CENTAUR || ZHAOXIN CPUs.
+
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20221006000314.73240-2-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Stable-dep-of: 098f4c061ea1 ("KVM: x86/pmu: Disallow legacy LBRs if architectural LBRs are available")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/intel/lbr.c       | 6 +-----
+ arch/x86/include/asm/perf_event.h | 6 +++---
+ arch/x86/kvm/vmx/capabilities.h   | 3 ++-
+ 3 files changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
+index 8259d725054d0..4dbde69c423ba 100644
+--- a/arch/x86/events/intel/lbr.c
++++ b/arch/x86/events/intel/lbr.c
+@@ -1603,10 +1603,8 @@ void __init intel_pmu_arch_lbr_init(void)
+  * x86_perf_get_lbr - get the LBR records information
+  *
+  * @lbr: the caller's memory to store the LBR records information
+- *
+- * Returns: 0 indicates the LBR info has been successfully obtained
+  */
+-int x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
++void x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
+ {
+       int lbr_fmt = x86_pmu.intel_cap.lbr_format;
+@@ -1614,8 +1612,6 @@ int x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
+       lbr->from = x86_pmu.lbr_from;
+       lbr->to = x86_pmu.lbr_to;
+       lbr->info = (lbr_fmt == LBR_FORMAT_INFO) ? x86_pmu.lbr_info : 0;
+-
+-      return 0;
+ }
+ EXPORT_SYMBOL_GPL(x86_perf_get_lbr);
+diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
+index 9ac46dbe57d48..5d0f6891ae611 100644
+--- a/arch/x86/include/asm/perf_event.h
++++ b/arch/x86/include/asm/perf_event.h
+@@ -543,12 +543,12 @@ static inline void perf_check_microcode(void) { }
+ #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
+ extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr, void *data);
+-extern int x86_perf_get_lbr(struct x86_pmu_lbr *lbr);
++extern void x86_perf_get_lbr(struct x86_pmu_lbr *lbr);
+ #else
+ struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr, void *data);
+-static inline int x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
++static inline void x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
+ {
+-      return -1;
++      memset(lbr, 0, sizeof(*lbr));
+ }
+ #endif
+diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h
+index 07254314f3dd5..479124e49bbda 100644
+--- a/arch/x86/kvm/vmx/capabilities.h
++++ b/arch/x86/kvm/vmx/capabilities.h
+@@ -407,7 +407,8 @@ static inline u64 vmx_get_perf_capabilities(void)
+       if (boot_cpu_has(X86_FEATURE_PDCM))
+               rdmsrl(MSR_IA32_PERF_CAPABILITIES, host_perf_cap);
+-      if (x86_perf_get_lbr(&lbr) >= 0 && lbr.nr)
++      x86_perf_get_lbr(&lbr);
++      if (lbr.nr)
+               perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT;
+       if (vmx_pebs_supported()) {
+-- 
+2.39.2
+
diff --git a/queue-6.1/qcom-llcc-edac-support-polling-mode-for-ecc-handling.patch b/queue-6.1/qcom-llcc-edac-support-polling-mode-for-ecc-handling.patch
new file mode 100644 (file)
index 0000000..f21632f
--- /dev/null
@@ -0,0 +1,147 @@
+From cfc932a2861ef12a5c5b4d532321d22e2d83c7f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Mar 2023 13:34:42 +0530
+Subject: qcom: llcc/edac: Support polling mode for ECC handling
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 721d3e91bfc93975c5e1a76c7d588dd8df5d82da ]
+
+Not all Qcom platforms support IRQ mode for ECC handling. For those
+platforms, the current EDAC driver will not be probed due to missing ECC
+IRQ in devicetree.
+
+So add support for polling mode so that the EDAC driver can be used on all
+Qcom platforms supporting LLCC.
+
+The polling delay of 5000ms is chosen based on Qcom downstream/vendor
+driver.
+
+Reported-by: Luca Weiss <luca.weiss@fairphone.com>
+Tested-by: Luca Weiss <luca.weiss@fairphone.com>
+Tested-by: Steev Klimaszewski <steev@kali.org> # Thinkpad X13s
+Tested-by: Andrew Halaney <ahalaney@redhat.com> # sa8540p-ride
+Reviewed-by: Borislav Petkov (AMD) <bp@alien8.de>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230314080443.64635-14-manivannan.sadhasivam@linaro.org
+Stable-dep-of: cca94f1dd6d0 ("soc: qcom: llcc: Do not create EDAC platform device on SDM845")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/qcom_edac.c     | 50 +++++++++++++++++++++---------------
+ drivers/soc/qcom/llcc-qcom.c | 13 +++++-----
+ 2 files changed, 35 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/edac/qcom_edac.c b/drivers/edac/qcom_edac.c
+index c45519f59dc11..2c91ceff8a9ca 100644
+--- a/drivers/edac/qcom_edac.c
++++ b/drivers/edac/qcom_edac.c
+@@ -76,6 +76,8 @@
+ #define DRP0_INTERRUPT_ENABLE           BIT(6)
+ #define SB_DB_DRP_INTERRUPT_ENABLE      0x3
++#define ECC_POLL_MSEC                 5000
++
+ enum {
+       LLCC_DRAM_CE = 0,
+       LLCC_DRAM_UE,
+@@ -285,8 +287,7 @@ dump_syn_reg(struct edac_device_ctl_info *edev_ctl, int err_type, u32 bank)
+       return ret;
+ }
+-static irqreturn_t
+-llcc_ecc_irq_handler(int irq, void *edev_ctl)
++static irqreturn_t llcc_ecc_irq_handler(int irq, void *edev_ctl)
+ {
+       struct edac_device_ctl_info *edac_dev_ctl = edev_ctl;
+       struct llcc_drv_data *drv = edac_dev_ctl->dev->platform_data;
+@@ -332,6 +333,11 @@ llcc_ecc_irq_handler(int irq, void *edev_ctl)
+       return irq_rc;
+ }
++static void llcc_ecc_check(struct edac_device_ctl_info *edev_ctl)
++{
++      llcc_ecc_irq_handler(0, edev_ctl);
++}
++
+ static int qcom_llcc_edac_probe(struct platform_device *pdev)
+ {
+       struct llcc_drv_data *llcc_driv_data = pdev->dev.platform_data;
+@@ -359,29 +365,31 @@ static int qcom_llcc_edac_probe(struct platform_device *pdev)
+       edev_ctl->ctl_name = "llcc";
+       edev_ctl->panic_on_ue = LLCC_ERP_PANIC_ON_UE;
+-      rc = edac_device_add_device(edev_ctl);
+-      if (rc)
+-              goto out_mem;
+-
+-      platform_set_drvdata(pdev, edev_ctl);
+-
+-      /* Request for ecc irq */
++      /* Check if LLCC driver has passed ECC IRQ */
+       ecc_irq = llcc_driv_data->ecc_irq;
+-      if (ecc_irq < 0) {
+-              rc = -ENODEV;
+-              goto out_dev;
+-      }
+-      rc = devm_request_irq(dev, ecc_irq, llcc_ecc_irq_handler,
++      if (ecc_irq > 0) {
++              /* Use interrupt mode if IRQ is available */
++              rc = devm_request_irq(dev, ecc_irq, llcc_ecc_irq_handler,
+                             IRQF_TRIGGER_HIGH, "llcc_ecc", edev_ctl);
+-      if (rc)
+-              goto out_dev;
++              if (!rc) {
++                      edac_op_state = EDAC_OPSTATE_INT;
++                      goto irq_done;
++              }
++      }
+-      return rc;
++      /* Fall back to polling mode otherwise */
++      edev_ctl->poll_msec = ECC_POLL_MSEC;
++      edev_ctl->edac_check = llcc_ecc_check;
++      edac_op_state = EDAC_OPSTATE_POLL;
+-out_dev:
+-      edac_device_del_device(edev_ctl->dev);
+-out_mem:
+-      edac_device_free_ctl_info(edev_ctl);
++irq_done:
++      rc = edac_device_add_device(edev_ctl);
++      if (rc) {
++              edac_device_free_ctl_info(edev_ctl);
++              return rc;
++      }
++
++      platform_set_drvdata(pdev, edev_ctl);
+       return rc;
+ }
+diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
+index 9c6cf2f5d77ce..63a08635fc159 100644
+--- a/drivers/soc/qcom/llcc-qcom.c
++++ b/drivers/soc/qcom/llcc-qcom.c
+@@ -850,13 +850,12 @@ static int qcom_llcc_probe(struct platform_device *pdev)
+               goto err;
+       drv_data->ecc_irq = platform_get_irq_optional(pdev, 0);
+-      if (drv_data->ecc_irq >= 0) {
+-              llcc_edac = platform_device_register_data(&pdev->dev,
+-                                              "qcom_llcc_edac", -1, drv_data,
+-                                              sizeof(*drv_data));
+-              if (IS_ERR(llcc_edac))
+-                      dev_err(dev, "Failed to register llcc edac driver\n");
+-      }
++
++      llcc_edac = platform_device_register_data(&pdev->dev,
++                                      "qcom_llcc_edac", -1, drv_data,
++                                      sizeof(*drv_data));
++      if (IS_ERR(llcc_edac))
++              dev_err(dev, "Failed to register llcc edac driver\n");
+       return 0;
+ err:
+-- 
+2.39.2
+
diff --git a/queue-6.1/series b/queue-6.1/series
new file mode 100644 (file)
index 0000000..e010c42
--- /dev/null
@@ -0,0 +1,17 @@
+usb-dwc3-gadget-drop-dead-hibernation-code.patch
+usb-dwc3-gadget-execute-gadget-stop-after-halting-th.patch
+drm-vmwgfx-remove-explicit-and-broken-vblank-handlin.patch
+drm-vmwgfx-fix-legacy-display-unit-atomic-drm-suppor.patch
+crypto-ccp-clear-psp-interrupt-status-register-befor.patch
+perf-x86-core-zero-lbr-instead-of-returning-1-in-x86.patch
+kvm-x86-track-supported-perf_capabilities-in-kvm_cap.patch
+kvm-x86-pmu-disallow-legacy-lbrs-if-architectural-lb.patch
+mtd-spi-nor-spansion-remove-no_sfdp_flags-from-s28hs.patch
+mtd-spi-nor-add-sfdp-fixups-for-quad-page-program.patch
+mtd-spi-nor-add-a-rww-flag.patch
+mtd-spi-nor-spansion-enable-jffs2-write-buffer-for-i.patch
+qcom-llcc-edac-support-polling-mode-for-ecc-handling.patch
+soc-qcom-llcc-do-not-create-edac-platform-device-on-.patch
+mailbox-zynq-switch-to-flexible-array-to-simplify-co.patch
+mailbox-zynqmp-fix-counts-of-child-nodes.patch
+mtd-spi-nor-spansion-enable-jffs2-write-buffer-for-i.patch-26314
diff --git a/queue-6.1/soc-qcom-llcc-do-not-create-edac-platform-device-on-.patch b/queue-6.1/soc-qcom-llcc-do-not-create-edac-platform-device-on-.patch
new file mode 100644 (file)
index 0000000..134b55d
--- /dev/null
@@ -0,0 +1,82 @@
+From 3652e1d712d275ed7a4453383773080551ab627f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Mar 2023 13:34:43 +0530
+Subject: soc: qcom: llcc: Do not create EDAC platform device on SDM845
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit cca94f1dd6d0a4c7e5c8190672f5747e3c00ddde ]
+
+The platforms based on SDM845 SoC locks the access to EDAC registers in the
+bootloader. So probing the EDAC driver will result in a crash. Hence,
+disable the creation of EDAC platform device on all SDM845 devices.
+
+The issue has been observed on Lenovo Yoga C630 and DB845c.
+
+While at it, also sort the members of `struct qcom_llcc_config` to avoid
+any holes in-between.
+
+Cc: <stable@vger.kernel.org> # 5.10
+Reported-by: Steev Klimaszewski <steev@kali.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20230314080443.64635-15-manivannan.sadhasivam@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/llcc-qcom.c | 24 +++++++++++++++++-------
+ 1 file changed, 17 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
+index 63a08635fc159..d4cba3b3c56c4 100644
+--- a/drivers/soc/qcom/llcc-qcom.c
++++ b/drivers/soc/qcom/llcc-qcom.c
+@@ -101,10 +101,11 @@ struct llcc_slice_config {
+ struct qcom_llcc_config {
+       const struct llcc_slice_config *sct_data;
+-      int size;
+-      bool need_llcc_cfg;
+       const u32 *reg_offset;
+       const struct llcc_edac_reg_offset *edac_reg_offset;
++      int size;
++      bool need_llcc_cfg;
++      bool no_edac;
+ };
+ enum llcc_reg_offset {
+@@ -401,6 +402,7 @@ static const struct qcom_llcc_config sdm845_cfg = {
+       .need_llcc_cfg  = false,
+       .reg_offset     = llcc_v1_reg_offset,
+       .edac_reg_offset = &llcc_v1_edac_reg_offset,
++      .no_edac        = true,
+ };
+ static const struct qcom_llcc_config sm6350_cfg = {
+@@ -851,11 +853,19 @@ static int qcom_llcc_probe(struct platform_device *pdev)
+       drv_data->ecc_irq = platform_get_irq_optional(pdev, 0);
+-      llcc_edac = platform_device_register_data(&pdev->dev,
+-                                      "qcom_llcc_edac", -1, drv_data,
+-                                      sizeof(*drv_data));
+-      if (IS_ERR(llcc_edac))
+-              dev_err(dev, "Failed to register llcc edac driver\n");
++      /*
++       * On some platforms, the access to EDAC registers will be locked by
++       * the bootloader. So probing the EDAC driver will result in a crash.
++       * Hence, disable the creation of EDAC platform device for the
++       * problematic platforms.
++       */
++      if (!cfg->no_edac) {
++              llcc_edac = platform_device_register_data(&pdev->dev,
++                                              "qcom_llcc_edac", -1, drv_data,
++                                              sizeof(*drv_data));
++              if (IS_ERR(llcc_edac))
++                      dev_err(dev, "Failed to register llcc edac driver\n");
++      }
+       return 0;
+ err:
+-- 
+2.39.2
+
diff --git a/queue-6.1/usb-dwc3-gadget-drop-dead-hibernation-code.patch b/queue-6.1/usb-dwc3-gadget-drop-dead-hibernation-code.patch
new file mode 100644 (file)
index 0000000..1a3fa11
--- /dev/null
@@ -0,0 +1,141 @@
+From 7b152b997d3238abd30da7e7328659f3df663e70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Apr 2023 09:25:17 +0200
+Subject: USB: dwc3: gadget: drop dead hibernation code
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit bdb19d01026a5cccfa437be8adcf2df472c5889e ]
+
+The hibernation code is broken and has never been enabled in mainline
+and should thus be dropped.
+
+Remove the hibernation bits from the gadget code, which effectively
+reverts commits e1dadd3b0f27 ("usb: dwc3: workaround: bogus hibernation
+events") and 7b2a0368bbc9 ("usb: dwc3: gadget: set KEEP_CONNECT in case
+of hibernation") except for the spurious interrupt warning.
+
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Link: https://lore.kernel.org/r/20230404072524.19014-5-johan+linaro@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 39674be56fba ("usb: dwc3: gadget: Execute gadget stop after halting the controller")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/gadget.c | 46 +++++----------------------------------
+ 1 file changed, 6 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index d2622378ce040..2a6a5ffa54836 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -2468,7 +2468,7 @@ static void __dwc3_gadget_set_speed(struct dwc3 *dwc)
+       dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+ }
+-static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
++static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
+ {
+       u32                     reg;
+       u32                     timeout = 2000;
+@@ -2487,17 +2487,11 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
+                       reg &= ~DWC3_DCTL_KEEP_CONNECT;
+               reg |= DWC3_DCTL_RUN_STOP;
+-              if (dwc->has_hibernation)
+-                      reg |= DWC3_DCTL_KEEP_CONNECT;
+-
+               __dwc3_gadget_set_speed(dwc);
+               dwc->pullups_connected = true;
+       } else {
+               reg &= ~DWC3_DCTL_RUN_STOP;
+-              if (dwc->has_hibernation && !suspend)
+-                      reg &= ~DWC3_DCTL_KEEP_CONNECT;
+-
+               dwc->pullups_connected = false;
+       }
+@@ -2579,7 +2573,7 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
+        * remaining event generated by the controller while polling for
+        * DSTS.DEVCTLHLT.
+        */
+-      return dwc3_gadget_run_stop(dwc, false, false);
++      return dwc3_gadget_run_stop(dwc, false);
+ }
+ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
+@@ -2633,7 +2627,7 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
+               dwc3_event_buffers_setup(dwc);
+               __dwc3_gadget_start(dwc);
+-              ret = dwc3_gadget_run_stop(dwc, true, false);
++              ret = dwc3_gadget_run_stop(dwc, true);
+       }
+       pm_runtime_put(dwc->dev);
+@@ -4200,30 +4194,6 @@ static void dwc3_gadget_suspend_interrupt(struct dwc3 *dwc,
+       dwc->link_state = next;
+ }
+-static void dwc3_gadget_hibernation_interrupt(struct dwc3 *dwc,
+-              unsigned int evtinfo)
+-{
+-      unsigned int is_ss = evtinfo & BIT(4);
+-
+-      /*
+-       * WORKAROUND: DWC3 revision 2.20a with hibernation support
+-       * have a known issue which can cause USB CV TD.9.23 to fail
+-       * randomly.
+-       *
+-       * Because of this issue, core could generate bogus hibernation
+-       * events which SW needs to ignore.
+-       *
+-       * Refers to:
+-       *
+-       * STAR#9000546576: Device Mode Hibernation: Issue in USB 2.0
+-       * Device Fallback from SuperSpeed
+-       */
+-      if (is_ss ^ (dwc->speed == USB_SPEED_SUPER))
+-              return;
+-
+-      /* enter hibernation here */
+-}
+-
+ static void dwc3_gadget_interrupt(struct dwc3 *dwc,
+               const struct dwc3_event_devt *event)
+ {
+@@ -4241,11 +4211,7 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc,
+               dwc3_gadget_wakeup_interrupt(dwc);
+               break;
+       case DWC3_DEVICE_EVENT_HIBER_REQ:
+-              if (dev_WARN_ONCE(dwc->dev, !dwc->has_hibernation,
+-                                      "unexpected hibernation event\n"))
+-                      break;
+-
+-              dwc3_gadget_hibernation_interrupt(dwc, event->event_info);
++              dev_WARN_ONCE(dwc->dev, true, "unexpected hibernation event\n");
+               break;
+       case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
+               dwc3_gadget_linksts_change_interrupt(dwc, event->event_info);
+@@ -4582,7 +4548,7 @@ int dwc3_gadget_suspend(struct dwc3 *dwc)
+       if (!dwc->gadget_driver)
+               return 0;
+-      dwc3_gadget_run_stop(dwc, false, false);
++      dwc3_gadget_run_stop(dwc, false);
+       spin_lock_irqsave(&dwc->lock, flags);
+       dwc3_disconnect_gadget(dwc);
+@@ -4603,7 +4569,7 @@ int dwc3_gadget_resume(struct dwc3 *dwc)
+       if (ret < 0)
+               goto err0;
+-      ret = dwc3_gadget_run_stop(dwc, true, false);
++      ret = dwc3_gadget_run_stop(dwc, true);
+       if (ret < 0)
+               goto err1;
+-- 
+2.39.2
+
diff --git a/queue-6.1/usb-dwc3-gadget-execute-gadget-stop-after-halting-th.patch b/queue-6.1/usb-dwc3-gadget-execute-gadget-stop-after-halting-th.patch
new file mode 100644 (file)
index 0000000..fe557e4
--- /dev/null
@@ -0,0 +1,61 @@
+From 1cd45cc5f6694f3e8025f7dcc6b21723818f14d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Apr 2023 14:27:58 -0700
+Subject: usb: dwc3: gadget: Execute gadget stop after halting the controller
+
+From: Wesley Cheng <quic_wcheng@quicinc.com>
+
+[ Upstream commit 39674be56fba1cd3a03bf4617f523a35f85fd2c1 ]
+
+Do not call gadget stop until the poll for controller halt is
+completed.  DEVTEN is cleared as part of gadget stop, so the intention to
+allow ep0 events to continue while waiting for controller halt is not
+happening.
+
+Fixes: c96683798e27 ("usb: dwc3: ep0: Don't prepare beyond Setup stage")
+Cc: stable@vger.kernel.org
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
+Link: https://lore.kernel.org/r/20230420212759.29429-2-quic_wcheng@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/gadget.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 2a6a5ffa54836..daa7673833557 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -2536,7 +2536,6 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
+        * bit.
+        */
+       dwc3_stop_active_transfers(dwc);
+-      __dwc3_gadget_stop(dwc);
+       spin_unlock_irqrestore(&dwc->lock, flags);
+       /*
+@@ -2573,7 +2572,19 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
+        * remaining event generated by the controller while polling for
+        * DSTS.DEVCTLHLT.
+        */
+-      return dwc3_gadget_run_stop(dwc, false);
++      ret = dwc3_gadget_run_stop(dwc, false);
++
++      /*
++       * Stop the gadget after controller is halted, so that if needed, the
++       * events to update EP0 state can still occur while the run/stop
++       * routine polls for the halted state.  DEVTEN is cleared as part of
++       * gadget stop.
++       */
++      spin_lock_irqsave(&dwc->lock, flags);
++      __dwc3_gadget_stop(dwc);
++      spin_unlock_irqrestore(&dwc->lock, flags);
++
++      return ret;
+ }
+ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
+-- 
+2.39.2
+