Skip to content

Commit 6e204ef

Browse files
Athira Rajeevmaddy-kerneldev
authored andcommitted
powerpc/pseries/htmdump: Add htm_hcall_wrapper to integrate other htm operations
H_HTM (Hardware Trace Macro) hypervisor call is an HCALL to export data from Hardware Trace Macro (HTM) function. The debugfs interface to export the HTM function data in an lpar currently supports only dumping of HTM data in an lpar. To add support for setup, configuration and control of HTM function via debugfs interface, update the hcall wrapper function. Rename and update htm_get_dump_hardware to htm_hcall_wrapper() so that it can be used for other HTM operations as well. Additionally include parameter "htm_op". Update htmdump module to check the return code of hcall in a separate function so that it can be reused for other option too. Add check to disable the interface in guest environment. Signed-off-by: Athira Rajeev <[email protected]> Tested-by: Venkat Rao Bagalkote <[email protected]> Signed-off-by: Madhavan Srinivasan <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent 5ea6a98 commit 6e204ef

File tree

2 files changed

+63
-18
lines changed

2 files changed

+63
-18
lines changed

arch/powerpc/include/asm/plpar_wrappers.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ static inline long register_dtl(unsigned long cpu, unsigned long vpa)
6565
return vpa_call(H_VPA_REG_DTL, cpu, vpa);
6666
}
6767

68+
/*
69+
* Invokes H_HTM hcall with parameters passed from htm_hcall_wrapper.
70+
* flags: Set to hardwareTarget.
71+
* target: Specifies target using node index, nodal chip index and core index.
72+
* operation : action to perform ie configure, start, stop, deconfigure, trace
73+
* based on the HTM type.
74+
* param1, param2, param3: parameters for each action.
75+
*/
6876
static inline long htm_call(unsigned long flags, unsigned long target,
6977
unsigned long operation, unsigned long param1,
7078
unsigned long param2, unsigned long param3)
@@ -73,17 +81,17 @@ static inline long htm_call(unsigned long flags, unsigned long target,
7381
param1, param2, param3);
7482
}
7583

76-
static inline long htm_get_dump_hardware(unsigned long nodeindex,
84+
static inline long htm_hcall_wrapper(unsigned long nodeindex,
7785
unsigned long nodalchipindex, unsigned long coreindexonchip,
78-
unsigned long type, unsigned long addr, unsigned long size,
79-
unsigned long offset)
86+
unsigned long type, unsigned long htm_op, unsigned long param1, unsigned long param2,
87+
unsigned long param3)
8088
{
8189
return htm_call(H_HTM_FLAGS_HARDWARE_TARGET,
8290
H_HTM_TARGET_NODE_INDEX(nodeindex) |
8391
H_HTM_TARGET_NODAL_CHIP_INDEX(nodalchipindex) |
8492
H_HTM_TARGET_CORE_INDEX_ON_CHIP(coreindexonchip),
85-
H_HTM_OP(H_HTM_OP_DUMP_DATA) | H_HTM_TYPE(type),
86-
addr, size, offset);
93+
H_HTM_OP(htm_op) | H_HTM_TYPE(type),
94+
param1, param2, param3);
8795
}
8896

8997
extern void vpa_init(int cpu);

arch/powerpc/platforms/pseries/htmdump.c

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,19 @@ static u32 coreindexonchip;
1818
static u32 htmtype;
1919
static struct dentry *htmdump_debugfs_dir;
2020

21-
static ssize_t htmdump_read(struct file *filp, char __user *ubuf,
22-
size_t count, loff_t *ppos)
21+
/*
22+
* Check the return code for H_HTM hcall.
23+
* Return non-zero value (1) if either H_PARTIAL or H_SUCCESS
24+
* is returned. For other return codes:
25+
* Return zero if H_NOT_AVAILABLE.
26+
* Return -EBUSY if hcall return busy.
27+
* Return -EINVAL if any parameter or operation is not valid.
28+
* Return -EPERM if HTM Virtualization Engine Technology code
29+
* is not applied.
30+
* Return -EIO if the HTM state is not valid.
31+
*/
32+
static ssize_t htm_return_check(long rc)
2333
{
24-
void *htm_buf = filp->private_data;
25-
unsigned long page, read_size, available;
26-
loff_t offset;
27-
long rc;
28-
29-
page = ALIGN_DOWN(*ppos, PAGE_SIZE);
30-
offset = (*ppos) % PAGE_SIZE;
31-
32-
rc = htm_get_dump_hardware(nodeindex, nodalchipindex, coreindexonchip,
33-
htmtype, virt_to_phys(htm_buf), PAGE_SIZE, page);
34-
3534
switch (rc) {
3635
case H_SUCCESS:
3736
/* H_PARTIAL for the case where all available data can't be
@@ -65,6 +64,38 @@ static ssize_t htmdump_read(struct file *filp, char __user *ubuf,
6564
return -EPERM;
6665
}
6766

67+
/*
68+
* Return 1 for H_SUCCESS/H_PARTIAL
69+
*/
70+
return 1;
71+
}
72+
73+
static ssize_t htmdump_read(struct file *filp, char __user *ubuf,
74+
size_t count, loff_t *ppos)
75+
{
76+
void *htm_buf = filp->private_data;
77+
unsigned long page, read_size, available;
78+
loff_t offset;
79+
long rc, ret;
80+
81+
page = ALIGN_DOWN(*ppos, PAGE_SIZE);
82+
offset = (*ppos) % PAGE_SIZE;
83+
84+
/*
85+
* Invoke H_HTM call with:
86+
* - operation as htm dump (H_HTM_OP_DUMP_DATA)
87+
* - last three values are address, size and offset
88+
*/
89+
rc = htm_hcall_wrapper(nodeindex, nodalchipindex, coreindexonchip,
90+
htmtype, H_HTM_OP_DUMP_DATA, virt_to_phys(htm_buf),
91+
PAGE_SIZE, page);
92+
93+
ret = htm_return_check(rc);
94+
if (ret <= 0) {
95+
pr_debug("H_HTM hcall failed for op: H_HTM_OP_DUMP_DATA, returning %ld\n", ret);
96+
return ret;
97+
}
98+
6899
available = PAGE_SIZE;
69100
read_size = min(count, available);
70101
*ppos += read_size;
@@ -103,6 +134,12 @@ static int htmdump_init_debugfs(void)
103134

104135
static int __init htmdump_init(void)
105136
{
137+
/* Disable on kvm guest */
138+
if (is_kvm_guest()) {
139+
pr_info("htmdump not supported inside KVM guest\n");
140+
return -EOPNOTSUPP;
141+
}
142+
106143
if (htmdump_init_debugfs())
107144
return -ENOMEM;
108145

0 commit comments

Comments
 (0)