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_misc_for_v6.14_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull misc x86 updates from Borislav Petkov:

- The first part of a restructuring of AMD's representation of a
northbridge which is legacy now, and the creation of the new AMD node
concept which represents the Zen architecture of having a collection
of I/O devices within an SoC. Those nodes comprise the so-called data
fabric on Zen.

This has at least one practical advantage of not having to add a PCI
ID each time a new data fabric PCI device releases. Eventually, the
lot more uniform provider of data fabric functionality amd_node.c
will be used by all the drivers which need it

- Smaller cleanups

* tag 'x86_misc_for_v6.14_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/amd_node: Use defines for SMN register offsets
x86/amd_node: Remove dependency on AMD_NB
x86/amd_node: Update __amd_smn_rw() error paths
x86/amd_nb: Move SMN access code to a new amd_node driver
x86/amd_nb, hwmon: (k10temp): Simplify amd_pci_dev_to_node_id()
x86/amd_nb: Simplify function 3 search
x86/amd_nb: Use topology info to get AMD node count
x86/amd_nb: Simplify root device search
x86/amd_nb: Simplify function 4 search
x86: Start moving AMD node functionality out of AMD_NB
x86/amd_nb: Clean up early_is_amd_nb()
x86/amd_nb: Restrict init function to AMD-based systems
x86/mtrr: Rename mtrr_overwrite_state() to guest_force_mtrr_state()

+317 -320
+8
MAINTAINERS
··· 1120 1120 S: Supported 1121 1121 F: drivers/i2c/busses/i2c-amd-asf-plat.c 1122 1122 1123 + AMD NODE DRIVER 1124 + M: Mario Limonciello <mario.limonciello@amd.com> 1125 + M: Yazen Ghannam <yazen.ghannam@amd.com> 1126 + L: linux-kernel@vger.kernel.org 1127 + S: Supported 1128 + F: arch/x86/include/asm/amd_node.h 1129 + F: arch/x86/kernel/amd_node.c 1130 + 1123 1131 AMD PDS CORE DRIVER 1124 1132 M: Shannon Nelson <shannon.nelson@amd.com> 1125 1133 M: Brett Creeley <brett.creeley@amd.com>
+4
arch/x86/Kconfig
··· 3129 3129 3130 3130 config AMD_NB 3131 3131 def_bool y 3132 + depends on AMD_NODE 3133 + 3134 + config AMD_NODE 3135 + def_bool y 3132 3136 depends on CPU_SUP_AMD && PCI 3133 3137 3134 3138 endmenu
+1 -1
arch/x86/hyperv/ivm.c
··· 664 664 x86_platform.guest.enc_status_change_finish = hv_vtom_set_host_visibility; 665 665 666 666 /* Set WB as the default cache mode. */ 667 - mtrr_overwrite_state(NULL, 0, MTRR_TYPE_WRBACK); 667 + guest_force_mtrr_state(NULL, 0, MTRR_TYPE_WRBACK); 668 668 } 669 669 670 670 #endif /* defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST) */
+1 -20
arch/x86/include/asm/amd_nb.h
··· 4 4 5 5 #include <linux/ioport.h> 6 6 #include <linux/pci.h> 7 + #include <asm/amd_node.h> 7 8 8 9 struct amd_nb_bus_dev_range { 9 10 u8 bus; ··· 20 19 extern int amd_numa_init(void); 21 20 extern int amd_get_subcaches(int); 22 21 extern int amd_set_subcaches(int, unsigned long); 23 - 24 - int __must_check amd_smn_read(u16 node, u32 address, u32 *value); 25 - int __must_check amd_smn_write(u16 node, u32 address, u32 value); 26 22 27 23 struct amd_l3_cache { 28 24 unsigned indices; ··· 48 50 u16 amd_nb_num(void); 49 51 bool amd_nb_has_feature(unsigned int feature); 50 52 struct amd_northbridge *node_to_amd_nb(int node); 51 - 52 - static inline u16 amd_pci_dev_to_node_id(struct pci_dev *pdev) 53 - { 54 - struct pci_dev *misc; 55 - int i; 56 - 57 - for (i = 0; i != amd_nb_num(); i++) { 58 - misc = node_to_amd_nb(i)->misc; 59 - 60 - if (pci_domain_nr(misc->bus) == pci_domain_nr(pdev->bus) && 61 - PCI_SLOT(misc->devfn) == PCI_SLOT(pdev->devfn)) 62 - return i; 63 - } 64 - 65 - WARN(1, "Unable to find AMD Northbridge id for %s\n", pci_name(pdev)); 66 - return 0; 67 - } 68 53 69 54 static inline bool amd_gart_present(void) 70 55 {
+36
arch/x86/include/asm/amd_node.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * AMD Node helper functions and common defines 4 + * 5 + * Copyright (c) 2024, Advanced Micro Devices, Inc. 6 + * All Rights Reserved. 7 + * 8 + * Author: Yazen Ghannam <Yazen.Ghannam@amd.com> 9 + * 10 + * Note: 11 + * Items in this file may only be used in a single place. 12 + * However, it's prudent to keep all AMD Node functionality 13 + * in a unified place rather than spreading throughout the 14 + * kernel. 15 + */ 16 + 17 + #ifndef _ASM_X86_AMD_NODE_H_ 18 + #define _ASM_X86_AMD_NODE_H_ 19 + 20 + #include <linux/pci.h> 21 + 22 + #define MAX_AMD_NUM_NODES 8 23 + #define AMD_NODE0_PCI_SLOT 0x18 24 + 25 + struct pci_dev *amd_node_get_func(u16 node, u8 func); 26 + struct pci_dev *amd_node_get_root(u16 node); 27 + 28 + static inline u16 amd_num_nodes(void) 29 + { 30 + return topology_amd_nodes_per_pkg() * topology_max_packages(); 31 + } 32 + 33 + int __must_check amd_smn_read(u16 node, u32 address, u32 *value); 34 + int __must_check amd_smn_write(u16 node, u32 address, u32 value); 35 + 36 + #endif /*_ASM_X86_AMD_NODE_H_*/
+5 -5
arch/x86/include/asm/mtrr.h
··· 58 58 */ 59 59 # ifdef CONFIG_MTRR 60 60 void mtrr_bp_init(void); 61 - void mtrr_overwrite_state(struct mtrr_var_range *var, unsigned int num_var, 62 - mtrr_type def_type); 61 + void guest_force_mtrr_state(struct mtrr_var_range *var, unsigned int num_var, 62 + mtrr_type def_type); 63 63 extern u8 mtrr_type_lookup(u64 addr, u64 end, u8 *uniform); 64 64 extern void mtrr_save_fixed_ranges(void *); 65 65 extern void mtrr_save_state(void); ··· 75 75 void mtrr_enable(void); 76 76 void mtrr_generic_set_state(void); 77 77 # else 78 - static inline void mtrr_overwrite_state(struct mtrr_var_range *var, 79 - unsigned int num_var, 80 - mtrr_type def_type) 78 + static inline void guest_force_mtrr_state(struct mtrr_var_range *var, 79 + unsigned int num_var, 80 + mtrr_type def_type) 81 81 { 82 82 } 83 83
+1
arch/x86/kernel/Makefile
··· 119 119 obj-$(CONFIG_HPET_TIMER) += hpet.o 120 120 121 121 obj-$(CONFIG_AMD_NB) += amd_nb.o 122 + obj-$(CONFIG_AMD_NODE) += amd_node.o 122 123 obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o 123 124 124 125 obj-$(CONFIG_KVM_GUEST) += kvm.o kvmclock.o
+21 -279
arch/x86/kernel/amd_nb.c
··· 15 15 #include <linux/pci_ids.h> 16 16 #include <asm/amd_nb.h> 17 17 18 - #define PCI_DEVICE_ID_AMD_17H_ROOT 0x1450 19 - #define PCI_DEVICE_ID_AMD_17H_M10H_ROOT 0x15d0 20 - #define PCI_DEVICE_ID_AMD_17H_M30H_ROOT 0x1480 21 - #define PCI_DEVICE_ID_AMD_17H_M60H_ROOT 0x1630 22 - #define PCI_DEVICE_ID_AMD_17H_MA0H_ROOT 0x14b5 23 - #define PCI_DEVICE_ID_AMD_19H_M10H_ROOT 0x14a4 24 - #define PCI_DEVICE_ID_AMD_19H_M40H_ROOT 0x14b5 25 - #define PCI_DEVICE_ID_AMD_19H_M60H_ROOT 0x14d8 26 - #define PCI_DEVICE_ID_AMD_19H_M70H_ROOT 0x14e8 27 - #define PCI_DEVICE_ID_AMD_1AH_M00H_ROOT 0x153a 28 - #define PCI_DEVICE_ID_AMD_1AH_M20H_ROOT 0x1507 29 - #define PCI_DEVICE_ID_AMD_1AH_M60H_ROOT 0x1122 30 - #define PCI_DEVICE_ID_AMD_MI200_ROOT 0x14bb 31 - #define PCI_DEVICE_ID_AMD_MI300_ROOT 0x14f8 32 - 33 - #define PCI_DEVICE_ID_AMD_17H_DF_F4 0x1464 34 - #define PCI_DEVICE_ID_AMD_17H_M10H_DF_F4 0x15ec 35 - #define PCI_DEVICE_ID_AMD_17H_M30H_DF_F4 0x1494 36 - #define PCI_DEVICE_ID_AMD_17H_M60H_DF_F4 0x144c 37 - #define PCI_DEVICE_ID_AMD_17H_M70H_DF_F4 0x1444 38 - #define PCI_DEVICE_ID_AMD_17H_MA0H_DF_F4 0x1728 39 - #define PCI_DEVICE_ID_AMD_19H_DF_F4 0x1654 40 - #define PCI_DEVICE_ID_AMD_19H_M10H_DF_F4 0x14b1 41 - #define PCI_DEVICE_ID_AMD_19H_M40H_DF_F4 0x167d 42 - #define PCI_DEVICE_ID_AMD_19H_M50H_DF_F4 0x166e 43 - #define PCI_DEVICE_ID_AMD_19H_M60H_DF_F4 0x14e4 44 - #define PCI_DEVICE_ID_AMD_19H_M70H_DF_F4 0x14f4 45 - #define PCI_DEVICE_ID_AMD_19H_M78H_DF_F4 0x12fc 46 - #define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4 0x12c4 47 - #define PCI_DEVICE_ID_AMD_1AH_M20H_DF_F4 0x16fc 48 - #define PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4 0x124c 49 - #define PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4 0x12bc 50 - #define PCI_DEVICE_ID_AMD_MI200_DF_F4 0x14d4 51 - #define PCI_DEVICE_ID_AMD_MI300_DF_F4 0x152c 52 - 53 - /* Protect the PCI config register pairs used for SMN. */ 54 - static DEFINE_MUTEX(smn_mutex); 55 - 56 18 static u32 *flush_words; 57 - 58 - static const struct pci_device_id amd_root_ids[] = { 59 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_ROOT) }, 60 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_ROOT) }, 61 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_ROOT) }, 62 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M60H_ROOT) }, 63 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_MA0H_ROOT) }, 64 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M10H_ROOT) }, 65 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M40H_ROOT) }, 66 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M60H_ROOT) }, 67 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M70H_ROOT) }, 68 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_ROOT) }, 69 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_ROOT) }, 70 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_ROOT) }, 71 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_ROOT) }, 72 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_ROOT) }, 73 - {} 74 - }; 75 - 76 - #define PCI_DEVICE_ID_AMD_CNB17H_F4 0x1704 77 19 78 20 static const struct pci_device_id amd_nb_misc_ids[] = { 79 21 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, ··· 26 84 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F3) }, 27 85 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) }, 28 86 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) }, 29 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) }, 30 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) }, 31 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) }, 32 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F3) }, 33 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_MA0H_DF_F3) }, 34 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) }, 35 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) }, 36 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_DF_F3) }, 37 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M10H_DF_F3) }, 38 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M40H_DF_F3) }, 39 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F3) }, 40 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M60H_DF_F3) }, 41 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M70H_DF_F3) }, 42 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) }, 43 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3) }, 44 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3) }, 45 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F3) }, 46 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F3) }, 47 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F3) }, 48 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_DF_F3) }, 49 - {} 50 - }; 51 - 52 - static const struct pci_device_id amd_nb_link_ids[] = { 53 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, 54 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F4) }, 55 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F4) }, 56 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) }, 57 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) }, 58 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) }, 59 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F4) }, 60 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F4) }, 61 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F4) }, 62 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F4) }, 63 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_MA0H_DF_F4) }, 64 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_DF_F4) }, 65 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M10H_DF_F4) }, 66 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M40H_DF_F4) }, 67 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F4) }, 68 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M60H_DF_F4) }, 69 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M70H_DF_F4) }, 70 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F4) }, 71 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) }, 72 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4) }, 73 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F4) }, 74 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4) }, 75 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4) }, 76 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F4) }, 77 - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_DF_F4) }, 78 - {} 79 - }; 80 - 81 - static const struct pci_device_id hygon_root_ids[] = { 82 - { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_ROOT) }, 83 - {} 84 - }; 85 - 86 - static const struct pci_device_id hygon_nb_misc_ids[] = { 87 - { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) }, 88 - {} 89 - }; 90 - 91 - static const struct pci_device_id hygon_nb_link_ids[] = { 92 - { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_DF_F4) }, 93 87 {} 94 88 }; 95 89 ··· 56 178 } 57 179 EXPORT_SYMBOL_GPL(node_to_amd_nb); 58 180 59 - static struct pci_dev *next_northbridge(struct pci_dev *dev, 60 - const struct pci_device_id *ids) 61 - { 62 - do { 63 - dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); 64 - if (!dev) 65 - break; 66 - } while (!pci_match_id(ids, dev)); 67 - return dev; 68 - } 69 - 70 - /* 71 - * SMN accesses may fail in ways that are difficult to detect here in the called 72 - * functions amd_smn_read() and amd_smn_write(). Therefore, callers must do 73 - * their own checking based on what behavior they expect. 74 - * 75 - * For SMN reads, the returned value may be zero if the register is Read-as-Zero. 76 - * Or it may be a "PCI Error Response", e.g. all 0xFFs. The "PCI Error Response" 77 - * can be checked here, and a proper error code can be returned. 78 - * 79 - * But the Read-as-Zero response cannot be verified here. A value of 0 may be 80 - * correct in some cases, so callers must check that this correct is for the 81 - * register/fields they need. 82 - * 83 - * For SMN writes, success can be determined through a "write and read back" 84 - * However, this is not robust when done here. 85 - * 86 - * Possible issues: 87 - * 88 - * 1) Bits that are "Write-1-to-Clear". In this case, the read value should 89 - * *not* match the write value. 90 - * 91 - * 2) Bits that are "Read-as-Zero"/"Writes-Ignored". This information cannot be 92 - * known here. 93 - * 94 - * 3) Bits that are "Reserved / Set to 1". Ditto above. 95 - * 96 - * Callers of amd_smn_write() should do the "write and read back" check 97 - * themselves, if needed. 98 - * 99 - * For #1, they can see if their target bits got cleared. 100 - * 101 - * For #2 and #3, they can check if their target bits got set as intended. 102 - * 103 - * This matches what is done for RDMSR/WRMSR. As long as there's no #GP, then 104 - * the operation is considered a success, and the caller does their own 105 - * checking. 106 - */ 107 - static int __amd_smn_rw(u16 node, u32 address, u32 *value, bool write) 108 - { 109 - struct pci_dev *root; 110 - int err = -ENODEV; 111 - 112 - if (node >= amd_northbridges.num) 113 - goto out; 114 - 115 - root = node_to_amd_nb(node)->root; 116 - if (!root) 117 - goto out; 118 - 119 - mutex_lock(&smn_mutex); 120 - 121 - err = pci_write_config_dword(root, 0x60, address); 122 - if (err) { 123 - pr_warn("Error programming SMN address 0x%x.\n", address); 124 - goto out_unlock; 125 - } 126 - 127 - err = (write ? pci_write_config_dword(root, 0x64, *value) 128 - : pci_read_config_dword(root, 0x64, value)); 129 - 130 - out_unlock: 131 - mutex_unlock(&smn_mutex); 132 - 133 - out: 134 - return err; 135 - } 136 - 137 - int __must_check amd_smn_read(u16 node, u32 address, u32 *value) 138 - { 139 - int err = __amd_smn_rw(node, address, value, false); 140 - 141 - if (PCI_POSSIBLE_ERROR(*value)) { 142 - err = -ENODEV; 143 - *value = 0; 144 - } 145 - 146 - return err; 147 - } 148 - EXPORT_SYMBOL_GPL(amd_smn_read); 149 - 150 - int __must_check amd_smn_write(u16 node, u32 address, u32 value) 151 - { 152 - return __amd_smn_rw(node, address, &value, true); 153 - } 154 - EXPORT_SYMBOL_GPL(amd_smn_write); 155 - 156 - 157 181 static int amd_cache_northbridges(void) 158 182 { 159 - const struct pci_device_id *misc_ids = amd_nb_misc_ids; 160 - const struct pci_device_id *link_ids = amd_nb_link_ids; 161 - const struct pci_device_id *root_ids = amd_root_ids; 162 - struct pci_dev *root, *misc, *link; 163 183 struct amd_northbridge *nb; 164 - u16 roots_per_misc = 0; 165 - u16 misc_count = 0; 166 - u16 root_count = 0; 167 - u16 i, j; 184 + u16 i; 168 185 169 186 if (amd_northbridges.num) 170 187 return 0; 171 188 172 - if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) { 173 - root_ids = hygon_root_ids; 174 - misc_ids = hygon_nb_misc_ids; 175 - link_ids = hygon_nb_link_ids; 176 - } 189 + amd_northbridges.num = amd_num_nodes(); 177 190 178 - misc = NULL; 179 - while ((misc = next_northbridge(misc, misc_ids))) 180 - misc_count++; 181 - 182 - if (!misc_count) 183 - return -ENODEV; 184 - 185 - root = NULL; 186 - while ((root = next_northbridge(root, root_ids))) 187 - root_count++; 188 - 189 - if (root_count) { 190 - roots_per_misc = root_count / misc_count; 191 - 192 - /* 193 - * There should be _exactly_ N roots for each DF/SMN 194 - * interface. 195 - */ 196 - if (!roots_per_misc || (root_count % roots_per_misc)) { 197 - pr_info("Unsupported AMD DF/PCI configuration found\n"); 198 - return -ENODEV; 199 - } 200 - } 201 - 202 - nb = kcalloc(misc_count, sizeof(struct amd_northbridge), GFP_KERNEL); 191 + nb = kcalloc(amd_northbridges.num, sizeof(struct amd_northbridge), GFP_KERNEL); 203 192 if (!nb) 204 193 return -ENOMEM; 205 194 206 195 amd_northbridges.nb = nb; 207 - amd_northbridges.num = misc_count; 208 196 209 - link = misc = root = NULL; 210 197 for (i = 0; i < amd_northbridges.num; i++) { 211 - node_to_amd_nb(i)->root = root = 212 - next_northbridge(root, root_ids); 213 - node_to_amd_nb(i)->misc = misc = 214 - next_northbridge(misc, misc_ids); 215 - node_to_amd_nb(i)->link = link = 216 - next_northbridge(link, link_ids); 198 + node_to_amd_nb(i)->root = amd_node_get_root(i); 199 + node_to_amd_nb(i)->misc = amd_node_get_func(i, 3); 217 200 218 201 /* 219 - * If there are more PCI root devices than data fabric/ 220 - * system management network interfaces, then the (N) 221 - * PCI roots per DF/SMN interface are functionally the 222 - * same (for DF/SMN access) and N-1 are redundant. N-1 223 - * PCI roots should be skipped per DF/SMN interface so 224 - * the following DF/SMN interfaces get mapped to 225 - * correct PCI roots. 202 + * Each Northbridge must have a 'misc' device. 203 + * If not, then uninitialize everything. 226 204 */ 227 - for (j = 1; j < roots_per_misc; j++) 228 - root = next_northbridge(root, root_ids); 205 + if (!node_to_amd_nb(i)->misc) { 206 + amd_northbridges.num = 0; 207 + kfree(nb); 208 + return -ENODEV; 209 + } 210 + 211 + node_to_amd_nb(i)->link = amd_node_get_func(i, 4); 229 212 } 230 213 231 214 if (amd_gart_present()) ··· 124 385 */ 125 386 bool __init early_is_amd_nb(u32 device) 126 387 { 127 - const struct pci_device_id *misc_ids = amd_nb_misc_ids; 128 388 const struct pci_device_id *id; 129 389 u32 vendor = device & 0xffff; 130 390 ··· 131 393 boot_cpu_data.x86_vendor != X86_VENDOR_HYGON) 132 394 return false; 133 395 134 - if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) 135 - misc_ids = hygon_nb_misc_ids; 396 + if (cpu_feature_enabled(X86_FEATURE_ZEN)) 397 + return false; 136 398 137 399 device >>= 16; 138 - for (id = misc_ids; id->vendor; id++) 400 + for (id = amd_nb_misc_ids; id->vendor; id++) 139 401 if (vendor == id->vendor && device == id->device) 140 402 return true; 141 403 return false; ··· 320 582 321 583 static __init int init_amd_nbs(void) 322 584 { 585 + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD && 586 + boot_cpu_data.x86_vendor != X86_VENDOR_HYGON) 587 + return 0; 588 + 323 589 amd_cache_northbridges(); 324 590 amd_cache_gart(); 325 591
+215
arch/x86/kernel/amd_node.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * AMD Node helper functions and common defines 4 + * 5 + * Copyright (c) 2024, Advanced Micro Devices, Inc. 6 + * All Rights Reserved. 7 + * 8 + * Author: Yazen Ghannam <Yazen.Ghannam@amd.com> 9 + */ 10 + 11 + #include <asm/amd_node.h> 12 + 13 + /* 14 + * AMD Nodes are a physical collection of I/O devices within an SoC. There can be one 15 + * or more nodes per package. 16 + * 17 + * The nodes are software-visible through PCI config space. All nodes are enumerated 18 + * on segment 0 bus 0. The device (slot) numbers range from 0x18 to 0x1F (maximum 8 19 + * nodes) with 0x18 corresponding to node 0, 0x19 to node 1, etc. Each node can be a 20 + * multi-function device. 21 + * 22 + * On legacy systems, these node devices represent integrated Northbridge functionality. 23 + * On Zen-based systems, these node devices represent Data Fabric functionality. 24 + * 25 + * See "Configuration Space Accesses" section in BKDGs or 26 + * "Processor x86 Core" -> "Configuration Space" section in PPRs. 27 + */ 28 + struct pci_dev *amd_node_get_func(u16 node, u8 func) 29 + { 30 + if (node >= MAX_AMD_NUM_NODES) 31 + return NULL; 32 + 33 + return pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(AMD_NODE0_PCI_SLOT + node, func)); 34 + } 35 + 36 + #define DF_BLK_INST_CNT 0x040 37 + #define DF_CFG_ADDR_CNTL_LEGACY 0x084 38 + #define DF_CFG_ADDR_CNTL_DF4 0xC04 39 + 40 + #define DF_MAJOR_REVISION GENMASK(27, 24) 41 + 42 + static u16 get_cfg_addr_cntl_offset(struct pci_dev *df_f0) 43 + { 44 + u32 reg; 45 + 46 + /* 47 + * Revision fields added for DF4 and later. 48 + * 49 + * Major revision of '0' is found pre-DF4. Field is Read-as-Zero. 50 + */ 51 + if (pci_read_config_dword(df_f0, DF_BLK_INST_CNT, &reg)) 52 + return 0; 53 + 54 + if (reg & DF_MAJOR_REVISION) 55 + return DF_CFG_ADDR_CNTL_DF4; 56 + 57 + return DF_CFG_ADDR_CNTL_LEGACY; 58 + } 59 + 60 + struct pci_dev *amd_node_get_root(u16 node) 61 + { 62 + struct pci_dev *root; 63 + u16 cntl_off; 64 + u8 bus; 65 + 66 + if (!cpu_feature_enabled(X86_FEATURE_ZEN)) 67 + return NULL; 68 + 69 + /* 70 + * D18F0xXXX [Config Address Control] (DF::CfgAddressCntl) 71 + * Bits [7:0] (SecBusNum) holds the bus number of the root device for 72 + * this Data Fabric instance. The segment, device, and function will be 0. 73 + */ 74 + struct pci_dev *df_f0 __free(pci_dev_put) = amd_node_get_func(node, 0); 75 + if (!df_f0) 76 + return NULL; 77 + 78 + cntl_off = get_cfg_addr_cntl_offset(df_f0); 79 + if (!cntl_off) 80 + return NULL; 81 + 82 + if (pci_read_config_byte(df_f0, cntl_off, &bus)) 83 + return NULL; 84 + 85 + /* Grab the pointer for the actual root device instance. */ 86 + root = pci_get_domain_bus_and_slot(0, bus, 0); 87 + 88 + pci_dbg(root, "is root for AMD node %u\n", node); 89 + return root; 90 + } 91 + 92 + static struct pci_dev **amd_roots; 93 + 94 + /* Protect the PCI config register pairs used for SMN. */ 95 + static DEFINE_MUTEX(smn_mutex); 96 + 97 + #define SMN_INDEX_OFFSET 0x60 98 + #define SMN_DATA_OFFSET 0x64 99 + 100 + /* 101 + * SMN accesses may fail in ways that are difficult to detect here in the called 102 + * functions amd_smn_read() and amd_smn_write(). Therefore, callers must do 103 + * their own checking based on what behavior they expect. 104 + * 105 + * For SMN reads, the returned value may be zero if the register is Read-as-Zero. 106 + * Or it may be a "PCI Error Response", e.g. all 0xFFs. The "PCI Error Response" 107 + * can be checked here, and a proper error code can be returned. 108 + * 109 + * But the Read-as-Zero response cannot be verified here. A value of 0 may be 110 + * correct in some cases, so callers must check that this correct is for the 111 + * register/fields they need. 112 + * 113 + * For SMN writes, success can be determined through a "write and read back" 114 + * However, this is not robust when done here. 115 + * 116 + * Possible issues: 117 + * 118 + * 1) Bits that are "Write-1-to-Clear". In this case, the read value should 119 + * *not* match the write value. 120 + * 121 + * 2) Bits that are "Read-as-Zero"/"Writes-Ignored". This information cannot be 122 + * known here. 123 + * 124 + * 3) Bits that are "Reserved / Set to 1". Ditto above. 125 + * 126 + * Callers of amd_smn_write() should do the "write and read back" check 127 + * themselves, if needed. 128 + * 129 + * For #1, they can see if their target bits got cleared. 130 + * 131 + * For #2 and #3, they can check if their target bits got set as intended. 132 + * 133 + * This matches what is done for RDMSR/WRMSR. As long as there's no #GP, then 134 + * the operation is considered a success, and the caller does their own 135 + * checking. 136 + */ 137 + static int __amd_smn_rw(u8 i_off, u8 d_off, u16 node, u32 address, u32 *value, bool write) 138 + { 139 + struct pci_dev *root; 140 + int err = -ENODEV; 141 + 142 + if (node >= amd_num_nodes()) 143 + return err; 144 + 145 + root = amd_roots[node]; 146 + if (!root) 147 + return err; 148 + 149 + guard(mutex)(&smn_mutex); 150 + 151 + err = pci_write_config_dword(root, i_off, address); 152 + if (err) { 153 + pr_warn("Error programming SMN address 0x%x.\n", address); 154 + return pcibios_err_to_errno(err); 155 + } 156 + 157 + err = (write ? pci_write_config_dword(root, d_off, *value) 158 + : pci_read_config_dword(root, d_off, value)); 159 + 160 + return pcibios_err_to_errno(err); 161 + } 162 + 163 + int __must_check amd_smn_read(u16 node, u32 address, u32 *value) 164 + { 165 + int err = __amd_smn_rw(SMN_INDEX_OFFSET, SMN_DATA_OFFSET, node, address, value, false); 166 + 167 + if (PCI_POSSIBLE_ERROR(*value)) { 168 + err = -ENODEV; 169 + *value = 0; 170 + } 171 + 172 + return err; 173 + } 174 + EXPORT_SYMBOL_GPL(amd_smn_read); 175 + 176 + int __must_check amd_smn_write(u16 node, u32 address, u32 value) 177 + { 178 + return __amd_smn_rw(SMN_INDEX_OFFSET, SMN_DATA_OFFSET, node, address, &value, true); 179 + } 180 + EXPORT_SYMBOL_GPL(amd_smn_write); 181 + 182 + static int amd_cache_roots(void) 183 + { 184 + u16 node, num_nodes = amd_num_nodes(); 185 + 186 + amd_roots = kcalloc(num_nodes, sizeof(*amd_roots), GFP_KERNEL); 187 + if (!amd_roots) 188 + return -ENOMEM; 189 + 190 + for (node = 0; node < num_nodes; node++) 191 + amd_roots[node] = amd_node_get_root(node); 192 + 193 + return 0; 194 + } 195 + 196 + static int __init amd_smn_init(void) 197 + { 198 + int err; 199 + 200 + if (!cpu_feature_enabled(X86_FEATURE_ZEN)) 201 + return 0; 202 + 203 + guard(mutex)(&smn_mutex); 204 + 205 + if (amd_roots) 206 + return 0; 207 + 208 + err = amd_cache_roots(); 209 + if (err) 210 + return err; 211 + 212 + return 0; 213 + } 214 + 215 + fs_initcall(amd_smn_init);
+3 -3
arch/x86/kernel/cpu/mtrr/generic.c
··· 423 423 } 424 424 425 425 /** 426 - * mtrr_overwrite_state - set static MTRR state 426 + * guest_force_mtrr_state - set static MTRR state for a guest 427 427 * 428 428 * Used to set MTRR state via different means (e.g. with data obtained from 429 429 * a hypervisor). ··· 436 436 * @num_var: length of the @var array 437 437 * @def_type: default caching type 438 438 */ 439 - void mtrr_overwrite_state(struct mtrr_var_range *var, unsigned int num_var, 440 - mtrr_type def_type) 439 + void guest_force_mtrr_state(struct mtrr_var_range *var, unsigned int num_var, 440 + mtrr_type def_type) 441 441 { 442 442 unsigned int i; 443 443
+1 -1
arch/x86/kernel/cpu/mtrr/mtrr.c
··· 625 625 static int __init mtrr_init_finalize(void) 626 626 { 627 627 /* 628 - * Map might exist if mtrr_overwrite_state() has been called or if 628 + * Map might exist if guest_force_mtrr_state() has been called or if 629 629 * mtrr_enabled() returns true. 630 630 */ 631 631 mtrr_copy_map();
+1 -1
arch/x86/kernel/kvm.c
··· 983 983 x86_platform.apic_post_init = kvm_apic_init; 984 984 985 985 /* Set WB as the default cache mode for SEV-SNP and TDX */ 986 - mtrr_overwrite_state(NULL, 0, MTRR_TYPE_WRBACK); 986 + guest_force_mtrr_state(NULL, 0, MTRR_TYPE_WRBACK); 987 987 } 988 988 989 989 #if defined(CONFIG_AMD_MEM_ENCRYPT)
+2 -2
arch/x86/pci/fixup.c
··· 9 9 #include <linux/pci.h> 10 10 #include <linux/suspend.h> 11 11 #include <linux/vgaarb.h> 12 - #include <asm/amd_nb.h> 12 + #include <asm/amd_node.h> 13 13 #include <asm/hpet.h> 14 14 #include <asm/pci_x86.h> 15 15 ··· 828 828 829 829 #endif 830 830 831 - #ifdef CONFIG_AMD_NB 831 + #ifdef CONFIG_AMD_NODE 832 832 833 833 #define AMD_15B8_RCC_DEV2_EPF0_STRAP2 0x10136008 834 834 #define AMD_15B8_RCC_DEV2_EPF0_STRAP2_NO_SOFT_RESET_DEV2_F0_MASK 0x00000080L
+2 -2
arch/x86/xen/enlighten_pv.c
··· 172 172 173 173 /* Only overwrite MTRR state if any MTRR could be got from Xen. */ 174 174 if (reg) 175 - mtrr_overwrite_state(var, reg, MTRR_TYPE_UNCACHABLE); 175 + guest_force_mtrr_state(var, reg, MTRR_TYPE_UNCACHABLE); 176 176 #endif 177 177 } 178 178 ··· 196 196 if (xen_initial_domain()) 197 197 xen_set_mtrr_data(); 198 198 else 199 - mtrr_overwrite_state(NULL, 0, MTRR_TYPE_WRBACK); 199 + guest_force_mtrr_state(NULL, 0, MTRR_TYPE_WRBACK); 200 200 201 201 /* Adjust nr_cpu_ids before "enumeration" happens */ 202 202 xen_smp_count_cpus();
+1
drivers/edac/Kconfig
··· 78 78 config EDAC_AMD64 79 79 tristate "AMD64 (Opteron, Athlon64)" 80 80 depends on AMD_NB && EDAC_DECODE_MCE 81 + depends on AMD_NODE 81 82 imply AMD_ATL 82 83 help 83 84 Support for error detection and correction of DRAM ECC errors on
+1
drivers/edac/amd64_edac.c
··· 2 2 #include <linux/ras.h> 3 3 #include "amd64_edac.h" 4 4 #include <asm/amd_nb.h> 5 + #include <asm/amd_node.h> 5 6 6 7 static struct edac_pci_ctl_info *pci_ctl; 7 8
+1 -1
drivers/hwmon/Kconfig
··· 324 324 325 325 config SENSORS_K10TEMP 326 326 tristate "AMD Family 10h+ temperature sensor" 327 - depends on X86 && PCI && AMD_NB 327 + depends on X86 && PCI && AMD_NODE 328 328 help 329 329 If you say yes here you get support for the temperature 330 330 sensor(s) inside your CPU. Supported are later revisions of
+6 -1
drivers/hwmon/k10temp.c
··· 20 20 #include <linux/module.h> 21 21 #include <linux/pci.h> 22 22 #include <linux/pci_ids.h> 23 - #include <asm/amd_nb.h> 23 + #include <asm/amd_node.h> 24 24 #include <asm/processor.h> 25 25 26 26 MODULE_DESCRIPTION("AMD Family 10h+ CPU core temperature monitor"); ··· 148 148 { 149 149 amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8, 150 150 F15H_M60H_REPORTED_TEMP_CTRL_OFFSET, regval); 151 + } 152 + 153 + static u16 amd_pci_dev_to_node_id(struct pci_dev *pdev) 154 + { 155 + return PCI_SLOT(pdev->devfn) - AMD_NODE0_PCI_SLOT; 151 156 } 152 157 153 158 static void read_tempreg_nb_zen(struct pci_dev *pdev, u32 *regval)
+1 -1
drivers/platform/x86/amd/pmc/Kconfig
··· 5 5 6 6 config AMD_PMC 7 7 tristate "AMD SoC PMC driver" 8 - depends on ACPI && PCI && RTC_CLASS && AMD_NB 8 + depends on ACPI && PCI && RTC_CLASS && AMD_NODE 9 9 depends on SUSPEND 10 10 select SERIO 11 11 help
+2 -1
drivers/platform/x86/amd/pmc/pmc.c
··· 10 10 11 11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 12 12 13 - #include <asm/amd_nb.h> 14 13 #include <linux/acpi.h> 15 14 #include <linux/bitfield.h> 16 15 #include <linux/bits.h> ··· 26 27 #include <linux/suspend.h> 27 28 #include <linux/seq_file.h> 28 29 #include <linux/uaccess.h> 30 + 31 + #include <asm/amd_node.h> 29 32 30 33 #include "pmc.h" 31 34
+1 -1
drivers/platform/x86/amd/pmf/Kconfig
··· 7 7 tristate "AMD Platform Management Framework" 8 8 depends on ACPI && PCI 9 9 depends on POWER_SUPPLY 10 - depends on AMD_NB 10 + depends on AMD_NODE 11 11 select ACPI_PLATFORM_PROFILE 12 12 depends on TEE && AMDTEE 13 13 depends on AMD_SFH_HID
+1 -1
drivers/platform/x86/amd/pmf/core.c
··· 8 8 * Author: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> 9 9 */ 10 10 11 - #include <asm/amd_nb.h> 12 11 #include <linux/debugfs.h> 13 12 #include <linux/iopoll.h> 14 13 #include <linux/module.h> 15 14 #include <linux/pci.h> 16 15 #include <linux/platform_device.h> 17 16 #include <linux/power_supply.h> 17 + #include <asm/amd_node.h> 18 18 #include "pmf.h" 19 19 20 20 /* PMF-SMU communication registers */
+1
drivers/ras/amd/atl/Kconfig
··· 10 10 config AMD_ATL 11 11 tristate "AMD Address Translation Library" 12 12 depends on AMD_NB && X86_64 && RAS 13 + depends on AMD_NODE 13 14 depends on MEMORY_FAILURE 14 15 default N 15 16 help
+1
drivers/ras/amd/atl/internal.h
··· 18 18 #include <linux/ras.h> 19 19 20 20 #include <asm/amd_nb.h> 21 + #include <asm/amd_node.h> 21 22 22 23 #include "reg_fields.h" 23 24