xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Xiong Zhang <xiong.y.zhang@intel.com>
To: xen-devel@lists.xen.org
Cc: andrew.cooper3@citrix.com, george.dunlap@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 V2] x86/ioreq server: Fix XenGT couldn't reboot when XenGT use p2m_ioreq_server p2m_type
Date: Wed, 10 May 2017 05:22:44 +0800	[thread overview]
Message-ID: <1494364964-3775-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.
During XenGT domU reboot, it will unmap, map and unmap ioreq
server with old domid, the map will fail as ioreq.entry_count > 0 and
reboot process is terminated.

This patch add p2m->recalc() hook which use the existing implementation
specific function as ept resolve_misconfig and pt do_recalc, so
p2m_finish_type_change() could call p2m->recalc() directly to
change gfn p2m_type which need recalc.

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

v1: Add ioreq_pre_recalc query flag to get the old p2m_type.(Jan)
v2: Add p2m->recalc() hook to change gfn p2m_type. (George)

Signed-off-by: Xiong Zhang <xiong.y.zhang@intel.com>
Signed-off-by: Yu Zhang <yu.c.zhang@linux.intel.com>
---
 xen/arch/x86/hvm/dm.c     |  3 +--
 xen/arch/x86/mm/p2m-ept.c |  7 ++++---
 xen/arch/x86/mm/p2m-pt.c  |  7 ++++---
 xen/arch/x86/mm/p2m.c     | 12 ++----------
 xen/include/asm-x86/p2m.h |  5 +++--
 5 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c
