Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 4517

kernel-2.6.18-194.11.1.el5.src.rpm

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)