diff --git a/kernel.spec.in b/kernel.spec.in index 6ff50462..5631374c 100644 --- a/kernel.spec.in +++ b/kernel.spec.in @@ -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 diff --git a/usb-1.patch b/usb-1.patch new file mode 100644 index 00000000..0ae9ebf2 --- /dev/null +++ b/usb-1.patch @@ -0,0 +1,51 @@ +Date: Tue, 2 Jun 2026 11:48:23 -0700 +From: Borislav Petkov +To: Penny Zheng +Cc: x86@kernel.org, ray.huang@amd.com, Jason.Andryuk@amd.com, + stefano.stabellini@amd.com, + Mario Limonciello , + Yazen Ghannam , + Thomas Gleixner , Ingo Molnar , + Dave Hansen , + "H. Peter Anvin" , 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; + diff --git a/usb-2.patch b/usb-2.patch new file mode 100644 index 00000000..79303bb3 --- /dev/null +++ b/usb-2.patch @@ -0,0 +1,68 @@ +From: Penny Zheng +To: +CC: , , + , Penny Zheng , "Mario + Limonciello" , Yazen Ghannam + , Thomas Gleixner , Ingo Molnar + , Borislav Petkov , Dave Hansen + , "H. Peter Anvin" , + , +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 +--- + 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