From: David Woodhouse <dwmw2@infradead.org>
To: xen-devel <xen-devel@lists.xenproject.org>
Cc: "Andrew Cooper" <andrew.cooper3@citrix.com>,
"Wei Liu" <wl@xen.org>, "Jan Beulich" <jbeulich@suse.com>,
"Roger Pau Monné" <roger.pau@citrix.com>
Subject: [Xen-devel] [PATCH v2 3/6] x86/boot: Split bootsym() into four types of relocations
Date: Fri, 09 Aug 2019 16:01:55 +0100 [thread overview]
Message-ID: <b14f575d4445e439e3d4fd7d385aab7f7f2bedd5.camel@infradead.org> (raw)
In-Reply-To: <cover.1565362089.git.dwmw@amazon.co.uk>
[-- Attachment #1.1: Type: text/plain, Size: 19906 bytes --]
From: David Woodhouse <dwmw@amazon.co.uk>
As a first step toward using the low-memory trampoline only when necessary
for a legacy boot without no-real-mode, clean up the relocations into
three separate groups.
• bootsym() is now used only at boot time when no-real-mode isn't set.
• bootdatasym() is for variables containing information discovered by
the 16-bit boot code. This is currently accessed directly in place
in low memory by Xen at runtime, but will be copied back to its
location in high memory to avoid the pointer gymnastics (and because
a subsequent patch will stop copying the 16-bit boot code into low
memory at all when it isn't being used).
• trampsym() is for the permanent 16-bit trampoline used for AP startup
and for wake from sleep. This is not used at boot, and can be copied
into (properly allocated) low memory once the system is running.
• tramp32sym() is used both at boot and for AP startup/wakeup. During
boot it can be used in-place, running from the physical address of
the Xen image. For AP startup it can't, because at that point there
isn't a full 1:1 mapping of all memory; only the low trampoline page
is mapped.
No (intentional) functional change yet; just a "cleanup" to allow the
various parts to be treated separately in subsequent patches.
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
---
xen/arch/x86/boot/edd.S | 16 +++----
xen/arch/x86/boot/head.S | 22 +++++++--
xen/arch/x86/boot/mem.S | 12 ++---
xen/arch/x86/boot/trampoline.S | 85 ++++++++++++++++++++++++++--------
xen/arch/x86/boot/video.S | 6 +--
xen/arch/x86/boot/wakeup.S | 12 ++---
xen/arch/x86/efi/efi-boot.h | 8 ++--
xen/arch/x86/xen.lds.S | 15 ++++--
8 files changed, 122 insertions(+), 54 deletions(-)
diff --git a/xen/arch/x86/boot/edd.S b/xen/arch/x86/boot/edd.S
index 3df712bce1..434bbbd960 100644
--- a/xen/arch/x86/boot/edd.S
+++ b/xen/arch/x86/boot/edd.S
@@ -41,7 +41,7 @@ get_edd:
# This code is sensitive to the size of the structs in edd.h
edd_start:
/* ds:si points at fn48 results. Fn41 results go immediately before. */
- movw $bootsym(boot_edd_info)+EDDEXTSIZE, %si
+ movw $bootdatasym(boot_edd_info)+EDDEXTSIZE, %si
movb $0x80, %dl # BIOS device 0x80
edd_check_ext:
@@ -56,7 +56,7 @@ edd_check_ext:
movb %dl, %ds:-8(%si) # store device number
movb %ah, %ds:-7(%si) # store version
movw %cx, %ds:-6(%si) # store extensions
- incb bootsym(boot_edd_info_nr) # note that we stored something
+ incb bootdatasym(boot_edd_info_nr) # note that we stored something
edd_get_device_params:
movw $EDDPARMSIZE, %ds:(%si) # put size
@@ -97,7 +97,7 @@ edd_legacy_done:
edd_next:
incb %dl # increment to next device
jz edd_done
- cmpb $EDD_INFO_MAX,bootsym(boot_edd_info_nr)
+ cmpb $EDD_INFO_MAX,bootdatasym(boot_edd_info_nr)
jb edd_check_ext
edd_done:
@@ -108,11 +108,11 @@ edd_done:
.Ledd_mbr_sig_start:
pushw %es
movb $0x80, %dl # from device 80
- movw $bootsym(boot_mbr_signature), %bx # store buffer ptr in bx
+ movw $bootdatasym(boot_mbr_signature), %bx # store buffer ptr in bx
.Ledd_mbr_sig_read:
pushw %bx
- movw $bootsym(boot_edd_info), %bx
- movzbw bootsym(boot_edd_info_nr), %cx
+ movw $bootdatasym(boot_edd_info), %bx
+ movzbw bootdatasym(boot_edd_info_nr), %cx
jcxz .Ledd_mbr_sig_default
.Ledd_mbr_sig_find_info:
cmpb %dl, (%bx)
@@ -151,12 +151,12 @@ edd_done:
jne .Ledd_mbr_sig_next
movb %dl, (%bx) # store BIOS drive number
movl %ecx, 4(%bx) # store signature from MBR
- incb bootsym(boot_mbr_signature_nr) # note that we stored something
+ incb bootdatasym(boot_mbr_signature_nr) # note that we stored something
addw $8, %bx # increment sig buffer ptr
.Ledd_mbr_sig_next:
incb %dl # increment to next device
jz .Ledd_mbr_sig_done
- cmpb $EDD_MBR_SIG_MAX, bootsym(boot_mbr_signature_nr)
+ cmpb $EDD_MBR_SIG_MAX, bootdatasym(boot_mbr_signature_nr)
jb .Ledd_mbr_sig_read
.Ledd_mbr_sig_done:
popw %es
diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index e3b42e3263..07621d1a30 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -707,14 +707,30 @@ trampoline_setup:
cmp $sym_offs(__trampoline_rel_stop),%edi
jb 1b
- /* Patch in the trampoline segment. */
+ mov $sym_offs(__trampoline32_rel_start),%edi
+1:
+ mov %fs:(%edi),%eax
+ add %edx,%fs:(%edi,%eax)
+ add $4,%edi
+ cmp $sym_offs(__trampoline32_rel_stop),%edi
+ jb 1b
+
+ mov $sym_offs(__bootsym_rel_start),%edi
+1:
+ mov %fs:(%edi),%eax
+ add %edx,%fs:(%edi,%eax)
+ add $4,%edi
+ cmp $sym_offs(__bootsym_rel_stop),%edi
+ jb 1b
+
+ /* Patch in the boot trampoline segment. */
shr $4,%edx
- mov $sym_offs(__trampoline_seg_start),%edi
+ mov $sym_offs(__bootsym_seg_start),%edi
1:
mov %fs:(%edi),%eax
mov %dx,%fs:(%edi,%eax)
add $4,%edi
- cmp $sym_offs(__trampoline_seg_stop),%edi
+ cmp $sym_offs(__bootsym_seg_stop),%edi
jb 1b
/* Do not parse command line on EFI platform here. */
diff --git a/xen/arch/x86/boot/mem.S b/xen/arch/x86/boot/mem.S
index 2d61d28835..aa39608442 100644
--- a/xen/arch/x86/boot/mem.S
+++ b/xen/arch/x86/boot/mem.S
@@ -7,7 +7,7 @@ get_memory_map:
.Lmeme820:
xorl %ebx, %ebx # continuation counter
- movw $bootsym(bios_e820map), %di # point into the whitelist
+ movw $bootdatasym(bios_e820map), %di # point into the whitelist
# so we can have the bios
# directly write into it.
@@ -22,8 +22,8 @@ get_memory_map:
cmpl $SMAP,%eax # check the return is `SMAP'
jne .Lmem88
- incw bootsym(bios_e820nr)
- cmpw $E820_BIOS_MAX,bootsym(bios_e820nr) # up to this many entries
+ incw bootdatasym(bios_e820nr)
+ cmpw $E820_BIOS_MAX,bootdatasym(bios_e820nr) # up to this many entries
jae .Lmem88
movw %di,%ax
@@ -35,7 +35,7 @@ get_memory_map:
.Lmem88:
movb $0x88, %ah
int $0x15
- movw %ax,bootsym(highmem_kb)
+ movw %ax,bootdatasym(highmem_kb)
.Lmeme801:
stc # fix to work around buggy
@@ -58,11 +58,11 @@ get_memory_map:
shll $6,%edx # and go from 64k to 1k chunks
movzwl %cx, %ecx
addl %ecx, %edx # add in lower memory
- movl %edx,bootsym(highmem_kb) # store extended memory size
+ movl %edx,bootdatasym(highmem_kb) # store extended memory size
.Lint12:
int $0x12
- movw %ax,bootsym(lowmem_kb)
+ movw %ax,bootdatasym(lowmem_kb)
ret
diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S
index 429a088b19..95a4bef553 100644
--- a/xen/arch/x86/boot/trampoline.S
+++ b/xen/arch/x86/boot/trampoline.S
@@ -16,21 +16,62 @@
* not guaranteed to persist.
*/
-/* NB. bootsym() is only usable in real mode, or via BOOT_PSEUDORM_DS. */
+/*
+ * There are four sets of relocations:
+ *
+ * bootsym(): Boot-time code relocated to low memory and run only once.
+ * Only usable at boot, in real mode or via BOOT_PSEUDORM_DS.
+ * bootdatasym(): Boot-time BIOS-discovered data, relocated back up to Xen
+ * image after discovery.
+ * trampsym(): Trampoline code relocated into low memory for AP startup
+ * and wakeup.
+ * tramp32sym(): 32-bit trampoline code which at boot can be used directly
+ * from the Xen image in memory, but which will need to be
+ * relocated into low (well, into *mapped*) memory in order
+ * to be used for AP startup.
+ */
#undef bootsym
#define bootsym(s) ((s)-trampoline_start)
#define bootsym_rel(sym, off, opnd...) \
bootsym(sym),##opnd; \
111:; \
- .pushsection .trampoline_rel, "a"; \
+ .pushsection .bootsym_rel, "a"; \
.long 111b - (off) - .; \
.popsection
#define bootsym_segrel(sym, off) \
$0,$bootsym(sym); \
111:; \
- .pushsection .trampoline_seg, "a"; \
+ .pushsection .bootsym_seg, "a"; \
+ .long 111b - (off) - .; \
+ .popsection
+
+#define bootdatasym(s) ((s)-trampoline_start)
+#define bootdatasym_rel(sym, off, opnd...) \
+ bootdatasym(sym),##opnd; \
+111:; \
+ .pushsection .bootdatasym_rel, "a";\
+ .long 111b - (off) - .; \
+ .popsection
+
+#undef trampsym
+#define trampsym(s) ((s)-trampoline_start)
+
+#define trampsym_rel(sym, off, opnd...) \
+ trampsym(sym),##opnd; \
+111:; \
+ .pushsection .trampsym_rel, "a"; \
+ .long 111b - (off) - .; \
+ .popsection
+
+#undef tramp32sym
+#define tramp32sym(s) ((s)-trampoline_start)
+
+#define tramp32sym_rel(sym, off, opnd...) \
+ tramp32sym(sym),##opnd; \
+111:; \
+ .pushsection .tramp32sym_rel, "a"; \
.long 111b - (off) - .; \
.popsection
@@ -48,16 +89,19 @@
GLOBAL(trampoline_realmode_entry)
mov %cs,%ax
mov %ax,%ds
- movb $0xA5,bootsym(trampoline_cpu_started)
+ movb $0xA5,trampsym(trampoline_cpu_started)
cld
cli
- lidt bootsym(idt_48)
- lgdt bootsym(gdt_48)
+ lidt trampsym(idt_48)
+ lgdt trampsym(gdt_48)
mov $1,%bl # EBX != 0 indicates we are an AP
xor %ax, %ax
inc %ax
lmsw %ax # CR0.PE = 1 (enter protected mode)
- ljmpl $BOOT_CS32,$bootsym_rel(trampoline_protmode_entry,6)
+ ljmpl $BOOT_CS32,$tramp32sym_rel(trampoline_protmode_entry,6)
+
+GLOBAL(trampoline_cpu_started)
+ .byte 0
trampoline_gdt:
/* 0x0000: unused */
@@ -79,8 +123,12 @@ trampoline_gdt:
* address is computed at runtime.
*/
.quad 0x00c0920000000fff
-
- .pushsection .trampoline_rel, "a"
+ /*
+ * BOOT_PSEUDORM_CS and BOOT_PSEUDORM_DS are usable only at boot time,
+ * and their base addresses must reference the low location to which
+ * the boot-time code was loaded. Hence bootsym.
+ */
+ .pushsection .bootsym_rel, "a"
.long trampoline_gdt + BOOT_PSEUDORM_CS + 2 - .
.long trampoline_gdt + BOOT_PSEUDORM_DS + 2 - .
.popsection
@@ -94,9 +142,6 @@ GLOBAL(cpuid_ext_features)
GLOBAL(trampoline_xen_phys_start)
.long 0
-GLOBAL(trampoline_cpu_started)
- .byte 0
-
.code32
trampoline_protmode_entry:
/* Set up a few descriptors: on entry only CS is guaranteed good. */
@@ -113,12 +158,12 @@ trampoline_protmode_entry:
/* Load pagetable base register. */
mov $sym_offs(idle_pg_table),%eax
- add bootsym_rel(trampoline_xen_phys_start,4,%eax)
+ add tramp32sym_rel(trampoline_xen_phys_start,4,%eax)
mov %eax,%cr3
/* Adjust IA32_MISC_ENABLE if needed (for NX enabling below). */
- mov bootsym_rel(trampoline_misc_enable_off,4,%esi)
- mov bootsym_rel(trampoline_misc_enable_off+4,4,%edi)
+ mov tramp32sym_rel(trampoline_misc_enable_off,4,%esi)
+ mov tramp32sym_rel(trampoline_misc_enable_off+4,4,%edi)
mov %esi,%eax
or %edi,%eax
jz 1f
@@ -132,7 +177,7 @@ trampoline_protmode_entry:
1:
/* Set up EFER (Extended Feature Enable Register). */
- mov bootsym_rel(cpuid_ext_features,4,%edi)
+ mov tramp32sym_rel(cpuid_ext_features,4,%edi)
movl $MSR_EFER,%ecx
rdmsr
or $EFER_LME|EFER_SCE,%eax /* Long Mode + SYSCALL/SYSRET */
@@ -148,7 +193,7 @@ trampoline_protmode_entry:
1:
/* Now in compatibility mode. Long-jump into 64-bit mode. */
- ljmp $BOOT_CS64,$bootsym_rel(start64,6)
+ ljmp $BOOT_CS64,$tramp32sym_rel(start64,6)
.code64
start64:
@@ -183,7 +228,7 @@ start64:
idt_48: .word 0, 0, 0 # base = limit = 0
.word 0
gdt_48: .word 6*8-1
- .long bootsym_rel(trampoline_gdt,4)
+ .long tramp32sym_rel(trampoline_gdt,4)
/* The first page of trampoline is permanent, the rest boot-time only. */
/* Reuse the boot trampoline on the 1st trampoline page as stack for wakeup. */
@@ -249,7 +294,7 @@ trampoline_boot_cpu_entry:
mov $0x0200,%ax
int $0x16
- mov %al,bootsym(kbd_shift_flags)
+ mov %al,bootdatasym(kbd_shift_flags)
/* Disable irqs before returning to protected mode. */
cli
@@ -294,7 +339,7 @@ opt_edid:
.byte 0
#ifdef CONFIG_VIDEO
-GLOBAL(boot_vid_mode)
+boot_vid_mode:
.word VIDEO_80x25 /* If we don't run at all, assume basic video mode 3 at 80x25. */
vesa_size:
.word 0,0,0 /* width x depth x height */
diff --git a/xen/arch/x86/boot/video.S b/xen/arch/x86/boot/video.S
index 335a51c9b5..03907e9e9a 100644
--- a/xen/arch/x86/boot/video.S
+++ b/xen/arch/x86/boot/video.S
@@ -45,7 +45,7 @@
#define PARAM_VESAPM_SEG 0x24
#define PARAM_VESAPM_OFF 0x26
#define PARAM_VESA_ATTRIB 0x28
-#define _param(param) bootsym(boot_vid_info)+(param)
+#define _param(param) bootdatasym(boot_vid_info)+(param)
video: xorw %ax, %ax
movw %ax, %gs # GS is zero
@@ -917,7 +917,7 @@ store_edid:
cmpw $0x004f, %ax # Call failed?
jne .Lno_edid
- movw %bx, bootsym(boot_edid_caps)
+ movw %bx, bootdatasym(boot_edid_caps)
cmpb $2, bootsym(opt_edid) # EDID forced on cmdline (edid=force)?
je .Lforce_edid
@@ -933,7 +933,7 @@ store_edid:
movw $0x01, %bx
movw $0x00, %cx
movw $0x00, %dx
- movw $bootsym(boot_edid_info), %di
+ movw $bootdatasym(boot_edid_info), %di
int $0x10
.Lno_edid:
diff --git a/xen/arch/x86/boot/wakeup.S b/xen/arch/x86/boot/wakeup.S
index e3cb9e033a..95bedddd0f 100644
--- a/xen/arch/x86/boot/wakeup.S
+++ b/xen/arch/x86/boot/wakeup.S
@@ -53,7 +53,7 @@ ENTRY(wakeup_start)
movw $1, %ax
lmsw %ax # Turn on CR0.PE
- ljmpl $BOOT_CS32, $bootsym_rel(wakeup_32, 6)
+ ljmpl $BOOT_CS32, $trampsym_rel(wakeup_32, 6)
/* This code uses an extended set of video mode numbers. These include:
* Aliases for standard modes
@@ -118,11 +118,11 @@ wakeup_32:
mov $BOOT_DS, %eax
mov %eax, %ds
mov %eax, %ss
- mov $bootsym_rel(wakeup_stack, 4, %esp)
+ mov $trampsym_rel(wakeup_stack, 4, %esp)
# check saved magic again
mov $sym_offs(saved_magic),%eax
- add bootsym_rel(trampoline_xen_phys_start, 4, %eax)
+ add trampsym_rel(trampoline_xen_phys_start, 4, %eax)
mov (%eax), %eax
cmp $0x9abcdef0, %eax
jne bogus_saved_magic
@@ -135,12 +135,12 @@ wakeup_32:
/* Load pagetable base register */
mov $sym_offs(idle_pg_table),%eax
- add bootsym_rel(trampoline_xen_phys_start,4,%eax)
+ add trampsym_rel(trampoline_xen_phys_start,4,%eax)
mov %eax,%cr3
/* Will cpuid feature change after resume? */
/* Set up EFER (Extended Feature Enable Register). */
- mov bootsym_rel(cpuid_ext_features,4,%edi)
+ mov trampsym_rel(cpuid_ext_features,4,%edi)
test $0x20100800,%edi /* SYSCALL/SYSRET, No Execute, Long Mode? */
jz .Lskip_eferw
movl $MSR_EFER,%ecx
@@ -162,7 +162,7 @@ wakeup_32:
1:
/* Now in compatibility mode. Long-jump to 64-bit mode */
- ljmp $BOOT_CS64, $bootsym_rel(wakeup_64,6)
+ ljmp $BOOT_CS64, $trampsym_rel(wakeup_64,6)
.code64
wakeup_64:
diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
index 7a13a30bc0..556942482e 100644
--- a/xen/arch/x86/efi/efi-boot.h
+++ b/xen/arch/x86/efi/efi-boot.h
@@ -99,7 +99,7 @@ static void __init efi_arch_relocate_image(unsigned long delta)
}
extern const s32 __trampoline_rel_start[], __trampoline_rel_stop[];
-extern const s32 __trampoline_seg_start[], __trampoline_seg_stop[];
+extern const s32 __trampoline32_rel_start[], __trampoline32_rel_stop[];
static void __init relocate_trampoline(unsigned long phys)
{
@@ -115,10 +115,10 @@ static void __init relocate_trampoline(unsigned long phys)
trampoline_ptr < __trampoline_rel_stop;
++trampoline_ptr )
*(u32 *)(*trampoline_ptr + (long)trampoline_ptr) += phys;
- for ( trampoline_ptr = __trampoline_seg_start;
- trampoline_ptr < __trampoline_seg_stop;
+ for ( trampoline_ptr = __trampoline32_rel_start;
+ trampoline_ptr < __trampoline32_rel_stop;
++trampoline_ptr )
- *(u16 *)(*trampoline_ptr + (long)trampoline_ptr) = phys >> 4;
+ *(u32 *)(*trampoline_ptr + (long)trampoline_ptr) += phys;
}
static void __init place_string(u32 *addr, const char *s)
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index a73139cd29..400dffaf23 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -237,11 +237,18 @@ SECTIONS
*(.init.data.rel.*)
. = ALIGN(4);
__trampoline_rel_start = .;
- *(.trampoline_rel)
+ *(.trampsym_rel)
__trampoline_rel_stop = .;
- __trampoline_seg_start = .;
- *(.trampoline_seg)
- __trampoline_seg_stop = .;
+ __trampoline32_rel_start = .;
+ *(.tramp32sym_rel)
+ __trampoline32_rel_stop = .;
+ __bootsym_rel_start = .;
+ *(.bootsym_rel)
+ *(.bootdatasym_rel)
+ __bootsym_rel_stop = .;
+ __bootsym_seg_start = .;
+ *(.bootsym_seg)
+ __bootsym_seg_stop = .;
/*
* struct alt_inst entries. From the header (alternative.h):
* "Alternative instructions for different CPU types or capabilities"
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5174 bytes --]
[-- Attachment #2: Type: text/plain, Size: 157 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2019-08-09 15:02 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1565362089.git.dwmw@amazon.co.uk>
2019-08-09 15:01 ` [Xen-devel] [PATCH v2 1/6] x86/boot: Remove gratuitous call back into low-memory code David Woodhouse
2019-08-09 15:01 ` [Xen-devel] [PATCH v2 2/6] x86/boot: Only jump into low trampoline code for real-mode boot David Woodhouse
2019-08-12 9:10 ` Jan Beulich
2019-08-21 14:04 ` David Woodhouse
2019-08-27 8:43 ` Jan Beulich
2019-08-09 15:01 ` David Woodhouse [this message]
2019-08-12 9:41 ` [Xen-devel] [PATCH v2 3/6] x86/boot: Split bootsym() into four types of relocations Jan Beulich
2019-08-19 15:24 ` David Woodhouse
2019-08-09 15:02 ` [Xen-devel] [PATCH v2 4/6] x86/boot: Rename trampoline_{start, end} to boot_trampoline_{start, end} David Woodhouse
2019-08-12 9:55 ` Jan Beulich
2019-08-19 15:24 ` David Woodhouse
2019-08-27 8:51 ` Jan Beulich
2019-08-27 9:31 ` David Woodhouse
2019-08-09 15:02 ` [Xen-devel] [PATCH v2 5/6] x86/boot: Copy 16-bit boot variables back up to Xen image David Woodhouse
2019-08-12 10:24 ` Jan Beulich
2019-08-19 15:25 ` David Woodhouse
2019-08-27 8:59 ` Jan Beulich
2019-08-27 9:19 ` David Woodhouse
2019-08-09 15:02 ` [Xen-devel] [PATCH v2 6/6] x86/boot: Do not use trampoline for no-real-mode boot paths David Woodhouse
2019-08-12 10:55 ` Jan Beulich
2019-08-19 15:25 ` David Woodhouse
2019-08-27 9:07 ` Jan Beulich
2019-08-27 9:12 ` David Woodhouse
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=b14f575d4445e439e3d4fd7d385aab7f7f2bedd5.camel@infradead.org \
--to=dwmw2@infradead.org \
--cc=andrew.cooper3@citrix.com \
--cc=jbeulich@suse.com \
--cc=roger.pau@citrix.com \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.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).