Re: kernel NULL pointer dereference in quirk_clear_strap_no_soft_reset_dev2_f0 -> amd_smn_read

From: Borislav Petkov

Date: Fri Jun 05 2026 - 19:10:21 EST


On Sat, Jun 06, 2026 at 12:40:20AM +0200, Marek Marczykowski-Górecki wrote:
> There is nothing here that would prevent amd_smn_read() being called
> inside a guest...

Yah, there should've been...

Anyway, something like the untested below, pls give it a run.

Thx.

---
diff --git a/arch/x86/kernel/amd_node.c b/arch/x86/kernel/amd_node.c
index 0be01725a2a4..52eff7fac667 100644
--- a/arch/x86/kernel/amd_node.c
+++ b/arch/x86/kernel/amd_node.c
@@ -39,6 +39,7 @@ static struct pci_dev **amd_roots;
/* Protect the PCI config register pairs used for SMN. */
static DEFINE_MUTEX(smn_mutex);
static bool smn_exclusive;
+static bool amd_node_off;

#define SMN_INDEX_OFFSET 0x60
#define SMN_DATA_OFFSET 0x64
@@ -88,6 +89,9 @@ static int __amd_smn_rw(u8 i_off, u8 d_off, u16 node, u32 address, u32 *value, b
struct pci_dev *root;
int err = -ENODEV;

+ if (amd_node_off)
+ return -EINVAL;
+
if (node >= amd_num_nodes())
return err;

@@ -248,9 +252,13 @@ static int __init amd_smn_init(void)
{
u16 count, num_roots, roots_per_node, node, num_nodes;
struct pci_dev *root;
+ int err = -EINVAL;
+
+ if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
+ goto err_out;

if (!cpu_feature_enabled(X86_FEATURE_ZEN))
- return 0;
+ goto err_out;

guard(mutex)(&smn_mutex);

@@ -270,7 +278,8 @@ static int __init amd_smn_init(void)
*/
if (!pci_request_config_region_exclusive(root, 0, PCI_CFG_SPACE_SIZE, NULL)) {
pci_err(root, "Failed to reserve config space\n");
- return -EEXIST;
+ err = -EEXIST;
+ goto err_out;
}

num_roots++;
@@ -278,13 +287,17 @@ static int __init amd_smn_init(void)

pr_debug("Found %d AMD root devices\n", num_roots);

- if (!num_roots)
- return -ENODEV;
+ if (!num_roots) {
+ err = -ENODEV;
+ goto err_out;
+ }

num_nodes = amd_num_nodes();
amd_roots = kzalloc_objs(*amd_roots, num_nodes);
- if (!amd_roots)
- return -ENOMEM;
+ if (!amd_roots) {
+ err = -ENOMEM;
+ goto err_out;
+ }

roots_per_node = num_roots / num_nodes;

@@ -311,6 +324,10 @@ static int __init amd_smn_init(void)
smn_exclusive = true;

return 0;
+
+err_out:
+ amd_node_off = true;
+ return err;
}

fs_initcall(amd_smn_init);


--
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette