<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>CHOON.NET Forums - Xen-devel</title>
        <description>A list for the Xen developer community. Please do not use this list for technical support queries. This is the archive of the Xen-Devel Mailing List. Archive started at 29 March 2011.</description>
        <link>http://choon.net/forum/list.php?22</link>
        <lastBuildDate>Wed, 19 Jun 2013 13:56:23 +0800</lastBuildDate>
        <generator>Phorum 5.2.19</generator>
        <item>
            <guid>http://choon.net/forum/read.php?22,1703544,1703544#msg-1703544</guid>
            <title>[Xen-devel] how to configure a vm so as to use .../tools/blktap/drivers/block-qcow2.c (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1703544,1703544#msg-1703544</link>
            <description><![CDATA[ hello,guys,<br />
<br />
<br />
In order to use ...tools/blktap/drivers/block-qcow2.c  I have tried many ways to set up a virtual machine including pvm/hvm, but I always failed.Under the situation that a hvm is configure with &quot;tap:qcow2:...&quot;, qemu-dm is running and support the I/O process.But how to let block-qcow2.c in blktap running for image file write and read ?I need your help about the way on which a vm is created and a configure file example .<br />
Thank you.<br />
<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>hxkhust</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Wed, 26 Dec 2012 12:06:21 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1702672,1702672#msg-1702672</guid>
            <title>[Xen-devel] Error : libxenlight state driver is not active (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1702672,1702672#msg-1702672</link>
            <description><![CDATA[ Hi all. I recently compiled xen 4.1.3 on Fedora 17(64 bit). The xen entry<br />
appears in the grub. Inspite of booting Fedora, with xen hypervisor entry ,<br />
when I start virt-manager, I get an error<br />
&quot; Internal Error : libxenlight state driver is not active &quot;<br />
<br />
Can anyone help me on this?<br />
<br />
-- <br />
Rohit S Damkondwar<br />
B.Tech Computer Engineering<br />
CoEP<br />
MyBlog [<a href="http://www.rohitsdamkondwar.wordpress.com"  rel="nofollow">www.rohitsdamkondwar.wordpress.com</a>]<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Rohit Damkondwar</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Wed, 26 Dec 2012 04:15:18 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1702637,1702637#msg-1702637</guid>
            <title>[Xen-devel] It's said 'when the guest has PCI passthrough devices in use, operations like migration/save/restore are not possible.' where are the corresponding codes in xen? (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1702637,1702637#msg-1702637</link>
            <description><![CDATA[ It's said 'when the guest has PCI passthrough devices in use, operations<br />
like migration/save/restore are not possible.' where are the corresponding<br />
codes in xen?<br />
<br />
I'm wondering how xend/xenlight tells whether a guest has a pci passthu<br />
device in use or not.<br />
<br />
   1. thank you in advance!<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Oscar Ben</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Wed, 26 Dec 2012 03:55:08 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1702506,1702506#msg-1702506</guid>
            <title>[Xen-devel] Using collectd: CPUFreq in dom0 (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1702506,1702506#msg-1702506</link>
            <description><![CDATA[ Hello,<br />
<br />
I've tried to get the CPUFreq plugin of collectd running in dom0.<br />
But I mentioned that it isn't so easy to get a file in sysfs on the<br />
rigth place.<br />
<br />
I know that the value has to come from hypervisor and I've seen the code<br />
in xenpm.<br />
<br />
The only value I need is<br />
&quot;/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq&quot; which would<br />
create cpufreq.c.<br />
<br />
Can anyone help me by giving me some hints?<br />
I've read many websites and papers and coded many things.<br />
I'm glade to get the sysfs file.<br />
<br />
With &quot;sysfs_create...&quot; I've many trouble but &quot;kobject_add&quot; works fine.<br />
<br />
Regards,<br />
Stefan Kuhne<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Stefan Kuhne</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Wed, 26 Dec 2012 03:01:29 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1700819,1700819#msg-1700819</guid>
            <title>[Xen-devel] blktap2 and blktap2-new (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1700819,1700819#msg-1700819</link>
            <description><![CDATA[ Hello. I found, that opensuse kernel-xen have two blktap2 modules. One<br />
blktap2 and other blktap-new. What is difference and why needed two<br />
modules (blktap2-new created by suse/opensuse patches)<br />
<br />
xen10:~ # modinfo xen-blktap<br />
filename:<br />
/lib/modules/3.6.9-1-xen/kernel/drivers/xen/blktap2-new/xen-blktap.ko<br />
alias:          xen-backend:tap2<br />
alias:          devname:xen/blktap-2/control<br />
license:        Dual BSD/GPL<br />
srcversion:     A4659328DBBF5A422315CA5<br />
depends:<br />
intree:         Y<br />
vermagic:       3.6.9-1-xen SMP mod_unload modversions Xen<br />
xen10:~ # modinfo blktap2<br />
filename:       /lib/modules/3.6.9-1-xen/kernel/drivers/xen/blktap2/blktap2.ko<br />
alias:          xen-backend:tap2<br />
alias:          devname:xen/blktap-2/control<br />
license:        Dual BSD/GPL<br />
srcversion:     8C21A63E6BCEEFFAD2B0DDA<br />
depends:        blkback-pagemap<br />
intree:         Y<br />
vermagic:       3.6.9-1-xen SMP mod_unload modversions Xen<br />
<br />
<br />
--<br />
Vasiliy Tolstov,<br />
Clodo.ru<br />
e-mail: <a href="mailto:&#118;&#46;&#116;&#111;&#108;&#115;&#116;&#111;&#118;&#64;&#115;&#101;&#108;&#102;&#105;&#112;&#46;&#114;&#117;">&#118;&#46;&#116;&#111;&#108;&#115;&#116;&#111;&#118;&#64;&#115;&#101;&#108;&#102;&#105;&#112;&#46;&#114;&#117;</a><br />
jabber: <a href="mailto:&#118;&#97;&#115;&#101;&#64;&#115;&#101;&#108;&#102;&#105;&#112;&#46;&#114;&#117;">&#118;&#97;&#115;&#101;&#64;&#115;&#101;&#108;&#102;&#105;&#112;&#46;&#114;&#117;</a><br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Vasiliy Tolstov</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Tue, 25 Dec 2012 14:52:29 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1698374,1698374#msg-1698374</guid>
            <title>[Xen-devel] [PATCH v4 00/10] Nested VMX: Add virtual EPT &amp; VPID support to L1 VMM (6 replies)</title>
            <link>http://choon.net/forum/read.php?22,1698374,1698374#msg-1698374</link>
            <description><![CDATA[ From: Zhang Xiantao &lt;xiantao.zhang@intel.com&gt;<br />
<br />
With virtual EPT support, L1 hyerpvisor can use EPT hardware for L2 guest's memory virtualization.<br />
In this way, L2 guest's performance can be improved sharply.<br />
According to our testing, some benchmarks can show &gt; 5x performance gain.<br />
<br />
Changes from v1:<br />
Update the patches according to Tim's comments. <br />
1. Patch 03: Enhance the virtual EPT's walker logic.<br />
2. Patch 04: Add a new field in struct p2m_domain, and use it to store<br />
   EPT-specific data. For host p2m, it saves L1 VMM's EPT data,<br />
   and for nested p2m, it saves nested EPT's data 3. Patch 07: strictly check host's p2m access type.<br />
4. Other patches: some whitespace mangling fixes.<br />
<br />
Changes form v2:<br />
Addressed comments from Jan and Jun:<br />
1. Add Acked-by message for reviewed patches by Tim. <br />
2. Fixed one whitespace mangling issue in PATCH 08 3. Add some comments to describe the meaning of <br />
   the return value of hvm_hap_nested_page_fault <br />
   in PATCH 05.<br />
4. Add the logic for handling default case of two switch<br />
   statements.<br />
<br />
Changes v3:<br />
1. Re-check all patches' whitespace mangling issue.<br />
<br />
2. Addressed Jan's comments in Patch08 and Patch09 that once return X86EMUL_EXCEPTION, the callee<br />
should be responsible for handling the execption before its return.<br />
<br />
3. Addressed Tim's comments in Patch03 and Patch04 and Patch07:<br />
   Patch03: If host doesn't support exec-only capability, we shoudln't expost this feature to L1 VMM.<br />
            Once map guest's EPT table error, inject an EPT misconfiguration errot to L1.<br />
   Patch04: Re-organize p2m's and nested p2m's structure {init/teardown} logic.<br />
   Patch07: Initialize p2ma_21  -&gt; p2m_access_rwx, so not to change SVM's behavior.<br />
<br />
Zhang Xiantao (10):<br />
  nestedhap: Change hostcr3 and p2m-&gt;cr3 to meaningful words<br />
  nestedhap: Change nested p2m's walker to vendor-specific<br />
  nested_ept: Implement guest ept's walker<br />
  EPT: Make ept data structure or operations neutral<br />
  nEPT: Try to enable EPT paging for L2 guest.<br />
  nEPT: Sync PDPTR fields if L2 guest in PAE paging mode<br />
  nEPT: Use minimal permission for nested p2m.<br />
  nEPT: handle invept instruction from L1 VMM<br />
  nVMX: virutalize VPID capability to nested VMM.<br />
  nEPT: expose EPT &amp; VPID capablities to L1 VMM<br />
<br />
 xen/arch/x86/hvm/hvm.c                  |    7 +-<br />
 xen/arch/x86/hvm/svm/nestedsvm.c        |   31 ++++<br />
 xen/arch/x86/hvm/svm/svm.c              |    3 +-<br />
 xen/arch/x86/hvm/vmx/vmcs.c             |    8 +-<br />
 xen/arch/x86/hvm/vmx/vmx.c              |   91 ++++------<br />
 xen/arch/x86/hvm/vmx/vvmx.c             |  208 ++++++++++++++++++++--<br />
 xen/arch/x86/mm/guest_walk.c            |   16 +-<br />
 xen/arch/x86/mm/hap/Makefile            |    1 +<br />
 xen/arch/x86/mm/hap/nested_ept.c        |  298 +++++++++++++++++++++++++++++++<br />
 xen/arch/x86/mm/hap/nested_hap.c        |   96 ++++++-----<br />
 xen/arch/x86/mm/mm-locks.h              |    2 +-<br />
 xen/arch/x86/mm/p2m-ept.c               |  104 +++++++++---<br />
 xen/arch/x86/mm/p2m.c                   |  159 +++++++++++------<br />
 xen/include/asm-x86/guest_pt.h          |    8 +<br />
 xen/include/asm-x86/hvm/hvm.h           |    9 +-<br />
 xen/include/asm-x86/hvm/nestedhvm.h     |    1 +<br />
 xen/include/asm-x86/hvm/svm/nestedsvm.h |    3 +<br />
 xen/include/asm-x86/hvm/vmx/vmcs.h      |   24 ++--<br />
 xen/include/asm-x86/hvm/vmx/vmx.h       |   41 ++++-<br />
 xen/include/asm-x86/hvm/vmx/vvmx.h      |   28 +++-<br />
 xen/include/asm-x86/p2m.h               |   20 ++-<br />
 21 files changed, 932 insertions(+), 226 deletions(-)<br />
 create mode 100644 xen/arch/x86/mm/hap/nested_ept.c<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Xiantao Zhang</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Mon, 24 Dec 2012 22:31:45 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1698373,1698373#msg-1698373</guid>
            <title>[Xen-devel] [PATCH v4 03/10] nested_ept: Implement guest ept's walker (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1698373,1698373#msg-1698373</link>
            <description><![CDATA[ From: Zhang Xiantao &lt;xiantao.zhang@intel.com&gt;<br />
<br />
Implment guest EPT PT walker, some logic is based on shadow's<br />
ia32e PT walker. During the PT walking, if the target pages are<br />
not in memory, use RETRY mechanism and get a chance to let the<br />
target page back.<br />
<br />
Signed-off-by: Zhang Xiantao &lt;xiantao.zhang@intel.com&gt;<br />
---<br />
 xen/arch/x86/hvm/hvm.c              |    1 +<br />
 xen/arch/x86/hvm/vmx/vvmx.c         |   42 +++++-<br />
 xen/arch/x86/mm/guest_walk.c        |   16 ++-<br />
 xen/arch/x86/mm/hap/Makefile        |    1 +<br />
 xen/arch/x86/mm/hap/nested_ept.c    |  287 +++++++++++++++++++++++++++++++++++<br />
 xen/arch/x86/mm/hap/nested_hap.c    |    2 +-<br />
 xen/include/asm-x86/guest_pt.h      |    8 +<br />
 xen/include/asm-x86/hvm/nestedhvm.h |    1 +<br />
 xen/include/asm-x86/hvm/vmx/vmcs.h  |    1 +<br />
 xen/include/asm-x86/hvm/vmx/vmx.h   |   31 ++++<br />
 xen/include/asm-x86/hvm/vmx/vvmx.h  |   13 ++<br />
 11 files changed, 394 insertions(+), 9 deletions(-)<br />
 create mode 100644 xen/arch/x86/mm/hap/nested_ept.c<br />
<br />
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c<br />
index f63ee52..bd7314f 100644<br />
--- a/xen/arch/x86/hvm/hvm.c<br />
+++ b/xen/arch/x86/hvm/hvm.c<br />
@@ -1324,6 +1324,7 @@ int hvm_hap_nested_page_fault(paddr_t gpa,<br />
                                              access_r, access_w, access_x);<br />
         switch (rv) {<br />
         case NESTEDHVM_PAGEFAULT_DONE:<br />
+        case NESTEDHVM_PAGEFAULT_RETRY:<br />
             return 1;<br />
         case NESTEDHVM_PAGEFAULT_L1_ERROR:<br />
             /* An error occured while translating gpa from<br />
diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c<br />
index 53f6a4d..1d3090d 100644<br />
--- a/xen/arch/x86/hvm/vmx/vvmx.c<br />
+++ b/xen/arch/x86/hvm/vmx/vvmx.c<br />
@@ -939,9 +939,18 @@ static void sync_vvmcs_ro(struct vcpu *v)<br />
 {<br />
     int i;<br />
     struct nestedvcpu *nvcpu = &amp;vcpu_nestedhvm(v);<br />
+    struct nestedvmx *nvmx = &amp;vcpu_2_nvmx(v);<br />
+    void *vvmcs = nvcpu-&gt;nv_vvmcx;<br />
 <br />
     for ( i = 0; i &lt; ARRAY_SIZE(vmcs_ro_field); i++ )<br />
         shadow_to_vvmcs(nvcpu-&gt;nv_vvmcx, vmcs_ro_field<i>);<br />
+<br />
+    /* Adjust exit_reason/exit_qualifciation for violation case */<br />
+    if ( __get_vvmcs(vvmcs, VM_EXIT_REASON) == EXIT_REASON_EPT_VIOLATION )<br />
+    {<br />
+        __set_vvmcs(vvmcs, EXIT_QUALIFICATION, nvmx-&gt;ept_exit.exit_qual);<br />
+        __set_vvmcs(vvmcs, VM_EXIT_REASON, nvmx-&gt;ept_exit.exit_reason);<br />
+    }<br />
 }<br />
 <br />
 static void load_vvmcs_host_state(struct vcpu *v)<br />
@@ -1488,8 +1497,37 @@ nvmx_hap_walk_L1_p2m(struct vcpu *v, paddr_t L2_gpa, paddr_t *L1_gpa,<br />
                       unsigned int *page_order,<br />
                       bool_t access_r, bool_t access_w, bool_t access_x)<br />
 {<br />
-    /*TODO:*/<br />
-    return 0;<br />
+    int rc;<br />
+    unsigned long gfn;<br />
+    uint64_t exit_qual = __vmread(EXIT_QUALIFICATION);<br />
+    uint32_t exit_reason = EXIT_REASON_EPT_VIOLATION;<br />
+    uint32_t rwx_rights = (access_x &lt;&lt; 2) | (access_w &lt;&lt; 1) | access_r;<br />
+    struct nestedvmx *nvmx = &amp;vcpu_2_nvmx(v);<br />
+<br />
+    rc = nept_translate_l2ga(v, L2_gpa, page_order, rwx_rights, &amp;gfn,<br />
+                                &amp;exit_qual, &amp;exit_reason);<br />
+    switch ( rc )<br />
+    {<br />
+    case EPT_TRANSLATE_SUCCEED:<br />
+        *L1_gpa = (gfn &lt;&lt; PAGE_SHIFT) + (L2_gpa &amp; ~PAGE_MASK);<br />
+        rc = NESTEDHVM_PAGEFAULT_DONE;<br />
+        break;<br />
+    case EPT_TRANSLATE_VIOLATION:<br />
+    case EPT_TRANSLATE_MISCONFIG:<br />
+        rc = NESTEDHVM_PAGEFAULT_INJECT;<br />
+        nvmx-&gt;ept_exit.exit_reason = exit_reason;<br />
+        nvmx-&gt;ept_exit.exit_qual = exit_qual;<br />
+        break;<br />
+    case EPT_TRANSLATE_RETRY:<br />
+        rc = NESTEDHVM_PAGEFAULT_RETRY;<br />
+        break;<br />
+    default:<br />
+        gdprintk(XENLOG_ERR, &quot;GUEST EPT translation error!:%d\n&quot;, rc);<br />
+        BUG();<br />
+        break;<br />
+    }<br />
+<br />
+    return rc;<br />
 }<br />
 <br />
 void nvmx_idtv_handling(void)<br />
diff --git a/xen/arch/x86/mm/guest_walk.c b/xen/arch/x86/mm/guest_walk.c<br />
index 0f08fb0..1c165c6 100644<br />
--- a/xen/arch/x86/mm/guest_walk.c<br />
+++ b/xen/arch/x86/mm/guest_walk.c<br />
@@ -88,18 +88,19 @@ static uint32_t set_ad_bits(void *guest_p, void *walk_p, int set_dirty)<br />
 <br />
 /* If the map is non-NULL, we leave this function having <br />
  * acquired an extra ref on mfn_to_page(*mfn) */<br />
-static inline void *map_domain_gfn(struct p2m_domain *p2m,<br />
-                                   gfn_t gfn, <br />
+void *map_domain_gfn(struct p2m_domain *p2m,<br />
+                                   gfn_t gfn,<br />
                                    mfn_t *mfn,<br />
                                    p2m_type_t *p2mt,<br />
-                                   uint32_t *rc) <br />
+                                   p2m_query_t q,<br />
+                                   uint32_t *rc)<br />
 {<br />
     struct page_info *page;<br />
     void *map;<br />
 <br />
     /* Translate the gfn, unsharing if shared */<br />
     page = get_page_from_gfn_p2m(p2m-&gt;domain, p2m, gfn_x(gfn), p2mt, NULL,<br />
-                                  P2M_ALLOC | P2M_UNSHARE);<br />
+                                  q);<br />
     if ( p2m_is_paging(*p2mt) )<br />
     {<br />
         ASSERT(!p2m_is_nestedp2m(p2m));<br />
@@ -128,7 +129,6 @@ static inline void *map_domain_gfn(struct p2m_domain *p2m,<br />
     return map;<br />
 }<br />
 <br />
-<br />
 /* Walk the guest pagetables, after the manner of a hardware walker. */<br />
 /* Because the walk is essentially random, it can cause a deadlock <br />
  * warning in the p2m locking code. Highly unlikely this is an actual<br />
@@ -149,6 +149,7 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,<br />
     uint32_t gflags, mflags, iflags, rc = 0;<br />
     int smep;<br />
     bool_t pse1G = 0, pse2M = 0;<br />
+    p2m_query_t qt = P2M_ALLOC | P2M_UNSHARE;<br />
 <br />
     perfc_incr(guest_walk);<br />
     memset(gw, 0, sizeof(*gw));<br />
@@ -188,7 +189,8 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,<br />
     l3p = map_domain_gfn(p2m, <br />
                          guest_l4e_get_gfn(gw-&gt;l4e), <br />
                          &amp;gw-&gt;l3mfn,<br />
-                         &amp;p2mt, <br />
+                         &amp;p2mt,<br />
+                         qt, <br />
                          &amp;rc); <br />
     if(l3p == NULL)<br />
         goto out;<br />
@@ -249,6 +251,7 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,<br />
                          guest_l3e_get_gfn(gw-&gt;l3e), <br />
                          &amp;gw-&gt;l2mfn,<br />
                          &amp;p2mt, <br />
+                         qt,<br />
                          &amp;rc); <br />
     if(l2p == NULL)<br />
         goto out;<br />
@@ -322,6 +325,7 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,<br />
                              guest_l2e_get_gfn(gw-&gt;l2e), <br />
                              &amp;gw-&gt;l1mfn,<br />
                              &amp;p2mt,<br />
+                             qt,<br />
                              &amp;rc);<br />
         if(l1p == NULL)<br />
             goto out;<br />
diff --git a/xen/arch/x86/mm/hap/Makefile b/xen/arch/x86/mm/hap/Makefile<br />
index 80a6bec..68f2bb5 100644<br />
--- a/xen/arch/x86/mm/hap/Makefile<br />
+++ b/xen/arch/x86/mm/hap/Makefile<br />
@@ -3,6 +3,7 @@ obj-y += guest_walk_2level.o<br />
 obj-y += guest_walk_3level.o<br />
 obj-$(x86_64) += guest_walk_4level.o<br />
 obj-y += nested_hap.o<br />
+obj-y += nested_ept.o<br />
 <br />
 guest_walk_%level.o: guest_walk.c Makefile<br />
 	$(CC) $(CFLAGS) -DGUEST_PAGING_LEVELS=$* -c $&lt; -o $@<br />
diff --git a/xen/arch/x86/mm/hap/nested_ept.c b/xen/arch/x86/mm/hap/nested_ept.c<br />
new file mode 100644<br />
index 0000000..1463d81<br />
--- /dev/null<br />
+++ b/xen/arch/x86/mm/hap/nested_ept.c<br />
@@ -0,0 +1,287 @@<br />
+/*<br />
+ * nested_ept.c: Handling virtulized EPT for guest in nested case.<br />
+ *<br />
+ * Copyright (c) 2012, Intel Corporation<br />
+ *  Xiantao Zhang &lt;xiantao.zhang@intel.com&gt;<br />
+ *<br />
+ * This program is free software; you can redistribute it and/or modify it<br />
+ * under the terms and conditions of the GNU General Public License,<br />
+ * version 2, as published by the Free Software Foundation.<br />
+ *<br />
+ * This program is distributed in the hope it will be useful, but WITHOUT<br />
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or<br />
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for<br />
+ * more details.<br />
+ *<br />
+ * You should have received a copy of the GNU General Public License along with<br />
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple<br />
+ * Place - Suite 330, Boston, MA 02111-1307 USA.<br />
+ */<br />
+#include &lt;asm/domain.h&gt;<br />
+#include &lt;asm/page.h&gt;<br />
+#include &lt;asm/paging.h&gt;<br />
+#include &lt;asm/p2m.h&gt;<br />
+#include &lt;asm/mem_event.h&gt;<br />
+#include &lt;public/mem_event.h&gt;<br />
+#include &lt;asm/mem_sharing.h&gt;<br />
+#include &lt;xen/event.h&gt;<br />
+#include &lt;asm/hap.h&gt;<br />
+#include &lt;asm/hvm/support.h&gt;<br />
+<br />
+#include &lt;asm/hvm/nestedhvm.h&gt;<br />
+<br />
+#include &quot;private.h&quot;<br />
+<br />
+#include &lt;asm/hvm/vmx/vmx.h&gt;<br />
+#include &lt;asm/hvm/vmx/vvmx.h&gt;<br />
+<br />
+/* EPT always use 4-level paging structure */<br />
+#define GUEST_PAGING_LEVELS 4<br />
+#include &lt;asm/guest_pt.h&gt;<br />
+<br />
+/* Must reserved bits in all level entries  */<br />
+#define EPT_MUST_RSV_BITS (((1ull &lt;&lt; PADDR_BITS) -1) &amp; \<br />
+                     ~((1ull &lt;&lt; paddr_bits) - 1))<br />
+<br />
+/*<br />
+ *TODO: Just leave it as 0 here for compile pass, will<br />
+ * define real capabilities in the subsequent patches.<br />
+ */<br />
+#define NEPT_VPID_CAP_BITS 0<br />
+<br />
+<br />
+#define NEPT_1G_ENTRY_FLAG (1 &lt;&lt; 11)<br />
+#define NEPT_2M_ENTRY_FLAG (1 &lt;&lt; 10)<br />
+#define NEPT_4K_ENTRY_FLAG (1 &lt;&lt; 9)<br />
+<br />
+bool_t nept_sp_entry(ept_entry_t e)<br />
+{<br />
+    return !!(e.sp);<br />
+}<br />
+<br />
+static bool_t nept_rsv_bits_check(ept_entry_t e, uint32_t level)<br />
+{<br />
+    uint64_t rsv_bits = EPT_MUST_RSV_BITS;<br />
+<br />
+    switch ( level )<br />
+    {<br />
+    case 1:<br />
+        break;<br />
+    case 2 ... 3:<br />
+        if ( nept_sp_entry(e) )<br />
+            rsv_bits |=  ((1ull &lt;&lt; (9 * (level -1 ))) -1) &lt;&lt; PAGE_SHIFT;<br />
+        else<br />
+            rsv_bits |= EPTE_EMT_MASK | EPTE_IGMT_MASK;<br />
+        break;<br />
+    case 4:<br />
+        rsv_bits |= EPTE_EMT_MASK | EPTE_IGMT_MASK | EPTE_SUPER_PAGE_MASK;<br />
+    break;<br />
+    default:<br />
+        gdprintk(XENLOG_ERR,&quot;Unsupported EPT paging level: %d\n&quot;, level);<br />
+        BUG();<br />
+        break;<br />
+    }<br />
+    return !!(e.epte &amp; rsv_bits);<br />
+}<br />
+<br />
+/* EMT checking*/<br />
+static bool_t nept_emt_bits_check(ept_entry_t e, uint32_t level)<br />
+{<br />
+    if ( e.sp || level == 1 )<br />
+    {<br />
+        if ( e.emt == EPT_EMT_RSV0 || e.emt == EPT_EMT_RSV1 ||<br />
+                e.emt == EPT_EMT_RSV2 )<br />
+            return 1;<br />
+    }<br />
+    return 0;<br />
+}<br />
+<br />
+static bool_t nept_permission_check(uint32_t rwx_acc, uint32_t rwx_bits)<br />
+{<br />
+    return !(EPTE_RWX_MASK &amp; rwx_acc &amp; ~rwx_bits);<br />
+}<br />
+<br />
+/* nept's non-present check */<br />
+static bool_t nept_non_present_check(ept_entry_t e)<br />
+{<br />
+    if ( e.epte &amp; EPTE_RWX_MASK )<br />
+        return 0;<br />
+    return 1;<br />
+}<br />
+<br />
+uint64_t nept_get_ept_vpid_cap(void)<br />
+{<br />
+    uint64_t caps = NEPT_VPID_CAP_BITS;<br />
+<br />
+    if ( !cpu_has_vmx_ept_exec_only_supported )<br />
+        caps &amp;= ~VMX_EPT_EXEC_ONLY_SUPPORTED;<br />
+    return caps;<br />
+}<br />
+<br />
+static bool_t nept_rwx_bits_check(ept_entry_t e)<br />
+{<br />
+    /*write only or write/execute only*/<br />
+    uint8_t rwx_bits = e.epte &amp; EPTE_RWX_MASK;<br />
+<br />
+    if ( rwx_bits == ept_access_w || rwx_bits == ept_access_wx )<br />
+        return 1;<br />
+<br />
+    if ( rwx_bits == ept_access_x &amp;&amp; !(nept_get_ept_vpid_cap() &amp;<br />
+                        VMX_EPT_EXEC_ONLY_SUPPORTED) )<br />
+        return 1;<br />
+<br />
+    return 0;<br />
+}<br />
+<br />
+/* nept's misconfiguration check */<br />
+static bool_t nept_misconfiguration_check(ept_entry_t e, uint32_t level)<br />
+{<br />
+    return (nept_rsv_bits_check(e, level) ||<br />
+                nept_emt_bits_check(e, level) ||<br />
+                nept_rwx_bits_check(e));<br />
+}<br />
+<br />
+static int ept_lvl_table_offset(unsigned long gpa, int lvl)<br />
+{<br />
+    return (gpa &gt;&gt;(EPT_L4_PAGETABLE_SHIFT -(4 - lvl) * 9)) &amp;<br />
+                (EPT_PAGETABLE_ENTRIES -1 );<br />
+}<br />
+<br />
+static uint32_t<br />
+nept_walk_tables(struct vcpu *v, unsigned long l2ga, ept_walk_t *gw)<br />
+{<br />
+    int lvl;<br />
+    p2m_type_t p2mt;<br />
+    uint32_t rc = 0, ret = 0, gflags;<br />
+    struct domain *d = v-&gt;domain;<br />
+    struct p2m_domain *p2m = d-&gt;arch.p2m;<br />
+    gfn_t base_gfn = _gfn(nhvm_vcpu_p2m_base(v) &gt;&gt; PAGE_SHIFT);<br />
+    mfn_t lxmfn;<br />
+    ept_entry_t *lxp = NULL;<br />
+<br />
+    memset(gw, 0, sizeof(*gw));<br />
+<br />
+    for (lvl = 4; lvl &gt; 0; lvl--)<br />
+    {<br />
+        lxp = map_domain_gfn(p2m, base_gfn, &amp;lxmfn, &amp;p2mt, P2M_ALLOC, &amp;rc);<br />
+        if ( !lxp )<br />
+            goto map_err;<br />
+        gw-&gt;lxe[lvl] = lxp[ept_lvl_table_offset(l2ga, lvl)];<br />
+        unmap_domain_page(lxp);<br />
+        put_page(mfn_to_page(mfn_x(lxmfn)));<br />
+<br />
+        if ( nept_non_present_check(gw-&gt;lxe[lvl]) )<br />
+            goto non_present;<br />
+<br />
+        if ( nept_misconfiguration_check(gw-&gt;lxe[lvl], lvl) )<br />
+            goto misconfig_err;<br />
+<br />
+        if ( (lvl == 2 || lvl == 3) &amp;&amp; nept_sp_entry(gw-&gt;lxe[lvl]) )<br />
+        {<br />
+            /* Generate a fake l1 table entry so callers don't all<br />
+             * have to understand superpages. */<br />
+            unsigned long gfn_lvl_mask =  (1ull &lt;&lt; ((lvl - 1) * 9)) - 1;<br />
+            gfn_t start = _gfn(gw-&gt;lxe[lvl].mfn);<br />
+            /* Increment the pfn by the right number of 4k pages. */<br />
+            start = _gfn((gfn_x(start) &amp; ~gfn_lvl_mask) +<br />
+                     ((l2ga &gt;&gt; PAGE_SHIFT) &amp; gfn_lvl_mask));<br />
+            gflags = (gw-&gt;lxe[lvl].epte &amp; EPTE_FLAG_MASK) |<br />
+                    (lvl == 3 ? NEPT_1G_ENTRY_FLAG: NEPT_2M_ENTRY_FLAG);<br />
+            gw-&gt;lxe[0].epte = (gfn_x(start) &lt;&lt; PAGE_SHIFT) | gflags;<br />
+            goto done;<br />
+        }<br />
+        if ( lvl &gt; 1 )<br />
+            base_gfn = _gfn(gw-&gt;lxe[lvl].mfn);<br />
+    }<br />
+<br />
+    /* If this is not a super entry, we can reach here. */<br />
+    gflags = (gw-&gt;lxe[1].epte &amp; EPTE_FLAG_MASK) | NEPT_4K_ENTRY_FLAG;<br />
+    gw-&gt;lxe[0].epte = (gw-&gt;lxe[1].epte &amp; PAGE_MASK) | gflags;<br />
+<br />
+done:<br />
+    ret = EPT_TRANSLATE_SUCCEED;<br />
+    goto out;<br />
+<br />
+map_err:<br />
+    if ( rc == _PAGE_PAGED )<br />
+    {<br />
+        ret = EPT_TRANSLATE_RETRY;<br />
+        goto out;<br />
+    }<br />
+    /* fall through to misconfig error */<br />
+misconfig_err:<br />
+    ret =  EPT_TRANSLATE_MISCONFIG;<br />
+    goto out;<br />
+<br />
+non_present:<br />
+    ret = EPT_TRANSLATE_VIOLATION;<br />
+    /* fall through. */<br />
+out:<br />
+    return ret;<br />
+}<br />
+<br />
+/* Translate a L2 guest address to L1 gpa via L1 EPT paging structure */<br />
+<br />
+int nept_translate_l2ga(struct vcpu *v, paddr_t l2ga,<br />
+                        unsigned int *page_order, uint32_t rwx_acc,<br />
+                        unsigned long *l1gfn, uint64_t *exit_qual,<br />
+                        uint32_t *exit_reason)<br />
+{<br />
+    uint32_t rc, rwx_bits = 0;<br />
+    ept_walk_t gw;<br />
+    rwx_acc &amp;= EPTE_RWX_MASK;<br />
+<br />
+    *l1gfn = INVALID_GFN;<br />
+<br />
+    rc = nept_walk_tables(v, l2ga, &amp;gw);<br />
+    switch ( rc )<br />
+    {<br />
+    case EPT_TRANSLATE_SUCCEED:<br />
+        if ( likely(gw.lxe[0].epte &amp; NEPT_2M_ENTRY_FLAG) )<br />
+        {<br />
+            rwx_bits = gw.lxe[4].epte &amp; gw.lxe[3].epte &amp; gw.lxe[2].epte &amp;<br />
+                            EPTE_RWX_MASK;<br />
+            *page_order = 9;<br />
+        }<br />
+        else if ( gw.lxe[0].epte &amp; NEPT_4K_ENTRY_FLAG )<br />
+        {<br />
+            rwx_bits = gw.lxe[4].epte &amp; gw.lxe[3].epte &amp; gw.lxe[2].epte &amp;<br />
+                    gw.lxe[1].epte &amp; EPTE_RWX_MASK;<br />
+            *page_order = 0;<br />
+        }<br />
+        else if ( gw.lxe[0].epte &amp; NEPT_1G_ENTRY_FLAG  )<br />
+        {<br />
+            rwx_bits = gw.lxe[4].epte &amp; gw.lxe[3].epte  &amp; EPTE_RWX_MASK;<br />
+            *page_order = 18;<br />
+        }<br />
+        else<br />
+        {<br />
+            gdprintk(XENLOG_ERR, &quot;Uncorrect l1 entry!\n&quot;);<br />
+            BUG();<br />
+        }<br />
+        if ( nept_permission_check(rwx_acc, rwx_bits) )<br />
+        {<br />
+            *l1gfn = gw.lxe[0].mfn;<br />
+            break;<br />
+        }<br />
+        rc = EPT_TRANSLATE_VIOLATION;<br />
+    /* Fall through to EPT violation if permission check fails. */<br />
+    case EPT_TRANSLATE_VIOLATION:<br />
+        *exit_qual = (*exit_qual &amp; 0xffffffc0) | (rwx_bits &lt;&lt; 3) | rwx_acc;<br />
+        *exit_reason = EXIT_REASON_EPT_VIOLATION;<br />
+        break;<br />
+<br />
+    case EPT_TRANSLATE_MISCONFIG:<br />
+        rc = EPT_TRANSLATE_MISCONFIG;<br />
+        *exit_qual = 0;<br />
+        *exit_reason = EXIT_REASON_EPT_MISCONFIG;<br />
+        break;<br />
+    case EPT_TRANSLATE_RETRY:<br />
+        break;<br />
+    default:<br />
+        gdprintk(XENLOG_ERR, &quot;Unsupported ept translation type!:%d\n&quot;, rc);<br />
+        BUG();<br />
+        break;<br />
+    }<br />
+    return rc;<br />
+}<br />
diff --git a/xen/arch/x86/mm/hap/nested_hap.c b/xen/arch/x86/mm/hap/nested_hap.c<br />
index 8787c91..6d1264b 100644<br />
--- a/xen/arch/x86/mm/hap/nested_hap.c<br />
+++ b/xen/arch/x86/mm/hap/nested_hap.c<br />
@@ -217,7 +217,7 @@ nestedhvm_hap_nested_page_fault(struct vcpu *v, paddr_t *L2_gpa,<br />
     /* let caller to handle these two cases */<br />
     switch (rv) {<br />
     case NESTEDHVM_PAGEFAULT_INJECT:<br />
-        return rv;<br />
+    case NESTEDHVM_PAGEFAULT_RETRY:<br />
     case NESTEDHVM_PAGEFAULT_L1_ERROR:<br />
         return rv;<br />
     case NESTEDHVM_PAGEFAULT_DONE:<br />
diff --git a/xen/include/asm-x86/guest_pt.h b/xen/include/asm-x86/guest_pt.h<br />
index 4e1dda0..db8a0b6 100644<br />
--- a/xen/include/asm-x86/guest_pt.h<br />
+++ b/xen/include/asm-x86/guest_pt.h<br />
@@ -315,6 +315,14 @@ guest_walk_to_page_order(walk_t *gw)<br />
 #define GPT_RENAME2(_n, _l) _n ## _ ## _l ## _levels<br />
 #define GPT_RENAME(_n, _l) GPT_RENAME2(_n, _l)<br />
 #define guest_walk_tables GPT_RENAME(guest_walk_tables, GUEST_PAGING_LEVELS)<br />
+#define map_domain_gfn GPT_RENAME(map_domain_gfn, GUEST_PAGING_LEVELS)<br />
+<br />
+extern void *map_domain_gfn(struct p2m_domain *p2m,<br />
+                                   gfn_t gfn,<br />
+                                   mfn_t *mfn,<br />
+                                   p2m_type_t *p2mt,<br />
+                                   p2m_query_t q,<br />
+                                   uint32_t *rc);<br />
 <br />
 extern uint32_t <br />
 guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m, unsigned long va,<br />
diff --git a/xen/include/asm-x86/hvm/nestedhvm.h b/xen/include/asm-x86/hvm/nestedhvm.h<br />
index 91fde0b..649c511 100644<br />
--- a/xen/include/asm-x86/hvm/nestedhvm.h<br />
+++ b/xen/include/asm-x86/hvm/nestedhvm.h<br />
@@ -52,6 +52,7 @@ bool_t nestedhvm_vcpu_in_guestmode(struct vcpu *v);<br />
 #define NESTEDHVM_PAGEFAULT_L1_ERROR   2<br />
 #define NESTEDHVM_PAGEFAULT_L0_ERROR   3<br />
 #define NESTEDHVM_PAGEFAULT_MMIO       4<br />
+#define NESTEDHVM_PAGEFAULT_RETRY      5<br />
 int nestedhvm_hap_nested_page_fault(struct vcpu *v, paddr_t *L2_gpa,<br />
     bool_t access_r, bool_t access_w, bool_t access_x);<br />
 <br />
diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h<br />
index ef2c9c9..9a728b6 100644<br />
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h<br />
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h<br />
@@ -194,6 +194,7 @@ extern u32 vmx_secondary_exec_control;<br />
 <br />
 extern bool_t cpu_has_vmx_ins_outs_instr_info;<br />
 <br />
+#define VMX_EPT_EXEC_ONLY_SUPPORTED             0x00000001<br />
 #define VMX_EPT_WALK_LENGTH_4_SUPPORTED         0x00000040<br />
 #define VMX_EPT_MEMORY_TYPE_UC                  0x00000100<br />
 #define VMX_EPT_MEMORY_TYPE_WB                  0x00004000<br />
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h<br />
index aa5b080..c73946f 100644<br />
--- a/xen/include/asm-x86/hvm/vmx/vmx.h<br />
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h<br />
@@ -51,6 +51,22 @@ typedef union {<br />
     u64 epte;<br />
 } ept_entry_t;<br />
 <br />
+typedef struct {<br />
+    /*use lxe[0] to save result */<br />
+    ept_entry_t lxe[5];<br />
+} ept_walk_t;<br />
+<br />
+typedef enum {<br />
+    ept_access_n     = 0, /* No access permissions allowed */<br />
+    ept_access_r     = 1, /* Read only */<br />
+    ept_access_w     = 2, /* Write only */<br />
+    ept_access_rw    = 3, /* Read &amp; Write */<br />
+    ept_access_x     = 4, /* Exec Only */<br />
+    ept_access_rx    = 5, /* Read &amp; Exec */<br />
+    ept_access_wx    = 6, /* Write &amp; Exec*/<br />
+    ept_access_all   = 7, /* Full permissions */<br />
+} ept_access_t;<br />
+<br />
 #define EPT_TABLE_ORDER         9<br />
 #define EPTE_SUPER_PAGE_MASK    0x80<br />
 #define EPTE_MFN_MASK           0xffffffffff000ULL<br />
@@ -60,6 +76,17 @@ typedef union {<br />
 #define EPTE_AVAIL1_SHIFT       8<br />
 #define EPTE_EMT_SHIFT          3<br />
 #define EPTE_IGMT_SHIFT         6<br />
+#define EPTE_RWX_MASK           0x7<br />
+#define EPTE_FLAG_MASK          0x7f<br />
+<br />
+#define EPT_EMT_UC              0<br />
+#define EPT_EMT_WC              1<br />
+#define EPT_EMT_RSV0            2<br />
+#define EPT_EMT_RSV1            3<br />
+#define EPT_EMT_WT              4<br />
+#define EPT_EMT_WP              5<br />
+#define EPT_EMT_WB              6<br />
+#define EPT_EMT_RSV2            7<br />
 <br />
 void vmx_asm_vmexit_handler(struct cpu_user_regs);<br />
 void vmx_asm_do_vmentry(void);<br />
@@ -191,6 +218,9 @@ void vmx_update_secondary_exec_control(struct vcpu *v);<br />
 <br />
 extern u64 vmx_ept_vpid_cap;<br />
 <br />
+#define cpu_has_vmx_ept_exec_only_supported        \<br />
+    (vmx_ept_vpid_cap &amp; VMX_EPT_EXEC_ONLY_SUPPORTED)<br />
+<br />
 #define cpu_has_vmx_ept_wl4_supported           \<br />
     (vmx_ept_vpid_cap &amp; VMX_EPT_WALK_LENGTH_4_SUPPORTED)<br />
 #define cpu_has_vmx_ept_mt_uc                   \<br />
@@ -419,6 +449,7 @@ void update_guest_eip(void);<br />
 #define _EPT_GLA_FAULT              8<br />
 #define EPT_GLA_FAULT               (1UL&lt;&lt;_EPT_GLA_FAULT)<br />
 <br />
+#define EPT_L4_PAGETABLE_SHIFT      39<br />
 #define EPT_PAGETABLE_ENTRIES       512<br />
 <br />
 #endif /* __ASM_X86_HVM_VMX_VMX_H__ */<br />
diff --git a/xen/include/asm-x86/hvm/vmx/vvmx.h b/xen/include/asm-x86/hvm/vmx/vvmx.h<br />
index 422f006..97554bf 100644<br />
--- a/xen/include/asm-x86/hvm/vmx/vvmx.h<br />
+++ b/xen/include/asm-x86/hvm/vmx/vvmx.h<br />
@@ -32,6 +32,10 @@ struct nestedvmx {<br />
         unsigned long intr_info;<br />
         u32           error_code;<br />
     } intr;<br />
+    struct {<br />
+        uint32_t exit_reason;<br />
+        uint32_t exit_qual;<br />
+    } ept_exit;<br />
 };<br />
 <br />
 #define vcpu_2_nvmx(v)	(vcpu_nestedhvm(v).u.nvmx)<br />
@@ -109,6 +113,11 @@ void nvmx_domain_relinquish_resources(struct domain *d);<br />
 int nvmx_handle_vmxon(struct cpu_user_regs *regs);<br />
 int nvmx_handle_vmxoff(struct cpu_user_regs *regs);<br />
 <br />
+#define EPT_TRANSLATE_SUCCEED       0<br />
+#define EPT_TRANSLATE_VIOLATION     1<br />
+#define EPT_TRANSLATE_MISCONFIG     2<br />
+#define EPT_TRANSLATE_RETRY         3<br />
+<br />
 int<br />
 nvmx_hap_walk_L1_p2m(struct vcpu *v, paddr_t L2_gpa, paddr_t *L1_gpa,<br />
                       unsigned int *page_order,<br />
@@ -192,5 +201,9 @@ u64 nvmx_get_tsc_offset(struct vcpu *v);<br />
 int nvmx_n2_vmexit_handler(struct cpu_user_regs *regs,<br />
                           unsigned int exit_reason);<br />
 <br />
+int nept_translate_l2ga(struct vcpu *v, paddr_t l2ga, <br />
+                        unsigned int *page_order, uint32_t rwx_acc,<br />
+                        unsigned long *l1gfn, uint64_t *exit_qual,<br />
+                        uint32_t *exit_reason);<br />
 #endif /* __ASM_X86_HVM_VVMX_H__ */<br />
 <br />
-- <br />
1.7.1<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]</i>]]></description>
            <dc:creator>Xiantao Zhang</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Mon, 24 Dec 2012 22:31:40 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1698372,1698372#msg-1698372</guid>
            <title>[Xen-devel] [PATCH v4 04/10] EPT: Make ept data structure or operations neutral (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1698372,1698372#msg-1698372</link>
            <description><![CDATA[ From: Zhang Xiantao &lt;xiantao.zhang@intel.com&gt;<br />
<br />
Share the current EPT logic with nested EPT case, so<br />
make the related data structure or operations netural<br />
to comment EPT and nested EPT.<br />
<br />
Signed-off-by: Zhang Xiantao &lt;xiantao.zhang@intel.com&gt;<br />
---<br />
 xen/arch/x86/hvm/vmx/vmcs.c        |    8 ++-<br />
 xen/arch/x86/hvm/vmx/vmx.c         |   53 +-------------<br />
 xen/arch/x86/mm/p2m-ept.c          |  104 ++++++++++++++++++++++------<br />
 xen/arch/x86/mm/p2m.c              |  132 +++++++++++++++++++++++++-----------<br />
 xen/include/asm-x86/hvm/vmx/vmcs.h |   23 +++---<br />
 xen/include/asm-x86/hvm/vmx/vmx.h  |   10 ++-<br />
 xen/include/asm-x86/p2m.h          |    4 +<br />
 7 files changed, 208 insertions(+), 126 deletions(-)<br />
<br />
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c<br />
index 9adc7a4..de22e03 100644<br />
--- a/xen/arch/x86/hvm/vmx/vmcs.c<br />
+++ b/xen/arch/x86/hvm/vmx/vmcs.c<br />
@@ -942,7 +942,13 @@ static int construct_vmcs(struct vcpu *v)<br />
     }<br />
 <br />
     if ( paging_mode_hap(d) )<br />
-        __vmwrite(EPT_POINTER, d-&gt;arch.hvm_domain.vmx.ept_control.eptp);<br />
+    {<br />
+        struct p2m_domain *p2m = p2m_get_hostp2m(d);<br />
+        struct ept_data *ept = &amp;p2m-&gt;ept;<br />
+<br />
+        ept-&gt;asr  = pagetable_get_pfn(p2m_get_pagetable(p2m));<br />
+        __vmwrite(EPT_POINTER, ept_get_eptp(ept));<br />
+    }<br />
 <br />
     if ( cpu_has_vmx_pat &amp;&amp; paging_mode_hap(d) )<br />
     {<br />
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c<br />
index 4abfa90..d74aae0 100644<br />
--- a/xen/arch/x86/hvm/vmx/vmx.c<br />
+++ b/xen/arch/x86/hvm/vmx/vmx.c<br />
@@ -74,38 +74,19 @@ static void vmx_fpu_dirty_intercept(void);<br />
 static int vmx_msr_read_intercept(unsigned int msr, uint64_t *msr_content);<br />
 static int vmx_msr_write_intercept(unsigned int msr, uint64_t msr_content);<br />
 static void vmx_invlpg_intercept(unsigned long vaddr);<br />
-static void __ept_sync_domain(void *info);<br />
 <br />
 static int vmx_domain_initialise(struct domain *d)<br />
 {<br />
     int rc;<br />
 <br />
-    /* Set the memory type used when accessing EPT paging structures. */<br />
-    d-&gt;arch.hvm_domain.vmx.ept_control.ept_mt = EPT_DEFAULT_MT;<br />
-<br />
-    /* set EPT page-walk length, now it's actual walk length - 1, i.e. 3 */<br />
-    d-&gt;arch.hvm_domain.vmx.ept_control.ept_wl = 3;<br />
-<br />
-    d-&gt;arch.hvm_domain.vmx.ept_control.asr  =<br />
-        pagetable_get_pfn(p2m_get_pagetable(p2m_get_hostp2m(d)));<br />
-<br />
-    if ( !zalloc_cpumask_var(&amp;d-&gt;arch.hvm_domain.vmx.ept_synced) )<br />
-        return -ENOMEM;<br />
-<br />
     if ( (rc = vmx_alloc_vlapic_mapping(d)) != 0 )<br />
-    {<br />
-        free_cpumask_var(d-&gt;arch.hvm_domain.vmx.ept_synced);<br />
         return rc;<br />
-    }<br />
 <br />
     return 0;<br />
 }<br />
 <br />
 static void vmx_domain_destroy(struct domain *d)<br />
 {<br />
-    if ( paging_mode_hap(d) )<br />
-        on_each_cpu(__ept_sync_domain, d, 1);<br />
-    free_cpumask_var(d-&gt;arch.hvm_domain.vmx.ept_synced);<br />
     vmx_free_vlapic_mapping(d);<br />
 }<br />
 <br />
@@ -641,6 +622,7 @@ static void vmx_ctxt_switch_to(struct vcpu *v)<br />
 {<br />
     struct domain *d = v-&gt;domain;<br />
     unsigned long old_cr4 = read_cr4(), new_cr4 = mmu_cr4_features;<br />
+    struct ept_data *ept_data = &amp;p2m_get_hostp2m(d)-&gt;ept;<br />
 <br />
     /* HOST_CR4 in VMCS is always mmu_cr4_features. Sync CR4 now. */<br />
     if ( old_cr4 != new_cr4 )<br />
@@ -650,10 +632,10 @@ static void vmx_ctxt_switch_to(struct vcpu *v)<br />
     {<br />
         unsigned int cpu = smp_processor_id();<br />
         /* Test-and-test-and-set this CPU in the EPT-is-synced mask. */<br />
-        if ( !cpumask_test_cpu(cpu, d-&gt;arch.hvm_domain.vmx.ept_synced) &amp;&amp;<br />
+        if ( !cpumask_test_cpu(cpu, ept_get_synced_mask(ept_data)) &amp;&amp;<br />
              !cpumask_test_and_set_cpu(cpu,<br />
-                                       d-&gt;arch.hvm_domain.vmx.ept_synced) )<br />
-            __invept(INVEPT_SINGLE_CONTEXT, ept_get_eptp(d), 0);<br />
+                                       ept_get_synced_mask(ept_data)) )<br />
+            __invept(INVEPT_SINGLE_CONTEXT, ept_get_eptp(ept_data), 0);<br />
     }<br />
 <br />
     vmx_restore_guest_msrs(v);<br />
@@ -1216,33 +1198,6 @@ static void vmx_update_guest_efer(struct vcpu *v)<br />
                    (v-&gt;arch.hvm_vcpu.guest_efer &amp; EFER_SCE));<br />
 }<br />
 <br />
-static void __ept_sync_domain(void *info)<br />
-{<br />
-    struct domain *d = info;<br />
-    __invept(INVEPT_SINGLE_CONTEXT, ept_get_eptp(d), 0);<br />
-}<br />
-<br />
-void ept_sync_domain(struct domain *d)<br />
-{<br />
-    /* Only if using EPT and this domain has some VCPUs to dirty. */<br />
-    if ( !paging_mode_hap(d) || !d-&gt;vcpu || !d-&gt;vcpu[0] )<br />
-        return;<br />
-<br />
-    ASSERT(local_irq_is_enabled());<br />
-<br />
-    /*<br />
-     * Flush active cpus synchronously. Flush others the next time this domain<br />
-     * is scheduled onto them. We accept the race of other CPUs adding to<br />
-     * the ept_synced mask before on_selected_cpus() reads it, resulting in<br />
-     * unnecessary extra flushes, to avoid allocating a cpumask_t on the stack.<br />
-     */<br />
-    cpumask_and(d-&gt;arch.hvm_domain.vmx.ept_synced,<br />
-                d-&gt;domain_dirty_cpumask, &amp;cpu_online_map);<br />
-<br />
-    on_selected_cpus(d-&gt;arch.hvm_domain.vmx.ept_synced,<br />
-                     __ept_sync_domain, d, 1);<br />
-}<br />
-<br />
 void nvmx_enqueue_n2_exceptions(struct vcpu *v, <br />
             unsigned long intr_fields, int error_code)<br />
 {<br />
diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c<br />
index c964f54..e33f415 100644<br />
--- a/xen/arch/x86/mm/p2m-ept.c<br />
+++ b/xen/arch/x86/mm/p2m-ept.c<br />
@@ -291,9 +291,11 @@ ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn,<br />
     int need_modify_vtd_table = 1;<br />
     int vtd_pte_present = 0;<br />
     int needs_sync = 1;<br />
-    struct domain *d = p2m-&gt;domain;<br />
     ept_entry_t old_entry = { .epte = 0 };<br />
+    struct ept_data *ept = &amp;p2m-&gt;ept;<br />
+    struct domain *d = p2m-&gt;domain;<br />
 <br />
+    ASSERT(ept);<br />
     /*<br />
      * the caller must make sure:<br />
      * 1. passing valid gfn and mfn at order boundary.<br />
@@ -301,17 +303,17 @@ ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn,<br />
      * 3. passing a valid order.<br />
      */<br />
     if ( ((gfn | mfn_x(mfn)) &amp; ((1UL &lt;&lt; order) - 1)) ||<br />
-         ((u64)gfn &gt;&gt; ((ept_get_wl(d) + 1) * EPT_TABLE_ORDER)) ||<br />
+         ((u64)gfn &gt;&gt; ((ept_get_wl(ept) + 1) * EPT_TABLE_ORDER)) ||<br />
          (order % EPT_TABLE_ORDER) )<br />
         return 0;<br />
 <br />
-    ASSERT((target == 2 &amp;&amp; hvm_hap_has_1gb(d)) ||<br />
-           (target == 1 &amp;&amp; hvm_hap_has_2mb(d)) ||<br />
+    ASSERT((target == 2 &amp;&amp; hvm_hap_has_1gb()) ||<br />
+           (target == 1 &amp;&amp; hvm_hap_has_2mb()) ||<br />
            (target == 0));<br />
 <br />
-    table = map_domain_page(ept_get_asr(d));<br />
+    table = map_domain_page(pagetable_get_pfn(p2m_get_pagetable(p2m)));<br />
 <br />
-    for ( i = ept_get_wl(d); i &gt; target; i-- )<br />
+    for ( i = ept_get_wl(ept); i &gt; target; i-- )<br />
     {<br />
         ret = ept_next_level(p2m, 0, &amp;table, &amp;gfn_remainder, i);<br />
         if ( !ret )<br />
@@ -439,9 +441,11 @@ out:<br />
     unmap_domain_page(table);<br />
 <br />
     if ( needs_sync )<br />
-        ept_sync_domain(p2m-&gt;domain);<br />
+        ept_sync_domain(p2m);<br />
 <br />
-    if ( rv &amp;&amp; iommu_enabled &amp;&amp; need_iommu(p2m-&gt;domain) &amp;&amp; need_modify_vtd_table )<br />
+    /* For non-nested p2m, may need to change VT-d page table.*/<br />
+    if ( rv &amp;&amp; !p2m_is_nestedp2m(p2m) &amp;&amp; iommu_enabled &amp;&amp; need_iommu(p2m-&gt;domain) &amp;&amp;<br />
+                need_modify_vtd_table )<br />
     {<br />
         if ( iommu_hap_pt_share )<br />
             iommu_pte_flush(d, gfn, (u64*)ept_entry, order, vtd_pte_present);<br />
@@ -488,14 +492,14 @@ static mfn_t ept_get_entry(struct p2m_domain *p2m,<br />
                            unsigned long gfn, p2m_type_t *t, p2m_access_t* a,<br />
                            p2m_query_t q, unsigned int *page_order)<br />
 {<br />
-    struct domain *d = p2m-&gt;domain;<br />
-    ept_entry_t *table = map_domain_page(ept_get_asr(d));<br />
+    ept_entry_t *table = map_domain_page(pagetable_get_pfn(p2m_get_pagetable(p2m)));<br />
     unsigned long gfn_remainder = gfn;<br />
     ept_entry_t *ept_entry;<br />
     u32 index;<br />
     int i;<br />
     int ret = 0;<br />
     mfn_t mfn = _mfn(INVALID_MFN);<br />
+    struct ept_data *ept = &amp;p2m-&gt;ept;<br />
 <br />
     *t = p2m_mmio_dm;<br />
     *a = p2m_access_n;<br />
@@ -506,7 +510,7 @@ static mfn_t ept_get_entry(struct p2m_domain *p2m,<br />
 <br />
     /* Should check if gfn obeys GAW here. */<br />
 <br />
-    for ( i = ept_get_wl(d); i &gt; 0; i-- )<br />
+    for ( i = ept_get_wl(ept); i &gt; 0; i-- )<br />
     {<br />
     retry:<br />
         ret = ept_next_level(p2m, 1, &amp;table, &amp;gfn_remainder, i);<br />
@@ -588,19 +592,20 @@ out:<br />
 static ept_entry_t ept_get_entry_content(struct p2m_domain *p2m,<br />
     unsigned long gfn, int *level)<br />
 {<br />
-    ept_entry_t *table = map_domain_page(ept_get_asr(p2m-&gt;domain));<br />
+    ept_entry_t *table =  map_domain_page(pagetable_get_pfn(p2m_get_pagetable(p2m)));<br />
     unsigned long gfn_remainder = gfn;<br />
     ept_entry_t *ept_entry;<br />
     ept_entry_t content = { .epte = 0 };<br />
     u32 index;<br />
     int i;<br />
     int ret=0;<br />
+    struct ept_data *ept = &amp;p2m-&gt;ept;<br />
 <br />
     /* This pfn is higher than the highest the p2m map currently holds */<br />
     if ( gfn &gt; p2m-&gt;max_mapped_pfn )<br />
         goto out;<br />
 <br />
-    for ( i = ept_get_wl(p2m-&gt;domain); i &gt; 0; i-- )<br />
+    for ( i = ept_get_wl(ept); i &gt; 0; i-- )<br />
     {<br />
         ret = ept_next_level(p2m, 1, &amp;table, &amp;gfn_remainder, i);<br />
         if ( !ret || ret == GUEST_TABLE_POD_PAGE )<br />
@@ -622,7 +627,8 @@ static ept_entry_t ept_get_entry_content(struct p2m_domain *p2m,<br />
 void ept_walk_table(struct domain *d, unsigned long gfn)<br />
 {<br />
     struct p2m_domain *p2m = p2m_get_hostp2m(d);<br />
-    ept_entry_t *table = map_domain_page(ept_get_asr(d));<br />
+    struct ept_data *ept = &amp;p2m-&gt;ept;<br />
+    ept_entry_t *table =  map_domain_page(pagetable_get_pfn(p2m_get_pagetable(p2m)));<br />
     unsigned long gfn_remainder = gfn;<br />
 <br />
     int i;<br />
@@ -638,7 +644,7 @@ void ept_walk_table(struct domain *d, unsigned long gfn)<br />
         goto out;<br />
     }<br />
 <br />
-    for ( i = ept_get_wl(d); i &gt;= 0; i-- )<br />
+    for ( i = ept_get_wl(ept); i &gt;= 0; i-- )<br />
     {<br />
         ept_entry_t *ept_entry, *next;<br />
         u32 index;<br />
@@ -778,24 +784,76 @@ static void ept_change_entry_type_page(mfn_t ept_page_mfn, int ept_page_level,<br />
 static void ept_change_entry_type_global(struct p2m_domain *p2m,<br />
                                          p2m_type_t ot, p2m_type_t nt)<br />
 {<br />
-    struct domain *d = p2m-&gt;domain;<br />
-    if ( ept_get_asr(d) == 0 )<br />
+    struct ept_data *ept = &amp;p2m-&gt;ept;<br />
+    if ( ept_get_asr(ept) == 0 )<br />
         return;<br />
 <br />
     BUG_ON(p2m_is_grant(ot) || p2m_is_grant(nt));<br />
     BUG_ON(ot != nt &amp;&amp; (ot == p2m_mmio_direct || nt == p2m_mmio_direct));<br />
 <br />
-    ept_change_entry_type_page(_mfn(ept_get_asr(d)), ept_get_wl(d), ot, nt);<br />
+    ept_change_entry_type_page(_mfn(ept_get_asr(ept)),<br />
+            ept_get_wl(ept), ot, nt);<br />
+<br />
+    ept_sync_domain(p2m);<br />
+}<br />
+<br />
+static void __ept_sync_domain(void *info)<br />
+{<br />
+    struct ept_data *ept = &amp;((struct p2m_domain *)info)-&gt;ept;<br />
 <br />
-    ept_sync_domain(d);<br />
+    __invept(INVEPT_SINGLE_CONTEXT, ept_get_eptp(ept), 0);<br />
 }<br />
 <br />
-void ept_p2m_init(struct p2m_domain *p2m)<br />
+void ept_sync_domain(struct p2m_domain *p2m)<br />
 {<br />
+    struct domain *d = p2m-&gt;domain;<br />
+    struct ept_data *ept = &amp;p2m-&gt;ept;<br />
+    /* Only if using EPT and this domain has some VCPUs to dirty. */<br />
+    if ( !paging_mode_hap(d) || !d-&gt;vcpu || !d-&gt;vcpu[0] )<br />
+        return;<br />
+<br />
+    ASSERT(local_irq_is_enabled());<br />
+<br />
+    /*<br />
+     * Flush active cpus synchronously. Flush others the next time this domain<br />
+     * is scheduled onto them. We accept the race of other CPUs adding to<br />
+     * the ept_synced mask before on_selected_cpus() reads it, resulting in<br />
+     * unnecessary extra flushes, to avoid allocating a cpumask_t on the stack.<br />
+     */<br />
+    cpumask_and(ept_get_synced_mask(ept),<br />
+                d-&gt;domain_dirty_cpumask, &amp;cpu_online_map);<br />
+<br />
+    on_selected_cpus(ept_get_synced_mask(ept),<br />
+                     __ept_sync_domain, p2m, 1);<br />
+}<br />
+<br />
+int ept_p2m_init(struct p2m_domain *p2m)<br />
+{<br />
+    struct ept_data *ept = &amp;p2m-&gt;ept;<br />
+<br />
     p2m-&gt;set_entry = ept_set_entry;<br />
     p2m-&gt;get_entry = ept_get_entry;<br />
     p2m-&gt;change_entry_type_global = ept_change_entry_type_global;<br />
     p2m-&gt;audit_p2m = NULL;<br />
+<br />
+    /* Set the memory type used when accessing EPT paging structures. */<br />
+    ept-&gt;ept_mt = EPT_DEFAULT_MT;<br />
+<br />
+    /* set EPT page-walk length, now it's actual walk length - 1, i.e. 3 */<br />
+    ept-&gt;ept_wl = 3;<br />
+<br />
+    if ( !zalloc_cpumask_var(&amp;ept-&gt;synced_mask) )<br />
+        return -ENOMEM;<br />
+<br />
+    on_each_cpu(__ept_sync_domain, p2m, 1);<br />
+<br />
+    return 0;<br />
+}<br />
+<br />
+void ept_p2m_uninit(struct p2m_domain *p2m)<br />
+{<br />
+    struct ept_data *ept = &amp;p2m-&gt;ept;<br />
+    free_cpumask_var(ept-&gt;synced_mask);<br />
 }<br />
 <br />
 static void ept_dump_p2m_table(unsigned char key)<br />
@@ -811,6 +869,7 @@ static void ept_dump_p2m_table(unsigned char key)<br />
     unsigned long gfn, gfn_remainder;<br />
     unsigned long record_counter = 0;<br />
     struct p2m_domain *p2m;<br />
+    struct ept_data *ept;<br />
 <br />
     for_each_domain(d)<br />
     {<br />
@@ -818,15 +877,16 @@ static void ept_dump_p2m_table(unsigned char key)<br />
             continue;<br />
 <br />
         p2m = p2m_get_hostp2m(d);<br />
+        ept = &amp;p2m-&gt;ept;<br />
         printk(&quot;\ndomain%d EPT p2m table: \n&quot;, d-&gt;domain_id);<br />
 <br />
         for ( gfn = 0; gfn &lt;= p2m-&gt;max_mapped_pfn; gfn += (1 &lt;&lt; order) )<br />
         {<br />
             gfn_remainder = gfn;<br />
             mfn = _mfn(INVALID_MFN);<br />
-            table = map_domain_page(ept_get_asr(d));<br />
+            table = map_domain_page(pagetable_get_pfn(p2m_get_pagetable(p2m)));<br />
 <br />
-            for ( i = ept_get_wl(d); i &gt; 0; i-- )<br />
+            for ( i = ept_get_wl(ept); i &gt; 0; i-- )<br />
             {<br />
                 ret = ept_next_level(p2m, 1, &amp;table, &amp;gfn_remainder, i);<br />
                 if ( ret != GUEST_TABLE_NORMAL_PAGE )<br />
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c<br />
index 41a461b..49eb8af 100644<br />
--- a/xen/arch/x86/mm/p2m.c<br />
+++ b/xen/arch/x86/mm/p2m.c<br />
@@ -57,8 +57,10 @@ boolean_param(&quot;hap_2mb&quot;, opt_hap_2mb);<br />
 <br />
 <br />
 /* Init the datastructures for later use by the p2m code */<br />
-static void p2m_initialise(struct domain *d, struct p2m_domain *p2m)<br />
+static int p2m_initialise(struct domain *d, struct p2m_domain *p2m)<br />
 {<br />
+    int ret = 0;<br />
+<br />
     mm_rwlock_init(&amp;p2m-&gt;lock);<br />
     mm_lock_init(&amp;p2m-&gt;pod.lock);<br />
     INIT_LIST_HEAD(&amp;p2m-&gt;np2m_list);<br />
@@ -72,27 +74,81 @@ static void p2m_initialise(struct domain *d, struct p2m_domain *p2m)<br />
     p2m-&gt;np2m_base = P2M_BASE_EADDR;<br />
 <br />
     if ( hap_enabled(d) &amp;&amp; cpu_has_vmx )<br />
-        ept_p2m_init(p2m);<br />
+        ret = ept_p2m_init(p2m);<br />
     else<br />
         p2m_pt_init(p2m);<br />
 <br />
-    return;<br />
+    return ret;<br />
+}<br />
+<br />
+static struct p2m_domain *p2m_init_one(struct domain *d)<br />
+{<br />
+    struct p2m_domain *p2m = xzalloc(struct p2m_domain);<br />
+<br />
+    if ( !p2m )<br />
+        return NULL;<br />
+<br />
+    if ( !zalloc_cpumask_var(&amp;p2m-&gt;dirty_cpumask) )<br />
+        goto free_p2m;<br />
+<br />
+    if ( p2m_initialise(d, p2m) )<br />
+        goto free_cpumask;<br />
+    return p2m;<br />
+<br />
+free_cpumask:<br />
+    free_cpumask_var(p2m-&gt;dirty_cpumask);<br />
+free_p2m:<br />
+    xfree(p2m);<br />
+    return NULL;<br />
 }<br />
 <br />
-static int<br />
-p2m_init_nestedp2m(struct domain *d)<br />
+static void p2m_free_one(struct p2m_domain *p2m)<br />
+{<br />
+    if ( hap_enabled(p2m-&gt;domain) &amp;&amp; cpu_has_vmx )<br />
+        ept_p2m_uninit(p2m);<br />
+    free_cpumask_var(p2m-&gt;dirty_cpumask);<br />
+    xfree(p2m);<br />
+}<br />
+<br />
+static int p2m_init_hostp2m(struct domain *d)<br />
+{<br />
+    struct p2m_domain *p2m = p2m_init_one(d);<br />
+<br />
+    if ( p2m )<br />
+    {<br />
+        d-&gt;arch.p2m = p2m;<br />
+        return 0;<br />
+    }<br />
+    return -ENOMEM;<br />
+}<br />
+<br />
+static void p2m_teardown_hostp2m(struct domain *d)<br />
+{<br />
+    /* Iterate over all p2m tables per domain */<br />
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);<br />
+<br />
+    if ( p2m ) {<br />
+        p2m_free_one(p2m);<br />
+        d-&gt;arch.p2m = NULL;<br />
+    }<br />
+}<br />
+<br />
+static void p2m_teardown_nestedp2m(struct domain *d);<br />
+<br />
+static int p2m_init_nestedp2m(struct domain *d)<br />
 {<br />
     uint8_t i;<br />
     struct p2m_domain *p2m;<br />
 <br />
     mm_lock_init(&amp;d-&gt;arch.nested_p2m_lock);<br />
-    for (i = 0; i &lt; MAX_NESTEDP2M; i++) {<br />
-        d-&gt;arch.nested_p2m<i> = p2m = xzalloc(struct p2m_domain);<br />
-        if (p2m == NULL)<br />
-            return -ENOMEM;<br />
-        if ( !zalloc_cpumask_var(&amp;p2m-&gt;dirty_cpumask) )<br />
+    for (i = 0; i &lt; MAX_NESTEDP2M; i++)<br />
+    {<br />
+        d-&gt;arch.nested_p2m<i> = p2m = p2m_init_one(d);<br />
+        if ( p2m == NULL )<br />
+        {<br />
+            p2m_teardown_nestedp2m(d);<br />
             return -ENOMEM;<br />
-        p2m_initialise(d, p2m);<br />
+        }<br />
         p2m-&gt;write_p2m_entry = nestedp2m_write_p2m_entry;<br />
         list_add(&amp;p2m-&gt;np2m_list, &amp;p2m_get_hostp2m(d)-&gt;np2m_list);<br />
     }<br />
@@ -100,27 +156,37 @@ p2m_init_nestedp2m(struct domain *d)<br />
     return 0;<br />
 }<br />
 <br />
-int p2m_init(struct domain *d)<br />
+static void p2m_teardown_nestedp2m(struct domain *d)<br />
 {<br />
+    uint8_t i;<br />
     struct p2m_domain *p2m;<br />
-    int rc;<br />
 <br />
-    p2m_get_hostp2m(d) = p2m = xzalloc(struct p2m_domain);<br />
-    if ( p2m == NULL )<br />
-        return -ENOMEM;<br />
-    if ( !zalloc_cpumask_var(&amp;p2m-&gt;dirty_cpumask) )<br />
+    for (i = 0; i &lt; MAX_NESTEDP2M; i++)<br />
     {<br />
-        xfree(p2m);<br />
-        return -ENOMEM;<br />
+        if ( !d-&gt;arch.nested_p2m<i> )<br />
+            continue;<br />
+        p2m = d-&gt;arch.nested_p2m<i>;<br />
+        list_del(&amp;p2m-&gt;np2m_list);<br />
+        p2m_free_one(p2m);<br />
+        d-&gt;arch.nested_p2m<i> = NULL;<br />
     }<br />
-    p2m_initialise(d, p2m);<br />
+}<br />
+<br />
+int p2m_init(struct domain *d)<br />
+{<br />
+    int rc;<br />
+<br />
+    rc = p2m_init_hostp2m(d);<br />
+    if ( rc )<br />
+        return rc;<br />
 <br />
     /* Must initialise nestedp2m unconditionally<br />
      * since nestedhvm_enabled(d) returns false here.<br />
      * (p2m_init runs too early for HVM_PARAM_* options) */<br />
     rc = p2m_init_nestedp2m(d);<br />
-    if ( rc ) <br />
-        p2m_final_teardown(d);<br />
+    if ( rc )<br />
+        p2m_teardown_hostp2m(d);<br />
+<br />
     return rc;<br />
 }<br />
 <br />
@@ -421,28 +487,12 @@ void p2m_teardown(struct p2m_domain *p2m)<br />
     p2m_unlock(p2m);<br />
 }<br />
 <br />
-static void p2m_teardown_nestedp2m(struct domain *d)<br />
-{<br />
-    uint8_t i;<br />
-<br />
-    for (i = 0; i &lt; MAX_NESTEDP2M; i++) {<br />
-        if ( !d-&gt;arch.nested_p2m<i> )<br />
-            continue;<br />
-        free_cpumask_var(d-&gt;arch.nested_p2m<i>-&gt;dirty_cpumask);<br />
-        xfree(d-&gt;arch.nested_p2m<i>);<br />
-        d-&gt;arch.nested_p2m<i> = NULL;<br />
-    }<br />
-}<br />
-<br />
 void p2m_final_teardown(struct domain *d)<br />
 {<br />
     /* Iterate over all p2m tables per domain */<br />
-    if ( d-&gt;arch.p2m )<br />
-    {<br />
-        free_cpumask_var(d-&gt;arch.p2m-&gt;dirty_cpumask);<br />
-        xfree(d-&gt;arch.p2m);<br />
-        d-&gt;arch.p2m = NULL;<br />
-    }<br />
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);<br />
+    if ( p2m )<br />
+        p2m_teardown_hostp2m(d);<br />
 <br />
     /* We must teardown unconditionally because<br />
      * we initialise them unconditionally.<br />
diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h<br />
index 9a728b6..2d38b43 100644<br />
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h<br />
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h<br />
@@ -56,26 +56,27 @@ struct vmx_msr_state {<br />
 <br />
 #define EPT_DEFAULT_MT      MTRR_TYPE_WRBACK<br />
 <br />
-struct vmx_domain {<br />
-    unsigned long apic_access_mfn;<br />
+struct ept_data{<br />
     union {<br />
-        struct {<br />
+    struct {<br />
             u64 ept_mt :3,<br />
                 ept_wl :3,<br />
                 rsvd   :6,<br />
                 asr    :52;<br />
         };<br />
         u64 eptp;<br />
-    } ept_control;<br />
-    cpumask_var_t ept_synced;<br />
+    };<br />
+    cpumask_var_t synced_mask;<br />
+};<br />
+<br />
+struct vmx_domain {<br />
+    unsigned long apic_access_mfn;<br />
 };<br />
 <br />
-#define ept_get_wl(d)   \<br />
-    ((d)-&gt;arch.hvm_domain.vmx.ept_control.ept_wl)<br />
-#define ept_get_asr(d)  \<br />
-    ((d)-&gt;arch.hvm_domain.vmx.ept_control.asr)<br />
-#define ept_get_eptp(d) \<br />
-    ((d)-&gt;arch.hvm_domain.vmx.ept_control.eptp)<br />
+#define ept_get_wl(ept)   ((ept)-&gt;ept_wl)<br />
+#define ept_get_asr(ept)  ((ept)-&gt;asr)<br />
+#define ept_get_eptp(ept) ((ept)-&gt;eptp)<br />
+#define ept_get_synced_mask(ept) ((ept)-&gt;synced_mask)<br />
 <br />
 struct arch_vmx_struct {<br />
     /* Virtual address of VMCS. */<br />
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h<br />
index c73946f..d4d6feb 100644<br />
--- a/xen/include/asm-x86/hvm/vmx/vmx.h<br />
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h<br />
@@ -363,7 +363,7 @@ static inline void ept_sync_all(void)<br />
     __invept(INVEPT_ALL_CONTEXT, 0, 0);<br />
 }<br />
 <br />
-void ept_sync_domain(struct domain *d);<br />
+void ept_sync_domain(struct p2m_domain *p2m);<br />
 <br />
 static inline void vpid_sync_vcpu_gva(struct vcpu *v, unsigned long gva)<br />
 {<br />
@@ -425,12 +425,18 @@ void vmx_get_segment_register(struct vcpu *, enum x86_segment,<br />
 void vmx_inject_extint(int trap);<br />
 void vmx_inject_nmi(void);<br />
 <br />
-void ept_p2m_init(struct p2m_domain *p2m);<br />
+int ept_p2m_init(struct p2m_domain *p2m);<br />
+void ept_p2m_uninit(struct p2m_domain *p2m);<br />
+<br />
 void ept_walk_table(struct domain *d, unsigned long gfn);<br />
 void setup_ept_dump(void);<br />
 <br />
 void update_guest_eip(void);<br />
 <br />
+int alloc_p2m_hap_data(struct p2m_domain *p2m);<br />
+void free_p2m_hap_data(struct p2m_domain *p2m);<br />
+void p2m_init_hap_data(struct p2m_domain *p2m);<br />
+<br />
 /* EPT violation qualifications definitions */<br />
 #define _EPT_READ_VIOLATION         0<br />
 #define EPT_READ_VIOLATION          (1UL&lt;&lt;_EPT_READ_VIOLATION)<br />
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h<br />
index ce26594..b6a84b6 100644<br />
--- a/xen/include/asm-x86/p2m.h<br />
+++ b/xen/include/asm-x86/p2m.h<br />
@@ -277,6 +277,10 @@ struct p2m_domain {<br />
         mm_lock_t        lock;         /* Locking of private pod structs,   *<br />
                                         * not relying on the p2m lock.      */<br />
     } pod;<br />
+    union {<br />
+        struct ept_data ept;<br />
+        /* NPT-equivalent structure could be added here. */<br />
+    };<br />
 };<br />
 <br />
 /* get host p2m table */<br />
-- <br />
1.7.1<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]</i></i></i></i></i></i></i></i></i>]]></description>
            <dc:creator>Xiantao Zhang</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Mon, 24 Dec 2012 22:31:38 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1698371,1698371#msg-1698371</guid>
            <title>[Xen-devel] [PATCH v4 09/10] nVMX: virutalize VPID capability to nested VMM. (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1698371,1698371#msg-1698371</link>
            <description><![CDATA[ From: Zhang Xiantao &lt;xiantao.zhang@intel.com&gt;<br />
<br />
Virtualize VPID for the nested vmm, use host's VPID<br />
to emualte guest's VPID. For each virtual vmentry, if<br />
guest'v vpid is changed, allocate a new host VPID for<br />
L2 guest.<br />
<br />
Signed-off-by: Zhang Xiantao &lt;xiantao.zhang@intel.com&gt;<br />
Acked-by: Tim Deegan &lt;tim@xen.org&gt;<br />
---<br />
 xen/arch/x86/hvm/vmx/vmx.c         |   11 ++++++-<br />
 xen/arch/x86/hvm/vmx/vvmx.c        |   52 +++++++++++++++++++++++++++++++++++-<br />
 xen/include/asm-x86/hvm/vmx/vvmx.h |    2 +<br />
 3 files changed, 62 insertions(+), 3 deletions(-)<br />
<br />
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c<br />
index 94cac17..0e479f8 100644<br />
--- a/xen/arch/x86/hvm/vmx/vmx.c<br />
+++ b/xen/arch/x86/hvm/vmx/vmx.c<br />
@@ -2578,10 +2578,14 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)<br />
             update_guest_eip();<br />
         break;<br />
 <br />
+    case EXIT_REASON_INVVPID:<br />
+        if ( nvmx_handle_invvpid(regs) == X86EMUL_OKAY )<br />
+            update_guest_eip();<br />
+        break;<br />
+<br />
     case EXIT_REASON_MWAIT_INSTRUCTION:<br />
     case EXIT_REASON_MONITOR_INSTRUCTION:<br />
     case EXIT_REASON_GETSEC:<br />
-    case EXIT_REASON_INVVPID:<br />
         /*<br />
          * We should never exit on GETSEC because CR4.SMXE is always 0 when<br />
          * running in guest context, and the CPU checks that before getting<br />
@@ -2699,8 +2703,11 @@ void vmx_vmenter_helper(void)<br />
 <br />
     if ( !cpu_has_vmx_vpid )<br />
         goto out;<br />
+    if ( nestedhvm_vcpu_in_guestmode(curr) )<br />
+        p_asid = &amp;vcpu_nestedhvm(curr).nv_n2asid;<br />
+    else<br />
+        p_asid = &amp;curr-&gt;arch.hvm_vcpu.n1asid;<br />
 <br />
-    p_asid = &amp;curr-&gt;arch.hvm_vcpu.n1asid;<br />
     old_asid = p_asid-&gt;asid;<br />
     need_flush = hvm_asid_handle_vmenter(p_asid);<br />
     new_asid = p_asid-&gt;asid;<br />
diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c<br />
index c31f7ba..c54ee44 100644<br />
--- a/xen/arch/x86/hvm/vmx/vvmx.c<br />
+++ b/xen/arch/x86/hvm/vmx/vvmx.c<br />
@@ -42,6 +42,7 @@ int nvmx_vcpu_initialise(struct vcpu *v)<br />
 	goto out;<br />
     }<br />
     nvmx-&gt;ept.enabled = 0;<br />
+    nvmx-&gt;guest_vpid = 0;<br />
     nvmx-&gt;vmxon_region_pa = 0;<br />
     nvcpu-&gt;nv_vvmcx = NULL;<br />
     nvcpu-&gt;nv_vvmcxaddr = VMCX_EADDR;<br />
@@ -882,6 +883,16 @@ static uint64_t get_shadow_eptp(struct vcpu *v)<br />
     return ept_get_eptp(ept);<br />
 }<br />
 <br />
+static bool_t nvmx_vpid_enabled(struct nestedvcpu *nvcpu)<br />
+{<br />
+    uint32_t second_cntl;<br />
+<br />
+    second_cntl = __get_vvmcs(nvcpu-&gt;nv_vvmcx, SECONDARY_VM_EXEC_CONTROL);<br />
+    if ( second_cntl &amp; SECONDARY_EXEC_ENABLE_VPID )<br />
+        return 1;<br />
+    return 0;<br />
+}<br />
+<br />
 static void virtual_vmentry(struct cpu_user_regs *regs)<br />
 {<br />
     struct vcpu *v = current;<br />
@@ -930,6 +941,18 @@ static void virtual_vmentry(struct cpu_user_regs *regs)<br />
     if ( nestedhvm_paging_mode_hap(v) )<br />
         __vmwrite(EPT_POINTER, get_shadow_eptp(v));<br />
 <br />
+    /* nested VPID support! */<br />
+    if ( cpu_has_vmx_vpid &amp;&amp; nvmx_vpid_enabled(nvcpu) )<br />
+    {<br />
+        struct nestedvmx *nvmx = &amp;vcpu_2_nvmx(v);<br />
+        uint32_t new_vpid =  __get_vvmcs(vvmcs, VIRTUAL_PROCESSOR_ID);<br />
+        if ( nvmx-&gt;guest_vpid != new_vpid )<br />
+        {<br />
+            hvm_asid_flush_vcpu_asid(&amp;vcpu_nestedhvm(v).nv_n2asid);<br />
+            nvmx-&gt;guest_vpid = new_vpid;<br />
+        }<br />
+    }<br />
+<br />
 }<br />
 <br />
 static void sync_vvmcs_guest_state(struct vcpu *v, struct cpu_user_regs *regs)<br />
@@ -1221,7 +1244,7 @@ int nvmx_handle_vmlaunch(struct cpu_user_regs *regs)<br />
     if ( vcpu_nestedhvm(v).nv_vvmcxaddr == VMCX_EADDR )<br />
     {<br />
         vmreturn (regs, VMFAIL_INVALID);<br />
-        return X86EMUL_OKAY;        <br />
+        return X86EMUL_OKAY;<br />
     }<br />
 <br />
     launched = __get_vvmcs(vcpu_nestedhvm(v).nv_vvmcx,<br />
@@ -1433,6 +1456,33 @@ int nvmx_handle_invept(struct cpu_user_regs *regs)<br />
     (((__emul_value(enable1, default1) &amp; host_value) &amp; (~0ul &lt;&lt; 32)) | \<br />
     ((uint32_t)(__emul_value(enable1, default1) | host_value)))<br />
 <br />
+int nvmx_handle_invvpid(struct cpu_user_regs *regs)<br />
+{<br />
+    struct vmx_inst_decoded decode;<br />
+    unsigned long vpid;<br />
+    u64 inv_type;<br />
+<br />
+    if ( decode_vmx_inst(regs, &amp;decode, &amp;vpid, 0) != X86EMUL_OKAY )<br />
+        return X86EMUL_EXCEPTION;<br />
+<br />
+    inv_type = reg_read(regs, decode.reg2);<br />
+<br />
+    switch ( inv_type ) {<br />
+    /* Just invalidate all tlb entries for all types! */<br />
+    case INVVPID_INDIVIDUAL_ADDR:<br />
+    case INVVPID_SINGLE_CONTEXT:<br />
+    case INVVPID_ALL_CONTEXT:<br />
+        hvm_asid_flush_vcpu_asid(&amp;vcpu_nestedhvm(current).nv_n2asid);<br />
+        break;<br />
+    default:<br />
+        vmreturn(regs, VMFAIL_INVALID);<br />
+        return X86EMUL_OKAY;<br />
+    }<br />
+<br />
+    vmreturn(regs, VMSUCCEED);<br />
+    return X86EMUL_OKAY;<br />
+}<br />
+<br />
 /*<br />
  * Capability reporting<br />
  */<br />
diff --git a/xen/include/asm-x86/hvm/vmx/vvmx.h b/xen/include/asm-x86/hvm/vmx/vvmx.h<br />
index e671635..d1368a3 100644<br />
--- a/xen/include/asm-x86/hvm/vmx/vvmx.h<br />
+++ b/xen/include/asm-x86/hvm/vmx/vvmx.h<br />
@@ -37,6 +37,7 @@ struct nestedvmx {<br />
         uint32_t exit_reason;<br />
         uint32_t exit_qual;<br />
     } ept;<br />
+    uint32_t guest_vpid;<br />
 };<br />
 <br />
 #define vcpu_2_nvmx(v)	(vcpu_nestedhvm(v).u.nvmx)<br />
@@ -190,6 +191,7 @@ int nvmx_handle_vmwrite(struct cpu_user_regs *regs);<br />
 int nvmx_handle_vmresume(struct cpu_user_regs *regs);<br />
 int nvmx_handle_vmlaunch(struct cpu_user_regs *regs);<br />
 int nvmx_handle_invept(struct cpu_user_regs *regs);<br />
+int nvmx_handle_invvpid(struct cpu_user_regs *regs);<br />
 int nvmx_msr_read_intercept(unsigned int msr,<br />
                                 u64 *msr_content);<br />
 int nvmx_msr_write_intercept(unsigned int msr,<br />
-- <br />
1.7.1<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Xiantao Zhang</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Mon, 24 Dec 2012 22:31:37 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1698370,1698370#msg-1698370</guid>
            <title>[Xen-devel] [PATCH v4 01/10] nestedhap: Change hostcr3 and p2m-&gt;cr3 to meaningful words (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1698370,1698370#msg-1698370</link>
            <description><![CDATA[ From: Zhang Xiantao &lt;xiantao.zhang@intel.com&gt;<br />
<br />
VMX doesn't have the concept about host cr3 for nested p2m,<br />
and only SVM has, so change it to netural words.<br />
<br />
Signed-off-by: Zhang Xiantao &lt;xiantao.zhang@intel.com&gt;<br />
Acked-by: Tim Deegan &lt;tim@xen.org&gt;<br />
---<br />
 xen/arch/x86/hvm/hvm.c             |    6 +++---<br />
 xen/arch/x86/hvm/svm/svm.c         |    2 +-<br />
 xen/arch/x86/hvm/vmx/vmx.c         |    2 +-<br />
 xen/arch/x86/hvm/vmx/vvmx.c        |    2 +-<br />
 xen/arch/x86/mm/hap/nested_hap.c   |   15 ++++++++-------<br />
 xen/arch/x86/mm/mm-locks.h         |    2 +-<br />
 xen/arch/x86/mm/p2m.c              |   26 +++++++++++++-------------<br />
 xen/include/asm-x86/hvm/hvm.h      |    4 ++--<br />
 xen/include/asm-x86/hvm/vmx/vvmx.h |    2 +-<br />
 xen/include/asm-x86/p2m.h          |   16 ++++++++--------<br />
 10 files changed, 39 insertions(+), 38 deletions(-)<br />
<br />
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c<br />
index 40c1ab2..f63ee52 100644<br />
--- a/xen/arch/x86/hvm/hvm.c<br />
+++ b/xen/arch/x86/hvm/hvm.c<br />
@@ -4536,10 +4536,10 @@ uint64_t nhvm_vcpu_guestcr3(struct vcpu *v)<br />
     return -EOPNOTSUPP;<br />
 }<br />
 <br />
-uint64_t nhvm_vcpu_hostcr3(struct vcpu *v)<br />
+uint64_t nhvm_vcpu_p2m_base(struct vcpu *v)<br />
 {<br />
-    if (hvm_funcs.nhvm_vcpu_hostcr3)<br />
-        return hvm_funcs.nhvm_vcpu_hostcr3(v);<br />
+    if ( hvm_funcs.nhvm_vcpu_p2m_base )<br />
+        return hvm_funcs.nhvm_vcpu_p2m_base(v);<br />
     return -EOPNOTSUPP;<br />
 }<br />
 <br />
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c<br />
index 55a5ae5..2c8504a 100644<br />
--- a/xen/arch/x86/hvm/svm/svm.c<br />
+++ b/xen/arch/x86/hvm/svm/svm.c<br />
@@ -2003,7 +2003,7 @@ static struct hvm_function_table __read_mostly svm_function_table = {<br />
     .nhvm_vcpu_vmexit = nsvm_vcpu_vmexit_inject,<br />
     .nhvm_vcpu_vmexit_trap = nsvm_vcpu_vmexit_trap,<br />
     .nhvm_vcpu_guestcr3 = nsvm_vcpu_guestcr3,<br />
-    .nhvm_vcpu_hostcr3 = nsvm_vcpu_hostcr3,<br />
+    .nhvm_vcpu_p2m_base = nsvm_vcpu_hostcr3,<br />
     .nhvm_vcpu_asid = nsvm_vcpu_asid,<br />
     .nhvm_vmcx_guest_intercepts_trap = nsvm_vmcb_guest_intercepts_trap,<br />
     .nhvm_vmcx_hap_enabled = nsvm_vmcb_hap_enabled,<br />
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c<br />
index aee1f9e..98309da 100644<br />
--- a/xen/arch/x86/hvm/vmx/vmx.c<br />
+++ b/xen/arch/x86/hvm/vmx/vmx.c<br />
@@ -1504,7 +1504,7 @@ static struct hvm_function_table __read_mostly vmx_function_table = {<br />
     .nhvm_vcpu_destroy    = nvmx_vcpu_destroy,<br />
     .nhvm_vcpu_reset      = nvmx_vcpu_reset,<br />
     .nhvm_vcpu_guestcr3   = nvmx_vcpu_guestcr3,<br />
-    .nhvm_vcpu_hostcr3    = nvmx_vcpu_hostcr3,<br />
+    .nhvm_vcpu_p2m_base   = nvmx_vcpu_eptp_base,<br />
     .nhvm_vcpu_asid       = nvmx_vcpu_asid,<br />
     .nhvm_vmcx_guest_intercepts_trap = nvmx_intercepts_exception,<br />
     .nhvm_vcpu_vmexit_trap = nvmx_vmexit_trap,<br />
diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c<br />
index 7b27d2d..6999c25 100644<br />
--- a/xen/arch/x86/hvm/vmx/vvmx.c<br />
+++ b/xen/arch/x86/hvm/vmx/vvmx.c<br />
@@ -94,7 +94,7 @@ uint64_t nvmx_vcpu_guestcr3(struct vcpu *v)<br />
     return 0;<br />
 }<br />
 <br />
-uint64_t nvmx_vcpu_hostcr3(struct vcpu *v)<br />
+uint64_t nvmx_vcpu_eptp_base(struct vcpu *v)<br />
 {<br />
     /* TODO */<br />
     ASSERT(0);<br />
diff --git a/xen/arch/x86/mm/hap/nested_hap.c b/xen/arch/x86/mm/hap/nested_hap.c<br />
index 317875d..f9a5edc 100644<br />
--- a/xen/arch/x86/mm/hap/nested_hap.c<br />
+++ b/xen/arch/x86/mm/hap/nested_hap.c<br />
@@ -48,9 +48,10 @@<br />
  *    1. If #NPF is from L1 guest, then we crash the guest VM (same as old <br />
  *       code)<br />
  *    2. If #NPF is from L2 guest, then we continue from (3)<br />
- *    3. Get h_cr3 from L1 guest. Map h_cr3 into L0 hypervisor address space.<br />
- *    4. Walk the h_cr3 page table<br />
- *    5.    - if not present, then we inject #NPF back to L1 guest and <br />
+ *    3. Get np2m base from L1 guest. Map np2m base into L0 hypervisor address space.<br />
+ *    4. Walk the np2m's  page table<br />
+ *    5.    - if not present or permission check failure, then we inject #NPF back to <br />
+ *    L1 guest and <br />
  *            re-launch L1 guest (L1 guest will either treat this #NPF as MMIO,<br />
  *            or fix its p2m table for L2 guest)<br />
  *    6.    - if present, then we will get the a new translated value L1-GPA <br />
@@ -89,7 +90,7 @@ nestedp2m_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,<br />
 <br />
     if (old_flags &amp; _PAGE_PRESENT)<br />
         flush_tlb_mask(p2m-&gt;dirty_cpumask);<br />
-    <br />
+<br />
     paging_unlock(d);<br />
 }<br />
 <br />
@@ -110,7 +111,7 @@ nestedhap_fix_p2m(struct vcpu *v, struct p2m_domain *p2m,<br />
     /* If this p2m table has been flushed or recycled under our feet, <br />
      * leave it alone.  We'll pick up the right one as we try to <br />
      * vmenter the guest. */<br />
-    if ( p2m-&gt;cr3 == nhvm_vcpu_hostcr3(v) )<br />
+    if ( p2m-&gt;np2m_base == nhvm_vcpu_p2m_base(v) )<br />
     {<br />
         unsigned long gfn, mask;<br />
         mfn_t mfn;<br />
@@ -186,7 +187,7 @@ nestedhap_walk_L1_p2m(struct vcpu *v, paddr_t L2_gpa, paddr_t *L1_gpa,<br />
     uint32_t pfec;<br />
     unsigned long nested_cr3, gfn;<br />
     <br />
-    nested_cr3 = nhvm_vcpu_hostcr3(v);<br />
+    nested_cr3 = nhvm_vcpu_p2m_base(v);<br />
 <br />
     pfec = PFEC_user_mode | PFEC_page_present;<br />
     if (access_w)<br />
@@ -221,7 +222,7 @@ nestedhvm_hap_nested_page_fault(struct vcpu *v, paddr_t *L2_gpa,<br />
     p2m_type_t p2mt_10;<br />
 <br />
     p2m = p2m_get_hostp2m(d); /* L0 p2m */<br />
-    nested_p2m = p2m_get_nestedp2m(v, nhvm_vcpu_hostcr3(v));<br />
+    nested_p2m = p2m_get_nestedp2m(v, nhvm_vcpu_p2m_base(v));<br />
 <br />
     /* walk the L1 P2M table */<br />
     rv = nestedhap_walk_L1_p2m(v, *L2_gpa, &amp;L1_gpa, &amp;page_order_21,<br />
diff --git a/xen/arch/x86/mm/mm-locks.h b/xen/arch/x86/mm/mm-locks.h<br />
index 3700e32..1817f81 100644<br />
--- a/xen/arch/x86/mm/mm-locks.h<br />
+++ b/xen/arch/x86/mm/mm-locks.h<br />
@@ -249,7 +249,7 @@ declare_mm_order_constraint(per_page_sharing)<br />
  * A per-domain lock that protects the mapping from nested-CR3 to <br />
  * nested-p2m.  In particular it covers:<br />
  * - the array of nested-p2m tables, and all LRU activity therein; and<br />
- * - setting the &quot;cr3&quot; field of any p2m table to a non-CR3_EADDR value. <br />
+ * - setting the &quot;cr3&quot; field of any p2m table to a non-P2M_BASE_EAADR value. <br />
  *   (i.e. assigning a p2m table to be the shadow of that cr3 */<br />
 <br />
 /* PoD lock (per-p2m-table)<br />
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c<br />
index 258f46e..41a461b 100644<br />
--- a/xen/arch/x86/mm/p2m.c<br />
+++ b/xen/arch/x86/mm/p2m.c<br />
@@ -69,7 +69,7 @@ static void p2m_initialise(struct domain *d, struct p2m_domain *p2m)<br />
     p2m-&gt;domain = d;<br />
     p2m-&gt;default_access = p2m_access_rwx;<br />
 <br />
-    p2m-&gt;cr3 = CR3_EADDR;<br />
+    p2m-&gt;np2m_base = P2M_BASE_EADDR;<br />
 <br />
     if ( hap_enabled(d) &amp;&amp; cpu_has_vmx )<br />
         ept_p2m_init(p2m);<br />
@@ -1433,7 +1433,7 @@ p2m_flush_table(struct p2m_domain *p2m)<br />
     ASSERT(page_list_empty(&amp;p2m-&gt;pod.single));<br />
 <br />
     /* This is no longer a valid nested p2m for any address space */<br />
-    p2m-&gt;cr3 = CR3_EADDR;<br />
+    p2m-&gt;np2m_base = P2M_BASE_EADDR;<br />
     <br />
     /* Zap the top level of the trie */<br />
     top = mfn_to_page(pagetable_get_mfn(p2m_get_pagetable(p2m)));<br />
@@ -1471,7 +1471,7 @@ p2m_flush_nestedp2m(struct domain *d)<br />
 }<br />
 <br />
 struct p2m_domain *<br />
-p2m_get_nestedp2m(struct vcpu *v, uint64_t cr3)<br />
+p2m_get_nestedp2m(struct vcpu *v, uint64_t np2m_base)<br />
 {<br />
     /* Use volatile to prevent gcc to cache nv-&gt;nv_p2m in a cpu register as<br />
      * this may change within the loop by an other (v)cpu.<br />
@@ -1480,8 +1480,8 @@ p2m_get_nestedp2m(struct vcpu *v, uint64_t cr3)<br />
     struct domain *d;<br />
     struct p2m_domain *p2m;<br />
 <br />
-    /* Mask out low bits; this avoids collisions with CR3_EADDR */<br />
-    cr3 &amp;= ~(0xfffull);<br />
+    /* Mask out low bits; this avoids collisions with P2M_BASE_EADDR */<br />
+    np2m_base &amp;= ~(0xfffull);<br />
 <br />
     if (nv-&gt;nv_flushp2m &amp;&amp; nv-&gt;nv_p2m) {<br />
         nv-&gt;nv_p2m = NULL;<br />
@@ -1493,14 +1493,14 @@ p2m_get_nestedp2m(struct vcpu *v, uint64_t cr3)<br />
     if ( p2m ) <br />
     {<br />
         p2m_lock(p2m);<br />
-        if ( p2m-&gt;cr3 == cr3 || p2m-&gt;cr3 == CR3_EADDR )<br />
+        if ( p2m-&gt;np2m_base == np2m_base || p2m-&gt;np2m_base == P2M_BASE_EADDR )<br />
         {<br />
             nv-&gt;nv_flushp2m = 0;<br />
             p2m_getlru_nestedp2m(d, p2m);<br />
             nv-&gt;nv_p2m = p2m;<br />
-            if (p2m-&gt;cr3 == CR3_EADDR)<br />
+            if ( p2m-&gt;np2m_base == P2M_BASE_EADDR )<br />
                 hvm_asid_flush_vcpu(v);<br />
-            p2m-&gt;cr3 = cr3;<br />
+            p2m-&gt;np2m_base = np2m_base;<br />
             cpumask_set_cpu(v-&gt;processor, p2m-&gt;dirty_cpumask);<br />
             p2m_unlock(p2m);<br />
             nestedp2m_unlock(d);<br />
@@ -1515,7 +1515,7 @@ p2m_get_nestedp2m(struct vcpu *v, uint64_t cr3)<br />
     p2m_flush_table(p2m);<br />
     p2m_lock(p2m);<br />
     nv-&gt;nv_p2m = p2m;<br />
-    p2m-&gt;cr3 = cr3;<br />
+    p2m-&gt;np2m_base = np2m_base;<br />
     nv-&gt;nv_flushp2m = 0;<br />
     hvm_asid_flush_vcpu(v);<br />
     cpumask_set_cpu(v-&gt;processor, p2m-&gt;dirty_cpumask);<br />
@@ -1531,7 +1531,7 @@ p2m_get_p2m(struct vcpu *v)<br />
     if (!nestedhvm_is_n2(v))<br />
         return p2m_get_hostp2m(v-&gt;domain);<br />
 <br />
-    return p2m_get_nestedp2m(v, nhvm_vcpu_hostcr3(v));<br />
+    return p2m_get_nestedp2m(v, nhvm_vcpu_p2m_base(v));<br />
 }<br />
 <br />
 unsigned long paging_gva_to_gfn(struct vcpu *v,<br />
@@ -1549,15 +1549,15 @@ unsigned long paging_gva_to_gfn(struct vcpu *v,<br />
         struct p2m_domain *p2m;<br />
         const struct paging_mode *mode;<br />
         uint32_t pfec_21 = *pfec;<br />
-        uint64_t ncr3 = nhvm_vcpu_hostcr3(v);<br />
+        uint64_t np2m_base = nhvm_vcpu_p2m_base(v);<br />
 <br />
         /* translate l2 guest va into l2 guest gfn */<br />
-        p2m = p2m_get_nestedp2m(v, ncr3);<br />
+        p2m = p2m_get_nestedp2m(v, np2m_base);<br />
         mode = paging_get_nestedmode(v);<br />
         gfn = mode-&gt;gva_to_gfn(v, p2m, va, pfec);<br />
 <br />
         /* translate l2 guest gfn into l1 guest gfn */<br />
-        return hostmode-&gt;p2m_ga_to_gfn(v, hostp2m, ncr3,<br />
+        return hostmode-&gt;p2m_ga_to_gfn(v, hostp2m, np2m_base,<br />
                                        gfn &lt;&lt; PAGE_SHIFT, &amp;pfec_21, NULL);<br />
     }<br />
 <br />
diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h<br />
index fdb0f58..d3535b6 100644<br />
--- a/xen/include/asm-x86/hvm/hvm.h<br />
+++ b/xen/include/asm-x86/hvm/hvm.h<br />
@@ -170,7 +170,7 @@ struct hvm_function_table {<br />
                                 uint64_t exitcode);<br />
     int (*nhvm_vcpu_vmexit_trap)(struct vcpu *v, struct hvm_trap *trap);<br />
     uint64_t (*nhvm_vcpu_guestcr3)(struct vcpu *v);<br />
-    uint64_t (*nhvm_vcpu_hostcr3)(struct vcpu *v);<br />
+    uint64_t (*nhvm_vcpu_p2m_base)(struct vcpu *v);<br />
     uint32_t (*nhvm_vcpu_asid)(struct vcpu *v);<br />
     int (*nhvm_vmcx_guest_intercepts_trap)(struct vcpu *v, <br />
                                unsigned int trapnr, int errcode);<br />
@@ -475,7 +475,7 @@ uint64_t nhvm_vcpu_guestcr3(struct vcpu *v);<br />
 /* returns l1 guest's cr3 that points to the page table used to<br />
  * translate l2 guest physical address to l1 guest physical address.<br />
  */<br />
-uint64_t nhvm_vcpu_hostcr3(struct vcpu *v);<br />
+uint64_t nhvm_vcpu_p2m_base(struct vcpu *v);<br />
 /* returns the asid number l1 guest wants to use to run the l2 guest */<br />
 uint32_t nhvm_vcpu_asid(struct vcpu *v);<br />
 <br />
diff --git a/xen/include/asm-x86/hvm/vmx/vvmx.h b/xen/include/asm-x86/hvm/vmx/vvmx.h<br />
index dce2cd8..d97011d 100644<br />
--- a/xen/include/asm-x86/hvm/vmx/vvmx.h<br />
+++ b/xen/include/asm-x86/hvm/vmx/vvmx.h<br />
@@ -99,7 +99,7 @@ int nvmx_vcpu_initialise(struct vcpu *v);<br />
 void nvmx_vcpu_destroy(struct vcpu *v);<br />
 int nvmx_vcpu_reset(struct vcpu *v);<br />
 uint64_t nvmx_vcpu_guestcr3(struct vcpu *v);<br />
-uint64_t nvmx_vcpu_hostcr3(struct vcpu *v);<br />
+uint64_t nvmx_vcpu_eptp_base(struct vcpu *v);<br />
 uint32_t nvmx_vcpu_asid(struct vcpu *v);<br />
 enum hvm_intblk nvmx_intr_blocked(struct vcpu *v);<br />
 int nvmx_intercepts_exception(struct vcpu *v, <br />
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h<br />
index 2bd2048..ce26594 100644<br />
--- a/xen/include/asm-x86/p2m.h<br />
+++ b/xen/include/asm-x86/p2m.h<br />
@@ -197,17 +197,17 @@ struct p2m_domain {<br />
 <br />
     struct domain     *domain;   /* back pointer to domain */<br />
 <br />
-    /* Nested p2ms only: nested-CR3 value that this p2m shadows. <br />
-     * This can be cleared to CR3_EADDR under the per-p2m lock but<br />
+    /* Nested p2ms only: nested p2m base value that this p2m shadows. <br />
+     * This can be cleared to P2M_BASE_EADDR under the per-p2m lock but<br />
      * needs both the per-p2m lock and the per-domain nestedp2m lock<br />
      * to set it to any other value. */<br />
-#define CR3_EADDR     (~0ULL)<br />
-    uint64_t           cr3;<br />
+#define P2M_BASE_EADDR     (~0ULL)<br />
+    uint64_t           np2m_base;<br />
 <br />
     /* Nested p2ms: linked list of n2pms allocated to this domain. <br />
      * The host p2m hasolds the head of the list and the np2ms are <br />
      * threaded on in LRU order. */<br />
-    struct list_head np2m_list; <br />
+    struct list_head   np2m_list; <br />
 <br />
 <br />
     /* Host p2m: when this flag is set, don't flush all the nested-p2m <br />
@@ -282,11 +282,11 @@ struct p2m_domain {<br />
 /* get host p2m table */<br />
 #define p2m_get_hostp2m(d)      ((d)-&gt;arch.p2m)<br />
 <br />
-/* Get p2m table (re)usable for specified cr3.<br />
+/* Get p2m table (re)usable for specified np2m base.<br />
  * Automatically destroys and re-initializes a p2m if none found.<br />
- * If cr3 == 0 then v-&gt;arch.hvm_vcpu.guest_cr[3] is used.<br />
+ * If np2m_base == 0 then v-&gt;arch.hvm_vcpu.guest_cr[3] is used.<br />
  */<br />
-struct p2m_domain *p2m_get_nestedp2m(struct vcpu *v, uint64_t cr3);<br />
+struct p2m_domain *p2m_get_nestedp2m(struct vcpu *v, uint64_t np2m_base);<br />
 <br />
 /* If vcpu is in host mode then behaviour matches p2m_get_hostp2m().<br />
  * If vcpu is in guest mode then behaviour matches p2m_get_nestedp2m().<br />
-- <br />
1.7.1<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Xiantao Zhang</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Mon, 24 Dec 2012 22:31:35 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1697737,1697737#msg-1697737</guid>
            <title>[Xen-devel] test report for Xen 4.2.1 release (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1697737,1697737#msg-1697737</link>
            <description><![CDATA[ Hi All,<br />
We did some testing for Xen 4.2.1 RC1, RC2 and final RELEASE version on Intel SandyBridge and Westmere platforms.<br />
We found no regression and no fixed bug in our bug tracking list.<br />
We covered basic Windows &amp; Linux guest bootup, live migration, power management, VT-d, SR-IOV, vCPU hot-plug features.<br />
<br />
Xen: 4.2.1 RC1/RC2/RELEASE (xen-4.2-testing.hg tree)<br />
Dom0: Linux 3.7.1<br />
<br />
<br />
Best Regards,<br />
     Yongjie (Jay)<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Ren, Yongjie</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Mon, 24 Dec 2012 17:13:59 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1697034,1697034#msg-1697034</guid>
            <title>[Xen-devel] (updated) test report for xen-unstable tree with upstream QEMU (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1697034,1697034#msg-1697034</link>
            <description><![CDATA[ Hi All,<br />
We did some testing for Xen-unstable tree with upstream QEMU.<br />
We covered basic guest booting up, power management, VT-d, SR-IOV features.<br />
We found 4 new bugs which only exist in upstream QEMU not in qemu-xen.<br />
<br />
We followed the below wiki page to use upstream QEMU.<br />
[<a href="http://wiki.xen.org/wiki/QEMU_Upstream"  rel="nofollow">wiki.xen.org</a>]<br />
<br />
test tree:<br />
xen-unstable-tree.hg: C/S 26193 (about 20 days ago)<br />
qemu.git: commit e9bff10f8db (about 20 days ago)<br />
Dom0: Linux 3.6.9 release version.<br />
<br />
test machine:<br />
Intel Westmere-EP and SandyBridge-EP systems.<br />
<br />
new bugs (which don't exist with qemu-xen-unstable tree):<br />
1. 'maxvcpus=NUM' item is not supported in upstream QEMU<br />
  [<a href="http://bugzilla.xen.org/bugzilla/show_bug.cgi?id=1837"  rel="nofollow">bugzilla.xen.org</a>]<br />
  -- This blocked vCPU hot-plug for HVM guest.<br />
2. Guest console hangs after save/restore or live-migration when setting 'hpet=0' in guest config file<br />
  [<a href="http://bugzilla.xen.org/bugzilla/show_bug.cgi?id=1838"  rel="nofollow">bugzilla.xen.org</a>]<br />
3. 'xen_platform_pci=0' setting cannot make the guest use emulated PCI devices by default<br />
  [<a href="http://bugzilla.xen.org/bugzilla/show_bug.cgi?id=1839"  rel="nofollow">bugzilla.xen.org</a>]<br />
4. Guest free memory with upstream qemu is 14MB lower than that with qemu-xen-unstable.git<br />
  [<a href="http://bugzilla.xen.org/bugzilla/show_bug.cgi?id=1836"  rel="nofollow">bugzilla.xen.org</a>]<br />
  -- This might not be a bug; we just curious to know what the additional 14MB memory is for.<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Ren, Yongjie</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Mon, 24 Dec 2012 10:32:23 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1697019,1697019#msg-1697019</guid>
            <title>[Xen-devel] test report for xen-unstable tree with upstream QEMU (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1697019,1697019#msg-1697019</link>
            <description><![CDATA[ Hi All,<br />
We did some testing for Xen-unstable tree with upstream QEMU.<br />
We covered basic guest booting up, power management, VT-d, SR-IOV features.<br />
We found 4 new bugs which only exist in upstream QEMU not in qemu-xen.<br />
<br />
We followed the below wiki page to use upstream QEMU.<br />
[<a href="http://wiki.xen.org/wiki/QEMU_Upstream"  rel="nofollow">wiki.xen.org</a>]<br />
<br />
test tree:<br />
xen-unstable-tree.hg: C/S 26193 (about 20 days ago)<br />
qemu.git: commit e9bff10f8db (about 20 days ago)<br />
Dom0: Linux 3.6.9 release version.<br />
<br />
test machine:<br />
Intel Westmere-EP and SandyBridge-EP systems.<br />
<br />
new bugs (which don't exist with qemu-xen-unstable tree):<br />
1. 'maxvcpus=NUM' item is not supported in upstream QEMU<br />
  [<a href="http://bugzilla.xen.org/bugzilla/show_bug.cgi?id=1837"  rel="nofollow">bugzilla.xen.org</a>]<br />
  -- This blocked vCPU hot-plug for HVM guest.<br />
2. Guest console hangs after save/restore or live-migration when setting 'hpet=0' in guest config file<br />
  [<a href="http://bugzilla.xen.org/bugzilla/show_bug.cgi?id=1837"  rel="nofollow">bugzilla.xen.org</a>]<br />
3. 'xen_platform_pci=0' setting cannot make the guest use emulated PCI devices by default<br />
  [<a href="http://bugzilla.xen.org/bugzilla/show_bug.cgi?id=1839"  rel="nofollow">bugzilla.xen.org</a>]<br />
4. Guest free memory with upstream qemu is 14MB lower than that with qemu-xen-unstable.git<br />
  [<a href="http://bugzilla.xen.org/bugzilla/show_bug.cgi?id=1836"  rel="nofollow">bugzilla.xen.org</a>]<br />
  -- This might not be a bug; we just curious to know what the additional 14MB memory is for.<br />
<br />
<br />
Best Regards,<br />
     Yongjie (Jay)<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Ren, Yongjie</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Mon, 24 Dec 2012 10:24:05 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1695912,1695912#msg-1695912</guid>
            <title>[Xen-devel] [RFC 2/8] xen_platform: do not use old_portio-style callbacks (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1695912,1695912#msg-1695912</link>
            <description><![CDATA[ Signed-off-by: Hervé Poussineau &lt;hpoussin@reactos.org&gt;<br />
---<br />
 hw/xen_platform.c |   21 ++++++++++-----------<br />
 1 file changed, 10 insertions(+), 11 deletions(-)<br />
<br />
diff --git a/hw/xen_platform.c b/hw/xen_platform.c<br />
index a54e7a2..ad7cb06 100644<br />
--- a/hw/xen_platform.c<br />
+++ b/hw/xen_platform.c<br />
@@ -280,7 +280,8 @@ static void platform_fixed_ioport_init(PCIXenPlatformState* s)<br />
 <br />
 /* Xen Platform PCI Device */<br />
 <br />
-static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)<br />
+static uint64_t xen_platform_ioport_readb(void *opaque, hwaddr addr,<br />
+                                          unsigned int size)<br />
 {<br />
     if (addr == 0) {<br />
         return platform_fixed_ioport_readb(opaque, 0);<br />
@@ -289,30 +290,28 @@ static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)<br />
     }<br />
 }<br />
 <br />
-static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)<br />
+static void xen_platform_ioport_writeb(void *opaque, hwaddr addr,<br />
+                                       uint64_t val, unsigned int size)<br />
 {<br />
     PCIXenPlatformState *s = opaque;<br />
 <br />
     switch (addr) {<br />
     case 0: /* Platform flags */<br />
-        platform_fixed_ioport_writeb(opaque, 0, val);<br />
+        platform_fixed_ioport_writeb(opaque, 0, (uint32_t)val);<br />
         break;<br />
     case 8:<br />
-        log_writeb(s, val);<br />
+        log_writeb(s, (uint32_t)val);<br />
         break;<br />
     default:<br />
         break;<br />
     }<br />
 }<br />
 <br />
-static MemoryRegionPortio xen_pci_portio[] = {<br />
-    { 0, 0x100, 1, .read = xen_platform_ioport_readb, },<br />
-    { 0, 0x100, 1, .write = xen_platform_ioport_writeb, },<br />
-    PORTIO_END_OF_LIST()<br />
-};<br />
-<br />
 static const MemoryRegionOps xen_pci_io_ops = {<br />
-    .old_portio = xen_pci_portio,<br />
+    .read  = xen_platform_ioport_readb,<br />
+    .write = xen_platform_ioport_writeb,<br />
+    .impl.min_access_size = 1,<br />
+    .impl.max_access_size = 1,<br />
 };<br />
 <br />
 static void platform_ioport_bar_setup(PCIXenPlatformState *d)<br />
-- <br />
1.7.10.4<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Hervé Poussineau</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Mon, 24 Dec 2012 03:19:36 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1694549,1694549#msg-1694549</guid>
            <title>[Xen-devel] Creating guest with less than 4MB RAM causes Xen to crash immediately (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1694549,1694549#msg-1694549</link>
            <description><![CDATA[ Keir, Tim and IanJ<br />
<br />
When user creates a guest with less than 4MB of memory, Xen crashes<br />
immediately. That's because:<br />
<br />
      * libxc round up memory to 4MB and build page table for the guest,<br />
        see xc_dom_x86.c:count_pgtables. So the virt_pgtab_end is at<br />
        least 0x400000.<br />
      * When Xen try to pin page table for guest, it will scan through<br />
        page table and invoke arch/x86/mm.c:get_page_type, which has a<br />
        assertion that if any error happens the rc should only be<br />
        -EINVAL, otherwise Xen crashes.<br />
      * For a guest with less than 4MB memory, some of the entries in<br />
        the page table are not valid, causing __get_page_type to fail<br />
        with -EBUSY, which causes the assertion to fail.<br />
<br />
In practice few people will create a DomU with less than 4MB ram. I<br />
encounter this because I was trying to boot up ~3K+ minios.<br />
<br />
Xen console log and xl output files attached.<br />
<br />
<br />
Wei.<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Wei Liu</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sun, 23 Dec 2012 15:36:13 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1693012,1693012#msg-1693012</guid>
            <title>[Xen-devel] How to use the vTPM backend driver in the pv-ops kernel (2 replies)</title>
            <link>http://choon.net/forum/read.php?22,1693012,1693012#msg-1693012</link>
            <description><![CDATA[ Hi,<br />
<br />
I cannot find the vTPM config option CONFIG_XEN_TPMDEV_BACKEND in the config file of pv-ops kernel, such as kernel 2.6.32.50. However, this option exists in the config file of kernel version 2.6.18.8. I also cannot find the vTPM backed driver (such as linux-2.6.18-xen.hg/drivers/xen/tpmback ) in the pv-ops kernel.<br />
So, how can I configure and use the vTPM backend driver in kernel 2.6.32?<br />
Thank you for any advice.<br />
<br />
<br />
<br />
Best Regards,<br />
Gavin_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>gavin</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sun, 23 Dec 2012 21:12:21 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1692286,1692286#msg-1692286</guid>
            <title>[Xen-devel] how to run a qcow format para-virtualized machine with blktap modules used (2 replies)</title>
            <link>http://choon.net/forum/read.php?22,1692286,1692286#msg-1692286</link>
            <description><![CDATA[ Hi,guys,<br />
first of all,I'm working on xen 4.1 and xen 3.4.I need your help corresponding to these two kinds of xen.<br />
As I know ,para-virtualized machines will use blktap for their read/write and full-virtualized machines will use qemu. I have seen that there are block-qcow.c and block-qcow2.c in blktap/drives/, and I would like to use them for my VM's reading and writing.I plan to create raw-format image as bascking file image and then create qcow format images based on the raw-format one.I know it need to use para-virtualized machines.<br />
I have tried like these:<br />
I create a para-virtualized machine with config file in which vmlinuz and initrd are needed. when I finish the VM's os installation, I use bootloader pygrub to take the place of vmlinuz and initrd.Then I create a qcow format image based on the one created just now.but the vm could not been set up normally.<br />
so I failed.<br />
who could help me to create a para-virtualized machine which take a qcow format image as its virtual disk (and this qcow image is based on a backing file )?<br />
I need your help and the deadline is coming,exactly tomorrow is my deadline.<br />
<br />
<br />
<br />
<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>hxkhust</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sat, 22 Dec 2012 23:56:39 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1691765,1691765#msg-1691765</guid>
            <title>[Xen-devel] [xen-unstable test] 14810: tolerable FAIL (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1691765,1691765#msg-1691765</link>
            <description><![CDATA[ flight 14810 xen-unstable real [real]<br />
[<a href="http://www.chiark.greenend.org.uk/~xensrcts/logs/14810/"  rel="nofollow">www.chiark.greenend.org.uk</a>]<br />
<br />
Failures :-/ but no regressions.<br />
<br />
Regressions which are regarded as allowable (not blocking):<br />
 test-amd64-amd64-xl-sedf-pin 10 guest-saverestore            fail   like 14807<br />
 test-amd64-amd64-xl-sedf      5 xen-boot                     fail   like 14807<br />
<br />
Tests which did not succeed, but are not blocking:<br />
 test-amd64-amd64-xl-pcipt-intel  9 guest-start                 fail never pass<br />
 test-amd64-i386-xend-winxpsp3 16 leak-check/check             fail  never pass<br />
 test-amd64-i386-win          16 leak-check/check             fail   never pass<br />
 test-amd64-i386-xl-win-vcpus1 13 guest-stop                   fail  never pass<br />
 test-amd64-i386-qemut-win-vcpus1 16 leak-check/check           fail never pass<br />
 test-amd64-amd64-xl-qemuu-winxpsp3 13 guest-stop               fail never pass<br />
 test-amd64-amd64-win         16 leak-check/check             fail   never pass<br />
 test-amd64-i386-xl-win7-amd64 13 guest-stop                   fail  never pass<br />
 test-amd64-i386-xl-qemut-win7-amd64 13 guest-stop              fail never pass<br />
 test-amd64-i386-win-vcpus1   16 leak-check/check             fail   never pass<br />
 test-amd64-amd64-xl-winxpsp3 13 guest-stop                   fail   never pass<br />
 test-amd64-i386-xl-qemut-winxpsp3-vcpus1 13 guest-stop         fail never pass<br />
 test-amd64-i386-xl-winxpsp3-vcpus1 13 guest-stop               fail never pass<br />
 test-amd64-i386-xl-qemut-win-vcpus1 13 guest-stop              fail never pass<br />
 test-amd64-i386-xend-qemut-winxpsp3 16 leak-check/check        fail never pass<br />
 test-amd64-i386-qemut-win    16 leak-check/check             fail   never pass<br />
 test-amd64-amd64-xl-qemut-win7-amd64 13 guest-stop             fail never pass<br />
 test-amd64-amd64-xl-win7-amd64 13 guest-stop                   fail never pass<br />
 test-amd64-amd64-xl-qemuu-win7-amd64 13 guest-stop             fail never pass<br />
 test-amd64-amd64-xl-win      13 guest-stop                   fail   never pass<br />
 test-amd64-amd64-qemut-win   16 leak-check/check             fail   never pass<br />
 test-amd64-amd64-xl-qemut-win 13 guest-stop                   fail  never pass<br />
 test-amd64-amd64-xl-qemut-winxpsp3 13 guest-stop               fail never pass<br />
<br />
version targeted for testing:<br />
 xen                  c4114a042410<br />
baseline version:<br />
 xen                  c4114a042410<br />
<br />
jobs:<br />
 build-amd64                                                  pass    <br />
 build-i386                                                   pass    <br />
 build-amd64-oldkern                                          pass    <br />
 build-i386-oldkern                                           pass    <br />
 build-amd64-pvops                                            pass    <br />
 build-i386-pvops                                             pass    <br />
 test-amd64-amd64-xl                                          pass    <br />
 test-amd64-i386-xl                                           pass    <br />
 test-amd64-i386-rhel6hvm-amd                                 pass    <br />
 test-amd64-i386-qemut-rhel6hvm-amd                           pass    <br />
 test-amd64-i386-qemuu-rhel6hvm-amd                           pass    <br />
 test-amd64-amd64-xl-qemut-win7-amd64                         fail    <br />
 test-amd64-i386-xl-qemut-win7-amd64                          fail    <br />
 test-amd64-amd64-xl-qemuu-win7-amd64                         fail    <br />
 test-amd64-amd64-xl-win7-amd64                               fail    <br />
 test-amd64-i386-xl-win7-amd64                                fail    <br />
 test-amd64-i386-xl-credit2                                   pass    <br />
 test-amd64-amd64-xl-pcipt-intel                              fail    <br />
 test-amd64-i386-rhel6hvm-intel                               pass    <br />
 test-amd64-i386-qemut-rhel6hvm-intel                         pass    <br />
 test-amd64-i386-qemuu-rhel6hvm-intel                         pass    <br />
 test-amd64-i386-xl-multivcpu                                 pass    <br />
 test-amd64-amd64-pair                                        pass    <br />
 test-amd64-i386-pair                                         pass    <br />
 test-amd64-amd64-xl-sedf-pin                                 fail    <br />
 test-amd64-amd64-pv                                          pass    <br />
 test-amd64-i386-pv                                           pass    <br />
 test-amd64-amd64-xl-sedf                                     fail    <br />
 test-amd64-i386-win-vcpus1                                   fail    <br />
 test-amd64-i386-qemut-win-vcpus1                             fail    <br />
 test-amd64-i386-xl-qemut-win-vcpus1                          fail    <br />
 test-amd64-i386-xl-win-vcpus1                                fail    <br />
 test-amd64-i386-xl-qemut-winxpsp3-vcpus1                     fail    <br />
 test-amd64-i386-xl-winxpsp3-vcpus1                           fail    <br />
 test-amd64-amd64-win                                         fail    <br />
 test-amd64-i386-win                                          fail    <br />
 test-amd64-amd64-qemut-win                                   fail    <br />
 test-amd64-i386-qemut-win                                    fail    <br />
 test-amd64-amd64-xl-qemut-win                                fail    <br />
 test-amd64-amd64-xl-win                                      fail    <br />
 test-amd64-i386-xend-qemut-winxpsp3                          fail    <br />
 test-amd64-amd64-xl-qemut-winxpsp3                           fail    <br />
 test-amd64-amd64-xl-qemuu-winxpsp3                           fail    <br />
 test-amd64-i386-xend-winxpsp3                                fail    <br />
 test-amd64-amd64-xl-winxpsp3                                 fail    <br />
<br />
<br />
------------------------------------------------------------<br />
sg-report-flight on woking.cam.xci-test.com<br />
logs: /home/xc_osstest/logs<br />
images: /home/xc_osstest/images<br />
<br />
Logs, config files, etc. are available at<br />
    [<a href="http://www.chiark.greenend.org.uk/~xensrcts/logs"  rel="nofollow">www.chiark.greenend.org.uk</a>]<br />
<br />
Test harness code can be found at<br />
    [<a href="http://xenbits.xensource.com/gitweb?p=osstest.git;a=summary"  rel="nofollow">xenbits.xensource.com</a>]<br />
<br />
<br />
Published tested tree is already up to date.<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>xen.org</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sat, 22 Dec 2012 18:22:06 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1690749,1690749#msg-1690749</guid>
            <title>[Xen-devel] [xen-unstable test] 14807: tolerable FAIL - PUSHED (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1690749,1690749#msg-1690749</link>
            <description><![CDATA[ flight 14807 xen-unstable real [real]<br />
[<a href="http://www.chiark.greenend.org.uk/~xensrcts/logs/14807/"  rel="nofollow">www.chiark.greenend.org.uk</a>]<br />
<br />
Failures :-/ but no regressions.<br />
<br />
Regressions which are regarded as allowable (not blocking):<br />
 test-amd64-amd64-xl-sedf-pin 10 guest-saverestore            fail   like 14805<br />
 test-amd64-amd64-xl-sedf      5 xen-boot                     fail   like 14805<br />
<br />
Tests which did not succeed, but are not blocking:<br />
 test-amd64-amd64-xl-pcipt-intel  9 guest-start                 fail never pass<br />
 test-amd64-i386-xend-winxpsp3 16 leak-check/check             fail  never pass<br />
 test-amd64-i386-win          16 leak-check/check             fail   never pass<br />
 test-amd64-i386-xl-win-vcpus1 13 guest-stop                   fail  never pass<br />
 test-amd64-i386-qemut-win-vcpus1 16 leak-check/check           fail never pass<br />
 test-amd64-amd64-xl-qemuu-winxpsp3 13 guest-stop               fail never pass<br />
 test-amd64-amd64-win         16 leak-check/check             fail   never pass<br />
 test-amd64-i386-xl-win7-amd64 13 guest-stop                   fail  never pass<br />
 test-amd64-i386-xl-qemut-win7-amd64 13 guest-stop              fail never pass<br />
 test-amd64-i386-win-vcpus1   16 leak-check/check             fail   never pass<br />
 test-amd64-amd64-xl-winxpsp3 13 guest-stop                   fail   never pass<br />
 test-amd64-i386-xl-qemut-winxpsp3-vcpus1 13 guest-stop         fail never pass<br />
 test-amd64-i386-xl-winxpsp3-vcpus1 13 guest-stop               fail never pass<br />
 test-amd64-i386-xl-qemut-win-vcpus1 13 guest-stop              fail never pass<br />
 test-amd64-i386-xend-qemut-winxpsp3 16 leak-check/check        fail never pass<br />
 test-amd64-i386-qemut-win    16 leak-check/check             fail   never pass<br />
 test-amd64-amd64-xl-qemut-win7-amd64 13 guest-stop             fail never pass<br />
 test-amd64-amd64-xl-win7-amd64 13 guest-stop                   fail never pass<br />
 test-amd64-amd64-xl-qemuu-win7-amd64 13 guest-stop             fail never pass<br />
 test-amd64-amd64-xl-win      13 guest-stop                   fail   never pass<br />
 test-amd64-amd64-qemut-win   16 leak-check/check             fail   never pass<br />
 test-amd64-amd64-xl-qemut-win 13 guest-stop                   fail  never pass<br />
 test-amd64-amd64-xl-qemut-winxpsp3 13 guest-stop               fail never pass<br />
<br />
version targeted for testing:<br />
 xen                  c4114a042410<br />
baseline version:<br />
 xen                  6f5c96855a9e<br />
<br />
------------------------------------------------------------<br />
People who touched revisions under test:<br />
  Ian Campbell &lt;ian.campbell@citrix.com&gt;<br />
  Ian Jackson &lt;ian.jackson@eu.citrix.com&gt;<br />
  Jan Beulich &lt;jbeulich@suse.com&gt;<br />
  Keir Fraser &lt;keir@xen.org&gt;<br />
  Roger Pau Monn_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>xen.org</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sat, 22 Dec 2012 12:31:45 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1689871,1689871#msg-1689871</guid>
            <title>[Xen-devel] [xen-unstable test] 14806: regressions - FAIL (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1689871,1689871#msg-1689871</link>
            <description><![CDATA[ flight 14806 xen-unstable real [real]<br />
[<a href="http://www.chiark.greenend.org.uk/~xensrcts/logs/14806/"  rel="nofollow">www.chiark.greenend.org.uk</a>]<br />
<br />
Regressions :-(<br />
<br />
Tests which did not succeed and are blocking,<br />
including tests which could not be run:<br />
 test-amd64-amd64-xl-qemut-win7-amd64  7 windows-install   fail REGR. vs. 14805<br />
<br />
Regressions which are regarded as allowable (not blocking):<br />
 test-amd64-amd64-xl-sedf-pin 10 guest-saverestore            fail   like 14805<br />
 test-amd64-amd64-xl-sedf      5 xen-boot                     fail   like 14805<br />
<br />
Tests which did not succeed, but are not blocking:<br />
 test-amd64-amd64-xl-pcipt-intel  9 guest-start                 fail never pass<br />
 test-amd64-i386-xend-winxpsp3 16 leak-check/check             fail  never pass<br />
 test-amd64-i386-win          16 leak-check/check             fail   never pass<br />
 test-amd64-i386-xl-win-vcpus1 13 guest-stop                   fail  never pass<br />
 test-amd64-i386-qemut-win-vcpus1 16 leak-check/check           fail never pass<br />
 test-amd64-amd64-xl-qemuu-winxpsp3 13 guest-stop               fail never pass<br />
 test-amd64-amd64-win         16 leak-check/check             fail   never pass<br />
 test-amd64-i386-xl-win7-amd64 13 guest-stop                   fail  never pass<br />
 test-amd64-i386-xl-qemut-win7-amd64 13 guest-stop              fail never pass<br />
 test-amd64-i386-win-vcpus1   16 leak-check/check             fail   never pass<br />
 test-amd64-amd64-xl-winxpsp3 13 guest-stop                   fail   never pass<br />
 test-amd64-i386-xl-qemut-winxpsp3-vcpus1 13 guest-stop         fail never pass<br />
 test-amd64-i386-xl-winxpsp3-vcpus1 13 guest-stop               fail never pass<br />
 test-amd64-i386-xl-qemut-win-vcpus1 13 guest-stop              fail never pass<br />
 test-amd64-i386-xend-qemut-winxpsp3 16 leak-check/check        fail never pass<br />
 test-amd64-i386-qemut-win    16 leak-check/check             fail   never pass<br />
 test-amd64-amd64-xl-win7-amd64 13 guest-stop                   fail never pass<br />
 test-amd64-amd64-xl-qemuu-win7-amd64 13 guest-stop             fail never pass<br />
 test-amd64-amd64-xl-win      13 guest-stop                   fail   never pass<br />
 test-amd64-amd64-qemut-win   16 leak-check/check             fail   never pass<br />
 test-amd64-amd64-xl-qemut-win 13 guest-stop                   fail  never pass<br />
 test-amd64-amd64-xl-qemut-winxpsp3 13 guest-stop               fail never pass<br />
<br />
version targeted for testing:<br />
 xen                  c4114a042410<br />
baseline version:<br />
 xen                  6f5c96855a9e<br />
<br />
------------------------------------------------------------<br />
People who touched revisions under test:<br />
  Ian Campbell &lt;ian.campbell@citrix.com&gt;<br />
  Ian Jackson &lt;ian.jackson@eu.citrix.com&gt;<br />
  Jan Beulich &lt;jbeulich@suse.com&gt;<br />
  Keir Fraser &lt;keir@xen.org&gt;<br />
  Roger Pau Monn_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>xen.org</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sat, 22 Dec 2012 07:17:05 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1689368,1689368#msg-1689368</guid>
            <title>Re: [Xen-devel] oopsable race in xen-gntdev (unsafe vma access) (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1689368,1689368#msg-1689368</link>
            <description><![CDATA[ On Sat, Dec 15, 2012 at 06:12:11PM +0000, Al Viro wrote:<br />
&gt; 	1) find_vma() is *not* safe without -&gt;mmap_sem and its result may<br />
&gt; very well be freed just as it's returned to caller.  IOW,<br />
&gt; gntdev_ioctl_get_offset_for_vaddr() is racy and may end up with<br />
&gt; dereferencing freed memory.<br />
&gt; <br />
&gt; 	2) gntdev_vma_close() is putting NULL into map-&gt;vma with only<br />
&gt; -&gt;mmap_sem held by caller.  Things like<br />
&gt;                 if (!map-&gt;vma)<br />
&gt;                         continue;<br />
&gt;                 if (map-&gt;vma-&gt;vm_start &gt;= end)<br />
&gt;                         continue;<br />
&gt;                 if (map-&gt;vma-&gt;vm_end &lt;= start)<br />
&gt; done with just priv-&gt;lock held are racy.<br />
&gt; <br />
&gt; 	I'm not familiar with the code, but it looks like we need to<br />
&gt; protect gntdev_vma_close() guts with the same spinlock and probably<br />
&gt; hold -&gt;mmap_sem shared around the &quot;find_vma()+get to map-&gt;{index,count}&quot;<br />
&gt; in the ioctl.  Or replace the logics in ioctl with search through the<br />
&gt; list of grant_map under the same spinlock...<br />
&gt; <br />
&gt; 	Comments?<br />
Hey Al,<br />
<br />
Thank you for your analysis.<br />
<br />
CC-ing Daniel, David and Stefano. I recall we had some priv-&gt;lock movement<br />
in the past and there is also interaction with another piece of code - <br />
the balloon code so we better be circumspect of not blowing up.<br />
<br />
Al, it is around holidays and folks are mostly gone - so this will take<br />
a bit of time to get sorted out.<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Konrad Rzeszutek Wilk</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sat, 22 Dec 2012 04:35:10 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1689206,1689206#msg-1689206</guid>
            <title>[Xen-devel] [RFC] QEMU: Enabling live-migrate on HVM on qemu-xen device model in 4.2 (4 replies)</title>
            <link>http://choon.net/forum/read.php?22,1689206,1689206#msg-1689206</link>
            <description><![CDATA[ This is a COMPILE TESTED ONLY RFC for a backport of the qemu elements<br />
of:<br />
  [<a href="http://marc.info/?l=qemu-devel&amp;m=134920288412400&amp;w=2"  rel="nofollow">marc.info</a>]<br />
<br />
This is	a companion patchset to	the libxl elements I published<br />
here:<br />
  [<a href="http://marc.info/?l=xen-devel&amp;m=135539631713838&amp;w=4"  rel="nofollow">marc.info</a>]<br />
which in turn are a backport of:<br />
  [<a href="http://marc.info/?l=xen-devel&amp;m=134944750724252"  rel="nofollow">marc.info</a>]<br />
<br />
Stefano: I know you said you were going to have a look at this, but<br />
I thought I'd have a go. It compiles, which is about all I can say<br />
for it.	  Feel free to throw away     and redo.<br />
<br />
Comments very welcome.<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Alex Bligh</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sat, 22 Dec 2012 03:41:21 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1689205,1689205#msg-1689205</guid>
            <title>[Xen-devel] [PATCH 2/5] xen: Introduce xen_modified_memory. (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1689205,1689205#msg-1689205</link>
            <description><![CDATA[ This function is to be used during live migration. Every write access to the<br />
guest memory should call this funcion so the Xen tools knows which pages are<br />
dirty.<br />
<br />
Backport of 910b38e4dc4c37683c8b821e75a7f4cf095e4b21<br />
<br />
Signed-off-by: Alex Bligh &lt;alex@alex.org.uk&gt;<br />
---<br />
 hw/xen.h   |    1 +<br />
 xen-all.c  |   21 +++++++++++++++++++++<br />
 xen-stub.c |    4 ++++<br />
 3 files changed, 26 insertions(+), 0 deletions(-)<br />
<br />
diff --git a/hw/xen.h b/hw/xen.h<br />
index 2162111..359a275 100644<br />
--- a/hw/xen.h<br />
+++ b/hw/xen.h<br />
@@ -45,6 +45,7 @@ void xenstore_store_pv_console_info(int i, struct CharDriverState *chr);<br />
 <br />
 #if defined(NEED_CPU_H) &amp;&amp; !defined(CONFIG_USER_ONLY)<br />
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size);<br />
+void xen_modified_memory(ram_addr_t start, ram_addr_t length);<br />
 #endif<br />
 <br />
 #if defined(CONFIG_XEN) &amp;&amp; CONFIG_XEN_CTRL_INTERFACE_VERSION &lt; 400<br />
diff --git a/xen-all.c b/xen-all.c<br />
index 6b4e511..121289d 100644<br />
--- a/xen-all.c<br />
+++ b/xen-all.c<br />
@@ -1135,3 +1135,24 @@ void destroy_hvm_domain(bool reboot)<br />
         xc_interface_close(xc_handle);<br />
     }<br />
 }<br />
+<br />
+void xen_modified_memory(ram_addr_t start, ram_addr_t length)<br />
+{<br />
+    if (unlikely(cpu_physical_memory_get_dirty_tracking())) {<br />
+        int rc;<br />
+        ram_addr_t start_pfn, nb_pages;<br />
+<br />
+        if (length == 0) {<br />
+            length = TARGET_PAGE_SIZE;<br />
+        }<br />
+        start_pfn = start &gt;&gt; TARGET_PAGE_BITS;<br />
+        nb_pages = ((start + length + TARGET_PAGE_SIZE - 1) &gt;&gt; TARGET_PAGE_BITS)<br />
+            - start_pfn;<br />
+        rc = xc_hvm_modified_memory(xen_xc, xen_domid, start_pfn, nb_pages);<br />
+        if (rc) {<br />
+            fprintf(stderr,<br />
+                    &quot;%s failed for &quot;RAM_ADDR_FMT&quot; (&quot;RAM_ADDR_FMT&quot;): %i, %s\n&quot;,<br />
+                    __func__, start, nb_pages, rc, strerror(-rc));<br />
+        }<br />
+    }<br />
+}<br />
diff --git a/xen-stub.c b/xen-stub.c<br />
index 25317ec..7b54477 100644<br />
--- a/xen-stub.c<br />
+++ b/xen-stub.c<br />
@@ -48,3 +48,7 @@ int xen_init(void)<br />
 void qmp_xen_set_global_dirty_log(bool enable, Error **errp)<br />
 {<br />
 }<br />
+<br />
+void xen_modified_memory(ram_addr_t start, ram_addr_t length)<br />
+{<br />
+}<br />
-- <br />
1.7.4.1<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Alex Bligh</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sat, 22 Dec 2012 03:41:17 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1688661,1688661#msg-1688661</guid>
            <title>[Xen-devel] [PATCH RFC 00/10] libxl: new hotplug calling convention (4 replies)</title>
            <link>http://choon.net/forum/read.php?22,1688661,1688661#msg-1688661</link>
            <description><![CDATA[ This series implements a new hoplug calling convention for libxl.<br />
<br />
The aim of this new convention is to reduce the blackout phase of <br />
migration when using complex hotplug scripts, like iSCSI or other kind <br />
of storage backends that might have a non trivial setup time.<br />
<br />
There are some issues that I would like to discuss, the first one is <br />
the fact that pdev_path field in libxl_device_disk is no longuer used <br />
to store a physical path, since diskspec &quot;target&quot; can now contain <br />
&quot;random&quot; information to connect a block device.<br />
<br />
To solve this I would like to introduce a new field in <br />
libxl_device_disk called &quot;target&quot;, that will be used to store the <br />
diskspec target parameter. This can later be copied to pdev_path if <br />
using the old hotplug calling convention.<br />
<br />
The second issue is related to iSCSI and iscsiadm, specifically the <br />
way to set authentication parameters, which is done with command line <br />
parameters or editing files (which each distro seems to place in <br />
different locations). I will look into this to see if we can find a <br />
suitable solution.<br />
<br />
Thanks for the comments, Roger.<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Roger Pau Monne</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sat, 22 Dec 2012 01:15:11 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1688660,1688660#msg-1688660</guid>
            <title>[Xen-devel] [PATCH RFC 01/10] libxl: libxl__prepare_ao_device should reset num_exec (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1688660,1688660#msg-1688660</link>
            <description><![CDATA[ num_exec was not cleared when calling libxl__prepare_ao_device.<br />
<br />
Signed-off-by: Roger Pau Monné &lt;roger.pau@citrix.com&gt;<br />
---<br />
 tools/libxl/libxl_device.c |    1 +<br />
 1 files changed, 1 insertions(+), 0 deletions(-)<br />
<br />
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c<br />
index 51dd06e..58d3f35 100644<br />
--- a/tools/libxl/libxl_device.c<br />
+++ b/tools/libxl/libxl_device.c<br />
@@ -409,6 +409,7 @@ void libxl__prepare_ao_device(libxl__ao *ao, libxl__ao_device *aodev)<br />
     aodev-&gt;ao = ao;<br />
     aodev-&gt;rc = 0;<br />
     aodev-&gt;dev = NULL;<br />
+    aodev-&gt;num_exec = 0;<br />
     /* Initialize timer for QEMU Bodge and hotplug execution */<br />
     libxl__ev_time_init(&amp;aodev-&gt;timeout);<br />
     aodev-&gt;active = 1;<br />
-- <br />
1.7.7.5 (Apple Git-26)<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Roger Pau Monne</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sat, 22 Dec 2012 01:15:08 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1688659,1688659#msg-1688659</guid>
            <title>[Xen-devel] [PATCH RFC 03/10] libxl: add new &quot;method&quot; parameter to xl disk config (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1688659,1688659#msg-1688659</link>
            <description><![CDATA[ This new diskspec parameters will set script to the value passed in<br />
method, and hotplug_version to 1.<br />
<br />
This patch adds the basic support to handle this new scripts, by<br />
adding the prepare/unprepare private libxl functions, and modifying<br />
the current domain creation/destruction to call this functions at the<br />
appropriate spots.<br />
<br />
This patch also adds some helpers, that will be used here and in later<br />
patches.<br />
<br />
Signed-off-by: Roger Pau Monné &lt;roger.pau@citrix.com&gt;<br />
---<br />
 tools/libxl/libxl.c          |  131 +++++++++++++++++++++++++++++++++++++++++-<br />
 tools/libxl/libxl_create.c   |   62 +++++++++++++++++++-<br />
 tools/libxl/libxl_device.c   |   80 +++++++++++++++++++------<br />
 tools/libxl/libxl_internal.h |   34 +++++++++++<br />
 tools/libxl/libxl_types.idl  |    1 +<br />
 tools/libxl/libxlu_disk_l.l  |    2 +<br />
 6 files changed, 288 insertions(+), 22 deletions(-)<br />
<br />
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c<br />
index 8d921bc..e141379 100644<br />
--- a/tools/libxl/libxl.c<br />
+++ b/tools/libxl/libxl.c<br />
@@ -1999,6 +1999,108 @@ int libxl__device_from_disk(libxl__gc *gc, uint32_t domid,<br />
     return 0;<br />
 }<br />
 <br />
+void libxl__device_disk_prepare(libxl__egc *egc, uint32_t domid,<br />
+                                libxl_device_disk *disk,<br />
+                                libxl__ao_device *aodev)<br />
+{<br />
+    STATE_AO_GC(aodev-&gt;ao);<br />
+    char *hotplug_path;<br />
+    char *script_path;<br />
+    int rc;<br />
+    xs_transaction_t t = XBT_NULL;<br />
+<br />
+    if (disk-&gt;hotplug_version == 0) {<br />
+        aodev-&gt;callback(egc, aodev);<br />
+        return;<br />
+    }<br />
+<br />
+    GCNEW(aodev-&gt;dev);<br />
+    rc = libxl__device_from_disk(gc, domid, disk, aodev-&gt;dev);<br />
+    if (rc != 0) {<br />
+        LOG(ERROR, &quot;Invalid or unsupported virtual disk identifier %s&quot;,<br />
+                   disk-&gt;vdev);<br />
+        goto error;<br />
+    }<br />
+<br />
+    script_path = libxl__abs_path(gc, disk-&gt;script,<br />
+                                  libxl__xen_script_dir_path());<br />
+<br />
+    hotplug_path = libxl__device_xs_hotplug_path(gc, aodev-&gt;dev);<br />
+    for (;;) {<br />
+        rc = libxl__xs_transaction_start(gc, &amp;t);<br />
+        if (rc) goto error;<br />
+<br />
+        rc = libxl__xs_write_checked(gc, t,<br />
+                                 GCSPRINTF(&quot;%s/params&quot;, hotplug_path),<br />
+                                 disk-&gt;pdev_path);<br />
+        if (rc)<br />
+            goto error;<br />
+<br />
+        rc = libxl__xs_write_checked(gc, t,<br />
+                                 GCSPRINTF(&quot;%s/script&quot;, hotplug_path),<br />
+                                 script_path);<br />
+        if (rc)<br />
+            goto error;<br />
+<br />
+        rc = libxl__xs_transaction_commit(gc, &amp;t);<br />
+        if (!rc) break;<br />
+        if (rc &lt; 0) goto error;<br />
+    }<br />
+<br />
+    aodev-&gt;action = DEVICE_PREPARE;<br />
+    aodev-&gt;hotplug_version = disk-&gt;hotplug_version;<br />
+    libxl__device_hotplug(egc, aodev);<br />
+    return;<br />
+<br />
+error:<br />
+    assert(rc);<br />
+    libxl__xs_transaction_abort(gc, &amp;t);<br />
+    aodev-&gt;rc = rc;<br />
+    aodev-&gt;callback(egc, aodev);<br />
+    return;<br />
+}<br />
+<br />
+void libxl__device_disk_unprepare(libxl__egc *egc, uint32_t domid,<br />
+                                  libxl_device_disk *disk,<br />
+                                  libxl__ao_device *aodev)<br />
+{<br />
+    STATE_AO_GC(aodev-&gt;ao);<br />
+    char *hotplug_path;<br />
+    int rc;<br />
+<br />
+    if (disk-&gt;hotplug_version == 0) {<br />
+        aodev-&gt;callback(egc, aodev);<br />
+        return;<br />
+    }<br />
+<br />
+    GCNEW(aodev-&gt;dev);<br />
+    rc = libxl__device_from_disk(gc, domid, disk, aodev-&gt;dev);<br />
+    if (rc != 0) {<br />
+        LOG(ERROR, &quot;Invalid or unsupported virtual disk identifier %s&quot;,<br />
+                   disk-&gt;vdev);<br />
+        goto error;<br />
+    }<br />
+<br />
+    hotplug_path = libxl__device_xs_hotplug_path(gc, aodev-&gt;dev);<br />
+    if (!libxl__xs_read(gc, XBT_NULL, hotplug_path)) {<br />
+        LOG(DEBUG, &quot;unable to unprepare device because %s doesn't exist&quot;,<br />
+                   hotplug_path);<br />
+        aodev-&gt;callback(egc, aodev);<br />
+        return;<br />
+    }<br />
+<br />
+    aodev-&gt;action = DEVICE_UNPREPARE;<br />
+    aodev-&gt;hotplug_version = disk-&gt;hotplug_version;<br />
+    libxl__device_hotplug(egc, aodev);<br />
+    return;<br />
+<br />
+error:<br />
+    assert(rc);<br />
+    aodev-&gt;rc = rc;<br />
+    aodev-&gt;callback(egc, aodev);<br />
+    return;<br />
+}<br />
+<br />
 /* Specific function called directly only by local disk attach,<br />
  * all other users should instead use the regular<br />
  * libxl__device_disk_add wrapper<br />
@@ -2058,8 +2160,15 @@ static void device_disk_add(libxl__egc *egc, uint32_t domid,<br />
                 dev = disk-&gt;pdev_path;<br />
 <br />
         do_backend_phy:<br />
-                flexarray_append(back, &quot;params&quot;);<br />
-                flexarray_append(back, dev);<br />
+                if (disk-&gt;hotplug_version == 0) {<br />
+                    /*<br />
+                     * If the new hotplug version is used params is<br />
+                     * stored under a private path, since it can contain<br />
+                     * data that the guest should not see.<br />
+                     */<br />
+                    flexarray_append(back, &quot;params&quot;);<br />
+                    flexarray_append(back, dev);<br />
+                }<br />
 <br />
                 script = libxl__abs_path(gc, disk-&gt;script?: &quot;block&quot;,<br />
                                          libxl__xen_script_dir_path());<br />
@@ -2152,6 +2261,7 @@ static void device_disk_add(libxl__egc *egc, uint32_t domid,<br />
 <br />
     aodev-&gt;dev = device;<br />
     aodev-&gt;action = DEVICE_CONNECT;<br />
+    aodev-&gt;hotplug_version = disk-&gt;hotplug_version;<br />
     libxl__wait_device_connection(egc, aodev);<br />
 <br />
     rc = 0;<br />
@@ -2245,6 +2355,7 @@ int libxl_vdev_to_device_disk(libxl_ctx *ctx, uint32_t domid,<br />
     GC_INIT(ctx);<br />
     char *dompath, *path;<br />
     int devid = libxl__device_disk_dev_number(vdev, NULL, NULL);<br />
+    libxl__device dev;<br />
     int rc = ERROR_FAIL;<br />
 <br />
     if (devid &lt; 0)<br />
@@ -2263,6 +2374,22 @@ int libxl_vdev_to_device_disk(libxl_ctx *ctx, uint32_t domid,<br />
         goto out;<br />
 <br />
     rc = libxl__device_disk_from_xs_be(gc, path, disk);<br />
+    if (rc) {<br />
+        LOG(ERROR, &quot;unable to parse disk device from path %s&quot;, path);<br />
+        goto out;<br />
+    }<br />
+<br />
+    /* Check if the device is using the new hotplug interface */<br />
+    rc = libxl__device_from_disk(gc, domid, disk, &amp;dev);<br />
+    if (rc) {<br />
+        LOG(ERROR, &quot;invalid or unsupported virtual disk identifier %s&quot;,<br />
+                    disk-&gt;vdev);<br />
+        goto out;<br />
+    }<br />
+    path = libxl__device_xs_hotplug_path(gc, &amp;dev);<br />
+    if (libxl__xs_read(gc, XBT_NULL, path))<br />
+        disk-&gt;hotplug_version = 1;<br />
+<br />
 out:<br />
     GC_FREE;<br />
     return rc;<br />
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c<br />
index 9d20086..c176967 100644<br />
--- a/tools/libxl/libxl_create.c<br />
+++ b/tools/libxl/libxl_create.c<br />
@@ -591,6 +591,10 @@ static int store_libxl_entry(libxl__gc *gc, uint32_t domid,<br />
  */<br />
 <br />
 /* Event callbacks, in this order: */<br />
+<br />
+static void domcreate_launch_bootloader(libxl__egc *egc,<br />
+                                        libxl__multidev *multidev,<br />
+                                        int ret);<br />
 static void domcreate_devmodel_started(libxl__egc *egc,<br />
                                        libxl__dm_spawn_state *dmss,<br />
                                        int rc);<br />
@@ -627,6 +631,12 @@ static void domcreate_destruction_cb(libxl__egc *egc,<br />
                                      libxl__domain_destroy_state *dds,<br />
                                      int rc);<br />
 <br />
+/* If creation is not successful, this callback will be executed<br />
+ * when devices have been unprepared */<br />
+static void domcreate_unprepare_cb(libxl__egc *egc,<br />
+                                   libxl__multidev *multidev,<br />
+                                   int ret);<br />
+<br />
 static void initiate_domain_create(libxl__egc *egc,<br />
                                    libxl__domain_create_state *dcs)<br />
 {<br />
@@ -637,7 +647,6 @@ static void initiate_domain_create(libxl__egc *egc,<br />
 <br />
     /* convenience aliases */<br />
     libxl_domain_config *const d_config = dcs-&gt;guest_config;<br />
-    const int restore_fd = dcs-&gt;restore_fd;<br />
     memset(&amp;dcs-&gt;build_state, 0, sizeof(dcs-&gt;build_state));<br />
 <br />
     domid = 0;<br />
@@ -670,6 +679,33 @@ static void initiate_domain_create(libxl__egc *egc,<br />
         if (ret) goto error_out;<br />
     }<br />
 <br />
+    libxl__multidev_begin(ao, &amp;dcs-&gt;multidev);<br />
+    dcs-&gt;multidev.callback = domcreate_launch_bootloader;<br />
+    libxl__prepare_disks(egc, ao, domid, d_config, &amp;dcs-&gt;multidev);<br />
+    libxl__multidev_prepared(egc, &amp;dcs-&gt;multidev, 0);<br />
+    return;<br />
+<br />
+error_out:<br />
+    assert(ret);<br />
+    domcreate_complete(egc, dcs, ret);<br />
+}<br />
+<br />
+static void domcreate_launch_bootloader(libxl__egc *egc,<br />
+                                        libxl__multidev *multidev,<br />
+                                        int ret)<br />
+{<br />
+    libxl__domain_create_state *dcs = CONTAINER_OF(multidev, *dcs, multidev);<br />
+    STATE_AO_GC(dcs-&gt;ao);<br />
+<br />
+    /* convenience aliases */<br />
+    const int restore_fd = dcs-&gt;restore_fd;<br />
+    libxl_domain_config *const d_config = dcs-&gt;guest_config;<br />
+<br />
+    if (ret) {<br />
+        LOG(ERROR, &quot;unable to prepare devices&quot;);<br />
+        goto error_out;<br />
+    }<br />
+<br />
     dcs-&gt;bl.ao = ao;<br />
     libxl_device_disk *bootdisk =<br />
         d_config-&gt;num_disks &gt; 0 ? &amp;d_config-&gt;disks[0] : NULL;<br />
@@ -1202,11 +1238,35 @@ static void domcreate_destruction_cb(libxl__egc *egc,<br />
 {<br />
     STATE_AO_GC(dds-&gt;ao);<br />
     libxl__domain_create_state *dcs = CONTAINER_OF(dds, *dcs, dds);<br />
+    uint32_t domid = dcs-&gt;guest_domid;<br />
+    libxl_domain_config *const d_config = dcs-&gt;guest_config;<br />
 <br />
     if (rc)<br />
         LOG(ERROR, &quot;unable to destroy domain %u following failed creation&quot;,<br />
                    dds-&gt;domid);<br />
 <br />
+    /*<br />
+     * We might have devices that have been prepared, but with no<br />
+     * frontend xenstore entries, so domain destruction fails to<br />
+     * find them, that is why we have to unprepare them manually.<br />
+     */<br />
+    libxl__multidev_begin(ao, &amp;dcs-&gt;multidev);<br />
+    dcs-&gt;multidev.callback = domcreate_unprepare_cb;<br />
+    libxl__unprepare_disks(egc, ao, domid, d_config, &amp;dcs-&gt;multidev);<br />
+    libxl__multidev_prepared(egc, &amp;dcs-&gt;multidev, 0);<br />
+    return;<br />
+}<br />
+<br />
+static void domcreate_unprepare_cb(libxl__egc *egc,<br />
+                                   libxl__multidev *multidev,<br />
+                                   int ret)<br />
+{<br />
+    libxl__domain_create_state *dcs = CONTAINER_OF(multidev, *dcs, multidev);<br />
+    STATE_AO_GC(dcs-&gt;ao);<br />
+<br />
+    if (ret)<br />
+        LOG(ERROR, &quot;unable to unprepare devices&quot;);<br />
+<br />
     dcs-&gt;callback(egc, dcs, ERROR_FAIL, dcs-&gt;guest_domid);<br />
 }<br />
 <br />
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c<br />
index 85c9953..ce99d99 100644<br />
--- a/tools/libxl/libxl_device.c<br />
+++ b/tools/libxl/libxl_device.c<br />
@@ -521,18 +521,21 @@ void libxl__multidev_prepared(libxl__egc *egc,<br />
 <br />
 /******************************************************************************/<br />
 <br />
-/* Macro for defining the functions that will add a bunch of disks when<br />
+/* Macro for defining the functions that will operate a bunch of devices when<br />
  * inside an async op with multidev.<br />
  * This macro is added to prevent repetition of code.<br />
  *<br />
  * The following functions are defined:<br />
+ * libxl__prepare_disks<br />
+ * libxl__unprepare_disks<br />
  * libxl__add_disks<br />
  * libxl__add_nics<br />
  * libxl__add_vtpms<br />
  */<br />
 <br />
-#define DEFINE_DEVICES_ADD(type)                                        \<br />
-    void libxl__add_##type##s(libxl__egc *egc, libxl__ao *ao, uint32_t domid, \<br />
+#define DEFINE_DEVICES_FUNC(type, op)                                   \<br />
+    void libxl__##op##_##type##s(libxl__egc *egc, libxl__ao *ao,        \<br />
+                              uint32_t domid,                           \<br />
                               libxl_domain_config *d_config,            \<br />
                               libxl__multidev *multidev)                \<br />
     {                                                                   \<br />
@@ -540,16 +543,19 @@ void libxl__multidev_prepared(libxl__egc *egc,<br />
         int i;                                                          \<br />
         for (i = 0; i &lt; d_config-&gt;num_##type##s; i++) {                 \<br />
             libxl__ao_device *aodev = libxl__multidev_prepare(multidev);  \<br />
-            libxl__device_##type##_add(egc, domid, &amp;d_config-&gt;type##s<i>, \<br />
+            libxl__device_##type##_##op(egc, domid, &amp;d_config-&gt;type##s<i>, \<br />
                                        aodev);                          \<br />
         }                                                               \<br />
     }<br />
 <br />
-DEFINE_DEVICES_ADD(disk)<br />
-DEFINE_DEVICES_ADD(nic)<br />
-DEFINE_DEVICES_ADD(vtpm)<br />
+DEFINE_DEVICES_FUNC(disk, add)<br />
+DEFINE_DEVICES_FUNC(nic, add)<br />
+DEFINE_DEVICES_FUNC(vtpm, add)<br />
 <br />
-#undef DEFINE_DEVICES_ADD<br />
+DEFINE_DEVICES_FUNC(disk, prepare)<br />
+DEFINE_DEVICES_FUNC(disk, unprepare)<br />
+<br />
+#undef DEFINE_DEVICES_FUNC<br />
 <br />
 /******************************************************************************/<br />
 <br />
@@ -557,6 +563,7 @@ int libxl__device_destroy(libxl__gc *gc, libxl__device *dev)<br />
 {<br />
     const char *be_path = libxl__device_backend_path(gc, dev);<br />
     const char *fe_path = libxl__device_frontend_path(gc, dev);<br />
+    const char *hotplug_path = libxl__device_xs_hotplug_path(gc, dev);<br />
     const char *tapdisk_path = GCSPRINTF(&quot;%s/%s&quot;, be_path, &quot;tapdisk-params&quot;);<br />
     const char *tapdisk_params;<br />
     xs_transaction_t t = 0;<br />
@@ -572,6 +579,7 @@ int libxl__device_destroy(libxl__gc *gc, libxl__device *dev)<br />
 <br />
         libxl__xs_path_cleanup(gc, t, fe_path);<br />
         libxl__xs_path_cleanup(gc, t, be_path);<br />
+        libxl__xs_path_cleanup(gc, t, hotplug_path);<br />
 <br />
         rc = libxl__xs_transaction_commit(gc, &amp;t);<br />
         if (!rc) break;<br />
@@ -644,6 +652,14 @@ void libxl__devices_destroy(libxl__egc *egc, libxl__devices_remove_state *drs)<br />
                     continue;<br />
                 }<br />
                 aodev = libxl__multidev_prepare(multidev);<br />
+                /*<br />
+                 * Check if the device has hotplug entries in xenstore,<br />
+                 * which would mean it's using the new hotplug calling<br />
+                 * convention.<br />
+                 */<br />
+                path = libxl__device_xs_hotplug_path(gc, dev);<br />
+                if (libxl__xs_read(gc, XBT_NULL, path))<br />
+                    aodev-&gt;hotplug_version = 1;<br />
                 aodev-&gt;action = DEVICE_DISCONNECT;<br />
                 aodev-&gt;dev = dev;<br />
                 aodev-&gt;force = drs-&gt;force;<br />
@@ -696,8 +712,6 @@ static void device_backend_callback(libxl__egc *egc, libxl__ev_devstate *ds,<br />
 static void device_backend_cleanup(libxl__gc *gc,<br />
                                    libxl__ao_device *aodev);<br />
 <br />
-static void device_hotplug(libxl__egc *egc, libxl__ao_device *aodev);<br />
-<br />
 static void device_hotplug_timeout_cb(libxl__egc *egc, libxl__ev_time *ev,<br />
                                       const struct timeval *requested_abs);<br />
 <br />
@@ -732,7 +746,7 @@ void libxl__wait_device_connection(libxl__egc *egc, libxl__ao_device *aodev)<br />
          * If Qemu is running, it will set the state of the device to<br />
          * 4 directly, without waiting in state 2 for any hotplug execution.<br />
          */<br />
-        device_hotplug(egc, aodev);<br />
+        libxl__device_hotplug(egc, aodev);<br />
         return;<br />
     }<br />
 <br />
@@ -864,7 +878,7 @@ static void device_qemu_timeout(libxl__egc *egc, libxl__ev_time *ev,<br />
     rc = libxl__xs_write_checked(gc, XBT_NULL, state_path, &quot;6&quot;);<br />
     if (rc) goto out;<br />
 <br />
-    device_hotplug(egc, aodev);<br />
+    libxl__device_hotplug(egc, aodev);<br />
     return;<br />
 <br />
 out:<br />
@@ -893,7 +907,7 @@ static void device_backend_callback(libxl__egc *egc, libxl__ev_devstate *ds,<br />
         goto out;<br />
     }<br />
 <br />
-    device_hotplug(egc, aodev);<br />
+    libxl__device_hotplug(egc, aodev);<br />
     return;<br />
 <br />
 out:<br />
@@ -908,7 +922,7 @@ static void device_backend_cleanup(libxl__gc *gc, libxl__ao_device *aodev)<br />
     libxl__ev_devstate_cancel(gc, &amp;aodev-&gt;backend_ds);<br />
 }<br />
 <br />
-static void device_hotplug(libxl__egc *egc, libxl__ao_device *aodev)<br />
+void libxl__device_hotplug(libxl__egc *egc, libxl__ao_device *aodev)<br />
 {<br />
     STATE_AO_GC(aodev-&gt;ao);<br />
     char *be_path = libxl__device_backend_path(gc, aodev-&gt;dev);<br />
@@ -1012,10 +1026,13 @@ static void device_hotplug_child_death_cb(libxl__egc *egc,<br />
         if (hotplug_error)<br />
             LOG(ERROR, &quot;script: %s&quot;, hotplug_error);<br />
         aodev-&gt;rc = ERROR_FAIL;<br />
-        if (aodev-&gt;action == DEVICE_CONNECT)<br />
+        if (aodev-&gt;action == DEVICE_CONNECT ||<br />
+            aodev-&gt;action == DEVICE_PREPARE ||<br />
+            aodev-&gt;action == DEVICE_LOCALATTACH)<br />
             /*<br />
-             * Only fail on device connection, on disconnection<br />
-             * ignore error, and continue with the remove process<br />
+             * Only fail on device connection, prepare or localattach,<br />
+             * on other cases ignore error, and continue with the remove<br />
+             * process.<br />
              */<br />
              goto error;<br />
     }<br />
@@ -1025,7 +1042,7 @@ static void device_hotplug_child_death_cb(libxl__egc *egc,<br />
      * device_hotplug_done breaking the loop.<br />
      */<br />
     aodev-&gt;num_exec++;<br />
-    device_hotplug(egc, aodev);<br />
+    libxl__device_hotplug(egc, aodev);<br />
 <br />
     return;<br />
 <br />
@@ -1041,8 +1058,33 @@ static void device_hotplug_done(libxl__egc *egc, libxl__ao_device *aodev)<br />
 <br />
     device_hotplug_clean(gc, aodev);<br />
 <br />
-    /* Clean xenstore if it's a disconnection */<br />
     if (aodev-&gt;action == DEVICE_DISCONNECT) {<br />
+        switch (aodev-&gt;hotplug_version) {<br />
+        case 0:<br />
+            /* Clean xenstore if it's a disconnection */<br />
+            rc = libxl__device_destroy(gc, aodev-&gt;dev);<br />
+            if (!aodev-&gt;rc)<br />
+                aodev-&gt;rc = rc;<br />
+            break;<br />
+        case 1:<br />
+            /*<br />
+             * Chain unprepare hotplug execution<br />
+             * after disconnection of device.<br />
+             */<br />
+            aodev-&gt;num_exec = 0;<br />
+            aodev-&gt;action = DEVICE_UNPREPARE;<br />
+            libxl__device_hotplug(egc, aodev);<br />
+            return;<br />
+        default:<br />
+            LOG(ERROR, &quot;unknown hotplug script version (%d)&quot;,<br />
+                       aodev-&gt;hotplug_version);<br />
+            if (!aodev-&gt;rc)<br />
+                aodev-&gt;rc = ERROR_FAIL;<br />
+            break;<br />
+        }<br />
+    }<br />
+    /* Clean hotplug xenstore path */<br />
+    if (aodev-&gt;action == DEVICE_UNPREPARE) {<br />
         rc = libxl__device_destroy(gc, aodev-&gt;dev);<br />
         if (!aodev-&gt;rc)<br />
             aodev-&gt;rc = rc;<br />
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h<br />
index c41e608..16907ff 100644<br />
--- a/tools/libxl/libxl_internal.h<br />
+++ b/tools/libxl/libxl_internal.h<br />
@@ -2018,6 +2018,12 @@ struct libxl__multidev {<br />
 _hidden void libxl__device_disk_add(libxl__egc *egc, uint32_t domid,<br />
                                     libxl_device_disk *disk,<br />
                                     libxl__ao_device *aodev);<br />
+_hidden void libxl__device_disk_prepare(libxl__egc *egc, uint32_t domid,<br />
+                                        libxl_device_disk *disk,<br />
+                                        libxl__ao_device *aodev);<br />
+_hidden void libxl__device_disk_unprepare(libxl__egc *egc, uint32_t domid,<br />
+                                          libxl_device_disk *disk,<br />
+                                          libxl__ao_device *aodev);<br />
 <br />
 /* AO operation to connect a nic device */<br />
 _hidden void libxl__device_nic_add(libxl__egc *egc, uint32_t domid,<br />
@@ -2094,6 +2100,19 @@ _hidden int libxl__get_hotplug_script_info(libxl__gc *gc, libxl__device *dev,<br />
                                            libxl__device_action action,<br />
                                            int num_exec, int hotplug_version);<br />
 <br />
+/*<br />
+ * libxl__device_hotplug runs the hotplug script associated<br />
+ * with the device passed in aodev-&gt;dev.<br />
+ *<br />
+ * The libxl__ao_device passed to this function should be<br />
+ * prepared using libxl__prepare_ao_device prior to calling<br />
+ * this function.<br />
+ *<br />
+ * Once finished, aodev-&gt;callback will be executed.<br />
+ */<br />
+_hidden void libxl__device_hotplug(libxl__egc *egc,<br />
+                                   libxl__ao_device *aodev);<br />
+<br />
 /*----- local disk attach: attach a disk locally to run the bootloader -----*/<br />
 <br />
 typedef struct libxl__disk_local_state libxl__disk_local_state;<br />
@@ -2467,6 +2486,21 @@ _hidden void libxl__add_disks(libxl__egc *egc, libxl__ao *ao, uint32_t domid,<br />
                               libxl_domain_config *d_config,<br />
                               libxl__multidev *multidev);<br />
 <br />
+_hidden void libxl__prepare_disks(libxl__egc *egc, libxl__ao *ao,<br />
+                                  uint32_t domid,<br />
+                                  libxl_domain_config *d_config,<br />
+                                  libxl__multidev *multidev);<br />
+<br />
+_hidden void libxl__prepare_undisks(libxl__egc *egc, libxl__ao *ao,<br />
+                                    uint32_t domid,<br />
+                                    libxl_domain_config *d_config,<br />
+                                    libxl__multidev *multidev);<br />
+<br />
+_hidden void libxl__unprepare_disks(libxl__egc *egc, libxl__ao *ao,<br />
+                                    uint32_t domid,<br />
+                                    libxl_domain_config *d_config,<br />
+                                    libxl__multidev *multidev);<br />
+<br />
 _hidden void libxl__add_nics(libxl__egc *egc, libxl__ao *ao, uint32_t domid,<br />
                              libxl_domain_config *d_config,<br />
                              libxl__multidev *multidev);<br />
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl<br />
index 7eac4a8..272ff54 100644<br />
--- a/tools/libxl/libxl_types.idl<br />
+++ b/tools/libxl/libxl_types.idl<br />
@@ -366,6 +366,7 @@ libxl_device_disk = Struct(&quot;device_disk&quot;, [<br />
     (&quot;removable&quot;, integer),<br />
     (&quot;readwrite&quot;, integer),<br />
     (&quot;is_cdrom&quot;, integer),<br />
+    (&quot;hotplug_version&quot;, integer),<br />
     ])<br />
 <br />
 libxl_device_nic = Struct(&quot;device_nic&quot;, [<br />
diff --git a/tools/libxl/libxlu_disk_l.l b/tools/libxl/libxlu_disk_l.l<br />
index bee16a1..4486c1a 100644<br />
--- a/tools/libxl/libxlu_disk_l.l<br />
+++ b/tools/libxl/libxlu_disk_l.l<br />
@@ -172,6 +172,8 @@ backendtype=[^,]*,? { STRIP(','); setbackendtype(DPC,FROMEQUALS); }<br />
 <br />
 vdev=[^,]*,?	{ STRIP(','); SAVESTRING(&quot;vdev&quot;, vdev, FROMEQUALS); }<br />
 script=[^,]*,?	{ STRIP(','); SAVESTRING(&quot;script&quot;, script, FROMEQUALS); }<br />
+method=[^,]*,?	{ STRIP(','); SAVESTRING(&quot;script&quot;, script, FROMEQUALS);<br />
+		  DPC-&gt;disk-&gt;hotplug_version = 1; }<br />
 <br />
  /* the target magic parameter, eats the rest of the string */<br />
 <br />
-- <br />
1.7.7.5 (Apple Git-26)<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]</i></i>]]></description>
            <dc:creator>Roger Pau Monne</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sat, 22 Dec 2012 01:15:06 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1688658,1688658#msg-1688658</guid>
            <title>[Xen-devel] [PATCH RFC 02/10] libxl: add new hotplug interface support to hotplug script callers (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1688658,1688658#msg-1688658</link>
            <description><![CDATA[ Add support to call hotplug scripts that use the new hotplug interface<br />
to the low-level functions in charge of calling hotplug scripts. This<br />
new calling convention will be used when the hotplug_version aodev<br />
field is 1.<br />
<br />
Signed-off-by: Roger Pau Monné &lt;roger.pau@citrix.com&gt;<br />
---<br />
 tools/libxl/libxl_device.c   |   33 +++++++++++++++++++-<br />
 tools/libxl/libxl_internal.h |   33 ++++++++++++++++++--<br />
 tools/libxl/libxl_linux.c    |   68 ++++++++++++++++++++++++++++++++----------<br />
 tools/libxl/libxl_netbsd.c   |    2 +-<br />
 4 files changed, 115 insertions(+), 21 deletions(-)<br />
<br />
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c<br />
index 58d3f35..85c9953 100644<br />
--- a/tools/libxl/libxl_device.c<br />
+++ b/tools/libxl/libxl_device.c<br />
@@ -83,6 +83,35 @@ out:<br />
     return rc;<br />
 }<br />
 <br />
+char *libxl__device_hotplug_action(libxl__gc *gc,<br />
+                                   libxl__device_action action)<br />
+{<br />
+    switch (action) {<br />
+    case DEVICE_CONNECT:<br />
+        return &quot;add&quot;;<br />
+    case DEVICE_DISCONNECT:<br />
+        return &quot;remove&quot;;<br />
+    case DEVICE_PREPARE:<br />
+        return &quot;prepare&quot;;<br />
+    case DEVICE_UNPREPARE:<br />
+        return &quot;unprepare&quot;;<br />
+    case DEVICE_LOCALATTACH:<br />
+        return &quot;localattach&quot;;<br />
+    case DEVICE_LOCALDETACH:<br />
+        return &quot;localdetach&quot;;<br />
+    default:<br />
+        LOG(ERROR, &quot;invalid action (%d) for device&quot;, action);<br />
+        break;<br />
+    }<br />
+    return NULL;<br />
+}<br />
+<br />
+char *libxl__device_xs_hotplug_path(libxl__gc *gc, libxl__device *dev)<br />
+{<br />
+    return GCSPRINTF(&quot;/local/domain/%u/libxl/hotplug/%u/%u&quot;,<br />
+                     dev-&gt;backend_domid, dev-&gt;domid, dev-&gt;devid);<br />
+}<br />
+<br />
 int libxl__device_generic_add(libxl__gc *gc, xs_transaction_t t,<br />
         libxl__device *device, char **bents, char **fents)<br />
 {<br />
@@ -410,6 +439,7 @@ void libxl__prepare_ao_device(libxl__ao *ao, libxl__ao_device *aodev)<br />
     aodev-&gt;rc = 0;<br />
     aodev-&gt;dev = NULL;<br />
     aodev-&gt;num_exec = 0;<br />
+    aodev-&gt;hotplug_version = 0;<br />
     /* Initialize timer for QEMU Bodge and hotplug execution */<br />
     libxl__ev_time_init(&amp;aodev-&gt;timeout);<br />
     aodev-&gt;active = 1;<br />
@@ -891,7 +921,8 @@ static void device_hotplug(libxl__egc *egc, libxl__ao_device *aodev)<br />
      * and return the necessary args/env vars for execution */<br />
     hotplug = libxl__get_hotplug_script_info(gc, aodev-&gt;dev, &amp;args, &amp;env,<br />
                                              aodev-&gt;action,<br />
-                                             aodev-&gt;num_exec);<br />
+                                             aodev-&gt;num_exec,<br />
+                                             aodev-&gt;hotplug_version);<br />
     switch (hotplug) {<br />
     case 0:<br />
         /* no hotplug script to execute */<br />
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h<br />
index 0b38e3e..c41e608 100644<br />
--- a/tools/libxl/libxl_internal.h<br />
+++ b/tools/libxl/libxl_internal.h<br />
@@ -1829,12 +1829,19 @@ _hidden const char *libxl__run_dir_path(void);<br />
 <br />
 /*----- device addition/removal -----*/<br />
 <br />
-/* Action to perform (either connect or disconnect) */<br />
+/* Action to perform */<br />
 typedef enum {<br />
     DEVICE_CONNECT,<br />
-    DEVICE_DISCONNECT<br />
+    DEVICE_DISCONNECT,<br />
+    DEVICE_PREPARE,<br />
+    DEVICE_UNPREPARE,<br />
+    DEVICE_LOCALATTACH,<br />
+    DEVICE_LOCALDETACH<br />
 } libxl__device_action;<br />
 <br />
+_hidden char *libxl__device_hotplug_action(libxl__gc *gc,<br />
+                                           libxl__device_action action);<br />
+<br />
 typedef struct libxl__ao_device libxl__ao_device;<br />
 typedef struct libxl__multidev libxl__multidev;<br />
 typedef void libxl__device_callback(libxl__egc*, libxl__ao_device*);<br />
@@ -1852,6 +1859,14 @@ typedef void libxl__device_callback(libxl__egc*, libxl__ao_device*);<br />
  * Once _prepare has been called on a libxl__ao_device, it is safe to just<br />
  * discard this struct, there's no need to call any destroy function.<br />
  * _prepare can also be called multiple times with the same libxl__ao_device.<br />
+ *<br />
+ * If hotplug_version field is 1, the new hotplug script calling convention<br />
+ * will be used to call the hotplug script. This new convention provides<br />
+ * two new actions to hotplug scripts, &quot;prepare&quot;, &quot;unprepare&quot;, &quot;localattach&quot;<br />
+ * and &quot;localdetach&quot;. This new actions have been added to offload work done<br />
+ * by hotplug scripts during the blackout phase of migration. &quot;prepare&quot; is<br />
+ * called before the remote domain is paused, so as much operations as<br />
+ * possible should be done in this phase.<br />
  */<br />
 _hidden void libxl__prepare_ao_device(libxl__ao *ao, libxl__ao_device *aodev);<br />
 <br />
@@ -1862,6 +1877,7 @@ struct libxl__ao_device {<br />
     libxl__device *dev;<br />
     int force;<br />
     libxl__device_callback *callback;<br />
+    int hotplug_version;<br />
     /* return value, zeroed by user on entry, is valid on callback */<br />
     int rc;<br />
     /* private for multidev */<br />
@@ -2045,6 +2061,17 @@ _hidden void libxl__initiate_device_remove(libxl__egc *egc,<br />
                                            libxl__ao_device *aodev);<br />
 <br />
 /*<br />
+ * libxl__device_xs_hotplug_path returns the xenstore hotplug<br />
+ * path that is used to share information with the hotplug<br />
+ * script.<br />
+ *<br />
+ * This path is only used by new hotplug scripts, that are<br />
+ * specified using &quot;method&quot; instead of &quot;script&quot; in the disk<br />
+ * parameters.<br />
+ */<br />
+_hidden char *libxl__device_xs_hotplug_path(libxl__gc *gc, libxl__device *dev);<br />
+<br />
+/*<br />
  * libxl__get_hotplug_script_info returns the args and env that should<br />
  * be passed to the hotplug script for the requested device.<br />
  *<br />
@@ -2065,7 +2092,7 @@ _hidden void libxl__initiate_device_remove(libxl__egc *egc,<br />
 _hidden int libxl__get_hotplug_script_info(libxl__gc *gc, libxl__device *dev,<br />
                                            char ***args, char ***env,<br />
                                            libxl__device_action action,<br />
-                                           int num_exec);<br />
+                                           int num_exec, int hotplug_version);<br />
 <br />
 /*----- local disk attach: attach a disk locally to run the bootloader -----*/<br />
 <br />
diff --git a/tools/libxl/libxl_linux.c b/tools/libxl/libxl_linux.c<br />
index 1fed3cd..43f23dd 100644<br />
--- a/tools/libxl/libxl_linux.c<br />
+++ b/tools/libxl/libxl_linux.c<br />
@@ -190,32 +190,68 @@ out:<br />
 <br />
 static int libxl__hotplug_disk(libxl__gc *gc, libxl__device *dev,<br />
                                char ***args, char ***env,<br />
-                               libxl__device_action action)<br />
+                               libxl__device_action action,<br />
+                               int hotplug_version)<br />
 {<br />
     char *be_path = libxl__device_backend_path(gc, dev);<br />
-    char *script;<br />
+    char *hotplug_path = libxl__device_xs_hotplug_path(gc, dev);<br />
+    char *script, *saction;<br />
     int nr = 0, rc = 0;<br />
+    const int env_arraysize = 5;<br />
+    const int arg_arraysize = 3;<br />
 <br />
-    script = libxl__xs_read(gc, XBT_NULL,<br />
-                            GCSPRINTF(&quot;%s/%s&quot;, be_path, &quot;script&quot;));<br />
-    if (!script) {<br />
-        LOGEV(ERROR, errno, &quot;unable to read script from %s&quot;, be_path);<br />
+    switch (hotplug_version) {<br />
+    case 0:<br />
+        script = libxl__xs_read(gc, XBT_NULL, GCSPRINTF(&quot;%s/script&quot;, be_path));<br />
+        if (!script) {<br />
+            LOGEV(ERROR, errno, &quot;unable to read script from %s&quot;, be_path);<br />
+            rc = ERROR_FAIL;<br />
+            goto error;<br />
+        }<br />
+        *env = get_hotplug_env(gc, script, dev);<br />
+        if (!*env) {<br />
+            rc = ERROR_FAIL;<br />
+            goto error;<br />
+        }<br />
+        break;<br />
+    case 1:<br />
+        /* The new hotplug calling convention only uses two ENV variables:<br />
+         * BACKEND_PATH: path to xenstore backend of the related device.<br />
+         * HOTPLUG_PATH: path to the xenstore directory that can be used to<br />
+         * pass extra parameters to the script.<br />
+         */<br />
+        script = libxl__xs_read(gc, XBT_NULL,<br />
+                                GCSPRINTF(&quot;%s/script&quot;, hotplug_path));<br />
+        if (!script) {<br />
+            LOGEV(ERROR, errno, &quot;unable to read script from %s&quot;, hotplug_path);<br />
+            rc = ERROR_FAIL;<br />
+            goto error;<br />
+        }<br />
+        GCNEW_ARRAY(*env, env_arraysize);<br />
+        (*env)[nr++] = &quot;BACKEND_PATH&quot;;<br />
+        (*env)[nr++] = be_path;<br />
+        (*env)[nr++] = &quot;HOTPLUG_PATH&quot;;<br />
+        (*env)[nr++] = hotplug_path;<br />
+        (*env)[nr++] = NULL;<br />
+        assert(nr == env_arraysize);<br />
+        nr = 0;<br />
+        break;<br />
+    default:<br />
+        LOG(ERROR, &quot;unknown hotplug script version %d&quot;, hotplug_version);<br />
         rc = ERROR_FAIL;<br />
         goto error;<br />
     }<br />
 <br />
-    *env = get_hotplug_env(gc, script, dev);<br />
-    if (!*env) {<br />
+    GCNEW_ARRAY(*args, arg_arraysize);<br />
+    (*args)[nr++] = script;<br />
+    saction = libxl__device_hotplug_action(gc, action);<br />
+    if (!saction) {<br />
         rc = ERROR_FAIL;<br />
         goto error;<br />
     }<br />
-<br />
-    const int arraysize = 3;<br />
-    GCNEW_ARRAY(*args, arraysize);<br />
-    (*args)[nr++] = script;<br />
-    (*args)[nr++] = action == DEVICE_CONNECT ? &quot;add&quot; : &quot;remove&quot;;<br />
+    (*args)[nr++] = saction;<br />
     (*args)[nr++] = NULL;<br />
-    assert(nr == arraysize);<br />
+    assert(nr == arg_arraysize);<br />
 <br />
     rc = 1;<br />
 <br />
@@ -226,7 +262,7 @@ error:<br />
 int libxl__get_hotplug_script_info(libxl__gc *gc, libxl__device *dev,<br />
                                    char ***args, char ***env,<br />
                                    libxl__device_action action,<br />
-                                   int num_exec)<br />
+                                   int num_exec, int hotplug_version)<br />
 {<br />
     char *disable_udev = libxl__xs_read(gc, XBT_NULL, DISABLE_UDEV_PATH);<br />
     int rc;<br />
@@ -243,7 +279,7 @@ int libxl__get_hotplug_script_info(libxl__gc *gc, libxl__device *dev,<br />
             rc = 0;<br />
             goto out;<br />
         }<br />
-        rc = libxl__hotplug_disk(gc, dev, args, env, action);<br />
+        rc = libxl__hotplug_disk(gc, dev, args, env, action, hotplug_version);<br />
         break;<br />
     case LIBXL__DEVICE_KIND_VIF:<br />
         /*<br />
diff --git a/tools/libxl/libxl_netbsd.c b/tools/libxl/libxl_netbsd.c<br />
index 9587833..8061e7a 100644<br />
--- a/tools/libxl/libxl_netbsd.c<br />
+++ b/tools/libxl/libxl_netbsd.c<br />
@@ -62,7 +62,7 @@ out:<br />
 int libxl__get_hotplug_script_info(libxl__gc *gc, libxl__device *dev,<br />
                                    char ***args, char ***env,<br />
                                    libxl__device_action action,<br />
-                                   int num_exec)<br />
+                                   int num_exec, int hotplug_version)<br />
 {<br />
     char *disable_udev = libxl__xs_read(gc, XBT_NULL, DISABLE_UDEV_PATH);<br />
     int rc;<br />
-- <br />
1.7.7.5 (Apple Git-26)<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Roger Pau Monne</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sat, 22 Dec 2012 01:15:05 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1688657,1688657#msg-1688657</guid>
            <title>[Xen-devel] [PATCH RFC 07/10] libxl: add local attach support for new hotplug scripts (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1688657,1688657#msg-1688657</link>
            <description><![CDATA[ Adds support for locally attaching disks that use the new hotplug<br />
script interface, by calling the localattach/localdetach operations<br />
and returning a block device that can be used to execute pygrub.<br />
<br />
Signed-off-by: Roger Pau Monné &lt;roger.pau@citrix.com&gt;<br />
---<br />
 tools/libxl/libxl.c            |   88 ++++++++++++++++++++++++++++++++++------<br />
 tools/libxl/libxl_bootloader.c |    1 +<br />
 tools/libxl/libxl_internal.h   |    1 +<br />
 3 files changed, 77 insertions(+), 13 deletions(-)<br />
<br />
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c<br />
index 29b2765..b21eefc 100644<br />
--- a/tools/libxl/libxl.c<br />
+++ b/tools/libxl/libxl.c<br />
@@ -2657,6 +2657,7 @@ void libxl__device_disk_local_initiate_attach(libxl__egc *egc,<br />
     const libxl_device_disk *in_disk = dls-&gt;in_disk;<br />
     libxl_device_disk *disk = &amp;dls-&gt;disk;<br />
     const char *blkdev_start = dls-&gt;blkdev_start;<br />
+    uint32_t domid = dls-&gt;domid;<br />
 <br />
     assert(in_disk-&gt;pdev_path);<br />
 <br />
@@ -2673,6 +2674,23 @@ void libxl__device_disk_local_initiate_attach(libxl__egc *egc,<br />
         case LIBXL_DISK_BACKEND_PHY:<br />
             LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, &quot;locally attaching PHY disk %s&quot;,<br />
                        disk-&gt;pdev_path);<br />
+            if (disk-&gt;hotplug_version != 0) {<br />
+                disk-&gt;vdev = libxl__strdup(gc, in_disk-&gt;vdev);<br />
+                libxl__prepare_ao_device(ao, &amp;dls-&gt;aodev);<br />
+                GCNEW(dls-&gt;aodev.dev);<br />
+                rc = libxl__device_from_disk(gc, domid, disk,<br />
+                                             dls-&gt;aodev.dev);<br />
+                if (rc != 0) {<br />
+                    LOG(ERROR, &quot;Invalid or unsupported virtual disk &quot;<br />
+                               &quot;identifier %s&quot;, disk-&gt;vdev);<br />
+                    goto out;<br />
+                }<br />
+                dls-&gt;aodev.action = DEVICE_LOCALATTACH;<br />
+                dls-&gt;aodev.hotplug_version = disk-&gt;hotplug_version;<br />
+                dls-&gt;aodev.callback = local_device_attach_cb;<br />
+                libxl__device_hotplug(egc, &amp;dls-&gt;aodev);<br />
+                return;<br />
+            }<br />
             dev = disk-&gt;pdev_path;<br />
             break;<br />
         case LIBXL_DISK_BACKEND_TAP:<br />
@@ -2735,7 +2753,8 @@ static void local_device_attach_cb(libxl__egc *egc, libxl__ao_device *aodev)<br />
 {<br />
     STATE_AO_GC(aodev-&gt;ao);<br />
     libxl__disk_local_state *dls = CONTAINER_OF(aodev, *dls, aodev);<br />
-    char *dev = NULL, *be_path = NULL;<br />
+    char *dev = NULL, *be_path = NULL, *hotplug_path;<br />
+    const char *pdev = NULL;<br />
     int rc;<br />
     libxl__device device;<br />
     libxl_device_disk *disk = &amp;dls-&gt;disk;<br />
@@ -2748,20 +2767,45 @@ static void local_device_attach_cb(libxl__egc *egc, libxl__ao_device *aodev)<br />
                     aodev-&gt;dev-&gt;devid);<br />
         goto out;<br />
     }<br />
+    switch (disk-&gt;backend) {<br />
+    case LIBXL_DISK_BACKEND_PHY:<br />
+        /* Fetch hotplug output to obtain the block device */<br />
+        rc = libxl__device_from_disk(gc, dls-&gt;domid, disk, &amp;device);<br />
+        if (rc)<br />
+            goto out;<br />
+        hotplug_path = libxl__device_xs_hotplug_path(gc, &amp;device);<br />
+        rc = libxl__xs_read_checked(gc, XBT_NULL,<br />
+                                    GCSPRINTF(&quot;%s/pdev&quot;, hotplug_path),<br />
+                                    &amp;pdev);<br />
+        if (rc)<br />
+            goto out;<br />
+        if (!pdev) {<br />
+            rc = ERROR_FAIL;<br />
+            goto out;<br />
+        }<br />
+        LOG(DEBUG, &quot;attached local block device %s&quot;, pdev);<br />
+        dls-&gt;diskpath = libxl__strdup(gc, pdev);<br />
+        break;<br />
+    case LIBXL_DISK_BACKEND_QDISK:<br />
+        dev = GCSPRINTF(&quot;/dev/%s&quot;, disk-&gt;vdev);<br />
+        LOG(DEBUG, &quot;locally attaching qdisk %s&quot;, dev);<br />
 <br />
-    dev = GCSPRINTF(&quot;/dev/%s&quot;, disk-&gt;vdev);<br />
-    LOG(DEBUG, &quot;locally attaching qdisk %s&quot;, dev);<br />
+        rc = libxl__device_from_disk(gc, LIBXL_TOOLSTACK_DOMID, disk, &amp;device);<br />
+        if (rc &lt; 0)<br />
+            goto out;<br />
+        be_path = libxl__device_backend_path(gc, &amp;device);<br />
+        rc = libxl__wait_for_backend(gc, be_path, &quot;4&quot;);<br />
+        if (rc &lt; 0)<br />
+            goto out;<br />
 <br />
-    rc = libxl__device_from_disk(gc, LIBXL_TOOLSTACK_DOMID, disk, &amp;device);<br />
-    if (rc &lt; 0)<br />
-        goto out;<br />
-    be_path = libxl__device_backend_path(gc, &amp;device);<br />
-    rc = libxl__wait_for_backend(gc, be_path, &quot;4&quot;);<br />
-    if (rc &lt; 0)<br />
+        if (dev != NULL)<br />
+            dls-&gt;diskpath = libxl__strdup(gc, dev);<br />
+        break;<br />
+    default:<br />
+        LOG(ERROR, &quot;invalid disk backend for local attach callback&quot;);<br />
+        rc = ERROR_FAIL;<br />
         goto out;<br />
-<br />
-    if (dev != NULL)<br />
-        dls-&gt;diskpath = libxl__strdup(gc, dev);<br />
+    }<br />
 <br />
     dls-&gt;callback(egc, dls, 0);<br />
     return;<br />
@@ -2785,11 +2829,29 @@ void libxl__device_disk_local_initiate_detach(libxl__egc *egc,<br />
     libxl_device_disk *disk = &amp;dls-&gt;disk;<br />
     libxl__device *device;<br />
     libxl__ao_device *aodev = &amp;dls-&gt;aodev;<br />
+    uint32_t domid = dls-&gt;domid;<br />
     libxl__prepare_ao_device(ao, aodev);<br />
 <br />
     if (!dls-&gt;diskpath) goto out;<br />
 <br />
     switch (disk-&gt;backend) {<br />
+        case LIBXL_DISK_BACKEND_PHY:<br />
+            if (disk-&gt;hotplug_version != 0) {<br />
+                GCNEW(aodev-&gt;dev);<br />
+                rc = libxl__device_from_disk(gc, domid, disk,<br />
+                                             aodev-&gt;dev);<br />
+                if (rc != 0) {<br />
+                    LOG(ERROR, &quot;Invalid or unsupported virtual disk &quot;<br />
+                               &quot;identifier %s&quot;, disk-&gt;vdev);<br />
+                    goto out;<br />
+                }<br />
+                aodev-&gt;action = DEVICE_LOCALDETACH;<br />
+                aodev-&gt;hotplug_version = disk-&gt;hotplug_version;<br />
+                aodev-&gt;callback = local_device_detach_cb;<br />
+                libxl__device_hotplug(egc, aodev);<br />
+                return;<br />
+            }<br />
+            break;<br />
         case LIBXL_DISK_BACKEND_QDISK:<br />
             if (disk-&gt;vdev != NULL) {<br />
                 GCNEW(device);<br />
@@ -2828,7 +2890,7 @@ static void local_device_detach_cb(libxl__egc *egc, libxl__ao_device *aodev)<br />
 <br />
     if (aodev-&gt;rc) {<br />
         LOGE(ERROR, &quot;unable to %s %s with id %u&quot;,<br />
-                    aodev-&gt;action == DEVICE_CONNECT ? &quot;add&quot; : &quot;remove&quot;,<br />
+                    libxl__device_hotplug_action(gc, aodev-&gt;action),<br />
                     libxl__device_kind_to_string(aodev-&gt;dev-&gt;kind),<br />
                     aodev-&gt;dev-&gt;devid);<br />
         goto out;<br />
diff --git a/tools/libxl/libxl_bootloader.c b/tools/libxl/libxl_bootloader.c<br />
index e103ee9..ff2e48c 100644<br />
--- a/tools/libxl/libxl_bootloader.c<br />
+++ b/tools/libxl/libxl_bootloader.c<br />
@@ -381,6 +381,7 @@ void libxl__bootloader_run(libxl__egc *egc, libxl__bootloader_state *bl)<br />
     bl-&gt;dls.ao = ao;<br />
     bl-&gt;dls.in_disk = bl-&gt;disk;<br />
     bl-&gt;dls.blkdev_start = info-&gt;blkdev_start;<br />
+    bl-&gt;dls.domid = domid;<br />
     bl-&gt;dls.callback = bootloader_disk_attached_cb;<br />
     libxl__device_disk_local_initiate_attach(egc, &amp;bl-&gt;dls);<br />
     return;<br />
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h<br />
index 16907ff..67c56a6 100644<br />
--- a/tools/libxl/libxl_internal.h<br />
+++ b/tools/libxl/libxl_internal.h<br />
@@ -2130,6 +2130,7 @@ struct libxl__disk_local_state {<br />
     libxl_device_disk disk;<br />
     const char *blkdev_start;<br />
     libxl__disk_local_state_callback *callback;<br />
+    uint32_t domid;<br />
     /* filled by libxl__device_disk_local_initiate_attach */<br />
     char *diskpath;<br />
     /* private for implementation of local detach */<br />
-- <br />
1.7.7.5 (Apple Git-26)<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Roger Pau Monne</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sat, 22 Dec 2012 01:15:04 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1688656,1688656#msg-1688656</guid>
            <title>[Xen-devel] [PATCH RFC 08/10] libxl: add new hotplug interface support for HVM guests (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1688656,1688656#msg-1688656</link>
            <description><![CDATA[ Reads the results of the hotplug script execution and changes<br />
pdev_path libxl_device_disk to point to the block device. This will be<br />
used later when Qemu is launched.<br />
<br />
Signed-off-by: Roger Pau Monné &lt;roger.pau@citrix.com&gt;<br />
---<br />
 tools/libxl/libxl_create.c |   33 +++++++++++++++++++++++++++++++++<br />
 1 files changed, 33 insertions(+), 0 deletions(-)<br />
<br />
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c<br />
index c176967..1d5410f 100644<br />
--- a/tools/libxl/libxl_create.c<br />
+++ b/tools/libxl/libxl_create.c<br />
@@ -964,6 +964,10 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev,<br />
     libxl__domain_create_state *dcs = CONTAINER_OF(multidev, *dcs, multidev);<br />
     STATE_AO_GC(dcs-&gt;ao);<br />
     int i;<br />
+    char *hotplug_path;<br />
+    const char *pdev;<br />
+    libxl__device dev;<br />
+    libxl_device_disk *disk;<br />
 <br />
     /* convenience aliases */<br />
     const uint32_t domid = dcs-&gt;guest_domid;<br />
@@ -975,6 +979,35 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev,<br />
         goto error_out;<br />
     }<br />
 <br />
+    /*<br />
+     * If using the new hotplug interface change disks pdev_path<br />
+     * to point to the real physical path, so it can be used by Qemu.<br />
+     */<br />
+    for (i = 0; i &lt; d_config-&gt;num_disks; i++) {<br />
+        disk = &amp;d_config-&gt;disks<i>;<br />
+        if (disk-&gt;hotplug_version != 0) {<br />
+            /* Update pdev_path */<br />
+            ret = libxl__device_from_disk(gc, domid, disk, &amp;dev);<br />
+            if (ret != 0) {<br />
+                LOG(ERROR, &quot;Invalid or unsupported virtual disk identifier %s&quot;,<br />
+                           disk-&gt;vdev);<br />
+                goto error_out;<br />
+            }<br />
+            hotplug_path = libxl__device_xs_hotplug_path(gc, &amp;dev);<br />
+            ret = libxl__xs_read_checked(gc, XBT_NULL,<br />
+                                         GCSPRINTF(&quot;%s/pdev&quot;, hotplug_path),<br />
+                                         &amp;pdev);<br />
+            if (ret)<br />
+                goto error_out;<br />
+            if (!pdev) {<br />
+                ret = ERROR_FAIL;<br />
+                goto error_out;<br />
+            }<br />
+            free(disk-&gt;pdev_path);<br />
+            disk-&gt;pdev_path = libxl__strdup(NOGC, pdev);<br />
+        }<br />
+    }<br />
+<br />
     for (i = 0; i &lt; d_config-&gt;b_info.num_ioports; i++) {<br />
         libxl_ioport_range *io = &amp;d_config-&gt;b_info.ioports<i>;<br />
 <br />
-- <br />
1.7.7.5 (Apple Git-26)<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]</i></i>]]></description>
            <dc:creator>Roger Pau Monne</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sat, 22 Dec 2012 01:15:03 +0800</pubDate>
        </item>
        <item>
            <guid>http://choon.net/forum/read.php?22,1688655,1688655#msg-1688655</guid>
            <title>[Xen-devel] [PATCH RFC 10/10] hotplug/Linux: add iscsi block hotplug script (no replies)</title>
            <link>http://choon.net/forum/read.php?22,1688655,1688655#msg-1688655</link>
            <description><![CDATA[ This hotplug script has been tested with IET and NetBSD iSCSI targets,<br />
without authentication.<br />
<br />
Authentication parameters, including the password are passed as<br />
parameters to iscsiadm, which is not recommended because other users<br />
of the system can see them. This parameters could also be set by<br />
editing a corresponding file directly, but the location of this file<br />
seems to be different depending on the distribution used.<br />
<br />
Signed-off-by: Roger Pau Monné &lt;roger.pau@citrix.com&gt;<br />
---<br />
 tools/hotplug/Linux/Makefile    |    1 +<br />
 tools/hotplug/Linux/block-iscsi |  254 +++++++++++++++++++++++++++++++++++++++<br />
 2 files changed, 255 insertions(+), 0 deletions(-)<br />
 create mode 100644 tools/hotplug/Linux/block-iscsi<br />
<br />
diff --git a/tools/hotplug/Linux/Makefile b/tools/hotplug/Linux/Makefile<br />
index 0605559..98c7738 100644<br />
--- a/tools/hotplug/Linux/Makefile<br />
+++ b/tools/hotplug/Linux/Makefile<br />
@@ -21,6 +21,7 @@ XEN_SCRIPTS += blktap<br />
 XEN_SCRIPTS += xen-hotplug-cleanup<br />
 XEN_SCRIPTS += external-device-migrate<br />
 XEN_SCRIPTS += vscsi<br />
+XEN_SCRIPTS += block-iscsi<br />
 XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh<br />
 XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh<br />
 XEN_SCRIPT_DATA += block-common.sh<br />
diff --git a/tools/hotplug/Linux/block-iscsi b/tools/hotplug/Linux/block-iscsi<br />
new file mode 100644<br />
index 0000000..ddb96c5<br />
--- /dev/null<br />
+++ b/tools/hotplug/Linux/block-iscsi<br />
@@ -0,0 +1,254 @@<br />
+#!/bin/sh<br />
+#<br />
+# Open-iSCSI Xen block device hotplug script<br />
+#<br />
+# Author Roger Pau Monné &lt;roger.pau@citrix.com&gt;<br />
+#<br />
+# This program is free software; you can redistribute it and/or modify<br />
+# it under the terms of the GNU Lesser General Public License as published<br />
+# by the Free Software Foundation; version 2.1 only. with the special<br />
+# exception on linking described in file LICENSE.<br />
+#<br />
+# This program is distributed in the hope that it will be useful,<br />
+# but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br />
+# GNU Lesser General Public License for more details.<br />
+<br />
+remove_label()<br />
+{<br />
+    echo $1 | sed &quot;s/^\(&quot;$2&quot;\)//&quot;<br />
+}<br />
+<br />
+check_tools()<br />
+{<br />
+    if ! type iscsiadm &gt; /dev/null 2&gt;&amp;1; then<br />
+        echo &quot;Unable to find iscsiadm tool&quot;<br />
+        return 1<br />
+    fi<br />
+    if [ &quot;$multipath&quot; = &quot;y&quot; ] &amp;&amp; ! type multipath &gt; /dev/null 2&gt;&amp;1; then<br />
+        echo &quot;Unable to find multipath&quot;<br />
+        return 1<br />
+    fi<br />
+}<br />
+<br />
+# Sets the following global variables based on the params field passed in as<br />
+# a parameter: iqn, portal, auth_method, user, multipath, password<br />
+parse_target()<br />
+{<br />
+    # set multipath default value<br />
+    multipath=&quot;n&quot;<br />
+    for param in $(echo &quot;$1&quot; | tr &quot;,&quot; &quot;\n&quot;)<br />
+    do<br />
+        if [ -n &quot;$password&quot; ]; then<br />
+            password=&quot;$password,$param&quot;<br />
+            continue<br />
+        fi<br />
+        case $param in<br />
+        iqn=*)<br />
+            iqn=$(remove_label $param &quot;iqn=&quot;)<br />
+            ;;<br />
+        portal=*)<br />
+            portal=$(remove_label $param &quot;portal=&quot;)<br />
+            ;;<br />
+        auth_method=*)<br />
+            auth_method=$(remove_label $param &quot;auth_method=&quot;)<br />
+            ;;<br />
+        user=*)<br />
+            user=$(remove_label $param &quot;user=&quot;)<br />
+            ;;<br />
+        multipath=*)<br />
+            multipath=$(remove_label $param &quot;multipath=&quot;)<br />
+            ;;<br />
+        password=*)<br />
+            password=$(remove_label $param &quot;password=&quot;)<br />
+            ;;<br />
+        esac<br />
+    done<br />
+    if [ -z &quot;$iqn&quot; ] || [ -z &quot;$portal&quot; ]; then<br />
+        echo &quot;iqn= and portal= are required parameters&quot;<br />
+        return 1<br />
+    fi<br />
+    if [ &quot;$multipath&quot; != &quot;y&quot; ] &amp;&amp; [ &quot;$multipath&quot; != &quot;n&quot; ]; then<br />
+        echo &quot;multipath valid values are y and n, $multipath not a valid value&quot;<br />
+        return 1<br />
+    fi<br />
+    return 0<br />
+}<br />
+<br />
+# Outputs the block device major:minor<br />
+device_major_minor()<br />
+{<br />
+    stat -L -c %t:%T &quot;$1&quot;<br />
+}<br />
+<br />
+# Sets $dev to point to the device associated with the value in iqn<br />
+find_device()<br />
+{<br />
+    while [ ! -e /dev/disk/by-path/*&quot;$iqn&quot;-lun-0 ]; do<br />
+        sleep 0.1<br />
+    done<br />
+    sddev=$(readlink -f /dev/disk/by-path/*&quot;$iqn&quot;-lun-0)<br />
+    if [ ! -b &quot;$sddev&quot; ]; then<br />
+        echo &quot;Unable to find attached device path&quot;<br />
+        return 1<br />
+    fi<br />
+    if [ &quot;$multipath&quot; = &quot;y&quot; ]; then<br />
+        mdev=$(multipath -ll &quot;$sddev&quot; | head -1 | awk '{ print $1}')<br />
+        if [ ! -b /dev/mapper/&quot;$mdev&quot; ]; then<br />
+            echo &quot;Unable to find attached device multipath&quot;<br />
+            return 1<br />
+        fi<br />
+        dev=&quot;/dev/mapper/$mdev&quot;<br />
+    else<br />
+        dev=&quot;$sddev&quot;<br />
+    fi<br />
+    return 0<br />
+}<br />
+<br />
+# Attaches the target $iqn in $portal and sets $dev to point to the<br />
+# multipath device<br />
+attach()<br />
+{<br />
+    iscsiadm -m node --targetname &quot;$iqn&quot; -p &quot;$portal&quot; --login &gt; /dev/null 2&gt;&amp;1<br />
+    if [ $? -ne 0 ]; then<br />
+        echo &quot;Unable to connect to target&quot;<br />
+        return 1<br />
+    fi<br />
+    find_device<br />
+    if [ $? -ne 0 ]; then<br />
+        echo &quot;Unable to find iSCSI device&quot;<br />
+        return 1<br />
+    fi<br />
+    return 0<br />
+}<br />
+<br />
+# Discovers targets in $portal and checks that $iqn is one of those targets<br />
+# Also sets the auth parameters to attach the device<br />
+prepare()<br />
+{<br />
+    # Check if target is already opened<br />
+    iscsiadm -m session 2&gt;&amp;1 | grep -q &quot;$iqn&quot;<br />
+    if [ $? -eq 0 ]; then<br />
+        echo &quot;Device already opened&quot;<br />
+        return 1<br />
+    fi<br />
+    # Discover portal targets<br />
+    iscsiadm -m discovery -t st -p $portal 2&gt;&amp;1 | grep -q &quot;$iqn&quot;<br />
+    if [ $? -ne 0 ]; then<br />
+        echo &quot;No matching target iqn found&quot;<br />
+        return 1<br />
+    fi<br />
+    # Set auth method if necessary<br />
+    if [ -n &quot;$auth_method&quot; ] || [ -n &quot;$user&quot; ] || [ -n &quot;$password&quot; ]; then<br />
+        iscsiadm -m node --targetname &quot;$iqn&quot; -p &quot;$portal&quot; --op=update --name \<br />
+            node.session.auth.authmethod --value=&quot;$auth_method&quot; \<br />
+            &gt; /dev/null 2&gt;&amp;1 &amp;&amp; \<br />
+        iscsiadm -m node --targetname &quot;$iqn&quot; -p &quot;$portal&quot; --op=update --name \<br />
+            node.session.auth.username --value=&quot;$user&quot; \<br />
+            &gt; /dev/null 2&gt;&amp;1 &amp;&amp; \<br />
+        iscsiadm -m node --targetname &quot;$iqn&quot; -p &quot;$portal&quot; --op=update --name \<br />
+            node.session.auth.password --value=&quot;$password&quot; \<br />
+            &gt; /dev/null 2&gt;&amp;1<br />
+        if [ $? -ne 0 ]; then<br />
+            echo &quot;Unable to set authentication parameters&quot;<br />
+            return 1<br />
+        fi<br />
+    fi<br />
+    return 0<br />
+}<br />
+<br />
+# Attaches the device and writes xenstore backend entries to connect<br />
+# the device<br />
+add()<br />
+{<br />
+    localattach<br />
+    if [ $? -ne 0 ]; then<br />
+        echo &quot;Failed to attach device&quot;<br />
+        return 1<br />
+    fi<br />
+    mm=$(device_major_minor &quot;$dev&quot;)<br />
+    xenstore-write &quot;$BACKEND_PATH/physical-device&quot; &quot;$mm&quot;<br />
+    xenstore-write &quot;$BACKEND_PATH/params&quot; &quot;$dev&quot;<br />
+    return 0<br />
+}<br />
+<br />
+# Disconnects the device<br />
+remove()<br />
+{<br />
+    find_device<br />
+    if [ $? -ne 0 ]; then<br />
+        echo &quot;Unable to find device&quot;<br />
+        return 1<br />
+    fi<br />
+    iscsiadm -m node --targetname &quot;$iqn&quot; -p &quot;$portal&quot; --logout &gt; /dev/null 2&gt;&amp;1<br />
+    if [ $? -ne 0 ]; then<br />
+        echo &quot;Unable to disconnect target&quot;<br />
+        return 1<br />
+    fi<br />
+    return 0<br />
+}<br />
+<br />
+# Removes the auth params set by prepare<br />
+unprepare()<br />
+{<br />
+    if [ -n &quot;$auth_method&quot; ] || [ -n &quot;$user&quot; ] || [ -n &quot;$password&quot; ]; then<br />
+        iscsiadm -m node --targetname &quot;$iqn&quot; -p &quot;$portal&quot; --op=delete --name \<br />
+            node.session.auth.authmethod &gt; /dev/null 2&gt;&amp;1<br />
+        iscsiadm -m node --targetname &quot;$iqn&quot; -p &quot;$portal&quot; --op=delete --name \<br />
+            node.session.auth.username &gt; /dev/null 2&gt;&amp;1<br />
+        iscsiadm -m node --targetname &quot;$iqn&quot; -p &quot;$portal&quot; --op=delete --name \<br />
+            node.session.auth.password &gt; /dev/null 2&gt;&amp;1<br />
+    fi<br />
+}<br />
+<br />
+# Attaches the device to the current domain, and writes the resulting<br />
+# block device to xenstore<br />
+localattach()<br />
+{<br />
+    attach<br />
+    if [ $? -ne 0 ]; then<br />
+        echo &quot;Failed to attach device&quot;<br />
+        return 1<br />
+    fi<br />
+    xenstore-write &quot;$HOTPLUG_PATH/pdev&quot; &quot;$dev&quot;<br />
+    return 0<br />
+}<br />
+<br />
+command=$1<br />
+target=$(xenstore-read $HOTPLUG_PATH/params)<br />
+<br />
+if [ -z &quot;$target&quot; ]; then<br />
+    echo &quot;No information about the target&quot;<br />
+    exit 1<br />
+fi<br />
+<br />
+check_tools || exit 1<br />
+<br />
+parse_target &quot;$target&quot;<br />
+<br />
+case $command in<br />
+prepare)<br />
+    prepare<br />
+    exit $?<br />
+    ;;<br />
+add)<br />
+    add<br />
+    exit $?<br />
+    ;;<br />
+remove)<br />
+    remove<br />
+    exit $?<br />
+    ;;<br />
+unprepare)<br />
+    unprepare<br />
+    exit $?<br />
+    ;;<br />
+localattach)<br />
+    localattach<br />
+    exit $?<br />
+    ;;<br />
+localdetach)<br />
+    remove<br />
+    exit $?<br />
+    ;;<br />
+esac<br />
-- <br />
1.7.7.5 (Apple Git-26)<br />
<br />
<br />
_______________________________________________<br />
Xen-devel mailing list<br />
<a href="mailto:&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;">&#88;&#101;&#110;&#45;&#100;&#101;&#118;&#101;&#108;&#64;&#108;&#105;&#115;&#116;&#115;&#46;&#120;&#101;&#110;&#46;&#111;&#114;&#103;</a><br />
[<a href="http://lists.xen.org/xen-devel"  rel="nofollow">lists.xen.org</a>]]]></description>
            <dc:creator>Roger Pau Monne</dc:creator>
            <category>Xen-devel</category>
            <pubDate>Sat, 22 Dec 2012 01:15:02 +0800</pubDate>
        </item>
    </channel>
</rss>
