Skip to content

Commit 047e314

Browse files
author
Fox Snowpatch
committed
1 parent 5c2c0ba commit 047e314

2 files changed

Lines changed: 66 additions & 70 deletions

File tree

arch/powerpc/platforms/pseries/papr-hvpipe.c

Lines changed: 66 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -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

480480
static 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);
792788
out:
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
}
797794
machine_device_initcall(pseries, papr_hvpipe_init);

arch/powerpc/platforms/pseries/papr-hvpipe.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ struct hvpipe_source_info {
2121
u32 srcID;
2222
u32 hvpipe_status;
2323
wait_queue_head_t recv_wqh; /* wake up poll() waitq */
24-
struct task_struct *tsk;
2524
};
2625

2726
/*

0 commit comments

Comments
 (0)