xen/26532-AMD-IOMMU-phantom-MSI.patch
Charles Arnold 0d71e75f73 - Add upstream patch to fix vfb/vkb initialization in libxl
26369-libxl-devid.patch

- fate##313584: pass bios information to XEN HVM guest
  26554-hvm-firmware-passthrough.patch
  26555-hvm-firmware-passthrough.patch
  26556-hvm-firmware-passthrough.patch

- Upstream patches from Jan
  26516-ACPI-parse-table-retval.patch (Replaces CVE-2013-0153-xsa36.patch)
  26517-AMD-IOMMU-clear-irtes.patch (Replaces CVE-2013-0153-xsa36.patch)
  26518-AMD-IOMMU-disable-if-SATA-combined-mode.patch (Replaces CVE-2013-0153-xsa36.patch)
  26519-AMD-IOMMU-perdev-intremap-default.patch (Replaces CVE-2013-0153-xsa36.patch)
  26526-pvdrv-no-devinit.patch
  26529-gcc48-build-fix.patch
  26531-AMD-IOMMU-IVHD-special-missing.patch (Replaces CVE-2013-0153-xsa36.patch)
  26532-AMD-IOMMU-phantom-MSI.patch
  26536-xenoprof-div-by-0.patch
  26576-x86-APICV-migration.patch
  26577-x86-APICV-x2APIC.patch
  26578-AMD-IOMMU-replace-BUG_ON.patch

- bnc#797014 - no way to control live migrations
  26547-tools-xc_fix_logic_error_in_stdiostream_progress.patch
  26548-tools-xc_handle_tty_output_differently_in_stdiostream_progress.patch
  26549-tools-xc_turn_XCFLAGS_*_into_shifts.patch
  26550-tools-xc_restore_logging_in_xc_save.patch
  26551-tools-xc_log_pid_in_xc_save-xc_restore_output.patch

- PVonHVM: __devinit was removed in linux-3.8

OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=229
2013-02-22 21:42:01 +00:00

138 lines
5.0 KiB
Diff

References: bnc#787169
# HG changeset patch
# User Jan Beulich <jbeulich@suse.com>
# Date 1360831377 -3600
# Node ID 788f4551580d476e13ea907e373e58806a32179e
# Parent e68f14b9e73925e9d404e517ba510f73fe472e4e
AMD IOMMU: handle MSI for phantom functions
With ordinary requests allowed to come from phantom functions, the
remapping tables ought to be set up to also allow for MSI triggers to
come from other than the "real" device too.
It is not clear to me whether the alias-ID handling also needs
adjustment for this to work properly, or whether firmware can be
expected to properly express this through a device alias range
descriptor (or multiple device alias ones).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
--- a/xen/drivers/passthrough/amd/iommu_intr.c
+++ b/xen/drivers/passthrough/amd/iommu_intr.c
@@ -284,33 +284,32 @@ void amd_iommu_ioapic_update_ire(
}
static void update_intremap_entry_from_msi_msg(
- struct amd_iommu *iommu, struct pci_dev *pdev,
- struct msi_desc *msi_desc, struct msi_msg *msg)
+ struct amd_iommu *iommu, u16 bdf,
+ int *remap_index, const struct msi_msg *msg)
{
unsigned long flags;
u32* entry;
- u16 bdf, req_id, alias_id;
+ u16 req_id, alias_id;
u8 delivery_mode, dest, vector, dest_mode;
spinlock_t *lock;
int offset;
- bdf = (pdev->bus << 8) | pdev->devfn;
- req_id = get_dma_requestor_id(pdev->seg, bdf);
- alias_id = get_intremap_requestor_id(pdev->seg, bdf);
+ req_id = get_dma_requestor_id(iommu->seg, bdf);
+ alias_id = get_intremap_requestor_id(iommu->seg, bdf);
if ( msg == NULL )
{
lock = get_intremap_lock(iommu->seg, req_id);
spin_lock_irqsave(lock, flags);
- free_intremap_entry(iommu->seg, req_id, msi_desc->remap_index);
+ free_intremap_entry(iommu->seg, req_id, *remap_index);
spin_unlock_irqrestore(lock, flags);
if ( ( req_id != alias_id ) &&
- get_ivrs_mappings(pdev->seg)[alias_id].intremap_table != NULL )
+ get_ivrs_mappings(iommu->seg)[alias_id].intremap_table != NULL )
{
lock = get_intremap_lock(iommu->seg, alias_id);
spin_lock_irqsave(lock, flags);
- free_intremap_entry(iommu->seg, alias_id, msi_desc->remap_index);
+ free_intremap_entry(iommu->seg, alias_id, *remap_index);
spin_unlock_irqrestore(lock, flags);
}
goto done;
@@ -324,7 +323,10 @@ static void update_intremap_entry_from_m
vector = (msg->data >> MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK;
dest = (msg->address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff;
offset = get_intremap_offset(vector, delivery_mode);
- msi_desc->remap_index = offset;
+ if ( *remap_index < 0)
+ *remap_index = offset;
+ else
+ BUG_ON(*remap_index != offset);
entry = (u32*)get_intremap_entry(iommu->seg, req_id, offset);
update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest);
@@ -339,7 +341,7 @@ static void update_intremap_entry_from_m
lock = get_intremap_lock(iommu->seg, alias_id);
if ( ( req_id != alias_id ) &&
- get_ivrs_mappings(pdev->seg)[alias_id].intremap_table != NULL )
+ get_ivrs_mappings(iommu->seg)[alias_id].intremap_table != NULL )
{
spin_lock_irqsave(lock, flags);
entry = (u32*)get_intremap_entry(iommu->seg, alias_id, offset);
@@ -362,27 +364,44 @@ void amd_iommu_msi_msg_update_ire(
struct msi_desc *msi_desc, struct msi_msg *msg)
{
struct pci_dev *pdev = msi_desc->dev;
+ int bdf = PCI_BDF2(pdev->bus, pdev->devfn);
struct amd_iommu *iommu = NULL;
if ( !iommu_intremap )
return;
- iommu = find_iommu_for_device(pdev->seg, (pdev->bus << 8) | pdev->devfn);
-
+ iommu = find_iommu_for_device(pdev->seg, bdf);
if ( !iommu )
{
- AMD_IOMMU_DEBUG("Fail to find iommu for MSI device id = 0x%x\n",
- (pdev->bus << 8) | pdev->devfn);
+ AMD_IOMMU_DEBUG("Fail to find iommu for MSI device id = 0x%x\n", bdf);
return;
}
if ( msi_desc->remap_index >= 0 )
- update_intremap_entry_from_msi_msg(iommu, pdev, msi_desc, NULL);
+ {
+ do {
+ update_intremap_entry_from_msi_msg(iommu, bdf,
+ &msi_desc->remap_index, NULL);
+ if ( !pdev || !pdev->phantom_stride )
+ break;
+ bdf += pdev->phantom_stride;
+ } while ( PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
+
+ msi_desc->remap_index = -1;
+ if ( pdev )
+ bdf = PCI_BDF2(pdev->bus, pdev->devfn);
+ }
if ( !msg )
return;
- update_intremap_entry_from_msi_msg(iommu, pdev, msi_desc, msg);
+ do {
+ update_intremap_entry_from_msi_msg(iommu, bdf, &msi_desc->remap_index,
+ msg);
+ if ( !pdev || !pdev->phantom_stride )
+ break;
+ bdf += pdev->phantom_stride;
+ } while ( PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
}
void amd_iommu_read_msi_from_ire(