From: Wei Wang2 Subject: [PATCH] AMD IOMMU: Defer IO pagetable construction until device assignment Date: Wed, 02 Apr 2008 16:13:14 +0200 Message-ID: <1207145594.3980.28.camel@gran.amd.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-XbaM7aiWjU/s1SWDI4RD" Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com List-Id: xen-devel@lists.xenproject.org --=-XbaM7aiWjU/s1SWDI4RD Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable During HVM domain creation, I/O page tables are filled by coping p2m entries from p2m table, which is a useless step for non-passthru domain. This patch defers I/O page table construction until the moment of device assignment. In case that pci devices are never assigned or hot plugged, the unnecessary duplication will be avoid.=20 Wei Signed-off-by: Wei Wang --=20 AMD Saxony, Dresden, Germany Operating System Research Center Legal Information: AMD Saxony Limited Liability Company & Co. KG Sitz (Gesch=C3=A4ftsanschrift): Wilschdorfer Landstr. 101, 01109 Dresden, Deutschland Registergericht Dresden: HRA 4896 vertretungsberechtigter Komplement=C3=A4r: AMD Saxony LLC (Sitz Wilmington, Delaware, USA) Gesch=C3=A4ftsf=C3=BChrer der AMD Saxony LLC: Dr. Hans-R. Deppe, Thomas McCoy=20 --=-XbaM7aiWjU/s1SWDI4RD Content-Disposition: attachment; filename=defer_p2m.patch Content-Type: text/x-patch; name=defer_p2m.patch; charset=UTF-8 Content-Transfer-Encoding: 7bit diff -r db943e8d1051 xen/arch/x86/mm/p2m.c --- a/xen/arch/x86/mm/p2m.c Tue Apr 01 10:09:33 2008 +0100 +++ b/xen/arch/x86/mm/p2m.c Wed Apr 02 15:16:19 2008 +0200 @@ -264,10 +264,13 @@ set_p2m_entry(struct domain *d, unsigned } else if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) { - if ( p2mt == p2m_ram_rw ) - iommu_map_page(d, gfn, mfn_x(mfn)); - else - iommu_unmap_page(d, gfn); + if ( !list_empty(&domain_hvm_iommu(d)->pdev_list) ) + { + if ( p2mt == p2m_ram_rw ) + iommu_map_page(d, gfn, mfn_x(mfn)); + else + iommu_unmap_page(d, gfn); + } } } diff -r db943e8d1051 xen/drivers/passthrough/amd/pci_amd_iommu.c --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c Tue Apr 01 10:09:33 2008 +0100 +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c Wed Apr 02 15:16:19 2008 +0200 @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "../pci-direct.h" #include "../pci_regs.h" @@ -550,11 +552,33 @@ static int reassign_device( struct domai return 0; } +static int construct_p2m_mapping(struct domain *d) +{ + p2m_type_t type; + mfn_t mfn; + unsigned long gfn; + + p2m_lock(d); + + for ( gfn = 0; gfn < d->tot_pages; gfn++ ) + { + mfn = gfn_to_mfn(d, gfn, &type); + if ( type == p2m_ram_rw ) + amd_iommu_map_page(d, gfn, mfn_x(mfn)); + } + + p2m_unlock(d); + return 0; +} + int amd_iommu_assign_device(struct domain *d, u8 bus, u8 devfn) { int bdf = (bus << 8) | devfn; - int req_id; - req_id = ivrs_mappings[bdf].dte_requestor_id; + int req_id = ivrs_mappings[bdf].dte_requestor_id; + struct hvm_iommu *hd = domain_hvm_iommu(d); + + if ( is_hvm_domain(d) && list_empty(&hd->pdev_list) ) + construct_p2m_mapping(d); if ( ivrs_mappings[req_id].unity_map_enable ) { diff -r db943e8d1051 xen/include/asm-x86/hvm/svm/amd-iommu-proto.h --- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Tue Apr 01 10:09:33 2008 +0100 +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Wed Apr 02 15:16:19 2008 +0200 @@ -109,4 +109,28 @@ static inline unsigned long region_to_pa return (PAGE_ALIGN(addr + size) - (addr & PAGE_MASK)) >> PAGE_SHIFT; } +/* copy p2m_lock definition from p2m.c */ + +#define p2m_lock(_d) \ + do { \ + if ( unlikely((_d)->arch.p2m.locker == current->processor) )\ + { \ + printk("Error: p2m lock held by %s\n", \ + (_d)->arch.p2m.locker_function); \ + BUG(); \ + } \ + spin_lock(&(_d)->arch.p2m.lock); \ + ASSERT((_d)->arch.p2m.locker == -1); \ + (_d)->arch.p2m.locker = current->processor; \ + (_d)->arch.p2m.locker_function = __func__; \ + } while (0) + +#define p2m_unlock(_d) \ + do { \ + ASSERT((_d)->arch.p2m.locker == current->processor); \ + (_d)->arch.p2m.locker = -1; \ + (_d)->arch.p2m.locker_function = "nobody"; \ + spin_unlock(&(_d)->arch.p2m.lock); \ + } while (0) + #endif /* _ASM_X86_64_AMD_IOMMU_PROTO_H */ --=-XbaM7aiWjU/s1SWDI4RD Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel --=-XbaM7aiWjU/s1SWDI4RD--