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
130131static 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+
132157static 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
509557static 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
580635parse_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