diff options
Diffstat (limited to 'drivers/s390/char')
-rw-r--r-- | drivers/s390/char/vmcp.c | 22 |
1 files changed, 8 insertions, 14 deletions
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index 2f419b0ea628..af616aeaa938 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c | |||
@@ -61,30 +61,24 @@ static int vmcp_release(struct inode *inode, struct file *file) | |||
61 | static ssize_t | 61 | static ssize_t |
62 | vmcp_read(struct file *file, char __user *buff, size_t count, loff_t *ppos) | 62 | vmcp_read(struct file *file, char __user *buff, size_t count, loff_t *ppos) |
63 | { | 63 | { |
64 | size_t tocopy; | 64 | ssize_t ret; |
65 | size_t size; | ||
65 | struct vmcp_session *session; | 66 | struct vmcp_session *session; |
66 | 67 | ||
67 | session = (struct vmcp_session *)file->private_data; | 68 | session = file->private_data; |
68 | if (mutex_lock_interruptible(&session->mutex)) | 69 | if (mutex_lock_interruptible(&session->mutex)) |
69 | return -ERESTARTSYS; | 70 | return -ERESTARTSYS; |
70 | if (!session->response) { | 71 | if (!session->response) { |
71 | mutex_unlock(&session->mutex); | 72 | mutex_unlock(&session->mutex); |
72 | return 0; | 73 | return 0; |
73 | } | 74 | } |
74 | if (*ppos > session->resp_size) { | 75 | size = min_t(size_t, session->resp_size, session->bufsize); |
75 | mutex_unlock(&session->mutex); | 76 | ret = simple_read_from_buffer(buff, count, ppos, |
76 | return 0; | 77 | session->response, size); |
77 | } | ||
78 | tocopy = min(session->resp_size - (size_t) (*ppos), count); | ||
79 | tocopy = min(tocopy, session->bufsize - (size_t) (*ppos)); | ||
80 | 78 | ||
81 | if (copy_to_user(buff, session->response + (*ppos), tocopy)) { | ||
82 | mutex_unlock(&session->mutex); | ||
83 | return -EFAULT; | ||
84 | } | ||
85 | mutex_unlock(&session->mutex); | 79 | mutex_unlock(&session->mutex); |
86 | *ppos += tocopy; | 80 | |
87 | return tocopy; | 81 | return ret; |
88 | } | 82 | } |
89 | 83 | ||
90 | static ssize_t | 84 | static ssize_t |