amd_iommu_free_intremap_table(list_first_entry(&amd_iommu_head,
struct amd_iommu,
list),
- NULL);
+ NULL, 0);
/* free amd iommu list */
list_for_each_entry_safe ( iommu, next, &amd_iommu_head, list )
}
int iterate_ivrs_entries(int (*handler)(const struct amd_iommu *,
- struct ivrs_mappings *))
+ struct ivrs_mappings *, uint16_t bdf))
{
u16 seg = 0;
int rc = 0;
const struct amd_iommu *iommu = map[bdf].iommu;
if ( iommu && map[bdf].dte_requestor_id == bdf )
- rc = handler(iommu, &map[bdf]);
+ rc = handler(iommu, &map[bdf], bdf);
}
} while ( !rc && ++seg );
if ( pdev )
{
- unsigned int req_id = bdf;
-
- do {
- ivrs_mappings[req_id].intremap_table =
- amd_iommu_alloc_intremap_table(
- ivrs_mappings[bdf].iommu,
- &ivrs_mappings[req_id].intremap_inuse);
- if ( !ivrs_mappings[req_id].intremap_table )
- return -ENOMEM;
-
- if ( !pdev->phantom_stride )
- break;
- req_id += pdev->phantom_stride;
- } while ( PCI_SLOT(req_id) == pdev->sbdf.dev );
+ ivrs_mappings[bdf].intremap_table =
+ amd_iommu_alloc_intremap_table(
+ ivrs_mappings[bdf].iommu,
+ &ivrs_mappings[bdf].intremap_inuse);
+ if ( !ivrs_mappings[bdf].intremap_table )
+ return -ENOMEM;
+
+ if ( pdev->phantom_stride )
+ {
+ unsigned int req_id = bdf;
+
+ for ( ; ; )
+ {
+ req_id += pdev->phantom_stride;
+ if ( PCI_SLOT(req_id) != pdev->sbdf.dev )
+ break;
+
+ ivrs_mappings[req_id].intremap_table =
+ ivrs_mappings[bdf].intremap_table;
+ ivrs_mappings[req_id].intremap_inuse =
+ ivrs_mappings[bdf].intremap_inuse;
+ }
+ }
}
amd_iommu_set_intremap_table(
if ( msi_desc->remap_index >= 0 && !msg )
{
- do {
- update_intremap_entry_from_msi_msg(iommu, bdf, nr,
- &msi_desc->remap_index,
- NULL, NULL);
- if ( !pdev || !pdev->phantom_stride )
- break;
- bdf += pdev->phantom_stride;
- } while ( PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
+ update_intremap_entry_from_msi_msg(iommu, bdf, nr,
+ &msi_desc->remap_index,
+ NULL, NULL);
for ( i = 0; i < nr; ++i )
msi_desc[i].remap_index = -1;
- if ( pdev )
- bdf = PCI_BDF2(pdev->bus, pdev->devfn);
}
if ( !msg )
return 0;
- do {
- rc = update_intremap_entry_from_msi_msg(iommu, bdf, nr,
- &msi_desc->remap_index,
- msg, &data);
- if ( rc || !pdev || !pdev->phantom_stride )
- break;
- bdf += pdev->phantom_stride;
- } while ( PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
-
+ rc = update_intremap_entry_from_msi_msg(iommu, bdf, nr,
+ &msi_desc->remap_index,
+ msg, &data);
if ( !rc )
{
for ( i = 1; i < nr; ++i )
}
int amd_iommu_free_intremap_table(
- const struct amd_iommu *iommu, struct ivrs_mappings *ivrs_mapping)
+ const struct amd_iommu *iommu, struct ivrs_mappings *ivrs_mapping,
+ uint16_t bdf)
{
void **tblp;
if ( ivrs_mapping )
{
+ unsigned int i;
+
+ /*
+ * PCI device phantom functions use the same tables as their "base"
+ * function: Look ahead to zap the pointers.
+ */
+ for ( i = 1; PCI_FUNC(bdf + i) && bdf + i < ivrs_bdf_entries; ++i )
+ if ( ivrs_mapping[i].intremap_table ==
+ ivrs_mapping->intremap_table )
+ {
+ ivrs_mapping[i].intremap_table = NULL;
+ ivrs_mapping[i].intremap_inuse = NULL;
+ }
+
XFREE(ivrs_mapping->intremap_inuse);
tblp = &ivrs_mapping->intremap_table;
}
}
static int dump_intremap_mapping(const struct amd_iommu *iommu,
- struct ivrs_mappings *ivrs_mapping)
+ struct ivrs_mappings *ivrs_mapping,
+ uint16_t unused)
{
unsigned long flags;
if ( amd_iommu_perdev_intremap &&
ivrs_mappings[bdf].dte_requestor_id == bdf &&
ivrs_mappings[bdf].intremap_table )
- amd_iommu_free_intremap_table(iommu, &ivrs_mappings[bdf]);
+ amd_iommu_free_intremap_table(iommu, &ivrs_mappings[bdf], bdf);
return 0;
}
struct ivrs_mappings *get_ivrs_mappings(u16 seg);
int iterate_ivrs_mappings(int (*)(u16 seg, struct ivrs_mappings *));
int iterate_ivrs_entries(int (*)(const struct amd_iommu *,
- struct ivrs_mappings *));
+ struct ivrs_mappings *, uint16_t));
/* iommu tables in guest space */
struct mmio_reg {
void *amd_iommu_alloc_intremap_table(
const struct amd_iommu *, unsigned long **);
int amd_iommu_free_intremap_table(
- const struct amd_iommu *, struct ivrs_mappings *);
+ const struct amd_iommu *, struct ivrs_mappings *, uint16_t);
void amd_iommu_ioapic_update_ire(
unsigned int apic, unsigned int reg, unsigned int value);
unsigned int amd_iommu_read_ioapic_from_ire(