From patchwork Tue May 9 21:22:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Xiong Y" X-Patchwork-Id: 9717041 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 063D260365 for ; Tue, 9 May 2017 05:21:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EA3F3269DA for ; Tue, 9 May 2017 05:21:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DBFA528338; Tue, 9 May 2017 05:21:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=BAYES_00, DATE_IN_FUTURE_12_24, RCVD_IN_DNSWL_MED autolearn=no version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 45237269DA for ; Tue, 9 May 2017 05:21:56 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d7xXc-00057j-Ja; Tue, 09 May 2017 05:18:32 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d7xXb-00057d-SH for xen-devel@lists.xen.org; Tue, 09 May 2017 05:18:31 +0000 Received: from [85.158.139.211] by server-13.bemta-5.messagelabs.com id AD/74-01709-72151195; Tue, 09 May 2017 05:18:31 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrELMWRWlGSWpSXmKPExsXS1tbhqKscKBh pcPSwvMWSj4tZHBg9ju7+zRTAGMWamZeUX5HAmjF7xn62gvnWFVMePWVsYPyo28XIxSEkMJ1R ov3UHaYuRk4OCQFeiSPLZrB2MXIA2QESzStVIWpaGCVmdZ9iBKlhE9CWWPv3FBuILSIgLXHt8 2VGkCJmgUOMEtt+zmQGSQgLZEpM/TcFrIFFQFXi1c8NYA28Am4S67uvM0Isk5O4ea6TeQIj9w JGhlWM6sWpRWWpRbrGeklFmekZJbmJmTm6hgamermpxcWJ6ak5iUnFesn5uZsYgf5lAIIdjHv /OR1ilORgUhLl9SkWiBTiS8pPqcxILM6ILyrNSS0+xCjDwaEkwesWIBgpJFiUmp5akZaZAww0 mLQEB4+SCK8uSJq3uCAxtzgzHSJ1ilGXY9fcd++ZhFjy8vNSpcR5t/sDFQmAFGWU5sGNgAX9J UZZKWFeRqCjhHgKUotyM0tQ5V8xinMwKgnzbgSZwpOZVwK36RXQEUxARwQyCIAcUZKIkJJqYD RMLC3XOqMVs7C5XLosjc8kUPtQt9udC1s2/jmRziKvzqopUFesdjqax/9/+vZd8n6LYk5FfEg 662rQEHnU1Iaz33mOG1+7XqVxwaqD9+NviNVu/6D9bcon19vSLdN0dxucb7YJkm8TbHtsaGT6 uSBPc17Ajrjme+uvFKuZ6+tvadi4I6FPiaU4I9FQi7moOBEA54IE5nUCAAA= X-Env-Sender: xiong.y.zhang@intel.com X-Msg-Ref: server-4.tower-206.messagelabs.com!1494307105!96970652!1 X-Originating-IP: [134.134.136.65] X-SpamReason: No, hits=2.8 required=7.0 tests=BODY_RANDOM_LONG, DATE_IN_FUTURE_12_24 X-StarScan-Received: X-StarScan-Version: 9.4.12; banners=-,-,- X-VirusChecked: Checked Received: (qmail 27864 invoked from network); 9 May 2017 05:18:27 -0000 Received: from mga03.intel.com (HELO mga03.intel.com) (134.134.136.65) by server-4.tower-206.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 9 May 2017 05:18:27 -0000 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 May 2017 22:18:24 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.38,312,1491289200"; d="scan'208"; a="1145424705" Received: from test-optiplex-7040.bj.intel.com ([10.238.154.174]) by fmsmga001.fm.intel.com with ESMTP; 08 May 2017 22:18:22 -0700 From: Xiong Zhang To: xen-devel@lists.xen.org Date: Wed, 10 May 2017 05:22:44 +0800 Message-Id: <1494364964-3775-1-git-send-email-xiong.y.zhang@intel.com> X-Mailer: git-send-email 2.7.4 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 Subject: [Xen-devel] [PATCH V2] x86/ioreq server: Fix XenGT couldn't reboot when XenGT use p2m_ioreq_server p2m_type X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP '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 Signed-off-by: Yu Zhang --- 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);