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