[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] VT-d: Improve page table debug output
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1211618105 -3600 # Node ID 36bbcc6baadf40b93372c39a387109b65dde20ad # Parent 5590509941b1cc12a5408d773532d9aa21e93e8e VT-d: Improve page table debug output Ignore 'current' domain when dumping VT-d page tables. Also add page type summary for domain pages output. Signed-off-by: Espen Skoglund <espen.skoglund@xxxxxxxxxxxxx> --- xen/drivers/passthrough/vtd/extern.h | 3 xen/drivers/passthrough/vtd/iommu.c | 10 + xen/drivers/passthrough/vtd/utils.c | 178 ++++++++++++++++------------------- 3 files changed, 90 insertions(+), 101 deletions(-) diff -r 5590509941b1 -r 36bbcc6baadf xen/drivers/passthrough/vtd/extern.h --- a/xen/drivers/passthrough/vtd/extern.h Sat May 24 09:27:48 2008 +0100 +++ b/xen/drivers/passthrough/vtd/extern.h Sat May 24 09:35:05 2008 +0100 @@ -27,8 +27,7 @@ extern struct ir_ctrl *ir_ctrl; extern struct ir_ctrl *ir_ctrl; void print_iommu_regs(struct acpi_drhd_unit *drhd); -void print_vtd_entries(struct domain *d, struct iommu *iommu, - int bus, int devfn, unsigned long gmfn); +void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn); void pdev_flr(u8 bus, u8 devfn); int qinval_setup(struct iommu *iommu); diff -r 5590509941b1 -r 36bbcc6baadf xen/drivers/passthrough/vtd/iommu.c --- a/xen/drivers/passthrough/vtd/iommu.c Sat May 24 09:27:48 2008 +0100 +++ b/xen/drivers/passthrough/vtd/iommu.c Sat May 24 09:35:05 2008 +0100 @@ -777,16 +777,17 @@ int iommu_disable_translation(struct iom static struct iommu *vector_to_iommu[NR_VECTORS]; static int iommu_page_fault_do_one(struct iommu *iommu, int type, - u8 fault_reason, u16 source_id, u32 addr) + u8 fault_reason, u16 source_id, u64 addr) { dprintk(XENLOG_WARNING VTDPREFIX, - "iommu_fault:%s: %x:%x.%x addr %x REASON %x iommu->reg = %p\n", + "iommu_fault:%s: %x:%x.%x addr %"PRIx64" REASON %x " + "iommu->reg = %p\n", (type ? "DMA Read" : "DMA Write"), (source_id >> 8), PCI_SLOT(source_id & 0xFF), PCI_FUNC(source_id & 0xFF), addr, fault_reason, iommu->reg); if ( fault_reason < 0x20 ) - print_vtd_entries(current->domain, iommu, (source_id >> 8), + print_vtd_entries(iommu, (source_id >> 8), (source_id & 0xff), (addr >> PAGE_SHIFT)); return 0; @@ -844,7 +845,8 @@ static void iommu_page_fault(int vector, { u8 fault_reason; u16 source_id; - u32 guest_addr, data; + u32 data; + u64 guest_addr; int type; /* highest 32 bits */ diff -r 5590509941b1 -r 36bbcc6baadf xen/drivers/passthrough/vtd/utils.c --- a/xen/drivers/passthrough/vtd/utils.c Sat May 24 09:27:48 2008 +0100 +++ b/xen/drivers/passthrough/vtd/utils.c Sat May 24 09:35:05 2008 +0100 @@ -213,109 +213,97 @@ u32 get_level_index(unsigned long gmfn, return gmfn & LEVEL_MASK; } -void print_vtd_entries( - struct domain *d, - struct iommu *iommu, - int bus, int devfn, - unsigned long gmfn) -{ - struct hvm_iommu *hd = domain_hvm_iommu(d); - struct acpi_drhd_unit *drhd; +void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn) +{ struct context_entry *ctxt_entry; struct root_entry *root_entry; struct dma_pte pte; u64 *l; - u32 l_index; - u32 i = 0; - int level = agaw_to_level(hd->agaw); - - printk("print_vtd_entries: domain_id = %x bdf = %x:%x:%x gmfn = %lx\n", - d->domain_id, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), gmfn); - - if ( hd->pgd_maddr == 0 ) - { - printk(" hd->pgd_maddr == 0\n"); - return; - } - printk(" hd->pgd_maddr = %"PRIx64"\n", hd->pgd_maddr); - - for_each_drhd_unit ( drhd ) - { - printk("---- print_vtd_entries %d ----\n", i++); - - if ( iommu->root_maddr == 0 ) - { - printk(" iommu->root_maddr = 0\n"); - continue; - } - - root_entry = - (struct root_entry *)map_vtd_domain_page(iommu->root_maddr); + u32 l_index, level; + + printk("print_vtd_entries: iommu = %p bdf = %x:%x:%x gmfn = %"PRIx64"\n", + iommu, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), gmfn); + + if ( iommu->root_maddr == 0 ) + { + printk(" iommu->root_maddr = 0\n"); + return; + } + + root_entry = (struct root_entry *)map_vtd_domain_page(iommu->root_maddr); - printk(" root_entry = %p\n", root_entry); - printk(" root_entry[%x] = %"PRIx64"\n", bus, root_entry[bus].val); - if ( !root_present(root_entry[bus]) ) - { - unmap_vtd_domain_page(root_entry); - printk(" root_entry[%x] not present\n", bus); - continue; - } - - ctxt_entry = - (struct context_entry *)map_vtd_domain_page(root_entry[bus].val); - if ( ctxt_entry == NULL ) - { - unmap_vtd_domain_page(root_entry); - printk(" ctxt_entry == NULL\n"); - continue; - } - - printk(" context = %p\n", ctxt_entry); - printk(" context[%x] = %"PRIx64" %"PRIx64"\n", - devfn, ctxt_entry[devfn].hi, ctxt_entry[devfn].lo); - if ( !context_present(ctxt_entry[devfn]) ) + printk(" root_entry = %p\n", root_entry); + printk(" root_entry[%x] = %"PRIx64"\n", bus, root_entry[bus].val); + if ( !root_present(root_entry[bus]) ) + { + unmap_vtd_domain_page(root_entry); + printk(" root_entry[%x] not present\n", bus); + return; + } + + ctxt_entry = + (struct context_entry *)map_vtd_domain_page(root_entry[bus].val); + if ( ctxt_entry == NULL ) + { + unmap_vtd_domain_page(root_entry); + printk(" ctxt_entry == NULL\n"); + return; + } + + printk(" context = %p\n", ctxt_entry); + printk(" context[%x] = %"PRIx64"_%"PRIx64"\n", + devfn, ctxt_entry[devfn].hi, ctxt_entry[devfn].lo); + if ( !context_present(ctxt_entry[devfn]) ) + { + unmap_vtd_domain_page(ctxt_entry); + unmap_vtd_domain_page(root_entry); + printk(" ctxt_entry[%x] not present\n", devfn); + return; + } + + level = agaw_to_level(context_address_width(ctxt_entry[devfn])); + if ( level != VTD_PAGE_TABLE_LEVEL_3 && + level != VTD_PAGE_TABLE_LEVEL_4) + { + unmap_vtd_domain_page(ctxt_entry); + unmap_vtd_domain_page(root_entry); + printk("Unsupported VTD page table level (%d)!\n", level); + } + + l = maddr_to_virt(ctxt_entry[devfn].lo); + do + { + l = (u64*)(((unsigned long)l >> PAGE_SHIFT_4K) << PAGE_SHIFT_4K); + printk(" l%d = %p\n", level, l); + if ( l == NULL ) { unmap_vtd_domain_page(ctxt_entry); unmap_vtd_domain_page(root_entry); - printk(" ctxt_entry[%x] not present\n", devfn); - continue; - } - - if ( level != VTD_PAGE_TABLE_LEVEL_3 && - level != VTD_PAGE_TABLE_LEVEL_4) + printk(" l%d == NULL\n", level); + break; + } + l_index = get_level_index(gmfn, level); + printk(" l%d_index = %x\n", level, l_index); + printk(" l%d[%x] = %"PRIx64"\n", level, l_index, l[l_index]); + + pte.val = l[l_index]; + if ( !dma_pte_present(pte) ) { unmap_vtd_domain_page(ctxt_entry); unmap_vtd_domain_page(root_entry); - printk("Unsupported VTD page table level (%d)!\n", level); - continue; - } - - l = maddr_to_virt(ctxt_entry[devfn].lo); - do - { - l = (u64*)(((unsigned long)l >> PAGE_SHIFT_4K) << PAGE_SHIFT_4K); - printk(" l%d = %p\n", level, l); - if ( l == NULL ) - { - unmap_vtd_domain_page(ctxt_entry); - unmap_vtd_domain_page(root_entry); - printk(" l%d == NULL\n", level); - break; - } - l_index = get_level_index(gmfn, level); - printk(" l%d_index = %x\n", level, l_index); - printk(" l%d[%x] = %"PRIx64"\n", level, l_index, l[l_index]); - - pte.val = l[l_index]; - if ( !dma_pte_present(pte) ) - { - unmap_vtd_domain_page(ctxt_entry); - unmap_vtd_domain_page(root_entry); - printk(" l%d[%x] not present\n", level, l_index); - break; - } - - l = maddr_to_virt(l[l_index]); - } while ( --level ); - } -} + printk(" l%d[%x] not present\n", level, l_index); + break; + } + + l = maddr_to_virt(l[l_index]); + } while ( --level ); +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |