| From 52d04d408185b7aa47628d2339c28ec70074e0ae Mon Sep 17 00:00:00 2001 |
| From: Niklas Schnelle <schnelle@linux.ibm.com> |
| Date: Thu, 4 Nov 2021 15:04:10 +0100 |
| Subject: s390/pci: move pseudo-MMIO to prevent MIO overlap |
| |
| From: Niklas Schnelle <schnelle@linux.ibm.com> |
| |
| commit 52d04d408185b7aa47628d2339c28ec70074e0ae upstream. |
| |
| When running without MIO support, with pci=nomio or for devices which |
| are not MIO-capable the zPCI subsystem generates pseudo-MMIO addresses |
| to allow access to PCI BARs via MMIO based Linux APIs even though the |
| platform uses function handles and BAR numbers. |
| |
| This is done by stashing an index into our global IOMAP array which |
| contains the function handle in the 16 most significant bits of the |
| addresses returned by ioremap() always setting the most significant bit. |
| |
| On the other hand the MIO addresses assigned by the platform for use, |
| while requiring special instructions, allow PCI access with virtually |
| mapped physical addresses. Now the problem is that these MIO addresses |
| and our own pseudo-MMIO addresses may overlap, while functionally this |
| would not be a problem by itself this overlap is detected by common code |
| as both address types are added as resources in the iomem_resource tree. |
| This leads to the overlapping resource claim of either the MIO capable |
| or non-MIO capable devices with being rejected. |
| |
| Since PCI is tightly coupled to the use of the iomem_resource tree, see |
| for example the code for request_mem_region(), we can't reasonably get |
| rid of the overlap being detected by keeping our pseudo-MMIO addresses |
| out of the iomem_resource tree. |
| |
| Instead let's move the range used by our own pseudo-MMIO addresses by |
| starting at (1UL << 62) and only using addresses below (1UL << 63) thus |
| avoiding the range currently used for MIO addresses. |
| |
| Fixes: c7ff0e918a7c ("s390/pci: deal with devices that have no support for MIO instructions") |
| Cc: stable@vger.kernel.org # 5.3+ |
| Reviewed-by: Pierre Morel <pmorel@linux.ibm.com> |
| Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com> |
| Signed-off-by: Heiko Carstens <hca@linux.ibm.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/s390/include/asm/pci_io.h | 7 ++++--- |
| 1 file changed, 4 insertions(+), 3 deletions(-) |
| |
| --- a/arch/s390/include/asm/pci_io.h |
| +++ b/arch/s390/include/asm/pci_io.h |
| @@ -14,12 +14,13 @@ |
| |
| /* I/O Map */ |
| #define ZPCI_IOMAP_SHIFT 48 |
| -#define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000UL |
| +#define ZPCI_IOMAP_ADDR_SHIFT 62 |
| +#define ZPCI_IOMAP_ADDR_BASE (1UL << ZPCI_IOMAP_ADDR_SHIFT) |
| #define ZPCI_IOMAP_ADDR_OFF_MASK ((1UL << ZPCI_IOMAP_SHIFT) - 1) |
| #define ZPCI_IOMAP_MAX_ENTRIES \ |
| - ((ULONG_MAX - ZPCI_IOMAP_ADDR_BASE + 1) / (1UL << ZPCI_IOMAP_SHIFT)) |
| + (1UL << (ZPCI_IOMAP_ADDR_SHIFT - ZPCI_IOMAP_SHIFT)) |
| #define ZPCI_IOMAP_ADDR_IDX_MASK \ |
| - (~ZPCI_IOMAP_ADDR_OFF_MASK - ZPCI_IOMAP_ADDR_BASE) |
| + ((ZPCI_IOMAP_ADDR_BASE - 1) & ~ZPCI_IOMAP_ADDR_OFF_MASK) |
| |
| struct zpci_iomap_entry { |
| u32 fh; |