--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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(¶ms->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(¶ms->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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+