From: Nathaniel McCallum <npmccallum@redhat.com>
To: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Cc: x86@kernel.org, linux-sgx@vger.kernel.org,
linux-kernel@vger.kernel.org,
Sean Christopherson <sean.j.christopherson@intel.com>,
Andy Lutomirski <luto@amacapital.net>,
Jethro Beekman <jethro@fortanix.com>,
Cedric Xing <cedric.xing@intel.com>,
akpm@linux-foundation.org, andriy.shevchenko@linux.intel.com,
asapek@google.com, bp@alien8.de, chenalexchen@google.com,
conradparker@google.com, cyhanish@google.com,
dave.hansen@intel.com, "Huang, Haitao" <haitao.huang@intel.com>,
Josh Triplett <josh@joshtriplett.org>,
kai.huang@intel.com, "Svahn, Kai" <kai.svahn@intel.com>,
kmoy@google.com, ludloff@google.com, luto@kernel.org,
Neil Horman <nhorman@redhat.com>,
Patrick Uiterwijk <puiterwijk@redhat.com>,
David Rientjes <rientjes@google.com>,
Thomas Gleixner <tglx@linutronix.de>,
yaozhangx@google.com
Subject: Re: [PATCH v36 21/24] x86/vdso: Implement a vDSO for Intel SGX enclave call
Date: Thu, 6 Aug 2020 10:55:43 -0400 [thread overview]
Message-ID: <CAOASepOqRfUafSv_qjUv-jW_6n8G7kZ9yh-2z_Z9sjL_2zqNCg@mail.gmail.com> (raw)
In-Reply-To: <20200716135303.276442-22-jarkko.sakkinen@linux.intel.com>
In a past revision of this patch, I had requested a void *misc
parameter that could be passed through vdso_sgx_enter_enclave_t into
sgx_enclave_exit_handler_t. This request encountered some push back
and I dropped the issue. However, I'd like to revisit it or something
similar.
One way to create a generic interface to SGX is to pass a structure
that captures the relevant CPU state from the handler so that it can
be evaluated in C code before reentry. Precedent for this approach can
be found in struct kvm_run[0]. Currently, however, there is no way to
pass a pointer to such a structure directly into the handler.
This can be done implicitly by wrapping the struct
sgx_enclave_exception in another structure and then using techniques
like container_of() to find another field. However, this is made more
difficult by the fact that the sgx_enclave_exit_handler_t is not
really using the x86_64 sysv calling convention. Therefore, the
sgx_enclave_exit_handler_t MUST be written in assembly. This also
implies that we can't use techniques like container_of() and must
calculate all the offsets manually, which is tedious, error prone and
fragile.
This is further complicated by the fact that I'm using Rust (as are a
number of other consumers), which has no native offsetof support (yes,
there is a crate for it, but it requires a number of complex
strategies to defeat the compiler which aren't great) and therefore no
container_of() support.
We could design a standard struct for this (similar to struct
kvm_run). But in order to keep performance in check we'd have to
define a limited ABI surface (to avoid things like xsave) which
wouldn't have the full flexibility of the current approach. This would
allow for a kernel provided vDSO function with a normal calling
convention, however (which does have some non-trivial value). I think
this is a trade-off we should consider (perhaps making it optional?).
But at the least, allowing a pass-through void *misc would reduce the
complexity of the assembly calculations.
[0]: https://github.com/torvalds/linux/blob/master/include/uapi/linux/kvm.h#L263
On Thu, Jul 16, 2020 at 9:58 AM Jarkko Sakkinen
<jarkko.sakkinen@linux.intel.com> wrote:
>
> From: Sean Christopherson <sean.j.christopherson@intel.com>
>
> An SGX runtime must be aware of the exceptions, which happen inside an
> enclave. Introduce a vDSO call that wraps EENTER/ERESUME cycle and returns
> the CPU exception back to the caller exactly when it happens.
>
> Kernel fixups the exception information to RDI, RSI and RDX. The SGX call
> vDSO handler fills this information to the user provided buffer or
> alternatively trigger user provided callback at the time of the exception.
>
> The calling convention is custom and does not follow System V x86-64 ABI.
>
> Suggested-by: Andy Lutomirski <luto@amacapital.net>
> Acked-by: Jethro Beekman <jethro@fortanix.com>
> Tested-by: Jethro Beekman <jethro@fortanix.com>
> Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
> Co-developed-by: Cedric Xing <cedric.xing@intel.com>
> Signed-off-by: Cedric Xing <cedric.xing@intel.com>
> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> ---
> arch/x86/entry/vdso/Makefile | 2 +
> arch/x86/entry/vdso/vdso.lds.S | 1 +
> arch/x86/entry/vdso/vsgx_enter_enclave.S | 131 +++++++++++++++++++++++
> arch/x86/include/asm/enclu.h | 8 ++
> arch/x86/include/uapi/asm/sgx.h | 98 +++++++++++++++++
> 5 files changed, 240 insertions(+)
> create mode 100644 arch/x86/entry/vdso/vsgx_enter_enclave.S
> create mode 100644 arch/x86/include/asm/enclu.h
>
> diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
> index ebe82b7aecda..f71ad5ebd0c4 100644
> --- a/arch/x86/entry/vdso/Makefile
> +++ b/arch/x86/entry/vdso/Makefile
> @@ -29,6 +29,7 @@ VDSO32-$(CONFIG_IA32_EMULATION) := y
> vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o
> vobjs32-y := vdso32/note.o vdso32/system_call.o vdso32/sigreturn.o
> vobjs32-y += vdso32/vclock_gettime.o
> +vobjs-$(VDSO64-y) += vsgx_enter_enclave.o
>
> # files to link into kernel
> obj-y += vma.o extable.o
> @@ -100,6 +101,7 @@ $(vobjs): KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS
> CFLAGS_REMOVE_vclock_gettime.o = -pg
> CFLAGS_REMOVE_vdso32/vclock_gettime.o = -pg
> CFLAGS_REMOVE_vgetcpu.o = -pg
> +CFLAGS_REMOVE_vsgx_enter_enclave.o = -pg
>
> #
> # X32 processes use x32 vDSO to access 64bit kernel data.
> diff --git a/arch/x86/entry/vdso/vdso.lds.S b/arch/x86/entry/vdso/vdso.lds.S
> index 36b644e16272..4bf48462fca7 100644
> --- a/arch/x86/entry/vdso/vdso.lds.S
> +++ b/arch/x86/entry/vdso/vdso.lds.S
> @@ -27,6 +27,7 @@ VERSION {
> __vdso_time;
> clock_getres;
> __vdso_clock_getres;
> + __vdso_sgx_enter_enclave;
> local: *;
> };
> }
> diff --git a/arch/x86/entry/vdso/vsgx_enter_enclave.S b/arch/x86/entry/vdso/vsgx_enter_enclave.S
> new file mode 100644
> index 000000000000..be7e467e1efb
> --- /dev/null
> +++ b/arch/x86/entry/vdso/vsgx_enter_enclave.S
> @@ -0,0 +1,131 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#include <linux/linkage.h>
> +#include <asm/export.h>
> +#include <asm/errno.h>
> +#include <asm/enclu.h>
> +
> +#include "extable.h"
> +
> +#define EX_LEAF 0*8
> +#define EX_TRAPNR 0*8+4
> +#define EX_ERROR_CODE 0*8+6
> +#define EX_ADDRESS 1*8
> +
> +.code64
> +.section .text, "ax"
> +
> +SYM_FUNC_START(__vdso_sgx_enter_enclave)
> + /* Prolog */
> + .cfi_startproc
> + push %rbp
> + .cfi_adjust_cfa_offset 8
> + .cfi_rel_offset %rbp, 0
> + mov %rsp, %rbp
> + .cfi_def_cfa_register %rbp
> + push %rbx
> + .cfi_rel_offset %rbx, -8
> +
> + mov %ecx, %eax
> +.Lenter_enclave:
> + /* EENTER <= leaf <= ERESUME */
> + cmp $EENTER, %eax
> + jb .Linvalid_leaf
> + cmp $ERESUME, %eax
> + ja .Linvalid_leaf
> +
> + /* Load TCS and AEP */
> + mov 0x10(%rbp), %rbx
> + lea .Lasync_exit_pointer(%rip), %rcx
> +
> + /* Single ENCLU serving as both EENTER and AEP (ERESUME) */
> +.Lasync_exit_pointer:
> +.Lenclu_eenter_eresume:
> + enclu
> +
> + /* EEXIT jumps here unless the enclave is doing something fancy. */
> + xor %eax, %eax
> +
> + /* Invoke userspace's exit handler if one was provided. */
> +.Lhandle_exit:
> + cmp $0, 0x20(%rbp)
> + jne .Linvoke_userspace_handler
> +
> +.Lout:
> + pop %rbx
> + leave
> + .cfi_def_cfa %rsp, 8
> + ret
> +
> + /* The out-of-line code runs with the pre-leave stack frame. */
> + .cfi_def_cfa %rbp, 16
> +
> +.Linvalid_leaf:
> + mov $(-EINVAL), %eax
> + jmp .Lout
> +
> +.Lhandle_exception:
> + mov 0x18(%rbp), %rcx
> + test %rcx, %rcx
> + je .Lskip_exception_info
> +
> + /* Fill optional exception info. */
> + mov %eax, EX_LEAF(%rcx)
> + mov %di, EX_TRAPNR(%rcx)
> + mov %si, EX_ERROR_CODE(%rcx)
> + mov %rdx, EX_ADDRESS(%rcx)
> +.Lskip_exception_info:
> + mov $(-EFAULT), %eax
> + jmp .Lhandle_exit
> +
> +.Linvoke_userspace_handler:
> + /* Pass the untrusted RSP (at exit) to the callback via %rcx. */
> + mov %rsp, %rcx
> +
> + /* Save the untrusted RSP offset in %rbx (non-volatile register). */
> + mov %rsp, %rbx
> + and $0xf, %rbx
> +
> + /*
> + * Align stack per x86_64 ABI. Note, %rsp needs to be 16-byte aligned
> + * _after_ pushing the parameters on the stack, hence the bonus push.
> + */
> + and $-0x10, %rsp
> + push %rax
> +
> + /* Push @e, the "return" value and @tcs as params to the callback. */
> + push 0x18(%rbp)
> + push %rax
> + push 0x10(%rbp)
> +
> + /* Clear RFLAGS.DF per x86_64 ABI */
> + cld
> +
> + /* Load the callback pointer to %rax and invoke it via retpoline. */
> + mov 0x20(%rbp), %rax
> + call .Lretpoline
> +
> + /* Undo the post-exit %rsp adjustment. */
> + lea 0x20(%rsp, %rbx), %rsp
> +
> + /*
> + * If the return from callback is zero or negative, return immediately,
> + * else re-execute ENCLU with the postive return value interpreted as
> + * the requested ENCLU leaf.
> + */
> + cmp $0, %eax
> + jle .Lout
> + jmp .Lenter_enclave
> +
> +.Lretpoline:
> + call 2f
> +1: pause
> + lfence
> + jmp 1b
> +2: mov %rax, (%rsp)
> + ret
> + .cfi_endproc
> +
> +_ASM_VDSO_EXTABLE_HANDLE(.Lenclu_eenter_eresume, .Lhandle_exception)
> +
> +SYM_FUNC_END(__vdso_sgx_enter_enclave)
> diff --git a/arch/x86/include/asm/enclu.h b/arch/x86/include/asm/enclu.h
> new file mode 100644
> index 000000000000..06157b3e9ede
> --- /dev/null
> +++ b/arch/x86/include/asm/enclu.h
> @@ -0,0 +1,8 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_X86_ENCLU_H
> +#define _ASM_X86_ENCLU_H
> +
> +#define EENTER 0x02
> +#define ERESUME 0x03
> +
> +#endif /* _ASM_X86_ENCLU_H */
> diff --git a/arch/x86/include/uapi/asm/sgx.h b/arch/x86/include/uapi/asm/sgx.h
> index 57d0d30c79b3..3760e5d5dc0c 100644
> --- a/arch/x86/include/uapi/asm/sgx.h
> +++ b/arch/x86/include/uapi/asm/sgx.h
> @@ -74,4 +74,102 @@ struct sgx_enclave_set_attribute {
> __u64 attribute_fd;
> };
>
> +/**
> + * struct sgx_enclave_exception - structure to report exceptions encountered in
> + * __vdso_sgx_enter_enclave()
> + *
> + * @leaf: ENCLU leaf from \%eax at time of exception
> + * @trapnr: exception trap number, a.k.a. fault vector
> + * @error_code: exception error code
> + * @address: exception address, e.g. CR2 on a #PF
> + * @reserved: reserved for future use
> + */
> +struct sgx_enclave_exception {
> + __u32 leaf;
> + __u16 trapnr;
> + __u16 error_code;
> + __u64 address;
> + __u64 reserved[2];
> +};
> +
> +/**
> + * typedef sgx_enclave_exit_handler_t - Exit handler function accepted by
> + * __vdso_sgx_enter_enclave()
> + *
> + * @rdi: RDI at the time of enclave exit
> + * @rsi: RSI at the time of enclave exit
> + * @rdx: RDX at the time of enclave exit
> + * @ursp: RSP at the time of enclave exit (untrusted stack)
> + * @r8: R8 at the time of enclave exit
> + * @r9: R9 at the time of enclave exit
> + * @tcs: Thread Control Structure used to enter enclave
> + * @ret: 0 on success (EEXIT), -EFAULT on an exception
> + * @e: Pointer to struct sgx_enclave_exception (as provided by caller)
> + */
> +typedef int (*sgx_enclave_exit_handler_t)(long rdi, long rsi, long rdx,
> + long ursp, long r8, long r9,
> + void *tcs, int ret,
> + struct sgx_enclave_exception *e);
> +
> +/**
> + * __vdso_sgx_enter_enclave() - Enter an SGX enclave
> + * @rdi: Pass-through value for RDI
> + * @rsi: Pass-through value for RSI
> + * @rdx: Pass-through value for RDX
> + * @leaf: ENCLU leaf, must be EENTER or ERESUME
> + * @r8: Pass-through value for R8
> + * @r9: Pass-through value for R9
> + * @tcs: TCS, must be non-NULL
> + * @e: Optional struct sgx_enclave_exception instance
> + * @handler: Optional enclave exit handler
> + *
> + * NOTE: __vdso_sgx_enter_enclave() does not ensure full compliance with the
> + * x86-64 ABI, e.g. doesn't explicitly clear EFLAGS.DF after EEXIT. Except for
> + * non-volatile general purpose registers, preserving/setting state in
> + * accordance with the x86-64 ABI is the responsibility of the enclave and its
> + * runtime, i.e. __vdso_sgx_enter_enclave() cannot be called from C code
> + * without careful consideration by both the enclave and its runtime.
> + *
> + * All general purpose registers except RAX, RBX and RCX are passed as-is to
> + * the enclave. RAX, RBX and RCX are consumed by EENTER and ERESUME and are
> + * loaded with @leaf, asynchronous exit pointer, and @tcs respectively.
> + *
> + * RBP and the stack are used to anchor __vdso_sgx_enter_enclave() to the
> + * pre-enclave state, e.g. to retrieve @e and @handler after an enclave exit.
> + * All other registers are available for use by the enclave and its runtime,
> + * e.g. an enclave can push additional data onto the stack (and modify RSP) to
> + * pass information to the optional exit handler (see below).
> + *
> + * Most exceptions reported on ENCLU, including those that occur within the
> + * enclave, are fixed up and reported synchronously instead of being delivered
> + * via a standard signal. Debug Exceptions (#DB) and Breakpoints (#BP) are
> + * never fixed up and are always delivered via standard signals. On synchrously
> + * reported exceptions, -EFAULT is returned and details about the exception are
> + * recorded in @e, the optional sgx_enclave_exception struct.
> +
> + * If an exit handler is provided, the handler will be invoked on synchronous
> + * exits from the enclave and for all synchronously reported exceptions. In
> + * latter case, @e is filled prior to invoking the handler.
> + *
> + * The exit handler's return value is interpreted as follows:
> + * >0: continue, restart __vdso_sgx_enter_enclave() with @ret as @leaf
> + * 0: success, return @ret to the caller
> + * <0: error, return @ret to the caller
> + *
> + * The exit handler may transfer control, e.g. via longjmp() or C++ exception,
> + * without returning to __vdso_sgx_enter_enclave().
> + *
> + * Return:
> + * 0 on success,
> + * -EINVAL if ENCLU leaf is not allowed,
> + * -EFAULT if an exception occurs on ENCLU or within the enclave
> + * -errno for all other negative values returned by the userspace exit handler
> + */
> +typedef int (*vdso_sgx_enter_enclave_t)(unsigned long rdi, unsigned long rsi,
> + unsigned long rdx, unsigned int leaf,
> + unsigned long r8, unsigned long r9,
> + void *tcs,
> + struct sgx_enclave_exception *e,
> + sgx_enclave_exit_handler_t handler);
> +
> #endif /* _UAPI_ASM_X86_SGX_H */
> --
> 2.25.1
>
next prev parent reply other threads:[~2020-08-06 17:56 UTC|newest]
Thread overview: 80+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-16 13:52 [PATCH v36 00/24] Intel SGX foundations Jarkko Sakkinen
2020-07-16 13:52 ` [PATCH v36 01/24] x86/cpufeatures: x86/msr: Add Intel SGX hardware bits Jarkko Sakkinen
2020-08-06 13:13 ` Darren Kenny
2020-07-16 13:52 ` [PATCH v36 02/24] x86/cpufeatures: x86/msr: Add Intel SGX Launch Control " Jarkko Sakkinen
2020-08-06 13:14 ` Darren Kenny
2020-07-16 13:52 ` [PATCH v36 03/24] x86/mm: x86/sgx: Signal SIGSEGV with PF_SGX Jarkko Sakkinen
2020-08-06 13:16 ` Darren Kenny
2020-08-20 15:31 ` Borislav Petkov
2020-08-21 17:35 ` Jarkko Sakkinen
2020-07-16 13:52 ` [PATCH v36 04/24] x86/sgx: Add SGX microarchitectural data structures Jarkko Sakkinen
2020-08-06 13:14 ` Darren Kenny
2020-07-16 13:52 ` [PATCH v36 05/24] x86/sgx: Add wrappers for ENCLS leaf functions Jarkko Sakkinen
2020-08-07 9:37 ` Darren Kenny
2020-07-16 13:52 ` [PATCH v36 06/24] x86/cpu/intel: Detect SGX support Jarkko Sakkinen
2020-08-06 13:17 ` Darren Kenny
2020-07-16 13:52 ` [PATCH v36 07/24] x86/cpu/intel: Add nosgx kernel parameter Jarkko Sakkinen
2020-08-06 13:18 ` Darren Kenny
2020-07-16 13:52 ` [PATCH v36 08/24] x86/sgx: Initialize metadata for Enclave Page Cache (EPC) sections Jarkko Sakkinen
2020-08-06 13:27 ` Darren Kenny
2020-07-16 13:52 ` [PATCH v36 09/24] x86/sgx: Add __sgx_alloc_epc_page() and sgx_free_epc_page() Jarkko Sakkinen
2020-08-06 13:29 ` Darren Kenny
2020-07-16 13:52 ` [PATCH v36 10/24] mm: Add vm_ops->mprotect() Jarkko Sakkinen
2020-08-06 13:35 ` Darren Kenny
2020-07-16 13:52 ` [PATCH v36 11/24] x86/sgx: Add SGX enclave driver Jarkko Sakkinen
2020-08-06 13:59 ` Darren Kenny
2020-08-25 16:44 ` Borislav Petkov
2020-08-26 13:46 ` Jarkko Sakkinen
2020-07-16 13:52 ` [PATCH v36 12/24] x86/sgx: Add SGX_IOC_ENCLAVE_CREATE Jarkko Sakkinen
2020-08-06 15:40 ` Darren Kenny
2020-08-26 14:52 ` Borislav Petkov
2020-08-27 13:24 ` Jarkko Sakkinen
2020-08-27 16:15 ` Borislav Petkov
2020-08-28 23:39 ` Jarkko Sakkinen
2020-08-29 0:21 ` Jarkko Sakkinen
2020-09-01 16:41 ` Haitao Huang
2020-09-04 11:55 ` Jarkko Sakkinen
2020-07-16 13:52 ` [PATCH v36 13/24] x86/sgx: Add SGX_IOC_ENCLAVE_ADD_PAGES Jarkko Sakkinen
2020-08-06 16:29 ` Darren Kenny
2020-07-16 13:52 ` [PATCH v36 14/24] x86/sgx: Add SGX_IOC_ENCLAVE_INIT Jarkko Sakkinen
2020-08-06 16:40 ` Darren Kenny
2020-07-16 13:52 ` [PATCH v36 15/24] x86/sgx: Allow a limited use of ATTRIBUTE.PROVISIONKEY for attestation Jarkko Sakkinen
2020-08-06 17:00 ` Darren Kenny
2020-08-18 13:30 ` Jarkko Sakkinen
2020-07-16 13:52 ` [PATCH v36 16/24] x86/sgx: Add a page reclaimer Jarkko Sakkinen
2020-07-16 13:52 ` [PATCH v36 17/24] x86/sgx: ptrace() support for the SGX driver Jarkko Sakkinen
2020-07-16 13:52 ` [PATCH v36 18/24] x86/vdso: Add support for exception fixup in vDSO functions Jarkko Sakkinen
2020-07-16 13:52 ` [PATCH v36 19/24] x86/fault: Add helper function to sanitize error code Jarkko Sakkinen
2020-07-16 13:52 ` [PATCH v36 20/24] x86/traps: Attempt to fixup exceptions in vDSO before signaling Jarkko Sakkinen
2020-07-16 13:53 ` [PATCH v36 21/24] x86/vdso: Implement a vDSO for Intel SGX enclave call Jarkko Sakkinen
2020-08-06 14:55 ` Nathaniel McCallum [this message]
2020-08-10 22:23 ` Sean Christopherson
2020-08-11 7:16 ` Jethro Beekman
2020-08-11 14:54 ` Sean Christopherson
2020-08-18 14:52 ` Jarkko Sakkinen
2020-08-18 15:06 ` Jarkko Sakkinen
2020-08-18 15:15 ` Nathaniel McCallum
2020-08-18 16:43 ` Jarkko Sakkinen
2020-08-19 13:33 ` Nathaniel McCallum
2020-08-19 14:00 ` Jethro Beekman
2020-08-19 21:23 ` Jarkko Sakkinen
2020-08-10 23:08 ` Andy Lutomirski
2020-08-10 23:48 ` Sean Christopherson
2020-08-11 0:52 ` Andy Lutomirski
2020-08-11 15:16 ` Andy Lutomirski
2020-08-13 19:38 ` Sean Christopherson
2020-08-17 13:12 ` Nathaniel McCallum
2020-08-17 15:01 ` Andy Lutomirski
2020-08-18 15:15 ` Jarkko Sakkinen
2020-08-20 0:19 ` Andy Lutomirski
2020-08-18 14:26 ` Jarkko Sakkinen
2020-07-16 13:53 ` [PATCH v36 22/24] selftests/x86: Add a selftest for SGX Jarkko Sakkinen
2020-08-27 4:47 ` Nathaniel McCallum
2020-08-27 15:20 ` Sean Christopherson
2020-08-28 23:27 ` Jarkko Sakkinen
2020-07-16 13:53 ` [PATCH v36 23/24] docs: x86/sgx: Document SGX micro architecture and kernel internals Jarkko Sakkinen
2020-07-28 21:35 ` Pavel Machek
2020-08-06 10:21 ` Dr. Greg
2020-08-08 22:18 ` Pavel Machek
2020-08-19 20:55 ` Jarkko Sakkinen
2020-07-16 13:53 ` [PATCH v36 24/24] x86/sgx: Update MAINTAINERS Jarkko Sakkinen
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=CAOASepOqRfUafSv_qjUv-jW_6n8G7kZ9yh-2z_Z9sjL_2zqNCg@mail.gmail.com \
--to=npmccallum@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=asapek@google.com \
--cc=bp@alien8.de \
--cc=cedric.xing@intel.com \
--cc=chenalexchen@google.com \
--cc=conradparker@google.com \
--cc=cyhanish@google.com \
--cc=dave.hansen@intel.com \
--cc=haitao.huang@intel.com \
--cc=jarkko.sakkinen@linux.intel.com \
--cc=jethro@fortanix.com \
--cc=josh@joshtriplett.org \
--cc=kai.huang@intel.com \
--cc=kai.svahn@intel.com \
--cc=kmoy@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sgx@vger.kernel.org \
--cc=ludloff@google.com \
--cc=luto@amacapital.net \
--cc=luto@kernel.org \
--cc=nhorman@redhat.com \
--cc=puiterwijk@redhat.com \
--cc=rientjes@google.com \
--cc=sean.j.christopherson@intel.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
--cc=yaozhangx@google.com \
/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).