ia64/xen-unstable

changeset 17774:0216f0d07efe

vtd: Fix pagetable teardown on domain detsruction.
Signed-off-by: Xiaowei Yang <xiaowei.yang@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Jun 02 10:04:19 2008 +0100 (2008-06-02)
parents 73a1daa9715f
children a4775034ef83
files xen/drivers/passthrough/vtd/iommu.c
line diff
     1.1 --- a/xen/drivers/passthrough/vtd/iommu.c	Mon Jun 02 10:03:18 2008 +0100
     1.2 +++ b/xen/drivers/passthrough/vtd/iommu.c	Mon Jun 02 10:04:19 2008 +0100
     1.3 @@ -587,50 +587,32 @@ static void dma_pte_clear_range(struct d
     1.4      }
     1.5  }
     1.6  
     1.7 -static void iommu_free_next_pagetable(u64 pt_maddr, unsigned long index,
     1.8 -                                      int level)
     1.9 +static void iommu_free_pagetable(u64 pt_maddr, int level)
    1.10  {
    1.11 -    unsigned long next_index;
    1.12 -    struct dma_pte *pt_vaddr, *pde;
    1.13 -    int next_level;
    1.14 +    int i;
    1.15 +    struct dma_pte *pt_vaddr, *pte;
    1.16 +    int next_level = level - 1;
    1.17  
    1.18      if ( pt_maddr == 0 )
    1.19          return;
    1.20  
    1.21      pt_vaddr = (struct dma_pte *)map_vtd_domain_page(pt_maddr);
    1.22 -    pde = &pt_vaddr[index];
    1.23 -    if ( dma_pte_addr(*pde) == 0 )
    1.24 -        goto out;
    1.25  
    1.26 -    next_level = level - 1;
    1.27 -    if ( next_level > 1 )
    1.28 +    for ( i = 0; i < PTE_NUM; i++ )
    1.29      {
    1.30 -        for ( next_index = 0; next_index < PTE_NUM; next_index++ )
    1.31 -            iommu_free_next_pagetable(pde->val, next_index, next_level);
    1.32 +        pte = &pt_vaddr[i];
    1.33 +        if ( !dma_pte_present(*pte) )
    1.34 +            continue;
    1.35 +
    1.36 +        if ( next_level >= 1 )
    1.37 +            iommu_free_pagetable(dma_pte_addr(*pte), next_level);
    1.38 +
    1.39 +        dma_clear_pte(*pte);
    1.40 +        iommu_flush_cache_entry(pte);
    1.41      }
    1.42  
    1.43 -    dma_clear_pte(*pde);
    1.44 -    iommu_flush_cache_entry(pde);
    1.45 -    free_pgtable_maddr(pde->val);
    1.46 -
    1.47 - out:
    1.48      unmap_vtd_domain_page(pt_vaddr);
    1.49 -}
    1.50 -
    1.51 -/* free all VT-d page tables when shut down or destroy domain. */
    1.52 -static void iommu_free_pagetable(struct domain *domain)
    1.53 -{
    1.54 -    struct hvm_iommu *hd = domain_hvm_iommu(domain);
    1.55 -    int i, total_level = agaw_to_level(hd->agaw);
    1.56 -
    1.57 -    if ( hd->pgd_maddr == 0 )
    1.58 -        return;
    1.59 -
    1.60 -    for ( i = 0; i < PTE_NUM; i++ )
    1.61 -        iommu_free_next_pagetable(hd->pgd_maddr, i, total_level + 1);
    1.62 -
    1.63 -    free_pgtable_maddr(hd->pgd_maddr);
    1.64 -    hd->pgd_maddr = 0;
    1.65 +    free_pgtable_maddr(pt_maddr);
    1.66  }
    1.67  
    1.68  static int iommu_set_root_entry(struct iommu *iommu)
    1.69 @@ -1456,11 +1438,14 @@ void return_devices_to_dom0(struct domai
    1.70  
    1.71  void iommu_domain_teardown(struct domain *d)
    1.72  {
    1.73 +    struct hvm_iommu *hd = domain_hvm_iommu(d);
    1.74 +
    1.75      if ( list_empty(&acpi_drhd_units) )
    1.76          return;
    1.77  
    1.78 -    iommu_free_pagetable(d);
    1.79      return_devices_to_dom0(d);
    1.80 +    iommu_free_pagetable(hd->pgd_maddr, agaw_to_level(hd->agaw));
    1.81 +    hd->pgd_maddr = 0;
    1.82      iommu_domid_release(d);
    1.83  }
    1.84