Skip to contentSkip to conversation

AMD IOMMU: Invalidate all pages on domain destruction

PATCH In review Wei Wang2 1 participant 1 message Dec 3, 2008

lore
Share & tools
lore

Wei Wang2

author
#0 lore raw

PATCH 3/3 AMD IOMMU: Invalidate all pages on domain destruction

Attached patch adds support to invalidate all pages associated with the same domain ID on domain destruction.

-Wei

--
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/iommu_map.c +44 -0
diff -r ab0c1bdede53 xen/drivers/passthrough/amd/iommu_map.c
@@ -580,3 +580,47 @@ out:
     spin_unlock_irqrestore(&hd->mapping_lock, flags);
     return 0;
 }
+
+void invalidate_all_iommu_pages(struct domain *d)
+{
+    u32 cmd[4], entry;
+    unsigned long flags;
+    struct amd_iommu *iommu;
+    int domain_id = d->domain_id;
+    u64 addr_lo = 0x7FFFFFFFFFFFF000ULL & DMA_32BIT_MASK;
+    u64 addr_hi = 0x7FFFFFFFFFFFF000ULL >> 32;
+
+    set_field_in_reg_u32(domain_id, 0,
+                         IOMMU_INV_IOMMU_PAGES_DOMAIN_ID_MASK,
+                         IOMMU_INV_IOMMU_PAGES_DOMAIN_ID_SHIFT, &entry);
+    set_field_in_reg_u32(IOMMU_CMD_INVALIDATE_IOMMU_PAGES, entry,
+                         IOMMU_CMD_OPCODE_MASK, IOMMU_CMD_OPCODE_SHIFT,
+                         &entry);
+    cmd[1] = entry;
+
+    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, 0,
+                         IOMMU_INV_IOMMU_PAGES_S_FLAG_MASK,
+                         IOMMU_INV_IOMMU_PAGES_S_FLAG_SHIFT, &entry);
+    set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry,
+                         IOMMU_INV_IOMMU_PAGES_PDE_FLAG_MASK,
+                         IOMMU_INV_IOMMU_PAGES_PDE_FLAG_SHIFT, &entry);
+    set_field_in_reg_u32((u32)addr_lo >> PAGE_SHIFT, entry,
+                         IOMMU_INV_IOMMU_PAGES_ADDR_LOW_MASK,
+                         IOMMU_INV_IOMMU_PAGES_ADDR_LOW_SHIFT, &entry);
+    cmd[2] = entry;
+
+    set_field_in_reg_u32((u32)addr_hi, 0,
+                         IOMMU_INV_IOMMU_PAGES_ADDR_HIGH_MASK,
+                         IOMMU_INV_IOMMU_PAGES_ADDR_HIGH_SHIFT, &entry);
+    cmd[3] = entry;
+
+    cmd[0] = 0;
+
+    for_each_amd_iommu ( iommu )
+    {
+        spin_lock_irqsave(&iommu->lock, flags);
+        send_iommu_command(iommu, cmd);
+        flush_command_buffer(iommu);
+        spin_unlock_irqrestore(&iommu->lock, flags);
+    }
+}
xen/drivers/passthrough/amd/pci_amd_iommu.c +1 -0
diff -r ab0c1bdede53 xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -389,6 +389,7 @@ static void amd_iommu_domain_destroy(str
 static void amd_iommu_domain_destroy(struct domain *d)
 {
     deallocate_iommu_page_tables(d);
+    invalidate_all_iommu_pages(d);
 }
 
 static int amd_iommu_return_device(
xen/include/asm-x86/hvm/svm/amd-iommu-proto.h +1 -0
diff -r ab0c1bdede53 xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
@@ -63,6 +63,7 @@ int amd_iommu_reserve_domain_unity_map(s
 int amd_iommu_reserve_domain_unity_map(struct domain *domain,
         unsigned long phys_addr, unsigned long size, int iw, int ir);
 int amd_iommu_sync_p2m(struct domain *d);
+void invalidate_all_iommu_pages(struct domain *d);
 
 /* device table functions */
 void amd_iommu_set_dev_table_entry(u32 *dte, u64 root_ptr, u64 intremap_ptr,

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