From: Bhavna Sarathy <bnagendr@redhat.com> Date: Thu, 22 Oct 2009 20:01:13 -0400 Subject: [xen] iommu: add passthrough and no-intremap parameters Message-id: <20091022200334.3419.27630.sendpatchset@localhost.localdomain> Patchwork-id: 21203 O-Subject: [RHEL5.5 PATCH 4/5] Add "passthrough" and "no-intremap" parameters Bugzilla: 518474 526766 RH-Acked-by: Christopher Lalancette <clalance@redhat.com> RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com> RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com> This patch adds support for the "passthrough" and "no-intremap" parameters. This is a useful feature to have, as it allows for interrupt remapping to be disabled for debugging. Resolves BZ 526766 and 518474 diff --git a/drivers/passthrough/amd/iommu_init.c b/drivers/passthrough/amd/iommu_init.c index 536288c..75b4173 100644 --- a/drivers/passthrough/amd/iommu_init.c +++ b/drivers/passthrough/amd/iommu_init.c @@ -692,6 +692,10 @@ void __init amd_iommu_init_cleanup(void) xfree(ivrs_mappings); ivrs_mappings = NULL; } + + iommu_enabled = 0; + iommu_passthrough = 0; + iommu_intremap = 0; } static int __init init_ivrs_mapping(void) @@ -736,7 +740,6 @@ static int __init amd_iommu_setup_device_table(void) void *intr_tb, *dte; int sys_mgt, dev_ex, lint1_pass, lint0_pass, nmi_pass, ext_int_pass, init_pass; - int iommu_intremap = 1; BUG_ON(ivrs_bdf_entries == 0); @@ -770,8 +773,6 @@ static int __init amd_iommu_setup_device_table(void) amd_iommu_add_dev_table_entry( dte, sys_mgt, dev_ex, lint1_pass, lint0_pass, nmi_pass, ext_int_pass, init_pass); - - iommu_intremap = 1; amd_iommu_set_intremap_table( dte, (u64)virt_to_maddr(intr_tb), iommu_intremap); diff --git a/drivers/passthrough/amd/iommu_intr.c b/drivers/passthrough/amd/iommu_intr.c index 5ff2070..e6d899a 100644 --- a/drivers/passthrough/amd/iommu_intr.c +++ b/drivers/passthrough/amd/iommu_intr.c @@ -170,10 +170,7 @@ int __init amd_iommu_setup_ioapic_remapping(void) delivery_mode = rte.delivery_mode; vector = rte.vector; dest_mode = rte.dest_mode; - if ( dest_mode == 0 ) - dest = rte.dest.physical.physical_dest & 0xf; - else - dest = rte.dest.logical.logical_dest & 0xff; + dest = rte.dest.logical.logical_dest; spin_lock_irqsave(&ivrs_mappings[req_id].intremap_lock, flags); entry = (u32*)get_intremap_entry(req_id, vector, delivery_mode); @@ -207,6 +204,9 @@ void amd_iommu_ioapic_update_ire( *IO_APIC_BASE(apic) = reg; *(IO_APIC_BASE(apic)+4) = value; + if ( !iommu_intremap ) + return; + /* get device id of ioapic devices */ bdf = ioapic_bdf[IO_APIC_ID(apic)]; bus = bdf >> 8; @@ -305,10 +305,18 @@ void amd_iommu_msi_msg_update_ire( struct pci_dev *pdev = msi_desc->dev; struct amd_iommu *iommu = NULL; + if ( !iommu_intremap ) + return; + iommu = find_iommu_for_device(pdev->bus, pdev->devfn); if ( !iommu ) + { + AMD_IOMMU_DEBUG( + "Fail to find iommu for MSI device id = 0x%x\n", + (pdev->bus << 8) | pdev->devfn); return; + } update_intremap_entry_from_msi_msg(iommu, pdev, msg); } diff --git a/drivers/passthrough/amd/pci_amd_iommu.c b/drivers/passthrough/amd/pci_amd_iommu.c index ded3bfe..21c50a9 100644 --- a/drivers/passthrough/amd/pci_amd_iommu.c +++ b/drivers/passthrough/amd/pci_amd_iommu.c @@ -61,12 +61,14 @@ static void amd_iommu_setup_domain_device( { void *dte; unsigned long flags; - int req_id, valid; + int req_id, valid = 1; struct hvm_iommu *hd = domain_hvm_iommu(domain); BUG_ON( !hd->root_table || !hd->paging_mode || !iommu->dev_table.buffer ); - valid = 1; + if ( iommu_passthrough && (domain->domain_id == 0) ) + valid = 0; + /* get device-table entry */ req_id = get_dma_requestor_id(bdf); dte = iommu->dev_table.buffer + (req_id * IOMMU_DEV_TABLE_ENTRY_SIZE); @@ -202,10 +204,14 @@ static int amd_iommu_domain_init(struct domain *domain) if ( domain->domain_id == 0 ) { - unsigned long i; - /* setup 1:1 page table for dom0 */ - for ( i = 0; i < max_page; i++ ) - amd_iommu_map_page(domain, i, i); + unsigned long i; + + if ( !iommu_passthrough ) + { + /* setup 1:1 page table for dom0 */ + for ( i = 0; i < max_page; i++ ) + amd_iommu_map_page(domain, i, i); + } amd_iommu_setup_dom0_devices(domain); } diff --git a/drivers/passthrough/iommu.c b/drivers/passthrough/iommu.c index 8c57637..2d16428 100644 --- a/drivers/passthrough/iommu.c +++ b/drivers/passthrough/iommu.c @@ -38,6 +38,7 @@ int iommu_enabled = 0; int force_iommu = 0; int iommu_passthrough = 0; int iommu_snoop = 0; +int iommu_intremap = 0; int amd_iommu_debug=0; static void __init parse_iommu_param(char *s) @@ -45,6 +46,7 @@ static void __init parse_iommu_param(char *s) char *ss; iommu_enabled = 1; iommu_snoop = 1; + iommu_intremap = 1; amd_iommu_debug = 0; do { @@ -63,6 +65,8 @@ static void __init parse_iommu_param(char *s) iommu_snoop = 1; else if ( !strcmp(s, "no-snoop") ) iommu_snoop = 0; + else if ( !strcmp(s, "no-intremap") ) + iommu_intremap = 0; else if ( !strcmp(s, "amd-iommu-debug") ) amd_iommu_debug = 1; diff --git a/include/xen/iommu.h b/include/xen/iommu.h index fac578c..6ab27e0 100644 --- a/include/xen/iommu.h +++ b/include/xen/iommu.h @@ -32,6 +32,7 @@ extern int iommu_pv_enabled; extern int force_iommu; extern int iommu_passthrough; extern int iommu_snoop; +extern int iommu_intremap; #define domain_hvm_iommu(d) (&d->arch.hvm_domain.hvm_iommu)