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 <linux/debugfs.h> 12 #include <asm/amd/node.h> 13 14 /* 15 * AMD Nodes are a physical collection of I/O devices within an SoC. There can be one 16 * or more nodes per package. 17 * 18 * The nodes are software-visible through PCI config space. All nodes are enumerated 19 * on segment 0 bus 0. The device (slot) numbers range from 0x18 to 0x1F (maximum 8 20 * nodes) with 0x18 corresponding to node 0, 0x19 to node 1, etc. Each node can be a 21 * multi-function device. 22 * 23 * On legacy systems, these node devices represent integrated Northbridge functionality. 24 * On Zen-based systems, these node devices represent Data Fabric functionality. 25 * 26 * See "Configuration Space Accesses" section in BKDGs or 27 * "Processor x86 Core" -> "Configuration Space" section in PPRs. 28 */ 29 struct pci_dev *amd_node_get_func(u16 node, u8 func) 30 { 31 if (node >= MAX_AMD_NUM_NODES) 32 return NULL; 33 34 return pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(AMD_NODE0_PCI_SLOT + node, func)); 35 } 36 37 static struct pci_dev **amd_roots; 38 39 /* Protect the PCI config register pairs used for SMN. */ 40 static DEFINE_MUTEX(smn_mutex); 41 42 #define SMN_INDEX_OFFSET 0x60 43 #define SMN_DATA_OFFSET 0x64 44 45 #define HSMP_INDEX_OFFSET 0xc4 46 #define HSMP_DATA_OFFSET 0xc8 47 48 /* 49 * SMN accesses may fail in ways that are difficult to detect here in the called 50 * functions amd_smn_read() and amd_smn_write(). Therefore, callers must do 51 * their own checking based on what behavior they expect. 52 * 53 * For SMN reads, the returned value may be zero if the register is Read-as-Zero. 54 * Or it may be a "PCI Error Response", e.g. all 0xFFs. The "PCI Error Response" 55 * can be checked here, and a proper error code can be returned. 56 * 57 * But the Read-as-Zero response cannot be verified here. A value of 0 may be 58 * correct in some cases, so callers must check that this correct is for the 59 * register/fields they need. 60 * 61 * For SMN writes, success can be determined through a "write and read back" 62 * However, this is not robust when done here. 63 * 64 * Possible issues: 65 * 66 * 1) Bits that are "Write-1-to-Clear". In this case, the read value should 67 * *not* match the write value. 68 * 69 * 2) Bits that are "Read-as-Zero"/"Writes-Ignored". This information cannot be 70 * known here. 71 * 72 * 3) Bits that are "Reserved / Set to 1". Ditto above. 73 * 74 * Callers of amd_smn_write() should do the "write and read back" check 75 * themselves, if needed. 76 * 77 * For #1, they can see if their target bits got cleared. 78 * 79 * For #2 and #3, they can check if their target bits got set as intended. 80 * 81 * This matches what is done for RDMSR/WRMSR. As long as there's no #GP, then 82 * the operation is considered a success, and the caller does their own 83 * checking. 84 */ 85 static int __amd_smn_rw(u8 i_off, u8 d_off, u16 node, u32 address, u32 *value, bool write) 86 { 87 struct pci_dev *root; 88 int err = -ENODEV; 89 90 if (node >= amd_num_nodes()) 91 return err; 92 93 /* 94 * Uninitialized amd_roots indicates pci_request_config_region_exclusive() 95 * didn't run or failed and thus the kernel cannot rely on having 96 * exclusive access to SMN registers so prevent that. 97 */ 98 if (!amd_roots) 99 return err; 100 101 root = amd_roots[node]; 102 if (!root) 103 return err; 104 105 guard(mutex)(&smn_mutex); 106 107 err = pci_write_config_dword(root, i_off, address); 108 if (err) { 109 pr_warn("Error programming SMN address 0x%x.\n", address); 110 return pcibios_err_to_errno(err); 111 } 112 113 err = (write ? pci_write_config_dword(root, d_off, *value) 114 : pci_read_config_dword(root, d_off, value)); 115 116 return pcibios_err_to_errno(err); 117 } 118 119 int __must_check amd_smn_read(u16 node, u32 address, u32 *value) 120 { 121 int err = __amd_smn_rw(SMN_INDEX_OFFSET, SMN_DATA_OFFSET, node, address, value, false); 122 123 if (PCI_POSSIBLE_ERROR(*value)) { 124 err = -ENODEV; 125 *value = 0; 126 } 127 128 return err; 129 } 130 EXPORT_SYMBOL_GPL(amd_smn_read); 131 132 int __must_check amd_smn_write(u16 node, u32 address, u32 value) 133 { 134 return __amd_smn_rw(SMN_INDEX_OFFSET, SMN_DATA_OFFSET, node, address, &value, true); 135 } 136 EXPORT_SYMBOL_GPL(amd_smn_write); 137 138 int __must_check amd_smn_hsmp_rdwr(u16 node, u32 address, u32 *value, bool write) 139 { 140 return __amd_smn_rw(HSMP_INDEX_OFFSET, HSMP_DATA_OFFSET, node, address, value, write); 141 } 142 EXPORT_SYMBOL_GPL(amd_smn_hsmp_rdwr); 143 144 static struct dentry *debugfs_dir; 145 static u16 debug_node; 146 static u32 debug_address; 147 148 static ssize_t smn_node_write(struct file *file, const char __user *userbuf, 149 size_t count, loff_t *ppos) 150 { 151 u16 node; 152 int ret; 153 154 ret = kstrtou16_from_user(userbuf, count, 0, &node); 155 if (ret) 156 return ret; 157 158 if (node >= amd_num_nodes()) 159 return -ENODEV; 160 161 debug_node = node; 162 return count; 163 } 164 165 static int smn_node_show(struct seq_file *m, void *v) 166 { 167 seq_printf(m, "0x%08x\n", debug_node); 168 return 0; 169 } 170 171 static ssize_t smn_address_write(struct file *file, const char __user *userbuf, 172 size_t count, loff_t *ppos) 173 { 174 int ret; 175 176 ret = kstrtouint_from_user(userbuf, count, 0, &debug_address); 177 if (ret) 178 return ret; 179 180 return count; 181 } 182 183 static int smn_address_show(struct seq_file *m, void *v) 184 { 185 seq_printf(m, "0x%08x\n", debug_address); 186 return 0; 187 } 188 189 static int smn_value_show(struct seq_file *m, void *v) 190 { 191 u32 val; 192 int ret; 193 194 ret = amd_smn_read(debug_node, debug_address, &val); 195 if (ret) 196 return ret; 197 198 seq_printf(m, "0x%08x\n", val); 199 return 0; 200 } 201 202 static ssize_t smn_value_write(struct file *file, const char __user *userbuf, 203 size_t count, loff_t *ppos) 204 { 205 u32 val; 206 int ret; 207 208 ret = kstrtouint_from_user(userbuf, count, 0, &val); 209 if (ret) 210 return ret; 211 212 add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK); 213 214 ret = amd_smn_write(debug_node, debug_address, val); 215 if (ret) 216 return ret; 217 218 return count; 219 } 220 221 DEFINE_SHOW_STORE_ATTRIBUTE(smn_node); 222 DEFINE_SHOW_STORE_ATTRIBUTE(smn_address); 223 DEFINE_SHOW_STORE_ATTRIBUTE(smn_value); 224 225 static struct pci_dev *get_next_root(struct pci_dev *root) 226 { 227 while ((root = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, root))) { 228 /* Root device is Device 0 Function 0. */ 229 if (root->devfn) 230 continue; 231 232 if (root->vendor != PCI_VENDOR_ID_AMD && 233 root->vendor != PCI_VENDOR_ID_HYGON) 234 continue; 235 236 break; 237 } 238 239 return root; 240 } 241 242 static bool enable_dfs; 243 244 static int __init amd_smn_enable_dfs(char *str) 245 { 246 enable_dfs = true; 247 return 1; 248 } 249 __setup("amd_smn_debugfs_enable", amd_smn_enable_dfs); 250 251 static int __init amd_smn_init(void) 252 { 253 u16 count, num_roots, roots_per_node, node, num_nodes; 254 struct pci_dev *root __free(pci_dev_put) = NULL; 255 256 if (!cpu_feature_enabled(X86_FEATURE_ZEN)) 257 return 0; 258 259 guard(mutex)(&smn_mutex); 260 261 if (amd_roots) 262 return 0; 263 264 num_roots = 0; 265 while ((root = get_next_root(root))) { 266 pci_dbg(root, "Reserving PCI config space\n"); 267 268 /* 269 * There are a few SMN index/data pairs and other registers 270 * that shouldn't be accessed by user space. So reserve the 271 * entire PCI config space for simplicity rather than covering 272 * specific registers piecemeal. 273 */ 274 if (!pci_request_config_region_exclusive(root, 0, PCI_CFG_SPACE_SIZE, NULL)) { 275 pci_err(root, "Failed to reserve config space\n"); 276 return -EEXIST; 277 } 278 279 num_roots++; 280 } 281 282 pr_debug("Found %d AMD root devices\n", num_roots); 283 284 if (!num_roots) 285 return -ENODEV; 286 287 num_nodes = amd_num_nodes(); 288 amd_roots = kzalloc_objs(*amd_roots, num_nodes); 289 if (!amd_roots) 290 return -ENOMEM; 291 292 roots_per_node = num_roots / num_nodes; 293 if (!roots_per_node) { 294 if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) 295 pr_warn(FW_BUG "Error detecting roots per node.\n"); 296 roots_per_node = 1; 297 } 298 299 count = 0; 300 node = 0; 301 while (node < num_nodes && (root = get_next_root(root))) { 302 /* Use one root for each node and skip the rest. */ 303 if (count++ % roots_per_node) 304 continue; 305 306 pci_dbg(root, "is root for AMD node %u\n", node); 307 amd_roots[node++] = pci_dev_get(root); 308 } 309 310 if (enable_dfs) { 311 debugfs_dir = debugfs_create_dir("amd_smn", arch_debugfs_dir); 312 313 debugfs_create_file("node", 0600, debugfs_dir, NULL, &smn_node_fops); 314 debugfs_create_file("address", 0600, debugfs_dir, NULL, &smn_address_fops); 315 debugfs_create_file("value", 0600, debugfs_dir, NULL, &smn_value_fops); 316 } 317 318 return 0; 319 } 320 321 fs_initcall(amd_smn_init); 322