[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v1 2/2] x86/pci: Prefer using mmcfg for accessing configuration space



Current logic prefer using CFC/CF8 and fallbacks on mmcfg when accessing
>255 registers or a non-zero segment. Change the logic to always rely
on mmcfg unless it is not available to avoid locking on pci_config_lock
if possible.

Signed-off-by: Teddy Astie <teddy.astie@xxxxxxxxxx>
---
Are there x86 platforms where MMCFG is the only way to access PCI configuration 
space ?

 xen/arch/x86/x86_64/pci.c | 52 +++++++++++++++++----------------------
 1 file changed, 23 insertions(+), 29 deletions(-)

diff --git a/xen/arch/x86/x86_64/pci.c b/xen/arch/x86/x86_64/pci.c
index 8d33429103..3b3df8014d 100644
--- a/xen/arch/x86/x86_64/pci.c
+++ b/xen/arch/x86/x86_64/pci.c
@@ -14,62 +14,56 @@
 uint8_t pci_conf_read8(pci_sbdf_t sbdf, unsigned int reg)
 {
     uint32_t value;
+    int ret = pci_mmcfg_read(sbdf.seg, sbdf.bus, sbdf.devfn, reg, 1, &value);
 
-    if ( sbdf.seg || reg > 255 )
-    {
-        pci_mmcfg_read(sbdf.seg, sbdf.bus, sbdf.devfn, reg, 1, &value);
-        return value;
-    }
+    if ( unlikely(ret == -ENODEV) && !sbdf.seg && reg <= 255 )
+        return pci_conf_read(PCI_CONF_ADDRESS(sbdf, reg), reg & 3, 1);
 
-    return pci_conf_read(PCI_CONF_ADDRESS(sbdf, reg), reg & 3, 1);
+    return value;
 }
 
 uint16_t pci_conf_read16(pci_sbdf_t sbdf, unsigned int reg)
 {
-    if ( sbdf.seg || reg > 255 )
-    {
-        uint32_t value;
+    uint32_t value;
+    int ret = pci_mmcfg_read(sbdf.seg, sbdf.bus, sbdf.devfn, reg, 2, &value);
 
-        pci_mmcfg_read(sbdf.seg, sbdf.bus, sbdf.devfn, reg, 2, &value);
-        return value;
-    }
+    if ( unlikely(ret == -ENODEV) && !sbdf.seg && reg <= 255 )
+        return pci_conf_read(PCI_CONF_ADDRESS(sbdf, reg), reg & 2, 2);
 
-    return pci_conf_read(PCI_CONF_ADDRESS(sbdf, reg), reg & 2, 2);
+    return value;
 }
 
 uint32_t pci_conf_read32(pci_sbdf_t sbdf, unsigned int reg)
 {
-    if ( sbdf.seg || reg > 255 )
-    {
-        uint32_t value;
+    uint32_t value;
+    int ret = pci_mmcfg_read(sbdf.seg, sbdf.bus, sbdf.devfn, reg, 4, &value);
 
-        pci_mmcfg_read(sbdf.seg, sbdf.bus, sbdf.devfn, reg, 4, &value);
-        return value;
-    }
+    if ( unlikely(ret == -ENODEV) && !sbdf.seg && reg <= 255 )
+        return pci_conf_read(PCI_CONF_ADDRESS(sbdf, reg), 0, 4);
 
-    return pci_conf_read(PCI_CONF_ADDRESS(sbdf, reg), 0, 4);
+    return value;
 }
 
 void pci_conf_write8(pci_sbdf_t sbdf, unsigned int reg, uint8_t data)
 {
-    if ( sbdf.seg || reg > 255 )
-        pci_mmcfg_write(sbdf.seg, sbdf.bus, sbdf.devfn, reg, 1, data);
-    else
+    int ret = pci_mmcfg_write(sbdf.seg, sbdf.bus, sbdf.devfn, reg, 1, data);
+
+    if ( unlikely(ret == -ENODEV) && !sbdf.seg && reg <= 255 )
         pci_conf_write(PCI_CONF_ADDRESS(sbdf, reg), reg & 3, 1, data);
 }
 
 void pci_conf_write16(pci_sbdf_t sbdf, unsigned int reg, uint16_t data)
 {
-    if ( sbdf.seg || reg > 255 )
-        pci_mmcfg_write(sbdf.seg, sbdf.bus, sbdf.devfn, reg, 2, data);
-    else
+    int ret = pci_mmcfg_write(sbdf.seg, sbdf.bus, sbdf.devfn, reg, 2, data);
+
+    if ( unlikely(ret == -ENODEV) && !sbdf.seg && reg <= 255 )
         pci_conf_write(PCI_CONF_ADDRESS(sbdf, reg), reg & 2, 2, data);
 }
 
 void pci_conf_write32(pci_sbdf_t sbdf, unsigned int reg, uint32_t data)
 {
-    if ( sbdf.seg || reg > 255 )
-        pci_mmcfg_write(sbdf.seg, sbdf.bus, sbdf.devfn, reg, 4, data);
-    else
+    int ret = pci_mmcfg_write(sbdf.seg, sbdf.bus, sbdf.devfn, reg, 4, data);
+
+    if ( unlikely(ret == -ENODEV) && !sbdf.seg && reg <= 255 )
         pci_conf_write(PCI_CONF_ADDRESS(sbdf, reg), 0, 4, data);
 }
-- 
2.52.0



--
Teddy Astie | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.