All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [VTD] Separate VT-d page table from P2M table
@ 2008-04-22  8:36 Han, Weidong
  2008-04-22  9:17 ` Keir Fraser
  0 siblings, 1 reply; 15+ messages in thread
From: Han, Weidong @ 2008-04-22  8:36 UTC (permalink / raw)
  To: xen-devel; +Cc: Xu, Anthony, Kay, Allen M

[-- Attachment #1: Type: text/plain, Size: 679 bytes --]

Currently VT-d page table shares with P2M table, this patch supports
separate VT-d page table. 
1) add an option (vtd_share) to control whether VT-d page table shares
with P2M table or not.
2) in p2m_set_entry(), map/unmap page in VT-d page table. And also add a
function to free VT-d page table when tear down. 
3) allocate extra memory for VT-d page table when allocate memory for
doamin. 

In addition, when VT-d page table shares with P2M table,  remove the if
conditional judgement for iommu_flush(). Or there is opential issue when
using balloon driver. 

Signed-off-by: Weidong Han <weidong.han@intel.com>
Signed-off-by: Anthony Xu <anthony.xu@intel.com>


[-- Attachment #2: vtd-sep.patch --]
[-- Type: application/octet-stream, Size: 4917 bytes --]

diff -r a4136cb2e23f tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py	Tue Apr 22 13:39:29 2008 +0800
+++ b/tools/python/xen/xend/XendDomainInfo.py	Tue Apr 22 14:14:04 2008 +0800
@@ -2132,8 +2132,13 @@ class XendDomainInfo:
             # set memory limit
             xc.domain_setmaxmem(self.domid, maxmem)
 
+            # Reserve 1 page per MiB of RAM for separate VT-d page table.
+            vtd_mem = 4 * (self.info['memory_static_max'] / 1024 / 1024)
+            # Round vtd_mem up to a multiple of a MiB.
+            vtd_mem = ((vtd_mem + 1023) / 1024) * 1024
+
             # Make sure there's enough RAM available for the domain
-            balloon.free(memory + shadow)
+            balloon.free(memory + shadow + vtd_mem)
 
             # Set up the shadow memory
             shadow_cur = xc.shadow_mem_control(self.domid, shadow / 1024)
diff -r a4136cb2e23f xen/arch/x86/mm/p2m.c
--- a/xen/arch/x86/mm/p2m.c	Tue Apr 22 13:39:29 2008 +0800
+++ b/xen/arch/x86/mm/p2m.c	Tue Apr 22 14:19:23 2008 +0800
@@ -259,12 +259,9 @@ p2m_set_entry(struct domain *d, unsigned
 
     if ( iommu_enabled && is_hvm_domain(d) )
     {
-        if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
-        {
-            if ( (p2mt == p2m_mmio_direct) )
-                iommu_flush(d, gfn, (u64*)p2m_entry);
-        }
-        else if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
+        if ( vtd_share )
+            iommu_flush(d, gfn, (u64*)p2m_entry);
+        else
         {
             if ( p2mt == p2m_ram_rw )
                 iommu_map_page(d, gfn, mfn_x(mfn));
@@ -530,7 +527,7 @@ int p2m_alloc_table(struct domain *d,
     }
 
 #if CONFIG_PAGING_LEVELS >= 3
-    if (vtd_enabled && is_hvm_domain(d))
+    if ( vtd_share && vtd_enabled && is_hvm_domain(d) )
         iommu_set_pgd(d);
 #endif
 
diff -r a4136cb2e23f xen/drivers/passthrough/vtd/dmar.c
--- a/xen/drivers/passthrough/vtd/dmar.c	Tue Apr 22 13:39:29 2008 +0800
+++ b/xen/drivers/passthrough/vtd/dmar.c	Tue Apr 22 14:14:04 2008 +0800
@@ -32,6 +32,10 @@
 
 int vtd_enabled = 1;
 
+/* Specify whether VT-d page table shares with P2M table or not. */
+int vtd_share;
+boolean_param("vtd_share", vtd_share);
+
 #undef PREFIX
 #define PREFIX VTDPREFIX "ACPI DMAR:"
 #define DEBUG
diff -r a4136cb2e23f xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c	Tue Apr 22 13:39:29 2008 +0800
+++ b/xen/drivers/passthrough/vtd/iommu.c	Tue Apr 22 14:14:04 2008 +0800
@@ -676,6 +676,58 @@ void dma_pte_free_pagetable(struct domai
     {
         free_pgtable_maddr(hd->pgd_maddr);
         hd->pgd_maddr = 0;
+    }
+}
+
+/* If VT-d page table doesn't share with p2m table, need to free
+ * VT-d page table explicitely when shut down or destroy domain.
+ */
+static void iommu_free_pagetable(struct domain *domain)
+{
+    struct hvm_iommu *hd = domain_hvm_iommu(domain);
+    int addr_width = agaw_to_width(hd->agaw);
+    int total_level = agaw_to_level(hd->agaw);
+    struct acpi_drhd_unit *drhd;
+    struct iommu *iommu;
+    int level;
+    struct dma_pte *page, *pte;
+    u64 pg_maddr, tmp;
+    u64 start, end;
+
+    if ( !vtd_share )
+    {
+        drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
+        iommu = drhd->iommu;
+
+        start = 0;
+        end = (((u64)1) << addr_width) - 1;
+
+        level = 2;
+        while ( level <= total_level )
+        {
+            tmp = align_to_level(start, level);
+            if ( (tmp >= end) || ((tmp + level_size(level)) > end) )
+                break;
+
+            while ( tmp < end )
+            {
+                pg_maddr = dma_addr_level_page_maddr(domain, tmp, level);
+                if ( pg_maddr == 0 )
+                {
+                    tmp += level_size(level);
+                    continue;
+                }
+                page = (struct dma_pte *)map_vtd_domain_page(pg_maddr);
+                pte = page + address_level_offset(tmp, level);
+                dma_clear_pte(*pte);
+                iommu_flush_cache_entry(iommu, pte);
+                unmap_vtd_domain_page(page);
+                free_pgtable_maddr(pg_maddr);
+
+                tmp += level_size(level);
+            }
+            level++;
+        }
     }
 }
 
@@ -1529,9 +1581,10 @@ void iommu_domain_teardown(struct domain
     if ( list_empty(&acpi_drhd_units) )
         return;
 
-    iommu_domid_release(d);
+    iommu_free_pagetable(d);
     iommu_free_pgd(d);
     return_devices_to_dom0(d);
+    iommu_domid_release(d);
 }
 
 static int domain_context_mapped(struct pci_dev *pdev)
diff -r a4136cb2e23f xen/include/xen/iommu.h
--- a/xen/include/xen/iommu.h	Tue Apr 22 13:39:29 2008 +0800
+++ b/xen/include/xen/iommu.h	Tue Apr 22 14:14:04 2008 +0800
@@ -26,6 +26,7 @@
 #include <public/hvm/ioreq.h>
 #include <public/domctl.h>
 
+extern int vtd_share;
 extern int vtd_enabled;
 extern int iommu_enabled;
 

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread
* RE: [PATCH] [VTD] Separate VT-d page table from P2M table
@ 2008-04-28  8:08 Han, Weidong
  0 siblings, 0 replies; 15+ messages in thread
From: Han, Weidong @ 2008-04-28  8:08 UTC (permalink / raw)
  To: xen-devel; +Cc: Xu, Anthony, Kay, Allen M, Keir Fraser, Nakajima, Jun

[-- Attachment #1: Type: text/plain, Size: 875 bytes --]

Keir,

Attached patch removes the shared option, and only supports separated
VT-d page table.

Randy (Weidong)

Keir Fraser wrote:
> On 22/4/08 16:43, "Li, Xin B" <xin.b.li@intel.com> wrote:
> 
>>> Then don't allow EPT 2MB mappings for domains which have passthru
>>> devices? 
>>> 
>> 
>> EPT 2M page is already supported while VT-d 2M not, so for we have to
>> seperate the 2 guys if we want to use 2M page in EPT.
>> and of course we share the page tables if both sides use 4K pages.
> 
> Just share the tables and put up with not having 2MB mappings
> available to you if a guest has devices passed through to it? Doesn't
> sound so bad to me, and you can get the performance back down the
> line by fixing the VT-d hardware to understand superpage mappings.
> We're going to end up with a silly number of p2m structures otherwise.
> 
>  -- Keir

[-- Attachment #2: vtd-sep-2.patch --]
[-- Type: application/octet-stream, Size: 3373 bytes --]

diff -r 483d006cc607 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py	Fri Apr 25 13:46:27 2008 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py	Mon Apr 28 15:23:10 2008 +0800
@@ -2135,8 +2135,13 @@ class XendDomainInfo:
             # set memory limit
             xc.domain_setmaxmem(self.domid, maxmem)
 
+            # Reserve 1 page per MiB of RAM for separate VT-d page table.
+            vtd_mem = 4 * (self.info['memory_static_max'] / 1024 / 1024)
+            # Round vtd_mem up to a multiple of a MiB.
+            vtd_mem = ((vtd_mem + 1023) / 1024) * 1024
+
             # Make sure there's enough RAM available for the domain
-            balloon.free(memory + shadow)
+            balloon.free(memory + shadow + vtd_mem)
 
             # Set up the shadow memory
             shadow_cur = xc.shadow_mem_control(self.domid, shadow / 1024)
diff -r 483d006cc607 xen/arch/x86/mm/p2m.c
--- a/xen/arch/x86/mm/p2m.c	Fri Apr 25 13:46:27 2008 +0100
+++ b/xen/arch/x86/mm/p2m.c	Mon Apr 28 15:23:10 2008 +0800
@@ -259,18 +259,10 @@ p2m_set_entry(struct domain *d, unsigned
 
     if ( iommu_enabled && is_hvm_domain(d) )
     {
-        if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
-        {
-            if ( (p2mt == p2m_mmio_direct) )
-                iommu_flush(d, gfn, (u64*)p2m_entry);
-        }
-        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 ( p2mt == p2m_ram_rw )
+            iommu_map_page(d, gfn, mfn_x(mfn));
+        else
+            iommu_unmap_page(d, gfn);
     }
 
     /* Success */
@@ -528,11 +520,6 @@ int p2m_alloc_table(struct domain *d,
             && !set_p2m_entry(d, gfn, mfn, p2m_ram_rw) )
             goto error;
     }
-
-#if CONFIG_PAGING_LEVELS >= 3
-    if (vtd_enabled && is_hvm_domain(d))
-        iommu_set_pgd(d);
-#endif
 
     P2M_PRINTK("p2m table initialised (%u pages)\n", page_count);
     p2m_unlock(p2m);
diff -r 483d006cc607 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c	Fri Apr 25 13:46:27 2008 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c	Mon Apr 28 15:43:58 2008 +0800
@@ -671,11 +671,24 @@ void dma_pte_free_pagetable(struct domai
     }
 
     /* free pgd */
-    if ( start == 0 && end == ((((u64)1) << addr_width) - 1) )
+    if ( start == 0 && end >= ((((u64)1) << addr_width) - 1) )
     {
         free_pgtable_maddr(hd->pgd_maddr);
         hd->pgd_maddr = 0;
     }
+}
+
+ /* free all VT-d page tables when shut down or destroy domain. */
+static void iommu_free_pagetable(struct domain *domain)
+{
+    struct hvm_iommu *hd = domain_hvm_iommu(domain);
+    int addr_width = agaw_to_width(hd->agaw);
+    u64 start, end;
+
+    start = 0;
+    end = (((u64)1) << addr_width) - 1;
+
+    dma_pte_free_pagetable(domain, start, end);
 }
 
 static int iommu_set_root_entry(struct iommu *iommu)
@@ -1472,9 +1485,9 @@ void iommu_domain_teardown(struct domain
     if ( list_empty(&acpi_drhd_units) )
         return;
 
+    iommu_free_pagetable(d);
+    return_devices_to_dom0(d);
     iommu_domid_release(d);
-    iommu_free_pgd(d);
-    return_devices_to_dom0(d);
 }
 
 static int domain_context_mapped(struct pci_dev *pdev)

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2008-04-28  8:08 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-22  8:36 [PATCH] [VTD] Separate VT-d page table from P2M table Han, Weidong
2008-04-22  9:17 ` Keir Fraser
2008-04-22  9:34   ` Han, Weidong
2008-04-22  9:37     ` Keir Fraser
2008-04-22 11:49       ` Han, Weidong
2008-04-22 11:57         ` Ian Pratt
2008-04-22 12:17           ` Han, Weidong
2008-04-22 12:20             ` Keir Fraser
2008-04-22 12:31               ` Han, Weidong
2008-04-22 14:51                 ` Espen Skoglund
2008-04-22 15:02                   ` [PATCH] [VTD] Separate VT-d page table fromP2M table Han, Weidong
2008-04-22 15:43               ` [PATCH] [VTD] Separate VT-d page table from P2M table Li, Xin B
2008-04-22 17:44                 ` Keir Fraser
2008-04-22  9:40     ` Samuel Thibault
  -- strict thread matches above, loose matches on Subject: below --
2008-04-28  8:08 Han, Weidong

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.