From: Greg Kroah-Hartman Date: Thu, 15 Jan 2026 11:41:00 +0000 (+0100) Subject: 6.6-stable patches X-Git-Tag: v6.6.121~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=55c698d554523f9d36a26493793a4129f0ae66ab;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: alsa-ac97-fix-a-double-free-in-snd_ac97_controller_register.patch alsa-ac97bus-use-guard-for-mutex-locks.patch loongarch-add-more-instruction-opcodes-and-emit_-helpers.patch nfs-trace-show-timedout-instead-of-0x6e.patch nfs_common-factor-out-nfs_errtbl-and-nfs_stat_to_errno.patch nfsd-remove-nfserr_eagain.patch riscv-uprobes-add-missing-fence.i-after-building-the-xol-buffer.patch x86-microcode-amd-select-which-microcode-patch-to-load.patch --- diff --git a/queue-6.6/alsa-ac97-fix-a-double-free-in-snd_ac97_controller_register.patch b/queue-6.6/alsa-ac97-fix-a-double-free-in-snd_ac97_controller_register.patch new file mode 100644 index 0000000000..0cdcd88e30 --- /dev/null +++ b/queue-6.6/alsa-ac97-fix-a-double-free-in-snd_ac97_controller_register.patch @@ -0,0 +1,67 @@ +From stable+bounces-208184-greg=kroah.com@vger.kernel.org Mon Jan 12 18:26:06 2026 +From: Sasha Levin +Date: Mon, 12 Jan 2026 12:25:58 -0500 +Subject: ALSA: ac97: fix a double free in snd_ac97_controller_register() +To: stable@vger.kernel.org +Cc: Haoxiang Li , Takashi Iwai , Sasha Levin +Message-ID: <20260112172558.815821-2-sashal@kernel.org> + +From: Haoxiang Li + +[ Upstream commit 830988b6cf197e6dcffdfe2008c5738e6c6c3c0f ] + +If ac97_add_adapter() fails, put_device() is the correct way to drop +the device reference. kfree() is not required. +Add kfree() if idr_alloc() fails and in ac97_adapter_release() to do +the cleanup. + +Found by code review. + +Fixes: 74426fbff66e ("ALSA: ac97: add an ac97 bus") +Cc: stable@vger.kernel.org +Signed-off-by: Haoxiang Li +Link: https://patch.msgid.link/20251219162845.657525-1-lihaoxiang@isrc.iscas.ac.cn +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + sound/ac97/bus.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/sound/ac97/bus.c ++++ b/sound/ac97/bus.c +@@ -299,6 +299,7 @@ static void ac97_adapter_release(struct + idr_remove(&ac97_adapter_idr, ac97_ctrl->nr); + dev_dbg(&ac97_ctrl->adap, "adapter unregistered by %s\n", + dev_name(ac97_ctrl->parent)); ++ kfree(ac97_ctrl); + } + + static const struct device_type ac97_adapter_type = { +@@ -320,7 +321,9 @@ static int ac97_add_adapter(struct ac97_ + ret = device_register(&ac97_ctrl->adap); + if (ret) + put_device(&ac97_ctrl->adap); +- } ++ } else ++ kfree(ac97_ctrl); ++ + if (!ret) { + list_add(&ac97_ctrl->controllers, &ac97_controllers); + dev_dbg(&ac97_ctrl->adap, "adapter registered by %s\n", +@@ -361,14 +364,11 @@ struct ac97_controller *snd_ac97_control + ret = ac97_add_adapter(ac97_ctrl); + + if (ret) +- goto err; ++ return ERR_PTR(ret); + ac97_bus_reset(ac97_ctrl); + ac97_bus_scan(ac97_ctrl); + + return ac97_ctrl; +-err: +- kfree(ac97_ctrl); +- return ERR_PTR(ret); + } + EXPORT_SYMBOL_GPL(snd_ac97_controller_register); + diff --git a/queue-6.6/alsa-ac97bus-use-guard-for-mutex-locks.patch b/queue-6.6/alsa-ac97bus-use-guard-for-mutex-locks.patch new file mode 100644 index 0000000000..3d799daf29 --- /dev/null +++ b/queue-6.6/alsa-ac97bus-use-guard-for-mutex-locks.patch @@ -0,0 +1,92 @@ +From stable+bounces-208183-greg=kroah.com@vger.kernel.org Mon Jan 12 18:26:04 2026 +From: Sasha Levin +Date: Mon, 12 Jan 2026 12:25:57 -0500 +Subject: ALSA: ac97bus: Use guard() for mutex locks +To: stable@vger.kernel.org +Cc: Takashi Iwai , Sasha Levin +Message-ID: <20260112172558.815821-1-sashal@kernel.org> + +From: Takashi Iwai + +[ Upstream commit c07824a14d99c10edd4ec4c389d219af336ecf20 ] + +Replace the manual mutex lock/unlock pairs with guard() for code +simplification. + +Only code refactoring, and no behavior change. + +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20250829151335.7342-18-tiwai@suse.de +Stable-dep-of: 830988b6cf19 ("ALSA: ac97: fix a double free in snd_ac97_controller_register()") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + sound/ac97/bus.c | 22 +++++++++------------- + 1 file changed, 9 insertions(+), 13 deletions(-) + +--- a/sound/ac97/bus.c ++++ b/sound/ac97/bus.c +@@ -242,10 +242,9 @@ static ssize_t cold_reset_store(struct d + { + struct ac97_controller *ac97_ctrl; + +- mutex_lock(&ac97_controllers_mutex); ++ guard(mutex)(&ac97_controllers_mutex); + ac97_ctrl = to_ac97_controller(dev); + ac97_ctrl->ops->reset(ac97_ctrl); +- mutex_unlock(&ac97_controllers_mutex); + return len; + } + static DEVICE_ATTR_WO(cold_reset); +@@ -259,10 +258,9 @@ static ssize_t warm_reset_store(struct d + if (!dev) + return -ENODEV; + +- mutex_lock(&ac97_controllers_mutex); ++ guard(mutex)(&ac97_controllers_mutex); + ac97_ctrl = to_ac97_controller(dev); + ac97_ctrl->ops->warm_reset(ac97_ctrl); +- mutex_unlock(&ac97_controllers_mutex); + return len; + } + static DEVICE_ATTR_WO(warm_reset); +@@ -285,10 +283,10 @@ static const struct attribute_group *ac9 + + static void ac97_del_adapter(struct ac97_controller *ac97_ctrl) + { +- mutex_lock(&ac97_controllers_mutex); +- ac97_ctrl_codecs_unregister(ac97_ctrl); +- list_del(&ac97_ctrl->controllers); +- mutex_unlock(&ac97_controllers_mutex); ++ scoped_guard(mutex, &ac97_controllers_mutex) { ++ ac97_ctrl_codecs_unregister(ac97_ctrl); ++ list_del(&ac97_ctrl->controllers); ++ } + + device_unregister(&ac97_ctrl->adap); + } +@@ -312,7 +310,7 @@ static int ac97_add_adapter(struct ac97_ + { + int ret; + +- mutex_lock(&ac97_controllers_mutex); ++ guard(mutex)(&ac97_controllers_mutex); + ret = idr_alloc(&ac97_adapter_idr, ac97_ctrl, 0, 0, GFP_KERNEL); + ac97_ctrl->nr = ret; + if (ret >= 0) { +@@ -323,13 +321,11 @@ static int ac97_add_adapter(struct ac97_ + if (ret) + put_device(&ac97_ctrl->adap); + } +- if (!ret) ++ if (!ret) { + list_add(&ac97_ctrl->controllers, &ac97_controllers); +- mutex_unlock(&ac97_controllers_mutex); +- +- if (!ret) + dev_dbg(&ac97_ctrl->adap, "adapter registered by %s\n", + dev_name(ac97_ctrl->parent)); ++ } + return ret; + } + diff --git a/queue-6.6/loongarch-add-more-instruction-opcodes-and-emit_-helpers.patch b/queue-6.6/loongarch-add-more-instruction-opcodes-and-emit_-helpers.patch new file mode 100644 index 0000000000..1bcf941627 --- /dev/null +++ b/queue-6.6/loongarch-add-more-instruction-opcodes-and-emit_-helpers.patch @@ -0,0 +1,72 @@ +From add28024405ed600afaa02749989d4fd119f9057 Mon Sep 17 00:00:00 2001 +From: Hengqi Chen +Date: Wed, 8 Nov 2023 14:12:15 +0800 +Subject: LoongArch: Add more instruction opcodes and emit_* helpers + +From: Hengqi Chen + +commit add28024405ed600afaa02749989d4fd119f9057 upstream. + +This patch adds more instruction opcodes and their corresponding emit_* +helpers which will be used in later patches. + +Signed-off-by: Hengqi Chen +Signed-off-by: Huacai Chen +Signed-off-by: Greg Kroah-Hartman +--- + arch/loongarch/include/asm/inst.h | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/arch/loongarch/include/asm/inst.h ++++ b/arch/loongarch/include/asm/inst.h +@@ -65,6 +65,8 @@ enum reg2_op { + revbd_op = 0x0f, + revh2w_op = 0x10, + revhd_op = 0x11, ++ extwh_op = 0x16, ++ extwb_op = 0x17, + }; + + enum reg2i5_op { +@@ -556,6 +558,8 @@ static inline void emit_##NAME(union loo + DEF_EMIT_REG2_FORMAT(revb2h, revb2h_op) + DEF_EMIT_REG2_FORMAT(revb2w, revb2w_op) + DEF_EMIT_REG2_FORMAT(revbd, revbd_op) ++DEF_EMIT_REG2_FORMAT(extwh, extwh_op) ++DEF_EMIT_REG2_FORMAT(extwb, extwb_op) + + #define DEF_EMIT_REG2I5_FORMAT(NAME, OP) \ + static inline void emit_##NAME(union loongarch_instruction *insn, \ +@@ -607,6 +611,9 @@ DEF_EMIT_REG2I12_FORMAT(lu52id, lu52id_o + DEF_EMIT_REG2I12_FORMAT(andi, andi_op) + DEF_EMIT_REG2I12_FORMAT(ori, ori_op) + DEF_EMIT_REG2I12_FORMAT(xori, xori_op) ++DEF_EMIT_REG2I12_FORMAT(ldb, ldb_op) ++DEF_EMIT_REG2I12_FORMAT(ldh, ldh_op) ++DEF_EMIT_REG2I12_FORMAT(ldw, ldw_op) + DEF_EMIT_REG2I12_FORMAT(ldbu, ldbu_op) + DEF_EMIT_REG2I12_FORMAT(ldhu, ldhu_op) + DEF_EMIT_REG2I12_FORMAT(ldwu, ldwu_op) +@@ -695,9 +702,12 @@ static inline void emit_##NAME(union loo + insn->reg3_format.rk = rk; \ + } + ++DEF_EMIT_REG3_FORMAT(addw, addw_op) + DEF_EMIT_REG3_FORMAT(addd, addd_op) + DEF_EMIT_REG3_FORMAT(subd, subd_op) + DEF_EMIT_REG3_FORMAT(muld, muld_op) ++DEF_EMIT_REG3_FORMAT(divd, divd_op) ++DEF_EMIT_REG3_FORMAT(modd, modd_op) + DEF_EMIT_REG3_FORMAT(divdu, divdu_op) + DEF_EMIT_REG3_FORMAT(moddu, moddu_op) + DEF_EMIT_REG3_FORMAT(and, and_op) +@@ -709,6 +719,9 @@ DEF_EMIT_REG3_FORMAT(srlw, srlw_op) + DEF_EMIT_REG3_FORMAT(srld, srld_op) + DEF_EMIT_REG3_FORMAT(sraw, sraw_op) + DEF_EMIT_REG3_FORMAT(srad, srad_op) ++DEF_EMIT_REG3_FORMAT(ldxb, ldxb_op) ++DEF_EMIT_REG3_FORMAT(ldxh, ldxh_op) ++DEF_EMIT_REG3_FORMAT(ldxw, ldxw_op) + DEF_EMIT_REG3_FORMAT(ldxbu, ldxbu_op) + DEF_EMIT_REG3_FORMAT(ldxhu, ldxhu_op) + DEF_EMIT_REG3_FORMAT(ldxwu, ldxwu_op) diff --git a/queue-6.6/nfs-trace-show-timedout-instead-of-0x6e.patch b/queue-6.6/nfs-trace-show-timedout-instead-of-0x6e.patch new file mode 100644 index 0000000000..539ee64d68 --- /dev/null +++ b/queue-6.6/nfs-trace-show-timedout-instead-of-0x6e.patch @@ -0,0 +1,42 @@ +From stable+bounces-208123-greg=kroah.com@vger.kernel.org Mon Jan 12 15:55:37 2026 +From: Sasha Levin +Date: Mon, 12 Jan 2026 09:26:59 -0500 +Subject: NFS: trace: show TIMEDOUT instead of 0x6e +To: stable@vger.kernel.org +Cc: Chen Hanxiao , Jeff Layton , Chuck Lever , Sasha Levin +Message-ID: <20260112142701.711948-1-sashal@kernel.org> + +From: Chen Hanxiao + +[ Upstream commit cef48236dfe55fa266d505e8a497963a7bc5ef2a ] + +__nfs_revalidate_inode may return ETIMEDOUT. + +print symbol of ETIMEDOUT in nfs trace: + +before: +cat-5191 [005] 119.331127: nfs_revalidate_inode_exit: error=-110 (0x6e) + +after: +cat-1738 [004] 44.365509: nfs_revalidate_inode_exit: error=-110 (TIMEDOUT) + +Signed-off-by: Chen Hanxiao +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Stable-dep-of: c6c209ceb87f ("NFSD: Remove NFSERR_EAGAIN") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/trace/misc/nfs.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/include/trace/misc/nfs.h ++++ b/include/trace/misc/nfs.h +@@ -52,6 +52,7 @@ TRACE_DEFINE_ENUM(NFSERR_JUKEBOX); + { NFSERR_IO, "IO" }, \ + { NFSERR_NXIO, "NXIO" }, \ + { ECHILD, "CHILD" }, \ ++ { ETIMEDOUT, "TIMEDOUT" }, \ + { NFSERR_EAGAIN, "AGAIN" }, \ + { NFSERR_ACCES, "ACCES" }, \ + { NFSERR_EXIST, "EXIST" }, \ diff --git a/queue-6.6/nfs_common-factor-out-nfs_errtbl-and-nfs_stat_to_errno.patch b/queue-6.6/nfs_common-factor-out-nfs_errtbl-and-nfs_stat_to_errno.patch new file mode 100644 index 0000000000..f5a53ffdef --- /dev/null +++ b/queue-6.6/nfs_common-factor-out-nfs_errtbl-and-nfs_stat_to_errno.patch @@ -0,0 +1,531 @@ +From stable+bounces-208124-greg=kroah.com@vger.kernel.org Mon Jan 12 15:55:39 2026 +From: Sasha Levin +Date: Mon, 12 Jan 2026 09:27:00 -0500 +Subject: nfs_common: factor out nfs_errtbl and nfs_stat_to_errno +To: stable@vger.kernel.org +Cc: Mike Snitzer , Jeff Layton , NeilBrown , Anna Schumaker , Sasha Levin +Message-ID: <20260112142701.711948-2-sashal@kernel.org> + +From: Mike Snitzer + +[ Upstream commit 4806ded4c14c5e8fdc6ce885d83221a78c06a428 ] + +Common nfs_stat_to_errno() is used by both fs/nfs/nfs2xdr.c and +fs/nfs/nfs3xdr.c + +Will also be used by fs/nfsd/localio.c + +Signed-off-by: Mike Snitzer +Reviewed-by: Jeff Layton +Reviewed-by: NeilBrown +Signed-off-by: Anna Schumaker +Stable-dep-of: c6c209ceb87f ("NFSD: Remove NFSERR_EAGAIN") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfs/Kconfig | 1 + fs/nfs/nfs2xdr.c | 70 ----------------------------- + fs/nfs/nfs3xdr.c | 108 ++++++++------------------------------------- + fs/nfs/nfs4xdr.c | 4 - + fs/nfs_common/Makefile | 2 + fs/nfs_common/common.c | 67 +++++++++++++++++++++++++++ + fs/nfsd/Kconfig | 1 + include/linux/nfs_common.h | 16 ++++++ + 8 files changed, 109 insertions(+), 160 deletions(-) + create mode 100644 fs/nfs_common/common.c + create mode 100644 include/linux/nfs_common.h + +--- a/fs/nfs/Kconfig ++++ b/fs/nfs/Kconfig +@@ -5,6 +5,7 @@ config NFS_FS + select CRC32 + select LOCKD + select SUNRPC ++ select NFS_COMMON + select NFS_ACL_SUPPORT if NFS_V3_ACL + help + Choose Y here if you want to access files residing on other +--- a/fs/nfs/nfs2xdr.c ++++ b/fs/nfs/nfs2xdr.c +@@ -22,14 +22,12 @@ + #include + #include + #include ++#include + #include "nfstrace.h" + #include "internal.h" + + #define NFSDBG_FACILITY NFSDBG_XDR + +-/* Mapping from NFS error code to "errno" error code. */ +-#define errno_NFSERR_IO EIO +- + /* + * Declare the space requirements for NFS arguments and replies as + * number of 32bit-words +@@ -64,8 +62,6 @@ + #define NFS_readdirres_sz (1+NFS_pagepad_sz) + #define NFS_statfsres_sz (1+NFS_info_sz) + +-static int nfs_stat_to_errno(enum nfs_stat); +- + /* + * Encode/decode NFSv2 basic data types + * +@@ -1054,70 +1050,6 @@ out_default: + return nfs_stat_to_errno(status); + } + +- +-/* +- * We need to translate between nfs status return values and +- * the local errno values which may not be the same. +- */ +-static const struct { +- int stat; +- int errno; +-} nfs_errtbl[] = { +- { NFS_OK, 0 }, +- { NFSERR_PERM, -EPERM }, +- { NFSERR_NOENT, -ENOENT }, +- { NFSERR_IO, -errno_NFSERR_IO}, +- { NFSERR_NXIO, -ENXIO }, +-/* { NFSERR_EAGAIN, -EAGAIN }, */ +- { NFSERR_ACCES, -EACCES }, +- { NFSERR_EXIST, -EEXIST }, +- { NFSERR_XDEV, -EXDEV }, +- { NFSERR_NODEV, -ENODEV }, +- { NFSERR_NOTDIR, -ENOTDIR }, +- { NFSERR_ISDIR, -EISDIR }, +- { NFSERR_INVAL, -EINVAL }, +- { NFSERR_FBIG, -EFBIG }, +- { NFSERR_NOSPC, -ENOSPC }, +- { NFSERR_ROFS, -EROFS }, +- { NFSERR_MLINK, -EMLINK }, +- { NFSERR_NAMETOOLONG, -ENAMETOOLONG }, +- { NFSERR_NOTEMPTY, -ENOTEMPTY }, +- { NFSERR_DQUOT, -EDQUOT }, +- { NFSERR_STALE, -ESTALE }, +- { NFSERR_REMOTE, -EREMOTE }, +-#ifdef EWFLUSH +- { NFSERR_WFLUSH, -EWFLUSH }, +-#endif +- { NFSERR_BADHANDLE, -EBADHANDLE }, +- { NFSERR_NOT_SYNC, -ENOTSYNC }, +- { NFSERR_BAD_COOKIE, -EBADCOOKIE }, +- { NFSERR_NOTSUPP, -ENOTSUPP }, +- { NFSERR_TOOSMALL, -ETOOSMALL }, +- { NFSERR_SERVERFAULT, -EREMOTEIO }, +- { NFSERR_BADTYPE, -EBADTYPE }, +- { NFSERR_JUKEBOX, -EJUKEBOX }, +- { -1, -EIO } +-}; +- +-/** +- * nfs_stat_to_errno - convert an NFS status code to a local errno +- * @status: NFS status code to convert +- * +- * Returns a local errno value, or -EIO if the NFS status code is +- * not recognized. This function is used jointly by NFSv2 and NFSv3. +- */ +-static int nfs_stat_to_errno(enum nfs_stat status) +-{ +- int i; +- +- for (i = 0; nfs_errtbl[i].stat != -1; i++) { +- if (nfs_errtbl[i].stat == (int)status) +- return nfs_errtbl[i].errno; +- } +- dprintk("NFS: Unrecognized nfs status value: %u\n", status); +- return nfs_errtbl[i].errno; +-} +- + #define PROC(proc, argtype, restype, timer) \ + [NFSPROC_##proc] = { \ + .p_proc = NFSPROC_##proc, \ +--- a/fs/nfs/nfs3xdr.c ++++ b/fs/nfs/nfs3xdr.c +@@ -21,14 +21,13 @@ + #include + #include + #include ++#include ++ + #include "nfstrace.h" + #include "internal.h" + + #define NFSDBG_FACILITY NFSDBG_XDR + +-/* Mapping from NFS error code to "errno" error code. */ +-#define errno_NFSERR_IO EIO +- + /* + * Declare the space requirements for NFS arguments and replies as + * number of 32bit-words +@@ -91,8 +90,6 @@ + NFS3_pagepad_sz) + #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz) + +-static int nfs3_stat_to_errno(enum nfs_stat); +- + /* + * Map file type to S_IFMT bits + */ +@@ -1406,7 +1403,7 @@ static int nfs3_xdr_dec_getattr3res(stru + out: + return error; + out_default: +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + /* +@@ -1445,7 +1442,7 @@ static int nfs3_xdr_dec_setattr3res(stru + out: + return error; + out_status: +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + /* +@@ -1495,7 +1492,7 @@ out_default: + error = decode_post_op_attr(xdr, result->dir_attr, userns); + if (unlikely(error)) + goto out; +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + /* +@@ -1537,7 +1534,7 @@ static int nfs3_xdr_dec_access3res(struc + out: + return error; + out_default: +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + /* +@@ -1578,7 +1575,7 @@ static int nfs3_xdr_dec_readlink3res(str + out: + return error; + out_default: +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + /* +@@ -1658,7 +1655,7 @@ static int nfs3_xdr_dec_read3res(struct + out: + return error; + out_status: +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + /* +@@ -1728,7 +1725,7 @@ static int nfs3_xdr_dec_write3res(struct + out: + return error; + out_status: +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + /* +@@ -1795,7 +1792,7 @@ out_default: + error = decode_wcc_data(xdr, result->dir_attr, userns); + if (unlikely(error)) + goto out; +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + /* +@@ -1835,7 +1832,7 @@ static int nfs3_xdr_dec_remove3res(struc + out: + return error; + out_status: +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + /* +@@ -1881,7 +1878,7 @@ static int nfs3_xdr_dec_rename3res(struc + out: + return error; + out_status: +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + /* +@@ -1926,7 +1923,7 @@ static int nfs3_xdr_dec_link3res(struct + out: + return error; + out_status: +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + /** +@@ -2101,7 +2098,7 @@ out_default: + error = decode_post_op_attr(xdr, result->dir_attr, rpc_rqst_userns(req)); + if (unlikely(error)) + goto out; +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + /* +@@ -2167,7 +2164,7 @@ static int nfs3_xdr_dec_fsstat3res(struc + out: + return error; + out_status: +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + /* +@@ -2243,7 +2240,7 @@ static int nfs3_xdr_dec_fsinfo3res(struc + out: + return error; + out_status: +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + /* +@@ -2304,7 +2301,7 @@ static int nfs3_xdr_dec_pathconf3res(str + out: + return error; + out_status: +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + /* +@@ -2350,7 +2347,7 @@ static int nfs3_xdr_dec_commit3res(struc + out: + return error; + out_status: +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + #ifdef CONFIG_NFS_V3_ACL +@@ -2416,7 +2413,7 @@ static int nfs3_xdr_dec_getacl3res(struc + out: + return error; + out_default: +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, +@@ -2435,76 +2432,11 @@ static int nfs3_xdr_dec_setacl3res(struc + out: + return error; + out_default: +- return nfs3_stat_to_errno(status); ++ return nfs_stat_to_errno(status); + } + + #endif /* CONFIG_NFS_V3_ACL */ + +- +-/* +- * We need to translate between nfs status return values and +- * the local errno values which may not be the same. +- */ +-static const struct { +- int stat; +- int errno; +-} nfs_errtbl[] = { +- { NFS_OK, 0 }, +- { NFSERR_PERM, -EPERM }, +- { NFSERR_NOENT, -ENOENT }, +- { NFSERR_IO, -errno_NFSERR_IO}, +- { NFSERR_NXIO, -ENXIO }, +-/* { NFSERR_EAGAIN, -EAGAIN }, */ +- { NFSERR_ACCES, -EACCES }, +- { NFSERR_EXIST, -EEXIST }, +- { NFSERR_XDEV, -EXDEV }, +- { NFSERR_NODEV, -ENODEV }, +- { NFSERR_NOTDIR, -ENOTDIR }, +- { NFSERR_ISDIR, -EISDIR }, +- { NFSERR_INVAL, -EINVAL }, +- { NFSERR_FBIG, -EFBIG }, +- { NFSERR_NOSPC, -ENOSPC }, +- { NFSERR_ROFS, -EROFS }, +- { NFSERR_MLINK, -EMLINK }, +- { NFSERR_NAMETOOLONG, -ENAMETOOLONG }, +- { NFSERR_NOTEMPTY, -ENOTEMPTY }, +- { NFSERR_DQUOT, -EDQUOT }, +- { NFSERR_STALE, -ESTALE }, +- { NFSERR_REMOTE, -EREMOTE }, +-#ifdef EWFLUSH +- { NFSERR_WFLUSH, -EWFLUSH }, +-#endif +- { NFSERR_BADHANDLE, -EBADHANDLE }, +- { NFSERR_NOT_SYNC, -ENOTSYNC }, +- { NFSERR_BAD_COOKIE, -EBADCOOKIE }, +- { NFSERR_NOTSUPP, -ENOTSUPP }, +- { NFSERR_TOOSMALL, -ETOOSMALL }, +- { NFSERR_SERVERFAULT, -EREMOTEIO }, +- { NFSERR_BADTYPE, -EBADTYPE }, +- { NFSERR_JUKEBOX, -EJUKEBOX }, +- { -1, -EIO } +-}; +- +-/** +- * nfs3_stat_to_errno - convert an NFS status code to a local errno +- * @status: NFS status code to convert +- * +- * Returns a local errno value, or -EIO if the NFS status code is +- * not recognized. This function is used jointly by NFSv2 and NFSv3. +- */ +-static int nfs3_stat_to_errno(enum nfs_stat status) +-{ +- int i; +- +- for (i = 0; nfs_errtbl[i].stat != -1; i++) { +- if (nfs_errtbl[i].stat == (int)status) +- return nfs_errtbl[i].errno; +- } +- dprintk("NFS: Unrecognized nfs status value: %u\n", status); +- return nfs_errtbl[i].errno; +-} +- +- + #define PROC(proc, argtype, restype, timer) \ + [NFS3PROC_##proc] = { \ + .p_proc = NFS3PROC_##proc, \ +--- a/fs/nfs/nfs4xdr.c ++++ b/fs/nfs/nfs4xdr.c +@@ -52,6 +52,7 @@ + #include + #include + #include ++#include + + #include "nfs4_fs.h" + #include "nfs4trace.h" +@@ -63,9 +64,6 @@ + + #define NFSDBG_FACILITY NFSDBG_XDR + +-/* Mapping from NFS error code to "errno" error code. */ +-#define errno_NFSERR_IO EIO +- + struct compound_hdr; + static int nfs4_stat_to_errno(int); + static void encode_layoutget(struct xdr_stream *xdr, +--- a/fs/nfs_common/Makefile ++++ b/fs/nfs_common/Makefile +@@ -8,3 +8,5 @@ nfs_acl-objs := nfsacl.o + + obj-$(CONFIG_GRACE_PERIOD) += grace.o + obj-$(CONFIG_NFS_V4_2_SSC_HELPER) += nfs_ssc.o ++ ++obj-$(CONFIG_NFS_COMMON) += common.o +--- /dev/null ++++ b/fs/nfs_common/common.c +@@ -0,0 +1,67 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++ ++#include ++#include ++ ++/* ++ * We need to translate between nfs status return values and ++ * the local errno values which may not be the same. ++ */ ++static const struct { ++ int stat; ++ int errno; ++} nfs_errtbl[] = { ++ { NFS_OK, 0 }, ++ { NFSERR_PERM, -EPERM }, ++ { NFSERR_NOENT, -ENOENT }, ++ { NFSERR_IO, -errno_NFSERR_IO}, ++ { NFSERR_NXIO, -ENXIO }, ++/* { NFSERR_EAGAIN, -EAGAIN }, */ ++ { NFSERR_ACCES, -EACCES }, ++ { NFSERR_EXIST, -EEXIST }, ++ { NFSERR_XDEV, -EXDEV }, ++ { NFSERR_NODEV, -ENODEV }, ++ { NFSERR_NOTDIR, -ENOTDIR }, ++ { NFSERR_ISDIR, -EISDIR }, ++ { NFSERR_INVAL, -EINVAL }, ++ { NFSERR_FBIG, -EFBIG }, ++ { NFSERR_NOSPC, -ENOSPC }, ++ { NFSERR_ROFS, -EROFS }, ++ { NFSERR_MLINK, -EMLINK }, ++ { NFSERR_NAMETOOLONG, -ENAMETOOLONG }, ++ { NFSERR_NOTEMPTY, -ENOTEMPTY }, ++ { NFSERR_DQUOT, -EDQUOT }, ++ { NFSERR_STALE, -ESTALE }, ++ { NFSERR_REMOTE, -EREMOTE }, ++#ifdef EWFLUSH ++ { NFSERR_WFLUSH, -EWFLUSH }, ++#endif ++ { NFSERR_BADHANDLE, -EBADHANDLE }, ++ { NFSERR_NOT_SYNC, -ENOTSYNC }, ++ { NFSERR_BAD_COOKIE, -EBADCOOKIE }, ++ { NFSERR_NOTSUPP, -ENOTSUPP }, ++ { NFSERR_TOOSMALL, -ETOOSMALL }, ++ { NFSERR_SERVERFAULT, -EREMOTEIO }, ++ { NFSERR_BADTYPE, -EBADTYPE }, ++ { NFSERR_JUKEBOX, -EJUKEBOX }, ++ { -1, -EIO } ++}; ++ ++/** ++ * nfs_stat_to_errno - convert an NFS status code to a local errno ++ * @status: NFS status code to convert ++ * ++ * Returns a local errno value, or -EIO if the NFS status code is ++ * not recognized. This function is used jointly by NFSv2 and NFSv3. ++ */ ++int nfs_stat_to_errno(enum nfs_stat status) ++{ ++ int i; ++ ++ for (i = 0; nfs_errtbl[i].stat != -1; i++) { ++ if (nfs_errtbl[i].stat == (int)status) ++ return nfs_errtbl[i].errno; ++ } ++ return nfs_errtbl[i].errno; ++} ++EXPORT_SYMBOL_GPL(nfs_stat_to_errno); +--- a/fs/nfsd/Kconfig ++++ b/fs/nfsd/Kconfig +@@ -8,6 +8,7 @@ config NFSD + select LOCKD + select SUNRPC + select EXPORTFS ++ select NFS_COMMON + select NFS_ACL_SUPPORT if NFSD_V2_ACL + select NFS_ACL_SUPPORT if NFSD_V3_ACL + depends on MULTIUSER +--- /dev/null ++++ b/include/linux/nfs_common.h +@@ -0,0 +1,16 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * This file contains constants and methods used by both NFS client and server. ++ */ ++#ifndef _LINUX_NFS_COMMON_H ++#define _LINUX_NFS_COMMON_H ++ ++#include ++#include ++ ++/* Mapping from NFS error code to "errno" error code. */ ++#define errno_NFSERR_IO EIO ++ ++int nfs_stat_to_errno(enum nfs_stat status); ++ ++#endif /* _LINUX_NFS_COMMON_H */ diff --git a/queue-6.6/nfsd-remove-nfserr_eagain.patch b/queue-6.6/nfsd-remove-nfserr_eagain.patch new file mode 100644 index 0000000000..1b091ca861 --- /dev/null +++ b/queue-6.6/nfsd-remove-nfserr_eagain.patch @@ -0,0 +1,101 @@ +From stable+bounces-208125-greg=kroah.com@vger.kernel.org Mon Jan 12 15:50:33 2026 +From: Sasha Levin +Date: Mon, 12 Jan 2026 09:27:01 -0500 +Subject: NFSD: Remove NFSERR_EAGAIN +To: stable@vger.kernel.org +Cc: Chuck Lever , NeilBrown , Jeff Layton , Sasha Levin +Message-ID: <20260112142701.711948-3-sashal@kernel.org> + +From: Chuck Lever + +[ Upstream commit c6c209ceb87f64a6ceebe61761951dcbbf4a0baa ] + +I haven't found an NFSERR_EAGAIN in RFCs 1094, 1813, 7530, or 8881. +None of these RFCs have an NFS status code that match the numeric +value "11". + +Based on the meaning of the EAGAIN errno, I presume the use of this +status in NFSD means NFS4ERR_DELAY. So replace the one usage of +nfserr_eagain, and remove it from NFSD's NFS status conversion +tables. + +As far as I can tell, NFSERR_EAGAIN has existed since the pre-git +era, but was not actually used by any code until commit f4e44b393389 +("NFSD: delay unmount source's export after inter-server copy +completed."), at which time it become possible for NFSD to return +a status code of 11 (which is not valid NFS protocol). + +Fixes: f4e44b393389 ("NFSD: delay unmount source's export after inter-server copy completed.") +Cc: stable@vger.kernel.org +Reviewed-by: NeilBrown +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfs_common/common.c | 1 - + fs/nfsd/nfs4proc.c | 2 +- + fs/nfsd/nfsd.h | 1 - + include/trace/misc/nfs.h | 2 -- + include/uapi/linux/nfs.h | 1 - + 5 files changed, 1 insertion(+), 6 deletions(-) + +--- a/fs/nfs_common/common.c ++++ b/fs/nfs_common/common.c +@@ -16,7 +16,6 @@ static const struct { + { NFSERR_NOENT, -ENOENT }, + { NFSERR_IO, -errno_NFSERR_IO}, + { NFSERR_NXIO, -ENXIO }, +-/* { NFSERR_EAGAIN, -EAGAIN }, */ + { NFSERR_ACCES, -EACCES }, + { NFSERR_EXIST, -EEXIST }, + { NFSERR_XDEV, -EXDEV }, +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -1354,7 +1354,7 @@ try_again: + (schedule_timeout(20*HZ) == 0)) { + finish_wait(&nn->nfsd_ssc_waitq, &wait); + kfree(work); +- return nfserr_eagain; ++ return nfserr_jukebox; + } + finish_wait(&nn->nfsd_ssc_waitq, &wait); + goto try_again; +--- a/fs/nfsd/nfsd.h ++++ b/fs/nfsd/nfsd.h +@@ -201,7 +201,6 @@ void nfsd_lockd_shutdown(void); + #define nfserr_noent cpu_to_be32(NFSERR_NOENT) + #define nfserr_io cpu_to_be32(NFSERR_IO) + #define nfserr_nxio cpu_to_be32(NFSERR_NXIO) +-#define nfserr_eagain cpu_to_be32(NFSERR_EAGAIN) + #define nfserr_acces cpu_to_be32(NFSERR_ACCES) + #define nfserr_exist cpu_to_be32(NFSERR_EXIST) + #define nfserr_xdev cpu_to_be32(NFSERR_XDEV) +--- a/include/trace/misc/nfs.h ++++ b/include/trace/misc/nfs.h +@@ -16,7 +16,6 @@ TRACE_DEFINE_ENUM(NFSERR_PERM); + TRACE_DEFINE_ENUM(NFSERR_NOENT); + TRACE_DEFINE_ENUM(NFSERR_IO); + TRACE_DEFINE_ENUM(NFSERR_NXIO); +-TRACE_DEFINE_ENUM(NFSERR_EAGAIN); + TRACE_DEFINE_ENUM(NFSERR_ACCES); + TRACE_DEFINE_ENUM(NFSERR_EXIST); + TRACE_DEFINE_ENUM(NFSERR_XDEV); +@@ -53,7 +52,6 @@ TRACE_DEFINE_ENUM(NFSERR_JUKEBOX); + { NFSERR_NXIO, "NXIO" }, \ + { ECHILD, "CHILD" }, \ + { ETIMEDOUT, "TIMEDOUT" }, \ +- { NFSERR_EAGAIN, "AGAIN" }, \ + { NFSERR_ACCES, "ACCES" }, \ + { NFSERR_EXIST, "EXIST" }, \ + { NFSERR_XDEV, "XDEV" }, \ +--- a/include/uapi/linux/nfs.h ++++ b/include/uapi/linux/nfs.h +@@ -49,7 +49,6 @@ + NFSERR_NOENT = 2, /* v2 v3 v4 */ + NFSERR_IO = 5, /* v2 v3 v4 */ + NFSERR_NXIO = 6, /* v2 v3 v4 */ +- NFSERR_EAGAIN = 11, /* v2 v3 */ + NFSERR_ACCES = 13, /* v2 v3 v4 */ + NFSERR_EXIST = 17, /* v2 v3 v4 */ + NFSERR_XDEV = 18, /* v3 v4 */ diff --git a/queue-6.6/riscv-uprobes-add-missing-fence.i-after-building-the-xol-buffer.patch b/queue-6.6/riscv-uprobes-add-missing-fence.i-after-building-the-xol-buffer.patch new file mode 100644 index 0000000000..9165528d10 --- /dev/null +++ b/queue-6.6/riscv-uprobes-add-missing-fence.i-after-building-the-xol-buffer.patch @@ -0,0 +1,57 @@ +From stable+bounces-208309-greg=kroah.com@vger.kernel.org Wed Jan 14 02:19:26 2026 +From: Rahul Sharma +Date: Wed, 14 Jan 2026 09:18:30 +0800 +Subject: riscv: uprobes: Add missing fence.i after building the XOL buffer +To: gregkh@linuxfoundation.org, stable@vger.kernel.org +Cc: linux-kernel@vger.kernel.org, "Björn Töpel" , "Guo Ren" , "Palmer Dabbelt" , "Rahul Sharma" +Message-ID: <20260114011830.2045424-1-black.hawk@163.com> + +From: Björn Töpel + +[ Upstream commit 7d1d19a11cfbfd8bae1d89cc010b2cc397cd0c48 ] + +The XOL (execute out-of-line) buffer is used to single-step the +replaced instruction(s) for uprobes. The RISC-V port was missing a +proper fence.i (i$ flushing) after constructing the XOL buffer, which +can result in incorrect execution of stale/broken instructions. + +This was found running the BPF selftests "test_progs: +uprobe_autoattach, attach_probe" on the Spacemit K1/X60, where the +uprobes tests randomly blew up. + +Reviewed-by: Guo Ren +Fixes: 74784081aac8 ("riscv: Add uprobes supported") +Signed-off-by: Björn Töpel +Link: https://lore.kernel.org/r/20250419111402.1660267-2-bjorn@kernel.org +Signed-off-by: Palmer Dabbelt +Signed-off-by: Rahul Sharma +Signed-off-by: Greg Kroah-Hartman +--- + arch/riscv/kernel/probes/uprobes.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +--- a/arch/riscv/kernel/probes/uprobes.c ++++ b/arch/riscv/kernel/probes/uprobes.c +@@ -167,6 +167,7 @@ void arch_uprobe_copy_ixol(struct page * + /* Initialize the slot */ + void *kaddr = kmap_atomic(page); + void *dst = kaddr + (vaddr & ~PAGE_MASK); ++ unsigned long start = (unsigned long)dst; + + memcpy(dst, src, len); + +@@ -176,13 +177,6 @@ void arch_uprobe_copy_ixol(struct page * + *(uprobe_opcode_t *)dst = __BUG_INSN_32; + } + ++ flush_icache_range(start, start + len); + kunmap_atomic(kaddr); +- +- /* +- * We probably need flush_icache_user_page() but it needs vma. +- * This should work on most of architectures by default. If +- * architecture needs to do something different it can define +- * its own version of the function. +- */ +- flush_dcache_page(page); + } diff --git a/queue-6.6/series b/queue-6.6/series index 8fd302c823..a971647a94 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -63,3 +63,11 @@ net-sched-sch_qfq-fix-null-deref-when-deactivating-i.patch net-usb-pegasus-fix-memory-leak-in-update_eth_regs_a.patch net-enetc-fix-build-warning-when-page_size-is-greate.patch arp-do-not-assume-dev_hard_header-does-not-change-sk.patch +loongarch-add-more-instruction-opcodes-and-emit_-helpers.patch +alsa-ac97bus-use-guard-for-mutex-locks.patch +alsa-ac97-fix-a-double-free-in-snd_ac97_controller_register.patch +nfs-trace-show-timedout-instead-of-0x6e.patch +nfs_common-factor-out-nfs_errtbl-and-nfs_stat_to_errno.patch +nfsd-remove-nfserr_eagain.patch +x86-microcode-amd-select-which-microcode-patch-to-load.patch +riscv-uprobes-add-missing-fence.i-after-building-the-xol-buffer.patch diff --git a/queue-6.6/x86-microcode-amd-select-which-microcode-patch-to-load.patch b/queue-6.6/x86-microcode-amd-select-which-microcode-patch-to-load.patch new file mode 100644 index 0000000000..0607ec3344 --- /dev/null +++ b/queue-6.6/x86-microcode-amd-select-which-microcode-patch-to-load.patch @@ -0,0 +1,167 @@ +From stable+bounces-208112-greg=kroah.com@vger.kernel.org Mon Jan 12 12:30:47 2026 +From: Borislav Petkov +Date: Mon, 12 Jan 2026 12:27:48 +0100 +Subject: x86/microcode/AMD: Select which microcode patch to load +To: +Cc: LKML , "Borislav Petkov (AMD)" , Waiman Long +Message-ID: <20260112112748.20677-1-bp@kernel.org> + +From: "Borislav Petkov (AMD)" + +Commit 8d171045069c804e5ffaa18be590c42c6af0cf3f upstream. + +All microcode patches up to the proper BIOS Entrysign fix are loaded +only after the sha256 signature carried in the driver has been verified. + +Microcode patches after the Entrysign fix has been applied, do not need +that signature verification anymore. + +In order to not abandon machines which haven't received the BIOS update +yet, add the capability to select which microcode patch to load. + +The corresponding microcode container supplied through firmware-linux +has been modified to carry two patches per CPU type +(family/model/stepping) so that the proper one gets selected. + +Signed-off-by: Borislav Petkov (AMD) +Tested-by: Waiman Long +Link: https://patch.msgid.link/20251027133818.4363-1-bp@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/microcode/amd.c | 104 +++++++++++++++++++++++------------- + 1 file changed, 67 insertions(+), 37 deletions(-) + +--- a/arch/x86/kernel/cpu/microcode/amd.c ++++ b/arch/x86/kernel/cpu/microcode/amd.c +@@ -176,50 +176,61 @@ static u32 cpuid_to_ucode_rev(unsigned i + return p.ucode_rev; + } + ++static u32 get_cutoff_revision(u32 rev) ++{ ++ switch (rev >> 8) { ++ case 0x80012: return 0x8001277; break; ++ case 0x80082: return 0x800820f; break; ++ case 0x83010: return 0x830107c; break; ++ case 0x86001: return 0x860010e; break; ++ case 0x86081: return 0x8608108; break; ++ case 0x87010: return 0x8701034; break; ++ case 0x8a000: return 0x8a0000a; break; ++ case 0xa0010: return 0xa00107a; break; ++ case 0xa0011: return 0xa0011da; break; ++ case 0xa0012: return 0xa001243; break; ++ case 0xa0082: return 0xa00820e; break; ++ case 0xa1011: return 0xa101153; break; ++ case 0xa1012: return 0xa10124e; break; ++ case 0xa1081: return 0xa108109; break; ++ case 0xa2010: return 0xa20102f; break; ++ case 0xa2012: return 0xa201212; break; ++ case 0xa4041: return 0xa404109; break; ++ case 0xa5000: return 0xa500013; break; ++ case 0xa6012: return 0xa60120a; break; ++ case 0xa7041: return 0xa704109; break; ++ case 0xa7052: return 0xa705208; break; ++ case 0xa7080: return 0xa708009; break; ++ case 0xa70c0: return 0xa70C009; break; ++ case 0xaa001: return 0xaa00116; break; ++ case 0xaa002: return 0xaa00218; break; ++ case 0xb0021: return 0xb002146; break; ++ case 0xb0081: return 0xb008111; break; ++ case 0xb1010: return 0xb101046; break; ++ case 0xb2040: return 0xb204031; break; ++ case 0xb4040: return 0xb404031; break; ++ case 0xb4041: return 0xb404101; break; ++ case 0xb6000: return 0xb600031; break; ++ case 0xb6080: return 0xb608031; break; ++ case 0xb7000: return 0xb700031; break; ++ default: break; ++ ++ } ++ return 0; ++} ++ + static bool need_sha_check(u32 cur_rev) + { ++ u32 cutoff; ++ + if (!cur_rev) { + cur_rev = cpuid_to_ucode_rev(bsp_cpuid_1_eax); + pr_info_once("No current revision, generating the lowest one: 0x%x\n", cur_rev); + } + +- switch (cur_rev >> 8) { +- case 0x80012: return cur_rev <= 0x8001277; break; +- case 0x80082: return cur_rev <= 0x800820f; break; +- case 0x83010: return cur_rev <= 0x830107c; break; +- case 0x86001: return cur_rev <= 0x860010e; break; +- case 0x86081: return cur_rev <= 0x8608108; break; +- case 0x87010: return cur_rev <= 0x8701034; break; +- case 0x8a000: return cur_rev <= 0x8a0000a; break; +- case 0xa0010: return cur_rev <= 0xa00107a; break; +- case 0xa0011: return cur_rev <= 0xa0011da; break; +- case 0xa0012: return cur_rev <= 0xa001243; break; +- case 0xa0082: return cur_rev <= 0xa00820e; break; +- case 0xa1011: return cur_rev <= 0xa101153; break; +- case 0xa1012: return cur_rev <= 0xa10124e; break; +- case 0xa1081: return cur_rev <= 0xa108109; break; +- case 0xa2010: return cur_rev <= 0xa20102f; break; +- case 0xa2012: return cur_rev <= 0xa201212; break; +- case 0xa4041: return cur_rev <= 0xa404109; break; +- case 0xa5000: return cur_rev <= 0xa500013; break; +- case 0xa6012: return cur_rev <= 0xa60120a; break; +- case 0xa7041: return cur_rev <= 0xa704109; break; +- case 0xa7052: return cur_rev <= 0xa705208; break; +- case 0xa7080: return cur_rev <= 0xa708009; break; +- case 0xa70c0: return cur_rev <= 0xa70C009; break; +- case 0xaa001: return cur_rev <= 0xaa00116; break; +- case 0xaa002: return cur_rev <= 0xaa00218; break; +- case 0xb0021: return cur_rev <= 0xb002146; break; +- case 0xb0081: return cur_rev <= 0xb008111; break; +- case 0xb1010: return cur_rev <= 0xb101046; break; +- case 0xb2040: return cur_rev <= 0xb204031; break; +- case 0xb4040: return cur_rev <= 0xb404031; break; +- case 0xb4041: return cur_rev <= 0xb404101; break; +- case 0xb6000: return cur_rev <= 0xb600031; break; +- case 0xb6080: return cur_rev <= 0xb608031; break; +- case 0xb7000: return cur_rev <= 0xb700031; break; +- default: break; +- } ++ cutoff = get_cutoff_revision(cur_rev); ++ if (cutoff) ++ return cur_rev <= cutoff; + + pr_info("You should not be seeing this. Please send the following couple of lines to x86--kernel.org\n"); + pr_info("CPUID(1).EAX: 0x%x, current revision: 0x%x\n", bsp_cpuid_1_eax, cur_rev); +@@ -473,6 +484,7 @@ static int verify_patch(const u8 *buf, s + { + u8 family = x86_family(bsp_cpuid_1_eax); + struct microcode_header_amd *mc_hdr; ++ u32 cur_rev, cutoff, patch_rev; + u32 sh_psize; + u16 proc_id; + u8 patch_fam; +@@ -514,6 +526,24 @@ static int verify_patch(const u8 *buf, s + if (patch_fam != family) + return 1; + ++ cur_rev = get_patch_level(); ++ ++ /* No cutoff revision means old/unaffected by signing algorithm weakness => matches */ ++ cutoff = get_cutoff_revision(cur_rev); ++ if (!cutoff) ++ goto ok; ++ ++ patch_rev = mc_hdr->patch_id; ++ ++ if (cur_rev <= cutoff && patch_rev <= cutoff) ++ goto ok; ++ ++ if (cur_rev > cutoff && patch_rev > cutoff) ++ goto ok; ++ ++ return 1; ++ok: ++ + return 0; + } +