All of lore.kernel.org
 help / color / mirror / Atom feed
From: Xiong Zhang <xiong.y.zhang@intel.com>
To: xen-devel@lists.xen.org
Cc: george.dunlap@eu.citrix.com, andrew.cooper3@citrix.com,
	paul.durrant@citrix.com, yu.c.zhang@linux.intel.com,
	zhiyuan.lv@intel.com, JBeulich@suse.com,
	Xiong Zhang <xiong.y.zhang@intel.com>
Subject: [PATCH] x86/ioreq server: Fix DomU couldn't reboot when using p2m_ioreq_server p2m_type
Date: Fri,  5 May 2017 11:52:14 +0800	[thread overview]
Message-ID: <1493956334-3310-1-git-send-email-xiong.y.zhang@intel.com> (raw)

'commit 1679e0df3df6 ("x86/ioreq server: asynchronously reset
outstanding p2m_ioreq_server entries")' will call
p2m_change_entry_type_global() which set entry.recalc=1. Then
the following get_entry(p2m_ioreq_server) will return
p2m_ram_rw type.
But 'commit 6d774a951696 ("x86/ioreq server: synchronously reset
outstanding p2m_ioreq_server entries when an ioreq server unmaps")'
assume get_entry(p2m_ioreq_server) will return p2m_ioreq_server
type, then reset p2m_ioreq_server entries. The fact is the assumption
isn't true, and sysnchronously reset function couldn't work. Then
ioreq.entry_count is larger than zero after an ioreq server unmaps,
finally this results DomU couldn't reboot.

This patch add a P2M_PRE_RECALC flag to p2m_query_t, then
get_entry(P2M_PRE_RECALC) will return p2m_ioreq_server type
for p2m_ioreq_server pfn, and finally change mem type through set_entry.

Fix: 'commit 6d774a951696 ("x86/ioreq server: synchronously reset
      outstanding p2m_ioreq_server entries when an ioreq server unmaps")'

Signed-off-by: Xiong Zhang <xiong.y.zhang@intel.com>
Signed-off-by: Yu Zhang <yu.c.zhang@linux.intel.com>
---
 xen/arch/x86/mm/p2m-ept.c |  7 +++++--
 xen/arch/x86/mm/p2m-pt.c  | 19 ++++++++++++++-----
 xen/arch/x86/mm/p2m.c     |  8 +++++---
 xen/include/asm-x86/p2m.h |  1 +
 4 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
