xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Boqun Feng <boqun.feng@intel.com>
To: xen-devel@lists.xen.org
Cc: "Kevin Tian" <kevin.tian@intel.com>,
	"Stefano Stabellini" <sstabellini@kernel.org>,
	"Wei Liu" <wei.liu2@citrix.com>,
	"Jun Nakajima" <jun.nakajima@intel.com>,
	"George Dunlap" <George.Dunlap@eu.citrix.com>,
	"Andrew Cooper" <andrew.cooper3@citrix.com>,
	"Ian Jackson" <ian.jackson@eu.citrix.com>,
	"Marek Marczykowski-Górecki" <marmarek@invisiblethingslab.com>,
	"Tim Deegan" <tim@xen.org>,
	kai.huang@linux.intel.com, "Julien Grall" <julien.grall@arm.com>,
	"Jan Beulich" <jbeulich@suse.com>,
	"David Scott" <dave@recoil.org>,
	"Boqun Feng" <boqun.feng@intel.com>
Subject: [PATCH v2 08/17] xen: x86/mm: add SGX EPC management
Date: Mon,  4 Dec 2017 08:15:19 +0800	[thread overview]
Message-ID: <20171204001528.1342-9-boqun.feng@intel.com> (raw)
In-Reply-To: <20171204001528.1342-1-boqun.feng@intel.com>

As now the heap allocator supports EPC pages, the management of EPC
pages is simply putting EPC pages into the heap at booting up if SGX is
supported and the EPC section is reported consistently. Allocation and
reclamation are just heap allocation and reclamation with MEMF_epc.

One more thing we need to do is to populate the portion of EPC pages in
the 'frame_table' and set up the mapping properly.

SGX would be disabled, if EPC initialization found any problem.

Signed-off-by: Boqun Feng <boqun.feng@intel.com>
---
 xen/arch/x86/sgx.c        | 161 ++++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-x86/sgx.h |   3 +
 2 files changed, 164 insertions(+)

diff --git a/xen/arch/x86/sgx.c b/xen/arch/x86/sgx.c
index ead917543f3e..9409b041e4f7 100644
--- a/xen/arch/x86/sgx.c
+++ b/xen/arch/x86/sgx.c
@@ -22,6 +22,8 @@
 #include <asm/cpufeature.h>
 #include <asm/msr-index.h>
 #include <asm/msr.h>
+#include <xen/errno.h>
+#include <xen/mm.h>
 #include <asm/sgx.h>
 
 struct sgx_cpuinfo __read_mostly boot_sgx_cpudata;
@@ -29,6 +31,13 @@ struct sgx_cpuinfo __read_mostly boot_sgx_cpudata;
 static bool __read_mostly opt_sgx_enabled = false;
 boolean_param("sgx", opt_sgx_enabled);
 
+#define total_epc_npages (boot_sgx_cpudata.epc_size >> PAGE_SHIFT)
+#define epc_base_mfn (boot_sgx_cpudata.epc_base >> PAGE_SHIFT)
+#define epc_base_maddr (boot_sgx_cpudata.epc_base)
+#define epc_end_maddr (epc_base_maddr + boot_sgx_cpudata.epc_size)
+
+static void *epc_base_vaddr = NULL;
+
 static void __detect_sgx(struct sgx_cpuinfo *sgxinfo)
 {
     u32 eax, ebx, ecx, edx;
@@ -166,11 +175,163 @@ static void __init print_sgx_cpuinfo(struct sgx_cpuinfo *sgxinfo)
            boot_sgx_cpudata.epc_base + boot_sgx_cpudata.epc_size);
 }
 
+struct ft_page {
+    struct page_info *pg;
+    unsigned int order;
+    unsigned long idx;
+    struct list_head list;
+};
+
+static int extend_epc_frametable(unsigned long smfn, unsigned long emfn)
+{
+    unsigned long idx;
+    LIST_HEAD(ft_pages);
+    struct ft_page *ftp, *nftp;
+    int rc = 0;
+
+    for ( ; smfn < emfn; smfn += PDX_GROUP_COUNT )
+    {
+        idx = pfn_to_pdx(smfn) / PDX_GROUP_COUNT;
+
+        if (!test_bit(idx, pdx_group_valid))
+        {
+            unsigned long s = (unsigned long)pdx_to_page(idx * PDX_GROUP_COUNT);
+            struct page_info *pg;
+
+            ftp = xzalloc(struct ft_page);
+
+            if ( !ftp )
+            {
+                rc = -ENOMEM;
+                goto out;
+            }
+
+            pg = alloc_domheap_pages(NULL, PDX_GROUP_SHIFT - PAGE_SHIFT, 0);
+
+            if ( !pg )
+            {
+                xfree(ftp);
+                rc = -ENOMEM;
+                goto out;
+            }
+
+            ftp->order = PDX_GROUP_SHIFT - PAGE_SHIFT;
+            ftp->pg = pg;
+            ftp->idx = idx;
+
+            list_add_tail(&ftp->list, &ft_pages);
+
+            map_pages_to_xen(s, page_to_mfn(pg),
+                             1UL << (PDX_GROUP_SHIFT - PAGE_SHIFT),
+                             PAGE_HYPERVISOR);
+            memset((void *)s, 0, sizeof(struct page_info) * PDX_GROUP_COUNT);
+        }
+    }
+
+out:
+    list_for_each_entry_safe(ftp, nftp, &ft_pages, list)
+    {
+        if ( rc )
+        {
+            unsigned long s = (unsigned long)pdx_to_page(ftp->idx * PDX_GROUP_COUNT);
+
+            destroy_xen_mappings(s, s + (1UL << PDX_GROUP_SHIFT));
+            free_domheap_pages(ftp->pg, ftp->order);
+        }
+        list_del(&ftp->list);
+        xfree(ftp);
+    }
+
+    if ( !rc )
+        set_pdx_range(smfn, emfn);
+
+    return rc;
+}
+
+static int __init init_epc_frametable(unsigned long mfn, unsigned long npages)
+{
+    return extend_epc_frametable(mfn, mfn + npages);
+}
+
+static int __init init_epc_heap(void)
+{
+    struct page_info *pg;
+    unsigned long nrpages = total_epc_npages;
+    unsigned long i;
+    int rc = 0;
+
+    rc = init_epc_frametable(epc_base_mfn, nrpages);
+
+    if ( rc )
+        return rc;
+
+    for ( i = 0; i < nrpages; i++ )
+    {
+        pg = mfn_to_page(epc_base_mfn + i);
+        pg->count_info |= PGC_epc;
+    }
+
+    init_domheap_pages(epc_base_maddr, epc_end_maddr);
+
+    return rc;
+}
+
+struct page_info *alloc_epc_page(void)
+{
+    struct page_info *pg = alloc_domheap_page(NULL, MEMF_epc);
+
+    if ( !pg )
+        return NULL;
+
+    /*
+     * PGC_epc will be cleared in free_heap_pages(), so we add it back at
+     * allocation time, so that is_epc_page() will return true, when this page
+     * gets freed.
+     */
+    pg->count_info |= PGC_epc;
+
+    return pg;
+}
+
+void free_epc_page(struct page_info *epg)
+{
+    free_domheap_page(epg);
+}
+
+
+static int __init sgx_init_epc(void)
+{
+    int rc = 0;
+
+    epc_base_vaddr = ioremap_wb(epc_base_maddr,
+                                total_epc_npages << PAGE_SHIFT);
+
+    if ( !epc_base_maddr )
+    {
+        printk("Failed to ioremap_wb EPC range. Disable SGX.\n");
+
+        return -EFAULT;
+    }
+
+    rc = init_epc_heap();
+
+    if ( rc )
+    {
+        printk("Failed to init heap for EPC pages. Disable SGX.\n");
+        iounmap(epc_base_vaddr);
+    }
+
+    return rc;
+}
+
 static int __init sgx_init(void)
 {
     if ( !cpu_has_sgx )
         goto not_supported;
 
+    if ( sgx_init_epc() )
+        goto not_supported;
+
     print_sgx_cpuinfo(&boot_sgx_cpudata);
 
     return 0;
diff --git a/xen/include/asm-x86/sgx.h b/xen/include/asm-x86/sgx.h
index b37ebde64e84..8fed664fa154 100644
--- a/xen/include/asm-x86/sgx.h
+++ b/xen/include/asm-x86/sgx.h
@@ -58,4 +58,7 @@ void detect_sgx(struct sgx_cpuinfo *sgxinfo);
 void disable_sgx(void);
 #define sgx_lewr() (boot_sgx_cpudata.lewr)
 
+struct page_info *alloc_epc_page(void);
+void free_epc_page(struct page_info *epg);
+
 #endif  /* __ASM_X86_SGX_H__ */
-- 
2.15.0


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

  parent reply	other threads:[~2017-12-04  0:15 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-04  0:15 [RFC PATCH v2 00/17] RFC: SGX Virtualization design and draft patches Boqun Feng
2017-12-04  0:15 ` [PATCH v2 01/17] xen: x86: expose SGX to HVM domain in CPU featureset Boqun Feng
2017-12-04 11:13   ` Julien Grall
2017-12-04 13:10     ` Boqun Feng
2017-12-04 14:13       ` Jan Beulich
2017-12-05  0:22         ` Boqun Feng
2017-12-04  0:15 ` [PATCH v2 02/17] xen: x86: add early stage SGX feature detection Boqun Feng
2017-12-04  0:15 ` [PATCH v2 03/17] xen: vmx: detect ENCLS VMEXIT Boqun Feng
2017-12-04  0:15 ` [PATCH v2 04/17] xen: x86/mm: introduce ioremap_wb() Boqun Feng
2017-12-04  0:15 ` [PATCH v2 05/17] xen: p2m: new 'p2m_epc' type for EPC mapping Boqun Feng
2017-12-04  0:15 ` [PATCH v2 06/17] xen: mm: introduce non-scrubbable pages Boqun Feng
2017-12-04  0:15 ` [PATCH v2 07/17] xen: mm: manage EPC pages in Xen heaps Boqun Feng
2017-12-04  0:15 ` Boqun Feng [this message]
2017-12-04  0:15 ` [PATCH v2 09/17] xen: x86: add functions to populate and destroy EPC for domain Boqun Feng
2017-12-04  0:15 ` [PATCH v2 10/17] xen: x86: add SGX cpuid handling support Boqun Feng
2017-12-04  0:15 ` [PATCH v2 11/17] xen: vmx: handle SGX related MSRs Boqun Feng
2017-12-04  0:15 ` [PATCH v2 12/17] xen: vmx: handle ENCLS VMEXIT Boqun Feng
2017-12-04  0:15 ` [PATCH v2 13/17] xen: vmx: handle VMEXIT from SGX enclave Boqun Feng
2017-12-04  0:15 ` [PATCH v2 14/17] xen: x86: reset EPC when guest got suspended Boqun Feng
2017-12-04  0:15 ` [PATCH v2 15/17] xen: tools: add new 'sgx' parameter support Boqun Feng
2017-12-04  0:15 ` [PATCH v2 16/17] xen: tools: add SGX to applying CPUID policy Boqun Feng
2017-12-04  0:15 ` [PATCH v2 17/17] xen: tools: add SGX to applying MSR policy Boqun Feng
2017-12-25  5:01 ` [RFC PATCH v2 00/17] RFC: SGX Virtualization design and draft patches Boqun Feng

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=20171204001528.1342-9-boqun.feng@intel.com \
    --to=boqun.feng@intel.com \
    --cc=George.Dunlap@eu.citrix.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=dave@recoil.org \
    --cc=ian.jackson@eu.citrix.com \
    --cc=jbeulich@suse.com \
    --cc=julien.grall@arm.com \
    --cc=jun.nakajima@intel.com \
    --cc=kai.huang@linux.intel.com \
    --cc=kevin.tian@intel.com \
    --cc=marmarek@invisiblethingslab.com \
    --cc=sstabellini@kernel.org \
    --cc=tim@xen.org \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xen.org \
    /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).