@@ -77,8 +77,14 @@ struct amd_iommu {
struct list_head list;
spinlock_t lock; /* protect iommu */
- u16 seg;
- u16 bdf;
+ union {
+ struct {
+ uint16_t bdf;
+ uint16_t seg;
+ };
+ pci_sbdf_t sbdf;
+ };
+
struct msi_desc msi;
u16 cap_offset;
@@ -85,7 +85,7 @@ static void flush_command_buffer(struct amd_iommu *iommu,
threshold |= threshold << 1;
printk(XENLOG_WARNING
"AMD IOMMU %pp: %scompletion wait taking too long\n",
- &PCI_SBDF(iommu->seg, iommu->bdf),
+ &iommu->sbdf,
timeout_base ? "iotlb " : "");
timeout = 0;
}
@@ -95,7 +95,7 @@ static void flush_command_buffer(struct amd_iommu *iommu,
if ( !timeout )
printk(XENLOG_WARNING
"AMD IOMMU %pp: %scompletion wait took %lums\n",
- &PCI_SBDF(iommu->seg, iommu->bdf),
+ &iommu->sbdf,
timeout_base ? "iotlb " : "",
(NOW() - start) / 10000000);
}
@@ -231,7 +231,7 @@ 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 %pp read-only (%d)\n",
- &PCI_SBDF(iommu->seg, iommu->bdf), rt);
+ &iommu->sbdf, rt);
list_add_tail(&iommu->list, &amd_iommu_head);
rt = 0;
@@ -409,9 +409,7 @@ static void iommu_reset_log(struct amd_iommu *iommu,
static void amd_iommu_msi_enable(struct amd_iommu *iommu, int flag)
{
- pci_sbdf_t sbdf = { .seg = iommu->seg, .bdf = iommu->bdf };
-
- __msi_set_enable(sbdf, iommu->msi.msi_attrib.pos, flag);
+ __msi_set_enable(iommu->sbdf, iommu->msi.msi_attrib.pos, flag);
}
static void cf_check iommu_msi_unmask(struct irq_desc *desc)
@@ -752,12 +750,11 @@ static bool __init set_iommu_interrupt_handler(struct amd_iommu *iommu)
}
pcidevs_lock();
- iommu->msi.dev = pci_get_pdev(NULL, PCI_SBDF(iommu->seg, iommu->bdf));
+ iommu->msi.dev = pci_get_pdev(NULL, iommu->sbdf);
pcidevs_unlock();
if ( !iommu->msi.dev )
{
- AMD_IOMMU_WARN("no pdev for %pp\n",
- &PCI_SBDF(iommu->seg, iommu->bdf));
+ AMD_IOMMU_WARN("no pdev for %pp\n", &iommu->sbdf);
return 0;
}
@@ -779,7 +776,7 @@ static bool __init set_iommu_interrupt_handler(struct amd_iommu *iommu)
hw_irq_controller *handler;
u16 control;
- control = pci_conf_read16(PCI_SBDF(iommu->seg, iommu->bdf),
+ control = pci_conf_read16(iommu->sbdf,
iommu->msi.msi_attrib.pos + PCI_MSI_FLAGS);
iommu->msi.msi.nvec = 1;
@@ -843,22 +840,22 @@ static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
(boot_cpu_data.x86_model > 0x1f) )
return;
- pci_conf_write32(PCI_SBDF(iommu->seg, iommu->bdf), 0xf0, 0x90);
- value = pci_conf_read32(PCI_SBDF(iommu->seg, iommu->bdf), 0xf4);
+ pci_conf_write32(iommu->sbdf, 0xf0, 0x90);
+ value = pci_conf_read32(iommu->sbdf, 0xf4);
if ( value & (1 << 2) )
return;
/* Select NB indirect register 0x90 and enable writing */
- pci_conf_write32(PCI_SBDF(iommu->seg, iommu->bdf), 0xf0, 0x90 | (1 << 8));
+ pci_conf_write32(iommu->sbdf, 0xf0, 0x90 | (1 << 8));
- pci_conf_write32(PCI_SBDF(iommu->seg, iommu->bdf), 0xf4, value | (1 << 2));
+ pci_conf_write32(iommu->sbdf, 0xf4, value | (1 << 2));
printk(XENLOG_INFO
"AMD-Vi: Applying erratum 746 workaround for IOMMU at %pp\n",
- &PCI_SBDF(iommu->seg, iommu->bdf));
+ &iommu->sbdf);
/* Clear the enable writing bit */
- pci_conf_write32(PCI_SBDF(iommu->seg, iommu->bdf), 0xf0, 0x90);
+ pci_conf_write32(iommu->sbdf, 0xf0, 0x90);
}
static void enable_iommu(struct amd_iommu *iommu)
@@ -730,7 +730,7 @@ int cf_check amd_iommu_get_reserved_device_memory(
* the same alias ID.
*/
if ( bdf != req && ivrs_mappings[req].iommu &&
- func(0, 0, PCI_SBDF(seg, req).sbdf, ctxt) )
+ func(0, 0, sbdf.sbdf, ctxt) )
continue;
if ( global == pending )
Following on from 250d87dc3ff9 ("x86/msi: Change __msi_set_enable() to take pci_sbdf_t"), struct amd_iommu has its seg and bdf fields backwards with relation to pci_sbdf_t. Swap them around, and simplify the expressions regenerating an sbdf_t from seg+bdf. Bloat-o-meter reports: add/remove: 0/0 grow/shrink: 6/11 up/down: 135/-327 (-192) Function old new delta _einittext 22028 22092 +64 amd_iommu_prepare 853 897 +44 _hvm_dpci_msi_eoi 157 168 +11 __mon_lengths 2928 2936 +8 _invalidate_all_devices 133 138 +5 amd_iommu_get_reserved_device_memory 521 524 +3 amd_iommu_domain_destroy 46 43 -3 build_info 752 744 -8 amd_iommu_add_device 856 844 -12 amd_iommu_msi_enable 33 20 -13 update_intremap_entry_from_msi_msg 879 859 -20 amd_iommu_get_supported_ivhd_type 86 54 -32 amd_iommu_detect_one_acpi 918 886 -32 iterate_ivrs_mappings 169 129 -40 flush_command_buffer 460 417 -43 set_iommu_interrupt_handler 421 377 -44 enable_iommu 1745 1665 -80 Resolves: https://gitlab.com/xen-project/xen/-/issues/198 Reported-by: Andrew Cooper <andrew.cooper3@citrix.com> Signed-off-by: Andrii Sultanov <sultanovandriy@gmail.com> --- Changes in V2: * Split single commit into several patches * Added the commit title of the referenced patch * Dropped brackets around &(iommu->sbdf) and &(sbdf) --- xen/drivers/passthrough/amd/iommu.h | 10 ++++++++-- xen/drivers/passthrough/amd/iommu_cmd.c | 4 ++-- xen/drivers/passthrough/amd/iommu_detect.c | 2 +- xen/drivers/passthrough/amd/iommu_init.c | 23 ++++++++++------------ xen/drivers/passthrough/amd/iommu_map.c | 2 +- 5 files changed, 22 insertions(+), 19 deletions(-)