Hi all,
This set unifies the AMD MCA interrupt handlers with common MCA code.
The goal is to avoid duplicating functionality like reading and clearing
MCA banks.
Based on feedback, this revision also include changes to the MCA init
flow.
Patches 1-4:
General fixes and cleanups.
Patches 5-10:
Add BSP-only init flow and related changes.
Patches 11-15:
Updates from v1 set.
Patch 16:
Interrupt storm handling rebased on current set.
Thanks,
Yazen
---
Changes in v2:
- Add general cleanup pre-patches.
- Add changes for BSP-only init.
- Add interrupt storm handling for AMD.
- Link to v1: https://lore.kernel.org/r/20240523155641.2805411-1-yazen.ghannam@amd.com
---
Borislav Petkov (1):
x86/mce: Cleanup bank processing on init
Smita Koralahalli (1):
x86/mce: Handle AMD threshold interrupt storms
Yazen Ghannam (14):
x86/mce: Don't remove sysfs if thresholding sysfs init fails
x86/mce/amd: Remove return value for mce_threshold_create_device()
x86/mce/amd: Remove smca_banks_map
x86/mce/amd: Put list_head in threshold_bank
x86/mce: Remove __mcheck_cpu_init_early()
x86/mce: Define BSP-only init
x86/mce: Define BSP-only SMCA init
x86/mce: Do 'UNKNOWN' vendor check early
x86/mce: Separate global and per-CPU quirks
x86/mce: Move machine_check_poll() status checks to helper functions
x86/mce: Unify AMD THR handler with MCA Polling
x86/mce: Unify AMD DFR handler with MCA Polling
x86/mce/amd: Enable interrupt vectors once per-CPU on SMCA systems
x86/mce/amd: Support SMCA Corrected Error Interrupt
arch/x86/include/asm/mce.h | 7 +-
arch/x86/kernel/cpu/common.c | 1 +
arch/x86/kernel/cpu/mce/amd.c | 391 +++++++++++++-----------------------
arch/x86/kernel/cpu/mce/core.c | 322 ++++++++++++++---------------
arch/x86/kernel/cpu/mce/intel.c | 15 ++
arch/x86/kernel/cpu/mce/internal.h | 8 +
arch/x86/kernel/cpu/mce/threshold.c | 3 +
7 files changed, 332 insertions(+), 415 deletions(-)
---
base-commit: b36de8b904b8ff2095ece7af6b3cfff8c73c2fb1
change-id: 20250210-wip-mca-updates-bed2a67c9c57
Once device_register() failed, we should call put_device() to
decrement reference count for cleanup. Or it could cause memory leak.
device_register() includes device_add(). As comment of device_add()
says, 'if device_add() succeeds, you should call device_del() when you
want to get rid of it. If device_add() has not succeeded, use only
put_device() to drop the reference count'.
Found by code review.
Cc: stable(a)vger.kernel.org
Fixes: 37d6a0a6f470 ("PCI: Add pci_register_host_bridge() interface")
Signed-off-by: Ma Ke <make24(a)iscas.ac.cn>
---
Changes in v2:
- modified the patch description.
---
drivers/pci/probe.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index b6536ed599c3..03dc65cf48f1 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1017,8 +1017,10 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
name = dev_name(&bus->dev);
err = device_register(&bus->dev);
- if (err)
+ if (err) {
+ put_device(&bus->dev);
goto unregister;
+ }
pcibios_add_bus(bus);
--
2.25.1
Once device_register() failed, we should call put_device() to
decrement reference count for cleanup. Or it could cause memory leak.
As comment of device_register() says, 'NOTE: _Never_ directly free
@dev after calling this function, even if it returned an error! Always
use put_device() to give up the reference initialized in this function
instead.'
Found by code review.
Cc: stable(a)vger.kernel.org
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Ma Ke <make24(a)iscas.ac.cn>
---
Changes in v5:
- modified the bug description as suggestions;
Changes in v4:
- deleted the redundant initialization;
Changes in v3:
- modified the patch as suggestions;
Changes in v2:
- modified the patch as suggestions.
---
arch/arm/common/locomo.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index cb6ef449b987..45106066a17f 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -223,10 +223,8 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info)
int ret;
dev = kzalloc(sizeof(struct locomo_dev), GFP_KERNEL);
- if (!dev) {
- ret = -ENOMEM;
- goto out;
- }
+ if (!dev)
+ return -ENOMEM;
/*
* If the parent device has a DMA mask associated with it,
@@ -254,10 +252,9 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info)
NO_IRQ : lchip->irq_base + info->irq[0];
ret = device_register(&dev->dev);
- if (ret) {
- out:
- kfree(dev);
- }
+ if (ret)
+ put_device(&dev->dev);
+
return ret;
}
--
2.25.1
If device_add() fails, do not use device_unregister() for error
handling. device_unregister() consists two functions: device_del() and
put_device(). device_unregister() should only be called after
device_add() succeeded because device_del() undoes what device_add()
does if successful. Change device_unregister() to put_device() call
before returning from the function.
As comment of device_add() says, 'if device_add() succeeds, you should
call device_del() when you want to get rid of it. If device_add() has
not succeeded, use only put_device() to drop the reference count'.
Found by code review.
Cc: stable(a)vger.kernel.org
Fixes: 53d2a715c240 ("phy: Add Tegra XUSB pad controller support")
Signed-off-by: Ma Ke <make24(a)iscas.ac.cn>
---
Changes in v2:
- modified the bug description as suggestions.
---
drivers/phy/tegra/xusb.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index 79d4814d758d..c89df95aa6ca 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -548,16 +548,16 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
err = dev_set_name(&port->dev, "%s-%u", name, index);
if (err < 0)
- goto unregister;
+ goto put_device;
err = device_add(&port->dev);
if (err < 0)
- goto unregister;
+ goto put_device;
return 0;
-unregister:
- device_unregister(&port->dev);
+put_device:
+ put_device(&port->dev);
return err;
}
--
2.25.1
Fix two issues when cross-building userprogs with clang.
Reproducer, using nolibc to avoid libc requirements for cross building:
$ tail -2 init/Makefile
userprogs-always-y += test-llvm
test-llvm-userccflags += -nostdlib -nolibc -static -isystem usr/ -include $(srctree)/tools/include/nolibc/nolibc.h
$ cat init/test-llvm.c
int main(void)
{
return 0;
}
$ make ARCH=arm64 LLVM=1 allnoconfig headers_install init/
Validate that init/test-llvm builds and has the correct binary format.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh(a)linutronix.de>
---
Thomas Weißschuh (2):
kbuild: userprogs: fix bitsize and target detection on clang
kbuild: userprogs: use lld to link through clang
Makefile | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
---
base-commit: 2014c95afecee3e76ca4a56956a936e23283f05b
change-id: 20250213-kbuild-userprog-fixes-4f07b62ae818
Best regards,
--
Thomas Weißschuh <thomas.weissschuh(a)linutronix.de>
On xiaomi-beryllium and oneplus-enchilada audio does not work reliably
with the in-kernel pd-mapper. Deferring the probe solves these issues.
Specifically, audio only works reliably with the in-kernel pd-mapper, if
the probe succeeds when remoteproc3 triggers the first successful probe.
I.e., probes from remoteproc0, 1, and 2 need to be deferred until
remoteproc3 has been probed.
Introduce a device specific quirk that lists the first auxdev for which
the probe must be executed. Until then, defer probes from other auxdevs.
Fixes: 1ebcde047c54 ("soc: qcom: add pd-mapper implementation")
Cc: stable(a)vger.kernel.org
Signed-off-by: Frank Oltmanns <frank(a)oltmanns.dev>
---
The in-kernel pd-mapper has been causing audio issues on sdm845
devices (specifically, xiaomi-beryllium and oneplus-enchilada). I
observed that Stephan’s approach [1] - which defers module probing by
blocklisting the module and triggering a later probe - works reliably.
Inspired by this, I experimented with delaying the probe within the
module itself by returning -EPROBE_DEFER in qcom_pdm_probe() until a
certain time (13.9 seconds after boot, based on ktime_get()) had
elapsed. This method also restored audio functionality.
Further logging of auxdev->id in qcom_pdm_probe() led to an interesting
discovery: audio only works reliably with the in-kernel pd-mapper when
the first successful probe is triggered by remoteproc3. In other words,
probes from remoteproc0, 1, and 2 must be deferred until remoteproc3 has
been probed.
To address this, I propose introducing a quirk table (which currently
only contains sdm845) to defer probing until the correct auxiliary
device (remoteproc3) initiates the probe.
I look forward to your feedback.
Thanks,
Frank
[1]: https://lore.kernel.org/linux-arm-msm/Zwj3jDhc9fRoCCn6@linaro.org/
---
drivers/soc/qcom/qcom_pd_mapper.c | 43 +++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/drivers/soc/qcom/qcom_pd_mapper.c b/drivers/soc/qcom/qcom_pd_mapper.c
index 154ca5beb47160cc404a46a27840818fe3187420..34b26df665a888ac4872f56e948e73b561ae3b6b 100644
--- a/drivers/soc/qcom/qcom_pd_mapper.c
+++ b/drivers/soc/qcom/qcom_pd_mapper.c
@@ -46,6 +46,11 @@ struct qcom_pdm_data {
struct list_head services;
};
+struct qcom_pdm_probe_first_dev_quirk {
+ const char *name;
+ u32 id;
+};
+
static DEFINE_MUTEX(qcom_pdm_mutex); /* protects __qcom_pdm_data */
static struct qcom_pdm_data *__qcom_pdm_data;
@@ -526,6 +531,11 @@ static const struct qcom_pdm_domain_data *x1e80100_domains[] = {
NULL,
};
+static const struct qcom_pdm_probe_first_dev_quirk first_dev_remoteproc3 = {
+ .id = 3,
+ .name = "pd-mapper"
+};
+
static const struct of_device_id qcom_pdm_domains[] __maybe_unused = {
{ .compatible = "qcom,apq8016", .data = NULL, },
{ .compatible = "qcom,apq8064", .data = NULL, },
@@ -566,6 +576,10 @@ static const struct of_device_id qcom_pdm_domains[] __maybe_unused = {
{},
};
+static const struct of_device_id qcom_pdm_defer[] __maybe_unused = {
+ { .compatible = "qcom,sdm845", .data = &first_dev_remoteproc3, },
+ {},
+};
static void qcom_pdm_stop(struct qcom_pdm_data *data)
{
qcom_pdm_free_domains(data);
@@ -637,6 +651,25 @@ static struct qcom_pdm_data *qcom_pdm_start(void)
return ERR_PTR(ret);
}
+static bool qcom_pdm_ready(struct auxiliary_device *auxdev)
+{
+ const struct of_device_id *match;
+ struct device_node *root;
+ struct qcom_pdm_probe_first_dev_quirk *first_dev;
+
+ root = of_find_node_by_path("/");
+ if (!root)
+ return true;
+
+ match = of_match_node(qcom_pdm_defer, root);
+ of_node_put(root);
+ if (!match)
+ return true;
+
+ first_dev = (struct qcom_pdm_probe_first_dev_quirk *) match->data;
+ return (auxdev->id == first_dev->id) && !strcmp(auxdev->name, first_dev->name);
+}
+
static int qcom_pdm_probe(struct auxiliary_device *auxdev,
const struct auxiliary_device_id *id)
@@ -647,6 +680,15 @@ static int qcom_pdm_probe(struct auxiliary_device *auxdev,
mutex_lock(&qcom_pdm_mutex);
if (!__qcom_pdm_data) {
+ if (!qcom_pdm_ready(auxdev)) {
+ pr_debug("%s: Deferring probe for device %s (id: %u)\n",
+ __func__, auxdev->name, auxdev->id);
+ ret = -EPROBE_DEFER;
+ goto probe_stop;
+ }
+ pr_debug("%s: Probing for device %s (id: %u), starting pdm\n",
+ __func__, auxdev->name, auxdev->id);
+
data = qcom_pdm_start();
if (IS_ERR(data))
@@ -659,6 +701,7 @@ static int qcom_pdm_probe(struct auxiliary_device *auxdev,
auxiliary_set_drvdata(auxdev, __qcom_pdm_data);
+probe_stop:
mutex_unlock(&qcom_pdm_mutex);
return ret;
---
base-commit: 7f048b202333b967782a98aa21bb3354dc379bbf
change-id: 20250205-qcom_pdm_defer-3dc1271d74d9
Best regards,
--
Frank Oltmanns <frank(a)oltmanns.dev>