From patchwork Tue Aug 6 18:56:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 11079553 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3934C14DB for ; Tue, 6 Aug 2019 18:57:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2AAE328832 for ; Tue, 6 Aug 2019 18:57:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1D2D12887B; Tue, 6 Aug 2019 18:57:43 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id AEFA028832 for ; Tue, 6 Aug 2019 18:57:42 +0000 (UTC) Received: from localhost ([::1]:35678 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hv4eT-00061e-Gf for patchwork-qemu-devel@patchwork.kernel.org; Tue, 06 Aug 2019 14:57:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41045) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hv4dw-0004OB-Sn for qemu-devel@nongnu.org; Tue, 06 Aug 2019 14:57:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hv4dv-00072C-Gd for qemu-devel@nongnu.org; Tue, 06 Aug 2019 14:57:08 -0400 Received: from mga14.intel.com ([192.55.52.115]:31803) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hv4dv-0006z4-6e for qemu-devel@nongnu.org; Tue, 06 Aug 2019 14:57:07 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Aug 2019 11:56:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,353,1559545200"; d="scan'208";a="176715063" Received: from sjchrist-coffee.jf.intel.com ([10.54.74.41]) by orsmga003.jf.intel.com with ESMTP; 06 Aug 2019 11:56:59 -0700 From: Sean Christopherson To: Eduardo Habkost , Igor Mammedov , "Michael S. Tsirkin" , Marcel Apfelbaum , Paolo Bonzini , Richard Henderson , Cornelia Huck , Eric Blake , Markus Armbruster , Marcelo Tosatti Date: Tue, 6 Aug 2019 11:56:30 -0700 Message-Id: <20190806185649.2476-2-sean.j.christopherson@intel.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190806185649.2476-1-sean.j.christopherson@intel.com> References: <20190806185649.2476-1-sean.j.christopherson@intel.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 192.55.52.115 Subject: [Qemu-devel] [RFC PATCH 01/20] hostmem: Add hostmem-epc as a backend for SGX EPC X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP EPC (Enclave Page Cache) is a specialized type of memory used by Intel SGX (Software Guard Extensions). The SDM desribes EPC as: The Enclave Page Cache (EPC) is the secure storage used to store enclave pages when they are a part of an executing enclave. For an EPC page, hardware performs additional access control checks to restrict access to the page. After the current page access checks and translations are performed, the hardware checks that the EPC page is accessible to the program currently executing. Generally an EPC page is only accessed by the owner of the executing enclave or an instruction which is setting up an EPC page. Because of its unique requirements, Linux manages EPC separately from normal memory. Similar to memfd, the device /dev/sgx/virt_epc can be opened to obtain a file descriptor which can in turn be used to mmap() EPC memory. Signed-off-by: Sean Christopherson --- backends/Makefile.objs | 1 + backends/hostmem-epc.c | 91 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 backends/hostmem-epc.c diff --git a/backends/Makefile.objs b/backends/Makefile.objs index 981e8e122f..6e96549c5e 100644 --- a/backends/Makefile.objs +++ b/backends/Makefile.objs @@ -17,3 +17,4 @@ endif common-obj-$(call land,$(CONFIG_VHOST_USER),$(CONFIG_VIRTIO)) += vhost-user.o common-obj-$(CONFIG_LINUX) += hostmem-memfd.o +common-obj-$(CONFIG_LINUX) += hostmem-epc.o diff --git a/backends/hostmem-epc.c b/backends/hostmem-epc.c new file mode 100644 index 0000000000..24a22dede5 --- /dev/null +++ b/backends/hostmem-epc.c @@ -0,0 +1,91 @@ +/* + * QEMU host SGX EPC memory backend + * + * Copyright (C) 2019 Intel Corporation + * + * Authors: + * Sean Christopherson + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#include + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "qom/object_interfaces.h" +#include "qapi/error.h" +#include "sysemu/hostmem.h" + +#define TYPE_MEMORY_BACKEND_EPC "memory-backend-epc" + +#define MEMORY_BACKEND_EPC(obj) \ + OBJECT_CHECK(HostMemoryBackendEpc, (obj), TYPE_MEMORY_BACKEND_EPC) + +typedef struct HostMemoryBackendEpc HostMemoryBackendEpc; + +struct HostMemoryBackendEpc { + HostMemoryBackend parent_obj; +}; + +static void +sgx_epc_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) +{ + char *name; + int fd; + + if (!backend->size) { + error_setg(errp, "can't create backend with size 0"); + return; + } + backend->force_prealloc = mem_prealloc; + + fd = open("/dev/sgx/virt_epc", O_RDWR); + if (fd < 0) { + error_setg_errno(errp, errno, + "failed to open /dev/sgx/virt_epc to alloc SGX EPC"); + return; + } + + name = object_get_canonical_path(OBJECT(backend)); + memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), + name, backend->size, + backend->share, fd, errp); + g_free(name); +} + +static void sgx_epc_backend_instance_init(Object *obj) +{ + HostMemoryBackend *m = MEMORY_BACKEND(obj); + + m->share = true; + m->merge = false; + m->dump = false; +} + +static void sgx_epc_backend_class_init(ObjectClass *oc, void *data) +{ + HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc); + + bc->alloc = sgx_epc_backend_memory_alloc; +} + +static const TypeInfo sgx_epc_backed_info = { + .name = TYPE_MEMORY_BACKEND_EPC, + .parent = TYPE_MEMORY_BACKEND, + .instance_init = sgx_epc_backend_instance_init, + .class_init = sgx_epc_backend_class_init, + .instance_size = sizeof(HostMemoryBackendEpc), +}; + +static void register_types(void) +{ + int fd = open("/dev/sgx/virt_epc", O_RDWR); + if (fd >= 0) { + close(fd); + + type_register_static(&sgx_epc_backed_info); + } +} + +type_init(register_types);