Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Gerd Bayer and committed by
Alex Williamson
186bfe44 6ba59ff4

+46 -60
+46 -60
drivers/vfio/pci/vfio_pci_rdwr.c
··· 90 90 VFIO_IOREAD(16) 91 91 VFIO_IOREAD(32) 92 92 93 + #define VFIO_IORDWR(size) \ 94 + static int vfio_pci_iordwr##size(struct vfio_pci_core_device *vdev,\ 95 + bool iswrite, bool test_mem, \ 96 + void __iomem *io, char __user *buf, \ 97 + loff_t off, size_t *filled) \ 98 + { \ 99 + u##size val; \ 100 + int ret; \ 101 + \ 102 + if (iswrite) { \ 103 + if (copy_from_user(&val, buf, sizeof(val))) \ 104 + return -EFAULT; \ 105 + \ 106 + ret = vfio_pci_core_iowrite##size(vdev, test_mem, \ 107 + val, io + off); \ 108 + if (ret) \ 109 + return ret; \ 110 + } else { \ 111 + ret = vfio_pci_core_ioread##size(vdev, test_mem, \ 112 + &val, io + off); \ 113 + if (ret) \ 114 + return ret; \ 115 + \ 116 + if (copy_to_user(buf, &val, sizeof(val))) \ 117 + return -EFAULT; \ 118 + } \ 119 + \ 120 + *filled = sizeof(val); \ 121 + return 0; \ 122 + } \ 123 + 124 + VFIO_IORDWR(8) 125 + VFIO_IORDWR(16) 126 + VFIO_IORDWR(32) 93 127 /* 94 128 * Read or write from an __iomem region (MMIO or I/O port) with an excluded 95 129 * range which is inaccessible. The excluded range drops writes and fills ··· 149 115 fillable = 0; 150 116 151 117 if (fillable >= 4 && !(off % 4)) { 152 - u32 val; 118 + ret = vfio_pci_iordwr32(vdev, iswrite, test_mem, 119 + io, buf, off, &filled); 120 + if (ret) 121 + return ret; 153 122 154 - if (iswrite) { 155 - if (copy_from_user(&val, buf, 4)) 156 - return -EFAULT; 157 - 158 - ret = vfio_pci_core_iowrite32(vdev, test_mem, 159 - val, io + off); 160 - if (ret) 161 - return ret; 162 - } else { 163 - ret = vfio_pci_core_ioread32(vdev, test_mem, 164 - &val, io + off); 165 - if (ret) 166 - return ret; 167 - 168 - if (copy_to_user(buf, &val, 4)) 169 - return -EFAULT; 170 - } 171 - 172 - filled = 4; 173 123 } else if (fillable >= 2 && !(off % 2)) { 174 - u16 val; 124 + ret = vfio_pci_iordwr16(vdev, iswrite, test_mem, 125 + io, buf, off, &filled); 126 + if (ret) 127 + return ret; 175 128 176 - if (iswrite) { 177 - if (copy_from_user(&val, buf, 2)) 178 - return -EFAULT; 179 - 180 - ret = vfio_pci_core_iowrite16(vdev, test_mem, 181 - val, io + off); 182 - if (ret) 183 - return ret; 184 - } else { 185 - ret = vfio_pci_core_ioread16(vdev, test_mem, 186 - &val, io + off); 187 - if (ret) 188 - return ret; 189 - 190 - if (copy_to_user(buf, &val, 2)) 191 - return -EFAULT; 192 - } 193 - 194 - filled = 2; 195 129 } else if (fillable) { 196 - u8 val; 130 + ret = vfio_pci_iordwr8(vdev, iswrite, test_mem, 131 + io, buf, off, &filled); 132 + if (ret) 133 + return ret; 197 134 198 - if (iswrite) { 199 - if (copy_from_user(&val, buf, 1)) 200 - return -EFAULT; 201 - 202 - ret = vfio_pci_core_iowrite8(vdev, test_mem, 203 - val, io + off); 204 - if (ret) 205 - return ret; 206 - } else { 207 - ret = vfio_pci_core_ioread8(vdev, test_mem, 208 - &val, io + off); 209 - if (ret) 210 - return ret; 211 - 212 - if (copy_to_user(buf, &val, 1)) 213 - return -EFAULT; 214 - } 215 - 216 - filled = 1; 217 135 } else { 218 136 /* Fill reads with -1, drop writes */ 219 137 filled = min(count, (size_t)(x_end - off));