Received: by 2002:ac0:a581:0:0:0:0:0 with SMTP id m1-v6csp1455128imm; Tue, 3 Jul 2018 11:25:41 -0700 (PDT) X-Google-Smtp-Source: ADUXVKIgldsw6OZnl1AT3wqFdpuuPShy2blgrXElrp4LlzMPNuO8vPaN1+Ao67YAA8lCaGardknp X-Received: by 2002:a63:b91c:: with SMTP id z28-v6mr26650234pge.22.1530642341780; Tue, 03 Jul 2018 11:25:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530642341; cv=none; d=google.com; s=arc-20160816; b=m5DH/wi1LS0Nnv6cqVJy5eMR2r+DBUAkGtTnOBn2nVSgoZ6K8Xx4Ivx7zPL/VKswFL hUBRfHncqzEQwrEAZMobxuWp/48etN+A66ta7W58Wht9Y18MD6Z05Ng3g63MQhx/Exk/ veAX7HoHQ64RaCw6QJJqFoF+m3iZz9L7ATvPkb+pAkqWHiYO16QY8bN645ZoJkO+dAWZ 1ZCwZt12s8I+a3AG6YDBiY/5JFd+DNrhVdh/vuxcVv2Bu9axPUTz3FJPLCKDaowB6tCQ 07d8pEQJDW+fMi3wLWx5Uv51J67mEJdq79OAou4NO5dg6LIqbfjfeuFTbuGM9b7Xlg/8 sEzw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=Eo1TucJejtJsQZCzDG3stfwgGD5uo4YjW9HJXYOW9yE=; b=olca0GHPpM96zd24fmrjxs8XVJXy1GGHi3pYdDwkPbseG6s9FvMojk3AOAGotRfrGK sLRKx/PX4/1tmJrS+kyF/Z8TG5bmiVye+2ZAnMNP0JbOnxsi/q5RU8q9RvZs4B3gM11w VcK6IfEtJKHTzny48zpz4jRADdiGVc5Tj9lulUVyDsdhF+79bq1BzXoFqLv/LU7Jl8aj c6jCwOutxPBHDAa6zmtPEKDxQpyELoVPpyoIVwyi15v+azeMAPygxIq7D7oLscHSkETp gZroxdZhJKyaeHPPZww7xEJF+t2LREKZIqkW0lgafA66a1gOoE4LZxuBTP/qhL4OfsnL 9lAw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x9-v6si1519388plo.368.2018.07.03.11.25.27; Tue, 03 Jul 2018 11:25:41 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934714AbeGCSYF (ORCPT + 99 others); Tue, 3 Jul 2018 14:24:05 -0400 Received: from mga14.intel.com ([192.55.52.115]:20295 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934492AbeGCSXn (ORCPT ); Tue, 3 Jul 2018 14:23:43 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 03 Jul 2018 11:23:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,304,1526367600"; d="scan'208";a="242708253" Received: from cdikicix-mobl.ger.corp.intel.com (HELO localhost) ([10.249.254.69]) by fmsmga006.fm.intel.com with ESMTP; 03 Jul 2018 11:23:35 -0700 From: Jarkko Sakkinen To: x86@kernel.org, platform-driver-x86@vger.kernel.org Cc: dave.hansen@intel.com, sean.j.christopherson@intel.com, nhorman@redhat.com, npmccallum@redhat.com, linux-sgx@vger.kernel.org, Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , Jarkko Sakkinen , linux-kernel@vger.kernel.org (open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)) Subject: [PATCH v12 10/13] x86/sgx: sgx_einit() Date: Tue, 3 Jul 2018 21:19:55 +0300 Message-Id: <20180703182118.15024-11-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180703182118.15024-1-jarkko.sakkinen@linux.intel.com> References: <20180703182118.15024-1-jarkko.sakkinen@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Sean Christopherson Implements function to perform ENCLS(EINIT) leaf function that initializes an enclave, which can be used by a driver for running enclaves and VMMs. Writing the LE hash MSRs is extraordinarily expensive, e.g. 3-4x slower than normal MSRs, so we use a per-cpu cache to track the last known value of the MSRs to avoid unnecessarily writing the MSRs with the current value. Signed-off-by: Sean Christopherson --- arch/x86/include/asm/sgx.h | 2 ++ arch/x86/kernel/cpu/intel_sgx.c | 46 +++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/arch/x86/include/asm/sgx.h b/arch/x86/include/asm/sgx.h index 4f5f32b37b5d..bc09b4576d68 100644 --- a/arch/x86/include/asm/sgx.h +++ b/arch/x86/include/asm/sgx.h @@ -215,6 +215,8 @@ void *sgx_get_page(struct sgx_epc_page *ptr); void sgx_put_page(void *epc_page_ptr); struct page *sgx_get_backing(struct file *file, pgoff_t index); void sgx_put_backing(struct page *backing_page, bool write); +int sgx_einit(struct sgx_sigstruct *sigstruct, struct sgx_einittoken *token, + struct sgx_epc_page *secs_page, u64 le_pubkey_hash[4]); #define SGX_FN(name, params...) \ { \ diff --git a/arch/x86/kernel/cpu/intel_sgx.c b/arch/x86/kernel/cpu/intel_sgx.c index b52bab8eff99..53dd91cb7a49 100644 --- a/arch/x86/kernel/cpu/intel_sgx.c +++ b/arch/x86/kernel/cpu/intel_sgx.c @@ -31,6 +31,12 @@ static int sgx_nr_epc_banks; static struct task_struct *ksgxswapd_tsk; static DECLARE_WAIT_QUEUE_HEAD(ksgxswapd_waitq); +/* + * A cache for last known values of IA32_SGXLEPUBKEYHASHx MSRs. Cache entries + * are initialized when they are first used by sgx_einit(). + */ +static DEFINE_PER_CPU(u64 [4], sgx_le_pubkey_hash_cache); + static void sgx_swap_cluster(void) { struct sgx_epc_page *cluster[SGX_NR_TO_SCAN + 1]; @@ -255,6 +261,46 @@ void sgx_put_backing(struct page *backing_page, bool write) } EXPORT_SYMBOL(sgx_put_backing); +/** + * sgx_einit - EINIT an enclave with the appropriate LE pubkey hash + * @sigstruct: a pointer to the enclave's sigstruct + * @token: a pointer to the enclave's EINIT token + * @secs_page: a pointer to the enclave's SECS EPC page + * @le_pubkey_hash: the desired LE pubkey hash for EINIT + */ +int sgx_einit(struct sgx_sigstruct *sigstruct, struct sgx_einittoken *token, + struct sgx_epc_page *secs_page, u64 le_pubkey_hash[4]) +{ + u64 __percpu *cache; + void *secs; + int i, ret; + + secs = sgx_get_page(secs_page); + + if (!sgx_lc_enabled) { + ret = __einit(sigstruct, token, secs); + goto out; + } + + cache = per_cpu(sgx_le_pubkey_hash_cache, smp_processor_id()); + + preempt_disable(); + for (i = 0; i < 4; i++) { + if (le_pubkey_hash[i] == cache[i]) + continue; + + wrmsrl(MSR_IA32_SGXLEPUBKEYHASH0 + i, le_pubkey_hash[i]); + cache[i] = le_pubkey_hash[i]; + } + ret = __einit(sigstruct, token, secs); + preempt_enable(); + +out: + sgx_put_page(secs); + return ret; +} +EXPORT_SYMBOL(sgx_einit); + static __init int sgx_init_epc_bank(unsigned long addr, unsigned long size, unsigned long index, struct sgx_epc_bank *bank) -- 2.17.1