@@ -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}
@@ -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
@@ -454,17 +455,16 @@ static int papr_hvpipe_handle_release(struct inode *inode,
454455 src_info = file -> private_data ;
455456 list_del (& src_info -> list );
456457 file -> private_data = NULL ;
458+ spin_unlock (& hvpipe_src_list_lock );
457459 /*
458460 * If the pipe for this specific source has any pending
459461 * payload, issue recv HVPIPE RTAS so that pipe will not
460462 * be blocked.
461463 */
462464 if (src_info -> hvpipe_status & HVPIPE_MSG_AVAILABLE ) {
463465 src_info -> hvpipe_status = 0 ;
464- spin_unlock (& hvpipe_src_list_lock );
465466 hvpipe_rtas_recv_msg (NULL , 0 );
466- } else
467- spin_unlock (& hvpipe_src_list_lock );
467+ }
468468
469469 kfree (src_info );
470470 return 0 ;
@@ -479,50 +479,43 @@ static const struct file_operations papr_hvpipe_handle_ops = {
479479
480480static int papr_hvpipe_dev_create_handle (u32 srcID )
481481{
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 );
482+ struct hvpipe_source_info * src_info ;
483+ int fd ;
497484
498485 src_info = kzalloc_obj (* src_info , GFP_KERNEL_ACCOUNT );
499486 if (!src_info )
500487 return - ENOMEM ;
501488
502489 src_info -> srcID = srcID ;
503- src_info -> tsk = current ;
504490 init_waitqueue_head (& src_info -> recv_wqh );
505491
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 );
514492 /*
515- * If two processes are executing ioctl() for the same
516- * source ID concurrently, prevent the second process to
517- * acquire FD.
493+ * Do not allow more than one process communicates with
494+ * each source.
518495 */
519- if (hvpipe_find_source (srcID )) {
496+ spin_lock (& hvpipe_src_list_lock );
497+ if (hvpipe_find_source (srcID )) {
520498 spin_unlock (& hvpipe_src_list_lock );
499+ pr_err ("pid(%s:%d) could not get the source(%d)\n" ,
500+ current -> comm , task_pid_nr (current ), srcID );
501+ kfree (src_info );
521502 return - EALREADY ;
522503 }
523504 list_add (& src_info -> list , & hvpipe_src_list );
524505 spin_unlock (& hvpipe_src_list_lock );
525- return fd_publish (fdf );
506+
507+ fd = FD_ADD (O_RDONLY | O_CLOEXEC ,
508+ anon_inode_getfile ("[papr-hvpipe]" , & papr_hvpipe_handle_ops ,
509+ (void * )src_info , O_RDWR ));
510+ if (fd < 0 ) {
511+ spin_lock (& hvpipe_src_list_lock );
512+ list_del (& src_info -> list );
513+ spin_unlock (& hvpipe_src_list_lock );
514+ kfree (src_info );
515+ return fd ;
516+ }
517+
518+ return fd ;
526519}
527520
528521/*
@@ -775,23 +768,27 @@ static int __init papr_hvpipe_init(void)
775768 }
776769
777770 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- }
771+ if (ret )
772+ goto out_wq ;
783773
784- if (!ret ) {
785- pr_info ("hvpipe feature is enabled\n" );
786- hvpipe_feature = true;
787- return 0 ;
788- }
774+ ret = set_hvpipe_sys_param (1 );
775+ if (ret )
776+ goto out_wq ;
789777
790- pr_err ("hvpipe feature is not enabled %d\n" , ret );
778+ ret = misc_register (& papr_hvpipe_dev );
779+ if (ret )
780+ goto out_wq ;
781+
782+ pr_info ("hvpipe feature is enabled\n" );
783+ hvpipe_feature = true;
784+ return 0 ;
785+
786+ out_wq :
791787 destroy_workqueue (papr_hvpipe_wq );
792788out :
793789 kfree (papr_hvpipe_work );
794790 papr_hvpipe_work = NULL ;
791+ pr_err ("hvpipe feature is not enabled %d\n" , ret );
795792 return ret ;
796793}
797794machine_device_initcall (pseries , papr_hvpipe_init );
0 commit comments