From: Dave Martin <Dave.Martin@arm.com> To: linux-arm-kernel@lists.infradead.org Cc: linux-arch@vger.kernel.org, Okamoto Takayuki <tokamoto@jp.fujitsu.com>, libc-alpha@sourceware.org, Ard Biesheuvel <ard.biesheuvel@linaro.org>, Szabolcs Nagy <szabolcs.nagy@arm.com>, Catalin Marinas <catalin.marinas@arm.com>, Will Deacon <will.deacon@arm.com>, kvmarm@lists.cs.columbia.edu Subject: [RFC PATCH v5 29/30] arm64: signal: Report signal frame size to userspace via auxv Date: Tue, 31 Oct 2017 15:51:21 +0000 [thread overview] Message-ID: <1509465082-30427-30-git-send-email-Dave.Martin@arm.com> (raw) In-Reply-To: <1509465082-30427-1-git-send-email-Dave.Martin@arm.com> Stateful CPU architecture extensions may require the signal frame to grow to a size that exceeds the arch's MINSIGSTKSZ #define. However, changing this #define is an ABI break. To allow userspace the option of determining the signal frame size in a more forwards-compatible way, this patch adds a new auxv entry tagged with AT_MINSIGSTKSZ, which provides the maximum signal frame size that the process can observe during its lifetime. If AT_MINSIGSTKSZ is absent from the aux vector, the caller can assume that the MINSIGSTKSZ #define is sufficient. This allows for a consistent interface with older kernels that do not provide AT_MINSIGSTKSZ. The idea is that libc could expose this via sysconf() or some similar mechanism. There is deliberately no AT_SIGSTKSZ. The kernel knows nothing about userspace's own stack overheads and should not pretend to know. For arm64: The primary motivation for this interface is the Scalable Vector Extension, which can require at least 4KB or so of extra space in the signal frame for the largest hardware implementations. To determine the correct value, a "Christmas tree" mode (via the add_all argument) is added to setup_sigframe_layout(), to simulate addition of all possible records to the signal frame at maximum possible size. If this procedure goes wrong somehow, resulting in a stupidly large frame layout and hence failure of sigframe_alloc() to allocate a record to the frame, then this is indicative of a kernel bug: the kernel's internal SIGFRAME_MAXSZ is supposed to sanity-check against generting frames that we consider _impossibly_ large. In this case, SIGSTKSZ is returned as a "reasonable guess that is at least bigger than MINSIGSTKSZ" and we WARN(). Signed-off-by: Dave Martin <Dave.Martin@arm.com> --- arch/arm64/include/asm/elf.h | 5 +++++ arch/arm64/include/asm/processor.h | 3 +++ arch/arm64/include/uapi/asm/auxvec.h | 3 ++- arch/arm64/kernel/signal.c | 39 +++++++++++++++++++++++++++++++----- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index fac1c4d..771c7a8 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -24,6 +24,10 @@ #include <asm/ptrace.h> #include <asm/user.h> +#ifndef __ASSEMBLY__ +#include <asm/processor.h> /* for get_minsigstksz(), used by ARCH_DLINFO */ +#endif + /* * AArch64 static relocation types. */ @@ -148,6 +152,7 @@ typedef struct user_fpsimd_state elf_fpregset_t; do { \ NEW_AUX_ENT(AT_SYSINFO_EHDR, \ (elf_addr_t)current->mm->context.vdso); \ + NEW_AUX_ENT(AT_MINSIGSTKSZ, get_minsigstksz()); \ } while (0) #define ARCH_HAS_SETUP_ADDITIONAL_PAGES diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 023cacb..055b06d 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -217,6 +217,9 @@ static inline void spin_lock_prefetch(const void *ptr) int cpu_enable_pan(void *__unused); int cpu_enable_cache_maint_trap(void *__unused); +/* User signal frame size discovery: */ +int get_minsigstksz(void); + /* Userspace interface for PR_SVE_{SET,GET}_VL prctl()s: */ #define SVE_SET_VL(arg) sve_set_current_vl(arg) #define SVE_GET_VL() sve_get_current_vl() diff --git a/arch/arm64/include/uapi/asm/auxvec.h b/arch/arm64/include/uapi/asm/auxvec.h index 4cf0c17..1d45b28 100644 --- a/arch/arm64/include/uapi/asm/auxvec.h +++ b/arch/arm64/include/uapi/asm/auxvec.h @@ -18,7 +18,8 @@ /* vDSO location */ #define AT_SYSINFO_EHDR 33 +#define AT_MINSIGSTKSZ 34 /* stack needed for signal delivery */ -#define AT_VECTOR_SIZE_ARCH 1 /* entries in ARCH_DLINFO */ +#define AT_VECTOR_SIZE_ARCH 2 /* entries in ARCH_DLINFO */ #endif diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 64abf88..7c7d9ae 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -571,8 +571,15 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) return 0; } -/* Determine the layout of optional records in the signal frame */ -static int setup_sigframe_layout(struct rt_sigframe_user_layout *user) +/* + * Determine the layout of optional records in the signal frame + * + * add_all: if true, lays out the biggest possible signal frame for + * this task; otherwise, generates a layout for the current state + * of the task. + */ +static int setup_sigframe_layout(struct rt_sigframe_user_layout *user, + bool add_all) { int err; @@ -582,7 +589,7 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user) return err; /* fault information, if valid */ - if (current->thread.fault_code) { + if (add_all || current->thread.fault_code) { err = sigframe_alloc(user, &user->esr_offset, sizeof(struct esr_context)); if (err) @@ -604,7 +611,6 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user) return sigframe_alloc_end(user); } - static int setup_sigframe(struct rt_sigframe_user_layout *user, struct pt_regs *regs, sigset_t *set) { @@ -702,7 +708,7 @@ static int get_sigframe(struct rt_sigframe_user_layout *user, int err; init_user_layout(user); - err = setup_sigframe_layout(user); + err = setup_sigframe_layout(user, false); if (err) return err; @@ -934,3 +940,26 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, thread_flags = READ_ONCE(current_thread_info()->flags); } while (thread_flags & _TIF_WORK_MASK); } + +/* + * Determine the stack space required for guaranteed signal devliery. + * This function is used to populate AT_MINSIGSTKSZ at process startup. + */ +int get_minsigstksz(void) +{ + struct rt_sigframe_user_layout user; + int err; + + init_user_layout(&user); + err = setup_sigframe_layout(&user, true); + + if (err) { + WARN_ON(1); + + return SIGSTKSZ; + } else { + return sigframe_size(&user) + + round_up(sizeof(struct frame_record), 16) + + 16; /* max alignment padding */ + } +} -- 2.1.4
WARNING: multiple messages have this Message-ID (diff)
From: Dave Martin <Dave.Martin@arm.com> To: linux-arm-kernel@lists.infradead.org Cc: "Catalin Marinas" <catalin.marinas@arm.com>, "Will Deacon" <will.deacon@arm.com>, "Ard Biesheuvel" <ard.biesheuvel@linaro.org>, "Alex Bennée" <alex.bennee@linaro.org>, "Szabolcs Nagy" <szabolcs.nagy@arm.com>, "Okamoto Takayuki" <tokamoto@jp.fujitsu.com>, kvmarm@lists.cs.columbia.edu, libc-alpha@sourceware.org, linux-arch@vger.kernel.org Subject: [RFC PATCH v5 29/30] arm64: signal: Report signal frame size to userspace via auxv Date: Tue, 31 Oct 2017 15:51:21 +0000 [thread overview] Message-ID: <1509465082-30427-30-git-send-email-Dave.Martin@arm.com> (raw) Message-ID: <20171031155121.owbNtslcfTzF5toPp-eeo1YrZqo8UvWjIIS1TRaA31Q@z> (raw) In-Reply-To: <1509465082-30427-1-git-send-email-Dave.Martin@arm.com> Stateful CPU architecture extensions may require the signal frame to grow to a size that exceeds the arch's MINSIGSTKSZ #define. However, changing this #define is an ABI break. To allow userspace the option of determining the signal frame size in a more forwards-compatible way, this patch adds a new auxv entry tagged with AT_MINSIGSTKSZ, which provides the maximum signal frame size that the process can observe during its lifetime. If AT_MINSIGSTKSZ is absent from the aux vector, the caller can assume that the MINSIGSTKSZ #define is sufficient. This allows for a consistent interface with older kernels that do not provide AT_MINSIGSTKSZ. The idea is that libc could expose this via sysconf() or some similar mechanism. There is deliberately no AT_SIGSTKSZ. The kernel knows nothing about userspace's own stack overheads and should not pretend to know. For arm64: The primary motivation for this interface is the Scalable Vector Extension, which can require at least 4KB or so of extra space in the signal frame for the largest hardware implementations. To determine the correct value, a "Christmas tree" mode (via the add_all argument) is added to setup_sigframe_layout(), to simulate addition of all possible records to the signal frame at maximum possible size. If this procedure goes wrong somehow, resulting in a stupidly large frame layout and hence failure of sigframe_alloc() to allocate a record to the frame, then this is indicative of a kernel bug: the kernel's internal SIGFRAME_MAXSZ is supposed to sanity-check against generting frames that we consider _impossibly_ large. In this case, SIGSTKSZ is returned as a "reasonable guess that is at least bigger than MINSIGSTKSZ" and we WARN(). Signed-off-by: Dave Martin <Dave.Martin@arm.com> --- arch/arm64/include/asm/elf.h | 5 +++++ arch/arm64/include/asm/processor.h | 3 +++ arch/arm64/include/uapi/asm/auxvec.h | 3 ++- arch/arm64/kernel/signal.c | 39 +++++++++++++++++++++++++++++++----- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index fac1c4d..771c7a8 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -24,6 +24,10 @@ #include <asm/ptrace.h> #include <asm/user.h> +#ifndef __ASSEMBLY__ +#include <asm/processor.h> /* for get_minsigstksz(), used by ARCH_DLINFO */ +#endif + /* * AArch64 static relocation types. */ @@ -148,6 +152,7 @@ typedef struct user_fpsimd_state elf_fpregset_t; do { \ NEW_AUX_ENT(AT_SYSINFO_EHDR, \ (elf_addr_t)current->mm->context.vdso); \ + NEW_AUX_ENT(AT_MINSIGSTKSZ, get_minsigstksz()); \ } while (0) #define ARCH_HAS_SETUP_ADDITIONAL_PAGES diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 023cacb..055b06d 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -217,6 +217,9 @@ static inline void spin_lock_prefetch(const void *ptr) int cpu_enable_pan(void *__unused); int cpu_enable_cache_maint_trap(void *__unused); +/* User signal frame size discovery: */ +int get_minsigstksz(void); + /* Userspace interface for PR_SVE_{SET,GET}_VL prctl()s: */ #define SVE_SET_VL(arg) sve_set_current_vl(arg) #define SVE_GET_VL() sve_get_current_vl() diff --git a/arch/arm64/include/uapi/asm/auxvec.h b/arch/arm64/include/uapi/asm/auxvec.h index 4cf0c17..1d45b28 100644 --- a/arch/arm64/include/uapi/asm/auxvec.h +++ b/arch/arm64/include/uapi/asm/auxvec.h @@ -18,7 +18,8 @@ /* vDSO location */ #define AT_SYSINFO_EHDR 33 +#define AT_MINSIGSTKSZ 34 /* stack needed for signal delivery */ -#define AT_VECTOR_SIZE_ARCH 1 /* entries in ARCH_DLINFO */ +#define AT_VECTOR_SIZE_ARCH 2 /* entries in ARCH_DLINFO */ #endif diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 64abf88..7c7d9ae 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -571,8 +571,15 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) return 0; } -/* Determine the layout of optional records in the signal frame */ -static int setup_sigframe_layout(struct rt_sigframe_user_layout *user) +/* + * Determine the layout of optional records in the signal frame + * + * add_all: if true, lays out the biggest possible signal frame for + * this task; otherwise, generates a layout for the current state + * of the task. + */ +static int setup_sigframe_layout(struct rt_sigframe_user_layout *user, + bool add_all) { int err; @@ -582,7 +589,7 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user) return err; /* fault information, if valid */ - if (current->thread.fault_code) { + if (add_all || current->thread.fault_code) { err = sigframe_alloc(user, &user->esr_offset, sizeof(struct esr_context)); if (err) @@ -604,7 +611,6 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user) return sigframe_alloc_end(user); } - static int setup_sigframe(struct rt_sigframe_user_layout *user, struct pt_regs *regs, sigset_t *set) { @@ -702,7 +708,7 @@ static int get_sigframe(struct rt_sigframe_user_layout *user, int err; init_user_layout(user); - err = setup_sigframe_layout(user); + err = setup_sigframe_layout(user, false); if (err) return err; @@ -934,3 +940,26 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, thread_flags = READ_ONCE(current_thread_info()->flags); } while (thread_flags & _TIF_WORK_MASK); } + +/* + * Determine the stack space required for guaranteed signal devliery. + * This function is used to populate AT_MINSIGSTKSZ at process startup. + */ +int get_minsigstksz(void) +{ + struct rt_sigframe_user_layout user; + int err; + + init_user_layout(&user); + err = setup_sigframe_layout(&user, true); + + if (err) { + WARN_ON(1); + + return SIGSTKSZ; + } else { + return sigframe_size(&user) + + round_up(sizeof(struct frame_record), 16) + + 16; /* max alignment padding */ + } +} -- 2.1.4
next prev parent reply other threads:[~2017-10-31 15:51 UTC|newest] Thread overview: 106+ messages / expand[flat|nested] mbox.gz Atom feed top 2017-10-31 15:50 [PATCH v5 00/30] ARM Scalable Vector Extension (SVE) Dave Martin 2017-10-31 15:50 ` Dave Martin 2017-10-31 15:50 ` [PATCH v5 01/30] regset: Add support for dynamically sized regsets Dave Martin 2017-11-01 11:42 ` Catalin Marinas 2017-11-01 13:16 ` Dave Martin 2017-11-01 13:16 ` Dave Martin 2017-11-08 11:50 ` Alex Bennée 2017-11-08 11:50 ` Alex Bennée 2017-10-31 15:50 ` [PATCH v5 02/30] arm64: fpsimd: Correctly annotate exception helpers called from asm Dave Martin 2017-10-31 15:50 ` Dave Martin 2017-11-01 11:42 ` Catalin Marinas 2017-10-31 15:50 ` [PATCH v5 03/30] arm64: signal: Verify extra data is user-readable in sys_rt_sigreturn Dave Martin 2017-10-31 15:50 ` Dave Martin 2017-11-01 11:43 ` Catalin Marinas 2017-10-31 15:50 ` [PATCH v5 04/30] arm64: KVM: Hide unsupported AArch64 CPU features from guests Dave Martin 2017-11-01 4:47 ` Christoffer Dall 2017-11-01 10:26 ` Dave Martin 2017-11-02 8:15 ` Christoffer Dall 2017-11-02 9:20 ` Dave Martin 2017-11-02 11:01 ` Dave Martin 2017-11-02 19:18 ` Christoffer Dall 2017-10-31 15:50 ` [PATCH v5 05/30] arm64: efi: Add missing Kconfig dependency on KERNEL_MODE_NEON Dave Martin 2017-10-31 15:50 ` Dave Martin 2017-10-31 15:50 ` [PATCH v5 06/30] arm64: Port deprecated instruction emulation to new sysctl interface Dave Martin 2017-10-31 15:50 ` [PATCH v5 07/30] arm64: fpsimd: Simplify uses of {set,clear}_ti_thread_flag() Dave Martin 2017-10-31 15:51 ` [PATCH v5 08/30] arm64/sve: System register and exception syndrome definitions Dave Martin 2017-10-31 15:51 ` [PATCH v5 09/30] arm64/sve: Low-level SVE architectural state manipulation functions Dave Martin 2017-10-31 15:51 ` [PATCH v5 10/30] arm64/sve: Kconfig update and conditional compilation support Dave Martin 2017-10-31 15:51 ` [PATCH v5 11/30] arm64/sve: Signal frame and context structure definition Dave Martin 2017-11-08 16:34 ` Alex Bennée 2017-11-08 16:34 ` Alex Bennée 2017-10-31 15:51 ` [PATCH v5 12/30] arm64/sve: Low-level CPU setup Dave Martin 2017-11-08 16:37 ` Alex Bennée 2017-11-08 16:37 ` Alex Bennée 2017-10-31 15:51 ` [PATCH v5 13/30] arm64/sve: Core task context handling Dave Martin 2017-10-31 15:51 ` Dave Martin 2017-11-09 17:16 ` Alex Bennée 2017-11-09 17:16 ` Alex Bennée 2017-11-09 17:56 ` Dave Martin 2017-11-09 18:06 ` Alex Bennée 2017-11-09 18:06 ` Alex Bennée 2017-10-31 15:51 ` [PATCH v5 14/30] arm64/sve: Support vector length resetting for new processes Dave Martin 2017-10-31 15:51 ` [PATCH v5 15/30] arm64/sve: Signal handling support Dave Martin 2017-10-31 15:51 ` Dave Martin 2017-11-01 14:33 ` Catalin Marinas 2017-11-07 13:22 ` Alex Bennée 2017-11-07 13:22 ` Alex Bennée 2017-11-08 16:11 ` Dave Martin 2017-12-06 19:56 ` Kees Cook 2017-12-07 10:49 ` Will Deacon 2017-12-07 12:03 ` Dave Martin 2017-12-07 18:50 ` Kees Cook 2017-12-11 14:07 ` Will Deacon 2017-12-11 19:23 ` Kees Cook 2017-12-12 10:40 ` Will Deacon 2017-12-12 11:11 ` Dave Martin 2017-12-12 19:36 ` Kees Cook 2017-12-12 19:36 ` Kees Cook 2017-10-31 15:51 ` [PATCH v5 16/30] arm64/sve: Backend logic for setting the vector length Dave Martin 2017-10-31 15:51 ` Dave Martin 2017-11-10 10:27 ` Alex Bennée 2017-11-10 10:27 ` Alex Bennée 2017-10-31 15:51 ` [PATCH v5 17/30] arm64: cpufeature: Move sys_caps_initialised declarations Dave Martin 2017-10-31 15:51 ` [PATCH v5 18/30] arm64/sve: Probe SVE capabilities and usable vector lengths Dave Martin 2017-10-31 15:51 ` Dave Martin 2017-10-31 15:51 ` [PATCH v5 19/30] arm64/sve: Preserve SVE registers around kernel-mode NEON use Dave Martin 2017-10-31 15:51 ` [PATCH v5 20/30] arm64/sve: Preserve SVE registers around EFI runtime service calls Dave Martin 2017-10-31 15:51 ` [PATCH v5 21/30] arm64/sve: ptrace and ELF coredump support Dave Martin 2017-10-31 15:51 ` [PATCH v5 22/30] arm64/sve: Add prctl controls for userspace vector length management Dave Martin 2017-10-31 15:51 ` Dave Martin 2017-10-31 15:51 ` [PATCH v5 23/30] arm64/sve: Add sysctl to set the default vector length for new processes Dave Martin 2017-10-31 15:51 ` Dave Martin 2017-10-31 15:51 ` [PATCH v5 24/30] arm64/sve: KVM: Prevent guests from using SVE Dave Martin 2017-10-31 15:51 ` Dave Martin 2017-10-31 15:51 ` [PATCH v5 25/30] arm64/sve: KVM: Treat guest SVE use as undefined instruction execution Dave Martin 2017-10-31 15:51 ` [PATCH v5 26/30] arm64/sve: KVM: Hide SVE from CPU features exposed to guests Dave Martin 2017-10-31 15:51 ` [PATCH v5 27/30] arm64/sve: Detect SVE and activate runtime support Dave Martin 2017-10-31 15:51 ` Dave Martin [not found] ` <1509465082-30427-1-git-send-email-Dave.Martin-5wv7dgnIgG8@public.gmane.org> 2017-10-31 15:51 ` [PATCH v5 28/30] arm64/sve: Add documentation Dave Martin 2017-10-31 15:51 ` Dave Martin 2017-11-02 16:32 ` [PATCH v5 00/30] ARM Scalable Vector Extension (SVE) Will Deacon 2017-11-02 16:32 ` Will Deacon [not found] ` <20171102163248.GB595-5wv7dgnIgG8@public.gmane.org> 2017-11-02 17:04 ` Dave P Martin 2017-11-02 17:04 ` Dave P Martin 2017-10-31 15:51 ` Dave Martin [this message] 2017-10-31 15:51 ` [RFC PATCH v5 29/30] arm64: signal: Report signal frame size to userspace via auxv Dave Martin 2017-10-31 15:51 ` [RFC PATCH v5 30/30] arm64/sve: signal: Include SVE when computing AT_MINSIGSTKSZ Dave Martin 2017-10-31 15:51 ` Dave Martin 2017-11-29 15:04 ` [PATCH v5 00/30] ARM Scalable Vector Extension (SVE) Alex Bennée 2017-11-29 15:04 ` Alex Bennée [not found] ` <877eu9dt3n.fsf-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> 2017-11-29 15:21 ` Will Deacon 2017-11-29 15:21 ` Will Deacon [not found] ` <20171129152140.GD10650-5wv7dgnIgG8@public.gmane.org> 2017-11-29 15:37 ` Dave Martin 2017-11-29 15:37 ` Dave Martin 2018-01-08 14:49 ` Yury Norov 2018-01-08 14:49 ` Yury Norov 2018-01-09 16:51 ` Yury Norov 2018-01-09 16:51 ` Yury Norov 2018-01-15 17:22 ` Dave Martin 2018-01-15 17:22 ` Dave Martin [not found] ` <20180115172201.GW22781-M5GwZQ6tE7x5pKCnmE3YQBJ8xKzm50AiAL8bYrjMMd8@public.gmane.org> 2018-01-16 10:11 ` Yury Norov 2018-01-16 10:11 ` Yury Norov 2018-01-16 16:05 ` Dave Martin 2018-01-16 16:05 ` Dave Martin 2018-01-15 16:55 ` Dave Martin 2018-01-15 16:55 ` Dave Martin
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=1509465082-30427-30-git-send-email-Dave.Martin@arm.com \ --to=dave.martin@arm.com \ --cc=ard.biesheuvel@linaro.org \ --cc=catalin.marinas@arm.com \ --cc=kvmarm@lists.cs.columbia.edu \ --cc=libc-alpha@sourceware.org \ --cc=linux-arch@vger.kernel.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=szabolcs.nagy@arm.com \ --cc=tokamoto@jp.fujitsu.com \ --cc=will.deacon@arm.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: linkBe 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).