From patchwork Mon Sep 11 04:38:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haozhong Zhang X-Patchwork-Id: 9946605 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 52C156035D for ; Mon, 11 Sep 2017 04:42:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4917621C9A for ; Mon, 11 Sep 2017 04:42:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3D7CC27F2B; Mon, 11 Sep 2017 04:42:05 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham 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 ADE4728173 for ; Mon, 11 Sep 2017 04:42:04 +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 1drGVc-0002GE-GY; Mon, 11 Sep 2017 04:39:44 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1drGVb-0002Dl-Ef for xen-devel@lists.xen.org; Mon, 11 Sep 2017 04:39:43 +0000 Received: from [193.109.254.147] by server-9.bemta-6.messagelabs.com id BF/9C-03422-E8316B95; Mon, 11 Sep 2017 04:39:42 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrJLMWRWlGSWpSXmKPExsXS1tYhotsnvC3 S4N0HJoslHxezODB6HN39mymAMYo1My8pvyKBNePjt06WgotmFTte6TYw3tPoYuTiEBKYzihx dtdd5i5GTg4JAV6JI8tmsELYARIfz3UyQhT1MkosbZkLVsQmoC+x4vFBsCIRAWmJa58vM4LYz AINTBJvboaB2MICERI/Jtxk62Lk4GARUJXof1kMEuYVsJN437ULar68xK62i2A2J1D84Mt3YO OFBGwlFpxewDqBkXcBI8MqRo3i1KKy1CJdI3O9pKLM9IyS3MTMHF1DAzO93NTi4sT01JzEpGK 95PzcTYzAYGAAgh2Mi9cGHmKU5GBSEuV9d3xLpBBfUn5KZUZicUZ8UWlOavEhRhkODiUJXhWh bZFCgkWp6akVaZk5wLCESUtw8CiJ8EaBpHmLCxJzizPTIVKnGHU5Om7e/cMkxJKXn5cqJc4rB 1IkAFKUUZoHNwIWI5cYZaWEeRmBjhLiKUgtys0sQZV/xSjOwagkzBsBMoUnM68EbtMroCOYgI 7gubQF5IiSRISUVAOjQCfLlk8ieTtCmO9G5x25MuGk5eGa5CC9zZP2LXX751T98cKSB6ayG+s niZWkd5yU23wooj0yJ3G6yETdx5OnzRc1SF387YzgL4N4PhlJ1rWPvnpOdF3DL7a7wSSnM7lx +4f7p+8Hvk1OkBQuZj6j7BHJy2++sfLztLNbu7cxbvYIUloqYzNDiaU4I9FQi7moOBEA1ZTYL IwCAAA= X-Env-Sender: haozhong.zhang@intel.com X-Msg-Ref: server-2.tower-27.messagelabs.com!1505104735!56506342!21 X-Originating-IP: [134.134.136.20] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogMTM0LjEzNC4xMzYuMjAgPT4gMzU1MzU4\n X-StarScan-Received: X-StarScan-Version: 9.4.45; banners=-,-,- X-VirusChecked: Checked Received: (qmail 50210 invoked from network); 11 Sep 2017 04:39:41 -0000 Received: from mga02.intel.com (HELO mga02.intel.com) (134.134.136.20) by server-2.tower-27.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 11 Sep 2017 04:39:41 -0000 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 10 Sep 2017 21:39:40 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.42,376,1500966000"; d="scan'208"; a="1217078515" Received: from hz-desktop.sh.intel.com (HELO localhost) ([10.239.159.142]) by fmsmga002.fm.intel.com with ESMTP; 10 Sep 2017 21:39:39 -0700 From: Haozhong Zhang To: xen-devel@lists.xen.org Date: Mon, 11 Sep 2017 12:38:07 +0800 Message-Id: <20170911043820.14617-27-haozhong.zhang@intel.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170911043820.14617-1-haozhong.zhang@intel.com> References: <20170911043820.14617-1-haozhong.zhang@intel.com> Cc: Haozhong Zhang , Andrew Cooper , Jan Beulich , Chao Peng , Dan Williams Subject: [Xen-devel] [RFC XEN PATCH v3 26/39] xen/pmem: add function to map PMEM pages to HVM domain 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 pmem_populate() is added to map the specifed data PMEM pages to a HVM domain. No called is added in this commit. Signed-off-by: Haozhong Zhang --- Cc: Andrew Cooper Cc: Jan Beulich --- xen/common/domain.c | 3 ++ xen/common/pmem.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++ xen/include/xen/pmem.h | 19 +++++++ xen/include/xen/sched.h | 3 ++ 4 files changed, 166 insertions(+) diff --git a/xen/common/domain.c b/xen/common/domain.c index 5aebcf265f..4354342b02 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -290,6 +290,9 @@ struct domain *domain_create(domid_t domid, unsigned int domcr_flags, INIT_PAGE_LIST_HEAD(&d->page_list); INIT_PAGE_LIST_HEAD(&d->xenpage_list); + spin_lock_init(&d->pmem_lock); + INIT_PAGE_LIST_HEAD(&d->pmem_page_list); + spin_lock_init(&d->node_affinity_lock); d->node_affinity = NODE_MASK_ALL; d->auto_node_affinity = 1; diff --git a/xen/common/pmem.c b/xen/common/pmem.c index ed4a014c30..2f9ad64a26 100644 --- a/xen/common/pmem.c +++ b/xen/common/pmem.c @@ -17,10 +17,12 @@ */ #include +#include #include #include #include #include +#include #include @@ -78,6 +80,31 @@ static bool check_overlap(unsigned long smfn1, unsigned long emfn1, (emfn1 > smfn2 && emfn1 <= emfn2); } +static bool check_cover(struct list_head *list, + unsigned long smfn, unsigned long emfn) +{ + struct list_head *cur; + struct pmem *pmem; + unsigned long pmem_smfn, pmem_emfn; + + list_for_each(cur, list) + { + pmem = list_entry(cur, struct pmem, link); + pmem_smfn = pmem->smfn; + pmem_emfn = pmem->emfn; + + if ( smfn < pmem_smfn ) + return false; + + if ( emfn <= pmem_emfn ) + return true; + + smfn = max(smfn, pmem_emfn); + } + + return false; +} + /** * Add a PMEM region to a list. All PMEM regions in the list are * sorted in the ascending order of the start address. A PMEM region, @@ -600,6 +627,120 @@ int pmem_do_sysctl(struct xen_sysctl_nvdimm_op *nvdimm) #ifdef CONFIG_X86 +static int pmem_assign_page(struct domain *d, struct page_info *pg, + unsigned long gfn) +{ + int rc; + + if ( pg->count_info != (PGC_state_free | PGC_pmem_page) ) + return -EBUSY; + + pg->count_info = PGC_allocated | PGC_state_inuse | PGC_pmem_page | 1; + pg->u.inuse.type_info = 0; + page_set_owner(pg, d); + + rc = guest_physmap_add_page(d, _gfn(gfn), _mfn(page_to_mfn(pg)), 0); + if ( rc ) + { + page_set_owner(pg, NULL); + pg->count_info = PGC_state_free | PGC_pmem_page; + + return rc; + } + + spin_lock(&d->pmem_lock); + page_list_add_tail(pg, &d->pmem_page_list); + spin_unlock(&d->pmem_lock); + + return 0; +} + +static int pmem_unassign_page(struct domain *d, struct page_info *pg, + unsigned long gfn) +{ + int rc; + + spin_lock(&d->pmem_lock); + page_list_del(pg, &d->pmem_page_list); + spin_unlock(&d->pmem_lock); + + rc = guest_physmap_remove_page(d, _gfn(gfn), _mfn(page_to_mfn(pg)), 0); + + page_set_owner(pg, NULL); + pg->count_info = PGC_state_free | PGC_pmem_page; + + return 0; +} + +int pmem_populate(struct xen_pmem_map_args *args) +{ + struct domain *d = args->domain; + unsigned long i = args->nr_done; + unsigned long mfn = args->mfn + i; + unsigned long emfn = args->mfn + args->nr_mfns; + unsigned long gfn = args->gfn + i; + struct page_info *page; + int rc = 0, err = 0; + + if ( unlikely(d->is_dying) ) + return -EINVAL; + + if ( !is_hvm_domain(d) ) + return -EINVAL; + + spin_lock(&pmem_data_lock); + + if ( !check_cover(&pmem_data_regions, mfn, emfn) ) + { + rc = -ENXIO; + goto out; + } + + for ( ; mfn < emfn; i++, mfn++, gfn++ ) + { + if ( i != args->nr_done && hypercall_preempt_check() ) + { + args->preempted = 1; + rc = -ERESTART; + break; + } + + page = mfn_to_page(mfn); + if ( !page_state_is(page, free) ) + { + rc = -EBUSY; + break; + } + + rc = pmem_assign_page(d, page, gfn); + if ( rc ) + break; + } + + out: + if ( rc && rc != -ERESTART ) + while ( i-- && !err ) + err = pmem_unassign_page(d, mfn_to_page(--mfn), --gfn); + + spin_unlock(&pmem_data_lock); + + if ( unlikely(err) ) + { + /* + * If we unfortunately fails to recover from the previous + * failure, some PMEM pages may still be mapped to the + * domain. As pmem_populate() is now called only during domain + * creation, let's crash the domain. + */ + domain_crash(d); + rc = err; + } + + args->nr_done = i; + + return rc; +} + int __init pmem_dom0_setup_permission(struct domain *d) { struct list_head *cur; diff --git a/xen/include/xen/pmem.h b/xen/include/xen/pmem.h index 9323d679a6..2dab90530b 100644 --- a/xen/include/xen/pmem.h +++ b/xen/include/xen/pmem.h @@ -33,6 +33,20 @@ int pmem_arch_setup(unsigned long smfn, unsigned long emfn, unsigned int pxm, unsigned long mgmt_smfn, unsigned long mgmt_emfn, unsigned long *used_mgmt_mfns); +struct xen_pmem_map_args { + struct domain *domain; + + unsigned long mfn; /* start MFN of pmems page to be mapped */ + unsigned long gfn; /* start GFN of target domain */ + unsigned long nr_mfns; /* number of pmem pages to be mapped */ + + /* For preemption ... */ + unsigned long nr_done; /* number of pmem pages processed so far */ + int preempted; /* Is the operation preempted? */ +}; + +int pmem_populate(struct xen_pmem_map_args *args); + #else /* !CONFIG_X86 */ static inline int pmem_dom0_setup_permission(...) @@ -45,6 +59,11 @@ static inline int pmem_arch_setup(...) return -ENOSYS; } +static inline int pmem_populate(...) +{ + return -ENOSYS; +} + #endif /* CONFIG_X86 */ #endif /* CONFIG_NVDIMM_PMEM */ diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 5b8f8c68ea..de5b85b1dd 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -323,6 +323,9 @@ struct domain atomic_t shr_pages; /* number of shared pages */ atomic_t paged_pages; /* number of paged-out pages */ + spinlock_t pmem_lock; /* protect all following pmem_ fields */ + struct page_list_head pmem_page_list; /* linked list of PMEM pages */ + /* Scheduling. */ void *sched_priv; /* scheduler-specific data */ struct cpupool *cpupool;