Skip to content

Commit 6f6a50a

Browse files
riteshharjanigregkh
authored andcommitted
pseries/papr-hvpipe: Fix the usage of copy_to_user()
commit d48654b upstream. copy_to_user() return bytes_not_copied to the user buffer. If there was an error writing bytes into the user buffer, i.e. if copy_to_user returns a non-zero value, then we should simply return -EFAULT from the ->read() call. Otherwise, in the non-patched version, we may end up mixing "bytes_not_copied + bytes_copied (HVPIPE_HDR_LEN)" as the return value to the user in ->read() call Also let's make sure we clear the hvpipe_status flag, if we have consumed the hvpipe msg by making the rtas call. ret = -EFAULT means copy_to_user has failed but that still means that the msg was read from the hvpipe, hence for both cases, success & -EFAULT, we should clear the HVPIPE_MSG_AVAILABLE flag in hvpipe_status. Cc: stable@vger.kernel.org Fixes: cebdb52 ("powerpc/pseries: Receive payload with ibm,receive-hvpipe-msg RTAS") Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com> Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com> Link: https://patch.msgid.link/8fda3212a1ad48879c174e92f67472d9b9f1c3b7.1777606826.git.ritesh.list@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 1db6f08 commit 6f6a50a

1 file changed

Lines changed: 14 additions & 9 deletions

File tree

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

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,11 @@ static int hvpipe_rtas_recv_msg(char __user *buf, int size)
206206
bytes_written, size);
207207
bytes_written = size;
208208
}
209-
ret = copy_to_user(buf,
209+
if (copy_to_user(buf,
210210
rtas_work_area_raw_buf(work_area),
211-
bytes_written);
212-
if (!ret)
211+
bytes_written))
212+
ret = -EFAULT;
213+
else
213214
ret = bytes_written;
214215
}
215216
} else {
@@ -328,7 +329,7 @@ static ssize_t papr_hvpipe_handle_read(struct file *file,
328329

329330
struct hvpipe_source_info *src_info = file->private_data;
330331
struct papr_hvpipe_hdr hdr = {};
331-
long ret;
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

0 commit comments

Comments
 (0)