]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/5.15.153/powerpc-hv-gpci-fix-the-h_get_perf_counter_info-hcal.patch
Linux 5.15.153
[thirdparty/kernel/stable-queue.git] / releases / 5.15.153 / powerpc-hv-gpci-fix-the-h_get_perf_counter_info-hcal.patch
1 From a4e7838f9c6a75adab23becb8d2100b964ab4b2b Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Thu, 29 Feb 2024 17:58:47 +0530
4 Subject: powerpc/hv-gpci: Fix the H_GET_PERF_COUNTER_INFO hcall return value
5 checks
6
7 From: Kajol Jain <kjain@linux.ibm.com>
8
9 [ Upstream commit ad86d7ee43b22aa2ed60fb982ae94b285c1be671 ]
10
11 Running event hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/
12 in one of the system throws below error:
13
14 ---Logs---
15 # perf list | grep hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles
16 hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=?/[Kernel PMU event]
17
18 # perf stat -v -e hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/ sleep 2
19 Using CPUID 00800200
20 Control descriptor is not initialized
21 Warning:
22 hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/ event is not supported by the kernel.
23 failed to read counter hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/
24
25 Performance counter stats for 'system wide':
26
27 <not supported> hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/
28
29 2.000700771 seconds time elapsed
30
31 The above error is because of the hcall failure as required
32 permission "Enable Performance Information Collection" is not set.
33 Based on current code, single_gpci_request function did not check the
34 error type incase hcall fails and by default returns EINVAL. But we can
35 have other reasons for hcall failures like H_AUTHORITY/H_PARAMETER with
36 detail_rc as GEN_BUF_TOO_SMALL, for which we need to act accordingly.
37
38 Fix this issue by adding new checks in the single_gpci_request and
39 h_gpci_event_init functions.
40
41 Result after fix patch changes:
42
43 # perf stat -e hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/ sleep 2
44 Error:
45 No permission to enable hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/ event.
46
47 Fixes: 220a0c609ad1 ("powerpc/perf: Add support for the hv gpci (get performance counter info) interface")
48 Reported-by: Akanksha J N <akanksha@linux.ibm.com>
49 Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
50 Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
51 Link: https://msgid.link/20240229122847.101162-1-kjain@linux.ibm.com
52 Signed-off-by: Sasha Levin <sashal@kernel.org>
53 ---
54 arch/powerpc/perf/hv-gpci.c | 29 +++++++++++++++++++++++++++--
55 1 file changed, 27 insertions(+), 2 deletions(-)
56
57 diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
58 index 28b770bbc10b4..2a054de80e50b 100644
59 --- a/arch/powerpc/perf/hv-gpci.c
60 +++ b/arch/powerpc/perf/hv-gpci.c
61 @@ -164,6 +164,20 @@ static unsigned long single_gpci_request(u32 req, u32 starting_index,
62
63 ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
64 virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE);
65 +
66 + /*
67 + * ret value as 'H_PARAMETER' with detail_rc as 'GEN_BUF_TOO_SMALL',
68 + * specifies that the current buffer size cannot accommodate
69 + * all the information and a partial buffer returned.
70 + * Since in this function we are only accessing data for a given starting index,
71 + * we don't need to accommodate whole data and can get required count by
72 + * accessing first entry data.
73 + * Hence hcall fails only incase the ret value is other than H_SUCCESS or
74 + * H_PARAMETER with detail_rc value as GEN_BUF_TOO_SMALL(0x1B).
75 + */
76 + if (ret == H_PARAMETER && be32_to_cpu(arg->params.detail_rc) == 0x1B)
77 + ret = 0;
78 +
79 if (ret) {
80 pr_devel("hcall failed: 0x%lx\n", ret);
81 goto out;
82 @@ -228,6 +242,7 @@ static int h_gpci_event_init(struct perf_event *event)
83 {
84 u64 count;
85 u8 length;
86 + unsigned long ret;
87
88 /* Not our event */
89 if (event->attr.type != event->pmu->type)
90 @@ -258,13 +273,23 @@ static int h_gpci_event_init(struct perf_event *event)
91 }
92
93 /* check if the request works... */
94 - if (single_gpci_request(event_get_request(event),
95 + ret = single_gpci_request(event_get_request(event),
96 event_get_starting_index(event),
97 event_get_secondary_index(event),
98 event_get_counter_info_version(event),
99 event_get_offset(event),
100 length,
101 - &count)) {
102 + &count);
103 +
104 + /*
105 + * ret value as H_AUTHORITY implies that partition is not permitted to retrieve
106 + * performance information, and required to set
107 + * "Enable Performance Information Collection" option.
108 + */
109 + if (ret == H_AUTHORITY)
110 + return -EPERM;
111 +
112 + if (ret) {
113 pr_devel("gpci hcall failed\n");
114 return -EINVAL;
115 }
116 --
117 2.43.0
118