ia64/xen-unstable
changeset 18858:bb7683510600
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@amd.com>
Attached patch adds support to invalidate all pages associated with
the same domain ID on domain destruction.
Signed-off-by: Wei Wang <wei.wang2@amd.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Wed Dec 03 15:56:33 2008 +0000 (2008-12-03) |
parents | f571834d3f5d |
children | 7338f6301067 |
files | xen/drivers/passthrough/amd/iommu_map.c xen/drivers/passthrough/amd/pci_amd_iommu.c xen/include/asm-x86/hvm/svm/amd-iommu-proto.h |
line diff
1.1 --- a/xen/drivers/passthrough/amd/iommu_map.c Wed Dec 03 15:56:05 2008 +0000 1.2 +++ b/xen/drivers/passthrough/amd/iommu_map.c Wed Dec 03 15:56:33 2008 +0000 1.3 @@ -580,3 +580,47 @@ out: 1.4 spin_unlock_irqrestore(&hd->mapping_lock, flags); 1.5 return 0; 1.6 } 1.7 + 1.8 +void invalidate_all_iommu_pages(struct domain *d) 1.9 +{ 1.10 + u32 cmd[4], entry; 1.11 + unsigned long flags; 1.12 + struct amd_iommu *iommu; 1.13 + int domain_id = d->domain_id; 1.14 + u64 addr_lo = 0x7FFFFFFFFFFFF000ULL & DMA_32BIT_MASK; 1.15 + u64 addr_hi = 0x7FFFFFFFFFFFF000ULL >> 32; 1.16 + 1.17 + set_field_in_reg_u32(domain_id, 0, 1.18 + IOMMU_INV_IOMMU_PAGES_DOMAIN_ID_MASK, 1.19 + IOMMU_INV_IOMMU_PAGES_DOMAIN_ID_SHIFT, &entry); 1.20 + set_field_in_reg_u32(IOMMU_CMD_INVALIDATE_IOMMU_PAGES, entry, 1.21 + IOMMU_CMD_OPCODE_MASK, IOMMU_CMD_OPCODE_SHIFT, 1.22 + &entry); 1.23 + cmd[1] = entry; 1.24 + 1.25 + set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, 0, 1.26 + IOMMU_INV_IOMMU_PAGES_S_FLAG_MASK, 1.27 + IOMMU_INV_IOMMU_PAGES_S_FLAG_SHIFT, &entry); 1.28 + set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry, 1.29 + IOMMU_INV_IOMMU_PAGES_PDE_FLAG_MASK, 1.30 + IOMMU_INV_IOMMU_PAGES_PDE_FLAG_SHIFT, &entry); 1.31 + set_field_in_reg_u32((u32)addr_lo >> PAGE_SHIFT, entry, 1.32 + IOMMU_INV_IOMMU_PAGES_ADDR_LOW_MASK, 1.33 + IOMMU_INV_IOMMU_PAGES_ADDR_LOW_SHIFT, &entry); 1.34 + cmd[2] = entry; 1.35 + 1.36 + set_field_in_reg_u32((u32)addr_hi, 0, 1.37 + IOMMU_INV_IOMMU_PAGES_ADDR_HIGH_MASK, 1.38 + IOMMU_INV_IOMMU_PAGES_ADDR_HIGH_SHIFT, &entry); 1.39 + cmd[3] = entry; 1.40 + 1.41 + cmd[0] = 0; 1.42 + 1.43 + for_each_amd_iommu ( iommu ) 1.44 + { 1.45 + spin_lock_irqsave(&iommu->lock, flags); 1.46 + send_iommu_command(iommu, cmd); 1.47 + flush_command_buffer(iommu); 1.48 + spin_unlock_irqrestore(&iommu->lock, flags); 1.49 + } 1.50 +}
2.1 --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c Wed Dec 03 15:56:05 2008 +0000 2.2 +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c Wed Dec 03 15:56:33 2008 +0000 2.3 @@ -389,6 +389,7 @@ static void deallocate_iommu_page_tables 2.4 static void amd_iommu_domain_destroy(struct domain *d) 2.5 { 2.6 deallocate_iommu_page_tables(d); 2.7 + invalidate_all_iommu_pages(d); 2.8 } 2.9 2.10 static int amd_iommu_return_device(
3.1 --- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Wed Dec 03 15:56:05 2008 +0000 3.2 +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Wed Dec 03 15:56:33 2008 +0000 3.3 @@ -63,6 +63,7 @@ void *amd_iommu_get_vptr_from_page_table 3.4 int amd_iommu_reserve_domain_unity_map(struct domain *domain, 3.5 unsigned long phys_addr, unsigned long size, int iw, int ir); 3.6 int amd_iommu_sync_p2m(struct domain *d); 3.7 +void invalidate_all_iommu_pages(struct domain *d); 3.8 3.9 /* device table functions */ 3.10 void amd_iommu_set_dev_table_entry(u32 *dte, u64 root_ptr, u64 intremap_ptr,