* [PATCH v4 0/3] vfio/pci: Support 8-byte PCI loads and stores
@ 2024-05-22 15:06 Gerd Bayer
2024-05-22 15:06 ` [PATCH v4 1/3] vfio/pci: Extract duplicated code into macro Gerd Bayer
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Gerd Bayer @ 2024-05-22 15:06 UTC (permalink / raw)
To: Alex Williamson, Jason Gunthorpe, Niklas Schnelle, Ramesh Thomas
Cc: kvm, linux-s390, Ankit Agrawal, Yishai Hadas, Halil Pasic,
Julian Ruess, Gerd Bayer
Hi all,
this all started with a single patch by Ben to enable writing a user-mode
driver for a PCI device that requires 64bit register read/writes on s390.
A quick grep showed that there are several other drivers for PCI devices
in the kernel that use readq/writeq and eventually could use this, too.
So we decided to propose this for general inclusion.
A couple of suggestions for refactorizations by Jason Gunthorpe and Alex
Williamson later [1], I arrived at this little series that avoids some
code duplication in vfio_pci_core_do_io_rw().
Also, I've added a small patch to correct the spelling in one of the
declaration macros that was suggested by Ramesh Thomas [2].
This version was tested with a pass-through PCI device in a KVM guest
and with explicit test reads of size 8, 16, 32, and 64 bit on
s390. For 32bit architectures this has only been compile tested for the
32bit ARM architecture.
Thank you,
Gerd Bayer
[1] https://lore.kernel.org/all/20240422153508.2355844-1-gbayer@linux.ibm.com/
[2] https://lore.kernel.org/kvm/20240425165604.899447-1-gbayer@linux.ibm.com/T/#m1b51fe155c60d04313695fbee11a2ccea856a98c
Changes v3 -> v4:
- Make 64-bit accessors depend on CONFIG_64BIT (for x86, too).
- Drop conversion of if-else if chain to switch-case.
- Add patch to fix spelling of declaration macro.
Changes v2 -> v3:
- Introduce macro to generate body of different-size accesses in
vfio_pci_core_do_io_rw (courtesy Alex Williamson).
- Convert if-else if chain to a switch-case construct to better
accommodate conditional compiles.
Changes v1 -> v2:
- On non 64bit architecture use at most 32bit accesses in
vfio_pci_core_do_io_rw and describe that in the commit message.
- Drop the run-time error on 32bit architectures.
- The #endif splitting the "else if" is not really fortunate, but I'm
open to suggestions.
Ben Segal (1):
vfio/pci: Support 8-byte PCI loads and stores
Gerd Bayer (2):
vfio/pci: Extract duplicated code into macro
vfio/pci: Fix typo in macro to declare accessors
drivers/vfio/pci/vfio_pci_rdwr.c | 124 ++++++++++++++++---------------
include/linux/vfio_pci_core.h | 27 ++++---
2 files changed, 78 insertions(+), 73 deletions(-)
--
2.45.0
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH v4 1/3] vfio/pci: Extract duplicated code into macro 2024-05-22 15:06 [PATCH v4 0/3] vfio/pci: Support 8-byte PCI loads and stores Gerd Bayer @ 2024-05-22 15:06 ` Gerd Bayer 2024-05-22 15:06 ` [PATCH v4 2/3] vfio/pci: Support 8-byte PCI loads and stores Gerd Bayer 2024-05-22 15:06 ` [PATCH v4 3/3] vfio/pci: Fix typo in macro to declare accessors Gerd Bayer 2 siblings, 0 replies; 10+ messages in thread From: Gerd Bayer @ 2024-05-22 15:06 UTC (permalink / raw) To: Alex Williamson, Jason Gunthorpe, Niklas Schnelle, Ramesh Thomas Cc: kvm, linux-s390, Ankit Agrawal, Yishai Hadas, Halil Pasic, Julian Ruess, Gerd Bayer 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> --- drivers/vfio/pci/vfio_pci_rdwr.c | 106 ++++++++++++++----------------- 1 file 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)); -- 2.45.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 2/3] vfio/pci: Support 8-byte PCI loads and stores 2024-05-22 15:06 [PATCH v4 0/3] vfio/pci: Support 8-byte PCI loads and stores Gerd Bayer 2024-05-22 15:06 ` [PATCH v4 1/3] vfio/pci: Extract duplicated code into macro Gerd Bayer @ 2024-05-22 15:06 ` Gerd Bayer 2024-05-22 23:38 ` Ramesh Thomas 2024-05-23 15:10 ` Gerd Bayer 2024-05-22 15:06 ` [PATCH v4 3/3] vfio/pci: Fix typo in macro to declare accessors Gerd Bayer 2 siblings, 2 replies; 10+ messages in thread From: Gerd Bayer @ 2024-05-22 15:06 UTC (permalink / raw) To: Alex Williamson, Jason Gunthorpe, Niklas Schnelle, Ramesh Thomas Cc: kvm, linux-s390, Ankit Agrawal, Yishai Hadas, Halil Pasic, Julian Ruess, Ben Segal, Gerd Bayer From: Ben Segal <bpsegal@us.ibm.com> Many PCI adapters can benefit or even require full 64bit read and write access to their registers. In order to enable work on user-space drivers for these devices add two new variations vfio_pci_core_io{read|write}64 of the existing access methods when the architecture supports 64-bit ioreads and iowrites. Signed-off-by: Ben Segal <bpsegal@us.ibm.com> Co-developed-by: Gerd Bayer <gbayer@linux.ibm.com> Signed-off-by: Gerd Bayer <gbayer@linux.ibm.com> --- drivers/vfio/pci/vfio_pci_rdwr.c | 18 +++++++++++++++++- include/linux/vfio_pci_core.h | 5 ++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c index d07bfb0ab892..07351ea76604 100644 --- a/drivers/vfio/pci/vfio_pci_rdwr.c +++ b/drivers/vfio/pci/vfio_pci_rdwr.c @@ -61,7 +61,7 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_iowrite##size); VFIO_IOWRITE(8) VFIO_IOWRITE(16) VFIO_IOWRITE(32) -#ifdef iowrite64 +#ifdef CONFIG_64BIT VFIO_IOWRITE(64) #endif @@ -89,6 +89,9 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_ioread##size); VFIO_IOREAD(8) VFIO_IOREAD(16) VFIO_IOREAD(32) +#ifdef CONFIG_64BIT +VFIO_IOREAD(64) +#endif #define VFIO_IORDWR(size) \ static int vfio_pci_iordwr##size(struct vfio_pci_core_device *vdev,\ @@ -124,6 +127,10 @@ static int vfio_pci_iordwr##size(struct vfio_pci_core_device *vdev,\ VFIO_IORDWR(8) VFIO_IORDWR(16) VFIO_IORDWR(32) +#if CONFIG_64BIT +VFIO_IORDWR(64) +#endif + /* * 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 @@ -148,6 +155,15 @@ ssize_t vfio_pci_core_do_io_rw(struct vfio_pci_core_device *vdev, bool test_mem, else fillable = 0; +#if CONFIG_64BIT + 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)) { ret = vfio_pci_iordwr32(vdev, iswrite, test_mem, io, buf, off, &filled); diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h index a2c8b8bba711..5f9b02d4a3e9 100644 --- a/include/linux/vfio_pci_core.h +++ b/include/linux/vfio_pci_core.h @@ -146,7 +146,7 @@ int vfio_pci_core_iowrite##size(struct vfio_pci_core_device *vdev, \ VFIO_IOWRITE_DECLATION(8) VFIO_IOWRITE_DECLATION(16) VFIO_IOWRITE_DECLATION(32) -#ifdef iowrite64 +#ifdef CONFIG_64BIT VFIO_IOWRITE_DECLATION(64) #endif @@ -157,5 +157,8 @@ int vfio_pci_core_ioread##size(struct vfio_pci_core_device *vdev, \ VFIO_IOREAD_DECLATION(8) VFIO_IOREAD_DECLATION(16) VFIO_IOREAD_DECLATION(32) +#ifdef CONFIG_64BIT +VFIO_IOREAD_DECLATION(64) +#endif #endif /* VFIO_PCI_CORE_H */ -- 2.45.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v4 2/3] vfio/pci: Support 8-byte PCI loads and stores 2024-05-22 15:06 ` [PATCH v4 2/3] vfio/pci: Support 8-byte PCI loads and stores Gerd Bayer @ 2024-05-22 23:38 ` Ramesh Thomas 2024-05-23 15:01 ` Gerd Bayer 2024-05-23 15:10 ` Gerd Bayer 1 sibling, 1 reply; 10+ messages in thread From: Ramesh Thomas @ 2024-05-22 23:38 UTC (permalink / raw) To: Gerd Bayer, Alex Williamson, Jason Gunthorpe, Niklas Schnelle Cc: kvm, linux-s390, Ankit Agrawal, Yishai Hadas, Halil Pasic, Julian Ruess, Ben Segal The removal of the check for iowrite64 and ioread64 causes build error because those macros don't get defined anywhere if CONFIG_GENERIC_IOMAP is not defined. However, I do think the removal of the checks is correct. It is better to include linux/io-64-nonatomic-lo-hi.h which define those macros mapping to generic implementations in lib/iomap.c. If the architecture does not implement 64 bit rw functions (readq/writeq), then it does 32 bit back to back. I have sent a patch with the change that includes the above header file. Please review and include in this patch series if ok. Thanks, Ramesh On 5/22/2024 8:06 AM, Gerd Bayer wrote: > From: Ben Segal <bpsegal@us.ibm.com> > > Many PCI adapters can benefit or even require full 64bit read > and write access to their registers. In order to enable work on > user-space drivers for these devices add two new variations > vfio_pci_core_io{read|write}64 of the existing access methods > when the architecture supports 64-bit ioreads and iowrites. > > Signed-off-by: Ben Segal <bpsegal@us.ibm.com> > Co-developed-by: Gerd Bayer <gbayer@linux.ibm.com> > Signed-off-by: Gerd Bayer <gbayer@linux.ibm.com> > --- > drivers/vfio/pci/vfio_pci_rdwr.c | 18 +++++++++++++++++- > include/linux/vfio_pci_core.h | 5 ++++- > 2 files changed, 21 insertions(+), 2 deletions(-) > > diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c > index d07bfb0ab892..07351ea76604 100644 > --- a/drivers/vfio/pci/vfio_pci_rdwr.c > +++ b/drivers/vfio/pci/vfio_pci_rdwr.c > @@ -61,7 +61,7 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_iowrite##size); > VFIO_IOWRITE(8) > VFIO_IOWRITE(16) > VFIO_IOWRITE(32) > -#ifdef iowrite64 > +#ifdef CONFIG_64BIT > VFIO_IOWRITE(64) > #endif > > @@ -89,6 +89,9 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_ioread##size); > VFIO_IOREAD(8) > VFIO_IOREAD(16) > VFIO_IOREAD(32) > +#ifdef CONFIG_64BIT > +VFIO_IOREAD(64) > +#endif > > #define VFIO_IORDWR(size) \ > static int vfio_pci_iordwr##size(struct vfio_pci_core_device *vdev,\ > @@ -124,6 +127,10 @@ static int vfio_pci_iordwr##size(struct vfio_pci_core_device *vdev,\ > VFIO_IORDWR(8) > VFIO_IORDWR(16) > VFIO_IORDWR(32) > +#if CONFIG_64BIT > +VFIO_IORDWR(64) > +#endif > + > /* > * 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 > @@ -148,6 +155,15 @@ ssize_t vfio_pci_core_do_io_rw(struct vfio_pci_core_device *vdev, bool test_mem, > else > fillable = 0; > > +#if CONFIG_64BIT > + 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)) { > ret = vfio_pci_iordwr32(vdev, iswrite, test_mem, > io, buf, off, &filled); > diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h > index a2c8b8bba711..5f9b02d4a3e9 100644 > --- a/include/linux/vfio_pci_core.h > +++ b/include/linux/vfio_pci_core.h > @@ -146,7 +146,7 @@ int vfio_pci_core_iowrite##size(struct vfio_pci_core_device *vdev, \ > VFIO_IOWRITE_DECLATION(8) > VFIO_IOWRITE_DECLATION(16) > VFIO_IOWRITE_DECLATION(32) > -#ifdef iowrite64 > +#ifdef CONFIG_64BIT > VFIO_IOWRITE_DECLATION(64) > #endif > > @@ -157,5 +157,8 @@ int vfio_pci_core_ioread##size(struct vfio_pci_core_device *vdev, \ > VFIO_IOREAD_DECLATION(8) > VFIO_IOREAD_DECLATION(16) > VFIO_IOREAD_DECLATION(32) > +#ifdef CONFIG_64BIT > +VFIO_IOREAD_DECLATION(64) > +#endif > > #endif /* VFIO_PCI_CORE_H */ ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 2/3] vfio/pci: Support 8-byte PCI loads and stores 2024-05-22 23:38 ` Ramesh Thomas @ 2024-05-23 15:01 ` Gerd Bayer 2024-05-23 21:47 ` Ramesh Thomas 0 siblings, 1 reply; 10+ messages in thread From: Gerd Bayer @ 2024-05-23 15:01 UTC (permalink / raw) To: Ramesh Thomas, Alex Williamson, Jason Gunthorpe, Niklas Schnelle Cc: kvm, linux-s390, Ankit Agrawal, Yishai Hadas, Halil Pasic, Julian Ruess, Ben Segal Hi Ramesh, On Wed, 2024-05-22 at 16:38 -0700, Ramesh Thomas wrote: > The removal of the check for iowrite64 and ioread64 causes build > error because those macros don't get defined anywhere if > CONFIG_GENERIC_IOMAP is not defined. However, I do think the removal > of the checks is correct. Wait, I believe it is the other way around. If your config *is* specifying CONFIG_GENERIC_IOMAP, lib/iomap.c will provide implementations for back-to-back 32bit operations to emulate 64bit accesses - and you have to "select" which of the two types of emulation (hi/lo or lo/hi order) get mapped onto ioread64(be) or iowrite64(be) by including linux/io-64-nonatomic-lo-hi.h (or -hi-lo.h). > It is better to include linux/io-64-nonatomic-lo-hi.h which define > those macros mapping to generic implementations in lib/iomap.c. If > the architecture does not implement 64 bit rw functions > (readq/writeq), then it does 32 bit back to back. I have sent a > patch with the change that includes the above header file. Please > review and include in this patch series if ok. I did find your patch, thank you. I had a very hard time to find a kernel config that actually showed the unresolved symbols situation: Some 64bit MIPS config, that relied on GENERIC_IOMAP. And with your patch applied, I could compile successfully. Do you have an easier way steer a kernel config into this dead-end? > Thanks, > Ramesh Frankly, I'd rather not make any assumptions in this rather generic vfio/pci layer about whether hi-lo or lo-hi is the right order to emulate a 64bit access when the base architecture does not support 64bit accesses naturally. So, if CONFIG_64BIT is no guarantee that there's a definitive implementation of ioread64/iowrite64, I'd rather revert to make the conditional compiles depend on those definitions. But maybe Alex has an opinion on this, too? Thanks, Gerd ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 2/3] vfio/pci: Support 8-byte PCI loads and stores 2024-05-23 15:01 ` Gerd Bayer @ 2024-05-23 21:47 ` Ramesh Thomas 2024-05-24 13:42 ` Gerd Bayer 0 siblings, 1 reply; 10+ messages in thread From: Ramesh Thomas @ 2024-05-23 21:47 UTC (permalink / raw) To: Gerd Bayer, Alex Williamson, Jason Gunthorpe, Niklas Schnelle Cc: kvm, linux-s390, Ankit Agrawal, Yishai Hadas, Halil Pasic, Julian Ruess, Ben Segal On 5/23/2024 8:01 AM, Gerd Bayer wrote: > Hi Ramesh, > > On Wed, 2024-05-22 at 16:38 -0700, Ramesh Thomas wrote: >> The removal of the check for iowrite64 and ioread64 causes build >> error because those macros don't get defined anywhere if >> CONFIG_GENERIC_IOMAP is not defined. However, I do think the removal >> of the checks is correct. > > Wait, I believe it is the other way around. If your config *is* > specifying CONFIG_GENERIC_IOMAP, lib/iomap.c will provide > implementations for back-to-back 32bit operations to emulate 64bit > accesses - and you have to "select" which of the two types of emulation > (hi/lo or lo/hi order) get mapped onto ioread64(be) or iowrite64(be) by > including linux/io-64-nonatomic-lo-hi.h (or -hi-lo.h). Sorry, yes I meant to write they don't get defined anywhere in your code path if CONFIG_GENERIC_IOMAP *is defined*. The only place in your code path where iowrit64 and ioread64 get defined is in asm/io.h. Those definitions are surrounded by #ifndef CONFIG_GENERIC_IOMAP. CONFIG_GENERIC_IOMAP gets defined for x86. > >> It is better to include linux/io-64-nonatomic-lo-hi.h which define >> those macros mapping to generic implementations in lib/iomap.c. If >> the architecture does not implement 64 bit rw functions >> (readq/writeq), then it does 32 bit back to back. I have sent a >> patch with the change that includes the above header file. Please >> review and include in this patch series if ok. > > I did find your patch, thank you. I had a very hard time to find a > kernel config that actually showed the unresolved symbols situation: > Some 64bit MIPS config, that relied on GENERIC_IOMAP. And with your > patch applied, I could compile successfully. > Do you have an easier way steer a kernel config into this dead-end? The generic implementation takes care of all conditions. I guess some build bot would report error on build failures. But checks like #ifdef iowrite64 would hide the missing definitions error. > >> Thanks, >> Ramesh > > Frankly, I'd rather not make any assumptions in this rather generic > vfio/pci layer about whether hi-lo or lo-hi is the right order to > emulate a 64bit access when the base architecture does not support > 64bit accesses naturally. So, if CONFIG_64BIT is no guarantee that > there's a definitive implementation of ioread64/iowrite64, I'd rather There is already an assumption of the order in the current implementation regardless e.g. vfio_pci_core_do_io_rw(). If there is no iowrite64 found, the code does back to back 34 bit writes without checking for any particular order requirements. io-64-nonatomic-lo-hi.h and io-64-nonatomic-hi-lo.h would define ioread64/iowrite64 only if they are not already defined in asm/io.h. Also since there is a check for CONFIG_64BIT, most likely a 64 bit readq/writeq will get used in the lib/iomap.c implementations. I think we can pick either lo-hi or hi-lo for the unlikely 32 bit fall through when CONFIG_64BIT is defined. > revert to make the conditional compiles depend on those definitions. > > But maybe Alex has an opinion on this, too? > > Thanks, > Gerd > > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 2/3] vfio/pci: Support 8-byte PCI loads and stores 2024-05-23 21:47 ` Ramesh Thomas @ 2024-05-24 13:42 ` Gerd Bayer 2024-05-29 3:45 ` Ramesh Thomas 0 siblings, 1 reply; 10+ messages in thread From: Gerd Bayer @ 2024-05-24 13:42 UTC (permalink / raw) To: Ramesh Thomas, Alex Williamson, Jason Gunthorpe, Niklas Schnelle, Tian, Kevin Cc: kvm, linux-s390, Ankit Agrawal, Yishai Hadas, Halil Pasic, Julian Ruess, Ben Segal On Thu, 2024-05-23 at 14:47 -0700, Ramesh Thomas wrote: > On 5/23/2024 8:01 AM, Gerd Bayer wrote: > > Hi Ramesh, > > > > On Wed, 2024-05-22 at 16:38 -0700, Ramesh Thomas wrote: > > > The removal of the check for iowrite64 and ioread64 causes build > > > error because those macros don't get defined anywhere if > > > CONFIG_GENERIC_IOMAP is not defined. However, I do think the > > > removal of the checks is correct. > > > > Wait, I believe it is the other way around. If your config *is* > > specifying CONFIG_GENERIC_IOMAP, lib/iomap.c will provide > > implementations for back-to-back 32bit operations to emulate 64bit > > accesses - and you have to "select" which of the two types of > > emulation (hi/lo or lo/hi order) get mapped onto ioread64(be) or > > iowrite64(be) by including linux/io-64-nonatomic-lo-hi.h (or -hi- > > lo.h). > > Sorry, yes I meant to write they don't get defined anywhere in your > code path if CONFIG_GENERIC_IOMAP *is defined*. The only place in > your code path where iowrit64 and ioread64 get defined is in > asm/io.h. Those definitions are surrounded by #ifndef > CONFIG_GENERIC_IOMAP. CONFIG_GENERIC_IOMAP gets defined for x86. Now I got it - I think. And I see that plain x86 is aleady affected by this issue. > > > It is better to include linux/io-64-nonatomic-lo-hi.h which > > > define those macros mapping to generic implementations in > > > lib/iomap.c. > > > If the architecture does not implement 64 bit rw functions > > > (readq/writeq), then it does 32 bit back to back. I have sent a > > > patch with the change that includes the above header file. Please > > > review and include in this patch series if ok. > > > > I did find your patch, thank you. I had a very hard time to find a > > kernel config that actually showed the unresolved symbols > > situation: > > Some 64bit MIPS config, that relied on GENERIC_IOMAP. And with your > > patch applied, I could compile successfully. > > Do you have an easier way steer a kernel config into this dead-end? > > The generic implementation takes care of all conditions. I guess some > build bot would report error on build failures. But checks like > #ifdef iowrite64 would hide the missing definitions error. Yes definitely, we need to avoid this. > > > > > Thanks, > > > Ramesh > > > > Frankly, I'd rather not make any assumptions in this rather generic > > vfio/pci layer about whether hi-lo or lo-hi is the right order to > > > emulate a 64bit access when the base architecture does not support > > 64bit accesses naturally. So, if CONFIG_64BIT is no guarantee that > > there's a definitive implementation of ioread64/iowrite64, I'd > > rather > > There is already an assumption of the order in the current > implementation regardless e.g. vfio_pci_core_do_io_rw(). If there is > no iowrite64 found, the code does back to back 34 bit writes without > checking for any particular order requirements. > > io-64-nonatomic-lo-hi.h and io-64-nonatomic-hi-lo.h would define > ioread64/iowrite64 only if they are not already defined in asm/io.h. > > Also since there is a check for CONFIG_64BIT, most likely a 64 bit > readq/writeq will get used in the lib/iomap.c implementations. I > think we can pick either lo-hi or hi-lo for the unlikely 32 bit fall > through when CONFIG_64BIT is defined. I dug into lib/iomap.c some more today and I see your point, that it is desireable to make the 64bit accessors useable through vfio/pci when they're implemented in lib/iomap.c. And I follow your argument that in most cases these will map onto readq/writeq - only programmed IO (PIO) has to emulate this with 2 32bit back-to-back accesses. If only the code in lib/iomap.c was structured differently - and made readq/writeq available under ioread64/iowrite64 proper and only fell back to the nonatomic hi-lo or lo-hi emulation with 32bit accesses if PIO is used. As much as I'd like to have it differently, it seems like it was a lengthy process to have that change accepted at the time: https://lore.kernel.org/all/20181106205234.25792-1-logang@deltatee.com/ I'm not sure if we can clean that up, easily. Plus there are appear to be plenty of users of io-64-nonatomic-{lo-hi|-hi-lo}.h in tree already - 103 and 18, resp. > > revert to make the conditional compiles depend on those > > definitions. But maybe Alex has an opinion on this, too? > > > > Thanks, > > Gerd So I'd like to hear from Alex and Tian (who was not a big fan) if we should support 64bit accessors in vfio/pci (primarily) on x86 with this series, or not at all, or split that work off, maybe? Thanks, Gerd ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 2/3] vfio/pci: Support 8-byte PCI loads and stores 2024-05-24 13:42 ` Gerd Bayer @ 2024-05-29 3:45 ` Ramesh Thomas 0 siblings, 0 replies; 10+ messages in thread From: Ramesh Thomas @ 2024-05-29 3:45 UTC (permalink / raw) To: Gerd Bayer, Alex Williamson, Jason Gunthorpe, Niklas Schnelle Cc: kvm, linux-s390, Ankit Agrawal, Yishai Hadas, Halil Pasic, Julian Ruess, Ben Segal, Tian, Kevin On 5/24/2024 6:42 AM, Gerd Bayer wrote: > On Thu, 2024-05-23 at 14:47 -0700, Ramesh Thomas wrote: >> On 5/23/2024 8:01 AM, Gerd Bayer wrote: >>> Hi Ramesh, >>> >>> On Wed, 2024-05-22 at 16:38 -0700, Ramesh Thomas wrote: >>>> The removal of the check for iowrite64 and ioread64 causes build >>>> error because those macros don't get defined anywhere if >>>> CONFIG_GENERIC_IOMAP is not defined. However, I do think the >>>> removal of the checks is correct. >>> >>> Wait, I believe it is the other way around. If your config *is* >>> specifying CONFIG_GENERIC_IOMAP, lib/iomap.c will provide >>> implementations for back-to-back 32bit operations to emulate 64bit >>> accesses - and you have to "select" which of the two types of >>> emulation (hi/lo or lo/hi order) get mapped onto ioread64(be) or >>> iowrite64(be) by including linux/io-64-nonatomic-lo-hi.h (or -hi- >>> lo.h). >> >> Sorry, yes I meant to write they don't get defined anywhere in your >> code path if CONFIG_GENERIC_IOMAP *is defined*. The only place in >> your code path where iowrit64 and ioread64 get defined is in >> asm/io.h. Those definitions are surrounded by #ifndef >> CONFIG_GENERIC_IOMAP. CONFIG_GENERIC_IOMAP gets defined for x86. > > Now I got it - I think. And I see that plain x86 is aleady affected by > this issue. > >>>> It is better to include linux/io-64-nonatomic-lo-hi.h which >>>> define those macros mapping to generic implementations in >>>> lib/iomap.c. >>>> If the architecture does not implement 64 bit rw functions >>>> (readq/writeq), then it does 32 bit back to back. I have sent a >>>> patch with the change that includes the above header file. Please >>>> review and include in this patch series if ok. >>> >>> I did find your patch, thank you. I had a very hard time to find a >>> kernel config that actually showed the unresolved symbols >>> situation: >>> Some 64bit MIPS config, that relied on GENERIC_IOMAP. And with your >>> patch applied, I could compile successfully. >>> Do you have an easier way steer a kernel config into this dead-end? >> >> The generic implementation takes care of all conditions. I guess some >> build bot would report error on build failures. But checks like >> #ifdef iowrite64 would hide the missing definitions error. > > Yes definitely, we need to avoid this. > >>> >>>> Thanks, >>>> Ramesh >>> >>> Frankly, I'd rather not make any assumptions in this rather generic >>> vfio/pci layer about whether hi-lo or lo-hi is the right order to > >>> emulate a 64bit access when the base architecture does not support >>> 64bit accesses naturally. So, if CONFIG_64BIT is no guarantee that >>> there's a definitive implementation of ioread64/iowrite64, I'd >>> rather >> >> There is already an assumption of the order in the current >> implementation regardless e.g. vfio_pci_core_do_io_rw(). If there is >> no iowrite64 found, the code does back to back 34 bit writes without >> checking for any particular order requirements. >> >> io-64-nonatomic-lo-hi.h and io-64-nonatomic-hi-lo.h would define >> ioread64/iowrite64 only if they are not already defined in asm/io.h. >> >> Also since there is a check for CONFIG_64BIT, most likely a 64 bit >> readq/writeq will get used in the lib/iomap.c implementations. I >> think we can pick either lo-hi or hi-lo for the unlikely 32 bit fall >> through when CONFIG_64BIT is defined. > > I dug into lib/iomap.c some more today and I see your point, that it is > desireable to make the 64bit accessors useable through vfio/pci when > they're implemented in lib/iomap.c. And I follow your argument that in > most cases these will map onto readq/writeq - only programmed IO (PIO) > has to emulate this with 2 32bit back-to-back accesses. > > If only the code in lib/iomap.c was structured differently - and made > readq/writeq available under ioread64/iowrite64 proper and only fell > back to the nonatomic hi-lo or lo-hi emulation with 32bit accesses if > PIO is used. It determines if it is PIO or MMIO based on the address. If the address is >= PIO_RESERVED then it calls readq/writeq. PIO_RESERVED is arch dependent. Looks like if asm/io.h didn't define ioread64/iowrite64 already, then the intention is to use the generic implementation, especially when it defines CONFIG_GENERIC_IOMAP. lib/iomap.c and io-64-nonatomic-{lo-hi|-hi-lo}.h include linux/io.h which includes asm/io.h. > > As much as I'd like to have it differently, it seems like it was a > lengthy process to have that change accepted at the time: > https://lore.kernel.org/all/20181106205234.25792-1-logang@deltatee.com/ > > I'm not sure if we can clean that up, easily. Plus there are appear to > be plenty of users of io-64-nonatomic-{lo-hi|-hi-lo}.h in tree already > - 103 and 18, resp. > >>> revert to make the conditional compiles depend on those >>> definitions. But maybe Alex has an opinion on this, too? >>> >>> Thanks, >>> Gerd > > So I'd like to hear from Alex and Tian (who was not a big fan) if we > should support 64bit accessors in vfio/pci (primarily) on x86 with this > series, or not at all, or split that work off, maybe? > > Thanks, > Gerd > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 2/3] vfio/pci: Support 8-byte PCI loads and stores 2024-05-22 15:06 ` [PATCH v4 2/3] vfio/pci: Support 8-byte PCI loads and stores Gerd Bayer 2024-05-22 23:38 ` Ramesh Thomas @ 2024-05-23 15:10 ` Gerd Bayer 1 sibling, 0 replies; 10+ messages in thread From: Gerd Bayer @ 2024-05-23 15:10 UTC (permalink / raw) To: Alex Williamson, Jason Gunthorpe, Niklas Schnelle, Ramesh Thomas Cc: kvm, linux-s390, Ankit Agrawal, Yishai Hadas, Halil Pasic, Julian Ruess, Ben Segal On Wed, 2024-05-22 at 17:06 +0200, Gerd Bayer wrote: > diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c > b/drivers/vfio/pci/vfio_pci_rdwr.c > index d07bfb0ab892..07351ea76604 100644 > --- a/drivers/vfio/pci/vfio_pci_rdwr.c > +++ b/drivers/vfio/pci/vfio_pci_rdwr.c > @@ -124,6 +127,10 @@ static int vfio_pci_iordwr##size(struct > vfio_pci_core_device *vdev,\ > VFIO_IORDWR(8) > VFIO_IORDWR(16) > VFIO_IORDWR(32) > +#if CONFIG_64BIT During my experimenations to reproduce Ramesh's complaint about unresolved symbols, I found that this should have been #ifdef > +VFIO_IORDWR(64) > +#endif > + > /* > * 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 > @@ -148,6 +155,15 @@ ssize_t vfio_pci_core_do_io_rw(struct > vfio_pci_core_device *vdev, bool test_mem, > else > fillable = 0; > > +#if CONFIG_64BIT ... as should this have been. > + 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)) { > ret = vfio_pci_iordwr32(vdev, iswrite, > test_mem, > io, buf, off, > &filled); > diff --git a/include/linux/vfio_pci_core.h > b/include/linux/vfio_pci_core.h > index a2c8b8bba711..5f9b02d4a3e9 100644 > --- a/include/linux/vfio_pci_core.h > +++ b/include/linux/vfio_pci_core.h > @@ -146,7 +146,7 @@ int vfio_pci_core_iowrite##size(struct > vfio_pci_core_device *vdev, \ > VFIO_IOWRITE_DECLATION(8) > VFIO_IOWRITE_DECLATION(16) > VFIO_IOWRITE_DECLATION(32) > -#ifdef iowrite64 > +#ifdef CONFIG_64BIT > VFIO_IOWRITE_DECLATION(64) > #endif > > @@ -157,5 +157,8 @@ int vfio_pci_core_ioread##size(struct > vfio_pci_core_device *vdev, \ > VFIO_IOREAD_DECLATION(8) > VFIO_IOREAD_DECLATION(16) > VFIO_IOREAD_DECLATION(32) > +#ifdef CONFIG_64BIT > +VFIO_IOREAD_DECLATION(64) > +#endif > > #endif /* VFIO_PCI_CORE_H */ So there will be a v5. Thanks, Gerd ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 3/3] vfio/pci: Fix typo in macro to declare accessors 2024-05-22 15:06 [PATCH v4 0/3] vfio/pci: Support 8-byte PCI loads and stores Gerd Bayer 2024-05-22 15:06 ` [PATCH v4 1/3] vfio/pci: Extract duplicated code into macro Gerd Bayer 2024-05-22 15:06 ` [PATCH v4 2/3] vfio/pci: Support 8-byte PCI loads and stores Gerd Bayer @ 2024-05-22 15:06 ` Gerd Bayer 2 siblings, 0 replies; 10+ messages in thread From: Gerd Bayer @ 2024-05-22 15:06 UTC (permalink / raw) To: Alex Williamson, Jason Gunthorpe, Niklas Schnelle, Ramesh Thomas Cc: kvm, linux-s390, Ankit Agrawal, Yishai Hadas, Halil Pasic, Julian Ruess, Gerd Bayer Correct spelling of DECLA[RA]TION Suggested-by: Ramesh Thomas <ramesh.thomas@intel.com> Signed-off-by: Gerd Bayer <gbayer@linux.ibm.com> --- include/linux/vfio_pci_core.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h index 5f9b02d4a3e9..15d6d6da6e78 100644 --- a/include/linux/vfio_pci_core.h +++ b/include/linux/vfio_pci_core.h @@ -139,26 +139,26 @@ bool vfio_pci_core_range_intersect_range(loff_t buf_start, size_t buf_cnt, loff_t *buf_offset, size_t *intersect_count, size_t *register_offset); -#define VFIO_IOWRITE_DECLATION(size) \ +#define VFIO_IOWRITE_DECLARATION(size) \ int vfio_pci_core_iowrite##size(struct vfio_pci_core_device *vdev, \ - bool test_mem, u##size val, void __iomem *io); + bool test_mem, u##size val, void __iomem *io) -VFIO_IOWRITE_DECLATION(8) -VFIO_IOWRITE_DECLATION(16) -VFIO_IOWRITE_DECLATION(32) +VFIO_IOWRITE_DECLARATION(8); +VFIO_IOWRITE_DECLARATION(16); +VFIO_IOWRITE_DECLARATION(32); #ifdef CONFIG_64BIT -VFIO_IOWRITE_DECLATION(64) +VFIO_IOWRITE_DECLARATION(64); #endif -#define VFIO_IOREAD_DECLATION(size) \ +#define VFIO_IOREAD_DECLARATION(size) \ int vfio_pci_core_ioread##size(struct vfio_pci_core_device *vdev, \ - bool test_mem, u##size *val, void __iomem *io); + bool test_mem, u##size *val, void __iomem *io) -VFIO_IOREAD_DECLATION(8) -VFIO_IOREAD_DECLATION(16) -VFIO_IOREAD_DECLATION(32) +VFIO_IOREAD_DECLARATION(8); +VFIO_IOREAD_DECLARATION(16); +VFIO_IOREAD_DECLARATION(32); #ifdef CONFIG_64BIT -VFIO_IOREAD_DECLATION(64) +VFIO_IOREAD_DECLARATION(64); #endif #endif /* VFIO_PCI_CORE_H */ -- 2.45.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2024-05-29 3:45 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-05-22 15:06 [PATCH v4 0/3] vfio/pci: Support 8-byte PCI loads and stores Gerd Bayer 2024-05-22 15:06 ` [PATCH v4 1/3] vfio/pci: Extract duplicated code into macro Gerd Bayer 2024-05-22 15:06 ` [PATCH v4 2/3] vfio/pci: Support 8-byte PCI loads and stores Gerd Bayer 2024-05-22 23:38 ` Ramesh Thomas 2024-05-23 15:01 ` Gerd Bayer 2024-05-23 21:47 ` Ramesh Thomas 2024-05-24 13:42 ` Gerd Bayer 2024-05-29 3:45 ` Ramesh Thomas 2024-05-23 15:10 ` Gerd Bayer 2024-05-22 15:06 ` [PATCH v4 3/3] vfio/pci: Fix typo in macro to declare accessors Gerd Bayer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox