[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] amd iommu: reduce io page level for hvm guest (3/3)
# HG changeset patch # User Wei Wang <wei.wang2@xxxxxxx> # Date 1296144727 0 # Node ID 3b00ee057c4ac8f404a516f89b1497570f8e5e5f # Parent 699f2248147996173f13cc8a9cf097fcbf5cb7de amd iommu: reduce io page level for hvm guest (3/3) Clean up invalidate_iommu_page function. Make it suitable for variable page sizes and can be reused by invalidate_all_iommu_pages. Signed-off-by: Wei Wang <wei.wang2@xxxxxxx> --- xen/drivers/passthrough/amd/iommu_map.c | 61 +++++++++++++------------------- 1 files changed, 25 insertions(+), 36 deletions(-) diff -r 699f22481479 -r 3b00ee057c4a xen/drivers/passthrough/amd/iommu_map.c --- a/xen/drivers/passthrough/amd/iommu_map.c Thu Jan 27 16:11:37 2011 +0000 +++ b/xen/drivers/passthrough/amd/iommu_map.c Thu Jan 27 16:12:07 2011 +0000 @@ -71,11 +71,29 @@ int send_iommu_command(struct amd_iommu return 0; } -static void invalidate_iommu_page(struct amd_iommu *iommu, - u64 io_addr, u16 domain_id) +static void invalidate_iommu_pages(struct amd_iommu *iommu, + u64 io_addr, u16 domain_id, u16 order) { u64 addr_lo, addr_hi; u32 cmd[4], entry; + u64 mask = 0; + int sflag = 0, pde = 0; + + /* If sflag == 1, the size of the invalidate command is determined + by the first zero bit in the address starting from Address[12] */ + if ( order == 9 || order == 18 ) + { + mask = ((1ULL << (order - 1)) - 1) << PAGE_SHIFT; + io_addr |= mask; + sflag = 1; + } + + /* All pages associated with the domainID are invalidated */ + else if ( io_addr == 0x7FFFFFFFFFFFF000ULL ) + { + sflag = 1; + pde = 1; + } addr_lo = io_addr & DMA_32BIT_MASK; addr_hi = io_addr >> 32; @@ -88,10 +106,10 @@ static void invalidate_iommu_page(struct &entry); cmd[1] = entry; - set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, 0, + set_field_in_reg_u32(sflag, 0, IOMMU_INV_IOMMU_PAGES_S_FLAG_MASK, IOMMU_INV_IOMMU_PAGES_S_FLAG_SHIFT, &entry); - set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, entry, + set_field_in_reg_u32(pde, entry, IOMMU_INV_IOMMU_PAGES_PDE_FLAG_MASK, IOMMU_INV_IOMMU_PAGES_PDE_FLAG_SHIFT, &entry); set_field_in_reg_u32((u32)addr_lo >> PAGE_SHIFT, entry, @@ -510,7 +528,7 @@ int amd_iommu_unmap_page(struct domain * for_each_amd_iommu ( iommu ) { spin_lock_irqsave(&iommu->lock, flags); - invalidate_iommu_page(iommu, (u64)gfn << PAGE_SHIFT, hd->domain_id); + invalidate_iommu_pages(iommu, (u64)gfn << PAGE_SHIFT, hd->domain_id, 0); flush_command_buffer(iommu); spin_unlock_irqrestore(&iommu->lock, flags); } @@ -543,43 +561,14 @@ int amd_iommu_reserve_domain_unity_map(s void invalidate_all_iommu_pages(struct domain *d) { - u32 cmd[4], entry; unsigned long flags; struct amd_iommu *iommu; - int domain_id = d->domain_id; - u64 addr_lo = 0x7FFFFFFFFFFFF000ULL & DMA_32BIT_MASK; - u64 addr_hi = 0x7FFFFFFFFFFFF000ULL >> 32; - - set_field_in_reg_u32(domain_id, 0, - IOMMU_INV_IOMMU_PAGES_DOMAIN_ID_MASK, - IOMMU_INV_IOMMU_PAGES_DOMAIN_ID_SHIFT, &entry); - set_field_in_reg_u32(IOMMU_CMD_INVALIDATE_IOMMU_PAGES, entry, - IOMMU_CMD_OPCODE_MASK, IOMMU_CMD_OPCODE_SHIFT, - &entry); - cmd[1] = entry; - - set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, 0, - IOMMU_INV_IOMMU_PAGES_S_FLAG_MASK, - IOMMU_INV_IOMMU_PAGES_S_FLAG_SHIFT, &entry); - set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, entry, - IOMMU_INV_IOMMU_PAGES_PDE_FLAG_MASK, - IOMMU_INV_IOMMU_PAGES_PDE_FLAG_SHIFT, &entry); - set_field_in_reg_u32((u32)addr_lo >> PAGE_SHIFT, entry, - IOMMU_INV_IOMMU_PAGES_ADDR_LOW_MASK, - IOMMU_INV_IOMMU_PAGES_ADDR_LOW_SHIFT, &entry); - cmd[2] = entry; - - set_field_in_reg_u32((u32)addr_hi, 0, - IOMMU_INV_IOMMU_PAGES_ADDR_HIGH_MASK, - IOMMU_INV_IOMMU_PAGES_ADDR_HIGH_SHIFT, &entry); - cmd[3] = entry; - - cmd[0] = 0; for_each_amd_iommu ( iommu ) { spin_lock_irqsave(&iommu->lock, flags); - send_iommu_command(iommu, cmd); + invalidate_iommu_pages(iommu, 0x7FFFFFFFFFFFF000ULL, + d->domain_id, 0); flush_command_buffer(iommu); spin_unlock_irqrestore(&iommu->lock, flags); } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |