Skip to content

Commit 77a4ae2

Browse files
committed
x86/amd_node: Add support for debugfs access to SMN registers
JIRA: https://issues.redhat.com/browse/RHEL-127821 commit 9c19cc1 Author: Mario Limonciello <mario.limonciello@amd.com> Date: Thu Jan 30 19:48:57 2025 +0000 x86/amd_node: Add support for debugfs access to SMN registers There are certain registers on AMD Zen systems that can only be accessed through SMN. Introduce a new interface that provides debugfs files for accessing SMN. As this introduces the capability for userspace to manipulate the hardware in unpredictable ways, taint the kernel when writing. Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20250130-wip-x86-amd-nb-cleanup-v4-3-b5cc997e471b@amd.com (cherry picked from commit 9c19cc1) Assisted-by: Patchpal Signed-off-by: David Arcari <darcari@redhat.com>
1 parent b0b8e0c commit 77a4ae2

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

arch/x86/kernel/amd_node.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* Author: Yazen Ghannam <Yazen.Ghannam@amd.com>
99
*/
1010

11+
#include <linux/debugfs.h>
1112
#include <asm/amd/node.h>
1213

1314
/*
@@ -192,6 +193,87 @@ int __must_check amd_smn_hsmp_rdwr(u16 node, u32 address, u32 *value, bool write
192193
}
193194
EXPORT_SYMBOL_GPL(amd_smn_hsmp_rdwr);
194195

196+
static struct dentry *debugfs_dir;
197+
static u16 debug_node;
198+
static u32 debug_address;
199+
200+
static ssize_t smn_node_write(struct file *file, const char __user *userbuf,
201+
size_t count, loff_t *ppos)
202+
{
203+
u16 node;
204+
int ret;
205+
206+
ret = kstrtou16_from_user(userbuf, count, 0, &node);
207+
if (ret)
208+
return ret;
209+
210+
if (node >= amd_num_nodes())
211+
return -ENODEV;
212+
213+
debug_node = node;
214+
return count;
215+
}
216+
217+
static int smn_node_show(struct seq_file *m, void *v)
218+
{
219+
seq_printf(m, "0x%08x\n", debug_node);
220+
return 0;
221+
}
222+
223+
static ssize_t smn_address_write(struct file *file, const char __user *userbuf,
224+
size_t count, loff_t *ppos)
225+
{
226+
int ret;
227+
228+
ret = kstrtouint_from_user(userbuf, count, 0, &debug_address);
229+
if (ret)
230+
return ret;
231+
232+
return count;
233+
}
234+
235+
static int smn_address_show(struct seq_file *m, void *v)
236+
{
237+
seq_printf(m, "0x%08x\n", debug_address);
238+
return 0;
239+
}
240+
241+
static int smn_value_show(struct seq_file *m, void *v)
242+
{
243+
u32 val;
244+
int ret;
245+
246+
ret = amd_smn_read(debug_node, debug_address, &val);
247+
if (ret)
248+
return ret;
249+
250+
seq_printf(m, "0x%08x\n", val);
251+
return 0;
252+
}
253+
254+
static ssize_t smn_value_write(struct file *file, const char __user *userbuf,
255+
size_t count, loff_t *ppos)
256+
{
257+
u32 val;
258+
int ret;
259+
260+
ret = kstrtouint_from_user(userbuf, count, 0, &val);
261+
if (ret)
262+
return ret;
263+
264+
add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
265+
266+
ret = amd_smn_write(debug_node, debug_address, val);
267+
if (ret)
268+
return ret;
269+
270+
return count;
271+
}
272+
273+
DEFINE_SHOW_STORE_ATTRIBUTE(smn_node);
274+
DEFINE_SHOW_STORE_ATTRIBUTE(smn_address);
275+
DEFINE_SHOW_STORE_ATTRIBUTE(smn_value);
276+
195277
static int amd_cache_roots(void)
196278
{
197279
u16 node, num_nodes = amd_num_nodes();
@@ -239,6 +321,15 @@ static int reserve_root_config_spaces(void)
239321
return 0;
240322
}
241323

324+
static bool enable_dfs;
325+
326+
static int __init amd_smn_enable_dfs(char *str)
327+
{
328+
enable_dfs = true;
329+
return 1;
330+
}
331+
__setup("amd_smn_debugfs_enable", amd_smn_enable_dfs);
332+
242333
static int __init amd_smn_init(void)
243334
{
244335
int err;
@@ -259,6 +350,14 @@ static int __init amd_smn_init(void)
259350
if (err)
260351
return err;
261352

353+
if (enable_dfs) {
354+
debugfs_dir = debugfs_create_dir("amd_smn", arch_debugfs_dir);
355+
356+
debugfs_create_file("node", 0600, debugfs_dir, NULL, &smn_node_fops);
357+
debugfs_create_file("address", 0600, debugfs_dir, NULL, &smn_address_fops);
358+
debugfs_create_file("value", 0600, debugfs_dir, NULL, &smn_value_fops);
359+
}
360+
262361
return 0;
263362
}
264363

0 commit comments

Comments
 (0)