[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] dump_p2m_table: For IOMMU
>>> On 10.08.12 at 21:14, Santosh Jodh <santosh.jodh@xxxxxxxxxx> wrote: > --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c Tue Aug 07 18:37:31 > 2012 +0100 > +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c Fri Aug 10 08:19:58 > 2012 -0700 > @@ -512,6 +513,80 @@ static int amd_iommu_group_id(u16 seg, u > > #include <asm/io_apic.h> > > +static void amd_dump_p2m_table_level(struct page_info* pg, int level, > + paddr_t gpa, int indent) > +{ > + paddr_t address; > + void *table_vaddr, *pde; > + paddr_t next_table_maddr; > + int index, next_level, present; > + u32 *entry; > + > + if ( level < 1 ) > + return; > + > + table_vaddr = __map_domain_page(pg); > + if ( table_vaddr == NULL ) > + { > + printk("Failed to map IOMMU domain page %"PRIpaddr"\n", > + page_to_maddr(pg)); > + return; > + } > + > + for ( index = 0; index < PTE_PER_TABLE_SIZE; index++ ) > + { > + if ( !(index % 2) ) > + process_pending_softirqs(); > + > + pde = table_vaddr + (index * IOMMU_PAGE_TABLE_ENTRY_SIZE); > + next_table_maddr = amd_iommu_get_next_table_from_pte(pde); > + entry = (u32*)pde; > + > + present = get_field_from_reg_u32(entry[0], > + IOMMU_PDE_PRESENT_MASK, > + IOMMU_PDE_PRESENT_SHIFT); > + > + if ( !present ) > + continue; > + > + next_level = get_field_from_reg_u32(entry[0], > + IOMMU_PDE_NEXT_LEVEL_MASK, > + IOMMU_PDE_NEXT_LEVEL_SHIFT); > + > + address = gpa + amd_offset_level_address(index, level); > + if ( (next_table_maddr != 0) && (next_level != 0) ) Why do you do this differently than for VT-d here? There you don't check next_table_maddr (and I see no reason you would need to). Oh, I see, there's a similar check in a different place there. But this needs to be functionally similar here then. Specifically, ... > + { > + amd_dump_p2m_table_level( > + maddr_to_page(next_table_maddr), level - 1, > + address, indent + 1); > + } > + else ... you'd get into the else's body if next_table_maddr was zero, which is wrong afaict. So I think flow like if ( next_level ) print else if ( next_table_maddr ) recurse would be the preferable way to go if you feel that these zero checks are necessary (and if you do then, because this being the case is really a bug, this shouldn't go through silently). > + { > + int i; > + > + for ( i = 0; i < indent; i++ ) > + printk(" "); printk("%*s...", indent, "", ...); > + > + printk("gfn: %08lx mfn: %08lx\n", > + (unsigned long)PFN_DOWN(address), > + (unsigned long)PFN_DOWN(next_table_maddr)); > + } > + } > + > + unmap_domain_page(table_vaddr); > +} >... > --- a/xen/drivers/passthrough/vtd/iommu.c Tue Aug 07 18:37:31 2012 +0100 > +++ b/xen/drivers/passthrough/vtd/iommu.c Fri Aug 10 08:19:58 2012 -0700 > @@ -2365,6 +2366,71 @@ static void vtd_resume(void) > } > } > > +static void vtd_dump_p2m_table_level(paddr_t pt_maddr, int level, paddr_t > gpa, > + int indent) > +{ > + paddr_t address; > + int i; > + struct dma_pte *pt_vaddr, *pte; > + int next_level; > + > + if ( pt_maddr == 0 ) > + return; > + > + pt_vaddr = map_vtd_domain_page(pt_maddr); > + if ( pt_vaddr == NULL ) > + { > + printk("Failed to map VT-D domain page %"PRIpaddr"\n", pt_maddr); > + return; > + } > + > + next_level = level - 1; > + for ( i = 0; i < PTE_NUM; i++ ) > + { > + if ( !(i % 2) ) > + process_pending_softirqs(); > + > + pte = &pt_vaddr[i]; > + if ( !dma_pte_present(*pte) ) > + continue; > + > + address = gpa + offset_level_address(i, level); > + if ( next_level >= 1 ) > + { > + vtd_dump_p2m_table_level(dma_pte_addr(*pte), next_level, > + address, indent + 1); > + } > + else > + { > + int j; > + > + for ( j = 0; j < indent; j++ ) > + printk(" "); See above. Jan > + > + printk("gfn: %08lx mfn: %08lx super=%d rd=%d wr=%d\n", > + (unsigned long)(address >> PAGE_SHIFT_4K), > + (unsigned long)(pte->val >> PAGE_SHIFT_4K), > + dma_pte_superpage(*pte)? 1 : 0, > + dma_pte_read(*pte)? 1 : 0, > + dma_pte_write(*pte)? 1 : 0); > + } > + } > + > + unmap_vtd_domain_page(pt_vaddr); > +} _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |