linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Andy Chiu <andybnac@gmail.com>
To: Deepak Gupta <debug@rivosinc.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: Fri, 13 Sep 2024 21:25:57 +0200	[thread overview]
Message-ID: <CAFTtA3ONu7CUNHwQf47ePMh9uvAi-uCV8B0YJAuFX+s0thC41Q@mail.gmail.com> (raw)
In-Reply-To: <20240912231650.3740732-24-debug@rivosinc.com>

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.

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.

>         /* 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-13 19:26 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 [this message]
2024-09-16 22:03     ` Deepak Gupta
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=CAFTtA3ONu7CUNHwQf47ePMh9uvAi-uCV8B0YJAuFX+s0thC41Q@mail.gmail.com \
    --to=andybnac@gmail.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=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=debug@rivosinc.com \
    --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