* [PATCH 0/7] Intel platform driver to reset bitfix filters
@ 2026-08-25 18:15 Tony Luck
2026-08-25 18:15 ` [PATCH 1/7] cacheinfo: Export get_cpu_cacheinfo_id() for loadable modules Tony Luck
` (7 more replies)
0 siblings, 8 replies; 15+ messages in thread
From: Tony Luck @ 2026-08-25 18:15 UTC (permalink / raw)
To: Ilpo Järvinen, Hans de Goede
Cc: Borislav Petkov, Breno Leitao, platform-driver-x86, linux-kernel,
patches, Tony Luck
Some Intel CPUs implement a "bitfix filter" to suppress reporting of the
same corrected errors repeatedly in the case where aging silicon
develops stuck bits.
But when systems run for weeks, or months, the filters may become clogged
with transient errors.
When the filter is full (indicated by a "yellow" signature in a machine
check bank) clear the filter. This may make space for additional hard
errors.
Save a time stamp when clearing a filter. Log with "WARN" severity if
the filter overflows quickly (in tem minutes or less).
This code was originally developend by Qiuxu as an add-on to an EDAC
driver. But not everyone wants to run an EDAC driver, so I pulled the
code out into a standalone platform driver. Much of Qiuxu's code was
cut-and-pasted into this driver, so he gets Co-developed-by credit
throughout.
Qiuxu Zhuo (1):
cacheinfo: Export get_cpu_cacheinfo_id() for loadable modules
Tony Luck (6):
x86/mce: Enumeration updates for Intel bitfix filter reset
platform/x86/intel/bff: Add stub Intel bitfix filter driver
platform/x86/intel/bff: Add Diamond Rapids support
platform/x86/intel/bff: Reset bitfix filter when it overflows
platform/x86/intel/bff: Compute unique ID for overflowed filter
platform/x86/intel/bff: Report frequent filter resets
include/linux/cacheinfo.h | 12 +-
arch/x86/include/asm/mce.h | 6 +
arch/x86/include/asm/msr-index.h | 2 +
drivers/base/cacheinfo.c | 17 ++
drivers/platform/x86/intel/bff.c | 284 ++++++++++++++++++++++++++++
drivers/platform/x86/intel/Kconfig | 13 ++
drivers/platform/x86/intel/Makefile | 1 +
7 files changed, 324 insertions(+), 11 deletions(-)
create mode 100644 drivers/platform/x86/intel/bff.c
base-commit: 8d3ae59288f1e7d58d76558a6ee96d533bc5019f
--
2.55.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 1/7] cacheinfo: Export get_cpu_cacheinfo_id() for loadable modules
2026-08-25 18:15 [PATCH 0/7] Intel platform driver to reset bitfix filters Tony Luck
@ 2026-08-25 18:15 ` Tony Luck
2026-08-25 18:15 ` [PATCH 2/7] x86/mce: Enumeration updates for Intel bitfix filter reset Tony Luck
` (6 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: Tony Luck @ 2026-08-25 18:15 UTC (permalink / raw)
To: Ilpo Järvinen, Hans de Goede
Cc: Borislav Petkov, Breno Leitao, platform-driver-x86, linux-kernel,
patches, Qiuxu Zhuo, Tony Luck
From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Loadable drivers that track bitfix filter state need the cache ID to
distinguish shared cache instances. Without access to the cache ID, CPUs
sharing the same cache cannot be associated with the same tracking state.
The existing helper cannot be used by loadable modules because it depends
on a non-exported symbol, preventing the such drivers from building as
a module.
Export get_cpu_cacheinfo_id() so loadable modules can retrieve cache IDs
through a common cacheinfo interface.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
include/linux/cacheinfo.h | 12 +-----------
drivers/base/cacheinfo.c | 17 +++++++++++++++++
2 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/include/linux/cacheinfo.h b/include/linux/cacheinfo.h
index fc879ac4cc4f..56fa646df0d1 100644
--- a/include/linux/cacheinfo.h
+++ b/include/linux/cacheinfo.h
@@ -82,6 +82,7 @@ struct cpu_cacheinfo {
};
struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu);
+int get_cpu_cacheinfo_id(int cpu, int level);
int early_cache_level(unsigned int cpu);
int init_cache_level(unsigned int cpu);
int init_of_cache_level(unsigned int cpu);
@@ -137,17 +138,6 @@ static inline struct cacheinfo *get_cpu_cacheinfo_level(int cpu, int level)
return NULL;
}
-/*
- * Get the id of the cache associated with @cpu at level @level.
- * cpuhp lock must be held.
- */
-static inline int get_cpu_cacheinfo_id(int cpu, int level)
-{
- struct cacheinfo *ci = get_cpu_cacheinfo_level(cpu, level);
-
- return ci ? ci->id : -1;
-}
-
#if defined(CONFIG_ARM64) || defined(CONFIG_ARM)
#define use_arch_cache_info() (true)
#else
diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c
index 70701d3bc81c..28d193bf6064 100644
--- a/drivers/base/cacheinfo.c
+++ b/drivers/base/cacheinfo.c
@@ -38,6 +38,23 @@ struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu)
return ci_cacheinfo(cpu);
}
+/**
+ * get_cpu_cacheinfo_id - Return the cache ID for a CPU and cache level
+ * @cpu: CPU number
+ * @level: Cache level
+ *
+ * The caller must hold the cpuhp lock.
+ *
+ * Return: Cache ID on success, or -1 if no matching cache exists.
+ */
+int get_cpu_cacheinfo_id(int cpu, int level)
+{
+ struct cacheinfo *ci = get_cpu_cacheinfo_level(cpu, level);
+
+ return ci ? ci->id : -1;
+}
+EXPORT_SYMBOL_GPL(get_cpu_cacheinfo_id);
+
static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf,
struct cacheinfo *sib_leaf)
{
--
2.55.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 2/7] x86/mce: Enumeration updates for Intel bitfix filter reset
2026-08-25 18:15 [PATCH 0/7] Intel platform driver to reset bitfix filters Tony Luck
2026-08-25 18:15 ` [PATCH 1/7] cacheinfo: Export get_cpu_cacheinfo_id() for loadable modules Tony Luck
@ 2026-08-25 18:15 ` Tony Luck
2026-08-26 8:15 ` Ilpo Järvinen
2026-08-25 18:15 ` [PATCH 3/7] platform/x86/intel/bff: Add stub Intel bitfix filter driver Tony Luck
` (5 subsequent siblings)
7 siblings, 1 reply; 15+ messages in thread
From: Tony Luck @ 2026-08-25 18:15 UTC (permalink / raw)
To: Ilpo Järvinen, Hans de Goede
Cc: Borislav Petkov, Breno Leitao, platform-driver-x86, linux-kernel,
patches, Tony Luck, Qiuxu Zhuo
IA32_CORE_CAPABILITIES enumerates the bitfix filter reset feature.
Also add definitions for the threshold status field in the machine
check status registers.
Co-developed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
arch/x86/include/asm/mce.h | 6 ++++++
arch/x86/include/asm/msr-index.h | 2 ++
2 files changed, 8 insertions(+)
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index e575b702063d..0d5bcb6f1750 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -13,6 +13,7 @@
#define MCG_CTL_P BIT_ULL(8) /* MCG_CTL register available */
#define MCG_EXT_P BIT_ULL(9) /* Extended registers available */
#define MCG_CMCI_P BIT_ULL(10) /* CMCI supported */
+#define MCG_TES_P BIT_ULL(11) /* Threshold-based error status supported */
#define MCG_SEAM_NR BIT_ULL(12) /* MCG_STATUS_SEAM_NR supported */
#define MCG_EXT_CNT_MASK 0xff0000 /* Number of Extended registers */
#define MCG_EXT_CNT_SHIFT 16
@@ -41,6 +42,11 @@
#define MCI_STATUS_PCC BIT_ULL(57) /* processor context corrupt */
#define MCI_STATUS_S BIT_ULL(56) /* Signaled machine check */
#define MCI_STATUS_AR BIT_ULL(55) /* Action required */
+#define MCI_STATUS_TES_SHIFT 53 /* Threshold-based error status */
+#define MCI_STATUS_TES_MASK GENMASK_ULL(54, 53)
+#define MCI_STATUS_TES(s) (((s) & MCI_STATUS_TES_MASK) >> MCI_STATUS_TES_SHIFT)
+#define MCI_STATUS_TES_GREEN 1 /* Threshold-based errors below threshold */
+#define MCI_STATUS_TES_YELLOW 2 /* Threshold-based errors above threshold */
#define MCI_STATUS_CEC_SHIFT 38 /* Corrected Error Count */
#define MCI_STATUS_CEC_MASK GENMASK_ULL(52,38)
#define MCI_STATUS_CEC(c) (((c) & MCI_STATUS_CEC_MASK) >> MCI_STATUS_CEC_SHIFT)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 18c4be75e927..13d3efc87b14 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -114,6 +114,8 @@
#define MSR_IA32_CORE_CAPS_INTEGRITY_CAPS BIT(MSR_IA32_CORE_CAPS_INTEGRITY_CAPS_BIT)
#define MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT_BIT 5
#define MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT BIT(MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT_BIT)
+#define MSR_IA32_CORE_CAPS_BFF_RESET_DETECT_BIT 9
+#define MSR_IA32_CORE_CAPS_BFF_RESET_DETECT BIT(MSR_IA32_CORE_CAPS_BFF_RESET_DETECT_BIT)
#define MSR_PKG_CST_CONFIG_CONTROL 0x000000e2
#define NHM_C3_AUTO_DEMOTE (1UL << 25)
--
2.55.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 3/7] platform/x86/intel/bff: Add stub Intel bitfix filter driver
2026-08-25 18:15 [PATCH 0/7] Intel platform driver to reset bitfix filters Tony Luck
2026-08-25 18:15 ` [PATCH 1/7] cacheinfo: Export get_cpu_cacheinfo_id() for loadable modules Tony Luck
2026-08-25 18:15 ` [PATCH 2/7] x86/mce: Enumeration updates for Intel bitfix filter reset Tony Luck
@ 2026-08-25 18:15 ` Tony Luck
2026-08-25 18:15 ` [PATCH 4/7] platform/x86/intel/bff: Add Diamond Rapids support Tony Luck
` (4 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: Tony Luck @ 2026-08-25 18:15 UTC (permalink / raw)
To: Ilpo Järvinen, Hans de Goede
Cc: Borislav Petkov, Breno Leitao, platform-driver-x86, linux-kernel,
patches, Tony Luck, Qiuxu Zhuo
Check if platform supports enhanced cache error reporting and the
bitfix filter reset feature.
Co-developed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
drivers/platform/x86/intel/bff.c | 59 +++++++++++++++++++++++++++++
drivers/platform/x86/intel/Kconfig | 13 +++++++
drivers/platform/x86/intel/Makefile | 1 +
3 files changed, 73 insertions(+)
create mode 100644 drivers/platform/x86/intel/bff.c
diff --git a/drivers/platform/x86/intel/bff.c b/drivers/platform/x86/intel/bff.c
new file mode 100644
index 000000000000..9522bdb1401d
--- /dev/null
+++ b/drivers/platform/x86/intel/bff.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2026 Intel Corporation. */
+
+/*
+ * Intel driver to reset bitfix filters when they overflow.
+ *
+ * Each bitfix filter has limited slots to track corrected errors.
+ * These slots can be filled by transient corrected errors (e.g.,
+ * bit flips from particle strikes) that don't represent permanent
+ * hardware defects.
+ *
+ * When the filter overflows (yellow status), reset it to reclaim
+ * slots occupied by transient corrected errors. If the overflow
+ * repeats frequently after reset, it indicates persistent hardware
+ * defects that need attention: the system should be scheduled for
+ * servicing.
+ */
+#define pr_fmt(fmt) "bff: " fmt
+
+#include <linux/cpufeature.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include <asm/cpufeatures.h>
+#include <asm/mce.h>
+#include <asm/msr.h>
+#include <asm/msr-index.h>
+
+static int __init bff_init(void)
+{
+ u64 core_caps, mcg_cap;
+
+ if (!cpu_feature_enabled(X86_FEATURE_MCA))
+ return -ENODEV;
+ rdmsrq(MSR_IA32_MCG_CAP, mcg_cap);
+ if (!(mcg_cap & MCG_TES_P))
+ return -ENODEV;
+
+ if (!cpu_feature_enabled(X86_FEATURE_CORE_CAPABILITIES))
+ return -ENODEV;
+
+ rdmsrq(MSR_IA32_CORE_CAPS, core_caps);
+ if (!(core_caps & MSR_IA32_CORE_CAPS_BFF_RESET_DETECT))
+ return -ENODEV;
+
+ return 0;
+}
+
+static void __exit bff_exit(void)
+{
+}
+
+module_init(bff_init);
+module_exit(bff_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Intel bitfix filter reset driver");
diff --git a/drivers/platform/x86/intel/Kconfig b/drivers/platform/x86/intel/Kconfig
index 2900407d6095..f4e9af0116ee 100644
--- a/drivers/platform/x86/intel/Kconfig
+++ b/drivers/platform/x86/intel/Kconfig
@@ -251,3 +251,16 @@ config INTEL_VSEC
To compile this driver as a module, choose M here: the module will
be called intel_vsec.
+
+config INTEL_BFF_RESET
+ tristate "Intel bitfix filter reset driver"
+ depends on CPU_SUP_INTEL && X86_MCE
+ help
+ Adds support for Intel systems that implement bitfix filters to
+ suppress repeated logging and signaling of the same corrected
+ error. Those filters can become clogged with transient errors
+ over time. Clearing the filter may make space for additional
+ hard errors.
+
+ To compile this driver as a module, choose M here: the module will
+ be called intel_bff.
diff --git a/drivers/platform/x86/intel/Makefile b/drivers/platform/x86/intel/Makefile
index 138b13756158..dc4e374758d5 100644
--- a/drivers/platform/x86/intel/Makefile
+++ b/drivers/platform/x86/intel/Makefile
@@ -27,6 +27,7 @@ intel-target-$(CONFIG_INTEL_ISHTP_ECLITE) += ishtp_eclite.o
intel-target-$(CONFIG_INTEL_OAKTRAIL) += oaktrail.o
intel-target-$(CONFIG_INTEL_SDSI) += sdsi.o
intel-target-$(CONFIG_INTEL_VSEC) += vsec.o
+intel-target-$(CONFIG_INTEL_BFF_RESET) += bff.o
# Intel PMIC / PMC / P-Unit drivers
intel-target-$(CONFIG_INTEL_BYTCRC_PWRSRC) += bytcrc_pwrsrc.o
--
2.55.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 4/7] platform/x86/intel/bff: Add Diamond Rapids support
2026-08-25 18:15 [PATCH 0/7] Intel platform driver to reset bitfix filters Tony Luck
` (2 preceding siblings ...)
2026-08-25 18:15 ` [PATCH 3/7] platform/x86/intel/bff: Add stub Intel bitfix filter driver Tony Luck
@ 2026-08-25 18:15 ` Tony Luck
2026-08-26 8:17 ` Ilpo Järvinen
2026-08-25 18:15 ` [PATCH 5/7] platform/x86/intel/bff: Reset bitfix filter when it overflows Tony Luck
` (3 subsequent siblings)
7 siblings, 1 reply; 15+ messages in thread
From: Tony Luck @ 2026-08-25 18:15 UTC (permalink / raw)
To: Ilpo Järvinen, Hans de Goede
Cc: Borislav Petkov, Breno Leitao, platform-driver-x86, linux-kernel,
patches, Tony Luck, Qiuxu Zhuo
There are potentially bitfix filters associated with each machine check
bank. Only some banks may implement them.
Machine check banks have varying scope. E.g. there is a separate L2
cache for each module, each instance has its own bitfix filter.
Add information that will be used to map a <cpu,bank> pair to a unique
instance number for a bitfix filter.
Co-developed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
drivers/platform/x86/intel/bff.c | 41 ++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/drivers/platform/x86/intel/bff.c b/drivers/platform/x86/intel/bff.c
index 9522bdb1401d..6360bbc92347 100644
--- a/drivers/platform/x86/intel/bff.c
+++ b/drivers/platform/x86/intel/bff.c
@@ -18,18 +18,51 @@
#define pr_fmt(fmt) "bff: " fmt
#include <linux/cpufeature.h>
+#include <linux/device-id/x86_cpu.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/printk.h>
#include <linux/types.h>
+#include <asm/cpu_device_id.h>
#include <asm/cpufeatures.h>
+#include <asm/intel-family.h>
#include <asm/mce.h>
#include <asm/msr.h>
#include <asm/msr-index.h>
+/* Machine check bank scope types */
+enum bff_type {
+ BFF_NONE = 0,
+ BFF_BANK_DCU,
+ BFF_BANK_DTLB,
+ BFF_BANK_MLC,
+ BFF_BANK_CCF,
+ BFF_BANK_HSF,
+ BFF_BANK_IOCACHE,
+};
+
+static const enum bff_type dmr_mcbanks[MAX_NR_BANKS] = {
+ [1] = BFF_BANK_DCU,
+ [2] = BFF_BANK_DTLB,
+ [3] = BFF_BANK_MLC,
+ [6] = BFF_BANK_CCF,
+ [13] = BFF_BANK_HSF,
+ [17] = BFF_BANK_IOCACHE
+};
+
+static const struct x86_cpu_id bff_cpu_ids[] __initconst = {
+ X86_MATCH_VFM(INTEL_DIAMONDRAPIDS_X, dmr_mcbanks),
+ {}
+};
+MODULE_DEVICE_TABLE(x86cpu, bff_cpu_ids);
+
+static const enum bff_type *bank_types;
+
static int __init bff_init(void)
{
+ const struct x86_cpu_id *m;
u64 core_caps, mcg_cap;
if (!cpu_feature_enabled(X86_FEATURE_MCA))
@@ -45,6 +78,14 @@ static int __init bff_init(void)
if (!(core_caps & MSR_IA32_CORE_CAPS_BFF_RESET_DETECT))
return -ENODEV;
+ m = x86_match_cpu(bff_cpu_ids);
+ if (!m) {
+ pr_info("CPU supports bitfix filter, but driver does not\n");
+ return -ENODEV;
+ }
+
+ bank_types = (const enum bff_type *)m->driver_data;
+
return 0;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 5/7] platform/x86/intel/bff: Reset bitfix filter when it overflows
2026-08-25 18:15 [PATCH 0/7] Intel platform driver to reset bitfix filters Tony Luck
` (3 preceding siblings ...)
2026-08-25 18:15 ` [PATCH 4/7] platform/x86/intel/bff: Add Diamond Rapids support Tony Luck
@ 2026-08-25 18:15 ` Tony Luck
2026-08-25 18:15 ` [PATCH 6/7] platform/x86/intel/bff: Compute unique ID for overflowed filter Tony Luck
` (2 subsequent siblings)
7 siblings, 0 replies; 15+ messages in thread
From: Tony Luck @ 2026-08-25 18:15 UTC (permalink / raw)
To: Ilpo Järvinen, Hans de Goede
Cc: Borislav Petkov, Breno Leitao, platform-driver-x86, linux-kernel,
patches, Tony Luck, Qiuxu Zhuo
Get notifications for all errors logged in machine check banks. Skip any
that do not indicate a bitfix filter overflow.
Reset the bitfix filter using the CPU that reported the error to get
the right scoped machine check bank.
Co-developed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
drivers/platform/x86/intel/bff.c | 41 ++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/drivers/platform/x86/intel/bff.c b/drivers/platform/x86/intel/bff.c
index 6360bbc92347..8cc29d11e019 100644
--- a/drivers/platform/x86/intel/bff.c
+++ b/drivers/platform/x86/intel/bff.c
@@ -17,11 +17,13 @@
*/
#define pr_fmt(fmt) "bff: " fmt
+#include <linux/bits.h>
#include <linux/cpufeature.h>
#include <linux/device-id/x86_cpu.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/notifier.h>
#include <linux/printk.h>
#include <linux/types.h>
@@ -32,6 +34,11 @@
#include <asm/msr.h>
#include <asm/msr-index.h>
+/* Intel bitfix filter control register defines */
+#define MSR_MC0_BFF_CTL 0x000006c0
+#define MSR_MCx_BFF_CTL(x) (MSR_MC0_BFF_CTL + (x))
+#define MCI_BFF_RESET BIT_ULL(0)
+
/* Machine check bank scope types */
enum bff_type {
BFF_NONE = 0,
@@ -60,6 +67,37 @@ MODULE_DEVICE_TABLE(x86cpu, bff_cpu_ids);
static const enum bff_type *bank_types;
+static void handle_bff(struct mce *mce)
+{
+ /* The bitfix filter overflowed, get the target CPU to reset it. */
+ if (wrmsrq_on_cpu(mce->extcpu, MSR_MCx_BFF_CTL(mce->bank), MCI_BFF_RESET))
+ pr_warn("Failed to reset bitfix filter for CPU %d Bank %d\n", mce->extcpu, mce->bank);
+}
+
+static int bff_mce_notify(struct notifier_block *nb, unsigned long val, void *data)
+{
+ struct mce *mce = (struct mce *)data;
+
+ /* TES is undefined for uncorrected errors. */
+ if (mce->status & MCI_STATUS_UC)
+ return NOTIFY_DONE;
+
+ if (MCI_STATUS_TES(mce->status) != MCI_STATUS_TES_YELLOW)
+ return NOTIFY_DONE;
+
+ if (mce->bank >= MAX_NR_BANKS || bank_types[mce->bank] == BFF_NONE)
+ return NOTIFY_DONE;
+
+ handle_bff(mce);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block bff_notifier = {
+ .notifier_call = bff_mce_notify,
+ .priority = MCE_PRIO_EARLY,
+};
+
static int __init bff_init(void)
{
const struct x86_cpu_id *m;
@@ -86,11 +124,14 @@ static int __init bff_init(void)
bank_types = (const enum bff_type *)m->driver_data;
+ mce_register_decode_chain(&bff_notifier);
+
return 0;
}
static void __exit bff_exit(void)
{
+ mce_unregister_decode_chain(&bff_notifier);
}
module_init(bff_init);
--
2.55.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 6/7] platform/x86/intel/bff: Compute unique ID for overflowed filter
2026-08-25 18:15 [PATCH 0/7] Intel platform driver to reset bitfix filters Tony Luck
` (4 preceding siblings ...)
2026-08-25 18:15 ` [PATCH 5/7] platform/x86/intel/bff: Reset bitfix filter when it overflows Tony Luck
@ 2026-08-25 18:15 ` Tony Luck
2026-08-26 8:26 ` Ilpo Järvinen
2026-08-25 18:15 ` [PATCH 7/7] platform/x86/intel/bff: Report frequent filter resets Tony Luck
2026-08-25 18:28 ` [PATCH 0/7] Intel platform driver to reset bitfix filters Borislav Petkov
7 siblings, 1 reply; 15+ messages in thread
From: Tony Luck @ 2026-08-25 18:15 UTC (permalink / raw)
To: Ilpo Järvinen, Hans de Goede
Cc: Borislav Petkov, Breno Leitao, platform-driver-x86, linux-kernel,
patches, Tony Luck, Qiuxu Zhuo
Each L2 cache instance has its own bitfix filter, but always reports
errors in machine check bank 3 (on Diamond Rapids).
Compute a unique bitfix filter instance number based on the CPU that
logged the error and the machine check bank number.
Special case for banks associated with the Integrated Memory Hub (IMH).
Here the "even" numbered CPU modules are associated with IMH0 and the
"odd" modules with IMH1.
The unique id will be used to store a time stamp of when the bitfix
filter overflowed so that frequent overflows can be logged.
Co-developed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
drivers/platform/x86/intel/bff.c | 74 ++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/drivers/platform/x86/intel/bff.c b/drivers/platform/x86/intel/bff.c
index 8cc29d11e019..ae9dc0bf2777 100644
--- a/drivers/platform/x86/intel/bff.c
+++ b/drivers/platform/x86/intel/bff.c
@@ -18,13 +18,18 @@
#define pr_fmt(fmt) "bff: " fmt
#include <linux/bits.h>
+#include <linux/cacheinfo.h>
+#include <linux/cleanup.h>
#include <linux/cpufeature.h>
+#include <linux/cpuhplock.h>
#include <linux/device-id/x86_cpu.h>
#include <linux/errno.h>
#include <linux/init.h>
+#include <linux/limits.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/printk.h>
+#include <linux/topology.h>
#include <linux/types.h>
#include <asm/cpu_device_id.h>
@@ -34,6 +39,8 @@
#include <asm/msr.h>
#include <asm/msr-index.h>
+#define NUM_IMH_PER_SKT 2
+
/* Intel bitfix filter control register defines */
#define MSR_MC0_BFF_CTL 0x000006c0
#define MSR_MCx_BFF_CTL(x) (MSR_MC0_BFF_CTL + (x))
@@ -67,11 +74,78 @@ MODULE_DEVICE_TABLE(x86cpu, bff_cpu_ids);
static const enum bff_type *bank_types;
+/* Diamond Rapids maps APICID[2] to the IMH instance. */
+static void bff_set_imh_id(struct mce *mce, unsigned long *id)
+{
+ int imh_num = (NUM_IMH_PER_SKT * topology_physical_package_id(mce->extcpu)) +
+ ((mce->apicid >> 2) & 0x1);
+
+ *id |= imh_num;
+}
+
+static bool bff_set_cache_id(int cpu, int level, unsigned long *id)
+{
+ int cacheid;
+
+ guard(cpus_read_lock)();
+
+ cacheid = get_cpu_cacheinfo_id(cpu, level);
+ if (cacheid == -1) {
+ pr_warn("Could not get L%d cache id for CPU %d\n", level, cpu);
+ return false;
+ }
+
+ *id |= cacheid;
+
+ return true;
+}
+
+#define BFF_ID_BANK_SHIFT 16
+
+/*
+ * Cache IDs are only unique within a cache level.
+ * Include the MCA bank number so each BFF-capable hardware
+ * resource has a unique tracking ID.
+ */
+static unsigned long get_bff_id(struct mce *mce)
+{
+ unsigned long id = (unsigned long)mce->bank << BFF_ID_BANK_SHIFT;
+
+ switch (bank_types[mce->bank]) {
+ case BFF_BANK_DCU:
+ case BFF_BANK_DTLB:
+ if (!bff_set_cache_id(mce->extcpu, 1, &id))
+ return ULONG_MAX;
+ break;
+
+ case BFF_BANK_MLC:
+ if (!bff_set_cache_id(mce->extcpu, 2, &id))
+ return ULONG_MAX;
+ break;
+
+ case BFF_BANK_CCF:
+ if (!bff_set_cache_id(mce->extcpu, 3, &id))
+ return ULONG_MAX;
+ break;
+
+ case BFF_BANK_HSF:
+ case BFF_BANK_IOCACHE:
+ bff_set_imh_id(mce, &id);
+ break;
+ default:
+ return ULONG_MAX;
+ }
+
+ return id;
+}
+
static void handle_bff(struct mce *mce)
{
/* The bitfix filter overflowed, get the target CPU to reset it. */
if (wrmsrq_on_cpu(mce->extcpu, MSR_MCx_BFF_CTL(mce->bank), MCI_BFF_RESET))
pr_warn("Failed to reset bitfix filter for CPU %d Bank %d\n", mce->extcpu, mce->bank);
+
+ pr_debug("unique_id = 0x%lx\n", get_bff_id(mce));
}
static int bff_mce_notify(struct notifier_block *nb, unsigned long val, void *data)
--
2.55.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 7/7] platform/x86/intel/bff: Report frequent filter resets
2026-08-25 18:15 [PATCH 0/7] Intel platform driver to reset bitfix filters Tony Luck
` (5 preceding siblings ...)
2026-08-25 18:15 ` [PATCH 6/7] platform/x86/intel/bff: Compute unique ID for overflowed filter Tony Luck
@ 2026-08-25 18:15 ` Tony Luck
2026-08-26 8:39 ` Ilpo Järvinen
2026-08-25 18:28 ` [PATCH 0/7] Intel platform driver to reset bitfix filters Borislav Petkov
7 siblings, 1 reply; 15+ messages in thread
From: Tony Luck @ 2026-08-25 18:15 UTC (permalink / raw)
To: Ilpo Järvinen, Hans de Goede
Cc: Borislav Petkov, Breno Leitao, platform-driver-x86, linux-kernel,
patches, Tony Luck, Qiuxu Zhuo
If an instance of a bitfix filter contains some transient errors built
up over time, then resetting the filter will free up slots in the filter
to store persistent errors.
Save a time stamp when "yellow" status is seen and clear the filter.
Log at KERN_WARNING level if the overflow occurred quickly after a
previous overflow on the same bitfix filter instance. Use KERN_NOTICE
for first, or long delayed, overflow.
Co-developed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
drivers/platform/x86/intel/bff.c | 71 +++++++++++++++++++++++++++++++-
1 file changed, 70 insertions(+), 1 deletion(-)
diff --git a/drivers/platform/x86/intel/bff.c b/drivers/platform/x86/intel/bff.c
index ae9dc0bf2777..7c22a1ad6b9d 100644
--- a/drivers/platform/x86/intel/bff.c
+++ b/drivers/platform/x86/intel/bff.c
@@ -23,14 +23,19 @@
#include <linux/cpufeature.h>
#include <linux/cpuhplock.h>
#include <linux/device-id/x86_cpu.h>
+#include <linux/err.h>
#include <linux/errno.h>
+#include <linux/gfp_types.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
#include <linux/limits.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/printk.h>
+#include <linux/slab.h>
#include <linux/topology.h>
#include <linux/types.h>
+#include <linux/xarray.h>
#include <asm/cpu_device_id.h>
#include <asm/cpufeatures.h>
@@ -39,6 +44,16 @@
#include <asm/msr.h>
#include <asm/msr-index.h>
+/*
+ * A 10-minute observation period helps distinguish between:
+ *
+ * - A long-term accumulation of transient corrected errors
+ * (filter stays clear after reset).
+ *
+ * - Permanent defects (filter overflows again quickly).
+ */
+#define BFF_OVERFLOW_INTERVAL secs_to_jiffies(10 * 60)
+
#define NUM_IMH_PER_SKT 2
/* Intel bitfix filter control register defines */
@@ -74,6 +89,8 @@ MODULE_DEVICE_TABLE(x86cpu, bff_cpu_ids);
static const enum bff_type *bank_types;
+static DEFINE_XARRAY(bff_bank_xa);
+
/* Diamond Rapids maps APICID[2] to the IMH instance. */
static void bff_set_imh_id(struct mce *mce, unsigned long *id)
{
@@ -139,13 +156,58 @@ static unsigned long get_bff_id(struct mce *mce)
return id;
}
+/*
+ * Save current timestamp for bff_id. Return true if it is within
+ * BFF_OVERFLOW_INTERVAL of previous timestamp for this bff_id.
+ */
+static bool bff_note_event_and_check_burst(unsigned long bff_id)
+{
+ unsigned long now = jiffies, when;
+ unsigned long *ts;
+
+ if (bff_id == ULONG_MAX)
+ return false;
+
+ ts = xa_load(&bff_bank_xa, bff_id);
+ if (!ts) {
+ ts = kzalloc_obj(*ts);
+ if (!ts) {
+ pr_warn("Timestamp allocation failed\n");
+ return false;
+ }
+ if (IS_ERR(xa_store(&bff_bank_xa, bff_id, ts, GFP_KERNEL))) {
+ kfree(ts);
+ pr_warn("Timestamp save failure\n");
+ return false;
+ }
+ *ts = now;
+
+ return false;
+ }
+
+ when = *ts + BFF_OVERFLOW_INTERVAL;
+ *ts = now;
+
+ return time_before(now, when);
+}
+
static void handle_bff(struct mce *mce)
{
+ bool burst = false;
+
/* The bitfix filter overflowed, get the target CPU to reset it. */
if (wrmsrq_on_cpu(mce->extcpu, MSR_MCx_BFF_CTL(mce->bank), MCI_BFF_RESET))
pr_warn("Failed to reset bitfix filter for CPU %d Bank %d\n", mce->extcpu, mce->bank);
- pr_debug("unique_id = 0x%lx\n", get_bff_id(mce));
+ /* Get unique id for bitfix filter instance that overflowed */
+ burst = bff_note_event_and_check_burst(get_bff_id(mce));
+
+ if (burst)
+ pr_warn_ratelimited(HW_ERR "Socket %d CPU %d Bank %d bitfix filter overflowed frequently\n",
+ mce->socketid, mce->extcpu, mce->bank);
+ else
+ pr_notice_ratelimited(HW_ERR "Socket %d CPU %d Bank %d bitfix filter overflowed\n",
+ mce->socketid, mce->extcpu, mce->bank);
}
static int bff_mce_notify(struct notifier_block *nb, unsigned long val, void *data)
@@ -205,7 +267,14 @@ static int __init bff_init(void)
static void __exit bff_exit(void)
{
+ unsigned long bff_id;
+ unsigned long *ts;
+
mce_unregister_decode_chain(&bff_notifier);
+
+ xa_for_each(&bff_bank_xa, bff_id, ts)
+ kfree(ts);
+ xa_destroy(&bff_bank_xa);
}
module_init(bff_init);
--
2.55.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 0/7] Intel platform driver to reset bitfix filters
2026-08-25 18:15 [PATCH 0/7] Intel platform driver to reset bitfix filters Tony Luck
` (6 preceding siblings ...)
2026-08-25 18:15 ` [PATCH 7/7] platform/x86/intel/bff: Report frequent filter resets Tony Luck
@ 2026-08-25 18:28 ` Borislav Petkov
2026-08-25 18:55 ` Luck, Tony
7 siblings, 1 reply; 15+ messages in thread
From: Borislav Petkov @ 2026-08-25 18:28 UTC (permalink / raw)
To: Tony Luck
Cc: Ilpo Järvinen, Hans de Goede, Breno Leitao,
platform-driver-x86, linux-kernel, patches
On Tue, Aug 25, 2026 at 11:15:19AM -0700, Tony Luck wrote:
> This code was originally developend by Qiuxu as an add-on to an EDAC
> driver. But not everyone wants to run an EDAC driver,
Interesting, what's so bad about EDAC drivers that makes you move all that
functionality which is clearly RAS/MCE/EDAC into some random platform driver?
There's also arch/x86/kernel/cpu/mce/intel.c and that doesn't fit either?
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 15+ messages in thread
* RE: [PATCH 0/7] Intel platform driver to reset bitfix filters
2026-08-25 18:28 ` [PATCH 0/7] Intel platform driver to reset bitfix filters Borislav Petkov
@ 2026-08-25 18:55 ` Luck, Tony
2026-08-25 19:23 ` Borislav Petkov
0 siblings, 1 reply; 15+ messages in thread
From: Luck, Tony @ 2026-08-25 18:55 UTC (permalink / raw)
To: Borislav Petkov
Cc: Ilpo Järvinen, Hans de Goede, Breno Leitao,
platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org,
patches@lists.linux.dev
> > This code was originally developend by Qiuxu as an add-on to an EDAC
> > driver. But not everyone wants to run an EDAC driver,
>
> Interesting, what's so bad about EDAC drivers that makes you move all that
> functionality which is clearly RAS/MCE/EDAC into some random platform driver?
Mostly that not everyone wants to run EDAC drivers.
> There's also arch/x86/kernel/cpu/mce/intel.c and that doesn't fit either?
Plausibly. But it is model specific. Needs to know how h/w banks are shared
between logical CPUs so it can get the time comparisons right when a shared
bank reports BFF overflow on different CPUs. Intel doesn't have any enumeration
for bank sharing, and changes things often.
It's also just for one (not yet released) CPU model today. So, building it into the MCE
code would be overhead for almost everyone.
But I can move it if you think that is a better place for it.
-Tony
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 0/7] Intel platform driver to reset bitfix filters
2026-08-25 18:55 ` Luck, Tony
@ 2026-08-25 19:23 ` Borislav Petkov
0 siblings, 0 replies; 15+ messages in thread
From: Borislav Petkov @ 2026-08-25 19:23 UTC (permalink / raw)
To: Luck, Tony
Cc: Ilpo Järvinen, Hans de Goede, Breno Leitao,
platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org,
patches@lists.linux.dev
On Tue, Aug 25, 2026 at 06:55:27PM +0000, Luck, Tony wrote:
> Mostly that not everyone wants to run EDAC drivers.
Just because or is there a particular reason?
Because we could try to address those reasons if they were more concrete and
valid...
> Plausibly. But it is model specific. Needs to know how h/w banks are shared
> between logical CPUs so it can get the time comparisons right when a shared
> bank reports BFF overflow on different CPUs. Intel doesn't have any enumeration
> for bank sharing, and changes things often.
>
> It's also just for one (not yet released) CPU model today. So, building it into the MCE
> code would be overhead for almost everyone.
>
> But I can move it if you think that is a better place for it.
Well, my angle is: we already have soo much RAS glue in the kernel so adding
a *platform* driver for it is simply unnecessary.
For example, drivers/edac/mce_amd.c is the whole AMD MCE decoding and even
though it is in drivers/edac/, it is not really an EDAC driver. So your BFFs
(wonderful acronym btw :-P) would likely fit there too.
And looking at the code, it looks very familiar to that thing - simply
a notifier callback with a bunch of logic to decode and report the error.
And there's drivers/ras/ too.
And we already have the whole machinery around it so let's move it somewhere
more fitting than in yet another new place pls.
Thx.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/7] x86/mce: Enumeration updates for Intel bitfix filter reset
2026-08-25 18:15 ` [PATCH 2/7] x86/mce: Enumeration updates for Intel bitfix filter reset Tony Luck
@ 2026-08-26 8:15 ` Ilpo Järvinen
0 siblings, 0 replies; 15+ messages in thread
From: Ilpo Järvinen @ 2026-08-26 8:15 UTC (permalink / raw)
To: Tony Luck
Cc: Hans de Goede, Borislav Petkov, Breno Leitao, platform-driver-x86,
LKML, patches, Qiuxu Zhuo
On Tue, 25 Aug 2026, Tony Luck wrote:
> IA32_CORE_CAPABILITIES enumerates the bitfix filter reset feature.
>
> Also add definitions for the threshold status field in the machine
> check status registers.
>
> Co-developed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
> Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
> Signed-off-by: Tony Luck <tony.luck@intel.com>
> ---
> arch/x86/include/asm/mce.h | 6 ++++++
> arch/x86/include/asm/msr-index.h | 2 ++
> 2 files changed, 8 insertions(+)
>
> diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
> index e575b702063d..0d5bcb6f1750 100644
> --- a/arch/x86/include/asm/mce.h
> +++ b/arch/x86/include/asm/mce.h
> @@ -13,6 +13,7 @@
> #define MCG_CTL_P BIT_ULL(8) /* MCG_CTL register available */
> #define MCG_EXT_P BIT_ULL(9) /* Extended registers available */
> #define MCG_CMCI_P BIT_ULL(10) /* CMCI supported */
> +#define MCG_TES_P BIT_ULL(11) /* Threshold-based error status supported */
> #define MCG_SEAM_NR BIT_ULL(12) /* MCG_STATUS_SEAM_NR supported */
> #define MCG_EXT_CNT_MASK 0xff0000 /* Number of Extended registers */
> #define MCG_EXT_CNT_SHIFT 16
> @@ -41,6 +42,11 @@
> #define MCI_STATUS_PCC BIT_ULL(57) /* processor context corrupt */
> #define MCI_STATUS_S BIT_ULL(56) /* Signaled machine check */
> #define MCI_STATUS_AR BIT_ULL(55) /* Action required */
> +#define MCI_STATUS_TES_SHIFT 53 /* Threshold-based error status */
> +#define MCI_STATUS_TES_MASK GENMASK_ULL(54, 53)
> +#define MCI_STATUS_TES(s) (((s) & MCI_STATUS_TES_MASK) >> MCI_STATUS_TES_SHIFT)
This opencodes FIELD_GET(), and you don't need usually need _SHIFT define
at all when you use FIELD_GET().
> +#define MCI_STATUS_TES_GREEN 1 /* Threshold-based errors below threshold */
> +#define MCI_STATUS_TES_YELLOW 2 /* Threshold-based errors above threshold */
> #define MCI_STATUS_CEC_SHIFT 38 /* Corrected Error Count */
> #define MCI_STATUS_CEC_MASK GENMASK_ULL(52,38)
> #define MCI_STATUS_CEC(c) (((c) & MCI_STATUS_CEC_MASK) >> MCI_STATUS_CEC_SHIFT)
> diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
> index 18c4be75e927..13d3efc87b14 100644
> --- a/arch/x86/include/asm/msr-index.h
> +++ b/arch/x86/include/asm/msr-index.h
> @@ -114,6 +114,8 @@
> #define MSR_IA32_CORE_CAPS_INTEGRITY_CAPS BIT(MSR_IA32_CORE_CAPS_INTEGRITY_CAPS_BIT)
> #define MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT_BIT 5
> #define MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT BIT(MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT_BIT)
> +#define MSR_IA32_CORE_CAPS_BFF_RESET_DETECT_BIT 9
> +#define MSR_IA32_CORE_CAPS_BFF_RESET_DETECT BIT(MSR_IA32_CORE_CAPS_BFF_RESET_DETECT_BIT)
>
> #define MSR_PKG_CST_CONFIG_CONTROL 0x000000e2
> #define NHM_C3_AUTO_DEMOTE (1UL << 25)
>
--
i.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 4/7] platform/x86/intel/bff: Add Diamond Rapids support
2026-08-25 18:15 ` [PATCH 4/7] platform/x86/intel/bff: Add Diamond Rapids support Tony Luck
@ 2026-08-26 8:17 ` Ilpo Järvinen
0 siblings, 0 replies; 15+ messages in thread
From: Ilpo Järvinen @ 2026-08-26 8:17 UTC (permalink / raw)
To: Tony Luck
Cc: Ilpo Järvinen, Hans de Goede, Borislav Petkov, Breno Leitao,
platform-driver-x86, linux-kernel, patches, Qiuxu Zhuo
On Tue, 25 Aug 2026, Tony Luck wrote:
> There are potentially bitfix filters associated with each machine check
> bank. Only some banks may implement them.
>
> Machine check banks have varying scope. E.g. there is a separate L2
> cache for each module, each instance has its own bitfix filter.
>
> Add information that will be used to map a <cpu,bank> pair to a unique
> instance number for a bitfix filter.
>
> Co-developed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
> Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
> Signed-off-by: Tony Luck <tony.luck@intel.com>
> ---
> drivers/platform/x86/intel/bff.c | 41 ++++++++++++++++++++++++++++++++
> 1 file changed, 41 insertions(+)
>
> diff --git a/drivers/platform/x86/intel/bff.c b/drivers/platform/x86/intel/bff.c
> index 9522bdb1401d..6360bbc92347 100644
> --- a/drivers/platform/x86/intel/bff.c
> +++ b/drivers/platform/x86/intel/bff.c
> @@ -18,18 +18,51 @@
> #define pr_fmt(fmt) "bff: " fmt
>
> #include <linux/cpufeature.h>
> +#include <linux/device-id/x86_cpu.h>
> #include <linux/errno.h>
> #include <linux/init.h>
> #include <linux/module.h>
> +#include <linux/printk.h>
> #include <linux/types.h>
>
> +#include <asm/cpu_device_id.h>
> #include <asm/cpufeatures.h>
> +#include <asm/intel-family.h>
> #include <asm/mce.h>
> #include <asm/msr.h>
> #include <asm/msr-index.h>
>
> +/* Machine check bank scope types */
> +enum bff_type {
> + BFF_NONE = 0,
> + BFF_BANK_DCU,
> + BFF_BANK_DTLB,
> + BFF_BANK_MLC,
> + BFF_BANK_CCF,
> + BFF_BANK_HSF,
> + BFF_BANK_IOCACHE,
> +};
> +
> +static const enum bff_type dmr_mcbanks[MAX_NR_BANKS] = {
> + [1] = BFF_BANK_DCU,
> + [2] = BFF_BANK_DTLB,
> + [3] = BFF_BANK_MLC,
> + [6] = BFF_BANK_CCF,
> + [13] = BFF_BANK_HSF,
> + [17] = BFF_BANK_IOCACHE
Please add trailing comma.
> +};
> +
> +static const struct x86_cpu_id bff_cpu_ids[] __initconst = {
> + X86_MATCH_VFM(INTEL_DIAMONDRAPIDS_X, dmr_mcbanks),
> + {}
> +};
> +MODULE_DEVICE_TABLE(x86cpu, bff_cpu_ids);
> +
> +static const enum bff_type *bank_types;
> +
> static int __init bff_init(void)
> {
> + const struct x86_cpu_id *m;
> u64 core_caps, mcg_cap;
>
> if (!cpu_feature_enabled(X86_FEATURE_MCA))
> @@ -45,6 +78,14 @@ static int __init bff_init(void)
> if (!(core_caps & MSR_IA32_CORE_CAPS_BFF_RESET_DETECT))
> return -ENODEV;
>
> + m = x86_match_cpu(bff_cpu_ids);
> + if (!m) {
> + pr_info("CPU supports bitfix filter, but driver does not\n");
> + return -ENODEV;
> + }
> +
> + bank_types = (const enum bff_type *)m->driver_data;
> +
> return 0;
> }
>
>
--
i.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 6/7] platform/x86/intel/bff: Compute unique ID for overflowed filter
2026-08-25 18:15 ` [PATCH 6/7] platform/x86/intel/bff: Compute unique ID for overflowed filter Tony Luck
@ 2026-08-26 8:26 ` Ilpo Järvinen
0 siblings, 0 replies; 15+ messages in thread
From: Ilpo Järvinen @ 2026-08-26 8:26 UTC (permalink / raw)
To: Tony Luck
Cc: Hans de Goede, Borislav Petkov, Breno Leitao, platform-driver-x86,
LKML, patches, Qiuxu Zhuo
On Tue, 25 Aug 2026, Tony Luck wrote:
> Each L2 cache instance has its own bitfix filter, but always reports
> errors in machine check bank 3 (on Diamond Rapids).
>
> Compute a unique bitfix filter instance number based on the CPU that
> logged the error and the machine check bank number.
>
> Special case for banks associated with the Integrated Memory Hub (IMH).
> Here the "even" numbered CPU modules are associated with IMH0 and the
> "odd" modules with IMH1.
>
> The unique id will be used to store a time stamp of when the bitfix
> filter overflowed so that frequent overflows can be logged.
>
> Co-developed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
> Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
> Signed-off-by: Tony Luck <tony.luck@intel.com>
> ---
> drivers/platform/x86/intel/bff.c | 74 ++++++++++++++++++++++++++++++++
> 1 file changed, 74 insertions(+)
>
> diff --git a/drivers/platform/x86/intel/bff.c b/drivers/platform/x86/intel/bff.c
> index 8cc29d11e019..ae9dc0bf2777 100644
> --- a/drivers/platform/x86/intel/bff.c
> +++ b/drivers/platform/x86/intel/bff.c
> @@ -18,13 +18,18 @@
> #define pr_fmt(fmt) "bff: " fmt
>
> #include <linux/bits.h>
> +#include <linux/cacheinfo.h>
> +#include <linux/cleanup.h>
> #include <linux/cpufeature.h>
> +#include <linux/cpuhplock.h>
> #include <linux/device-id/x86_cpu.h>
> #include <linux/errno.h>
> #include <linux/init.h>
> +#include <linux/limits.h>
> #include <linux/module.h>
> #include <linux/notifier.h>
> #include <linux/printk.h>
> +#include <linux/topology.h>
> #include <linux/types.h>
>
> #include <asm/cpu_device_id.h>
> @@ -34,6 +39,8 @@
> #include <asm/msr.h>
> #include <asm/msr-index.h>
>
> +#define NUM_IMH_PER_SKT 2
> +
> /* Intel bitfix filter control register defines */
> #define MSR_MC0_BFF_CTL 0x000006c0
> #define MSR_MCx_BFF_CTL(x) (MSR_MC0_BFF_CTL + (x))
> @@ -67,11 +74,78 @@ MODULE_DEVICE_TABLE(x86cpu, bff_cpu_ids);
>
> static const enum bff_type *bank_types;
>
> +/* Diamond Rapids maps APICID[2] to the IMH instance. */
> +static void bff_set_imh_id(struct mce *mce, unsigned long *id)
> +{
> + int imh_num = (NUM_IMH_PER_SKT * topology_physical_package_id(mce->extcpu)) +
> + ((mce->apicid >> 2) & 0x1);
FIELD_GET(), I suggest moving comment where you define the field for that.
> +
> + *id |= imh_num;
> +}
> +
> +static bool bff_set_cache_id(int cpu, int level, unsigned long *id)
> +{
> + int cacheid;
> +
> + guard(cpus_read_lock)();
> +
> + cacheid = get_cpu_cacheinfo_id(cpu, level);
> + if (cacheid == -1) {
> + pr_warn("Could not get L%d cache id for CPU %d\n", level, cpu);
> + return false;
> + }
> +
> + *id |= cacheid;
> +
> + return true;
> +}
> +
> +#define BFF_ID_BANK_SHIFT 16
> +
> +/*
> + * Cache IDs are only unique within a cache level.
> + * Include the MCA bank number so each BFF-capable hardware
> + * resource has a unique tracking ID.
> + */
> +static unsigned long get_bff_id(struct mce *mce)
> +{
> + unsigned long id = (unsigned long)mce->bank << BFF_ID_BANK_SHIFT;
FIELD_PREP() ?
> +
> + switch (bank_types[mce->bank]) {
> + case BFF_BANK_DCU:
> + case BFF_BANK_DTLB:
> + if (!bff_set_cache_id(mce->extcpu, 1, &id))
> + return ULONG_MAX;
> + break;
> +
> + case BFF_BANK_MLC:
> + if (!bff_set_cache_id(mce->extcpu, 2, &id))
> + return ULONG_MAX;
> + break;
> +
> + case BFF_BANK_CCF:
> + if (!bff_set_cache_id(mce->extcpu, 3, &id))
> + return ULONG_MAX;
> + break;
> +
> + case BFF_BANK_HSF:
> + case BFF_BANK_IOCACHE:
> + bff_set_imh_id(mce, &id);
> + break;
> + default:
> + return ULONG_MAX;
> + }
> +
> + return id;
> +}
> +
> static void handle_bff(struct mce *mce)
> {
> /* The bitfix filter overflowed, get the target CPU to reset it. */
> if (wrmsrq_on_cpu(mce->extcpu, MSR_MCx_BFF_CTL(mce->bank), MCI_BFF_RESET))
> pr_warn("Failed to reset bitfix filter for CPU %d Bank %d\n", mce->extcpu, mce->bank);
> +
> + pr_debug("unique_id = 0x%lx\n", get_bff_id(mce));
> }
>
> static int bff_mce_notify(struct notifier_block *nb, unsigned long val, void *data)
>
--
i.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 7/7] platform/x86/intel/bff: Report frequent filter resets
2026-08-25 18:15 ` [PATCH 7/7] platform/x86/intel/bff: Report frequent filter resets Tony Luck
@ 2026-08-26 8:39 ` Ilpo Järvinen
0 siblings, 0 replies; 15+ messages in thread
From: Ilpo Järvinen @ 2026-08-26 8:39 UTC (permalink / raw)
To: Tony Luck
Cc: Hans de Goede, Borislav Petkov, Breno Leitao, platform-driver-x86,
LKML, patches, Qiuxu Zhuo
On Tue, 25 Aug 2026, Tony Luck wrote:
> If an instance of a bitfix filter contains some transient errors built
> up over time, then resetting the filter will free up slots in the filter
> to store persistent errors.
>
> Save a time stamp when "yellow" status is seen and clear the filter.
>
> Log at KERN_WARNING level if the overflow occurred quickly after a
> previous overflow on the same bitfix filter instance. Use KERN_NOTICE
> for first, or long delayed, overflow.
>
> Co-developed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
> Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
> Signed-off-by: Tony Luck <tony.luck@intel.com>
> ---
> drivers/platform/x86/intel/bff.c | 71 +++++++++++++++++++++++++++++++-
> 1 file changed, 70 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/platform/x86/intel/bff.c b/drivers/platform/x86/intel/bff.c
> index ae9dc0bf2777..7c22a1ad6b9d 100644
> --- a/drivers/platform/x86/intel/bff.c
> +++ b/drivers/platform/x86/intel/bff.c
> @@ -23,14 +23,19 @@
> #include <linux/cpufeature.h>
> #include <linux/cpuhplock.h>
> #include <linux/device-id/x86_cpu.h>
> +#include <linux/err.h>
> #include <linux/errno.h>
> +#include <linux/gfp_types.h>
> #include <linux/init.h>
> +#include <linux/jiffies.h>
> #include <linux/limits.h>
> #include <linux/module.h>
> #include <linux/notifier.h>
> #include <linux/printk.h>
> +#include <linux/slab.h>
> #include <linux/topology.h>
> #include <linux/types.h>
> +#include <linux/xarray.h>
A bonus point from paying attention to having necessary includes already
in v1 throughout the series. :-) (No action required, I'm just happy to
see that for a change.)
> #include <asm/cpu_device_id.h>
> #include <asm/cpufeatures.h>
> @@ -39,6 +44,16 @@
> #include <asm/msr.h>
> #include <asm/msr-index.h>
>
> +/*
> + * A 10-minute observation period helps distinguish between:
> + *
> + * - A long-term accumulation of transient corrected errors
> + * (filter stays clear after reset).
> + *
> + * - Permanent defects (filter overflows again quickly).
> + */
> +#define BFF_OVERFLOW_INTERVAL secs_to_jiffies(10 * 60)
> +
> #define NUM_IMH_PER_SKT 2
>
> /* Intel bitfix filter control register defines */
> @@ -74,6 +89,8 @@ MODULE_DEVICE_TABLE(x86cpu, bff_cpu_ids);
>
> static const enum bff_type *bank_types;
>
> +static DEFINE_XARRAY(bff_bank_xa);
> +
> /* Diamond Rapids maps APICID[2] to the IMH instance. */
> static void bff_set_imh_id(struct mce *mce, unsigned long *id)
> {
> @@ -139,13 +156,58 @@ static unsigned long get_bff_id(struct mce *mce)
> return id;
> }
>
> +/*
> + * Save current timestamp for bff_id. Return true if it is within
> + * BFF_OVERFLOW_INTERVAL of previous timestamp for this bff_id.
> + */
> +static bool bff_note_event_and_check_burst(unsigned long bff_id)
> +{
> + unsigned long now = jiffies, when;
> + unsigned long *ts;
> +
> + if (bff_id == ULONG_MAX)
> + return false;
> +
> + ts = xa_load(&bff_bank_xa, bff_id);
> + if (!ts) {
> + ts = kzalloc_obj(*ts);
> + if (!ts) {
> + pr_warn("Timestamp allocation failed\n");
> + return false;
> + }
> + if (IS_ERR(xa_store(&bff_bank_xa, bff_id, ts, GFP_KERNEL))) {
> + kfree(ts);
> + pr_warn("Timestamp save failure\n");
> + return false;
> + }
> + *ts = now;
> +
> + return false;
> + }
> +
> + when = *ts + BFF_OVERFLOW_INTERVAL;
You could try to name "when" more descriptively so the name tells its the
end of the ("too fast") burst time window.
> + *ts = now;
> +
> + return time_before(now, when);
> +}
> +
> static void handle_bff(struct mce *mce)
> {
> + bool burst = false;
> +
> /* The bitfix filter overflowed, get the target CPU to reset it. */
> if (wrmsrq_on_cpu(mce->extcpu, MSR_MCx_BFF_CTL(mce->bank), MCI_BFF_RESET))
> pr_warn("Failed to reset bitfix filter for CPU %d Bank %d\n", mce->extcpu, mce->bank);
>
> - pr_debug("unique_id = 0x%lx\n", get_bff_id(mce));
> + /* Get unique id for bitfix filter instance that overflowed */
> + burst = bff_note_event_and_check_burst(get_bff_id(mce));
> +
> + if (burst)
> + pr_warn_ratelimited(HW_ERR "Socket %d CPU %d Bank %d bitfix filter overflowed frequently\n",
> + mce->socketid, mce->extcpu, mce->bank);
> + else
> + pr_notice_ratelimited(HW_ERR "Socket %d CPU %d Bank %d bitfix filter overflowed\n",
> + mce->socketid, mce->extcpu, mce->bank);
> }
>
> static int bff_mce_notify(struct notifier_block *nb, unsigned long val, void *data)
> @@ -205,7 +267,14 @@ static int __init bff_init(void)
>
> static void __exit bff_exit(void)
> {
> + unsigned long bff_id;
> + unsigned long *ts;
> +
> mce_unregister_decode_chain(&bff_notifier);
> +
> + xa_for_each(&bff_bank_xa, bff_id, ts)
> + kfree(ts);
> + xa_destroy(&bff_bank_xa);
> }
>
> module_init(bff_init);
>
--
i.
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2026-08-26 8:39 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-25 18:15 [PATCH 0/7] Intel platform driver to reset bitfix filters Tony Luck
2026-08-25 18:15 ` [PATCH 1/7] cacheinfo: Export get_cpu_cacheinfo_id() for loadable modules Tony Luck
2026-08-25 18:15 ` [PATCH 2/7] x86/mce: Enumeration updates for Intel bitfix filter reset Tony Luck
2026-08-26 8:15 ` Ilpo Järvinen
2026-08-25 18:15 ` [PATCH 3/7] platform/x86/intel/bff: Add stub Intel bitfix filter driver Tony Luck
2026-08-25 18:15 ` [PATCH 4/7] platform/x86/intel/bff: Add Diamond Rapids support Tony Luck
2026-08-26 8:17 ` Ilpo Järvinen
2026-08-25 18:15 ` [PATCH 5/7] platform/x86/intel/bff: Reset bitfix filter when it overflows Tony Luck
2026-08-25 18:15 ` [PATCH 6/7] platform/x86/intel/bff: Compute unique ID for overflowed filter Tony Luck
2026-08-26 8:26 ` Ilpo Järvinen
2026-08-25 18:15 ` [PATCH 7/7] platform/x86/intel/bff: Report frequent filter resets Tony Luck
2026-08-26 8:39 ` Ilpo Järvinen
2026-08-25 18:28 ` [PATCH 0/7] Intel platform driver to reset bitfix filters Borislav Petkov
2026-08-25 18:55 ` Luck, Tony
2026-08-25 19:23 ` Borislav Petkov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox