From: Keith Busch <kbusch@meta.com>
To: <kvm@vger.kernel.org>
Cc: <alex.williamson@redhat.com>, <jgg@ziepe.ca>,
Keith Busch <kbusch@kernel.org>
Subject: [PATCH rfc] vfio-pci: Allow write combining
Date: Wed, 31 Jul 2024 08:53:52 -0700 [thread overview]
Message-ID: <20240731155352.3973857-1-kbusch@meta.com> (raw)
From: Keith Busch <kbusch@kernel.org>
Write combining can be provide performance improvement for places that
can safely use this capability.
Previous discussions on the topic suggest a vfio user needs to
explicitly request such a mapping, and it sounds like a new vfio
specific ioctl to request this is one way recommended way to do that.
This patch implements a new ioctl to achieve that so a user can request
write combining on prefetchable memory. A new ioctl seems a bit much for
just this purpose, so the implementation here provides a "flags" field
with only the write combine option defined. The rest of the bits are
reserved for future use.
Link: https://lore.kernel.org/all/20171009025000.39435-1-aik@ozlabs.ru/
Link: https://lore.kernel.org/lkml/ZLFBnACjoTbDmKuU@nvidia.com/
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
drivers/vfio/pci/vfio_pci_core.c | 39 +++++++++++++++++++++++++++++++-
include/linux/vfio_pci_core.h | 1 +
include/uapi/linux/vfio.h | 17 ++++++++++++++
3 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index ba0ce0075b2fb..c275c95eafe32 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -1042,12 +1042,18 @@ static int vfio_pci_ioctl_get_region_info(struct vfio_pci_core_device *vdev,
info.flags = VFIO_REGION_INFO_FLAG_READ |
VFIO_REGION_INFO_FLAG_WRITE;
if (vdev->bar_mmap_supported[info.index]) {
+ struct resource *res;
+
info.flags |= VFIO_REGION_INFO_FLAG_MMAP;
if (info.index == vdev->msix_bar) {
ret = msix_mmappable_cap(vdev, &caps);
if (ret)
return ret;
}
+
+ res = &vdev->pdev->resource[index];
+ if (res->flags & IORESOURCE_PREFETCH)
+ info.flags |= VFIO_REGION_INFO_FLAG_PREFETCH;
}
break;
@@ -1223,6 +1229,32 @@ static int vfio_pci_ioctl_set_irqs(struct vfio_pci_core_device *vdev,
return ret;
}
+static int vfio_pci_ioctl_set_region_flags(struct vfio_pci_core_device *vdev,
+ struct vfio_region_flags __user *arg)
+{
+ struct vfio_region_flags region_flags;
+ struct resource *res;
+ u32 index;
+
+ if (copy_from_user(®ion_flags, arg, sizeof(region_flags)))
+ return -EFAULT;
+
+ index = region_flags.index;
+ if (index >= PCI_STD_NUM_BARS)
+ return -EINVAL;
+
+ if (region_flags.flags & VFIO_REGION_FLAG_WRITE_COMBINE) {
+ res = &vdev->pdev->resource[index];
+ if (!(res->flags & IORESOURCE_MEM) ||
+ !(res->flags & IORESOURCE_PREFETCH))
+ return -EINVAL;
+ vdev->bar_write_combine[index] = true;
+ } else
+ vdev->bar_write_combine[index] = false;
+
+ return 0;
+}
+
static int vfio_pci_ioctl_reset(struct vfio_pci_core_device *vdev,
void __user *arg)
{
@@ -1484,6 +1516,8 @@ long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd,
return vfio_pci_ioctl_reset(vdev, uarg);
case VFIO_DEVICE_SET_IRQS:
return vfio_pci_ioctl_set_irqs(vdev, uarg);
+ case VFIO_DEVICE_SET_REGION_FLAGS:
+ return vfio_pci_ioctl_set_region_flags(vdev, uarg);
default:
return -ENOTTY;
}
@@ -1756,7 +1790,10 @@ int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma
}
vma->vm_private_data = vdev;
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ if (vdev->bar_write_combine[index])
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+ else
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
/*
diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h
index fbb472dd99b36..0e0122ce4196a 100644
--- a/include/linux/vfio_pci_core.h
+++ b/include/linux/vfio_pci_core.h
@@ -54,6 +54,7 @@ struct vfio_pci_core_device {
struct pci_dev *pdev;
void __iomem *barmap[PCI_STD_NUM_BARS];
bool bar_mmap_supported[PCI_STD_NUM_BARS];
+ bool bar_write_combine[PCI_STD_NUM_BARS];
u8 *pci_config_map;
u8 *vconfig;
struct perm_bits *msi_perm;
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 2b68e6cdf1902..5537b20b23541 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -275,6 +275,7 @@ struct vfio_region_info {
#define VFIO_REGION_INFO_FLAG_WRITE (1 << 1) /* Region supports write */
#define VFIO_REGION_INFO_FLAG_MMAP (1 << 2) /* Region supports mmap */
#define VFIO_REGION_INFO_FLAG_CAPS (1 << 3) /* Info supports caps */
+#define VFIO_REGION_INFO_FLAG_PREFETCH (1 << 4) /* Region is prefetchable */
__u32 index; /* Region index */
__u32 cap_offset; /* Offset within info struct of first cap */
__aligned_u64 size; /* Region size (bytes) */
@@ -1821,6 +1822,22 @@ struct vfio_iommu_spapr_tce_remove {
};
#define VFIO_IOMMU_SPAPR_TCE_REMOVE _IO(VFIO_TYPE, VFIO_BASE + 20)
+/**
+ * VFIO_DEVICE_SET_REGION_FLAGS - _IOW(VFIO_TYPE, VFIO_BASE + 21, struct vfio_region_flags)
+ *
+ * Set mapping options for the region
+ *
+ * Flags supported:
+ * - VFIO_REGION_FLAG_WRITE_COMBINE: use write-combine when requested to map
+ * this region. Supported only if the region is prefetchable.
+ */
+struct vfio_region_flags {
+ __u32 index; /* Region index */
+ __u32 flags; /* Region flags */
+#define VFIO_REGION_FLAG_WRITE_COMBINE (1 << 0)
+};
+#define VFIO_DEVICE_SET_REGION_FLAGS _IO(VFIO_TYPE, VFIO_BASE + 21)
+
/* ***************************************************************** */
#endif /* _UAPIVFIO_H */
--
2.43.5
next reply other threads:[~2024-07-31 15:53 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-31 15:53 Keith Busch [this message]
2024-08-01 14:19 ` [PATCH rfc] vfio-pci: Allow write combining Jason Gunthorpe
2024-08-01 15:41 ` Alex Williamson
2024-08-01 16:11 ` Jason Gunthorpe
2024-08-01 16:52 ` Alex Williamson
2024-08-01 17:13 ` Jason Gunthorpe
2024-08-01 17:33 ` Alex Williamson
2024-08-01 17:53 ` Jason Gunthorpe
2024-08-01 18:16 ` Alex Williamson
2024-08-02 11:53 ` Jason Gunthorpe
2024-08-02 17:05 ` Alex Williamson
2024-08-06 16:53 ` Jason Gunthorpe
2024-08-06 18:43 ` Alex Williamson
2024-08-07 14:19 ` Jason Gunthorpe
2024-08-07 17:46 ` Alex Williamson
2024-08-13 18:02 ` Jason Gunthorpe
2024-08-02 14:24 ` Keith Busch
2024-08-02 14:33 ` Jason Gunthorpe
2024-08-06 7:19 ` Tian, Kevin
2024-08-06 16:47 ` Jason Gunthorpe
2024-08-15 5:05 ` Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240731155352.3973857-1-kbusch@meta.com \
--to=kbusch@meta.com \
--cc=alex.williamson@redhat.com \
--cc=jgg@ziepe.ca \
--cc=kbusch@kernel.org \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.