@@ -190,33 +190,34 @@ static int hvpipe_rtas_recv_msg(char __user *buf, int size)
190190 return - ENOMEM ;
191191 }
192192
193- ret = rtas_ibm_receive_hvpipe_msg (work_area , & srcID ,
194- & bytes_written );
195- if (!ret ) {
196- /*
197- * Recv HVPIPE RTAS is successful.
198- * When releasing FD or no one is waiting on the
199- * specific source, issue recv HVPIPE RTAS call
200- * so that pipe is not blocked - this func is called
201- * with NULL buf.
202- */
203- if (buf ) {
204- if (size < bytes_written ) {
205- pr_err ("Received the payload size = %d, but the buffer size = %d\n" ,
206- bytes_written , size );
207- bytes_written = size ;
208- }
209- ret = copy_to_user (buf ,
210- rtas_work_area_raw_buf (work_area ),
211- bytes_written );
212- if (!ret )
213- ret = bytes_written ;
214- }
215- } else {
216- pr_err ("ibm,receive-hvpipe-msg failed with %d\n" ,
217- ret );
193+ /*
194+ * Recv HVPIPE RTAS is successful.
195+ * When releasing FD or no one is waiting on the
196+ * specific source, issue recv HVPIPE RTAS call
197+ * so that pipe is not blocked - this func is called
198+ * with NULL buf.
199+ */
200+ ret = rtas_ibm_receive_hvpipe_msg (work_area , & srcID , & bytes_written );
201+ if (ret ) {
202+ pr_err ("ibm,receive-hvpipe-msg failed with %d\n" , ret );
203+ goto out ;
218204 }
219205
206+ if (!buf )
207+ goto out ;
208+
209+ if (size < bytes_written ) {
210+ pr_err ("Received the payload size = %d, but the buffer size = %d\n" ,
211+ bytes_written , size );
212+ bytes_written = size ;
213+ }
214+
215+ if (copy_to_user (buf , rtas_work_area_raw_buf (work_area ), bytes_written ))
216+ ret = - EFAULT ;
217+ else
218+ ret = bytes_written ;
219+
220+ out :
220221 rtas_work_area_free (work_area );
221222 return ret ;
222223}
@@ -327,8 +328,8 @@ static ssize_t papr_hvpipe_handle_read(struct file *file,
327328{
328329
329330 struct hvpipe_source_info * src_info = file -> private_data ;
330- struct papr_hvpipe_hdr hdr ;
331- long ret ;
331+ struct papr_hvpipe_hdr hdr = {} ;
332+ ssize_t ret = 0 ;
332333
333334 /*
334335 * Return -ENXIO during migration
@@ -376,7 +377,7 @@ static ssize_t papr_hvpipe_handle_read(struct file *file,
376377
377378 ret = copy_to_user (buf , & hdr , HVPIPE_HDR_LEN );
378379 if (ret )
379- return ret ;
380+ return - EFAULT ;
380381
381382 /*
382383 * Message event has payload, so get the payload with
@@ -385,19 +386,23 @@ static ssize_t papr_hvpipe_handle_read(struct file *file,
385386 if (hdr .flags & HVPIPE_MSG_AVAILABLE ) {
386387 ret = hvpipe_rtas_recv_msg (buf + HVPIPE_HDR_LEN ,
387388 size - HVPIPE_HDR_LEN );
388- if (ret > 0 ) {
389+ /*
390+ * Always clear MSG_AVAILABLE once the RTAS call has drained
391+ * the message, regardless of whether copy_to_user succeeded.
392+ */
393+ if (ret > 0 || ret == - EFAULT )
389394 src_info -> hvpipe_status &= ~HVPIPE_MSG_AVAILABLE ;
390- ret += HVPIPE_HDR_LEN ;
391- }
392395 } else if (hdr .flags & HVPIPE_LOST_CONNECTION ) {
393396 /*
394397 * Hypervisor is closing the pipe for the specific
395398 * source. So notify user space.
396399 */
397400 src_info -> hvpipe_status &= ~HVPIPE_LOST_CONNECTION ;
398- ret = HVPIPE_HDR_LEN ;
399401 }
400402
403+ if (ret >= 0 )
404+ ret += HVPIPE_HDR_LEN ;
405+
401406 return ret ;
402407}
403408
@@ -444,27 +449,27 @@ static int papr_hvpipe_handle_release(struct inode *inode,
444449 struct file * file )
445450{
446451 struct hvpipe_source_info * src_info ;
452+ unsigned long flags ;
447453
448454 /*
449455 * Hold the lock, remove source from src_list, reset the
450456 * hvpipe status and release the lock to prevent any race
451457 * with message event IRQ.
452458 */
453- spin_lock (& hvpipe_src_list_lock );
459+ spin_lock_irqsave (& hvpipe_src_list_lock , flags );
454460 src_info = file -> private_data ;
455461 list_del (& src_info -> list );
456462 file -> private_data = NULL ;
463+ spin_unlock_irqrestore (& hvpipe_src_list_lock , flags );
457464 /*
458465 * If the pipe for this specific source has any pending
459466 * payload, issue recv HVPIPE RTAS so that pipe will not
460467 * be blocked.
461468 */
462469 if (src_info -> hvpipe_status & HVPIPE_MSG_AVAILABLE ) {
463470 src_info -> hvpipe_status = 0 ;
464- spin_unlock (& hvpipe_src_list_lock );
465471 hvpipe_rtas_recv_msg (NULL , 0 );
466- } else
467- spin_unlock (& hvpipe_src_list_lock );
472+ }
468473
469474 kfree (src_info );
470475 return 0 ;
@@ -479,50 +484,53 @@ static const struct file_operations papr_hvpipe_handle_ops = {
479484
480485static int papr_hvpipe_dev_create_handle (u32 srcID )
481486{
482- struct hvpipe_source_info * src_info __free (kfree ) = NULL ;
483-
484- spin_lock (& hvpipe_src_list_lock );
485- /*
486- * Do not allow more than one process communicates with
487- * each source.
488- */
489- src_info = hvpipe_find_source (srcID );
490- if (src_info ) {
491- spin_unlock (& hvpipe_src_list_lock );
492- pr_err ("pid(%d) is already using the source(%d)\n" ,
493- src_info -> tsk -> pid , srcID );
494- return - EALREADY ;
495- }
496- spin_unlock (& hvpipe_src_list_lock );
487+ struct hvpipe_source_info * src_info ;
488+ int fd ;
489+ unsigned long flags ;
497490
498491 src_info = kzalloc_obj (* src_info , GFP_KERNEL_ACCOUNT );
499492 if (!src_info )
500493 return - ENOMEM ;
501494
502495 src_info -> srcID = srcID ;
503- src_info -> tsk = current ;
504496 init_waitqueue_head (& src_info -> recv_wqh );
505497
506- FD_PREPARE (fdf , O_RDONLY | O_CLOEXEC ,
507- anon_inode_getfile ("[papr-hvpipe]" , & papr_hvpipe_handle_ops ,
508- (void * )src_info , O_RDWR ));
509- if (fdf .err )
510- return fdf .err ;
511-
512- retain_and_null_ptr (src_info );
513- spin_lock (& hvpipe_src_list_lock );
514498 /*
515- * If two processes are executing ioctl() for the same
516- * source ID concurrently, prevent the second process to
517- * acquire FD.
499+ * Do not allow more than one process communicates with
500+ * each source.
518501 */
502+ spin_lock_irqsave (& hvpipe_src_list_lock , flags );
519503 if (hvpipe_find_source (srcID )) {
520- spin_unlock (& hvpipe_src_list_lock );
504+ spin_unlock_irqrestore (& hvpipe_src_list_lock , flags );
505+ pr_err ("pid(%s:%d) could not get the source(%d)\n" ,
506+ current -> comm , task_pid_nr (current ), srcID );
507+ kfree (src_info );
521508 return - EALREADY ;
522509 }
523510 list_add (& src_info -> list , & hvpipe_src_list );
524- spin_unlock (& hvpipe_src_list_lock );
525- return fd_publish (fdf );
511+ spin_unlock_irqrestore (& hvpipe_src_list_lock , flags );
512+
513+ fd = FD_ADD (O_RDONLY | O_CLOEXEC ,
514+ anon_inode_getfile ("[papr-hvpipe]" , & papr_hvpipe_handle_ops ,
515+ (void * )src_info , O_RDWR ));
516+ if (fd < 0 ) {
517+ spin_lock_irqsave (& hvpipe_src_list_lock , flags );
518+ list_del (& src_info -> list );
519+ spin_unlock_irqrestore (& hvpipe_src_list_lock , flags );
520+ /*
521+ * if we fail to add FD, that means no userspace program is
522+ * polling. In that case if there is a msg pending because the
523+ * interrupt was fired after the src_info was added to the
524+ * global list, then let's consume it here, to unblock the
525+ * hvpipe
526+ */
527+ if (src_info -> hvpipe_status & HVPIPE_MSG_AVAILABLE )
528+ hvpipe_rtas_recv_msg (NULL , 0 );
529+ kfree (src_info );
530+ return fd ;
531+ }
532+
533+ return fd ;
526534}
527535
528536/*
@@ -685,20 +693,19 @@ static int __init enable_hvpipe_IRQ(void)
685693 struct device_node * np ;
686694
687695 hvpipe_check_exception_token = rtas_function_token (RTAS_FN_CHECK_EXCEPTION );
688- if (hvpipe_check_exception_token == RTAS_UNKNOWN_SERVICE )
696+ if (hvpipe_check_exception_token == RTAS_UNKNOWN_SERVICE )
689697 return - ENODEV ;
690698
691699 /* hvpipe events */
692700 np = of_find_node_by_path ("/event-sources/ibm,hvpipe-msg-events" );
693- if (np != NULL ) {
694- request_event_sources_irqs (np , hvpipe_event_interrupt ,
695- "HPIPE_EVENT" );
696- of_node_put (np );
697- } else {
698- pr_err ("Can not enable hvpipe event IRQ\n" );
701+ if (!np ) {
702+ pr_err ("No device node found, could not enable hvpipe event IRQ\n" );
699703 return - ENODEV ;
700704 }
701705
706+ request_event_sources_irqs (np , hvpipe_event_interrupt , "HPIPE_EVENT" );
707+ of_node_put (np );
708+
702709 return 0 ;
703710}
704711
@@ -775,23 +782,29 @@ static int __init papr_hvpipe_init(void)
775782 }
776783
777784 ret = enable_hvpipe_IRQ ();
778- if (!ret ) {
779- ret = set_hvpipe_sys_param (1 );
780- if (!ret )
781- ret = misc_register (& papr_hvpipe_dev );
782- }
785+ if (ret )
786+ goto out_wq ;
783787
784- if (!ret ) {
785- pr_info ("hvpipe feature is enabled\n" );
786- hvpipe_feature = true;
787- return 0 ;
788- }
788+ ret = misc_register (& papr_hvpipe_dev );
789+ if (ret )
790+ goto out_wq ;
789791
790- pr_err ("hvpipe feature is not enabled %d\n" , ret );
792+ ret = set_hvpipe_sys_param (1 );
793+ if (ret )
794+ goto out_misc ;
795+
796+ pr_info ("hvpipe feature is enabled\n" );
797+ hvpipe_feature = true;
798+ return 0 ;
799+
800+ out_misc :
801+ misc_deregister (& papr_hvpipe_dev );
802+ out_wq :
791803 destroy_workqueue (papr_hvpipe_wq );
792804out :
793805 kfree (papr_hvpipe_work );
794806 papr_hvpipe_work = NULL ;
807+ pr_err ("hvpipe feature is not enabled %d\n" , ret );
795808 return ret ;
796809}
797810machine_device_initcall (pseries , papr_hvpipe_init );
0 commit comments