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
next 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 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).