WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] AMD IOMMU: Miscellaneous fixes and cleanu

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] AMD IOMMU: Miscellaneous fixes and cleanups.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 01 Aug 2008 02:20:29 -0700
Delivery-date: Fri, 01 Aug 2008 02:21:56 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1217507849 -3600
# Node ID 09ee974e722f50be8bd3eec271774647966d180c
# Parent  f1486d8c06fbf56613b9898a31956ed02e12d4ac
AMD IOMMU: Miscellaneous fixes and cleanups.

Signed-off-by: Wei Wang <wei.wang2@xxxxxxx>
---
 xen/drivers/passthrough/amd/iommu_map.c       |    2 
 xen/drivers/passthrough/amd/pci_amd_iommu.c   |  289 +++-----------------------
 xen/include/asm-x86/amd-iommu.h               |    8 
 xen/include/asm-x86/hvm/svm/amd-iommu-proto.h |   27 --
 4 files changed, 49 insertions(+), 277 deletions(-)

diff -r f1486d8c06fb -r 09ee974e722f xen/drivers/passthrough/amd/iommu_map.c
--- a/xen/drivers/passthrough/amd/iommu_map.c   Thu Jul 31 13:36:45 2008 +0100
+++ b/xen/drivers/passthrough/amd/iommu_map.c   Thu Jul 31 13:37:29 2008 +0100
@@ -23,7 +23,7 @@
 #include <asm/amd-iommu.h>
 #include <asm/hvm/svm/amd-iommu-proto.h>
 
