Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions kernel.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ Patch31: 0001-PCI-add-a-reset-quirk-for-Intel-I219LM-ethernet-adap.patch
Patch32: 0001-Revert-e1000e-change-k1-configuration-on-MTP-and-lat.patch
Patch33: 0001-xen-xenbus-better-handle-backend-crash.patch
Patch34: 0001-rust-fixup.patch
Patch35: usb-1.patch
Patch36: usb-2.patch

# S0ix support:
Patch61: xen-events-Add-wakeup-support-to-xen-pirq.patch
Expand Down
51 changes: 51 additions & 0 deletions usb-1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
Date: Tue, 2 Jun 2026 11:48:23 -0700
From: Borislav Petkov <bp@alien8.de>
To: Penny Zheng <penny.zheng@amd.com>
Cc: x86@kernel.org, ray.huang@amd.com, Jason.Andryuk@amd.com,
stefano.stabellini@amd.com,
Mario Limonciello <mario.limonciello@amd.com>,
Yazen Ghannam <yazen.ghannam@amd.com>,
Thomas Gleixner <tglx@kernel.org>, Ingo Molnar <mingo@redhat.com>,
Dave Hansen <dave.hansen@linux.intel.com>,
"H. Peter Anvin" <hpa@zytor.com>, xen-devel@lists.xenproject.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v1 0/2] x86/amd_node: harden amd_smn_init() against Xen
dom0 topology
Message-ID: <20260602184823.GKah8ld2QJLm28xoa9@fat_crate.local>

On Wed, May 06, 2026 at 01:55:17PM +0800, Penny Zheng wrote:
> While booting a recent linux-next kernel as a Xen PVH dom0 on x86, the kernel
> oopses very early during fs_initcall:
>
> Oops: divide error: 0000 [#1] SMP NOPTI
> RIP: 0010:amd_smn_init+0x188/0x2e0
>
> Followed: on a kernel that survives the divide, it will fail by a NULL pointer
> dereference from the first SMN consumer (amd_pmc_probe -> amd_smn_read).
>
> Root cause
> ==========
>
> To prevent each dom0 vCPU from looking like an SMT sibling of another
> vCPU, Xen synthesizes guest x2APIC IDs as vcpu_index * 2. This spacing every
> vCPU's APIC ID by 2 can push the synthesized IDs past the package-field
> boundary. Linux then infers more "packages" and therefore more AMD
> nodes via amd_num_nodes() than the platform actually has, while the
> PCI-side host-bridge scan correctly reports the number of root complex.

Does that work?

diff --git a/arch/x86/kernel/amd_node.c b/arch/x86/kernel/amd_node.c
index 0be01725a2a4..0f1ad1883883 100644
--- a/arch/x86/kernel/amd_node.c
+++ b/arch/x86/kernel/amd_node.c
@@ -249,6 +249,9 @@ static int __init amd_smn_init(void)
u16 count, num_roots, roots_per_node, node, num_nodes;
struct pci_dev *root;

+ if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
+ return 0;
+
if (!cpu_feature_enabled(X86_FEATURE_ZEN))
return 0;

68 changes: 68 additions & 0 deletions usb-2.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
From: Penny Zheng <penny.zheng@amd.com>
To: <x86@kernel.org>
CC: <ray.huang@amd.com>, <Jason.Andryuk@amd.com>,
<stefano.stabellini@amd.com>, Penny Zheng <penny.zheng@amd.com>, "Mario
Limonciello" <mario.limonciello@amd.com>, Yazen Ghannam
<yazen.ghannam@amd.com>, Thomas Gleixner <tglx@kernel.org>, Ingo Molnar
<mingo@redhat.com>, Borislav Petkov <bp@alien8.de>, Dave Hansen
<dave.hansen@linux.intel.com>, "H. Peter Anvin" <hpa@zytor.com>,
<xen-devel@lists.xenproject.org>, <linux-kernel@vger.kernel.org>
Subject: [PATCH v1 2/2] x86/amd_node: reject SMN access when amd_smn_init() did not complete
Date: Wed, 6 May 2026 13:55:19 +0800
Message-ID: <20260506055528.476493-3-penny.zheng@amd.com>

amd_smn_init() can fail early (e.g. -ENODEV when num_roots < num_nodes,
-ENOMEM from kcalloc) without setting smn_exclusive. In that case
amd_roots stays NULL, but the existing __amd_smn_rw() ordering dereferenced
amd_roots[node] before the smn_exclusive guard. The first SMN consumer (e.g.
amd_pmc_probe -> amd_smn_read) then hit a NULL pointer dereference
instead of getting -ENODEV.

Move the smn_exclusive check to the very beginning of __amd_smn_rw()
so a failed init is rejected before any deref. Also zero *value in
amd_smn_read() on the error path so callers never read uninitialized
data via the subsequent PCI_POSSIBLE_ERROR() check.

Signed-off-by: Penny Zheng <penny.zheng@amd.com>
---
arch/x86/kernel/amd_node.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/amd_node.c b/arch/x86/kernel/amd_node.c
index c896060fe0df..cb9ed022c53c 100644
--- a/arch/x86/kernel/amd_node.c
+++ b/arch/x86/kernel/amd_node.c
@@ -88,6 +88,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 (!smn_exclusive)
+ return err;
+
if (node >= amd_num_nodes())
return err;

@@ -95,9 +98,6 @@ static int __amd_smn_rw(u8 i_off, u8 d_off, u16 node, u32 address, u32 *value, b
if (!root)
return err;

- if (!smn_exclusive)
- return err;
-
guard(mutex)(&smn_mutex);

err = pci_write_config_dword(root, i_off, address);
@@ -116,6 +116,11 @@ int __must_check amd_smn_read(u16 node, u32 address, u32 *value)
{
int err = __amd_smn_rw(SMN_INDEX_OFFSET, SMN_DATA_OFFSET, node, address, value, false);

+ if (err) {
+ *value = 0;
+ return err;
+ }
+
if (PCI_POSSIBLE_ERROR(*value)) {
err = -ENODEV;
*value = 0;
--
2.43.0