@@ -1,5 +1,5 @@
# core
-obj-y += encl.o main.o reclaim.o
+obj-y += encl.o encls.o main.o reclaim.o
# driver
obj-y += driver.o ioctl.o
new file mode 100644
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+// Copyright(c) 2016-19 Intel Corporation.
+
+#include <linux/highmem.h>
+#include <asm/cpufeature.h>
+#include "encls.h"
+
+/* A per-cpu cache for the last known values of IA32_SGXLEPUBKEYHASHx MSRs. */
+static DEFINE_PER_CPU(u64 [4], sgx_lepubkeyhash_cache);
+
+static void sgx_update_lepubkeyhash_msrs(u64 *lepubkeyhash, bool enforce)
+{
+ u64 *cache;
+ int i;
+
+ cache = per_cpu(sgx_lepubkeyhash_cache, smp_processor_id());
+ for (i = 0; i < 4; i++) {
+ if (enforce || (lepubkeyhash[i] != cache[i])) {
+ wrmsrl(MSR_IA32_SGXLEPUBKEYHASH0 + i, lepubkeyhash[i]);
+ cache[i] = lepubkeyhash[i];
+ }
+ }
+}
+
+/**
+ * sgx_einit() - Initialize an enclave
+ * @sigstruct: a pointer a SIGSTRUCT
+ * @token: a pointer an EINITTOKEN (optional)
+ * @secs: a pointer a SECS
+ * @lepubkeyhash: the desired value for IA32_SGXLEPUBKEYHASHx MSRs
+ *
+ * Execute ENCLS[EINIT], writing the IA32_SGXLEPUBKEYHASHx MSRs according
+ * to @lepubkeyhash (if possible and necessary).
+ *
+ * Return:
+ * 0 on success,
+ * -errno or SGX error on failure
+ */
+int sgx_einit(struct sgx_sigstruct *sigstruct, struct sgx_einittoken *token,
+ struct sgx_epc_page *secs, u64 *lepubkeyhash)
+{
+ int ret;
+
+ if (!boot_cpu_has(X86_FEATURE_SGX_LC))
+ return __einit(sigstruct, token, sgx_epc_addr(secs));
+
+ preempt_disable();
+ sgx_update_lepubkeyhash_msrs(lepubkeyhash, false);
+ ret = __einit(sigstruct, token, sgx_epc_addr(secs));
+ if (ret == SGX_INVALID_EINITTOKEN) {
+ sgx_update_lepubkeyhash_msrs(lepubkeyhash, true);
+ ret = __einit(sigstruct, token, sgx_epc_addr(secs));
+ }
+ preempt_enable();
+ return ret;
+}
@@ -257,4 +257,7 @@ static inline int __emodt(struct sgx_secinfo *secinfo, void *addr)
return __encls_ret_2(SGX_EMODT, secinfo, addr);
}
+int sgx_einit(struct sgx_sigstruct *sigstruct, struct sgx_einittoken *token,
+ struct sgx_epc_page *secs, u64 *lepubkeyhash);
+
#endif /* _X86_ENCLS_H */
@@ -15,9 +15,6 @@
struct sgx_epc_section sgx_epc_sections[SGX_MAX_EPC_SECTIONS];
int sgx_nr_epc_sections;
-/* A per-cpu cache for the last known values of IA32_SGXLEPUBKEYHASHx MSRs. */
-static DEFINE_PER_CPU(u64 [4], sgx_lepubkeyhash_cache);
-
static struct sgx_epc_page *sgx_section_try_take_page(
struct sgx_epc_section *section)
{
@@ -162,53 +159,6 @@ void sgx_free_page(struct sgx_epc_page *page)
WARN(ret > 0, "sgx: EREMOVE returned %d (0x%x)", ret, ret);
}
-static void sgx_update_lepubkeyhash_msrs(u64 *lepubkeyhash, bool enforce)
-{
- u64 *cache;
- int i;
-
- cache = per_cpu(sgx_lepubkeyhash_cache, smp_processor_id());
- for (i = 0; i < 4; i++) {
- if (enforce || (lepubkeyhash[i] != cache[i])) {
- wrmsrl(MSR_IA32_SGXLEPUBKEYHASH0 + i, lepubkeyhash[i]);
- cache[i] = lepubkeyhash[i];
- }
- }
-}
-
-/**
- * sgx_einit - initialize an enclave
- * @sigstruct: a pointer a SIGSTRUCT
- * @token: a pointer an EINITTOKEN (optional)
- * @secs: a pointer a SECS
- * @lepubkeyhash: the desired value for IA32_SGXLEPUBKEYHASHx MSRs
- *
- * Execute ENCLS[EINIT], writing the IA32_SGXLEPUBKEYHASHx MSRs according
- * to @lepubkeyhash (if possible and necessary).
- *
- * Return:
- * 0 on success,
- * -errno or SGX error on failure
- */
-int sgx_einit(struct sgx_sigstruct *sigstruct, struct sgx_einittoken *token,
- struct sgx_epc_page *secs, u64 *lepubkeyhash)
-{
- int ret;
-
- if (!boot_cpu_has(X86_FEATURE_SGX_LC))
- return __einit(sigstruct, token, sgx_epc_addr(secs));
-
- preempt_disable();
- sgx_update_lepubkeyhash_msrs(lepubkeyhash, false);
- ret = __einit(sigstruct, token, sgx_epc_addr(secs));
- if (ret == SGX_INVALID_EINITTOKEN) {
- sgx_update_lepubkeyhash_msrs(lepubkeyhash, true);
- ret = __einit(sigstruct, token, sgx_epc_addr(secs));
- }
- preempt_enable();
- return ret;
-}
-
static __init void sgx_free_epc_section(struct sgx_epc_section *section)
{
struct sgx_epc_page *page;
@@ -85,7 +85,5 @@ void sgx_reclaim_pages(void);
struct sgx_epc_page *sgx_alloc_page(void *owner, bool reclaim);
int __sgx_free_page(struct sgx_epc_page *page);
void sgx_free_page(struct sgx_epc_page *page);
-int sgx_einit(struct sgx_sigstruct *sigstruct, struct sgx_einittoken *token,
- struct sgx_epc_page *secs, u64 *lepubkeyhash);
#endif /* _X86_SGX_H */
Move sgx_einit() to encls.c as it is essentially a global wrapper for EINIT somewhat independent of the code using it. It does not have any binding with the code in main.c. Cc: Sean Christopherson <sean.j.christopherson@intel.com> Cc: Shay Katz-zamir <shay.katz-zamir@intel.com> Cc: Serge Ayoun <serge.ayoun@intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> --- arch/x86/kernel/cpu/sgx/Makefile | 2 +- arch/x86/kernel/cpu/sgx/encls.c | 56 ++++++++++++++++++++++++++++++++ arch/x86/kernel/cpu/sgx/encls.h | 3 ++ arch/x86/kernel/cpu/sgx/main.c | 50 ---------------------------- arch/x86/kernel/cpu/sgx/sgx.h | 2 -- 5 files changed, 60 insertions(+), 53 deletions(-) create mode 100644 arch/x86/kernel/cpu/sgx/encls.c