linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Deepak Gupta <debug@rivosinc.com>
To: Andy Chiu <andybnac@gmail.com>
Cc: paul.walmsley@sifive.com, palmer@sifive.com, conor@kernel.org,
	linux-doc@vger.kernel.org, linux-riscv@lists.infradead.org,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
	linux-fsdevel@vger.kernel.org, linux-mm@kvack.org,
	linux-arch@vger.kernel.org, linux-kselftest@vger.kernel.org,
	quic_zhonhan@quicinc.com, zong.li@sifive.com,
	zev@bewilderbeest.net, david@redhat.com, peterz@infradead.org,
	catalin.marinas@arm.com, broonie@kernel.org,
	dave.hansen@linux.intel.com, atishp@rivosinc.com,
	bjorn@rivosinc.com, namcaov@gmail.com, usama.anjum@collabora.com,
	guoren@kernel.org, alx@kernel.org, jszhang@kernel.org,
	hpa@zytor.com, puranjay@kernel.org, shuah@kernel.org,
	sorear@fastmail.com, costa.shul@redhat.com, robh@kernel.org,
	antonb@tenstorrent.com, quic_bjorande@quicinc.com,
	lorenzo.stoakes@oracle.com, corbet@lwn.net,
	dawei.li@shingroup.cn, anup@brainfault.org, deller@gmx.de,
	x86@kernel.org, andrii@kernel.org, willy@infradead.org,
	kees@kernel.org, mingo@redhat.com, libang.li@antgroup.com,
	samitolvanen@google.com, greentime.hu@sifive.com,
	osalvador@suse.de, ajones@ventanamicro.com, revest@chromium.org,
	ancientmodern4@gmail.com, aou@eecs.berkeley.edu,
	jerry.shih@sifive.com, alexghiti@rivosinc.com, arnd@arndb.de,
	yang.lee@linux.alibaba.com, charlie@rivosinc.com,
	bgray@linux.ibm.com, Liam.Howlett@oracle.com, leobras@redhat.com,
	songshuaishuai@tinylab.org, xiao.w.wang@intel.com, bp@alien8.de,
	cuiyunhui@bytedance.com, mchitale@ventanamicro.com,
	cleger@rivosinc.com, tglx@linutronix.de, krzk+dt@kernel.org,
	vbabka@suse.cz, brauner@kernel.org, bhe@redhat.com,
	ke.zhao@shingroup.cn, oleg@redhat.com, samuel.holland@sifive.com,
	ben.dooks@codethink.co.uk, evan@rivosinc.com, palmer@dabbelt.com,
	ebiederm@xmission.com, andy.chiu@sifive.com, schwab@suse.de,
	akpm@linux-foundation.org, sameo@rivosinc.com,
	tanzhasanwork@gmail.com, rppt@kernel.org, ryan.roberts@arm.com
Subject: Re: [PATCH v4 23/30] riscv signal: save and restore of shadow stack for signal
Date: Mon, 16 Sep 2024 15:03:26 -0700	[thread overview]
Message-ID: <ZuirLvsl6gukn/SG@debug.ba.rivosinc.com> (raw)
In-Reply-To: <CAFTtA3ONu7CUNHwQf47ePMh9uvAi-uCV8B0YJAuFX+s0thC41Q@mail.gmail.com>