-extern long amd_iommu_poll_comp_wait;
+long amd_iommu_poll_comp_wait = COMPLETION_WAIT_DEFAULT_POLLING_COUNT;
 
 static int queue_iommu_command(struct amd_iommu *iommu, u32 cmd[])
 {
diff -r f1486d8c06fb -r 09ee974e722f xen/drivers/passthrough/amd/pci_amd_iommu.c
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c       Thu Jul 31 13:36:45 
2008 +0100
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c       Thu Jul 31 13:37:29 
2008 +0100
@@ -23,17 +23,10 @@
 #include <xen/pci_regs.h>
 #include <asm/amd-iommu.h>
 #include <asm/hvm/svm/amd-iommu-proto.h>
-#include <asm/hvm/svm/amd-iommu-acpi.h>
 #include <asm/mm.h>
 
-struct list_head amd_iommu_head;
-long amd_iommu_poll_comp_wait = COMPLETION_WAIT_DEFAULT_POLLING_COUNT;
-static long amd_iommu_cmd_buffer_entries = IOMMU_CMD_BUFFER_DEFAULT_ENTRIES;
-static long amd_iommu_event_log_entries = IOMMU_EVENT_LOG_DEFAULT_ENTRIES;
-int nr_amd_iommus;
-
-unsigned short ivrs_bdf_entries;
-struct ivrs_mappings *ivrs_mappings;
+extern unsigned short ivrs_bdf_entries;
+extern struct ivrs_mappings *ivrs_mappings;
 extern void *int_remap_table;
 
 static void deallocate_domain_page_tables(struct hvm_iommu *hd)
@@ -47,209 +40,39 @@ static void deallocate_domain_resources(
     deallocate_domain_page_tables(hd);
 }
 
-static void __init init_cleanup(void)
-{
-    struct amd_iommu *iommu;
+int __init amd_iommu_init(void)
+{
+    struct amd_iommu *iommu;
+
+    BUG_ON( !iommu_found() );
+
+    ivrs_bdf_entries = amd_iommu_get_ivrs_dev_entries();
+
+    if ( !ivrs_bdf_entries )
+        goto error_out;
+
+    if ( amd_iommu_setup_shared_tables() != 0 )
+        goto error_out;
+
+    if ( amd_iommu_update_ivrs_mapping_acpi() != 0 )
+        goto error_out;
 
     for_each_amd_iommu ( iommu )
-        unmap_iommu_mmio_region(iommu);
-}
-
-static void __init deallocate_iommu_table_struct(
-    struct table_struct *table)
-{
-    if ( table->buffer )
-    {
-        free_xenheap_pages(table->buffer,
-                           get_order_from_bytes(table->alloc_size));
-        table->buffer = NULL;
-    }
-}
-
-static void __init deallocate_iommu_resources(struct amd_iommu *iommu)
-{
-    deallocate_iommu_table_struct(&iommu->dev_table);
-    deallocate_iommu_table_struct(&iommu->cmd_buffer);
-    deallocate_iommu_table_struct(&iommu->event_log);
-}
-
-static int __init allocate_iommu_table_struct(struct table_struct *table,
-                                              const char *name)
-{
-    table->buffer = (void *) alloc_xenheap_pages(
-        get_order_from_bytes(table->alloc_size));
-
-    if ( !table->buffer )
-    {
-        amd_iov_error("Error allocating %s\n", name);
-        return -ENOMEM;
-    }
-
-    memset(table->buffer, 0, table->alloc_size);
-
-    return 0;
-}
-
-static int __init allocate_iommu_resources(struct amd_iommu *iommu)
-{
-    /* allocate 'device table' on a 4K boundary */
-    iommu->dev_table.alloc_size =
-        PAGE_ALIGN(((iommu->last_downstream_bus + 1) *
-                    IOMMU_DEV_TABLE_ENTRIES_PER_BUS) *
-                   IOMMU_DEV_TABLE_ENTRY_SIZE);
-    iommu->dev_table.entries =
-        iommu->dev_table.alloc_size / IOMMU_DEV_TABLE_ENTRY_SIZE;
-
-    if ( allocate_iommu_table_struct(&iommu->dev_table,
-                                     "Device Table") != 0 )
-        goto error_out;
-
-    /* allocate 'command buffer' in power of 2 increments of 4K */
-    iommu->cmd_buffer_tail = 0;
-    iommu->cmd_buffer.alloc_size =
-        PAGE_SIZE << get_order_from_bytes(
-            PAGE_ALIGN(amd_iommu_cmd_buffer_entries *
-                       IOMMU_CMD_BUFFER_ENTRY_SIZE));
-
-    iommu->cmd_buffer.entries =
-        iommu->cmd_buffer.alloc_size / IOMMU_CMD_BUFFER_ENTRY_SIZE;
-
-    if ( allocate_iommu_table_struct(&iommu->cmd_buffer,
-                                     "Command Buffer") != 0 )
-        goto error_out;
-
-    /* allocate 'event log' in power of 2 increments of 4K */
-    iommu->event_log_head = 0;
-    iommu->event_log.alloc_size =
-        PAGE_SIZE << get_order_from_bytes(
-            PAGE_ALIGN(amd_iommu_event_log_entries *
-                        IOMMU_EVENT_LOG_ENTRY_SIZE));
-
-    iommu->event_log.entries =
-        iommu->event_log.alloc_size / IOMMU_EVENT_LOG_ENTRY_SIZE;
-
-    if ( allocate_iommu_table_struct(&iommu->event_log,
-                                     "Event Log") != 0 )
-        goto error_out;
-
-    return 0;
-
- error_out:
-    deallocate_iommu_resources(iommu);
-    return -ENOMEM;
-}
-
-int iommu_detect_callback(u8 bus, u8 dev, u8 func, u8 cap_ptr)
-{
-    struct amd_iommu *iommu;
-
-    iommu = (struct amd_iommu *) xmalloc(struct amd_iommu);
-    if ( !iommu )
-    {
-        amd_iov_error("Error allocating amd_iommu\n");
-        return -ENOMEM;
-    }
-    memset(iommu, 0, sizeof(struct amd_iommu));
-    spin_lock_init(&iommu->lock);
-
-    /* get capability and topology information */
-    if ( get_iommu_capabilities(bus, dev, func, cap_ptr, iommu) != 0 )
-        goto error_out;
-    if ( get_iommu_last_downstream_bus(iommu) != 0 )
-        goto error_out;
-
-    list_add_tail(&iommu->list, &amd_iommu_head);
-
-    /* allocate resources for this IOMMU */
-    if ( allocate_iommu_resources(iommu) != 0 )
-        goto error_out;
-
-    return 0;
-
- error_out:
-    xfree(iommu);
+        if ( amd_iommu_init_one(iommu) != 0 )
+            goto error_out;
+
+    return 0;
+
+error_out:
+    amd_iommu_init_cleanup();
     return -ENODEV;
 }
 
-static int __init amd_iommu_init(void)
-{
-    struct amd_iommu *iommu;
-    unsigned long flags;
-    u16 bdf;
-
-    for_each_amd_iommu ( iommu )
-    {
-        spin_lock_irqsave(&iommu->lock, flags);
-
-        /* assign default IOMMU values */
-        iommu->coherent = IOMMU_CONTROL_ENABLED;
-        iommu->isochronous = IOMMU_CONTROL_ENABLED;
-        iommu->res_pass_pw = IOMMU_CONTROL_ENABLED;
-        iommu->pass_pw = IOMMU_CONTROL_ENABLED;
-        iommu->ht_tunnel_enable = iommu->ht_tunnel_support ?
-            IOMMU_CONTROL_ENABLED : IOMMU_CONTROL_DISABLED;
-        iommu->exclusion_enable = IOMMU_CONTROL_DISABLED;
-        iommu->exclusion_allow_all = IOMMU_CONTROL_DISABLED;
-
-        /* register IOMMU data strucures in MMIO space */
-        if ( map_iommu_mmio_region(iommu) != 0 )
-            goto error_out;
-        register_iommu_dev_table_in_mmio_space(iommu);
-        register_iommu_cmd_buffer_in_mmio_space(iommu);
-        register_iommu_event_log_in_mmio_space(iommu);
-
-        spin_unlock_irqrestore(&iommu->lock, flags);
-    }
-
-    /* assign default values for device entries */
-    for ( bdf = 0; bdf < ivrs_bdf_entries; bdf++ )
-    {
-        ivrs_mappings[bdf].dte_requestor_id = bdf;
-        ivrs_mappings[bdf].dte_sys_mgt_enable =
-            IOMMU_DEV_TABLE_SYS_MGT_MSG_FORWARDED;
-        ivrs_mappings[bdf].dte_allow_exclusion =
-            IOMMU_CONTROL_DISABLED;
-        ivrs_mappings[bdf].unity_map_enable =
-            IOMMU_CONTROL_DISABLED;
-    }
-
-    if ( acpi_table_parse(AMD_IOMMU_ACPI_IVRS_SIG, parse_ivrs_table) != 0 )
-        amd_iov_error("Did not find IVRS table!\n");
-
-    for_each_amd_iommu ( iommu )
-    {
-        /* enable IOMMU translation services */
-        enable_iommu(iommu);
-        nr_amd_iommus++;
-    }
-
-    return 0;
-
- error_out:
-    init_cleanup();
-    return -ENODEV;
-}
-
 struct amd_iommu *find_iommu_for_device(int bus, int devfn)
 {
-    struct amd_iommu *iommu;
-
-    for_each_amd_iommu ( iommu )
-    {
-        if ( bus == iommu->root_bus )
-        {
-            if ( (devfn >= iommu->first_devfn) &&
-                 (devfn <= iommu->last_devfn) )
-                return iommu;
-        }
-        else if ( bus <= iommu->last_downstream_bus )
-        {
-            if ( iommu->downstream_bus_present[bus] )
-                return iommu;
-        }
-    }
-
-    return NULL;
+    u16 bdf = (bus << 8) | devfn;
+    BUG_ON ( bdf >= ivrs_bdf_entries );
+    return ivrs_mappings[bdf].iommu;
 }
 
 static void amd_iommu_setup_domain_device(
@@ -335,70 +158,26 @@ static void amd_iommu_setup_dom0_devices
 
 int amd_iov_detect(void)
 {
-    int last_bus;
-    struct amd_iommu *iommu, *next;
-
     INIT_LIST_HEAD(&amd_iommu_head);
 
-    if ( scan_for_iommu(iommu_detect_callback) != 0 )
+    if ( amd_iommu_detect_acpi() != 0 )
     {
         amd_iov_error("Error detection\n");
-        goto error_out;
+        return -ENODEV;
     }
 
     if ( !iommu_found() )
     {
         printk("AMD_IOV: IOMMU not found!\n");
-        goto error_out;
-    }
-
-    /* allocate 'ivrs mappings' table */
-    /* note: the table has entries to accomodate all IOMMUs */
-    last_bus = 0;
-    for_each_amd_iommu ( iommu )
-        if ( iommu->last_downstream_bus > last_bus )
-            last_bus = iommu->last_downstream_bus;
-
-    ivrs_bdf_entries = (last_bus + 1) *
-        IOMMU_DEV_TABLE_ENTRIES_PER_BUS;
-    ivrs_mappings = xmalloc_array( struct ivrs_mappings, ivrs_bdf_entries);
-    if ( ivrs_mappings == NULL )
-    {
-        amd_iov_error("Error allocating IVRS DevMappings table\n");
-        goto error_out;
-    }
-    memset(ivrs_mappings, 0,
-           ivrs_bdf_entries * sizeof(struct ivrs_mappings));
-
-    if ( amd_iommu_setup_intremap_table() != 0 )
-    {
-        amd_iov_error("Error allocating interrupt remapping table\n");
-        goto error_out;
+        return -ENODEV;
     }
 
     if ( amd_iommu_init() != 0 )
     {
         amd_iov_error("Error initialization\n");
-        goto error_out;
-    }
-
-    return 0;
-
- error_out:
-    list_for_each_entry_safe ( iommu, next, &amd_iommu_head, list )
-    {
-        list_del(&iommu->list);
-        deallocate_iommu_resources(iommu);
-        xfree(iommu);
-    }
-
-    if ( ivrs_mappings )
-    {
-        xfree(ivrs_mappings);
-        ivrs_mappings = NULL;
-    }
-
-    return -ENODEV;
+        return -ENODEV;
+    }
+    return 0;
 }
 
 static int allocate_domain_resources(struct hvm_iommu *hd)
diff -r f1486d8c06fb -r 09ee974e722f xen/include/asm-x86/amd-iommu.h
--- a/xen/include/asm-x86/amd-iommu.h   Thu Jul 31 13:36:45 2008 +0100
+++ b/xen/include/asm-x86/amd-iommu.h   Thu Jul 31 13:37:29 2008 +0100
@@ -48,10 +48,6 @@ struct amd_iommu {
     u8  unit_id;
     u8  msi_number;
 
-    u8  root_bus;
-    u8  first_devfn;
-    u8  last_devfn;
-
     u8 pte_not_present_cached;
     u8 ht_tunnel_support;
     u8 iotlb_support;
@@ -81,6 +77,9 @@ struct amd_iommu {
 
     int msi_cap;
     int maskbit;
+
+    int enabled;
+    int vector;
 };
 
 struct ivrs_mappings {
@@ -92,5 +91,6 @@ struct ivrs_mappings {
     u8 read_permission;
     unsigned long addr_range_start;
     unsigned long addr_range_length;
+    struct amd_iommu *iommu;
 };
 #endif /* _ASM_X86_64_AMD_IOMMU_H */
diff -r f1486d8c06fb -r 09ee974e722f 
xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h     Thu Jul 31 13:36:45 
2008 +0100
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h     Thu Jul 31 13:37:29 
2008 +0100
@@ -44,22 +44,17 @@
 #define amd_iov_error(fmt, args...)
 #endif
 
-typedef int (*iommu_detect_callback_ptr_t)(
-    u8 bus, u8 dev, u8 func, u8 cap_ptr);
-
 /* amd-iommu-detect functions */
-int __init scan_for_iommu(iommu_detect_callback_ptr_t iommu_detect_callback);
-int __init get_iommu_capabilities(u8 bus, u8 dev, u8 func, u8 cap_ptr,
-           struct amd_iommu *iommu);
-int __init get_iommu_last_downstream_bus(struct amd_iommu *iommu);
+int __init amd_iommu_get_ivrs_dev_entries(void);
+int __init amd_iommu_detect_one_acpi(void *ivhd);
+int __init amd_iommu_detect_acpi(void);
 
 /* amd-iommu-init functions */
-int __init map_iommu_mmio_region(struct amd_iommu *iommu);
-void __init unmap_iommu_mmio_region(struct amd_iommu *iommu);
-void __init register_iommu_dev_table_in_mmio_space(struct amd_iommu *iommu);
-void __init register_iommu_cmd_buffer_in_mmio_space(struct amd_iommu *iommu);
-void __init register_iommu_event_log_in_mmio_space(struct amd_iommu *iommu);
-void __init enable_iommu(struct amd_iommu *iommu);
+int __init amd_iommu_init(void);
+int __init amd_iommu_init_one(struct amd_iommu *iommu);
+int __init amd_iommu_update_ivrs_mapping_acpi(void);
+void __init amd_iommu_init_cleanup(void);
+int __init amd_iommu_setup_shared_tables(void);
 
 /* mapping functions */
 int amd_iommu_map_page(struct domain *d, unsigned long gfn, unsigned long mfn);
@@ -83,11 +78,9 @@ void flush_command_buffer(struct amd_iom
 /* find iommu for bdf */
 struct amd_iommu *find_iommu_for_device(int bus, int devfn);
 
-/* amd-iommu-acpi functions */
-int __init parse_ivrs_table(struct acpi_table_header *table);
-
 /*interrupt remapping */
-int amd_iommu_setup_intremap_table(void);
+int __init amd_iommu_setup_intremap_table(void);
+int __init deallocate_intremap_table(void);
 void invalidate_interrupt_table(struct amd_iommu *iommu, u16 device_id);
 void amd_iommu_ioapic_update_ire(
     unsigned int apic, unsigned int reg, unsigned int value);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] AMD IOMMU: Miscellaneous fixes and cleanups., Xen patchbot-unstable <=