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>
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,