# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1228319793 0
# Node ID bb768351060037735c9ee4dfef996e198cb4d4bb
# Parent f571834d3f5d9f24bf978139d610c97178af009d
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.
Signed-off-by: Wei Wang <wei.wang2@xxxxxxx>
---
xen/drivers/passthrough/amd/iommu_map.c | 44 ++++++++++++++++++++++++++
xen/drivers/passthrough/amd/pci_amd_iommu.c | 1
xen/include/asm-x86/hvm/svm/amd-iommu-proto.h | 1
3 files changed, 46 insertions(+)
diff -r f571834d3f5d -r bb7683510600 xen/drivers/passthrough/amd/iommu_map.c
--- a/xen/drivers/passthrough/amd/iommu_map.c Wed Dec 03 15:56:05 2008 +0000
+++ b/xen/drivers/passthrough/amd/iommu_map.c Wed Dec 03 15:56:33 2008 +0000
@@ -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);
+ }
+}
diff -r f571834d3f5d -r bb7683510600 xen/drivers/passthrough/amd/pci_amd_iommu.c
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c Wed Dec 03 15:56:05
2008 +0000
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c Wed Dec 03 15:56:33
2008 +0000
@@ -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(
diff -r f571834d3f5d -r bb7683510600
xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Wed Dec 03 15:56:05
2008 +0000
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Wed Dec 03 15:56:33
2008 +0000
@@ -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-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|