On Fri, Sep 13, 2024 at 09:25:57PM +0200, Andy Chiu wrote:
>Hi Deepak,
>
>Deepak Gupta <debug@rivosinc.com> 於 2024年9月13日 週五 上午1:20寫道:
>>
>> Save shadow stack pointer in sigcontext structure while delivering signal.
>> Restore shadow stack pointer from sigcontext on sigreturn.
>>
>> As part of save operation, kernel uses `ssamoswap` to save snapshot of
>> current shadow stack on shadow stack itself (can be called as a save
>> token). During restore on sigreturn, kernel retrieves token from top of
>> shadow stack and validates it. This allows that user mode can't arbitrary
>> pivot to any shadow stack address without having a token and thus provide
>> strong security assurance between signaly delivery and sigreturn window.
>>
>> Signed-off-by: Deepak Gupta <debug@rivosinc.com>
>> Suggested-by: Andy Chiu <andy.chiu@sifive.com>
>> ---
>>  arch/riscv/include/asm/usercfi.h | 19 ++++++++++
>>  arch/riscv/kernel/signal.c       | 62 +++++++++++++++++++++++++++++++-
>>  arch/riscv/kernel/usercfi.c      | 57 +++++++++++++++++++++++++++++
>>  3 files changed, 137 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/riscv/include/asm/usercfi.h b/arch/riscv/include/asm/usercfi.h
>> index 20a9102cce51..d5050a5df26c 100644
>> --- a/arch/riscv/include/asm/usercfi.h
>> +++ b/arch/riscv/include/asm/usercfi.h
>> @@ -8,6 +8,7 @@
>>  #ifndef __ASSEMBLY__
>>  #include <linux/types.h>
>>  #include <linux/prctl.h>
>> +#include <linux/errno.h>
>>
>>  struct task_struct;
>>  struct kernel_clone_args;
>> @@ -35,6 +36,9 @@ bool is_shstk_locked(struct task_struct *task);
>>  bool is_shstk_allocated(struct task_struct *task);
>>  void set_shstk_lock(struct task_struct *task);
>>  void set_shstk_status(struct task_struct *task, bool enable);
>> +unsigned long get_active_shstk(struct task_struct *task);
>> +int restore_user_shstk(struct task_struct *tsk, unsigned long shstk_ptr);
>> +int save_user_shstk(struct task_struct *tsk, unsigned long *saved_shstk_ptr);
>>  bool is_indir_lp_enabled(struct task_struct *task);
>>  bool is_indir_lp_locked(struct task_struct *task);
>>  void set_indir_lp_status(struct task_struct *task, bool enable);
>> @@ -96,6 +100,21 @@ static inline void set_shstk_status(struct task_struct *task, bool enable)
>>
>>  }
>>
>> +static inline int restore_user_shstk(struct task_struct *tsk, unsigned long shstk_ptr)
>> +{
>> +       return -EINVAL;
>> +}
>> +
>> +static inline int save_user_shstk(struct task_struct *tsk, unsigned long *saved_shstk_ptr)
>> +{
>> +       return -EINVAL;
>> +}
>> +
>> +static inline unsigned long get_active_shstk(struct task_struct *task)
>> +{
>> +       return 0;
>> +}
>> +
>>  static inline bool is_indir_lp_enabled(struct task_struct *task)
>>  {
>>         return false;
>> diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
>> index dcd282419456..7d5c1825650f 100644
>> --- a/arch/riscv/kernel/signal.c
>> +++ b/arch/riscv/kernel/signal.c
>> @@ -22,6 +22,7 @@
>>  #include <asm/vector.h>
>>  #include <asm/csr.h>
>>  #include <asm/cacheflush.h>
>> +#include <asm/usercfi.h>
>>
>>  unsigned long signal_minsigstksz __ro_after_init;
>>
>> @@ -153,6 +154,16 @@ static long restore_sigcontext(struct pt_regs *regs,
>>         void __user *sc_ext_ptr = &sc->sc_extdesc.hdr;
>>         __u32 rsvd;
>>         long err;
>> +       unsigned long ss_ptr = 0;
>> +       struct __sc_riscv_cfi_state __user *sc_cfi = NULL;
>> +
>> +       sc_cfi = (struct __sc_riscv_cfi_state *)
>> +                ((unsigned long) sc_ext_ptr + sizeof(struct __riscv_ctx_hdr));
>> +
>> +       if (has_vector() && riscv_v_vstate_query(regs))
>> +               sc_cfi = (struct __sc_riscv_cfi_state *)
>> +                        ((unsigned long) sc_cfi + riscv_v_sc_size);
>> +
>>         /* sc_regs is structured the same as the start of pt_regs */
>>         err = __copy_from_user(regs, &sc->sc_regs, sizeof(sc->sc_regs));
>>         if (unlikely(err))
>> @@ -172,6 +183,24 @@ static long restore_sigcontext(struct pt_regs *regs,
>>         if (unlikely(rsvd))
>>                 return -EINVAL;
>>
>> +       /*
>> +        * Restore shadow stack as a form of token stored on shadow stack itself as a safe
>> +        * way to restore.
>> +        * A token on shadow gives following properties
>> +        *      - Safe save and restore for shadow stack switching. Any save of shadow stack
>> +        *        must have had saved a token on shadow stack. Similarly any restore of shadow
>> +        *        stack must check the token before restore. Since writing to shadow stack with
>> +        *        address of shadow stack itself is not easily allowed. A restore without a save
>> +        *        is quite difficult for an attacker to perform.
>> +        *      - A natural break. A token in shadow stack provides a natural break in shadow stack
>> +        *        So a single linear range can be bucketed into different shadow stack segments.
>> +        *        sspopchk will detect the condition and fault to kernel as sw check exception.
>> +        */
>> +       if (is_shstk_enabled(current)) {
>> +               err |= __copy_from_user(&ss_ptr, &sc_cfi->ss_ptr, sizeof(unsigned long));
>> +               err |= restore_user_shstk(current, ss_ptr);
>> +       }
>> +
>>         while (!err) {
>>                 __u32 magic, size;
>>                 struct __riscv_ctx_hdr __user *head = sc_ext_ptr;
>> @@ -215,6 +244,10 @@ static size_t get_rt_frame_size(bool cal_all)
>>                 if (cal_all || riscv_v_vstate_query(task_pt_regs(current)))
>>                         total_context_size += riscv_v_sc_size;
>>         }
>> +
>> +       if (is_shstk_enabled(current))
>> +               total_context_size += sizeof(struct __sc_riscv_cfi_state);
>> +
>>         /*
>>          * Preserved a __riscv_ctx_hdr for END signal context header if an
>>          * extension uses __riscv_extra_ext_header
>> @@ -276,18 +309,40 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
>>  {
>>         struct sigcontext __user *sc = &frame->uc.uc_mcontext;
>>         struct __riscv_ctx_hdr __user *sc_ext_ptr = &sc->sc_extdesc.hdr;
>> +       unsigned long ss_ptr = 0;
>> +       struct __sc_riscv_cfi_state __user *sc_cfi = NULL;
>>         long err;
>>
>> +       sc_cfi = (struct __sc_riscv_cfi_state *) (sc_ext_ptr + 1);
>> +
>
>Is it intended that cfi sigcontext does not follow the sigcontext rule
>setup by Vector? It seems like there is no extension header (struct
>__riscv_ctx_hdr) defined for cfi sigcontext here. If the sigcontext is
>directly appended to the signal stack, the user may not be able to
>recognize the meaning without defining a new ABI.

Hmm... I didn't realize that struct `struct __riscv_ctx_hdr` is strongly
tied to vector state. I was under the impression that any new extended
state addition would require this header to be present.

cfi sigcontenxt doesn't need any ABI between user and kernel here. We need
this space so that kernel can save a pointer to shadow stack token on signal
delivery. Once sigreturn happens, kernel will use the same pointer, verify
the token saved on shadow stack and restore shadow stack for user mode.
At no point in this scheme, user mode is required to perform any action.

All that is needed is that user mode doesn't accidenly trample at this offset.

Since I was under the impression that `struct __riscv_ctx_hdr` is there for
context extension and must be present for any state beyond `sc_regs`, I assumed
that I must make space for this header (even if vector state is not present).

>
>BTW, I have sent a patch[1] that refactor setup_sigcontext so it'd be
>easier for future extensions to expand on the signal stack.

I can adopt to this, although its orthogonal to what we are discussing here.

>
>>         /* sc_regs is structured the same as the start of pt_regs */
>>         err = __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs));
>>         /* Save the floating-point state. */
>>         if (has_fpu())
>>                 err |= save_fp_state(regs, &sc->sc_fpregs);
>>         /* Save the vector state. */
>> -       if (has_vector() && riscv_v_vstate_query(regs))
>> +       if (has_vector() && riscv_v_vstate_query(regs)) {
>>                 err |= save_v_state(regs, (void __user **)&sc_ext_ptr);
>> +               sc_cfi = (struct __sc_riscv_cfi_state *) ((unsigned long) sc_cfi + riscv_v_sc_size);
>> +       }
>>         /* Write zero to fp-reserved space and check it on restore_sigcontext */
>>         err |= __put_user(0, &sc->sc_extdesc.reserved);
>> +       /*
>> +        * Save a pointer to shadow stack itself on shadow stack as a form of token.
>> +        * A token on shadow gives following properties
>> +        *      - Safe save and restore for shadow stack switching. Any save of shadow stack
>> +        *        must have had saved a token on shadow stack. Similarly any restore of shadow
>> +        *        stack must check the token before restore. Since writing to shadow stack with
>> +        *        address of shadow stack itself is not easily allowed. A restore without a save
>> +        *        is quite difficult for an attacker to perform.
>> +        *      - A natural break. A token in shadow stack provides a natural break in shadow stack
>> +        *        So a single linear range can be bucketed into different shadow stack segments. Any
>> +        *        sspopchk will detect the condition and fault to kernel as sw check exception.
>> +        */
>> +       if (is_shstk_enabled(current)) {
>> +               err |= save_user_shstk(current, &ss_ptr);
>> +               err |= __put_user(ss_ptr, &sc_cfi->ss_ptr);
>> +       }
>>         /* And put END __riscv_ctx_hdr at the end. */
>>         err |= __put_user(END_MAGIC, &sc_ext_ptr->magic);
>>         err |= __put_user(END_HDR_SIZE, &sc_ext_ptr->size);
>> @@ -345,6 +400,11 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
>>  #ifdef CONFIG_MMU
>>         regs->ra = (unsigned long)VDSO_SYMBOL(
>>                 current->mm->context.vdso, rt_sigreturn);
>> +
>> +       /* if bcfi is enabled x1 (ra) and x5 (t0) must match. not sure if we need this? */
>> +       if (is_shstk_enabled(current))
>> +               regs->t0 = regs->ra;
>> +
>>  #else
>>         /*
>>          * For the nommu case we don't have a VDSO.  Instead we push two
>> diff --git a/arch/riscv/kernel/usercfi.c b/arch/riscv/kernel/usercfi.c
>> index 8da509afdbe9..40c32258b6ec 100644
>> --- a/arch/riscv/kernel/usercfi.c
>> +++ b/arch/riscv/kernel/usercfi.c
>> @@ -52,6 +52,11 @@ void set_active_shstk(struct task_struct *task, unsigned long shstk_addr)
>>         task->thread_info.user_cfi_state.user_shdw_stk = shstk_addr;
>>  }
>>
>> +unsigned long get_active_shstk(struct task_struct *task)
>> +{
>> +       return task->thread_info.user_cfi_state.user_shdw_stk;
>> +}
>> +
>>  void set_shstk_status(struct task_struct *task, bool enable)
>>  {
>>         task->thread_info.user_cfi_state.ubcfi_en = enable ? 1 : 0;
>> @@ -164,6 +169,58 @@ static int create_rstor_token(unsigned long ssp, unsigned long *token_addr)
>>         return 0;
>>  }
>>
>> +/*
>> + * Save user shadow stack pointer on shadow stack itself and return pointer to saved location
>> + * returns -EFAULT if operation was unsuccessful
>> + */
>> +int save_user_shstk(struct task_struct *tsk, unsigned long *saved_shstk_ptr)
>> +{
>> +       unsigned long ss_ptr = 0;
>> +       unsigned long token_loc = 0;
>> +       int ret = 0;
>> +
>> +       if (saved_shstk_ptr == NULL)
>> +               return -EINVAL;
>> +
>> +       ss_ptr = get_active_shstk(tsk);
>> +       ret = create_rstor_token(ss_ptr, &token_loc);
>> +
>> +       if (!ret) {
>> +               *saved_shstk_ptr = token_loc;
>> +               set_active_shstk(tsk, token_loc);
>> +       }
>> +
>> +       return ret;
>> +}
>> +
>> +/*
>> + * Restores user shadow stack pointer from token on shadow stack for task `tsk`
>> + * returns -EFAULT if operation was unsuccessful
>> + */
>> +int restore_user_shstk(struct task_struct *tsk, unsigned long shstk_ptr)
>> +{
>> +       unsigned long token = 0;
>> +
>> +       token = amo_user_shstk((unsigned long __user *)shstk_ptr, 0);
>> +
>> +       if (token == -1)
>> +               return -EFAULT;
>> +
>> +       /* invalid token, return EINVAL */
>> +       if ((token - shstk_ptr) != SHSTK_ENTRY_SIZE) {
>> +               pr_info_ratelimited(
>> +                               "%s[%d]: bad restore token in %s: pc=%p sp=%p, token=%p, shstk_ptr=%p\n",
>> +                               tsk->comm, task_pid_nr(tsk), __func__,
>> +                               (void *)(task_pt_regs(tsk)->epc), (void *)(task_pt_regs(tsk)->sp),
>> +                               (void *)token, (void *)shstk_ptr);
>> +               return -EINVAL;
>> +       }
>> +
>> +       /* all checks passed, set active shstk and return success */
>> +       set_active_shstk(tsk, token);
>> +       return 0;
>> +}
>> +
>>  static unsigned long allocate_shadow_stack(unsigned long addr, unsigned long size,
>>                                 unsigned long token_offset,
>>                                 bool set_tok)
>> --
>> 2.45.0
>>
>>
>> _______________________________________________
>> linux-riscv mailing list
>> linux-riscv@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-riscv
>
>- [1]: https://lore.kernel.org/all/20240628-dev-signal-refactor-v1-1-0c391b260261@sifive.com/
>
>Thanks,
>Andy

  reply	other threads:[~2024-09-16 22:03 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-12 23:16 [PATCH v4 00/30] riscv control-flow integrity for usermode Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 01/30] mm: Introduce ARCH_HAS_USER_SHADOW_STACK Deepak Gupta
2024-09-13 15:51   ` Carlos Bilbao
2024-09-12 23:16 ` [PATCH v4 02/30] mm: helper `is_shadow_stack_vma` to check shadow stack vma Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 03/30] riscv: Enable cbo.zero only when all harts support Zicboz Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 04/30] riscv: Add support for per-thread envcfg CSR values Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 05/30] riscv: Call riscv_user_isa_enable() only on the boot hart Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 06/30] riscv/Kconfig: enable HAVE_EXIT_THREAD for riscv Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 07/30] riscv: zicfilp / zicfiss in dt-bindings (extensions.yaml) Deepak Gupta
2024-09-13  0:18   ` Rob Herring (Arm)
2024-09-13 18:33   ` Conor Dooley
2024-09-12 23:16 ` [PATCH v4 08/30] riscv: zicfiss / zicfilp enumeration Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 09/30] riscv: zicfiss / zicfilp extension csr and bit definitions Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 10/30] riscv: usercfi state for task and save/restore of CSR_SSP on trap entry/exit Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 11/30] riscv/mm : ensure PROT_WRITE leads to VM_READ | VM_WRITE Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 12/30] riscv mm: manufacture shadow stack pte Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 13/30] riscv mmu: teach pte_mkwrite to manufacture shadow stack PTEs Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 14/30] riscv mmu: write protect and shadow stack Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 15/30] riscv/mm: Implement map_shadow_stack() syscall Deepak Gupta
2024-09-13 15:26   ` Mark Brown
2024-09-12 23:16 ` [PATCH v4 16/30] riscv/shstk: If needed allocate a new shadow stack on clone Deepak Gupta
2024-09-14  1:54   ` kernel test robot
2024-09-14  3:06   ` kernel test robot
2024-09-14  3:26   ` kernel test robot
2024-09-12 23:16 ` [PATCH v4 17/30] prctl: arch-agnostic prctl for shadow stack Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 18/30] prctl: arch-agnostic prctl for indirect branch tracking Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 19/30] riscv: Implements arch agnostic shadow stack prctls Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 20/30] riscv: Implements arch agnostic indirect branch tracking prctls Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 21/30] riscv/traps: Introduce software check exception Deepak Gupta
2024-09-13 19:35   ` Andy Chiu
2024-09-17  0:00     ` Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 22/30] riscv sigcontext: cfi state struct definition for sigcontext Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 23/30] riscv signal: save and restore of shadow stack for signal Deepak Gupta
2024-09-13 19:25   ` Andy Chiu
2024-09-16 22:03     ` Deepak Gupta [this message]
2024-09-17 22:03       ` Andy Chiu
2024-09-17 22:52         ` Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 24/30] riscv/kernel: update __show_regs to print shadow stack register Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 25/30] riscv/ptrace: riscv cfi status and state via ptrace and in core files Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 26/30] riscv/hwprobe: zicfilp / zicfiss enumeration in hwprobe Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 27/30] riscv: create a config for shadow stack and landing pad instr support Deepak Gupta
2024-09-12 23:16 ` [PATCH v4 28/30] riscv: Documentation for landing pad / indirect branch tracking Deepak Gupta
2024-09-16  2:41   ` Bagas Sanjaya
2024-09-12 23:16 ` [PATCH v4 29/30] riscv: Documentation for shadow stack on riscv Deepak Gupta
2024-09-16  3:20   ` Bagas Sanjaya
2024-09-12 23:16 ` [PATCH v4 30/30] kselftest/riscv: kselftest for user mode cfi Deepak Gupta

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=ZuirLvsl6gukn/SG@debug.ba.rivosinc.com \
    --to=debug@rivosinc.com \
    --cc=Liam.Howlett@oracle.com \
    --cc=ajones@ventanamicro.com \
    --cc=akpm@linux-foundation.org \
    --cc=alexghiti@rivosinc.com \
    --cc=alx@kernel.org \
    --cc=ancientmodern4@gmail.com \
    --cc=andrii@kernel.org \
    --cc=andy.chiu@sifive.com \
    --cc=andybnac@gmail.com \
    --cc=antonb@tenstorrent.com \
    --cc=anup@brainfault.org \
    --cc=aou@eecs.berkeley.edu \
    --cc=arnd@arndb.de \
    --cc=atishp@rivosinc.com \
    --cc=ben.dooks@codethink.co.uk \
    --cc=bgray@linux.ibm.com \
    --cc=bhe@redhat.com \
    --cc=bjorn@rivosinc.com \
    --cc=bp@alien8.de \
    --cc=brauner@kernel.org \
    --cc=broonie@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=charlie@rivosinc.com \
    --cc=cleger@rivosinc.com \
    --cc=conor@kernel.org \
    --cc=corbet@lwn.net \
    --cc=costa.shul@redhat.com \
    --cc=cuiyunhui@bytedance.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=david@redhat.com \
    --cc=dawei.li@shingroup.cn \
    --cc=deller@gmx.de \
    --cc=devicetree@vger.kernel.org \
    --cc=ebiederm@xmission.com \
    --cc=evan@rivosinc.com \
    --cc=greentime.hu@sifive.com \
    --cc=guoren@kernel.org \
    --cc=hpa@zytor.com \
    --cc=jerry.shih@sifive.com \
    --cc=jszhang@kernel.org \
    --cc=ke.zhao@shingroup.cn \
    --cc=kees@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=leobras@redhat.com \
    --cc=libang.li@antgroup.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=lorenzo.stoakes@oracle.com \
    --cc=mchitale@ventanamicro.com \
    --cc=mingo@redhat.com \
    --cc=namcaov@gmail.com \
    --cc=oleg@redhat.com \
    --cc=osalvador@suse.de \
    --cc=palmer@dabbelt.com \
    --cc=palmer@sifive.com \
    --cc=paul.walmsley@sifive.com \
    --cc=peterz@infradead.org \
    --cc=puranjay@kernel.org \
    --cc=quic_bjorande@quicinc.com \
    --cc=quic_zhonhan@quicinc.com \
    --cc=revest@chromium.org \
    --cc=robh@kernel.org \
    --cc=rppt@kernel.org \
    --cc=ryan.roberts@arm.com \
    --cc=sameo@rivosinc.com \
    --cc=samitolvanen@google.com \
    --cc=samuel.holland@sifive.com \
    --cc=schwab@suse.de \
    --cc=shuah@kernel.org \
    --cc=songshuaishuai@tinylab.org \
    --cc=sorear@fastmail.com \
    --cc=tanzhasanwork@gmail.com \
    --cc=tglx@linutronix.de \
    --cc=usama.anjum@collabora.com \
    --cc=vbabka@suse.cz \
    --cc=willy@infradead.org \
    --cc=x86@kernel.org \
    --cc=xiao.w.wang@intel.com \
    --cc=yang.lee@linux.alibaba.com \
    --cc=zev@bewilderbeest.net \
    --cc=zong.li@sifive.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).