All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] pci: expand usage of pci_sbdf_t
@ 2019-05-10 16:10 ` Roger Pau Monne
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monne @ 2019-05-10 16:10 UTC (permalink / raw)
  To: xen-devel; +Cc: Roger Pau Monne

pci: expand usage of pci_sbdf_t

Start by switching the seg, bus and devfn fields of pci_dev to a single
pci_sdbf_t field, and fixup the users. Also change the pci_conf and pci
capabilities related functions to use pci_sbdf_t as parameter instead of
passing the sbdf in multiple parameters. Finally also introduce a printf
format specifier to print a pci_sbdf_t.

IMO pci_sbdf_t it's nicer to use than passing around a sbdf in multiple
fields. However it's hard to expand the usage of pci_sbdf_t in the code
base without changing some of the core pci functions and the pci_dev
struct fields, hence this patch set.

Note there's still more low hanging fruit that could benefit from
switching to pci_sbdf_t, this patch series just changes some of the more
core pci functions to use pci_sbdf_t.

This series should not introduce any functional changes.

Roger Pau Monne (5):
  pci: use pci_sbdf_t in pci_dev
  pci: use function generation macros for pci_config_{write,read}<size>
  pci: switch pci_conf_{read/write} to use pci_sbdf_t
  print: introduce a format specifier for pci_sbdf_t
  pci: switch PCI capabilities related functions to use pci_sbdf_t

 docs/misc/printk-formats.txt                |   5 +
 xen/arch/x86/cpu/amd.c                      |  27 +-
 xen/arch/x86/dmi_scan.c                     |   9 +-
 xen/arch/x86/hvm/vmsi.c                     |  16 +-
 xen/arch/x86/mm.c                           |   2 +-
 xen/arch/x86/msi.c                          | 288 +++++++----------
 xen/arch/x86/oprofile/op_model_athlon.c     |  12 +-
 xen/arch/x86/x86_64/mmconf-fam10h.c         |  13 +-
 xen/arch/x86/x86_64/mmconfig-shared.c       |  26 +-
 xen/arch/x86/x86_64/pci.c                   | 136 +++-----
 xen/common/vsprintf.c                       |  18 ++
 xen/drivers/acpi/reboot.c                   |   8 +-
 xen/drivers/char/ehci-dbgp.c                |  78 +++--
 xen/drivers/char/ns16550.c                  |  80 ++---
 xen/drivers/passthrough/amd/iommu_acpi.c    |  17 +-
 xen/drivers/passthrough/amd/iommu_cmd.c     |  17 +-
 xen/drivers/passthrough/amd/iommu_detect.c  |  10 +-
 xen/drivers/passthrough/amd/iommu_init.c    |  37 ++-
 xen/drivers/passthrough/amd/iommu_intr.c    |  22 +-
 xen/drivers/passthrough/amd/iommu_map.c     |  10 +-
 xen/drivers/passthrough/amd/pci_amd_iommu.c |  65 ++--
 xen/drivers/passthrough/ats.h               |  14 +-
 xen/drivers/passthrough/pci.c               | 325 ++++++++------------
 xen/drivers/passthrough/vtd/dmar.c          |  56 ++--
 xen/drivers/passthrough/vtd/intremap.c      |  19 +-
 xen/drivers/passthrough/vtd/iommu.c         | 108 +++----
 xen/drivers/passthrough/vtd/qinval.c        |   2 +-
 xen/drivers/passthrough/vtd/quirks.c        | 102 +++---
 xen/drivers/passthrough/vtd/utils.c         |   6 +-
 xen/drivers/passthrough/vtd/x86/ats.c       |  11 +-
 xen/drivers/passthrough/x86/ats.c           |  32 +-
 xen/drivers/pci/pci.c                       |  40 +--
 xen/drivers/video/vga.c                     |  21 +-
 xen/drivers/vpci/header.c                   |  65 ++--
 xen/drivers/vpci/msi.c                      |  17 +-
 xen/drivers/vpci/msix.c                     |  39 +--
 xen/drivers/vpci/vpci.c                     |  42 +--
 xen/include/xen/pci.h                       |  45 ++-
 38 files changed, 836 insertions(+), 1004 deletions(-)

-- 
2.17.2 (Apple Git-113)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [Xen-devel] [PATCH 0/5] pci: expand usage of pci_sbdf_t
@ 2019-05-10 16:10 ` Roger Pau Monne
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monne @ 2019-05-10 16:10 UTC (permalink / raw)
  To: xen-devel; +Cc: Roger Pau Monne

pci: expand usage of pci_sbdf_t

Start by switching the seg, bus and devfn fields of pci_dev to a single
pci_sdbf_t field, and fixup the users. Also change the pci_conf and pci
capabilities related functions to use pci_sbdf_t as parameter instead of
passing the sbdf in multiple parameters. Finally also introduce a printf
format specifier to print a pci_sbdf_t.

IMO pci_sbdf_t it's nicer to use than passing around a sbdf in multiple
fields. However it's hard to expand the usage of pci_sbdf_t in the code
base without changing some of the core pci functions and the pci_dev
struct fields, hence this patch set.

Note there's still more low hanging fruit that could benefit from
switching to pci_sbdf_t, this patch series just changes some of the more
core pci functions to use pci_sbdf_t.

This series should not introduce any functional changes.

Roger Pau Monne (5):
  pci: use pci_sbdf_t in pci_dev
  pci: use function generation macros for pci_config_{write,read}<size>
  pci: switch pci_conf_{read/write} to use pci_sbdf_t
  print: introduce a format specifier for pci_sbdf_t
  pci: switch PCI capabilities related functions to use pci_sbdf_t

 docs/misc/printk-formats.txt                |   5 +
 xen/arch/x86/cpu/amd.c                      |  27 +-
 xen/arch/x86/dmi_scan.c                     |   9 +-
 xen/arch/x86/hvm/vmsi.c                     |  16 +-
 xen/arch/x86/mm.c                           |   2 +-
 xen/arch/x86/msi.c                          | 288 +++++++----------
 xen/arch/x86/oprofile/op_model_athlon.c     |  12 +-
 xen/arch/x86/x86_64/mmconf-fam10h.c         |  13 +-
 xen/arch/x86/x86_64/mmconfig-shared.c       |  26 +-
 xen/arch/x86/x86_64/pci.c                   | 136 +++-----
 xen/common/vsprintf.c                       |  18 ++
 xen/drivers/acpi/reboot.c                   |   8 +-
 xen/drivers/char/ehci-dbgp.c                |  78 +++--
 xen/drivers/char/ns16550.c                  |  80 ++---
 xen/drivers/passthrough/amd/iommu_acpi.c    |  17 +-
 xen/drivers/passthrough/amd/iommu_cmd.c     |  17 +-
 xen/drivers/passthrough/amd/iommu_detect.c  |  10 +-
 xen/drivers/passthrough/amd/iommu_init.c    |  37 ++-
 xen/drivers/passthrough/amd/iommu_intr.c    |  22 +-
 xen/drivers/passthrough/amd/iommu_map.c     |  10 +-
 xen/drivers/passthrough/amd/pci_amd_iommu.c |  65 ++--
 xen/drivers/passthrough/ats.h               |  14 +-
 xen/drivers/passthrough/pci.c               | 325 ++++++++------------
 xen/drivers/passthrough/vtd/dmar.c          |  56 ++--
 xen/drivers/passthrough/vtd/intremap.c      |  19 +-
 xen/drivers/passthrough/vtd/iommu.c         | 108 +++----
 xen/drivers/passthrough/vtd/qinval.c        |   2 +-
 xen/drivers/passthrough/vtd/quirks.c        | 102 +++---
 xen/drivers/passthrough/vtd/utils.c         |   6 +-
 xen/drivers/passthrough/vtd/x86/ats.c       |  11 +-
 xen/drivers/passthrough/x86/ats.c           |  32 +-
 xen/drivers/pci/pci.c                       |  40 +--
 xen/drivers/video/vga.c                     |  21 +-
 xen/drivers/vpci/header.c                   |  65 ++--
 xen/drivers/vpci/msi.c                      |  17 +-
 xen/drivers/vpci/msix.c                     |  39 +--
 xen/drivers/vpci/vpci.c                     |  42 +--
 xen/include/xen/pci.h                       |  45 ++-
 38 files changed, 836 insertions(+), 1004 deletions(-)

-- 
2.17.2 (Apple Git-113)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH 1/5] pci: use pci_sbdf_t in pci_dev
@ 2019-05-10 16:10   ` Roger Pau Monne
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monne @ 2019-05-10 16:10 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Suravee Suthikulpanit,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper, Ian Jackson,
	Tim Deegan, Julien Grall, Jan Beulich, Brian Woods,
	Roger Pau Monne

This patch replaces the seg, bus and devfn fields of the struct and
fixes the callers. While there instances of u<size> have also been
replaced with uint<size>_t.

No functional change intended.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Julien Grall <julien.grall@arm.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Brian Woods <brian.woods@amd.com>
Cc: Kevin Tian <kevin.tian@intel.com>
---
 xen/arch/x86/hvm/vmsi.c                     |  14 +-
 xen/arch/x86/msi.c                          | 136 ++++++++--------
 xen/drivers/passthrough/amd/iommu_cmd.c     |  16 +-
 xen/drivers/passthrough/amd/iommu_intr.c    |  14 +-
 xen/drivers/passthrough/amd/iommu_map.c     |  10 +-
 xen/drivers/passthrough/amd/pci_amd_iommu.c |  58 ++++---
 xen/drivers/passthrough/pci.c               | 162 ++++++++++----------
 xen/drivers/passthrough/vtd/dmar.c          |  12 +-
 xen/drivers/passthrough/vtd/intremap.c      |   8 +-
 xen/drivers/passthrough/vtd/iommu.c         |  34 ++--
 xen/drivers/passthrough/vtd/qinval.c        |   2 +-
 xen/drivers/passthrough/vtd/quirks.c        |  16 +-
 xen/drivers/passthrough/vtd/x86/ats.c       |  12 +-
 xen/drivers/passthrough/x86/ats.c           |   8 +-
 xen/drivers/pci/pci.c                       |   8 +-
 xen/drivers/vpci/header.c                   |  74 ++++-----
 xen/drivers/vpci/msi.c                      |  21 ++-
 xen/drivers/vpci/msix.c                     |  36 +++--
 xen/drivers/vpci/vpci.c                     |   8 +-
 xen/include/xen/pci.h                       |   5 +-
 20 files changed, 322 insertions(+), 332 deletions(-)

diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c
index aeb5a70104..15cfe8d057 100644
--- a/xen/arch/x86/hvm/vmsi.c
+++ b/xen/arch/x86/hvm/vmsi.c
@@ -688,8 +688,8 @@ static int vpci_msi_update(const struct pci_dev *pdev, uint32_t data,
         {
             gdprintk(XENLOG_ERR,
                      "%04x:%02x:%02x.%u: failed to bind PIRQ %u: %d\n",
-                     pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                     PCI_FUNC(pdev->devfn), pirq + i, rc);
+                     pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                     pdev->sbdf.func, pirq + i, rc);
             while ( bind.machine_irq-- > pirq )
                 pt_irq_destroy_bind(pdev->domain, &bind);
             return rc;
@@ -727,9 +727,9 @@ static int vpci_msi_enable(const struct pci_dev *pdev, uint32_t data,
                            paddr_t table_base, uint32_t mask)
 {
     struct msi_info msi_info = {
-        .seg = pdev->seg,
-        .bus = pdev->bus,
-        .devfn = pdev->devfn,
+        .seg = pdev->sbdf.seg,
+        .bus = pdev->sbdf.bus,
+        .devfn = pdev->sbdf.extfunc,
         .table_base = table_base,
         .entry_nr = nr,
     };
@@ -744,8 +744,8 @@ static int vpci_msi_enable(const struct pci_dev *pdev, uint32_t data,
     if ( rc )
     {
         gdprintk(XENLOG_ERR, "%04x:%02x:%02x.%u: failed to map PIRQ: %d\n",
-                 pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                 PCI_FUNC(pdev->devfn), rc);
+                 pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                 pdev->sbdf.func, rc);
         return rc;
     }
 
diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index babc4147c4..f30f592ee2 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -124,13 +124,13 @@ static void msix_put_fixmap(struct arch_msix *msix, int idx)
 
 static bool memory_decoded(const struct pci_dev *dev)
 {
-    u8 bus, slot, func;
+    uint8_t bus, slot, func;
 
     if ( !dev->info.is_virtfn )
     {
-        bus = dev->bus;
-        slot = PCI_SLOT(dev->devfn);
-        func = PCI_FUNC(dev->devfn);
+        bus = dev->sbdf.bus;
+        slot = dev->sbdf.dev;
+        func = dev->sbdf.func;
     }
     else
     {
@@ -139,14 +139,14 @@ static bool memory_decoded(const struct pci_dev *dev)
         func = PCI_FUNC(dev->info.physfn.devfn);
     }
 
-    return !!(pci_conf_read16(dev->seg, bus, slot, func, PCI_COMMAND) &
+    return !!(pci_conf_read16(dev->sbdf.seg, bus, slot, func, PCI_COMMAND) &
               PCI_COMMAND_MEMORY);
 }
 
 static bool msix_memory_decoded(const struct pci_dev *dev, unsigned int pos)
 {
-    u16 control = pci_conf_read16(dev->seg, dev->bus, PCI_SLOT(dev->devfn),
-                                  PCI_FUNC(dev->devfn), msix_control_reg(pos));
+    u16 control = pci_conf_read16(dev->sbdf.seg, dev->sbdf.bus, dev->sbdf.dev,
+                                  dev->sbdf.func, msix_control_reg(pos));
 
     if ( !(control & PCI_MSIX_FLAGS_ENABLE) )
         return false;
@@ -200,10 +200,10 @@ static bool read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
     {
         struct pci_dev *dev = entry->dev;
         int pos = entry->msi_attrib.pos;
-        u16 data, seg = dev->seg;
-        u8 bus = dev->bus;
-        u8 slot = PCI_SLOT(dev->devfn);
-        u8 func = PCI_FUNC(dev->devfn);
+        uint16_t data, seg = dev->sbdf.seg;
+        uint8_t bus = dev->sbdf.bus;
+        uint8_t slot = dev->sbdf.dev;
+        uint8_t func = dev->sbdf.func;
 
         msg->address_lo = pci_conf_read32(seg, bus, slot, func,
                                           msi_lower_address_reg(pos));
@@ -265,10 +265,10 @@ static int write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
     {
         struct pci_dev *dev = entry->dev;
         int pos = entry->msi_attrib.pos;
-        u16 seg = dev->seg;
-        u8 bus = dev->bus;
-        u8 slot = PCI_SLOT(dev->devfn);
-        u8 func = PCI_FUNC(dev->devfn);
+        uint16_t seg = dev->sbdf.seg;
+        uint8_t bus = dev->sbdf.bus;
+        uint8_t slot = dev->sbdf.dev;
+        uint8_t func = dev->sbdf.func;
         int nr = entry->msi_attrib.entry_nr;
 
         ASSERT((msg->data & (entry[-nr].msi.nvec - 1)) == nr);
@@ -348,10 +348,10 @@ void __msi_set_enable(u16 seg, u8 bus, u8 slot, u8 func, int pos, int enable)
 static void msi_set_enable(struct pci_dev *dev, int enable)
 {
     int pos;
-    u16 seg = dev->seg;
-    u8 bus = dev->bus;
-    u8 slot = PCI_SLOT(dev->devfn);
-    u8 func = PCI_FUNC(dev->devfn);
+    uint16_t seg = dev->sbdf.seg;
+    uint8_t bus = dev->sbdf.bus;
+    uint8_t slot = dev->sbdf.dev;
+    uint8_t func = dev->sbdf.func;
 
     pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSI);
     if ( pos )
@@ -361,10 +361,10 @@ static void msi_set_enable(struct pci_dev *dev, int enable)
 static void msix_set_enable(struct pci_dev *dev, int enable)
 {
     int pos;
-    u16 control, seg = dev->seg;
-    u8 bus = dev->bus;
-    u8 slot = PCI_SLOT(dev->devfn);
-    u8 func = PCI_FUNC(dev->devfn);
+    uint16_t control, seg = dev->sbdf.seg;
+    uint8_t bus = dev->sbdf.bus;
+    uint8_t slot = dev->sbdf.dev;
+    uint8_t func = dev->sbdf.func;
 
     pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSIX);
     if ( pos )
@@ -388,17 +388,17 @@ static bool msi_set_mask_bit(struct irq_desc *desc, bool host, bool guest)
 {
     struct msi_desc *entry = desc->msi_desc;
     struct pci_dev *pdev;
-    u16 seg, control;
-    u8 bus, slot, func;
+    uint16_t seg, control;
+    uint8_t bus, slot, func;
     bool flag = host || guest, maskall;
 
     ASSERT(spin_is_locked(&desc->lock));
     BUG_ON(!entry || !entry->dev);
     pdev = entry->dev;
-    seg = pdev->seg;
-    bus = pdev->bus;
-    slot = PCI_SLOT(pdev->devfn);
-    func = PCI_FUNC(pdev->devfn);
+    seg = pdev->sbdf.seg;
+    bus = pdev->sbdf.bus;
+    slot = pdev->sbdf.dev;
+    func = pdev->sbdf.func;
     switch ( entry->msi_attrib.type )
     {
     case PCI_CAP_ID_MSI:
@@ -475,9 +475,8 @@ static int msi_get_mask_bit(const struct msi_desc *entry)
     case PCI_CAP_ID_MSI:
         if ( !entry->msi_attrib.maskbit )
             break;
-        return (pci_conf_read32(entry->dev->seg, entry->dev->bus,
-                                PCI_SLOT(entry->dev->devfn),
-                                PCI_FUNC(entry->dev->devfn),
+        return (pci_conf_read32(entry->dev->sbdf.seg, entry->dev->sbdf.bus,
+                                entry->dev->sbdf.dev, entry->dev->sbdf.func,
                                 entry->msi.mpos) >>
                 entry->msi_attrib.entry_nr) & 1;
     case PCI_CAP_ID_MSIX:
@@ -594,11 +593,11 @@ int setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc)
 
     if ( msidesc->msi_attrib.type == PCI_CAP_ID_MSIX )
     {
-        control = pci_conf_read16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                                  PCI_FUNC(pdev->devfn), cpos);
+        control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
+                                  pdev->sbdf.dev, pdev->sbdf.func, cpos);
         if ( !(control & PCI_MSIX_FLAGS_ENABLE) )
-            pci_conf_write16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                             PCI_FUNC(pdev->devfn), cpos,
+            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                             pdev->sbdf.func, cpos,
                              control | (PCI_MSIX_FLAGS_ENABLE |
                                         PCI_MSIX_FLAGS_MASKALL));
     }
@@ -608,8 +607,8 @@ int setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc)
                                                    : &pci_msi_nonmaskable);
 
     if ( !(control & PCI_MSIX_FLAGS_ENABLE) )
-        pci_conf_write16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                         PCI_FUNC(pdev->devfn), cpos, control);
+        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                         pdev->sbdf.func, cpos, control);
 
     return rc;
 }
@@ -689,10 +688,10 @@ static int msi_capability_init(struct pci_dev *dev,
     struct msi_desc *entry;
     int pos;
     unsigned int i, maxvec, mpos;
-    u16 control, seg = dev->seg;
-    u8 bus = dev->bus;
-    u8 slot = PCI_SLOT(dev->devfn);
-    u8 func = PCI_FUNC(dev->devfn);
+    uint16_t control, seg = dev->sbdf.seg;
+    uint8_t bus = dev->sbdf.bus;
+    uint8_t slot = dev->sbdf.dev;
+    uint8_t func = dev->sbdf.func;
 
     ASSERT(pcidevs_locked());
     pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSI);
@@ -856,10 +855,10 @@ static int msix_capability_init(struct pci_dev *dev,
     u64 table_paddr;
     u32 table_offset;
     u8 bir, pbus, pslot, pfunc;
-    u16 seg = dev->seg;
-    u8 bus = dev->bus;
-    u8 slot = PCI_SLOT(dev->devfn);
-    u8 func = PCI_FUNC(dev->devfn);
+    uint16_t seg = dev->sbdf.seg;
+    uint8_t bus = dev->sbdf.bus;
+    uint8_t slot = dev->sbdf.dev;
+    uint8_t func = dev->sbdf.func;
     bool maskall = msix->host_maskall;
 
     ASSERT(pcidevs_locked());
@@ -913,7 +912,7 @@ static int msix_capability_init(struct pci_dev *dev,
         pbus = dev->info.physfn.bus;
         pslot = PCI_SLOT(dev->info.physfn.devfn);
         pfunc = PCI_FUNC(dev->info.physfn.devfn);
-        vf = PCI_BDF2(dev->bus, dev->devfn);
+        vf = dev->sbdf.bdf;
     }
 
     table_paddr = read_pci_mem_bar(seg, pbus, pslot, pfunc, bir, vf);
@@ -1172,10 +1171,10 @@ static void _pci_cleanup_msix(struct arch_msix *msix)
 static void __pci_disable_msix(struct msi_desc *entry)
 {
     struct pci_dev *dev = entry->dev;
-    u16 seg = dev->seg;
-    u8 bus = dev->bus;
-    u8 slot = PCI_SLOT(dev->devfn);
-    u8 func = PCI_FUNC(dev->devfn);
+    uint16_t seg = dev->sbdf.seg;
+    uint8_t bus = dev->sbdf.bus;
+    uint8_t slot = dev->sbdf.dev;
+    uint8_t func = dev->sbdf.func;
     unsigned int pos = pci_find_cap_offset(seg, bus, slot, func,
                                            PCI_CAP_ID_MSIX);
     u16 control = pci_conf_read16(seg, bus, slot, func,
@@ -1295,10 +1294,10 @@ void pci_cleanup_msi(struct pci_dev *pdev)
 int pci_msi_conf_write_intercept(struct pci_dev *pdev, unsigned int reg,
                                  unsigned int size, uint32_t *data)
 {
-    u16 seg = pdev->seg;
-    u8 bus = pdev->bus;
-    u8 slot = PCI_SLOT(pdev->devfn);
-    u8 func = PCI_FUNC(pdev->devfn);
+    uint16_t seg = pdev->sbdf.seg;
+    uint8_t bus = pdev->sbdf.bus;
+    uint8_t slot = pdev->sbdf.dev;
+    uint8_t func = pdev->sbdf.func;
     struct msi_desc *entry;
     unsigned int pos;
 
@@ -1365,7 +1364,7 @@ int pci_restore_msi_state(struct pci_dev *pdev)
     struct msi_desc *entry, *tmp;
     struct irq_desc *desc;
     struct msi_msg msg;
-    u8 slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
+    uint8_t slot = pdev->sbdf.dev, func = pdev->sbdf.func;
     unsigned int type = 0, pos = 0;
     u16 control = 0;
 
@@ -1374,9 +1373,7 @@ int pci_restore_msi_state(struct pci_dev *pdev)
     if ( !use_msi )
         return -EOPNOTSUPP;
 
-    ret = xsm_resource_setup_pci(XSM_PRIV,
-                                (pdev->seg << 16) | (pdev->bus << 8) |
-                                pdev->devfn);
+    ret = xsm_resource_setup_pci(XSM_PRIV, pdev->sbdf.sbdf);
     if ( ret )
         return ret;
 
@@ -1396,10 +1393,10 @@ int pci_restore_msi_state(struct pci_dev *pdev)
     bogus:
             dprintk(XENLOG_ERR,
                     "Restore MSI for %04x:%02x:%02x:%u entry %u not set?\n",
-                    pdev->seg, pdev->bus, slot, func, i);
+                    pdev->sbdf.seg, pdev->sbdf.bus, slot, func, i);
             spin_unlock_irqrestore(&desc->lock, flags);
             if ( type == PCI_CAP_ID_MSIX )
-                pci_conf_write16(pdev->seg, pdev->bus, slot, func,
+                pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
                                  msix_control_reg(pos),
                                  control & ~PCI_MSIX_FLAGS_ENABLE);
             return -EINVAL;
@@ -1414,16 +1411,16 @@ int pci_restore_msi_state(struct pci_dev *pdev)
         }
         else if ( !type && entry->msi_attrib.type == PCI_CAP_ID_MSIX )
         {
-            control = pci_conf_read16(pdev->seg, pdev->bus, slot, func,
-                                      msix_control_reg(pos));
-            pci_conf_write16(pdev->seg, pdev->bus, slot, func,
+            control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, slot,
+                                      func, msix_control_reg(pos));
+            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
                              msix_control_reg(pos),
                              control | (PCI_MSIX_FLAGS_ENABLE |
                                         PCI_MSIX_FLAGS_MASKALL));
             if ( unlikely(!memory_decoded(pdev)) )
             {
                 spin_unlock_irqrestore(&desc->lock, flags);
-                pci_conf_write16(pdev->seg, pdev->bus, slot, func,
+                pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
                                  msix_control_reg(pos),
                                  control & ~PCI_MSIX_FLAGS_ENABLE);
                 return -ENXIO;
@@ -1457,17 +1454,18 @@ int pci_restore_msi_state(struct pci_dev *pdev)
         {
             unsigned int cpos = msi_control_reg(pos);
 
-            control = pci_conf_read16(pdev->seg, pdev->bus, slot, func, cpos) &
-                      ~PCI_MSI_FLAGS_QSIZE;
+            control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, slot,
+                                      func, cpos) & ~PCI_MSI_FLAGS_QSIZE;
             multi_msi_enable(control, entry->msi.nvec);
-            pci_conf_write16(pdev->seg, pdev->bus, slot, func, cpos, control);
+            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func, cpos,
+                             control);
 
             msi_set_enable(pdev, 1);
         }
     }
 
     if ( type == PCI_CAP_ID_MSIX )
-        pci_conf_write16(pdev->seg, pdev->bus, slot, func,
+        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
                          msix_control_reg(pos),
                          control | PCI_MSIX_FLAGS_ENABLE);
 
diff --git a/xen/drivers/passthrough/amd/iommu_cmd.c b/xen/drivers/passthrough/amd/iommu_cmd.c
index af3a1fb865..82330c24ba 100644
--- a/xen/drivers/passthrough/amd/iommu_cmd.c
+++ b/xen/drivers/passthrough/amd/iommu_cmd.c
@@ -289,23 +289,23 @@ void amd_iommu_flush_iotlb(u8 devfn, const struct pci_dev *pdev,
     if ( !ats_enabled )
         return;
 
-    if ( !pci_ats_enabled(pdev->seg, pdev->bus, pdev->devfn) )
+    if ( !pci_ats_enabled(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.extfunc) )
         return;
 
-    iommu = find_iommu_for_device(pdev->seg, PCI_BDF2(pdev->bus, pdev->devfn));
+    iommu = find_iommu_for_device(pdev->sbdf.seg, pdev->sbdf.bdf);
 
     if ( !iommu )
     {
         AMD_IOMMU_DEBUG("%s: Can't find iommu for %04x:%02x:%02x.%u\n",
-                        __func__, pdev->seg, pdev->bus,
-                        PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+                        __func__, pdev->sbdf.seg, pdev->sbdf.bus,
+                        pdev->sbdf.dev, pdev->sbdf.func);
         return;
     }
 
     if ( !iommu_has_cap(iommu, PCI_CAP_IOTLB_SHIFT) )
         return;
 
-    req_id = get_dma_requestor_id(iommu->seg, PCI_BDF2(pdev->bus, devfn));
+    req_id = get_dma_requestor_id(iommu->seg, PCI_BDF2(pdev->sbdf.bus, devfn));
     queueid = req_id;
     maxpend = pdev->ats.queue_depth & 0xff;
 
@@ -326,13 +326,13 @@ static void amd_iommu_flush_all_iotlbs(struct domain *d, daddr_t daddr,
 
     for_each_pdev( d, pdev )
     {
-        u8 devfn = pdev->devfn;
+        uint8_t devfn = pdev->sbdf.extfunc;
 
         do {
             amd_iommu_flush_iotlb(devfn, pdev, daddr, order);
             devfn += pdev->phantom_stride;
-        } while ( devfn != pdev->devfn &&
-                  PCI_SLOT(devfn) == PCI_SLOT(pdev->devfn) );
+        } while ( devfn != pdev->sbdf.extfunc &&
+                  PCI_SLOT(devfn) == pdev->sbdf.dev );
     }
 }
 
diff --git a/xen/drivers/passthrough/amd/iommu_intr.c b/xen/drivers/passthrough/amd/iommu_intr.c
index dad2d1e5ab..71594cc27d 100644
--- a/xen/drivers/passthrough/amd/iommu_intr.c
+++ b/xen/drivers/passthrough/amd/iommu_intr.c
@@ -525,8 +525,8 @@ int amd_iommu_msi_msg_update_ire(
     unsigned int i, nr = 1;
     u32 data;
 
-    bdf = pdev ? PCI_BDF2(pdev->bus, pdev->devfn) : hpet_sbdf.bdf;
-    seg = pdev ? pdev->seg : hpet_sbdf.seg;
+    bdf = pdev ? pdev->sbdf.bdf : hpet_sbdf.bdf;
+    seg = pdev ? pdev->sbdf.seg : hpet_sbdf.seg;
 
     iommu = _find_iommu_for_device(seg, bdf);
     if ( IS_ERR_OR_NULL(iommu) )
@@ -544,12 +544,12 @@ int amd_iommu_msi_msg_update_ire(
             if ( !pdev || !pdev->phantom_stride )
                 break;
             bdf += pdev->phantom_stride;
-        } while ( PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
+        } while ( PCI_SLOT(bdf) == pdev->sbdf.dev );
 
         for ( i = 0; i < nr; ++i )
             msi_desc[i].remap_index = -1;
         if ( pdev )
-            bdf = PCI_BDF2(pdev->bus, pdev->devfn);
+            bdf = pdev->sbdf.bdf;
     }
 
     if ( !msg )
@@ -562,7 +562,7 @@ int amd_iommu_msi_msg_update_ire(
         if ( rc || !pdev || !pdev->phantom_stride )
             break;
         bdf += pdev->phantom_stride;
-    } while ( PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
+    } while ( PCI_SLOT(bdf) == pdev->sbdf.dev );
 
     if ( !rc )
     {
@@ -579,8 +579,8 @@ void amd_iommu_read_msi_from_ire(
 {
     unsigned int offset = msg->data & (INTREMAP_ENTRIES - 1);
     const struct pci_dev *pdev = msi_desc->dev;
-    u16 bdf = pdev ? PCI_BDF2(pdev->bus, pdev->devfn) : hpet_sbdf.bdf;
-    u16 seg = pdev ? pdev->seg : hpet_sbdf.seg;
+    uint16_t bdf = pdev ? pdev->sbdf.bdf : hpet_sbdf.bdf;
+    uint16_t seg = pdev ? pdev->sbdf.seg : hpet_sbdf.seg;
     const u32 *entry;
 
     if ( IS_ERR_OR_NULL(_find_iommu_for_device(seg, bdf)) )
diff --git a/xen/drivers/passthrough/amd/iommu_map.c b/xen/drivers/passthrough/amd/iommu_map.c
index cbf00e9e72..314d871c9e 100644
--- a/xen/drivers/passthrough/amd/iommu_map.c
+++ b/xen/drivers/passthrough/amd/iommu_map.c
@@ -324,8 +324,8 @@ static int update_paging_mode(struct domain *d, unsigned long dfn)
             if ( pdev->type == DEV_TYPE_PCI_HOST_BRIDGE )
                 continue;
 
-            bdf = PCI_BDF2(pdev->bus, pdev->devfn);
-            iommu = find_iommu_for_device(pdev->seg, bdf);
+            bdf = pdev->sbdf.bdf;
+            iommu = find_iommu_for_device(pdev->sbdf.seg, bdf);
             if ( !iommu )
             {
                 AMD_IOMMU_DEBUG("%s Fail to find iommu.\n", __func__);
@@ -334,7 +334,7 @@ static int update_paging_mode(struct domain *d, unsigned long dfn)
 
             spin_lock_irqsave(&iommu->lock, flags);
             do {
-                req_id = get_dma_requestor_id(pdev->seg, bdf);
+                req_id = get_dma_requestor_id(pdev->sbdf.seg, bdf);
                 table = iommu->dev_table.buffer;
                 dte = &table[req_id];
 
@@ -346,8 +346,8 @@ static int update_paging_mode(struct domain *d, unsigned long dfn)
 
                 amd_iommu_flush_device(iommu, req_id);
                 bdf += pdev->phantom_stride;
-            } while ( PCI_DEVFN2(bdf) != pdev->devfn &&
-                      PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
+            } while ( PCI_DEVFN2(bdf) != pdev->sbdf.extfunc &&
+                      PCI_SLOT(bdf) == pdev->sbdf.dev );
             spin_unlock_irqrestore(&iommu->lock, flags);
         }
 
diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/passthrough/amd/pci_amd_iommu.c
index dbc71ca7d5..0e4c5b4994 100644
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -94,7 +94,7 @@ static void amd_iommu_setup_domain_device(
     unsigned long flags;
     int req_id, valid = 1;
     int dte_i = 0;
-    u8 bus = pdev->bus;
+    uint8_t bus = pdev->sbdf.bus;
     const struct domain_iommu *hd = dom_iommu(domain);
 
     BUG_ON( !hd->arch.root_table || !hd->arch.paging_mode ||
@@ -120,7 +120,7 @@ static void amd_iommu_setup_domain_device(
             dte, page_to_maddr(hd->arch.root_table), domain->domain_id,
             hd->arch.paging_mode, valid);
 
-        if ( pci_ats_device(iommu->seg, bus, pdev->devfn) &&
+        if ( pci_ats_device(iommu->seg, bus, pdev->sbdf.extfunc) &&
              iommu_has_cap(iommu, PCI_CAP_IOTLB_SHIFT) )
             dte->i = dte_i;
 
@@ -138,10 +138,10 @@ static void amd_iommu_setup_domain_device(
 
     ASSERT(pcidevs_locked());
 
-    if ( pci_ats_device(iommu->seg, bus, pdev->devfn) &&
-         !pci_ats_enabled(iommu->seg, bus, pdev->devfn) )
+    if ( pci_ats_device(iommu->seg, bus, pdev->sbdf.extfunc) &&
+         !pci_ats_enabled(iommu->seg, bus, pdev->sbdf.extfunc) )
     {
-        if ( devfn == pdev->devfn )
+        if ( devfn == pdev->sbdf.extfunc )
             enable_ats_device(pdev, &iommu->ats_devices);
 
         amd_iommu_flush_iotlb(devfn, pdev, INV_IOMMU_ALL_PAGES_ADDRESS, 0);
@@ -261,7 +261,7 @@ void amd_iommu_disable_domain_device(struct domain *domain,
     struct amd_iommu_dte *table, *dte;
     unsigned long flags;
     int req_id;
-    u8 bus = pdev->bus;
+    uint8_t bus = pdev->sbdf.bus;
 
     BUG_ON ( iommu->dev_table.buffer == NULL );
     req_id = get_dma_requestor_id(iommu->seg, PCI_BDF2(bus, devfn));
@@ -274,7 +274,7 @@ void amd_iommu_disable_domain_device(struct domain *domain,
         dte->tv = 0;
         dte->v = 0;
 
-        if ( pci_ats_device(iommu->seg, bus, pdev->devfn) &&
+        if ( pci_ats_device(iommu->seg, bus, pdev->sbdf.extfunc) &&
              iommu_has_cap(iommu, PCI_CAP_IOTLB_SHIFT) )
             dte->i = 0;
 
@@ -289,7 +289,7 @@ void amd_iommu_disable_domain_device(struct domain *domain,
 
     ASSERT(pcidevs_locked());
 
-    if ( devfn == pdev->devfn &&
+    if ( devfn == pdev->sbdf.extfunc &&
          pci_ats_device(iommu->seg, bus, devfn) &&
          pci_ats_enabled(iommu->seg, bus, devfn) )
         disable_ats_device(pdev);
@@ -299,23 +299,22 @@ static int reassign_device(struct domain *source, struct domain *target,
                            u8 devfn, struct pci_dev *pdev)
 {
     struct amd_iommu *iommu;
-    int bdf, rc;
+    int rc;
     struct domain_iommu *t = dom_iommu(target);
 
-    bdf = PCI_BDF2(pdev->bus, pdev->devfn);
-    iommu = find_iommu_for_device(pdev->seg, bdf);
+    iommu = find_iommu_for_device(pdev->sbdf.seg, pdev->sbdf.bdf);
     if ( !iommu )
     {
         AMD_IOMMU_DEBUG("Fail to find iommu."
                         " %04x:%02x:%x02.%x cannot be assigned to dom%d\n",
-                        pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                        target->domain_id);
+                        pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn),
+                        PCI_FUNC(devfn), target->domain_id);
         return -ENODEV;
     }
 
     amd_iommu_disable_domain_device(source, iommu, devfn, pdev);
 
-    if ( devfn == pdev->devfn )
+    if ( devfn == pdev->sbdf.extfunc )
     {
         list_move(&pdev->domain_list, &target->arch.pdev_list);
         pdev->domain = target;
@@ -327,8 +326,8 @@ static int reassign_device(struct domain *source, struct domain *target,
 
     amd_iommu_setup_domain_device(target, iommu, devfn, pdev);
     AMD_IOMMU_DEBUG("Re-assign %04x:%02x:%02x.%u from dom%d to dom%d\n",
-                    pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                    source->domain_id, target->domain_id);
+                    pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn),
+                    PCI_FUNC(devfn), source->domain_id, target->domain_id);
 
     return 0;
 }
@@ -337,9 +336,9 @@ static int amd_iommu_assign_device(struct domain *d, u8 devfn,
                                    struct pci_dev *pdev,
                                    u32 flag)
 {
-    struct ivrs_mappings *ivrs_mappings = get_ivrs_mappings(pdev->seg);
-    int bdf = PCI_BDF2(pdev->bus, devfn);
-    int req_id = get_dma_requestor_id(pdev->seg, bdf);
+    struct ivrs_mappings *ivrs_mappings = get_ivrs_mappings(pdev->sbdf.seg);
+    int bdf = PCI_BDF2(pdev->sbdf.bus, devfn);
+    int req_id = get_dma_requestor_id(pdev->sbdf.seg, bdf);
 
     if ( ivrs_mappings[req_id].unity_map_enable )
     {
@@ -420,13 +419,11 @@ static void amd_iommu_domain_destroy(struct domain *d)
 static int amd_iommu_add_device(u8 devfn, struct pci_dev *pdev)
 {
     struct amd_iommu *iommu;
-    u16 bdf;
 
     if ( !pdev->domain )
         return -EINVAL;
 
-    bdf = PCI_BDF2(pdev->bus, pdev->devfn);
-    iommu = find_iommu_for_device(pdev->seg, bdf);
+    iommu = find_iommu_for_device(pdev->sbdf.seg, pdev->sbdf.bdf);
     if ( unlikely(!iommu) )
     {
         /* Filter bridge devices. */
@@ -434,14 +431,14 @@ static int amd_iommu_add_device(u8 devfn, struct pci_dev *pdev)
              is_hardware_domain(pdev->domain) )
         {
             AMD_IOMMU_DEBUG("Skipping host bridge %04x:%02x:%02x.%u\n",
-                            pdev->seg, pdev->bus, PCI_SLOT(devfn),
-                            PCI_FUNC(devfn));
+                            pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                            pdev->sbdf.func);
             return 0;
         }
 
         AMD_IOMMU_DEBUG("No iommu for %04x:%02x:%02x.%u; cannot be handed to d%d\n",
-                        pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                        pdev->domain->domain_id);
+                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                        pdev->sbdf.func, pdev->domain->domain_id);
         return -ENODEV;
     }
 
@@ -452,18 +449,17 @@ static int amd_iommu_add_device(u8 devfn, struct pci_dev *pdev)
 static int amd_iommu_remove_device(u8 devfn, struct pci_dev *pdev)
 {
     struct amd_iommu *iommu;
-    u16 bdf;
+
     if ( !pdev->domain )
         return -EINVAL;
 
-    bdf = PCI_BDF2(pdev->bus, pdev->devfn);
-    iommu = find_iommu_for_device(pdev->seg, bdf);
+    iommu = find_iommu_for_device(pdev->sbdf.seg, pdev->sbdf.bdf);
     if ( !iommu )
     {
         AMD_IOMMU_DEBUG("Fail to find iommu."
                         " %04x:%02x:%02x.%u cannot be removed from dom%d\n",
-                        pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                        pdev->domain->domain_id);
+                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                        pdev->sbdf.func, pdev->domain->domain_id);
         return -ENODEV;
     }
 
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index 8108ed5f9a..8de8d8e110 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -238,10 +238,10 @@ static void check_pdev(const struct pci_dev *pdev)
     (PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT | \
      PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT | \
      PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY)
-    u16 seg = pdev->seg;
-    u8 bus = pdev->bus;
-    u8 dev = PCI_SLOT(pdev->devfn);
-    u8 func = PCI_FUNC(pdev->devfn);
+    uint16_t seg = pdev->sbdf.seg;
+    uint8_t bus = pdev->sbdf.bus;
+    uint8_t dev = pdev->sbdf.dev;
+    uint8_t func = pdev->sbdf.func;
     u16 val;
 
     if ( command_mask )
@@ -289,12 +289,12 @@ static void check_pdev(const struct pci_dev *pdev)
 
 static void apply_quirks(struct pci_dev *pdev)
 {
-    uint16_t vendor = pci_conf_read16(pdev->seg, pdev->bus,
-                                      PCI_SLOT(pdev->devfn),
-                                      PCI_FUNC(pdev->devfn), PCI_VENDOR_ID);
-    uint16_t device = pci_conf_read16(pdev->seg, pdev->bus,
-                                      PCI_SLOT(pdev->devfn),
-                                      PCI_FUNC(pdev->devfn), PCI_DEVICE_ID);
+    uint16_t vendor = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
+                                      pdev->sbdf.dev, pdev->sbdf.func,
+                                      PCI_VENDOR_ID);
+    uint16_t device = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
+                                      pdev->sbdf.dev, pdev->sbdf.func,
+                                      PCI_DEVICE_ID);
     static const struct {
         uint16_t vendor, device;
     } ignore_bars[] = {
@@ -332,16 +332,14 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
     struct pci_dev *pdev;
 
     list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
-        if ( pdev->bus == bus && pdev->devfn == devfn )
+        if ( pdev->sbdf.bus == bus && pdev->sbdf.extfunc == devfn )
             return pdev;
 
     pdev = xzalloc(struct pci_dev);
     if ( !pdev )
         return NULL;
 
-    *(u16*) &pdev->seg = pseg->nr;
-    *((u8*) &pdev->bus) = bus;
-    *((u8*) &pdev->devfn) = devfn;
+    *(uint32_t *) &pdev->sbdf.sbdf = PCI_SBDF3(pseg->nr, bus, devfn);
     pdev->domain = NULL;
     INIT_LIST_HEAD(&pdev->msi_list);
 
@@ -436,20 +434,18 @@ static void free_pdev(struct pci_seg *pseg, struct pci_dev *pdev)
     /* update bus2bridge */
     switch ( pdev->type )
     {
-        u8 dev, func, sec_bus, sub_bus;
+        uint8_t sec_bus, sub_bus;
 
         case DEV_TYPE_PCIe2PCI_BRIDGE:
         case DEV_TYPE_LEGACY_PCI_BRIDGE:
-            dev = PCI_SLOT(pdev->devfn);
-            func = PCI_FUNC(pdev->devfn);
-            sec_bus = pci_conf_read8(pseg->nr, pdev->bus, dev, func,
-                                     PCI_SECONDARY_BUS);
-            sub_bus = pci_conf_read8(pseg->nr, pdev->bus, dev, func,
-                                     PCI_SUBORDINATE_BUS);
+            sec_bus = pci_conf_read8(pseg->nr, pdev->sbdf.bus, pdev->sbdf.dev,
+                                     pdev->sbdf.func, PCI_SECONDARY_BUS);
+            sub_bus = pci_conf_read8(pseg->nr, pdev->sbdf.bus, pdev->sbdf.dev,
+                                     pdev->sbdf.func, PCI_SUBORDINATE_BUS);
 
             spin_lock(&pseg->bus2bridge_lock);
             for ( ; sec_bus <= sub_bus; sec_bus++ )
-                pseg->bus2bridge[sec_bus] = pseg->bus2bridge[pdev->bus];
+                pseg->bus2bridge[sec_bus] = pseg->bus2bridge[pdev->sbdf.bus];
             spin_unlock(&pseg->bus2bridge_lock);
             break;
 
@@ -539,8 +535,8 @@ struct pci_dev *pci_get_pdev(int seg, int bus, int devfn)
 
     do {
         list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
-            if ( (pdev->bus == bus || bus == -1) &&
-                 (pdev->devfn == devfn || devfn == -1) )
+            if ( (pdev->sbdf.bus == bus || bus == -1) &&
+                 (pdev->sbdf.extfunc == devfn || devfn == -1) )
                 return pdev;
     } while ( radix_tree_gang_lookup(&pci_segments, (void **)&pseg,
                                      pseg->nr + 1, 1) );
@@ -588,8 +584,8 @@ struct pci_dev *pci_get_pdev_by_domain(const struct domain *d, int seg,
 
     do {
         list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
-            if ( (pdev->bus == bus || bus == -1) &&
-                 (pdev->devfn == devfn || devfn == -1) &&
+            if ( (pdev->sbdf.bus == bus || bus == -1) &&
+                 (pdev->sbdf.extfunc == devfn || devfn == -1) &&
                  (pdev->domain == d) )
                 return pdev;
     } while ( radix_tree_gang_lookup(&pci_segments, (void **)&pseg,
@@ -605,15 +601,15 @@ struct pci_dev *pci_get_pdev_by_domain(const struct domain *d, int seg,
 static void pci_enable_acs(struct pci_dev *pdev)
 {
     int pos;
-    u16 cap, ctrl, seg = pdev->seg;
-    u8 bus = pdev->bus;
-    u8 dev = PCI_SLOT(pdev->devfn);
-    u8 func = PCI_FUNC(pdev->devfn);
+    uint16_t cap, ctrl, seg = pdev->sbdf.seg;
+    uint8_t bus = pdev->sbdf.bus;
+    uint8_t dev = pdev->sbdf.dev;
+    uint8_t func = pdev->sbdf.func;
 
     if ( !iommu_enabled )
         return;
 
-    pos = pci_find_ext_capability(seg, bus, pdev->devfn, PCI_EXT_CAP_ID_ACS);
+    pos = pci_find_ext_capability(seg, bus, pdev->sbdf.extfunc, PCI_EXT_CAP_ID_ACS);
     if (!pos)
         return;
 
@@ -845,7 +841,7 @@ int pci_remove_device(u16 seg, u8 bus, u8 devfn)
 
     pcidevs_lock();
     list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
-        if ( pdev->bus == bus && pdev->devfn == devfn )
+        if ( pdev->sbdf.bus == bus && pdev->sbdf.extfunc == devfn )
         {
             ret = iommu_remove_device(pdev);
             if ( pdev->domain )
@@ -924,11 +920,11 @@ int pci_release_devices(struct domain *d)
     }
     while ( (pdev = pci_get_pdev_by_domain(d, -1, -1, -1)) )
     {
-        bus = pdev->bus;
-        devfn = pdev->devfn;
-        if ( deassign_device(d, pdev->seg, bus, devfn) )
+        bus = pdev->sbdf.bus;
+        devfn = pdev->sbdf.extfunc;
+        if ( deassign_device(d, pdev->sbdf.seg, bus, devfn) )
             printk("domain %d: deassign device (%04x:%02x:%02x.%u) failed!\n",
-                   d->domain_id, pdev->seg, bus,
+                   d->domain_id, pdev->sbdf.seg, bus,
                    PCI_SLOT(devfn), PCI_FUNC(devfn));
     }
     pcidevs_unlock();
@@ -1047,10 +1043,9 @@ void pci_check_disable_device(u16 seg, u8 bus, u8 devfn)
 
     /* Tell the device to stop DMAing; we can't rely on the guest to
      * control it for us. */
-    devfn = pdev->devfn;
-    cword = pci_conf_read16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+    cword = pci_conf_read16(seg, bus, pdev->sbdf.dev, pdev->sbdf.func,
                             PCI_COMMAND);
-    pci_conf_write16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+    pci_conf_write16(seg, bus, pdev->sbdf.dev, pdev->sbdf.func,
                      PCI_COMMAND, cword & ~PCI_COMMAND_MASTER);
 }
 
@@ -1113,7 +1108,7 @@ struct setup_hwdom {
 static void __hwdom_init setup_one_hwdom_device(const struct setup_hwdom *ctxt,
                                                 struct pci_dev *pdev)
 {
-    u8 devfn = pdev->devfn;
+    uint8_t devfn = pdev->sbdf.extfunc;
     int err;
 
     do {
@@ -1121,14 +1116,14 @@ static void __hwdom_init setup_one_hwdom_device(const struct setup_hwdom *ctxt,
         if ( err )
         {
             printk(XENLOG_ERR "setup %04x:%02x:%02x.%u for d%d failed (%d)\n",
-                   pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                   ctxt->d->domain_id, err);
-            if ( devfn == pdev->devfn )
+                   pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                   pdev->sbdf.func, ctxt->d->domain_id, err);
+            if ( devfn == pdev->sbdf.extfunc )
                 return;
         }
         devfn += pdev->phantom_stride;
-    } while ( devfn != pdev->devfn &&
-              PCI_SLOT(devfn) == PCI_SLOT(pdev->devfn) );
+    } while ( devfn != pdev->sbdf.extfunc &&
+              PCI_SLOT(devfn) == pdev->sbdf.dev );
 
     err = vpci_add_handlers(pdev);
     if ( err )
@@ -1203,24 +1198,22 @@ void __hwdom_init setup_hwdom_pci_devices(
 static int hest_match_pci(const struct acpi_hest_aer_common *p,
                           const struct pci_dev *pdev)
 {
-    return ACPI_HEST_SEGMENT(p->bus) == pdev->seg &&
-           ACPI_HEST_BUS(p->bus)     == pdev->bus &&
-           p->device                 == PCI_SLOT(pdev->devfn) &&
-           p->function               == PCI_FUNC(pdev->devfn);
+    return ACPI_HEST_SEGMENT(p->bus) == pdev->sbdf.seg &&
+           ACPI_HEST_BUS(p->bus)     == pdev->sbdf.bus &&
+           p->device                 == pdev->sbdf.dev &&
+           p->function               == pdev->sbdf.func;
 }
 
 static bool_t hest_match_type(const struct acpi_hest_header *hest_hdr,
                               const struct pci_dev *pdev)
 {
-    unsigned int pos = pci_find_cap_offset(pdev->seg, pdev->bus,
-                                           PCI_SLOT(pdev->devfn),
-                                           PCI_FUNC(pdev->devfn),
+    unsigned int pos = pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus,
+                                           pdev->sbdf.dev, pdev->sbdf.func,
                                            PCI_CAP_ID_EXP);
-    u8 pcie = MASK_EXTR(pci_conf_read16(pdev->seg, pdev->bus,
-                                        PCI_SLOT(pdev->devfn),
-                                        PCI_FUNC(pdev->devfn),
-                                        pos + PCI_EXP_FLAGS),
-                        PCI_EXP_FLAGS_TYPE);
+    uint8_t pcie = MASK_EXTR(pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
+                                             pdev->sbdf.dev, pdev->sbdf.func,
+                                             pos + PCI_EXP_FLAGS),
+                             PCI_EXP_FLAGS_TYPE);
 
     switch ( hest_hdr->type )
     {
@@ -1229,8 +1222,8 @@ static bool_t hest_match_type(const struct acpi_hest_header *hest_hdr,
     case ACPI_HEST_TYPE_AER_ENDPOINT:
         return pcie == PCI_EXP_TYPE_ENDPOINT;
     case ACPI_HEST_TYPE_AER_BRIDGE:
-        return pci_conf_read16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                               PCI_FUNC(pdev->devfn), PCI_CLASS_DEVICE) ==
+        return pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                               pdev->sbdf.func, PCI_CLASS_DEVICE) ==
                PCI_CLASS_BRIDGE_PCI;
     }
 
@@ -1289,8 +1282,8 @@ bool_t pcie_aer_get_firmware_first(const struct pci_dev *pdev)
 {
     struct aer_hest_parse_info info = { .pdev = pdev };
 
-    return pci_find_cap_offset(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                               PCI_FUNC(pdev->devfn), PCI_CAP_ID_EXP) &&
+    return pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                               pdev->sbdf.func, PCI_CAP_ID_EXP) &&
            apei_hest_parse(aer_hest_parse, &info) >= 0 &&
            info.firmware_first;
 }
@@ -1306,8 +1299,7 @@ static int _dump_pci_devices(struct pci_seg *pseg, void *arg)
     list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
     {
         printk("%04x:%02x:%02x.%u - dom %-3d - node %-3d - MSIs < ",
-               pseg->nr, pdev->bus,
-               PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
+               pseg->nr, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func,
                pdev->domain ? pdev->domain->domain_id : -1,
                (pdev->node != NUMA_NO_NODE) ? pdev->node : -1);
         list_for_each_entry ( msi, &pdev->msi_list, list )
@@ -1362,19 +1354,20 @@ static int iommu_add_device(struct pci_dev *pdev)
     if ( !iommu_enabled || !hd->platform_ops )
         return 0;
 
-    rc = hd->platform_ops->add_device(pdev->devfn, pci_to_dev(pdev));
+    rc = hd->platform_ops->add_device(pdev->sbdf.extfunc, pci_to_dev(pdev));
     if ( rc || !pdev->phantom_stride )
         return rc;
 
-    for ( devfn = pdev->devfn ; ; )
+    for ( devfn = pdev->sbdf.extfunc ; ; )
     {
         devfn += pdev->phantom_stride;
-        if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
+        if ( PCI_SLOT(devfn) != pdev->sbdf.dev )
             return 0;
         rc = hd->platform_ops->add_device(devfn, pci_to_dev(pdev));
         if ( rc )
             printk(XENLOG_WARNING "IOMMU: add %04x:%02x:%02x.%u failed (%d)\n",
-                   pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn), rc);
+                   pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn),
+                   PCI_FUNC(devfn), rc);
     }
 }
 
@@ -1398,7 +1391,7 @@ static int iommu_enable_device(struct pci_dev *pdev)
 static int iommu_remove_device(struct pci_dev *pdev)
 {
     const struct domain_iommu *hd;
-    u8 devfn;
+    uint8_t devfn;
 
     if ( !pdev->domain )
         return -EINVAL;
@@ -1407,23 +1400,24 @@ static int iommu_remove_device(struct pci_dev *pdev)
     if ( !iommu_enabled || !hd->platform_ops )
         return 0;
 
-    for ( devfn = pdev->devfn ; pdev->phantom_stride; )
+    for ( devfn = pdev->sbdf.extfunc ; pdev->phantom_stride; )
     {
         int rc;
 
         devfn += pdev->phantom_stride;
-        if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
+        if ( PCI_SLOT(devfn) != pdev->sbdf.dev )
             break;
         rc = hd->platform_ops->remove_device(devfn, pci_to_dev(pdev));
         if ( !rc )
             continue;
 
         printk(XENLOG_ERR "IOMMU: remove %04x:%02x:%02x.%u failed (%d)\n",
-               pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn), rc);
+               pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+               rc);
         return rc;
     }
 
-    return hd->platform_ops->remove_device(pdev->devfn, pci_to_dev(pdev));
+    return hd->platform_ops->remove_device(pdev->sbdf.extfunc, pci_to_dev(pdev));
 }
 
 /*
@@ -1485,7 +1479,7 @@ static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn, u32 flag)
     for ( ; pdev->phantom_stride; rc = 0 )
     {
         devfn += pdev->phantom_stride;
-        if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
+        if ( PCI_SLOT(devfn) != pdev->sbdf.dev )
             break;
         rc = hd->platform_ops->assign_device(d, devfn, pci_to_dev(pdev), flag);
         if ( rc )
@@ -1520,7 +1514,7 @@ int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
     while ( pdev->phantom_stride )
     {
         devfn += pdev->phantom_stride;
-        if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
+        if ( PCI_SLOT(devfn) != pdev->sbdf.dev )
             break;
         ret = hd->platform_ops->reassign_device(d, hardware_domain, devfn,
                                                 pci_to_dev(pdev));
@@ -1532,7 +1526,7 @@ int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
         return ret;
     }
 
-    devfn = pdev->devfn;
+    devfn = pdev->sbdf.extfunc;
     ret = hd->platform_ops->reassign_device(d, hardware_domain, devfn,
                                             pci_to_dev(pdev));
     if ( ret )
@@ -1558,7 +1552,6 @@ static int iommu_get_device_group(
     const struct domain_iommu *hd = dom_iommu(d);
     struct pci_dev *pdev;
     int group_id, sdev_id;
-    u32 bdf;
     int i = 0;
     const struct iommu_ops *ops = hd->platform_ops;
 
@@ -1570,19 +1563,18 @@ static int iommu_get_device_group(
     pcidevs_lock();
     for_each_pdev( d, pdev )
     {
-        if ( (pdev->seg != seg) ||
-             ((pdev->bus == bus) && (pdev->devfn == devfn)) )
+        if ( (pdev->sbdf.seg != seg) ||
+             ((pdev->sbdf.bus == bus) && (pdev->sbdf.extfunc == devfn)) )
             continue;
 
-        if ( xsm_get_device_group(XSM_HOOK, (seg << 16) | (pdev->bus << 8) | pdev->devfn) )
+        if ( xsm_get_device_group(XSM_HOOK, (seg << 16) | pdev->sbdf.bdf) )
             continue;
 
-        sdev_id = ops->get_device_group_id(seg, pdev->bus, pdev->devfn);
+        sdev_id = ops->get_device_group_id(seg, pdev->sbdf.bus,
+                                           pdev->sbdf.extfunc);
         if ( (sdev_id == group_id) && (i < max_sdevs) )
         {
-            bdf = 0;
-            bdf |= (pdev->bus & 0xff) << 16;
-            bdf |= (pdev->devfn & 0xff) << 8;
+            uint32_t bdf = pdev->sbdf.bdf;
 
             if ( unlikely(copy_to_guest_offset(buf, i, &bdf, 1)) )
             {
@@ -1618,8 +1610,8 @@ void iommu_dev_iotlb_flush_timeout(struct domain *d, struct pci_dev *pdev)
     if ( !d->is_shutting_down && printk_ratelimit() )
         printk(XENLOG_ERR
                "dom%d: ATS device %04x:%02x:%02x.%u flush failed\n",
-               d->domain_id, pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-               PCI_FUNC(pdev->devfn));
+               d->domain_id, pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+               pdev->sbdf.func);
     if ( !is_hardware_domain(d) )
         domain_crash(d);
 
diff --git a/xen/drivers/passthrough/vtd/dmar.c b/xen/drivers/passthrough/vtd/dmar.c
index 9cc8623e53..effaf93222 100644
--- a/xen/drivers/passthrough/vtd/dmar.c
+++ b/xen/drivers/passthrough/vtd/dmar.c
@@ -219,18 +219,18 @@ struct acpi_drhd_unit *acpi_find_matched_drhd_unit(const struct pci_dev *pdev)
     }
     else if ( pdev->info.is_extfn )
     {
-        bus = pdev->bus;
+        bus = pdev->sbdf.bus;
         devfn = 0;
     }
     else
     {
-        bus = pdev->bus;
-        devfn = pdev->devfn;
+        bus = pdev->sbdf.bus;
+        devfn = pdev->sbdf.extfunc;
     }
 
     list_for_each_entry ( drhd, &acpi_drhd_units, list )
     {
-        if ( drhd->segment != pdev->seg )
+        if ( drhd->segment != pdev->sbdf.seg )
             continue;
 
         for (i = 0; i < drhd->scope.devices_cnt; i++)
@@ -253,10 +253,10 @@ struct acpi_atsr_unit *acpi_find_matched_atsr_unit(const struct pci_dev *pdev)
 
     list_for_each_entry ( atsr, &acpi_atsr_units, list )
     {
-        if ( atsr->segment != pdev->seg )
+        if ( atsr->segment != pdev->sbdf.seg )
             continue;
 
-        if ( test_bit(pdev->bus, atsr->scope.buses) )
+        if ( test_bit(pdev->sbdf.bus, atsr->scope.buses) )
             return atsr;
 
         if ( atsr->all_ports )
diff --git a/xen/drivers/passthrough/vtd/intremap.c b/xen/drivers/passthrough/vtd/intremap.c
index df0e8ac5cb..0dbf99551e 100644
--- a/xen/drivers/passthrough/vtd/intremap.c
+++ b/xen/drivers/passthrough/vtd/intremap.c
@@ -483,9 +483,9 @@ static void set_msi_source_id(struct pci_dev *pdev, struct iremap_entry *ire)
     if ( !pdev || !ire )
         return;
 
-    seg = pdev->seg;
-    bus = pdev->bus;
-    devfn = pdev->devfn;
+    seg = pdev->sbdf.seg;
+    bus = pdev->sbdf.bus;
+    devfn = pdev->sbdf.extfunc;
     switch ( pdev->type )
     {
         unsigned int sq;
@@ -517,7 +517,7 @@ static void set_msi_source_id(struct pci_dev *pdev, struct iremap_entry *ire)
         {
             if ( pdev_type(seg, bus, devfn) == DEV_TYPE_PCIe2PCI_BRIDGE )
                 set_ire_sid(ire, SVT_VERIFY_BUS, SQ_ALL_16,
-                            (bus << 8) | pdev->bus);
+                            (bus << 8) | pdev->sbdf.bus);
             else
                 set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_ALL_16,
                             PCI_BDF2(bus, devfn));
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index 7b9e09a084..7b70732863 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -1484,7 +1484,7 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
 {
     struct acpi_drhd_unit *drhd;
     int ret = 0;
-    u8 seg = pdev->seg, bus = pdev->bus, secbus;
+    uint8_t seg = pdev->sbdf.seg, bus = pdev->sbdf.bus, secbus;
 
     drhd = acpi_find_matched_drhd_unit(pdev);
     if ( !drhd )
@@ -1515,7 +1515,7 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
                    PCI_SLOT(devfn), PCI_FUNC(devfn));
         ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn,
                                          pdev);
-        if ( !ret && devfn == pdev->devfn && ats_device(pdev, drhd) > 0 )
+        if ( !ret && devfn == pdev->sbdf.extfunc && ats_device(pdev, drhd) > 0 )
             enable_ats_device(pdev, &drhd->iommu->ats_devices);
 
         break;
@@ -1543,7 +1543,7 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
          * behind the bridge. Map that id as well if we didn't already.
          */
         if ( !ret && pdev_type(seg, bus, devfn) == DEV_TYPE_PCIe2PCI_BRIDGE &&
-             (secbus != pdev->bus || pdev->devfn != 0) )
+             (secbus != pdev->sbdf.bus || pdev->sbdf.extfunc != 0) )
             ret = domain_context_mapping_one(domain, drhd->iommu, secbus, 0,
                                              pci_get_pdev(seg, secbus, 0));
 
@@ -1557,7 +1557,7 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
         break;
     }
 
-    if ( !ret && devfn == pdev->devfn )
+    if ( !ret && devfn == pdev->sbdf.extfunc )
         pci_vtd_quirk(pdev);
 
     return ret;
@@ -1635,7 +1635,8 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
     struct acpi_drhd_unit *drhd;
     struct iommu *iommu;
     int ret = 0;
-    u8 seg = pdev->seg, bus = pdev->bus, tmp_bus, tmp_devfn, secbus;
+    uint8_t seg = pdev->sbdf.seg, bus = pdev->sbdf.bus, tmp_bus, tmp_devfn,
+            secbus;
     int found = 0;
 
     drhd = acpi_find_matched_drhd_unit(pdev);
@@ -1665,7 +1666,7 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
                    domain->domain_id, seg, bus,
                    PCI_SLOT(devfn), PCI_FUNC(devfn));
         ret = domain_context_unmap_one(domain, iommu, bus, devfn);
-        if ( !ret && devfn == pdev->devfn && ats_device(pdev, drhd) > 0 )
+        if ( !ret && devfn == pdev->sbdf.extfunc && ats_device(pdev, drhd) > 0 )
             disable_ats_device(pdev);
 
         break;
@@ -1711,7 +1712,8 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
      */
     for_each_pdev ( domain, pdev )
     {
-        if ( pdev->seg == seg && pdev->bus == bus && pdev->devfn == devfn )
+        if ( pdev->sbdf.seg == seg && pdev->sbdf.bus == bus &&
+             pdev->sbdf.extfunc == devfn )
             continue;
 
         drhd = acpi_find_matched_drhd_unit(pdev);
@@ -2050,8 +2052,8 @@ static int intel_iommu_add_device(u8 devfn, struct pci_dev *pdev)
 
     for_each_rmrr_device ( rmrr, bdf, i )
     {
-        if ( rmrr->segment == pdev->seg &&
-             PCI_BUS(bdf) == pdev->bus &&
+        if ( rmrr->segment == pdev->sbdf.seg &&
+             PCI_BUS(bdf) == pdev->sbdf.bus &&
              PCI_DEVFN2(bdf) == devfn )
         {
             /*
@@ -2096,8 +2098,8 @@ static int intel_iommu_remove_device(u8 devfn, struct pci_dev *pdev)
 
     for_each_rmrr_device ( rmrr, bdf, i )
     {
-        if ( rmrr->segment != pdev->seg ||
-             PCI_BUS(bdf) != pdev->bus ||
+        if ( rmrr->segment != pdev->sbdf.seg ||
+             PCI_BUS(bdf) != pdev->sbdf.bus ||
              PCI_DEVFN2(bdf) != devfn )
             continue;
 
@@ -2421,8 +2423,8 @@ static int reassign_device_ownership(
         unsigned int i;
 
         for_each_rmrr_device( rmrr, bdf, i )
-            if ( rmrr->segment == pdev->seg &&
-                 PCI_BUS(bdf) == pdev->bus &&
+            if ( rmrr->segment == pdev->sbdf.seg &&
+                 PCI_BUS(bdf) == pdev->sbdf.bus &&
                  PCI_DEVFN2(bdf) == devfn )
             {
                 /*
@@ -2451,7 +2453,7 @@ static int reassign_device_ownership(
         return ret;
     }
 
-    if ( devfn == pdev->devfn )
+    if ( devfn == pdev->sbdf.extfunc )
     {
         list_move(&pdev->domain_list, &target->arch.pdev_list);
         pdev->domain = target;
@@ -2474,8 +2476,8 @@ static int intel_iommu_assign_device(
     if ( list_empty(&acpi_drhd_units) )
         return -ENODEV;
 
-    seg = pdev->seg;
-    bus = pdev->bus;
+    seg = pdev->sbdf.seg;
+    bus = pdev->sbdf.bus;
     /*
      * In rare cases one given rmrr is shared by multiple devices but
      * obviously this would put the security of a system at risk. So
diff --git a/xen/drivers/passthrough/vtd/qinval.c b/xen/drivers/passthrough/vtd/qinval.c
index 01447cf9a8..8015d16531 100644
--- a/xen/drivers/passthrough/vtd/qinval.c
+++ b/xen/drivers/passthrough/vtd/qinval.c
@@ -257,7 +257,7 @@ int qinval_device_iotlb_sync(struct iommu *iommu, struct pci_dev *pdev,
     qinval_entry->q.dev_iotlb_inv_dsc.lo.res_1 = 0;
     qinval_entry->q.dev_iotlb_inv_dsc.lo.max_invs_pend = pdev->ats.queue_depth;
     qinval_entry->q.dev_iotlb_inv_dsc.lo.res_2 = 0;
-    qinval_entry->q.dev_iotlb_inv_dsc.lo.sid = PCI_BDF2(pdev->bus, pdev->devfn);
+    qinval_entry->q.dev_iotlb_inv_dsc.lo.sid = pdev->sbdf.bdf;
     qinval_entry->q.dev_iotlb_inv_dsc.lo.res_3 = 0;
 
     qinval_entry->q.dev_iotlb_inv_dsc.hi.size = size;
diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c
index d6db862678..fa811605ee 100644
--- a/xen/drivers/passthrough/vtd/quirks.c
+++ b/xen/drivers/passthrough/vtd/quirks.c
@@ -413,10 +413,10 @@ int me_wifi_quirk(struct domain *domain, u8 bus, u8 devfn, int map)
 
 void pci_vtd_quirk(const struct pci_dev *pdev)
 {
-    int seg = pdev->seg;
-    int bus = pdev->bus;
-    int dev = PCI_SLOT(pdev->devfn);
-    int func = PCI_FUNC(pdev->devfn);
+    int seg = pdev->sbdf.seg;
+    int bus = pdev->sbdf.bus;
+    int dev = pdev->sbdf.dev;
+    int func = pdev->sbdf.func;
     int pos;
     bool_t ff;
     u32 val, val2;
@@ -454,11 +454,11 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
     /* Sandybridge-EP (Romley) */
     case 0x3c00: /* host bridge */
     case 0x3c01 ... 0x3c0b: /* root ports */
-        pos = pci_find_ext_capability(seg, bus, pdev->devfn,
+        pos = pci_find_ext_capability(seg, bus, pdev->sbdf.extfunc,
                                       PCI_EXT_CAP_ID_ERR);
         if ( !pos )
         {
-            pos = pci_find_ext_capability(seg, bus, pdev->devfn,
+            pos = pci_find_ext_capability(seg, bus, pdev->sbdf.extfunc,
                                           PCI_EXT_CAP_ID_VNDR);
             while ( pos )
             {
@@ -468,8 +468,8 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
                     pos += PCI_VNDR_HEADER;
                     break;
                 }
-                pos = pci_find_next_ext_capability(seg, bus, pdev->devfn, pos,
-                                                   PCI_EXT_CAP_ID_VNDR);
+                pos = pci_find_next_ext_capability(seg, bus, pdev->sbdf.extfunc,
+                                                   pos, PCI_EXT_CAP_ID_VNDR);
             }
             ff = 0;
         }
diff --git a/xen/drivers/passthrough/vtd/x86/ats.c b/xen/drivers/passthrough/vtd/x86/ats.c
index 1a3adb4acb..e0904df5b6 100644
--- a/xen/drivers/passthrough/vtd/x86/ats.c
+++ b/xen/drivers/passthrough/vtd/x86/ats.c
@@ -57,8 +57,8 @@ int ats_device(const struct pci_dev *pdev, const struct acpi_drhd_unit *drhd)
         return 0;
 
     ats_drhd = find_ats_dev_drhd(drhd->iommu);
-    pos = pci_find_ext_capability(pdev->seg, pdev->bus, pdev->devfn,
-                                  PCI_EXT_CAP_ID_ATS);
+    pos = pci_find_ext_capability(pdev->sbdf.seg, pdev->sbdf.bus,
+                                  pdev->sbdf.extfunc, PCI_EXT_CAP_ID_ATS);
 
     if ( pos && (ats_drhd == NULL) )
     {
@@ -79,19 +79,19 @@ static int device_in_domain(const struct iommu *iommu,
     int tt, found = 0;
 
     root_entry = (struct root_entry *) map_vtd_domain_page(iommu->root_maddr);
-    if ( !root_entry || !root_present(root_entry[pdev->bus]) )
+    if ( !root_entry || !root_present(root_entry[pdev->sbdf.bus]) )
         goto out;
 
     ctxt_entry = (struct context_entry *)
-                 map_vtd_domain_page(root_entry[pdev->bus].val);
+                 map_vtd_domain_page(root_entry[pdev->sbdf.bus].val);
 
     if ( ctxt_entry == NULL )
         goto out;
 
-    if ( context_domain_id(ctxt_entry[pdev->devfn]) != did )
+    if ( context_domain_id(ctxt_entry[pdev->sbdf.extfunc]) != did )
         goto out;
 
-    tt = context_translation_type(ctxt_entry[pdev->devfn]);
+    tt = context_translation_type(ctxt_entry[pdev->sbdf.extfunc]);
     if ( tt != CONTEXT_TT_DEV_IOTLB )
         goto out;
 
diff --git a/xen/drivers/passthrough/x86/ats.c b/xen/drivers/passthrough/x86/ats.c
index 59c163459a..ddaec72d19 100644
--- a/xen/drivers/passthrough/x86/ats.c
+++ b/xen/drivers/passthrough/x86/ats.c
@@ -23,8 +23,8 @@ boolean_param("ats", ats_enabled);
 int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
 {
     u32 value;
-    u16 seg = pdev->seg;
-    u8 bus = pdev->bus, devfn = pdev->devfn;
+    uint16_t seg = pdev->sbdf.seg;
+    uint16_t bus = pdev->sbdf.bus, devfn = pdev->sbdf.extfunc;
     int pos;
 
     pos = pci_find_ext_capability(seg, bus, devfn, PCI_EXT_CAP_ID_ATS);
@@ -76,8 +76,8 @@ int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
 void disable_ats_device(struct pci_dev *pdev)
 {
     u32 value;
-    u16 seg = pdev->seg;
-    u8 bus = pdev->bus, devfn = pdev->devfn;
+    uint16_t seg = pdev->sbdf.seg;
+    uint8_t bus = pdev->sbdf.bus, devfn = pdev->sbdf.extfunc;
 
     BUG_ON(!pdev->ats.cap_pos);
 
diff --git a/xen/drivers/pci/pci.c b/xen/drivers/pci/pci.c
index 1c808d6632..a3223a2b29 100644
--- a/xen/drivers/pci/pci.c
+++ b/xen/drivers/pci/pci.c
@@ -117,10 +117,10 @@ int pci_find_next_ext_capability(int seg, int bus, int devfn, int start, int cap
 
 void pci_intx(const struct pci_dev *pdev, bool enable)
 {
-    uint16_t seg = pdev->seg;
-    uint8_t bus = pdev->bus;
-    uint8_t slot = PCI_SLOT(pdev->devfn);
-    uint8_t func = PCI_FUNC(pdev->devfn);
+    uint16_t seg = pdev->sbdf.seg;
+    uint8_t bus = pdev->sbdf.bus;
+    uint8_t slot = pdev->sbdf.dev;
+    uint8_t func = pdev->sbdf.func;
     uint16_t cmd = pci_conf_read16(seg, bus, slot, func, PCI_COMMAND);
 
     if ( enable )
diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
index efb6ca90e3..74d70a4278 100644
--- a/xen/drivers/vpci/header.c
+++ b/xen/drivers/vpci/header.c
@@ -85,7 +85,6 @@ static void modify_decoding(const struct pci_dev *pdev, uint16_t cmd,
                             bool rom_only)
 {
     struct vpci_header *header = &pdev->vpci->header;
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
     bool map = cmd & PCI_COMMAND_MEMORY;
     unsigned int i;
 
@@ -113,7 +112,8 @@ static void modify_decoding(const struct pci_dev *pdev, uint16_t cmd,
                            (map ? PCI_ROM_ADDRESS_ENABLE : 0);
 
             header->bars[i].enabled = header->rom_enabled = map;
-            pci_conf_write32(pdev->seg, pdev->bus, slot, func, rom_pos, val);
+            pci_conf_write32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                             pdev->sbdf.func, rom_pos, val);
             return;
         }
 
@@ -123,8 +123,8 @@ static void modify_decoding(const struct pci_dev *pdev, uint16_t cmd,
     }
 
     if ( !rom_only )
-        pci_conf_write16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND,
-                         cmd);
+        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                         pdev->sbdf.func, PCI_COMMAND, cmd);
     else
         ASSERT_UNREACHABLE();
 }
@@ -335,8 +335,8 @@ static int modify_bars(const struct pci_dev *pdev, uint16_t cmd, bool rom_only)
 static void cmd_write(const struct pci_dev *pdev, unsigned int reg,
                       uint32_t cmd, void *data)
 {
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
-    uint16_t current_cmd = pci_conf_read16(pdev->seg, pdev->bus, slot, func,
+    uint16_t current_cmd = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
+                                           pdev->sbdf.dev, pdev->sbdf.func,
                                            reg);
 
     /*
@@ -352,14 +352,14 @@ static void cmd_write(const struct pci_dev *pdev, unsigned int reg,
          */
         modify_bars(pdev, cmd, false);
     else
-        pci_conf_write16(pdev->seg, pdev->bus, slot, func, reg, cmd);
+        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                         pdev->sbdf.func, reg, cmd);
 }
 
 static void bar_write(const struct pci_dev *pdev, unsigned int reg,
                       uint32_t val, void *data)
 {
     struct vpci_bar *bar = data;
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
     bool hi = false;
 
     if ( bar->type == VPCI_BAR_MEM64_HI )
@@ -371,15 +371,15 @@ static void bar_write(const struct pci_dev *pdev, unsigned int reg,
     else
         val &= PCI_BASE_ADDRESS_MEM_MASK;
 
-    if ( pci_conf_read16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND) &
-         PCI_COMMAND_MEMORY )
+    if ( pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                         pdev->sbdf.func, PCI_COMMAND) & PCI_COMMAND_MEMORY )
     {
         /* If the value written is the current one avoid printing a warning. */
         if ( val != (uint32_t)(bar->addr >> (hi ? 32 : 0)) )
             gprintk(XENLOG_WARNING,
                     "%04x:%02x:%02x.%u: ignored BAR %lu write with memory decoding enabled\n",
-                    pdev->seg, pdev->bus, slot, func,
-                    bar - pdev->vpci->header.bars + hi);
+                    pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                    pdev->sbdf.func, bar - pdev->vpci->header.bars + hi);
         return;
     }
 
@@ -399,8 +399,8 @@ static void bar_write(const struct pci_dev *pdev, unsigned int reg,
         val |= bar->prefetchable ? PCI_BASE_ADDRESS_MEM_PREFETCH : 0;
     }
 
-    pci_conf_write32(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                     PCI_FUNC(pdev->devfn), reg, val);
+    pci_conf_write32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                     pdev->sbdf.func, reg, val);
 }
 
 static void rom_write(const struct pci_dev *pdev, unsigned int reg,
@@ -408,8 +408,8 @@ static void rom_write(const struct pci_dev *pdev, unsigned int reg,
 {
     struct vpci_header *header = &pdev->vpci->header;
     struct vpci_bar *rom = data;
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
-    uint16_t cmd = pci_conf_read16(pdev->seg, pdev->bus, slot, func,
+    uint16_t cmd = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
+                                   pdev->sbdf.dev, pdev->sbdf.func,
                                    PCI_COMMAND);
     bool new_enabled = val & PCI_ROM_ADDRESS_ENABLE;
 
@@ -417,7 +417,8 @@ static void rom_write(const struct pci_dev *pdev, unsigned int reg,
     {
         gprintk(XENLOG_WARNING,
                 "%04x:%02x:%02x.%u: ignored ROM BAR write with memory decoding enabled\n",
-                pdev->seg, pdev->bus, slot, func);
+                pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                pdev->sbdf.func);
         return;
     }
 
@@ -432,7 +433,8 @@ static void rom_write(const struct pci_dev *pdev, unsigned int reg,
     {
         /* Just update the ROM BAR field. */
         header->rom_enabled = new_enabled;
-        pci_conf_write32(pdev->seg, pdev->bus, slot, func, reg, val);
+        pci_conf_write32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                         pdev->sbdf.func, reg, val);
     }
     /*
      * Pass PCI_COMMAND_MEMORY or 0 to signal a map/unmap request, note that
@@ -455,19 +457,15 @@ static void rom_write(const struct pci_dev *pdev, unsigned int reg,
 
 static int init_bars(struct pci_dev *pdev)
 {
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
     uint16_t cmd;
     uint64_t addr, size;
     unsigned int i, num_bars, rom_reg;
     struct vpci_header *header = &pdev->vpci->header;
     struct vpci_bar *bars = header->bars;
-    pci_sbdf_t sbdf = {
-        .sbdf = PCI_SBDF3(pdev->seg, pdev->bus, pdev->devfn),
-    };
     int rc;
 
-    switch ( pci_conf_read8(pdev->seg, pdev->bus, slot, func, PCI_HEADER_TYPE)
-             & 0x7f )
+    switch ( pci_conf_read8(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                            pdev->sbdf.func, PCI_HEADER_TYPE) & 0x7f )
     {
     case PCI_HEADER_TYPE_NORMAL:
         num_bars = PCI_HEADER_NORMAL_NR_BARS;
@@ -493,9 +491,11 @@ static int init_bars(struct pci_dev *pdev)
         return 0;
 
     /* Disable memory decoding before sizing. */
-    cmd = pci_conf_read16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND);
+    cmd = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                          pdev->sbdf.func, PCI_COMMAND);
     if ( cmd & PCI_COMMAND_MEMORY )
-        pci_conf_write16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND,
+        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                         pdev->sbdf.func, PCI_COMMAND,
                          cmd & ~PCI_COMMAND_MEMORY);
 
     for ( i = 0; i < num_bars; i++ )
@@ -510,15 +510,16 @@ static int init_bars(struct pci_dev *pdev)
                                    4, &bars[i]);
             if ( rc )
             {
-                pci_conf_write16(pdev->seg, pdev->bus, slot, func,
-                                 PCI_COMMAND, cmd);
+                pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                                 pdev->sbdf.func, PCI_COMMAND, cmd);
                 return rc;
             }
 
             continue;
         }
 
-        val = pci_conf_read32(pdev->seg, pdev->bus, slot, func, reg);
+        val = pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                              pdev->sbdf.func, reg);
         if ( (val & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO )
         {
             bars[i].type = VPCI_BAR_IO;
@@ -530,12 +531,12 @@ static int init_bars(struct pci_dev *pdev)
         else
             bars[i].type = VPCI_BAR_MEM32;
 
-        rc = pci_size_mem_bar(sbdf, reg, &addr, &size,
+        rc = pci_size_mem_bar(pdev->sbdf, reg, &addr, &size,
                               (i == num_bars - 1) ? PCI_BAR_LAST : 0);
         if ( rc < 0 )
         {
-            pci_conf_write16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND,
-                             cmd);
+            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                             pdev->sbdf.func, PCI_COMMAND, cmd);
             return rc;
         }
 
@@ -553,14 +554,14 @@ static int init_bars(struct pci_dev *pdev)
                                &bars[i]);
         if ( rc )
         {
-            pci_conf_write16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND,
-                             cmd);
+            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                             pdev->sbdf.func, PCI_COMMAND, cmd);
             return rc;
         }
     }
 
     /* Check expansion ROM. */
-    rc = pci_size_mem_bar(sbdf, rom_reg, &addr, &size, PCI_BAR_ROM);
+    rc = pci_size_mem_bar(pdev->sbdf, rom_reg, &addr, &size, PCI_BAR_ROM);
     if ( rc > 0 && size )
     {
         struct vpci_bar *rom = &header->bars[num_bars];
@@ -568,7 +569,8 @@ static int init_bars(struct pci_dev *pdev)
         rom->type = VPCI_BAR_ROM;
         rom->size = size;
         rom->addr = addr;
-        header->rom_enabled = pci_conf_read32(pdev->seg, pdev->bus, slot, func,
+        header->rom_enabled = pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus,
+                                              pdev->sbdf.dev, pdev->sbdf.func,
                                               rom_reg) & PCI_ROM_ADDRESS_ENABLE;
 
         rc = vpci_add_register(pdev->vpci, vpci_hw_read32, rom_write, rom_reg,
diff --git a/xen/drivers/vpci/msi.c b/xen/drivers/vpci/msi.c
index 8f15ad7bf2..dfc894dcc6 100644
--- a/xen/drivers/vpci/msi.c
+++ b/xen/drivers/vpci/msi.c
@@ -77,9 +77,8 @@ static void control_write(const struct pci_dev *pdev, unsigned int reg,
     msi->vectors = vectors;
     msi->enabled = new_enabled;
 
-    pci_conf_write16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                     PCI_FUNC(pdev->devfn), reg,
-                     control_read(pdev, reg, data));
+    pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                     pdev->sbdf.func, reg, control_read(pdev, reg, data));
 }
 
 static void update_msi(const struct pci_dev *pdev, struct vpci_msi *msi)
@@ -187,8 +186,8 @@ static void mask_write(const struct pci_dev *pdev, unsigned int reg,
 
 static int init_msi(struct pci_dev *pdev)
 {
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
-    unsigned int pos = pci_find_cap_offset(pdev->seg, pdev->bus, slot, func,
+    unsigned int pos = pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus,
+                                           pdev->sbdf.dev, pdev->sbdf.func,
                                            PCI_CAP_ID_MSI);
     uint16_t control;
     int ret;
@@ -211,8 +210,8 @@ static int init_msi(struct pci_dev *pdev)
         return ret;
 
     /* Get the maximum number of vectors the device supports. */
-    control = pci_conf_read16(pdev->seg, pdev->bus, slot, func,
-                              msi_control_reg(pos));
+    control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                              pdev->sbdf.func, msi_control_reg(pos));
 
     /*
      * FIXME: I've only been able to test this code with devices using a single
@@ -293,8 +292,8 @@ void vpci_dump_msi(void)
             msi = pdev->vpci->msi;
             if ( msi && msi->enabled )
             {
-                printk("%04x:%02x:%02x.%u MSI\n", pdev->seg, pdev->bus,
-                       PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+                printk("%04x:%02x:%02x.%u MSI\n", pdev->sbdf.seg,
+                       pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func);
 
                 printk("  enabled: %d 64-bit: %d",
                        msi->enabled, msi->address64);
@@ -311,8 +310,8 @@ void vpci_dump_msi(void)
             {
                 int rc;
 
-                printk("%04x:%02x:%02x.%u MSI-X\n", pdev->seg, pdev->bus,
-                       PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+                printk("%04x:%02x:%02x.%u MSI-X\n", pdev->sbdf.seg,
+                       pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func);
 
                 printk("  entries: %u maskall: %d enabled: %d\n",
                        msix->max_entries, msix->masked, msix->enabled);
diff --git a/xen/drivers/vpci/msix.c b/xen/drivers/vpci/msix.c
index af3ffa087d..04431715f5 100644
--- a/xen/drivers/vpci/msix.c
+++ b/xen/drivers/vpci/msix.c
@@ -42,7 +42,6 @@ static uint32_t control_read(const struct pci_dev *pdev, unsigned int reg,
 static int update_entry(struct vpci_msix_entry *entry,
                         const struct pci_dev *pdev, unsigned int nr)
 {
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
     int rc = vpci_msix_arch_disable_entry(entry, pdev);
 
     /* Ignore ENOENT, it means the entry wasn't setup. */
@@ -50,7 +49,8 @@ static int update_entry(struct vpci_msix_entry *entry,
     {
         gprintk(XENLOG_WARNING,
                 "%04x:%02x:%02x.%u: unable to disable entry %u for update: %d\n",
-                pdev->seg, pdev->bus, slot, func, nr, rc);
+                pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func,
+                nr, rc);
         return rc;
     }
 
@@ -61,7 +61,8 @@ static int update_entry(struct vpci_msix_entry *entry,
     {
         gprintk(XENLOG_WARNING,
                 "%04x:%02x:%02x.%u: unable to enable entry %u: %d\n",
-                pdev->seg, pdev->bus, slot, func, nr, rc);
+                pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func,
+                nr, rc);
         /* Entry is likely not properly configured. */
         return rc;
     }
@@ -72,7 +73,6 @@ static int update_entry(struct vpci_msix_entry *entry,
 static void control_write(const struct pci_dev *pdev, unsigned int reg,
                           uint32_t val, void *data)
 {
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
     struct vpci_msix *msix = data;
     bool new_masked = val & PCI_MSIX_FLAGS_MASKALL;
     bool new_enabled = val & PCI_MSIX_FLAGS_ENABLE;
@@ -135,7 +135,8 @@ static void control_write(const struct pci_dev *pdev, unsigned int reg,
             default:
                 gprintk(XENLOG_WARNING,
                         "%04x:%02x:%02x.%u: unable to disable entry %u: %d\n",
-                        pdev->seg, pdev->bus, slot, func, i, rc);
+                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                        pdev->sbdf.func, i, rc);
                 return;
             }
         }
@@ -146,7 +147,8 @@ static void control_write(const struct pci_dev *pdev, unsigned int reg,
 
     val = control_read(pdev, reg, data);
     if ( pci_msi_conf_write_intercept(msix->pdev, reg, 2, &val) >= 0 )
-        pci_conf_write16(pdev->seg, pdev->bus, slot, func, reg, val);
+        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                         pdev->sbdf.func, reg, val);
 }
 
 static struct vpci_msix *msix_find(const struct domain *d, unsigned long addr)
@@ -181,7 +183,7 @@ static bool access_allowed(const struct pci_dev *pdev, unsigned long addr,
 
     gprintk(XENLOG_WARNING,
             "%04x:%02x:%02x.%u: unaligned or invalid size MSI-X table access\n",
-            pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+            pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func);
 
     return false;
 }
@@ -433,8 +435,8 @@ int vpci_make_msix_hole(const struct pci_dev *pdev)
                 gprintk(XENLOG_WARNING,
                         "%04x:%02x:%02x.%u: existing mapping (mfn: %" PRI_mfn
                         "type: %d) at %#lx clobbers MSIX MMIO area\n",
-                        pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                        PCI_FUNC(pdev->devfn), mfn_x(mfn), t, start);
+                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                        pdev->sbdf.func, mfn_x(mfn), t, start);
                 return -EEXIST;
             }
             put_gfn(d, start);
@@ -447,18 +449,18 @@ int vpci_make_msix_hole(const struct pci_dev *pdev)
 static int init_msix(struct pci_dev *pdev)
 {
     struct domain *d = pdev->domain;
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
     unsigned int msix_offset, i, max_entries;
     uint16_t control;
     int rc;
 
-    msix_offset = pci_find_cap_offset(pdev->seg, pdev->bus, slot, func,
+    msix_offset = pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus,
+                                      pdev->sbdf.dev, pdev->sbdf.func,
                                       PCI_CAP_ID_MSIX);
     if ( !msix_offset )
         return 0;
 
-    control = pci_conf_read16(pdev->seg, pdev->bus, slot, func,
-                              msix_control_reg(msix_offset));
+    control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                              pdev->sbdf.func, msix_control_reg(msix_offset));
 
     max_entries = msix_table_size(control);
 
@@ -470,11 +472,11 @@ static int init_msix(struct pci_dev *pdev)
     pdev->vpci->msix->pdev = pdev;
 
     pdev->vpci->msix->tables[VPCI_MSIX_TABLE] =
-        pci_conf_read32(pdev->seg, pdev->bus, slot, func,
-                        msix_table_offset_reg(msix_offset));
+        pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                        pdev->sbdf.func, msix_table_offset_reg(msix_offset));
     pdev->vpci->msix->tables[VPCI_MSIX_PBA] =
-        pci_conf_read32(pdev->seg, pdev->bus, slot, func,
-                        msix_pba_offset_reg(msix_offset));
+        pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                        pdev->sbdf.func, msix_pba_offset_reg(msix_offset));
 
     for ( i = 0; i < pdev->vpci->msix->max_entries; i++)
     {
diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c
index 82607bdb9a..9a060c108e 100644
--- a/xen/drivers/vpci/vpci.c
+++ b/xen/drivers/vpci/vpci.c
@@ -114,15 +114,15 @@ static void vpci_ignored_write(const struct pci_dev *pdev, unsigned int reg,
 uint32_t vpci_hw_read16(const struct pci_dev *pdev, unsigned int reg,
                         void *data)
 {
-    return pci_conf_read16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                           PCI_FUNC(pdev->devfn), reg);
+    return pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                           pdev->sbdf.func, reg);
 }
 
 uint32_t vpci_hw_read32(const struct pci_dev *pdev, unsigned int reg,
                         void *data)
 {
-    return pci_conf_read32(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                           PCI_FUNC(pdev->devfn), reg);
+    return pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                           pdev->sbdf.func, reg);
 }
 
 int vpci_add_register(struct vpci *vpci, vpci_read_t *read_handler,
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 8b21e8dc84..1cf54eb466 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -80,9 +80,8 @@ struct pci_dev {
     struct arch_msix *msix;
 
     struct domain *domain;
-    const u16 seg;
-    const u8 bus;
-    const u8 devfn;
+
+    const pci_sbdf_t sbdf;
 
     u8 phantom_stride;
 
-- 
2.17.2 (Apple Git-113)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Xen-devel] [PATCH 1/5] pci: use pci_sbdf_t in pci_dev
@ 2019-05-10 16:10   ` Roger Pau Monne
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monne @ 2019-05-10 16:10 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Suravee Suthikulpanit,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper, Ian Jackson,
	Tim Deegan, Julien Grall, Jan Beulich, Brian Woods,
	Roger Pau Monne

This patch replaces the seg, bus and devfn fields of the struct and
fixes the callers. While there instances of u<size> have also been
replaced with uint<size>_t.

No functional change intended.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Julien Grall <julien.grall@arm.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Brian Woods <brian.woods@amd.com>
Cc: Kevin Tian <kevin.tian@intel.com>
---
 xen/arch/x86/hvm/vmsi.c                     |  14 +-
 xen/arch/x86/msi.c                          | 136 ++++++++--------
 xen/drivers/passthrough/amd/iommu_cmd.c     |  16 +-
 xen/drivers/passthrough/amd/iommu_intr.c    |  14 +-
 xen/drivers/passthrough/amd/iommu_map.c     |  10 +-
 xen/drivers/passthrough/amd/pci_amd_iommu.c |  58 ++++---
 xen/drivers/passthrough/pci.c               | 162 ++++++++++----------
 xen/drivers/passthrough/vtd/dmar.c          |  12 +-
 xen/drivers/passthrough/vtd/intremap.c      |   8 +-
 xen/drivers/passthrough/vtd/iommu.c         |  34 ++--
 xen/drivers/passthrough/vtd/qinval.c        |   2 +-
 xen/drivers/passthrough/vtd/quirks.c        |  16 +-
 xen/drivers/passthrough/vtd/x86/ats.c       |  12 +-
 xen/drivers/passthrough/x86/ats.c           |   8 +-
 xen/drivers/pci/pci.c                       |   8 +-
 xen/drivers/vpci/header.c                   |  74 ++++-----
 xen/drivers/vpci/msi.c                      |  21 ++-
 xen/drivers/vpci/msix.c                     |  36 +++--
 xen/drivers/vpci/vpci.c                     |   8 +-
 xen/include/xen/pci.h                       |   5 +-
 20 files changed, 322 insertions(+), 332 deletions(-)

diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c
index aeb5a70104..15cfe8d057 100644
--- a/xen/arch/x86/hvm/vmsi.c
+++ b/xen/arch/x86/hvm/vmsi.c
@@ -688,8 +688,8 @@ static int vpci_msi_update(const struct pci_dev *pdev, uint32_t data,
         {
             gdprintk(XENLOG_ERR,
                      "%04x:%02x:%02x.%u: failed to bind PIRQ %u: %d\n",
-                     pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                     PCI_FUNC(pdev->devfn), pirq + i, rc);
+                     pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                     pdev->sbdf.func, pirq + i, rc);
             while ( bind.machine_irq-- > pirq )
                 pt_irq_destroy_bind(pdev->domain, &bind);
             return rc;
@@ -727,9 +727,9 @@ static int vpci_msi_enable(const struct pci_dev *pdev, uint32_t data,
                            paddr_t table_base, uint32_t mask)
 {
     struct msi_info msi_info = {
-        .seg = pdev->seg,
-        .bus = pdev->bus,
-        .devfn = pdev->devfn,
+        .seg = pdev->sbdf.seg,
+        .bus = pdev->sbdf.bus,
+        .devfn = pdev->sbdf.extfunc,
         .table_base = table_base,
         .entry_nr = nr,
     };
@@ -744,8 +744,8 @@ static int vpci_msi_enable(const struct pci_dev *pdev, uint32_t data,
     if ( rc )
     {
         gdprintk(XENLOG_ERR, "%04x:%02x:%02x.%u: failed to map PIRQ: %d\n",
-                 pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                 PCI_FUNC(pdev->devfn), rc);
+                 pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                 pdev->sbdf.func, rc);
         return rc;
     }
 
diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index babc4147c4..f30f592ee2 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -124,13 +124,13 @@ static void msix_put_fixmap(struct arch_msix *msix, int idx)
 
 static bool memory_decoded(const struct pci_dev *dev)
 {
-    u8 bus, slot, func;
+    uint8_t bus, slot, func;
 
     if ( !dev->info.is_virtfn )
     {
-        bus = dev->bus;
-        slot = PCI_SLOT(dev->devfn);
-        func = PCI_FUNC(dev->devfn);
+        bus = dev->sbdf.bus;
+        slot = dev->sbdf.dev;
+        func = dev->sbdf.func;
     }
     else
     {
@@ -139,14 +139,14 @@ static bool memory_decoded(const struct pci_dev *dev)
         func = PCI_FUNC(dev->info.physfn.devfn);
     }
 
-    return !!(pci_conf_read16(dev->seg, bus, slot, func, PCI_COMMAND) &
+    return !!(pci_conf_read16(dev->sbdf.seg, bus, slot, func, PCI_COMMAND) &
               PCI_COMMAND_MEMORY);
 }
 
 static bool msix_memory_decoded(const struct pci_dev *dev, unsigned int pos)
 {
-    u16 control = pci_conf_read16(dev->seg, dev->bus, PCI_SLOT(dev->devfn),
-                                  PCI_FUNC(dev->devfn), msix_control_reg(pos));
+    u16 control = pci_conf_read16(dev->sbdf.seg, dev->sbdf.bus, dev->sbdf.dev,
+                                  dev->sbdf.func, msix_control_reg(pos));
 
     if ( !(control & PCI_MSIX_FLAGS_ENABLE) )
         return false;
@@ -200,10 +200,10 @@ static bool read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
     {
         struct pci_dev *dev = entry->dev;
         int pos = entry->msi_attrib.pos;
-        u16 data, seg = dev->seg;
-        u8 bus = dev->bus;
-        u8 slot = PCI_SLOT(dev->devfn);
-        u8 func = PCI_FUNC(dev->devfn);
+        uint16_t data, seg = dev->sbdf.seg;
+        uint8_t bus = dev->sbdf.bus;
+        uint8_t slot = dev->sbdf.dev;
+        uint8_t func = dev->sbdf.func;
 
         msg->address_lo = pci_conf_read32(seg, bus, slot, func,
                                           msi_lower_address_reg(pos));
@@ -265,10 +265,10 @@ static int write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
     {
         struct pci_dev *dev = entry->dev;
         int pos = entry->msi_attrib.pos;
-        u16 seg = dev->seg;
-        u8 bus = dev->bus;
-        u8 slot = PCI_SLOT(dev->devfn);
-        u8 func = PCI_FUNC(dev->devfn);
+        uint16_t seg = dev->sbdf.seg;
+        uint8_t bus = dev->sbdf.bus;
+        uint8_t slot = dev->sbdf.dev;
+        uint8_t func = dev->sbdf.func;
         int nr = entry->msi_attrib.entry_nr;
 
         ASSERT((msg->data & (entry[-nr].msi.nvec - 1)) == nr);
@@ -348,10 +348,10 @@ void __msi_set_enable(u16 seg, u8 bus, u8 slot, u8 func, int pos, int enable)
 static void msi_set_enable(struct pci_dev *dev, int enable)
 {
     int pos;
-    u16 seg = dev->seg;
-    u8 bus = dev->bus;
-    u8 slot = PCI_SLOT(dev->devfn);
-    u8 func = PCI_FUNC(dev->devfn);
+    uint16_t seg = dev->sbdf.seg;
+    uint8_t bus = dev->sbdf.bus;
+    uint8_t slot = dev->sbdf.dev;
+    uint8_t func = dev->sbdf.func;
 
     pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSI);
     if ( pos )
@@ -361,10 +361,10 @@ static void msi_set_enable(struct pci_dev *dev, int enable)
 static void msix_set_enable(struct pci_dev *dev, int enable)
 {
     int pos;
-    u16 control, seg = dev->seg;
-    u8 bus = dev->bus;
-    u8 slot = PCI_SLOT(dev->devfn);
-    u8 func = PCI_FUNC(dev->devfn);
+    uint16_t control, seg = dev->sbdf.seg;
+    uint8_t bus = dev->sbdf.bus;
+    uint8_t slot = dev->sbdf.dev;
+    uint8_t func = dev->sbdf.func;
 
     pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSIX);
     if ( pos )
@@ -388,17 +388,17 @@ static bool msi_set_mask_bit(struct irq_desc *desc, bool host, bool guest)
 {
     struct msi_desc *entry = desc->msi_desc;
     struct pci_dev *pdev;
-    u16 seg, control;
-    u8 bus, slot, func;
+    uint16_t seg, control;
+    uint8_t bus, slot, func;
     bool flag = host || guest, maskall;
 
     ASSERT(spin_is_locked(&desc->lock));
     BUG_ON(!entry || !entry->dev);
     pdev = entry->dev;
-    seg = pdev->seg;
-    bus = pdev->bus;
-    slot = PCI_SLOT(pdev->devfn);
-    func = PCI_FUNC(pdev->devfn);
+    seg = pdev->sbdf.seg;
+    bus = pdev->sbdf.bus;
+    slot = pdev->sbdf.dev;
+    func = pdev->sbdf.func;
     switch ( entry->msi_attrib.type )
     {
     case PCI_CAP_ID_MSI:
@@ -475,9 +475,8 @@ static int msi_get_mask_bit(const struct msi_desc *entry)
     case PCI_CAP_ID_MSI:
         if ( !entry->msi_attrib.maskbit )
             break;
-        return (pci_conf_read32(entry->dev->seg, entry->dev->bus,
-                                PCI_SLOT(entry->dev->devfn),
-                                PCI_FUNC(entry->dev->devfn),
+        return (pci_conf_read32(entry->dev->sbdf.seg, entry->dev->sbdf.bus,
+                                entry->dev->sbdf.dev, entry->dev->sbdf.func,
                                 entry->msi.mpos) >>
                 entry->msi_attrib.entry_nr) & 1;
     case PCI_CAP_ID_MSIX:
@@ -594,11 +593,11 @@ int setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc)
 
     if ( msidesc->msi_attrib.type == PCI_CAP_ID_MSIX )
     {
-        control = pci_conf_read16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                                  PCI_FUNC(pdev->devfn), cpos);
+        control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
+                                  pdev->sbdf.dev, pdev->sbdf.func, cpos);
         if ( !(control & PCI_MSIX_FLAGS_ENABLE) )
-            pci_conf_write16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                             PCI_FUNC(pdev->devfn), cpos,
+            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                             pdev->sbdf.func, cpos,
                              control | (PCI_MSIX_FLAGS_ENABLE |
                                         PCI_MSIX_FLAGS_MASKALL));
     }
@@ -608,8 +607,8 @@ int setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc)
                                                    : &pci_msi_nonmaskable);
 
     if ( !(control & PCI_MSIX_FLAGS_ENABLE) )
-        pci_conf_write16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                         PCI_FUNC(pdev->devfn), cpos, control);
+        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                         pdev->sbdf.func, cpos, control);
 
     return rc;
 }
@@ -689,10 +688,10 @@ static int msi_capability_init(struct pci_dev *dev,
     struct msi_desc *entry;
     int pos;
     unsigned int i, maxvec, mpos;
-    u16 control, seg = dev->seg;
-    u8 bus = dev->bus;
-    u8 slot = PCI_SLOT(dev->devfn);
-    u8 func = PCI_FUNC(dev->devfn);
+    uint16_t control, seg = dev->sbdf.seg;
+    uint8_t bus = dev->sbdf.bus;
+    uint8_t slot = dev->sbdf.dev;
+    uint8_t func = dev->sbdf.func;
 
     ASSERT(pcidevs_locked());
     pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSI);
@@ -856,10 +855,10 @@ static int msix_capability_init(struct pci_dev *dev,
     u64 table_paddr;
     u32 table_offset;
     u8 bir, pbus, pslot, pfunc;
-    u16 seg = dev->seg;
-    u8 bus = dev->bus;
-    u8 slot = PCI_SLOT(dev->devfn);
-    u8 func = PCI_FUNC(dev->devfn);
+    uint16_t seg = dev->sbdf.seg;
+    uint8_t bus = dev->sbdf.bus;
+    uint8_t slot = dev->sbdf.dev;
+    uint8_t func = dev->sbdf.func;
     bool maskall = msix->host_maskall;
 
     ASSERT(pcidevs_locked());
@@ -913,7 +912,7 @@ static int msix_capability_init(struct pci_dev *dev,
         pbus = dev->info.physfn.bus;
         pslot = PCI_SLOT(dev->info.physfn.devfn);
         pfunc = PCI_FUNC(dev->info.physfn.devfn);
-        vf = PCI_BDF2(dev->bus, dev->devfn);
+        vf = dev->sbdf.bdf;
     }
 
     table_paddr = read_pci_mem_bar(seg, pbus, pslot, pfunc, bir, vf);
@@ -1172,10 +1171,10 @@ static void _pci_cleanup_msix(struct arch_msix *msix)
 static void __pci_disable_msix(struct msi_desc *entry)
 {
     struct pci_dev *dev = entry->dev;
-    u16 seg = dev->seg;
-    u8 bus = dev->bus;
-    u8 slot = PCI_SLOT(dev->devfn);
-    u8 func = PCI_FUNC(dev->devfn);
+    uint16_t seg = dev->sbdf.seg;
+    uint8_t bus = dev->sbdf.bus;
+    uint8_t slot = dev->sbdf.dev;
+    uint8_t func = dev->sbdf.func;
     unsigned int pos = pci_find_cap_offset(seg, bus, slot, func,
                                            PCI_CAP_ID_MSIX);
     u16 control = pci_conf_read16(seg, bus, slot, func,
@@ -1295,10 +1294,10 @@ void pci_cleanup_msi(struct pci_dev *pdev)
 int pci_msi_conf_write_intercept(struct pci_dev *pdev, unsigned int reg,
                                  unsigned int size, uint32_t *data)
 {
-    u16 seg = pdev->seg;
-    u8 bus = pdev->bus;
-    u8 slot = PCI_SLOT(pdev->devfn);
-    u8 func = PCI_FUNC(pdev->devfn);
+    uint16_t seg = pdev->sbdf.seg;
+    uint8_t bus = pdev->sbdf.bus;
+    uint8_t slot = pdev->sbdf.dev;
+    uint8_t func = pdev->sbdf.func;
     struct msi_desc *entry;
     unsigned int pos;
 
@@ -1365,7 +1364,7 @@ int pci_restore_msi_state(struct pci_dev *pdev)
     struct msi_desc *entry, *tmp;
     struct irq_desc *desc;
     struct msi_msg msg;
-    u8 slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
+    uint8_t slot = pdev->sbdf.dev, func = pdev->sbdf.func;
     unsigned int type = 0, pos = 0;
     u16 control = 0;
 
@@ -1374,9 +1373,7 @@ int pci_restore_msi_state(struct pci_dev *pdev)
     if ( !use_msi )
         return -EOPNOTSUPP;
 
-    ret = xsm_resource_setup_pci(XSM_PRIV,
-                                (pdev->seg << 16) | (pdev->bus << 8) |
-                                pdev->devfn);
+    ret = xsm_resource_setup_pci(XSM_PRIV, pdev->sbdf.sbdf);
     if ( ret )
         return ret;
 
@@ -1396,10 +1393,10 @@ int pci_restore_msi_state(struct pci_dev *pdev)
     bogus:
             dprintk(XENLOG_ERR,
                     "Restore MSI for %04x:%02x:%02x:%u entry %u not set?\n",
-                    pdev->seg, pdev->bus, slot, func, i);
+                    pdev->sbdf.seg, pdev->sbdf.bus, slot, func, i);
             spin_unlock_irqrestore(&desc->lock, flags);
             if ( type == PCI_CAP_ID_MSIX )
-                pci_conf_write16(pdev->seg, pdev->bus, slot, func,
+                pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
                                  msix_control_reg(pos),
                                  control & ~PCI_MSIX_FLAGS_ENABLE);
             return -EINVAL;
@@ -1414,16 +1411,16 @@ int pci_restore_msi_state(struct pci_dev *pdev)
         }
         else if ( !type && entry->msi_attrib.type == PCI_CAP_ID_MSIX )
         {
-            control = pci_conf_read16(pdev->seg, pdev->bus, slot, func,
-                                      msix_control_reg(pos));
-            pci_conf_write16(pdev->seg, pdev->bus, slot, func,
+            control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, slot,
+                                      func, msix_control_reg(pos));
+            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
                              msix_control_reg(pos),
                              control | (PCI_MSIX_FLAGS_ENABLE |
                                         PCI_MSIX_FLAGS_MASKALL));
             if ( unlikely(!memory_decoded(pdev)) )
             {
                 spin_unlock_irqrestore(&desc->lock, flags);
-                pci_conf_write16(pdev->seg, pdev->bus, slot, func,
+                pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
                                  msix_control_reg(pos),
                                  control & ~PCI_MSIX_FLAGS_ENABLE);
                 return -ENXIO;
@@ -1457,17 +1454,18 @@ int pci_restore_msi_state(struct pci_dev *pdev)
         {
             unsigned int cpos = msi_control_reg(pos);
 
-            control = pci_conf_read16(pdev->seg, pdev->bus, slot, func, cpos) &
-                      ~PCI_MSI_FLAGS_QSIZE;
+            control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, slot,
+                                      func, cpos) & ~PCI_MSI_FLAGS_QSIZE;
             multi_msi_enable(control, entry->msi.nvec);
-            pci_conf_write16(pdev->seg, pdev->bus, slot, func, cpos, control);
+            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func, cpos,
+                             control);
 
             msi_set_enable(pdev, 1);
         }
     }
 
     if ( type == PCI_CAP_ID_MSIX )
-        pci_conf_write16(pdev->seg, pdev->bus, slot, func,
+        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
                          msix_control_reg(pos),
                          control | PCI_MSIX_FLAGS_ENABLE);
 
diff --git a/xen/drivers/passthrough/amd/iommu_cmd.c b/xen/drivers/passthrough/amd/iommu_cmd.c
index af3a1fb865..82330c24ba 100644
--- a/xen/drivers/passthrough/amd/iommu_cmd.c
+++ b/xen/drivers/passthrough/amd/iommu_cmd.c
@@ -289,23 +289,23 @@ void amd_iommu_flush_iotlb(u8 devfn, const struct pci_dev *pdev,
     if ( !ats_enabled )
         return;
 
-    if ( !pci_ats_enabled(pdev->seg, pdev->bus, pdev->devfn) )
+    if ( !pci_ats_enabled(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.extfunc) )
         return;
 
-    iommu = find_iommu_for_device(pdev->seg, PCI_BDF2(pdev->bus, pdev->devfn));
+    iommu = find_iommu_for_device(pdev->sbdf.seg, pdev->sbdf.bdf);
 
     if ( !iommu )
     {
         AMD_IOMMU_DEBUG("%s: Can't find iommu for %04x:%02x:%02x.%u\n",
-                        __func__, pdev->seg, pdev->bus,
-                        PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+                        __func__, pdev->sbdf.seg, pdev->sbdf.bus,
+                        pdev->sbdf.dev, pdev->sbdf.func);
         return;
     }
 
     if ( !iommu_has_cap(iommu, PCI_CAP_IOTLB_SHIFT) )
         return;
 
-    req_id = get_dma_requestor_id(iommu->seg, PCI_BDF2(pdev->bus, devfn));
+    req_id = get_dma_requestor_id(iommu->seg, PCI_BDF2(pdev->sbdf.bus, devfn));
     queueid = req_id;
     maxpend = pdev->ats.queue_depth & 0xff;
 
@@ -326,13 +326,13 @@ static void amd_iommu_flush_all_iotlbs(struct domain *d, daddr_t daddr,
 
     for_each_pdev( d, pdev )
     {
-        u8 devfn = pdev->devfn;
+        uint8_t devfn = pdev->sbdf.extfunc;
 
         do {
             amd_iommu_flush_iotlb(devfn, pdev, daddr, order);
             devfn += pdev->phantom_stride;
-        } while ( devfn != pdev->devfn &&
-                  PCI_SLOT(devfn) == PCI_SLOT(pdev->devfn) );
+        } while ( devfn != pdev->sbdf.extfunc &&
+                  PCI_SLOT(devfn) == pdev->sbdf.dev );
     }
 }
 
diff --git a/xen/drivers/passthrough/amd/iommu_intr.c b/xen/drivers/passthrough/amd/iommu_intr.c
index dad2d1e5ab..71594cc27d 100644
--- a/xen/drivers/passthrough/amd/iommu_intr.c
+++ b/xen/drivers/passthrough/amd/iommu_intr.c
@@ -525,8 +525,8 @@ int amd_iommu_msi_msg_update_ire(
     unsigned int i, nr = 1;
     u32 data;
 
-    bdf = pdev ? PCI_BDF2(pdev->bus, pdev->devfn) : hpet_sbdf.bdf;
-    seg = pdev ? pdev->seg : hpet_sbdf.seg;
+    bdf = pdev ? pdev->sbdf.bdf : hpet_sbdf.bdf;
+    seg = pdev ? pdev->sbdf.seg : hpet_sbdf.seg;
 
     iommu = _find_iommu_for_device(seg, bdf);
     if ( IS_ERR_OR_NULL(iommu) )
@@ -544,12 +544,12 @@ int amd_iommu_msi_msg_update_ire(
             if ( !pdev || !pdev->phantom_stride )
                 break;
             bdf += pdev->phantom_stride;
-        } while ( PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
+        } while ( PCI_SLOT(bdf) == pdev->sbdf.dev );
 
         for ( i = 0; i < nr; ++i )
             msi_desc[i].remap_index = -1;
         if ( pdev )
-            bdf = PCI_BDF2(pdev->bus, pdev->devfn);
+            bdf = pdev->sbdf.bdf;
     }
 
     if ( !msg )
@@ -562,7 +562,7 @@ int amd_iommu_msi_msg_update_ire(
         if ( rc || !pdev || !pdev->phantom_stride )
             break;
         bdf += pdev->phantom_stride;
-    } while ( PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
+    } while ( PCI_SLOT(bdf) == pdev->sbdf.dev );
 
     if ( !rc )
     {
@@ -579,8 +579,8 @@ void amd_iommu_read_msi_from_ire(
 {
     unsigned int offset = msg->data & (INTREMAP_ENTRIES - 1);
     const struct pci_dev *pdev = msi_desc->dev;
-    u16 bdf = pdev ? PCI_BDF2(pdev->bus, pdev->devfn) : hpet_sbdf.bdf;
-    u16 seg = pdev ? pdev->seg : hpet_sbdf.seg;
+    uint16_t bdf = pdev ? pdev->sbdf.bdf : hpet_sbdf.bdf;
+    uint16_t seg = pdev ? pdev->sbdf.seg : hpet_sbdf.seg;
     const u32 *entry;
 
     if ( IS_ERR_OR_NULL(_find_iommu_for_device(seg, bdf)) )
diff --git a/xen/drivers/passthrough/amd/iommu_map.c b/xen/drivers/passthrough/amd/iommu_map.c
index cbf00e9e72..314d871c9e 100644
--- a/xen/drivers/passthrough/amd/iommu_map.c
+++ b/xen/drivers/passthrough/amd/iommu_map.c
@@ -324,8 +324,8 @@ static int update_paging_mode(struct domain *d, unsigned long dfn)
             if ( pdev->type == DEV_TYPE_PCI_HOST_BRIDGE )
                 continue;
 
-            bdf = PCI_BDF2(pdev->bus, pdev->devfn);
-            iommu = find_iommu_for_device(pdev->seg, bdf);
+            bdf = pdev->sbdf.bdf;
+            iommu = find_iommu_for_device(pdev->sbdf.seg, bdf);
             if ( !iommu )
             {
                 AMD_IOMMU_DEBUG("%s Fail to find iommu.\n", __func__);
@@ -334,7 +334,7 @@ static int update_paging_mode(struct domain *d, unsigned long dfn)
 
             spin_lock_irqsave(&iommu->lock, flags);
             do {
-                req_id = get_dma_requestor_id(pdev->seg, bdf);
+                req_id = get_dma_requestor_id(pdev->sbdf.seg, bdf);
                 table = iommu->dev_table.buffer;
                 dte = &table[req_id];
 
@@ -346,8 +346,8 @@ static int update_paging_mode(struct domain *d, unsigned long dfn)
 
                 amd_iommu_flush_device(iommu, req_id);
                 bdf += pdev->phantom_stride;
-            } while ( PCI_DEVFN2(bdf) != pdev->devfn &&
-                      PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
+            } while ( PCI_DEVFN2(bdf) != pdev->sbdf.extfunc &&
+                      PCI_SLOT(bdf) == pdev->sbdf.dev );
             spin_unlock_irqrestore(&iommu->lock, flags);
         }
 
diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/passthrough/amd/pci_amd_iommu.c
index dbc71ca7d5..0e4c5b4994 100644
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -94,7 +94,7 @@ static void amd_iommu_setup_domain_device(
     unsigned long flags;
     int req_id, valid = 1;
     int dte_i = 0;
-    u8 bus = pdev->bus;
+    uint8_t bus = pdev->sbdf.bus;
     const struct domain_iommu *hd = dom_iommu(domain);
 
     BUG_ON( !hd->arch.root_table || !hd->arch.paging_mode ||
@@ -120,7 +120,7 @@ static void amd_iommu_setup_domain_device(
             dte, page_to_maddr(hd->arch.root_table), domain->domain_id,
             hd->arch.paging_mode, valid);
 
-        if ( pci_ats_device(iommu->seg, bus, pdev->devfn) &&
+        if ( pci_ats_device(iommu->seg, bus, pdev->sbdf.extfunc) &&
              iommu_has_cap(iommu, PCI_CAP_IOTLB_SHIFT) )
             dte->i = dte_i;
 
@@ -138,10 +138,10 @@ static void amd_iommu_setup_domain_device(
 
     ASSERT(pcidevs_locked());
 
-    if ( pci_ats_device(iommu->seg, bus, pdev->devfn) &&
-         !pci_ats_enabled(iommu->seg, bus, pdev->devfn) )
+    if ( pci_ats_device(iommu->seg, bus, pdev->sbdf.extfunc) &&
+         !pci_ats_enabled(iommu->seg, bus, pdev->sbdf.extfunc) )
     {
-        if ( devfn == pdev->devfn )
+        if ( devfn == pdev->sbdf.extfunc )
             enable_ats_device(pdev, &iommu->ats_devices);
 
         amd_iommu_flush_iotlb(devfn, pdev, INV_IOMMU_ALL_PAGES_ADDRESS, 0);
@@ -261,7 +261,7 @@ void amd_iommu_disable_domain_device(struct domain *domain,
     struct amd_iommu_dte *table, *dte;
     unsigned long flags;
     int req_id;
-    u8 bus = pdev->bus;
+    uint8_t bus = pdev->sbdf.bus;
 
     BUG_ON ( iommu->dev_table.buffer == NULL );
     req_id = get_dma_requestor_id(iommu->seg, PCI_BDF2(bus, devfn));
@@ -274,7 +274,7 @@ void amd_iommu_disable_domain_device(struct domain *domain,
         dte->tv = 0;
         dte->v = 0;
 
-        if ( pci_ats_device(iommu->seg, bus, pdev->devfn) &&
+        if ( pci_ats_device(iommu->seg, bus, pdev->sbdf.extfunc) &&
              iommu_has_cap(iommu, PCI_CAP_IOTLB_SHIFT) )
             dte->i = 0;
 
@@ -289,7 +289,7 @@ void amd_iommu_disable_domain_device(struct domain *domain,
 
     ASSERT(pcidevs_locked());
 
-    if ( devfn == pdev->devfn &&
+    if ( devfn == pdev->sbdf.extfunc &&
          pci_ats_device(iommu->seg, bus, devfn) &&
          pci_ats_enabled(iommu->seg, bus, devfn) )
         disable_ats_device(pdev);
@@ -299,23 +299,22 @@ static int reassign_device(struct domain *source, struct domain *target,
                            u8 devfn, struct pci_dev *pdev)
 {
     struct amd_iommu *iommu;
-    int bdf, rc;
+    int rc;
     struct domain_iommu *t = dom_iommu(target);
 
-    bdf = PCI_BDF2(pdev->bus, pdev->devfn);
-    iommu = find_iommu_for_device(pdev->seg, bdf);
+    iommu = find_iommu_for_device(pdev->sbdf.seg, pdev->sbdf.bdf);
     if ( !iommu )
     {
         AMD_IOMMU_DEBUG("Fail to find iommu."
                         " %04x:%02x:%x02.%x cannot be assigned to dom%d\n",
-                        pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                        target->domain_id);
+                        pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn),
+                        PCI_FUNC(devfn), target->domain_id);
         return -ENODEV;
     }
 
     amd_iommu_disable_domain_device(source, iommu, devfn, pdev);
 
-    if ( devfn == pdev->devfn )
+    if ( devfn == pdev->sbdf.extfunc )
     {
         list_move(&pdev->domain_list, &target->arch.pdev_list);
         pdev->domain = target;
@@ -327,8 +326,8 @@ static int reassign_device(struct domain *source, struct domain *target,
 
     amd_iommu_setup_domain_device(target, iommu, devfn, pdev);
     AMD_IOMMU_DEBUG("Re-assign %04x:%02x:%02x.%u from dom%d to dom%d\n",
-                    pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                    source->domain_id, target->domain_id);
+                    pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn),
+                    PCI_FUNC(devfn), source->domain_id, target->domain_id);
 
     return 0;
 }
@@ -337,9 +336,9 @@ static int amd_iommu_assign_device(struct domain *d, u8 devfn,
                                    struct pci_dev *pdev,
                                    u32 flag)
 {
-    struct ivrs_mappings *ivrs_mappings = get_ivrs_mappings(pdev->seg);
-    int bdf = PCI_BDF2(pdev->bus, devfn);
-    int req_id = get_dma_requestor_id(pdev->seg, bdf);
+    struct ivrs_mappings *ivrs_mappings = get_ivrs_mappings(pdev->sbdf.seg);
+    int bdf = PCI_BDF2(pdev->sbdf.bus, devfn);
+    int req_id = get_dma_requestor_id(pdev->sbdf.seg, bdf);
 
     if ( ivrs_mappings[req_id].unity_map_enable )
     {
@@ -420,13 +419,11 @@ static void amd_iommu_domain_destroy(struct domain *d)
 static int amd_iommu_add_device(u8 devfn, struct pci_dev *pdev)
 {
     struct amd_iommu *iommu;
-    u16 bdf;
 
     if ( !pdev->domain )
         return -EINVAL;
 
-    bdf = PCI_BDF2(pdev->bus, pdev->devfn);
-    iommu = find_iommu_for_device(pdev->seg, bdf);
+    iommu = find_iommu_for_device(pdev->sbdf.seg, pdev->sbdf.bdf);
     if ( unlikely(!iommu) )
     {
         /* Filter bridge devices. */
@@ -434,14 +431,14 @@ static int amd_iommu_add_device(u8 devfn, struct pci_dev *pdev)
              is_hardware_domain(pdev->domain) )
         {
             AMD_IOMMU_DEBUG("Skipping host bridge %04x:%02x:%02x.%u\n",
-                            pdev->seg, pdev->bus, PCI_SLOT(devfn),
-                            PCI_FUNC(devfn));
+                            pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                            pdev->sbdf.func);
             return 0;
         }
 
         AMD_IOMMU_DEBUG("No iommu for %04x:%02x:%02x.%u; cannot be handed to d%d\n",
-                        pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                        pdev->domain->domain_id);
+                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                        pdev->sbdf.func, pdev->domain->domain_id);
         return -ENODEV;
     }
 
@@ -452,18 +449,17 @@ static int amd_iommu_add_device(u8 devfn, struct pci_dev *pdev)
 static int amd_iommu_remove_device(u8 devfn, struct pci_dev *pdev)
 {
     struct amd_iommu *iommu;
-    u16 bdf;
+
     if ( !pdev->domain )
         return -EINVAL;
 
-    bdf = PCI_BDF2(pdev->bus, pdev->devfn);
-    iommu = find_iommu_for_device(pdev->seg, bdf);
+    iommu = find_iommu_for_device(pdev->sbdf.seg, pdev->sbdf.bdf);
     if ( !iommu )
     {
         AMD_IOMMU_DEBUG("Fail to find iommu."
                         " %04x:%02x:%02x.%u cannot be removed from dom%d\n",
-                        pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                        pdev->domain->domain_id);
+                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                        pdev->sbdf.func, pdev->domain->domain_id);
         return -ENODEV;
     }
 
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index 8108ed5f9a..8de8d8e110 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -238,10 +238,10 @@ static void check_pdev(const struct pci_dev *pdev)
     (PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT | \
      PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT | \
      PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY)
-    u16 seg = pdev->seg;
-    u8 bus = pdev->bus;
-    u8 dev = PCI_SLOT(pdev->devfn);
-    u8 func = PCI_FUNC(pdev->devfn);
+    uint16_t seg = pdev->sbdf.seg;
+    uint8_t bus = pdev->sbdf.bus;
+    uint8_t dev = pdev->sbdf.dev;
+    uint8_t func = pdev->sbdf.func;
     u16 val;
 
     if ( command_mask )
@@ -289,12 +289,12 @@ static void check_pdev(const struct pci_dev *pdev)
 
 static void apply_quirks(struct pci_dev *pdev)
 {
-    uint16_t vendor = pci_conf_read16(pdev->seg, pdev->bus,
-                                      PCI_SLOT(pdev->devfn),
-                                      PCI_FUNC(pdev->devfn), PCI_VENDOR_ID);
-    uint16_t device = pci_conf_read16(pdev->seg, pdev->bus,
-                                      PCI_SLOT(pdev->devfn),
-                                      PCI_FUNC(pdev->devfn), PCI_DEVICE_ID);
+    uint16_t vendor = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
+                                      pdev->sbdf.dev, pdev->sbdf.func,
+                                      PCI_VENDOR_ID);
+    uint16_t device = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
+                                      pdev->sbdf.dev, pdev->sbdf.func,
+                                      PCI_DEVICE_ID);
     static const struct {
         uint16_t vendor, device;
     } ignore_bars[] = {
@@ -332,16 +332,14 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
     struct pci_dev *pdev;
 
     list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
-        if ( pdev->bus == bus && pdev->devfn == devfn )
+        if ( pdev->sbdf.bus == bus && pdev->sbdf.extfunc == devfn )
             return pdev;
 
     pdev = xzalloc(struct pci_dev);
     if ( !pdev )
         return NULL;
 
-    *(u16*) &pdev->seg = pseg->nr;
-    *((u8*) &pdev->bus) = bus;
-    *((u8*) &pdev->devfn) = devfn;
+    *(uint32_t *) &pdev->sbdf.sbdf = PCI_SBDF3(pseg->nr, bus, devfn);
     pdev->domain = NULL;
     INIT_LIST_HEAD(&pdev->msi_list);
 
@@ -436,20 +434,18 @@ static void free_pdev(struct pci_seg *pseg, struct pci_dev *pdev)
     /* update bus2bridge */
     switch ( pdev->type )
     {
-        u8 dev, func, sec_bus, sub_bus;
+        uint8_t sec_bus, sub_bus;
 
         case DEV_TYPE_PCIe2PCI_BRIDGE:
         case DEV_TYPE_LEGACY_PCI_BRIDGE:
-            dev = PCI_SLOT(pdev->devfn);
-            func = PCI_FUNC(pdev->devfn);
-            sec_bus = pci_conf_read8(pseg->nr, pdev->bus, dev, func,
-                                     PCI_SECONDARY_BUS);
-            sub_bus = pci_conf_read8(pseg->nr, pdev->bus, dev, func,
-                                     PCI_SUBORDINATE_BUS);
+            sec_bus = pci_conf_read8(pseg->nr, pdev->sbdf.bus, pdev->sbdf.dev,
+                                     pdev->sbdf.func, PCI_SECONDARY_BUS);
+            sub_bus = pci_conf_read8(pseg->nr, pdev->sbdf.bus, pdev->sbdf.dev,
+                                     pdev->sbdf.func, PCI_SUBORDINATE_BUS);
 
             spin_lock(&pseg->bus2bridge_lock);
             for ( ; sec_bus <= sub_bus; sec_bus++ )
-                pseg->bus2bridge[sec_bus] = pseg->bus2bridge[pdev->bus];
+                pseg->bus2bridge[sec_bus] = pseg->bus2bridge[pdev->sbdf.bus];
             spin_unlock(&pseg->bus2bridge_lock);
             break;
 
@@ -539,8 +535,8 @@ struct pci_dev *pci_get_pdev(int seg, int bus, int devfn)
 
     do {
         list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
-            if ( (pdev->bus == bus || bus == -1) &&
-                 (pdev->devfn == devfn || devfn == -1) )
+            if ( (pdev->sbdf.bus == bus || bus == -1) &&
+                 (pdev->sbdf.extfunc == devfn || devfn == -1) )
                 return pdev;
     } while ( radix_tree_gang_lookup(&pci_segments, (void **)&pseg,
                                      pseg->nr + 1, 1) );
@@ -588,8 +584,8 @@ struct pci_dev *pci_get_pdev_by_domain(const struct domain *d, int seg,
 
     do {
         list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
-            if ( (pdev->bus == bus || bus == -1) &&
-                 (pdev->devfn == devfn || devfn == -1) &&
+            if ( (pdev->sbdf.bus == bus || bus == -1) &&
+                 (pdev->sbdf.extfunc == devfn || devfn == -1) &&
                  (pdev->domain == d) )
                 return pdev;
     } while ( radix_tree_gang_lookup(&pci_segments, (void **)&pseg,
@@ -605,15 +601,15 @@ struct pci_dev *pci_get_pdev_by_domain(const struct domain *d, int seg,
 static void pci_enable_acs(struct pci_dev *pdev)
 {
     int pos;
-    u16 cap, ctrl, seg = pdev->seg;
-    u8 bus = pdev->bus;
-    u8 dev = PCI_SLOT(pdev->devfn);
-    u8 func = PCI_FUNC(pdev->devfn);
+    uint16_t cap, ctrl, seg = pdev->sbdf.seg;
+    uint8_t bus = pdev->sbdf.bus;
+    uint8_t dev = pdev->sbdf.dev;
+    uint8_t func = pdev->sbdf.func;
 
     if ( !iommu_enabled )
         return;
 
-    pos = pci_find_ext_capability(seg, bus, pdev->devfn, PCI_EXT_CAP_ID_ACS);
+    pos = pci_find_ext_capability(seg, bus, pdev->sbdf.extfunc, PCI_EXT_CAP_ID_ACS);
     if (!pos)
         return;
 
@@ -845,7 +841,7 @@ int pci_remove_device(u16 seg, u8 bus, u8 devfn)
 
     pcidevs_lock();
     list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
-        if ( pdev->bus == bus && pdev->devfn == devfn )
+        if ( pdev->sbdf.bus == bus && pdev->sbdf.extfunc == devfn )
         {
             ret = iommu_remove_device(pdev);
             if ( pdev->domain )
@@ -924,11 +920,11 @@ int pci_release_devices(struct domain *d)
     }
     while ( (pdev = pci_get_pdev_by_domain(d, -1, -1, -1)) )
     {
-        bus = pdev->bus;
-        devfn = pdev->devfn;
-        if ( deassign_device(d, pdev->seg, bus, devfn) )
+        bus = pdev->sbdf.bus;
+        devfn = pdev->sbdf.extfunc;
+        if ( deassign_device(d, pdev->sbdf.seg, bus, devfn) )
             printk("domain %d: deassign device (%04x:%02x:%02x.%u) failed!\n",
-                   d->domain_id, pdev->seg, bus,
+                   d->domain_id, pdev->sbdf.seg, bus,
                    PCI_SLOT(devfn), PCI_FUNC(devfn));
     }
     pcidevs_unlock();
@@ -1047,10 +1043,9 @@ void pci_check_disable_device(u16 seg, u8 bus, u8 devfn)
 
     /* Tell the device to stop DMAing; we can't rely on the guest to
      * control it for us. */
-    devfn = pdev->devfn;
-    cword = pci_conf_read16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+    cword = pci_conf_read16(seg, bus, pdev->sbdf.dev, pdev->sbdf.func,
                             PCI_COMMAND);
-    pci_conf_write16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+    pci_conf_write16(seg, bus, pdev->sbdf.dev, pdev->sbdf.func,
                      PCI_COMMAND, cword & ~PCI_COMMAND_MASTER);
 }
 
@@ -1113,7 +1108,7 @@ struct setup_hwdom {
 static void __hwdom_init setup_one_hwdom_device(const struct setup_hwdom *ctxt,
                                                 struct pci_dev *pdev)
 {
-    u8 devfn = pdev->devfn;
+    uint8_t devfn = pdev->sbdf.extfunc;
     int err;
 
     do {
@@ -1121,14 +1116,14 @@ static void __hwdom_init setup_one_hwdom_device(const struct setup_hwdom *ctxt,
         if ( err )
         {
             printk(XENLOG_ERR "setup %04x:%02x:%02x.%u for d%d failed (%d)\n",
-                   pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                   ctxt->d->domain_id, err);
-            if ( devfn == pdev->devfn )
+                   pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                   pdev->sbdf.func, ctxt->d->domain_id, err);
+            if ( devfn == pdev->sbdf.extfunc )
                 return;
         }
         devfn += pdev->phantom_stride;
-    } while ( devfn != pdev->devfn &&
-              PCI_SLOT(devfn) == PCI_SLOT(pdev->devfn) );
+    } while ( devfn != pdev->sbdf.extfunc &&
+              PCI_SLOT(devfn) == pdev->sbdf.dev );
 
     err = vpci_add_handlers(pdev);
     if ( err )
@@ -1203,24 +1198,22 @@ void __hwdom_init setup_hwdom_pci_devices(
 static int hest_match_pci(const struct acpi_hest_aer_common *p,
                           const struct pci_dev *pdev)
 {
-    return ACPI_HEST_SEGMENT(p->bus) == pdev->seg &&
-           ACPI_HEST_BUS(p->bus)     == pdev->bus &&
-           p->device                 == PCI_SLOT(pdev->devfn) &&
-           p->function               == PCI_FUNC(pdev->devfn);
+    return ACPI_HEST_SEGMENT(p->bus) == pdev->sbdf.seg &&
+           ACPI_HEST_BUS(p->bus)     == pdev->sbdf.bus &&
+           p->device                 == pdev->sbdf.dev &&
+           p->function               == pdev->sbdf.func;
 }
 
 static bool_t hest_match_type(const struct acpi_hest_header *hest_hdr,
                               const struct pci_dev *pdev)
 {
-    unsigned int pos = pci_find_cap_offset(pdev->seg, pdev->bus,
-                                           PCI_SLOT(pdev->devfn),
-                                           PCI_FUNC(pdev->devfn),
+    unsigned int pos = pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus,
+                                           pdev->sbdf.dev, pdev->sbdf.func,
                                            PCI_CAP_ID_EXP);
-    u8 pcie = MASK_EXTR(pci_conf_read16(pdev->seg, pdev->bus,
-                                        PCI_SLOT(pdev->devfn),
-                                        PCI_FUNC(pdev->devfn),
-                                        pos + PCI_EXP_FLAGS),
-                        PCI_EXP_FLAGS_TYPE);
+    uint8_t pcie = MASK_EXTR(pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
+                                             pdev->sbdf.dev, pdev->sbdf.func,
+                                             pos + PCI_EXP_FLAGS),
+                             PCI_EXP_FLAGS_TYPE);
 
     switch ( hest_hdr->type )
     {
@@ -1229,8 +1222,8 @@ static bool_t hest_match_type(const struct acpi_hest_header *hest_hdr,
     case ACPI_HEST_TYPE_AER_ENDPOINT:
         return pcie == PCI_EXP_TYPE_ENDPOINT;
     case ACPI_HEST_TYPE_AER_BRIDGE:
-        return pci_conf_read16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                               PCI_FUNC(pdev->devfn), PCI_CLASS_DEVICE) ==
+        return pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                               pdev->sbdf.func, PCI_CLASS_DEVICE) ==
                PCI_CLASS_BRIDGE_PCI;
     }
 
@@ -1289,8 +1282,8 @@ bool_t pcie_aer_get_firmware_first(const struct pci_dev *pdev)
 {
     struct aer_hest_parse_info info = { .pdev = pdev };
 
-    return pci_find_cap_offset(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                               PCI_FUNC(pdev->devfn), PCI_CAP_ID_EXP) &&
+    return pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                               pdev->sbdf.func, PCI_CAP_ID_EXP) &&
            apei_hest_parse(aer_hest_parse, &info) >= 0 &&
            info.firmware_first;
 }
@@ -1306,8 +1299,7 @@ static int _dump_pci_devices(struct pci_seg *pseg, void *arg)
     list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
     {
         printk("%04x:%02x:%02x.%u - dom %-3d - node %-3d - MSIs < ",
-               pseg->nr, pdev->bus,
-               PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
+               pseg->nr, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func,
                pdev->domain ? pdev->domain->domain_id : -1,
                (pdev->node != NUMA_NO_NODE) ? pdev->node : -1);
         list_for_each_entry ( msi, &pdev->msi_list, list )
@@ -1362,19 +1354,20 @@ static int iommu_add_device(struct pci_dev *pdev)
     if ( !iommu_enabled || !hd->platform_ops )
         return 0;
 
-    rc = hd->platform_ops->add_device(pdev->devfn, pci_to_dev(pdev));
+    rc = hd->platform_ops->add_device(pdev->sbdf.extfunc, pci_to_dev(pdev));
     if ( rc || !pdev->phantom_stride )
         return rc;
 
-    for ( devfn = pdev->devfn ; ; )
+    for ( devfn = pdev->sbdf.extfunc ; ; )
     {
         devfn += pdev->phantom_stride;
-        if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
+        if ( PCI_SLOT(devfn) != pdev->sbdf.dev )
             return 0;
         rc = hd->platform_ops->add_device(devfn, pci_to_dev(pdev));
         if ( rc )
             printk(XENLOG_WARNING "IOMMU: add %04x:%02x:%02x.%u failed (%d)\n",
-                   pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn), rc);
+                   pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn),
+                   PCI_FUNC(devfn), rc);
     }
 }
 
@@ -1398,7 +1391,7 @@ static int iommu_enable_device(struct pci_dev *pdev)
 static int iommu_remove_device(struct pci_dev *pdev)
 {
     const struct domain_iommu *hd;
-    u8 devfn;
+    uint8_t devfn;
 
     if ( !pdev->domain )
         return -EINVAL;
@@ -1407,23 +1400,24 @@ static int iommu_remove_device(struct pci_dev *pdev)
     if ( !iommu_enabled || !hd->platform_ops )
         return 0;
 
-    for ( devfn = pdev->devfn ; pdev->phantom_stride; )
+    for ( devfn = pdev->sbdf.extfunc ; pdev->phantom_stride; )
     {
         int rc;
 
         devfn += pdev->phantom_stride;
-        if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
+        if ( PCI_SLOT(devfn) != pdev->sbdf.dev )
             break;
         rc = hd->platform_ops->remove_device(devfn, pci_to_dev(pdev));
         if ( !rc )
             continue;
 
         printk(XENLOG_ERR "IOMMU: remove %04x:%02x:%02x.%u failed (%d)\n",
-               pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn), rc);
+               pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+               rc);
         return rc;
     }
 
-    return hd->platform_ops->remove_device(pdev->devfn, pci_to_dev(pdev));
+    return hd->platform_ops->remove_device(pdev->sbdf.extfunc, pci_to_dev(pdev));
 }
 
 /*
@@ -1485,7 +1479,7 @@ static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn, u32 flag)
     for ( ; pdev->phantom_stride; rc = 0 )
     {
         devfn += pdev->phantom_stride;
-        if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
+        if ( PCI_SLOT(devfn) != pdev->sbdf.dev )
             break;
         rc = hd->platform_ops->assign_device(d, devfn, pci_to_dev(pdev), flag);
         if ( rc )
@@ -1520,7 +1514,7 @@ int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
     while ( pdev->phantom_stride )
     {
         devfn += pdev->phantom_stride;
-        if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
+        if ( PCI_SLOT(devfn) != pdev->sbdf.dev )
             break;
         ret = hd->platform_ops->reassign_device(d, hardware_domain, devfn,
                                                 pci_to_dev(pdev));
@@ -1532,7 +1526,7 @@ int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
         return ret;
     }
 
-    devfn = pdev->devfn;
+    devfn = pdev->sbdf.extfunc;
     ret = hd->platform_ops->reassign_device(d, hardware_domain, devfn,
                                             pci_to_dev(pdev));
     if ( ret )
@@ -1558,7 +1552,6 @@ static int iommu_get_device_group(
     const struct domain_iommu *hd = dom_iommu(d);
     struct pci_dev *pdev;
     int group_id, sdev_id;
-    u32 bdf;
     int i = 0;
     const struct iommu_ops *ops = hd->platform_ops;
 
@@ -1570,19 +1563,18 @@ static int iommu_get_device_group(
     pcidevs_lock();
     for_each_pdev( d, pdev )
     {
-        if ( (pdev->seg != seg) ||
-             ((pdev->bus == bus) && (pdev->devfn == devfn)) )
+        if ( (pdev->sbdf.seg != seg) ||
+             ((pdev->sbdf.bus == bus) && (pdev->sbdf.extfunc == devfn)) )
             continue;
 
-        if ( xsm_get_device_group(XSM_HOOK, (seg << 16) | (pdev->bus << 8) | pdev->devfn) )
+        if ( xsm_get_device_group(XSM_HOOK, (seg << 16) | pdev->sbdf.bdf) )
             continue;
 
-        sdev_id = ops->get_device_group_id(seg, pdev->bus, pdev->devfn);
+        sdev_id = ops->get_device_group_id(seg, pdev->sbdf.bus,
+                                           pdev->sbdf.extfunc);
         if ( (sdev_id == group_id) && (i < max_sdevs) )
         {
-            bdf = 0;
-            bdf |= (pdev->bus & 0xff) << 16;
-            bdf |= (pdev->devfn & 0xff) << 8;
+            uint32_t bdf = pdev->sbdf.bdf;
 
             if ( unlikely(copy_to_guest_offset(buf, i, &bdf, 1)) )
             {
@@ -1618,8 +1610,8 @@ void iommu_dev_iotlb_flush_timeout(struct domain *d, struct pci_dev *pdev)
     if ( !d->is_shutting_down && printk_ratelimit() )
         printk(XENLOG_ERR
                "dom%d: ATS device %04x:%02x:%02x.%u flush failed\n",
-               d->domain_id, pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-               PCI_FUNC(pdev->devfn));
+               d->domain_id, pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+               pdev->sbdf.func);
     if ( !is_hardware_domain(d) )
         domain_crash(d);
 
diff --git a/xen/drivers/passthrough/vtd/dmar.c b/xen/drivers/passthrough/vtd/dmar.c
index 9cc8623e53..effaf93222 100644
--- a/xen/drivers/passthrough/vtd/dmar.c
+++ b/xen/drivers/passthrough/vtd/dmar.c
@@ -219,18 +219,18 @@ struct acpi_drhd_unit *acpi_find_matched_drhd_unit(const struct pci_dev *pdev)
     }
     else if ( pdev->info.is_extfn )
     {
-        bus = pdev->bus;
+        bus = pdev->sbdf.bus;
         devfn = 0;
     }
     else
     {
-        bus = pdev->bus;
-        devfn = pdev->devfn;
+        bus = pdev->sbdf.bus;
+        devfn = pdev->sbdf.extfunc;
     }
 
     list_for_each_entry ( drhd, &acpi_drhd_units, list )
     {
-        if ( drhd->segment != pdev->seg )
+        if ( drhd->segment != pdev->sbdf.seg )
             continue;
 
         for (i = 0; i < drhd->scope.devices_cnt; i++)
@@ -253,10 +253,10 @@ struct acpi_atsr_unit *acpi_find_matched_atsr_unit(const struct pci_dev *pdev)
 
     list_for_each_entry ( atsr, &acpi_atsr_units, list )
     {
-        if ( atsr->segment != pdev->seg )
+        if ( atsr->segment != pdev->sbdf.seg )
             continue;
 
-        if ( test_bit(pdev->bus, atsr->scope.buses) )
+        if ( test_bit(pdev->sbdf.bus, atsr->scope.buses) )
             return atsr;
 
         if ( atsr->all_ports )
diff --git a/xen/drivers/passthrough/vtd/intremap.c b/xen/drivers/passthrough/vtd/intremap.c
index df0e8ac5cb..0dbf99551e 100644
--- a/xen/drivers/passthrough/vtd/intremap.c
+++ b/xen/drivers/passthrough/vtd/intremap.c
@@ -483,9 +483,9 @@ static void set_msi_source_id(struct pci_dev *pdev, struct iremap_entry *ire)
     if ( !pdev || !ire )
         return;
 
-    seg = pdev->seg;
-    bus = pdev->bus;
-    devfn = pdev->devfn;
+    seg = pdev->sbdf.seg;
+    bus = pdev->sbdf.bus;
+    devfn = pdev->sbdf.extfunc;
     switch ( pdev->type )
     {
         unsigned int sq;
@@ -517,7 +517,7 @@ static void set_msi_source_id(struct pci_dev *pdev, struct iremap_entry *ire)
         {
             if ( pdev_type(seg, bus, devfn) == DEV_TYPE_PCIe2PCI_BRIDGE )
                 set_ire_sid(ire, SVT_VERIFY_BUS, SQ_ALL_16,
-                            (bus << 8) | pdev->bus);
+                            (bus << 8) | pdev->sbdf.bus);
             else
                 set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_ALL_16,
                             PCI_BDF2(bus, devfn));
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index 7b9e09a084..7b70732863 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -1484,7 +1484,7 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
 {
     struct acpi_drhd_unit *drhd;
     int ret = 0;
-    u8 seg = pdev->seg, bus = pdev->bus, secbus;
+    uint8_t seg = pdev->sbdf.seg, bus = pdev->sbdf.bus, secbus;
 
     drhd = acpi_find_matched_drhd_unit(pdev);
     if ( !drhd )
@@ -1515,7 +1515,7 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
                    PCI_SLOT(devfn), PCI_FUNC(devfn));
         ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn,
                                          pdev);
-        if ( !ret && devfn == pdev->devfn && ats_device(pdev, drhd) > 0 )
+        if ( !ret && devfn == pdev->sbdf.extfunc && ats_device(pdev, drhd) > 0 )
             enable_ats_device(pdev, &drhd->iommu->ats_devices);
 
         break;
@@ -1543,7 +1543,7 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
          * behind the bridge. Map that id as well if we didn't already.
          */
         if ( !ret && pdev_type(seg, bus, devfn) == DEV_TYPE_PCIe2PCI_BRIDGE &&
-             (secbus != pdev->bus || pdev->devfn != 0) )
+             (secbus != pdev->sbdf.bus || pdev->sbdf.extfunc != 0) )
             ret = domain_context_mapping_one(domain, drhd->iommu, secbus, 0,
                                              pci_get_pdev(seg, secbus, 0));
 
@@ -1557,7 +1557,7 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
         break;
     }
 
-    if ( !ret && devfn == pdev->devfn )
+    if ( !ret && devfn == pdev->sbdf.extfunc )
         pci_vtd_quirk(pdev);
 
     return ret;
@@ -1635,7 +1635,8 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
     struct acpi_drhd_unit *drhd;
     struct iommu *iommu;
     int ret = 0;
-    u8 seg = pdev->seg, bus = pdev->bus, tmp_bus, tmp_devfn, secbus;
+    uint8_t seg = pdev->sbdf.seg, bus = pdev->sbdf.bus, tmp_bus, tmp_devfn,
+            secbus;
     int found = 0;
 
     drhd = acpi_find_matched_drhd_unit(pdev);
@@ -1665,7 +1666,7 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
                    domain->domain_id, seg, bus,
                    PCI_SLOT(devfn), PCI_FUNC(devfn));
         ret = domain_context_unmap_one(domain, iommu, bus, devfn);
-        if ( !ret && devfn == pdev->devfn && ats_device(pdev, drhd) > 0 )
+        if ( !ret && devfn == pdev->sbdf.extfunc && ats_device(pdev, drhd) > 0 )
             disable_ats_device(pdev);
 
         break;
@@ -1711,7 +1712,8 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
      */
     for_each_pdev ( domain, pdev )
     {
-        if ( pdev->seg == seg && pdev->bus == bus && pdev->devfn == devfn )
+        if ( pdev->sbdf.seg == seg && pdev->sbdf.bus == bus &&
+             pdev->sbdf.extfunc == devfn )
             continue;
 
         drhd = acpi_find_matched_drhd_unit(pdev);
@@ -2050,8 +2052,8 @@ static int intel_iommu_add_device(u8 devfn, struct pci_dev *pdev)
 
     for_each_rmrr_device ( rmrr, bdf, i )
     {
-        if ( rmrr->segment == pdev->seg &&
-             PCI_BUS(bdf) == pdev->bus &&
+        if ( rmrr->segment == pdev->sbdf.seg &&
+             PCI_BUS(bdf) == pdev->sbdf.bus &&
              PCI_DEVFN2(bdf) == devfn )
         {
             /*
@@ -2096,8 +2098,8 @@ static int intel_iommu_remove_device(u8 devfn, struct pci_dev *pdev)
 
     for_each_rmrr_device ( rmrr, bdf, i )
     {
-        if ( rmrr->segment != pdev->seg ||
-             PCI_BUS(bdf) != pdev->bus ||
+        if ( rmrr->segment != pdev->sbdf.seg ||
+             PCI_BUS(bdf) != pdev->sbdf.bus ||
              PCI_DEVFN2(bdf) != devfn )
             continue;
 
@@ -2421,8 +2423,8 @@ static int reassign_device_ownership(
         unsigned int i;
 
         for_each_rmrr_device( rmrr, bdf, i )
-            if ( rmrr->segment == pdev->seg &&
-                 PCI_BUS(bdf) == pdev->bus &&
+            if ( rmrr->segment == pdev->sbdf.seg &&
+                 PCI_BUS(bdf) == pdev->sbdf.bus &&
                  PCI_DEVFN2(bdf) == devfn )
             {
                 /*
@@ -2451,7 +2453,7 @@ static int reassign_device_ownership(
         return ret;
     }
 
-    if ( devfn == pdev->devfn )
+    if ( devfn == pdev->sbdf.extfunc )
     {
         list_move(&pdev->domain_list, &target->arch.pdev_list);
         pdev->domain = target;
@@ -2474,8 +2476,8 @@ static int intel_iommu_assign_device(
     if ( list_empty(&acpi_drhd_units) )
         return -ENODEV;
 
-    seg = pdev->seg;
-    bus = pdev->bus;
+    seg = pdev->sbdf.seg;
+    bus = pdev->sbdf.bus;
     /*
      * In rare cases one given rmrr is shared by multiple devices but
      * obviously this would put the security of a system at risk. So
diff --git a/xen/drivers/passthrough/vtd/qinval.c b/xen/drivers/passthrough/vtd/qinval.c
index 01447cf9a8..8015d16531 100644
--- a/xen/drivers/passthrough/vtd/qinval.c
+++ b/xen/drivers/passthrough/vtd/qinval.c
@@ -257,7 +257,7 @@ int qinval_device_iotlb_sync(struct iommu *iommu, struct pci_dev *pdev,
     qinval_entry->q.dev_iotlb_inv_dsc.lo.res_1 = 0;
     qinval_entry->q.dev_iotlb_inv_dsc.lo.max_invs_pend = pdev->ats.queue_depth;
     qinval_entry->q.dev_iotlb_inv_dsc.lo.res_2 = 0;
-    qinval_entry->q.dev_iotlb_inv_dsc.lo.sid = PCI_BDF2(pdev->bus, pdev->devfn);
+    qinval_entry->q.dev_iotlb_inv_dsc.lo.sid = pdev->sbdf.bdf;
     qinval_entry->q.dev_iotlb_inv_dsc.lo.res_3 = 0;
 
     qinval_entry->q.dev_iotlb_inv_dsc.hi.size = size;
diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c
index d6db862678..fa811605ee 100644
--- a/xen/drivers/passthrough/vtd/quirks.c
+++ b/xen/drivers/passthrough/vtd/quirks.c
@@ -413,10 +413,10 @@ int me_wifi_quirk(struct domain *domain, u8 bus, u8 devfn, int map)
 
 void pci_vtd_quirk(const struct pci_dev *pdev)
 {
-    int seg = pdev->seg;
-    int bus = pdev->bus;
-    int dev = PCI_SLOT(pdev->devfn);
-    int func = PCI_FUNC(pdev->devfn);
+    int seg = pdev->sbdf.seg;
+    int bus = pdev->sbdf.bus;
+    int dev = pdev->sbdf.dev;
+    int func = pdev->sbdf.func;
     int pos;
     bool_t ff;
     u32 val, val2;
@@ -454,11 +454,11 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
     /* Sandybridge-EP (Romley) */
     case 0x3c00: /* host bridge */
     case 0x3c01 ... 0x3c0b: /* root ports */
-        pos = pci_find_ext_capability(seg, bus, pdev->devfn,
+        pos = pci_find_ext_capability(seg, bus, pdev->sbdf.extfunc,
                                       PCI_EXT_CAP_ID_ERR);
         if ( !pos )
         {
-            pos = pci_find_ext_capability(seg, bus, pdev->devfn,
+            pos = pci_find_ext_capability(seg, bus, pdev->sbdf.extfunc,
                                           PCI_EXT_CAP_ID_VNDR);
             while ( pos )
             {
@@ -468,8 +468,8 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
                     pos += PCI_VNDR_HEADER;
                     break;
                 }
-                pos = pci_find_next_ext_capability(seg, bus, pdev->devfn, pos,
-                                                   PCI_EXT_CAP_ID_VNDR);
+                pos = pci_find_next_ext_capability(seg, bus, pdev->sbdf.extfunc,
+                                                   pos, PCI_EXT_CAP_ID_VNDR);
             }
             ff = 0;
         }
diff --git a/xen/drivers/passthrough/vtd/x86/ats.c b/xen/drivers/passthrough/vtd/x86/ats.c
index 1a3adb4acb..e0904df5b6 100644
--- a/xen/drivers/passthrough/vtd/x86/ats.c
+++ b/xen/drivers/passthrough/vtd/x86/ats.c
@@ -57,8 +57,8 @@ int ats_device(const struct pci_dev *pdev, const struct acpi_drhd_unit *drhd)
         return 0;
 
     ats_drhd = find_ats_dev_drhd(drhd->iommu);
-    pos = pci_find_ext_capability(pdev->seg, pdev->bus, pdev->devfn,
-                                  PCI_EXT_CAP_ID_ATS);
+    pos = pci_find_ext_capability(pdev->sbdf.seg, pdev->sbdf.bus,
+                                  pdev->sbdf.extfunc, PCI_EXT_CAP_ID_ATS);
 
     if ( pos && (ats_drhd == NULL) )
     {
@@ -79,19 +79,19 @@ static int device_in_domain(const struct iommu *iommu,
     int tt, found = 0;
 
     root_entry = (struct root_entry *) map_vtd_domain_page(iommu->root_maddr);
-    if ( !root_entry || !root_present(root_entry[pdev->bus]) )
+    if ( !root_entry || !root_present(root_entry[pdev->sbdf.bus]) )
         goto out;
 
     ctxt_entry = (struct context_entry *)
-                 map_vtd_domain_page(root_entry[pdev->bus].val);
+                 map_vtd_domain_page(root_entry[pdev->sbdf.bus].val);
 
     if ( ctxt_entry == NULL )
         goto out;
 
-    if ( context_domain_id(ctxt_entry[pdev->devfn]) != did )
+    if ( context_domain_id(ctxt_entry[pdev->sbdf.extfunc]) != did )
         goto out;
 
-    tt = context_translation_type(ctxt_entry[pdev->devfn]);
+    tt = context_translation_type(ctxt_entry[pdev->sbdf.extfunc]);
     if ( tt != CONTEXT_TT_DEV_IOTLB )
         goto out;
 
diff --git a/xen/drivers/passthrough/x86/ats.c b/xen/drivers/passthrough/x86/ats.c
index 59c163459a..ddaec72d19 100644
--- a/xen/drivers/passthrough/x86/ats.c
+++ b/xen/drivers/passthrough/x86/ats.c
@@ -23,8 +23,8 @@ boolean_param("ats", ats_enabled);
 int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
 {
     u32 value;
-    u16 seg = pdev->seg;
-    u8 bus = pdev->bus, devfn = pdev->devfn;
+    uint16_t seg = pdev->sbdf.seg;
+    uint16_t bus = pdev->sbdf.bus, devfn = pdev->sbdf.extfunc;
     int pos;
 
     pos = pci_find_ext_capability(seg, bus, devfn, PCI_EXT_CAP_ID_ATS);
@@ -76,8 +76,8 @@ int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
 void disable_ats_device(struct pci_dev *pdev)
 {
     u32 value;
-    u16 seg = pdev->seg;
-    u8 bus = pdev->bus, devfn = pdev->devfn;
+    uint16_t seg = pdev->sbdf.seg;
+    uint8_t bus = pdev->sbdf.bus, devfn = pdev->sbdf.extfunc;
 
     BUG_ON(!pdev->ats.cap_pos);
 
diff --git a/xen/drivers/pci/pci.c b/xen/drivers/pci/pci.c
index 1c808d6632..a3223a2b29 100644
--- a/xen/drivers/pci/pci.c
+++ b/xen/drivers/pci/pci.c
@@ -117,10 +117,10 @@ int pci_find_next_ext_capability(int seg, int bus, int devfn, int start, int cap
 
 void pci_intx(const struct pci_dev *pdev, bool enable)
 {
-    uint16_t seg = pdev->seg;
-    uint8_t bus = pdev->bus;
-    uint8_t slot = PCI_SLOT(pdev->devfn);
-    uint8_t func = PCI_FUNC(pdev->devfn);
+    uint16_t seg = pdev->sbdf.seg;
+    uint8_t bus = pdev->sbdf.bus;
+    uint8_t slot = pdev->sbdf.dev;
+    uint8_t func = pdev->sbdf.func;
     uint16_t cmd = pci_conf_read16(seg, bus, slot, func, PCI_COMMAND);
 
     if ( enable )
diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
index efb6ca90e3..74d70a4278 100644
--- a/xen/drivers/vpci/header.c
+++ b/xen/drivers/vpci/header.c
@@ -85,7 +85,6 @@ static void modify_decoding(const struct pci_dev *pdev, uint16_t cmd,
                             bool rom_only)
 {
     struct vpci_header *header = &pdev->vpci->header;
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
     bool map = cmd & PCI_COMMAND_MEMORY;
     unsigned int i;
 
@@ -113,7 +112,8 @@ static void modify_decoding(const struct pci_dev *pdev, uint16_t cmd,
                            (map ? PCI_ROM_ADDRESS_ENABLE : 0);
 
             header->bars[i].enabled = header->rom_enabled = map;
-            pci_conf_write32(pdev->seg, pdev->bus, slot, func, rom_pos, val);
+            pci_conf_write32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                             pdev->sbdf.func, rom_pos, val);
             return;
         }
 
@@ -123,8 +123,8 @@ static void modify_decoding(const struct pci_dev *pdev, uint16_t cmd,
     }
 
     if ( !rom_only )
-        pci_conf_write16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND,
-                         cmd);
+        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                         pdev->sbdf.func, PCI_COMMAND, cmd);
     else
         ASSERT_UNREACHABLE();
 }
@@ -335,8 +335,8 @@ static int modify_bars(const struct pci_dev *pdev, uint16_t cmd, bool rom_only)
 static void cmd_write(const struct pci_dev *pdev, unsigned int reg,
                       uint32_t cmd, void *data)
 {
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
-    uint16_t current_cmd = pci_conf_read16(pdev->seg, pdev->bus, slot, func,
+    uint16_t current_cmd = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
+                                           pdev->sbdf.dev, pdev->sbdf.func,
                                            reg);
 
     /*
@@ -352,14 +352,14 @@ static void cmd_write(const struct pci_dev *pdev, unsigned int reg,
          */
         modify_bars(pdev, cmd, false);
     else
-        pci_conf_write16(pdev->seg, pdev->bus, slot, func, reg, cmd);
+        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                         pdev->sbdf.func, reg, cmd);
 }
 
 static void bar_write(const struct pci_dev *pdev, unsigned int reg,
                       uint32_t val, void *data)
 {
     struct vpci_bar *bar = data;
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
     bool hi = false;
 
     if ( bar->type == VPCI_BAR_MEM64_HI )
@@ -371,15 +371,15 @@ static void bar_write(const struct pci_dev *pdev, unsigned int reg,
     else
         val &= PCI_BASE_ADDRESS_MEM_MASK;
 
-    if ( pci_conf_read16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND) &
-         PCI_COMMAND_MEMORY )
+    if ( pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                         pdev->sbdf.func, PCI_COMMAND) & PCI_COMMAND_MEMORY )
     {
         /* If the value written is the current one avoid printing a warning. */
         if ( val != (uint32_t)(bar->addr >> (hi ? 32 : 0)) )
             gprintk(XENLOG_WARNING,
                     "%04x:%02x:%02x.%u: ignored BAR %lu write with memory decoding enabled\n",
-                    pdev->seg, pdev->bus, slot, func,
-                    bar - pdev->vpci->header.bars + hi);
+                    pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                    pdev->sbdf.func, bar - pdev->vpci->header.bars + hi);
         return;
     }
 
@@ -399,8 +399,8 @@ static void bar_write(const struct pci_dev *pdev, unsigned int reg,
         val |= bar->prefetchable ? PCI_BASE_ADDRESS_MEM_PREFETCH : 0;
     }
 
-    pci_conf_write32(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                     PCI_FUNC(pdev->devfn), reg, val);
+    pci_conf_write32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                     pdev->sbdf.func, reg, val);
 }
 
 static void rom_write(const struct pci_dev *pdev, unsigned int reg,
@@ -408,8 +408,8 @@ static void rom_write(const struct pci_dev *pdev, unsigned int reg,
 {
     struct vpci_header *header = &pdev->vpci->header;
     struct vpci_bar *rom = data;
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
-    uint16_t cmd = pci_conf_read16(pdev->seg, pdev->bus, slot, func,
+    uint16_t cmd = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
+                                   pdev->sbdf.dev, pdev->sbdf.func,
                                    PCI_COMMAND);
     bool new_enabled = val & PCI_ROM_ADDRESS_ENABLE;
 
@@ -417,7 +417,8 @@ static void rom_write(const struct pci_dev *pdev, unsigned int reg,
     {
         gprintk(XENLOG_WARNING,
                 "%04x:%02x:%02x.%u: ignored ROM BAR write with memory decoding enabled\n",
-                pdev->seg, pdev->bus, slot, func);
+                pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                pdev->sbdf.func);
         return;
     }
 
@@ -432,7 +433,8 @@ static void rom_write(const struct pci_dev *pdev, unsigned int reg,
     {
         /* Just update the ROM BAR field. */
         header->rom_enabled = new_enabled;
-        pci_conf_write32(pdev->seg, pdev->bus, slot, func, reg, val);
+        pci_conf_write32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                         pdev->sbdf.func, reg, val);
     }
     /*
      * Pass PCI_COMMAND_MEMORY or 0 to signal a map/unmap request, note that
@@ -455,19 +457,15 @@ static void rom_write(const struct pci_dev *pdev, unsigned int reg,
 
 static int init_bars(struct pci_dev *pdev)
 {
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
     uint16_t cmd;
     uint64_t addr, size;
     unsigned int i, num_bars, rom_reg;
     struct vpci_header *header = &pdev->vpci->header;
     struct vpci_bar *bars = header->bars;
-    pci_sbdf_t sbdf = {
-        .sbdf = PCI_SBDF3(pdev->seg, pdev->bus, pdev->devfn),
-    };
     int rc;
 
-    switch ( pci_conf_read8(pdev->seg, pdev->bus, slot, func, PCI_HEADER_TYPE)
-             & 0x7f )
+    switch ( pci_conf_read8(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                            pdev->sbdf.func, PCI_HEADER_TYPE) & 0x7f )
     {
     case PCI_HEADER_TYPE_NORMAL:
         num_bars = PCI_HEADER_NORMAL_NR_BARS;
@@ -493,9 +491,11 @@ static int init_bars(struct pci_dev *pdev)
         return 0;
 
     /* Disable memory decoding before sizing. */
-    cmd = pci_conf_read16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND);
+    cmd = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                          pdev->sbdf.func, PCI_COMMAND);
     if ( cmd & PCI_COMMAND_MEMORY )
-        pci_conf_write16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND,
+        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                         pdev->sbdf.func, PCI_COMMAND,
                          cmd & ~PCI_COMMAND_MEMORY);
 
     for ( i = 0; i < num_bars; i++ )
@@ -510,15 +510,16 @@ static int init_bars(struct pci_dev *pdev)
                                    4, &bars[i]);
             if ( rc )
             {
-                pci_conf_write16(pdev->seg, pdev->bus, slot, func,
-                                 PCI_COMMAND, cmd);
+                pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                                 pdev->sbdf.func, PCI_COMMAND, cmd);
                 return rc;
             }
 
             continue;
         }
 
-        val = pci_conf_read32(pdev->seg, pdev->bus, slot, func, reg);
+        val = pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                              pdev->sbdf.func, reg);
         if ( (val & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO )
         {
             bars[i].type = VPCI_BAR_IO;
@@ -530,12 +531,12 @@ static int init_bars(struct pci_dev *pdev)
         else
             bars[i].type = VPCI_BAR_MEM32;
 
-        rc = pci_size_mem_bar(sbdf, reg, &addr, &size,
+        rc = pci_size_mem_bar(pdev->sbdf, reg, &addr, &size,
                               (i == num_bars - 1) ? PCI_BAR_LAST : 0);
         if ( rc < 0 )
         {
-            pci_conf_write16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND,
-                             cmd);
+            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                             pdev->sbdf.func, PCI_COMMAND, cmd);
             return rc;
         }
 
@@ -553,14 +554,14 @@ static int init_bars(struct pci_dev *pdev)
                                &bars[i]);
         if ( rc )
         {
-            pci_conf_write16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND,
-                             cmd);
+            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                             pdev->sbdf.func, PCI_COMMAND, cmd);
             return rc;
         }
     }
 
     /* Check expansion ROM. */
-    rc = pci_size_mem_bar(sbdf, rom_reg, &addr, &size, PCI_BAR_ROM);
+    rc = pci_size_mem_bar(pdev->sbdf, rom_reg, &addr, &size, PCI_BAR_ROM);
     if ( rc > 0 && size )
     {
         struct vpci_bar *rom = &header->bars[num_bars];
@@ -568,7 +569,8 @@ static int init_bars(struct pci_dev *pdev)
         rom->type = VPCI_BAR_ROM;
         rom->size = size;
         rom->addr = addr;
-        header->rom_enabled = pci_conf_read32(pdev->seg, pdev->bus, slot, func,
+        header->rom_enabled = pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus,
+                                              pdev->sbdf.dev, pdev->sbdf.func,
                                               rom_reg) & PCI_ROM_ADDRESS_ENABLE;
 
         rc = vpci_add_register(pdev->vpci, vpci_hw_read32, rom_write, rom_reg,
diff --git a/xen/drivers/vpci/msi.c b/xen/drivers/vpci/msi.c
index 8f15ad7bf2..dfc894dcc6 100644
--- a/xen/drivers/vpci/msi.c
+++ b/xen/drivers/vpci/msi.c
@@ -77,9 +77,8 @@ static void control_write(const struct pci_dev *pdev, unsigned int reg,
     msi->vectors = vectors;
     msi->enabled = new_enabled;
 
-    pci_conf_write16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                     PCI_FUNC(pdev->devfn), reg,
-                     control_read(pdev, reg, data));
+    pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                     pdev->sbdf.func, reg, control_read(pdev, reg, data));
 }
 
 static void update_msi(const struct pci_dev *pdev, struct vpci_msi *msi)
@@ -187,8 +186,8 @@ static void mask_write(const struct pci_dev *pdev, unsigned int reg,
 
 static int init_msi(struct pci_dev *pdev)
 {
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
-    unsigned int pos = pci_find_cap_offset(pdev->seg, pdev->bus, slot, func,
+    unsigned int pos = pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus,
+                                           pdev->sbdf.dev, pdev->sbdf.func,
                                            PCI_CAP_ID_MSI);
     uint16_t control;
     int ret;
@@ -211,8 +210,8 @@ static int init_msi(struct pci_dev *pdev)
         return ret;
 
     /* Get the maximum number of vectors the device supports. */
-    control = pci_conf_read16(pdev->seg, pdev->bus, slot, func,
-                              msi_control_reg(pos));
+    control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                              pdev->sbdf.func, msi_control_reg(pos));
 
     /*
      * FIXME: I've only been able to test this code with devices using a single
@@ -293,8 +292,8 @@ void vpci_dump_msi(void)
             msi = pdev->vpci->msi;
             if ( msi && msi->enabled )
             {
-                printk("%04x:%02x:%02x.%u MSI\n", pdev->seg, pdev->bus,
-                       PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+                printk("%04x:%02x:%02x.%u MSI\n", pdev->sbdf.seg,
+                       pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func);
 
                 printk("  enabled: %d 64-bit: %d",
                        msi->enabled, msi->address64);
@@ -311,8 +310,8 @@ void vpci_dump_msi(void)
             {
                 int rc;
 
-                printk("%04x:%02x:%02x.%u MSI-X\n", pdev->seg, pdev->bus,
-                       PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+                printk("%04x:%02x:%02x.%u MSI-X\n", pdev->sbdf.seg,
+                       pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func);
 
                 printk("  entries: %u maskall: %d enabled: %d\n",
                        msix->max_entries, msix->masked, msix->enabled);
diff --git a/xen/drivers/vpci/msix.c b/xen/drivers/vpci/msix.c
index af3ffa087d..04431715f5 100644
--- a/xen/drivers/vpci/msix.c
+++ b/xen/drivers/vpci/msix.c
@@ -42,7 +42,6 @@ static uint32_t control_read(const struct pci_dev *pdev, unsigned int reg,
 static int update_entry(struct vpci_msix_entry *entry,
                         const struct pci_dev *pdev, unsigned int nr)
 {
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
     int rc = vpci_msix_arch_disable_entry(entry, pdev);
 
     /* Ignore ENOENT, it means the entry wasn't setup. */
@@ -50,7 +49,8 @@ static int update_entry(struct vpci_msix_entry *entry,
     {
         gprintk(XENLOG_WARNING,
                 "%04x:%02x:%02x.%u: unable to disable entry %u for update: %d\n",
-                pdev->seg, pdev->bus, slot, func, nr, rc);
+                pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func,
+                nr, rc);
         return rc;
     }
 
@@ -61,7 +61,8 @@ static int update_entry(struct vpci_msix_entry *entry,
     {
         gprintk(XENLOG_WARNING,
                 "%04x:%02x:%02x.%u: unable to enable entry %u: %d\n",
-                pdev->seg, pdev->bus, slot, func, nr, rc);
+                pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func,
+                nr, rc);
         /* Entry is likely not properly configured. */
         return rc;
     }
@@ -72,7 +73,6 @@ static int update_entry(struct vpci_msix_entry *entry,
 static void control_write(const struct pci_dev *pdev, unsigned int reg,
                           uint32_t val, void *data)
 {
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
     struct vpci_msix *msix = data;
     bool new_masked = val & PCI_MSIX_FLAGS_MASKALL;
     bool new_enabled = val & PCI_MSIX_FLAGS_ENABLE;
@@ -135,7 +135,8 @@ static void control_write(const struct pci_dev *pdev, unsigned int reg,
             default:
                 gprintk(XENLOG_WARNING,
                         "%04x:%02x:%02x.%u: unable to disable entry %u: %d\n",
-                        pdev->seg, pdev->bus, slot, func, i, rc);
+                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                        pdev->sbdf.func, i, rc);
                 return;
             }
         }
@@ -146,7 +147,8 @@ static void control_write(const struct pci_dev *pdev, unsigned int reg,
 
     val = control_read(pdev, reg, data);
     if ( pci_msi_conf_write_intercept(msix->pdev, reg, 2, &val) >= 0 )
-        pci_conf_write16(pdev->seg, pdev->bus, slot, func, reg, val);
+        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                         pdev->sbdf.func, reg, val);
 }
 
 static struct vpci_msix *msix_find(const struct domain *d, unsigned long addr)
@@ -181,7 +183,7 @@ static bool access_allowed(const struct pci_dev *pdev, unsigned long addr,
 
     gprintk(XENLOG_WARNING,
             "%04x:%02x:%02x.%u: unaligned or invalid size MSI-X table access\n",
-            pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+            pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func);
 
     return false;
 }
@@ -433,8 +435,8 @@ int vpci_make_msix_hole(const struct pci_dev *pdev)
                 gprintk(XENLOG_WARNING,
                         "%04x:%02x:%02x.%u: existing mapping (mfn: %" PRI_mfn
                         "type: %d) at %#lx clobbers MSIX MMIO area\n",
-                        pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                        PCI_FUNC(pdev->devfn), mfn_x(mfn), t, start);
+                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                        pdev->sbdf.func, mfn_x(mfn), t, start);
                 return -EEXIST;
             }
             put_gfn(d, start);
@@ -447,18 +449,18 @@ int vpci_make_msix_hole(const struct pci_dev *pdev)
 static int init_msix(struct pci_dev *pdev)
 {
     struct domain *d = pdev->domain;
-    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
     unsigned int msix_offset, i, max_entries;
     uint16_t control;
     int rc;
 
-    msix_offset = pci_find_cap_offset(pdev->seg, pdev->bus, slot, func,
+    msix_offset = pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus,
+                                      pdev->sbdf.dev, pdev->sbdf.func,
                                       PCI_CAP_ID_MSIX);
     if ( !msix_offset )
         return 0;
 
-    control = pci_conf_read16(pdev->seg, pdev->bus, slot, func,
-                              msix_control_reg(msix_offset));
+    control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                              pdev->sbdf.func, msix_control_reg(msix_offset));
 
     max_entries = msix_table_size(control);
 
@@ -470,11 +472,11 @@ static int init_msix(struct pci_dev *pdev)
     pdev->vpci->msix->pdev = pdev;
 
     pdev->vpci->msix->tables[VPCI_MSIX_TABLE] =
-        pci_conf_read32(pdev->seg, pdev->bus, slot, func,
-                        msix_table_offset_reg(msix_offset));
+        pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                        pdev->sbdf.func, msix_table_offset_reg(msix_offset));
     pdev->vpci->msix->tables[VPCI_MSIX_PBA] =
-        pci_conf_read32(pdev->seg, pdev->bus, slot, func,
-                        msix_pba_offset_reg(msix_offset));
+        pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                        pdev->sbdf.func, msix_pba_offset_reg(msix_offset));
 
     for ( i = 0; i < pdev->vpci->msix->max_entries; i++)
     {
diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c
index 82607bdb9a..9a060c108e 100644
--- a/xen/drivers/vpci/vpci.c
+++ b/xen/drivers/vpci/vpci.c
@@ -114,15 +114,15 @@ static void vpci_ignored_write(const struct pci_dev *pdev, unsigned int reg,
 uint32_t vpci_hw_read16(const struct pci_dev *pdev, unsigned int reg,
                         void *data)
 {
-    return pci_conf_read16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                           PCI_FUNC(pdev->devfn), reg);
+    return pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                           pdev->sbdf.func, reg);
 }
 
 uint32_t vpci_hw_read32(const struct pci_dev *pdev, unsigned int reg,
                         void *data)
 {
-    return pci_conf_read32(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
-                           PCI_FUNC(pdev->devfn), reg);
+    return pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
+                           pdev->sbdf.func, reg);
 }
 
 int vpci_add_register(struct vpci *vpci, vpci_read_t *read_handler,
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 8b21e8dc84..1cf54eb466 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -80,9 +80,8 @@ struct pci_dev {
     struct arch_msix *msix;
 
     struct domain *domain;
-    const u16 seg;
-    const u8 bus;
-    const u8 devfn;
+
+    const pci_sbdf_t sbdf;
 
     u8 phantom_stride;
 
-- 
2.17.2 (Apple Git-113)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 2/5] pci: use function generation macros for pci_config_{write, read}<size>
@ 2019-05-10 16:10   ` Roger Pau Monne
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monne @ 2019-05-10 16:10 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Wei Liu, Jan Beulich, Roger Pau Monne

This avoids code duplication between the helpers.

No functional change intended.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
 xen/arch/x86/x86_64/pci.c | 140 ++++++++++++++++----------------------
 1 file changed, 57 insertions(+), 83 deletions(-)

diff --git a/xen/arch/x86/x86_64/pci.c b/xen/arch/x86/x86_64/pci.c
index 6e3f5cf203..4f77beb119 100644
--- a/xen/arch/x86/x86_64/pci.c
+++ b/xen/arch/x86/x86_64/pci.c
@@ -11,95 +11,69 @@
 #define PCI_CONF_ADDRESS(bus, dev, func, reg) \
     (0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3))
 
-uint8_t pci_conf_read8(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg)
-{
-    u32 value;
-
-    if ( seg || reg > 255 )
-    {
-        pci_mmcfg_read(seg, bus, PCI_DEVFN(dev, func), reg, 1, &value);
-        return value;
-    }
-    else
-    {
-        BUG_ON((bus > 255) || (dev > 31) || (func > 7));
-        return pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 3, 1);
+#define GEN_PCI_CONF_READ(s)                                                   \
+    uint ## s ## _t pci_conf_read ## s (unsigned int seg, unsigned int bus,    \
+                                        unsigned int dev, unsigned int func,   \
+                                        unsigned int reg)                      \
+    {                                                                          \
+        uint32_t value;                                                        \
+                                                                               \
+        BUILD_BUG_ON(s != 8 && s != 16 && s != 32);                            \
+        if ( seg || reg > 255 )                                                \
+            pci_mmcfg_read(seg, bus, PCI_DEVFN(dev, func), reg, s / 8, &value);\
+        else                                                                   \
+        {                                                                      \
+            BUG_ON((bus > 255) || (dev > 31) || (func > 7));                   \
+            value = pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg),       \
+                                  reg & (4 - s / 8), s / 8);                   \
+        }                                                                      \
+                                                                               \
+        return value;                                                          \
     }
-}
 
-uint16_t pci_conf_read16(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg)
-{
-    u32 value;
+/* Grep fodder */
+#define pci_conf_read8
+#define pci_conf_read16
+#define pci_conf_read32
 
-    if ( seg || reg > 255 )
-    {
-        pci_mmcfg_read(seg, bus, PCI_DEVFN(dev, func), reg, 2, &value);
-        return value;
-    }
-    else
-    {
-        BUG_ON((bus > 255) || (dev > 31) || (func > 7));
-        return pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 2, 2);
-    }
-}
+#undef pci_conf_read8
+#undef pci_conf_read16
+#undef pci_conf_read32
 
-uint32_t pci_conf_read32(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg)
-{
-    u32 value;
+GEN_PCI_CONF_READ(8)
+GEN_PCI_CONF_READ(16)
+GEN_PCI_CONF_READ(32)
 
-    if ( seg || reg > 255 )
-    {
-        pci_mmcfg_read(seg, bus, PCI_DEVFN(dev, func), reg, 4, &value);
-        return value;
-    }
-    else
-    {
-        BUG_ON((bus > 255) || (dev > 31) || (func > 7));
-        return pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg), 0, 4);
-    }
-}
+#undef GEN_PCI_CONF_READ
 
-void pci_conf_write8(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg, uint8_t data)
-{
-    if ( seg || reg > 255 )
-        pci_mmcfg_write(seg, bus, PCI_DEVFN(dev, func), reg, 1, data);
-    else
-    {
-        BUG_ON((bus > 255) || (dev > 31) || (func > 7));
-        pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 3, 1, data);
+#define GEN_PCI_CONF_WRITE(s)                                                  \
+    void pci_conf_write ## s (unsigned int seg, unsigned int bus,              \
+                              unsigned int dev, unsigned int func,             \
+                              unsigned int reg, uint ## s ## _t data)          \
+    {                                                                          \
+        BUILD_BUG_ON(s != 8 && s != 16 && s != 32);                            \
+        if ( seg || reg > 255 )                                                \
+            pci_mmcfg_write(seg, bus, PCI_DEVFN(dev, func), reg, s / 8, data); \
+        else                                                                   \
+        {                                                                      \
+            BUG_ON((bus > 255) || (dev > 31) || (func > 7));                   \
+            pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg),              \
+                           reg & (4 - s / 8), s / 8, data);                    \
+        }                                                                      \
     }
-}
 
-void pci_conf_write16(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg, uint16_t data)
-{
-    if ( seg || reg > 255 )
-        pci_mmcfg_write(seg, bus, PCI_DEVFN(dev, func), reg, 2, data);
-    else
-    {
-        BUG_ON((bus > 255) || (dev > 31) || (func > 7));
-        pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 2, 2, data);
-    }
-}
+/* Grep fodder */
+#define pci_conf_write8
+#define pci_conf_write16
+#define pci_conf_write32
+
+#undef pci_conf_write8
+#undef pci_conf_write16
+#undef pci_conf_write32
+
+GEN_PCI_CONF_WRITE(8)
+GEN_PCI_CONF_WRITE(16)
+GEN_PCI_CONF_WRITE(32)
+
+#undef GEN_PCI_CONF_WRITE
 
-void pci_conf_write32(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg, uint32_t data)
-{
-    if ( seg || reg > 255 )
-        pci_mmcfg_write(seg, bus, PCI_DEVFN(dev, func), reg, 4, data);
-    else
-    {
-        BUG_ON((bus > 255) || (dev > 31) || (func > 7));
-        pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), 0, 4, data);
-    }
-}
-- 
2.17.2 (Apple Git-113)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Xen-devel] [PATCH 2/5] pci: use function generation macros for pci_config_{write, read}<size>
@ 2019-05-10 16:10   ` Roger Pau Monne
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monne @ 2019-05-10 16:10 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Wei Liu, Jan Beulich, Roger Pau Monne

This avoids code duplication between the helpers.

No functional change intended.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
 xen/arch/x86/x86_64/pci.c | 140 ++++++++++++++++----------------------
 1 file changed, 57 insertions(+), 83 deletions(-)

diff --git a/xen/arch/x86/x86_64/pci.c b/xen/arch/x86/x86_64/pci.c
index 6e3f5cf203..4f77beb119 100644
--- a/xen/arch/x86/x86_64/pci.c
+++ b/xen/arch/x86/x86_64/pci.c
@@ -11,95 +11,69 @@
 #define PCI_CONF_ADDRESS(bus, dev, func, reg) \
     (0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3))
 
-uint8_t pci_conf_read8(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg)
-{
-    u32 value;
-
-    if ( seg || reg > 255 )
-    {
-        pci_mmcfg_read(seg, bus, PCI_DEVFN(dev, func), reg, 1, &value);
-        return value;
-    }
-    else
-    {
-        BUG_ON((bus > 255) || (dev > 31) || (func > 7));
-        return pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 3, 1);
+#define GEN_PCI_CONF_READ(s)                                                   \
+    uint ## s ## _t pci_conf_read ## s (unsigned int seg, unsigned int bus,    \
+                                        unsigned int dev, unsigned int func,   \
+                                        unsigned int reg)                      \
+    {                                                                          \
+        uint32_t value;                                                        \
+                                                                               \
+        BUILD_BUG_ON(s != 8 && s != 16 && s != 32);                            \
+        if ( seg || reg > 255 )                                                \
+            pci_mmcfg_read(seg, bus, PCI_DEVFN(dev, func), reg, s / 8, &value);\
+        else                                                                   \
+        {                                                                      \
+            BUG_ON((bus > 255) || (dev > 31) || (func > 7));                   \
+            value = pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg),       \
+                                  reg & (4 - s / 8), s / 8);                   \
+        }                                                                      \
+                                                                               \
+        return value;                                                          \
     }
-}
 
-uint16_t pci_conf_read16(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg)
-{
-    u32 value;
+/* Grep fodder */
+#define pci_conf_read8
+#define pci_conf_read16
+#define pci_conf_read32
 
-    if ( seg || reg > 255 )
-    {
-        pci_mmcfg_read(seg, bus, PCI_DEVFN(dev, func), reg, 2, &value);
-        return value;
-    }
-    else
-    {
-        BUG_ON((bus > 255) || (dev > 31) || (func > 7));
-        return pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 2, 2);
-    }
-}
+#undef pci_conf_read8
+#undef pci_conf_read16
+#undef pci_conf_read32
 
-uint32_t pci_conf_read32(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg)
-{
-    u32 value;
+GEN_PCI_CONF_READ(8)
+GEN_PCI_CONF_READ(16)
+GEN_PCI_CONF_READ(32)
 
-    if ( seg || reg > 255 )
-    {
-        pci_mmcfg_read(seg, bus, PCI_DEVFN(dev, func), reg, 4, &value);
-        return value;
-    }
-    else
-    {
-        BUG_ON((bus > 255) || (dev > 31) || (func > 7));
-        return pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg), 0, 4);
-    }
-}
+#undef GEN_PCI_CONF_READ
 
-void pci_conf_write8(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg, uint8_t data)
-{
-    if ( seg || reg > 255 )
-        pci_mmcfg_write(seg, bus, PCI_DEVFN(dev, func), reg, 1, data);
-    else
-    {
-        BUG_ON((bus > 255) || (dev > 31) || (func > 7));
-        pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 3, 1, data);
+#define GEN_PCI_CONF_WRITE(s)                                                  \
+    void pci_conf_write ## s (unsigned int seg, unsigned int bus,              \
+                              unsigned int dev, unsigned int func,             \
+                              unsigned int reg, uint ## s ## _t data)          \
+    {                                                                          \
+        BUILD_BUG_ON(s != 8 && s != 16 && s != 32);                            \
+        if ( seg || reg > 255 )                                                \
+            pci_mmcfg_write(seg, bus, PCI_DEVFN(dev, func), reg, s / 8, data); \
+        else                                                                   \
+        {                                                                      \
+            BUG_ON((bus > 255) || (dev > 31) || (func > 7));                   \
+            pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg),              \
+                           reg & (4 - s / 8), s / 8, data);                    \
+        }                                                                      \
     }
-}
 
-void pci_conf_write16(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg, uint16_t data)
-{
-    if ( seg || reg > 255 )
-        pci_mmcfg_write(seg, bus, PCI_DEVFN(dev, func), reg, 2, data);
-    else
-    {
-        BUG_ON((bus > 255) || (dev > 31) || (func > 7));
-        pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 2, 2, data);
-    }
-}
+/* Grep fodder */
+#define pci_conf_write8
+#define pci_conf_write16
+#define pci_conf_write32
+
+#undef pci_conf_write8
+#undef pci_conf_write16
+#undef pci_conf_write32
+
+GEN_PCI_CONF_WRITE(8)
+GEN_PCI_CONF_WRITE(16)
+GEN_PCI_CONF_WRITE(32)
+
+#undef GEN_PCI_CONF_WRITE
 
-void pci_conf_write32(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg, uint32_t data)
-{
-    if ( seg || reg > 255 )
-        pci_mmcfg_write(seg, bus, PCI_DEVFN(dev, func), reg, 4, data);
-    else
-    {
-        BUG_ON((bus > 255) || (dev > 31) || (func > 7));
-        pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), 0, 4, data);
-    }
-}
-- 
2.17.2 (Apple Git-113)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 3/5] pci: switch pci_conf_{read/write} to use pci_sbdf_t
@ 2019-05-10 16:10   ` Roger Pau Monne
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monne @ 2019-05-10 16:10 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Suravee Suthikulpanit,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper, Ian Jackson,
	Tim Deegan, Julien Grall, Jan Beulich, Brian Woods,
	Roger Pau Monne

pci_dev already uses pci_sbdf_t, so propagate the usage of the type to
pci_conf functions in order to shorten the calls when made from a
pci_dev struct.

No functional change intended.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Julien Grall <julien.grall@arm.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Brian Woods <brian.woods@amd.com>
Cc: Kevin Tian <kevin.tian@intel.com>
---
 xen/arch/x86/cpu/amd.c                     |  27 ++--
 xen/arch/x86/dmi_scan.c                    |   9 +-
 xen/arch/x86/mm.c                          |   2 +-
 xen/arch/x86/msi.c                         | 177 +++++++++------------
 xen/arch/x86/oprofile/op_model_athlon.c    |  12 +-
 xen/arch/x86/x86_64/mmconf-fam10h.c        |  13 +-
 xen/arch/x86/x86_64/mmconfig-shared.c      |  26 +--
 xen/arch/x86/x86_64/pci.c                  |  32 ++--
 xen/drivers/acpi/reboot.c                  |   8 +-
 xen/drivers/char/ehci-dbgp.c               |  75 +++++----
 xen/drivers/char/ns16550.c                 |  80 +++++-----
 xen/drivers/passthrough/amd/iommu_detect.c |   3 +-
 xen/drivers/passthrough/amd/iommu_init.c   |  26 +--
 xen/drivers/passthrough/ats.h              |   4 +-
 xen/drivers/passthrough/pci.c              | 106 +++++-------
 xen/drivers/passthrough/vtd/dmar.c         |  18 ++-
 xen/drivers/passthrough/vtd/quirks.c       |  69 ++++----
 xen/drivers/passthrough/x86/ats.c          |  15 +-
 xen/drivers/pci/pci.c                      |  43 +++--
 xen/drivers/video/vga.c                    |  21 +--
 xen/drivers/vpci/header.c                  |  53 ++----
 xen/drivers/vpci/msi.c                     |   6 +-
 xen/drivers/vpci/msix.c                    |  12 +-
 xen/drivers/vpci/vpci.c                    |  42 ++---
 xen/include/xen/pci.h                      |  29 ++--
 25 files changed, 444 insertions(+), 464 deletions(-)

diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
index e19a5ead3e..014d88925c 100644
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -417,15 +417,21 @@ static void disable_c1_ramping(void)
 	int node, nr_nodes;
 
 	/* Read the number of nodes from the first Northbridge. */
-	nr_nodes = ((pci_conf_read32(0, 0, 0x18, 0x0, 0x60)>>4)&0x07)+1;
+	nr_nodes = ((pci_conf_read32(PCI_SBDF_T(0, 0, 0x18, 0),
+				     0x60)>>4)&0x07)+1;
 	for (node = 0; node < nr_nodes; node++) {
+		const pci_sbdf_t sbdf = {
+			.dev = 0x18  + node,
+			.func = 0x3
+		};
+
 		/* PMM7: bus=0, dev=0x18+node, function=0x3, register=0x87. */
-		pmm7 = pci_conf_read8(0, 0, 0x18+node, 0x3, 0x87);
+		pmm7 = pci_conf_read8(sbdf, 0x87);
 		/* Invalid read means we've updated every Northbridge. */
 		if (pmm7 == 0xFF)
 			break;
 		pmm7 &= 0xFC; /* clear pmm7[1:0] */
-		pci_conf_write8(0, 0, 0x18+node, 0x3, 0x87, pmm7);
+		pci_conf_write8(sbdf, 0x87, pmm7);
 		printk ("AMD: Disabling C1 Clock Ramping Node #%x\n", node);
 	}
 }
@@ -696,8 +702,13 @@ static void init_amd(struct cpuinfo_x86 *c)
 
 	if (c->x86 == 0x16 && c->x86_model <= 0xf) {
 		if (c == &boot_cpu_data) {
-			l = pci_conf_read32(0, 0, 0x18, 0x3, 0x58);
-			h = pci_conf_read32(0, 0, 0x18, 0x3, 0x5c);
+			const pci_sbdf_t sbdf = {
+				.dev = 0x18,
+				.func = 0x3,
+			};
+
+			l = pci_conf_read32(sbdf, 0x58);
+			h = pci_conf_read32(sbdf, 0x5c);
 			if ((l & 0x1f) | (h & 0x1))
 				printk(KERN_WARNING
 				       "Applying workaround for erratum 792: %s%s%s\n",
@@ -706,12 +717,10 @@ static void init_amd(struct cpuinfo_x86 *c)
 				       (h & 0x1) ? "clearing D18F3x5C[0]" : "");
 
 			if (l & 0x1f)
-				pci_conf_write32(0, 0, 0x18, 0x3, 0x58,
-						 l & ~0x1f);
+				pci_conf_write32(sbdf, 0x58, l & ~0x1f);
 
 			if (h & 0x1)
-				pci_conf_write32(0, 0, 0x18, 0x3, 0x5c,
-						 h & ~0x1);
+				pci_conf_write32(sbdf, 0x5c, h & ~0x1);
 		}
 
 		rdmsrl(MSR_AMD64_LS_CFG, value);
diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
index fcdf2d3952..59557fa57b 100644
--- a/xen/arch/x86/dmi_scan.c
+++ b/xen/arch/x86/dmi_scan.c
@@ -468,16 +468,19 @@ static __init int broken_toshiba_keyboard(struct dmi_blacklist *d)
 static int __init ich10_bios_quirk(struct dmi_system_id *d)
 {
     u32 port, smictl;
+    const pci_sbdf_t sbdf = {
+	.dev = 0x1f,
+    };
 
-    if ( pci_conf_read16(0, 0, 0x1f, 0, PCI_VENDOR_ID) != 0x8086 )
+    if ( pci_conf_read16(sbdf, PCI_VENDOR_ID) != 0x8086 )
         return 0;
 
-    switch ( pci_conf_read16(0, 0, 0x1f, 0, PCI_DEVICE_ID) ) {
+    switch ( pci_conf_read16(sbdf, PCI_DEVICE_ID) ) {
     case 0x3a14:
     case 0x3a16:
     case 0x3a18:
     case 0x3a1a:
-        port = (pci_conf_read16(0, 0, 0x1f, 0, 0x40) & 0xff80) + 0x30;
+        port = (pci_conf_read16(sbdf, 0x40) & 0xff80) + 0x30;
         smictl = inl(port);
         /* turn off LEGACY_USB{,2}_EN if enabled */
         if ( smictl & 0x20008 )
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 45fadbab61..37d8141ed2 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -5984,7 +5984,7 @@ const struct platform_bad_page *__init get_platform_badpages(unsigned int *array
     }
 
     *array_size = ARRAY_SIZE(snb_bad_pages);
-    igd_id = pci_conf_read32(0, 0, 2, 0, 0);
+    igd_id = pci_conf_read32(PCI_SBDF_T(0, 0, 2, 0), 0);
     if ( IS_SNB_GFX(igd_id) )
         return snb_bad_pages;
 
diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index f30f592ee2..ad4a72d56b 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -124,29 +124,20 @@ static void msix_put_fixmap(struct arch_msix *msix, int idx)
 
 static bool memory_decoded(const struct pci_dev *dev)
 {
-    uint8_t bus, slot, func;
+    pci_sbdf_t sbdf = dev->sbdf;
 
-    if ( !dev->info.is_virtfn )
+    if ( dev->info.is_virtfn )
     {
-        bus = dev->sbdf.bus;
-        slot = dev->sbdf.dev;
-        func = dev->sbdf.func;
-    }
-    else
-    {
-        bus = dev->info.physfn.bus;
-        slot = PCI_SLOT(dev->info.physfn.devfn);
-        func = PCI_FUNC(dev->info.physfn.devfn);
+        sbdf.bus = dev->info.physfn.bus;
+        sbdf.extfunc = dev->info.physfn.devfn;
     }
 
-    return !!(pci_conf_read16(dev->sbdf.seg, bus, slot, func, PCI_COMMAND) &
-              PCI_COMMAND_MEMORY);
+    return !!(pci_conf_read16(sbdf, PCI_COMMAND) & PCI_COMMAND_MEMORY);
 }
 
 static bool msix_memory_decoded(const struct pci_dev *dev, unsigned int pos)
 {
-    u16 control = pci_conf_read16(dev->sbdf.seg, dev->sbdf.bus, dev->sbdf.dev,
-                                  dev->sbdf.func, msix_control_reg(pos));
+    u16 control = pci_conf_read16(dev->sbdf, msix_control_reg(pos));
 
     if ( !(control & PCI_MSIX_FLAGS_ENABLE) )
         return false;
@@ -200,25 +191,20 @@ static bool read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
     {
         struct pci_dev *dev = entry->dev;
         int pos = entry->msi_attrib.pos;
-        uint16_t data, seg = dev->sbdf.seg;
-        uint8_t bus = dev->sbdf.bus;
-        uint8_t slot = dev->sbdf.dev;
-        uint8_t func = dev->sbdf.func;
+        uint16_t data;
 
-        msg->address_lo = pci_conf_read32(seg, bus, slot, func,
+        msg->address_lo = pci_conf_read32(dev->sbdf,
                                           msi_lower_address_reg(pos));
         if ( entry->msi_attrib.is_64 )
         {
-            msg->address_hi = pci_conf_read32(seg, bus, slot, func,
+            msg->address_hi = pci_conf_read32(dev->sbdf,
                                               msi_upper_address_reg(pos));
-            data = pci_conf_read16(seg, bus, slot, func,
-                                   msi_data_reg(pos, 1));
+            data = pci_conf_read16(dev->sbdf, msi_data_reg(pos, 1));
         }
         else
         {
             msg->address_hi = 0;
-            data = pci_conf_read16(seg, bus, slot, func,
-                                   msi_data_reg(pos, 0));
+            data = pci_conf_read16(dev->sbdf, msi_data_reg(pos, 0));
         }
         msg->data = data;
         break;
@@ -265,28 +251,22 @@ static int write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
     {
         struct pci_dev *dev = entry->dev;
         int pos = entry->msi_attrib.pos;
-        uint16_t seg = dev->sbdf.seg;
-        uint8_t bus = dev->sbdf.bus;
-        uint8_t slot = dev->sbdf.dev;
-        uint8_t func = dev->sbdf.func;
         int nr = entry->msi_attrib.entry_nr;
 
         ASSERT((msg->data & (entry[-nr].msi.nvec - 1)) == nr);
         if ( nr )
             return 0;
 
-        pci_conf_write32(seg, bus, slot, func, msi_lower_address_reg(pos),
-                         msg->address_lo);
+        pci_conf_write32(dev->sbdf, msi_lower_address_reg(pos), msg->address_lo);
         if ( entry->msi_attrib.is_64 )
         {
-            pci_conf_write32(seg, bus, slot, func, msi_upper_address_reg(pos),
+            pci_conf_write32(dev->sbdf, msi_upper_address_reg(pos),
                              msg->address_hi);
-            pci_conf_write16(seg, bus, slot, func, msi_data_reg(pos, 1),
+            pci_conf_write16(dev->sbdf, msi_data_reg(pos, 1),
                              msg->data);
         }
         else
-            pci_conf_write16(seg, bus, slot, func, msi_data_reg(pos, 0),
-                             msg->data);
+            pci_conf_write16(dev->sbdf, msi_data_reg(pos, 0), msg->data);
         break;
     }
     case PCI_CAP_ID_MSIX:
@@ -337,12 +317,18 @@ void set_msi_affinity(struct irq_desc *desc, const cpumask_t *mask)
 
 void __msi_set_enable(u16 seg, u8 bus, u8 slot, u8 func, int pos, int enable)
 {
-    u16 control = pci_conf_read16(seg, bus, slot, func, pos + PCI_MSI_FLAGS);
+    const pci_sbdf_t sbdf = {
+        .seg = seg,
+        .bus = bus,
+        .dev = slot,
+        .func = func,
+    };
+    uint16_t control = pci_conf_read16(sbdf, pos + PCI_MSI_FLAGS);
 
     control &= ~PCI_MSI_FLAGS_ENABLE;
     if ( enable )
         control |= PCI_MSI_FLAGS_ENABLE;
-    pci_conf_write16(seg, bus, slot, func, pos + PCI_MSI_FLAGS, control);
+    pci_conf_write16(sbdf, pos + PCI_MSI_FLAGS, control);
 }
 
 static void msi_set_enable(struct pci_dev *dev, int enable)
@@ -369,11 +355,11 @@ static void msix_set_enable(struct pci_dev *dev, int enable)
     pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSIX);
     if ( pos )
     {
-        control = pci_conf_read16(seg, bus, slot, func, msix_control_reg(pos));
+        control = pci_conf_read16(dev->sbdf, msix_control_reg(pos));
         control &= ~PCI_MSIX_FLAGS_ENABLE;
         if ( enable )
             control |= PCI_MSIX_FLAGS_ENABLE;
-        pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), control);
+        pci_conf_write16(dev->sbdf, msix_control_reg(pos), control);
     }
 }
 
@@ -406,20 +392,20 @@ static bool msi_set_mask_bit(struct irq_desc *desc, bool host, bool guest)
         {
             u32 mask_bits;
 
-            mask_bits = pci_conf_read32(seg, bus, slot, func, entry->msi.mpos);
+            mask_bits = pci_conf_read32(pdev->sbdf, entry->msi.mpos);
             mask_bits &= ~((u32)1 << entry->msi_attrib.entry_nr);
             mask_bits |= (u32)flag << entry->msi_attrib.entry_nr;
-            pci_conf_write32(seg, bus, slot, func, entry->msi.mpos, mask_bits);
+            pci_conf_write32(pdev->sbdf, entry->msi.mpos, mask_bits);
         }
         break;
     case PCI_CAP_ID_MSIX:
         maskall = pdev->msix->host_maskall;
-        control = pci_conf_read16(seg, bus, slot, func,
+        control = pci_conf_read16(pdev->sbdf,
                                   msix_control_reg(entry->msi_attrib.pos));
         if ( unlikely(!(control & PCI_MSIX_FLAGS_ENABLE)) )
         {
             pdev->msix->host_maskall = 1;
-            pci_conf_write16(seg, bus, slot, func,
+            pci_conf_write16(pdev->sbdf,
                              msix_control_reg(entry->msi_attrib.pos),
                              control | (PCI_MSIX_FLAGS_ENABLE |
                                         PCI_MSIX_FLAGS_MASKALL));
@@ -453,7 +439,7 @@ static bool msi_set_mask_bit(struct irq_desc *desc, bool host, bool guest)
         pdev->msix->host_maskall = maskall;
         if ( maskall || pdev->msix->guest_maskall )
             control |= PCI_MSIX_FLAGS_MASKALL;
-        pci_conf_write16(seg, bus, slot, func,
+        pci_conf_write16(pdev->sbdf,
                          msix_control_reg(entry->msi_attrib.pos), control);
         return flag;
     default:
@@ -475,9 +461,7 @@ static int msi_get_mask_bit(const struct msi_desc *entry)
     case PCI_CAP_ID_MSI:
         if ( !entry->msi_attrib.maskbit )
             break;
-        return (pci_conf_read32(entry->dev->sbdf.seg, entry->dev->sbdf.bus,
-                                entry->dev->sbdf.dev, entry->dev->sbdf.func,
-                                entry->msi.mpos) >>
+        return (pci_conf_read32(entry->dev->sbdf, entry->msi.mpos) >>
                 entry->msi_attrib.entry_nr) & 1;
     case PCI_CAP_ID_MSIX:
         if ( unlikely(!msix_memory_decoded(entry->dev,
@@ -593,11 +577,9 @@ int setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc)
 
     if ( msidesc->msi_attrib.type == PCI_CAP_ID_MSIX )
     {
-        control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
-                                  pdev->sbdf.dev, pdev->sbdf.func, cpos);
+        control = pci_conf_read16(pdev->sbdf, cpos);
         if ( !(control & PCI_MSIX_FLAGS_ENABLE) )
-            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                             pdev->sbdf.func, cpos,
+            pci_conf_write16(pdev->sbdf, cpos,
                              control | (PCI_MSIX_FLAGS_ENABLE |
                                         PCI_MSIX_FLAGS_MASKALL));
     }
@@ -607,8 +589,7 @@ int setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc)
                                                    : &pci_msi_nonmaskable);
 
     if ( !(control & PCI_MSIX_FLAGS_ENABLE) )
-        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                         pdev->sbdf.func, cpos, control);
+        pci_conf_write16(pdev->sbdf, cpos, control);
 
     return rc;
 }
@@ -697,7 +678,7 @@ static int msi_capability_init(struct pci_dev *dev,
     pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSI);
     if ( !pos )
         return -ENODEV;
-    control = pci_conf_read16(seg, bus, slot, func, msi_control_reg(pos));
+    control = pci_conf_read16(dev->sbdf, msi_control_reg(pos));
     maxvec = multi_msi_capable(control);
     if ( nvec > maxvec )
         return maxvec;
@@ -733,9 +714,9 @@ static int msi_capability_init(struct pci_dev *dev,
         u32 maskbits;
 
         /* All MSIs are unmasked by default, Mask them all */
-        maskbits = pci_conf_read32(seg, bus, slot, func, mpos);
+        maskbits = pci_conf_read32(dev->sbdf, mpos);
         maskbits |= ~(u32)0 >> (32 - maxvec);
-        pci_conf_write32(seg, bus, slot, func, mpos, maskbits);
+        pci_conf_write32(dev->sbdf, mpos, maskbits);
     }
     list_add_tail(&entry->list, &dev->msi_list);
 
@@ -751,7 +732,7 @@ static int msi_capability_init(struct pci_dev *dev,
         pci_intx(dev, false);
         control |= PCI_MSI_FLAGS_ENABLE;
     }
-    pci_conf_write16(seg, bus, slot, func, msi_control_reg(pos), control);
+    pci_conf_write16(dev->sbdf, msi_control_reg(pos), control);
 
     return 0;
 }
@@ -761,6 +742,12 @@ static u64 read_pci_mem_bar(u16 seg, u8 bus, u8 slot, u8 func, u8 bir, int vf)
     u8 limit;
     u32 addr, base = PCI_BASE_ADDRESS_0;
     u64 disp = 0;
+    const pci_sbdf_t sbdf = {
+        .seg = seg,
+        .bus = bus,
+        .dev = slot,
+        .func = func,
+    };
 
     if ( vf >= 0 )
     {
@@ -768,13 +755,10 @@ static u64 read_pci_mem_bar(u16 seg, u8 bus, u8 slot, u8 func, u8 bir, int vf)
         unsigned int pos = pci_find_ext_capability(seg, bus,
                                                    PCI_DEVFN(slot, func),
                                                    PCI_EXT_CAP_ID_SRIOV);
-        u16 ctrl = pci_conf_read16(seg, bus, slot, func, pos + PCI_SRIOV_CTRL);
-        u16 num_vf = pci_conf_read16(seg, bus, slot, func,
-                                     pos + PCI_SRIOV_NUM_VF);
-        u16 offset = pci_conf_read16(seg, bus, slot, func,
-                                     pos + PCI_SRIOV_VF_OFFSET);
-        u16 stride = pci_conf_read16(seg, bus, slot, func,
-                                     pos + PCI_SRIOV_VF_STRIDE);
+        u16 ctrl = pci_conf_read16(sbdf, pos + PCI_SRIOV_CTRL);
+        u16 num_vf = pci_conf_read16(sbdf, pos + PCI_SRIOV_NUM_VF);
+        u16 offset = pci_conf_read16(sbdf, pos + PCI_SRIOV_VF_OFFSET);
+        u16 stride = pci_conf_read16(sbdf, pos + PCI_SRIOV_VF_STRIDE);
 
         if ( !pdev || !pos ||
              !(ctrl & PCI_SRIOV_CTRL_VFE) ||
@@ -799,8 +783,7 @@ static u64 read_pci_mem_bar(u16 seg, u8 bus, u8 slot, u8 func, u8 bir, int vf)
         disp = vf * pdev->vf_rlen[bir];
         limit = PCI_SRIOV_NUM_BARS;
     }
-    else switch ( pci_conf_read8(seg, bus, slot, func,
-                                 PCI_HEADER_TYPE) & 0x7f )
+    else switch ( pci_conf_read8(sbdf, PCI_HEADER_TYPE) & 0x7f )
     {
     case PCI_HEADER_TYPE_NORMAL:
         limit = 6;
@@ -817,7 +800,7 @@ static u64 read_pci_mem_bar(u16 seg, u8 bus, u8 slot, u8 func, u8 bir, int vf)
 
     if ( bir >= limit )
         return 0;
-    addr = pci_conf_read32(seg, bus, slot, func, base + bir * 4);
+    addr = pci_conf_read32(sbdf, base + bir * 4);
     if ( (addr & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO )
         return 0;
     if ( (addr & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64 )
@@ -826,8 +809,7 @@ static u64 read_pci_mem_bar(u16 seg, u8 bus, u8 slot, u8 func, u8 bir, int vf)
         if ( ++bir >= limit )
             return 0;
         return addr + disp +
-               ((u64)pci_conf_read32(seg, bus, slot, func,
-                                     base + bir * 4) << 32);
+               ((uint64_t)pci_conf_read32(sbdf, base + bir * 4) << 32);
     }
     return (addr & PCI_BASE_ADDRESS_MEM_MASK) + disp;
 }
@@ -863,7 +845,7 @@ static int msix_capability_init(struct pci_dev *dev,
 
     ASSERT(pcidevs_locked());
 
-    control = pci_conf_read16(seg, bus, slot, func, msix_control_reg(pos));
+    control = pci_conf_read16(dev->sbdf, msix_control_reg(pos));
     /*
      * Ensure MSI-X interrupts are masked during setup. Some devices require
      * MSI-X to be enabled before we can touch the MSI-X registers. We need
@@ -871,13 +853,13 @@ static int msix_capability_init(struct pci_dev *dev,
      * fully set up.
      */
     msix->host_maskall = 1;
-    pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+    pci_conf_write16(dev->sbdf, msix_control_reg(pos),
                      control | (PCI_MSIX_FLAGS_ENABLE |
                                 PCI_MSIX_FLAGS_MASKALL));
 
     if ( unlikely(!memory_decoded(dev)) )
     {
-        pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+        pci_conf_write16(dev->sbdf, msix_control_reg(pos),
                          control & ~PCI_MSIX_FLAGS_ENABLE);
         return -ENXIO;
     }
@@ -887,7 +869,7 @@ static int msix_capability_init(struct pci_dev *dev,
         entry = alloc_msi_entry(1);
         if ( !entry )
         {
-            pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+            pci_conf_write16(dev->sbdf, msix_control_reg(pos),
                              control & ~PCI_MSIX_FLAGS_ENABLE);
             return -ENOMEM;
         }
@@ -895,8 +877,7 @@ static int msix_capability_init(struct pci_dev *dev,
     }
 
     /* Locate MSI-X table region */
-    table_offset = pci_conf_read32(seg, bus, slot, func,
-                                   msix_table_offset_reg(pos));
+    table_offset = pci_conf_read32(dev->sbdf, msix_table_offset_reg(pos));
     bir = (u8)(table_offset & PCI_MSIX_BIRMASK);
     table_offset &= ~PCI_MSIX_BIRMASK;
 
@@ -921,7 +902,7 @@ static int msix_capability_init(struct pci_dev *dev,
     {
         if ( !msi || !msi->table_base )
         {
-            pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+            pci_conf_write16(dev->sbdf, msix_control_reg(pos),
                              control & ~PCI_MSIX_FLAGS_ENABLE);
             xfree(entry);
             return -ENXIO;
@@ -942,8 +923,7 @@ static int msix_capability_init(struct pci_dev *dev,
         WARN_ON(rangeset_overlaps_range(mmio_ro_ranges, msix->table.first,
                                         msix->table.last));
 
-        pba_offset = pci_conf_read32(seg, bus, slot, func,
-                                     msix_pba_offset_reg(pos));
+        pba_offset = pci_conf_read32(dev->sbdf, msix_pba_offset_reg(pos));
         bir = (u8)(pba_offset & PCI_MSIX_BIRMASK);
         pba_paddr = read_pci_mem_bar(seg, pbus, pslot, pfunc, bir, vf);
         WARN_ON(!pba_paddr);
@@ -965,7 +945,7 @@ static int msix_capability_init(struct pci_dev *dev,
 
         if ( idx < 0 )
         {
-            pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+            pci_conf_write16(dev->sbdf, msix_control_reg(pos),
                              control & ~PCI_MSIX_FLAGS_ENABLE);
             xfree(entry);
             return idx;
@@ -1041,7 +1021,7 @@ static int msix_capability_init(struct pci_dev *dev,
         maskall = 0;
     }
     msix->host_maskall = maskall;
-    pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), control);
+    pci_conf_write16(dev->sbdf, msix_control_reg(pos), control);
 
     return 0;
 }
@@ -1130,8 +1110,7 @@ static int __pci_enable_msix(struct msi_info *msi, struct msi_desc **desc)
     if ( !pdev || !pos )
         return -ENODEV;
 
-    control = pci_conf_read16(msi->seg, msi->bus, slot, func,
-                              msix_control_reg(pos));
+    control = pci_conf_read16(pdev->sbdf, msix_control_reg(pos));
     nr_entries = multi_msix_capable(control);
     if ( msi->entry_nr >= nr_entries )
         return -EINVAL;
@@ -1177,14 +1156,14 @@ static void __pci_disable_msix(struct msi_desc *entry)
     uint8_t func = dev->sbdf.func;
     unsigned int pos = pci_find_cap_offset(seg, bus, slot, func,
                                            PCI_CAP_ID_MSIX);
-    u16 control = pci_conf_read16(seg, bus, slot, func,
-                                  msix_control_reg(entry->msi_attrib.pos));
+    uint16_t control = pci_conf_read16(dev->sbdf,
+                                       msix_control_reg(entry->msi_attrib.pos));
     bool maskall = dev->msix->host_maskall;
 
     if ( unlikely(!(control & PCI_MSIX_FLAGS_ENABLE)) )
     {
         dev->msix->host_maskall = 1;
-        pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+        pci_conf_write16(dev->sbdf, msix_control_reg(pos),
                          control | (PCI_MSIX_FLAGS_ENABLE |
                                     PCI_MSIX_FLAGS_MASKALL));
     }
@@ -1203,7 +1182,7 @@ static void __pci_disable_msix(struct msi_desc *entry)
     dev->msix->host_maskall = maskall;
     if ( maskall || dev->msix->guest_maskall )
         control |= PCI_MSIX_FLAGS_MASKALL;
-    pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), control);
+    pci_conf_write16(dev->sbdf, msix_control_reg(pos), control);
 
     _pci_cleanup_msix(dev->msix);
 }
@@ -1235,8 +1214,7 @@ int pci_prepare_msix(u16 seg, u8 bus, u8 devfn, bool off)
     }
     else
     {
-        u16 control = pci_conf_read16(seg, bus, slot, func,
-                                      msix_control_reg(pos));
+        uint16_t control = pci_conf_read16(pdev->sbdf, msix_control_reg(pos));
 
         rc = msix_capability_init(pdev, pos, NULL, NULL,
                                   multi_msix_capable(control));
@@ -1337,7 +1315,7 @@ int pci_msi_conf_write_intercept(struct pci_dev *pdev, unsigned int reg,
         if ( reg < entry->msi.mpos || reg >= entry->msi.mpos + 4 || size != 4 )
             return -EACCES;
 
-        cntl = pci_conf_read16(seg, bus, slot, func, msi_control_reg(pos));
+        cntl = pci_conf_read16(pdev->sbdf, msi_control_reg(pos));
         unused = ~(uint32_t)0 >> (32 - multi_msi_capable(cntl));
         for ( pos = 0; pos < entry->msi.nvec; ++pos, ++entry )
         {
@@ -1396,8 +1374,7 @@ int pci_restore_msi_state(struct pci_dev *pdev)
                     pdev->sbdf.seg, pdev->sbdf.bus, slot, func, i);
             spin_unlock_irqrestore(&desc->lock, flags);
             if ( type == PCI_CAP_ID_MSIX )
-                pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
-                                 msix_control_reg(pos),
+                pci_conf_write16(pdev->sbdf, msix_control_reg(pos),
                                  control & ~PCI_MSIX_FLAGS_ENABLE);
             return -EINVAL;
         }
@@ -1411,17 +1388,14 @@ int pci_restore_msi_state(struct pci_dev *pdev)
         }
         else if ( !type && entry->msi_attrib.type == PCI_CAP_ID_MSIX )
         {
-            control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, slot,
-                                      func, msix_control_reg(pos));
-            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
-                             msix_control_reg(pos),
+            control = pci_conf_read16(pdev->sbdf, msix_control_reg(pos));
+            pci_conf_write16(pdev->sbdf, msix_control_reg(pos),
                              control | (PCI_MSIX_FLAGS_ENABLE |
                                         PCI_MSIX_FLAGS_MASKALL));
             if ( unlikely(!memory_decoded(pdev)) )
             {
                 spin_unlock_irqrestore(&desc->lock, flags);
-                pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
-                                 msix_control_reg(pos),
+                pci_conf_write16(pdev->sbdf, msix_control_reg(pos),
                                  control & ~PCI_MSIX_FLAGS_ENABLE);
                 return -ENXIO;
             }
@@ -1454,19 +1428,16 @@ int pci_restore_msi_state(struct pci_dev *pdev)
         {
             unsigned int cpos = msi_control_reg(pos);
 
-            control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, slot,
-                                      func, cpos) & ~PCI_MSI_FLAGS_QSIZE;
+            control = pci_conf_read16(pdev->sbdf, cpos) & ~PCI_MSI_FLAGS_QSIZE;
             multi_msi_enable(control, entry->msi.nvec);
-            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func, cpos,
-                             control);
+            pci_conf_write16(pdev->sbdf, cpos, control);
 
             msi_set_enable(pdev, 1);
         }
     }
 
     if ( type == PCI_CAP_ID_MSIX )
-        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
-                         msix_control_reg(pos),
+        pci_conf_write16(pdev->sbdf, msix_control_reg(pos),
                          control | PCI_MSIX_FLAGS_ENABLE);
 
     return 0;
diff --git a/xen/arch/x86/oprofile/op_model_athlon.c b/xen/arch/x86/oprofile/op_model_athlon.c
index 3d6e26f636..33f7394979 100644
--- a/xen/arch/x86/oprofile/op_model_athlon.c
+++ b/xen/arch/x86/oprofile/op_model_athlon.c
@@ -463,7 +463,13 @@ static int __init init_ibs_nmi(void)
 	for (bus = 0; bus < 256; bus++) {
 		for (dev = 0; dev < 32; dev++) {
 			for (func = 0; func < 8; func++) {
-				id = pci_conf_read32(0, bus, dev, func, PCI_VENDOR_ID);
+				const pci_sbdf_t sbdf = {
+				    .bus = bus,
+				    .dev = dev,
+				    .func = func,
+				};
+    
+				id = pci_conf_read32(sbdf, PCI_VENDOR_ID);
 
 				vendor_id = id & 0xffff;
 				dev_id = (id >> 16) & 0xffff;
@@ -471,10 +477,10 @@ static int __init init_ibs_nmi(void)
 				if ((vendor_id == PCI_VENDOR_ID_AMD) &&
 					(dev_id == PCI_DEVICE_ID_AMD_10H_NB_MISC)) {
 
-					pci_conf_write32(0, bus, dev, func, IBSCTL,
+					pci_conf_write32(sbdf, IBSCTL,
 						IBSCTL_LVTOFFSETVAL | APIC_EILVT_LVTOFF_IBS);
 
-					value = pci_conf_read32(0, bus, dev, func, IBSCTL);
+					value = pci_conf_read32(sbdf, IBSCTL);
 
 					if (value != (IBSCTL_LVTOFFSETVAL |
 						APIC_EILVT_LVTOFF_IBS)) {
diff --git a/xen/arch/x86/x86_64/mmconf-fam10h.c b/xen/arch/x86/x86_64/mmconf-fam10h.c
index ed0acb9968..e7f02de894 100644
--- a/xen/arch/x86/x86_64/mmconf-fam10h.c
+++ b/xen/arch/x86/x86_64/mmconf-fam10h.c
@@ -38,21 +38,22 @@ static struct pci_hostbridge_probe pci_probes[] = {
 #define BASE_VALID(b) ((b) + SIZE <= (0xfdULL<<32) || (b) >= (1ULL<<40))
 static void __init get_fam10h_pci_mmconf_base(void)
 {
-	unsigned int i, j, bus, slot, hi_mmio_num;
+	unsigned int i, j, hi_mmio_num;
 	u32 address;
 	u64 val, tom2, start, end;
 	struct range {
 		u64 start, end;
 	} range[8];
+	pci_sbdf_t sbdf = { };
 
 	for (i = 0; i < ARRAY_SIZE(pci_probes); i++) {
 		u32 id;
 		u16 device;
 		u16 vendor;
 
-		bus = pci_probes[i].bus;
-		slot = pci_probes[i].slot;
-		id = pci_conf_read32(0, bus, slot, 0, PCI_VENDOR_ID);
+		sbdf.bus = pci_probes[i].bus;
+		sbdf.dev = pci_probes[i].slot;
+		id = pci_conf_read32(sbdf, PCI_VENDOR_ID);
 
 		vendor = id & 0xffff;
 		device = (id>>16) & 0xffff;
@@ -83,12 +84,12 @@ static void __init get_fam10h_pci_mmconf_base(void)
 	 * above 4G
 	 */
 	for (hi_mmio_num = i = 0; i < 8; i++) {
-		val = pci_conf_read32(0, bus, slot, 1, 0x80 + (i << 3));
+		val = pci_conf_read32(sbdf, 0x80 + (i << 3));
 		if (!(val & 3))
 			continue;
 
 		start = (val & 0xffffff00) << 8; /* 39:16 on 31:8*/
-		val = pci_conf_read32(0, bus, slot, 1, 0x84 + (i << 3));
+		val = pci_conf_read32(sbdf, 0x84 + (i << 3));
 		end = ((val & 0xffffff00) << 8) | 0xffff; /* 39:16 on 31:8*/
 
 		if (end < tom2)
diff --git a/xen/arch/x86/x86_64/mmconfig-shared.c b/xen/arch/x86/x86_64/mmconfig-shared.c
index 9e1c81dcd2..284a788fcd 100644
--- a/xen/arch/x86/x86_64/mmconfig-shared.c
+++ b/xen/arch/x86/x86_64/mmconfig-shared.c
@@ -63,10 +63,8 @@ custom_param("mmcfg", parse_mmcfg);
 
 static const char __init *pci_mmcfg_e7520(void)
 {
-    u32 win;
-    win = pci_conf_read16(0, 0, 0, 0, 0xce);
+    uint32_t win = pci_conf_read16(PCI_SBDF_T(0, 0, 0, 0), 0xce) & 0xf000;
 
-    win = win & 0xf000;
     if(win == 0x0000 || win == 0xf000)
         pci_mmcfg_config_num = 0;
     else {
@@ -89,7 +87,7 @@ static const char __init *pci_mmcfg_intel_945(void)
 
     pci_mmcfg_config_num = 1;
 
-    pciexbar = pci_conf_read32(0, 0, 0, 0, 0x48);
+    pciexbar = pci_conf_read32(PCI_SBDF_T(0, 0, 0, 0), 0x48);
 
     /* Enable bit */
     if (!(pciexbar & 1))
@@ -212,15 +210,18 @@ static const char __init *pci_mmcfg_nvidia_mcp55(void)
     for (i = bus = 0; bus < 256; bus++) {
         u32 l, extcfg;
         u16 vendor, device;
+        const pci_sbdf_t sbdf = {
+            .bus = bus,
+        };
 
-        l = pci_conf_read32(0, bus, 0, 0, 0);
+        l = pci_conf_read32(sbdf, 0);
         vendor = l & 0xffff;
         device = (l >> 16) & 0xffff;
 
         if (PCI_VENDOR_ID_NVIDIA != vendor || 0x0369 != device)
             continue;
 
-        extcfg = pci_conf_read32(0, bus, 0, 0, extcfg_regnum);
+        extcfg = pci_conf_read32(sbdf, extcfg_regnum);
 
         if (extcfg & extcfg_enable_mask)
             i++;
@@ -238,15 +239,18 @@ static const char __init *pci_mmcfg_nvidia_mcp55(void)
         u32 l, extcfg;
         u16 vendor, device;
         int size_index;
+        const pci_sbdf_t sbdf = {
+            .bus = bus,
+        };
 
-        l = pci_conf_read32(0, bus, 0, 0, 0);
+        l = pci_conf_read32(sbdf, 0);
         vendor = l & 0xffff;
         device = (l >> 16) & 0xffff;
 
         if (PCI_VENDOR_ID_NVIDIA != vendor || 0x0369 != device)
             continue;
 
-        extcfg = pci_conf_read32(0, bus, 0, 0, extcfg_regnum);
+        extcfg = pci_conf_read32(sbdf, extcfg_regnum);
 
         if (!(extcfg & extcfg_enable_mask))
             continue;
@@ -300,7 +304,6 @@ static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = {
 static int __init pci_mmcfg_check_hostbridge(void)
 {
     u32 l;
-    u32 bus, devfn;
     u16 vendor, device;
     int i;
     const char *name;
@@ -310,9 +313,8 @@ static int __init pci_mmcfg_check_hostbridge(void)
     name = NULL;
 
     for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
-        bus =  pci_mmcfg_probes[i].bus;
-        devfn = pci_mmcfg_probes[i].devfn;
-        l = pci_conf_read32(0, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), 0);
+        l = pci_conf_read32(PCI_SBDF3_T(0, pci_mmcfg_probes[i].bus,
+                                        pci_mmcfg_probes[i].devfn), 0);
         vendor = l & 0xffff;
         device = (l >> 16) & 0xffff;
 
diff --git a/xen/arch/x86/x86_64/pci.c b/xen/arch/x86/x86_64/pci.c
index 4f77beb119..342c2aa8e6 100644
--- a/xen/arch/x86/x86_64/pci.c
+++ b/xen/arch/x86/x86_64/pci.c
@@ -8,25 +8,20 @@
 #include <xen/pci.h>
 #include <asm/io.h>
 
-#define PCI_CONF_ADDRESS(bus, dev, func, reg) \
-    (0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3))
+#define PCI_CONF_ADDRESS(bdf, reg) (0x80000000 | (bdf << 8) | (reg & ~3))
 
 #define GEN_PCI_CONF_READ(s)                                                   \
-    uint ## s ## _t pci_conf_read ## s (unsigned int seg, unsigned int bus,    \
-                                        unsigned int dev, unsigned int func,   \
-                                        unsigned int reg)                      \
+    uint ## s ## _t pci_conf_read ## s (pci_sbdf_t sbdf, unsigned  int reg)    \
     {                                                                          \
         uint32_t value;                                                        \
                                                                                \
         BUILD_BUG_ON(s != 8 && s != 16 && s != 32);                            \
-        if ( seg || reg > 255 )                                                \
-            pci_mmcfg_read(seg, bus, PCI_DEVFN(dev, func), reg, s / 8, &value);\
+        if ( sbdf.seg || reg > 255 )                                           \
+            pci_mmcfg_read(sbdf.seg, sbdf.bus, sbdf.extfunc, reg, s / 8,       \
+                           &value);                                            \
         else                                                                   \
-        {                                                                      \
-            BUG_ON((bus > 255) || (dev > 31) || (func > 7));                   \
-            value = pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg),       \
+            value = pci_conf_read(PCI_CONF_ADDRESS(sbdf.bdf, reg),             \
                                   reg & (4 - s / 8), s / 8);                   \
-        }                                                                      \
                                                                                \
         return value;                                                          \
     }
@@ -47,19 +42,16 @@ GEN_PCI_CONF_READ(32)
 #undef GEN_PCI_CONF_READ
 
 #define GEN_PCI_CONF_WRITE(s)                                                  \
-    void pci_conf_write ## s (unsigned int seg, unsigned int bus,              \
-                              unsigned int dev, unsigned int func,             \
-                              unsigned int reg, uint ## s ## _t data)          \
+    void pci_conf_write ## s (pci_sbdf_t sbdf, unsigned int reg,               \
+                              uint ## s ## _t data)                            \
     {                                                                          \
         BUILD_BUG_ON(s != 8 && s != 16 && s != 32);                            \
-        if ( seg || reg > 255 )                                                \
-            pci_mmcfg_write(seg, bus, PCI_DEVFN(dev, func), reg, s / 8, data); \
+        if ( sbdf.seg || reg > 255 )                                           \
+            pci_mmcfg_write(sbdf.seg, sbdf.bus, sbdf.extfunc, reg, s / 8,      \
+                            data);                                             \
         else                                                                   \
-        {                                                                      \
-            BUG_ON((bus > 255) || (dev > 31) || (func > 7));                   \
-            pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg),              \
+            pci_conf_write(PCI_CONF_ADDRESS(sbdf.bdf, reg),                    \
                            reg & (4 - s / 8), s / 8, data);                    \
-        }                                                                      \
     }
 
 /* Grep fodder */
diff --git a/xen/drivers/acpi/reboot.c b/xen/drivers/acpi/reboot.c
index 72d06fd8e5..919239faa1 100644
--- a/xen/drivers/acpi/reboot.c
+++ b/xen/drivers/acpi/reboot.c
@@ -23,11 +23,9 @@ void acpi_reboot(void)
 	case ACPI_ADR_SPACE_PCI_CONFIG:
 		printk("Resetting with ACPI PCI RESET_REG.\n");
 		/* Write the value that resets us. */
-		pci_conf_write8(0, 0,
-				(rr->address >> 32) & 31,
-				(rr->address >> 16) & 7,
-				(rr->address & 255),
-				reset_value);
+		pci_conf_write8(PCI_SBDF_T(0, 0, (rr->address >> 32) & 31,
+					   (rr->address >> 16) & 7),
+				(rr->address & 255), reset_value);
 		break;
 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 	case ACPI_ADR_SPACE_SYSTEM_IO:
diff --git a/xen/drivers/char/ehci-dbgp.c b/xen/drivers/char/ehci-dbgp.c
index 475dc41767..4cd4157353 100644
--- a/xen/drivers/char/ehci-dbgp.c
+++ b/xen/drivers/char/ehci-dbgp.c
@@ -682,7 +682,8 @@ static int dbgp_control_msg(struct ehci_dbgp *dbgp, unsigned int devnum,
 
 static unsigned int __init __find_dbgp(u8 bus, u8 slot, u8 func)
 {
-    u32 class = pci_conf_read32(0, bus, slot, func, PCI_CLASS_REVISION);
+    uint32_t class = pci_conf_read32(PCI_SBDF_T(0, bus, slot, func),
+                                     PCI_CLASS_REVISION);
 
     if ( (class >> 8) != PCI_CLASS_SERIAL_USB_EHCI )
         return 0;
@@ -713,8 +714,9 @@ static unsigned int __init find_dbgp(struct ehci_dbgp *dbgp,
                 cap = __find_dbgp(bus, slot, func);
                 if ( !cap || ehci_num-- )
                 {
-                    if ( !func && !(pci_conf_read8(0, bus, slot, func,
-                                                   PCI_HEADER_TYPE) & 0x80) )
+                    if ( !func &&
+                         !(pci_conf_read8(PCI_SBDF_T(0, bus, slot, func),
+                                          PCI_HEADER_TYPE) & 0x80) )
                         break;
                     continue;
                 }
@@ -1006,17 +1008,22 @@ static set_debug_port_t __read_mostly set_debug_port = default_set_debug_port;
 
 static void nvidia_set_debug_port(struct ehci_dbgp *dbgp, unsigned int port)
 {
-    u32 dword = pci_conf_read32(0, dbgp->bus, dbgp->slot, dbgp->func, 0x74);
+    const pci_sbdf_t sbdf = {
+        .bus = dbgp->bus,
+        .dev = dbgp->slot,
+        .func = dbgp->func,
+    };
+    uint32_t dword = pci_conf_read32(sbdf, 0x74);
 
     dword &= ~(0x0f << 12);
     dword |= (port & 0x0f) << 12;
-    pci_conf_write32(0, dbgp->bus, dbgp->slot, dbgp->func, 0x74, dword);
+    pci_conf_write32(sbdf, 0x74, dword);
     dbgp_printk("set debug port to %u\n", port);
 }
 
 static void __init detect_set_debug_port(struct ehci_dbgp *dbgp)
 {
-    if ( pci_conf_read16(0, dbgp->bus, dbgp->slot, dbgp->func,
+    if ( pci_conf_read16(PCI_SBDF_T(0, dbgp->bus, dbgp->slot, dbgp->func),
                          PCI_VENDOR_ID) == 0x10de )
     {
         dbgp_printk("using nvidia set_debug_port\n");
@@ -1035,17 +1042,22 @@ static void ehci_dbgp_bios_handoff(struct ehci_dbgp *dbgp, u32 hcc_params)
     u32 cap;
     unsigned int offset = HCC_EXT_CAPS(hcc_params);
     int msec;
+    const pci_sbdf_t sbdf = {
+        .bus = dbgp->bus,
+        .dev = dbgp->slot,
+        .func = dbgp->func,
+    };
 
     if ( !offset )
         return;
 
-    cap = pci_conf_read32(0, dbgp->bus, dbgp->slot, dbgp->func, offset);
+    cap = pci_conf_read32(sbdf, offset);
     dbgp_printk("dbgp: EHCI BIOS state %08x\n", cap);
 
     if ( (cap & 0xff) == 1 && (cap & EHCI_USBLEGSUP_BIOS) )
     {
         dbgp_printk("dbgp: BIOS handoff\n");
-        pci_conf_write8(0, dbgp->bus, dbgp->slot, dbgp->func, offset + 3, 1);
+        pci_conf_write8(sbdf, offset + 3, 1);
     }
 
     /* if boot firmware now owns EHCI, spin till it hands it over. */
@@ -1054,7 +1066,7 @@ static void ehci_dbgp_bios_handoff(struct ehci_dbgp *dbgp, u32 hcc_params)
     {
         mdelay(10);
         msec -= 10;
-        cap = pci_conf_read32(0, dbgp->bus, dbgp->slot, dbgp->func, offset);
+        cap = pci_conf_read32(sbdf, offset);
     }
 
     if ( cap & EHCI_USBLEGSUP_BIOS )
@@ -1062,12 +1074,11 @@ static void ehci_dbgp_bios_handoff(struct ehci_dbgp *dbgp, u32 hcc_params)
         /* well, possibly buggy BIOS... try to shut it down,
          * and hope nothing goes too wrong */
         dbgp_printk("dbgp: BIOS handoff failed: %08x\n", cap);
-        pci_conf_write8(0, dbgp->bus, dbgp->slot, dbgp->func, offset + 2, 0);
+        pci_conf_write8(sbdf, offset + 2, 0);
     }
 
     /* just in case, always disable EHCI SMIs */
-    pci_conf_write8(0, dbgp->bus, dbgp->slot, dbgp->func,
-                    offset + EHCI_USBLEGCTLSTS, 0);
+    pci_conf_write8(sbdf, offset + EHCI_USBLEGCTLSTS, 0);
 }
 
 static int ehci_dbgp_setup(struct ehci_dbgp *dbgp)
@@ -1306,19 +1317,21 @@ static void __init ehci_dbgp_init_preirq(struct serial_port *port)
     struct ehci_dbgp *dbgp = port->uart;
     u32 debug_port, offset;
     void __iomem *ehci_bar;
+    const pci_sbdf_t sbdf = {
+        .bus  = dbgp->bus,
+        .dev = dbgp->slot,
+        .func = dbgp->func,
+    };
 
-    debug_port = pci_conf_read32(0, dbgp->bus, dbgp->slot, dbgp->func,
-                                 dbgp->cap);
+    debug_port = pci_conf_read32(sbdf, dbgp->cap);
     offset = (debug_port >> 16) & 0xfff;
 
     /* double check if the mem space is enabled */
-    dbgp->pci_cr = pci_conf_read8(0, dbgp->bus, dbgp->slot, dbgp->func,
-                                  PCI_COMMAND);
+    dbgp->pci_cr = pci_conf_read8(sbdf, PCI_COMMAND);
     if ( !(dbgp->pci_cr & PCI_COMMAND_MEMORY) )
     {
         dbgp->pci_cr |= PCI_COMMAND_MEMORY;
-        pci_conf_write16(0, dbgp->bus, dbgp->slot, dbgp->func, PCI_COMMAND,
-                         dbgp->pci_cr);
+        pci_conf_write16(sbdf, PCI_COMMAND, dbgp->pci_cr);
         dbgp_printk("MMIO for EHCI enabled\n");
     }
 
@@ -1415,8 +1428,8 @@ static void ehci_dbgp_suspend(struct serial_port *port)
     stop_timer(&dbgp->timer);
     dbgp->timer.expires = 0;
 
-    dbgp->pci_cr = pci_conf_read16(0, dbgp->bus, dbgp->slot, dbgp->func,
-                                   PCI_COMMAND);
+    dbgp->pci_cr = pci_conf_read16(PCI_SBDF_T(0, dbgp->bus, dbgp->slot,
+                                              dbgp->func), PCI_COMMAND);
 
     dbgp->state = dbgp_unsafe;
 }
@@ -1424,14 +1437,17 @@ static void ehci_dbgp_suspend(struct serial_port *port)
 static void ehci_dbgp_resume(struct serial_port *port)
 {
     struct ehci_dbgp *dbgp = port->uart;
+    const pci_sbdf_t sbdf = {
+        .bus = dbgp->bus,
+        .dev = dbgp->slot,
+        .func = dbgp->func,
+    };
 
     if ( !dbgp->ehci_debug )
         return;
 
-    pci_conf_write32(0, dbgp->bus, dbgp->slot, dbgp->func, dbgp->bar,
-                     dbgp->bar_val);
-    pci_conf_write16(0, dbgp->bus, dbgp->slot, dbgp->func,
-                     PCI_COMMAND, dbgp->pci_cr);
+    pci_conf_write32(sbdf, dbgp->bar, dbgp->bar_val);
+    pci_conf_write16(sbdf, PCI_COMMAND, dbgp->pci_cr);
 
     ehci_dbgp_setup_preirq(dbgp);
     ehci_dbgp_setup_postirq(dbgp);
@@ -1459,6 +1475,11 @@ void __init ehci_dbgp_init(void)
     struct ehci_dbgp *dbgp = &ehci_dbgp;
     u32 debug_port, offset, bar_val;
     const char *e;
+    const pci_sbdf_t sbdf = {
+        .bus = dbgp->bus,
+        .dev = dbgp->slot,
+        .func = dbgp->func,
+    };
 
     if ( strncmp(opt_dbgp, "ehci", 4) )
         return;
@@ -1502,8 +1523,7 @@ void __init ehci_dbgp_init(void)
     else
         return;
 
-    debug_port = pci_conf_read32(0, dbgp->bus, dbgp->slot, dbgp->func,
-                                 dbgp->cap);
+    debug_port = pci_conf_read32(sbdf, dbgp->cap);
     dbgp->bar = (debug_port >> 29) & 0x7;
     dbgp->bar = ((dbgp->bar - 1) * 4) + PCI_BASE_ADDRESS_0;
     offset = (debug_port >> 16) & 0xfff;
@@ -1514,8 +1534,7 @@ void __init ehci_dbgp_init(void)
         return;
     }
 
-    dbgp->bar_val = bar_val = pci_conf_read32(0, dbgp->bus, dbgp->slot,
-                                              dbgp->func, dbgp->bar);
+    dbgp->bar_val = bar_val = pci_conf_read32(sbdf, dbgp->bar);
     dbgp_printk("bar_val: %08x\n", bar_val);
     if ( bar_val & ~PCI_BASE_ADDRESS_MEM_MASK )
     {
diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index 189e121b7e..698984d879 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -620,20 +620,23 @@ static int ns16550_getc(struct serial_port *port, char *pc)
 static void pci_serial_early_init(struct ns16550 *uart)
 {
 #ifdef CONFIG_HAS_PCI
+    const pci_sbdf_t sbdf = {
+        .bus = uart->pb_bdf[0],
+        .dev = uart->pb_bdf[1],
+        .func = uart->pb_bdf[2],
+    };
+
     if ( !uart->ps_bdf_enable || uart->io_base >= 0x10000 )
         return;
 
     if ( uart->pb_bdf_enable )
-        pci_conf_write16(0, uart->pb_bdf[0], uart->pb_bdf[1], uart->pb_bdf[2],
-                         PCI_IO_BASE,
+        pci_conf_write16(sbdf, PCI_IO_BASE,
                          (uart->io_base & 0xF000) |
                          ((uart->io_base & 0xF000) >> 8));
 
-    pci_conf_write32(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
-                     PCI_BASE_ADDRESS_0,
+    pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0,
                      uart->io_base | PCI_BASE_ADDRESS_SPACE_IO);
-    pci_conf_write16(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
-                     PCI_COMMAND, PCI_COMMAND_IO);
+    pci_conf_write16(sbdf, PCI_COMMAND, PCI_COMMAND_IO);
 #endif
 }
 
@@ -846,8 +849,9 @@ static void ns16550_suspend(struct serial_port *port)
 
 #ifdef CONFIG_HAS_PCI
     if ( uart->bar )
-       uart->cr = pci_conf_read16(0, uart->ps_bdf[0], uart->ps_bdf[1],
-                                  uart->ps_bdf[2], PCI_COMMAND);
+        uart->cr = pci_conf_read16(PCI_SBDF_T(0, uart->ps_bdf[0],
+                                              uart->ps_bdf[1], uart->ps_bdf[2]),
+                                   PCI_COMMAND);
 #endif
 }
 
@@ -855,20 +859,22 @@ static void _ns16550_resume(struct serial_port *port)
 {
 #ifdef CONFIG_HAS_PCI
     struct ns16550 *uart = port->uart;
+    const pci_sbdf_t sbdf = {
+        .bus = uart->ps_bdf[0],
+        .dev = uart->ps_bdf[1],
+        .func = uart->ps_bdf[2],
+    };
 
     if ( uart->bar )
     {
-       pci_conf_write32(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
-                        PCI_BASE_ADDRESS_0 + uart->bar_idx*4, uart->bar);
+       pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + uart->bar_idx*4, uart->bar);
 
         /* If 64 bit BAR, write higher 32 bits to BAR+4 */
         if ( uart->bar & PCI_BASE_ADDRESS_MEM_TYPE_64 )
-            pci_conf_write32(0, uart->ps_bdf[0],
-                        uart->ps_bdf[1], uart->ps_bdf[2],
-                        PCI_BASE_ADDRESS_0 + (uart->bar_idx+1)*4, uart->bar64);
+            pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + (uart->bar_idx+1)*4,
+                             uart->bar64);
 
-       pci_conf_write16(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
-                        PCI_COMMAND, uart->cr);
+       pci_conf_write16(sbdf, PCI_COMMAND, uart->cr);
     }
 #endif
 
@@ -1063,11 +1069,16 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
                 uint32_t bar, bar_64 = 0, len, len_64;
                 u64 size = 0;
                 const struct ns16550_config_param *param = uart_param;
+                const pci_sbdf_t sbdf = {
+                    .bus = b,
+                    .dev = d,
+                    .func = f,
+                };
 
-                nextf = (f || (pci_conf_read16(0, b, d, f, PCI_HEADER_TYPE) &
+                nextf = (f || (pci_conf_read16(sbdf, PCI_HEADER_TYPE) &
                                0x80)) ? f + 1 : 8;
 
-                switch ( pci_conf_read16(0, b, d, f, PCI_CLASS_DEVICE) )
+                switch ( pci_conf_read16(sbdf, PCI_CLASS_DEVICE) )
                 {
                 case 0x0700: /* single port serial */
                 case 0x0702: /* multi port serial */
@@ -1084,8 +1095,8 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
                 /* Check for params in uart_config lookup table */
                 for ( i = 0; i < ARRAY_SIZE(uart_config); i++ )
                 {
-                    u16 vendor = pci_conf_read16(0, b, d, f, PCI_VENDOR_ID);
-                    u16 device = pci_conf_read16(0, b, d, f, PCI_DEVICE_ID);
+                    uint16_t vendor = pci_conf_read16(sbdf, PCI_VENDOR_ID);
+                    uint16_t device = pci_conf_read16(sbdf, PCI_DEVICE_ID);
 
                     if ( uart_config[i].vendor_id == vendor &&
                          uart_config[i].dev_id == device )
@@ -1108,28 +1119,25 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
                 }
 
                 uart->io_base = 0;
-                bar = pci_conf_read32(0, b, d, f,
-                                      PCI_BASE_ADDRESS_0 + bar_idx*4);
+                bar = pci_conf_read32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4);
 
                 /* MMIO based */
                 if ( param->mmio && !(bar & PCI_BASE_ADDRESS_SPACE_IO) )
                 {
-                    pci_conf_write32(0, b, d, f,
-                                     PCI_BASE_ADDRESS_0 + bar_idx*4, ~0u);
-                    len = pci_conf_read32(0, b, d, f, PCI_BASE_ADDRESS_0 + bar_idx*4);
-                    pci_conf_write32(0, b, d, f,
-                                     PCI_BASE_ADDRESS_0 + bar_idx*4, bar);
+                    pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4, ~0u);
+                    len = pci_conf_read32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4);
+                    pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4, bar);
 
                     /* Handle 64 bit BAR if found */
                     if ( bar & PCI_BASE_ADDRESS_MEM_TYPE_64 )
                     {
-                        bar_64 = pci_conf_read32(0, b, d, f,
+                        bar_64 = pci_conf_read32(sbdf,
                                       PCI_BASE_ADDRESS_0 + (bar_idx+1)*4);
-                        pci_conf_write32(0, b, d, f,
+                        pci_conf_write32(sbdf,
                                     PCI_BASE_ADDRESS_0 + (bar_idx+1)*4, ~0u);
-                        len_64 = pci_conf_read32(0, b, d, f,
+                        len_64 = pci_conf_read32(sbdf,
                                     PCI_BASE_ADDRESS_0 + (bar_idx+1)*4);
-                        pci_conf_write32(0, b, d, f,
+                        pci_conf_write32(sbdf,
                                     PCI_BASE_ADDRESS_0 + (bar_idx+1)*4, bar_64);
                         size  = ((u64)~0 << 32) | PCI_BASE_ADDRESS_MEM_MASK;
                         size &= ((u64)len_64 << 32) | len;
@@ -1143,11 +1151,9 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
                 /* IO based */
                 else if ( !param->mmio && (bar & PCI_BASE_ADDRESS_SPACE_IO) )
                 {
-                    pci_conf_write32(0, b, d, f,
-                                     PCI_BASE_ADDRESS_0 + bar_idx*4, ~0u);
-                    len = pci_conf_read32(0, b, d, f, PCI_BASE_ADDRESS_0);
-                    pci_conf_write32(0, b, d, f,
-                                     PCI_BASE_ADDRESS_0 + bar_idx*4, bar);
+                    pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4, ~0u);
+                    len = pci_conf_read32(sbdf, PCI_BASE_ADDRESS_0);
+                    pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4, bar);
                     size = len & PCI_BASE_ADDRESS_IO_MASK;
 
                     uart->io_base = bar & ~PCI_BASE_ADDRESS_SPACE_IO;
@@ -1188,8 +1194,8 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
                 uart->bar64 = bar_64;
                 uart->io_size = max(8U << param->reg_shift,
                                     param->uart_offset);
-                uart->irq = pci_conf_read8(0, b, d, f, PCI_INTERRUPT_PIN) ?
-                    pci_conf_read8(0, b, d, f, PCI_INTERRUPT_LINE) : 0;
+                uart->irq = pci_conf_read8(sbdf, PCI_INTERRUPT_PIN) ?
+                    pci_conf_read8(sbdf, PCI_INTERRUPT_LINE) : 0;
 
                 return 0;
             }
diff --git a/xen/drivers/passthrough/amd/iommu_detect.c b/xen/drivers/passthrough/amd/iommu_detect.c
index 3c5d4de1a3..e8d8ec59bd 100644
--- a/xen/drivers/passthrough/amd/iommu_detect.c
+++ b/xen/drivers/passthrough/amd/iommu_detect.c
@@ -48,7 +48,8 @@ static int __init get_iommu_capabilities(
 {
     u8 type;
 
-    iommu->cap.header = pci_conf_read32(seg, bus, dev, func, cap_ptr);
+    iommu->cap.header = pci_conf_read32(PCI_SBDF_T(seg, bus, dev, func),
+                                        cap_ptr);
     type = get_field_from_reg_u32(iommu->cap.header, PCI_CAP_TYPE_MASK,
                                   PCI_CAP_TYPE_SHIFT);
 
diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c
index 17f39552a9..fe0516f788 100644
--- a/xen/drivers/passthrough/amd/iommu_init.c
+++ b/xen/drivers/passthrough/amd/iommu_init.c
@@ -798,8 +798,7 @@ static bool_t __init set_iommu_interrupt_handler(struct amd_iommu *iommu)
                         PCI_SLOT(iommu->bdf), PCI_FUNC(iommu->bdf));
         return 0;
     }
-    control = pci_conf_read16(iommu->seg, PCI_BUS(iommu->bdf),
-                              PCI_SLOT(iommu->bdf), PCI_FUNC(iommu->bdf),
+    control = pci_conf_read16(iommu->msi.dev->sbdf,
                               iommu->msi.msi_attrib.pos + PCI_MSI_FLAGS);
     iommu->msi.msi.nvec = 1;
     if ( is_mask_bit_support(control) )
@@ -835,6 +834,10 @@ static bool_t __init set_iommu_interrupt_handler(struct amd_iommu *iommu)
 static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
 {
     u32 value;
+    const pci_sbdf_t sbdf = {
+        .seg = iommu->seg,
+        .bdf = iommu->bdf,
+    };
     u8 bus = PCI_BUS(iommu->bdf);
     u8 dev = PCI_SLOT(iommu->bdf);
     u8 func = PCI_FUNC(iommu->bdf);
@@ -844,22 +847,22 @@ static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
          (boot_cpu_data.x86_model > 0x1f) )
         return;
 
-    pci_conf_write32(iommu->seg, bus, dev, func, 0xf0, 0x90);
-    value = pci_conf_read32(iommu->seg, bus, dev, func, 0xf4);
+    pci_conf_write32(sbdf, 0xf0, 0x90);
+    value = pci_conf_read32(sbdf, 0xf4);
 
     if ( value & (1 << 2) )
         return;
 
     /* Select NB indirect register 0x90 and enable writing */
-    pci_conf_write32(iommu->seg, bus, dev, func, 0xf0, 0x90 | (1 << 8));
+    pci_conf_write32(sbdf, 0xf0, 0x90 | (1 << 8));
 
-    pci_conf_write32(iommu->seg, bus, dev, func, 0xf4, value | (1 << 2));
+    pci_conf_write32(sbdf, 0xf4, value | (1 << 2));
     printk(XENLOG_INFO
            "AMD-Vi: Applying erratum 746 workaround for IOMMU at %04x:%02x:%02x.%u\n",
            iommu->seg, bus, dev, func);
 
     /* Clear the enable writing bit */
-    pci_conf_write32(iommu->seg, bus, dev, func, 0xf0, 0x90);
+    pci_conf_write32(sbdf, 0xf0, 0x90);
 }
 
 static void enable_iommu(struct amd_iommu *iommu)
@@ -1203,7 +1206,12 @@ static bool_t __init amd_sp5100_erratum28(void)
 
     for (bus = 0; bus < 256; bus++)
     {
-        id = pci_conf_read32(0, bus, 0x14, 0, PCI_VENDOR_ID);
+        const pci_sbdf_t sbdf = {
+            .bus = bus,
+            .dev = 0x14,
+        };
+
+        id = pci_conf_read32(sbdf, PCI_VENDOR_ID);
 
         vendor_id = id & 0xffff;
         dev_id = (id >> 16) & 0xffff;
@@ -1212,7 +1220,7 @@ static bool_t __init amd_sp5100_erratum28(void)
         if (vendor_id != 0x1002 || dev_id != 0x4385)
             continue;
 
-        byte = pci_conf_read8(0, bus, 0x14, 0, 0xad);
+        byte = pci_conf_read8(sbdf, 0xad);
         if ( (byte >> 3) & 1 )
         {
             printk(XENLOG_WARNING "AMD-Vi: SP5100 erratum 28 detected, disabling IOMMU.\n"
diff --git a/xen/drivers/passthrough/ats.h b/xen/drivers/passthrough/ats.h
index bee13911c0..e83a45d16e 100644
--- a/xen/drivers/passthrough/ats.h
+++ b/xen/drivers/passthrough/ats.h
@@ -35,8 +35,8 @@ static inline int pci_ats_enabled(int seg, int bus, int devfn)
     pos = pci_find_ext_capability(seg, bus, devfn, PCI_EXT_CAP_ID_ATS);
     BUG_ON(!pos);
 
-    value = pci_conf_read16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                            pos + ATS_REG_CTL);
+    value = pci_conf_read16(PCI_SBDF3_T(seg, bus, devfn), pos + ATS_REG_CTL);
+
     return value & ATS_ENABLE;
 }
 
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index 8de8d8e110..94fb3a183d 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -246,36 +246,34 @@ static void check_pdev(const struct pci_dev *pdev)
 
     if ( command_mask )
     {
-        val = pci_conf_read16(seg, bus, dev, func, PCI_COMMAND);
+        val = pci_conf_read16(pdev->sbdf, PCI_COMMAND);
         if ( val & command_mask )
-            pci_conf_write16(seg, bus, dev, func, PCI_COMMAND,
-                             val & ~command_mask);
-        val = pci_conf_read16(seg, bus, dev, func, PCI_STATUS);
+            pci_conf_write16(pdev->sbdf, PCI_COMMAND, val & ~command_mask);
+        val = pci_conf_read16(pdev->sbdf, PCI_STATUS);
         if ( val & PCI_STATUS_CHECK )
         {
             printk(XENLOG_INFO "%04x:%02x:%02x.%u status %04x -> %04x\n",
                    seg, bus, dev, func, val, val & ~PCI_STATUS_CHECK);
-            pci_conf_write16(seg, bus, dev, func, PCI_STATUS,
-                             val & PCI_STATUS_CHECK);
+            pci_conf_write16(pdev->sbdf, PCI_STATUS, val & PCI_STATUS_CHECK);
         }
     }
 
-    switch ( pci_conf_read8(seg, bus, dev, func, PCI_HEADER_TYPE) & 0x7f )
+    switch ( pci_conf_read8(pdev->sbdf, PCI_HEADER_TYPE) & 0x7f )
     {
     case PCI_HEADER_TYPE_BRIDGE:
         if ( !bridge_ctl_mask )
             break;
-        val = pci_conf_read16(seg, bus, dev, func, PCI_BRIDGE_CONTROL);
+        val = pci_conf_read16(pdev->sbdf, PCI_BRIDGE_CONTROL);
         if ( val & bridge_ctl_mask )
-            pci_conf_write16(seg, bus, dev, func, PCI_BRIDGE_CONTROL,
+            pci_conf_write16(pdev->sbdf, PCI_BRIDGE_CONTROL,
                              val & ~bridge_ctl_mask);
-        val = pci_conf_read16(seg, bus, dev, func, PCI_SEC_STATUS);
+        val = pci_conf_read16(pdev->sbdf, PCI_SEC_STATUS);
         if ( val & PCI_STATUS_CHECK )
         {
             printk(XENLOG_INFO
                    "%04x:%02x:%02x.%u secondary status %04x -> %04x\n",
                    seg, bus, dev, func, val, val & ~PCI_STATUS_CHECK);
-            pci_conf_write16(seg, bus, dev, func, PCI_SEC_STATUS,
+            pci_conf_write16(pdev->sbdf, PCI_SEC_STATUS,
                              val & PCI_STATUS_CHECK);
         }
         break;
@@ -289,12 +287,8 @@ static void check_pdev(const struct pci_dev *pdev)
 
 static void apply_quirks(struct pci_dev *pdev)
 {
-    uint16_t vendor = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
-                                      pdev->sbdf.dev, pdev->sbdf.func,
-                                      PCI_VENDOR_ID);
-    uint16_t device = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
-                                      pdev->sbdf.dev, pdev->sbdf.func,
-                                      PCI_DEVICE_ID);
+    uint16_t vendor = pci_conf_read16(pdev->sbdf, PCI_VENDOR_ID);
+    uint16_t device = pci_conf_read16(pdev->sbdf, PCI_DEVICE_ID);
     static const struct {
         uint16_t vendor, device;
     } ignore_bars[] = {
@@ -368,10 +362,8 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
 
         case DEV_TYPE_PCIe2PCI_BRIDGE:
         case DEV_TYPE_LEGACY_PCI_BRIDGE:
-            sec_bus = pci_conf_read8(pseg->nr, bus, PCI_SLOT(devfn),
-                                     PCI_FUNC(devfn), PCI_SECONDARY_BUS);
-            sub_bus = pci_conf_read8(pseg->nr, bus, PCI_SLOT(devfn),
-                                     PCI_FUNC(devfn), PCI_SUBORDINATE_BUS);
+            sec_bus = pci_conf_read8(pdev->sbdf, PCI_SECONDARY_BUS);
+            sub_bus = pci_conf_read8(pdev->sbdf, PCI_SUBORDINATE_BUS);
 
             spin_lock(&pseg->bus2bridge_lock);
             for ( ; sec_bus <= sub_bus; sec_bus++ )
@@ -387,8 +379,7 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
             pos = pci_find_cap_offset(pseg->nr, bus, PCI_SLOT(devfn),
                                       PCI_FUNC(devfn), PCI_CAP_ID_EXP);
             BUG_ON(!pos);
-            cap = pci_conf_read16(pseg->nr, bus, PCI_SLOT(devfn),
-                                  PCI_FUNC(devfn), pos + PCI_EXP_DEVCAP);
+            cap = pci_conf_read16(pdev->sbdf, pos + PCI_EXP_DEVCAP);
             if ( cap & PCI_EXP_DEVCAP_PHANTOM )
             {
                 pdev->phantom_stride = 8 >> MASK_EXTR(cap,
@@ -438,10 +429,8 @@ static void free_pdev(struct pci_seg *pseg, struct pci_dev *pdev)
 
         case DEV_TYPE_PCIe2PCI_BRIDGE:
         case DEV_TYPE_LEGACY_PCI_BRIDGE:
-            sec_bus = pci_conf_read8(pseg->nr, pdev->sbdf.bus, pdev->sbdf.dev,
-                                     pdev->sbdf.func, PCI_SECONDARY_BUS);
-            sub_bus = pci_conf_read8(pseg->nr, pdev->sbdf.bus, pdev->sbdf.dev,
-                                     pdev->sbdf.func, PCI_SUBORDINATE_BUS);
+            sec_bus = pci_conf_read8(pdev->sbdf, PCI_SECONDARY_BUS);
+            sub_bus = pci_conf_read8(pdev->sbdf, PCI_SUBORDINATE_BUS);
 
             spin_lock(&pseg->bus2bridge_lock);
             for ( ; sec_bus <= sub_bus; sec_bus++ )
@@ -603,8 +592,6 @@ static void pci_enable_acs(struct pci_dev *pdev)
     int pos;
     uint16_t cap, ctrl, seg = pdev->sbdf.seg;
     uint8_t bus = pdev->sbdf.bus;
-    uint8_t dev = pdev->sbdf.dev;
-    uint8_t func = pdev->sbdf.func;
 
     if ( !iommu_enabled )
         return;
@@ -613,8 +600,8 @@ static void pci_enable_acs(struct pci_dev *pdev)
     if (!pos)
         return;
 
-    cap = pci_conf_read16(seg, bus, dev, func, pos + PCI_ACS_CAP);
-    ctrl = pci_conf_read16(seg, bus, dev, func, pos + PCI_ACS_CTRL);
+    cap = pci_conf_read16(pdev->sbdf, pos + PCI_ACS_CAP);
+    ctrl = pci_conf_read16(pdev->sbdf, pos + PCI_ACS_CTRL);
 
     /* Source Validation */
     ctrl |= (cap & PCI_ACS_SV);
@@ -628,7 +615,7 @@ static void pci_enable_acs(struct pci_dev *pdev)
     /* Upstream Forwarding */
     ctrl |= (cap & PCI_ACS_UF);
 
-    pci_conf_write16(seg, bus, dev, func, pos + PCI_ACS_CTRL, ctrl);
+    pci_conf_write16(pdev->sbdf, pos + PCI_ACS_CTRL, ctrl);
 }
 
 static int iommu_add_device(struct pci_dev *pdev);
@@ -639,8 +626,7 @@ unsigned int pci_size_mem_bar(pci_sbdf_t sbdf, unsigned int pos,
                               uint64_t *paddr, uint64_t *psize,
                               unsigned int flags)
 {
-    uint32_t hi = 0, bar = pci_conf_read32(sbdf.seg, sbdf.bus, sbdf.dev,
-                                           sbdf.func, pos);
+    uint32_t hi = 0, bar = pci_conf_read32(sbdf, pos);
     uint64_t size;
     bool is64bits = !(flags & PCI_BAR_ROM) &&
         (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64;
@@ -650,7 +636,7 @@ unsigned int pci_size_mem_bar(pci_sbdf_t sbdf, unsigned int pos,
     ASSERT(!((flags & PCI_BAR_VF) && (flags & PCI_BAR_ROM)));
     ASSERT((flags & PCI_BAR_ROM) ||
            (bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY);
-    pci_conf_write32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos, ~0);
+    pci_conf_write32(sbdf, pos, ~0);
     if ( is64bits )
     {
         if ( flags & PCI_BAR_LAST )
@@ -662,20 +648,18 @@ unsigned int pci_size_mem_bar(pci_sbdf_t sbdf, unsigned int pos,
             *psize = 0;
             return 1;
         }
-        hi = pci_conf_read32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos + 4);
-        pci_conf_write32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos + 4, ~0);
+        hi = pci_conf_read32(sbdf, pos + 4);
+        pci_conf_write32(sbdf, pos + 4, ~0);
     }
-    size = pci_conf_read32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func,
-                           pos) & mask;
+    size = pci_conf_read32(sbdf, pos) & mask;
     if ( is64bits )
     {
-        size |= (uint64_t)pci_conf_read32(sbdf.seg, sbdf.bus, sbdf.dev,
-                                          sbdf.func, pos + 4) << 32;
-        pci_conf_write32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos + 4, hi);
+        size |= (uint64_t)pci_conf_read32(sbdf, pos + 4) << 32;
+        pci_conf_write32(sbdf, pos + 4, hi);
     }
     else if ( size )
         size |= (uint64_t)~0 << 32;
-    pci_conf_write32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos, bar);
+    pci_conf_write32(sbdf, pos, bar);
     size = -size;
 
     if ( paddr )
@@ -745,7 +729,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
     {
         unsigned int pos = pci_find_ext_capability(seg, bus, devfn,
                                                    PCI_EXT_CAP_ID_SRIOV);
-        u16 ctrl = pci_conf_read16(seg, bus, slot, func, pos + PCI_SRIOV_CTRL);
+        u16 ctrl = pci_conf_read16(pdev->sbdf, pos + PCI_SRIOV_CTRL);
 
         if ( !pos )
             /* Nothing */;
@@ -757,10 +741,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
             for ( i = 0; i < PCI_SRIOV_NUM_BARS; )
             {
                 unsigned int idx = pos + PCI_SRIOV_BAR + i * 4;
-                u32 bar = pci_conf_read32(seg, bus, slot, func, idx);
-                pci_sbdf_t sbdf = {
-                    .sbdf = PCI_SBDF3(seg, bus, devfn),
-                };
+                uint32_t bar = pci_conf_read32(pdev->sbdf, idx);
 
                 if ( (bar & PCI_BASE_ADDRESS_SPACE) ==
                      PCI_BASE_ADDRESS_SPACE_IO )
@@ -771,7 +752,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
                            seg, bus, slot, func, i);
                     continue;
                 }
-                ret = pci_size_mem_bar(sbdf, idx, NULL, &pdev->vf_rlen[i],
+                ret = pci_size_mem_bar(pdev->sbdf, idx, NULL, &pdev->vf_rlen[i],
                                        PCI_BAR_VF |
                                        ((i == PCI_SRIOV_NUM_BARS - 1) ?
                                         PCI_BAR_LAST : 0));
@@ -940,14 +921,20 @@ enum pdev_type pdev_type(u16 seg, u8 bus, u8 devfn)
     u16 class_device, creg;
     u8 d = PCI_SLOT(devfn), f = PCI_FUNC(devfn);
     int pos = pci_find_cap_offset(seg, bus, d, f, PCI_CAP_ID_EXP);
+    const pci_sbdf_t sbdf = {
+        .seg = seg,
+        .bus = bus,
+        .dev = d,
+        .func = f,
+    };
 
-    class_device = pci_conf_read16(seg, bus, d, f, PCI_CLASS_DEVICE);
+    class_device = pci_conf_read16(sbdf, PCI_CLASS_DEVICE);
     switch ( class_device )
     {
     case PCI_CLASS_BRIDGE_PCI:
         if ( !pos )
             return DEV_TYPE_LEGACY_PCI_BRIDGE;
-        creg = pci_conf_read16(seg, bus, d, f, pos + PCI_EXP_FLAGS);
+        creg = pci_conf_read16(sbdf, pos + PCI_EXP_FLAGS);
         switch ( (creg & PCI_EXP_FLAGS_TYPE) >> 4 )
         {
         case PCI_EXP_TYPE_PCI_BRIDGE:
@@ -1011,7 +998,7 @@ bool_t __init pci_device_detect(u16 seg, u8 bus, u8 dev, u8 func)
 {
     u32 vendor;
 
-    vendor = pci_conf_read32(seg, bus, dev, func, PCI_VENDOR_ID);
+    vendor = pci_conf_read32(PCI_SBDF_T(seg, bus, dev, func), PCI_VENDOR_ID);
     /* some broken boards return 0 or ~0 if a slot is empty: */
     if ( (vendor == 0xffffffff) || (vendor == 0x00000000) ||
          (vendor == 0x0000ffff) || (vendor == 0xffff0000) )
@@ -1043,10 +1030,8 @@ void pci_check_disable_device(u16 seg, u8 bus, u8 devfn)
 
     /* Tell the device to stop DMAing; we can't rely on the guest to
      * control it for us. */
-    cword = pci_conf_read16(seg, bus, pdev->sbdf.dev, pdev->sbdf.func,
-                            PCI_COMMAND);
-    pci_conf_write16(seg, bus, pdev->sbdf.dev, pdev->sbdf.func,
-                     PCI_COMMAND, cword & ~PCI_COMMAND_MASTER);
+    cword = pci_conf_read16(pdev->sbdf, PCI_COMMAND);
+    pci_conf_write16(pdev->sbdf, PCI_COMMAND, cword & ~PCI_COMMAND_MASTER);
 }
 
 /*
@@ -1079,7 +1064,7 @@ static int __init _scan_pci_devices(struct pci_seg *pseg, void *arg)
                     return -ENOMEM;
                 }
 
-                if ( !func && !(pci_conf_read8(pseg->nr, bus, dev, func,
+                if ( !func && !(pci_conf_read8(pdev->sbdf,
                                                PCI_HEADER_TYPE) & 0x80) )
                     break;
             }
@@ -1210,9 +1195,7 @@ static bool_t hest_match_type(const struct acpi_hest_header *hest_hdr,
     unsigned int pos = pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus,
                                            pdev->sbdf.dev, pdev->sbdf.func,
                                            PCI_CAP_ID_EXP);
-    uint8_t pcie = MASK_EXTR(pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
-                                             pdev->sbdf.dev, pdev->sbdf.func,
-                                             pos + PCI_EXP_FLAGS),
+    uint8_t pcie = MASK_EXTR(pci_conf_read16(pdev->sbdf, pos + PCI_EXP_FLAGS),
                              PCI_EXP_FLAGS_TYPE);
 
     switch ( hest_hdr->type )
@@ -1222,8 +1205,7 @@ static bool_t hest_match_type(const struct acpi_hest_header *hest_hdr,
     case ACPI_HEST_TYPE_AER_ENDPOINT:
         return pcie == PCI_EXP_TYPE_ENDPOINT;
     case ACPI_HEST_TYPE_AER_BRIDGE:
-        return pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                               pdev->sbdf.func, PCI_CLASS_DEVICE) ==
+        return pci_conf_read16(pdev->sbdf, PCI_CLASS_DEVICE) ==
                PCI_CLASS_BRIDGE_PCI;
     }
 
diff --git a/xen/drivers/passthrough/vtd/dmar.c b/xen/drivers/passthrough/vtd/dmar.c
index effaf93222..9d30188ab9 100644
--- a/xen/drivers/passthrough/vtd/dmar.c
+++ b/xen/drivers/passthrough/vtd/dmar.c
@@ -348,7 +348,7 @@ static int __init acpi_parse_dev_scope(
 
         while ( --depth > 0 )
         {
-            bus = pci_conf_read8(seg, bus, path->dev, path->fn,
+            bus = pci_conf_read8(PCI_SBDF_T(seg, bus, path->dev, path->fn),
                                  PCI_SECONDARY_BUS);
             path++;
         }
@@ -356,10 +356,16 @@ static int __init acpi_parse_dev_scope(
         switch ( acpi_scope->entry_type )
         {
         case ACPI_DMAR_SCOPE_TYPE_BRIDGE:
-            sec_bus = pci_conf_read8(seg, bus, path->dev, path->fn,
-                                     PCI_SECONDARY_BUS);
-            sub_bus = pci_conf_read8(seg, bus, path->dev, path->fn,
-                                     PCI_SUBORDINATE_BUS);
+        {
+            const pci_sbdf_t sbdf = {
+                .seg = seg,
+                .bus = bus,
+                .dev = path->dev,
+                .func = path->fn,
+            };
+
+            sec_bus = pci_conf_read8(sbdf, PCI_SECONDARY_BUS);
+            sub_bus = pci_conf_read8(sbdf, PCI_SUBORDINATE_BUS);
             if ( iommu_verbose )
                 printk(VTDPREFIX
                        " bridge: %04x:%02x:%02x.%u start=%x sec=%x sub=%x\n",
@@ -368,7 +374,7 @@ static int __init acpi_parse_dev_scope(
 
             dmar_scope_add_buses(scope, sec_bus, sub_bus);
             break;
-
+        }
         case ACPI_DMAR_SCOPE_TYPE_HPET:
             if ( iommu_verbose )
                 printk(VTDPREFIX " MSI HPET: %04x:%02x:%02x.%u\n",
diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c
index fa811605ee..48c7384b82 100644
--- a/xen/drivers/passthrough/vtd/quirks.c
+++ b/xen/drivers/passthrough/vtd/quirks.c
@@ -61,6 +61,14 @@ static bool_t __read_mostly is_snb_gfx;
 static u8 *__read_mostly igd_reg_va;
 static spinlock_t igd_lock;
 
+static const pci_sbdf_t igd_sbdf = {
+    .dev = IGD_DEV,
+};
+
+static const pci_sbdf_t ioh_sbdf = {
+    .dev = IOH_DEV,
+};
+
 /*
  * QUIRK to workaround Xen boot issue on Calpella/Ironlake OEM BIOS
  * not enabling VT-d properly in IGD.  The workaround is to not enabling
@@ -74,7 +82,7 @@ int is_igd_vt_enabled_quirk(void)
         return 1;
 
     /* integrated graphics on Intel platforms is located at 0:2.0 */
-    ggc = pci_conf_read16(0, 0, IGD_DEV, 0, GGC);
+    ggc = pci_conf_read16(igd_sbdf, GGC);
     return ( ggc & GGC_MEMORY_VT_ENABLED ? 1 : 0 );
 }
 
@@ -88,12 +96,12 @@ static void __init cantiga_b3_errata_init(void)
     u16 vid;
     u8 did_hi, rid;
 
-    vid = pci_conf_read16(0, 0, IGD_DEV, 0, 0);
+    vid = pci_conf_read16(igd_sbdf, 0);
     if ( vid != 0x8086 )
         return;
 
-    did_hi = pci_conf_read8(0, 0, IGD_DEV, 0, 3);
-    rid = pci_conf_read8(0, 0, IGD_DEV, 0, 8);
+    did_hi = pci_conf_read8(igd_sbdf, 3);
+    rid = pci_conf_read8(igd_sbdf, 8);
 
     if ( (did_hi == 0x2A) && (rid == 0x7) )
         is_cantiga_b3 = 1;
@@ -128,9 +136,9 @@ static void __init map_igd_reg(void)
     if ( igd_reg_va )
         return;
 
-    igd_mmio   = pci_conf_read32(0, 0, IGD_DEV, 0, PCI_BASE_ADDRESS_1);
+    igd_mmio   = pci_conf_read32(igd_sbdf, PCI_BASE_ADDRESS_1);
     igd_mmio <<= 32;
-    igd_mmio  += pci_conf_read32(0, 0, IGD_DEV, 0, PCI_BASE_ADDRESS_0);
+    igd_mmio  += pci_conf_read32(igd_sbdf, PCI_BASE_ADDRESS_0);
     igd_reg_va = ioremap(igd_mmio & IGD_BAR_MASK, 0x3000);
 }
 
@@ -279,9 +287,14 @@ static void __init tylersburg_intremap_quirk(void)
 
     for ( bus = 0; bus < 0x100; bus++ )
     {
+        const pci_sbdf_t sbdf = {
+            .bus = bus,
+            .dev = 20,
+        };
+
         /* Match on System Management Registers on Device 20 Function 0 */
-        device = pci_conf_read32(0, bus, 20, 0, PCI_VENDOR_ID);
-        rev = pci_conf_read8(0, bus, 20, 0, PCI_REVISION_ID);
+        device = pci_conf_read32(sbdf, PCI_VENDOR_ID);
+        rev = pci_conf_read8(sbdf, PCI_REVISION_ID);
 
         if ( rev == 0x13 && device == 0x342e8086 )
         {
@@ -296,8 +309,8 @@ static void __init tylersburg_intremap_quirk(void)
 /* initialize platform identification flags */
 void __init platform_quirks_init(void)
 {
-    ioh_id = pci_conf_read32(0, 0, IOH_DEV, 0, 0);
-    igd_id = pci_conf_read32(0, 0, IGD_DEV, 0, 0);
+    ioh_id = pci_conf_read32(ioh_sbdf, 0);
+    igd_id = pci_conf_read32(igd_sbdf, 0);
 
     /* Mobile 4 Series Chipset neglects to set RWBF capability. */
     if ( ioh_id == 0x2a408086 )
@@ -356,15 +369,15 @@ int me_wifi_quirk(struct domain *domain, u8 bus, u8 devfn, int map)
     u32 id;
     int rc = 0;
 
-    id = pci_conf_read32(0, 0, 0, 0, 0);
+    id = pci_conf_read32(PCI_SBDF_T(0, 0, 0, 0), 0);
     if ( IS_CTG(id) )
     {
         /* quit if ME does not exist */
-        if ( pci_conf_read32(0, 0, 3, 0, 0) == 0xffffffff )
+        if ( pci_conf_read32(PCI_SBDF_T(0, 0, 3, 0), 0) == 0xffffffff )
             return 0;
 
         /* if device is WLAN device, map ME phantom device 0:3.7 */
-        id = pci_conf_read32(0, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), 0);
+        id = pci_conf_read32(PCI_SBDF3_T(0, bus, devfn), 0);
         switch (id)
         {
             case 0x42328086:
@@ -384,11 +397,11 @@ int me_wifi_quirk(struct domain *domain, u8 bus, u8 devfn, int map)
     else if ( IS_ILK(id) || IS_CPT(id) )
     {
         /* quit if ME does not exist */
-        if ( pci_conf_read32(0, 0, 22, 0, 0) == 0xffffffff )
+        if ( pci_conf_read32(PCI_SBDF_T(0, 0, 22, 0), 0) == 0xffffffff )
             return 0;
 
         /* if device is WLAN device, map ME phantom device 0:22.7 */
-        id = pci_conf_read32(0, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), 0);
+        id = pci_conf_read32(PCI_SBDF3_T(0, bus, devfn), 0);
         switch (id)
         {
             case 0x00878086:        /* Kilmer Peak */
@@ -424,11 +437,11 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
     paddr_t pa;
     const char *action;
 
-    if ( pci_conf_read16(seg, bus, dev, func, PCI_VENDOR_ID) !=
+    if ( pci_conf_read16(pdev->sbdf, PCI_VENDOR_ID) !=
          PCI_VENDOR_ID_INTEL )
         return;
 
-    switch ( pci_conf_read16(seg, bus, dev, func, PCI_DEVICE_ID) )
+    switch ( pci_conf_read16(pdev->sbdf, PCI_DEVICE_ID) )
     {
     /*
      * Mask reporting Intel VT-d faults to IOH core logic:
@@ -439,8 +452,8 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
     case 0x342e: /* Tylersburg chipset (Nehalem / Westmere systems) */
     case 0x3728: /* Xeon C5500/C3500 (JasperForest) */
     case 0x3c28: /* Sandybridge */
-        val = pci_conf_read32(seg, bus, dev, func, 0x1AC);
-        pci_conf_write32(seg, bus, dev, func, 0x1AC, val | (1 << 31));
+        val = pci_conf_read32(pdev->sbdf, 0x1AC);
+        pci_conf_write32(pdev->sbdf, 0x1AC, val | (1 << 31));
         printk(XENLOG_INFO "Masked VT-d error signaling on %04x:%02x:%02x.%u\n",
                seg, bus, dev, func);
         break;
@@ -462,7 +475,7 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
                                           PCI_EXT_CAP_ID_VNDR);
             while ( pos )
             {
-                val = pci_conf_read32(seg, bus, dev, func, pos + PCI_VNDR_HEADER);
+                val = pci_conf_read32(pdev->sbdf, pos + PCI_VNDR_HEADER);
                 if ( PCI_VNDR_HEADER_ID(val) == 4 && PCI_VNDR_HEADER_REV(val) == 1 )
                 {
                     pos += PCI_VNDR_HEADER;
@@ -482,15 +495,15 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
             break;
         }
 
-        val = pci_conf_read32(seg, bus, dev, func, pos + PCI_ERR_UNCOR_MASK);
-        val2 = pci_conf_read32(seg, bus, dev, func, pos + PCI_ERR_COR_MASK);
+        val = pci_conf_read32(pdev->sbdf, pos + PCI_ERR_UNCOR_MASK);
+        val2 = pci_conf_read32(pdev->sbdf, pos + PCI_ERR_COR_MASK);
         if ( (val & PCI_ERR_UNC_UNSUP) && (val2 & PCI_ERR_COR_ADV_NFAT) )
             action = "Found masked";
         else if ( !ff )
         {
-            pci_conf_write32(seg, bus, dev, func, pos + PCI_ERR_UNCOR_MASK,
+            pci_conf_write32(pdev->sbdf, pos + PCI_ERR_UNCOR_MASK,
                              val | PCI_ERR_UNC_UNSUP);
-            pci_conf_write32(seg, bus, dev, func, pos + PCI_ERR_COR_MASK,
+            pci_conf_write32(pdev->sbdf, pos + PCI_ERR_COR_MASK,
                              val2 | PCI_ERR_COR_ADV_NFAT);
             action = "Masked";
         }
@@ -498,8 +511,8 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
             action = "Must not mask";
 
         /* XPUNCERRMSK Send Completion with Unsupported Request */
-        val = pci_conf_read32(seg, bus, dev, func, 0x20c);
-        pci_conf_write32(seg, bus, dev, func, 0x20c, val | (1 << 4));
+        val = pci_conf_read32(pdev->sbdf, 0x20c);
+        pci_conf_write32(pdev->sbdf, 0x20c, val | (1 << 4));
 
         printk(XENLOG_INFO "%s UR signaling on %04x:%02x:%02x.%u\n",
                action, seg, bus, dev, func);
@@ -515,8 +528,8 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
     case 0x1610: case 0x1614: case 0x1618: /* Broadwell */
     case 0x1900: case 0x1904: case 0x1908: case 0x190c: case 0x190f: /* Skylake */
     case 0x1910: case 0x1918: case 0x191f: /* Skylake */
-        bar = pci_conf_read32(seg, bus, dev, func, 0x6c);
-        bar = (bar << 32) | pci_conf_read32(seg, bus, dev, func, 0x68);
+        bar = pci_conf_read32(pdev->sbdf, 0x6c);
+        bar = (bar << 32) | pci_conf_read32(pdev->sbdf, 0x68);
         pa = bar & 0x7ffffff000UL; /* bits 12...38 */
         if ( (bar & 1) && pa &&
              page_is_ram_type(paddr_to_pfn(pa), RAM_TYPE_RESERVED) )
diff --git a/xen/drivers/passthrough/x86/ats.c b/xen/drivers/passthrough/x86/ats.c
index ddaec72d19..c3203793a6 100644
--- a/xen/drivers/passthrough/x86/ats.c
+++ b/xen/drivers/passthrough/x86/ats.c
@@ -34,8 +34,7 @@ int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
         dprintk(XENLOG_INFO, "%04x:%02x:%02x.%u: ATS capability found\n",
                 seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
 
-    value = pci_conf_read16(seg, bus, PCI_SLOT(devfn),
-                            PCI_FUNC(devfn), pos + ATS_REG_CTL);
+    value = pci_conf_read16(pdev->sbdf, pos + ATS_REG_CTL);
     if ( value & ATS_ENABLE )
     {
         struct pci_dev *other;
@@ -51,15 +50,13 @@ int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
     if ( !(value & ATS_ENABLE) )
     {
         value |= ATS_ENABLE;
-        pci_conf_write16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                         pos + ATS_REG_CTL, value);
+        pci_conf_write16(pdev->sbdf, pos + ATS_REG_CTL, value);
     }
 
     if ( pos )
     {
         pdev->ats.cap_pos = pos;
-        value = pci_conf_read16(seg, bus, PCI_SLOT(devfn),
-                                PCI_FUNC(devfn), pos + ATS_REG_CAP);
+        value = pci_conf_read16(pdev->sbdf, pos + ATS_REG_CAP);
         pdev->ats.queue_depth = value & ATS_QUEUE_DEPTH_MASK ?:
                                 ATS_QUEUE_DEPTH_MASK + 1;
         list_add(&pdev->ats.list, ats_list);
@@ -81,11 +78,9 @@ void disable_ats_device(struct pci_dev *pdev)
 
     BUG_ON(!pdev->ats.cap_pos);
 
-    value = pci_conf_read16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                            pdev->ats.cap_pos + ATS_REG_CTL);
+    value = pci_conf_read16(pdev->sbdf, pdev->ats.cap_pos + ATS_REG_CTL);
     value &= ~ATS_ENABLE;
-    pci_conf_write16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                     pdev->ats.cap_pos + ATS_REG_CTL, value);
+    pci_conf_write16(pdev->sbdf, pdev->ats.cap_pos + ATS_REG_CTL, value);
 
     list_del(&pdev->ats.list);
 
diff --git a/xen/drivers/pci/pci.c b/xen/drivers/pci/pci.c
index a3223a2b29..3d2acf6f77 100644
--- a/xen/drivers/pci/pci.c
+++ b/xen/drivers/pci/pci.c
@@ -14,19 +14,25 @@ int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 cap)
     int max_cap = 48;
     u8 pos = PCI_CAPABILITY_LIST;
     u16 status;
-
-    status = pci_conf_read16(seg, bus, dev, func, PCI_STATUS);
+    const pci_sbdf_t sbdf = {
+        .seg = seg,
+        .bus = bus,
+        .dev = dev,
+        .func = func,
+    };
+
+    status = pci_conf_read16(sbdf, PCI_STATUS);
     if ( (status & PCI_STATUS_CAP_LIST) == 0 )
         return 0;
 
     while ( max_cap-- )
     {
-        pos = pci_conf_read8(seg, bus, dev, func, pos);
+        pos = pci_conf_read8(sbdf, pos);
         if ( pos < 0x40 )
             break;
 
         pos &= ~3;
-        id = pci_conf_read8(seg, bus, dev, func, pos + PCI_CAP_LIST_ID);
+        id = pci_conf_read8(sbdf, pos + PCI_CAP_LIST_ID);
 
         if ( id == 0xff )
             break;
@@ -43,16 +49,20 @@ int pci_find_next_cap(u16 seg, u8 bus, unsigned int devfn, u8 pos, int cap)
 {
     u8 id;
     int ttl = 48;
+    const pci_sbdf_t sbdf = {
+        .seg = seg,
+        .bus = bus,
+        .extfunc = devfn,
+    };
 
     while ( ttl-- )
     {
-        pos = pci_conf_read8(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos);
+        pos = pci_conf_read8(sbdf, pos);
         if ( pos < 0x40 )
             break;
 
         pos &= ~3;
-        id = pci_conf_read8(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                            pos + PCI_CAP_LIST_ID);
+        id = pci_conf_read8(sbdf, pos + PCI_CAP_LIST_ID);
 
         if ( id == 0xff )
             break;
@@ -90,11 +100,14 @@ int pci_find_ext_capability(int seg, int bus, int devfn, int cap)
  */
 int pci_find_next_ext_capability(int seg, int bus, int devfn, int start, int cap)
 {
-    u32 header;
     int ttl = 480; /* 3840 bytes, minimum 8 bytes per capability */
     int pos = max(start, 0x100);
-
-    header = pci_conf_read32(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos);
+    const pci_sbdf_t sbdf = {
+        .seg = seg,
+        .bus = bus,
+        .extfunc = devfn,
+    };
+    uint32_t header = pci_conf_read32(sbdf, pos);
 
     /*
      * If we have no capabilities, this is indicated by cap ID,
@@ -110,24 +123,20 @@ int pci_find_next_ext_capability(int seg, int bus, int devfn, int start, int cap
         pos = PCI_EXT_CAP_NEXT(header);
         if ( pos < 0x100 )
             break;
-        header = pci_conf_read32(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos);
+        header = pci_conf_read32(sbdf, pos);
     }
     return 0;
 }
 
 void pci_intx(const struct pci_dev *pdev, bool enable)
 {
-    uint16_t seg = pdev->sbdf.seg;
-    uint8_t bus = pdev->sbdf.bus;
-    uint8_t slot = pdev->sbdf.dev;
-    uint8_t func = pdev->sbdf.func;
-    uint16_t cmd = pci_conf_read16(seg, bus, slot, func, PCI_COMMAND);
+    uint16_t cmd = pci_conf_read16(pdev->sbdf, PCI_COMMAND);
 
     if ( enable )
         cmd &= ~PCI_COMMAND_INTX_DISABLE;
     else
         cmd |= PCI_COMMAND_INTX_DISABLE;
-    pci_conf_write16(seg, bus, slot, func, PCI_COMMAND, cmd);
+    pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd);
 }
 
 const char *__init parse_pci(const char *s, unsigned int *seg_p,
diff --git a/xen/drivers/video/vga.c b/xen/drivers/video/vga.c
index 6a64fd9013..59f9c9de6f 100644
--- a/xen/drivers/video/vga.c
+++ b/xen/drivers/video/vga.c
@@ -121,10 +121,8 @@ void __init video_endboot(void)
                 pcidevs_unlock();
 
                 if ( !pdev ||
-                     pci_conf_read16(0, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                                     PCI_CLASS_DEVICE) != 0x0300 ||
-                     !(pci_conf_read16(0, bus, PCI_SLOT(devfn),
-                                       PCI_FUNC(devfn), PCI_COMMAND) &
+                     pci_conf_read16(pdev->sbdf, PCI_CLASS_DEVICE) != 0x0300 ||
+                     !(pci_conf_read16(pdev->sbdf, PCI_COMMAND) &
                        (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) )
                     continue;
 
@@ -136,21 +134,24 @@ void __init video_endboot(void)
                         b = 0;
                         break;
                     case 1:
-                        switch ( pci_conf_read8(0, b, PCI_SLOT(df),
-                                                PCI_FUNC(df),
-                                                PCI_HEADER_TYPE) )
+                    {
+                        const pci_sbdf_t sbdf = {
+                            .bus = b,
+                            .extfunc = df,
+                        };
+
+                        switch ( pci_conf_read8(sbdf, PCI_HEADER_TYPE) )
                         {
                         case PCI_HEADER_TYPE_BRIDGE:
                         case PCI_HEADER_TYPE_CARDBUS:
-                            if ( pci_conf_read16(0, b, PCI_SLOT(df),
-                                                 PCI_FUNC(df),
-                                                 PCI_BRIDGE_CONTROL) &
+                            if ( pci_conf_read16(sbdf, PCI_BRIDGE_CONTROL) &
                                  PCI_BRIDGE_CTL_VGA )
                                 continue;
                             break;
                         }
                         break;
                     }
+                    }
                     break;
                 }
                 if ( !b )
diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
index 74d70a4278..d693b1376c 100644
--- a/xen/drivers/vpci/header.c
+++ b/xen/drivers/vpci/header.c
@@ -112,8 +112,7 @@ static void modify_decoding(const struct pci_dev *pdev, uint16_t cmd,
                            (map ? PCI_ROM_ADDRESS_ENABLE : 0);
 
             header->bars[i].enabled = header->rom_enabled = map;
-            pci_conf_write32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                             pdev->sbdf.func, rom_pos, val);
+            pci_conf_write32(pdev->sbdf, rom_pos, val);
             return;
         }
 
@@ -123,8 +122,7 @@ static void modify_decoding(const struct pci_dev *pdev, uint16_t cmd,
     }
 
     if ( !rom_only )
-        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                         pdev->sbdf.func, PCI_COMMAND, cmd);
+        pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd);
     else
         ASSERT_UNREACHABLE();
 }
@@ -335,9 +333,7 @@ static int modify_bars(const struct pci_dev *pdev, uint16_t cmd, bool rom_only)
 static void cmd_write(const struct pci_dev *pdev, unsigned int reg,
                       uint32_t cmd, void *data)
 {
-    uint16_t current_cmd = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
-                                           pdev->sbdf.dev, pdev->sbdf.func,
-                                           reg);
+    uint16_t current_cmd = pci_conf_read16(pdev->sbdf, reg);
 
     /*
      * Let Dom0 play with all the bits directly except for the memory
@@ -352,8 +348,7 @@ static void cmd_write(const struct pci_dev *pdev, unsigned int reg,
          */
         modify_bars(pdev, cmd, false);
     else
-        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                         pdev->sbdf.func, reg, cmd);
+        pci_conf_write16(pdev->sbdf, reg, cmd);
 }
 
 static void bar_write(const struct pci_dev *pdev, unsigned int reg,
@@ -371,8 +366,7 @@ static void bar_write(const struct pci_dev *pdev, unsigned int reg,
     else
         val &= PCI_BASE_ADDRESS_MEM_MASK;
 
-    if ( pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                         pdev->sbdf.func, PCI_COMMAND) & PCI_COMMAND_MEMORY )
+    if ( pci_conf_read16(pdev->sbdf, PCI_COMMAND) & PCI_COMMAND_MEMORY )
     {
         /* If the value written is the current one avoid printing a warning. */
         if ( val != (uint32_t)(bar->addr >> (hi ? 32 : 0)) )
@@ -399,8 +393,7 @@ static void bar_write(const struct pci_dev *pdev, unsigned int reg,
         val |= bar->prefetchable ? PCI_BASE_ADDRESS_MEM_PREFETCH : 0;
     }
 
-    pci_conf_write32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                     pdev->sbdf.func, reg, val);
+    pci_conf_write32(pdev->sbdf, reg, val);
 }
 
 static void rom_write(const struct pci_dev *pdev, unsigned int reg,
@@ -408,9 +401,7 @@ static void rom_write(const struct pci_dev *pdev, unsigned int reg,
 {
     struct vpci_header *header = &pdev->vpci->header;
     struct vpci_bar *rom = data;
-    uint16_t cmd = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
-                                   pdev->sbdf.dev, pdev->sbdf.func,
-                                   PCI_COMMAND);
+    uint16_t cmd = pci_conf_read16(pdev->sbdf, PCI_COMMAND);
     bool new_enabled = val & PCI_ROM_ADDRESS_ENABLE;
 
     if ( (cmd & PCI_COMMAND_MEMORY) && header->rom_enabled && new_enabled )
@@ -433,8 +424,7 @@ static void rom_write(const struct pci_dev *pdev, unsigned int reg,
     {
         /* Just update the ROM BAR field. */
         header->rom_enabled = new_enabled;
-        pci_conf_write32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                         pdev->sbdf.func, reg, val);
+        pci_conf_write32(pdev->sbdf, reg, val);
     }
     /*
      * Pass PCI_COMMAND_MEMORY or 0 to signal a map/unmap request, note that
@@ -464,8 +454,7 @@ static int init_bars(struct pci_dev *pdev)
     struct vpci_bar *bars = header->bars;
     int rc;
 
-    switch ( pci_conf_read8(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                            pdev->sbdf.func, PCI_HEADER_TYPE) & 0x7f )
+    switch ( pci_conf_read8(pdev->sbdf, PCI_HEADER_TYPE) & 0x7f )
     {
     case PCI_HEADER_TYPE_NORMAL:
         num_bars = PCI_HEADER_NORMAL_NR_BARS;
@@ -491,12 +480,9 @@ static int init_bars(struct pci_dev *pdev)
         return 0;
 
     /* Disable memory decoding before sizing. */
-    cmd = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                          pdev->sbdf.func, PCI_COMMAND);
+    cmd = pci_conf_read16(pdev->sbdf, PCI_COMMAND);
     if ( cmd & PCI_COMMAND_MEMORY )
-        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                         pdev->sbdf.func, PCI_COMMAND,
-                         cmd & ~PCI_COMMAND_MEMORY);
+        pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd & ~PCI_COMMAND_MEMORY);
 
     for ( i = 0; i < num_bars; i++ )
     {
@@ -510,16 +496,14 @@ static int init_bars(struct pci_dev *pdev)
                                    4, &bars[i]);
             if ( rc )
             {
-                pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                                 pdev->sbdf.func, PCI_COMMAND, cmd);
+                pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd);
                 return rc;
             }
 
             continue;
         }
 
-        val = pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                              pdev->sbdf.func, reg);
+        val = pci_conf_read32(pdev->sbdf, reg);
         if ( (val & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO )
         {
             bars[i].type = VPCI_BAR_IO;
@@ -535,8 +519,7 @@ static int init_bars(struct pci_dev *pdev)
                               (i == num_bars - 1) ? PCI_BAR_LAST : 0);
         if ( rc < 0 )
         {
-            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                             pdev->sbdf.func, PCI_COMMAND, cmd);
+            pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd);
             return rc;
         }
 
@@ -554,8 +537,7 @@ static int init_bars(struct pci_dev *pdev)
                                &bars[i]);
         if ( rc )
         {
-            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                             pdev->sbdf.func, PCI_COMMAND, cmd);
+            pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd);
             return rc;
         }
     }
@@ -569,9 +551,8 @@ static int init_bars(struct pci_dev *pdev)
         rom->type = VPCI_BAR_ROM;
         rom->size = size;
         rom->addr = addr;
-        header->rom_enabled = pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus,
-                                              pdev->sbdf.dev, pdev->sbdf.func,
-                                              rom_reg) & PCI_ROM_ADDRESS_ENABLE;
+        header->rom_enabled = pci_conf_read32(pdev->sbdf, rom_reg) &
+                              PCI_ROM_ADDRESS_ENABLE;
 
         rc = vpci_add_register(pdev->vpci, vpci_hw_read32, rom_write, rom_reg,
                                4, rom);
diff --git a/xen/drivers/vpci/msi.c b/xen/drivers/vpci/msi.c
index dfc894dcc6..4f2e55f3fd 100644
--- a/xen/drivers/vpci/msi.c
+++ b/xen/drivers/vpci/msi.c
@@ -77,8 +77,7 @@ static void control_write(const struct pci_dev *pdev, unsigned int reg,
     msi->vectors = vectors;
     msi->enabled = new_enabled;
 
-    pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                     pdev->sbdf.func, reg, control_read(pdev, reg, data));
+    pci_conf_write16(pdev->sbdf, reg, control_read(pdev, reg, data));
 }
 
 static void update_msi(const struct pci_dev *pdev, struct vpci_msi *msi)
@@ -210,8 +209,7 @@ static int init_msi(struct pci_dev *pdev)
         return ret;
 
     /* Get the maximum number of vectors the device supports. */
-    control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                              pdev->sbdf.func, msi_control_reg(pos));
+    control = pci_conf_read16(pdev->sbdf, msi_control_reg(pos));
 
     /*
      * FIXME: I've only been able to test this code with devices using a single
diff --git a/xen/drivers/vpci/msix.c b/xen/drivers/vpci/msix.c
index 04431715f5..47d569121f 100644
--- a/xen/drivers/vpci/msix.c
+++ b/xen/drivers/vpci/msix.c
@@ -147,8 +147,7 @@ static void control_write(const struct pci_dev *pdev, unsigned int reg,
 
     val = control_read(pdev, reg, data);
     if ( pci_msi_conf_write_intercept(msix->pdev, reg, 2, &val) >= 0 )
-        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                         pdev->sbdf.func, reg, val);
+        pci_conf_write16(pdev->sbdf, reg, val);
 }
 
 static struct vpci_msix *msix_find(const struct domain *d, unsigned long addr)
@@ -459,8 +458,7 @@ static int init_msix(struct pci_dev *pdev)
     if ( !msix_offset )
         return 0;
 
-    control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                              pdev->sbdf.func, msix_control_reg(msix_offset));
+    control = pci_conf_read16(pdev->sbdf, msix_control_reg(msix_offset));
 
     max_entries = msix_table_size(control);
 
@@ -472,11 +470,9 @@ static int init_msix(struct pci_dev *pdev)
     pdev->vpci->msix->pdev = pdev;
 
     pdev->vpci->msix->tables[VPCI_MSIX_TABLE] =
-        pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                        pdev->sbdf.func, msix_table_offset_reg(msix_offset));
+        pci_conf_read32(pdev->sbdf, msix_table_offset_reg(msix_offset));
     pdev->vpci->msix->tables[VPCI_MSIX_PBA] =
-        pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                        pdev->sbdf.func, msix_pba_offset_reg(msix_offset));
+        pci_conf_read32(pdev->sbdf, msix_pba_offset_reg(msix_offset));
 
     for ( i = 0; i < pdev->vpci->msix->max_entries; i++)
     {
diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c
index 9a060c108e..afe0c38396 100644
--- a/xen/drivers/vpci/vpci.c
+++ b/xen/drivers/vpci/vpci.c
@@ -114,15 +114,13 @@ static void vpci_ignored_write(const struct pci_dev *pdev, unsigned int reg,
 uint32_t vpci_hw_read16(const struct pci_dev *pdev, unsigned int reg,
                         void *data)
 {
-    return pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                           pdev->sbdf.func, reg);
+    return pci_conf_read16(pdev->sbdf, reg);
 }
 
 uint32_t vpci_hw_read32(const struct pci_dev *pdev, unsigned int reg,
                         void *data)
 {
-    return pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                           pdev->sbdf.func, reg);
+    return pci_conf_read32(pdev->sbdf, reg);
 }
 
 int vpci_add_register(struct vpci *vpci, vpci_read_t *read_handler,
@@ -212,7 +210,7 @@ static uint32_t vpci_read_hw(pci_sbdf_t sbdf, unsigned int reg,
     switch ( size )
     {
     case 4:
-        data = pci_conf_read32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg);
+        data = pci_conf_read32(sbdf, reg);
         break;
 
     case 3:
@@ -222,26 +220,22 @@ static uint32_t vpci_read_hw(pci_sbdf_t sbdf, unsigned int reg,
          */
         if ( reg & 1 )
         {
-            data = pci_conf_read8(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func,
-                                  reg);
-            data |= pci_conf_read16(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func,
-                                    reg + 1) << 8;
+            data = pci_conf_read8(sbdf, reg);
+            data |= pci_conf_read16(sbdf, reg + 1) << 8;
         }
         else
         {
-            data = pci_conf_read16(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func,
-                                   reg);
-            data |= pci_conf_read8(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func,
-                                   reg + 2) << 16;
+            data = pci_conf_read16(sbdf, reg);
+            data |= pci_conf_read8(sbdf, reg + 2) << 16;
         }
         break;
 
     case 2:
-        data = pci_conf_read16(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg);
+        data = pci_conf_read16(sbdf, reg);
         break;
 
     case 1:
-        data = pci_conf_read8(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg);
+        data = pci_conf_read8(sbdf, reg);
         break;
 
     default:
@@ -259,7 +253,7 @@ static void vpci_write_hw(pci_sbdf_t sbdf, unsigned int reg, unsigned int size,
     switch ( size )
     {
     case 4:
-        pci_conf_write32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg, data);
+        pci_conf_write32(sbdf, reg, data);
         break;
 
     case 3:
@@ -269,26 +263,22 @@ static void vpci_write_hw(pci_sbdf_t sbdf, unsigned int reg, unsigned int size,
          */
         if ( reg & 1 )
         {
-            pci_conf_write8(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg,
-                            data);
-            pci_conf_write16(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg + 1,
-                             data >> 8);
+            pci_conf_write8(sbdf, reg, data);
+            pci_conf_write16(sbdf, reg + 1, data >> 8);
         }
         else
         {
-            pci_conf_write16(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg,
-                             data);
-            pci_conf_write8(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg + 2,
-                            data >> 16);
+            pci_conf_write16(sbdf, reg, data);
+            pci_conf_write8(sbdf, reg + 2, data >> 16);
         }
         break;
 
     case 2:
-        pci_conf_write16(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg, data);
+        pci_conf_write16(sbdf, reg, data);
         break;
 
     case 1:
-        pci_conf_write8(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg, data);
+        pci_conf_write8(sbdf, reg, data);
         break;
 
     default:
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 1cf54eb466..9908d0fe5d 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -58,6 +58,11 @@ typedef union {
     };
 } pci_sbdf_t;
 
+#define PCI_SBDF_T(s, b, d, f) \
+    ((pci_sbdf_t) { .seg = (s), .bus = (b), .dev = (d), .func = (f) })
+#define PCI_SBDF3_T(s, b, e) \
+    ((pci_sbdf_t) { .seg = (s), .bus = (b), .extfunc = (e) })
+
 struct pci_dev_info {
     /*
      * VF's 'is_extfn' field is used to indicate whether its PF is an extended
@@ -159,24 +164,12 @@ struct pci_dev *pci_get_pdev_by_domain(const struct domain *, int seg,
                                        int bus, int devfn);
 void pci_check_disable_device(u16 seg, u8 bus, u8 devfn);
 
-uint8_t pci_conf_read8(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg);
-uint16_t pci_conf_read16(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg);
-uint32_t pci_conf_read32(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg);
-void pci_conf_write8(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg, uint8_t data);
-void pci_conf_write16(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg, uint16_t data);
-void pci_conf_write32(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg, uint32_t data);
+uint8_t pci_conf_read8(pci_sbdf_t sbdf, unsigned int reg);
+uint16_t pci_conf_read16(pci_sbdf_t sbdf, unsigned int reg);
+uint32_t pci_conf_read32(pci_sbdf_t sbdf, unsigned int reg);
+void pci_conf_write8(pci_sbdf_t sbdf, unsigned int reg, uint8_t data);
+void pci_conf_write16(pci_sbdf_t sbdf, unsigned int reg, uint16_t data);
+void pci_conf_write32(pci_sbdf_t sbdf, unsigned int reg, uint32_t data);
 uint32_t pci_conf_read(uint32_t cf8, uint8_t offset, uint8_t bytes);
 void pci_conf_write(uint32_t cf8, uint8_t offset, uint8_t bytes, uint32_t data);
 int pci_mmcfg_read(unsigned int seg, unsigned int bus,
-- 
2.17.2 (Apple Git-113)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Xen-devel] [PATCH 3/5] pci: switch pci_conf_{read/write} to use pci_sbdf_t
@ 2019-05-10 16:10   ` Roger Pau Monne
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monne @ 2019-05-10 16:10 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Suravee Suthikulpanit,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper, Ian Jackson,
	Tim Deegan, Julien Grall, Jan Beulich, Brian Woods,
	Roger Pau Monne

pci_dev already uses pci_sbdf_t, so propagate the usage of the type to
pci_conf functions in order to shorten the calls when made from a
pci_dev struct.

No functional change intended.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Julien Grall <julien.grall@arm.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Brian Woods <brian.woods@amd.com>
Cc: Kevin Tian <kevin.tian@intel.com>
---
 xen/arch/x86/cpu/amd.c                     |  27 ++--
 xen/arch/x86/dmi_scan.c                    |   9 +-
 xen/arch/x86/mm.c                          |   2 +-
 xen/arch/x86/msi.c                         | 177 +++++++++------------
 xen/arch/x86/oprofile/op_model_athlon.c    |  12 +-
 xen/arch/x86/x86_64/mmconf-fam10h.c        |  13 +-
 xen/arch/x86/x86_64/mmconfig-shared.c      |  26 +--
 xen/arch/x86/x86_64/pci.c                  |  32 ++--
 xen/drivers/acpi/reboot.c                  |   8 +-
 xen/drivers/char/ehci-dbgp.c               |  75 +++++----
 xen/drivers/char/ns16550.c                 |  80 +++++-----
 xen/drivers/passthrough/amd/iommu_detect.c |   3 +-
 xen/drivers/passthrough/amd/iommu_init.c   |  26 +--
 xen/drivers/passthrough/ats.h              |   4 +-
 xen/drivers/passthrough/pci.c              | 106 +++++-------
 xen/drivers/passthrough/vtd/dmar.c         |  18 ++-
 xen/drivers/passthrough/vtd/quirks.c       |  69 ++++----
 xen/drivers/passthrough/x86/ats.c          |  15 +-
 xen/drivers/pci/pci.c                      |  43 +++--
 xen/drivers/video/vga.c                    |  21 +--
 xen/drivers/vpci/header.c                  |  53 ++----
 xen/drivers/vpci/msi.c                     |   6 +-
 xen/drivers/vpci/msix.c                    |  12 +-
 xen/drivers/vpci/vpci.c                    |  42 ++---
 xen/include/xen/pci.h                      |  29 ++--
 25 files changed, 444 insertions(+), 464 deletions(-)

diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
index e19a5ead3e..014d88925c 100644
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -417,15 +417,21 @@ static void disable_c1_ramping(void)
 	int node, nr_nodes;
 
 	/* Read the number of nodes from the first Northbridge. */
-	nr_nodes = ((pci_conf_read32(0, 0, 0x18, 0x0, 0x60)>>4)&0x07)+1;
+	nr_nodes = ((pci_conf_read32(PCI_SBDF_T(0, 0, 0x18, 0),
+				     0x60)>>4)&0x07)+1;
 	for (node = 0; node < nr_nodes; node++) {
+		const pci_sbdf_t sbdf = {
+			.dev = 0x18  + node,
+			.func = 0x3
+		};
+
 		/* PMM7: bus=0, dev=0x18+node, function=0x3, register=0x87. */
-		pmm7 = pci_conf_read8(0, 0, 0x18+node, 0x3, 0x87);
+		pmm7 = pci_conf_read8(sbdf, 0x87);
 		/* Invalid read means we've updated every Northbridge. */
 		if (pmm7 == 0xFF)
 			break;
 		pmm7 &= 0xFC; /* clear pmm7[1:0] */
-		pci_conf_write8(0, 0, 0x18+node, 0x3, 0x87, pmm7);
+		pci_conf_write8(sbdf, 0x87, pmm7);
 		printk ("AMD: Disabling C1 Clock Ramping Node #%x\n", node);
 	}
 }
@@ -696,8 +702,13 @@ static void init_amd(struct cpuinfo_x86 *c)
 
 	if (c->x86 == 0x16 && c->x86_model <= 0xf) {
 		if (c == &boot_cpu_data) {
-			l = pci_conf_read32(0, 0, 0x18, 0x3, 0x58);
-			h = pci_conf_read32(0, 0, 0x18, 0x3, 0x5c);
+			const pci_sbdf_t sbdf = {
+				.dev = 0x18,
+				.func = 0x3,
+			};
+
+			l = pci_conf_read32(sbdf, 0x58);
+			h = pci_conf_read32(sbdf, 0x5c);
 			if ((l & 0x1f) | (h & 0x1))
 				printk(KERN_WARNING
 				       "Applying workaround for erratum 792: %s%s%s\n",
@@ -706,12 +717,10 @@ static void init_amd(struct cpuinfo_x86 *c)
 				       (h & 0x1) ? "clearing D18F3x5C[0]" : "");
 
 			if (l & 0x1f)
-				pci_conf_write32(0, 0, 0x18, 0x3, 0x58,
-						 l & ~0x1f);
+				pci_conf_write32(sbdf, 0x58, l & ~0x1f);
 
 			if (h & 0x1)
-				pci_conf_write32(0, 0, 0x18, 0x3, 0x5c,
-						 h & ~0x1);
+				pci_conf_write32(sbdf, 0x5c, h & ~0x1);
 		}
 
 		rdmsrl(MSR_AMD64_LS_CFG, value);
diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
index fcdf2d3952..59557fa57b 100644
--- a/xen/arch/x86/dmi_scan.c
+++ b/xen/arch/x86/dmi_scan.c
@@ -468,16 +468,19 @@ static __init int broken_toshiba_keyboard(struct dmi_blacklist *d)
 static int __init ich10_bios_quirk(struct dmi_system_id *d)
 {
     u32 port, smictl;
+    const pci_sbdf_t sbdf = {
+	.dev = 0x1f,
+    };
 
-    if ( pci_conf_read16(0, 0, 0x1f, 0, PCI_VENDOR_ID) != 0x8086 )
+    if ( pci_conf_read16(sbdf, PCI_VENDOR_ID) != 0x8086 )
         return 0;
 
-    switch ( pci_conf_read16(0, 0, 0x1f, 0, PCI_DEVICE_ID) ) {
+    switch ( pci_conf_read16(sbdf, PCI_DEVICE_ID) ) {
     case 0x3a14:
     case 0x3a16:
     case 0x3a18:
     case 0x3a1a:
-        port = (pci_conf_read16(0, 0, 0x1f, 0, 0x40) & 0xff80) + 0x30;
+        port = (pci_conf_read16(sbdf, 0x40) & 0xff80) + 0x30;
         smictl = inl(port);
         /* turn off LEGACY_USB{,2}_EN if enabled */
         if ( smictl & 0x20008 )
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 45fadbab61..37d8141ed2 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -5984,7 +5984,7 @@ const struct platform_bad_page *__init get_platform_badpages(unsigned int *array
     }
 
     *array_size = ARRAY_SIZE(snb_bad_pages);
-    igd_id = pci_conf_read32(0, 0, 2, 0, 0);
+    igd_id = pci_conf_read32(PCI_SBDF_T(0, 0, 2, 0), 0);
     if ( IS_SNB_GFX(igd_id) )
         return snb_bad_pages;
 
diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index f30f592ee2..ad4a72d56b 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -124,29 +124,20 @@ static void msix_put_fixmap(struct arch_msix *msix, int idx)
 
 static bool memory_decoded(const struct pci_dev *dev)
 {
-    uint8_t bus, slot, func;
+    pci_sbdf_t sbdf = dev->sbdf;
 
-    if ( !dev->info.is_virtfn )
+    if ( dev->info.is_virtfn )
     {
-        bus = dev->sbdf.bus;
-        slot = dev->sbdf.dev;
-        func = dev->sbdf.func;
-    }
-    else
-    {
-        bus = dev->info.physfn.bus;
-        slot = PCI_SLOT(dev->info.physfn.devfn);
-        func = PCI_FUNC(dev->info.physfn.devfn);
+        sbdf.bus = dev->info.physfn.bus;
+        sbdf.extfunc = dev->info.physfn.devfn;
     }
 
-    return !!(pci_conf_read16(dev->sbdf.seg, bus, slot, func, PCI_COMMAND) &
-              PCI_COMMAND_MEMORY);
+    return !!(pci_conf_read16(sbdf, PCI_COMMAND) & PCI_COMMAND_MEMORY);
 }
 
 static bool msix_memory_decoded(const struct pci_dev *dev, unsigned int pos)
 {
-    u16 control = pci_conf_read16(dev->sbdf.seg, dev->sbdf.bus, dev->sbdf.dev,
-                                  dev->sbdf.func, msix_control_reg(pos));
+    u16 control = pci_conf_read16(dev->sbdf, msix_control_reg(pos));
 
     if ( !(control & PCI_MSIX_FLAGS_ENABLE) )
         return false;
@@ -200,25 +191,20 @@ static bool read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
     {
         struct pci_dev *dev = entry->dev;
         int pos = entry->msi_attrib.pos;
-        uint16_t data, seg = dev->sbdf.seg;
-        uint8_t bus = dev->sbdf.bus;
-        uint8_t slot = dev->sbdf.dev;
-        uint8_t func = dev->sbdf.func;
+        uint16_t data;
 
-        msg->address_lo = pci_conf_read32(seg, bus, slot, func,
+        msg->address_lo = pci_conf_read32(dev->sbdf,
                                           msi_lower_address_reg(pos));
         if ( entry->msi_attrib.is_64 )
         {
-            msg->address_hi = pci_conf_read32(seg, bus, slot, func,
+            msg->address_hi = pci_conf_read32(dev->sbdf,
                                               msi_upper_address_reg(pos));
-            data = pci_conf_read16(seg, bus, slot, func,
-                                   msi_data_reg(pos, 1));
+            data = pci_conf_read16(dev->sbdf, msi_data_reg(pos, 1));
         }
         else
         {
             msg->address_hi = 0;
-            data = pci_conf_read16(seg, bus, slot, func,
-                                   msi_data_reg(pos, 0));
+            data = pci_conf_read16(dev->sbdf, msi_data_reg(pos, 0));
         }
         msg->data = data;
         break;
@@ -265,28 +251,22 @@ static int write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
     {
         struct pci_dev *dev = entry->dev;
         int pos = entry->msi_attrib.pos;
-        uint16_t seg = dev->sbdf.seg;
-        uint8_t bus = dev->sbdf.bus;
-        uint8_t slot = dev->sbdf.dev;
-        uint8_t func = dev->sbdf.func;
         int nr = entry->msi_attrib.entry_nr;
 
         ASSERT((msg->data & (entry[-nr].msi.nvec - 1)) == nr);
         if ( nr )
             return 0;
 
-        pci_conf_write32(seg, bus, slot, func, msi_lower_address_reg(pos),
-                         msg->address_lo);
+        pci_conf_write32(dev->sbdf, msi_lower_address_reg(pos), msg->address_lo);
         if ( entry->msi_attrib.is_64 )
         {
-            pci_conf_write32(seg, bus, slot, func, msi_upper_address_reg(pos),
+            pci_conf_write32(dev->sbdf, msi_upper_address_reg(pos),
                              msg->address_hi);
-            pci_conf_write16(seg, bus, slot, func, msi_data_reg(pos, 1),
+            pci_conf_write16(dev->sbdf, msi_data_reg(pos, 1),
                              msg->data);
         }
         else
-            pci_conf_write16(seg, bus, slot, func, msi_data_reg(pos, 0),
-                             msg->data);
+            pci_conf_write16(dev->sbdf, msi_data_reg(pos, 0), msg->data);
         break;
     }
     case PCI_CAP_ID_MSIX:
@@ -337,12 +317,18 @@ void set_msi_affinity(struct irq_desc *desc, const cpumask_t *mask)
 
 void __msi_set_enable(u16 seg, u8 bus, u8 slot, u8 func, int pos, int enable)
 {
-    u16 control = pci_conf_read16(seg, bus, slot, func, pos + PCI_MSI_FLAGS);
+    const pci_sbdf_t sbdf = {
+        .seg = seg,
+        .bus = bus,
+        .dev = slot,
+        .func = func,
+    };
+    uint16_t control = pci_conf_read16(sbdf, pos + PCI_MSI_FLAGS);
 
     control &= ~PCI_MSI_FLAGS_ENABLE;
     if ( enable )
         control |= PCI_MSI_FLAGS_ENABLE;
-    pci_conf_write16(seg, bus, slot, func, pos + PCI_MSI_FLAGS, control);
+    pci_conf_write16(sbdf, pos + PCI_MSI_FLAGS, control);
 }
 
 static void msi_set_enable(struct pci_dev *dev, int enable)
@@ -369,11 +355,11 @@ static void msix_set_enable(struct pci_dev *dev, int enable)
     pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSIX);
     if ( pos )
     {
-        control = pci_conf_read16(seg, bus, slot, func, msix_control_reg(pos));
+        control = pci_conf_read16(dev->sbdf, msix_control_reg(pos));
         control &= ~PCI_MSIX_FLAGS_ENABLE;
         if ( enable )
             control |= PCI_MSIX_FLAGS_ENABLE;
-        pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), control);
+        pci_conf_write16(dev->sbdf, msix_control_reg(pos), control);
     }
 }
 
@@ -406,20 +392,20 @@ static bool msi_set_mask_bit(struct irq_desc *desc, bool host, bool guest)
         {
             u32 mask_bits;
 
-            mask_bits = pci_conf_read32(seg, bus, slot, func, entry->msi.mpos);
+            mask_bits = pci_conf_read32(pdev->sbdf, entry->msi.mpos);
             mask_bits &= ~((u32)1 << entry->msi_attrib.entry_nr);
             mask_bits |= (u32)flag << entry->msi_attrib.entry_nr;
-            pci_conf_write32(seg, bus, slot, func, entry->msi.mpos, mask_bits);
+            pci_conf_write32(pdev->sbdf, entry->msi.mpos, mask_bits);
         }
         break;
     case PCI_CAP_ID_MSIX:
         maskall = pdev->msix->host_maskall;
-        control = pci_conf_read16(seg, bus, slot, func,
+        control = pci_conf_read16(pdev->sbdf,
                                   msix_control_reg(entry->msi_attrib.pos));
         if ( unlikely(!(control & PCI_MSIX_FLAGS_ENABLE)) )
         {
             pdev->msix->host_maskall = 1;
-            pci_conf_write16(seg, bus, slot, func,
+            pci_conf_write16(pdev->sbdf,
                              msix_control_reg(entry->msi_attrib.pos),
                              control | (PCI_MSIX_FLAGS_ENABLE |
                                         PCI_MSIX_FLAGS_MASKALL));
@@ -453,7 +439,7 @@ static bool msi_set_mask_bit(struct irq_desc *desc, bool host, bool guest)
         pdev->msix->host_maskall = maskall;
         if ( maskall || pdev->msix->guest_maskall )
             control |= PCI_MSIX_FLAGS_MASKALL;
-        pci_conf_write16(seg, bus, slot, func,
+        pci_conf_write16(pdev->sbdf,
                          msix_control_reg(entry->msi_attrib.pos), control);
         return flag;
     default:
@@ -475,9 +461,7 @@ static int msi_get_mask_bit(const struct msi_desc *entry)
     case PCI_CAP_ID_MSI:
         if ( !entry->msi_attrib.maskbit )
             break;
-        return (pci_conf_read32(entry->dev->sbdf.seg, entry->dev->sbdf.bus,
-                                entry->dev->sbdf.dev, entry->dev->sbdf.func,
-                                entry->msi.mpos) >>
+        return (pci_conf_read32(entry->dev->sbdf, entry->msi.mpos) >>
                 entry->msi_attrib.entry_nr) & 1;
     case PCI_CAP_ID_MSIX:
         if ( unlikely(!msix_memory_decoded(entry->dev,
@@ -593,11 +577,9 @@ int setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc)
 
     if ( msidesc->msi_attrib.type == PCI_CAP_ID_MSIX )
     {
-        control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
-                                  pdev->sbdf.dev, pdev->sbdf.func, cpos);
+        control = pci_conf_read16(pdev->sbdf, cpos);
         if ( !(control & PCI_MSIX_FLAGS_ENABLE) )
-            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                             pdev->sbdf.func, cpos,
+            pci_conf_write16(pdev->sbdf, cpos,
                              control | (PCI_MSIX_FLAGS_ENABLE |
                                         PCI_MSIX_FLAGS_MASKALL));
     }
@@ -607,8 +589,7 @@ int setup_msi_irq(struct irq_desc *desc, struct msi_desc *msidesc)
                                                    : &pci_msi_nonmaskable);
 
     if ( !(control & PCI_MSIX_FLAGS_ENABLE) )
-        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                         pdev->sbdf.func, cpos, control);
+        pci_conf_write16(pdev->sbdf, cpos, control);
 
     return rc;
 }
@@ -697,7 +678,7 @@ static int msi_capability_init(struct pci_dev *dev,
     pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSI);
     if ( !pos )
         return -ENODEV;
-    control = pci_conf_read16(seg, bus, slot, func, msi_control_reg(pos));
+    control = pci_conf_read16(dev->sbdf, msi_control_reg(pos));
     maxvec = multi_msi_capable(control);
     if ( nvec > maxvec )
         return maxvec;
@@ -733,9 +714,9 @@ static int msi_capability_init(struct pci_dev *dev,
         u32 maskbits;
 
         /* All MSIs are unmasked by default, Mask them all */
-        maskbits = pci_conf_read32(seg, bus, slot, func, mpos);
+        maskbits = pci_conf_read32(dev->sbdf, mpos);
         maskbits |= ~(u32)0 >> (32 - maxvec);
-        pci_conf_write32(seg, bus, slot, func, mpos, maskbits);
+        pci_conf_write32(dev->sbdf, mpos, maskbits);
     }
     list_add_tail(&entry->list, &dev->msi_list);
 
@@ -751,7 +732,7 @@ static int msi_capability_init(struct pci_dev *dev,
         pci_intx(dev, false);
         control |= PCI_MSI_FLAGS_ENABLE;
     }
-    pci_conf_write16(seg, bus, slot, func, msi_control_reg(pos), control);
+    pci_conf_write16(dev->sbdf, msi_control_reg(pos), control);
 
     return 0;
 }
@@ -761,6 +742,12 @@ static u64 read_pci_mem_bar(u16 seg, u8 bus, u8 slot, u8 func, u8 bir, int vf)
     u8 limit;
     u32 addr, base = PCI_BASE_ADDRESS_0;
     u64 disp = 0;
+    const pci_sbdf_t sbdf = {
+        .seg = seg,
+        .bus = bus,
+        .dev = slot,
+        .func = func,
+    };
 
     if ( vf >= 0 )
     {
@@ -768,13 +755,10 @@ static u64 read_pci_mem_bar(u16 seg, u8 bus, u8 slot, u8 func, u8 bir, int vf)
         unsigned int pos = pci_find_ext_capability(seg, bus,
                                                    PCI_DEVFN(slot, func),
                                                    PCI_EXT_CAP_ID_SRIOV);
-        u16 ctrl = pci_conf_read16(seg, bus, slot, func, pos + PCI_SRIOV_CTRL);
-        u16 num_vf = pci_conf_read16(seg, bus, slot, func,
-                                     pos + PCI_SRIOV_NUM_VF);
-        u16 offset = pci_conf_read16(seg, bus, slot, func,
-                                     pos + PCI_SRIOV_VF_OFFSET);
-        u16 stride = pci_conf_read16(seg, bus, slot, func,
-                                     pos + PCI_SRIOV_VF_STRIDE);
+        u16 ctrl = pci_conf_read16(sbdf, pos + PCI_SRIOV_CTRL);
+        u16 num_vf = pci_conf_read16(sbdf, pos + PCI_SRIOV_NUM_VF);
+        u16 offset = pci_conf_read16(sbdf, pos + PCI_SRIOV_VF_OFFSET);
+        u16 stride = pci_conf_read16(sbdf, pos + PCI_SRIOV_VF_STRIDE);
 
         if ( !pdev || !pos ||
              !(ctrl & PCI_SRIOV_CTRL_VFE) ||
@@ -799,8 +783,7 @@ static u64 read_pci_mem_bar(u16 seg, u8 bus, u8 slot, u8 func, u8 bir, int vf)
         disp = vf * pdev->vf_rlen[bir];
         limit = PCI_SRIOV_NUM_BARS;
     }
-    else switch ( pci_conf_read8(seg, bus, slot, func,
-                                 PCI_HEADER_TYPE) & 0x7f )
+    else switch ( pci_conf_read8(sbdf, PCI_HEADER_TYPE) & 0x7f )
     {
     case PCI_HEADER_TYPE_NORMAL:
         limit = 6;
@@ -817,7 +800,7 @@ static u64 read_pci_mem_bar(u16 seg, u8 bus, u8 slot, u8 func, u8 bir, int vf)
 
     if ( bir >= limit )
         return 0;
-    addr = pci_conf_read32(seg, bus, slot, func, base + bir * 4);
+    addr = pci_conf_read32(sbdf, base + bir * 4);
     if ( (addr & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO )
         return 0;
     if ( (addr & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64 )
@@ -826,8 +809,7 @@ static u64 read_pci_mem_bar(u16 seg, u8 bus, u8 slot, u8 func, u8 bir, int vf)
         if ( ++bir >= limit )
             return 0;
         return addr + disp +
-               ((u64)pci_conf_read32(seg, bus, slot, func,
-                                     base + bir * 4) << 32);
+               ((uint64_t)pci_conf_read32(sbdf, base + bir * 4) << 32);
     }
     return (addr & PCI_BASE_ADDRESS_MEM_MASK) + disp;
 }
@@ -863,7 +845,7 @@ static int msix_capability_init(struct pci_dev *dev,
 
     ASSERT(pcidevs_locked());
 
-    control = pci_conf_read16(seg, bus, slot, func, msix_control_reg(pos));
+    control = pci_conf_read16(dev->sbdf, msix_control_reg(pos));
     /*
      * Ensure MSI-X interrupts are masked during setup. Some devices require
      * MSI-X to be enabled before we can touch the MSI-X registers. We need
@@ -871,13 +853,13 @@ static int msix_capability_init(struct pci_dev *dev,
      * fully set up.
      */
     msix->host_maskall = 1;
-    pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+    pci_conf_write16(dev->sbdf, msix_control_reg(pos),
                      control | (PCI_MSIX_FLAGS_ENABLE |
                                 PCI_MSIX_FLAGS_MASKALL));
 
     if ( unlikely(!memory_decoded(dev)) )
     {
-        pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+        pci_conf_write16(dev->sbdf, msix_control_reg(pos),
                          control & ~PCI_MSIX_FLAGS_ENABLE);
         return -ENXIO;
     }
@@ -887,7 +869,7 @@ static int msix_capability_init(struct pci_dev *dev,
         entry = alloc_msi_entry(1);
         if ( !entry )
         {
-            pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+            pci_conf_write16(dev->sbdf, msix_control_reg(pos),
                              control & ~PCI_MSIX_FLAGS_ENABLE);
             return -ENOMEM;
         }
@@ -895,8 +877,7 @@ static int msix_capability_init(struct pci_dev *dev,
     }
 
     /* Locate MSI-X table region */
-    table_offset = pci_conf_read32(seg, bus, slot, func,
-                                   msix_table_offset_reg(pos));
+    table_offset = pci_conf_read32(dev->sbdf, msix_table_offset_reg(pos));
     bir = (u8)(table_offset & PCI_MSIX_BIRMASK);
     table_offset &= ~PCI_MSIX_BIRMASK;
 
@@ -921,7 +902,7 @@ static int msix_capability_init(struct pci_dev *dev,
     {
         if ( !msi || !msi->table_base )
         {
-            pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+            pci_conf_write16(dev->sbdf, msix_control_reg(pos),
                              control & ~PCI_MSIX_FLAGS_ENABLE);
             xfree(entry);
             return -ENXIO;
@@ -942,8 +923,7 @@ static int msix_capability_init(struct pci_dev *dev,
         WARN_ON(rangeset_overlaps_range(mmio_ro_ranges, msix->table.first,
                                         msix->table.last));
 
-        pba_offset = pci_conf_read32(seg, bus, slot, func,
-                                     msix_pba_offset_reg(pos));
+        pba_offset = pci_conf_read32(dev->sbdf, msix_pba_offset_reg(pos));
         bir = (u8)(pba_offset & PCI_MSIX_BIRMASK);
         pba_paddr = read_pci_mem_bar(seg, pbus, pslot, pfunc, bir, vf);
         WARN_ON(!pba_paddr);
@@ -965,7 +945,7 @@ static int msix_capability_init(struct pci_dev *dev,
 
         if ( idx < 0 )
         {
-            pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+            pci_conf_write16(dev->sbdf, msix_control_reg(pos),
                              control & ~PCI_MSIX_FLAGS_ENABLE);
             xfree(entry);
             return idx;
@@ -1041,7 +1021,7 @@ static int msix_capability_init(struct pci_dev *dev,
         maskall = 0;
     }
     msix->host_maskall = maskall;
-    pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), control);
+    pci_conf_write16(dev->sbdf, msix_control_reg(pos), control);
 
     return 0;
 }
@@ -1130,8 +1110,7 @@ static int __pci_enable_msix(struct msi_info *msi, struct msi_desc **desc)
     if ( !pdev || !pos )
         return -ENODEV;
 
-    control = pci_conf_read16(msi->seg, msi->bus, slot, func,
-                              msix_control_reg(pos));
+    control = pci_conf_read16(pdev->sbdf, msix_control_reg(pos));
     nr_entries = multi_msix_capable(control);
     if ( msi->entry_nr >= nr_entries )
         return -EINVAL;
@@ -1177,14 +1156,14 @@ static void __pci_disable_msix(struct msi_desc *entry)
     uint8_t func = dev->sbdf.func;
     unsigned int pos = pci_find_cap_offset(seg, bus, slot, func,
                                            PCI_CAP_ID_MSIX);
-    u16 control = pci_conf_read16(seg, bus, slot, func,
-                                  msix_control_reg(entry->msi_attrib.pos));
+    uint16_t control = pci_conf_read16(dev->sbdf,
+                                       msix_control_reg(entry->msi_attrib.pos));
     bool maskall = dev->msix->host_maskall;
 
     if ( unlikely(!(control & PCI_MSIX_FLAGS_ENABLE)) )
     {
         dev->msix->host_maskall = 1;
-        pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos),
+        pci_conf_write16(dev->sbdf, msix_control_reg(pos),
                          control | (PCI_MSIX_FLAGS_ENABLE |
                                     PCI_MSIX_FLAGS_MASKALL));
     }
@@ -1203,7 +1182,7 @@ static void __pci_disable_msix(struct msi_desc *entry)
     dev->msix->host_maskall = maskall;
     if ( maskall || dev->msix->guest_maskall )
         control |= PCI_MSIX_FLAGS_MASKALL;
-    pci_conf_write16(seg, bus, slot, func, msix_control_reg(pos), control);
+    pci_conf_write16(dev->sbdf, msix_control_reg(pos), control);
 
     _pci_cleanup_msix(dev->msix);
 }
@@ -1235,8 +1214,7 @@ int pci_prepare_msix(u16 seg, u8 bus, u8 devfn, bool off)
     }
     else
     {
-        u16 control = pci_conf_read16(seg, bus, slot, func,
-                                      msix_control_reg(pos));
+        uint16_t control = pci_conf_read16(pdev->sbdf, msix_control_reg(pos));
 
         rc = msix_capability_init(pdev, pos, NULL, NULL,
                                   multi_msix_capable(control));
@@ -1337,7 +1315,7 @@ int pci_msi_conf_write_intercept(struct pci_dev *pdev, unsigned int reg,
         if ( reg < entry->msi.mpos || reg >= entry->msi.mpos + 4 || size != 4 )
             return -EACCES;
 
-        cntl = pci_conf_read16(seg, bus, slot, func, msi_control_reg(pos));
+        cntl = pci_conf_read16(pdev->sbdf, msi_control_reg(pos));
         unused = ~(uint32_t)0 >> (32 - multi_msi_capable(cntl));
         for ( pos = 0; pos < entry->msi.nvec; ++pos, ++entry )
         {
@@ -1396,8 +1374,7 @@ int pci_restore_msi_state(struct pci_dev *pdev)
                     pdev->sbdf.seg, pdev->sbdf.bus, slot, func, i);
             spin_unlock_irqrestore(&desc->lock, flags);
             if ( type == PCI_CAP_ID_MSIX )
-                pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
-                                 msix_control_reg(pos),
+                pci_conf_write16(pdev->sbdf, msix_control_reg(pos),
                                  control & ~PCI_MSIX_FLAGS_ENABLE);
             return -EINVAL;
         }
@@ -1411,17 +1388,14 @@ int pci_restore_msi_state(struct pci_dev *pdev)
         }
         else if ( !type && entry->msi_attrib.type == PCI_CAP_ID_MSIX )
         {
-            control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, slot,
-                                      func, msix_control_reg(pos));
-            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
-                             msix_control_reg(pos),
+            control = pci_conf_read16(pdev->sbdf, msix_control_reg(pos));
+            pci_conf_write16(pdev->sbdf, msix_control_reg(pos),
                              control | (PCI_MSIX_FLAGS_ENABLE |
                                         PCI_MSIX_FLAGS_MASKALL));
             if ( unlikely(!memory_decoded(pdev)) )
             {
                 spin_unlock_irqrestore(&desc->lock, flags);
-                pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
-                                 msix_control_reg(pos),
+                pci_conf_write16(pdev->sbdf, msix_control_reg(pos),
                                  control & ~PCI_MSIX_FLAGS_ENABLE);
                 return -ENXIO;
             }
@@ -1454,19 +1428,16 @@ int pci_restore_msi_state(struct pci_dev *pdev)
         {
             unsigned int cpos = msi_control_reg(pos);
 
-            control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, slot,
-                                      func, cpos) & ~PCI_MSI_FLAGS_QSIZE;
+            control = pci_conf_read16(pdev->sbdf, cpos) & ~PCI_MSI_FLAGS_QSIZE;
             multi_msi_enable(control, entry->msi.nvec);
-            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func, cpos,
-                             control);
+            pci_conf_write16(pdev->sbdf, cpos, control);
 
             msi_set_enable(pdev, 1);
         }
     }
 
     if ( type == PCI_CAP_ID_MSIX )
-        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, slot, func,
-                         msix_control_reg(pos),
+        pci_conf_write16(pdev->sbdf, msix_control_reg(pos),
                          control | PCI_MSIX_FLAGS_ENABLE);
 
     return 0;
diff --git a/xen/arch/x86/oprofile/op_model_athlon.c b/xen/arch/x86/oprofile/op_model_athlon.c
index 3d6e26f636..33f7394979 100644
--- a/xen/arch/x86/oprofile/op_model_athlon.c
+++ b/xen/arch/x86/oprofile/op_model_athlon.c
@@ -463,7 +463,13 @@ static int __init init_ibs_nmi(void)
 	for (bus = 0; bus < 256; bus++) {
 		for (dev = 0; dev < 32; dev++) {
 			for (func = 0; func < 8; func++) {
-				id = pci_conf_read32(0, bus, dev, func, PCI_VENDOR_ID);
+				const pci_sbdf_t sbdf = {
+				    .bus = bus,
+				    .dev = dev,
+				    .func = func,
+				};
+    
+				id = pci_conf_read32(sbdf, PCI_VENDOR_ID);
 
 				vendor_id = id & 0xffff;
 				dev_id = (id >> 16) & 0xffff;
@@ -471,10 +477,10 @@ static int __init init_ibs_nmi(void)
 				if ((vendor_id == PCI_VENDOR_ID_AMD) &&
 					(dev_id == PCI_DEVICE_ID_AMD_10H_NB_MISC)) {
 
-					pci_conf_write32(0, bus, dev, func, IBSCTL,
+					pci_conf_write32(sbdf, IBSCTL,
 						IBSCTL_LVTOFFSETVAL | APIC_EILVT_LVTOFF_IBS);
 
-					value = pci_conf_read32(0, bus, dev, func, IBSCTL);
+					value = pci_conf_read32(sbdf, IBSCTL);
 
 					if (value != (IBSCTL_LVTOFFSETVAL |
 						APIC_EILVT_LVTOFF_IBS)) {
diff --git a/xen/arch/x86/x86_64/mmconf-fam10h.c b/xen/arch/x86/x86_64/mmconf-fam10h.c
index ed0acb9968..e7f02de894 100644
--- a/xen/arch/x86/x86_64/mmconf-fam10h.c
+++ b/xen/arch/x86/x86_64/mmconf-fam10h.c
@@ -38,21 +38,22 @@ static struct pci_hostbridge_probe pci_probes[] = {
 #define BASE_VALID(b) ((b) + SIZE <= (0xfdULL<<32) || (b) >= (1ULL<<40))
 static void __init get_fam10h_pci_mmconf_base(void)
 {
-	unsigned int i, j, bus, slot, hi_mmio_num;
+	unsigned int i, j, hi_mmio_num;
 	u32 address;
 	u64 val, tom2, start, end;
 	struct range {
 		u64 start, end;
 	} range[8];
+	pci_sbdf_t sbdf = { };
 
 	for (i = 0; i < ARRAY_SIZE(pci_probes); i++) {
 		u32 id;
 		u16 device;
 		u16 vendor;
 
-		bus = pci_probes[i].bus;
-		slot = pci_probes[i].slot;
-		id = pci_conf_read32(0, bus, slot, 0, PCI_VENDOR_ID);
+		sbdf.bus = pci_probes[i].bus;
+		sbdf.dev = pci_probes[i].slot;
+		id = pci_conf_read32(sbdf, PCI_VENDOR_ID);
 
 		vendor = id & 0xffff;
 		device = (id>>16) & 0xffff;
@@ -83,12 +84,12 @@ static void __init get_fam10h_pci_mmconf_base(void)
 	 * above 4G
 	 */
 	for (hi_mmio_num = i = 0; i < 8; i++) {
-		val = pci_conf_read32(0, bus, slot, 1, 0x80 + (i << 3));
+		val = pci_conf_read32(sbdf, 0x80 + (i << 3));
 		if (!(val & 3))
 			continue;
 
 		start = (val & 0xffffff00) << 8; /* 39:16 on 31:8*/
-		val = pci_conf_read32(0, bus, slot, 1, 0x84 + (i << 3));
+		val = pci_conf_read32(sbdf, 0x84 + (i << 3));
 		end = ((val & 0xffffff00) << 8) | 0xffff; /* 39:16 on 31:8*/
 
 		if (end < tom2)
diff --git a/xen/arch/x86/x86_64/mmconfig-shared.c b/xen/arch/x86/x86_64/mmconfig-shared.c
index 9e1c81dcd2..284a788fcd 100644
--- a/xen/arch/x86/x86_64/mmconfig-shared.c
+++ b/xen/arch/x86/x86_64/mmconfig-shared.c
@@ -63,10 +63,8 @@ custom_param("mmcfg", parse_mmcfg);
 
 static const char __init *pci_mmcfg_e7520(void)
 {
-    u32 win;
-    win = pci_conf_read16(0, 0, 0, 0, 0xce);
+    uint32_t win = pci_conf_read16(PCI_SBDF_T(0, 0, 0, 0), 0xce) & 0xf000;
 
-    win = win & 0xf000;
     if(win == 0x0000 || win == 0xf000)
         pci_mmcfg_config_num = 0;
     else {
@@ -89,7 +87,7 @@ static const char __init *pci_mmcfg_intel_945(void)
 
     pci_mmcfg_config_num = 1;
 
-    pciexbar = pci_conf_read32(0, 0, 0, 0, 0x48);
+    pciexbar = pci_conf_read32(PCI_SBDF_T(0, 0, 0, 0), 0x48);
 
     /* Enable bit */
     if (!(pciexbar & 1))
@@ -212,15 +210,18 @@ static const char __init *pci_mmcfg_nvidia_mcp55(void)
     for (i = bus = 0; bus < 256; bus++) {
         u32 l, extcfg;
         u16 vendor, device;
+        const pci_sbdf_t sbdf = {
+            .bus = bus,
+        };
 
-        l = pci_conf_read32(0, bus, 0, 0, 0);
+        l = pci_conf_read32(sbdf, 0);
         vendor = l & 0xffff;
         device = (l >> 16) & 0xffff;
 
         if (PCI_VENDOR_ID_NVIDIA != vendor || 0x0369 != device)
             continue;
 
-        extcfg = pci_conf_read32(0, bus, 0, 0, extcfg_regnum);
+        extcfg = pci_conf_read32(sbdf, extcfg_regnum);
 
         if (extcfg & extcfg_enable_mask)
             i++;
@@ -238,15 +239,18 @@ static const char __init *pci_mmcfg_nvidia_mcp55(void)
         u32 l, extcfg;
         u16 vendor, device;
         int size_index;
+        const pci_sbdf_t sbdf = {
+            .bus = bus,
+        };
 
-        l = pci_conf_read32(0, bus, 0, 0, 0);
+        l = pci_conf_read32(sbdf, 0);
         vendor = l & 0xffff;
         device = (l >> 16) & 0xffff;
 
         if (PCI_VENDOR_ID_NVIDIA != vendor || 0x0369 != device)
             continue;
 
-        extcfg = pci_conf_read32(0, bus, 0, 0, extcfg_regnum);
+        extcfg = pci_conf_read32(sbdf, extcfg_regnum);
 
         if (!(extcfg & extcfg_enable_mask))
             continue;
@@ -300,7 +304,6 @@ static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = {
 static int __init pci_mmcfg_check_hostbridge(void)
 {
     u32 l;
-    u32 bus, devfn;
     u16 vendor, device;
     int i;
     const char *name;
@@ -310,9 +313,8 @@ static int __init pci_mmcfg_check_hostbridge(void)
     name = NULL;
 
     for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
-        bus =  pci_mmcfg_probes[i].bus;
-        devfn = pci_mmcfg_probes[i].devfn;
-        l = pci_conf_read32(0, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), 0);
+        l = pci_conf_read32(PCI_SBDF3_T(0, pci_mmcfg_probes[i].bus,
+                                        pci_mmcfg_probes[i].devfn), 0);
         vendor = l & 0xffff;
         device = (l >> 16) & 0xffff;
 
diff --git a/xen/arch/x86/x86_64/pci.c b/xen/arch/x86/x86_64/pci.c
index 4f77beb119..342c2aa8e6 100644
--- a/xen/arch/x86/x86_64/pci.c
+++ b/xen/arch/x86/x86_64/pci.c
@@ -8,25 +8,20 @@
 #include <xen/pci.h>
 #include <asm/io.h>
 
-#define PCI_CONF_ADDRESS(bus, dev, func, reg) \
-    (0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3))
+#define PCI_CONF_ADDRESS(bdf, reg) (0x80000000 | (bdf << 8) | (reg & ~3))
 
 #define GEN_PCI_CONF_READ(s)                                                   \
-    uint ## s ## _t pci_conf_read ## s (unsigned int seg, unsigned int bus,    \
-                                        unsigned int dev, unsigned int func,   \
-                                        unsigned int reg)                      \
+    uint ## s ## _t pci_conf_read ## s (pci_sbdf_t sbdf, unsigned  int reg)    \
     {                                                                          \
         uint32_t value;                                                        \
                                                                                \
         BUILD_BUG_ON(s != 8 && s != 16 && s != 32);                            \
-        if ( seg || reg > 255 )                                                \
-            pci_mmcfg_read(seg, bus, PCI_DEVFN(dev, func), reg, s / 8, &value);\
+        if ( sbdf.seg || reg > 255 )                                           \
+            pci_mmcfg_read(sbdf.seg, sbdf.bus, sbdf.extfunc, reg, s / 8,       \
+                           &value);                                            \
         else                                                                   \
-        {                                                                      \
-            BUG_ON((bus > 255) || (dev > 31) || (func > 7));                   \
-            value = pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg),       \
+            value = pci_conf_read(PCI_CONF_ADDRESS(sbdf.bdf, reg),             \
                                   reg & (4 - s / 8), s / 8);                   \
-        }                                                                      \
                                                                                \
         return value;                                                          \
     }
@@ -47,19 +42,16 @@ GEN_PCI_CONF_READ(32)
 #undef GEN_PCI_CONF_READ
 
 #define GEN_PCI_CONF_WRITE(s)                                                  \
-    void pci_conf_write ## s (unsigned int seg, unsigned int bus,              \
-                              unsigned int dev, unsigned int func,             \
-                              unsigned int reg, uint ## s ## _t data)          \
+    void pci_conf_write ## s (pci_sbdf_t sbdf, unsigned int reg,               \
+                              uint ## s ## _t data)                            \
     {                                                                          \
         BUILD_BUG_ON(s != 8 && s != 16 && s != 32);                            \
-        if ( seg || reg > 255 )                                                \
-            pci_mmcfg_write(seg, bus, PCI_DEVFN(dev, func), reg, s / 8, data); \
+        if ( sbdf.seg || reg > 255 )                                           \
+            pci_mmcfg_write(sbdf.seg, sbdf.bus, sbdf.extfunc, reg, s / 8,      \
+                            data);                                             \
         else                                                                   \
-        {                                                                      \
-            BUG_ON((bus > 255) || (dev > 31) || (func > 7));                   \
-            pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg),              \
+            pci_conf_write(PCI_CONF_ADDRESS(sbdf.bdf, reg),                    \
                            reg & (4 - s / 8), s / 8, data);                    \
-        }                                                                      \
     }
 
 /* Grep fodder */
diff --git a/xen/drivers/acpi/reboot.c b/xen/drivers/acpi/reboot.c
index 72d06fd8e5..919239faa1 100644
--- a/xen/drivers/acpi/reboot.c
+++ b/xen/drivers/acpi/reboot.c
@@ -23,11 +23,9 @@ void acpi_reboot(void)
 	case ACPI_ADR_SPACE_PCI_CONFIG:
 		printk("Resetting with ACPI PCI RESET_REG.\n");
 		/* Write the value that resets us. */
-		pci_conf_write8(0, 0,
-				(rr->address >> 32) & 31,
-				(rr->address >> 16) & 7,
-				(rr->address & 255),
-				reset_value);
+		pci_conf_write8(PCI_SBDF_T(0, 0, (rr->address >> 32) & 31,
+					   (rr->address >> 16) & 7),
+				(rr->address & 255), reset_value);
 		break;
 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
 	case ACPI_ADR_SPACE_SYSTEM_IO:
diff --git a/xen/drivers/char/ehci-dbgp.c b/xen/drivers/char/ehci-dbgp.c
index 475dc41767..4cd4157353 100644
--- a/xen/drivers/char/ehci-dbgp.c
+++ b/xen/drivers/char/ehci-dbgp.c
@@ -682,7 +682,8 @@ static int dbgp_control_msg(struct ehci_dbgp *dbgp, unsigned int devnum,
 
 static unsigned int __init __find_dbgp(u8 bus, u8 slot, u8 func)
 {
-    u32 class = pci_conf_read32(0, bus, slot, func, PCI_CLASS_REVISION);
+    uint32_t class = pci_conf_read32(PCI_SBDF_T(0, bus, slot, func),
+                                     PCI_CLASS_REVISION);
 
     if ( (class >> 8) != PCI_CLASS_SERIAL_USB_EHCI )
         return 0;
@@ -713,8 +714,9 @@ static unsigned int __init find_dbgp(struct ehci_dbgp *dbgp,
                 cap = __find_dbgp(bus, slot, func);
                 if ( !cap || ehci_num-- )
                 {
-                    if ( !func && !(pci_conf_read8(0, bus, slot, func,
-                                                   PCI_HEADER_TYPE) & 0x80) )
+                    if ( !func &&
+                         !(pci_conf_read8(PCI_SBDF_T(0, bus, slot, func),
+                                          PCI_HEADER_TYPE) & 0x80) )
                         break;
                     continue;
                 }
@@ -1006,17 +1008,22 @@ static set_debug_port_t __read_mostly set_debug_port = default_set_debug_port;
 
 static void nvidia_set_debug_port(struct ehci_dbgp *dbgp, unsigned int port)
 {
-    u32 dword = pci_conf_read32(0, dbgp->bus, dbgp->slot, dbgp->func, 0x74);
+    const pci_sbdf_t sbdf = {
+        .bus = dbgp->bus,
+        .dev = dbgp->slot,
+        .func = dbgp->func,
+    };
+    uint32_t dword = pci_conf_read32(sbdf, 0x74);
 
     dword &= ~(0x0f << 12);
     dword |= (port & 0x0f) << 12;
-    pci_conf_write32(0, dbgp->bus, dbgp->slot, dbgp->func, 0x74, dword);
+    pci_conf_write32(sbdf, 0x74, dword);
     dbgp_printk("set debug port to %u\n", port);
 }
 
 static void __init detect_set_debug_port(struct ehci_dbgp *dbgp)
 {
-    if ( pci_conf_read16(0, dbgp->bus, dbgp->slot, dbgp->func,
+    if ( pci_conf_read16(PCI_SBDF_T(0, dbgp->bus, dbgp->slot, dbgp->func),
                          PCI_VENDOR_ID) == 0x10de )
     {
         dbgp_printk("using nvidia set_debug_port\n");
@@ -1035,17 +1042,22 @@ static void ehci_dbgp_bios_handoff(struct ehci_dbgp *dbgp, u32 hcc_params)
     u32 cap;
     unsigned int offset = HCC_EXT_CAPS(hcc_params);
     int msec;
+    const pci_sbdf_t sbdf = {
+        .bus = dbgp->bus,
+        .dev = dbgp->slot,
+        .func = dbgp->func,
+    };
 
     if ( !offset )
         return;
 
-    cap = pci_conf_read32(0, dbgp->bus, dbgp->slot, dbgp->func, offset);
+    cap = pci_conf_read32(sbdf, offset);
     dbgp_printk("dbgp: EHCI BIOS state %08x\n", cap);
 
     if ( (cap & 0xff) == 1 && (cap & EHCI_USBLEGSUP_BIOS) )
     {
         dbgp_printk("dbgp: BIOS handoff\n");
-        pci_conf_write8(0, dbgp->bus, dbgp->slot, dbgp->func, offset + 3, 1);
+        pci_conf_write8(sbdf, offset + 3, 1);
     }
 
     /* if boot firmware now owns EHCI, spin till it hands it over. */
@@ -1054,7 +1066,7 @@ static void ehci_dbgp_bios_handoff(struct ehci_dbgp *dbgp, u32 hcc_params)
     {
         mdelay(10);
         msec -= 10;
-        cap = pci_conf_read32(0, dbgp->bus, dbgp->slot, dbgp->func, offset);
+        cap = pci_conf_read32(sbdf, offset);
     }
 
     if ( cap & EHCI_USBLEGSUP_BIOS )
@@ -1062,12 +1074,11 @@ static void ehci_dbgp_bios_handoff(struct ehci_dbgp *dbgp, u32 hcc_params)
         /* well, possibly buggy BIOS... try to shut it down,
          * and hope nothing goes too wrong */
         dbgp_printk("dbgp: BIOS handoff failed: %08x\n", cap);
-        pci_conf_write8(0, dbgp->bus, dbgp->slot, dbgp->func, offset + 2, 0);
+        pci_conf_write8(sbdf, offset + 2, 0);
     }
 
     /* just in case, always disable EHCI SMIs */
-    pci_conf_write8(0, dbgp->bus, dbgp->slot, dbgp->func,
-                    offset + EHCI_USBLEGCTLSTS, 0);
+    pci_conf_write8(sbdf, offset + EHCI_USBLEGCTLSTS, 0);
 }
 
 static int ehci_dbgp_setup(struct ehci_dbgp *dbgp)
@@ -1306,19 +1317,21 @@ static void __init ehci_dbgp_init_preirq(struct serial_port *port)
     struct ehci_dbgp *dbgp = port->uart;
     u32 debug_port, offset;
     void __iomem *ehci_bar;
+    const pci_sbdf_t sbdf = {
+        .bus  = dbgp->bus,
+        .dev = dbgp->slot,
+        .func = dbgp->func,
+    };
 
-    debug_port = pci_conf_read32(0, dbgp->bus, dbgp->slot, dbgp->func,
-                                 dbgp->cap);
+    debug_port = pci_conf_read32(sbdf, dbgp->cap);
     offset = (debug_port >> 16) & 0xfff;
 
     /* double check if the mem space is enabled */
-    dbgp->pci_cr = pci_conf_read8(0, dbgp->bus, dbgp->slot, dbgp->func,
-                                  PCI_COMMAND);
+    dbgp->pci_cr = pci_conf_read8(sbdf, PCI_COMMAND);
     if ( !(dbgp->pci_cr & PCI_COMMAND_MEMORY) )
     {
         dbgp->pci_cr |= PCI_COMMAND_MEMORY;
-        pci_conf_write16(0, dbgp->bus, dbgp->slot, dbgp->func, PCI_COMMAND,
-                         dbgp->pci_cr);
+        pci_conf_write16(sbdf, PCI_COMMAND, dbgp->pci_cr);
         dbgp_printk("MMIO for EHCI enabled\n");
     }
 
@@ -1415,8 +1428,8 @@ static void ehci_dbgp_suspend(struct serial_port *port)
     stop_timer(&dbgp->timer);
     dbgp->timer.expires = 0;
 
-    dbgp->pci_cr = pci_conf_read16(0, dbgp->bus, dbgp->slot, dbgp->func,
-                                   PCI_COMMAND);
+    dbgp->pci_cr = pci_conf_read16(PCI_SBDF_T(0, dbgp->bus, dbgp->slot,
+                                              dbgp->func), PCI_COMMAND);
 
     dbgp->state = dbgp_unsafe;
 }
@@ -1424,14 +1437,17 @@ static void ehci_dbgp_suspend(struct serial_port *port)
 static void ehci_dbgp_resume(struct serial_port *port)
 {
     struct ehci_dbgp *dbgp = port->uart;
+    const pci_sbdf_t sbdf = {
+        .bus = dbgp->bus,
+        .dev = dbgp->slot,
+        .func = dbgp->func,
+    };
 
     if ( !dbgp->ehci_debug )
         return;
 
-    pci_conf_write32(0, dbgp->bus, dbgp->slot, dbgp->func, dbgp->bar,
-                     dbgp->bar_val);
-    pci_conf_write16(0, dbgp->bus, dbgp->slot, dbgp->func,
-                     PCI_COMMAND, dbgp->pci_cr);
+    pci_conf_write32(sbdf, dbgp->bar, dbgp->bar_val);
+    pci_conf_write16(sbdf, PCI_COMMAND, dbgp->pci_cr);
 
     ehci_dbgp_setup_preirq(dbgp);
     ehci_dbgp_setup_postirq(dbgp);
@@ -1459,6 +1475,11 @@ void __init ehci_dbgp_init(void)
     struct ehci_dbgp *dbgp = &ehci_dbgp;
     u32 debug_port, offset, bar_val;
     const char *e;
+    const pci_sbdf_t sbdf = {
+        .bus = dbgp->bus,
+        .dev = dbgp->slot,
+        .func = dbgp->func,
+    };
 
     if ( strncmp(opt_dbgp, "ehci", 4) )
         return;
@@ -1502,8 +1523,7 @@ void __init ehci_dbgp_init(void)
     else
         return;
 
-    debug_port = pci_conf_read32(0, dbgp->bus, dbgp->slot, dbgp->func,
-                                 dbgp->cap);
+    debug_port = pci_conf_read32(sbdf, dbgp->cap);
     dbgp->bar = (debug_port >> 29) & 0x7;
     dbgp->bar = ((dbgp->bar - 1) * 4) + PCI_BASE_ADDRESS_0;
     offset = (debug_port >> 16) & 0xfff;
@@ -1514,8 +1534,7 @@ void __init ehci_dbgp_init(void)
         return;
     }
 
-    dbgp->bar_val = bar_val = pci_conf_read32(0, dbgp->bus, dbgp->slot,
-                                              dbgp->func, dbgp->bar);
+    dbgp->bar_val = bar_val = pci_conf_read32(sbdf, dbgp->bar);
     dbgp_printk("bar_val: %08x\n", bar_val);
     if ( bar_val & ~PCI_BASE_ADDRESS_MEM_MASK )
     {
diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index 189e121b7e..698984d879 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -620,20 +620,23 @@ static int ns16550_getc(struct serial_port *port, char *pc)
 static void pci_serial_early_init(struct ns16550 *uart)
 {
 #ifdef CONFIG_HAS_PCI
+    const pci_sbdf_t sbdf = {
+        .bus = uart->pb_bdf[0],
+        .dev = uart->pb_bdf[1],
+        .func = uart->pb_bdf[2],
+    };
+
     if ( !uart->ps_bdf_enable || uart->io_base >= 0x10000 )
         return;
 
     if ( uart->pb_bdf_enable )
-        pci_conf_write16(0, uart->pb_bdf[0], uart->pb_bdf[1], uart->pb_bdf[2],
-                         PCI_IO_BASE,
+        pci_conf_write16(sbdf, PCI_IO_BASE,
                          (uart->io_base & 0xF000) |
                          ((uart->io_base & 0xF000) >> 8));
 
-    pci_conf_write32(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
-                     PCI_BASE_ADDRESS_0,
+    pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0,
                      uart->io_base | PCI_BASE_ADDRESS_SPACE_IO);
-    pci_conf_write16(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
-                     PCI_COMMAND, PCI_COMMAND_IO);
+    pci_conf_write16(sbdf, PCI_COMMAND, PCI_COMMAND_IO);
 #endif
 }
 
@@ -846,8 +849,9 @@ static void ns16550_suspend(struct serial_port *port)
 
 #ifdef CONFIG_HAS_PCI
     if ( uart->bar )
-       uart->cr = pci_conf_read16(0, uart->ps_bdf[0], uart->ps_bdf[1],
-                                  uart->ps_bdf[2], PCI_COMMAND);
+        uart->cr = pci_conf_read16(PCI_SBDF_T(0, uart->ps_bdf[0],
+                                              uart->ps_bdf[1], uart->ps_bdf[2]),
+                                   PCI_COMMAND);
 #endif
 }
 
@@ -855,20 +859,22 @@ static void _ns16550_resume(struct serial_port *port)
 {
 #ifdef CONFIG_HAS_PCI
     struct ns16550 *uart = port->uart;
+    const pci_sbdf_t sbdf = {
+        .bus = uart->ps_bdf[0],
+        .dev = uart->ps_bdf[1],
+        .func = uart->ps_bdf[2],
+    };
 
     if ( uart->bar )
     {
-       pci_conf_write32(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
-                        PCI_BASE_ADDRESS_0 + uart->bar_idx*4, uart->bar);
+       pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + uart->bar_idx*4, uart->bar);
 
         /* If 64 bit BAR, write higher 32 bits to BAR+4 */
         if ( uart->bar & PCI_BASE_ADDRESS_MEM_TYPE_64 )
-            pci_conf_write32(0, uart->ps_bdf[0],
-                        uart->ps_bdf[1], uart->ps_bdf[2],
-                        PCI_BASE_ADDRESS_0 + (uart->bar_idx+1)*4, uart->bar64);
+            pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + (uart->bar_idx+1)*4,
+                             uart->bar64);
 
-       pci_conf_write16(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
-                        PCI_COMMAND, uart->cr);
+       pci_conf_write16(sbdf, PCI_COMMAND, uart->cr);
     }
 #endif
 
@@ -1063,11 +1069,16 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
                 uint32_t bar, bar_64 = 0, len, len_64;
                 u64 size = 0;
                 const struct ns16550_config_param *param = uart_param;
+                const pci_sbdf_t sbdf = {
+                    .bus = b,
+                    .dev = d,
+                    .func = f,
+                };
 
-                nextf = (f || (pci_conf_read16(0, b, d, f, PCI_HEADER_TYPE) &
+                nextf = (f || (pci_conf_read16(sbdf, PCI_HEADER_TYPE) &
                                0x80)) ? f + 1 : 8;
 
-                switch ( pci_conf_read16(0, b, d, f, PCI_CLASS_DEVICE) )
+                switch ( pci_conf_read16(sbdf, PCI_CLASS_DEVICE) )
                 {
                 case 0x0700: /* single port serial */
                 case 0x0702: /* multi port serial */
@@ -1084,8 +1095,8 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
                 /* Check for params in uart_config lookup table */
                 for ( i = 0; i < ARRAY_SIZE(uart_config); i++ )
                 {
-                    u16 vendor = pci_conf_read16(0, b, d, f, PCI_VENDOR_ID);
-                    u16 device = pci_conf_read16(0, b, d, f, PCI_DEVICE_ID);
+                    uint16_t vendor = pci_conf_read16(sbdf, PCI_VENDOR_ID);
+                    uint16_t device = pci_conf_read16(sbdf, PCI_DEVICE_ID);
 
                     if ( uart_config[i].vendor_id == vendor &&
                          uart_config[i].dev_id == device )
@@ -1108,28 +1119,25 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
                 }
 
                 uart->io_base = 0;
-                bar = pci_conf_read32(0, b, d, f,
-                                      PCI_BASE_ADDRESS_0 + bar_idx*4);
+                bar = pci_conf_read32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4);
 
                 /* MMIO based */
                 if ( param->mmio && !(bar & PCI_BASE_ADDRESS_SPACE_IO) )
                 {
-                    pci_conf_write32(0, b, d, f,
-                                     PCI_BASE_ADDRESS_0 + bar_idx*4, ~0u);
-                    len = pci_conf_read32(0, b, d, f, PCI_BASE_ADDRESS_0 + bar_idx*4);
-                    pci_conf_write32(0, b, d, f,
-                                     PCI_BASE_ADDRESS_0 + bar_idx*4, bar);
+                    pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4, ~0u);
+                    len = pci_conf_read32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4);
+                    pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4, bar);
 
                     /* Handle 64 bit BAR if found */
                     if ( bar & PCI_BASE_ADDRESS_MEM_TYPE_64 )
                     {
-                        bar_64 = pci_conf_read32(0, b, d, f,
+                        bar_64 = pci_conf_read32(sbdf,
                                       PCI_BASE_ADDRESS_0 + (bar_idx+1)*4);
-                        pci_conf_write32(0, b, d, f,
+                        pci_conf_write32(sbdf,
                                     PCI_BASE_ADDRESS_0 + (bar_idx+1)*4, ~0u);
-                        len_64 = pci_conf_read32(0, b, d, f,
+                        len_64 = pci_conf_read32(sbdf,
                                     PCI_BASE_ADDRESS_0 + (bar_idx+1)*4);
-                        pci_conf_write32(0, b, d, f,
+                        pci_conf_write32(sbdf,
                                     PCI_BASE_ADDRESS_0 + (bar_idx+1)*4, bar_64);
                         size  = ((u64)~0 << 32) | PCI_BASE_ADDRESS_MEM_MASK;
                         size &= ((u64)len_64 << 32) | len;
@@ -1143,11 +1151,9 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
                 /* IO based */
                 else if ( !param->mmio && (bar & PCI_BASE_ADDRESS_SPACE_IO) )
                 {
-                    pci_conf_write32(0, b, d, f,
-                                     PCI_BASE_ADDRESS_0 + bar_idx*4, ~0u);
-                    len = pci_conf_read32(0, b, d, f, PCI_BASE_ADDRESS_0);
-                    pci_conf_write32(0, b, d, f,
-                                     PCI_BASE_ADDRESS_0 + bar_idx*4, bar);
+                    pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4, ~0u);
+                    len = pci_conf_read32(sbdf, PCI_BASE_ADDRESS_0);
+                    pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + bar_idx*4, bar);
                     size = len & PCI_BASE_ADDRESS_IO_MASK;
 
                     uart->io_base = bar & ~PCI_BASE_ADDRESS_SPACE_IO;
@@ -1188,8 +1194,8 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
                 uart->bar64 = bar_64;
                 uart->io_size = max(8U << param->reg_shift,
                                     param->uart_offset);
-                uart->irq = pci_conf_read8(0, b, d, f, PCI_INTERRUPT_PIN) ?
-                    pci_conf_read8(0, b, d, f, PCI_INTERRUPT_LINE) : 0;
+                uart->irq = pci_conf_read8(sbdf, PCI_INTERRUPT_PIN) ?
+                    pci_conf_read8(sbdf, PCI_INTERRUPT_LINE) : 0;
 
                 return 0;
             }
diff --git a/xen/drivers/passthrough/amd/iommu_detect.c b/xen/drivers/passthrough/amd/iommu_detect.c
index 3c5d4de1a3..e8d8ec59bd 100644
--- a/xen/drivers/passthrough/amd/iommu_detect.c
+++ b/xen/drivers/passthrough/amd/iommu_detect.c
@@ -48,7 +48,8 @@ static int __init get_iommu_capabilities(
 {
     u8 type;
 
-    iommu->cap.header = pci_conf_read32(seg, bus, dev, func, cap_ptr);
+    iommu->cap.header = pci_conf_read32(PCI_SBDF_T(seg, bus, dev, func),
+                                        cap_ptr);
     type = get_field_from_reg_u32(iommu->cap.header, PCI_CAP_TYPE_MASK,
                                   PCI_CAP_TYPE_SHIFT);
 
diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c
index 17f39552a9..fe0516f788 100644
--- a/xen/drivers/passthrough/amd/iommu_init.c
+++ b/xen/drivers/passthrough/amd/iommu_init.c
@@ -798,8 +798,7 @@ static bool_t __init set_iommu_interrupt_handler(struct amd_iommu *iommu)
                         PCI_SLOT(iommu->bdf), PCI_FUNC(iommu->bdf));
         return 0;
     }
-    control = pci_conf_read16(iommu->seg, PCI_BUS(iommu->bdf),
-                              PCI_SLOT(iommu->bdf), PCI_FUNC(iommu->bdf),
+    control = pci_conf_read16(iommu->msi.dev->sbdf,
                               iommu->msi.msi_attrib.pos + PCI_MSI_FLAGS);
     iommu->msi.msi.nvec = 1;
     if ( is_mask_bit_support(control) )
@@ -835,6 +834,10 @@ static bool_t __init set_iommu_interrupt_handler(struct amd_iommu *iommu)
 static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
 {
     u32 value;
+    const pci_sbdf_t sbdf = {
+        .seg = iommu->seg,
+        .bdf = iommu->bdf,
+    };
     u8 bus = PCI_BUS(iommu->bdf);
     u8 dev = PCI_SLOT(iommu->bdf);
     u8 func = PCI_FUNC(iommu->bdf);
@@ -844,22 +847,22 @@ static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
          (boot_cpu_data.x86_model > 0x1f) )
         return;
 
-    pci_conf_write32(iommu->seg, bus, dev, func, 0xf0, 0x90);
-    value = pci_conf_read32(iommu->seg, bus, dev, func, 0xf4);
+    pci_conf_write32(sbdf, 0xf0, 0x90);
+    value = pci_conf_read32(sbdf, 0xf4);
 
     if ( value & (1 << 2) )
         return;
 
     /* Select NB indirect register 0x90 and enable writing */
-    pci_conf_write32(iommu->seg, bus, dev, func, 0xf0, 0x90 | (1 << 8));
+    pci_conf_write32(sbdf, 0xf0, 0x90 | (1 << 8));
 
-    pci_conf_write32(iommu->seg, bus, dev, func, 0xf4, value | (1 << 2));
+    pci_conf_write32(sbdf, 0xf4, value | (1 << 2));
     printk(XENLOG_INFO
            "AMD-Vi: Applying erratum 746 workaround for IOMMU at %04x:%02x:%02x.%u\n",
            iommu->seg, bus, dev, func);
 
     /* Clear the enable writing bit */
-    pci_conf_write32(iommu->seg, bus, dev, func, 0xf0, 0x90);
+    pci_conf_write32(sbdf, 0xf0, 0x90);
 }
 
 static void enable_iommu(struct amd_iommu *iommu)
@@ -1203,7 +1206,12 @@ static bool_t __init amd_sp5100_erratum28(void)
 
     for (bus = 0; bus < 256; bus++)
     {
-        id = pci_conf_read32(0, bus, 0x14, 0, PCI_VENDOR_ID);
+        const pci_sbdf_t sbdf = {
+            .bus = bus,
+            .dev = 0x14,
+        };
+
+        id = pci_conf_read32(sbdf, PCI_VENDOR_ID);
 
         vendor_id = id & 0xffff;
         dev_id = (id >> 16) & 0xffff;
@@ -1212,7 +1220,7 @@ static bool_t __init amd_sp5100_erratum28(void)
         if (vendor_id != 0x1002 || dev_id != 0x4385)
             continue;
 
-        byte = pci_conf_read8(0, bus, 0x14, 0, 0xad);
+        byte = pci_conf_read8(sbdf, 0xad);
         if ( (byte >> 3) & 1 )
         {
             printk(XENLOG_WARNING "AMD-Vi: SP5100 erratum 28 detected, disabling IOMMU.\n"
diff --git a/xen/drivers/passthrough/ats.h b/xen/drivers/passthrough/ats.h
index bee13911c0..e83a45d16e 100644
--- a/xen/drivers/passthrough/ats.h
+++ b/xen/drivers/passthrough/ats.h
@@ -35,8 +35,8 @@ static inline int pci_ats_enabled(int seg, int bus, int devfn)
     pos = pci_find_ext_capability(seg, bus, devfn, PCI_EXT_CAP_ID_ATS);
     BUG_ON(!pos);
 
-    value = pci_conf_read16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                            pos + ATS_REG_CTL);
+    value = pci_conf_read16(PCI_SBDF3_T(seg, bus, devfn), pos + ATS_REG_CTL);
+
     return value & ATS_ENABLE;
 }
 
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index 8de8d8e110..94fb3a183d 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -246,36 +246,34 @@ static void check_pdev(const struct pci_dev *pdev)
 
     if ( command_mask )
     {
-        val = pci_conf_read16(seg, bus, dev, func, PCI_COMMAND);
+        val = pci_conf_read16(pdev->sbdf, PCI_COMMAND);
         if ( val & command_mask )
-            pci_conf_write16(seg, bus, dev, func, PCI_COMMAND,
-                             val & ~command_mask);
-        val = pci_conf_read16(seg, bus, dev, func, PCI_STATUS);
+            pci_conf_write16(pdev->sbdf, PCI_COMMAND, val & ~command_mask);
+        val = pci_conf_read16(pdev->sbdf, PCI_STATUS);
         if ( val & PCI_STATUS_CHECK )
         {
             printk(XENLOG_INFO "%04x:%02x:%02x.%u status %04x -> %04x\n",
                    seg, bus, dev, func, val, val & ~PCI_STATUS_CHECK);
-            pci_conf_write16(seg, bus, dev, func, PCI_STATUS,
-                             val & PCI_STATUS_CHECK);
+            pci_conf_write16(pdev->sbdf, PCI_STATUS, val & PCI_STATUS_CHECK);
         }
     }
 
-    switch ( pci_conf_read8(seg, bus, dev, func, PCI_HEADER_TYPE) & 0x7f )
+    switch ( pci_conf_read8(pdev->sbdf, PCI_HEADER_TYPE) & 0x7f )
     {
     case PCI_HEADER_TYPE_BRIDGE:
         if ( !bridge_ctl_mask )
             break;
-        val = pci_conf_read16(seg, bus, dev, func, PCI_BRIDGE_CONTROL);
+        val = pci_conf_read16(pdev->sbdf, PCI_BRIDGE_CONTROL);
         if ( val & bridge_ctl_mask )
-            pci_conf_write16(seg, bus, dev, func, PCI_BRIDGE_CONTROL,
+            pci_conf_write16(pdev->sbdf, PCI_BRIDGE_CONTROL,
                              val & ~bridge_ctl_mask);
-        val = pci_conf_read16(seg, bus, dev, func, PCI_SEC_STATUS);
+        val = pci_conf_read16(pdev->sbdf, PCI_SEC_STATUS);
         if ( val & PCI_STATUS_CHECK )
         {
             printk(XENLOG_INFO
                    "%04x:%02x:%02x.%u secondary status %04x -> %04x\n",
                    seg, bus, dev, func, val, val & ~PCI_STATUS_CHECK);
-            pci_conf_write16(seg, bus, dev, func, PCI_SEC_STATUS,
+            pci_conf_write16(pdev->sbdf, PCI_SEC_STATUS,
                              val & PCI_STATUS_CHECK);
         }
         break;
@@ -289,12 +287,8 @@ static void check_pdev(const struct pci_dev *pdev)
 
 static void apply_quirks(struct pci_dev *pdev)
 {
-    uint16_t vendor = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
-                                      pdev->sbdf.dev, pdev->sbdf.func,
-                                      PCI_VENDOR_ID);
-    uint16_t device = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
-                                      pdev->sbdf.dev, pdev->sbdf.func,
-                                      PCI_DEVICE_ID);
+    uint16_t vendor = pci_conf_read16(pdev->sbdf, PCI_VENDOR_ID);
+    uint16_t device = pci_conf_read16(pdev->sbdf, PCI_DEVICE_ID);
     static const struct {
         uint16_t vendor, device;
     } ignore_bars[] = {
@@ -368,10 +362,8 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
 
         case DEV_TYPE_PCIe2PCI_BRIDGE:
         case DEV_TYPE_LEGACY_PCI_BRIDGE:
-            sec_bus = pci_conf_read8(pseg->nr, bus, PCI_SLOT(devfn),
-                                     PCI_FUNC(devfn), PCI_SECONDARY_BUS);
-            sub_bus = pci_conf_read8(pseg->nr, bus, PCI_SLOT(devfn),
-                                     PCI_FUNC(devfn), PCI_SUBORDINATE_BUS);
+            sec_bus = pci_conf_read8(pdev->sbdf, PCI_SECONDARY_BUS);
+            sub_bus = pci_conf_read8(pdev->sbdf, PCI_SUBORDINATE_BUS);
 
             spin_lock(&pseg->bus2bridge_lock);
             for ( ; sec_bus <= sub_bus; sec_bus++ )
@@ -387,8 +379,7 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
             pos = pci_find_cap_offset(pseg->nr, bus, PCI_SLOT(devfn),
                                       PCI_FUNC(devfn), PCI_CAP_ID_EXP);
             BUG_ON(!pos);
-            cap = pci_conf_read16(pseg->nr, bus, PCI_SLOT(devfn),
-                                  PCI_FUNC(devfn), pos + PCI_EXP_DEVCAP);
+            cap = pci_conf_read16(pdev->sbdf, pos + PCI_EXP_DEVCAP);
             if ( cap & PCI_EXP_DEVCAP_PHANTOM )
             {
                 pdev->phantom_stride = 8 >> MASK_EXTR(cap,
@@ -438,10 +429,8 @@ static void free_pdev(struct pci_seg *pseg, struct pci_dev *pdev)
 
         case DEV_TYPE_PCIe2PCI_BRIDGE:
         case DEV_TYPE_LEGACY_PCI_BRIDGE:
-            sec_bus = pci_conf_read8(pseg->nr, pdev->sbdf.bus, pdev->sbdf.dev,
-                                     pdev->sbdf.func, PCI_SECONDARY_BUS);
-            sub_bus = pci_conf_read8(pseg->nr, pdev->sbdf.bus, pdev->sbdf.dev,
-                                     pdev->sbdf.func, PCI_SUBORDINATE_BUS);
+            sec_bus = pci_conf_read8(pdev->sbdf, PCI_SECONDARY_BUS);
+            sub_bus = pci_conf_read8(pdev->sbdf, PCI_SUBORDINATE_BUS);
 
             spin_lock(&pseg->bus2bridge_lock);
             for ( ; sec_bus <= sub_bus; sec_bus++ )
@@ -603,8 +592,6 @@ static void pci_enable_acs(struct pci_dev *pdev)
     int pos;
     uint16_t cap, ctrl, seg = pdev->sbdf.seg;
     uint8_t bus = pdev->sbdf.bus;
-    uint8_t dev = pdev->sbdf.dev;
-    uint8_t func = pdev->sbdf.func;
 
     if ( !iommu_enabled )
         return;
@@ -613,8 +600,8 @@ static void pci_enable_acs(struct pci_dev *pdev)
     if (!pos)
         return;
 
-    cap = pci_conf_read16(seg, bus, dev, func, pos + PCI_ACS_CAP);
-    ctrl = pci_conf_read16(seg, bus, dev, func, pos + PCI_ACS_CTRL);
+    cap = pci_conf_read16(pdev->sbdf, pos + PCI_ACS_CAP);
+    ctrl = pci_conf_read16(pdev->sbdf, pos + PCI_ACS_CTRL);
 
     /* Source Validation */
     ctrl |= (cap & PCI_ACS_SV);
@@ -628,7 +615,7 @@ static void pci_enable_acs(struct pci_dev *pdev)
     /* Upstream Forwarding */
     ctrl |= (cap & PCI_ACS_UF);
 
-    pci_conf_write16(seg, bus, dev, func, pos + PCI_ACS_CTRL, ctrl);
+    pci_conf_write16(pdev->sbdf, pos + PCI_ACS_CTRL, ctrl);
 }
 
 static int iommu_add_device(struct pci_dev *pdev);
@@ -639,8 +626,7 @@ unsigned int pci_size_mem_bar(pci_sbdf_t sbdf, unsigned int pos,
                               uint64_t *paddr, uint64_t *psize,
                               unsigned int flags)
 {
-    uint32_t hi = 0, bar = pci_conf_read32(sbdf.seg, sbdf.bus, sbdf.dev,
-                                           sbdf.func, pos);
+    uint32_t hi = 0, bar = pci_conf_read32(sbdf, pos);
     uint64_t size;
     bool is64bits = !(flags & PCI_BAR_ROM) &&
         (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64;
@@ -650,7 +636,7 @@ unsigned int pci_size_mem_bar(pci_sbdf_t sbdf, unsigned int pos,
     ASSERT(!((flags & PCI_BAR_VF) && (flags & PCI_BAR_ROM)));
     ASSERT((flags & PCI_BAR_ROM) ||
            (bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY);
-    pci_conf_write32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos, ~0);
+    pci_conf_write32(sbdf, pos, ~0);
     if ( is64bits )
     {
         if ( flags & PCI_BAR_LAST )
@@ -662,20 +648,18 @@ unsigned int pci_size_mem_bar(pci_sbdf_t sbdf, unsigned int pos,
             *psize = 0;
             return 1;
         }
-        hi = pci_conf_read32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos + 4);
-        pci_conf_write32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos + 4, ~0);
+        hi = pci_conf_read32(sbdf, pos + 4);
+        pci_conf_write32(sbdf, pos + 4, ~0);
     }
-    size = pci_conf_read32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func,
-                           pos) & mask;
+    size = pci_conf_read32(sbdf, pos) & mask;
     if ( is64bits )
     {
-        size |= (uint64_t)pci_conf_read32(sbdf.seg, sbdf.bus, sbdf.dev,
-                                          sbdf.func, pos + 4) << 32;
-        pci_conf_write32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos + 4, hi);
+        size |= (uint64_t)pci_conf_read32(sbdf, pos + 4) << 32;
+        pci_conf_write32(sbdf, pos + 4, hi);
     }
     else if ( size )
         size |= (uint64_t)~0 << 32;
-    pci_conf_write32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, pos, bar);
+    pci_conf_write32(sbdf, pos, bar);
     size = -size;
 
     if ( paddr )
@@ -745,7 +729,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
     {
         unsigned int pos = pci_find_ext_capability(seg, bus, devfn,
                                                    PCI_EXT_CAP_ID_SRIOV);
-        u16 ctrl = pci_conf_read16(seg, bus, slot, func, pos + PCI_SRIOV_CTRL);
+        u16 ctrl = pci_conf_read16(pdev->sbdf, pos + PCI_SRIOV_CTRL);
 
         if ( !pos )
             /* Nothing */;
@@ -757,10 +741,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
             for ( i = 0; i < PCI_SRIOV_NUM_BARS; )
             {
                 unsigned int idx = pos + PCI_SRIOV_BAR + i * 4;
-                u32 bar = pci_conf_read32(seg, bus, slot, func, idx);
-                pci_sbdf_t sbdf = {
-                    .sbdf = PCI_SBDF3(seg, bus, devfn),
-                };
+                uint32_t bar = pci_conf_read32(pdev->sbdf, idx);
 
                 if ( (bar & PCI_BASE_ADDRESS_SPACE) ==
                      PCI_BASE_ADDRESS_SPACE_IO )
@@ -771,7 +752,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
                            seg, bus, slot, func, i);
                     continue;
                 }
-                ret = pci_size_mem_bar(sbdf, idx, NULL, &pdev->vf_rlen[i],
+                ret = pci_size_mem_bar(pdev->sbdf, idx, NULL, &pdev->vf_rlen[i],
                                        PCI_BAR_VF |
                                        ((i == PCI_SRIOV_NUM_BARS - 1) ?
                                         PCI_BAR_LAST : 0));
@@ -940,14 +921,20 @@ enum pdev_type pdev_type(u16 seg, u8 bus, u8 devfn)
     u16 class_device, creg;
     u8 d = PCI_SLOT(devfn), f = PCI_FUNC(devfn);
     int pos = pci_find_cap_offset(seg, bus, d, f, PCI_CAP_ID_EXP);
+    const pci_sbdf_t sbdf = {
+        .seg = seg,
+        .bus = bus,
+        .dev = d,
+        .func = f,
+    };
 
-    class_device = pci_conf_read16(seg, bus, d, f, PCI_CLASS_DEVICE);
+    class_device = pci_conf_read16(sbdf, PCI_CLASS_DEVICE);
     switch ( class_device )
     {
     case PCI_CLASS_BRIDGE_PCI:
         if ( !pos )
             return DEV_TYPE_LEGACY_PCI_BRIDGE;
-        creg = pci_conf_read16(seg, bus, d, f, pos + PCI_EXP_FLAGS);
+        creg = pci_conf_read16(sbdf, pos + PCI_EXP_FLAGS);
         switch ( (creg & PCI_EXP_FLAGS_TYPE) >> 4 )
         {
         case PCI_EXP_TYPE_PCI_BRIDGE:
@@ -1011,7 +998,7 @@ bool_t __init pci_device_detect(u16 seg, u8 bus, u8 dev, u8 func)
 {
     u32 vendor;
 
-    vendor = pci_conf_read32(seg, bus, dev, func, PCI_VENDOR_ID);
+    vendor = pci_conf_read32(PCI_SBDF_T(seg, bus, dev, func), PCI_VENDOR_ID);
     /* some broken boards return 0 or ~0 if a slot is empty: */
     if ( (vendor == 0xffffffff) || (vendor == 0x00000000) ||
          (vendor == 0x0000ffff) || (vendor == 0xffff0000) )
@@ -1043,10 +1030,8 @@ void pci_check_disable_device(u16 seg, u8 bus, u8 devfn)
 
     /* Tell the device to stop DMAing; we can't rely on the guest to
      * control it for us. */
-    cword = pci_conf_read16(seg, bus, pdev->sbdf.dev, pdev->sbdf.func,
-                            PCI_COMMAND);
-    pci_conf_write16(seg, bus, pdev->sbdf.dev, pdev->sbdf.func,
-                     PCI_COMMAND, cword & ~PCI_COMMAND_MASTER);
+    cword = pci_conf_read16(pdev->sbdf, PCI_COMMAND);
+    pci_conf_write16(pdev->sbdf, PCI_COMMAND, cword & ~PCI_COMMAND_MASTER);
 }
 
 /*
@@ -1079,7 +1064,7 @@ static int __init _scan_pci_devices(struct pci_seg *pseg, void *arg)
                     return -ENOMEM;
                 }
 
-                if ( !func && !(pci_conf_read8(pseg->nr, bus, dev, func,
+                if ( !func && !(pci_conf_read8(pdev->sbdf,
                                                PCI_HEADER_TYPE) & 0x80) )
                     break;
             }
@@ -1210,9 +1195,7 @@ static bool_t hest_match_type(const struct acpi_hest_header *hest_hdr,
     unsigned int pos = pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus,
                                            pdev->sbdf.dev, pdev->sbdf.func,
                                            PCI_CAP_ID_EXP);
-    uint8_t pcie = MASK_EXTR(pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
-                                             pdev->sbdf.dev, pdev->sbdf.func,
-                                             pos + PCI_EXP_FLAGS),
+    uint8_t pcie = MASK_EXTR(pci_conf_read16(pdev->sbdf, pos + PCI_EXP_FLAGS),
                              PCI_EXP_FLAGS_TYPE);
 
     switch ( hest_hdr->type )
@@ -1222,8 +1205,7 @@ static bool_t hest_match_type(const struct acpi_hest_header *hest_hdr,
     case ACPI_HEST_TYPE_AER_ENDPOINT:
         return pcie == PCI_EXP_TYPE_ENDPOINT;
     case ACPI_HEST_TYPE_AER_BRIDGE:
-        return pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                               pdev->sbdf.func, PCI_CLASS_DEVICE) ==
+        return pci_conf_read16(pdev->sbdf, PCI_CLASS_DEVICE) ==
                PCI_CLASS_BRIDGE_PCI;
     }
 
diff --git a/xen/drivers/passthrough/vtd/dmar.c b/xen/drivers/passthrough/vtd/dmar.c
index effaf93222..9d30188ab9 100644
--- a/xen/drivers/passthrough/vtd/dmar.c
+++ b/xen/drivers/passthrough/vtd/dmar.c
@@ -348,7 +348,7 @@ static int __init acpi_parse_dev_scope(
 
         while ( --depth > 0 )
         {
-            bus = pci_conf_read8(seg, bus, path->dev, path->fn,
+            bus = pci_conf_read8(PCI_SBDF_T(seg, bus, path->dev, path->fn),
                                  PCI_SECONDARY_BUS);
             path++;
         }
@@ -356,10 +356,16 @@ static int __init acpi_parse_dev_scope(
         switch ( acpi_scope->entry_type )
         {
         case ACPI_DMAR_SCOPE_TYPE_BRIDGE:
-            sec_bus = pci_conf_read8(seg, bus, path->dev, path->fn,
-                                     PCI_SECONDARY_BUS);
-            sub_bus = pci_conf_read8(seg, bus, path->dev, path->fn,
-                                     PCI_SUBORDINATE_BUS);
+        {
+            const pci_sbdf_t sbdf = {
+                .seg = seg,
+                .bus = bus,
+                .dev = path->dev,
+                .func = path->fn,
+            };
+
+            sec_bus = pci_conf_read8(sbdf, PCI_SECONDARY_BUS);
+            sub_bus = pci_conf_read8(sbdf, PCI_SUBORDINATE_BUS);
             if ( iommu_verbose )
                 printk(VTDPREFIX
                        " bridge: %04x:%02x:%02x.%u start=%x sec=%x sub=%x\n",
@@ -368,7 +374,7 @@ static int __init acpi_parse_dev_scope(
 
             dmar_scope_add_buses(scope, sec_bus, sub_bus);
             break;
-
+        }
         case ACPI_DMAR_SCOPE_TYPE_HPET:
             if ( iommu_verbose )
                 printk(VTDPREFIX " MSI HPET: %04x:%02x:%02x.%u\n",
diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c
index fa811605ee..48c7384b82 100644
--- a/xen/drivers/passthrough/vtd/quirks.c
+++ b/xen/drivers/passthrough/vtd/quirks.c
@@ -61,6 +61,14 @@ static bool_t __read_mostly is_snb_gfx;
 static u8 *__read_mostly igd_reg_va;
 static spinlock_t igd_lock;
 
+static const pci_sbdf_t igd_sbdf = {
+    .dev = IGD_DEV,
+};
+
+static const pci_sbdf_t ioh_sbdf = {
+    .dev = IOH_DEV,
+};
+
 /*
  * QUIRK to workaround Xen boot issue on Calpella/Ironlake OEM BIOS
  * not enabling VT-d properly in IGD.  The workaround is to not enabling
@@ -74,7 +82,7 @@ int is_igd_vt_enabled_quirk(void)
         return 1;
 
     /* integrated graphics on Intel platforms is located at 0:2.0 */
-    ggc = pci_conf_read16(0, 0, IGD_DEV, 0, GGC);
+    ggc = pci_conf_read16(igd_sbdf, GGC);
     return ( ggc & GGC_MEMORY_VT_ENABLED ? 1 : 0 );
 }
 
@@ -88,12 +96,12 @@ static void __init cantiga_b3_errata_init(void)
     u16 vid;
     u8 did_hi, rid;
 
-    vid = pci_conf_read16(0, 0, IGD_DEV, 0, 0);
+    vid = pci_conf_read16(igd_sbdf, 0);
     if ( vid != 0x8086 )
         return;
 
-    did_hi = pci_conf_read8(0, 0, IGD_DEV, 0, 3);
-    rid = pci_conf_read8(0, 0, IGD_DEV, 0, 8);
+    did_hi = pci_conf_read8(igd_sbdf, 3);
+    rid = pci_conf_read8(igd_sbdf, 8);
 
     if ( (did_hi == 0x2A) && (rid == 0x7) )
         is_cantiga_b3 = 1;
@@ -128,9 +136,9 @@ static void __init map_igd_reg(void)
     if ( igd_reg_va )
         return;
 
-    igd_mmio   = pci_conf_read32(0, 0, IGD_DEV, 0, PCI_BASE_ADDRESS_1);
+    igd_mmio   = pci_conf_read32(igd_sbdf, PCI_BASE_ADDRESS_1);
     igd_mmio <<= 32;
-    igd_mmio  += pci_conf_read32(0, 0, IGD_DEV, 0, PCI_BASE_ADDRESS_0);
+    igd_mmio  += pci_conf_read32(igd_sbdf, PCI_BASE_ADDRESS_0);
     igd_reg_va = ioremap(igd_mmio & IGD_BAR_MASK, 0x3000);
 }
 
@@ -279,9 +287,14 @@ static void __init tylersburg_intremap_quirk(void)
 
     for ( bus = 0; bus < 0x100; bus++ )
     {
+        const pci_sbdf_t sbdf = {
+            .bus = bus,
+            .dev = 20,
+        };
+
         /* Match on System Management Registers on Device 20 Function 0 */
-        device = pci_conf_read32(0, bus, 20, 0, PCI_VENDOR_ID);
-        rev = pci_conf_read8(0, bus, 20, 0, PCI_REVISION_ID);
+        device = pci_conf_read32(sbdf, PCI_VENDOR_ID);
+        rev = pci_conf_read8(sbdf, PCI_REVISION_ID);
 
         if ( rev == 0x13 && device == 0x342e8086 )
         {
@@ -296,8 +309,8 @@ static void __init tylersburg_intremap_quirk(void)
 /* initialize platform identification flags */
 void __init platform_quirks_init(void)
 {
-    ioh_id = pci_conf_read32(0, 0, IOH_DEV, 0, 0);
-    igd_id = pci_conf_read32(0, 0, IGD_DEV, 0, 0);
+    ioh_id = pci_conf_read32(ioh_sbdf, 0);
+    igd_id = pci_conf_read32(igd_sbdf, 0);
 
     /* Mobile 4 Series Chipset neglects to set RWBF capability. */
     if ( ioh_id == 0x2a408086 )
@@ -356,15 +369,15 @@ int me_wifi_quirk(struct domain *domain, u8 bus, u8 devfn, int map)
     u32 id;
     int rc = 0;
 
-    id = pci_conf_read32(0, 0, 0, 0, 0);
+    id = pci_conf_read32(PCI_SBDF_T(0, 0, 0, 0), 0);
     if ( IS_CTG(id) )
     {
         /* quit if ME does not exist */
-        if ( pci_conf_read32(0, 0, 3, 0, 0) == 0xffffffff )
+        if ( pci_conf_read32(PCI_SBDF_T(0, 0, 3, 0), 0) == 0xffffffff )
             return 0;
 
         /* if device is WLAN device, map ME phantom device 0:3.7 */
-        id = pci_conf_read32(0, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), 0);
+        id = pci_conf_read32(PCI_SBDF3_T(0, bus, devfn), 0);
         switch (id)
         {
             case 0x42328086:
@@ -384,11 +397,11 @@ int me_wifi_quirk(struct domain *domain, u8 bus, u8 devfn, int map)
     else if ( IS_ILK(id) || IS_CPT(id) )
     {
         /* quit if ME does not exist */
-        if ( pci_conf_read32(0, 0, 22, 0, 0) == 0xffffffff )
+        if ( pci_conf_read32(PCI_SBDF_T(0, 0, 22, 0), 0) == 0xffffffff )
             return 0;
 
         /* if device is WLAN device, map ME phantom device 0:22.7 */
-        id = pci_conf_read32(0, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), 0);
+        id = pci_conf_read32(PCI_SBDF3_T(0, bus, devfn), 0);
         switch (id)
         {
             case 0x00878086:        /* Kilmer Peak */
@@ -424,11 +437,11 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
     paddr_t pa;
     const char *action;
 
-    if ( pci_conf_read16(seg, bus, dev, func, PCI_VENDOR_ID) !=
+    if ( pci_conf_read16(pdev->sbdf, PCI_VENDOR_ID) !=
          PCI_VENDOR_ID_INTEL )
         return;
 
-    switch ( pci_conf_read16(seg, bus, dev, func, PCI_DEVICE_ID) )
+    switch ( pci_conf_read16(pdev->sbdf, PCI_DEVICE_ID) )
     {
     /*
      * Mask reporting Intel VT-d faults to IOH core logic:
@@ -439,8 +452,8 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
     case 0x342e: /* Tylersburg chipset (Nehalem / Westmere systems) */
     case 0x3728: /* Xeon C5500/C3500 (JasperForest) */
     case 0x3c28: /* Sandybridge */
-        val = pci_conf_read32(seg, bus, dev, func, 0x1AC);
-        pci_conf_write32(seg, bus, dev, func, 0x1AC, val | (1 << 31));
+        val = pci_conf_read32(pdev->sbdf, 0x1AC);
+        pci_conf_write32(pdev->sbdf, 0x1AC, val | (1 << 31));
         printk(XENLOG_INFO "Masked VT-d error signaling on %04x:%02x:%02x.%u\n",
                seg, bus, dev, func);
         break;
@@ -462,7 +475,7 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
                                           PCI_EXT_CAP_ID_VNDR);
             while ( pos )
             {
-                val = pci_conf_read32(seg, bus, dev, func, pos + PCI_VNDR_HEADER);
+                val = pci_conf_read32(pdev->sbdf, pos + PCI_VNDR_HEADER);
                 if ( PCI_VNDR_HEADER_ID(val) == 4 && PCI_VNDR_HEADER_REV(val) == 1 )
                 {
                     pos += PCI_VNDR_HEADER;
@@ -482,15 +495,15 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
             break;
         }
 
-        val = pci_conf_read32(seg, bus, dev, func, pos + PCI_ERR_UNCOR_MASK);
-        val2 = pci_conf_read32(seg, bus, dev, func, pos + PCI_ERR_COR_MASK);
+        val = pci_conf_read32(pdev->sbdf, pos + PCI_ERR_UNCOR_MASK);
+        val2 = pci_conf_read32(pdev->sbdf, pos + PCI_ERR_COR_MASK);
         if ( (val & PCI_ERR_UNC_UNSUP) && (val2 & PCI_ERR_COR_ADV_NFAT) )
             action = "Found masked";
         else if ( !ff )
         {
-            pci_conf_write32(seg, bus, dev, func, pos + PCI_ERR_UNCOR_MASK,
+            pci_conf_write32(pdev->sbdf, pos + PCI_ERR_UNCOR_MASK,
                              val | PCI_ERR_UNC_UNSUP);
-            pci_conf_write32(seg, bus, dev, func, pos + PCI_ERR_COR_MASK,
+            pci_conf_write32(pdev->sbdf, pos + PCI_ERR_COR_MASK,
                              val2 | PCI_ERR_COR_ADV_NFAT);
             action = "Masked";
         }
@@ -498,8 +511,8 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
             action = "Must not mask";
 
         /* XPUNCERRMSK Send Completion with Unsupported Request */
-        val = pci_conf_read32(seg, bus, dev, func, 0x20c);
-        pci_conf_write32(seg, bus, dev, func, 0x20c, val | (1 << 4));
+        val = pci_conf_read32(pdev->sbdf, 0x20c);
+        pci_conf_write32(pdev->sbdf, 0x20c, val | (1 << 4));
 
         printk(XENLOG_INFO "%s UR signaling on %04x:%02x:%02x.%u\n",
                action, seg, bus, dev, func);
@@ -515,8 +528,8 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
     case 0x1610: case 0x1614: case 0x1618: /* Broadwell */
     case 0x1900: case 0x1904: case 0x1908: case 0x190c: case 0x190f: /* Skylake */
     case 0x1910: case 0x1918: case 0x191f: /* Skylake */
-        bar = pci_conf_read32(seg, bus, dev, func, 0x6c);
-        bar = (bar << 32) | pci_conf_read32(seg, bus, dev, func, 0x68);
+        bar = pci_conf_read32(pdev->sbdf, 0x6c);
+        bar = (bar << 32) | pci_conf_read32(pdev->sbdf, 0x68);
         pa = bar & 0x7ffffff000UL; /* bits 12...38 */
         if ( (bar & 1) && pa &&
              page_is_ram_type(paddr_to_pfn(pa), RAM_TYPE_RESERVED) )
diff --git a/xen/drivers/passthrough/x86/ats.c b/xen/drivers/passthrough/x86/ats.c
index ddaec72d19..c3203793a6 100644
--- a/xen/drivers/passthrough/x86/ats.c
+++ b/xen/drivers/passthrough/x86/ats.c
@@ -34,8 +34,7 @@ int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
         dprintk(XENLOG_INFO, "%04x:%02x:%02x.%u: ATS capability found\n",
                 seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
 
-    value = pci_conf_read16(seg, bus, PCI_SLOT(devfn),
-                            PCI_FUNC(devfn), pos + ATS_REG_CTL);
+    value = pci_conf_read16(pdev->sbdf, pos + ATS_REG_CTL);
     if ( value & ATS_ENABLE )
     {
         struct pci_dev *other;
@@ -51,15 +50,13 @@ int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
     if ( !(value & ATS_ENABLE) )
     {
         value |= ATS_ENABLE;
-        pci_conf_write16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                         pos + ATS_REG_CTL, value);
+        pci_conf_write16(pdev->sbdf, pos + ATS_REG_CTL, value);
     }
 
     if ( pos )
     {
         pdev->ats.cap_pos = pos;
-        value = pci_conf_read16(seg, bus, PCI_SLOT(devfn),
-                                PCI_FUNC(devfn), pos + ATS_REG_CAP);
+        value = pci_conf_read16(pdev->sbdf, pos + ATS_REG_CAP);
         pdev->ats.queue_depth = value & ATS_QUEUE_DEPTH_MASK ?:
                                 ATS_QUEUE_DEPTH_MASK + 1;
         list_add(&pdev->ats.list, ats_list);
@@ -81,11 +78,9 @@ void disable_ats_device(struct pci_dev *pdev)
 
     BUG_ON(!pdev->ats.cap_pos);
 
-    value = pci_conf_read16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                            pdev->ats.cap_pos + ATS_REG_CTL);
+    value = pci_conf_read16(pdev->sbdf, pdev->ats.cap_pos + ATS_REG_CTL);
     value &= ~ATS_ENABLE;
-    pci_conf_write16(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                     pdev->ats.cap_pos + ATS_REG_CTL, value);
+    pci_conf_write16(pdev->sbdf, pdev->ats.cap_pos + ATS_REG_CTL, value);
 
     list_del(&pdev->ats.list);
 
diff --git a/xen/drivers/pci/pci.c b/xen/drivers/pci/pci.c
index a3223a2b29..3d2acf6f77 100644
--- a/xen/drivers/pci/pci.c
+++ b/xen/drivers/pci/pci.c
@@ -14,19 +14,25 @@ int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 cap)
     int max_cap = 48;
     u8 pos = PCI_CAPABILITY_LIST;
     u16 status;
-
-    status = pci_conf_read16(seg, bus, dev, func, PCI_STATUS);
+    const pci_sbdf_t sbdf = {
+        .seg = seg,
+        .bus = bus,
+        .dev = dev,
+        .func = func,
+    };
+
+    status = pci_conf_read16(sbdf, PCI_STATUS);
     if ( (status & PCI_STATUS_CAP_LIST) == 0 )
         return 0;
 
     while ( max_cap-- )
     {
-        pos = pci_conf_read8(seg, bus, dev, func, pos);
+        pos = pci_conf_read8(sbdf, pos);
         if ( pos < 0x40 )
             break;
 
         pos &= ~3;
-        id = pci_conf_read8(seg, bus, dev, func, pos + PCI_CAP_LIST_ID);
+        id = pci_conf_read8(sbdf, pos + PCI_CAP_LIST_ID);
 
         if ( id == 0xff )
             break;
@@ -43,16 +49,20 @@ int pci_find_next_cap(u16 seg, u8 bus, unsigned int devfn, u8 pos, int cap)
 {
     u8 id;
     int ttl = 48;
+    const pci_sbdf_t sbdf = {
+        .seg = seg,
+        .bus = bus,
+        .extfunc = devfn,
+    };
 
     while ( ttl-- )
     {
-        pos = pci_conf_read8(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos);
+        pos = pci_conf_read8(sbdf, pos);
         if ( pos < 0x40 )
             break;
 
         pos &= ~3;
-        id = pci_conf_read8(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                            pos + PCI_CAP_LIST_ID);
+        id = pci_conf_read8(sbdf, pos + PCI_CAP_LIST_ID);
 
         if ( id == 0xff )
             break;
@@ -90,11 +100,14 @@ int pci_find_ext_capability(int seg, int bus, int devfn, int cap)
  */
 int pci_find_next_ext_capability(int seg, int bus, int devfn, int start, int cap)
 {
-    u32 header;
     int ttl = 480; /* 3840 bytes, minimum 8 bytes per capability */
     int pos = max(start, 0x100);
-
-    header = pci_conf_read32(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos);
+    const pci_sbdf_t sbdf = {
+        .seg = seg,
+        .bus = bus,
+        .extfunc = devfn,
+    };
+    uint32_t header = pci_conf_read32(sbdf, pos);
 
     /*
      * If we have no capabilities, this is indicated by cap ID,
@@ -110,24 +123,20 @@ int pci_find_next_ext_capability(int seg, int bus, int devfn, int start, int cap
         pos = PCI_EXT_CAP_NEXT(header);
         if ( pos < 0x100 )
             break;
-        header = pci_conf_read32(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos);
+        header = pci_conf_read32(sbdf, pos);
     }
     return 0;
 }
 
 void pci_intx(const struct pci_dev *pdev, bool enable)
 {
-    uint16_t seg = pdev->sbdf.seg;
-    uint8_t bus = pdev->sbdf.bus;
-    uint8_t slot = pdev->sbdf.dev;
-    uint8_t func = pdev->sbdf.func;
-    uint16_t cmd = pci_conf_read16(seg, bus, slot, func, PCI_COMMAND);
+    uint16_t cmd = pci_conf_read16(pdev->sbdf, PCI_COMMAND);
 
     if ( enable )
         cmd &= ~PCI_COMMAND_INTX_DISABLE;
     else
         cmd |= PCI_COMMAND_INTX_DISABLE;
-    pci_conf_write16(seg, bus, slot, func, PCI_COMMAND, cmd);
+    pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd);
 }
 
 const char *__init parse_pci(const char *s, unsigned int *seg_p,
diff --git a/xen/drivers/video/vga.c b/xen/drivers/video/vga.c
index 6a64fd9013..59f9c9de6f 100644
--- a/xen/drivers/video/vga.c
+++ b/xen/drivers/video/vga.c
@@ -121,10 +121,8 @@ void __init video_endboot(void)
                 pcidevs_unlock();
 
                 if ( !pdev ||
-                     pci_conf_read16(0, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                                     PCI_CLASS_DEVICE) != 0x0300 ||
-                     !(pci_conf_read16(0, bus, PCI_SLOT(devfn),
-                                       PCI_FUNC(devfn), PCI_COMMAND) &
+                     pci_conf_read16(pdev->sbdf, PCI_CLASS_DEVICE) != 0x0300 ||
+                     !(pci_conf_read16(pdev->sbdf, PCI_COMMAND) &
                        (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) )
                     continue;
 
@@ -136,21 +134,24 @@ void __init video_endboot(void)
                         b = 0;
                         break;
                     case 1:
-                        switch ( pci_conf_read8(0, b, PCI_SLOT(df),
-                                                PCI_FUNC(df),
-                                                PCI_HEADER_TYPE) )
+                    {
+                        const pci_sbdf_t sbdf = {
+                            .bus = b,
+                            .extfunc = df,
+                        };
+
+                        switch ( pci_conf_read8(sbdf, PCI_HEADER_TYPE) )
                         {
                         case PCI_HEADER_TYPE_BRIDGE:
                         case PCI_HEADER_TYPE_CARDBUS:
-                            if ( pci_conf_read16(0, b, PCI_SLOT(df),
-                                                 PCI_FUNC(df),
-                                                 PCI_BRIDGE_CONTROL) &
+                            if ( pci_conf_read16(sbdf, PCI_BRIDGE_CONTROL) &
                                  PCI_BRIDGE_CTL_VGA )
                                 continue;
                             break;
                         }
                         break;
                     }
+                    }
                     break;
                 }
                 if ( !b )
diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
index 74d70a4278..d693b1376c 100644
--- a/xen/drivers/vpci/header.c
+++ b/xen/drivers/vpci/header.c
@@ -112,8 +112,7 @@ static void modify_decoding(const struct pci_dev *pdev, uint16_t cmd,
                            (map ? PCI_ROM_ADDRESS_ENABLE : 0);
 
             header->bars[i].enabled = header->rom_enabled = map;
-            pci_conf_write32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                             pdev->sbdf.func, rom_pos, val);
+            pci_conf_write32(pdev->sbdf, rom_pos, val);
             return;
         }
 
@@ -123,8 +122,7 @@ static void modify_decoding(const struct pci_dev *pdev, uint16_t cmd,
     }
 
     if ( !rom_only )
-        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                         pdev->sbdf.func, PCI_COMMAND, cmd);
+        pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd);
     else
         ASSERT_UNREACHABLE();
 }
@@ -335,9 +333,7 @@ static int modify_bars(const struct pci_dev *pdev, uint16_t cmd, bool rom_only)
 static void cmd_write(const struct pci_dev *pdev, unsigned int reg,
                       uint32_t cmd, void *data)
 {
-    uint16_t current_cmd = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
-                                           pdev->sbdf.dev, pdev->sbdf.func,
-                                           reg);
+    uint16_t current_cmd = pci_conf_read16(pdev->sbdf, reg);
 
     /*
      * Let Dom0 play with all the bits directly except for the memory
@@ -352,8 +348,7 @@ static void cmd_write(const struct pci_dev *pdev, unsigned int reg,
          */
         modify_bars(pdev, cmd, false);
     else
-        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                         pdev->sbdf.func, reg, cmd);
+        pci_conf_write16(pdev->sbdf, reg, cmd);
 }
 
 static void bar_write(const struct pci_dev *pdev, unsigned int reg,
@@ -371,8 +366,7 @@ static void bar_write(const struct pci_dev *pdev, unsigned int reg,
     else
         val &= PCI_BASE_ADDRESS_MEM_MASK;
 
-    if ( pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                         pdev->sbdf.func, PCI_COMMAND) & PCI_COMMAND_MEMORY )
+    if ( pci_conf_read16(pdev->sbdf, PCI_COMMAND) & PCI_COMMAND_MEMORY )
     {
         /* If the value written is the current one avoid printing a warning. */
         if ( val != (uint32_t)(bar->addr >> (hi ? 32 : 0)) )
@@ -399,8 +393,7 @@ static void bar_write(const struct pci_dev *pdev, unsigned int reg,
         val |= bar->prefetchable ? PCI_BASE_ADDRESS_MEM_PREFETCH : 0;
     }
 
-    pci_conf_write32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                     pdev->sbdf.func, reg, val);
+    pci_conf_write32(pdev->sbdf, reg, val);
 }
 
 static void rom_write(const struct pci_dev *pdev, unsigned int reg,
@@ -408,9 +401,7 @@ static void rom_write(const struct pci_dev *pdev, unsigned int reg,
 {
     struct vpci_header *header = &pdev->vpci->header;
     struct vpci_bar *rom = data;
-    uint16_t cmd = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus,
-                                   pdev->sbdf.dev, pdev->sbdf.func,
-                                   PCI_COMMAND);
+    uint16_t cmd = pci_conf_read16(pdev->sbdf, PCI_COMMAND);
     bool new_enabled = val & PCI_ROM_ADDRESS_ENABLE;
 
     if ( (cmd & PCI_COMMAND_MEMORY) && header->rom_enabled && new_enabled )
@@ -433,8 +424,7 @@ static void rom_write(const struct pci_dev *pdev, unsigned int reg,
     {
         /* Just update the ROM BAR field. */
         header->rom_enabled = new_enabled;
-        pci_conf_write32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                         pdev->sbdf.func, reg, val);
+        pci_conf_write32(pdev->sbdf, reg, val);
     }
     /*
      * Pass PCI_COMMAND_MEMORY or 0 to signal a map/unmap request, note that
@@ -464,8 +454,7 @@ static int init_bars(struct pci_dev *pdev)
     struct vpci_bar *bars = header->bars;
     int rc;
 
-    switch ( pci_conf_read8(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                            pdev->sbdf.func, PCI_HEADER_TYPE) & 0x7f )
+    switch ( pci_conf_read8(pdev->sbdf, PCI_HEADER_TYPE) & 0x7f )
     {
     case PCI_HEADER_TYPE_NORMAL:
         num_bars = PCI_HEADER_NORMAL_NR_BARS;
@@ -491,12 +480,9 @@ static int init_bars(struct pci_dev *pdev)
         return 0;
 
     /* Disable memory decoding before sizing. */
-    cmd = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                          pdev->sbdf.func, PCI_COMMAND);
+    cmd = pci_conf_read16(pdev->sbdf, PCI_COMMAND);
     if ( cmd & PCI_COMMAND_MEMORY )
-        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                         pdev->sbdf.func, PCI_COMMAND,
-                         cmd & ~PCI_COMMAND_MEMORY);
+        pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd & ~PCI_COMMAND_MEMORY);
 
     for ( i = 0; i < num_bars; i++ )
     {
@@ -510,16 +496,14 @@ static int init_bars(struct pci_dev *pdev)
                                    4, &bars[i]);
             if ( rc )
             {
-                pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                                 pdev->sbdf.func, PCI_COMMAND, cmd);
+                pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd);
                 return rc;
             }
 
             continue;
         }
 
-        val = pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                              pdev->sbdf.func, reg);
+        val = pci_conf_read32(pdev->sbdf, reg);
         if ( (val & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO )
         {
             bars[i].type = VPCI_BAR_IO;
@@ -535,8 +519,7 @@ static int init_bars(struct pci_dev *pdev)
                               (i == num_bars - 1) ? PCI_BAR_LAST : 0);
         if ( rc < 0 )
         {
-            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                             pdev->sbdf.func, PCI_COMMAND, cmd);
+            pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd);
             return rc;
         }
 
@@ -554,8 +537,7 @@ static int init_bars(struct pci_dev *pdev)
                                &bars[i]);
         if ( rc )
         {
-            pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                             pdev->sbdf.func, PCI_COMMAND, cmd);
+            pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd);
             return rc;
         }
     }
@@ -569,9 +551,8 @@ static int init_bars(struct pci_dev *pdev)
         rom->type = VPCI_BAR_ROM;
         rom->size = size;
         rom->addr = addr;
-        header->rom_enabled = pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus,
-                                              pdev->sbdf.dev, pdev->sbdf.func,
-                                              rom_reg) & PCI_ROM_ADDRESS_ENABLE;
+        header->rom_enabled = pci_conf_read32(pdev->sbdf, rom_reg) &
+                              PCI_ROM_ADDRESS_ENABLE;
 
         rc = vpci_add_register(pdev->vpci, vpci_hw_read32, rom_write, rom_reg,
                                4, rom);
diff --git a/xen/drivers/vpci/msi.c b/xen/drivers/vpci/msi.c
index dfc894dcc6..4f2e55f3fd 100644
--- a/xen/drivers/vpci/msi.c
+++ b/xen/drivers/vpci/msi.c
@@ -77,8 +77,7 @@ static void control_write(const struct pci_dev *pdev, unsigned int reg,
     msi->vectors = vectors;
     msi->enabled = new_enabled;
 
-    pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                     pdev->sbdf.func, reg, control_read(pdev, reg, data));
+    pci_conf_write16(pdev->sbdf, reg, control_read(pdev, reg, data));
 }
 
 static void update_msi(const struct pci_dev *pdev, struct vpci_msi *msi)
@@ -210,8 +209,7 @@ static int init_msi(struct pci_dev *pdev)
         return ret;
 
     /* Get the maximum number of vectors the device supports. */
-    control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                              pdev->sbdf.func, msi_control_reg(pos));
+    control = pci_conf_read16(pdev->sbdf, msi_control_reg(pos));
 
     /*
      * FIXME: I've only been able to test this code with devices using a single
diff --git a/xen/drivers/vpci/msix.c b/xen/drivers/vpci/msix.c
index 04431715f5..47d569121f 100644
--- a/xen/drivers/vpci/msix.c
+++ b/xen/drivers/vpci/msix.c
@@ -147,8 +147,7 @@ static void control_write(const struct pci_dev *pdev, unsigned int reg,
 
     val = control_read(pdev, reg, data);
     if ( pci_msi_conf_write_intercept(msix->pdev, reg, 2, &val) >= 0 )
-        pci_conf_write16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                         pdev->sbdf.func, reg, val);
+        pci_conf_write16(pdev->sbdf, reg, val);
 }
 
 static struct vpci_msix *msix_find(const struct domain *d, unsigned long addr)
@@ -459,8 +458,7 @@ static int init_msix(struct pci_dev *pdev)
     if ( !msix_offset )
         return 0;
 
-    control = pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                              pdev->sbdf.func, msix_control_reg(msix_offset));
+    control = pci_conf_read16(pdev->sbdf, msix_control_reg(msix_offset));
 
     max_entries = msix_table_size(control);
 
@@ -472,11 +470,9 @@ static int init_msix(struct pci_dev *pdev)
     pdev->vpci->msix->pdev = pdev;
 
     pdev->vpci->msix->tables[VPCI_MSIX_TABLE] =
-        pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                        pdev->sbdf.func, msix_table_offset_reg(msix_offset));
+        pci_conf_read32(pdev->sbdf, msix_table_offset_reg(msix_offset));
     pdev->vpci->msix->tables[VPCI_MSIX_PBA] =
-        pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                        pdev->sbdf.func, msix_pba_offset_reg(msix_offset));
+        pci_conf_read32(pdev->sbdf, msix_pba_offset_reg(msix_offset));
 
     for ( i = 0; i < pdev->vpci->msix->max_entries; i++)
     {
diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c
index 9a060c108e..afe0c38396 100644
--- a/xen/drivers/vpci/vpci.c
+++ b/xen/drivers/vpci/vpci.c
@@ -114,15 +114,13 @@ static void vpci_ignored_write(const struct pci_dev *pdev, unsigned int reg,
 uint32_t vpci_hw_read16(const struct pci_dev *pdev, unsigned int reg,
                         void *data)
 {
-    return pci_conf_read16(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                           pdev->sbdf.func, reg);
+    return pci_conf_read16(pdev->sbdf, reg);
 }
 
 uint32_t vpci_hw_read32(const struct pci_dev *pdev, unsigned int reg,
                         void *data)
 {
-    return pci_conf_read32(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                           pdev->sbdf.func, reg);
+    return pci_conf_read32(pdev->sbdf, reg);
 }
 
 int vpci_add_register(struct vpci *vpci, vpci_read_t *read_handler,
@@ -212,7 +210,7 @@ static uint32_t vpci_read_hw(pci_sbdf_t sbdf, unsigned int reg,
     switch ( size )
     {
     case 4:
-        data = pci_conf_read32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg);
+        data = pci_conf_read32(sbdf, reg);
         break;
 
     case 3:
@@ -222,26 +220,22 @@ static uint32_t vpci_read_hw(pci_sbdf_t sbdf, unsigned int reg,
          */
         if ( reg & 1 )
         {
-            data = pci_conf_read8(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func,
-                                  reg);
-            data |= pci_conf_read16(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func,
-                                    reg + 1) << 8;
+            data = pci_conf_read8(sbdf, reg);
+            data |= pci_conf_read16(sbdf, reg + 1) << 8;
         }
         else
         {
-            data = pci_conf_read16(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func,
-                                   reg);
-            data |= pci_conf_read8(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func,
-                                   reg + 2) << 16;
+            data = pci_conf_read16(sbdf, reg);
+            data |= pci_conf_read8(sbdf, reg + 2) << 16;
         }
         break;
 
     case 2:
-        data = pci_conf_read16(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg);
+        data = pci_conf_read16(sbdf, reg);
         break;
 
     case 1:
-        data = pci_conf_read8(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg);
+        data = pci_conf_read8(sbdf, reg);
         break;
 
     default:
@@ -259,7 +253,7 @@ static void vpci_write_hw(pci_sbdf_t sbdf, unsigned int reg, unsigned int size,
     switch ( size )
     {
     case 4:
-        pci_conf_write32(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg, data);
+        pci_conf_write32(sbdf, reg, data);
         break;
 
     case 3:
@@ -269,26 +263,22 @@ static void vpci_write_hw(pci_sbdf_t sbdf, unsigned int reg, unsigned int size,
          */
         if ( reg & 1 )
         {
-            pci_conf_write8(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg,
-                            data);
-            pci_conf_write16(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg + 1,
-                             data >> 8);
+            pci_conf_write8(sbdf, reg, data);
+            pci_conf_write16(sbdf, reg + 1, data >> 8);
         }
         else
         {
-            pci_conf_write16(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg,
-                             data);
-            pci_conf_write8(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg + 2,
-                            data >> 16);
+            pci_conf_write16(sbdf, reg, data);
+            pci_conf_write8(sbdf, reg + 2, data >> 16);
         }
         break;
 
     case 2:
-        pci_conf_write16(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg, data);
+        pci_conf_write16(sbdf, reg, data);
         break;
 
     case 1:
-        pci_conf_write8(sbdf.seg, sbdf.bus, sbdf.dev, sbdf.func, reg, data);
+        pci_conf_write8(sbdf, reg, data);
         break;
 
     default:
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 1cf54eb466..9908d0fe5d 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -58,6 +58,11 @@ typedef union {
     };
 } pci_sbdf_t;
 
+#define PCI_SBDF_T(s, b, d, f) \
+    ((pci_sbdf_t) { .seg = (s), .bus = (b), .dev = (d), .func = (f) })
+#define PCI_SBDF3_T(s, b, e) \
+    ((pci_sbdf_t) { .seg = (s), .bus = (b), .extfunc = (e) })
+
 struct pci_dev_info {
     /*
      * VF's 'is_extfn' field is used to indicate whether its PF is an extended
@@ -159,24 +164,12 @@ struct pci_dev *pci_get_pdev_by_domain(const struct domain *, int seg,
                                        int bus, int devfn);
 void pci_check_disable_device(u16 seg, u8 bus, u8 devfn);
 
-uint8_t pci_conf_read8(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg);
-uint16_t pci_conf_read16(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg);
-uint32_t pci_conf_read32(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg);
-void pci_conf_write8(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg, uint8_t data);
-void pci_conf_write16(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg, uint16_t data);
-void pci_conf_write32(
-    unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-    unsigned int reg, uint32_t data);
+uint8_t pci_conf_read8(pci_sbdf_t sbdf, unsigned int reg);
+uint16_t pci_conf_read16(pci_sbdf_t sbdf, unsigned int reg);
+uint32_t pci_conf_read32(pci_sbdf_t sbdf, unsigned int reg);
+void pci_conf_write8(pci_sbdf_t sbdf, unsigned int reg, uint8_t data);
+void pci_conf_write16(pci_sbdf_t sbdf, unsigned int reg, uint16_t data);
+void pci_conf_write32(pci_sbdf_t sbdf, unsigned int reg, uint32_t data);
 uint32_t pci_conf_read(uint32_t cf8, uint8_t offset, uint8_t bytes);
 void pci_conf_write(uint32_t cf8, uint8_t offset, uint8_t bytes, uint32_t data);
 int pci_mmcfg_read(unsigned int seg, unsigned int bus,
-- 
2.17.2 (Apple Git-113)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 4/5] print: introduce a format specifier for pci_sbdf_t
@ 2019-05-10 16:10   ` Roger Pau Monne
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monne @ 2019-05-10 16:10 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Suravee Suthikulpanit,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper, Ian Jackson,
	Tim Deegan, Julien Grall, Jan Beulich, Brian Woods,
	Roger Pau Monne

The new format specifier is '%pp', and prints a pci_sbdf_t using the
seg:bus:dev.func format. Replace all SBDFs printed using
'%04x:%02x:%02x.%u' to use the new format specifier.

No functional change expected.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Julien Grall <julien.grall@arm.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Brian Woods <brian.woods@amd.com>
Cc: Kevin Tian <kevin.tian@intel.com>
---
 docs/misc/printk-formats.txt                |   5 +
 xen/arch/x86/hvm/vmsi.c                     |  10 +-
 xen/arch/x86/msi.c                          |  35 +++---
 xen/common/vsprintf.c                       |  18 +++
 xen/drivers/passthrough/amd/iommu_acpi.c    |  17 ++-
 xen/drivers/passthrough/amd/iommu_cmd.c     |   5 +-
 xen/drivers/passthrough/amd/iommu_detect.c  |   5 +-
 xen/drivers/passthrough/amd/iommu_init.c    |  11 +-
 xen/drivers/passthrough/amd/iommu_intr.c    |   8 +-
 xen/drivers/passthrough/amd/pci_amd_iommu.c |  31 +++--
 xen/drivers/passthrough/pci.c               | 121 ++++++++------------
 xen/drivers/passthrough/vtd/dmar.c          |  26 ++---
 xen/drivers/passthrough/vtd/intremap.c      |  11 +-
 xen/drivers/passthrough/vtd/iommu.c         |  74 +++++-------
 xen/drivers/passthrough/vtd/quirks.c        |  23 ++--
 xen/drivers/passthrough/vtd/utils.c         |   6 +-
 xen/drivers/passthrough/x86/ats.c           |  13 +--
 xen/drivers/vpci/header.c                   |  10 +-
 xen/drivers/vpci/msi.c                      |   6 +-
 xen/drivers/vpci/msix.c                     |  25 ++--
 xen/include/xen/pci.h                       |   2 +
 21 files changed, 197 insertions(+), 265 deletions(-)

diff --git a/docs/misc/printk-formats.txt b/docs/misc/printk-formats.txt
index 080f498f65..8f666f696a 100644
--- a/docs/misc/printk-formats.txt
+++ b/docs/misc/printk-formats.txt
@@ -48,3 +48,8 @@ Domain and vCPU information:
                The domain part as above, with the vcpu_id printed in decimal.
                  e.g.  d0v1
                        d[IDLE]v0
+
+PCI:
+
+       %pp     PCI device address in S:B:D.F format from a pci_sbdf_t.
+                 e.g.  0004:02:00.0
diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c
index 15cfe8d057..6f4641afbc 100644
--- a/xen/arch/x86/hvm/vmsi.c
+++ b/xen/arch/x86/hvm/vmsi.c
@@ -686,10 +686,8 @@ static int vpci_msi_update(const struct pci_dev *pdev, uint32_t data,
 
         if ( rc )
         {
-            gdprintk(XENLOG_ERR,
-                     "%04x:%02x:%02x.%u: failed to bind PIRQ %u: %d\n",
-                     pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                     pdev->sbdf.func, pirq + i, rc);
+            gdprintk(XENLOG_ERR, "%pp: failed to bind PIRQ %u: %d\n",
+                     &pdev->sbdf, pirq + i, rc);
             while ( bind.machine_irq-- > pirq )
                 pt_irq_destroy_bind(pdev->domain, &bind);
             return rc;
@@ -743,9 +741,7 @@ static int vpci_msi_enable(const struct pci_dev *pdev, uint32_t data,
                                    &msi_info);
     if ( rc )
     {
-        gdprintk(XENLOG_ERR, "%04x:%02x:%02x.%u: failed to map PIRQ: %d\n",
-                 pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                 pdev->sbdf.func, rc);
+        gdprintk(XENLOG_ERR, "%pp: failed to map PIRQ: %d\n", &pdev->sbdf, rc);
         return rc;
     }
 
diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index ad4a72d56b..6832211772 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -432,8 +432,8 @@ static bool msi_set_mask_bit(struct irq_desc *desc, bool host, bool guest)
             {
                 pdev->msix->warned = domid;
                 printk(XENLOG_G_WARNING
-                       "cannot mask IRQ %d: masking MSI-X on Dom%d's %04x:%02x:%02x.%u\n",
-                       desc->irq, domid, seg, bus, slot, func);
+                       "cannot mask IRQ %d: masking MSI-X on Dom%d's %pp\n",
+                       desc->irq, domid, &pdev->sbdf);
             }
         }
         pdev->msix->host_maskall = maskall;
@@ -991,11 +991,10 @@ static int msix_capability_init(struct pci_dev *dev,
             struct domain *d = dev->domain ?: currd;
 
             if ( !is_hardware_domain(currd) || d != currd )
-                printk("%s use of MSI-X on %04x:%02x:%02x.%u by Dom%d\n",
+                printk("%s use of MSI-X on %pp by Dom%d\n",
                        is_hardware_domain(currd)
                        ? XENLOG_WARNING "Potentially insecure"
-                       : XENLOG_ERR "Insecure",
-                       seg, bus, slot, func, d->domain_id);
+                       : XENLOG_ERR "Insecure", &dev->sbdf, d->domain_id);
             if ( !is_hardware_domain(d) &&
                  /* Assume a domain without memory has no mappings yet. */
                  (!is_hardware_domain(currd) || d->tot_pages) )
@@ -1050,18 +1049,15 @@ static int __pci_enable_msi(struct msi_info *msi, struct msi_desc **desc)
     old_desc = find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSI);
     if ( old_desc )
     {
-        printk(XENLOG_ERR "irq %d already mapped to MSI on %04x:%02x:%02x.%u\n",
-               msi->irq, msi->seg, msi->bus,
-               PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn));
+        printk(XENLOG_ERR "irq %d already mapped to MSI on %pp\n",
+               msi->irq, &pdev->sbdf);
         return -EEXIST;
     }
 
     old_desc = find_msi_entry(pdev, -1, PCI_CAP_ID_MSIX);
     if ( old_desc )
     {
-        printk(XENLOG_WARNING "MSI-X already in use on %04x:%02x:%02x.%u\n",
-               msi->seg, msi->bus,
-               PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn));
+        printk(XENLOG_WARNING "MSI-X already in use on %pp\n", &pdev->sbdf);
         __pci_disable_msix(old_desc);
     }
 
@@ -1118,16 +1114,15 @@ static int __pci_enable_msix(struct msi_info *msi, struct msi_desc **desc)
     old_desc = find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSIX);
     if ( old_desc )
     {
-        printk(XENLOG_ERR "irq %d already mapped to MSI-X on %04x:%02x:%02x.%u\n",
-               msi->irq, msi->seg, msi->bus, slot, func);
+        printk(XENLOG_ERR "irq %d already mapped to MSI-X on %pp\n",
+               msi->irq, &pdev->sbdf);
         return -EEXIST;
     }
 
     old_desc = find_msi_entry(pdev, -1, PCI_CAP_ID_MSI);
     if ( old_desc )
     {
-        printk(XENLOG_WARNING "MSI already in use on %04x:%02x:%02x.%u\n",
-               msi->seg, msi->bus, slot, func);
+        printk(XENLOG_WARNING "MSI already in use on %pp\n", &pdev->sbdf);
         __pci_disable_msi(old_desc);
     }
 
@@ -1175,8 +1170,8 @@ static void __pci_disable_msix(struct msi_desc *entry)
     else if ( !(control & PCI_MSIX_FLAGS_MASKALL) )
     {
         printk(XENLOG_WARNING
-               "cannot disable IRQ %d: masking MSI-X on %04x:%02x:%02x.%u\n",
-               entry->irq, seg, bus, slot, func);
+               "cannot disable IRQ %d: masking MSI-X on %pp\n",
+               entry->irq, &dev->sbdf);
         maskall = true;
     }
     dev->msix->host_maskall = maskall;
@@ -1342,7 +1337,6 @@ int pci_restore_msi_state(struct pci_dev *pdev)
     struct msi_desc *entry, *tmp;
     struct irq_desc *desc;
     struct msi_msg msg;
-    uint8_t slot = pdev->sbdf.dev, func = pdev->sbdf.func;
     unsigned int type = 0, pos = 0;
     u16 control = 0;
 
@@ -1369,9 +1363,8 @@ int pci_restore_msi_state(struct pci_dev *pdev)
         if (desc->msi_desc != entry)
         {
     bogus:
-            dprintk(XENLOG_ERR,
-                    "Restore MSI for %04x:%02x:%02x:%u entry %u not set?\n",
-                    pdev->sbdf.seg, pdev->sbdf.bus, slot, func, i);
+            dprintk(XENLOG_ERR, "Restore MSI for %pp entry %u not set?\n",
+                    &pdev->sbdf, i);
             spin_unlock_irqrestore(&desc->lock, flags);
             if ( type == PCI_CAP_ID_MSIX )
                 pci_conf_write16(pdev->sbdf, msix_control_reg(pos),
diff --git a/xen/common/vsprintf.c b/xen/common/vsprintf.c
index 352d43b425..b30ed08687 100644
--- a/xen/common/vsprintf.c
+++ b/xen/common/vsprintf.c
@@ -392,6 +392,20 @@ static char *print_vcpu(char *str, char *end, const struct vcpu *v)
     return number(str + 1, end, v->vcpu_id, 10, -1, -1, 0);
 }
 
+static char *print_pci_addr(char *str, char *end, const pci_sbdf_t *sbdf)
+{
+    str = number(str, end, sbdf->seg, 16, 4, -1, ZEROPAD);
+    if ( str < end )
+        *str = ':';
+    str = number(str + 1, end, sbdf->bus, 16, 2, -1, ZEROPAD);
+    if ( str < end )
+        *str = ':';
+    str = number(str + 1, end, sbdf->dev, 16, 2, -1, ZEROPAD);
+    if ( str < end )
+        *str = '.';
+    return number(str + 1, end, sbdf->func, 10, -1, -1, 0);
+}
+
 static char *pointer(char *str, char *end, const char **fmt_ptr,
                      const void *arg, int field_width, int precision,
                      int flags)
@@ -519,6 +533,10 @@ static char *pointer(char *str, char *end, const char **fmt_ptr,
     case 'v': /* d<domain-id>v<vcpu-id> from a struct vcpu */
         ++*fmt_ptr;
         return print_vcpu(str, end, arg);
+
+    case 'p': /* PCI SBDF. */
+        ++*fmt_ptr;
+        return print_pci_addr(str, end, arg);
     }
 
     if ( field_width == -1 )
diff --git a/xen/drivers/passthrough/amd/iommu_acpi.c b/xen/drivers/passthrough/amd/iommu_acpi.c
index 64d10481d7..d900feef09 100644
--- a/xen/drivers/passthrough/amd/iommu_acpi.c
+++ b/xen/drivers/passthrough/amd/iommu_acpi.c
@@ -717,9 +717,8 @@ static u16 __init parse_ivhd_device_special(
         return 0;
     }
 
-    AMD_IOMMU_DEBUG("IVHD Special: %04x:%02x:%02x.%u variety %#x handle %#x\n",
-                    seg, PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf),
-                    special->variety, special->handle);
+    AMD_IOMMU_DEBUG("IVHD Special: %pp variety %#x handle %#x\n",
+                    &PCI_SBDF2_T(seg, bdf), special->variety, special->handle);
     add_ivrs_mapping_entry(bdf, bdf, special->header.data_setting, iommu);
 
     switch ( special->variety )
@@ -742,9 +741,9 @@ static u16 __init parse_ivhd_device_special(
         if ( idx < nr_ioapic_sbdf )
         {
             AMD_IOMMU_DEBUG("IVHD: Command line override present for IO-APIC %#x"
-                            "(IVRS: %#x devID %04x:%02x:%02x.%u)\n",
-                            ioapic_sbdf[idx].id, special->handle, seg,
-                            PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf));
+                            "(IVRS: %#x devID %pp)\n",
+                            ioapic_sbdf[idx].id, special->handle,
+                            &PCI_SBDF2_T(seg, bdf));
             break;
         }
 
@@ -814,9 +813,9 @@ static u16 __init parse_ivhd_device_special(
             break;
         case HPET_CMDL:
             AMD_IOMMU_DEBUG("IVHD: Command line override present for HPET %#x "
-                            "(IVRS: %#x devID %04x:%02x:%02x.%u)\n",
-                            hpet_sbdf.id, special->handle, seg, PCI_BUS(bdf),
-                            PCI_SLOT(bdf), PCI_FUNC(bdf));
+                            "(IVRS: %#x devID %pp)\n",
+                            hpet_sbdf.id, special->handle,
+                            &PCI_SBDF2_T(seg, bdf));
             break;
         case HPET_NONE:
             /* set device id of hpet */
diff --git a/xen/drivers/passthrough/amd/iommu_cmd.c b/xen/drivers/passthrough/amd/iommu_cmd.c
index 82330c24ba..9bbc5a5545 100644
--- a/xen/drivers/passthrough/amd/iommu_cmd.c
+++ b/xen/drivers/passthrough/amd/iommu_cmd.c
@@ -296,9 +296,8 @@ void amd_iommu_flush_iotlb(u8 devfn, const struct pci_dev *pdev,
 
     if ( !iommu )
     {
-        AMD_IOMMU_DEBUG("%s: Can't find iommu for %04x:%02x:%02x.%u\n",
-                        __func__, pdev->sbdf.seg, pdev->sbdf.bus,
-                        pdev->sbdf.dev, pdev->sbdf.func);
+        AMD_IOMMU_DEBUG("%s: Can't find iommu for %pp\n",
+                        __func__, &pdev->sbdf);
         return;
     }
 
diff --git a/xen/drivers/passthrough/amd/iommu_detect.c b/xen/drivers/passthrough/amd/iommu_detect.c
index e8d8ec59bd..91f5ea6bff 100644
--- a/xen/drivers/passthrough/amd/iommu_detect.c
+++ b/xen/drivers/passthrough/amd/iommu_detect.c
@@ -153,9 +153,8 @@ int __init amd_iommu_detect_one_acpi(
 
     rt = pci_ro_device(iommu->seg, bus, PCI_DEVFN(dev, func));
     if ( rt )
-        printk(XENLOG_ERR
-               "Could not mark config space of %04x:%02x:%02x.%u read-only (%d)\n",
-               iommu->seg, bus, dev, func, rt);
+        printk(XENLOG_ERR "Could not mark config space of %pp read-only (%d)\n",
+               &PCI_SBDF2_T(iommu->seg, iommu->bdf), rt);
 
     list_add_tail(&iommu->list, &amd_iommu_head);
     rt = 0;
diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c
index fe0516f788..f39c67949f 100644
--- a/xen/drivers/passthrough/amd/iommu_init.c
+++ b/xen/drivers/passthrough/amd/iommu_init.c
@@ -793,9 +793,8 @@ static bool_t __init set_iommu_interrupt_handler(struct amd_iommu *iommu)
     pcidevs_unlock();
     if ( !iommu->msi.dev )
     {
-        AMD_IOMMU_DEBUG("IOMMU: no pdev for %04x:%02x:%02x.%u\n",
-                        iommu->seg, PCI_BUS(iommu->bdf),
-                        PCI_SLOT(iommu->bdf), PCI_FUNC(iommu->bdf));
+        AMD_IOMMU_DEBUG("IOMMU: no pdev for %pp\n",
+                        &PCI_SBDF2_T(iommu->seg, iommu->bdf));
         return 0;
     }
     control = pci_conf_read16(iommu->msi.dev->sbdf,
@@ -838,9 +837,6 @@ static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
         .seg = iommu->seg,
         .bdf = iommu->bdf,
     };
-    u8 bus = PCI_BUS(iommu->bdf);
-    u8 dev = PCI_SLOT(iommu->bdf);
-    u8 func = PCI_FUNC(iommu->bdf);
 
     if ( (boot_cpu_data.x86 != 0x15) ||
          (boot_cpu_data.x86_model < 0x10) ||
@@ -858,8 +854,7 @@ static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
 
     pci_conf_write32(sbdf, 0xf4, value | (1 << 2));
     printk(XENLOG_INFO
-           "AMD-Vi: Applying erratum 746 workaround for IOMMU at %04x:%02x:%02x.%u\n",
-           iommu->seg, bus, dev, func);
+           "AMD-Vi: Applying erratum 746 workaround for IOMMU at %pp\n", &sbdf);
 
     /* Clear the enable writing bit */
     pci_conf_write32(sbdf, 0xf0, 0x90);
diff --git a/xen/drivers/passthrough/amd/iommu_intr.c b/xen/drivers/passthrough/amd/iommu_intr.c
index 71594cc27d..eca8decc05 100644
--- a/xen/drivers/passthrough/amd/iommu_intr.c
+++ b/xen/drivers/passthrough/amd/iommu_intr.c
@@ -511,8 +511,7 @@ static struct amd_iommu *_find_iommu_for_device(int seg, int bdf)
     if ( iommu )
         return iommu;
 
-    AMD_IOMMU_DEBUG("No IOMMU for MSI dev = %04x:%02x:%02x.%u\n",
-                    seg, PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf));
+    AMD_IOMMU_DEBUG("No IOMMU for MSI dev = %pp\n", &PCI_SBDF2_T(seg, bdf));
     return ERR_PTR(-EINVAL);
 }
 
@@ -687,10 +686,7 @@ static int dump_intremap_mapping(u16 seg, struct ivrs_mappings *ivrs_mapping)
     if ( !ivrs_mapping )
         return 0;
 
-    printk("  %04x:%02x:%02x:%u:\n", seg,
-           PCI_BUS(ivrs_mapping->dte_requestor_id),
-           PCI_SLOT(ivrs_mapping->dte_requestor_id),
-           PCI_FUNC(ivrs_mapping->dte_requestor_id));
+    printk("  %pp:\n", &PCI_SBDF2_T(seg,ivrs_mapping->dte_requestor_id));
 
     spin_lock_irqsave(&(ivrs_mapping->intremap_lock), flags);
     dump_intremap_table(ivrs_mapping->intremap_table);
diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/passthrough/amd/pci_amd_iommu.c
index 0e4c5b4994..5787dff914 100644
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -52,9 +52,8 @@ struct amd_iommu *find_iommu_for_device(int seg, int bdf)
                 tmp.dte_requestor_id = bdf;
             ivrs_mappings[bdf] = tmp;
 
-            printk(XENLOG_WARNING "%04x:%02x:%02x.%u not found in ACPI tables;"
-                   " using same IOMMU as function 0\n",
-                   seg, PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf));
+            printk(XENLOG_WARNING "%pp not found in ACPI tables;"
+                   " using same IOMMU as function 0\n", &PCI_SBDF2_T(seg, bdf));
 
             /* write iommu field last */
             ivrs_mappings[bdf].iommu = ivrs_mappings[bd0].iommu;
@@ -306,9 +305,9 @@ static int reassign_device(struct domain *source, struct domain *target,
     if ( !iommu )
     {
         AMD_IOMMU_DEBUG("Fail to find iommu."
-                        " %04x:%02x:%x02.%x cannot be assigned to dom%d\n",
-                        pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn),
-                        PCI_FUNC(devfn), target->domain_id);
+                        " %pp cannot be assigned to dom%d\n",
+                        &PCI_SBDF3_T(pdev->sbdf.seg, pdev->sbdf.bus, devfn),
+                        target->domain_id);
         return -ENODEV;
     }
 
@@ -325,9 +324,9 @@ static int reassign_device(struct domain *source, struct domain *target,
         return rc;
 
     amd_iommu_setup_domain_device(target, iommu, devfn, pdev);
-    AMD_IOMMU_DEBUG("Re-assign %04x:%02x:%02x.%u from dom%d to dom%d\n",
-                    pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn),
-                    PCI_FUNC(devfn), source->domain_id, target->domain_id);
+    AMD_IOMMU_DEBUG("Re-assign %pp from dom%d to dom%d\n",
+                    &PCI_SBDF3_T(pdev->sbdf.seg, pdev->sbdf.bus, devfn),
+                    source->domain_id, target->domain_id);
 
     return 0;
 }
@@ -430,15 +429,12 @@ static int amd_iommu_add_device(u8 devfn, struct pci_dev *pdev)
         if ( pdev->type == DEV_TYPE_PCI_HOST_BRIDGE &&
              is_hardware_domain(pdev->domain) )
         {
-            AMD_IOMMU_DEBUG("Skipping host bridge %04x:%02x:%02x.%u\n",
-                            pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                            pdev->sbdf.func);
+            AMD_IOMMU_DEBUG("Skipping host bridge %pp\n", &pdev->sbdf);
             return 0;
         }
 
-        AMD_IOMMU_DEBUG("No iommu for %04x:%02x:%02x.%u; cannot be handed to d%d\n",
-                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                        pdev->sbdf.func, pdev->domain->domain_id);
+        AMD_IOMMU_DEBUG("No iommu for %pp; cannot be handed to d%d\n",
+                        &pdev->sbdf, pdev->domain->domain_id);
         return -ENODEV;
     }
 
@@ -457,9 +453,8 @@ static int amd_iommu_remove_device(u8 devfn, struct pci_dev *pdev)
     if ( !iommu )
     {
         AMD_IOMMU_DEBUG("Fail to find iommu."
-                        " %04x:%02x:%02x.%u cannot be removed from dom%d\n",
-                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                        pdev->sbdf.func, pdev->domain->domain_id);
+                        " %pp cannot be removed from dom%d\n",
+                        &pdev->sbdf, pdev->domain->domain_id);
         return -ENODEV;
     }
 
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index 94fb3a183d..a9667ca21c 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -238,10 +238,6 @@ static void check_pdev(const struct pci_dev *pdev)
     (PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT | \
      PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT | \
      PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY)
-    uint16_t seg = pdev->sbdf.seg;
-    uint8_t bus = pdev->sbdf.bus;
-    uint8_t dev = pdev->sbdf.dev;
-    uint8_t func = pdev->sbdf.func;
     u16 val;
 
     if ( command_mask )
@@ -252,8 +248,8 @@ static void check_pdev(const struct pci_dev *pdev)
         val = pci_conf_read16(pdev->sbdf, PCI_STATUS);
         if ( val & PCI_STATUS_CHECK )
         {
-            printk(XENLOG_INFO "%04x:%02x:%02x.%u status %04x -> %04x\n",
-                   seg, bus, dev, func, val, val & ~PCI_STATUS_CHECK);
+            printk(XENLOG_INFO "%pp status %04x -> %04x\n",
+                   &pdev->sbdf, val, val & ~PCI_STATUS_CHECK);
             pci_conf_write16(pdev->sbdf, PCI_STATUS, val & PCI_STATUS_CHECK);
         }
     }
@@ -270,9 +266,8 @@ static void check_pdev(const struct pci_dev *pdev)
         val = pci_conf_read16(pdev->sbdf, PCI_SEC_STATUS);
         if ( val & PCI_STATUS_CHECK )
         {
-            printk(XENLOG_INFO
-                   "%04x:%02x:%02x.%u secondary status %04x -> %04x\n",
-                   seg, bus, dev, func, val, val & ~PCI_STATUS_CHECK);
+            printk(XENLOG_INFO "%pp secondary status %04x -> %04x\n",
+                   &pdev->sbdf, val, val & ~PCI_STATUS_CHECK);
             pci_conf_write16(pdev->sbdf, PCI_SEC_STATUS,
                              val & PCI_STATUS_CHECK);
         }
@@ -409,8 +404,8 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
             break;
 
         default:
-            printk(XENLOG_WARNING "%04x:%02x:%02x.%u: unknown type %d\n",
-                   pseg->nr, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pdev->type);
+            printk(XENLOG_WARNING "%pp: unknown type %d\n",
+                   &pdev->sbdf, pdev->type);
             break;
     }
 
@@ -642,9 +637,9 @@ unsigned int pci_size_mem_bar(pci_sbdf_t sbdf, unsigned int pos,
         if ( flags & PCI_BAR_LAST )
         {
             printk(XENLOG_WARNING
-                   "%sdevice %04x:%02x:%02x.%u with 64-bit %sBAR in last slot\n",
-                   (flags & PCI_BAR_VF) ? "SR-IOV " : "", sbdf.seg, sbdf.bus,
-                   sbdf.dev, sbdf.func, (flags & PCI_BAR_VF) ? "vf " : "");
+                   "%sdevice %pp with 64-bit %sBAR in last slot\n",
+                   (flags & PCI_BAR_VF) ? "SR-IOV " : "", &sbdf,
+                   (flags & PCI_BAR_VF) ? "vf " : "");
             *psize = 0;
             return 1;
         }
@@ -674,7 +669,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
 {
     struct pci_seg *pseg;
     struct pci_dev *pdev;
-    unsigned int slot = PCI_SLOT(devfn), func = PCI_FUNC(devfn);
+    unsigned int func = PCI_FUNC(devfn);
     const char *pdev_type;
     int ret;
     bool pf_is_extfn = false;
@@ -747,9 +742,8 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
                      PCI_BASE_ADDRESS_SPACE_IO )
                 {
                     printk(XENLOG_WARNING
-                           "SR-IOV device %04x:%02x:%02x.%u with vf BAR%u"
-                           " in IO space\n",
-                           seg, bus, slot, func, i);
+                           "SR-IOV device %pp with vf BAR%u in IO space\n",
+                           &pdev->sbdf, i);
                     continue;
                 }
                 ret = pci_size_mem_bar(pdev->sbdf, idx, NULL, &pdev->vf_rlen[i],
@@ -762,9 +756,9 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
         }
         else
             printk(XENLOG_WARNING
-                   "SR-IOV device %04x:%02x:%02x.%u has its virtual"
+                   "SR-IOV device %pp has its virtual"
                    " functions already enabled (%04x)\n",
-                   seg, bus, slot, func, ctrl);
+                   &pdev->sbdf, ctrl);
     }
 
     check_pdev(pdev);
@@ -791,15 +785,13 @@ out:
     pcidevs_unlock();
     if ( !ret )
     {
-        printk(XENLOG_DEBUG "PCI add %s %04x:%02x:%02x.%u\n", pdev_type,
-               seg, bus, slot, func);
+        printk(XENLOG_DEBUG "PCI add %s %pp\n", pdev_type, &pdev->sbdf);
         while ( pdev->phantom_stride )
         {
             func += pdev->phantom_stride;
             if ( PCI_SLOT(func) )
                 break;
-            printk(XENLOG_DEBUG "PCI phantom %04x:%02x:%02x.%u\n",
-                   seg, bus, slot, func);
+            printk(XENLOG_DEBUG "PCI phantom %pp\n", &pdev->sbdf);
         }
     }
     return ret;
@@ -829,8 +821,8 @@ int pci_remove_device(u16 seg, u8 bus, u8 devfn)
                 list_del(&pdev->domain_list);
             pci_cleanup_msi(pdev);
             free_pdev(pseg, pdev);
-            printk(XENLOG_DEBUG "PCI remove device %04x:%02x:%02x.%u\n",
-                   seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+            printk(XENLOG_DEBUG "PCI remove device %pp\n",
+                   &PCI_SBDF3_T(seg, bus, devfn));
             break;
         }
 
@@ -889,7 +881,6 @@ static int pci_clean_dpci_irqs(struct domain *d)
 int pci_release_devices(struct domain *d)
 {
     struct pci_dev *pdev;
-    u8 bus, devfn;
     int ret;
 
     pcidevs_lock();
@@ -900,14 +891,10 @@ int pci_release_devices(struct domain *d)
         return ret;
     }
     while ( (pdev = pci_get_pdev_by_domain(d, -1, -1, -1)) )
-    {
-        bus = pdev->sbdf.bus;
-        devfn = pdev->sbdf.extfunc;
-        if ( deassign_device(d, pdev->sbdf.seg, bus, devfn) )
-            printk("domain %d: deassign device (%04x:%02x:%02x.%u) failed!\n",
-                   d->domain_id, pdev->sbdf.seg, bus,
-                   PCI_SLOT(devfn), PCI_FUNC(devfn));
-    }
+        if ( deassign_device(d, pdev->sbdf.seg, pdev->sbdf.bus,
+                             pdev->sbdf.extfunc) )
+            printk("domain %d: deassign device (%pp) failed!\n",
+                   d->domain_id, &pdev->sbdf);
     pcidevs_unlock();
 
     return 0;
@@ -1059,8 +1046,8 @@ static int __init _scan_pci_devices(struct pci_seg *pseg, void *arg)
                 pdev = alloc_pdev(pseg, bus, PCI_DEVFN(dev, func));
                 if ( !pdev )
                 {
-                    printk(XENLOG_WARNING "%04x:%02x:%02x.%u: alloc_pdev failed\n",
-                           pseg->nr, bus, dev, func);
+                    printk(XENLOG_WARNING "%pp: alloc_pdev failed\n",
+                           &PCI_SBDF_T(pseg->nr, bus, dev, func));
                     return -ENOMEM;
                 }
 
@@ -1100,9 +1087,8 @@ static void __hwdom_init setup_one_hwdom_device(const struct setup_hwdom *ctxt,
         err = ctxt->handler(devfn, pdev);
         if ( err )
         {
-            printk(XENLOG_ERR "setup %04x:%02x:%02x.%u for d%d failed (%d)\n",
-                   pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                   pdev->sbdf.func, ctxt->d->domain_id, err);
+            printk(XENLOG_ERR "setup %pp for d%d failed (%d)\n",
+                   &pdev->sbdf, ctxt->d->domain_id, err);
             if ( devfn == pdev->sbdf.extfunc )
                 return;
         }
@@ -1143,9 +1129,8 @@ static int __hwdom_init _setup_hwdom_pci_devices(struct pci_seg *pseg, void *arg
                 pdev->domain = dom_xen;
             }
             else if ( pdev->domain != ctxt->d )
-                printk(XENLOG_WARNING "Dom%d owning %04x:%02x:%02x.%u?\n",
-                       pdev->domain->domain_id, pseg->nr, bus,
-                       PCI_SLOT(devfn), PCI_FUNC(devfn));
+                printk(XENLOG_WARNING "Dom%d owning %pp?\n",
+                       pdev->domain->domain_id, &pdev->sbdf);
 
             if ( iommu_verbose )
             {
@@ -1280,8 +1265,8 @@ static int _dump_pci_devices(struct pci_seg *pseg, void *arg)
 
     list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
     {
-        printk("%04x:%02x:%02x.%u - dom %-3d - node %-3d - MSIs < ",
-               pseg->nr, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func,
+        printk("%pp - dom %-3d - node %-3d - MSIs < ",
+               &pdev->sbdf,
                pdev->domain ? pdev->domain->domain_id : -1,
                (pdev->node != NUMA_NO_NODE) ? pdev->node : -1);
         list_for_each_entry ( msi, &pdev->msi_list, list )
@@ -1347,9 +1332,8 @@ static int iommu_add_device(struct pci_dev *pdev)
             return 0;
         rc = hd->platform_ops->add_device(devfn, pci_to_dev(pdev));
         if ( rc )
-            printk(XENLOG_WARNING "IOMMU: add %04x:%02x:%02x.%u failed (%d)\n",
-                   pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn),
-                   PCI_FUNC(devfn), rc);
+            printk(XENLOG_WARNING "IOMMU: add %pp failed (%d)\n",
+                   &pdev->sbdf, rc);
     }
 }
 
@@ -1393,9 +1377,8 @@ static int iommu_remove_device(struct pci_dev *pdev)
         if ( !rc )
             continue;
 
-        printk(XENLOG_ERR "IOMMU: remove %04x:%02x:%02x.%u failed (%d)\n",
-               pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-               rc);
+        printk(XENLOG_ERR "IOMMU: remove %pp failed (%d)\n",
+               &pdev->sbdf, rc);
         return rc;
     }
 
@@ -1465,9 +1448,8 @@ static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn, u32 flag)
             break;
         rc = hd->platform_ops->assign_device(d, devfn, pci_to_dev(pdev), flag);
         if ( rc )
-            printk(XENLOG_G_WARNING "d%d: assign %04x:%02x:%02x.%u failed (%d)\n",
-                   d->domain_id, seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                   rc);
+            printk(XENLOG_G_WARNING "d%d: assign %pp failed (%d)\n",
+                   d->domain_id, &PCI_SBDF3_T(seg, bus, devfn), rc);
     }
 
  done:
@@ -1503,8 +1485,8 @@ int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
         if ( !ret )
             continue;
 
-        printk(XENLOG_G_ERR "d%d: deassign %04x:%02x:%02x.%u failed (%d)\n",
-               d->domain_id, seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), ret);
+        printk(XENLOG_G_ERR "d%d: deassign %pp failed (%d)\n",
+               d->domain_id, &PCI_SBDF3_T(seg, bus, devfn), ret);
         return ret;
     }
 
@@ -1513,9 +1495,8 @@ int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
                                             pci_to_dev(pdev));
     if ( ret )
     {
-        dprintk(XENLOG_G_ERR,
-                "d%d: deassign device (%04x:%02x:%02x.%u) failed\n",
-                d->domain_id, seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+        dprintk(XENLOG_G_ERR, "d%d: deassign device (%pp) failed\n",
+                d->domain_id, &PCI_SBDF3_T(seg, bus, devfn));
         return ret;
     }
 
@@ -1590,10 +1571,8 @@ void iommu_dev_iotlb_flush_timeout(struct domain *d, struct pci_dev *pdev)
     _pci_hide_device(pdev);
 
     if ( !d->is_shutting_down && printk_ratelimit() )
-        printk(XENLOG_ERR
-               "dom%d: ATS device %04x:%02x:%02x.%u flush failed\n",
-               d->domain_id, pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-               pdev->sbdf.func);
+        printk(XENLOG_ERR "dom%d: ATS device %pp flush failed\n",
+               d->domain_id, &pdev->sbdf);
     if ( !is_hardware_domain(d) )
         domain_crash(d);
 
@@ -1682,9 +1661,8 @@ int iommu_do_pci_domctl(
         {
             if ( ret )
             {
-                printk(XENLOG_G_INFO
-                       "%04x:%02x:%02x.%u already assigned, or non-existent\n",
-                       seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+                printk(XENLOG_G_INFO "%pp already assigned, or non-existent\n",
+                       &PCI_SBDF3_T(seg, bus, devfn));
                 ret = -EINVAL;
             }
             break;
@@ -1696,9 +1674,8 @@ int iommu_do_pci_domctl(
                                                 "h", u_domctl);
         else if ( ret )
             printk(XENLOG_G_ERR "XEN_DOMCTL_assign_device: "
-                   "assign %04x:%02x:%02x.%u to dom%d failed (%d)\n",
-                   seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                   d->domain_id, ret);
+                   "assign %pp to dom%d failed (%d)\n",
+                   &PCI_SBDF3_T(seg, bus, devfn), d->domain_id, ret);
 
         break;
 
@@ -1732,10 +1709,8 @@ int iommu_do_pci_domctl(
         ret = deassign_device(d, seg, bus, devfn);
         pcidevs_unlock();
         if ( ret )
-            printk(XENLOG_G_ERR
-                   "deassign %04x:%02x:%02x.%u from dom%d failed (%d)\n",
-                   seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                   d->domain_id, ret);
+            printk(XENLOG_G_ERR "deassign %pp from dom%d failed (%d)\n",
+                   &PCI_SBDF3_T(seg, bus, devfn), d->domain_id, ret);
 
         break;
 
diff --git a/xen/drivers/passthrough/vtd/dmar.c b/xen/drivers/passthrough/vtd/dmar.c
index 9d30188ab9..911494752f 100644
--- a/xen/drivers/passthrough/vtd/dmar.c
+++ b/xen/drivers/passthrough/vtd/dmar.c
@@ -367,18 +367,16 @@ static int __init acpi_parse_dev_scope(
             sec_bus = pci_conf_read8(sbdf, PCI_SECONDARY_BUS);
             sub_bus = pci_conf_read8(sbdf, PCI_SUBORDINATE_BUS);
             if ( iommu_verbose )
-                printk(VTDPREFIX
-                       " bridge: %04x:%02x:%02x.%u start=%x sec=%x sub=%x\n",
-                       seg, bus, path->dev, path->fn,
-                       acpi_scope->bus, sec_bus, sub_bus);
+                printk(VTDPREFIX " bridge: %pp start=%x sec=%x sub=%x\n",
+                       &sbdf, acpi_scope->bus, sec_bus, sub_bus);
 
             dmar_scope_add_buses(scope, sec_bus, sub_bus);
             break;
         }
         case ACPI_DMAR_SCOPE_TYPE_HPET:
             if ( iommu_verbose )
-                printk(VTDPREFIX " MSI HPET: %04x:%02x:%02x.%u\n",
-                       seg, bus, path->dev, path->fn);
+                printk(VTDPREFIX " MSI HPET: %pp\n",
+                       &PCI_SBDF_T(seg, bus, path->dev, path->fn));
 
             if ( drhd )
             {
@@ -399,8 +397,8 @@ static int __init acpi_parse_dev_scope(
 
         case ACPI_DMAR_SCOPE_TYPE_ENDPOINT:
             if ( iommu_verbose )
-                printk(VTDPREFIX " endpoint: %04x:%02x:%02x.%u\n",
-                       seg, bus, path->dev, path->fn);
+                printk(VTDPREFIX " endpoint: %pp\n",
+                       &PCI_SBDF_T(seg, bus, path->dev, path->fn));
 
             if ( drhd )
             {
@@ -413,8 +411,8 @@ static int __init acpi_parse_dev_scope(
 
         case ACPI_DMAR_SCOPE_TYPE_IOAPIC:
             if ( iommu_verbose )
-                printk(VTDPREFIX " IOAPIC: %04x:%02x:%02x.%u\n",
-                       seg, bus, path->dev, path->fn);
+                printk(VTDPREFIX " IOAPIC: %pp\n",
+                       &PCI_SBDF_T(seg, bus, path->dev, path->fn));
 
             if ( drhd )
             {
@@ -543,8 +541,8 @@ acpi_parse_one_drhd(struct acpi_dmar_header *header)
 
             if ( !pci_device_detect(drhd->segment, b, d, f) )
                 printk(XENLOG_WARNING VTDPREFIX
-                       " Non-existent device (%04x:%02x:%02x.%u) in this DRHD's scope!\n",
-                       drhd->segment, b, d, f);
+                       " Non-existent device (%pp) in this DRHD's scope!\n",
+                       &PCI_SBDF_T(drhd->segment, b, d, f));
         }
 
         acpi_register_drhd_unit(dmaru);
@@ -580,9 +578,9 @@ static int register_one_rmrr(struct acpi_rmrr_unit *rmrru)
         if ( pci_device_detect(rmrru->segment, b, d, f) == 0 )
         {
             dprintk(XENLOG_WARNING VTDPREFIX,
-                    " Non-existent device (%04x:%02x:%02x.%u) is reported"
+                    " Non-existent device (%pp) is reported"
                     " in RMRR (%"PRIx64", %"PRIx64")'s scope!\n",
-                    rmrru->segment, b, d, f,
+                    &PCI_SBDF_T(rmrru->segment, b, d, f),
                     rmrru->base_address, rmrru->end_address);
             ignore = true;
         }
diff --git a/xen/drivers/passthrough/vtd/intremap.c b/xen/drivers/passthrough/vtd/intremap.c
index 0dbf99551e..bdf3758549 100644
--- a/xen/drivers/passthrough/vtd/intremap.c
+++ b/xen/drivers/passthrough/vtd/intremap.c
@@ -524,16 +524,13 @@ static void set_msi_source_id(struct pci_dev *pdev, struct iremap_entry *ire)
         }
         else
             dprintk(XENLOG_WARNING VTDPREFIX,
-                    "d%d: no upstream bridge for %04x:%02x:%02x.%u\n",
-                    pdev->domain->domain_id,
-                    seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+                    "d%d: no upstream bridge for %pp\n",
+                    pdev->domain->domain_id, &pdev->sbdf);
         break;
 
     default:
-        dprintk(XENLOG_WARNING VTDPREFIX,
-                "d%d: unknown(%u): %04x:%02x:%02x.%u\n",
-                pdev->domain->domain_id, pdev->type,
-                seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+        dprintk(XENLOG_WARNING VTDPREFIX, "d%d: unknown(%u): %pp\n",
+                pdev->domain->domain_id, pdev->type, &pdev->sbdf);
         break;
    }
 }
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index 7b70732863..3942df04b5 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -882,27 +882,24 @@ static int iommu_page_fault_do_one(struct iommu *iommu, int type,
     {
     case DMA_REMAP:
         printk(XENLOG_G_WARNING VTDPREFIX
-               "DMAR:[%s] Request device [%04x:%02x:%02x.%u] "
+               "DMAR:[%s] Request device [%pp] "
                "fault addr %"PRIx64", iommu reg = %p\n",
                (type ? "DMA Read" : "DMA Write"),
-               seg, PCI_BUS(source_id), PCI_SLOT(source_id),
-               PCI_FUNC(source_id), addr, iommu->reg);
+               &PCI_SBDF2_T(seg, source_id), addr, iommu->reg);
         kind = "DMAR";
         break;
     case INTR_REMAP:
         printk(XENLOG_G_WARNING VTDPREFIX
-               "INTR-REMAP: Request device [%04x:%02x:%02x.%u] "
+               "INTR-REMAP: Request device [%pp] "
                "fault index %"PRIx64", iommu reg = %p\n",
-               seg, PCI_BUS(source_id), PCI_SLOT(source_id),
-               PCI_FUNC(source_id), addr >> 48, iommu->reg);
+               &PCI_SBDF2_T(seg, source_id), addr >> 48, iommu->reg);
         kind = "INTR-REMAP";
         break;
     default:
         printk(XENLOG_G_WARNING VTDPREFIX
-               "UNKNOWN: Request device [%04x:%02x:%02x.%u] "
+               "UNKNOWN: Request device [%pp] "
                "fault addr %"PRIx64", iommu reg = %p\n",
-               seg, PCI_BUS(source_id), PCI_SLOT(source_id),
-               PCI_FUNC(source_id), addr, iommu->reg);
+               &PCI_SBDF2_T(seg, source_id), addr, iommu->reg);
         kind = "UNKNOWN";
         break;
     }
@@ -1354,10 +1351,8 @@ int domain_context_mapping_one(
         {
             if ( pdev->domain != domain )
             {
-                printk(XENLOG_G_INFO VTDPREFIX
-                       "d%d: %04x:%02x:%02x.%u owned by d%d!",
-                       domain->domain_id,
-                       seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+                printk(XENLOG_G_INFO VTDPREFIX "d%d: %pp owned by d%d!",
+                       domain->domain_id, &PCI_SBDF3_T(seg, bus, devfn),
                        pdev->domain ? pdev->domain->domain_id : -1);
                 res = -EINVAL;
             }
@@ -1370,17 +1365,15 @@ int domain_context_mapping_one(
             if ( cdomain < 0 )
             {
                 printk(XENLOG_G_WARNING VTDPREFIX
-                       "d%d: %04x:%02x:%02x.%u mapped, but can't find owner!\n",
-                       domain->domain_id,
-                       seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+                       "d%d: %pp mapped, but can't find owner!\n",
+                       domain->domain_id, &PCI_SBDF3_T(seg, bus, devfn));
                 res = -EINVAL;
             }
             else if ( cdomain != domain->domain_id )
             {
                 printk(XENLOG_G_INFO VTDPREFIX
-                       "d%d: %04x:%02x:%02x.%u already mapped to d%d!",
-                       domain->domain_id,
-                       seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+                       "d%d: %pp already mapped to d%d!",
+                       domain->domain_id, &PCI_SBDF3_T(seg, bus, devfn),
                        cdomain);
                 res = -EINVAL;
             }
@@ -1496,9 +1489,8 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
     {
     case DEV_TYPE_PCI_HOST_BRIDGE:
         if ( iommu_debug )
-            printk(VTDPREFIX "d%d:Hostbridge: skip %04x:%02x:%02x.%u map\n",
-                   domain->domain_id, seg, bus,
-                   PCI_SLOT(devfn), PCI_FUNC(devfn));
+            printk(VTDPREFIX "d%d:Hostbridge: skip %pp map\n",
+                   domain->domain_id, &pdev->sbdf);
         if ( !is_hardware_domain(domain) )
             return -EPERM;
         break;
@@ -1510,9 +1502,8 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
 
     case DEV_TYPE_PCIe_ENDPOINT:
         if ( iommu_debug )
-            printk(VTDPREFIX "d%d:PCIe: map %04x:%02x:%02x.%u\n",
-                   domain->domain_id, seg, bus,
-                   PCI_SLOT(devfn), PCI_FUNC(devfn));
+            printk(VTDPREFIX "d%d:PCIe: map %pp\n",
+                   domain->domain_id, &PCI_SBDF3_T(seg, bus, devfn));
         ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn,
                                          pdev);
         if ( !ret && devfn == pdev->sbdf.extfunc && ats_device(pdev, drhd) > 0 )
@@ -1522,9 +1513,8 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
 
     case DEV_TYPE_PCI:
         if ( iommu_debug )
-            printk(VTDPREFIX "d%d:PCI: map %04x:%02x:%02x.%u\n",
-                   domain->domain_id, seg, bus,
-                   PCI_SLOT(devfn), PCI_FUNC(devfn));
+            printk(VTDPREFIX "d%d:PCI: map %pp\n",
+                   domain->domain_id, &PCI_SBDF3_T(seg, bus, devfn));
 
         ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn,
                                          pdev);
@@ -1550,9 +1540,8 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
         break;
 
     default:
-        dprintk(XENLOG_ERR VTDPREFIX, "d%d:unknown(%u): %04x:%02x:%02x.%u\n",
-                domain->domain_id, pdev->type,
-                seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+        dprintk(XENLOG_ERR VTDPREFIX, "d%d:unknown(%u): %pp\n",
+                domain->domain_id, pdev->type, &PCI_SBDF3_T(seg, bus, devfn));
         ret = -EINVAL;
         break;
     }
@@ -1648,9 +1637,8 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
     {
     case DEV_TYPE_PCI_HOST_BRIDGE:
         if ( iommu_debug )
-            printk(VTDPREFIX "d%d:Hostbridge: skip %04x:%02x:%02x.%u unmap\n",
-                   domain->domain_id, seg, bus,
-                   PCI_SLOT(devfn), PCI_FUNC(devfn));
+            printk(VTDPREFIX "d%d:Hostbridge: skip %pp unmap\n",
+                   domain->domain_id, &pdev->sbdf);
         if ( !is_hardware_domain(domain) )
             return -EPERM;
         goto out;
@@ -1662,9 +1650,8 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
 
     case DEV_TYPE_PCIe_ENDPOINT:
         if ( iommu_debug )
-            printk(VTDPREFIX "d%d:PCIe: unmap %04x:%02x:%02x.%u\n",
-                   domain->domain_id, seg, bus,
-                   PCI_SLOT(devfn), PCI_FUNC(devfn));
+            printk(VTDPREFIX "d%d:PCIe: unmap %pp\n",
+                   domain->domain_id, &PCI_SBDF3_T(seg, bus, devfn));
         ret = domain_context_unmap_one(domain, iommu, bus, devfn);
         if ( !ret && devfn == pdev->sbdf.extfunc && ats_device(pdev, drhd) > 0 )
             disable_ats_device(pdev);
@@ -1673,8 +1660,8 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
 
     case DEV_TYPE_PCI:
         if ( iommu_debug )
-            printk(VTDPREFIX "d%d:PCI: unmap %04x:%02x:%02x.%u\n",
-                   domain->domain_id, seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+            printk(VTDPREFIX "d%d:PCI: unmap %pp\n",
+                   domain->domain_id, &PCI_SBDF3_T(seg, bus, devfn));
         ret = domain_context_unmap_one(domain, iommu, bus, devfn);
         if ( ret )
             break;
@@ -1699,9 +1686,8 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
         break;
 
     default:
-        dprintk(XENLOG_ERR VTDPREFIX, "d%d:unknown(%u): %04x:%02x:%02x.%u\n",
-                domain->domain_id, pdev->type,
-                seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+        dprintk(XENLOG_ERR VTDPREFIX, "d%d:unknown(%u): %pp\n",
+                domain->domain_id, pdev->type, &PCI_SBDF3_T(seg, bus, devfn));
         ret = -EINVAL;
         goto out;
     }
@@ -2499,11 +2485,11 @@ static int intel_iommu_assign_device(
             bool_t relaxed = !!(flag & XEN_DOMCTL_DEV_RDM_RELAXED);
 
             printk(XENLOG_GUEST "%s" VTDPREFIX
-                   " It's %s to assign %04x:%02x:%02x.%u"
+                   " It's %s to assign %pp"
                    " with shared RMRR at %"PRIx64" for Dom%d.\n",
                    relaxed ? XENLOG_WARNING : XENLOG_ERR,
                    relaxed ? "risky" : "disallowed",
-                   seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+                   &PCI_SBDF3_T(seg, bus, devfn),
                    rmrr->base_address, d->domain_id);
             if ( !relaxed )
                 return -EPERM;
diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c
index 48c7384b82..0302c503fb 100644
--- a/xen/drivers/passthrough/vtd/quirks.c
+++ b/xen/drivers/passthrough/vtd/quirks.c
@@ -428,8 +428,6 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
 {
     int seg = pdev->sbdf.seg;
     int bus = pdev->sbdf.bus;
-    int dev = pdev->sbdf.dev;
-    int func = pdev->sbdf.func;
     int pos;
     bool_t ff;
     u32 val, val2;
@@ -454,8 +452,7 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
     case 0x3c28: /* Sandybridge */
         val = pci_conf_read32(pdev->sbdf, 0x1AC);
         pci_conf_write32(pdev->sbdf, 0x1AC, val | (1 << 31));
-        printk(XENLOG_INFO "Masked VT-d error signaling on %04x:%02x:%02x.%u\n",
-               seg, bus, dev, func);
+        printk(XENLOG_INFO "Masked VT-d error signaling on %pp\n", &pdev->sbdf);
         break;
 
     /* Tylersburg (EP)/Boxboro (MP) chipsets (NHM-EP/EX, WSM-EP/EX) */
@@ -490,8 +487,7 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
             ff = pcie_aer_get_firmware_first(pdev);
         if ( !pos )
         {
-            printk(XENLOG_WARNING "%04x:%02x:%02x.%u without AER capability?\n",
-                   seg, bus, dev, func);
+            printk(XENLOG_WARNING "%pp without AER capability?\n", &pdev->sbdf);
             break;
         }
 
@@ -514,8 +510,7 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
         val = pci_conf_read32(pdev->sbdf, 0x20c);
         pci_conf_write32(pdev->sbdf, 0x20c, val | (1 << 4));
 
-        printk(XENLOG_INFO "%s UR signaling on %04x:%02x:%02x.%u\n",
-               action, seg, bus, dev, func);
+        printk(XENLOG_INFO "%s UR signaling on %pp\n", action, &pdev->sbdf);
         break;
 
     case 0x0040: case 0x0044: case 0x0048: /* Nehalem/Westmere */
@@ -540,16 +535,16 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
             {
                 __set_bit(0x1c8 * 8 + 20, va);
                 iounmap(va);
-                printk(XENLOG_INFO "Masked UR signaling on %04x:%02x:%02x.%u\n",
-                       seg, bus, dev, func);
+                printk(XENLOG_INFO "Masked UR signaling on %pp\n",
+                       &pdev->sbdf);
             }
             else
-                printk(XENLOG_ERR "Could not map %"PRIpaddr" for %04x:%02x:%02x.%u\n",
-                       pa, seg, bus, dev, func);
+                printk(XENLOG_ERR "Could not map %"PRIpaddr" for %pp\n",
+                       pa, &pdev->sbdf);
         }
         else
-            printk(XENLOG_WARNING "Bogus DMIBAR %#"PRIx64" on %04x:%02x:%02x.%u\n",
-                   bar, seg, bus, dev, func);
+            printk(XENLOG_WARNING "Bogus DMIBAR %#"PRIx64" on %pp\n",
+                   bar, &pdev->sbdf);
         break;
     }
 }
diff --git a/xen/drivers/passthrough/vtd/utils.c b/xen/drivers/passthrough/vtd/utils.c
index 94a6e4eec9..5665bf7697 100644
--- a/xen/drivers/passthrough/vtd/utils.c
+++ b/xen/drivers/passthrough/vtd/utils.c
@@ -95,9 +95,9 @@ void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn)
     u64 *l, val;
     u32 l_index, level;
 
-    printk("print_vtd_entries: iommu #%u dev %04x:%02x:%02x.%u gmfn %"PRI_gfn"\n",
-           iommu->index, iommu->intel->drhd->segment, bus,
-           PCI_SLOT(devfn), PCI_FUNC(devfn), gmfn);
+    printk("print_vtd_entries: iommu #%u dev %pp gmfn %"PRI_gfn"\n",
+           iommu->index, &PCI_SBDF3_T(iommu->intel->drhd->segment, bus, devfn),
+           gmfn);
 
     if ( iommu->root_maddr == 0 )
     {
diff --git a/xen/drivers/passthrough/x86/ats.c b/xen/drivers/passthrough/x86/ats.c
index c3203793a6..cfd610229d 100644
--- a/xen/drivers/passthrough/x86/ats.c
+++ b/xen/drivers/passthrough/x86/ats.c
@@ -31,8 +31,7 @@ int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
     BUG_ON(!pos);
 
     if ( iommu_verbose )
-        dprintk(XENLOG_INFO, "%04x:%02x:%02x.%u: ATS capability found\n",
-                seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+        dprintk(XENLOG_INFO, "%pp: ATS capability found\n", &pdev->sbdf);
 
     value = pci_conf_read16(pdev->sbdf, pos + ATS_REG_CTL);
     if ( value & ATS_ENABLE )
@@ -63,9 +62,8 @@ int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
     }
 
     if ( iommu_verbose )
-        dprintk(XENLOG_INFO, "%04x:%02x:%02x.%u: ATS %s enabled\n",
-                seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                pos ? "is" : "was");
+        dprintk(XENLOG_INFO, "%pp: ATS %s enabled\n",
+                &pdev->sbdf, pos ? "is" : "was");
 
     return pos;
 }
@@ -73,8 +71,6 @@ int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
 void disable_ats_device(struct pci_dev *pdev)
 {
     u32 value;
-    uint16_t seg = pdev->sbdf.seg;
-    uint8_t bus = pdev->sbdf.bus, devfn = pdev->sbdf.extfunc;
 
     BUG_ON(!pdev->ats.cap_pos);
 
@@ -85,6 +81,5 @@ void disable_ats_device(struct pci_dev *pdev)
     list_del(&pdev->ats.list);
 
     if ( iommu_verbose )
-        dprintk(XENLOG_INFO, "%04x:%02x:%02x.%u: ATS is disabled\n",
-                seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+        dprintk(XENLOG_INFO, "%pp: ATS is disabled\n", &pdev->sbdf);
 }
diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
index d693b1376c..ddda881366 100644
--- a/xen/drivers/vpci/header.c
+++ b/xen/drivers/vpci/header.c
@@ -371,9 +371,8 @@ static void bar_write(const struct pci_dev *pdev, unsigned int reg,
         /* If the value written is the current one avoid printing a warning. */
         if ( val != (uint32_t)(bar->addr >> (hi ? 32 : 0)) )
             gprintk(XENLOG_WARNING,
-                    "%04x:%02x:%02x.%u: ignored BAR %lu write with memory decoding enabled\n",
-                    pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                    pdev->sbdf.func, bar - pdev->vpci->header.bars + hi);
+                    "%pp: ignored BAR %lu write with memory decoding enabled\n",
+                    &pdev->sbdf, bar - pdev->vpci->header.bars + hi);
         return;
     }
 
@@ -407,9 +406,8 @@ static void rom_write(const struct pci_dev *pdev, unsigned int reg,
     if ( (cmd & PCI_COMMAND_MEMORY) && header->rom_enabled && new_enabled )
     {
         gprintk(XENLOG_WARNING,
-                "%04x:%02x:%02x.%u: ignored ROM BAR write with memory decoding enabled\n",
-                pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                pdev->sbdf.func);
+                "%pp: ignored ROM BAR write with memory decoding enabled\n",
+                &pdev->sbdf);
         return;
     }
 
diff --git a/xen/drivers/vpci/msi.c b/xen/drivers/vpci/msi.c
index 4f2e55f3fd..2bdae48edf 100644
--- a/xen/drivers/vpci/msi.c
+++ b/xen/drivers/vpci/msi.c
@@ -290,8 +290,7 @@ void vpci_dump_msi(void)
             msi = pdev->vpci->msi;
             if ( msi && msi->enabled )
             {
-                printk("%04x:%02x:%02x.%u MSI\n", pdev->sbdf.seg,
-                       pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func);
+                printk("%pp MSI\n", &pdev->sbdf);
 
                 printk("  enabled: %d 64-bit: %d",
                        msi->enabled, msi->address64);
@@ -308,8 +307,7 @@ void vpci_dump_msi(void)
             {
                 int rc;
 
-                printk("%04x:%02x:%02x.%u MSI-X\n", pdev->sbdf.seg,
-                       pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func);
+                printk("%pp MSI-X\n", &pdev->sbdf);
 
                 printk("  entries: %u maskall: %d enabled: %d\n",
                        msix->max_entries, msix->masked, msix->enabled);
diff --git a/xen/drivers/vpci/msix.c b/xen/drivers/vpci/msix.c
index 47d569121f..1006b01f4b 100644
--- a/xen/drivers/vpci/msix.c
+++ b/xen/drivers/vpci/msix.c
@@ -48,9 +48,8 @@ static int update_entry(struct vpci_msix_entry *entry,
     if ( rc && rc != -ENOENT )
     {
         gprintk(XENLOG_WARNING,
-                "%04x:%02x:%02x.%u: unable to disable entry %u for update: %d\n",
-                pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func,
-                nr, rc);
+                "%pp: unable to disable entry %u for update: %d\n",
+                &pdev->sbdf, nr, rc);
         return rc;
     }
 
@@ -59,10 +58,8 @@ static int update_entry(struct vpci_msix_entry *entry,
                                                       VPCI_MSIX_TABLE));
     if ( rc )
     {
-        gprintk(XENLOG_WARNING,
-                "%04x:%02x:%02x.%u: unable to enable entry %u: %d\n",
-                pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func,
-                nr, rc);
+        gprintk(XENLOG_WARNING, "%pp: unable to enable entry %u: %d\n",
+                &pdev->sbdf, nr, rc);
         /* Entry is likely not properly configured. */
         return rc;
     }
@@ -133,10 +130,8 @@ static void control_write(const struct pci_dev *pdev, unsigned int reg,
                 /* Ignore non-present entry. */
                 break;
             default:
-                gprintk(XENLOG_WARNING,
-                        "%04x:%02x:%02x.%u: unable to disable entry %u: %d\n",
-                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                        pdev->sbdf.func, i, rc);
+                gprintk(XENLOG_WARNING, "%pp: unable to disable entry %u: %d\n",
+                        &pdev->sbdf, i, rc);
                 return;
             }
         }
@@ -181,8 +176,7 @@ static bool access_allowed(const struct pci_dev *pdev, unsigned long addr,
         return true;
 
     gprintk(XENLOG_WARNING,
-            "%04x:%02x:%02x.%u: unaligned or invalid size MSI-X table access\n",
-            pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func);
+            "%pp: unaligned or invalid size MSI-X table access\n", &pdev->sbdf);
 
     return false;
 }
@@ -432,10 +426,9 @@ int vpci_make_msix_hole(const struct pci_dev *pdev)
             default:
                 put_gfn(d, start);
                 gprintk(XENLOG_WARNING,
-                        "%04x:%02x:%02x.%u: existing mapping (mfn: %" PRI_mfn
+                        "%pp: existing mapping (mfn: %" PRI_mfn
                         "type: %d) at %#lx clobbers MSIX MMIO area\n",
-                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                        pdev->sbdf.func, mfn_x(mfn), t, start);
+                        &pdev->sbdf, mfn_x(mfn), t, start);
                 return -EEXIST;
             }
             put_gfn(d, start);
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 9908d0fe5d..5e345c417f 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -60,6 +60,8 @@ typedef union {
 
 #define PCI_SBDF_T(s, b, d, f) \
     ((pci_sbdf_t) { .seg = (s), .bus = (b), .dev = (d), .func = (f) })
+#define PCI_SBDF2_T(s, b) \
+    ((pci_sbdf_t) { .seg = (s), .bdf = (b) })
 #define PCI_SBDF3_T(s, b, e) \
     ((pci_sbdf_t) { .seg = (s), .bus = (b), .extfunc = (e) })
 
-- 
2.17.2 (Apple Git-113)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Xen-devel] [PATCH 4/5] print: introduce a format specifier for pci_sbdf_t
@ 2019-05-10 16:10   ` Roger Pau Monne
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monne @ 2019-05-10 16:10 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Suravee Suthikulpanit,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper, Ian Jackson,
	Tim Deegan, Julien Grall, Jan Beulich, Brian Woods,
	Roger Pau Monne

The new format specifier is '%pp', and prints a pci_sbdf_t using the
seg:bus:dev.func format. Replace all SBDFs printed using
'%04x:%02x:%02x.%u' to use the new format specifier.

No functional change expected.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Julien Grall <julien.grall@arm.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Brian Woods <brian.woods@amd.com>
Cc: Kevin Tian <kevin.tian@intel.com>
---
 docs/misc/printk-formats.txt                |   5 +
 xen/arch/x86/hvm/vmsi.c                     |  10 +-
 xen/arch/x86/msi.c                          |  35 +++---
 xen/common/vsprintf.c                       |  18 +++
 xen/drivers/passthrough/amd/iommu_acpi.c    |  17 ++-
 xen/drivers/passthrough/amd/iommu_cmd.c     |   5 +-
 xen/drivers/passthrough/amd/iommu_detect.c  |   5 +-
 xen/drivers/passthrough/amd/iommu_init.c    |  11 +-
 xen/drivers/passthrough/amd/iommu_intr.c    |   8 +-
 xen/drivers/passthrough/amd/pci_amd_iommu.c |  31 +++--
 xen/drivers/passthrough/pci.c               | 121 ++++++++------------
 xen/drivers/passthrough/vtd/dmar.c          |  26 ++---
 xen/drivers/passthrough/vtd/intremap.c      |  11 +-
 xen/drivers/passthrough/vtd/iommu.c         |  74 +++++-------
 xen/drivers/passthrough/vtd/quirks.c        |  23 ++--
 xen/drivers/passthrough/vtd/utils.c         |   6 +-
 xen/drivers/passthrough/x86/ats.c           |  13 +--
 xen/drivers/vpci/header.c                   |  10 +-
 xen/drivers/vpci/msi.c                      |   6 +-
 xen/drivers/vpci/msix.c                     |  25 ++--
 xen/include/xen/pci.h                       |   2 +
 21 files changed, 197 insertions(+), 265 deletions(-)

diff --git a/docs/misc/printk-formats.txt b/docs/misc/printk-formats.txt
index 080f498f65..8f666f696a 100644
--- a/docs/misc/printk-formats.txt
+++ b/docs/misc/printk-formats.txt
@@ -48,3 +48,8 @@ Domain and vCPU information:
                The domain part as above, with the vcpu_id printed in decimal.
                  e.g.  d0v1
                        d[IDLE]v0
+
+PCI:
+
+       %pp     PCI device address in S:B:D.F format from a pci_sbdf_t.
+                 e.g.  0004:02:00.0
diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c
index 15cfe8d057..6f4641afbc 100644
--- a/xen/arch/x86/hvm/vmsi.c
+++ b/xen/arch/x86/hvm/vmsi.c
@@ -686,10 +686,8 @@ static int vpci_msi_update(const struct pci_dev *pdev, uint32_t data,
 
         if ( rc )
         {
-            gdprintk(XENLOG_ERR,
-                     "%04x:%02x:%02x.%u: failed to bind PIRQ %u: %d\n",
-                     pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                     pdev->sbdf.func, pirq + i, rc);
+            gdprintk(XENLOG_ERR, "%pp: failed to bind PIRQ %u: %d\n",
+                     &pdev->sbdf, pirq + i, rc);
             while ( bind.machine_irq-- > pirq )
                 pt_irq_destroy_bind(pdev->domain, &bind);
             return rc;
@@ -743,9 +741,7 @@ static int vpci_msi_enable(const struct pci_dev *pdev, uint32_t data,
                                    &msi_info);
     if ( rc )
     {
-        gdprintk(XENLOG_ERR, "%04x:%02x:%02x.%u: failed to map PIRQ: %d\n",
-                 pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                 pdev->sbdf.func, rc);
+        gdprintk(XENLOG_ERR, "%pp: failed to map PIRQ: %d\n", &pdev->sbdf, rc);
         return rc;
     }
 
diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index ad4a72d56b..6832211772 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -432,8 +432,8 @@ static bool msi_set_mask_bit(struct irq_desc *desc, bool host, bool guest)
             {
                 pdev->msix->warned = domid;
                 printk(XENLOG_G_WARNING
-                       "cannot mask IRQ %d: masking MSI-X on Dom%d's %04x:%02x:%02x.%u\n",
-                       desc->irq, domid, seg, bus, slot, func);
+                       "cannot mask IRQ %d: masking MSI-X on Dom%d's %pp\n",
+                       desc->irq, domid, &pdev->sbdf);
             }
         }
         pdev->msix->host_maskall = maskall;
@@ -991,11 +991,10 @@ static int msix_capability_init(struct pci_dev *dev,
             struct domain *d = dev->domain ?: currd;
 
             if ( !is_hardware_domain(currd) || d != currd )
-                printk("%s use of MSI-X on %04x:%02x:%02x.%u by Dom%d\n",
+                printk("%s use of MSI-X on %pp by Dom%d\n",
                        is_hardware_domain(currd)
                        ? XENLOG_WARNING "Potentially insecure"
-                       : XENLOG_ERR "Insecure",
-                       seg, bus, slot, func, d->domain_id);
+                       : XENLOG_ERR "Insecure", &dev->sbdf, d->domain_id);
             if ( !is_hardware_domain(d) &&
                  /* Assume a domain without memory has no mappings yet. */
                  (!is_hardware_domain(currd) || d->tot_pages) )
@@ -1050,18 +1049,15 @@ static int __pci_enable_msi(struct msi_info *msi, struct msi_desc **desc)
     old_desc = find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSI);
     if ( old_desc )
     {
-        printk(XENLOG_ERR "irq %d already mapped to MSI on %04x:%02x:%02x.%u\n",
-               msi->irq, msi->seg, msi->bus,
-               PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn));
+        printk(XENLOG_ERR "irq %d already mapped to MSI on %pp\n",
+               msi->irq, &pdev->sbdf);
         return -EEXIST;
     }
 
     old_desc = find_msi_entry(pdev, -1, PCI_CAP_ID_MSIX);
     if ( old_desc )
     {
-        printk(XENLOG_WARNING "MSI-X already in use on %04x:%02x:%02x.%u\n",
-               msi->seg, msi->bus,
-               PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn));
+        printk(XENLOG_WARNING "MSI-X already in use on %pp\n", &pdev->sbdf);
         __pci_disable_msix(old_desc);
     }
 
@@ -1118,16 +1114,15 @@ static int __pci_enable_msix(struct msi_info *msi, struct msi_desc **desc)
     old_desc = find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSIX);
     if ( old_desc )
     {
-        printk(XENLOG_ERR "irq %d already mapped to MSI-X on %04x:%02x:%02x.%u\n",
-               msi->irq, msi->seg, msi->bus, slot, func);
+        printk(XENLOG_ERR "irq %d already mapped to MSI-X on %pp\n",
+               msi->irq, &pdev->sbdf);
         return -EEXIST;
     }
 
     old_desc = find_msi_entry(pdev, -1, PCI_CAP_ID_MSI);
     if ( old_desc )
     {
-        printk(XENLOG_WARNING "MSI already in use on %04x:%02x:%02x.%u\n",
-               msi->seg, msi->bus, slot, func);
+        printk(XENLOG_WARNING "MSI already in use on %pp\n", &pdev->sbdf);
         __pci_disable_msi(old_desc);
     }
 
@@ -1175,8 +1170,8 @@ static void __pci_disable_msix(struct msi_desc *entry)
     else if ( !(control & PCI_MSIX_FLAGS_MASKALL) )
     {
         printk(XENLOG_WARNING
-               "cannot disable IRQ %d: masking MSI-X on %04x:%02x:%02x.%u\n",
-               entry->irq, seg, bus, slot, func);
+               "cannot disable IRQ %d: masking MSI-X on %pp\n",
+               entry->irq, &dev->sbdf);
         maskall = true;
     }
     dev->msix->host_maskall = maskall;
@@ -1342,7 +1337,6 @@ int pci_restore_msi_state(struct pci_dev *pdev)
     struct msi_desc *entry, *tmp;
     struct irq_desc *desc;
     struct msi_msg msg;
-    uint8_t slot = pdev->sbdf.dev, func = pdev->sbdf.func;
     unsigned int type = 0, pos = 0;
     u16 control = 0;
 
@@ -1369,9 +1363,8 @@ int pci_restore_msi_state(struct pci_dev *pdev)
         if (desc->msi_desc != entry)
         {
     bogus:
-            dprintk(XENLOG_ERR,
-                    "Restore MSI for %04x:%02x:%02x:%u entry %u not set?\n",
-                    pdev->sbdf.seg, pdev->sbdf.bus, slot, func, i);
+            dprintk(XENLOG_ERR, "Restore MSI for %pp entry %u not set?\n",
+                    &pdev->sbdf, i);
             spin_unlock_irqrestore(&desc->lock, flags);
             if ( type == PCI_CAP_ID_MSIX )
                 pci_conf_write16(pdev->sbdf, msix_control_reg(pos),
diff --git a/xen/common/vsprintf.c b/xen/common/vsprintf.c
index 352d43b425..b30ed08687 100644
--- a/xen/common/vsprintf.c
+++ b/xen/common/vsprintf.c
@@ -392,6 +392,20 @@ static char *print_vcpu(char *str, char *end, const struct vcpu *v)
     return number(str + 1, end, v->vcpu_id, 10, -1, -1, 0);
 }
 
+static char *print_pci_addr(char *str, char *end, const pci_sbdf_t *sbdf)
+{
+    str = number(str, end, sbdf->seg, 16, 4, -1, ZEROPAD);
+    if ( str < end )
+        *str = ':';
+    str = number(str + 1, end, sbdf->bus, 16, 2, -1, ZEROPAD);
+    if ( str < end )
+        *str = ':';
+    str = number(str + 1, end, sbdf->dev, 16, 2, -1, ZEROPAD);
+    if ( str < end )
+        *str = '.';
+    return number(str + 1, end, sbdf->func, 10, -1, -1, 0);
+}
+
 static char *pointer(char *str, char *end, const char **fmt_ptr,
                      const void *arg, int field_width, int precision,
                      int flags)
@@ -519,6 +533,10 @@ static char *pointer(char *str, char *end, const char **fmt_ptr,
     case 'v': /* d<domain-id>v<vcpu-id> from a struct vcpu */
         ++*fmt_ptr;
         return print_vcpu(str, end, arg);
+
+    case 'p': /* PCI SBDF. */
+        ++*fmt_ptr;
+        return print_pci_addr(str, end, arg);
     }
 
     if ( field_width == -1 )
diff --git a/xen/drivers/passthrough/amd/iommu_acpi.c b/xen/drivers/passthrough/amd/iommu_acpi.c
index 64d10481d7..d900feef09 100644
--- a/xen/drivers/passthrough/amd/iommu_acpi.c
+++ b/xen/drivers/passthrough/amd/iommu_acpi.c
@@ -717,9 +717,8 @@ static u16 __init parse_ivhd_device_special(
         return 0;
     }
 
-    AMD_IOMMU_DEBUG("IVHD Special: %04x:%02x:%02x.%u variety %#x handle %#x\n",
-                    seg, PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf),
-                    special->variety, special->handle);
+    AMD_IOMMU_DEBUG("IVHD Special: %pp variety %#x handle %#x\n",
+                    &PCI_SBDF2_T(seg, bdf), special->variety, special->handle);
     add_ivrs_mapping_entry(bdf, bdf, special->header.data_setting, iommu);
 
     switch ( special->variety )
@@ -742,9 +741,9 @@ static u16 __init parse_ivhd_device_special(
         if ( idx < nr_ioapic_sbdf )
         {
             AMD_IOMMU_DEBUG("IVHD: Command line override present for IO-APIC %#x"
-                            "(IVRS: %#x devID %04x:%02x:%02x.%u)\n",
-                            ioapic_sbdf[idx].id, special->handle, seg,
-                            PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf));
+                            "(IVRS: %#x devID %pp)\n",
+                            ioapic_sbdf[idx].id, special->handle,
+                            &PCI_SBDF2_T(seg, bdf));
             break;
         }
 
@@ -814,9 +813,9 @@ static u16 __init parse_ivhd_device_special(
             break;
         case HPET_CMDL:
             AMD_IOMMU_DEBUG("IVHD: Command line override present for HPET %#x "
-                            "(IVRS: %#x devID %04x:%02x:%02x.%u)\n",
-                            hpet_sbdf.id, special->handle, seg, PCI_BUS(bdf),
-                            PCI_SLOT(bdf), PCI_FUNC(bdf));
+                            "(IVRS: %#x devID %pp)\n",
+                            hpet_sbdf.id, special->handle,
+                            &PCI_SBDF2_T(seg, bdf));
             break;
         case HPET_NONE:
             /* set device id of hpet */
diff --git a/xen/drivers/passthrough/amd/iommu_cmd.c b/xen/drivers/passthrough/amd/iommu_cmd.c
index 82330c24ba..9bbc5a5545 100644
--- a/xen/drivers/passthrough/amd/iommu_cmd.c
+++ b/xen/drivers/passthrough/amd/iommu_cmd.c
@@ -296,9 +296,8 @@ void amd_iommu_flush_iotlb(u8 devfn, const struct pci_dev *pdev,
 
     if ( !iommu )
     {
-        AMD_IOMMU_DEBUG("%s: Can't find iommu for %04x:%02x:%02x.%u\n",
-                        __func__, pdev->sbdf.seg, pdev->sbdf.bus,
-                        pdev->sbdf.dev, pdev->sbdf.func);
+        AMD_IOMMU_DEBUG("%s: Can't find iommu for %pp\n",
+                        __func__, &pdev->sbdf);
         return;
     }
 
diff --git a/xen/drivers/passthrough/amd/iommu_detect.c b/xen/drivers/passthrough/amd/iommu_detect.c
index e8d8ec59bd..91f5ea6bff 100644
--- a/xen/drivers/passthrough/amd/iommu_detect.c
+++ b/xen/drivers/passthrough/amd/iommu_detect.c
@@ -153,9 +153,8 @@ int __init amd_iommu_detect_one_acpi(
 
     rt = pci_ro_device(iommu->seg, bus, PCI_DEVFN(dev, func));
     if ( rt )
-        printk(XENLOG_ERR
-               "Could not mark config space of %04x:%02x:%02x.%u read-only (%d)\n",
-               iommu->seg, bus, dev, func, rt);
+        printk(XENLOG_ERR "Could not mark config space of %pp read-only (%d)\n",
+               &PCI_SBDF2_T(iommu->seg, iommu->bdf), rt);
 
     list_add_tail(&iommu->list, &amd_iommu_head);
     rt = 0;
diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c
index fe0516f788..f39c67949f 100644
--- a/xen/drivers/passthrough/amd/iommu_init.c
+++ b/xen/drivers/passthrough/amd/iommu_init.c
@@ -793,9 +793,8 @@ static bool_t __init set_iommu_interrupt_handler(struct amd_iommu *iommu)
     pcidevs_unlock();
     if ( !iommu->msi.dev )
     {
-        AMD_IOMMU_DEBUG("IOMMU: no pdev for %04x:%02x:%02x.%u\n",
-                        iommu->seg, PCI_BUS(iommu->bdf),
-                        PCI_SLOT(iommu->bdf), PCI_FUNC(iommu->bdf));
+        AMD_IOMMU_DEBUG("IOMMU: no pdev for %pp\n",
+                        &PCI_SBDF2_T(iommu->seg, iommu->bdf));
         return 0;
     }
     control = pci_conf_read16(iommu->msi.dev->sbdf,
@@ -838,9 +837,6 @@ static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
         .seg = iommu->seg,
         .bdf = iommu->bdf,
     };
-    u8 bus = PCI_BUS(iommu->bdf);
-    u8 dev = PCI_SLOT(iommu->bdf);
-    u8 func = PCI_FUNC(iommu->bdf);
 
     if ( (boot_cpu_data.x86 != 0x15) ||
          (boot_cpu_data.x86_model < 0x10) ||
@@ -858,8 +854,7 @@ static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
 
     pci_conf_write32(sbdf, 0xf4, value | (1 << 2));
     printk(XENLOG_INFO
-           "AMD-Vi: Applying erratum 746 workaround for IOMMU at %04x:%02x:%02x.%u\n",
-           iommu->seg, bus, dev, func);
+           "AMD-Vi: Applying erratum 746 workaround for IOMMU at %pp\n", &sbdf);
 
     /* Clear the enable writing bit */
     pci_conf_write32(sbdf, 0xf0, 0x90);
diff --git a/xen/drivers/passthrough/amd/iommu_intr.c b/xen/drivers/passthrough/amd/iommu_intr.c
index 71594cc27d..eca8decc05 100644
--- a/xen/drivers/passthrough/amd/iommu_intr.c
+++ b/xen/drivers/passthrough/amd/iommu_intr.c
@@ -511,8 +511,7 @@ static struct amd_iommu *_find_iommu_for_device(int seg, int bdf)
     if ( iommu )
         return iommu;
 
-    AMD_IOMMU_DEBUG("No IOMMU for MSI dev = %04x:%02x:%02x.%u\n",
-                    seg, PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf));
+    AMD_IOMMU_DEBUG("No IOMMU for MSI dev = %pp\n", &PCI_SBDF2_T(seg, bdf));
     return ERR_PTR(-EINVAL);
 }
 
@@ -687,10 +686,7 @@ static int dump_intremap_mapping(u16 seg, struct ivrs_mappings *ivrs_mapping)
     if ( !ivrs_mapping )
         return 0;
 
-    printk("  %04x:%02x:%02x:%u:\n", seg,
-           PCI_BUS(ivrs_mapping->dte_requestor_id),
-           PCI_SLOT(ivrs_mapping->dte_requestor_id),
-           PCI_FUNC(ivrs_mapping->dte_requestor_id));
+    printk("  %pp:\n", &PCI_SBDF2_T(seg,ivrs_mapping->dte_requestor_id));
 
     spin_lock_irqsave(&(ivrs_mapping->intremap_lock), flags);
     dump_intremap_table(ivrs_mapping->intremap_table);
diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/passthrough/amd/pci_amd_iommu.c
index 0e4c5b4994..5787dff914 100644
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -52,9 +52,8 @@ struct amd_iommu *find_iommu_for_device(int seg, int bdf)
                 tmp.dte_requestor_id = bdf;
             ivrs_mappings[bdf] = tmp;
 
-            printk(XENLOG_WARNING "%04x:%02x:%02x.%u not found in ACPI tables;"
-                   " using same IOMMU as function 0\n",
-                   seg, PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf));
+            printk(XENLOG_WARNING "%pp not found in ACPI tables;"
+                   " using same IOMMU as function 0\n", &PCI_SBDF2_T(seg, bdf));
 
             /* write iommu field last */
             ivrs_mappings[bdf].iommu = ivrs_mappings[bd0].iommu;
@@ -306,9 +305,9 @@ static int reassign_device(struct domain *source, struct domain *target,
     if ( !iommu )
     {
         AMD_IOMMU_DEBUG("Fail to find iommu."
-                        " %04x:%02x:%x02.%x cannot be assigned to dom%d\n",
-                        pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn),
-                        PCI_FUNC(devfn), target->domain_id);
+                        " %pp cannot be assigned to dom%d\n",
+                        &PCI_SBDF3_T(pdev->sbdf.seg, pdev->sbdf.bus, devfn),
+                        target->domain_id);
         return -ENODEV;
     }
 
@@ -325,9 +324,9 @@ static int reassign_device(struct domain *source, struct domain *target,
         return rc;
 
     amd_iommu_setup_domain_device(target, iommu, devfn, pdev);
-    AMD_IOMMU_DEBUG("Re-assign %04x:%02x:%02x.%u from dom%d to dom%d\n",
-                    pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn),
-                    PCI_FUNC(devfn), source->domain_id, target->domain_id);
+    AMD_IOMMU_DEBUG("Re-assign %pp from dom%d to dom%d\n",
+                    &PCI_SBDF3_T(pdev->sbdf.seg, pdev->sbdf.bus, devfn),
+                    source->domain_id, target->domain_id);
 
     return 0;
 }
@@ -430,15 +429,12 @@ static int amd_iommu_add_device(u8 devfn, struct pci_dev *pdev)
         if ( pdev->type == DEV_TYPE_PCI_HOST_BRIDGE &&
              is_hardware_domain(pdev->domain) )
         {
-            AMD_IOMMU_DEBUG("Skipping host bridge %04x:%02x:%02x.%u\n",
-                            pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                            pdev->sbdf.func);
+            AMD_IOMMU_DEBUG("Skipping host bridge %pp\n", &pdev->sbdf);
             return 0;
         }
 
-        AMD_IOMMU_DEBUG("No iommu for %04x:%02x:%02x.%u; cannot be handed to d%d\n",
-                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                        pdev->sbdf.func, pdev->domain->domain_id);
+        AMD_IOMMU_DEBUG("No iommu for %pp; cannot be handed to d%d\n",
+                        &pdev->sbdf, pdev->domain->domain_id);
         return -ENODEV;
     }
 
@@ -457,9 +453,8 @@ static int amd_iommu_remove_device(u8 devfn, struct pci_dev *pdev)
     if ( !iommu )
     {
         AMD_IOMMU_DEBUG("Fail to find iommu."
-                        " %04x:%02x:%02x.%u cannot be removed from dom%d\n",
-                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                        pdev->sbdf.func, pdev->domain->domain_id);
+                        " %pp cannot be removed from dom%d\n",
+                        &pdev->sbdf, pdev->domain->domain_id);
         return -ENODEV;
     }
 
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index 94fb3a183d..a9667ca21c 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -238,10 +238,6 @@ static void check_pdev(const struct pci_dev *pdev)
     (PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT | \
      PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT | \
      PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY)
-    uint16_t seg = pdev->sbdf.seg;
-    uint8_t bus = pdev->sbdf.bus;
-    uint8_t dev = pdev->sbdf.dev;
-    uint8_t func = pdev->sbdf.func;
     u16 val;
 
     if ( command_mask )
@@ -252,8 +248,8 @@ static void check_pdev(const struct pci_dev *pdev)
         val = pci_conf_read16(pdev->sbdf, PCI_STATUS);
         if ( val & PCI_STATUS_CHECK )
         {
-            printk(XENLOG_INFO "%04x:%02x:%02x.%u status %04x -> %04x\n",
-                   seg, bus, dev, func, val, val & ~PCI_STATUS_CHECK);
+            printk(XENLOG_INFO "%pp status %04x -> %04x\n",
+                   &pdev->sbdf, val, val & ~PCI_STATUS_CHECK);
             pci_conf_write16(pdev->sbdf, PCI_STATUS, val & PCI_STATUS_CHECK);
         }
     }
@@ -270,9 +266,8 @@ static void check_pdev(const struct pci_dev *pdev)
         val = pci_conf_read16(pdev->sbdf, PCI_SEC_STATUS);
         if ( val & PCI_STATUS_CHECK )
         {
-            printk(XENLOG_INFO
-                   "%04x:%02x:%02x.%u secondary status %04x -> %04x\n",
-                   seg, bus, dev, func, val, val & ~PCI_STATUS_CHECK);
+            printk(XENLOG_INFO "%pp secondary status %04x -> %04x\n",
+                   &pdev->sbdf, val, val & ~PCI_STATUS_CHECK);
             pci_conf_write16(pdev->sbdf, PCI_SEC_STATUS,
                              val & PCI_STATUS_CHECK);
         }
@@ -409,8 +404,8 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
             break;
 
         default:
-            printk(XENLOG_WARNING "%04x:%02x:%02x.%u: unknown type %d\n",
-                   pseg->nr, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pdev->type);
+            printk(XENLOG_WARNING "%pp: unknown type %d\n",
+                   &pdev->sbdf, pdev->type);
             break;
     }
 
@@ -642,9 +637,9 @@ unsigned int pci_size_mem_bar(pci_sbdf_t sbdf, unsigned int pos,
         if ( flags & PCI_BAR_LAST )
         {
             printk(XENLOG_WARNING
-                   "%sdevice %04x:%02x:%02x.%u with 64-bit %sBAR in last slot\n",
-                   (flags & PCI_BAR_VF) ? "SR-IOV " : "", sbdf.seg, sbdf.bus,
-                   sbdf.dev, sbdf.func, (flags & PCI_BAR_VF) ? "vf " : "");
+                   "%sdevice %pp with 64-bit %sBAR in last slot\n",
+                   (flags & PCI_BAR_VF) ? "SR-IOV " : "", &sbdf,
+                   (flags & PCI_BAR_VF) ? "vf " : "");
             *psize = 0;
             return 1;
         }
@@ -674,7 +669,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
 {
     struct pci_seg *pseg;
     struct pci_dev *pdev;
-    unsigned int slot = PCI_SLOT(devfn), func = PCI_FUNC(devfn);
+    unsigned int func = PCI_FUNC(devfn);
     const char *pdev_type;
     int ret;
     bool pf_is_extfn = false;
@@ -747,9 +742,8 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
                      PCI_BASE_ADDRESS_SPACE_IO )
                 {
                     printk(XENLOG_WARNING
-                           "SR-IOV device %04x:%02x:%02x.%u with vf BAR%u"
-                           " in IO space\n",
-                           seg, bus, slot, func, i);
+                           "SR-IOV device %pp with vf BAR%u in IO space\n",
+                           &pdev->sbdf, i);
                     continue;
                 }
                 ret = pci_size_mem_bar(pdev->sbdf, idx, NULL, &pdev->vf_rlen[i],
@@ -762,9 +756,9 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
         }
         else
             printk(XENLOG_WARNING
-                   "SR-IOV device %04x:%02x:%02x.%u has its virtual"
+                   "SR-IOV device %pp has its virtual"
                    " functions already enabled (%04x)\n",
-                   seg, bus, slot, func, ctrl);
+                   &pdev->sbdf, ctrl);
     }
 
     check_pdev(pdev);
@@ -791,15 +785,13 @@ out:
     pcidevs_unlock();
     if ( !ret )
     {
-        printk(XENLOG_DEBUG "PCI add %s %04x:%02x:%02x.%u\n", pdev_type,
-               seg, bus, slot, func);
+        printk(XENLOG_DEBUG "PCI add %s %pp\n", pdev_type, &pdev->sbdf);
         while ( pdev->phantom_stride )
         {
             func += pdev->phantom_stride;
             if ( PCI_SLOT(func) )
                 break;
-            printk(XENLOG_DEBUG "PCI phantom %04x:%02x:%02x.%u\n",
-                   seg, bus, slot, func);
+            printk(XENLOG_DEBUG "PCI phantom %pp\n", &pdev->sbdf);
         }
     }
     return ret;
@@ -829,8 +821,8 @@ int pci_remove_device(u16 seg, u8 bus, u8 devfn)
                 list_del(&pdev->domain_list);
             pci_cleanup_msi(pdev);
             free_pdev(pseg, pdev);
-            printk(XENLOG_DEBUG "PCI remove device %04x:%02x:%02x.%u\n",
-                   seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+            printk(XENLOG_DEBUG "PCI remove device %pp\n",
+                   &PCI_SBDF3_T(seg, bus, devfn));
             break;
         }
 
@@ -889,7 +881,6 @@ static int pci_clean_dpci_irqs(struct domain *d)
 int pci_release_devices(struct domain *d)
 {
     struct pci_dev *pdev;
-    u8 bus, devfn;
     int ret;
 
     pcidevs_lock();
@@ -900,14 +891,10 @@ int pci_release_devices(struct domain *d)
         return ret;
     }
     while ( (pdev = pci_get_pdev_by_domain(d, -1, -1, -1)) )
-    {
-        bus = pdev->sbdf.bus;
-        devfn = pdev->sbdf.extfunc;
-        if ( deassign_device(d, pdev->sbdf.seg, bus, devfn) )
-            printk("domain %d: deassign device (%04x:%02x:%02x.%u) failed!\n",
-                   d->domain_id, pdev->sbdf.seg, bus,
-                   PCI_SLOT(devfn), PCI_FUNC(devfn));
-    }
+        if ( deassign_device(d, pdev->sbdf.seg, pdev->sbdf.bus,
+                             pdev->sbdf.extfunc) )
+            printk("domain %d: deassign device (%pp) failed!\n",
+                   d->domain_id, &pdev->sbdf);
     pcidevs_unlock();
 
     return 0;
@@ -1059,8 +1046,8 @@ static int __init _scan_pci_devices(struct pci_seg *pseg, void *arg)
                 pdev = alloc_pdev(pseg, bus, PCI_DEVFN(dev, func));
                 if ( !pdev )
                 {
-                    printk(XENLOG_WARNING "%04x:%02x:%02x.%u: alloc_pdev failed\n",
-                           pseg->nr, bus, dev, func);
+                    printk(XENLOG_WARNING "%pp: alloc_pdev failed\n",
+                           &PCI_SBDF_T(pseg->nr, bus, dev, func));
                     return -ENOMEM;
                 }
 
@@ -1100,9 +1087,8 @@ static void __hwdom_init setup_one_hwdom_device(const struct setup_hwdom *ctxt,
         err = ctxt->handler(devfn, pdev);
         if ( err )
         {
-            printk(XENLOG_ERR "setup %04x:%02x:%02x.%u for d%d failed (%d)\n",
-                   pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                   pdev->sbdf.func, ctxt->d->domain_id, err);
+            printk(XENLOG_ERR "setup %pp for d%d failed (%d)\n",
+                   &pdev->sbdf, ctxt->d->domain_id, err);
             if ( devfn == pdev->sbdf.extfunc )
                 return;
         }
@@ -1143,9 +1129,8 @@ static int __hwdom_init _setup_hwdom_pci_devices(struct pci_seg *pseg, void *arg
                 pdev->domain = dom_xen;
             }
             else if ( pdev->domain != ctxt->d )
-                printk(XENLOG_WARNING "Dom%d owning %04x:%02x:%02x.%u?\n",
-                       pdev->domain->domain_id, pseg->nr, bus,
-                       PCI_SLOT(devfn), PCI_FUNC(devfn));
+                printk(XENLOG_WARNING "Dom%d owning %pp?\n",
+                       pdev->domain->domain_id, &pdev->sbdf);
 
             if ( iommu_verbose )
             {
@@ -1280,8 +1265,8 @@ static int _dump_pci_devices(struct pci_seg *pseg, void *arg)
 
     list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
     {
-        printk("%04x:%02x:%02x.%u - dom %-3d - node %-3d - MSIs < ",
-               pseg->nr, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func,
+        printk("%pp - dom %-3d - node %-3d - MSIs < ",
+               &pdev->sbdf,
                pdev->domain ? pdev->domain->domain_id : -1,
                (pdev->node != NUMA_NO_NODE) ? pdev->node : -1);
         list_for_each_entry ( msi, &pdev->msi_list, list )
@@ -1347,9 +1332,8 @@ static int iommu_add_device(struct pci_dev *pdev)
             return 0;
         rc = hd->platform_ops->add_device(devfn, pci_to_dev(pdev));
         if ( rc )
-            printk(XENLOG_WARNING "IOMMU: add %04x:%02x:%02x.%u failed (%d)\n",
-                   pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn),
-                   PCI_FUNC(devfn), rc);
+            printk(XENLOG_WARNING "IOMMU: add %pp failed (%d)\n",
+                   &pdev->sbdf, rc);
     }
 }
 
@@ -1393,9 +1377,8 @@ static int iommu_remove_device(struct pci_dev *pdev)
         if ( !rc )
             continue;
 
-        printk(XENLOG_ERR "IOMMU: remove %04x:%02x:%02x.%u failed (%d)\n",
-               pdev->sbdf.seg, pdev->sbdf.bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-               rc);
+        printk(XENLOG_ERR "IOMMU: remove %pp failed (%d)\n",
+               &pdev->sbdf, rc);
         return rc;
     }
 
@@ -1465,9 +1448,8 @@ static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn, u32 flag)
             break;
         rc = hd->platform_ops->assign_device(d, devfn, pci_to_dev(pdev), flag);
         if ( rc )
-            printk(XENLOG_G_WARNING "d%d: assign %04x:%02x:%02x.%u failed (%d)\n",
-                   d->domain_id, seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                   rc);
+            printk(XENLOG_G_WARNING "d%d: assign %pp failed (%d)\n",
+                   d->domain_id, &PCI_SBDF3_T(seg, bus, devfn), rc);
     }
 
  done:
@@ -1503,8 +1485,8 @@ int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
         if ( !ret )
             continue;
 
-        printk(XENLOG_G_ERR "d%d: deassign %04x:%02x:%02x.%u failed (%d)\n",
-               d->domain_id, seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), ret);
+        printk(XENLOG_G_ERR "d%d: deassign %pp failed (%d)\n",
+               d->domain_id, &PCI_SBDF3_T(seg, bus, devfn), ret);
         return ret;
     }
 
@@ -1513,9 +1495,8 @@ int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
                                             pci_to_dev(pdev));
     if ( ret )
     {
-        dprintk(XENLOG_G_ERR,
-                "d%d: deassign device (%04x:%02x:%02x.%u) failed\n",
-                d->domain_id, seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+        dprintk(XENLOG_G_ERR, "d%d: deassign device (%pp) failed\n",
+                d->domain_id, &PCI_SBDF3_T(seg, bus, devfn));
         return ret;
     }
 
@@ -1590,10 +1571,8 @@ void iommu_dev_iotlb_flush_timeout(struct domain *d, struct pci_dev *pdev)
     _pci_hide_device(pdev);
 
     if ( !d->is_shutting_down && printk_ratelimit() )
-        printk(XENLOG_ERR
-               "dom%d: ATS device %04x:%02x:%02x.%u flush failed\n",
-               d->domain_id, pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-               pdev->sbdf.func);
+        printk(XENLOG_ERR "dom%d: ATS device %pp flush failed\n",
+               d->domain_id, &pdev->sbdf);
     if ( !is_hardware_domain(d) )
         domain_crash(d);
 
@@ -1682,9 +1661,8 @@ int iommu_do_pci_domctl(
         {
             if ( ret )
             {
-                printk(XENLOG_G_INFO
-                       "%04x:%02x:%02x.%u already assigned, or non-existent\n",
-                       seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+                printk(XENLOG_G_INFO "%pp already assigned, or non-existent\n",
+                       &PCI_SBDF3_T(seg, bus, devfn));
                 ret = -EINVAL;
             }
             break;
@@ -1696,9 +1674,8 @@ int iommu_do_pci_domctl(
                                                 "h", u_domctl);
         else if ( ret )
             printk(XENLOG_G_ERR "XEN_DOMCTL_assign_device: "
-                   "assign %04x:%02x:%02x.%u to dom%d failed (%d)\n",
-                   seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                   d->domain_id, ret);
+                   "assign %pp to dom%d failed (%d)\n",
+                   &PCI_SBDF3_T(seg, bus, devfn), d->domain_id, ret);
 
         break;
 
@@ -1732,10 +1709,8 @@ int iommu_do_pci_domctl(
         ret = deassign_device(d, seg, bus, devfn);
         pcidevs_unlock();
         if ( ret )
-            printk(XENLOG_G_ERR
-                   "deassign %04x:%02x:%02x.%u from dom%d failed (%d)\n",
-                   seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                   d->domain_id, ret);
+            printk(XENLOG_G_ERR "deassign %pp from dom%d failed (%d)\n",
+                   &PCI_SBDF3_T(seg, bus, devfn), d->domain_id, ret);
 
         break;
 
diff --git a/xen/drivers/passthrough/vtd/dmar.c b/xen/drivers/passthrough/vtd/dmar.c
index 9d30188ab9..911494752f 100644
--- a/xen/drivers/passthrough/vtd/dmar.c
+++ b/xen/drivers/passthrough/vtd/dmar.c
@@ -367,18 +367,16 @@ static int __init acpi_parse_dev_scope(
             sec_bus = pci_conf_read8(sbdf, PCI_SECONDARY_BUS);
             sub_bus = pci_conf_read8(sbdf, PCI_SUBORDINATE_BUS);
             if ( iommu_verbose )
-                printk(VTDPREFIX
-                       " bridge: %04x:%02x:%02x.%u start=%x sec=%x sub=%x\n",
-                       seg, bus, path->dev, path->fn,
-                       acpi_scope->bus, sec_bus, sub_bus);
+                printk(VTDPREFIX " bridge: %pp start=%x sec=%x sub=%x\n",
+                       &sbdf, acpi_scope->bus, sec_bus, sub_bus);
 
             dmar_scope_add_buses(scope, sec_bus, sub_bus);
             break;
         }
         case ACPI_DMAR_SCOPE_TYPE_HPET:
             if ( iommu_verbose )
-                printk(VTDPREFIX " MSI HPET: %04x:%02x:%02x.%u\n",
-                       seg, bus, path->dev, path->fn);
+                printk(VTDPREFIX " MSI HPET: %pp\n",
+                       &PCI_SBDF_T(seg, bus, path->dev, path->fn));
 
             if ( drhd )
             {
@@ -399,8 +397,8 @@ static int __init acpi_parse_dev_scope(
 
         case ACPI_DMAR_SCOPE_TYPE_ENDPOINT:
             if ( iommu_verbose )
-                printk(VTDPREFIX " endpoint: %04x:%02x:%02x.%u\n",
-                       seg, bus, path->dev, path->fn);
+                printk(VTDPREFIX " endpoint: %pp\n",
+                       &PCI_SBDF_T(seg, bus, path->dev, path->fn));
 
             if ( drhd )
             {
@@ -413,8 +411,8 @@ static int __init acpi_parse_dev_scope(
 
         case ACPI_DMAR_SCOPE_TYPE_IOAPIC:
             if ( iommu_verbose )
-                printk(VTDPREFIX " IOAPIC: %04x:%02x:%02x.%u\n",
-                       seg, bus, path->dev, path->fn);
+                printk(VTDPREFIX " IOAPIC: %pp\n",
+                       &PCI_SBDF_T(seg, bus, path->dev, path->fn));
 
             if ( drhd )
             {
@@ -543,8 +541,8 @@ acpi_parse_one_drhd(struct acpi_dmar_header *header)
 
             if ( !pci_device_detect(drhd->segment, b, d, f) )
                 printk(XENLOG_WARNING VTDPREFIX
-                       " Non-existent device (%04x:%02x:%02x.%u) in this DRHD's scope!\n",
-                       drhd->segment, b, d, f);
+                       " Non-existent device (%pp) in this DRHD's scope!\n",
+                       &PCI_SBDF_T(drhd->segment, b, d, f));
         }
 
         acpi_register_drhd_unit(dmaru);
@@ -580,9 +578,9 @@ static int register_one_rmrr(struct acpi_rmrr_unit *rmrru)
         if ( pci_device_detect(rmrru->segment, b, d, f) == 0 )
         {
             dprintk(XENLOG_WARNING VTDPREFIX,
-                    " Non-existent device (%04x:%02x:%02x.%u) is reported"
+                    " Non-existent device (%pp) is reported"
                     " in RMRR (%"PRIx64", %"PRIx64")'s scope!\n",
-                    rmrru->segment, b, d, f,
+                    &PCI_SBDF_T(rmrru->segment, b, d, f),
                     rmrru->base_address, rmrru->end_address);
             ignore = true;
         }
diff --git a/xen/drivers/passthrough/vtd/intremap.c b/xen/drivers/passthrough/vtd/intremap.c
index 0dbf99551e..bdf3758549 100644
--- a/xen/drivers/passthrough/vtd/intremap.c
+++ b/xen/drivers/passthrough/vtd/intremap.c
@@ -524,16 +524,13 @@ static void set_msi_source_id(struct pci_dev *pdev, struct iremap_entry *ire)
         }
         else
             dprintk(XENLOG_WARNING VTDPREFIX,
-                    "d%d: no upstream bridge for %04x:%02x:%02x.%u\n",
-                    pdev->domain->domain_id,
-                    seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+                    "d%d: no upstream bridge for %pp\n",
+                    pdev->domain->domain_id, &pdev->sbdf);
         break;
 
     default:
-        dprintk(XENLOG_WARNING VTDPREFIX,
-                "d%d: unknown(%u): %04x:%02x:%02x.%u\n",
-                pdev->domain->domain_id, pdev->type,
-                seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+        dprintk(XENLOG_WARNING VTDPREFIX, "d%d: unknown(%u): %pp\n",
+                pdev->domain->domain_id, pdev->type, &pdev->sbdf);
         break;
    }
 }
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index 7b70732863..3942df04b5 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -882,27 +882,24 @@ static int iommu_page_fault_do_one(struct iommu *iommu, int type,
     {
     case DMA_REMAP:
         printk(XENLOG_G_WARNING VTDPREFIX
-               "DMAR:[%s] Request device [%04x:%02x:%02x.%u] "
+               "DMAR:[%s] Request device [%pp] "
                "fault addr %"PRIx64", iommu reg = %p\n",
                (type ? "DMA Read" : "DMA Write"),
-               seg, PCI_BUS(source_id), PCI_SLOT(source_id),
-               PCI_FUNC(source_id), addr, iommu->reg);
+               &PCI_SBDF2_T(seg, source_id), addr, iommu->reg);
         kind = "DMAR";
         break;
     case INTR_REMAP:
         printk(XENLOG_G_WARNING VTDPREFIX
-               "INTR-REMAP: Request device [%04x:%02x:%02x.%u] "
+               "INTR-REMAP: Request device [%pp] "
                "fault index %"PRIx64", iommu reg = %p\n",
-               seg, PCI_BUS(source_id), PCI_SLOT(source_id),
-               PCI_FUNC(source_id), addr >> 48, iommu->reg);
+               &PCI_SBDF2_T(seg, source_id), addr >> 48, iommu->reg);
         kind = "INTR-REMAP";
         break;
     default:
         printk(XENLOG_G_WARNING VTDPREFIX
-               "UNKNOWN: Request device [%04x:%02x:%02x.%u] "
+               "UNKNOWN: Request device [%pp] "
                "fault addr %"PRIx64", iommu reg = %p\n",
-               seg, PCI_BUS(source_id), PCI_SLOT(source_id),
-               PCI_FUNC(source_id), addr, iommu->reg);
+               &PCI_SBDF2_T(seg, source_id), addr, iommu->reg);
         kind = "UNKNOWN";
         break;
     }
@@ -1354,10 +1351,8 @@ int domain_context_mapping_one(
         {
             if ( pdev->domain != domain )
             {
-                printk(XENLOG_G_INFO VTDPREFIX
-                       "d%d: %04x:%02x:%02x.%u owned by d%d!",
-                       domain->domain_id,
-                       seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+                printk(XENLOG_G_INFO VTDPREFIX "d%d: %pp owned by d%d!",
+                       domain->domain_id, &PCI_SBDF3_T(seg, bus, devfn),
                        pdev->domain ? pdev->domain->domain_id : -1);
                 res = -EINVAL;
             }
@@ -1370,17 +1365,15 @@ int domain_context_mapping_one(
             if ( cdomain < 0 )
             {
                 printk(XENLOG_G_WARNING VTDPREFIX
-                       "d%d: %04x:%02x:%02x.%u mapped, but can't find owner!\n",
-                       domain->domain_id,
-                       seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+                       "d%d: %pp mapped, but can't find owner!\n",
+                       domain->domain_id, &PCI_SBDF3_T(seg, bus, devfn));
                 res = -EINVAL;
             }
             else if ( cdomain != domain->domain_id )
             {
                 printk(XENLOG_G_INFO VTDPREFIX
-                       "d%d: %04x:%02x:%02x.%u already mapped to d%d!",
-                       domain->domain_id,
-                       seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+                       "d%d: %pp already mapped to d%d!",
+                       domain->domain_id, &PCI_SBDF3_T(seg, bus, devfn),
                        cdomain);
                 res = -EINVAL;
             }
@@ -1496,9 +1489,8 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
     {
     case DEV_TYPE_PCI_HOST_BRIDGE:
         if ( iommu_debug )
-            printk(VTDPREFIX "d%d:Hostbridge: skip %04x:%02x:%02x.%u map\n",
-                   domain->domain_id, seg, bus,
-                   PCI_SLOT(devfn), PCI_FUNC(devfn));
+            printk(VTDPREFIX "d%d:Hostbridge: skip %pp map\n",
+                   domain->domain_id, &pdev->sbdf);
         if ( !is_hardware_domain(domain) )
             return -EPERM;
         break;
@@ -1510,9 +1502,8 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
 
     case DEV_TYPE_PCIe_ENDPOINT:
         if ( iommu_debug )
-            printk(VTDPREFIX "d%d:PCIe: map %04x:%02x:%02x.%u\n",
-                   domain->domain_id, seg, bus,
-                   PCI_SLOT(devfn), PCI_FUNC(devfn));
+            printk(VTDPREFIX "d%d:PCIe: map %pp\n",
+                   domain->domain_id, &PCI_SBDF3_T(seg, bus, devfn));
         ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn,
                                          pdev);
         if ( !ret && devfn == pdev->sbdf.extfunc && ats_device(pdev, drhd) > 0 )
@@ -1522,9 +1513,8 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
 
     case DEV_TYPE_PCI:
         if ( iommu_debug )
-            printk(VTDPREFIX "d%d:PCI: map %04x:%02x:%02x.%u\n",
-                   domain->domain_id, seg, bus,
-                   PCI_SLOT(devfn), PCI_FUNC(devfn));
+            printk(VTDPREFIX "d%d:PCI: map %pp\n",
+                   domain->domain_id, &PCI_SBDF3_T(seg, bus, devfn));
 
         ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn,
                                          pdev);
@@ -1550,9 +1540,8 @@ static int domain_context_mapping(struct domain *domain, u8 devfn,
         break;
 
     default:
-        dprintk(XENLOG_ERR VTDPREFIX, "d%d:unknown(%u): %04x:%02x:%02x.%u\n",
-                domain->domain_id, pdev->type,
-                seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+        dprintk(XENLOG_ERR VTDPREFIX, "d%d:unknown(%u): %pp\n",
+                domain->domain_id, pdev->type, &PCI_SBDF3_T(seg, bus, devfn));
         ret = -EINVAL;
         break;
     }
@@ -1648,9 +1637,8 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
     {
     case DEV_TYPE_PCI_HOST_BRIDGE:
         if ( iommu_debug )
-            printk(VTDPREFIX "d%d:Hostbridge: skip %04x:%02x:%02x.%u unmap\n",
-                   domain->domain_id, seg, bus,
-                   PCI_SLOT(devfn), PCI_FUNC(devfn));
+            printk(VTDPREFIX "d%d:Hostbridge: skip %pp unmap\n",
+                   domain->domain_id, &pdev->sbdf);
         if ( !is_hardware_domain(domain) )
             return -EPERM;
         goto out;
@@ -1662,9 +1650,8 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
 
     case DEV_TYPE_PCIe_ENDPOINT:
         if ( iommu_debug )
-            printk(VTDPREFIX "d%d:PCIe: unmap %04x:%02x:%02x.%u\n",
-                   domain->domain_id, seg, bus,
-                   PCI_SLOT(devfn), PCI_FUNC(devfn));
+            printk(VTDPREFIX "d%d:PCIe: unmap %pp\n",
+                   domain->domain_id, &PCI_SBDF3_T(seg, bus, devfn));
         ret = domain_context_unmap_one(domain, iommu, bus, devfn);
         if ( !ret && devfn == pdev->sbdf.extfunc && ats_device(pdev, drhd) > 0 )
             disable_ats_device(pdev);
@@ -1673,8 +1660,8 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
 
     case DEV_TYPE_PCI:
         if ( iommu_debug )
-            printk(VTDPREFIX "d%d:PCI: unmap %04x:%02x:%02x.%u\n",
-                   domain->domain_id, seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+            printk(VTDPREFIX "d%d:PCI: unmap %pp\n",
+                   domain->domain_id, &PCI_SBDF3_T(seg, bus, devfn));
         ret = domain_context_unmap_one(domain, iommu, bus, devfn);
         if ( ret )
             break;
@@ -1699,9 +1686,8 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
         break;
 
     default:
-        dprintk(XENLOG_ERR VTDPREFIX, "d%d:unknown(%u): %04x:%02x:%02x.%u\n",
-                domain->domain_id, pdev->type,
-                seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+        dprintk(XENLOG_ERR VTDPREFIX, "d%d:unknown(%u): %pp\n",
+                domain->domain_id, pdev->type, &PCI_SBDF3_T(seg, bus, devfn));
         ret = -EINVAL;
         goto out;
     }
@@ -2499,11 +2485,11 @@ static int intel_iommu_assign_device(
             bool_t relaxed = !!(flag & XEN_DOMCTL_DEV_RDM_RELAXED);
 
             printk(XENLOG_GUEST "%s" VTDPREFIX
-                   " It's %s to assign %04x:%02x:%02x.%u"
+                   " It's %s to assign %pp"
                    " with shared RMRR at %"PRIx64" for Dom%d.\n",
                    relaxed ? XENLOG_WARNING : XENLOG_ERR,
                    relaxed ? "risky" : "disallowed",
-                   seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+                   &PCI_SBDF3_T(seg, bus, devfn),
                    rmrr->base_address, d->domain_id);
             if ( !relaxed )
                 return -EPERM;
diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c
index 48c7384b82..0302c503fb 100644
--- a/xen/drivers/passthrough/vtd/quirks.c
+++ b/xen/drivers/passthrough/vtd/quirks.c
@@ -428,8 +428,6 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
 {
     int seg = pdev->sbdf.seg;
     int bus = pdev->sbdf.bus;
-    int dev = pdev->sbdf.dev;
-    int func = pdev->sbdf.func;
     int pos;
     bool_t ff;
     u32 val, val2;
@@ -454,8 +452,7 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
     case 0x3c28: /* Sandybridge */
         val = pci_conf_read32(pdev->sbdf, 0x1AC);
         pci_conf_write32(pdev->sbdf, 0x1AC, val | (1 << 31));
-        printk(XENLOG_INFO "Masked VT-d error signaling on %04x:%02x:%02x.%u\n",
-               seg, bus, dev, func);
+        printk(XENLOG_INFO "Masked VT-d error signaling on %pp\n", &pdev->sbdf);
         break;
 
     /* Tylersburg (EP)/Boxboro (MP) chipsets (NHM-EP/EX, WSM-EP/EX) */
@@ -490,8 +487,7 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
             ff = pcie_aer_get_firmware_first(pdev);
         if ( !pos )
         {
-            printk(XENLOG_WARNING "%04x:%02x:%02x.%u without AER capability?\n",
-                   seg, bus, dev, func);
+            printk(XENLOG_WARNING "%pp without AER capability?\n", &pdev->sbdf);
             break;
         }
 
@@ -514,8 +510,7 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
         val = pci_conf_read32(pdev->sbdf, 0x20c);
         pci_conf_write32(pdev->sbdf, 0x20c, val | (1 << 4));
 
-        printk(XENLOG_INFO "%s UR signaling on %04x:%02x:%02x.%u\n",
-               action, seg, bus, dev, func);
+        printk(XENLOG_INFO "%s UR signaling on %pp\n", action, &pdev->sbdf);
         break;
 
     case 0x0040: case 0x0044: case 0x0048: /* Nehalem/Westmere */
@@ -540,16 +535,16 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
             {
                 __set_bit(0x1c8 * 8 + 20, va);
                 iounmap(va);
-                printk(XENLOG_INFO "Masked UR signaling on %04x:%02x:%02x.%u\n",
-                       seg, bus, dev, func);
+                printk(XENLOG_INFO "Masked UR signaling on %pp\n",
+                       &pdev->sbdf);
             }
             else
-                printk(XENLOG_ERR "Could not map %"PRIpaddr" for %04x:%02x:%02x.%u\n",
-                       pa, seg, bus, dev, func);
+                printk(XENLOG_ERR "Could not map %"PRIpaddr" for %pp\n",
+                       pa, &pdev->sbdf);
         }
         else
-            printk(XENLOG_WARNING "Bogus DMIBAR %#"PRIx64" on %04x:%02x:%02x.%u\n",
-                   bar, seg, bus, dev, func);
+            printk(XENLOG_WARNING "Bogus DMIBAR %#"PRIx64" on %pp\n",
+                   bar, &pdev->sbdf);
         break;
     }
 }
diff --git a/xen/drivers/passthrough/vtd/utils.c b/xen/drivers/passthrough/vtd/utils.c
index 94a6e4eec9..5665bf7697 100644
--- a/xen/drivers/passthrough/vtd/utils.c
+++ b/xen/drivers/passthrough/vtd/utils.c
@@ -95,9 +95,9 @@ void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn)
     u64 *l, val;
     u32 l_index, level;
 
-    printk("print_vtd_entries: iommu #%u dev %04x:%02x:%02x.%u gmfn %"PRI_gfn"\n",
-           iommu->index, iommu->intel->drhd->segment, bus,
-           PCI_SLOT(devfn), PCI_FUNC(devfn), gmfn);
+    printk("print_vtd_entries: iommu #%u dev %pp gmfn %"PRI_gfn"\n",
+           iommu->index, &PCI_SBDF3_T(iommu->intel->drhd->segment, bus, devfn),
+           gmfn);
 
     if ( iommu->root_maddr == 0 )
     {
diff --git a/xen/drivers/passthrough/x86/ats.c b/xen/drivers/passthrough/x86/ats.c
index c3203793a6..cfd610229d 100644
--- a/xen/drivers/passthrough/x86/ats.c
+++ b/xen/drivers/passthrough/x86/ats.c
@@ -31,8 +31,7 @@ int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
     BUG_ON(!pos);
 
     if ( iommu_verbose )
-        dprintk(XENLOG_INFO, "%04x:%02x:%02x.%u: ATS capability found\n",
-                seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+        dprintk(XENLOG_INFO, "%pp: ATS capability found\n", &pdev->sbdf);
 
     value = pci_conf_read16(pdev->sbdf, pos + ATS_REG_CTL);
     if ( value & ATS_ENABLE )
@@ -63,9 +62,8 @@ int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
     }
 
     if ( iommu_verbose )
-        dprintk(XENLOG_INFO, "%04x:%02x:%02x.%u: ATS %s enabled\n",
-                seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                pos ? "is" : "was");
+        dprintk(XENLOG_INFO, "%pp: ATS %s enabled\n",
+                &pdev->sbdf, pos ? "is" : "was");
 
     return pos;
 }
@@ -73,8 +71,6 @@ int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
 void disable_ats_device(struct pci_dev *pdev)
 {
     u32 value;
-    uint16_t seg = pdev->sbdf.seg;
-    uint8_t bus = pdev->sbdf.bus, devfn = pdev->sbdf.extfunc;
 
     BUG_ON(!pdev->ats.cap_pos);
 
@@ -85,6 +81,5 @@ void disable_ats_device(struct pci_dev *pdev)
     list_del(&pdev->ats.list);
 
     if ( iommu_verbose )
-        dprintk(XENLOG_INFO, "%04x:%02x:%02x.%u: ATS is disabled\n",
-                seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+        dprintk(XENLOG_INFO, "%pp: ATS is disabled\n", &pdev->sbdf);
 }
diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
index d693b1376c..ddda881366 100644
--- a/xen/drivers/vpci/header.c
+++ b/xen/drivers/vpci/header.c
@@ -371,9 +371,8 @@ static void bar_write(const struct pci_dev *pdev, unsigned int reg,
         /* If the value written is the current one avoid printing a warning. */
         if ( val != (uint32_t)(bar->addr >> (hi ? 32 : 0)) )
             gprintk(XENLOG_WARNING,
-                    "%04x:%02x:%02x.%u: ignored BAR %lu write with memory decoding enabled\n",
-                    pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                    pdev->sbdf.func, bar - pdev->vpci->header.bars + hi);
+                    "%pp: ignored BAR %lu write with memory decoding enabled\n",
+                    &pdev->sbdf, bar - pdev->vpci->header.bars + hi);
         return;
     }
 
@@ -407,9 +406,8 @@ static void rom_write(const struct pci_dev *pdev, unsigned int reg,
     if ( (cmd & PCI_COMMAND_MEMORY) && header->rom_enabled && new_enabled )
     {
         gprintk(XENLOG_WARNING,
-                "%04x:%02x:%02x.%u: ignored ROM BAR write with memory decoding enabled\n",
-                pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                pdev->sbdf.func);
+                "%pp: ignored ROM BAR write with memory decoding enabled\n",
+                &pdev->sbdf);
         return;
     }
 
diff --git a/xen/drivers/vpci/msi.c b/xen/drivers/vpci/msi.c
index 4f2e55f3fd..2bdae48edf 100644
--- a/xen/drivers/vpci/msi.c
+++ b/xen/drivers/vpci/msi.c
@@ -290,8 +290,7 @@ void vpci_dump_msi(void)
             msi = pdev->vpci->msi;
             if ( msi && msi->enabled )
             {
-                printk("%04x:%02x:%02x.%u MSI\n", pdev->sbdf.seg,
-                       pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func);
+                printk("%pp MSI\n", &pdev->sbdf);
 
                 printk("  enabled: %d 64-bit: %d",
                        msi->enabled, msi->address64);
@@ -308,8 +307,7 @@ void vpci_dump_msi(void)
             {
                 int rc;
 
-                printk("%04x:%02x:%02x.%u MSI-X\n", pdev->sbdf.seg,
-                       pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func);
+                printk("%pp MSI-X\n", &pdev->sbdf);
 
                 printk("  entries: %u maskall: %d enabled: %d\n",
                        msix->max_entries, msix->masked, msix->enabled);
diff --git a/xen/drivers/vpci/msix.c b/xen/drivers/vpci/msix.c
index 47d569121f..1006b01f4b 100644
--- a/xen/drivers/vpci/msix.c
+++ b/xen/drivers/vpci/msix.c
@@ -48,9 +48,8 @@ static int update_entry(struct vpci_msix_entry *entry,
     if ( rc && rc != -ENOENT )
     {
         gprintk(XENLOG_WARNING,
-                "%04x:%02x:%02x.%u: unable to disable entry %u for update: %d\n",
-                pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func,
-                nr, rc);
+                "%pp: unable to disable entry %u for update: %d\n",
+                &pdev->sbdf, nr, rc);
         return rc;
     }
 
@@ -59,10 +58,8 @@ static int update_entry(struct vpci_msix_entry *entry,
                                                       VPCI_MSIX_TABLE));
     if ( rc )
     {
-        gprintk(XENLOG_WARNING,
-                "%04x:%02x:%02x.%u: unable to enable entry %u: %d\n",
-                pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func,
-                nr, rc);
+        gprintk(XENLOG_WARNING, "%pp: unable to enable entry %u: %d\n",
+                &pdev->sbdf, nr, rc);
         /* Entry is likely not properly configured. */
         return rc;
     }
@@ -133,10 +130,8 @@ static void control_write(const struct pci_dev *pdev, unsigned int reg,
                 /* Ignore non-present entry. */
                 break;
             default:
-                gprintk(XENLOG_WARNING,
-                        "%04x:%02x:%02x.%u: unable to disable entry %u: %d\n",
-                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                        pdev->sbdf.func, i, rc);
+                gprintk(XENLOG_WARNING, "%pp: unable to disable entry %u: %d\n",
+                        &pdev->sbdf, i, rc);
                 return;
             }
         }
@@ -181,8 +176,7 @@ static bool access_allowed(const struct pci_dev *pdev, unsigned long addr,
         return true;
 
     gprintk(XENLOG_WARNING,
-            "%04x:%02x:%02x.%u: unaligned or invalid size MSI-X table access\n",
-            pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev, pdev->sbdf.func);
+            "%pp: unaligned or invalid size MSI-X table access\n", &pdev->sbdf);
 
     return false;
 }
@@ -432,10 +426,9 @@ int vpci_make_msix_hole(const struct pci_dev *pdev)
             default:
                 put_gfn(d, start);
                 gprintk(XENLOG_WARNING,
-                        "%04x:%02x:%02x.%u: existing mapping (mfn: %" PRI_mfn
+                        "%pp: existing mapping (mfn: %" PRI_mfn
                         "type: %d) at %#lx clobbers MSIX MMIO area\n",
-                        pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                        pdev->sbdf.func, mfn_x(mfn), t, start);
+                        &pdev->sbdf, mfn_x(mfn), t, start);
                 return -EEXIST;
             }
             put_gfn(d, start);
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 9908d0fe5d..5e345c417f 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -60,6 +60,8 @@ typedef union {
 
 #define PCI_SBDF_T(s, b, d, f) \
     ((pci_sbdf_t) { .seg = (s), .bus = (b), .dev = (d), .func = (f) })
+#define PCI_SBDF2_T(s, b) \
+    ((pci_sbdf_t) { .seg = (s), .bdf = (b) })
 #define PCI_SBDF3_T(s, b, e) \
     ((pci_sbdf_t) { .seg = (s), .bus = (b), .extfunc = (e) })
 
-- 
2.17.2 (Apple Git-113)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 5/5] pci: switch PCI capabilities related functions to use pci_sbdf_t
@ 2019-05-10 16:10   ` Roger Pau Monne
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monne @ 2019-05-10 16:10 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Suravee Suthikulpanit,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper, Ian Jackson,
	Tim Deegan, Julien Grall, Jan Beulich, Brian Woods,
	Roger Pau Monne

Since pci_dev already has a pci_sbdf_t field switch the capability
related functions SBDF parameters to a single pci_sbdf_t parameter.

No functional change expected.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Julien Grall <julien.grall@arm.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Brian Woods <brian.woods@amd.com>
Cc: Kevin Tian <kevin.tian@intel.com>
---
 xen/arch/x86/msi.c                         | 42 ++++++----------------
 xen/drivers/char/ehci-dbgp.c               |  3 +-
 xen/drivers/passthrough/amd/iommu_detect.c |  2 +-
 xen/drivers/passthrough/ats.h              | 12 +++++--
 xen/drivers/passthrough/pci.c              | 22 +++++-------
 xen/drivers/passthrough/vtd/quirks.c       | 12 +++----
 xen/drivers/passthrough/vtd/x86/ats.c      |  3 +-
 xen/drivers/passthrough/x86/ats.c          |  4 +--
 xen/drivers/pci/pci.c                      | 31 +++++-----------
 xen/drivers/vpci/msi.c                     |  4 +--
 xen/drivers/vpci/msix.c                    |  4 +--
 xen/include/xen/pci.h                      |  9 ++---
 12 files changed, 52 insertions(+), 96 deletions(-)

diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index 6832211772..27ea11b769 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -339,7 +339,7 @@ static void msi_set_enable(struct pci_dev *dev, int enable)
     uint8_t slot = dev->sbdf.dev;
     uint8_t func = dev->sbdf.func;
 
-    pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSI);
+    pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSI);
     if ( pos )
         __msi_set_enable(seg, bus, slot, func, pos, enable);
 }
@@ -347,12 +347,9 @@ static void msi_set_enable(struct pci_dev *dev, int enable)
 static void msix_set_enable(struct pci_dev *dev, int enable)
 {
     int pos;
-    uint16_t control, seg = dev->sbdf.seg;
-    uint8_t bus = dev->sbdf.bus;
-    uint8_t slot = dev->sbdf.dev;
-    uint8_t func = dev->sbdf.func;
+    uint16_t control;
 
-    pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSIX);
+    pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSIX);
     if ( pos )
     {
         control = pci_conf_read16(dev->sbdf, msix_control_reg(pos));
@@ -669,13 +666,10 @@ static int msi_capability_init(struct pci_dev *dev,
     struct msi_desc *entry;
     int pos;
     unsigned int i, maxvec, mpos;
-    uint16_t control, seg = dev->sbdf.seg;
-    uint8_t bus = dev->sbdf.bus;
-    uint8_t slot = dev->sbdf.dev;
-    uint8_t func = dev->sbdf.func;
+    uint16_t control;
 
     ASSERT(pcidevs_locked());
-    pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSI);
+    pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSI);
     if ( !pos )
         return -ENODEV;
     control = pci_conf_read16(dev->sbdf, msi_control_reg(pos));
@@ -752,9 +746,7 @@ static u64 read_pci_mem_bar(u16 seg, u8 bus, u8 slot, u8 func, u8 bir, int vf)
     if ( vf >= 0 )
     {
         struct pci_dev *pdev = pci_get_pdev(seg, bus, PCI_DEVFN(slot, func));
-        unsigned int pos = pci_find_ext_capability(seg, bus,
-                                                   PCI_DEVFN(slot, func),
-                                                   PCI_EXT_CAP_ID_SRIOV);
+        unsigned int pos = pci_find_ext_capability(sbdf, PCI_EXT_CAP_ID_SRIOV);
         u16 ctrl = pci_conf_read16(sbdf, pos + PCI_SRIOV_CTRL);
         u16 num_vf = pci_conf_read16(sbdf, pos + PCI_SRIOV_NUM_VF);
         u16 offset = pci_conf_read16(sbdf, pos + PCI_SRIOV_VF_OFFSET);
@@ -1096,13 +1088,12 @@ static int __pci_enable_msix(struct msi_info *msi, struct msi_desc **desc)
     int pos, nr_entries;
     struct pci_dev *pdev;
     u16 control;
-    u8 slot = PCI_SLOT(msi->devfn);
-    u8 func = PCI_FUNC(msi->devfn);
     struct msi_desc *old_desc;
 
     ASSERT(pcidevs_locked());
     pdev = pci_get_pdev(msi->seg, msi->bus, msi->devfn);
-    pos = pci_find_cap_offset(msi->seg, msi->bus, slot, func, PCI_CAP_ID_MSIX);
+    pos = pci_find_cap_offset(PCI_SBDF3_T(msi->seg, msi->bus, msi->devfn),
+                              PCI_CAP_ID_MSIX);
     if ( !pdev || !pos )
         return -ENODEV;
 
@@ -1145,12 +1136,7 @@ static void _pci_cleanup_msix(struct arch_msix *msix)
 static void __pci_disable_msix(struct msi_desc *entry)
 {
     struct pci_dev *dev = entry->dev;
-    uint16_t seg = dev->sbdf.seg;
-    uint8_t bus = dev->sbdf.bus;
-    uint8_t slot = dev->sbdf.dev;
-    uint8_t func = dev->sbdf.func;
-    unsigned int pos = pci_find_cap_offset(seg, bus, slot, func,
-                                           PCI_CAP_ID_MSIX);
+    unsigned int pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSIX);
     uint16_t control = pci_conf_read16(dev->sbdf,
                                        msix_control_reg(entry->msi_attrib.pos));
     bool maskall = dev->msix->host_maskall;
@@ -1186,8 +1172,7 @@ int pci_prepare_msix(u16 seg, u8 bus, u8 devfn, bool off)
 {
     int rc;
     struct pci_dev *pdev;
-    u8 slot = PCI_SLOT(devfn), func = PCI_FUNC(devfn);
-    unsigned int pos = pci_find_cap_offset(seg, bus, slot, func,
+    unsigned int pos = pci_find_cap_offset(PCI_SBDF3_T(seg, bus, devfn),
                                            PCI_CAP_ID_MSIX);
 
     if ( !use_msi )
@@ -1267,10 +1252,6 @@ void pci_cleanup_msi(struct pci_dev *pdev)
 int pci_msi_conf_write_intercept(struct pci_dev *pdev, unsigned int reg,
                                  unsigned int size, uint32_t *data)
 {
-    uint16_t seg = pdev->sbdf.seg;
-    uint8_t bus = pdev->sbdf.bus;
-    uint8_t slot = pdev->sbdf.dev;
-    uint8_t func = pdev->sbdf.func;
     struct msi_desc *entry;
     unsigned int pos;
 
@@ -1278,8 +1259,7 @@ int pci_msi_conf_write_intercept(struct pci_dev *pdev, unsigned int reg,
     {
         entry = find_msi_entry(pdev, -1, PCI_CAP_ID_MSIX);
         pos = entry ? entry->msi_attrib.pos
-                    : pci_find_cap_offset(seg, bus, slot, func,
-                                          PCI_CAP_ID_MSIX);
+                    : pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_MSIX);
         ASSERT(pos);
 
         if ( reg >= pos && reg < msix_pba_offset_reg(pos) + 4 )
diff --git a/xen/drivers/char/ehci-dbgp.c b/xen/drivers/char/ehci-dbgp.c
index 4cd4157353..27bd4b935d 100644
--- a/xen/drivers/char/ehci-dbgp.c
+++ b/xen/drivers/char/ehci-dbgp.c
@@ -688,7 +688,8 @@ static unsigned int __init __find_dbgp(u8 bus, u8 slot, u8 func)
     if ( (class >> 8) != PCI_CLASS_SERIAL_USB_EHCI )
         return 0;
 
-    return pci_find_cap_offset(0, bus, slot, func, PCI_CAP_ID_EHCI_DEBUG);
+    return pci_find_cap_offset(PCI_SBDF_T(0, bus, slot, func),
+                               PCI_CAP_ID_EHCI_DEBUG);
 }
 
 static unsigned int __init find_dbgp(struct ehci_dbgp *dbgp,
diff --git a/xen/drivers/passthrough/amd/iommu_detect.c b/xen/drivers/passthrough/amd/iommu_detect.c
index 91f5ea6bff..3b36827c14 100644
--- a/xen/drivers/passthrough/amd/iommu_detect.c
+++ b/xen/drivers/passthrough/amd/iommu_detect.c
@@ -30,7 +30,7 @@ static int __init get_iommu_msi_capabilities(
 {
     int pos;
 
-    pos = pci_find_cap_offset(seg, bus, dev, func, PCI_CAP_ID_MSI);
+    pos = pci_find_cap_offset(PCI_SBDF_T(seg, bus, dev, func), PCI_CAP_ID_MSI);
 
     if ( !pos )
         return -ENODEV;
diff --git a/xen/drivers/passthrough/ats.h b/xen/drivers/passthrough/ats.h
index e83a45d16e..3b996c748a 100644
--- a/xen/drivers/passthrough/ats.h
+++ b/xen/drivers/passthrough/ats.h
@@ -31,11 +31,16 @@ static inline int pci_ats_enabled(int seg, int bus, int devfn)
 {
     u32 value;
     int pos;
+    const pci_sbdf_t sbdf = {
+        .seg = seg,
+        .bus = bus,
+        .extfunc = devfn,
+    };
 
-    pos = pci_find_ext_capability(seg, bus, devfn, PCI_EXT_CAP_ID_ATS);
+    pos = pci_find_ext_capability(sbdf, PCI_EXT_CAP_ID_ATS);
     BUG_ON(!pos);
 
-    value = pci_conf_read16(PCI_SBDF3_T(seg, bus, devfn), pos + ATS_REG_CTL);
+    value = pci_conf_read16(sbdf, pos + ATS_REG_CTL);
 
     return value & ATS_ENABLE;
 }
@@ -45,7 +50,8 @@ static inline int pci_ats_device(int seg, int bus, int devfn)
     if ( !ats_enabled )
         return 0;
 
-    return pci_find_ext_capability(seg, bus, devfn, PCI_EXT_CAP_ID_ATS);
+    return pci_find_ext_capability(PCI_SBDF3_T(seg, bus, devfn),
+                                   PCI_EXT_CAP_ID_ATS);
 }
 
 #endif /* _ATS_H_ */
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index a9667ca21c..cfe2dda733 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -332,8 +332,7 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
     pdev->domain = NULL;
     INIT_LIST_HEAD(&pdev->msi_list);
 
-    if ( pci_find_cap_offset(pseg->nr, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                             PCI_CAP_ID_MSIX) )
+    if ( pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_MSIX) )
     {
         struct arch_msix *msix = xzalloc(struct arch_msix);
 
@@ -371,8 +370,7 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
             break;
 
         case DEV_TYPE_PCIe_ENDPOINT:
-            pos = pci_find_cap_offset(pseg->nr, bus, PCI_SLOT(devfn),
-                                      PCI_FUNC(devfn), PCI_CAP_ID_EXP);
+            pos = pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_EXP);
             BUG_ON(!pos);
             cap = pci_conf_read16(pdev->sbdf, pos + PCI_EXP_DEVCAP);
             if ( cap & PCI_EXP_DEVCAP_PHANTOM )
@@ -585,13 +583,12 @@ struct pci_dev *pci_get_pdev_by_domain(const struct domain *d, int seg,
 static void pci_enable_acs(struct pci_dev *pdev)
 {
     int pos;
-    uint16_t cap, ctrl, seg = pdev->sbdf.seg;
-    uint8_t bus = pdev->sbdf.bus;
+    uint16_t cap, ctrl;
 
     if ( !iommu_enabled )
         return;
 
-    pos = pci_find_ext_capability(seg, bus, pdev->sbdf.extfunc, PCI_EXT_CAP_ID_ACS);
+    pos = pci_find_ext_capability(pdev->sbdf, PCI_EXT_CAP_ID_ACS);
     if (!pos)
         return;
 
@@ -722,7 +719,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
 
     if ( !pdev->info.is_virtfn && !pdev->vf_rlen[0] )
     {
-        unsigned int pos = pci_find_ext_capability(seg, bus, devfn,
+        unsigned int pos = pci_find_ext_capability(pdev->sbdf,
                                                    PCI_EXT_CAP_ID_SRIOV);
         u16 ctrl = pci_conf_read16(pdev->sbdf, pos + PCI_SRIOV_CTRL);
 
@@ -907,13 +904,13 @@ enum pdev_type pdev_type(u16 seg, u8 bus, u8 devfn)
 {
     u16 class_device, creg;
     u8 d = PCI_SLOT(devfn), f = PCI_FUNC(devfn);
-    int pos = pci_find_cap_offset(seg, bus, d, f, PCI_CAP_ID_EXP);
     const pci_sbdf_t sbdf = {
         .seg = seg,
         .bus = bus,
         .dev = d,
         .func = f,
     };
+    int pos = pci_find_cap_offset(sbdf, PCI_CAP_ID_EXP);
 
     class_device = pci_conf_read16(sbdf, PCI_CLASS_DEVICE);
     switch ( class_device )
@@ -1177,9 +1174,7 @@ static int hest_match_pci(const struct acpi_hest_aer_common *p,
 static bool_t hest_match_type(const struct acpi_hest_header *hest_hdr,
                               const struct pci_dev *pdev)
 {
-    unsigned int pos = pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus,
-                                           pdev->sbdf.dev, pdev->sbdf.func,
-                                           PCI_CAP_ID_EXP);
+    unsigned int pos = pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_EXP);
     uint8_t pcie = MASK_EXTR(pci_conf_read16(pdev->sbdf, pos + PCI_EXP_FLAGS),
                              PCI_EXP_FLAGS_TYPE);
 
@@ -1249,8 +1244,7 @@ bool_t pcie_aer_get_firmware_first(const struct pci_dev *pdev)
 {
     struct aer_hest_parse_info info = { .pdev = pdev };
 
-    return pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                               pdev->sbdf.func, PCI_CAP_ID_EXP) &&
+    return pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_EXP) &&
            apei_hest_parse(aer_hest_parse, &info) >= 0 &&
            info.firmware_first;
 }
diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c
index 0302c503fb..289d43f0fe 100644
--- a/xen/drivers/passthrough/vtd/quirks.c
+++ b/xen/drivers/passthrough/vtd/quirks.c
@@ -426,8 +426,6 @@ int me_wifi_quirk(struct domain *domain, u8 bus, u8 devfn, int map)
 
 void pci_vtd_quirk(const struct pci_dev *pdev)
 {
-    int seg = pdev->sbdf.seg;
-    int bus = pdev->sbdf.bus;
     int pos;
     bool_t ff;
     u32 val, val2;
@@ -464,12 +462,10 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
     /* Sandybridge-EP (Romley) */
     case 0x3c00: /* host bridge */
     case 0x3c01 ... 0x3c0b: /* root ports */
-        pos = pci_find_ext_capability(seg, bus, pdev->sbdf.extfunc,
-                                      PCI_EXT_CAP_ID_ERR);
+        pos = pci_find_ext_capability(pdev->sbdf, PCI_EXT_CAP_ID_ERR);
         if ( !pos )
         {
-            pos = pci_find_ext_capability(seg, bus, pdev->sbdf.extfunc,
-                                          PCI_EXT_CAP_ID_VNDR);
+            pos = pci_find_ext_capability(pdev->sbdf, PCI_EXT_CAP_ID_VNDR);
             while ( pos )
             {
                 val = pci_conf_read32(pdev->sbdf, pos + PCI_VNDR_HEADER);
@@ -478,8 +474,8 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
                     pos += PCI_VNDR_HEADER;
                     break;
                 }
-                pos = pci_find_next_ext_capability(seg, bus, pdev->sbdf.extfunc,
-                                                   pos, PCI_EXT_CAP_ID_VNDR);
+                pos = pci_find_next_ext_capability(pdev->sbdf, pos,
+                                                   PCI_EXT_CAP_ID_VNDR);
             }
             ff = 0;
         }
diff --git a/xen/drivers/passthrough/vtd/x86/ats.c b/xen/drivers/passthrough/vtd/x86/ats.c
index e0904df5b6..260b06a856 100644
--- a/xen/drivers/passthrough/vtd/x86/ats.c
+++ b/xen/drivers/passthrough/vtd/x86/ats.c
@@ -57,8 +57,7 @@ int ats_device(const struct pci_dev *pdev, const struct acpi_drhd_unit *drhd)
         return 0;
 
     ats_drhd = find_ats_dev_drhd(drhd->iommu);
-    pos = pci_find_ext_capability(pdev->sbdf.seg, pdev->sbdf.bus,
-                                  pdev->sbdf.extfunc, PCI_EXT_CAP_ID_ATS);
+    pos = pci_find_ext_capability(pdev->sbdf, PCI_EXT_CAP_ID_ATS);
 
     if ( pos && (ats_drhd == NULL) )
     {
diff --git a/xen/drivers/passthrough/x86/ats.c b/xen/drivers/passthrough/x86/ats.c
index cfd610229d..bfbd50100a 100644
--- a/xen/drivers/passthrough/x86/ats.c
+++ b/xen/drivers/passthrough/x86/ats.c
@@ -23,11 +23,9 @@ boolean_param("ats", ats_enabled);
 int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
 {
     u32 value;
-    uint16_t seg = pdev->sbdf.seg;
-    uint16_t bus = pdev->sbdf.bus, devfn = pdev->sbdf.extfunc;
     int pos;
 
-    pos = pci_find_ext_capability(seg, bus, devfn, PCI_EXT_CAP_ID_ATS);
+    pos = pci_find_ext_capability(pdev->sbdf, PCI_EXT_CAP_ID_ATS);
     BUG_ON(!pos);
 
     if ( iommu_verbose )
diff --git a/xen/drivers/pci/pci.c b/xen/drivers/pci/pci.c
index 3d2acf6f77..e902a0aace 100644
--- a/xen/drivers/pci/pci.c
+++ b/xen/drivers/pci/pci.c
@@ -8,18 +8,12 @@
 #include <xen/pci.h>
 #include <xen/pci_regs.h>
 
-int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 cap)
+int pci_find_cap_offset(pci_sbdf_t sbdf, unsigned int cap)
 {
     u8 id;
     int max_cap = 48;
     u8 pos = PCI_CAPABILITY_LIST;
     u16 status;
-    const pci_sbdf_t sbdf = {
-        .seg = seg,
-        .bus = bus,
-        .dev = dev,
-        .func = func,
-    };
 
     status = pci_conf_read16(sbdf, PCI_STATUS);
     if ( (status & PCI_STATUS_CAP_LIST) == 0 )
@@ -45,15 +39,10 @@ int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 cap)
     return 0;
 }
 
-int pci_find_next_cap(u16 seg, u8 bus, unsigned int devfn, u8 pos, int cap)
+int pci_find_next_cap(pci_sbdf_t sbdf, unsigned int pos, unsigned int cap)
 {
     u8 id;
     int ttl = 48;
-    const pci_sbdf_t sbdf = {
-        .seg = seg,
-        .bus = bus,
-        .extfunc = devfn,
-    };
 
     while ( ttl-- )
     {
@@ -83,9 +72,9 @@ int pci_find_next_cap(u16 seg, u8 bus, unsigned int devfn, u8 pos, int cap)
  * within the device's PCI configuration space or 0 if the device does
  * not support it.
  */
-int pci_find_ext_capability(int seg, int bus, int devfn, int cap)
+int pci_find_ext_capability(pci_sbdf_t sbdf, unsigned int cap)
 {
-    return pci_find_next_ext_capability(seg, bus, devfn, 0, cap);
+    return pci_find_next_ext_capability(sbdf, 0, cap);
 }
 
 /**
@@ -98,15 +87,11 @@ int pci_find_ext_capability(int seg, int bus, int devfn, int cap)
  * within the device's PCI configuration space or 0 if the device does
  * not support it.
  */
-int pci_find_next_ext_capability(int seg, int bus, int devfn, int start, int cap)
+int pci_find_next_ext_capability(pci_sbdf_t sbdf, unsigned int start,
+                                 unsigned int cap)
 {
-    int ttl = 480; /* 3840 bytes, minimum 8 bytes per capability */
-    int pos = max(start, 0x100);
-    const pci_sbdf_t sbdf = {
-        .seg = seg,
-        .bus = bus,
-        .extfunc = devfn,
-    };
+    unsigned int ttl = 480; /* 3840 bytes, minimum 8 bytes per capability */
+    unsigned int pos = max(start, 0x100u);
     uint32_t header = pci_conf_read32(sbdf, pos);
 
     /*
diff --git a/xen/drivers/vpci/msi.c b/xen/drivers/vpci/msi.c
index 2bdae48edf..2a366828a1 100644
--- a/xen/drivers/vpci/msi.c
+++ b/xen/drivers/vpci/msi.c
@@ -185,9 +185,7 @@ static void mask_write(const struct pci_dev *pdev, unsigned int reg,
 
 static int init_msi(struct pci_dev *pdev)
 {
-    unsigned int pos = pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus,
-                                           pdev->sbdf.dev, pdev->sbdf.func,
-                                           PCI_CAP_ID_MSI);
+    unsigned int pos = pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_MSI);
     uint16_t control;
     int ret;
 
diff --git a/xen/drivers/vpci/msix.c b/xen/drivers/vpci/msix.c
index 1006b01f4b..44dbb086fd 100644
--- a/xen/drivers/vpci/msix.c
+++ b/xen/drivers/vpci/msix.c
@@ -445,9 +445,7 @@ static int init_msix(struct pci_dev *pdev)
     uint16_t control;
     int rc;
 
-    msix_offset = pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus,
-                                      pdev->sbdf.dev, pdev->sbdf.func,
-                                      PCI_CAP_ID_MSIX);
+    msix_offset = pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_MSIX);
     if ( !msix_offset )
         return 0;
 
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 5e345c417f..937465f5b5 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -178,10 +178,11 @@ int pci_mmcfg_read(unsigned int seg, unsigned int bus,
                    unsigned int devfn, int reg, int len, u32 *value);
 int pci_mmcfg_write(unsigned int seg, unsigned int bus,
                     unsigned int devfn, int reg, int len, u32 value);
-int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 cap);
-int pci_find_next_cap(u16 seg, u8 bus, unsigned int devfn, u8 pos, int cap);
-int pci_find_ext_capability(int seg, int bus, int devfn, int cap);
-int pci_find_next_ext_capability(int seg, int bus, int devfn, int pos, int cap);
+int pci_find_cap_offset(pci_sbdf_t sbdf, unsigned int cap);
+int pci_find_next_cap(pci_sbdf_t sbdf, unsigned int pos, unsigned int cap);
+int pci_find_ext_capability(pci_sbdf_t sbdf, unsigned int cap);
+int pci_find_next_ext_capability(pci_sbdf_t sbdf, unsigned int pos,
+                                 unsigned int cap);
 const char *parse_pci(const char *, unsigned int *seg, unsigned int *bus,
                       unsigned int *dev, unsigned int *func);
 const char *parse_pci_seg(const char *, unsigned int *seg, unsigned int *bus,
-- 
2.17.2 (Apple Git-113)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Xen-devel] [PATCH 5/5] pci: switch PCI capabilities related functions to use pci_sbdf_t
@ 2019-05-10 16:10   ` Roger Pau Monne
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monne @ 2019-05-10 16:10 UTC (permalink / raw)
  To: xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Suravee Suthikulpanit,
	Konrad Rzeszutek Wilk, George Dunlap, Andrew Cooper, Ian Jackson,
	Tim Deegan, Julien Grall, Jan Beulich, Brian Woods,
	Roger Pau Monne

Since pci_dev already has a pci_sbdf_t field switch the capability
related functions SBDF parameters to a single pci_sbdf_t parameter.

No functional change expected.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Julien Grall <julien.grall@arm.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Brian Woods <brian.woods@amd.com>
Cc: Kevin Tian <kevin.tian@intel.com>
---
 xen/arch/x86/msi.c                         | 42 ++++++----------------
 xen/drivers/char/ehci-dbgp.c               |  3 +-
 xen/drivers/passthrough/amd/iommu_detect.c |  2 +-
 xen/drivers/passthrough/ats.h              | 12 +++++--
 xen/drivers/passthrough/pci.c              | 22 +++++-------
 xen/drivers/passthrough/vtd/quirks.c       | 12 +++----
 xen/drivers/passthrough/vtd/x86/ats.c      |  3 +-
 xen/drivers/passthrough/x86/ats.c          |  4 +--
 xen/drivers/pci/pci.c                      | 31 +++++-----------
 xen/drivers/vpci/msi.c                     |  4 +--
 xen/drivers/vpci/msix.c                    |  4 +--
 xen/include/xen/pci.h                      |  9 ++---
 12 files changed, 52 insertions(+), 96 deletions(-)

diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index 6832211772..27ea11b769 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -339,7 +339,7 @@ static void msi_set_enable(struct pci_dev *dev, int enable)
     uint8_t slot = dev->sbdf.dev;
     uint8_t func = dev->sbdf.func;
 
-    pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSI);
+    pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSI);
     if ( pos )
         __msi_set_enable(seg, bus, slot, func, pos, enable);
 }
@@ -347,12 +347,9 @@ static void msi_set_enable(struct pci_dev *dev, int enable)
 static void msix_set_enable(struct pci_dev *dev, int enable)
 {
     int pos;
-    uint16_t control, seg = dev->sbdf.seg;
-    uint8_t bus = dev->sbdf.bus;
-    uint8_t slot = dev->sbdf.dev;
-    uint8_t func = dev->sbdf.func;
+    uint16_t control;
 
-    pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSIX);
+    pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSIX);
     if ( pos )
     {
         control = pci_conf_read16(dev->sbdf, msix_control_reg(pos));
@@ -669,13 +666,10 @@ static int msi_capability_init(struct pci_dev *dev,
     struct msi_desc *entry;
     int pos;
     unsigned int i, maxvec, mpos;
-    uint16_t control, seg = dev->sbdf.seg;
-    uint8_t bus = dev->sbdf.bus;
-    uint8_t slot = dev->sbdf.dev;
-    uint8_t func = dev->sbdf.func;
+    uint16_t control;
 
     ASSERT(pcidevs_locked());
-    pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSI);
+    pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSI);
     if ( !pos )
         return -ENODEV;
     control = pci_conf_read16(dev->sbdf, msi_control_reg(pos));
@@ -752,9 +746,7 @@ static u64 read_pci_mem_bar(u16 seg, u8 bus, u8 slot, u8 func, u8 bir, int vf)
     if ( vf >= 0 )
     {
         struct pci_dev *pdev = pci_get_pdev(seg, bus, PCI_DEVFN(slot, func));
-        unsigned int pos = pci_find_ext_capability(seg, bus,
-                                                   PCI_DEVFN(slot, func),
-                                                   PCI_EXT_CAP_ID_SRIOV);
+        unsigned int pos = pci_find_ext_capability(sbdf, PCI_EXT_CAP_ID_SRIOV);
         u16 ctrl = pci_conf_read16(sbdf, pos + PCI_SRIOV_CTRL);
         u16 num_vf = pci_conf_read16(sbdf, pos + PCI_SRIOV_NUM_VF);
         u16 offset = pci_conf_read16(sbdf, pos + PCI_SRIOV_VF_OFFSET);
@@ -1096,13 +1088,12 @@ static int __pci_enable_msix(struct msi_info *msi, struct msi_desc **desc)
     int pos, nr_entries;
     struct pci_dev *pdev;
     u16 control;
-    u8 slot = PCI_SLOT(msi->devfn);
-    u8 func = PCI_FUNC(msi->devfn);
     struct msi_desc *old_desc;
 
     ASSERT(pcidevs_locked());
     pdev = pci_get_pdev(msi->seg, msi->bus, msi->devfn);
-    pos = pci_find_cap_offset(msi->seg, msi->bus, slot, func, PCI_CAP_ID_MSIX);
+    pos = pci_find_cap_offset(PCI_SBDF3_T(msi->seg, msi->bus, msi->devfn),
+                              PCI_CAP_ID_MSIX);
     if ( !pdev || !pos )
         return -ENODEV;
 
@@ -1145,12 +1136,7 @@ static void _pci_cleanup_msix(struct arch_msix *msix)
 static void __pci_disable_msix(struct msi_desc *entry)
 {
     struct pci_dev *dev = entry->dev;
-    uint16_t seg = dev->sbdf.seg;
-    uint8_t bus = dev->sbdf.bus;
-    uint8_t slot = dev->sbdf.dev;
-    uint8_t func = dev->sbdf.func;
-    unsigned int pos = pci_find_cap_offset(seg, bus, slot, func,
-                                           PCI_CAP_ID_MSIX);
+    unsigned int pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSIX);
     uint16_t control = pci_conf_read16(dev->sbdf,
                                        msix_control_reg(entry->msi_attrib.pos));
     bool maskall = dev->msix->host_maskall;
@@ -1186,8 +1172,7 @@ int pci_prepare_msix(u16 seg, u8 bus, u8 devfn, bool off)
 {
     int rc;
     struct pci_dev *pdev;
-    u8 slot = PCI_SLOT(devfn), func = PCI_FUNC(devfn);
-    unsigned int pos = pci_find_cap_offset(seg, bus, slot, func,
+    unsigned int pos = pci_find_cap_offset(PCI_SBDF3_T(seg, bus, devfn),
                                            PCI_CAP_ID_MSIX);
 
     if ( !use_msi )
@@ -1267,10 +1252,6 @@ void pci_cleanup_msi(struct pci_dev *pdev)
 int pci_msi_conf_write_intercept(struct pci_dev *pdev, unsigned int reg,
                                  unsigned int size, uint32_t *data)
 {
-    uint16_t seg = pdev->sbdf.seg;
-    uint8_t bus = pdev->sbdf.bus;
-    uint8_t slot = pdev->sbdf.dev;
-    uint8_t func = pdev->sbdf.func;
     struct msi_desc *entry;
     unsigned int pos;
 
@@ -1278,8 +1259,7 @@ int pci_msi_conf_write_intercept(struct pci_dev *pdev, unsigned int reg,
     {
         entry = find_msi_entry(pdev, -1, PCI_CAP_ID_MSIX);
         pos = entry ? entry->msi_attrib.pos
-                    : pci_find_cap_offset(seg, bus, slot, func,
-                                          PCI_CAP_ID_MSIX);
+                    : pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_MSIX);
         ASSERT(pos);
 
         if ( reg >= pos && reg < msix_pba_offset_reg(pos) + 4 )
diff --git a/xen/drivers/char/ehci-dbgp.c b/xen/drivers/char/ehci-dbgp.c
index 4cd4157353..27bd4b935d 100644
--- a/xen/drivers/char/ehci-dbgp.c
+++ b/xen/drivers/char/ehci-dbgp.c
@@ -688,7 +688,8 @@ static unsigned int __init __find_dbgp(u8 bus, u8 slot, u8 func)
     if ( (class >> 8) != PCI_CLASS_SERIAL_USB_EHCI )
         return 0;
 
-    return pci_find_cap_offset(0, bus, slot, func, PCI_CAP_ID_EHCI_DEBUG);
+    return pci_find_cap_offset(PCI_SBDF_T(0, bus, slot, func),
+                               PCI_CAP_ID_EHCI_DEBUG);
 }
 
 static unsigned int __init find_dbgp(struct ehci_dbgp *dbgp,
diff --git a/xen/drivers/passthrough/amd/iommu_detect.c b/xen/drivers/passthrough/amd/iommu_detect.c
index 91f5ea6bff..3b36827c14 100644
--- a/xen/drivers/passthrough/amd/iommu_detect.c
+++ b/xen/drivers/passthrough/amd/iommu_detect.c
@@ -30,7 +30,7 @@ static int __init get_iommu_msi_capabilities(
 {
     int pos;
 
-    pos = pci_find_cap_offset(seg, bus, dev, func, PCI_CAP_ID_MSI);
+    pos = pci_find_cap_offset(PCI_SBDF_T(seg, bus, dev, func), PCI_CAP_ID_MSI);
 
     if ( !pos )
         return -ENODEV;
diff --git a/xen/drivers/passthrough/ats.h b/xen/drivers/passthrough/ats.h
index e83a45d16e..3b996c748a 100644
--- a/xen/drivers/passthrough/ats.h
+++ b/xen/drivers/passthrough/ats.h
@@ -31,11 +31,16 @@ static inline int pci_ats_enabled(int seg, int bus, int devfn)
 {
     u32 value;
     int pos;
+    const pci_sbdf_t sbdf = {
+        .seg = seg,
+        .bus = bus,
+        .extfunc = devfn,
+    };
 
-    pos = pci_find_ext_capability(seg, bus, devfn, PCI_EXT_CAP_ID_ATS);
+    pos = pci_find_ext_capability(sbdf, PCI_EXT_CAP_ID_ATS);
     BUG_ON(!pos);
 
-    value = pci_conf_read16(PCI_SBDF3_T(seg, bus, devfn), pos + ATS_REG_CTL);
+    value = pci_conf_read16(sbdf, pos + ATS_REG_CTL);
 
     return value & ATS_ENABLE;
 }
@@ -45,7 +50,8 @@ static inline int pci_ats_device(int seg, int bus, int devfn)
     if ( !ats_enabled )
         return 0;
 
-    return pci_find_ext_capability(seg, bus, devfn, PCI_EXT_CAP_ID_ATS);
+    return pci_find_ext_capability(PCI_SBDF3_T(seg, bus, devfn),
+                                   PCI_EXT_CAP_ID_ATS);
 }
 
 #endif /* _ATS_H_ */
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index a9667ca21c..cfe2dda733 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -332,8 +332,7 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
     pdev->domain = NULL;
     INIT_LIST_HEAD(&pdev->msi_list);
 
-    if ( pci_find_cap_offset(pseg->nr, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
-                             PCI_CAP_ID_MSIX) )
+    if ( pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_MSIX) )
     {
         struct arch_msix *msix = xzalloc(struct arch_msix);
 
@@ -371,8 +370,7 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
             break;
 
         case DEV_TYPE_PCIe_ENDPOINT:
-            pos = pci_find_cap_offset(pseg->nr, bus, PCI_SLOT(devfn),
-                                      PCI_FUNC(devfn), PCI_CAP_ID_EXP);
+            pos = pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_EXP);
             BUG_ON(!pos);
             cap = pci_conf_read16(pdev->sbdf, pos + PCI_EXP_DEVCAP);
             if ( cap & PCI_EXP_DEVCAP_PHANTOM )
@@ -585,13 +583,12 @@ struct pci_dev *pci_get_pdev_by_domain(const struct domain *d, int seg,
 static void pci_enable_acs(struct pci_dev *pdev)
 {
     int pos;
-    uint16_t cap, ctrl, seg = pdev->sbdf.seg;
-    uint8_t bus = pdev->sbdf.bus;
+    uint16_t cap, ctrl;
 
     if ( !iommu_enabled )
         return;
 
-    pos = pci_find_ext_capability(seg, bus, pdev->sbdf.extfunc, PCI_EXT_CAP_ID_ACS);
+    pos = pci_find_ext_capability(pdev->sbdf, PCI_EXT_CAP_ID_ACS);
     if (!pos)
         return;
 
@@ -722,7 +719,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn,
 
     if ( !pdev->info.is_virtfn && !pdev->vf_rlen[0] )
     {
-        unsigned int pos = pci_find_ext_capability(seg, bus, devfn,
+        unsigned int pos = pci_find_ext_capability(pdev->sbdf,
                                                    PCI_EXT_CAP_ID_SRIOV);
         u16 ctrl = pci_conf_read16(pdev->sbdf, pos + PCI_SRIOV_CTRL);
 
@@ -907,13 +904,13 @@ enum pdev_type pdev_type(u16 seg, u8 bus, u8 devfn)
 {
     u16 class_device, creg;
     u8 d = PCI_SLOT(devfn), f = PCI_FUNC(devfn);
-    int pos = pci_find_cap_offset(seg, bus, d, f, PCI_CAP_ID_EXP);
     const pci_sbdf_t sbdf = {
         .seg = seg,
         .bus = bus,
         .dev = d,
         .func = f,
     };
+    int pos = pci_find_cap_offset(sbdf, PCI_CAP_ID_EXP);
 
     class_device = pci_conf_read16(sbdf, PCI_CLASS_DEVICE);
     switch ( class_device )
@@ -1177,9 +1174,7 @@ static int hest_match_pci(const struct acpi_hest_aer_common *p,
 static bool_t hest_match_type(const struct acpi_hest_header *hest_hdr,
                               const struct pci_dev *pdev)
 {
-    unsigned int pos = pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus,
-                                           pdev->sbdf.dev, pdev->sbdf.func,
-                                           PCI_CAP_ID_EXP);
+    unsigned int pos = pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_EXP);
     uint8_t pcie = MASK_EXTR(pci_conf_read16(pdev->sbdf, pos + PCI_EXP_FLAGS),
                              PCI_EXP_FLAGS_TYPE);
 
@@ -1249,8 +1244,7 @@ bool_t pcie_aer_get_firmware_first(const struct pci_dev *pdev)
 {
     struct aer_hest_parse_info info = { .pdev = pdev };
 
-    return pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
-                               pdev->sbdf.func, PCI_CAP_ID_EXP) &&
+    return pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_EXP) &&
            apei_hest_parse(aer_hest_parse, &info) >= 0 &&
            info.firmware_first;
 }
diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c
index 0302c503fb..289d43f0fe 100644
--- a/xen/drivers/passthrough/vtd/quirks.c
+++ b/xen/drivers/passthrough/vtd/quirks.c
@@ -426,8 +426,6 @@ int me_wifi_quirk(struct domain *domain, u8 bus, u8 devfn, int map)
 
 void pci_vtd_quirk(const struct pci_dev *pdev)
 {
-    int seg = pdev->sbdf.seg;
-    int bus = pdev->sbdf.bus;
     int pos;
     bool_t ff;
     u32 val, val2;
@@ -464,12 +462,10 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
     /* Sandybridge-EP (Romley) */
     case 0x3c00: /* host bridge */
     case 0x3c01 ... 0x3c0b: /* root ports */
-        pos = pci_find_ext_capability(seg, bus, pdev->sbdf.extfunc,
-                                      PCI_EXT_CAP_ID_ERR);
+        pos = pci_find_ext_capability(pdev->sbdf, PCI_EXT_CAP_ID_ERR);
         if ( !pos )
         {
-            pos = pci_find_ext_capability(seg, bus, pdev->sbdf.extfunc,
-                                          PCI_EXT_CAP_ID_VNDR);
+            pos = pci_find_ext_capability(pdev->sbdf, PCI_EXT_CAP_ID_VNDR);
             while ( pos )
             {
                 val = pci_conf_read32(pdev->sbdf, pos + PCI_VNDR_HEADER);
@@ -478,8 +474,8 @@ void pci_vtd_quirk(const struct pci_dev *pdev)
                     pos += PCI_VNDR_HEADER;
                     break;
                 }
-                pos = pci_find_next_ext_capability(seg, bus, pdev->sbdf.extfunc,
-                                                   pos, PCI_EXT_CAP_ID_VNDR);
+                pos = pci_find_next_ext_capability(pdev->sbdf, pos,
+                                                   PCI_EXT_CAP_ID_VNDR);
             }
             ff = 0;
         }
diff --git a/xen/drivers/passthrough/vtd/x86/ats.c b/xen/drivers/passthrough/vtd/x86/ats.c
index e0904df5b6..260b06a856 100644
--- a/xen/drivers/passthrough/vtd/x86/ats.c
+++ b/xen/drivers/passthrough/vtd/x86/ats.c
@@ -57,8 +57,7 @@ int ats_device(const struct pci_dev *pdev, const struct acpi_drhd_unit *drhd)
         return 0;
 
     ats_drhd = find_ats_dev_drhd(drhd->iommu);
-    pos = pci_find_ext_capability(pdev->sbdf.seg, pdev->sbdf.bus,
-                                  pdev->sbdf.extfunc, PCI_EXT_CAP_ID_ATS);
+    pos = pci_find_ext_capability(pdev->sbdf, PCI_EXT_CAP_ID_ATS);
 
     if ( pos && (ats_drhd == NULL) )
     {
diff --git a/xen/drivers/passthrough/x86/ats.c b/xen/drivers/passthrough/x86/ats.c
index cfd610229d..bfbd50100a 100644
--- a/xen/drivers/passthrough/x86/ats.c
+++ b/xen/drivers/passthrough/x86/ats.c
@@ -23,11 +23,9 @@ boolean_param("ats", ats_enabled);
 int enable_ats_device(struct pci_dev *pdev, struct list_head *ats_list)
 {
     u32 value;
-    uint16_t seg = pdev->sbdf.seg;
-    uint16_t bus = pdev->sbdf.bus, devfn = pdev->sbdf.extfunc;
     int pos;
 
-    pos = pci_find_ext_capability(seg, bus, devfn, PCI_EXT_CAP_ID_ATS);
+    pos = pci_find_ext_capability(pdev->sbdf, PCI_EXT_CAP_ID_ATS);
     BUG_ON(!pos);
 
     if ( iommu_verbose )
diff --git a/xen/drivers/pci/pci.c b/xen/drivers/pci/pci.c
index 3d2acf6f77..e902a0aace 100644
--- a/xen/drivers/pci/pci.c
+++ b/xen/drivers/pci/pci.c
@@ -8,18 +8,12 @@
 #include <xen/pci.h>
 #include <xen/pci_regs.h>
 
-int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 cap)
+int pci_find_cap_offset(pci_sbdf_t sbdf, unsigned int cap)
 {
     u8 id;
     int max_cap = 48;
     u8 pos = PCI_CAPABILITY_LIST;
     u16 status;
-    const pci_sbdf_t sbdf = {
-        .seg = seg,
-        .bus = bus,
-        .dev = dev,
-        .func = func,
-    };
 
     status = pci_conf_read16(sbdf, PCI_STATUS);
     if ( (status & PCI_STATUS_CAP_LIST) == 0 )
@@ -45,15 +39,10 @@ int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 cap)
     return 0;
 }
 
-int pci_find_next_cap(u16 seg, u8 bus, unsigned int devfn, u8 pos, int cap)
+int pci_find_next_cap(pci_sbdf_t sbdf, unsigned int pos, unsigned int cap)
 {
     u8 id;
     int ttl = 48;
-    const pci_sbdf_t sbdf = {
-        .seg = seg,
-        .bus = bus,
-        .extfunc = devfn,
-    };
 
     while ( ttl-- )
     {
@@ -83,9 +72,9 @@ int pci_find_next_cap(u16 seg, u8 bus, unsigned int devfn, u8 pos, int cap)
  * within the device's PCI configuration space or 0 if the device does
  * not support it.
  */
-int pci_find_ext_capability(int seg, int bus, int devfn, int cap)
+int pci_find_ext_capability(pci_sbdf_t sbdf, unsigned int cap)
 {
-    return pci_find_next_ext_capability(seg, bus, devfn, 0, cap);
+    return pci_find_next_ext_capability(sbdf, 0, cap);
 }
 
 /**
@@ -98,15 +87,11 @@ int pci_find_ext_capability(int seg, int bus, int devfn, int cap)
  * within the device's PCI configuration space or 0 if the device does
  * not support it.
  */
-int pci_find_next_ext_capability(int seg, int bus, int devfn, int start, int cap)
+int pci_find_next_ext_capability(pci_sbdf_t sbdf, unsigned int start,
+                                 unsigned int cap)
 {
-    int ttl = 480; /* 3840 bytes, minimum 8 bytes per capability */
-    int pos = max(start, 0x100);
-    const pci_sbdf_t sbdf = {
-        .seg = seg,
-        .bus = bus,
-        .extfunc = devfn,
-    };
+    unsigned int ttl = 480; /* 3840 bytes, minimum 8 bytes per capability */
+    unsigned int pos = max(start, 0x100u);
     uint32_t header = pci_conf_read32(sbdf, pos);
 
     /*
diff --git a/xen/drivers/vpci/msi.c b/xen/drivers/vpci/msi.c
index 2bdae48edf..2a366828a1 100644
--- a/xen/drivers/vpci/msi.c
+++ b/xen/drivers/vpci/msi.c
@@ -185,9 +185,7 @@ static void mask_write(const struct pci_dev *pdev, unsigned int reg,
 
 static int init_msi(struct pci_dev *pdev)
 {
-    unsigned int pos = pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus,
-                                           pdev->sbdf.dev, pdev->sbdf.func,
-                                           PCI_CAP_ID_MSI);
+    unsigned int pos = pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_MSI);
     uint16_t control;
     int ret;
 
diff --git a/xen/drivers/vpci/msix.c b/xen/drivers/vpci/msix.c
index 1006b01f4b..44dbb086fd 100644
--- a/xen/drivers/vpci/msix.c
+++ b/xen/drivers/vpci/msix.c
@@ -445,9 +445,7 @@ static int init_msix(struct pci_dev *pdev)
     uint16_t control;
     int rc;
 
-    msix_offset = pci_find_cap_offset(pdev->sbdf.seg, pdev->sbdf.bus,
-                                      pdev->sbdf.dev, pdev->sbdf.func,
-                                      PCI_CAP_ID_MSIX);
+    msix_offset = pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_MSIX);
     if ( !msix_offset )
         return 0;
 
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 5e345c417f..937465f5b5 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -178,10 +178,11 @@ int pci_mmcfg_read(unsigned int seg, unsigned int bus,
                    unsigned int devfn, int reg, int len, u32 *value);
 int pci_mmcfg_write(unsigned int seg, unsigned int bus,
                     unsigned int devfn, int reg, int len, u32 value);
-int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 cap);
-int pci_find_next_cap(u16 seg, u8 bus, unsigned int devfn, u8 pos, int cap);
-int pci_find_ext_capability(int seg, int bus, int devfn, int cap);
-int pci_find_next_ext_capability(int seg, int bus, int devfn, int pos, int cap);
+int pci_find_cap_offset(pci_sbdf_t sbdf, unsigned int cap);
+int pci_find_next_cap(pci_sbdf_t sbdf, unsigned int pos, unsigned int cap);
+int pci_find_ext_capability(pci_sbdf_t sbdf, unsigned int cap);
+int pci_find_next_ext_capability(pci_sbdf_t sbdf, unsigned int pos,
+                                 unsigned int cap);
 const char *parse_pci(const char *, unsigned int *seg, unsigned int *bus,
                       unsigned int *dev, unsigned int *func);
 const char *parse_pci_seg(const char *, unsigned int *seg, unsigned int *bus,
-- 
2.17.2 (Apple Git-113)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: [PATCH 1/5] pci: use pci_sbdf_t in pci_dev
@ 2019-05-10 16:16     ` Andrew Cooper
  0 siblings, 0 replies; 54+ messages in thread
From: Andrew Cooper @ 2019-05-10 16:16 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Suravee Suthikulpanit,
	Konrad Rzeszutek Wilk, George Dunlap, Tim Deegan, Ian Jackson,
	Julien Grall, Jan Beulich, Brian Woods

On 10/05/2019 17:10, Roger Pau Monne wrote:
> diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c
> index aeb5a70104..15cfe8d057 100644
> --- a/xen/arch/x86/hvm/vmsi.c
> +++ b/xen/arch/x86/hvm/vmsi.c
> @@ -688,8 +688,8 @@ static int vpci_msi_update(const struct pci_dev *pdev, uint32_t data,
>          {
>              gdprintk(XENLOG_ERR,
>                       "%04x:%02x:%02x.%u: failed to bind PIRQ %u: %d\n",
> -                     pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
> -                     PCI_FUNC(pdev->devfn), pirq + i, rc);
> +                     pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
> +                     pdev->sbdf.func, pirq + i, rc);

A pci_sbdf_t is 32 bits wide.  I do actually have a custom %p formatter
from a year or so ago, which simplifies code like this substantially.

Is there any interest in dusting off that patch and folding it into this
cleanup series?  ISTR it also came with several corrections to existing
SBDF rendering.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 1/5] pci: use pci_sbdf_t in pci_dev
@ 2019-05-10 16:16     ` Andrew Cooper
  0 siblings, 0 replies; 54+ messages in thread
From: Andrew Cooper @ 2019-05-10 16:16 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Suravee Suthikulpanit,
	Konrad Rzeszutek Wilk, George Dunlap, Tim Deegan, Ian Jackson,
	Julien Grall, Jan Beulich, Brian Woods

On 10/05/2019 17:10, Roger Pau Monne wrote:
> diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c
> index aeb5a70104..15cfe8d057 100644
> --- a/xen/arch/x86/hvm/vmsi.c
> +++ b/xen/arch/x86/hvm/vmsi.c
> @@ -688,8 +688,8 @@ static int vpci_msi_update(const struct pci_dev *pdev, uint32_t data,
>          {
>              gdprintk(XENLOG_ERR,
>                       "%04x:%02x:%02x.%u: failed to bind PIRQ %u: %d\n",
> -                     pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
> -                     PCI_FUNC(pdev->devfn), pirq + i, rc);
> +                     pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
> +                     pdev->sbdf.func, pirq + i, rc);

A pci_sbdf_t is 32 bits wide.  I do actually have a custom %p formatter
from a year or so ago, which simplifies code like this substantially.

Is there any interest in dusting off that patch and folding it into this
cleanup series?  ISTR it also came with several corrections to existing
SBDF rendering.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 1/5] pci: use pci_sbdf_t in pci_dev
@ 2019-05-13  6:25       ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-13  6:25 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Tim Deegan, Ian Jackson, Julien Grall,
	Suravee Suthikulpanit, xen-devel, Brian Woods, Roger Pau Monne

>>> On 10.05.19 at 18:16, <andrew.cooper3@citrix.com> wrote:
> On 10/05/2019 17:10, Roger Pau Monne wrote:
>> --- a/xen/arch/x86/hvm/vmsi.c
>> +++ b/xen/arch/x86/hvm/vmsi.c
>> @@ -688,8 +688,8 @@ static int vpci_msi_update(const struct pci_dev *pdev, uint32_t data,
>>          {
>>              gdprintk(XENLOG_ERR,
>>                       "%04x:%02x:%02x.%u: failed to bind PIRQ %u: %d\n",
>> -                     pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
>> -                     PCI_FUNC(pdev->devfn), pirq + i, rc);
>> +                     pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
>> +                     pdev->sbdf.func, pirq + i, rc);
> 
> A pci_sbdf_t is 32 bits wide.  I do actually have a custom %p formatter
> from a year or so ago, which simplifies code like this substantially.
> 
> Is there any interest in dusting off that patch and folding it into this
> cleanup series?  ISTR it also came with several corrections to existing
> SBDF rendering.

Afaic: Yes please! The one thing I'm not sure about is whether this
should be PCI-specific, or whether it wouldn't better be a more
general device thing. But I guess we use SBDF also independent of
struct pci_dev.

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 1/5] pci: use pci_sbdf_t in pci_dev
@ 2019-05-13  6:25       ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-13  6:25 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Tim Deegan, Ian Jackson, Julien Grall,
	Suravee Suthikulpanit, xen-devel, Brian Woods, Roger Pau Monne

>>> On 10.05.19 at 18:16, <andrew.cooper3@citrix.com> wrote:
> On 10/05/2019 17:10, Roger Pau Monne wrote:
>> --- a/xen/arch/x86/hvm/vmsi.c
>> +++ b/xen/arch/x86/hvm/vmsi.c
>> @@ -688,8 +688,8 @@ static int vpci_msi_update(const struct pci_dev *pdev, uint32_t data,
>>          {
>>              gdprintk(XENLOG_ERR,
>>                       "%04x:%02x:%02x.%u: failed to bind PIRQ %u: %d\n",
>> -                     pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
>> -                     PCI_FUNC(pdev->devfn), pirq + i, rc);
>> +                     pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
>> +                     pdev->sbdf.func, pirq + i, rc);
> 
> A pci_sbdf_t is 32 bits wide.  I do actually have a custom %p formatter
> from a year or so ago, which simplifies code like this substantially.
> 
> Is there any interest in dusting off that patch and folding it into this
> cleanup series?  ISTR it also came with several corrections to existing
> SBDF rendering.

Afaic: Yes please! The one thing I'm not sure about is whether this
should be PCI-specific, or whether it wouldn't better be a more
general device thing. But I guess we use SBDF also independent of
struct pci_dev.

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 1/5] pci: use pci_sbdf_t in pci_dev
@ 2019-05-13  7:53         ` Roger Pau Monné
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monné @ 2019-05-13  7:53 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

On Mon, May 13, 2019 at 12:25:37AM -0600, Jan Beulich wrote:
> >>> On 10.05.19 at 18:16, <andrew.cooper3@citrix.com> wrote:
> > On 10/05/2019 17:10, Roger Pau Monne wrote:
> >> --- a/xen/arch/x86/hvm/vmsi.c
> >> +++ b/xen/arch/x86/hvm/vmsi.c
> >> @@ -688,8 +688,8 @@ static int vpci_msi_update(const struct pci_dev *pdev, uint32_t data,
> >>          {
> >>              gdprintk(XENLOG_ERR,
> >>                       "%04x:%02x:%02x.%u: failed to bind PIRQ %u: %d\n",
> >> -                     pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
> >> -                     PCI_FUNC(pdev->devfn), pirq + i, rc);
> >> +                     pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
> >> +                     pdev->sbdf.func, pirq + i, rc);
> > 
> > A pci_sbdf_t is 32 bits wide.  I do actually have a custom %p formatter
> > from a year or so ago, which simplifies code like this substantially.
> > 
> > Is there any interest in dusting off that patch and folding it into this
> > cleanup series?  ISTR it also came with several corrections to existing
> > SBDF rendering.
> 
> Afaic: Yes please! The one thing I'm not sure about is whether this
> should be PCI-specific, or whether it wouldn't better be a more
> general device thing. But I guess we use SBDF also independent of
> struct pci_dev.

See patch 4 which introduces a printf format specifier for pci_sbdf_t.

Thanks, Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 1/5] pci: use pci_sbdf_t in pci_dev
@ 2019-05-13  7:53         ` Roger Pau Monné
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monné @ 2019-05-13  7:53 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

On Mon, May 13, 2019 at 12:25:37AM -0600, Jan Beulich wrote:
> >>> On 10.05.19 at 18:16, <andrew.cooper3@citrix.com> wrote:
> > On 10/05/2019 17:10, Roger Pau Monne wrote:
> >> --- a/xen/arch/x86/hvm/vmsi.c
> >> +++ b/xen/arch/x86/hvm/vmsi.c
> >> @@ -688,8 +688,8 @@ static int vpci_msi_update(const struct pci_dev *pdev, uint32_t data,
> >>          {
> >>              gdprintk(XENLOG_ERR,
> >>                       "%04x:%02x:%02x.%u: failed to bind PIRQ %u: %d\n",
> >> -                     pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
> >> -                     PCI_FUNC(pdev->devfn), pirq + i, rc);
> >> +                     pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
> >> +                     pdev->sbdf.func, pirq + i, rc);
> > 
> > A pci_sbdf_t is 32 bits wide.  I do actually have a custom %p formatter
> > from a year or so ago, which simplifies code like this substantially.
> > 
> > Is there any interest in dusting off that patch and folding it into this
> > cleanup series?  ISTR it also came with several corrections to existing
> > SBDF rendering.
> 
> Afaic: Yes please! The one thing I'm not sure about is whether this
> should be PCI-specific, or whether it wouldn't better be a more
> general device thing. But I guess we use SBDF also independent of
> struct pci_dev.

See patch 4 which introduces a printf format specifier for pci_sbdf_t.

Thanks, Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 1/5] pci: use pci_sbdf_t in pci_dev
@ 2019-05-23 15:29     ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-23 15:29 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

>>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> --- a/xen/arch/x86/hvm/vmsi.c
> +++ b/xen/arch/x86/hvm/vmsi.c
> @@ -688,8 +688,8 @@ static int vpci_msi_update(const struct pci_dev *pdev, uint32_t data,
>          {
>              gdprintk(XENLOG_ERR,
>                       "%04x:%02x:%02x.%u: failed to bind PIRQ %u: %d\n",
> -                     pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
> -                     PCI_FUNC(pdev->devfn), pirq + i, rc);
> +                     pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
> +                     pdev->sbdf.func, pirq + i, rc);

I assume patch 4 could have been quite a bit smaller, and you could have
avoided touching the same places twice if that one came before the one
here.

> --- a/xen/drivers/passthrough/amd/iommu_cmd.c
> +++ b/xen/drivers/passthrough/amd/iommu_cmd.c
> @@ -289,23 +289,23 @@ void amd_iommu_flush_iotlb(u8 devfn, const struct pci_dev *pdev,
>      if ( !ats_enabled )
>          return;
>  
> -    if ( !pci_ats_enabled(pdev->seg, pdev->bus, pdev->devfn) )
> +    if ( !pci_ats_enabled(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.extfunc) )

Why extfunc and not (as it was before) devfn (same elsewhere)?
There should have been a devfn field from the beginning, even if
it's similarly uint8_t as extfunc is. As the meaning of both is different,
the correct (given context) one should be used. Existing uses of
extfunc should also be inspected and changed if necessary.

> --- a/xen/include/xen/pci.h
> +++ b/xen/include/xen/pci.h
> @@ -80,9 +80,8 @@ struct pci_dev {
>      struct arch_msix *msix;
>  
>      struct domain *domain;
> -    const u16 seg;
> -    const u8 bus;
> -    const u8 devfn;
> +
> +    const pci_sbdf_t sbdf;

To help the transition, did you consider first making this a union of
the existing fields and the new one, next replacing used in a per
component manner (so that individual maintainers would have to
look at smaller patches each only), and finally dropping the union
and its old fields?

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 1/5] pci: use pci_sbdf_t in pci_dev
@ 2019-05-23 15:29     ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-23 15:29 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

>>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> --- a/xen/arch/x86/hvm/vmsi.c
> +++ b/xen/arch/x86/hvm/vmsi.c
> @@ -688,8 +688,8 @@ static int vpci_msi_update(const struct pci_dev *pdev, uint32_t data,
>          {
>              gdprintk(XENLOG_ERR,
>                       "%04x:%02x:%02x.%u: failed to bind PIRQ %u: %d\n",
> -                     pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn),
> -                     PCI_FUNC(pdev->devfn), pirq + i, rc);
> +                     pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.dev,
> +                     pdev->sbdf.func, pirq + i, rc);

I assume patch 4 could have been quite a bit smaller, and you could have
avoided touching the same places twice if that one came before the one
here.

> --- a/xen/drivers/passthrough/amd/iommu_cmd.c
> +++ b/xen/drivers/passthrough/amd/iommu_cmd.c
> @@ -289,23 +289,23 @@ void amd_iommu_flush_iotlb(u8 devfn, const struct pci_dev *pdev,
>      if ( !ats_enabled )
>          return;
>  
> -    if ( !pci_ats_enabled(pdev->seg, pdev->bus, pdev->devfn) )
> +    if ( !pci_ats_enabled(pdev->sbdf.seg, pdev->sbdf.bus, pdev->sbdf.extfunc) )

Why extfunc and not (as it was before) devfn (same elsewhere)?
There should have been a devfn field from the beginning, even if
it's similarly uint8_t as extfunc is. As the meaning of both is different,
the correct (given context) one should be used. Existing uses of
extfunc should also be inspected and changed if necessary.

> --- a/xen/include/xen/pci.h
> +++ b/xen/include/xen/pci.h
> @@ -80,9 +80,8 @@ struct pci_dev {
>      struct arch_msix *msix;
>  
>      struct domain *domain;
> -    const u16 seg;
> -    const u8 bus;
> -    const u8 devfn;
> +
> +    const pci_sbdf_t sbdf;

To help the transition, did you consider first making this a union of
the existing fields and the new one, next replacing used in a per
component manner (so that individual maintainers would have to
look at smaller patches each only), and finally dropping the union
and its old fields?

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 2/5] pci: use function generation macros for pci_config_{write, read}<size>
@ 2019-05-24  9:10     ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-24  9:10 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: Andrew Cooper, Wei Liu, xen-devel

>>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> This avoids code duplication between the helpers.
> 
> No functional change intended.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 2/5] pci: use function generation macros for pci_config_{write, read}<size>
@ 2019-05-24  9:10     ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-24  9:10 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: Andrew Cooper, Wei Liu, xen-devel

>>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> This avoids code duplication between the helpers.
> 
> No functional change intended.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 2/5] pci: use function generation macros for pci_config_{write, read}<size>
@ 2019-05-24  9:29     ` Andrew Cooper
  0 siblings, 0 replies; 54+ messages in thread
From: Andrew Cooper @ 2019-05-24  9:29 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel; +Cc: Wei Liu, Jan Beulich

On 10/05/2019 17:10, Roger Pau Monne wrote:
> This avoids code duplication between the helpers.
>
> No functional change intended.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>

-1.  I see this as actively making the code worse, not an improvement.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 2/5] pci: use function generation macros for pci_config_{write, read}<size>
@ 2019-05-24  9:29     ` Andrew Cooper
  0 siblings, 0 replies; 54+ messages in thread
From: Andrew Cooper @ 2019-05-24  9:29 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel; +Cc: Wei Liu, Jan Beulich

On 10/05/2019 17:10, Roger Pau Monne wrote:
> This avoids code duplication between the helpers.
>
> No functional change intended.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>

-1.  I see this as actively making the code worse, not an improvement.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 3/5] pci: switch pci_conf_{read/write} to use pci_sbdf_t
@ 2019-05-24  9:40     ` Andrew Cooper
  0 siblings, 0 replies; 54+ messages in thread
From: Andrew Cooper @ 2019-05-24  9:40 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Suravee Suthikulpanit,
	Konrad Rzeszutek Wilk, George Dunlap, Tim Deegan, Ian Jackson,
	Julien Grall, Jan Beulich, Brian Woods

On 10/05/2019 17:10, Roger Pau Monne wrote:
> pci_dev already uses pci_sbdf_t, so propagate the usage of the type to
> pci_conf functions in order to shorten the calls when made from a
> pci_dev struct.
>
> No functional change intended.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> ---
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> Cc: George Dunlap <George.Dunlap@eu.citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Julien Grall <julien.grall@arm.com>
> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Tim Deegan <tim@xen.org>
> Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> Cc: Brian Woods <brian.woods@amd.com>
> Cc: Kevin Tian <kevin.tian@intel.com>
> ---
>  xen/arch/x86/cpu/amd.c                     |  27 ++--
>  xen/arch/x86/dmi_scan.c                    |   9 +-
>  xen/arch/x86/mm.c                          |   2 +-
>  xen/arch/x86/msi.c                         | 177 +++++++++------------
>  xen/arch/x86/oprofile/op_model_athlon.c    |  12 +-
>  xen/arch/x86/x86_64/mmconf-fam10h.c        |  13 +-
>  xen/arch/x86/x86_64/mmconfig-shared.c      |  26 +--
>  xen/arch/x86/x86_64/pci.c                  |  32 ++--
>  xen/drivers/acpi/reboot.c                  |   8 +-
>  xen/drivers/char/ehci-dbgp.c               |  75 +++++----
>  xen/drivers/char/ns16550.c                 |  80 +++++-----
>  xen/drivers/passthrough/amd/iommu_detect.c |   3 +-
>  xen/drivers/passthrough/amd/iommu_init.c   |  26 +--
>  xen/drivers/passthrough/ats.h              |   4 +-
>  xen/drivers/passthrough/pci.c              | 106 +++++-------
>  xen/drivers/passthrough/vtd/dmar.c         |  18 ++-
>  xen/drivers/passthrough/vtd/quirks.c       |  69 ++++----
>  xen/drivers/passthrough/x86/ats.c          |  15 +-
>  xen/drivers/pci/pci.c                      |  43 +++--
>  xen/drivers/video/vga.c                    |  21 +--
>  xen/drivers/vpci/header.c                  |  53 ++----
>  xen/drivers/vpci/msi.c                     |   6 +-
>  xen/drivers/vpci/msix.c                    |  12 +-
>  xen/drivers/vpci/vpci.c                    |  42 ++---
>  xen/include/xen/pci.h                      |  29 ++--
>  25 files changed, 444 insertions(+), 464 deletions(-)
>
> diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
> index e19a5ead3e..014d88925c 100644
> --- a/xen/arch/x86/cpu/amd.c
> +++ b/xen/arch/x86/cpu/amd.c
> @@ -417,15 +417,21 @@ static void disable_c1_ramping(void)
>  	int node, nr_nodes;
>  
>  	/* Read the number of nodes from the first Northbridge. */
> -	nr_nodes = ((pci_conf_read32(0, 0, 0x18, 0x0, 0x60)>>4)&0x07)+1;
> +	nr_nodes = ((pci_conf_read32(PCI_SBDF_T(0, 0, 0x18, 0),
> +				     0x60)>>4)&0x07)+1;

This looks suspiciously like it wants to use MASK_EXTR()

>  	for (node = 0; node < nr_nodes; node++) {
> +		const pci_sbdf_t sbdf = {
> +			.dev = 0x18  + node,
> +			.func = 0x3
> +		};

What is wrong with something like:

pci_sbdf_t pci = PCI_SBDF_T(0, 0, 0x18 + node, 3);

IMO, the resulting code would be more logical to read as
pci_conf_read8(pci, ...) (or perhaps dev?).  sbdf it a little awkward.

> +
>  		/* PMM7: bus=0, dev=0x18+node, function=0x3, register=0x87. */
> -		pmm7 = pci_conf_read8(0, 0, 0x18+node, 0x3, 0x87);
> +		pmm7 = pci_conf_read8(sbdf, 0x87);
>  		/* Invalid read means we've updated every Northbridge. */
>  		if (pmm7 == 0xFF)
>  			break;
>  		pmm7 &= 0xFC; /* clear pmm7[1:0] */
> -		pci_conf_write8(0, 0, 0x18+node, 0x3, 0x87, pmm7);
> +		pci_conf_write8(sbdf, 0x87, pmm7);
>  		printk ("AMD: Disabling C1 Clock Ramping Node #%x\n", node);
>  	}
>  }
> @@ -696,8 +702,13 @@ static void init_amd(struct cpuinfo_x86 *c)
>  
>  	if (c->x86 == 0x16 && c->x86_model <= 0xf) {
>  		if (c == &boot_cpu_data) {
> -			l = pci_conf_read32(0, 0, 0x18, 0x3, 0x58);
> -			h = pci_conf_read32(0, 0, 0x18, 0x3, 0x5c);
> +			const pci_sbdf_t sbdf = {
> +				.dev = 0x18,
> +				.func = 0x3,
> +			};
> +
> +			l = pci_conf_read32(sbdf, 0x58);
> +			h = pci_conf_read32(sbdf, 0x5c);
>  			if ((l & 0x1f) | (h & 0x1))
>  				printk(KERN_WARNING
>  				       "Applying workaround for erratum 792: %s%s%s\n",
> @@ -706,12 +717,10 @@ static void init_amd(struct cpuinfo_x86 *c)
>  				       (h & 0x1) ? "clearing D18F3x5C[0]" : "");
>  
>  			if (l & 0x1f)
> -				pci_conf_write32(0, 0, 0x18, 0x3, 0x58,
> -						 l & ~0x1f);
> +				pci_conf_write32(sbdf, 0x58, l & ~0x1f);
>  
>  			if (h & 0x1)
> -				pci_conf_write32(0, 0, 0x18, 0x3, 0x5c,
> -						 h & ~0x1);
> +				pci_conf_write32(sbdf, 0x5c, h & ~0x1);
>  		}
>  
>  		rdmsrl(MSR_AMD64_LS_CFG, value);
> diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
> index fcdf2d3952..59557fa57b 100644
> --- a/xen/arch/x86/dmi_scan.c
> +++ b/xen/arch/x86/dmi_scan.c
> @@ -468,16 +468,19 @@ static __init int broken_toshiba_keyboard(struct dmi_blacklist *d)
>  static int __init ich10_bios_quirk(struct dmi_system_id *d)
>  {
>      u32 port, smictl;
> +    const pci_sbdf_t sbdf = {
> +	.dev = 0x1f,
> +    };
>  
> -    if ( pci_conf_read16(0, 0, 0x1f, 0, PCI_VENDOR_ID) != 0x8086 )
> +    if ( pci_conf_read16(sbdf, PCI_VENDOR_ID) != 0x8086 )
>          return 0;
>  
> -    switch ( pci_conf_read16(0, 0, 0x1f, 0, PCI_DEVICE_ID) ) {
> +    switch ( pci_conf_read16(sbdf, PCI_DEVICE_ID) ) {
>      case 0x3a14:
>      case 0x3a16:
>      case 0x3a18:
>      case 0x3a1a:
> -        port = (pci_conf_read16(0, 0, 0x1f, 0, 0x40) & 0xff80) + 0x30;
> +        port = (pci_conf_read16(sbdf, 0x40) & 0xff80) + 0x30;
>          smictl = inl(port);
>          /* turn off LEGACY_USB{,2}_EN if enabled */
>          if ( smictl & 0x20008 )
> diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
> index 45fadbab61..37d8141ed2 100644
> --- a/xen/arch/x86/mm.c
> +++ b/xen/arch/x86/mm.c
> @@ -5984,7 +5984,7 @@ const struct platform_bad_page *__init get_platform_badpages(unsigned int *array
>      }
>  
>      *array_size = ARRAY_SIZE(snb_bad_pages);
> -    igd_id = pci_conf_read32(0, 0, 2, 0, 0);
> +    igd_id = pci_conf_read32(PCI_SBDF_T(0, 0, 2, 0), 0);
>      if ( IS_SNB_GFX(igd_id) )
>          return snb_bad_pages;
>  
> diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
> index f30f592ee2..ad4a72d56b 100644
> --- a/xen/arch/x86/msi.c
> +++ b/xen/arch/x86/msi.c
> @@ -124,29 +124,20 @@ static void msix_put_fixmap(struct arch_msix *msix, int idx)
>  
>  static bool memory_decoded(const struct pci_dev *dev)
>  {
> -    uint8_t bus, slot, func;
> +    pci_sbdf_t sbdf = dev->sbdf;
>  
> -    if ( !dev->info.is_virtfn )
> +    if ( dev->info.is_virtfn )
>      {
> -        bus = dev->sbdf.bus;
> -        slot = dev->sbdf.dev;
> -        func = dev->sbdf.func;
> -    }
> -    else
> -    {
> -        bus = dev->info.physfn.bus;
> -        slot = PCI_SLOT(dev->info.physfn.devfn);
> -        func = PCI_FUNC(dev->info.physfn.devfn);
> +        sbdf.bus = dev->info.physfn.bus;
> +        sbdf.extfunc = dev->info.physfn.devfn;
>      }
>  
> -    return !!(pci_conf_read16(dev->sbdf.seg, bus, slot, func, PCI_COMMAND) &
> -              PCI_COMMAND_MEMORY);
> +    return !!(pci_conf_read16(sbdf, PCI_COMMAND) & PCI_COMMAND_MEMORY);

Can drop the !! and brackets.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 3/5] pci: switch pci_conf_{read/write} to use pci_sbdf_t
@ 2019-05-24  9:40     ` Andrew Cooper
  0 siblings, 0 replies; 54+ messages in thread
From: Andrew Cooper @ 2019-05-24  9:40 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Suravee Suthikulpanit,
	Konrad Rzeszutek Wilk, George Dunlap, Tim Deegan, Ian Jackson,
	Julien Grall, Jan Beulich, Brian Woods

On 10/05/2019 17:10, Roger Pau Monne wrote:
> pci_dev already uses pci_sbdf_t, so propagate the usage of the type to
> pci_conf functions in order to shorten the calls when made from a
> pci_dev struct.
>
> No functional change intended.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> ---
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> Cc: George Dunlap <George.Dunlap@eu.citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Julien Grall <julien.grall@arm.com>
> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Tim Deegan <tim@xen.org>
> Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> Cc: Brian Woods <brian.woods@amd.com>
> Cc: Kevin Tian <kevin.tian@intel.com>
> ---
>  xen/arch/x86/cpu/amd.c                     |  27 ++--
>  xen/arch/x86/dmi_scan.c                    |   9 +-
>  xen/arch/x86/mm.c                          |   2 +-
>  xen/arch/x86/msi.c                         | 177 +++++++++------------
>  xen/arch/x86/oprofile/op_model_athlon.c    |  12 +-
>  xen/arch/x86/x86_64/mmconf-fam10h.c        |  13 +-
>  xen/arch/x86/x86_64/mmconfig-shared.c      |  26 +--
>  xen/arch/x86/x86_64/pci.c                  |  32 ++--
>  xen/drivers/acpi/reboot.c                  |   8 +-
>  xen/drivers/char/ehci-dbgp.c               |  75 +++++----
>  xen/drivers/char/ns16550.c                 |  80 +++++-----
>  xen/drivers/passthrough/amd/iommu_detect.c |   3 +-
>  xen/drivers/passthrough/amd/iommu_init.c   |  26 +--
>  xen/drivers/passthrough/ats.h              |   4 +-
>  xen/drivers/passthrough/pci.c              | 106 +++++-------
>  xen/drivers/passthrough/vtd/dmar.c         |  18 ++-
>  xen/drivers/passthrough/vtd/quirks.c       |  69 ++++----
>  xen/drivers/passthrough/x86/ats.c          |  15 +-
>  xen/drivers/pci/pci.c                      |  43 +++--
>  xen/drivers/video/vga.c                    |  21 +--
>  xen/drivers/vpci/header.c                  |  53 ++----
>  xen/drivers/vpci/msi.c                     |   6 +-
>  xen/drivers/vpci/msix.c                    |  12 +-
>  xen/drivers/vpci/vpci.c                    |  42 ++---
>  xen/include/xen/pci.h                      |  29 ++--
>  25 files changed, 444 insertions(+), 464 deletions(-)
>
> diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
> index e19a5ead3e..014d88925c 100644
> --- a/xen/arch/x86/cpu/amd.c
> +++ b/xen/arch/x86/cpu/amd.c
> @@ -417,15 +417,21 @@ static void disable_c1_ramping(void)
>  	int node, nr_nodes;
>  
>  	/* Read the number of nodes from the first Northbridge. */
> -	nr_nodes = ((pci_conf_read32(0, 0, 0x18, 0x0, 0x60)>>4)&0x07)+1;
> +	nr_nodes = ((pci_conf_read32(PCI_SBDF_T(0, 0, 0x18, 0),
> +				     0x60)>>4)&0x07)+1;

This looks suspiciously like it wants to use MASK_EXTR()

>  	for (node = 0; node < nr_nodes; node++) {
> +		const pci_sbdf_t sbdf = {
> +			.dev = 0x18  + node,
> +			.func = 0x3
> +		};

What is wrong with something like:

pci_sbdf_t pci = PCI_SBDF_T(0, 0, 0x18 + node, 3);

IMO, the resulting code would be more logical to read as
pci_conf_read8(pci, ...) (or perhaps dev?).  sbdf it a little awkward.

> +
>  		/* PMM7: bus=0, dev=0x18+node, function=0x3, register=0x87. */
> -		pmm7 = pci_conf_read8(0, 0, 0x18+node, 0x3, 0x87);
> +		pmm7 = pci_conf_read8(sbdf, 0x87);
>  		/* Invalid read means we've updated every Northbridge. */
>  		if (pmm7 == 0xFF)
>  			break;
>  		pmm7 &= 0xFC; /* clear pmm7[1:0] */
> -		pci_conf_write8(0, 0, 0x18+node, 0x3, 0x87, pmm7);
> +		pci_conf_write8(sbdf, 0x87, pmm7);
>  		printk ("AMD: Disabling C1 Clock Ramping Node #%x\n", node);
>  	}
>  }
> @@ -696,8 +702,13 @@ static void init_amd(struct cpuinfo_x86 *c)
>  
>  	if (c->x86 == 0x16 && c->x86_model <= 0xf) {
>  		if (c == &boot_cpu_data) {
> -			l = pci_conf_read32(0, 0, 0x18, 0x3, 0x58);
> -			h = pci_conf_read32(0, 0, 0x18, 0x3, 0x5c);
> +			const pci_sbdf_t sbdf = {
> +				.dev = 0x18,
> +				.func = 0x3,
> +			};
> +
> +			l = pci_conf_read32(sbdf, 0x58);
> +			h = pci_conf_read32(sbdf, 0x5c);
>  			if ((l & 0x1f) | (h & 0x1))
>  				printk(KERN_WARNING
>  				       "Applying workaround for erratum 792: %s%s%s\n",
> @@ -706,12 +717,10 @@ static void init_amd(struct cpuinfo_x86 *c)
>  				       (h & 0x1) ? "clearing D18F3x5C[0]" : "");
>  
>  			if (l & 0x1f)
> -				pci_conf_write32(0, 0, 0x18, 0x3, 0x58,
> -						 l & ~0x1f);
> +				pci_conf_write32(sbdf, 0x58, l & ~0x1f);
>  
>  			if (h & 0x1)
> -				pci_conf_write32(0, 0, 0x18, 0x3, 0x5c,
> -						 h & ~0x1);
> +				pci_conf_write32(sbdf, 0x5c, h & ~0x1);
>  		}
>  
>  		rdmsrl(MSR_AMD64_LS_CFG, value);
> diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
> index fcdf2d3952..59557fa57b 100644
> --- a/xen/arch/x86/dmi_scan.c
> +++ b/xen/arch/x86/dmi_scan.c
> @@ -468,16 +468,19 @@ static __init int broken_toshiba_keyboard(struct dmi_blacklist *d)
>  static int __init ich10_bios_quirk(struct dmi_system_id *d)
>  {
>      u32 port, smictl;
> +    const pci_sbdf_t sbdf = {
> +	.dev = 0x1f,
> +    };
>  
> -    if ( pci_conf_read16(0, 0, 0x1f, 0, PCI_VENDOR_ID) != 0x8086 )
> +    if ( pci_conf_read16(sbdf, PCI_VENDOR_ID) != 0x8086 )
>          return 0;
>  
> -    switch ( pci_conf_read16(0, 0, 0x1f, 0, PCI_DEVICE_ID) ) {
> +    switch ( pci_conf_read16(sbdf, PCI_DEVICE_ID) ) {
>      case 0x3a14:
>      case 0x3a16:
>      case 0x3a18:
>      case 0x3a1a:
> -        port = (pci_conf_read16(0, 0, 0x1f, 0, 0x40) & 0xff80) + 0x30;
> +        port = (pci_conf_read16(sbdf, 0x40) & 0xff80) + 0x30;
>          smictl = inl(port);
>          /* turn off LEGACY_USB{,2}_EN if enabled */
>          if ( smictl & 0x20008 )
> diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
> index 45fadbab61..37d8141ed2 100644
> --- a/xen/arch/x86/mm.c
> +++ b/xen/arch/x86/mm.c
> @@ -5984,7 +5984,7 @@ const struct platform_bad_page *__init get_platform_badpages(unsigned int *array
>      }
>  
>      *array_size = ARRAY_SIZE(snb_bad_pages);
> -    igd_id = pci_conf_read32(0, 0, 2, 0, 0);
> +    igd_id = pci_conf_read32(PCI_SBDF_T(0, 0, 2, 0), 0);
>      if ( IS_SNB_GFX(igd_id) )
>          return snb_bad_pages;
>  
> diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
> index f30f592ee2..ad4a72d56b 100644
> --- a/xen/arch/x86/msi.c
> +++ b/xen/arch/x86/msi.c
> @@ -124,29 +124,20 @@ static void msix_put_fixmap(struct arch_msix *msix, int idx)
>  
>  static bool memory_decoded(const struct pci_dev *dev)
>  {
> -    uint8_t bus, slot, func;
> +    pci_sbdf_t sbdf = dev->sbdf;
>  
> -    if ( !dev->info.is_virtfn )
> +    if ( dev->info.is_virtfn )
>      {
> -        bus = dev->sbdf.bus;
> -        slot = dev->sbdf.dev;
> -        func = dev->sbdf.func;
> -    }
> -    else
> -    {
> -        bus = dev->info.physfn.bus;
> -        slot = PCI_SLOT(dev->info.physfn.devfn);
> -        func = PCI_FUNC(dev->info.physfn.devfn);
> +        sbdf.bus = dev->info.physfn.bus;
> +        sbdf.extfunc = dev->info.physfn.devfn;
>      }
>  
> -    return !!(pci_conf_read16(dev->sbdf.seg, bus, slot, func, PCI_COMMAND) &
> -              PCI_COMMAND_MEMORY);
> +    return !!(pci_conf_read16(sbdf, PCI_COMMAND) & PCI_COMMAND_MEMORY);

Can drop the !! and brackets.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 3/5] pci: switch pci_conf_{read/write} to use pci_sbdf_t
@ 2019-05-24 10:01     ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-24 10:01 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

>>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> --- a/xen/arch/x86/cpu/amd.c
> +++ b/xen/arch/x86/cpu/amd.c
> @@ -417,15 +417,21 @@ static void disable_c1_ramping(void)
>  	int node, nr_nodes;
>  
>  	/* Read the number of nodes from the first Northbridge. */
> -	nr_nodes = ((pci_conf_read32(0, 0, 0x18, 0x0, 0x60)>>4)&0x07)+1;
> +	nr_nodes = ((pci_conf_read32(PCI_SBDF_T(0, 0, 0x18, 0),
> +				     0x60)>>4)&0x07)+1;

Could you please add the missing blanks here as you touch this anyway?

>  	for (node = 0; node < nr_nodes; node++) {
> +		const pci_sbdf_t sbdf = {
> +			.dev = 0x18  + node,
> +			.func = 0x3

Just like you do above, dropping the unnecessary 0x from this last line
would be nice. (Same again further down.)

> --- a/xen/arch/x86/msi.c
> +++ b/xen/arch/x86/msi.c
> @@ -124,29 +124,20 @@ static void msix_put_fixmap(struct arch_msix *msix, int idx)
>  
>  static bool memory_decoded(const struct pci_dev *dev)
>  {
> -    uint8_t bus, slot, func;
> +    pci_sbdf_t sbdf = dev->sbdf;
>  
> -    if ( !dev->info.is_virtfn )
> +    if ( dev->info.is_virtfn )
>      {
> -        bus = dev->sbdf.bus;
> -        slot = dev->sbdf.dev;
> -        func = dev->sbdf.func;
> -    }
> -    else
> -    {
> -        bus = dev->info.physfn.bus;
> -        slot = PCI_SLOT(dev->info.physfn.devfn);
> -        func = PCI_FUNC(dev->info.physfn.devfn);
> +        sbdf.bus = dev->info.physfn.bus;
> +        sbdf.extfunc = dev->info.physfn.devfn;
>      }
>  
> -    return !!(pci_conf_read16(dev->sbdf.seg, bus, slot, func, PCI_COMMAND) &
> -              PCI_COMMAND_MEMORY);
> +    return !!(pci_conf_read16(sbdf, PCI_COMMAND) & PCI_COMMAND_MEMORY);

Take the opportunity and also drop the pointless !! (and parentheses)?

> @@ -855,20 +859,22 @@ static void _ns16550_resume(struct serial_port *port)
>  {
>  #ifdef CONFIG_HAS_PCI
>      struct ns16550 *uart = port->uart;
> +    const pci_sbdf_t sbdf = {
> +        .bus = uart->ps_bdf[0],
> +        .dev = uart->ps_bdf[1],
> +        .func = uart->ps_bdf[2],
> +    };

In cases like this one, is there any particular reason you don't use the
macro you introduce?

>      if ( uart->bar )
>      {

Also it looks like the variable could move into this more narrow scope.

> -       pci_conf_write32(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
> -                        PCI_BASE_ADDRESS_0 + uart->bar_idx*4, uart->bar);
> +       pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + uart->bar_idx*4, uart->bar);

Ideally add the missing blanks again (many more below)?

> @@ -356,10 +356,16 @@ static int __init acpi_parse_dev_scope(
>          switch ( acpi_scope->entry_type )
>          {
>          case ACPI_DMAR_SCOPE_TYPE_BRIDGE:
> -            sec_bus = pci_conf_read8(seg, bus, path->dev, path->fn,
> -                                     PCI_SECONDARY_BUS);
> -            sub_bus = pci_conf_read8(seg, bus, path->dev, path->fn,
> -                                     PCI_SUBORDINATE_BUS);
> +        {
> +            const pci_sbdf_t sbdf = {
> +                .seg = seg,
> +                .bus = bus,
> +                .dev = path->dev,
> +                .func = path->fn,
> +            };
> +
> +            sec_bus = pci_conf_read8(sbdf, PCI_SECONDARY_BUS);
> +            sub_bus = pci_conf_read8(sbdf, PCI_SUBORDINATE_BUS);
>              if ( iommu_verbose )
>                  printk(VTDPREFIX
>                         " bridge: %04x:%02x:%02x.%u start=%x sec=%x sub=%x\n",
> @@ -368,7 +374,7 @@ static int __init acpi_parse_dev_scope(
>  
>              dmar_scope_add_buses(scope, sec_bus, sub_bus);
>              break;
> -
> +        }
>          case ACPI_DMAR_SCOPE_TYPE_HPET:

Please don't lose the blank line.

> --- a/xen/drivers/passthrough/vtd/quirks.c
> +++ b/xen/drivers/passthrough/vtd/quirks.c
> @@ -61,6 +61,14 @@ static bool_t __read_mostly is_snb_gfx;
>  static u8 *__read_mostly igd_reg_va;
>  static spinlock_t igd_lock;
>  
> +static const pci_sbdf_t igd_sbdf = {
> +    .dev = IGD_DEV,
> +};
> +
> +static const pci_sbdf_t ioh_sbdf = {
> +    .dev = IOH_DEV,
> +};

There's only a single use of this, and in an __init function. On one
hand we certainly expect the compiler to not emit to .rodata here
in the first place. But then - can we rely on this? If not, this would
want to become __initconst. So on the whole I think I'd prefer if
you used the initializer macro instead, making IGD_DEV and
IOH_DEV both invocations of that macro. That's then also better
in line with uses of the macro elsewhere in this file.

> --- a/xen/include/xen/pci.h
> +++ b/xen/include/xen/pci.h
> @@ -58,6 +58,11 @@ typedef union {
>      };
>  } pci_sbdf_t;
>  
> +#define PCI_SBDF_T(s, b, d, f) \
> +    ((pci_sbdf_t) { .seg = (s), .bus = (b), .dev = (d), .func = (f) })

I'd prefer if the _T suffix could be omitted. Afaics there's no use of the
existing PCI_SBDF() anywhere in the tree, so this should be fine. For
the 2nd macro below I can't easily tell whether the few existing used
have all disappeared by now, but it seems likely.

Also I'm afraid initializers of this kind will break the build with old gcc.

> +#define PCI_SBDF3_T(s, b, e) \
> +    ((pci_sbdf_t) { .seg = (s), .bus = (b), .extfunc = (e) })

Same remark as on the earlier patch regarding extfunc.

On the whole, again seeing the size of this patch, splitting this up would
probably have helped. At least doing reads and writes separately should
have been possible.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 3/5] pci: switch pci_conf_{read/write} to use pci_sbdf_t
@ 2019-05-24 10:01     ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-24 10:01 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

>>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> --- a/xen/arch/x86/cpu/amd.c
> +++ b/xen/arch/x86/cpu/amd.c
> @@ -417,15 +417,21 @@ static void disable_c1_ramping(void)
>  	int node, nr_nodes;
>  
>  	/* Read the number of nodes from the first Northbridge. */
> -	nr_nodes = ((pci_conf_read32(0, 0, 0x18, 0x0, 0x60)>>4)&0x07)+1;
> +	nr_nodes = ((pci_conf_read32(PCI_SBDF_T(0, 0, 0x18, 0),
> +				     0x60)>>4)&0x07)+1;

Could you please add the missing blanks here as you touch this anyway?

>  	for (node = 0; node < nr_nodes; node++) {
> +		const pci_sbdf_t sbdf = {
> +			.dev = 0x18  + node,
> +			.func = 0x3

Just like you do above, dropping the unnecessary 0x from this last line
would be nice. (Same again further down.)

> --- a/xen/arch/x86/msi.c
> +++ b/xen/arch/x86/msi.c
> @@ -124,29 +124,20 @@ static void msix_put_fixmap(struct arch_msix *msix, int idx)
>  
>  static bool memory_decoded(const struct pci_dev *dev)
>  {
> -    uint8_t bus, slot, func;
> +    pci_sbdf_t sbdf = dev->sbdf;
>  
> -    if ( !dev->info.is_virtfn )
> +    if ( dev->info.is_virtfn )
>      {
> -        bus = dev->sbdf.bus;
> -        slot = dev->sbdf.dev;
> -        func = dev->sbdf.func;
> -    }
> -    else
> -    {
> -        bus = dev->info.physfn.bus;
> -        slot = PCI_SLOT(dev->info.physfn.devfn);
> -        func = PCI_FUNC(dev->info.physfn.devfn);
> +        sbdf.bus = dev->info.physfn.bus;
> +        sbdf.extfunc = dev->info.physfn.devfn;
>      }
>  
> -    return !!(pci_conf_read16(dev->sbdf.seg, bus, slot, func, PCI_COMMAND) &
> -              PCI_COMMAND_MEMORY);
> +    return !!(pci_conf_read16(sbdf, PCI_COMMAND) & PCI_COMMAND_MEMORY);

Take the opportunity and also drop the pointless !! (and parentheses)?

> @@ -855,20 +859,22 @@ static void _ns16550_resume(struct serial_port *port)
>  {
>  #ifdef CONFIG_HAS_PCI
>      struct ns16550 *uart = port->uart;
> +    const pci_sbdf_t sbdf = {
> +        .bus = uart->ps_bdf[0],
> +        .dev = uart->ps_bdf[1],
> +        .func = uart->ps_bdf[2],
> +    };

In cases like this one, is there any particular reason you don't use the
macro you introduce?

>      if ( uart->bar )
>      {

Also it looks like the variable could move into this more narrow scope.

> -       pci_conf_write32(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2],
> -                        PCI_BASE_ADDRESS_0 + uart->bar_idx*4, uart->bar);
> +       pci_conf_write32(sbdf, PCI_BASE_ADDRESS_0 + uart->bar_idx*4, uart->bar);

Ideally add the missing blanks again (many more below)?

> @@ -356,10 +356,16 @@ static int __init acpi_parse_dev_scope(
>          switch ( acpi_scope->entry_type )
>          {
>          case ACPI_DMAR_SCOPE_TYPE_BRIDGE:
> -            sec_bus = pci_conf_read8(seg, bus, path->dev, path->fn,
> -                                     PCI_SECONDARY_BUS);
> -            sub_bus = pci_conf_read8(seg, bus, path->dev, path->fn,
> -                                     PCI_SUBORDINATE_BUS);
> +        {
> +            const pci_sbdf_t sbdf = {
> +                .seg = seg,
> +                .bus = bus,
> +                .dev = path->dev,
> +                .func = path->fn,
> +            };
> +
> +            sec_bus = pci_conf_read8(sbdf, PCI_SECONDARY_BUS);
> +            sub_bus = pci_conf_read8(sbdf, PCI_SUBORDINATE_BUS);
>              if ( iommu_verbose )
>                  printk(VTDPREFIX
>                         " bridge: %04x:%02x:%02x.%u start=%x sec=%x sub=%x\n",
> @@ -368,7 +374,7 @@ static int __init acpi_parse_dev_scope(
>  
>              dmar_scope_add_buses(scope, sec_bus, sub_bus);
>              break;
> -
> +        }
>          case ACPI_DMAR_SCOPE_TYPE_HPET:

Please don't lose the blank line.

> --- a/xen/drivers/passthrough/vtd/quirks.c
> +++ b/xen/drivers/passthrough/vtd/quirks.c
> @@ -61,6 +61,14 @@ static bool_t __read_mostly is_snb_gfx;
>  static u8 *__read_mostly igd_reg_va;
>  static spinlock_t igd_lock;
>  
> +static const pci_sbdf_t igd_sbdf = {
> +    .dev = IGD_DEV,
> +};
> +
> +static const pci_sbdf_t ioh_sbdf = {
> +    .dev = IOH_DEV,
> +};

There's only a single use of this, and in an __init function. On one
hand we certainly expect the compiler to not emit to .rodata here
in the first place. But then - can we rely on this? If not, this would
want to become __initconst. So on the whole I think I'd prefer if
you used the initializer macro instead, making IGD_DEV and
IOH_DEV both invocations of that macro. That's then also better
in line with uses of the macro elsewhere in this file.

> --- a/xen/include/xen/pci.h
> +++ b/xen/include/xen/pci.h
> @@ -58,6 +58,11 @@ typedef union {
>      };
>  } pci_sbdf_t;
>  
> +#define PCI_SBDF_T(s, b, d, f) \
> +    ((pci_sbdf_t) { .seg = (s), .bus = (b), .dev = (d), .func = (f) })

I'd prefer if the _T suffix could be omitted. Afaics there's no use of the
existing PCI_SBDF() anywhere in the tree, so this should be fine. For
the 2nd macro below I can't easily tell whether the few existing used
have all disappeared by now, but it seems likely.

Also I'm afraid initializers of this kind will break the build with old gcc.

> +#define PCI_SBDF3_T(s, b, e) \
> +    ((pci_sbdf_t) { .seg = (s), .bus = (b), .extfunc = (e) })

Same remark as on the earlier patch regarding extfunc.

On the whole, again seeing the size of this patch, splitting this up would
probably have helped. At least doing reads and writes separately should
have been possible.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 4/5] print: introduce a format specifier for pci_sbdf_t
@ 2019-05-24 10:36     ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-24 10:36 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

>>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> The new format specifier is '%pp', and prints a pci_sbdf_t using the
> seg:bus:dev.func format. Replace all SBDFs printed using
> '%04x:%02x:%02x.%u' to use the new format specifier.

So on the positive side Linux doesn't use 'p' yet, so we're only at risk
of a future conflict. However, having to pass a 64-bit pointer just
to print a 32-bit entity seems rather wasteful to me. Since we can't
use entirely new format specifiers, did you consider (ab)using one
we rarely use, like %o, suffixed similarly like we do for %p? The
extension could be restricted to apply only when neither field width
nor precision nor any flags were specified, i.e. only to plain %o (at
least initially).

We'd then have something along the lines of

#define PRI_sbdf "op"
#define PRI_SBDF(v) ((v).sbdf)

and

    printk("%" PRI_sbdf ": ...\n", PRI_SBDF(pdev->sbdf), ...);

> --- a/xen/common/vsprintf.c
> +++ b/xen/common/vsprintf.c
> @@ -392,6 +392,20 @@ static char *print_vcpu(char *str, char *end, const struct vcpu *v)
>      return number(str + 1, end, v->vcpu_id, 10, -1, -1, 0);
>  }
>  
> +static char *print_pci_addr(char *str, char *end, const pci_sbdf_t *sbdf)
> +{
> +    str = number(str, end, sbdf->seg, 16, 4, -1, ZEROPAD);
> +    if ( str < end )
> +        *str = ':';
> +    str = number(str + 1, end, sbdf->bus, 16, 2, -1, ZEROPAD);
> +    if ( str < end )
> +        *str = ':';
> +    str = number(str + 1, end, sbdf->dev, 16, 2, -1, ZEROPAD);
> +    if ( str < end )
> +        *str = '.';
> +    return number(str + 1, end, sbdf->func, 10, -1, -1, 0);

It shouldn't really matter, but may I suggest to use 8 instead of 10
here?

> @@ -519,6 +533,10 @@ static char *pointer(char *str, char *end, const char **fmt_ptr,
>      case 'v': /* d<domain-id>v<vcpu-id> from a struct vcpu */
>          ++*fmt_ptr;
>          return print_vcpu(str, end, arg);
> +
> +    case 'p': /* PCI SBDF. */
> +        ++*fmt_ptr;
> +        return print_pci_addr(str, end, arg);
>      }

Please insert at the alphabetically correct place.

> --- a/xen/drivers/passthrough/amd/iommu_acpi.c
> +++ b/xen/drivers/passthrough/amd/iommu_acpi.c
> @@ -717,9 +717,8 @@ static u16 __init parse_ivhd_device_special(
>          return 0;
>      }
>  
> -    AMD_IOMMU_DEBUG("IVHD Special: %04x:%02x:%02x.%u variety %#x handle %#x\n",
> -                    seg, PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf),
> -                    special->variety, special->handle);
> +    AMD_IOMMU_DEBUG("IVHD Special: %pp variety %#x handle %#x\n",
> +                    &PCI_SBDF2_T(seg, bdf), special->variety, special->handle);

The inefficiency of the%p-based approach is perhaps best seen with an
example like this: The compiler will have to instantiate an unnamed variable
on the stack to hold the value of the compound literal, just to be able to
take its address.

> @@ -900,14 +891,10 @@ int pci_release_devices(struct domain *d)
>          return ret;
>      }
>      while ( (pdev = pci_get_pdev_by_domain(d, -1, -1, -1)) )
> -    {
> -        bus = pdev->sbdf.bus;
> -        devfn = pdev->sbdf.extfunc;
> -        if ( deassign_device(d, pdev->sbdf.seg, bus, devfn) )
> -            printk("domain %d: deassign device (%04x:%02x:%02x.%u) failed!\n",
> -                   d->domain_id, pdev->sbdf.seg, bus,
> -                   PCI_SLOT(devfn), PCI_FUNC(devfn));
> -    }
> +        if ( deassign_device(d, pdev->sbdf.seg, pdev->sbdf.bus,
> +                             pdev->sbdf.extfunc) )
> +            printk("domain %d: deassign device (%pp) failed!\n",
> +                   d->domain_id, &pdev->sbdf);

Could you switch to %pd here (and elsewhere) at the same time?

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 4/5] print: introduce a format specifier for pci_sbdf_t
@ 2019-05-24 10:36     ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-24 10:36 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

>>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> The new format specifier is '%pp', and prints a pci_sbdf_t using the
> seg:bus:dev.func format. Replace all SBDFs printed using
> '%04x:%02x:%02x.%u' to use the new format specifier.

So on the positive side Linux doesn't use 'p' yet, so we're only at risk
of a future conflict. However, having to pass a 64-bit pointer just
to print a 32-bit entity seems rather wasteful to me. Since we can't
use entirely new format specifiers, did you consider (ab)using one
we rarely use, like %o, suffixed similarly like we do for %p? The
extension could be restricted to apply only when neither field width
nor precision nor any flags were specified, i.e. only to plain %o (at
least initially).

We'd then have something along the lines of

#define PRI_sbdf "op"
#define PRI_SBDF(v) ((v).sbdf)

and

    printk("%" PRI_sbdf ": ...\n", PRI_SBDF(pdev->sbdf), ...);

> --- a/xen/common/vsprintf.c
> +++ b/xen/common/vsprintf.c
> @@ -392,6 +392,20 @@ static char *print_vcpu(char *str, char *end, const struct vcpu *v)
>      return number(str + 1, end, v->vcpu_id, 10, -1, -1, 0);
>  }
>  
> +static char *print_pci_addr(char *str, char *end, const pci_sbdf_t *sbdf)
> +{
> +    str = number(str, end, sbdf->seg, 16, 4, -1, ZEROPAD);
> +    if ( str < end )
> +        *str = ':';
> +    str = number(str + 1, end, sbdf->bus, 16, 2, -1, ZEROPAD);
> +    if ( str < end )
> +        *str = ':';
> +    str = number(str + 1, end, sbdf->dev, 16, 2, -1, ZEROPAD);
> +    if ( str < end )
> +        *str = '.';
> +    return number(str + 1, end, sbdf->func, 10, -1, -1, 0);

It shouldn't really matter, but may I suggest to use 8 instead of 10
here?

> @@ -519,6 +533,10 @@ static char *pointer(char *str, char *end, const char **fmt_ptr,
>      case 'v': /* d<domain-id>v<vcpu-id> from a struct vcpu */
>          ++*fmt_ptr;
>          return print_vcpu(str, end, arg);
> +
> +    case 'p': /* PCI SBDF. */
> +        ++*fmt_ptr;
> +        return print_pci_addr(str, end, arg);
>      }

Please insert at the alphabetically correct place.

> --- a/xen/drivers/passthrough/amd/iommu_acpi.c
> +++ b/xen/drivers/passthrough/amd/iommu_acpi.c
> @@ -717,9 +717,8 @@ static u16 __init parse_ivhd_device_special(
>          return 0;
>      }
>  
> -    AMD_IOMMU_DEBUG("IVHD Special: %04x:%02x:%02x.%u variety %#x handle %#x\n",
> -                    seg, PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf),
> -                    special->variety, special->handle);
> +    AMD_IOMMU_DEBUG("IVHD Special: %pp variety %#x handle %#x\n",
> +                    &PCI_SBDF2_T(seg, bdf), special->variety, special->handle);

The inefficiency of the%p-based approach is perhaps best seen with an
example like this: The compiler will have to instantiate an unnamed variable
on the stack to hold the value of the compound literal, just to be able to
take its address.

> @@ -900,14 +891,10 @@ int pci_release_devices(struct domain *d)
>          return ret;
>      }
>      while ( (pdev = pci_get_pdev_by_domain(d, -1, -1, -1)) )
> -    {
> -        bus = pdev->sbdf.bus;
> -        devfn = pdev->sbdf.extfunc;
> -        if ( deassign_device(d, pdev->sbdf.seg, bus, devfn) )
> -            printk("domain %d: deassign device (%04x:%02x:%02x.%u) failed!\n",
> -                   d->domain_id, pdev->sbdf.seg, bus,
> -                   PCI_SLOT(devfn), PCI_FUNC(devfn));
> -    }
> +        if ( deassign_device(d, pdev->sbdf.seg, pdev->sbdf.bus,
> +                             pdev->sbdf.extfunc) )
> +            printk("domain %d: deassign device (%pp) failed!\n",
> +                   d->domain_id, &pdev->sbdf);

Could you switch to %pd here (and elsewhere) at the same time?

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 5/5] pci: switch PCI capabilities related functions to use pci_sbdf_t
@ 2019-05-24 10:52     ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-24 10:52 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

>>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> --- a/xen/drivers/pci/pci.c
> +++ b/xen/drivers/pci/pci.c
> @@ -8,18 +8,12 @@
>  #include <xen/pci.h>
>  #include <xen/pci_regs.h>
>  
> -int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 cap)
> +int pci_find_cap_offset(pci_sbdf_t sbdf, unsigned int cap)

The secondary type change here and ...

> @@ -45,15 +39,10 @@ int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 cap)
>      return 0;
>  }
>  
> -int pci_find_next_cap(u16 seg, u8 bus, unsigned int devfn, u8 pos, int cap)
> +int pci_find_next_cap(pci_sbdf_t sbdf, unsigned int pos, unsigned int cap)

... the two ones here aren't obviously safe, so should at least be
mentioned in the description. The latter function has no caller at
all, so is fine simply by that face, for the former this could in principle
result in change in behavior due to the compiler no longer truncating
possible out-of-range arguments. All callers look to be fine though.
(I don't view this as a potential issue for the "ext" counterparts, as
there it's only a change from plain int to unsigned int.)

Some of the comments given on earlier patches apply here as well.

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 5/5] pci: switch PCI capabilities related functions to use pci_sbdf_t
@ 2019-05-24 10:52     ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-24 10:52 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

>>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> --- a/xen/drivers/pci/pci.c
> +++ b/xen/drivers/pci/pci.c
> @@ -8,18 +8,12 @@
>  #include <xen/pci.h>
>  #include <xen/pci_regs.h>
>  
> -int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 cap)
> +int pci_find_cap_offset(pci_sbdf_t sbdf, unsigned int cap)

The secondary type change here and ...

> @@ -45,15 +39,10 @@ int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 cap)
>      return 0;
>  }
>  
> -int pci_find_next_cap(u16 seg, u8 bus, unsigned int devfn, u8 pos, int cap)
> +int pci_find_next_cap(pci_sbdf_t sbdf, unsigned int pos, unsigned int cap)

... the two ones here aren't obviously safe, so should at least be
mentioned in the description. The latter function has no caller at
all, so is fine simply by that face, for the former this could in principle
result in change in behavior due to the compiler no longer truncating
possible out-of-range arguments. All callers look to be fine though.
(I don't view this as a potential issue for the "ext" counterparts, as
there it's only a change from plain int to unsigned int.)

Some of the comments given on earlier patches apply here as well.

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 4/5] print: introduce a format specifier for pci_sbdf_t
@ 2019-05-24 10:59       ` Andrew Cooper
  0 siblings, 0 replies; 54+ messages in thread
From: Andrew Cooper @ 2019-05-24 10:59 UTC (permalink / raw)
  To: Jan Beulich, Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Tim Deegan, Ian Jackson, Julien Grall,
	Suravee Suthikulpanit, xen-devel, Brian Woods

On 24/05/2019 11:36, Jan Beulich wrote:
>>>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
>> The new format specifier is '%pp', and prints a pci_sbdf_t using the
>> seg:bus:dev.func format. Replace all SBDFs printed using
>> '%04x:%02x:%02x.%u' to use the new format specifier.
> So on the positive side Linux doesn't use 'p' yet, so we're only at risk
> of a future conflict. However, having to pass a 64-bit pointer just
> to print a 32-bit entity seems rather wasteful to me. Since we can't
> use entirely new format specifiers, did you consider (ab)using one
> we rarely use, like %o, suffixed similarly like we do for %p? The
> extension could be restricted to apply only when neither field width
> nor precision nor any flags were specified, i.e. only to plain %o (at
> least initially).
>
> We'd then have something along the lines of
>
> #define PRI_sbdf "op"
> #define PRI_SBDF(v) ((v).sbdf)
>
> and
>
>     printk("%" PRI_sbdf ": ...\n", PRI_SBDF(pdev->sbdf), ...);

Except the answer will be the same as every time you've asked this in
the past.

No, because -Wformat doesn't tolerate it.

The *only* flexibility we have to play with is suffixes to %p

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 4/5] print: introduce a format specifier for pci_sbdf_t
@ 2019-05-24 10:59       ` Andrew Cooper
  0 siblings, 0 replies; 54+ messages in thread
From: Andrew Cooper @ 2019-05-24 10:59 UTC (permalink / raw)
  To: Jan Beulich, Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Tim Deegan, Ian Jackson, Julien Grall,
	Suravee Suthikulpanit, xen-devel, Brian Woods

On 24/05/2019 11:36, Jan Beulich wrote:
>>>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
>> The new format specifier is '%pp', and prints a pci_sbdf_t using the
>> seg:bus:dev.func format. Replace all SBDFs printed using
>> '%04x:%02x:%02x.%u' to use the new format specifier.
> So on the positive side Linux doesn't use 'p' yet, so we're only at risk
> of a future conflict. However, having to pass a 64-bit pointer just
> to print a 32-bit entity seems rather wasteful to me. Since we can't
> use entirely new format specifiers, did you consider (ab)using one
> we rarely use, like %o, suffixed similarly like we do for %p? The
> extension could be restricted to apply only when neither field width
> nor precision nor any flags were specified, i.e. only to plain %o (at
> least initially).
>
> We'd then have something along the lines of
>
> #define PRI_sbdf "op"
> #define PRI_SBDF(v) ((v).sbdf)
>
> and
>
>     printk("%" PRI_sbdf ": ...\n", PRI_SBDF(pdev->sbdf), ...);

Except the answer will be the same as every time you've asked this in
the past.

No, because -Wformat doesn't tolerate it.

The *only* flexibility we have to play with is suffixes to %p

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 4/5] print: introduce a format specifier for pci_sbdf_t
@ 2019-05-24 11:16         ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-24 11:16 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Tim Deegan, Ian Jackson, Julien Grall,
	Suravee Suthikulpanit, xen-devel, Brian Woods, Roger Pau Monne

>>> On 24.05.19 at 12:59, <andrew.cooper3@citrix.com> wrote:
> On 24/05/2019 11:36, Jan Beulich wrote:
>>>>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
>>> The new format specifier is '%pp', and prints a pci_sbdf_t using the
>>> seg:bus:dev.func format. Replace all SBDFs printed using
>>> '%04x:%02x:%02x.%u' to use the new format specifier.
>> So on the positive side Linux doesn't use 'p' yet, so we're only at risk
>> of a future conflict. However, having to pass a 64-bit pointer just
>> to print a 32-bit entity seems rather wasteful to me. Since we can't
>> use entirely new format specifiers, did you consider (ab)using one
>> we rarely use, like %o, suffixed similarly like we do for %p? The
>> extension could be restricted to apply only when neither field width
>> nor precision nor any flags were specified, i.e. only to plain %o (at
>> least initially).
>>
>> We'd then have something along the lines of
>>
>> #define PRI_sbdf "op"
>> #define PRI_SBDF(v) ((v).sbdf)
>>
>> and
>>
>>     printk("%" PRI_sbdf ": ...\n", PRI_SBDF(pdev->sbdf), ...);
> 
> Except the answer will be the same as every time you've asked this in
> the past.

I don't recall suggesting any use of %o so far. The one thing I
do recall suggesting (and which turned out bad) was using an
l modifier with %pb.

> No, because -Wformat doesn't tolerate it.

How would -Wformat choke here? %o accepts (unsigned) integers,
doesn't it?

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 4/5] print: introduce a format specifier for pci_sbdf_t
@ 2019-05-24 11:16         ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-24 11:16 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Tim Deegan, Ian Jackson, Julien Grall,
	Suravee Suthikulpanit, xen-devel, Brian Woods, Roger Pau Monne

>>> On 24.05.19 at 12:59, <andrew.cooper3@citrix.com> wrote:
> On 24/05/2019 11:36, Jan Beulich wrote:
>>>>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
>>> The new format specifier is '%pp', and prints a pci_sbdf_t using the
>>> seg:bus:dev.func format. Replace all SBDFs printed using
>>> '%04x:%02x:%02x.%u' to use the new format specifier.
>> So on the positive side Linux doesn't use 'p' yet, so we're only at risk
>> of a future conflict. However, having to pass a 64-bit pointer just
>> to print a 32-bit entity seems rather wasteful to me. Since we can't
>> use entirely new format specifiers, did you consider (ab)using one
>> we rarely use, like %o, suffixed similarly like we do for %p? The
>> extension could be restricted to apply only when neither field width
>> nor precision nor any flags were specified, i.e. only to plain %o (at
>> least initially).
>>
>> We'd then have something along the lines of
>>
>> #define PRI_sbdf "op"
>> #define PRI_SBDF(v) ((v).sbdf)
>>
>> and
>>
>>     printk("%" PRI_sbdf ": ...\n", PRI_SBDF(pdev->sbdf), ...);
> 
> Except the answer will be the same as every time you've asked this in
> the past.

I don't recall suggesting any use of %o so far. The one thing I
do recall suggesting (and which turned out bad) was using an
l modifier with %pb.

> No, because -Wformat doesn't tolerate it.

How would -Wformat choke here? %o accepts (unsigned) integers,
doesn't it?

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 4/5] print: introduce a format specifier for pci_sbdf_t
@ 2019-05-27 15:48       ` Roger Pau Monné
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monné @ 2019-05-27 15:48 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

On Fri, May 24, 2019 at 04:36:42AM -0600, Jan Beulich wrote:
> >>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> > The new format specifier is '%pp', and prints a pci_sbdf_t using the
> > seg:bus:dev.func format. Replace all SBDFs printed using
> > '%04x:%02x:%02x.%u' to use the new format specifier.
> 
> So on the positive side Linux doesn't use 'p' yet, so we're only at risk
> of a future conflict. However, having to pass a 64-bit pointer just
> to print a 32-bit entity seems rather wasteful to me.

I think there are two issues here, one that you mention is the waste
of using a 64bit pointer to pass a 32bit value, the other one would
be the unneeded pointer indirection.

I've thought about the same, but then realized that this is used
(always?) to output messages, which is in itself a slow operation, and
the pointer indirection is likely negligible compared to the cost of
the rest of the operation. The usage of 64bit is also wasteful, but
again this shouldn't be a hotpath anyway, and this code replaces the
usage of four parameters to print a SBDF into a single one.

> Since we can't
> use entirely new format specifiers, did you consider (ab)using one
> we rarely use, like %o, suffixed similarly like we do for %p? The
> extension could be restricted to apply only when neither field width
> nor precision nor any flags were specified, i.e. only to plain %o (at
> least initially).
> 
> We'd then have something along the lines of
> 
> #define PRI_sbdf "op"
> #define PRI_SBDF(v) ((v).sbdf)
> 
> and
> 
>     printk("%" PRI_sbdf ": ...\n", PRI_SBDF(pdev->sbdf), ...);

I have to admit this looks more hacky than my current suggestion IMO.
The %p formatter overloading seems more standard and expected rather
than overloading %o.

Plus, one thing I didn't realize, I think Xen could even use %pci to
print and SBDF, which will make it even clearer.

> > --- a/xen/drivers/passthrough/amd/iommu_acpi.c
> > +++ b/xen/drivers/passthrough/amd/iommu_acpi.c
> > @@ -717,9 +717,8 @@ static u16 __init parse_ivhd_device_special(
> >          return 0;
> >      }
> >  
> > -    AMD_IOMMU_DEBUG("IVHD Special: %04x:%02x:%02x.%u variety %#x handle %#x\n",
> > -                    seg, PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf),
> > -                    special->variety, special->handle);
> > +    AMD_IOMMU_DEBUG("IVHD Special: %pp variety %#x handle %#x\n",
> > +                    &PCI_SBDF2_T(seg, bdf), special->variety, special->handle);
> 
> The inefficiency of the%p-based approach is perhaps best seen with an
> example like this: The compiler will have to instantiate an unnamed variable
> on the stack to hold the value of the compound literal, just to be able to
> take its address.

Right, and such iommu debug is enabled or disabled at runtime, so
regardless of whether iommu debug is enabled or not you will end up
with such stack variable pointer.

In this specific example such usage is not that bad because that's a
boot time only message, but I'm sure there are others which are not
boot time only. The vast majority of messages however don't require
the usage of a literal.

Thanks, Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 4/5] print: introduce a format specifier for pci_sbdf_t
@ 2019-05-27 15:48       ` Roger Pau Monné
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monné @ 2019-05-27 15:48 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

On Fri, May 24, 2019 at 04:36:42AM -0600, Jan Beulich wrote:
> >>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> > The new format specifier is '%pp', and prints a pci_sbdf_t using the
> > seg:bus:dev.func format. Replace all SBDFs printed using
> > '%04x:%02x:%02x.%u' to use the new format specifier.
> 
> So on the positive side Linux doesn't use 'p' yet, so we're only at risk
> of a future conflict. However, having to pass a 64-bit pointer just
> to print a 32-bit entity seems rather wasteful to me.

I think there are two issues here, one that you mention is the waste
of using a 64bit pointer to pass a 32bit value, the other one would
be the unneeded pointer indirection.

I've thought about the same, but then realized that this is used
(always?) to output messages, which is in itself a slow operation, and
the pointer indirection is likely negligible compared to the cost of
the rest of the operation. The usage of 64bit is also wasteful, but
again this shouldn't be a hotpath anyway, and this code replaces the
usage of four parameters to print a SBDF into a single one.

> Since we can't
> use entirely new format specifiers, did you consider (ab)using one
> we rarely use, like %o, suffixed similarly like we do for %p? The
> extension could be restricted to apply only when neither field width
> nor precision nor any flags were specified, i.e. only to plain %o (at
> least initially).
> 
> We'd then have something along the lines of
> 
> #define PRI_sbdf "op"
> #define PRI_SBDF(v) ((v).sbdf)
> 
> and
> 
>     printk("%" PRI_sbdf ": ...\n", PRI_SBDF(pdev->sbdf), ...);

I have to admit this looks more hacky than my current suggestion IMO.
The %p formatter overloading seems more standard and expected rather
than overloading %o.

Plus, one thing I didn't realize, I think Xen could even use %pci to
print and SBDF, which will make it even clearer.

> > --- a/xen/drivers/passthrough/amd/iommu_acpi.c
> > +++ b/xen/drivers/passthrough/amd/iommu_acpi.c
> > @@ -717,9 +717,8 @@ static u16 __init parse_ivhd_device_special(
> >          return 0;
> >      }
> >  
> > -    AMD_IOMMU_DEBUG("IVHD Special: %04x:%02x:%02x.%u variety %#x handle %#x\n",
> > -                    seg, PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf),
> > -                    special->variety, special->handle);
> > +    AMD_IOMMU_DEBUG("IVHD Special: %pp variety %#x handle %#x\n",
> > +                    &PCI_SBDF2_T(seg, bdf), special->variety, special->handle);
> 
> The inefficiency of the%p-based approach is perhaps best seen with an
> example like this: The compiler will have to instantiate an unnamed variable
> on the stack to hold the value of the compound literal, just to be able to
> take its address.

Right, and such iommu debug is enabled or disabled at runtime, so
regardless of whether iommu debug is enabled or not you will end up
with such stack variable pointer.

In this specific example such usage is not that bad because that's a
boot time only message, but I'm sure there are others which are not
boot time only. The vast majority of messages however don't require
the usage of a literal.

Thanks, Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 1/5] pci: use pci_sbdf_t in pci_dev
@ 2019-05-27 15:51       ` Roger Pau Monné
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monné @ 2019-05-27 15:51 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

On Thu, May 23, 2019 at 09:29:44AM -0600, Jan Beulich wrote:
> >>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> > --- a/xen/include/xen/pci.h
> > +++ b/xen/include/xen/pci.h
> > @@ -80,9 +80,8 @@ struct pci_dev {
> >      struct arch_msix *msix;
> >  
> >      struct domain *domain;
> > -    const u16 seg;
> > -    const u8 bus;
> > -    const u8 devfn;
> > +
> > +    const pci_sbdf_t sbdf;
> 
> To help the transition, did you consider first making this a union of
> the existing fields and the new one, next replacing used in a per
> component manner (so that individual maintainers would have to
> look at smaller patches each only), and finally dropping the union
> and its old fields?

No, that didn't occur to me and it's indeed likely to make this much
less painful. My plan was to switch this in one go ad done in this
series, but using such union would allow for smaller patches.

Thanks, Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 1/5] pci: use pci_sbdf_t in pci_dev
@ 2019-05-27 15:51       ` Roger Pau Monné
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monné @ 2019-05-27 15:51 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

On Thu, May 23, 2019 at 09:29:44AM -0600, Jan Beulich wrote:
> >>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> > --- a/xen/include/xen/pci.h
> > +++ b/xen/include/xen/pci.h
> > @@ -80,9 +80,8 @@ struct pci_dev {
> >      struct arch_msix *msix;
> >  
> >      struct domain *domain;
> > -    const u16 seg;
> > -    const u8 bus;
> > -    const u8 devfn;
> > +
> > +    const pci_sbdf_t sbdf;
> 
> To help the transition, did you consider first making this a union of
> the existing fields and the new one, next replacing used in a per
> component manner (so that individual maintainers would have to
> look at smaller patches each only), and finally dropping the union
> and its old fields?

No, that didn't occur to me and it's indeed likely to make this much
less painful. My plan was to switch this in one go ad done in this
series, but using such union would allow for smaller patches.

Thanks, Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 4/5] print: introduce a format specifier for pci_sbdf_t
@ 2019-05-27 15:58         ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-27 15:58 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

>>> On 27.05.19 at 17:48, <roger.pau@citrix.com> wrote:
> On Fri, May 24, 2019 at 04:36:42AM -0600, Jan Beulich wrote:
>> Since we can't
>> use entirely new format specifiers, did you consider (ab)using one
>> we rarely use, like %o, suffixed similarly like we do for %p? The
>> extension could be restricted to apply only when neither field width
>> nor precision nor any flags were specified, i.e. only to plain %o (at
>> least initially).
>> 
>> We'd then have something along the lines of
>> 
>> #define PRI_sbdf "op"
>> #define PRI_SBDF(v) ((v).sbdf)
>> 
>> and
>> 
>>     printk("%" PRI_sbdf ": ...\n", PRI_SBDF(pdev->sbdf), ...);
> 
> I have to admit this looks more hacky than my current suggestion IMO.

Hmm, a matter of taste perhaps. I certainly consider constructs
like "&PCI_SBDF2_T(seg, bdf)" ugly/hacky enough. Taking
Andrew's position of wanting function-style macros to behave
function-like, this isn't even legal C then (because you can't
take the address of the result of a function call).

> The %p formatter overloading seems more standard and expected rather
> than overloading %o.

Well, it looked odd (to me at least) for %p in the beginning too, so
perhaps it's just a matter of getting used to it.

> Plus, one thing I didn't realize, I think Xen could even use %pci to
> print and SBDF, which will make it even clearer.

Documentation-wise - nice. But making every involved string literal
one character longer again.

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 4/5] print: introduce a format specifier for pci_sbdf_t
@ 2019-05-27 15:58         ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-27 15:58 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

>>> On 27.05.19 at 17:48, <roger.pau@citrix.com> wrote:
> On Fri, May 24, 2019 at 04:36:42AM -0600, Jan Beulich wrote:
>> Since we can't
>> use entirely new format specifiers, did you consider (ab)using one
>> we rarely use, like %o, suffixed similarly like we do for %p? The
>> extension could be restricted to apply only when neither field width
>> nor precision nor any flags were specified, i.e. only to plain %o (at
>> least initially).
>> 
>> We'd then have something along the lines of
>> 
>> #define PRI_sbdf "op"
>> #define PRI_SBDF(v) ((v).sbdf)
>> 
>> and
>> 
>>     printk("%" PRI_sbdf ": ...\n", PRI_SBDF(pdev->sbdf), ...);
> 
> I have to admit this looks more hacky than my current suggestion IMO.

Hmm, a matter of taste perhaps. I certainly consider constructs
like "&PCI_SBDF2_T(seg, bdf)" ugly/hacky enough. Taking
Andrew's position of wanting function-style macros to behave
function-like, this isn't even legal C then (because you can't
take the address of the result of a function call).

> The %p formatter overloading seems more standard and expected rather
> than overloading %o.

Well, it looked odd (to me at least) for %p in the beginning too, so
perhaps it's just a matter of getting used to it.

> Plus, one thing I didn't realize, I think Xen could even use %pci to
> print and SBDF, which will make it even clearer.

Documentation-wise - nice. But making every involved string literal
one character longer again.

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 2/5] pci: use function generation macros for pci_config_{write, read}<size>
@ 2019-05-27 16:08       ` Roger Pau Monné
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monné @ 2019-05-27 16:08 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: xen-devel, Wei Liu, Jan Beulich

On Fri, May 24, 2019 at 10:29:26AM +0100, Andrew Cooper wrote:
> On 10/05/2019 17:10, Roger Pau Monne wrote:
> > This avoids code duplication between the helpers.
> >
> > No functional change intended.
> >
> > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> 
> -1.  I see this as actively making the code worse, not an improvement.

Thanks for the feedback. I'm not specially thrilled either way (seeing
Jan provided his RB), the main motivation behind the change was to
avoid having to change the list of parameters to a pci_sbdf_t in each
helper, I find this error prone when the code is the same in all 3
different helpers except for the size difference.

Given Andrew's opinion do you still consider this useful Jan?

Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 2/5] pci: use function generation macros for pci_config_{write, read}<size>
@ 2019-05-27 16:08       ` Roger Pau Monné
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monné @ 2019-05-27 16:08 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: xen-devel, Wei Liu, Jan Beulich

On Fri, May 24, 2019 at 10:29:26AM +0100, Andrew Cooper wrote:
> On 10/05/2019 17:10, Roger Pau Monne wrote:
> > This avoids code duplication between the helpers.
> >
> > No functional change intended.
> >
> > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> 
> -1.  I see this as actively making the code worse, not an improvement.

Thanks for the feedback. I'm not specially thrilled either way (seeing
Jan provided his RB), the main motivation behind the change was to
avoid having to change the list of parameters to a pci_sbdf_t in each
helper, I find this error prone when the code is the same in all 3
different helpers except for the size difference.

Given Andrew's opinion do you still consider this useful Jan?

Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 3/5] pci: switch pci_conf_{read/write} to use pci_sbdf_t
@ 2019-05-27 16:44       ` Roger Pau Monné
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monné @ 2019-05-27 16:44 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

On Fri, May 24, 2019 at 04:01:23AM -0600, Jan Beulich wrote:
> >>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> > --- a/xen/arch/x86/cpu/amd.c
> > +++ b/xen/arch/x86/cpu/amd.c
> > @@ -855,20 +859,22 @@ static void _ns16550_resume(struct serial_port *port)
> >  {
> >  #ifdef CONFIG_HAS_PCI
> >      struct ns16550 *uart = port->uart;
> > +    const pci_sbdf_t sbdf = {
> > +        .bus = uart->ps_bdf[0],
> > +        .dev = uart->ps_bdf[1],
> > +        .func = uart->ps_bdf[2],
> > +    };
> 
> In cases like this one, is there any particular reason you don't use the
> macro you introduce?

At first I preferred this explicit field based initialization because
it makes it easier to read IMO, but I will switch to use the macro.

> > --- a/xen/include/xen/pci.h
> > +++ b/xen/include/xen/pci.h
> > @@ -58,6 +58,11 @@ typedef union {
> >      };
> >  } pci_sbdf_t;
> >  
> > +#define PCI_SBDF_T(s, b, d, f) \
> > +    ((pci_sbdf_t) { .seg = (s), .bus = (b), .dev = (d), .func = (f) })
> 
> I'd prefer if the _T suffix could be omitted. Afaics there's no use of the
> existing PCI_SBDF() anywhere in the tree, so this should be fine. For
> the 2nd macro below I can't easily tell whether the few existing used
> have all disappeared by now, but it seems likely.

I can see about dropping the _T suffix, but I think there's likely
some overlap between the introduction of PCI_SBDF_T and the last user
of the current PCI_SBDF helpers, so maybe it's fine to use the _T
suffix at first and have one final patch that removes it?

> Also I'm afraid initializers of this kind will break the build with old gcc.

I thought we dropped support for such old versions of gcc, is that not
the case?

If not this is all a no-go.

Thanks, Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 3/5] pci: switch pci_conf_{read/write} to use pci_sbdf_t
@ 2019-05-27 16:44       ` Roger Pau Monné
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monné @ 2019-05-27 16:44 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

On Fri, May 24, 2019 at 04:01:23AM -0600, Jan Beulich wrote:
> >>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> > --- a/xen/arch/x86/cpu/amd.c
> > +++ b/xen/arch/x86/cpu/amd.c
> > @@ -855,20 +859,22 @@ static void _ns16550_resume(struct serial_port *port)
> >  {
> >  #ifdef CONFIG_HAS_PCI
> >      struct ns16550 *uart = port->uart;
> > +    const pci_sbdf_t sbdf = {
> > +        .bus = uart->ps_bdf[0],
> > +        .dev = uart->ps_bdf[1],
> > +        .func = uart->ps_bdf[2],
> > +    };
> 
> In cases like this one, is there any particular reason you don't use the
> macro you introduce?

At first I preferred this explicit field based initialization because
it makes it easier to read IMO, but I will switch to use the macro.

> > --- a/xen/include/xen/pci.h
> > +++ b/xen/include/xen/pci.h
> > @@ -58,6 +58,11 @@ typedef union {
> >      };
> >  } pci_sbdf_t;
> >  
> > +#define PCI_SBDF_T(s, b, d, f) \
> > +    ((pci_sbdf_t) { .seg = (s), .bus = (b), .dev = (d), .func = (f) })
> 
> I'd prefer if the _T suffix could be omitted. Afaics there's no use of the
> existing PCI_SBDF() anywhere in the tree, so this should be fine. For
> the 2nd macro below I can't easily tell whether the few existing used
> have all disappeared by now, but it seems likely.

I can see about dropping the _T suffix, but I think there's likely
some overlap between the introduction of PCI_SBDF_T and the last user
of the current PCI_SBDF helpers, so maybe it's fine to use the _T
suffix at first and have one final patch that removes it?

> Also I'm afraid initializers of this kind will break the build with old gcc.

I thought we dropped support for such old versions of gcc, is that not
the case?

If not this is all a no-go.

Thanks, Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 3/5] pci: switch pci_conf_{read/write} to use pci_sbdf_t
@ 2019-05-28  8:51         ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-28  8:51 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

>>> On 27.05.19 at 18:44, <roger.pau@citrix.com> wrote:
> On Fri, May 24, 2019 at 04:01:23AM -0600, Jan Beulich wrote:
>> >>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
>> > --- a/xen/include/xen/pci.h
>> > +++ b/xen/include/xen/pci.h
>> > @@ -58,6 +58,11 @@ typedef union {
>> >      };
>> >  } pci_sbdf_t;
>> >  
>> > +#define PCI_SBDF_T(s, b, d, f) \
>> > +    ((pci_sbdf_t) { .seg = (s), .bus = (b), .dev = (d), .func = (f) })
>> 
>> I'd prefer if the _T suffix could be omitted. Afaics there's no use of the
>> existing PCI_SBDF() anywhere in the tree, so this should be fine. For
>> the 2nd macro below I can't easily tell whether the few existing used
>> have all disappeared by now, but it seems likely.
> 
> I can see about dropping the _T suffix, but I think there's likely
> some overlap between the introduction of PCI_SBDF_T and the last user
> of the current PCI_SBDF helpers, so maybe it's fine to use the _T
> suffix at first and have one final patch that removes it?

That would be an option if it can't be done in one go, sure.

>> Also I'm afraid initializers of this kind will break the build with old gcc.
> 
> I thought we dropped support for such old versions of gcc, is that not
> the case?

No yet, as per ./README.

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 3/5] pci: switch pci_conf_{read/write} to use pci_sbdf_t
@ 2019-05-28  8:51         ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-28  8:51 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

>>> On 27.05.19 at 18:44, <roger.pau@citrix.com> wrote:
> On Fri, May 24, 2019 at 04:01:23AM -0600, Jan Beulich wrote:
>> >>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
>> > --- a/xen/include/xen/pci.h
>> > +++ b/xen/include/xen/pci.h
>> > @@ -58,6 +58,11 @@ typedef union {
>> >      };
>> >  } pci_sbdf_t;
>> >  
>> > +#define PCI_SBDF_T(s, b, d, f) \
>> > +    ((pci_sbdf_t) { .seg = (s), .bus = (b), .dev = (d), .func = (f) })
>> 
>> I'd prefer if the _T suffix could be omitted. Afaics there's no use of the
>> existing PCI_SBDF() anywhere in the tree, so this should be fine. For
>> the 2nd macro below I can't easily tell whether the few existing used
>> have all disappeared by now, but it seems likely.
> 
> I can see about dropping the _T suffix, but I think there's likely
> some overlap between the introduction of PCI_SBDF_T and the last user
> of the current PCI_SBDF helpers, so maybe it's fine to use the _T
> suffix at first and have one final patch that removes it?

That would be an option if it can't be done in one go, sure.

>> Also I'm afraid initializers of this kind will break the build with old gcc.
> 
> I thought we dropped support for such old versions of gcc, is that not
> the case?

No yet, as per ./README.

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 2/5] pci: use function generation macros for pci_config_{write, read}<size>
@ 2019-05-28  8:54         ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-28  8:54 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: Andrew Cooper, Wei Liu, xen-devel

>>> On 27.05.19 at 18:08, <roger.pau@citrix.com> wrote:
> On Fri, May 24, 2019 at 10:29:26AM +0100, Andrew Cooper wrote:
>> On 10/05/2019 17:10, Roger Pau Monne wrote:
>> > This avoids code duplication between the helpers.
>> >
>> > No functional change intended.
>> >
>> > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>> 
>> -1.  I see this as actively making the code worse, not an improvement.
> 
> Thanks for the feedback. I'm not specially thrilled either way (seeing
> Jan provided his RB), the main motivation behind the change was to
> avoid having to change the list of parameters to a pci_sbdf_t in each
> helper, I find this error prone when the code is the same in all 3
> different helpers except for the size difference.
> 
> Given Andrew's opinion do you still consider this useful Jan?

Well, let me put it that way: I'm fine with the change, but I'm also
fine with the code staying as is, seeing Andrew's objection.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 2/5] pci: use function generation macros for pci_config_{write, read}<size>
@ 2019-05-28  8:54         ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-28  8:54 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: Andrew Cooper, Wei Liu, xen-devel

>>> On 27.05.19 at 18:08, <roger.pau@citrix.com> wrote:
> On Fri, May 24, 2019 at 10:29:26AM +0100, Andrew Cooper wrote:
>> On 10/05/2019 17:10, Roger Pau Monne wrote:
>> > This avoids code duplication between the helpers.
>> >
>> > No functional change intended.
>> >
>> > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
>> 
>> -1.  I see this as actively making the code worse, not an improvement.
> 
> Thanks for the feedback. I'm not specially thrilled either way (seeing
> Jan provided his RB), the main motivation behind the change was to
> avoid having to change the list of parameters to a pci_sbdf_t in each
> helper, I find this error prone when the code is the same in all 3
> different helpers except for the size difference.
> 
> Given Andrew's opinion do you still consider this useful Jan?

Well, let me put it that way: I'm fine with the change, but I'm also
fine with the code staying as is, seeing Andrew's objection.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 3/5] pci: switch pci_conf_{read/write} to use pci_sbdf_t
@ 2019-05-28 10:05           ` Roger Pau Monné
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monné @ 2019-05-28 10:05 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

On Tue, May 28, 2019 at 02:51:22AM -0600, Jan Beulich wrote:
> >>> On 27.05.19 at 18:44, <roger.pau@citrix.com> wrote:
> > On Fri, May 24, 2019 at 04:01:23AM -0600, Jan Beulich wrote:
> >> >>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> >> > --- a/xen/include/xen/pci.h
> >> > +++ b/xen/include/xen/pci.h
> >> > @@ -58,6 +58,11 @@ typedef union {
> >> >      };
> >> >  } pci_sbdf_t;
> >> >  
> >> > +#define PCI_SBDF_T(s, b, d, f) \
> >> > +    ((pci_sbdf_t) { .seg = (s), .bus = (b), .dev = (d), .func = (f) })
> >> 
> >> I'd prefer if the _T suffix could be omitted. Afaics there's no use of the
> >> existing PCI_SBDF() anywhere in the tree, so this should be fine. For
> >> the 2nd macro below I can't easily tell whether the few existing used
> >> have all disappeared by now, but it seems likely.
> > 
> > I can see about dropping the _T suffix, but I think there's likely
> > some overlap between the introduction of PCI_SBDF_T and the last user
> > of the current PCI_SBDF helpers, so maybe it's fine to use the _T
> > suffix at first and have one final patch that removes it?
> 
> That would be an option if it can't be done in one go, sure.
> 
> >> Also I'm afraid initializers of this kind will break the build with old gcc.
> > 
> > I thought we dropped support for such old versions of gcc, is that not
> > the case?
> 
> No yet, as per ./README.

Right, so then I guess the only solution would be to use something
like:

#define PCI_SBDF_T(s, b, d, f) \
    ((pci_sbdf_t) { .sbdf = PCI_SBDF(s,b,d,f) })

And similarly for the other initializers. I guess then you would be
fine with using the _T suffix for those helpers and keeping the
current ones as-is?

Thanks, Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 3/5] pci: switch pci_conf_{read/write} to use pci_sbdf_t
@ 2019-05-28 10:05           ` Roger Pau Monné
  0 siblings, 0 replies; 54+ messages in thread
From: Roger Pau Monné @ 2019-05-28 10:05 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

On Tue, May 28, 2019 at 02:51:22AM -0600, Jan Beulich wrote:
> >>> On 27.05.19 at 18:44, <roger.pau@citrix.com> wrote:
> > On Fri, May 24, 2019 at 04:01:23AM -0600, Jan Beulich wrote:
> >> >>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
> >> > --- a/xen/include/xen/pci.h
> >> > +++ b/xen/include/xen/pci.h
> >> > @@ -58,6 +58,11 @@ typedef union {
> >> >      };
> >> >  } pci_sbdf_t;
> >> >  
> >> > +#define PCI_SBDF_T(s, b, d, f) \
> >> > +    ((pci_sbdf_t) { .seg = (s), .bus = (b), .dev = (d), .func = (f) })
> >> 
> >> I'd prefer if the _T suffix could be omitted. Afaics there's no use of the
> >> existing PCI_SBDF() anywhere in the tree, so this should be fine. For
> >> the 2nd macro below I can't easily tell whether the few existing used
> >> have all disappeared by now, but it seems likely.
> > 
> > I can see about dropping the _T suffix, but I think there's likely
> > some overlap between the introduction of PCI_SBDF_T and the last user
> > of the current PCI_SBDF helpers, so maybe it's fine to use the _T
> > suffix at first and have one final patch that removes it?
> 
> That would be an option if it can't be done in one go, sure.
> 
> >> Also I'm afraid initializers of this kind will break the build with old gcc.
> > 
> > I thought we dropped support for such old versions of gcc, is that not
> > the case?
> 
> No yet, as per ./README.

Right, so then I guess the only solution would be to use something
like:

#define PCI_SBDF_T(s, b, d, f) \
    ((pci_sbdf_t) { .sbdf = PCI_SBDF(s,b,d,f) })

And similarly for the other initializers. I guess then you would be
fine with using the _T suffix for those helpers and keeping the
current ones as-is?

Thanks, Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 3/5] pci: switch pci_conf_{read/write} to use pci_sbdf_t
@ 2019-05-28 10:38             ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-28 10:38 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

>>> On 28.05.19 at 12:05, <roger.pau@citrix.com> wrote:
> On Tue, May 28, 2019 at 02:51:22AM -0600, Jan Beulich wrote:
>> >>> On 27.05.19 at 18:44, <roger.pau@citrix.com> wrote:
>> > On Fri, May 24, 2019 at 04:01:23AM -0600, Jan Beulich wrote:
>> >> >>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
>> >> > --- a/xen/include/xen/pci.h
>> >> > +++ b/xen/include/xen/pci.h
>> >> > @@ -58,6 +58,11 @@ typedef union {
>> >> >      };
>> >> >  } pci_sbdf_t;
>> >> >  
>> >> > +#define PCI_SBDF_T(s, b, d, f) \
>> >> > +    ((pci_sbdf_t) { .seg = (s), .bus = (b), .dev = (d), .func = (f) })
>> >> 
>> >> I'd prefer if the _T suffix could be omitted. Afaics there's no use of the
>> >> existing PCI_SBDF() anywhere in the tree, so this should be fine. For
>> >> the 2nd macro below I can't easily tell whether the few existing used
>> >> have all disappeared by now, but it seems likely.
>> > 
>> > I can see about dropping the _T suffix, but I think there's likely
>> > some overlap between the introduction of PCI_SBDF_T and the last user
>> > of the current PCI_SBDF helpers, so maybe it's fine to use the _T
>> > suffix at first and have one final patch that removes it?
>> 
>> That would be an option if it can't be done in one go, sure.
>> 
>> >> Also I'm afraid initializers of this kind will break the build with old 
> gcc.
>> > 
>> > I thought we dropped support for such old versions of gcc, is that not
>> > the case?
>> 
>> No yet, as per ./README.
> 
> Right, so then I guess the only solution would be to use something
> like:
> 
> #define PCI_SBDF_T(s, b, d, f) \
>     ((pci_sbdf_t) { .sbdf = PCI_SBDF(s,b,d,f) })

I think so, yes.

> And similarly for the other initializers. I guess then you would be
> fine with using the _T suffix for those helpers and keeping the
> current ones as-is?

Not really, no - I would hope for this to be the only use of
PCI_SBDF(), and hence I'd still like the _T to be dropped and the
current macro to be expanded explicitly.

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Xen-devel] [PATCH 3/5] pci: switch pci_conf_{read/write} to use pci_sbdf_t
@ 2019-05-28 10:38             ` Jan Beulich
  0 siblings, 0 replies; 54+ messages in thread
From: Jan Beulich @ 2019-05-28 10:38 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Kevin Tian, Stefano Stabellini, Wei Liu, Konrad Rzeszutek Wilk,
	George Dunlap, Andrew Cooper, Ian Jackson, Tim Deegan,
	Julien Grall, Suravee Suthikulpanit, xen-devel, Brian Woods

>>> On 28.05.19 at 12:05, <roger.pau@citrix.com> wrote:
> On Tue, May 28, 2019 at 02:51:22AM -0600, Jan Beulich wrote:
>> >>> On 27.05.19 at 18:44, <roger.pau@citrix.com> wrote:
>> > On Fri, May 24, 2019 at 04:01:23AM -0600, Jan Beulich wrote:
>> >> >>> On 10.05.19 at 18:10, <roger.pau@citrix.com> wrote:
>> >> > --- a/xen/include/xen/pci.h
>> >> > +++ b/xen/include/xen/pci.h
>> >> > @@ -58,6 +58,11 @@ typedef union {
>> >> >      };
>> >> >  } pci_sbdf_t;
>> >> >  
>> >> > +#define PCI_SBDF_T(s, b, d, f) \
>> >> > +    ((pci_sbdf_t) { .seg = (s), .bus = (b), .dev = (d), .func = (f) })
>> >> 
>> >> I'd prefer if the _T suffix could be omitted. Afaics there's no use of the
>> >> existing PCI_SBDF() anywhere in the tree, so this should be fine. For
>> >> the 2nd macro below I can't easily tell whether the few existing used
>> >> have all disappeared by now, but it seems likely.
>> > 
>> > I can see about dropping the _T suffix, but I think there's likely
>> > some overlap between the introduction of PCI_SBDF_T and the last user
>> > of the current PCI_SBDF helpers, so maybe it's fine to use the _T
>> > suffix at first and have one final patch that removes it?
>> 
>> That would be an option if it can't be done in one go, sure.
>> 
>> >> Also I'm afraid initializers of this kind will break the build with old 
> gcc.
>> > 
>> > I thought we dropped support for such old versions of gcc, is that not
>> > the case?
>> 
>> No yet, as per ./README.
> 
> Right, so then I guess the only solution would be to use something
> like:
> 
> #define PCI_SBDF_T(s, b, d, f) \
>     ((pci_sbdf_t) { .sbdf = PCI_SBDF(s,b,d,f) })

I think so, yes.

> And similarly for the other initializers. I guess then you would be
> fine with using the _T suffix for those helpers and keeping the
> current ones as-is?

Not really, no - I would hope for this to be the only use of
PCI_SBDF(), and hence I'd still like the _T to be dropped and the
current macro to be expanded explicitly.

Jan



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2019-05-28 10:38 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-10 16:10 [PATCH 0/5] pci: expand usage of pci_sbdf_t Roger Pau Monne
2019-05-10 16:10 ` [Xen-devel] " Roger Pau Monne
2019-05-10 16:10 ` [PATCH 1/5] pci: use pci_sbdf_t in pci_dev Roger Pau Monne
2019-05-10 16:10   ` [Xen-devel] " Roger Pau Monne
2019-05-10 16:16   ` Andrew Cooper
2019-05-10 16:16     ` [Xen-devel] " Andrew Cooper
2019-05-13  6:25     ` Jan Beulich
2019-05-13  6:25       ` [Xen-devel] " Jan Beulich
2019-05-13  7:53       ` Roger Pau Monné
2019-05-13  7:53         ` [Xen-devel] " Roger Pau Monné
2019-05-23 15:29   ` Jan Beulich
2019-05-23 15:29     ` [Xen-devel] " Jan Beulich
2019-05-27 15:51     ` Roger Pau Monné
2019-05-27 15:51       ` [Xen-devel] " Roger Pau Monné
2019-05-10 16:10 ` [PATCH 2/5] pci: use function generation macros for pci_config_{write, read}<size> Roger Pau Monne
2019-05-10 16:10   ` [Xen-devel] " Roger Pau Monne
2019-05-24  9:10   ` Jan Beulich
2019-05-24  9:10     ` [Xen-devel] " Jan Beulich
2019-05-24  9:29   ` Andrew Cooper
2019-05-24  9:29     ` [Xen-devel] " Andrew Cooper
2019-05-27 16:08     ` Roger Pau Monné
2019-05-27 16:08       ` [Xen-devel] " Roger Pau Monné
2019-05-28  8:54       ` Jan Beulich
2019-05-28  8:54         ` [Xen-devel] " Jan Beulich
2019-05-10 16:10 ` [PATCH 3/5] pci: switch pci_conf_{read/write} to use pci_sbdf_t Roger Pau Monne
2019-05-10 16:10   ` [Xen-devel] " Roger Pau Monne
2019-05-24  9:40   ` Andrew Cooper
2019-05-24  9:40     ` [Xen-devel] " Andrew Cooper
2019-05-24 10:01   ` Jan Beulich
2019-05-24 10:01     ` [Xen-devel] " Jan Beulich
2019-05-27 16:44     ` Roger Pau Monné
2019-05-27 16:44       ` [Xen-devel] " Roger Pau Monné
2019-05-28  8:51       ` Jan Beulich
2019-05-28  8:51         ` [Xen-devel] " Jan Beulich
2019-05-28 10:05         ` Roger Pau Monné
2019-05-28 10:05           ` [Xen-devel] " Roger Pau Monné
2019-05-28 10:38           ` Jan Beulich
2019-05-28 10:38             ` [Xen-devel] " Jan Beulich
2019-05-10 16:10 ` [PATCH 4/5] print: introduce a format specifier for pci_sbdf_t Roger Pau Monne
2019-05-10 16:10   ` [Xen-devel] " Roger Pau Monne
2019-05-24 10:36   ` Jan Beulich
2019-05-24 10:36     ` [Xen-devel] " Jan Beulich
2019-05-24 10:59     ` Andrew Cooper
2019-05-24 10:59       ` [Xen-devel] " Andrew Cooper
2019-05-24 11:16       ` Jan Beulich
2019-05-24 11:16         ` [Xen-devel] " Jan Beulich
2019-05-27 15:48     ` Roger Pau Monné
2019-05-27 15:48       ` [Xen-devel] " Roger Pau Monné
2019-05-27 15:58       ` Jan Beulich
2019-05-27 15:58         ` [Xen-devel] " Jan Beulich
2019-05-10 16:10 ` [PATCH 5/5] pci: switch PCI capabilities related functions to use pci_sbdf_t Roger Pau Monne
2019-05-10 16:10   ` [Xen-devel] " Roger Pau Monne
2019-05-24 10:52   ` Jan Beulich
2019-05-24 10:52     ` [Xen-devel] " Jan Beulich

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.