debuggers.hg

changeset 22678:7cc87dcf30a1

VT-d: fix and improve print_vtd_entries()

Fix leaking of mapped domain pages (root_entry and ctxt_entry when
falling out of the level traversing loop). Do this by re-arranging
things slightly so that a mapping is retained only as long as it
really is needed.

Fix the failure to use map_domain_page() in the level traversing loop
of the function.

Add a mssing return statement in one of the error paths.

Also I wonder whether not being able to call print_vtd_entries() from
iommu_page_fault_do_one() in ix86 is still correct, now that
map_domain_page() is IRQ safe.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Keir Fraser <keir@xen.org>
date Fri Dec 24 10:14:01 2010 +0000 (2010-12-24)
parents dca1b7cf2e2c
children 609da2035aab
files xen/drivers/passthrough/vtd/utils.c
line diff
     1.1 --- a/xen/drivers/passthrough/vtd/utils.c	Fri Dec 24 10:12:58 2010 +0000
     1.2 +++ b/xen/drivers/passthrough/vtd/utils.c	Fri Dec 24 10:14:01 2010 +0000
     1.3 @@ -103,7 +103,7 @@ void print_vtd_entries(struct iommu *iom
     1.4      struct context_entry *ctxt_entry;
     1.5      struct root_entry *root_entry;
     1.6      struct dma_pte pte;
     1.7 -    u64 *l;
     1.8 +    u64 *l, val;
     1.9      u32 l_index, level;
    1.10  
    1.11      printk("print_vtd_entries: iommu = %p bdf = %x:%x.%x gmfn = %"PRIx64"\n",
    1.12 @@ -116,6 +116,11 @@ void print_vtd_entries(struct iommu *iom
    1.13      }
    1.14  
    1.15      root_entry = (struct root_entry *)map_vtd_domain_page(iommu->root_maddr);
    1.16 +    if ( root_entry == NULL )
    1.17 +    {
    1.18 +        printk("    root_entry == NULL\n");
    1.19 +        return;
    1.20 +    }
    1.21  
    1.22      printk("    root_entry = %p\n", root_entry);
    1.23      printk("    root_entry[%x] = %"PRIx64"\n", bus, root_entry[bus].val);
    1.24 @@ -126,61 +131,57 @@ void print_vtd_entries(struct iommu *iom
    1.25          return;
    1.26      }
    1.27  
    1.28 -    ctxt_entry =
    1.29 -        (struct context_entry *)map_vtd_domain_page(root_entry[bus].val);
    1.30 +    val = root_entry[bus].val;
    1.31 +    unmap_vtd_domain_page(root_entry);
    1.32 +    ctxt_entry = map_vtd_domain_page(val);
    1.33      if ( ctxt_entry == NULL )
    1.34      {
    1.35 -        unmap_vtd_domain_page(root_entry);
    1.36          printk("    ctxt_entry == NULL\n");
    1.37          return;
    1.38      }
    1.39  
    1.40      printk("    context = %p\n", ctxt_entry);
    1.41 +    val = ctxt_entry[devfn].lo;
    1.42      printk("    context[%x] = %"PRIx64"_%"PRIx64"\n",
    1.43 -           devfn, ctxt_entry[devfn].hi, ctxt_entry[devfn].lo);
    1.44 +           devfn, ctxt_entry[devfn].hi, val);
    1.45      if ( !context_present(ctxt_entry[devfn]) )
    1.46      {
    1.47          unmap_vtd_domain_page(ctxt_entry);
    1.48 -        unmap_vtd_domain_page(root_entry);
    1.49          printk("    ctxt_entry[%x] not present\n", devfn);
    1.50          return;
    1.51      }
    1.52  
    1.53      level = agaw_to_level(context_address_width(ctxt_entry[devfn]));
    1.54 +    unmap_vtd_domain_page(ctxt_entry);
    1.55      if ( level != VTD_PAGE_TABLE_LEVEL_3 &&
    1.56           level != VTD_PAGE_TABLE_LEVEL_4)
    1.57      {
    1.58 -        unmap_vtd_domain_page(ctxt_entry);
    1.59 -        unmap_vtd_domain_page(root_entry);
    1.60          printk("Unsupported VTD page table level (%d)!\n", level);
    1.61 +        return;
    1.62      }
    1.63  
    1.64 -    l = maddr_to_virt(ctxt_entry[devfn].lo);
    1.65      do
    1.66      {
    1.67 -        l = (u64*)(((unsigned long)l >> PAGE_SHIFT_4K) << PAGE_SHIFT_4K);
    1.68 +        l = map_vtd_domain_page(val);
    1.69          printk("    l%d = %p\n", level, l);
    1.70          if ( l == NULL )
    1.71          {
    1.72 -            unmap_vtd_domain_page(ctxt_entry);
    1.73 -            unmap_vtd_domain_page(root_entry);
    1.74              printk("    l%d == NULL\n", level);
    1.75              break;
    1.76          }
    1.77          l_index = get_level_index(gmfn, level);
    1.78          printk("    l%d_index = %x\n", level, l_index);
    1.79 -        printk("    l%d[%x] = %"PRIx64"\n", level, l_index, l[l_index]);
    1.80  
    1.81 -        pte.val = l[l_index];
    1.82 +        pte.val = val = l[l_index];
    1.83 +        unmap_vtd_domain_page(l);
    1.84 +        printk("    l%d[%x] = %"PRIx64"\n", level, l_index, val);
    1.85 +
    1.86 +        pte.val = val;
    1.87          if ( !dma_pte_present(pte) )
    1.88          {
    1.89 -            unmap_vtd_domain_page(ctxt_entry);
    1.90 -            unmap_vtd_domain_page(root_entry);
    1.91              printk("    l%d[%x] not present\n", level, l_index);
    1.92              break;
    1.93          }
    1.94 -
    1.95 -        l = maddr_to_virt(l[l_index]);
    1.96      } while ( --level );
    1.97  }
    1.98