mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 21:51:40 +00:00
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>
This commit is contained in:
parent
6ba59ff422
commit
186bfe44ea
@ -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;
|
||||
ret = vfio_pci_iordwr32(vdev, iswrite, test_mem,
|
||||
io, buf, off, &filled);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
filled = 4;
|
||||
} else if (fillable >= 2 && !(off % 2)) {
|
||||
u16 val;
|
||||
ret = vfio_pci_iordwr16(vdev, iswrite, test_mem,
|
||||
io, buf, off, &filled);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
filled = 2;
|
||||
} else if (fillable) {
|
||||
u8 val;
|
||||
ret = vfio_pci_iordwr8(vdev, iswrite, test_mem,
|
||||
io, buf, off, &filled);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
filled = 1;
|
||||
} else {
|
||||
/* Fill reads with -1, drop writes */
|
||||
filled = min(count, (size_t)(x_end - off));
|
||||
|
Loading…
Reference in New Issue
Block a user