Skip to contentSkip to conversation

amd iommu: add interrupt remapping support

PATCH New Wei Wang2 1 participant 1 message Jul 11, 2008

lore
Share & tools
lore

Wei Wang2

author
#0 lore raw

PATCH 1/1 amd iommu: add interrupt remapping support

Keir,
Attached patch adds interrupt remapping for amd systems and makes Xen3.3 to support all features of amd iommu. Thanks!
-Wei

Signature · 12 lines
AMD Saxony, Dresden, Germany
Operating System Research Center

Legal Information:
AMD Saxony Limited Liability Company & Co. KG
Sitz (Geschäftsanschrift):
   Wilschdorfer Landstr. 101, 01109 Dresden, Deutschland
Registergericht Dresden: HRA 4896
vertretungsberechtigter Komplementär:
   AMD Saxony LLC (Sitz Wilmington, Delaware, USA)
Geschäftsführer der AMD Saxony LLC:
   Dr. Hans-R. Deppe, Thomas McCoy
xen/drivers/passthrough/amd/Makefile +1 -0
diff -r 914a31d2ad08 xen/drivers/passthrough/amd/Makefile
@@ -3,3 +3,4 @@ obj-y += iommu_map.o
 obj-y += iommu_map.o
 obj-y += pci_amd_iommu.o
 obj-y += iommu_acpi.o
+obj-y += iommu_intr.o
xen/drivers/passthrough/amd/iommu_map.c +46 -3

59 lines not on this page · raw message

xen/drivers/passthrough/amd/pci_amd_iommu.c +13 -2
diff -r 914a31d2ad08 xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -34,6 +34,7 @@ int nr_amd_iommus;
 
 unsigned short ivrs_bdf_entries;
 struct ivrs_mappings *ivrs_mappings;
+extern void *int_remap_table;
 
 static void deallocate_domain_page_tables(struct hvm_iommu *hd)
 {
@@ -256,12 +257,13 @@ static void amd_iommu_setup_domain_devic
 {
     void *dte;
     u64 root_ptr;
+    u64 intremap_ptr;
     unsigned long flags;
     int req_id;
     u8 sys_mgt, dev_ex;
     struct hvm_iommu *hd = domain_hvm_iommu(domain);
 
-    BUG_ON( !hd->root_table || !hd->paging_mode );
+    BUG_ON( !hd->root_table || !hd->paging_mode || !int_remap_table );
 
     root_ptr = (u64)virt_to_maddr(hd->root_table);
     /* get device-table entry */
@@ -269,6 +271,8 @@ static void amd_iommu_setup_domain_devic
     dte = iommu->dev_table.buffer +
         (req_id * IOMMU_DEV_TABLE_ENTRY_SIZE);
 
+    intremap_ptr = (u64)virt_to_maddr(int_remap_table);
+
     if ( !amd_iommu_is_dte_page_translation_valid((u32 *)dte) )
     {
         spin_lock_irqsave(&iommu->lock, flags); 
@@ -276,11 +280,12 @@ static void amd_iommu_setup_domain_devic
         /* bind DTE to domain page-tables */
         sys_mgt = ivrs_mappings[req_id].dte_sys_mgt_enable;
         dev_ex = ivrs_mappings[req_id].dte_allow_exclusion;
-        amd_iommu_set_dev_table_entry((u32 *)dte, root_ptr,
+        amd_iommu_set_dev_table_entry((u32 *)dte, root_ptr, intremap_ptr,
                                       hd->domain_id, sys_mgt, dev_ex,
                                       hd->paging_mode);
 
         invalidate_dev_table_entry(iommu, req_id);
+        invalidate_interrupt_table(iommu, req_id);
         flush_command_buffer(iommu);
         amd_iov_info("Enable DTE:0x%x, "
                 "root_ptr:%"PRIx64", domain_id:%d, paging_mode:%d\n",
@@ -364,6 +369,12 @@ int amd_iov_detect(void)
     }
     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;
+    }
 
     if ( amd_iommu_init() != 0 )
     {
xen/include/asm-x86/hvm/svm/amd-iommu-defs.h +46 -20

84 lines not on this page · raw message

xen/include/asm-x86/hvm/svm/amd-iommu-proto.h +9 -1
diff -r 914a31d2ad08 xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
@@ -70,7 +70,7 @@ int amd_iommu_sync_p2m(struct domain *d)
 int amd_iommu_sync_p2m(struct domain *d);
 
 /* device table functions */
-void amd_iommu_set_dev_table_entry(u32 *dte, u64 root_ptr,
+void amd_iommu_set_dev_table_entry(u32 *dte, u64 root_ptr, u64 intremap_ptr,
         u16 domain_id, u8 sys_mgt, u8 dev_ex, u8 paging_mode);
 int amd_iommu_is_dte_page_translation_valid(u32 *entry);
 void invalidate_dev_table_entry(struct amd_iommu *iommu,
@@ -85,6 +85,14 @@ struct amd_iommu *find_iommu_for_device(
 
 /* amd-iommu-acpi functions */
 int __init parse_ivrs_table(struct acpi_table_header *table);
+
+/*interrupt remapping */
+int amd_iommu_setup_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);
+void amd_iommu_msi_msg_update_ire(
+    struct msi_desc *msi_desc, struct msi_msg *msg);
 
 static inline u32 get_field_from_reg_u32(u32 reg_value, u32 mask, u32 shift)
 {
xen/drivers/passthrough/amd/iommu_intr.c new file +205 -0

205 lines not on this page · raw message

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel