From: Jarkko Sakkinen <jarkko@kernel.org>
To: Reinette Chatre <reinette.chatre@intel.com>
Cc: dave.hansen@linux.intel.com, tglx@linutronix.de, bp@alien8.de,
luto@kernel.org, mingo@redhat.com, linux-sgx@vger.kernel.org,
x86@kernel.org, seanjc@google.com, kai.huang@intel.com,
cathy.zhang@intel.com, cedric.xing@intel.com,
haitao.huang@intel.com, mark.shanahan@intel.com, hpa@zytor.com,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH V3 21/30] selftests/sgx: Add test for EPCM permission changes
Date: Tue, 5 Apr 2022 10:02:35 +0300 [thread overview]
Message-ID: <Ykvpi6HRL9cLorw6@kernel.org> (raw)
In-Reply-To: <b2304ac0322d945b4bfdce36d3aae654f6ed35a0.1648847675.git.reinette.chatre@intel.com>
On Mon, Apr 04, 2022 at 09:49:29AM -0700, Reinette Chatre wrote:
> EPCM permission changes could be made from within (to relax
> permissions) or out (to restrict permissions) the enclave. Kernel
> support is needed when permissions are restricted to be able to
> call the privileged ENCLS[EMODPR] instruction. EPCM permissions
> can be relaxed via ENCLU[EMODPE] from within the enclave but the
> enclave still depends on the kernel to install PTEs with the needed
> permissions.
>
> Add a test that exercises a few of the enclave page permission flows:
> 1) Test starts with a RW (from enclave and kernel perspective)
> enclave page that is mapped via a RW VMA.
> 2) Use the SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS ioctl() to restrict
> the enclave (EPCM) page permissions to read-only.
> 3) Run ENCLU[EACCEPT] from within the enclave to accept the new page
> permissions.
> 4) Attempt to write to the enclave page from within the enclave - this
> should fail with a page fault on the EPCM permissions since the page
> table entry continues to allow RW access.
> 5) Restore EPCM permissions to RW by running ENCLU[EMODPE] from within
> the enclave.
> 6) Attempt to write to the enclave page from within the enclave - this
> should succeed since both EPCM and PTE permissions allow this access.
>
> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
> ---
> Changes since V2:
> - Modify test to support separation between EPCM and PTE/VMA permissions
> - Fix changelog and comments to reflect new relationship between
> EPCM and PTE/VMA permissions.
> - With EPCM permissions controlling access instead of PTE permissions,
> check for SGX error code now encountered in page fault.
> - Stop calling SGX_IOC_ENCLAVE_RELAX_PERMISSIONS and ensure that
> only calling ENCLU[EMODPE] from within enclave is necessary to restore
> access to the enclave page.
> - Update to use new struct name struct sgx_enclave_restrict_perm -> struct
> sgx_enclave_restrict_permissions. (Jarkko)
>
> Changes since V1:
> - Adapt test to the kernel interface changes: the ioctl() name change
> and providing entire secinfo as parameter.
> - Remove the ENCLU[EACCEPT] call after permissions are relaxed since
> the new flow no longer results in the EPCM PR bit being set.
> - Rewrite error path to reduce line lengths.
>
> tools/testing/selftests/sgx/defines.h | 15 ++
> tools/testing/selftests/sgx/main.c | 218 ++++++++++++++++++++++++
> tools/testing/selftests/sgx/test_encl.c | 38 +++++
> 3 files changed, 271 insertions(+)
>
> diff --git a/tools/testing/selftests/sgx/defines.h b/tools/testing/selftests/sgx/defines.h
> index 02d775789ea7..b638eb98c80c 100644
> --- a/tools/testing/selftests/sgx/defines.h
> +++ b/tools/testing/selftests/sgx/defines.h
> @@ -24,6 +24,8 @@ enum encl_op_type {
> ENCL_OP_PUT_TO_ADDRESS,
> ENCL_OP_GET_FROM_ADDRESS,
> ENCL_OP_NOP,
> + ENCL_OP_EACCEPT,
> + ENCL_OP_EMODPE,
> ENCL_OP_MAX,
> };
>
> @@ -53,4 +55,17 @@ struct encl_op_get_from_addr {
> uint64_t addr;
> };
>
> +struct encl_op_eaccept {
> + struct encl_op_header header;
> + uint64_t epc_addr;
> + uint64_t flags;
> + uint64_t ret;
> +};
> +
> +struct encl_op_emodpe {
> + struct encl_op_header header;
> + uint64_t epc_addr;
> + uint64_t flags;
> +};
> +
> #endif /* DEFINES_H */
> diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
> index dd74fa42302e..0e0bd1c4d702 100644
> --- a/tools/testing/selftests/sgx/main.c
> +++ b/tools/testing/selftests/sgx/main.c
> @@ -25,6 +25,18 @@ static const uint64_t MAGIC = 0x1122334455667788ULL;
> static const uint64_t MAGIC2 = 0x8877665544332211ULL;
> vdso_sgx_enter_enclave_t vdso_sgx_enter_enclave;
>
> +/*
> + * Security Information (SECINFO) data structure needed by a few SGX
> + * instructions (eg. ENCLU[EACCEPT] and ENCLU[EMODPE]) holds meta-data
> + * about an enclave page. &enum sgx_secinfo_page_state specifies the
> + * secinfo flags used for page state.
> + */
> +enum sgx_secinfo_page_state {
> + SGX_SECINFO_PENDING = (1 << 3),
> + SGX_SECINFO_MODIFIED = (1 << 4),
> + SGX_SECINFO_PR = (1 << 5),
> +};
> +
> struct vdso_symtab {
> Elf64_Sym *elf_symtab;
> const char *elf_symstrtab;
> @@ -555,4 +567,210 @@ TEST_F(enclave, pte_permissions)
> EXPECT_EQ(self->run.exception_addr, 0);
> }
>
> +/*
> + * Enclave page permission test.
> + *
> + * Modify and restore enclave page's EPCM (enclave) permissions from
> + * outside enclave (ENCLS[EMODPR] via kernel) as well as from within
> + * enclave (via ENCLU[EMODPE]). Check for page fault if
> + * VMA allows access but EPCM permissions do not.
> + */
> +TEST_F(enclave, epcm_permissions)
> +{
> + struct sgx_enclave_restrict_permissions restrict_ioc;
> + struct encl_op_get_from_addr get_addr_op;
> + struct encl_op_put_to_addr put_addr_op;
> + struct encl_op_eaccept eaccept_op;
> + struct encl_op_emodpe emodpe_op;
> + struct sgx_secinfo secinfo;
> + unsigned long data_start;
> + int ret, errno_save;
> +
> + ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata));
> +
> + memset(&self->run, 0, sizeof(self->run));
> + self->run.tcs = self->encl.encl_base;
> +
> + /*
> + * Ensure kernel supports needed ioctl() and system supports needed
> + * commands.
> + */
> + memset(&restrict_ioc, 0, sizeof(restrict_ioc));
> + memset(&secinfo, 0, sizeof(secinfo));
> +
> + ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS,
> + &restrict_ioc);
> + errno_save = ret == -1 ? errno : 0;
> +
> + /*
> + * Invalid parameters were provided during sanity check,
> + * expect command to fail.
> + */
> + ASSERT_EQ(ret, -1);
> +
> + /* ret == -1 */
> + if (errno_save == ENOTTY)
> + SKIP(return,
> + "Kernel does not support SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS ioctl()");
> + else if (errno_save == ENODEV)
> + SKIP(return, "System does not support SGX2");
> +
> + /*
> + * Page that will have its permissions changed is the second data
> + * page in the .data segment. This forms part of the local encl_buffer
> + * within the enclave.
> + *
> + * At start of test @data_start should have EPCM as well as PTE and
> + * VMA permissions of RW.
> + */
> +
> + data_start = self->encl.encl_base +
> + encl_get_data_offset(&self->encl) + PAGE_SIZE;
> +
> + /*
> + * Sanity check that page at @data_start is writable before making
> + * any changes to page permissions.
> + *
> + * Start by writing MAGIC to test page.
> + */
> + put_addr_op.value = MAGIC;
> + put_addr_op.addr = data_start;
> + put_addr_op.header.type = ENCL_OP_PUT_TO_ADDRESS;
> +
> + EXPECT_EQ(ENCL_CALL(&put_addr_op, &self->run, true), 0);
> +
> + EXPECT_EEXIT(&self->run);
> + EXPECT_EQ(self->run.exception_vector, 0);
> + EXPECT_EQ(self->run.exception_error_code, 0);
> + EXPECT_EQ(self->run.exception_addr, 0);
> +
> + /*
> + * Read memory that was just written to, confirming that
> + * page is writable.
> + */
> + get_addr_op.value = 0;
> + get_addr_op.addr = data_start;
> + get_addr_op.header.type = ENCL_OP_GET_FROM_ADDRESS;
> +
> + EXPECT_EQ(ENCL_CALL(&get_addr_op, &self->run, true), 0);
> +
> + EXPECT_EQ(get_addr_op.value, MAGIC);
> + EXPECT_EEXIT(&self->run);
> + EXPECT_EQ(self->run.exception_vector, 0);
> + EXPECT_EQ(self->run.exception_error_code, 0);
> + EXPECT_EQ(self->run.exception_addr, 0);
> +
> + /*
> + * Change EPCM permissions to read-only. Kernel still considers
> + * the page writable.
> + */
> + memset(&restrict_ioc, 0, sizeof(restrict_ioc));
> + memset(&secinfo, 0, sizeof(secinfo));
> +
> + secinfo.flags = PROT_READ;
> + restrict_ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
> + restrict_ioc.length = PAGE_SIZE;
> + restrict_ioc.secinfo = (unsigned long)&secinfo;
> +
> + ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS,
> + &restrict_ioc);
> + errno_save = ret == -1 ? errno : 0;
> +
> + EXPECT_EQ(ret, 0);
> + EXPECT_EQ(errno_save, 0);
> + EXPECT_EQ(restrict_ioc.result, 0);
> + EXPECT_EQ(restrict_ioc.count, 4096);
> +
> + /*
> + * EPCM permissions changed from kernel, need to EACCEPT from enclave.
> + */
> + eaccept_op.epc_addr = data_start;
> + eaccept_op.flags = PROT_READ | SGX_SECINFO_REG | SGX_SECINFO_PR;
> + eaccept_op.ret = 0;
> + eaccept_op.header.type = ENCL_OP_EACCEPT;
> +
> + EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
> +
> + EXPECT_EEXIT(&self->run);
> + EXPECT_EQ(self->run.exception_vector, 0);
> + EXPECT_EQ(self->run.exception_error_code, 0);
> + EXPECT_EQ(self->run.exception_addr, 0);
> + EXPECT_EQ(eaccept_op.ret, 0);
> +
> + /*
> + * EPCM permissions of page is now read-only, expect #PF
> + * on EPCM when attempting to write to page from within enclave.
> + */
> + put_addr_op.value = MAGIC2;
> +
> + EXPECT_EQ(ENCL_CALL(&put_addr_op, &self->run, true), 0);
> +
> + EXPECT_EQ(self->run.function, ERESUME);
> + EXPECT_EQ(self->run.exception_vector, 14);
> + EXPECT_EQ(self->run.exception_error_code, 0x8007);
> + EXPECT_EQ(self->run.exception_addr, data_start);
> +
> + self->run.exception_vector = 0;
> + self->run.exception_error_code = 0;
> + self->run.exception_addr = 0;
> +
> + /*
> + * Received AEX but cannot return to enclave at same entrypoint,
> + * need different TCS from where EPCM permission can be made writable
> + * again.
> + */
> + self->run.tcs = self->encl.encl_base + PAGE_SIZE;
> +
> + /*
> + * Enter enclave at new TCS to change EPCM permissions to be
> + * writable again and thus fix the page fault that triggered the
> + * AEX.
> + */
> +
> + emodpe_op.epc_addr = data_start;
> + emodpe_op.flags = PROT_READ | PROT_WRITE;
> + emodpe_op.header.type = ENCL_OP_EMODPE;
> +
> + EXPECT_EQ(ENCL_CALL(&emodpe_op, &self->run, true), 0);
> +
> + EXPECT_EEXIT(&self->run);
> + EXPECT_EQ(self->run.exception_vector, 0);
> + EXPECT_EQ(self->run.exception_error_code, 0);
> + EXPECT_EQ(self->run.exception_addr, 0);
> +
> + /*
> + * Attempt to return to main TCS to resume execution at faulting
> + * instruction, PTE should continue to allow writing to the page.
> + */
> + self->run.tcs = self->encl.encl_base;
> +
> + /*
> + * Wrong page permissions that caused original fault has
> + * now been fixed via EPCM permissions.
> + * Resume execution in main TCS to re-attempt the memory access.
> + */
> + self->run.tcs = self->encl.encl_base;
> +
> + EXPECT_EQ(vdso_sgx_enter_enclave((unsigned long)&put_addr_op, 0, 0,
> + ERESUME, 0, 0,
> + &self->run),
> + 0);
> +
> + EXPECT_EEXIT(&self->run);
> + EXPECT_EQ(self->run.exception_vector, 0);
> + EXPECT_EQ(self->run.exception_error_code, 0);
> + EXPECT_EQ(self->run.exception_addr, 0);
> +
> + get_addr_op.value = 0;
> +
> + EXPECT_EQ(ENCL_CALL(&get_addr_op, &self->run, true), 0);
> +
> + EXPECT_EQ(get_addr_op.value, MAGIC2);
> + EXPECT_EEXIT(&self->run);
> + EXPECT_EQ(self->run.user_data, 0);
> + EXPECT_EQ(self->run.exception_vector, 0);
> + EXPECT_EQ(self->run.exception_error_code, 0);
> + EXPECT_EQ(self->run.exception_addr, 0);
> +}
> +
> TEST_HARNESS_MAIN
> diff --git a/tools/testing/selftests/sgx/test_encl.c b/tools/testing/selftests/sgx/test_encl.c
> index 4fca01cfd898..5b6c65331527 100644
> --- a/tools/testing/selftests/sgx/test_encl.c
> +++ b/tools/testing/selftests/sgx/test_encl.c
> @@ -11,6 +11,42 @@
> */
> static uint8_t encl_buffer[8192] = { 1 };
>
> +enum sgx_enclu_function {
> + EACCEPT = 0x5,
> + EMODPE = 0x6,
> +};
> +
> +static void do_encl_emodpe(void *_op)
> +{
> + struct sgx_secinfo secinfo __aligned(sizeof(struct sgx_secinfo)) = {0};
> + struct encl_op_emodpe *op = _op;
> +
> + secinfo.flags = op->flags;
> +
> + asm volatile(".byte 0x0f, 0x01, 0xd7"
> + :
> + : "a" (EMODPE),
> + "b" (&secinfo),
> + "c" (op->epc_addr));
> +}
> +
> +static void do_encl_eaccept(void *_op)
> +{
> + struct sgx_secinfo secinfo __aligned(sizeof(struct sgx_secinfo)) = {0};
> + struct encl_op_eaccept *op = _op;
> + int rax;
> +
> + secinfo.flags = op->flags;
> +
> + asm volatile(".byte 0x0f, 0x01, 0xd7"
> + : "=a" (rax)
> + : "a" (EACCEPT),
> + "b" (&secinfo),
> + "c" (op->epc_addr));
> +
> + op->ret = rax;
> +}
> +
> static void *memcpy(void *dest, const void *src, size_t n)
> {
> size_t i;
> @@ -62,6 +98,8 @@ void encl_body(void *rdi, void *rsi)
> do_encl_op_put_to_addr,
> do_encl_op_get_from_addr,
> do_encl_op_nop,
> + do_encl_eaccept,
> + do_encl_emodpe,
> };
>
> struct encl_op_header *op = (struct encl_op_header *)rdi;
> --
> 2.25.1
>
Lacking:
KERNEL SELFTEST FRAMEWORK
M: Shuah Khan <shuah@kernel.org>
M: Shuah Khan <skhan@linuxfoundation.org>
L: linux-kselftest@vger.kernel.org
S: Maintained
Q: https://patchwork.kernel.org/project/linux-kselftest/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git
F: Documentation/dev-tools/kselftest*
F: tools/testing/selftests/
BR, Jarkko
next prev parent reply other threads:[~2022-04-05 7:01 UTC|newest]
Thread overview: 79+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-04 16:49 [PATCH V3 00/30] x86/sgx and selftests/sgx: Support SGX2 Reinette Chatre
2022-04-04 16:49 ` [PATCH V3 01/30] x86/sgx: Add short descriptions to ENCLS wrappers Reinette Chatre
2022-04-05 6:52 ` Jarkko Sakkinen
2022-04-04 16:49 ` [PATCH V3 02/30] x86/sgx: Add wrapper for SGX2 EMODPR function Reinette Chatre
2022-04-05 6:53 ` Jarkko Sakkinen
2022-04-04 16:49 ` [PATCH V3 03/30] x86/sgx: Add wrapper for SGX2 EMODT function Reinette Chatre
2022-04-05 6:53 ` Jarkko Sakkinen
2022-04-04 16:49 ` [PATCH V3 04/30] x86/sgx: Add wrapper for SGX2 EAUG function Reinette Chatre
2022-04-05 6:54 ` Jarkko Sakkinen
2022-04-04 16:49 ` [PATCH V3 05/30] x86/sgx: Support loading enclave page without VMA permissions check Reinette Chatre
2022-04-05 6:56 ` Jarkko Sakkinen
2022-04-04 16:49 ` [PATCH V3 06/30] x86/sgx: Export sgx_encl_ewb_cpumask() Reinette Chatre
2022-04-05 6:56 ` Jarkko Sakkinen
2022-04-04 16:49 ` [PATCH V3 07/30] x86/sgx: Rename sgx_encl_ewb_cpumask() as sgx_encl_cpumask() Reinette Chatre
2022-04-05 6:57 ` Jarkko Sakkinen
2022-04-04 16:49 ` [PATCH V3 08/30] x86/sgx: Move PTE zap code to new sgx_zap_enclave_ptes() Reinette Chatre
2022-04-05 6:59 ` Jarkko Sakkinen
2022-04-04 16:49 ` [PATCH V3 09/30] x86/sgx: Make sgx_ipi_cb() available internally Reinette Chatre
2022-04-05 6:59 ` Jarkko Sakkinen
2022-04-04 16:49 ` [PATCH V3 10/30] x86/sgx: Create utility to validate user provided offset and length Reinette Chatre
2022-04-05 7:00 ` Jarkko Sakkinen
2022-04-04 16:49 ` [PATCH V3 11/30] x86/sgx: Keep record of SGX page type Reinette Chatre
2022-04-05 7:00 ` Jarkko Sakkinen
2022-04-04 16:49 ` [PATCH V3 12/30] x86/sgx: Export sgx_encl_{grow,shrink}() Reinette Chatre
2022-04-05 7:04 ` Jarkko Sakkinen
2022-04-04 16:49 ` [PATCH V3 13/30] x86/sgx: Export sgx_encl_page_alloc() Reinette Chatre
2022-04-04 16:49 ` [PATCH V3 14/30] x86/sgx: Support restricting of enclave page permissions Reinette Chatre
2022-04-05 5:03 ` Jarkko Sakkinen
2022-04-05 5:07 ` Jarkko Sakkinen
2022-04-05 13:40 ` Jarkko Sakkinen
2022-04-05 14:19 ` Jarkko Sakkinen
2022-04-05 14:27 ` Jarkko Sakkinen
2022-04-05 14:52 ` Jarkko Sakkinen
2022-04-05 16:49 ` Reinette Chatre
2022-04-05 18:39 ` Jarkko Sakkinen
2022-04-05 18:59 ` Reinette Chatre
2022-04-06 7:30 ` Jarkko Sakkinen
2022-04-06 17:51 ` Reinette Chatre
2022-04-05 16:40 ` Reinette Chatre
2022-04-04 16:49 ` [PATCH V3 15/30] x86/sgx: Support adding of pages to an initialized enclave Reinette Chatre
2022-04-05 5:05 ` Jarkko Sakkinen
2022-04-05 10:03 ` Jarkko Sakkinen
2022-04-06 7:37 ` Jarkko Sakkinen
2022-04-06 22:42 ` Reinette Chatre
2022-04-04 16:49 ` [PATCH V3 16/30] x86/sgx: Tighten accessible memory range after enclave initialization Reinette Chatre
2022-04-05 7:05 ` Jarkko Sakkinen
2022-04-04 16:49 ` [PATCH V3 17/30] x86/sgx: Support modifying SGX page type Reinette Chatre
2022-04-05 7:06 ` Jarkko Sakkinen
2022-04-05 15:34 ` Jarkko Sakkinen
2022-04-05 17:05 ` Reinette Chatre
2022-04-05 18:41 ` Jarkko Sakkinen
2022-04-05 18:59 ` Reinette Chatre
2022-04-06 7:32 ` Jarkko Sakkinen
2022-04-06 17:50 ` Reinette Chatre
2022-04-04 16:49 ` [PATCH V3 18/30] x86/sgx: Support complete page removal Reinette Chatre
2022-04-05 7:08 ` Jarkko Sakkinen
2022-04-04 16:49 ` [PATCH V3 19/30] x86/sgx: Free up EPC pages directly to support large page ranges Reinette Chatre
2022-04-05 7:11 ` Jarkko Sakkinen
2022-04-05 17:13 ` Reinette Chatre
2022-04-05 17:25 ` Dave Hansen
2022-04-06 6:35 ` Jarkko Sakkinen
2022-04-06 17:50 ` Reinette Chatre
2022-04-05 18:42 ` Jarkko Sakkinen
2022-04-05 19:56 ` Reinette Chatre
2022-04-04 16:49 ` [PATCH V3 20/30] Documentation/x86: Introduce enclave runtime management section Reinette Chatre
2022-04-04 16:49 ` [PATCH V3 21/30] selftests/sgx: Add test for EPCM permission changes Reinette Chatre
2022-04-05 7:02 ` Jarkko Sakkinen [this message]
2022-04-05 7:03 ` Jarkko Sakkinen
2022-04-05 17:28 ` Reinette Chatre
2022-04-05 18:43 ` Jarkko Sakkinen
2022-04-04 16:49 ` [PATCH V3 22/30] selftests/sgx: Add test for TCS page " Reinette Chatre
2022-04-04 16:49 ` [PATCH V3 23/30] selftests/sgx: Test two different SGX2 EAUG flows Reinette Chatre
2022-04-04 16:49 ` [PATCH V3 24/30] selftests/sgx: Introduce dynamic entry point Reinette Chatre
2022-04-04 16:49 ` [PATCH V3 25/30] selftests/sgx: Introduce TCS initialization enclave operation Reinette Chatre
2022-04-04 16:49 ` [PATCH V3 26/30] selftests/sgx: Test complete changing of page type flow Reinette Chatre
2022-04-04 16:49 ` [PATCH V3 27/30] selftests/sgx: Test faulty enclave behavior Reinette Chatre
2022-04-04 16:49 ` [PATCH V3 28/30] selftests/sgx: Test invalid access to removed enclave page Reinette Chatre
2022-04-04 16:49 ` [PATCH V3 29/30] selftests/sgx: Test reclaiming of untouched page Reinette Chatre
2022-04-04 16:49 ` [PATCH V3 30/30] selftests/sgx: Page removal stress test Reinette Chatre
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=Ykvpi6HRL9cLorw6@kernel.org \
--to=jarkko@kernel.org \
--cc=bp@alien8.de \
--cc=cathy.zhang@intel.com \
--cc=cedric.xing@intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=haitao.huang@intel.com \
--cc=hpa@zytor.com \
--cc=kai.huang@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sgx@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mark.shanahan@intel.com \
--cc=mingo@redhat.com \
--cc=reinette.chatre@intel.com \
--cc=seanjc@google.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.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).