--- /dev/null
+From 61f9e455ee9a802d89a2212de388811b15ed43e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 22:39:45 +0800
+Subject: btrfs: fix extent map use-after-free when handling missing device in
+ read_one_chunk
+
+From: void0red <void0red@gmail.com>
+
+[ Upstream commit 1742e1c90c3da344f3bb9b1f1309b3f47482756a ]
+
+Store the error code before freeing the extent_map. Though it's
+reference counted structure, in that function it's the first and last
+allocation so this would lead to a potential use-after-free.
+
+The error can happen eg. when chunk is stored on a missing device and
+the degraded mount option is missing.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216721
+Reported-by: eriri <1527030098@qq.com>
+Fixes: adfb69af7d8c ("btrfs: add_missing_dev() should return the actual error")
+CC: stable@vger.kernel.org # 4.9+
+Signed-off-by: void0red <void0red@gmail.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/volumes.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index c773ecba7c2d..6b86a3cec04c 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -7155,8 +7155,9 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ map->stripes[i].dev = handle_missing_device(fs_info,
+ devid, uuid);
+ if (IS_ERR(map->stripes[i].dev)) {
++ ret = PTR_ERR(map->stripes[i].dev);
+ free_extent_map(em);
+- return PTR_ERR(map->stripes[i].dev);
++ return ret;
+ }
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 4841bb739cab1b30bf6256543959cee61018ec03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jan 2022 18:00:26 +0200
+Subject: btrfs: move missing device handling in a dedicate function
+
+From: Nikolay Borisov <nborisov@suse.com>
+
+[ Upstream commit ff37c89f94be14b0e22a532d1e6d57187bfd5bb8 ]
+
+This simplifies the code flow in read_one_chunk and makes error handling
+when handling missing devices a bit simpler by reducing it to a single
+check if something went wrong. No functional changes.
+
+Reviewed-by: Su Yue <l@damenly.su>
+Signed-off-by: Nikolay Borisov <nborisov@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: 1742e1c90c3d ("btrfs: fix extent map use-after-free when handling missing device in read_one_chunk")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/volumes.c | 38 ++++++++++++++++++++++++--------------
+ 1 file changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index c886ec81c5d0..c773ecba7c2d 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -7043,6 +7043,27 @@ static void warn_32bit_meta_chunk(struct btrfs_fs_info *fs_info,
+ }
+ #endif
+
++static struct btrfs_device *handle_missing_device(struct btrfs_fs_info *fs_info,
++ u64 devid, u8 *uuid)
++{
++ struct btrfs_device *dev;
++
++ if (!btrfs_test_opt(fs_info, DEGRADED)) {
++ btrfs_report_missing_device(fs_info, devid, uuid, true);
++ return ERR_PTR(-ENOENT);
++ }
++
++ dev = add_missing_dev(fs_info->fs_devices, devid, uuid);
++ if (IS_ERR(dev)) {
++ btrfs_err(fs_info, "failed to init missing device %llu: %ld",
++ devid, PTR_ERR(dev));
++ return dev;
++ }
++ btrfs_report_missing_device(fs_info, devid, uuid, false);
++
++ return dev;
++}
++
+ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ struct btrfs_chunk *chunk)
+ {
+@@ -7130,28 +7151,17 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ BTRFS_UUID_SIZE);
+ args.uuid = uuid;
+ map->stripes[i].dev = btrfs_find_device(fs_info->fs_devices, &args);
+- if (!map->stripes[i].dev &&
+- !btrfs_test_opt(fs_info, DEGRADED)) {
+- free_extent_map(em);
+- btrfs_report_missing_device(fs_info, devid, uuid, true);
+- return -ENOENT;
+- }
+ if (!map->stripes[i].dev) {
+- map->stripes[i].dev =
+- add_missing_dev(fs_info->fs_devices, devid,
+- uuid);
++ map->stripes[i].dev = handle_missing_device(fs_info,
++ devid, uuid);
+ if (IS_ERR(map->stripes[i].dev)) {
+ free_extent_map(em);
+- btrfs_err(fs_info,
+- "failed to init missing dev %llu: %ld",
+- devid, PTR_ERR(map->stripes[i].dev));
+ return PTR_ERR(map->stripes[i].dev);
+ }
+- btrfs_report_missing_device(fs_info, devid, uuid, false);
+ }
++
+ set_bit(BTRFS_DEV_STATE_IN_FS_METADATA,
+ &(map->stripes[i].dev->dev_state));
+-
+ }
+
+ write_lock(&map_tree->lock);
+--
+2.35.1
+
--- /dev/null
+From 74fac19f8f48d77cc5065a0fa9713d51c08078c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jan 2023 11:14:45 -0500
+Subject: btrfs: replace strncpy() with strscpy()
+
+[ Upstream commit 63d5429f68a3d4c4aa27e65a05196c17f86c41d6 ]
+
+Using strncpy() on NUL-terminated strings are deprecated. To avoid
+possible forming of non-terminated string strscpy() should be used.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+CC: stable@vger.kernel.org # 4.9+
+Signed-off-by: Artem Chernyshev <artem.chernyshev@red-soft.ru>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/ioctl.c | 9 +++------
+ fs/btrfs/rcu-string.h | 6 +++++-
+ 2 files changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index 391a4af9c5e5..ed9c715d2579 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -3415,13 +3415,10 @@ static long btrfs_ioctl_dev_info(struct btrfs_fs_info *fs_info,
+ di_args->bytes_used = btrfs_device_get_bytes_used(dev);
+ di_args->total_bytes = btrfs_device_get_total_bytes(dev);
+ memcpy(di_args->uuid, dev->uuid, sizeof(di_args->uuid));
+- if (dev->name) {
+- strncpy(di_args->path, rcu_str_deref(dev->name),
+- sizeof(di_args->path) - 1);
+- di_args->path[sizeof(di_args->path) - 1] = 0;
+- } else {
++ if (dev->name)
++ strscpy(di_args->path, rcu_str_deref(dev->name), sizeof(di_args->path));
++ else
+ di_args->path[0] = '\0';
+- }
+
+ out:
+ rcu_read_unlock();
+diff --git a/fs/btrfs/rcu-string.h b/fs/btrfs/rcu-string.h
+index 5c1a617eb25d..5c2b66d155ef 100644
+--- a/fs/btrfs/rcu-string.h
++++ b/fs/btrfs/rcu-string.h
+@@ -18,7 +18,11 @@ static inline struct rcu_string *rcu_string_strdup(const char *src, gfp_t mask)
+ (len * sizeof(char)), mask);
+ if (!ret)
+ return ret;
+- strncpy(ret->str, src, len);
++ /* Warn if the source got unexpectedly truncated. */
++ if (WARN_ON(strscpy(ret->str, src, len) < 0)) {
++ kfree(ret);
++ return NULL;
++ }
+ return ret;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From ae14634deb03836d018c00fd22a3b6614adcb11d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Sep 2022 16:02:26 +0530
+Subject: media: s5p-mfc: Clear workbit to handle error condition
+
+From: Smitha T Murthy <smitha.t@samsung.com>
+
+[ Upstream commit d3f3c2fe54e30b0636496d842ffbb5ad3a547f9b ]
+
+During error on CLOSE_INSTANCE command, ctx_work_bits was not getting
+cleared. During consequent mfc execution NULL pointer dereferencing of
+this context led to kernel panic. This patch fixes this issue by making
+sure to clear ctx_work_bits always.
+
+Fixes: 818cd91ab8c6 ("[media] s5p-mfc: Extract open/close MFC instance commands")
+Cc: stable@vger.kernel.org
+Cc: linux-fsd@tesla.com
+Signed-off-by: Smitha T Murthy <smitha.t@samsung.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
+index da138c314963..58822ec5370e 100644
+--- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
+@@ -468,8 +468,10 @@ void s5p_mfc_close_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx)
+ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
+ /* Wait until instance is returned or timeout occurred */
+ if (s5p_mfc_wait_for_done_ctx(ctx,
+- S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0))
++ S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)){
++ clear_work_bit_irqsave(ctx);
+ mfc_err("Err returning instance\n");
++ }
+
+ /* Free resources */
+ s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx);
+--
+2.35.1
+
--- /dev/null
+From b35e4c69785813167b2ff76dff4b0ad78da83e46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Sep 2022 16:02:25 +0530
+Subject: media: s5p-mfc: Fix in register read and write for H264
+
+From: Smitha T Murthy <smitha.t@samsung.com>
+
+[ Upstream commit 06710cd5d2436135046898d7e4b9408c8bb99446 ]
+
+Few of the H264 encoder registers written were not getting reflected
+since the read values were not stored and getting overwritten.
+
+Fixes: 6a9c6f681257 ("[media] s5p-mfc: Add variants to access mfc registers")
+
+Cc: stable@vger.kernel.org
+Cc: linux-fsd@tesla.com
+Signed-off-by: Smitha T Murthy <smitha.t@samsung.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
+index a1453053e31a..ef8169f6c428 100644
+--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
+@@ -1060,7 +1060,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+ }
+
+ /* aspect ratio VUI */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 5);
+ reg |= ((p_h264->vui_sar & 0x1) << 5);
+ writel(reg, mfc_regs->e_h264_options);
+@@ -1083,7 +1083,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+
+ /* intra picture period for H.264 open GOP */
+ /* control */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 4);
+ reg |= ((p_h264->open_gop & 0x1) << 4);
+ writel(reg, mfc_regs->e_h264_options);
+@@ -1097,23 +1097,23 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+ }
+
+ /* 'WEIGHTED_BI_PREDICTION' for B is disable */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x3 << 9);
+ writel(reg, mfc_regs->e_h264_options);
+
+ /* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 14);
+ writel(reg, mfc_regs->e_h264_options);
+
+ /* ASO */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 6);
+ reg |= ((p_h264->aso & 0x1) << 6);
+ writel(reg, mfc_regs->e_h264_options);
+
+ /* hier qp enable */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 8);
+ reg |= ((p_h264->open_gop & 0x1) << 8);
+ writel(reg, mfc_regs->e_h264_options);
+@@ -1134,7 +1134,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+ writel(reg, mfc_regs->e_h264_num_t_layer);
+
+ /* frame packing SEI generation */
+- readl(mfc_regs->e_h264_options);
++ reg = readl(mfc_regs->e_h264_options);
+ reg &= ~(0x1 << 25);
+ reg |= ((p_h264->sei_frame_packing & 0x1) << 25);
+ writel(reg, mfc_regs->e_h264_options);
+--
+2.35.1
+
--- /dev/null
+From 8e9110a0e45bc99bcfafc6fe4d5b7a26b7cc1bab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Sep 2022 16:02:27 +0530
+Subject: media: s5p-mfc: Fix to handle reference queue during finishing
+
+From: Smitha T Murthy <smitha.t@samsung.com>
+
+[ Upstream commit d8a46bc4e1e0446459daa77c4ce14218d32dacf9 ]
+
+On receiving last buffer driver puts MFC to MFCINST_FINISHING state which
+in turn skips transferring of frame from SRC to REF queue. This causes
+driver to stop MFC encoding and last frame is lost.
+
+This patch guarantees safe handling of frames during MFCINST_FINISHING and
+correct clearing of workbit to avoid early stopping of encoding.
+
+Fixes: af9357467810 ("[media] MFC: Add MFC 5.1 V4L2 driver")
+
+Cc: stable@vger.kernel.org
+Cc: linux-fsd@tesla.com
+Signed-off-by: Smitha T Murthy <smitha.t@samsung.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+index 1fad99edb091..3da1775a65f1 100644
+--- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+@@ -1218,6 +1218,7 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
+ unsigned long mb_y_addr, mb_c_addr;
+ int slice_type;
+ unsigned int strm_size;
++ bool src_ready;
+
+ slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev);
+ strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev);
+@@ -1257,7 +1258,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
+ }
+ }
+ }
+- if ((ctx->src_queue_cnt > 0) && (ctx->state == MFCINST_RUNNING)) {
++ if (ctx->src_queue_cnt > 0 && (ctx->state == MFCINST_RUNNING ||
++ ctx->state == MFCINST_FINISHING)) {
+ mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
+ list);
+ if (mb_entry->flags & MFC_BUF_FLAG_USED) {
+@@ -1288,7 +1290,13 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
+ vb2_set_plane_payload(&mb_entry->b->vb2_buf, 0, strm_size);
+ vb2_buffer_done(&mb_entry->b->vb2_buf, VB2_BUF_STATE_DONE);
+ }
+- if ((ctx->src_queue_cnt == 0) || (ctx->dst_queue_cnt == 0))
++
++ src_ready = true;
++ if (ctx->state == MFCINST_RUNNING && ctx->src_queue_cnt == 0)
++ src_ready = false;
++ if (ctx->state == MFCINST_FINISHING && ctx->ref_queue_cnt == 0)
++ src_ready = false;
++ if (!src_ready || ctx->dst_queue_cnt == 0)
+ clear_work_bit(ctx);
+
+ return 0;
+--
+2.35.1
+
--- /dev/null
+From 353062ef5c34912feb3db2fb38c389ca063287cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Jan 2023 11:35:11 -0500
+Subject: phy: qcom-qmp-combo: fix out-of-bounds clock access
+
+[ Upstream commit d8a5b59c5fc75c99ba17e3eb1a8f580d8d172b28 ]
+
+The SM8250 only uses three clocks but the DP configuration erroneously
+described four clocks.
+
+In case the DP part of the PHY is initialised before the USB part, this
+would lead to uninitialised memory beyond the bulk-clocks array to be
+treated as a clock pointer as the clocks are requested based on the USB
+configuration.
+
+Fixes: aff188feb5e1 ("phy: qcom-qmp: add support for sm8250-usb3-dp phy")
+Cc: stable@vger.kernel.org # 5.13
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Link: https://lore.kernel.org/r/20221114081346.5116-2-johan+linaro@kernel.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/qualcomm/phy-qcom-qmp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
+index 817298d8b0e3..a9687e040960 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
+@@ -3805,8 +3805,8 @@ static const struct qmp_phy_cfg sm8250_dpphy_cfg = {
+ .serdes_tbl_hbr3 = qmp_v4_dp_serdes_tbl_hbr3,
+ .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
+
+- .clk_list = qmp_v4_phy_clk_l,
+- .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l),
++ .clk_list = qmp_v4_sm8250_usbphy_clk_l,
++ .num_clks = ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
+ .reset_list = msm8996_usb3phy_reset_l,
+ .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+--
+2.35.1
+
ext4-fix-off-by-one-errors-in-fast-commit-block-filling.patch
cifs-prevent-copying-past-input-buffer-boundaries.patch
arm-renumber-bits-related-to-_tif_work_mask.patch
+phy-qcom-qmp-combo-fix-out-of-bounds-clock-access.patch
+btrfs-replace-strncpy-with-strscpy.patch
+btrfs-move-missing-device-handling-in-a-dedicate-fun.patch
+btrfs-fix-extent-map-use-after-free-when-handling-mi.patch
+x86-mce-get-rid-of-msr_ops.patch
+x86-mce-amd-clear-dfr-errors-found-in-thr-handler.patch
+media-s5p-mfc-fix-to-handle-reference-queue-during-f.patch
+media-s5p-mfc-clear-workbit-to-handle-error-conditio.patch
+media-s5p-mfc-fix-in-register-read-and-write-for-h26.patch
--- /dev/null
+From 077e2103b585c7c05b2221b487b9fe7bac0cd5b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jun 2022 15:59:43 +0000
+Subject: x86/MCE/AMD: Clear DFR errors found in THR handler
+
+From: Yazen Ghannam <yazen.ghannam@amd.com>
+
+[ Upstream commit bc1b705b0eee4c645ad8b3bbff3c8a66e9688362 ]
+
+AMD's MCA Thresholding feature counts errors of all severity levels, not
+just correctable errors. If a deferred error causes the threshold limit
+to be reached (it was the error that caused the overflow), then both a
+deferred error interrupt and a thresholding interrupt will be triggered.
+
+The order of the interrupts is not guaranteed. If the threshold
+interrupt handler is executed first, then it will clear MCA_STATUS for
+the error. It will not check or clear MCA_DESTAT which also holds a copy
+of the deferred error. When the deferred error interrupt handler runs it
+will not find an error in MCA_STATUS, but it will find the error in
+MCA_DESTAT. This will cause two errors to be logged.
+
+Check for deferred errors when handling a threshold interrupt. If a bank
+contains a deferred error, then clear the bank's MCA_DESTAT register.
+
+Define a new helper function to do the deferred error check and clearing
+of MCA_DESTAT.
+
+ [ bp: Simplify, convert comment to passive voice. ]
+
+Fixes: 37d43acfd79f ("x86/mce/AMD: Redo error logging from APIC LVT interrupt handlers")
+Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20220621155943.33623-1-yazen.ghannam@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/mce/amd.c | 33 ++++++++++++++++++++-------------
+ 1 file changed, 20 insertions(+), 13 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
+index b8b7c304e4ba..6469d3135d26 100644
+--- a/arch/x86/kernel/cpu/mce/amd.c
++++ b/arch/x86/kernel/cpu/mce/amd.c
+@@ -965,6 +965,24 @@ _log_error_bank(unsigned int bank, u32 msr_stat, u32 msr_addr, u64 misc)
+ return status & MCI_STATUS_DEFERRED;
+ }
+
++static bool _log_error_deferred(unsigned int bank, u32 misc)
++{
++ if (!_log_error_bank(bank, mca_msr_reg(bank, MCA_STATUS),
++ mca_msr_reg(bank, MCA_ADDR), misc))
++ return false;
++
++ /*
++ * Non-SMCA systems don't have MCA_DESTAT/MCA_DEADDR registers.
++ * Return true here to avoid accessing these registers.
++ */
++ if (!mce_flags.smca)
++ return true;
++
++ /* Clear MCA_DESTAT if the deferred error was logged from MCA_STATUS. */
++ wrmsrl(MSR_AMD64_SMCA_MCx_DESTAT(bank), 0);
++ return true;
++}
++
+ /*
+ * We have three scenarios for checking for Deferred errors:
+ *
+@@ -976,19 +994,8 @@ _log_error_bank(unsigned int bank, u32 msr_stat, u32 msr_addr, u64 misc)
+ */
+ static void log_error_deferred(unsigned int bank)
+ {
+- bool defrd;
+-
+- defrd = _log_error_bank(bank, mca_msr_reg(bank, MCA_STATUS),
+- mca_msr_reg(bank, MCA_ADDR), 0);
+-
+- if (!mce_flags.smca)
+- return;
+-
+- /* Clear MCA_DESTAT if we logged the deferred error from MCA_STATUS. */
+- if (defrd) {
+- wrmsrl(MSR_AMD64_SMCA_MCx_DESTAT(bank), 0);
++ if (_log_error_deferred(bank, 0))
+ return;
+- }
+
+ /*
+ * Only deferred errors are logged in MCA_DE{STAT,ADDR} so just check
+@@ -1009,7 +1016,7 @@ static void amd_deferred_error_interrupt(void)
+
+ static void log_error_thresholding(unsigned int bank, u64 misc)
+ {
+- _log_error_bank(bank, mca_msr_reg(bank, MCA_STATUS), mca_msr_reg(bank, MCA_ADDR), misc);
++ _log_error_deferred(bank, misc);
+ }
+
+ static void log_and_reset_block(struct threshold_block *block)
+--
+2.35.1
+
--- /dev/null
+From 874d4eb565aa2a5f87c5ab513df21abb00a5fd5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Sep 2021 13:33:22 +0200
+Subject: x86/mce: Get rid of msr_ops
+
+From: Borislav Petkov <bp@suse.de>
+
+[ Upstream commit 8121b8f947be0033f567619be204639a50cad298 ]
+
+Avoid having indirect calls and use a normal function which returns the
+proper MSR address based on ->smca setting.
+
+No functional changes.
+
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Tony Luck <tony.luck@intel.com>
+Link: https://lkml.kernel.org/r/20210922165101.18951-4-bp@alien8.de
+Stable-dep-of: bc1b705b0eee ("x86/MCE/AMD: Clear DFR errors found in THR handler")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/mce/amd.c | 10 ++--
+ arch/x86/kernel/cpu/mce/core.c | 95 ++++++++++--------------------
+ arch/x86/kernel/cpu/mce/internal.h | 12 ++--
+ 3 files changed, 42 insertions(+), 75 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
+index a873577e49dc..b8b7c304e4ba 100644
+--- a/arch/x86/kernel/cpu/mce/amd.c
++++ b/arch/x86/kernel/cpu/mce/amd.c
+@@ -526,7 +526,7 @@ static u32 get_block_address(u32 current_addr, u32 low, u32 high,
+ /* Fall back to method we used for older processors: */
+ switch (block) {
+ case 0:
+- addr = msr_ops.misc(bank);
++ addr = mca_msr_reg(bank, MCA_MISC);
+ break;
+ case 1:
+ offset = ((low & MASK_BLKPTR_LO) >> 21);
+@@ -978,8 +978,8 @@ static void log_error_deferred(unsigned int bank)
+ {
+ bool defrd;
+
+- defrd = _log_error_bank(bank, msr_ops.status(bank),
+- msr_ops.addr(bank), 0);
++ defrd = _log_error_bank(bank, mca_msr_reg(bank, MCA_STATUS),
++ mca_msr_reg(bank, MCA_ADDR), 0);
+
+ if (!mce_flags.smca)
+ return;
+@@ -1009,7 +1009,7 @@ static void amd_deferred_error_interrupt(void)
+
+ static void log_error_thresholding(unsigned int bank, u64 misc)
+ {
+- _log_error_bank(bank, msr_ops.status(bank), msr_ops.addr(bank), misc);
++ _log_error_bank(bank, mca_msr_reg(bank, MCA_STATUS), mca_msr_reg(bank, MCA_ADDR), misc);
+ }
+
+ static void log_and_reset_block(struct threshold_block *block)
+@@ -1397,7 +1397,7 @@ static int threshold_create_bank(struct threshold_bank **bp, unsigned int cpu,
+ }
+ }
+
+- err = allocate_threshold_blocks(cpu, b, bank, 0, msr_ops.misc(bank));
++ err = allocate_threshold_blocks(cpu, b, bank, 0, mca_msr_reg(bank, MCA_MISC));
+ if (err)
+ goto out_kobj;
+
+diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
+index 773037e5fd76..5ee82fd386dd 100644
+--- a/arch/x86/kernel/cpu/mce/core.c
++++ b/arch/x86/kernel/cpu/mce/core.c
+@@ -176,53 +176,27 @@ void mce_unregister_decode_chain(struct notifier_block *nb)
+ }
+ EXPORT_SYMBOL_GPL(mce_unregister_decode_chain);
+
+-static inline u32 ctl_reg(int bank)
++u32 mca_msr_reg(int bank, enum mca_msr reg)
+ {
+- return MSR_IA32_MCx_CTL(bank);
+-}
+-
+-static inline u32 status_reg(int bank)
+-{
+- return MSR_IA32_MCx_STATUS(bank);
+-}
+-
+-static inline u32 addr_reg(int bank)
+-{
+- return MSR_IA32_MCx_ADDR(bank);
+-}
+-
+-static inline u32 misc_reg(int bank)
+-{
+- return MSR_IA32_MCx_MISC(bank);
+-}
+-
+-static inline u32 smca_ctl_reg(int bank)
+-{
+- return MSR_AMD64_SMCA_MCx_CTL(bank);
+-}
+-
+-static inline u32 smca_status_reg(int bank)
+-{
+- return MSR_AMD64_SMCA_MCx_STATUS(bank);
+-}
++ if (mce_flags.smca) {
++ switch (reg) {
++ case MCA_CTL: return MSR_AMD64_SMCA_MCx_CTL(bank);
++ case MCA_ADDR: return MSR_AMD64_SMCA_MCx_ADDR(bank);
++ case MCA_MISC: return MSR_AMD64_SMCA_MCx_MISC(bank);
++ case MCA_STATUS: return MSR_AMD64_SMCA_MCx_STATUS(bank);
++ }
++ }
+
+-static inline u32 smca_addr_reg(int bank)
+-{
+- return MSR_AMD64_SMCA_MCx_ADDR(bank);
+-}
++ switch (reg) {
++ case MCA_CTL: return MSR_IA32_MCx_CTL(bank);
++ case MCA_ADDR: return MSR_IA32_MCx_ADDR(bank);
++ case MCA_MISC: return MSR_IA32_MCx_MISC(bank);
++ case MCA_STATUS: return MSR_IA32_MCx_STATUS(bank);
++ }
+
+-static inline u32 smca_misc_reg(int bank)
+-{
+- return MSR_AMD64_SMCA_MCx_MISC(bank);
++ return 0;
+ }
+
+-struct mca_msr_regs msr_ops = {
+- .ctl = ctl_reg,
+- .status = status_reg,
+- .addr = addr_reg,
+- .misc = misc_reg
+-};
+-
+ static void __print_mce(struct mce *m)
+ {
+ pr_emerg(HW_ERR "CPU %d: Machine Check%s: %Lx Bank %d: %016Lx\n",
+@@ -371,11 +345,11 @@ static int msr_to_offset(u32 msr)
+
+ if (msr == mca_cfg.rip_msr)
+ return offsetof(struct mce, ip);
+- if (msr == msr_ops.status(bank))
++ if (msr == mca_msr_reg(bank, MCA_STATUS))
+ return offsetof(struct mce, status);
+- if (msr == msr_ops.addr(bank))
++ if (msr == mca_msr_reg(bank, MCA_ADDR))
+ return offsetof(struct mce, addr);
+- if (msr == msr_ops.misc(bank))
++ if (msr == mca_msr_reg(bank, MCA_MISC))
+ return offsetof(struct mce, misc);
+ if (msr == MSR_IA32_MCG_STATUS)
+ return offsetof(struct mce, mcgstatus);
+@@ -676,10 +650,10 @@ static struct notifier_block mce_default_nb = {
+ static noinstr void mce_read_aux(struct mce *m, int i)
+ {
+ if (m->status & MCI_STATUS_MISCV)
+- m->misc = mce_rdmsrl(msr_ops.misc(i));
++ m->misc = mce_rdmsrl(mca_msr_reg(i, MCA_MISC));
+
+ if (m->status & MCI_STATUS_ADDRV) {
+- m->addr = mce_rdmsrl(msr_ops.addr(i));
++ m->addr = mce_rdmsrl(mca_msr_reg(i, MCA_ADDR));
+
+ /*
+ * Mask the reported address by the reported granularity.
+@@ -749,7 +723,7 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
+ m.bank = i;
+
+ barrier();
+- m.status = mce_rdmsrl(msr_ops.status(i));
++ m.status = mce_rdmsrl(mca_msr_reg(i, MCA_STATUS));
+
+ /* If this entry is not valid, ignore it */
+ if (!(m.status & MCI_STATUS_VAL))
+@@ -817,7 +791,7 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
+ /*
+ * Clear state for this bank.
+ */
+- mce_wrmsrl(msr_ops.status(i), 0);
++ mce_wrmsrl(mca_msr_reg(i, MCA_STATUS), 0);
+ }
+
+ /*
+@@ -842,7 +816,7 @@ static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp,
+ int i;
+
+ for (i = 0; i < this_cpu_read(mce_num_banks); i++) {
+- m->status = mce_rdmsrl(msr_ops.status(i));
++ m->status = mce_rdmsrl(mca_msr_reg(i, MCA_STATUS));
+ if (!(m->status & MCI_STATUS_VAL))
+ continue;
+
+@@ -1143,7 +1117,7 @@ static void mce_clear_state(unsigned long *toclear)
+
+ for (i = 0; i < this_cpu_read(mce_num_banks); i++) {
+ if (test_bit(i, toclear))
+- mce_wrmsrl(msr_ops.status(i), 0);
++ mce_wrmsrl(mca_msr_reg(i, MCA_STATUS), 0);
+ }
+ }
+
+@@ -1202,7 +1176,7 @@ static void __mc_scan_banks(struct mce *m, struct pt_regs *regs, struct mce *fin
+ m->addr = 0;
+ m->bank = i;
+
+- m->status = mce_rdmsrl(msr_ops.status(i));
++ m->status = mce_rdmsrl(mca_msr_reg(i, MCA_STATUS));
+ if (!(m->status & MCI_STATUS_VAL))
+ continue;
+
+@@ -1699,8 +1673,8 @@ static void __mcheck_cpu_init_clear_banks(void)
+
+ if (!b->init)
+ continue;
+- wrmsrl(msr_ops.ctl(i), b->ctl);
+- wrmsrl(msr_ops.status(i), 0);
++ wrmsrl(mca_msr_reg(i, MCA_CTL), b->ctl);
++ wrmsrl(mca_msr_reg(i, MCA_STATUS), 0);
+ }
+ }
+
+@@ -1726,7 +1700,7 @@ static void __mcheck_cpu_check_banks(void)
+ if (!b->init)
+ continue;
+
+- rdmsrl(msr_ops.ctl(i), msrval);
++ rdmsrl(mca_msr_reg(i, MCA_CTL), msrval);
+ b->init = !!msrval;
+ }
+ }
+@@ -1883,13 +1857,6 @@ static void __mcheck_cpu_init_early(struct cpuinfo_x86 *c)
+ mce_flags.succor = !!cpu_has(c, X86_FEATURE_SUCCOR);
+ mce_flags.smca = !!cpu_has(c, X86_FEATURE_SMCA);
+ mce_flags.amd_threshold = 1;
+-
+- if (mce_flags.smca) {
+- msr_ops.ctl = smca_ctl_reg;
+- msr_ops.status = smca_status_reg;
+- msr_ops.addr = smca_addr_reg;
+- msr_ops.misc = smca_misc_reg;
+- }
+ }
+ }
+
+@@ -2265,7 +2232,7 @@ static void mce_disable_error_reporting(void)
+ struct mce_bank *b = &mce_banks[i];
+
+ if (b->init)
+- wrmsrl(msr_ops.ctl(i), 0);
++ wrmsrl(mca_msr_reg(i, MCA_CTL), 0);
+ }
+ return;
+ }
+@@ -2617,7 +2584,7 @@ static void mce_reenable_cpu(void)
+ struct mce_bank *b = &mce_banks[i];
+
+ if (b->init)
+- wrmsrl(msr_ops.ctl(i), b->ctl);
++ wrmsrl(mca_msr_reg(i, MCA_CTL), b->ctl);
+ }
+ }
+
+diff --git a/arch/x86/kernel/cpu/mce/internal.h b/arch/x86/kernel/cpu/mce/internal.h
+index 80dc94313bcf..760b57814760 100644
+--- a/arch/x86/kernel/cpu/mce/internal.h
++++ b/arch/x86/kernel/cpu/mce/internal.h
+@@ -168,14 +168,14 @@ struct mce_vendor_flags {
+
+ extern struct mce_vendor_flags mce_flags;
+
+-struct mca_msr_regs {
+- u32 (*ctl) (int bank);
+- u32 (*status) (int bank);
+- u32 (*addr) (int bank);
+- u32 (*misc) (int bank);
++enum mca_msr {
++ MCA_CTL,
++ MCA_STATUS,
++ MCA_ADDR,
++ MCA_MISC,
+ };
+
+-extern struct mca_msr_regs msr_ops;
++u32 mca_msr_reg(int bank, enum mca_msr reg);
+
+ /* Decide whether to add MCE record to MCE event pool or filter it out. */
+ extern bool filter_mce(struct mce *m);
+--
+2.35.1
+