aboutsummaryrefslogtreecommitdiffstats
path: root/xen/drivers/passthrough
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2013-03-25 14:28:31 +0100
committerJan Beulich <jbeulich@suse.com>2013-03-25 14:28:31 +0100
commitfae0372140befb88d890a30704a8ec058c902af8 (patch)
treeeae6ad998551ddd302104d765a75375b7319747f /xen/drivers/passthrough
parent85bae8b3406b234f3074617771072623525a3576 (diff)
downloadxen-fae0372140befb88d890a30704a8ec058c902af8.tar.gz
xen-fae0372140befb88d890a30704a8ec058c902af8.tar.bz2
xen-fae0372140befb88d890a30704a8ec058c902af8.zip
IOMMU: properly check whether interrupt remapping is enabled
... rather than the IOMMU as a whole. That in turn required to make sure iommu_intremap gets properly cleared when the respective initialization fails (or isn't being done at all). Along with making sure interrupt remapping doesn't get inconsistently enabled on some IOMMUs and not on others in the VT-d code, this in turn allowed quite a bit of cleanup on the VT-d side (if desired, that cleanup could of course be broken out into a separate patch). Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: "Zhang, Xiantao" <xiantao.zhang@intel.com>
Diffstat (limited to 'xen/drivers/passthrough')
-rw-r--r--xen/drivers/passthrough/iommu.c5
-rw-r--r--xen/drivers/passthrough/vtd/intremap.c35
-rw-r--r--xen/drivers/passthrough/vtd/iommu.c3
3 files changed, 13 insertions, 30 deletions
diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index c1d3c122e3..2db2e17494 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -470,6 +470,8 @@ int __init iommu_setup(void)
rc = iommu_hardware_setup();
iommu_enabled = (rc == 0);
}
+ if ( !iommu_enabled )
+ iommu_intremap = 0;
if ( (force_iommu && !iommu_enabled) ||
(force_intremap && !iommu_intremap) )
@@ -484,9 +486,12 @@ int __init iommu_setup(void)
}
printk("I/O virtualisation %sabled\n", iommu_enabled ? "en" : "dis");
if ( iommu_enabled )
+ {
printk(" - Dom0 mode: %s\n",
iommu_passthrough ? "Passthrough" :
iommu_dom0_strict ? "Strict" : "Relaxed");
+ printk("Interrupt remapping %sabled\n", iommu_intremap ? "en" : "dis");
+ }
return rc;
}
diff --git a/xen/drivers/passthrough/vtd/intremap.c b/xen/drivers/passthrough/vtd/intremap.c
index a9c3bc4c10..0dc1788b24 100644
--- a/xen/drivers/passthrough/vtd/intremap.c
+++ b/xen/drivers/passthrough/vtd/intremap.c
@@ -373,7 +373,7 @@ unsigned int io_apic_read_remap_rte(
struct iommu *iommu = ioapic_to_iommu(IO_APIC_ID(apic));
struct ir_ctrl *ir_ctrl = iommu_ir_ctrl(iommu);
- if ( !ir_ctrl || !ir_ctrl->iremap_maddr || !ir_ctrl->iremap_num ||
+ if ( !ir_ctrl->iremap_num ||
( (index = apic_pin_2_ir_idx[apic][ioapic_pin]) < 0 ) )
return __io_apic_read(apic, reg);
@@ -396,15 +396,8 @@ void io_apic_write_remap_rte(
struct IO_APIC_route_remap_entry *remap_rte;
unsigned int rte_upper = (reg & 1) ? 1 : 0;
struct iommu *iommu = ioapic_to_iommu(IO_APIC_ID(apic));
- struct ir_ctrl *ir_ctrl = iommu_ir_ctrl(iommu);
int saved_mask;
- if ( !ir_ctrl || !ir_ctrl->iremap_maddr )
- {
- __io_apic_write(apic, reg, value);
- return;
- }
-
old_rte = __ioapic_read_entry(apic, ioapic_pin, 1);
remap_rte = (struct IO_APIC_route_remap_entry *) &old_rte;
@@ -653,20 +646,11 @@ void msi_msg_read_remap_rte(
{
struct pci_dev *pdev = msi_desc->dev;
struct acpi_drhd_unit *drhd = NULL;
- struct iommu *iommu = NULL;
- struct ir_ctrl *ir_ctrl;
drhd = pdev ? acpi_find_matched_drhd_unit(pdev)
: hpet_to_drhd(msi_desc->hpet_id);
- if ( !drhd )
- return;
- iommu = drhd->iommu;
-
- ir_ctrl = iommu_ir_ctrl(iommu);
- if ( !ir_ctrl || !ir_ctrl->iremap_maddr )
- return;
-
- remap_entry_to_msi_msg(iommu, msg);
+ if ( drhd )
+ remap_entry_to_msi_msg(drhd->iommu, msg);
}
void msi_msg_write_remap_rte(
@@ -674,20 +658,11 @@ void msi_msg_write_remap_rte(
{
struct pci_dev *pdev = msi_desc->dev;
struct acpi_drhd_unit *drhd = NULL;
- struct iommu *iommu = NULL;
- struct ir_ctrl *ir_ctrl;
drhd = pdev ? acpi_find_matched_drhd_unit(pdev)
: hpet_to_drhd(msi_desc->hpet_id);
- if ( !drhd )
- return;
- iommu = drhd->iommu;
-
- ir_ctrl = iommu_ir_ctrl(iommu);
- if ( !ir_ctrl || !ir_ctrl->iremap_maddr )
- return;
-
- msi_msg_to_remap_entry(iommu, pdev, msi_desc, msg);
+ if ( drhd )
+ msi_msg_to_remap_entry(drhd->iommu, pdev, msi_desc, msg);
}
int __init intel_setup_hpet_msi(struct msi_desc *msi_desc)
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index 132f04a083..ef8bc95b72 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -2065,6 +2065,9 @@ static int init_vtd_hw(void)
break;
}
}
+ if ( !iommu_intremap )
+ for_each_drhd_unit ( drhd )
+ disable_intremap(drhd->iommu);
}
/*