index d72b7bd..c1627ec 100644
--- a/xen/arch/x86/hvm/dm.c
+++ b/xen/arch/x86/hvm/dm.c
@@ -412,8 +412,7 @@ static int dm_op(domid_t domid,
                     first_gfn <= p2m->max_mapped_pfn )
             {
                 /* Iterate p2m table for 256 gfns each time. */
-                p2m_finish_type_change(d, _gfn(first_gfn), 256,
-                                       p2m_ioreq_server, p2m_ram_rw);
+                p2m_finish_type_change(d, _gfn(first_gfn), 256);
 
                 first_gfn += 256;
 
diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
index f37a1f2..f96bd3b 100644
--- a/xen/arch/x86/mm/p2m-ept.c
+++ b/xen/arch/x86/mm/p2m-ept.c
@@ -502,7 +502,7 @@ static int ept_invalidate_emt_range(struct p2m_domain *p2m,
  * - zero if no adjustment was done,
  * - a positive value if at least one adjustment was done.
  */
-static int resolve_misconfig(struct p2m_domain *p2m, unsigned long gfn)
+static int ept_resolve_misconfig(struct p2m_domain *p2m, unsigned long gfn)
 {
     struct ept_data *ept = &p2m->ept;
     unsigned int level = ept->wl;
@@ -659,7 +659,7 @@ bool_t ept_handle_misconfig(uint64_t gpa)
     p2m_lock(p2m);
 
     spurious = curr->arch.hvm_vmx.ept_spurious_misconfig;
-    rc = resolve_misconfig(p2m, PFN_DOWN(gpa));
+    rc = ept_resolve_misconfig(p2m, PFN_DOWN(gpa));
     curr->arch.hvm_vmx.ept_spurious_misconfig = 0;
 
     p2m_unlock(p2m);
@@ -707,7 +707,7 @@ ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn,
         return -EINVAL;
 
     /* Carry out any eventually pending earlier changes first. */
-    ret = resolve_misconfig(p2m, gfn);
+    ret = ept_resolve_misconfig(p2m, gfn);
     if ( ret < 0 )
         return ret;
 
@@ -1238,6 +1238,7 @@ int ept_p2m_init(struct p2m_domain *p2m)
 
     p2m->set_entry = ept_set_entry;
     p2m->get_entry = ept_get_entry;
+    p2m->recalc = ept_resolve_misconfig;
     p2m->change_entry_type_global = ept_change_entry_type_global;
     p2m->change_entry_type_range = ept_change_entry_type_range;
     p2m->memory_type_changed = ept_memory_type_changed;
diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c
index 5079b59..b0f6aa0 100644
--- a/xen/arch/x86/mm/p2m-pt.c
+++ b/xen/arch/x86/mm/p2m-pt.c
@@ -367,7 +367,7 @@ static int p2m_pt_set_recalc_range(struct p2m_domain *p2m,
  * GFN. Propagate the re-calculation flag down to the next page table level
  * for entries not involved in the translation of the given GFN.
  */
-static int do_recalc(struct p2m_domain *p2m, unsigned long gfn)
+static int p2m_pt_do_recalc(struct p2m_domain *p2m, unsigned long gfn)
 {
     void *table;
     unsigned long gfn_remainder = gfn;
@@ -493,7 +493,7 @@ int p2m_pt_handle_deferred_changes(uint64_t gpa)
     int rc;
 
     p2m_lock(p2m);
-    rc = do_recalc(p2m, PFN_DOWN(gpa));
+    rc = p2m_pt_do_recalc(p2m, PFN_DOWN(gpa));
     p2m_unlock(p2m);
 
     return rc;
@@ -555,7 +555,7 @@ p2m_pt_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn,
     }
 
     /* Carry out any eventually pending earlier changes first. */
-    rc = do_recalc(p2m, gfn);
+    rc = p2m_pt_do_recalc(p2m, gfn);
     if ( rc < 0 )
         return rc;
 
@@ -1153,6 +1153,7 @@ void p2m_pt_init(struct p2m_domain *p2m)
 {
     p2m->set_entry = p2m_pt_set_entry;
     p2m->get_entry = p2m_pt_get_entry;
+    p2m->recalc = p2m_pt_do_recalc;
     p2m->change_entry_type_global = p2m_pt_change_entry_type_global;
     p2m->change_entry_type_range = p2m_pt_change_entry_type_range;
     p2m->write_p2m_entry = paging_write_p2m_entry;
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 1d57e5c..2bad2e1 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1013,26 +1013,18 @@ void p2m_change_type_range(struct domain *d,
 
 /* Synchronously modify the p2m type for a range of gfns from ot to nt. */
 void p2m_finish_type_change(struct domain *d,
-                            gfn_t first_gfn, unsigned long max_nr,
-                            p2m_type_t ot, p2m_type_t nt)
+                            gfn_t first_gfn, unsigned long max_nr)
 {
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
-    p2m_type_t t;
     unsigned long gfn = gfn_x(first_gfn);
     unsigned long last_gfn = gfn + max_nr - 1;
 
-    ASSERT(ot != nt);
-    ASSERT(p2m_is_changeable(ot) && p2m_is_changeable(nt));
-
     p2m_lock(p2m);
 
     last_gfn = min(last_gfn, p2m->max_mapped_pfn);
     while ( gfn <= last_gfn )
     {
-        get_gfn_query_unlocked(d, gfn, &t);
-
-        if ( t == ot )
-            p2m_change_type_one(d, gfn, t, nt);
+        p2m->recalc(p2m, gfn);
 
         gfn++;
     }
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 7574a9b..081639c 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -246,6 +246,8 @@ struct p2m_domain {
                                     p2m_query_t q,
                                     unsigned int *page_order,
                                     bool_t *sve);
+    int                (*recalc)(struct p2m_domain *p2m,
+                                 unsigned long gfn);
     void               (*enable_hardware_log_dirty)(struct p2m_domain *p2m);
     void               (*disable_hardware_log_dirty)(struct p2m_domain *p2m);
     void               (*flush_hardware_cached_dirty)(struct p2m_domain *p2m);
@@ -609,8 +611,7 @@ int p2m_change_type_one(struct domain *d, unsigned long gfn,
 /* Synchronously change the p2m type for a range of gfns */
 void p2m_finish_type_change(struct domain *d,
                             gfn_t first_gfn,
-                            unsigned long max_nr,
-                            p2m_type_t ot, p2m_type_t nt);
+                            unsigned long max_nr);
 
 /* Report a change affecting memory types. */
 void p2m_memory_type_changed(struct domain *d);
-- 
2.7.4


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

             reply	other threads:[~2017-05-09 21:22 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-09 21:22 Xiong Zhang [this message]
2017-05-09  9:44 ` [PATCH V2] x86/ioreq server: Fix XenGT couldn't reboot when XenGT use p2m_ioreq_server p2m_type George Dunlap
2017-05-09 10:08   ` Jan Beulich
2017-05-09 10:21     ` George Dunlap
2017-05-09 10:51       ` Jan Beulich
2017-05-09 11:02         ` George Dunlap
2017-05-10 22:57           ` [PATCH V3] x86/ioreq_server: Make p2m_finish_type_change actually work Xiong Zhang
2017-05-10 10:34             ` George Dunlap
2017-05-10 10:41             ` Jan Beulich
2017-05-12  2:42             ` [PATCH V4] " Xiong Zhang
2017-05-11 11:12               ` Jan Beulich
2017-05-11 17:46                 ` Julien Grall
2017-05-13  0:34                   ` [PATCH V5] " Xiong Zhang
2017-05-15 13:47                     ` George Dunlap
2017-05-17 13:58                       ` Julien Grall
2017-05-15 13:46               ` [PATCH V4] " George Dunlap
2017-05-09 10:22     ` [PATCH V2] x86/ioreq server: Fix XenGT couldn't reboot when XenGT use p2m_ioreq_server p2m_type Zhang, Xiong Y

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=1494364964-3775-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@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).