summaryrefslogtreecommitdiff
path: root/drivers/vfio
diff options
context:
space:
mode:
authorGerd Bayer <gbayer@linux.ibm.com>2024-06-19 13:58:45 +0200
committerAlex Williamson <alex.williamson@redhat.com>2024-06-21 12:47:01 -0600
commit186bfe44ea41fb38c7a69becd7078724d28cd03c (patch)
tree316855475d1cc5cf1be2cbcfef9de338cfaf7ac4 /drivers/vfio
parent6ba59ff4227927d3a8530fc2973b80e94b54d58f (diff)
vfio/pci: Extract duplicated code into macro
vfio_pci_core_do_io_rw() repeats the same code for multiple access widths. Factor this out into a macro Suggested-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Gerd Bayer <gbayer@linux.ibm.com> Link: https://lore.kernel.org/r/20240619115847.1344875-2-gbayer@linux.ibm.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'drivers/vfio')
-rw-r--r--drivers/vfio/pci/vfio_pci_rdwr.c106
1 files changed, 46 insertions, 60 deletions
diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c
index 03b8f7ada1ac..d07bfb0ab892 100644
--- a/drivers/vfio/pci/vfio_pci_rdwr.c
+++ b/drivers/vfio/pci/vfio_pci_rdwr.c
@@ -90,6 +90,40 @@ VFIO_IOREAD(8)
VFIO_IOREAD(16)
VFIO_IOREAD(32)
+#define VFIO_IORDWR(size) \
+static int vfio_pci_iordwr##size(struct vfio_pci_core_device *vdev,\
+ bool iswrite, bool test_mem, \
+ void __iomem *io, char __user *buf, \
+ loff_t off, size_t *filled) \
+{ \
+ u##size val; \
+ int ret; \
+ \
+ if (iswrite) { \
+ if (copy_from_user(&val, buf, sizeof(val))) \
+ return -EFAULT; \
+ \
+ ret = vfio_pci_core_iowrite##size(vdev, test_mem, \
+ val, io + off); \
+ if (ret) \
+ return ret; \
+ } else { \
+ ret = vfio_pci_core_ioread##size(vdev, test_mem, \
+ &val, io + off); \
+ if (ret) \
+ return ret; \
+ \
+ if (copy_to_user(buf, &val, sizeof(val))) \
+ return -EFAULT; \
+ } \
+ \
+ *filled = sizeof(val); \
+ return 0; \
+} \
+
+VFIO_IORDWR(8)
+VFIO_IORDWR(16)
+VFIO_IORDWR(32)
/*
* Read or write from an __iomem region (MMIO or I/O port) with an excluded
* range which is inaccessible. The excluded range drops writes and fills
@@ -115,71 +149,23 @@ ssize_t vfio_pci_core_do_io_rw(struct vfio_pci_core_device *vdev, bool test_mem,
fillable = 0;
if (fillable >= 4 && !(off % 4)) {
- u32 val;
-
- if (iswrite) {
- if (copy_from_user(&val, buf, 4))
- return -EFAULT;
-
- ret = vfio_pci_core_iowrite32(vdev, test_mem,
- val, io + off);
- if (ret)
- return ret;
- } else {
- ret = vfio_pci_core_ioread32(vdev, test_mem,
- &val, io + off);
- if (ret)
- return ret;
-
- if (copy_to_user(buf, &val, 4))
- return -EFAULT;
- }
+ ret = vfio_pci_iordwr32(vdev, iswrite, test_mem,
+ io, buf, off, &filled);
+ if (ret)
+ return ret;
- filled = 4;
} else if (fillable >= 2 && !(off % 2)) {
- u16 val;
-
- if (iswrite) {
- if (copy_from_user(&val, buf, 2))
- return -EFAULT;
-
- ret = vfio_pci_core_iowrite16(vdev, test_mem,
- val, io + off);
- if (ret)
- return ret;
- } else {
- ret = vfio_pci_core_ioread16(vdev, test_mem,
- &val, io + off);
- if (ret)
- return ret;
-
- if (copy_to_user(buf, &val, 2))
- return -EFAULT;
- }
+ ret = vfio_pci_iordwr16(vdev, iswrite, test_mem,
+ io, buf, off, &filled);
+ if (ret)
+ return ret;
- filled = 2;
} else if (fillable) {
- u8 val;
-
- if (iswrite) {
- if (copy_from_user(&val, buf, 1))
- return -EFAULT;
-
- ret = vfio_pci_core_iowrite8(vdev, test_mem,
- val, io + off);
- if (ret)
- return ret;
- } else {
- ret = vfio_pci_core_ioread8(vdev, test_mem,
- &val, io + off);
- if (ret)
- return ret;
-
- if (copy_to_user(buf, &val, 1))
- return -EFAULT;
- }
+ ret = vfio_pci_iordwr8(vdev, iswrite, test_mem,
+ io, buf, off, &filled);
+ if (ret)
+ return ret;
- filled = 1;
} else {
/* Fill reads with -1, drop writes */
filled = min(count, (size_t)(x_end - off));