x86/sgx: Keep record of SGX page type
authorReinette Chatre <reinette.chatre@intel.com>
Tue, 10 May 2022 18:08:47 +0000 (11:08 -0700)
committerDave Hansen <dave.hansen@linux.intel.com>
Thu, 7 Jul 2022 17:13:02 +0000 (10:13 -0700)
SGX2 functions are not allowed on all page types. For example,
ENCLS[EMODPR] is only allowed on regular SGX enclave pages and
ENCLS[EMODPT] is only allowed on TCS and regular pages. If these
functions are attempted on another type of page the hardware would
trigger a fault.

Keep a record of the SGX page type so that there is more
certainty whether an SGX2 instruction can succeed and faults
can be treated as real failures.

The page type is a property of struct sgx_encl_page
and thus does not cover the VA page type. VA pages are maintained
in separate structures and their type can be determined in
a different way. The SGX2 instructions needing the page type do not
operate on VA pages and this is thus not a scenario needing to
be covered at this time.

struct sgx_encl_page hosting this information is maintained for each
enclave page so the space consumed by the struct is important.
The existing sgx_encl_page->vm_max_prot_bits is already unsigned long
while only using three bits. Transition to a bitfield for the two
members to support the additional information without increasing
the space consumed by the struct.

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lkml.kernel.org/r/a0a6939eefe7ba26514f6c49723521cde372de64.1652137848.git.reinette.chatre@intel.com
arch/x86/include/asm/sgx.h
arch/x86/kernel/cpu/sgx/encl.h
arch/x86/kernel/cpu/sgx/ioctl.c

index d67810b50a813f74e22abb049a0cd7a0b2e47de6..eae20fa52b933ec4cf851b6cfdc314af29e26408 100644 (file)
@@ -239,6 +239,9 @@ struct sgx_pageinfo {
  * %SGX_PAGE_TYPE_REG: a regular page
  * %SGX_PAGE_TYPE_VA:  a VA page
  * %SGX_PAGE_TYPE_TRIM:        a page in trimmed state
+ *
+ * Make sure when making changes to this enum that its values can still fit
+ * in the bitfield within &struct sgx_encl_page
  */
 enum sgx_page_type {
        SGX_PAGE_TYPE_SECS,
index f72a674e26059c393545d65ae87441ea1e019d08..799d4cdb12d5747216ccdc114515750d03370d9f 100644 (file)
@@ -27,7 +27,8 @@
 
 struct sgx_encl_page {
        unsigned long desc;
-       unsigned long vm_max_prot_bits;
+       unsigned long vm_max_prot_bits:8;
+       enum sgx_page_type type:16;
        struct sgx_epc_page *epc_page;
        struct sgx_encl *encl;
        struct sgx_va_page *va_page;
index a66795e0b685a22d8e452c8045be70dffde60b00..21078c6643f7269488fda253825617f8dfbbae20 100644 (file)
@@ -107,6 +107,7 @@ static int sgx_encl_create(struct sgx_encl *encl, struct sgx_secs *secs)
                set_bit(SGX_ENCL_DEBUG, &encl->flags);
 
        encl->secs.encl = encl;
+       encl->secs.type = SGX_PAGE_TYPE_SECS;
        encl->base = secs->base;
        encl->size = secs->size;
        encl->attributes = secs->attributes;
@@ -344,6 +345,7 @@ static int sgx_encl_add_page(struct sgx_encl *encl, unsigned long src,
         */
        encl_page->encl = encl;
        encl_page->epc_page = epc_page;
+       encl_page->type = (secinfo->flags & SGX_SECINFO_PAGE_TYPE_MASK) >> 8;
        encl->secs_child_cnt++;
 
        if (flags & SGX_PAGE_MEASURE) {