diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-07-19 21:53:09 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-07-19 21:53:09 +0300 |
commit | f66b07c56119833b88bffa4ecaf9f983834675de (patch) | |
tree | ecedbc44ba3270000fdfdde767c5872f98637fa6 /drivers/vfio | |
parent | 4305ca0087dd99c3c3e0e2ac8a228b7e53a21c78 (diff) | |
parent | 0756bec2e45b206ccb5fc3e8791c08d696dd06f7 (diff) | |
download | linux-f66b07c56119833b88bffa4ecaf9f983834675de.tar.xz |
Merge tag 'vfio-v6.11-rc1' of https://github.com/awilliam/linux-vfio
Pull VFIO updates from Alex Williamson:
- Add support for 8-byte accesses when using read/write through the
device regions. This fills a gap for userspace drivers that might
not be able to use access through mmap to perform native register
width accesses (Gerd Bayer)
- Add missing MODULE_DESCRIPTION to vfio-mdev sample drivers and
replace a non-standard MODULE_INFO usage (Jeff Johnson)
* tag 'vfio-v6.11-rc1' of https://github.com/awilliam/linux-vfio:
vfio-mdev: add missing MODULE_DESCRIPTION() macros
vfio/pci: Fix typo in macro to declare accessors
vfio/pci: Support 8-byte PCI loads and stores
vfio/pci: Extract duplicated code into macro
Diffstat (limited to 'drivers/vfio')
-rw-r--r-- | drivers/vfio/pci/vfio_pci_rdwr.c | 122 |
1 files changed, 62 insertions, 60 deletions
diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c index 03b8f7ada1ac..66b72c289284 100644 --- a/drivers/vfio/pci/vfio_pci_rdwr.c +++ b/drivers/vfio/pci/vfio_pci_rdwr.c @@ -89,6 +89,47 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_ioread##size); VFIO_IOREAD(8) VFIO_IOREAD(16) VFIO_IOREAD(32) +#ifdef ioread64 +VFIO_IOREAD(64) +#endif + +#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) +#if defined(ioread64) && defined(iowrite64) +VFIO_IORDWR(64) +#endif /* * Read or write from an __iomem region (MMIO or I/O port) with an excluded @@ -114,72 +155,33 @@ ssize_t vfio_pci_core_do_io_rw(struct vfio_pci_core_device *vdev, bool test_mem, else fillable = 0; +#if defined(ioread64) && defined(iowrite64) + if (fillable >= 8 && !(off % 8)) { + ret = vfio_pci_iordwr64(vdev, iswrite, test_mem, + io, buf, off, &filled); + if (ret) + return ret; + + } else +#endif 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)); |