From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Xen-devel <xen-devel@lists.xen.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Subject: [PATCH v6.5 05/26] x86/entry: Remove support for partial cpu_user_regs frames
Date: Thu, 4 Jan 2018 00:15:34 +0000 [thread overview]
Message-ID: <1515024955-13390-6-git-send-email-andrew.cooper3@citrix.com> (raw)
In-Reply-To: <1515024955-13390-1-git-send-email-andrew.cooper3@citrix.com>
Save all GPRs on entry to Xen.
The entry_int82() path is via a DPL1 gate, only usable by 32bit PV guests, so
can get away with only saving the 32bit registers. All other entrypoints can
be reached from 32 or 64bit contexts.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
---
tools/tests/x86_emulator/x86-emulate.c | 1 -
xen/arch/x86/pv/domain.c | 1 -
xen/arch/x86/pv/emul-priv-op.c | 2 -
xen/arch/x86/x86_64/compat/entry.S | 7 ++-
xen/arch/x86/x86_64/entry.S | 12 ++--
xen/arch/x86/x86_64/traps.c | 13 ++--
xen/arch/x86/x86_emulate.c | 1 -
xen/arch/x86/x86_emulate/x86_emulate.c | 8 +--
xen/common/wait.c | 1 -
xen/include/asm-x86/asm_defns.h | 105 +++------------------------------
10 files changed, 26 insertions(+), 125 deletions(-)
diff --git a/tools/tests/x86_emulator/x86-emulate.c b/tools/tests/x86_emulator/x86-emulate.c
index 975ddc7..9056610 100644
--- a/tools/tests/x86_emulator/x86-emulate.c
+++ b/tools/tests/x86_emulator/x86-emulate.c
@@ -3,7 +3,6 @@
#include <sys/mman.h>
#define cpu_has_amd_erratum(nr) 0
-#define mark_regs_dirty(r) ((void)(r))
#define cpu_has_mpx false
#define read_bndcfgu() 0
#define xstate_set_init(what)
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 2234128..74e9e66 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -20,7 +20,6 @@
static void noreturn continue_nonidle_domain(struct vcpu *v)
{
check_wakeup_from_wait();
- mark_regs_dirty(guest_cpu_user_regs());
reset_stack_and_jump(ret_from_intr);
}
diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c
index 6115840..1041a4c 100644
--- a/xen/arch/x86/pv/emul-priv-op.c
+++ b/xen/arch/x86/pv/emul-priv-op.c
@@ -337,7 +337,6 @@ static int read_io(unsigned int port, unsigned int bytes,
io_emul_stub_t *io_emul =
io_emul_stub_setup(poc, ctxt->opcode, port, bytes);
- mark_regs_dirty(ctxt->regs);
io_emul(ctxt->regs);
return X86EMUL_DONE;
}
@@ -436,7 +435,6 @@ static int write_io(unsigned int port, unsigned int bytes,
io_emul_stub_t *io_emul =
io_emul_stub_setup(poc, ctxt->opcode, port, bytes);
- mark_regs_dirty(ctxt->regs);
io_emul(ctxt->regs);
if ( (bytes == 1) && pv_post_outb_hook )
pv_post_outb_hook(port, val);
diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S
index ba6e941..3fea54e 100644
--- a/xen/arch/x86/x86_64/compat/entry.S
+++ b/xen/arch/x86/x86_64/compat/entry.S
@@ -16,7 +16,8 @@
ENTRY(entry_int82)
ASM_CLAC
pushq $0
- SAVE_VOLATILE type=HYPERCALL_VECTOR compat=1
+ movl $HYPERCALL_VECTOR, 4(%rsp)
+ SAVE_ALL compat=1 /* DPL1 gate, restricted to 32bit PV guests only. */
CR4_PV32_RESTORE
GET_CURRENT(bx)
@@ -60,7 +61,6 @@ compat_test_guest_events:
/* %rbx: struct vcpu */
compat_process_softirqs:
sti
- andl $~TRAP_regs_partial,UREGS_entry_vector(%rsp)
call do_softirq
jmp compat_test_all_events
@@ -197,7 +197,8 @@ ENTRY(cstar_enter)
pushq $FLAT_USER_CS32
pushq %rcx
pushq $0
- SAVE_VOLATILE TRAP_syscall
+ movl $TRAP_syscall, 4(%rsp)
+ SAVE_ALL
GET_CURRENT(bx)
movq VCPU_domain(%rbx),%rcx
cmpb $0,DOMAIN_is_32bit_pv(%rcx)
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index 6066ed8..1dd9ccf 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -98,7 +98,8 @@ ENTRY(lstar_enter)
pushq $FLAT_KERNEL_CS64
pushq %rcx
pushq $0
- SAVE_VOLATILE TRAP_syscall
+ movl $TRAP_syscall, 4(%rsp)
+ SAVE_ALL
GET_CURRENT(bx)
testb $TF_kernel_mode,VCPU_thread_flags(%rbx)
jz switch_to_kernel
@@ -140,7 +141,6 @@ test_guest_events:
/* %rbx: struct vcpu */
process_softirqs:
sti
- SAVE_PRESERVED
call do_softirq
jmp test_all_events
@@ -190,7 +190,8 @@ GLOBAL(sysenter_eflags_saved)
pushq $3 /* ring 3 null cs */
pushq $0 /* null rip */
pushq $0
- SAVE_VOLATILE TRAP_syscall
+ movl $TRAP_syscall, 4(%rsp)
+ SAVE_ALL
GET_CURRENT(bx)
cmpb $0,VCPU_sysenter_disables_events(%rbx)
movq VCPU_sysenter_addr(%rbx),%rax
@@ -207,7 +208,6 @@ UNLIKELY_END(sysenter_nt_set)
leal (,%rcx,TBF_INTERRUPT),%ecx
UNLIKELY_START(z, sysenter_gpf)
movq VCPU_trap_ctxt(%rbx),%rsi
- SAVE_PRESERVED
movl $TRAP_gp_fault,UREGS_entry_vector(%rsp)
movl %eax,TRAPBOUNCE_error_code(%rdx)
movq TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_eip(%rsi),%rax
@@ -225,7 +225,8 @@ UNLIKELY_END(sysenter_gpf)
ENTRY(int80_direct_trap)
ASM_CLAC
pushq $0
- SAVE_VOLATILE 0x80
+ movl $0x80, 4(%rsp)
+ SAVE_ALL
cmpb $0,untrusted_msi(%rip)
UNLIKELY_START(ne, msi_check)
@@ -253,7 +254,6 @@ int80_slow_path:
* IDT entry with DPL==0.
*/
movl $((0x80 << 3) | X86_XEC_IDT),UREGS_error_code(%rsp)
- SAVE_PRESERVED
movl $TRAP_gp_fault,UREGS_entry_vector(%rsp)
/* A GPF wouldn't have incremented the instruction pointer. */
subq $2,UREGS_rip(%rsp)
diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c
index 2a326be..3652f5f 100644
--- a/xen/arch/x86/x86_64/traps.c
+++ b/xen/arch/x86/x86_64/traps.c
@@ -80,15 +80,10 @@ static void _show_registers(
regs->rbp, regs->rsp, regs->r8);
printk("r9: %016lx r10: %016lx r11: %016lx\n",
regs->r9, regs->r10, regs->r11);
- if ( !(regs->entry_vector & TRAP_regs_partial) )
- {
- printk("r12: %016lx r13: %016lx r14: %016lx\n",
- regs->r12, regs->r13, regs->r14);
- printk("r15: %016lx cr0: %016lx cr4: %016lx\n",
- regs->r15, crs[0], crs[4]);
- }
- else
- printk("cr0: %016lx cr4: %016lx\n", crs[0], crs[4]);
+ printk("r12: %016lx r13: %016lx r14: %016lx\n",
+ regs->r12, regs->r13, regs->r14);
+ printk("r15: %016lx cr0: %016lx cr4: %016lx\n",
+ regs->r15, crs[0], crs[4]);
printk("cr3: %016lx cr2: %016lx\n", crs[3], crs[2]);
printk("fsb: %016lx gsb: %016lx gss: %016lx\n",
crs[5], crs[6], crs[7]);
diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c
index cc334ca..c7ba221 100644
--- a/xen/arch/x86/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate.c
@@ -11,7 +11,6 @@
#include <xen/domain_page.h>
#include <asm/x86_emulate.h>
-#include <asm/asm_defns.h> /* mark_regs_dirty() */
#include <asm/processor.h> /* current_cpu_info */
#include <asm/xstate.h>
#include <asm/amd.h> /* cpu_has_amd_erratum() */
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
index 54a2756..820495f 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -1956,10 +1956,10 @@ decode_register(
case 9: p = ®s->r9; break;
case 10: p = ®s->r10; break;
case 11: p = ®s->r11; break;
- case 12: mark_regs_dirty(regs); p = ®s->r12; break;
- case 13: mark_regs_dirty(regs); p = ®s->r13; break;
- case 14: mark_regs_dirty(regs); p = ®s->r14; break;
- case 15: mark_regs_dirty(regs); p = ®s->r15; break;
+ case 12: p = ®s->r12; break;
+ case 13: p = ®s->r13; break;
+ case 14: p = ®s->r14; break;
+ case 15: p = ®s->r15; break;
#endif
default: BUG(); p = NULL; break;
}
diff --git a/xen/common/wait.c b/xen/common/wait.c
index 9490a17..c5fc094 100644
--- a/xen/common/wait.c
+++ b/xen/common/wait.c
@@ -127,7 +127,6 @@ static void __prepare_to_wait(struct waitqueue_vcpu *wqv)
unsigned long dummy;
u32 entry_vector = cpu_info->guest_cpu_user_regs.entry_vector;
- cpu_info->guest_cpu_user_regs.entry_vector &= ~TRAP_regs_partial;
ASSERT(wqv->esp == 0);
/* Save current VCPU affinity; force wakeup on *this* CPU only. */
diff --git a/xen/include/asm-x86/asm_defns.h b/xen/include/asm-x86/asm_defns.h
index 388fc93..98192eb 100644
--- a/xen/include/asm-x86/asm_defns.h
+++ b/xen/include/asm-x86/asm_defns.h
@@ -17,15 +17,6 @@
void ret_from_intr(void);
#endif
-#ifdef CONFIG_FRAME_POINTER
-/* Indicate special exception stack frame by inverting the frame pointer. */
-#define SETUP_EXCEPTION_FRAME_POINTER(offs) \
- leaq offs(%rsp),%rbp; \
- notq %rbp
-#else
-#define SETUP_EXCEPTION_FRAME_POINTER(offs)
-#endif
-
#ifndef NDEBUG
#define ASSERT_INTERRUPT_STATUS(x, msg) \
pushf; \
@@ -42,31 +33,6 @@ void ret_from_intr(void);
#define ASSERT_INTERRUPTS_DISABLED \
ASSERT_INTERRUPT_STATUS(z, "INTERRUPTS DISABLED")
-/*
- * This flag is set in an exception frame when registers R12-R15 did not get
- * saved.
- */
-#define _TRAP_regs_partial 16
-#define TRAP_regs_partial (1 << _TRAP_regs_partial)
-/*
- * This flag gets set in an exception frame when registers R12-R15 possibly
- * get modified from their originally saved values and hence need to be
- * restored even if the normal call flow would restore register values.
- *
- * The flag being set implies _TRAP_regs_partial to be unset. Restoring
- * R12-R15 thus is
- * - required when this flag is set,
- * - safe when _TRAP_regs_partial is unset.
- */
-#define _TRAP_regs_dirty 17
-#define TRAP_regs_dirty (1 << _TRAP_regs_dirty)
-
-#define mark_regs_dirty(r) ({ \
- struct cpu_user_regs *r__ = (r); \
- ASSERT(!((r__)->entry_vector & TRAP_regs_partial)); \
- r__->entry_vector |= TRAP_regs_dirty; \
-})
-
#ifdef __ASSEMBLY__
# define _ASM_EX(p) p-.
#else
@@ -236,7 +202,7 @@ static always_inline void stac(void)
#endif
#ifdef __ASSEMBLY__
-.macro SAVE_ALL op
+.macro SAVE_ALL op, compat=0
.ifeqs "\op", "CLAC"
ASM_CLAC
.else
@@ -255,40 +221,6 @@ static always_inline void stac(void)
movq %rdx,UREGS_rdx(%rsp)
movq %rcx,UREGS_rcx(%rsp)
movq %rax,UREGS_rax(%rsp)
- movq %r8,UREGS_r8(%rsp)
- movq %r9,UREGS_r9(%rsp)
- movq %r10,UREGS_r10(%rsp)
- movq %r11,UREGS_r11(%rsp)
- movq %rbx,UREGS_rbx(%rsp)
- movq %rbp,UREGS_rbp(%rsp)
- SETUP_EXCEPTION_FRAME_POINTER(UREGS_rbp)
- movq %r12,UREGS_r12(%rsp)
- movq %r13,UREGS_r13(%rsp)
- movq %r14,UREGS_r14(%rsp)
- movq %r15,UREGS_r15(%rsp)
-.endm
-
-/*
- * Save all registers not preserved by C code or used in entry/exit code. Mark
- * the frame as partial.
- *
- * @type: exception type
- * @compat: R8-R15 don't need saving, and the frame nevertheless is complete
- */
-.macro SAVE_VOLATILE type compat=0
-.if \compat
- movl $\type,UREGS_entry_vector-UREGS_error_code(%rsp)
-.else
- movl $\type|TRAP_regs_partial,\
- UREGS_entry_vector-UREGS_error_code(%rsp)
-.endif
- addq $-(UREGS_error_code-UREGS_r15),%rsp
- cld
- movq %rdi,UREGS_rdi(%rsp)
- movq %rsi,UREGS_rsi(%rsp)
- movq %rdx,UREGS_rdx(%rsp)
- movq %rcx,UREGS_rcx(%rsp)
- movq %rax,UREGS_rax(%rsp)
.if !\compat
movq %r8,UREGS_r8(%rsp)
movq %r9,UREGS_r9(%rsp)
@@ -297,20 +229,17 @@ static always_inline void stac(void)
.endif
movq %rbx,UREGS_rbx(%rsp)
movq %rbp,UREGS_rbp(%rsp)
- SETUP_EXCEPTION_FRAME_POINTER(UREGS_rbp)
-.endm
-
-/*
- * Complete a frame potentially only partially saved.
- */
-.macro SAVE_PRESERVED
- btrl $_TRAP_regs_partial,UREGS_entry_vector(%rsp)
- jnc 987f
+#ifdef CONFIG_FRAME_POINTER
+/* Indicate special exception stack frame by inverting the frame pointer. */
+ leaq UREGS_rbp(%rsp), %rbp
+ notq %rbp
+#endif
+.if !\compat
movq %r12,UREGS_r12(%rsp)
movq %r13,UREGS_r13(%rsp)
movq %r14,UREGS_r14(%rsp)
movq %r15,UREGS_r15(%rsp)
-987:
+.endif
.endm
#define LOAD_ONE_REG(reg, compat) \
@@ -330,7 +259,6 @@ static always_inline void stac(void)
*/
.macro RESTORE_ALL adj=0 compat=0
.if !\compat
- testl $TRAP_regs_dirty,UREGS_entry_vector(%rsp)
movq UREGS_r11(%rsp),%r11
movq UREGS_r10(%rsp),%r10
movq UREGS_r9(%rsp),%r9
@@ -347,33 +275,16 @@ static always_inline void stac(void)
LOAD_ONE_REG(si, \compat)
LOAD_ONE_REG(di, \compat)
.if !\compat
- jz 987f
movq UREGS_r15(%rsp),%r15
movq UREGS_r14(%rsp),%r14
movq UREGS_r13(%rsp),%r13
movq UREGS_r12(%rsp),%r12
-#ifndef NDEBUG
- .subsection 1
-987: testl $TRAP_regs_partial,UREGS_entry_vector(%rsp)
- jnz 987f
- cmpq UREGS_r15(%rsp),%r15
- jne 789f
- cmpq UREGS_r14(%rsp),%r14
- jne 789f
- cmpq UREGS_r13(%rsp),%r13
- jne 789f
- cmpq UREGS_r12(%rsp),%r12
- je 987f
-789: BUG /* Corruption of partial register state. */
- .subsection 0
-#endif
.else
xor %r15, %r15
xor %r14, %r14
xor %r13, %r13
xor %r12, %r12
.endif
-987:
LOAD_ONE_REG(bp, \compat)
LOAD_ONE_REG(bx, \compat)
subq $-(UREGS_error_code-UREGS_r15+\adj), %rsp
--
2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2018-01-04 0:15 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-04 0:15 [PATCH v6.5 00/26] x86: Mitigations for SP2/CVE-2017-5715/Branch Target Injection Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 01/26] x86/alt: Break out alternative-asm into a separate header file Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 02/26] x86/alt: Introduce ALTERNATIVE{, _2} macros Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 03/26] x86/hvm: Rename update_guest_vendor() callback to cpuid_policy_changed() Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 04/26] x86: Introduce a common cpuid_policy_updated() Andrew Cooper
2018-01-04 0:15 ` Andrew Cooper [this message]
2018-01-04 8:51 ` [PATCH v6.5 05/26] x86/entry: Remove support for partial cpu_user_regs frames Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 06/26] x86/entry: Rearrange RESTORE_ALL to restore register in stack order Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 07/26] x86/hvm: Use SAVE_ALL to construct the cpu_user_regs frame after VMExit Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 08/26] x86/entry: Erase guest GPR state on entry to Xen Andrew Cooper
2018-01-22 10:04 ` David Woodhouse
2018-01-22 10:18 ` Andrew Cooper
2018-01-22 10:27 ` David Woodhouse
2018-01-04 0:15 ` [PATCH v6.5 09/26] x86: Support compiling with indirect branch thunks Andrew Cooper
2018-01-04 9:02 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 10/26] common/wait: Clarifications to wait infrastructure Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 11/26] x86: Support indirect thunks from assembly code Andrew Cooper
2018-01-04 9:23 ` Jan Beulich
2018-01-08 18:24 ` Andrew Cooper
2018-01-09 8:36 ` Jan Beulich
2018-01-09 11:23 ` Andrew Cooper
2018-01-09 13:18 ` Jan Beulich
2018-01-11 13:03 ` David Woodhouse
2018-01-11 13:41 ` Andrew Cooper
2018-01-11 13:46 ` David Woodhouse
2018-01-04 0:15 ` [PATCH v6.5 12/26] x86/boot: Report details of speculative mitigations Andrew Cooper
2018-01-04 9:29 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 13/26] x86/amd: Try to set lfence as being Dispatch Serialising Andrew Cooper
2018-01-04 9:32 ` Jan Beulich
2018-01-08 19:01 ` Andrew Cooper
2018-01-09 8:38 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 14/26] x86: Introduce alternative indirect thunks Andrew Cooper
2018-01-04 9:40 ` Jan Beulich
2018-01-09 11:44 ` Andrew Cooper
2018-01-09 13:24 ` Jan Beulich
2018-01-09 13:30 ` Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 15/26] x86/feature: Definitions for Indirect Branch Controls Andrew Cooper
2018-01-04 1:14 ` Doug Goldstein
2018-01-04 1:16 ` Andrew Cooper
2018-01-04 4:05 ` Anthony Liguori
2018-01-04 9:42 ` Jan Beulich
2018-01-04 18:51 ` Wei Liu
2018-01-04 0:15 ` [PATCH v6.5 16/26] x86/cmdline: Introduce a command line option to disable IBRS/IBPB, STIBP and IBPB Andrew Cooper
2018-01-04 9:43 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 17/26] x86/msr: Emulation of MSR_{SPEC_CTRL, PRED_CMD} for guests Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 18/26] x86/migrate: Move MSR_SPEC_CTRL on migrate Andrew Cooper
2018-01-04 0:15 ` [PATCH v6.5 19/26] x86/hvm: Permit guests direct access to MSR_{SPEC_CTRL, PRED_CMD} Andrew Cooper
2018-01-04 9:52 ` Jan Beulich
2018-01-09 12:03 ` Andrew Cooper
2018-01-09 13:28 ` Jan Beulich
2018-01-09 13:34 ` Andrew Cooper
2018-01-09 13:58 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 20/26] x86: Protect unaware domains from meddling hyperthreads Andrew Cooper
2018-01-04 9:59 ` Jan Beulich
2018-01-09 14:21 ` Andrew Cooper
2018-01-09 14:29 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 21/26] x86/entry: Use MSR_SPEC_CTRL at each entry/exit point Andrew Cooper
2018-01-04 10:14 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 22/26] x86/boot: Calculate the most appropriate BTI mitigation to use Andrew Cooper
2018-01-04 10:17 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 23/26] x86/entry: Clobber the Return Stack Buffer on entry to Xen Andrew Cooper
2018-01-04 10:22 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 24/26] x86/ctxt: Issue a speculation barrier between vcpu contexts Andrew Cooper
2018-01-04 10:25 ` Jan Beulich
2018-01-04 0:15 ` [PATCH v6.5 25/26] x86/cpuid: Offer Indirect Branch Controls to guests Andrew Cooper
2018-01-09 11:44 ` Wei Liu
2018-01-04 0:15 ` [PATCH v6.5 26/26] x86/idle: Clear SPEC_CTRL while idle Andrew Cooper
2018-01-04 10:29 ` Jan Beulich
2018-01-04 10:41 ` Jan Beulich
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=1515024955-13390-6-git-send-email-andrew.cooper3@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=xen-devel@lists.xen.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).