Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'x86-urgent-2025-11-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Ingo Molnar:

- Fix AMD PCI root device caching regression that triggers
on certain firmware variants

- Fix the zen5_rdseed_microcode[] array to be NULL-terminated

- Add more AMD models to microcode signature checking

* tag 'x86-urgent-2025-11-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/microcode/AMD: Add more known models to entry sign checking
x86/CPU/AMD: Add missing terminator for zen5_rdseed_microcode
x86/amd_node: Fix AMD root device caching

+54 -100
-1
arch/x86/include/asm/amd/node.h
··· 23 23 #define AMD_NODE0_PCI_SLOT 0x18 24 24 25 25 struct pci_dev *amd_node_get_func(u16 node, u8 func); 26 - struct pci_dev *amd_node_get_root(u16 node); 27 26 28 27 static inline u16 amd_num_nodes(void) 29 28 {
+51 -99
arch/x86/kernel/amd_node.c
··· 34 34 return pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(AMD_NODE0_PCI_SLOT + node, func)); 35 35 } 36 36 37 - #define DF_BLK_INST_CNT 0x040 38 - #define DF_CFG_ADDR_CNTL_LEGACY 0x084 39 - #define DF_CFG_ADDR_CNTL_DF4 0xC04 40 - 41 - #define DF_MAJOR_REVISION GENMASK(27, 24) 42 - 43 - static u16 get_cfg_addr_cntl_offset(struct pci_dev *df_f0) 44 - { 45 - u32 reg; 46 - 47 - /* 48 - * Revision fields added for DF4 and later. 49 - * 50 - * Major revision of '0' is found pre-DF4. Field is Read-as-Zero. 51 - */ 52 - if (pci_read_config_dword(df_f0, DF_BLK_INST_CNT, &reg)) 53 - return 0; 54 - 55 - if (reg & DF_MAJOR_REVISION) 56 - return DF_CFG_ADDR_CNTL_DF4; 57 - 58 - return DF_CFG_ADDR_CNTL_LEGACY; 59 - } 60 - 61 - struct pci_dev *amd_node_get_root(u16 node) 62 - { 63 - struct pci_dev *root; 64 - u16 cntl_off; 65 - u8 bus; 66 - 67 - if (!cpu_feature_enabled(X86_FEATURE_ZEN)) 68 - return NULL; 69 - 70 - /* 71 - * D18F0xXXX [Config Address Control] (DF::CfgAddressCntl) 72 - * Bits [7:0] (SecBusNum) holds the bus number of the root device for 73 - * this Data Fabric instance. The segment, device, and function will be 0. 74 - */ 75 - struct pci_dev *df_f0 __free(pci_dev_put) = amd_node_get_func(node, 0); 76 - if (!df_f0) 77 - return NULL; 78 - 79 - cntl_off = get_cfg_addr_cntl_offset(df_f0); 80 - if (!cntl_off) 81 - return NULL; 82 - 83 - if (pci_read_config_byte(df_f0, cntl_off, &bus)) 84 - return NULL; 85 - 86 - /* Grab the pointer for the actual root device instance. */ 87 - root = pci_get_domain_bus_and_slot(0, bus, 0); 88 - 89 - pci_dbg(root, "is root for AMD node %u\n", node); 90 - return root; 91 - } 92 - 93 37 static struct pci_dev **amd_roots; 94 38 95 39 /* Protect the PCI config register pairs used for SMN. */ ··· 218 274 DEFINE_SHOW_STORE_ATTRIBUTE(smn_address); 219 275 DEFINE_SHOW_STORE_ATTRIBUTE(smn_value); 220 276 221 - static int amd_cache_roots(void) 277 + static struct pci_dev *get_next_root(struct pci_dev *root) 222 278 { 223 - u16 node, num_nodes = amd_num_nodes(); 224 - 225 - amd_roots = kcalloc(num_nodes, sizeof(*amd_roots), GFP_KERNEL); 226 - if (!amd_roots) 227 - return -ENOMEM; 228 - 229 - for (node = 0; node < num_nodes; node++) 230 - amd_roots[node] = amd_node_get_root(node); 231 - 232 - return 0; 233 - } 234 - 235 - static int reserve_root_config_spaces(void) 236 - { 237 - struct pci_dev *root = NULL; 238 - struct pci_bus *bus = NULL; 239 - 240 - while ((bus = pci_find_next_bus(bus))) { 241 - /* Root device is Device 0 Function 0 on each Primary Bus. */ 242 - root = pci_get_slot(bus, 0); 243 - if (!root) 279 + while ((root = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, root))) { 280 + /* Root device is Device 0 Function 0. */ 281 + if (root->devfn) 244 282 continue; 245 283 246 284 if (root->vendor != PCI_VENDOR_ID_AMD && 247 285 root->vendor != PCI_VENDOR_ID_HYGON) 248 286 continue; 249 287 250 - pci_dbg(root, "Reserving PCI config space\n"); 251 - 252 - /* 253 - * There are a few SMN index/data pairs and other registers 254 - * that shouldn't be accessed by user space. 255 - * So reserve the entire PCI config space for simplicity rather 256 - * than covering specific registers piecemeal. 257 - */ 258 - if (!pci_request_config_region_exclusive(root, 0, PCI_CFG_SPACE_SIZE, NULL)) { 259 - pci_err(root, "Failed to reserve config space\n"); 260 - return -EEXIST; 261 - } 288 + break; 262 289 } 263 290 264 - smn_exclusive = true; 265 - return 0; 291 + return root; 266 292 } 267 293 268 294 static bool enable_dfs; ··· 246 332 247 333 static int __init amd_smn_init(void) 248 334 { 249 - int err; 335 + u16 count, num_roots, roots_per_node, node, num_nodes; 336 + struct pci_dev *root; 250 337 251 338 if (!cpu_feature_enabled(X86_FEATURE_ZEN)) 252 339 return 0; ··· 257 342 if (amd_roots) 258 343 return 0; 259 344 260 - err = amd_cache_roots(); 261 - if (err) 262 - return err; 345 + num_roots = 0; 346 + root = NULL; 347 + while ((root = get_next_root(root))) { 348 + pci_dbg(root, "Reserving PCI config space\n"); 263 349 264 - err = reserve_root_config_spaces(); 265 - if (err) 266 - return err; 350 + /* 351 + * There are a few SMN index/data pairs and other registers 352 + * that shouldn't be accessed by user space. So reserve the 353 + * entire PCI config space for simplicity rather than covering 354 + * specific registers piecemeal. 355 + */ 356 + if (!pci_request_config_region_exclusive(root, 0, PCI_CFG_SPACE_SIZE, NULL)) { 357 + pci_err(root, "Failed to reserve config space\n"); 358 + return -EEXIST; 359 + } 360 + 361 + num_roots++; 362 + } 363 + 364 + pr_debug("Found %d AMD root devices\n", num_roots); 365 + 366 + if (!num_roots) 367 + return -ENODEV; 368 + 369 + num_nodes = amd_num_nodes(); 370 + amd_roots = kcalloc(num_nodes, sizeof(*amd_roots), GFP_KERNEL); 371 + if (!amd_roots) 372 + return -ENOMEM; 373 + 374 + roots_per_node = num_roots / num_nodes; 375 + 376 + count = 0; 377 + node = 0; 378 + root = NULL; 379 + while (node < num_nodes && (root = get_next_root(root))) { 380 + /* Use one root for each node and skip the rest. */ 381 + if (count++ % roots_per_node) 382 + continue; 383 + 384 + pci_dbg(root, "is root for AMD node %u\n", node); 385 + amd_roots[node++] = root; 386 + } 267 387 268 388 if (enable_dfs) { 269 389 debugfs_dir = debugfs_create_dir("amd_smn", arch_debugfs_dir); ··· 307 357 debugfs_create_file("address", 0600, debugfs_dir, NULL, &smn_address_fops); 308 358 debugfs_create_file("value", 0600, debugfs_dir, NULL, &smn_value_fops); 309 359 } 360 + 361 + smn_exclusive = true; 310 362 311 363 return 0; 312 364 }
+1
arch/x86/kernel/cpu/amd.c
··· 1038 1038 static const struct x86_cpu_id zen5_rdseed_microcode[] = { 1039 1039 ZEN_MODEL_STEP_UCODE(0x1a, 0x02, 0x1, 0x0b00215a), 1040 1040 ZEN_MODEL_STEP_UCODE(0x1a, 0x11, 0x0, 0x0b101054), 1041 + {}, 1041 1042 }; 1042 1043 1043 1044 static void init_amd_zen5(struct cpuinfo_x86 *c)
+2
arch/x86/kernel/cpu/microcode/amd.c
··· 220 220 case 0xaa001: return cur_rev <= 0xaa00116; break; 221 221 case 0xaa002: return cur_rev <= 0xaa00218; break; 222 222 case 0xb0021: return cur_rev <= 0xb002146; break; 223 + case 0xb0081: return cur_rev <= 0xb008111; break; 223 224 case 0xb1010: return cur_rev <= 0xb101046; break; 224 225 case 0xb2040: return cur_rev <= 0xb204031; break; 225 226 case 0xb4040: return cur_rev <= 0xb404031; break; 226 227 case 0xb6000: return cur_rev <= 0xb600031; break; 228 + case 0xb6080: return cur_rev <= 0xb608031; break; 227 229 case 0xb7000: return cur_rev <= 0xb700031; break; 228 230 default: break; 229 231 }