summaryrefslogtreecommitdiff
path: root/drivers/misc
diff options
context:
space:
mode:
authorYousef Alhouseen <alhouseenyousef@gmail.com>2026-06-24 20:59:25 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-17 15:50:01 +0200
commitfd62c1f591372f7dc4c5bc041569c2f0a4a86be1 (patch)
tree0e7ec1016fb56997b9625e052a997c8f77caced8 /drivers/misc
parent7bf6940d7cf41f1f0330a9bae4b7a886e18fd8e3 (diff)
downloadlinux-next-fd62c1f591372f7dc4c5bc041569c2f0a4a86be1.tar.gz
linux-next-fd62c1f591372f7dc4c5bc041569c2f0a4a86be1.zip
misc: ibmvmc: release send buffer on write errors
ibmvmc_get_valid_hmc_buffer() marks the selected send buffer busy before ibmvmc_write() validates the backing storage or copies data from user space. Error exits after that point leave the buffer permanently busy. Keep the buffer pointer until ownership is handed to the hypervisor, and mark it free again on local write failures. Also report an RDMA send failure instead of returning a successful byte count. Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com> Link: https://patch.msgid.link/20260624185925.2133-1-alhouseenyousef@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/ibmvmc.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/misc/ibmvmc.c b/drivers/misc/ibmvmc.c
index beb18c34f20d..1f2968d9d01b 100644
--- a/drivers/misc/ibmvmc.c
+++ b/drivers/misc/ibmvmc.c
@@ -1040,7 +1040,7 @@ static ssize_t ibmvmc_write(struct file *file, const char *buffer,
size_t count, loff_t *ppos)
{
struct inode *inode;
- struct ibmvmc_buffer *vmc_buffer;
+ struct ibmvmc_buffer *vmc_buffer = NULL;
struct ibmvmc_file_session *session;
struct crq_server_adapter *adapter;
struct ibmvmc_hmc *hmc;
@@ -1130,9 +1130,15 @@ static ssize_t ibmvmc_write(struct file *file, const char *buffer,
dev_dbg(adapter->dev, "write: file = 0x%lx, count = 0x%lx\n",
(unsigned long)file, (unsigned long)count);
- ibmvmc_send_msg(adapter, vmc_buffer, hmc, count);
+ if (ibmvmc_send_msg(adapter, vmc_buffer, hmc, count)) {
+ ret = -EIO;
+ goto out;
+ }
+ vmc_buffer = NULL;
ret = p - buffer;
out:
+ if (vmc_buffer)
+ vmc_buffer->free = 1;
spin_unlock_irqrestore(&hmc->lock, flags);
return (ssize_t)(ret);
}