Skip to content

Commit a38edf0

Browse files
author
Fox Snowpatch
committed
1 parent 182544a commit a38edf0

1 file changed

Lines changed: 80 additions & 20 deletions

File tree

arch/powerpc/perf/hv-gpci.c

Lines changed: 80 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <linux/init.h>
1313
#include <linux/perf_event.h>
14+
#include <linux/sysfs.h>
1415
#include <asm/firmware.h>
1516
#include <asm/hvcall.h>
1617
#include <asm/io.h>
@@ -129,11 +130,36 @@ static int sysinfo_counter_request[] = {
129130

130131
static DEFINE_PER_CPU(char, hv_gpci_reqb[HGPCI_REQ_BUFFER_SIZE]) __aligned(sizeof(uint64_t));
131132

133+
static int hv_gpci_emit_hex_byte(char *buf, size_t *n, u8 byte)
134+
{
135+
int len;
136+
137+
len = sysfs_emit_at(buf, *n, "%02x", byte);
138+
if (len <= 0)
139+
return -EFBIG;
140+
141+
*n += len;
142+
return 0;
143+
}
144+
145+
static int hv_gpci_emit_newline(char *buf, size_t *n)
146+
{
147+
int len;
148+
149+
len = sysfs_emit_at(buf, *n, "\n");
150+
if (len <= 0)
151+
return -EFBIG;
152+
153+
*n += len;
154+
return 0;
155+
}
156+
132157
static unsigned long systeminfo_gpci_request(u32 req, u32 starting_index,
133158
u16 secondary_index, char *buf,
134159
size_t *n, struct hv_gpci_request_buffer *arg)
135160
{
136161
unsigned long ret;
162+
int rc;
137163
size_t i, j;
138164

139165
arg->params.counter_request = cpu_to_be32(req);
@@ -176,9 +202,14 @@ static unsigned long systeminfo_gpci_request(u32 req, u32 starting_index,
176202
for (i = 0; i < be16_to_cpu(arg->params.returned_values); i++) {
177203
j = i * be16_to_cpu(arg->params.cv_element_size);
178204

179-
for (; j < (i + 1) * be16_to_cpu(arg->params.cv_element_size); j++)
180-
*n += sprintf(buf + *n, "%02x", (u8)arg->bytes[j]);
181-
*n += sprintf(buf + *n, "\n");
205+
for (; j < (i + 1) * be16_to_cpu(arg->params.cv_element_size); j++) {
206+
rc = hv_gpci_emit_hex_byte(buf, n, (u8)arg->bytes[j]);
207+
if (rc)
208+
return rc;
209+
}
210+
rc = hv_gpci_emit_newline(buf, n);
211+
if (rc)
212+
return rc;
182213
}
183214

184215
if (*n >= PAGE_SIZE) {
@@ -461,10 +492,14 @@ static ssize_t affinity_domain_via_domain_show(struct device *dev, struct device
461492
return ret;
462493
}
463494

464-
static void affinity_domain_via_partition_result_parse(int returned_values,
465-
int element_size, char *buf, size_t *last_element,
466-
size_t *n, struct hv_gpci_request_buffer *arg)
495+
static int affinity_domain_via_partition_result_parse(int returned_values,
496+
int element_size,
497+
char *buf,
498+
size_t *last_element,
499+
size_t *n,
500+
struct hv_gpci_request_buffer *arg)
467501
{
502+
int rc;
468503
size_t i = 0, j = 0;
469504
size_t k, l, m;
470505
uint16_t total_affinity_domain_ele, size_of_each_affinity_domain_ele;
@@ -483,27 +518,40 @@ static void affinity_domain_via_partition_result_parse(int returned_values,
483518
*/
484519
while (i < returned_values) {
485520
k = j;
486-
for (; k < j + element_size; k++)
487-
*n += sprintf(buf + *n, "%02x", (u8)arg->bytes[k]);
488-
*n += sprintf(buf + *n, "\n");
521+
for (; k < j + element_size; k++) {
522+
rc = hv_gpci_emit_hex_byte(buf, n, (u8)arg->bytes[k]);
523+
if (rc)
524+
return rc;
525+
}
526+
rc = hv_gpci_emit_newline(buf, n);
527+
if (rc)
528+
return rc;
489529

490530
total_affinity_domain_ele = (u8)arg->bytes[k - 2] << 8 | (u8)arg->bytes[k - 3];
491531
size_of_each_affinity_domain_ele = (u8)arg->bytes[k] << 8 | (u8)arg->bytes[k - 1];
492532

493533
for (l = 0; l < total_affinity_domain_ele; l++) {
494534
for (m = 0; m < size_of_each_affinity_domain_ele; m++) {
495-
*n += sprintf(buf + *n, "%02x", (u8)arg->bytes[k]);
535+
rc = hv_gpci_emit_hex_byte(buf, n, (u8)arg->bytes[k]);
536+
if (rc)
537+
return rc;
496538
k++;
497539
}
498-
*n += sprintf(buf + *n, "\n");
540+
rc = hv_gpci_emit_newline(buf, n);
541+
if (rc)
542+
return rc;
499543
}
500544

501-
*n += sprintf(buf + *n, "\n");
545+
rc = hv_gpci_emit_newline(buf, n);
546+
if (rc)
547+
return rc;
502548
i++;
503549
j = k;
504550
}
505551

506552
*last_element = k;
553+
554+
return 0;
507555
}
508556

509557
static ssize_t affinity_domain_via_partition_show(struct device *dev, struct device_attribute *attr,
@@ -514,6 +562,7 @@ static ssize_t affinity_domain_via_partition_show(struct device *dev, struct dev
514562
size_t n = 0;
515563
size_t last_element = 0;
516564
u32 starting_index;
565+
int element_size, rc, returned_values;
517566

518567
arg = (void *)get_cpu_var(hv_gpci_reqb);
519568
memset(arg, 0, HGPCI_REQ_BUFFER_SIZE);
@@ -546,10 +595,16 @@ static ssize_t affinity_domain_via_partition_show(struct device *dev, struct dev
546595
* to buffer util we get all the information.
547596
*/
548597
while (ret == H_PARAMETER) {
549-
affinity_domain_via_partition_result_parse(
550-
be16_to_cpu(arg->params.returned_values) - 1,
551-
be16_to_cpu(arg->params.cv_element_size), buf,
552-
&last_element, &n, arg);
598+
returned_values = be16_to_cpu(arg->params.returned_values);
599+
element_size = be16_to_cpu(arg->params.cv_element_size);
600+
rc = affinity_domain_via_partition_result_parse(returned_values - 1,
601+
element_size, buf,
602+
&last_element, &n,
603+
arg);
604+
if (rc) {
605+
put_cpu_var(hv_gpci_reqb);
606+
return rc;
607+
}
553608

554609
if (n >= PAGE_SIZE) {
555610
put_cpu_var(hv_gpci_reqb);
@@ -578,10 +633,15 @@ static ssize_t affinity_domain_via_partition_show(struct device *dev, struct dev
578633
}
579634

580635
parse_result:
581-
affinity_domain_via_partition_result_parse(
582-
be16_to_cpu(arg->params.returned_values),
583-
be16_to_cpu(arg->params.cv_element_size),
584-
buf, &last_element, &n, arg);
636+
returned_values = be16_to_cpu(arg->params.returned_values);
637+
element_size = be16_to_cpu(arg->params.cv_element_size);
638+
rc = affinity_domain_via_partition_result_parse(returned_values,
639+
element_size, buf,
640+
&last_element, &n, arg);
641+
if (rc) {
642+
put_cpu_var(hv_gpci_reqb);
643+
return rc;
644+
}
585645

586646
put_cpu_var(hv_gpci_reqb);
587647
return n;

0 commit comments

Comments
 (0)