mirror of
https://github.com/torvalds/linux.git
synced 2026-05-29 17:43:52 +02:00
powerpc/pseries: Export hardware trace macro dump via debugfs
This patch adds debugfs interface to export Hardware Trace Macro (HTM) function data in a LPAR. New hypervisor call "H_HTM" has been defined to setup, configure, control and dump the HTM data. This patch supports only dumping of HTM data in a LPAR. New debugfs folder called "htmdump" has been added under /sys/kernel/debug/arch path which contains files need to pass required parameters for the H_HTM dump function. New Kconfig option called "CONFIG_HTMDUMP" is added in platform/pseries for the same. With this module loaded, list of files in debugfs path /sys/kernel/debug/powerpc/htmdump coreindexonchip htmtype nodalchipindex nodeindex trace Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com> Co-developed-by: Madhavan Srinivasan <maddy@linux.ibm.com> Reviewed-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com> Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com> Link: https://patch.msgid.link/20250113164039.302017-2-adubey@linux.ibm.com
This commit is contained in:
parent
708220ae50
commit
81c3d637c3
|
|
@ -128,6 +128,15 @@ config CMM
|
|||
will be reused for other LPARs. The interface allows firmware to
|
||||
balance memory across many LPARs.
|
||||
|
||||
config HTMDUMP
|
||||
tristate "PowerVM data dumper"
|
||||
depends on PPC_PSERIES && DEBUG_FS
|
||||
default m
|
||||
help
|
||||
Select this option, if you want to enable the kernel debugfs
|
||||
interface to dump the Hardware Trace Macro (HTM) function data
|
||||
in the LPAR.
|
||||
|
||||
config HV_PERF_CTRS
|
||||
bool "Hypervisor supplied PMU events (24x7 & GPCI)"
|
||||
default y
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
|
|||
obj-$(CONFIG_HVCS) += hvcserver.o
|
||||
obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o
|
||||
obj-$(CONFIG_CMM) += cmm.o
|
||||
obj-$(CONFIG_HTMDUMP) += htmdump.o
|
||||
obj-$(CONFIG_IO_EVENT_IRQ) += io_event_irq.o
|
||||
obj-$(CONFIG_LPARCFG) += lparcfg.o
|
||||
obj-$(CONFIG_IBMVIO) += vio.o
|
||||
|
|
|
|||
121
arch/powerpc/platforms/pseries/htmdump.c
Normal file
121
arch/powerpc/platforms/pseries/htmdump.c
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) IBM Corporation, 2024
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "htmdump: " fmt
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/plpar_wrappers.h>
|
||||
|
||||
static void *htm_buf;
|
||||
static u32 nodeindex;
|
||||
static u32 nodalchipindex;
|
||||
static u32 coreindexonchip;
|
||||
static u32 htmtype;
|
||||
static struct dentry *htmdump_debugfs_dir;
|
||||
|
||||
static ssize_t htmdump_read(struct file *filp, char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
void *htm_buf = filp->private_data;
|
||||
unsigned long page, read_size, available;
|
||||
loff_t offset;
|
||||
long rc;
|
||||
|
||||
page = ALIGN_DOWN(*ppos, PAGE_SIZE);
|
||||
offset = (*ppos) % PAGE_SIZE;
|
||||
|
||||
rc = htm_get_dump_hardware(nodeindex, nodalchipindex, coreindexonchip,
|
||||
htmtype, virt_to_phys(htm_buf), PAGE_SIZE, page);
|
||||
|
||||
switch (rc) {
|
||||
case H_SUCCESS:
|
||||
/* H_PARTIAL for the case where all available data can't be
|
||||
* returned due to buffer size constraint.
|
||||
*/
|
||||
case H_PARTIAL:
|
||||
break;
|
||||
/* H_NOT_AVAILABLE indicates reading from an offset outside the range,
|
||||
* i.e. past end of file.
|
||||
*/
|
||||
case H_NOT_AVAILABLE:
|
||||
return 0;
|
||||
case H_BUSY:
|
||||
case H_LONG_BUSY_ORDER_1_MSEC:
|
||||
case H_LONG_BUSY_ORDER_10_MSEC:
|
||||
case H_LONG_BUSY_ORDER_100_MSEC:
|
||||
case H_LONG_BUSY_ORDER_1_SEC:
|
||||
case H_LONG_BUSY_ORDER_10_SEC:
|
||||
case H_LONG_BUSY_ORDER_100_SEC:
|
||||
return -EBUSY;
|
||||
case H_PARAMETER:
|
||||
case H_P2:
|
||||
case H_P3:
|
||||
case H_P4:
|
||||
case H_P5:
|
||||
case H_P6:
|
||||
return -EINVAL;
|
||||
case H_STATE:
|
||||
return -EIO;
|
||||
case H_AUTHORITY:
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
available = PAGE_SIZE;
|
||||
read_size = min(count, available);
|
||||
*ppos += read_size;
|
||||
return simple_read_from_buffer(ubuf, count, &offset, htm_buf, available);
|
||||
}
|
||||
|
||||
static const struct file_operations htmdump_fops = {
|
||||
.llseek = NULL,
|
||||
.read = htmdump_read,
|
||||
.open = simple_open,
|
||||
};
|
||||
|
||||
static int htmdump_init_debugfs(void)
|
||||
{
|
||||
htm_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!htm_buf) {
|
||||
pr_err("Failed to allocate htmdump buf\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
htmdump_debugfs_dir = debugfs_create_dir("htmdump",
|
||||
arch_debugfs_dir);
|
||||
|
||||
debugfs_create_u32("nodeindex", 0600,
|
||||
htmdump_debugfs_dir, &nodeindex);
|
||||
debugfs_create_u32("nodalchipindex", 0600,
|
||||
htmdump_debugfs_dir, &nodalchipindex);
|
||||
debugfs_create_u32("coreindexonchip", 0600,
|
||||
htmdump_debugfs_dir, &coreindexonchip);
|
||||
debugfs_create_u32("htmtype", 0600,
|
||||
htmdump_debugfs_dir, &htmtype);
|
||||
debugfs_create_file("trace", 0400, htmdump_debugfs_dir, htm_buf, &htmdump_fops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init htmdump_init(void)
|
||||
{
|
||||
if (htmdump_init_debugfs())
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit htmdump_exit(void)
|
||||
{
|
||||
debugfs_remove_recursive(htmdump_debugfs_dir);
|
||||
kfree(htm_buf);
|
||||
}
|
||||
|
||||
module_init(htmdump_init);
|
||||
module_exit(htmdump_exit);
|
||||
MODULE_DESCRIPTION("PHYP Hardware Trace Macro (HTM) data dumper");
|
||||
MODULE_LICENSE("GPL");
|
||||
Loading…
Reference in New Issue
Block a user