index f37a1f2..8f88d2b 100644
--- a/xen/arch/x86/mm/p2m-ept.c
+++ b/xen/arch/x86/mm/p2m-ept.c
@@ -991,8 +991,11 @@ static mfn_t ept_get_entry(struct p2m_domain *p2m,
 
     if ( is_epte_valid(ept_entry) )
     {
-        *t = p2m_recalc_type(recalc || ept_entry->recalc,
-                             ept_entry->sa_p2mt, p2m, gfn);
+        if ( !(q & P2M_PRE_RECALC) )
+            *t = p2m_recalc_type(recalc || ept_entry->recalc,
+                                 ept_entry->sa_p2mt, p2m, gfn);
+        else
+            *t = ept_entry->sa_p2mt;
         *a = ept_entry->access;
         if ( sve )
             *sve = ept_entry->suppress_ve;
diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c
index 5079b59..50e74f5 100644
--- a/xen/arch/x86/mm/p2m-pt.c
+++ b/xen/arch/x86/mm/p2m-pt.c
@@ -840,8 +840,11 @@ pod_retry_l3:
             mfn = _mfn(l3e_get_pfn(*l3e) +
                        l2_table_offset(addr) * L1_PAGETABLE_ENTRIES +
                        l1_table_offset(addr));
-            *t = p2m_recalc_type(recalc || _needs_recalc(flags),
-                                 p2m_flags_to_type(flags), p2m, gfn);
+            if ( !(q & P2M_PRE_RECALC) )
+                *t = p2m_recalc_type(recalc || _needs_recalc(flags),
+                                p2m_flags_to_type(flags), p2m, gfn);
+            else
+                *t = p2m_flags_to_type(flags);
             unmap_domain_page(l3e);
 
             ASSERT(mfn_valid(mfn) || !p2m_is_ram(*t));
@@ -879,8 +882,11 @@ pod_retry_l2:
     if ( flags & _PAGE_PSE )
     {
         mfn = _mfn(l2e_get_pfn(*l2e) + l1_table_offset(addr));
-        *t = p2m_recalc_type(recalc || _needs_recalc(flags),
-                             p2m_flags_to_type(flags), p2m, gfn);
+        if ( !(q & P2M_PRE_RECALC) )
+            *t = p2m_recalc_type(recalc || _needs_recalc(flags),
+                                p2m_flags_to_type(flags), p2m, gfn);
+        else
+            *t = p2m_flags_to_type(flags);
         unmap_domain_page(l2e);
         
         ASSERT(mfn_valid(mfn) || !p2m_is_ram(*t));
@@ -916,7 +922,10 @@ pod_retry_l1:
         return INVALID_MFN;
     }
     mfn = _mfn(l1e_get_pfn(*l1e));
-    *t = p2m_recalc_type(recalc || _needs_recalc(flags), l1t, p2m, gfn);
+    if ( !(q & P2M_PRE_RECALC) )
+        *t = p2m_recalc_type(recalc || _needs_recalc(flags), l1t, p2m, gfn);
+    else
+        *t = l1t;
     unmap_domain_page(l1e);
 
     ASSERT(mfn_valid(mfn) || !p2m_is_ram(*t) || p2m_is_paging(*t));
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 1d57e5c..1c3e22f 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1020,6 +1020,8 @@ void p2m_finish_type_change(struct domain *d,
     p2m_type_t t;
     unsigned long gfn = gfn_x(first_gfn);
     unsigned long last_gfn = gfn + max_nr - 1;
+    mfn_t mfn;
+    p2m_access_t a;
 
     ASSERT(ot != nt);
     ASSERT(p2m_is_changeable(ot) && p2m_is_changeable(nt));
@@ -1029,10 +1031,10 @@ void p2m_finish_type_change(struct domain *d,
     last_gfn = min(last_gfn, p2m->max_mapped_pfn);
     while ( gfn <= last_gfn )
     {
-        get_gfn_query_unlocked(d, gfn, &t);
-
+        mfn = p2m->get_entry(p2m, gfn, &t, &a, P2M_PRE_RECALC, NULL, NULL);
         if ( t == ot )
-            p2m_change_type_one(d, gfn, t, nt);
+            p2m_set_entry(p2m, gfn, mfn, PAGE_ORDER_4K, nt,
+                          p2m->default_access);
 
         gfn++;
     }
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 7574a9b..9645260 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -78,6 +78,7 @@ typedef enum {
 typedef unsigned int p2m_query_t;
 #define P2M_ALLOC    (1u<<0)   /* Populate PoD and paged-out entries */
 #define P2M_UNSHARE  (1u<<1)   /* Break CoW sharing */
+#define P2M_PRE_RECALC (1u<<2)   /* Get p2m type before recalc */
 
 /* We use bitmaps and maks to handle groups of types */
 #define p2m_to_mask(_t) (1UL << (_t))
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

             reply	other threads:[~2017-05-05  3:52 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-05  3:52 Xiong Zhang [this message]
2017-05-05 14:40 ` [PATCH] x86/ioreq server: Fix DomU couldn't reboot when using p2m_ioreq_server p2m_type Jan Beulich
2017-05-06  1:51   ` Zhang, Xiong Y
2017-05-08  7:04     ` Jan Beulich
2017-05-08 10:52       ` Zhang, Xiong Y
2017-05-08 11:12         ` George Dunlap
2017-05-08 11:59           ` Zhang, Xiong Y
2017-05-08 12:13             ` Jan Beulich
2017-05-09  5:21           ` Yu Zhang
2017-05-09  9:24             ` George Dunlap
2017-05-08 13:26   ` George Dunlap
2017-05-08 13:55     ` George Dunlap
2017-05-08 15:47       ` Jan Beulich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1493956334-3310-1-git-send-email-xiong.y.zhang@intel.com \
    --to=xiong.y.zhang@intel.com \
    --cc=JBeulich@suse.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=george.dunlap@eu.citrix.com \
    --cc=paul.durrant@citrix.com \
    --cc=xen-devel@lists.xen.org \
    --cc=yu.c.zhang@linux.intel.com \
    --cc=zhiyuan.lv@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.