From: Brijesh Singh <brijesh.singh@amd.com>
To: ehabkost@redhat.com, crosthwaite.peter@gmail.com,
armbru@redhat.com, mst@redhat.com, p.fedin@samsung.com,
qemu-devel@nongnu.org, lcapitulino@redhat.com,
pbonzini@redhat.com, rth@twiddle.net
Subject: [Qemu-devel] [RFC PATCH v1 06/22] sev: add initial SEV support
Date: Tue, 13 Sep 2016 10:47:47 -0400 [thread overview]
Message-ID: <147377806784.11859.11149856529336910514.stgit@brijesh-build-machine> (raw)
In-Reply-To: <147377800565.11859.4411044563640180545.stgit@brijesh-build-machine>
This patch adds the initial support required to integrate Secure
Encrypted Virtualization feature, the patch include the following
changes:
- adds sev.c and sev.h files: the file will contain SEV APIs implemention.
- add kvm_sev_enabled(): similar to kvm_enabled() this function can be
used to check if sev is enabled on this guest.
- implement functions to parse SEV specific configuration file.
A typical SEV config file looks like this:
[sev-launch]
flags = "00000000"
policy = "000000"
dh_pub_qx = "0123456789abcdef0123456789abcdef"
dh_pub_qy = "0123456789abcdef0123456789abcdef"
nonce = "0123456789abcdef"
vcpu_count = "1"
vcpu_length = "30"
vcpu_mask = "00ab"
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
Makefile.target | 2
include/sysemu/kvm.h | 10 ++
include/sysemu/sev.h | 27 +++++
kvm-all.c | 6 +
sev.c | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 326 insertions(+), 1 deletion(-)
create mode 100644 include/sysemu/sev.h
create mode 100644 sev.c
diff --git a/Makefile.target b/Makefile.target
index a440bcb..74ad204 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -136,7 +136,7 @@ ifdef CONFIG_SOFTMMU
obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o numa.o
obj-y += qtest.o bootdevice.o
obj-y += hw/
-obj-$(CONFIG_KVM) += kvm-all.o
+obj-$(CONFIG_KVM) += kvm-all.o sev.o
obj-y += memory.o cputlb.o
obj-y += memory_mapping.o
obj-y += dump.o
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index c9c2436..7f83de0 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -40,6 +40,7 @@
#endif
extern bool kvm_allowed;
+extern bool kvm_sev_allowed;
extern bool kvm_kernel_irqchip;
extern bool kvm_split_irqchip;
extern bool kvm_async_interrupts_allowed;
@@ -56,6 +57,14 @@ extern bool kvm_ioeventfd_any_length_allowed;
#if defined CONFIG_KVM || !defined NEED_CPU_H
#define kvm_enabled() (kvm_allowed)
+
+/**
+ * kvm_sev_enabled:
+ *
+ * Returns: true if guest is running into SEV-enabled mode.
+ */
+#define kvm_sev_enabled() (kvm_sev_allowed)
+
/**
* kvm_irqchip_in_kernel:
*
@@ -171,6 +180,7 @@ extern bool kvm_ioeventfd_any_length_allowed;
#else
#define kvm_enabled() (0)
+#define kvm_sev_enabled() (false)
#define kvm_irqchip_in_kernel() (false)
#define kvm_irqchip_is_split() (false)
#define kvm_async_interrupts_enabled() (false)
diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
new file mode 100644
index 0000000..0ee8aff
--- /dev/null
+++ b/include/sysemu/sev.h
@@ -0,0 +1,27 @@
+/*
+ * QEMU SEV support
+ *
+ * Copyright: Advanced Micro Devices, 2016
+ *
+ * Authors:
+ * Brijesh Singh <brijesh.singh@amd.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_SEV_H
+#define QEMU_SEV_H
+
+#include "sysemu/kvm.h"
+
+/**
+ * sev_init - initialize Secure Encrypted Virtualization on this guest
+ * @kvm_state - KVM handle
+ * Returns: 1 on error, 0 on success
+ */
+int sev_init(KVMState *kvm_state);
+
+#endif
+
diff --git a/kvm-all.c b/kvm-all.c
index ebf35b0..e194849 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -36,6 +36,7 @@
#include "qemu/event_notifier.h"
#include "trace.h"
#include "hw/irq.h"
+#include "sysemu/sev.h"
#include "hw/boards.h"
@@ -119,6 +120,7 @@ bool kvm_readonly_mem_allowed;
bool kvm_vm_attributes_allowed;
bool kvm_direct_msi_allowed;
bool kvm_ioeventfd_any_length_allowed;
+bool kvm_sev_allowed;
static const KVMCapabilityInfo kvm_required_capabilites[] = {
KVM_CAP_INFO(USER_MEMORY),
@@ -1745,6 +1747,10 @@ static int kvm_init(MachineState *ms)
kvm_state = s;
+ if (!sev_init(kvm_state)) {
+ kvm_sev_allowed = true;
+ }
+
if (kvm_eventfds_allowed) {
s->memory_listener.listener.eventfd_add = kvm_mem_ioeventfd_add;
s->memory_listener.listener.eventfd_del = kvm_mem_ioeventfd_del;
diff --git a/sev.c b/sev.c
new file mode 100644
index 0000000..2d71ca6
--- /dev/null
+++ b/sev.c
@@ -0,0 +1,282 @@
+/*
+ * QEMU SEV support
+ *
+ * Copyright Advanced Micro Devices 2016
+ *
+ * Author:
+ * Brijesh Singh <brijesh.singh@amd.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include <linux/kvm.h>
+
+#include "qemu-common.h"
+#include "qemu/atomic.h"
+#include "qemu/option.h"
+#include "qemu/config-file.h"
+#include "qemu/error-report.h"
+#include "hw/hw.h"
+#include "hw/pci/msi.h"
+#include "hw/s390x/adapter.h"
+#include "exec/gdbstub.h"
+#include "sysemu/kvm_int.h"
+#include "sysemu/sev.h"
+#include "qemu/bswap.h"
+#include "exec/memory.h"
+#include "exec/ram_addr.h"
+#include "exec/address-spaces.h"
+#include "qemu/event_notifier.h"
+#include "trace.h"
+#include "hw/irq.h"
+
+//#define DEBUG_SEV
+
+#ifdef DEBUG_SEV
+#define DPRINTF(fmt, ...) \
+ do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+ do { } while (0)
+#endif
+
+struct SEVInfo {
+ uint8_t state; /* guest current state */
+ uint8_t type; /* guest type (encrypted, unencrypted) */
+ struct kvm_sev_launch_start *launch_start;
+ struct kvm_sev_launch_update *launch_update;
+ struct kvm_sev_launch_finish *launch_finish;
+};
+
+typedef struct SEVInfo SEVInfo;
+static SEVInfo *sev_info;
+static const char *cfg_file;
+
+enum {
+ LAUNCH_OPTS = 0,
+};
+
+enum {
+ PRE_ENCRYPTED_GUEST = 0,
+ UNENCRYPTED_GUEST,
+};
+
+static QemuOptsList launch_opts = {
+ .name = "sev-launch",
+ .head = QTAILQ_HEAD_INITIALIZER(launch_opts.head),
+ .desc = {
+ {
+ .name = "flags",
+ .type = QEMU_OPT_NUMBER,
+ },
+ {
+ .name = "policy",
+ .type = QEMU_OPT_NUMBER,
+ },
+ {
+ .name = "dh_pub_qx",
+ .type = QEMU_OPT_STRING,
+ },
+ {
+ .name = "dh_pub_qy",
+ .type = QEMU_OPT_STRING,
+ },
+ {
+ .name = "nonce",
+ .type = QEMU_OPT_STRING,
+ },
+ {
+ .name = "vcpu_length",
+ .type = QEMU_OPT_NUMBER,
+ },
+ {
+ .name = "vcpu_count",
+ .type = QEMU_OPT_NUMBER,
+ },
+ {
+ .name = "vcpu_mask",
+ .type = QEMU_OPT_STRING,
+ },
+ { /* end of list */ }
+ },
+};
+
+static QemuOptsList *config_groups[] = {
+ &launch_opts,
+ NULL
+};
+
+struct add_rule_data {
+ SEVInfo *s;
+ int action;
+};
+
+static unsigned int read_config_u32(QemuOpts *opts, const char *key)
+{
+ unsigned int val;
+
+ val = qemu_opt_get_number_del(opts, key, -1);
+ DPRINTF(" %s = %08x\n", key, val);
+
+ return val;
+}
+
+static int read_config_u8(QemuOpts *opts, const char *key, uint8_t *val)
+{
+ int i;
+ const char *v;
+
+ v = qemu_opt_get(opts, key);
+ if (!v) {
+ return 0;
+ }
+
+ DPRINTF(" %s = ", key);
+ i = 0;
+ while (*v) {
+ sscanf(v, "%2hhx", &val[i]);
+ DPRINTF("%02hhx", val[i]);
+ v += 2;
+ i++;
+ }
+ DPRINTF("\n");
+
+ return i;
+}
+
+static int add_rule(void *opaque, QemuOpts *opts, Error **errp)
+{
+ struct add_rule_data *d = opaque;
+
+ switch (d->action) {
+ case LAUNCH_OPTS: {
+ struct kvm_sev_launch_start *start;
+ struct kvm_sev_launch_update *update;
+ struct kvm_sev_launch_finish *finish;
+
+ /* LAUNCH_START parameters */
+ start = g_malloc0(sizeof(*start));
+
+ DPRINTF("Parsing 'sev-launch' parameters\n");
+ start->flags = read_config_u32(opts, "flags");
+ start->policy = read_config_u32(opts, "policy");
+ read_config_u8(opts, "nonce", start->nonce);
+ read_config_u8(opts, "dh_pub_qx", start->dh_pub_qx);
+ read_config_u8(opts, "dh_pub_qy", start->dh_pub_qy);
+ sev_info->launch_start = start;
+
+ /* LAUNCH_UPDATE */
+ update = g_malloc0(sizeof(*update));
+ sev_info->launch_update = update;
+
+ /* LAUNCH_FINISH parameters */
+ finish = g_malloc0(sizeof(*finish));
+
+ finish->vcpu_count = read_config_u32(opts, "vcpu_count");
+ finish->vcpu_length = read_config_u32(opts, "vcpu_length");
+ if (qemu_opt_get(opts, "vcpu_mask")) {
+ finish->vcpu_mask_length =
+ strlen(qemu_opt_get(opts, "vcpu_mask")) / 2;
+ finish->vcpu_mask_addr = (unsigned long)
+ g_malloc0(finish->vcpu_length);
+ read_config_u8(opts, "vcpu_mask",
+ (uint8_t *)finish->vcpu_mask_addr);
+ }
+
+ sev_info->launch_finish = finish;
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int parse_add_rules(QemuOptsList *list, struct add_rule_data *d)
+{
+ Error *local_err = NULL;
+
+ qemu_opts_foreach(list, add_rule, d, &local_err);
+ if (local_err) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static int parse_sev_cfg(SEVInfo *s, int type, const char *filename)
+{
+ FILE *f;
+ int ret = 0;
+ struct add_rule_data d;
+
+ if (filename) {
+ f = fopen(filename, "r");
+ if (f == NULL) {
+ return 1;
+ }
+
+ ret = qemu_config_parse(f, config_groups, filename);
+ if (ret < 0) {
+ fprintf(stderr, "SEV: could not parse config file\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ switch (type) {
+ case LAUNCH_OPTS:
+ d.s = s;
+ d.action = type;
+ ret = parse_add_rules(&launch_opts, &d);
+ break;
+ }
+
+ return ret;
+
+}
+
+int sev_init(KVMState *kvm_state)
+{
+ QemuOpts *opts;
+ const char *type;
+
+ opts = qemu_find_opts_singleton("sev");
+ cfg_file = qemu_opt_get(opts, "config");
+ if (!cfg_file) {
+ return 1;
+ }
+
+ type = qemu_opt_get(opts, "type");
+ if (!type) {
+ return 1;
+ }
+
+ sev_info = calloc(1, sizeof(*sev_info));
+ if (!sev_info) {
+ return 1;
+ }
+
+ if (!strcmp(type, "unencrypted")) {
+ sev_info->type = UNENCRYPTED_GUEST;
+ } else if (!strcmp(type, "encrypted")) {
+ sev_info->type = PRE_ENCRYPTED_GUEST;
+ } else {
+ fprintf(stderr, "SEV: unsupported type '%s'\n", type);
+ goto err;
+ }
+
+ /* call SEV launch start APIs based on guest type */
+
+ return 0;
+err:
+ free(sev_info);
+ sev_info = NULL;
+ return 1;
+}
+
next prev parent reply other threads:[~2016-09-13 15:21 UTC|newest]
Thread overview: 125+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-13 14:46 [Qemu-devel] [RFC PATCH v1 00/22] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
2016-09-13 14:46 ` [Qemu-devel] [RFC PATCH v1 01/22] exec: add guest RAM read/write ops Brijesh Singh
2016-09-13 14:47 ` [Qemu-devel] [RFC PATCH v1 02/22] cpu-common: add debug version of physical memory read/write Brijesh Singh
2016-09-13 14:47 ` [Qemu-devel] [RFC PATCH v1 03/22] monitor: use debug version of physical memory read api Brijesh Singh
2016-09-13 14:47 ` [Qemu-devel] [RFC PATCH v1 04/22] memattrs: add SEV debug attrs Brijesh Singh
2016-09-13 23:00 ` Paolo Bonzini
2016-09-14 20:30 ` Brijesh Singh
2016-09-13 14:47 ` [Qemu-devel] [RFC PATCH v1 05/22] i386: add new option to enable SEV guest Brijesh Singh
2016-09-13 22:41 ` Paolo Bonzini
2016-09-14 8:41 ` Daniel P. Berrange
2016-09-14 9:11 ` Paolo Bonzini
2016-09-13 14:47 ` Brijesh Singh [this message]
2016-09-13 15:58 ` [Qemu-devel] [RFC PATCH v1 06/22] sev: add initial SEV support Eduardo Habkost
2016-09-13 19:54 ` Brijesh Singh
2016-09-13 20:10 ` Michael S. Tsirkin
2016-09-13 22:00 ` Eduardo Habkost
2016-09-14 8:30 ` Daniel P. Berrange
2016-09-14 11:54 ` Eduardo Habkost
2016-09-14 11:58 ` Daniel P. Berrange
2016-09-14 16:10 ` Brijesh Singh
2016-09-14 16:13 ` Daniel P. Berrange
2016-09-14 16:20 ` Michael S. Tsirkin
2016-09-14 18:46 ` Brijesh Singh
2016-09-14 20:23 ` Michael S. Tsirkin
2016-09-14 8:37 ` Daniel P. Berrange
2016-09-13 14:47 ` [Qemu-devel] [RFC PATCH v1 07/22] sev: add SEV launch start command Brijesh Singh
2016-09-13 14:48 ` [Qemu-devel] [RFC PATCH v1 08/22] sev: add SEV launch update command Brijesh Singh
2016-09-13 14:48 ` [Qemu-devel] [RFC PATCH v1 09/22] sev: add SEV launch finish command Brijesh Singh
2016-09-13 22:15 ` Eduardo Habkost
2016-09-13 14:48 ` [Qemu-devel] [RFC PATCH v1 10/22] sev: add SEV debug decrypt command Brijesh Singh
2016-09-14 2:28 ` Michael S. Tsirkin
2016-09-14 8:57 ` Paolo Bonzini
2016-09-14 13:05 ` Michael S. Tsirkin
2016-09-14 13:07 ` Paolo Bonzini
2016-09-14 13:23 ` Daniel P. Berrange
2016-09-14 13:32 ` Michael S. Tsirkin
2016-09-14 13:37 ` Daniel P. Berrange
2016-09-14 13:50 ` Michael S. Tsirkin
2016-09-14 14:08 ` Eduardo Habkost
2016-09-14 14:14 ` Paolo Bonzini
2016-09-14 14:38 ` Michael S. Tsirkin
2016-09-14 15:17 ` Michael S. Tsirkin
2016-09-14 14:15 ` Daniel P. Berrange
2016-09-14 14:48 ` Michael S. Tsirkin
2016-09-14 15:06 ` Daniel P. Berrange
2016-09-14 15:46 ` Michael S. Tsirkin
2016-09-14 17:35 ` Eduardo Habkost
2016-09-14 22:05 ` Michael S. Tsirkin
2016-09-15 14:58 ` Eduardo Habkost
2016-09-14 13:27 ` [Qemu-devel] [PATCH v2] virtio_pci: Limit DMA mask to 44 bits for legacy virtio devices Michael S. Tsirkin
2016-09-14 13:36 ` [Qemu-devel] [RFC PATCH v1 10/22] sev: add SEV debug decrypt command Brijesh Singh
2016-09-14 13:48 ` Michael S. Tsirkin
2016-09-14 14:19 ` Paolo Bonzini
2016-09-14 15:02 ` Michael S. Tsirkin
2016-09-14 16:53 ` Paolo Bonzini
2016-09-14 18:15 ` Michael S. Tsirkin
2016-09-14 18:45 ` Paolo Bonzini
2016-09-14 19:24 ` Michael S. Tsirkin
2016-09-14 19:58 ` Paolo Bonzini
2016-09-14 20:36 ` Michael S. Tsirkin
2016-09-14 20:44 ` Paolo Bonzini
2016-09-14 21:25 ` Brijesh Singh
2016-09-14 21:38 ` Michael S. Tsirkin
2016-09-13 14:48 ` [Qemu-devel] [RFC PATCH v1 11/22] sev: add SEV debug encrypt command Brijesh Singh
2016-09-13 14:48 ` [Qemu-devel] [RFC PATCH v1 12/22] sev: add SEV guest status command Brijesh Singh
2016-09-13 14:48 ` [Qemu-devel] [RFC PATCH v1 13/22] hmp: update 'info kvm' to display SEV status Brijesh Singh
2016-09-13 16:09 ` Eric Blake
2016-09-14 16:16 ` Brijesh Singh
2016-09-15 4:13 ` Michael S. Tsirkin
2016-09-13 23:01 ` Paolo Bonzini
2016-09-13 14:49 ` [Qemu-devel] [RFC PATCH v1 14/22] sev: provide SEV-enabled guest RAM read/write ops Brijesh Singh
2016-09-13 14:49 ` [Qemu-devel] [RFC PATCH v1 15/22] i386: sev: register RAM read/write ops for BIOS and PC.RAM region Brijesh Singh
2016-09-13 23:05 ` Paolo Bonzini
2016-09-14 20:59 ` Brijesh Singh
2016-09-14 21:00 ` Paolo Bonzini
2016-09-14 21:47 ` Brijesh Singh
2016-09-14 21:52 ` Paolo Bonzini
2016-09-14 22:06 ` Brijesh Singh
2016-09-14 22:17 ` Paolo Bonzini
2016-09-14 22:26 ` Brijesh Singh
2016-09-15 14:13 ` Brijesh Singh
2016-09-15 15:19 ` Paolo Bonzini
2016-09-13 14:49 ` [Qemu-devel] [RFC PATCH v1 17/22] target-i386: add cpuid Fn8000_001f Brijesh Singh
2016-09-13 23:07 ` Paolo Bonzini
2016-09-21 16:20 ` Brijesh Singh
2016-09-21 16:24 ` Paolo Bonzini
2016-09-21 18:21 ` Eduardo Habkost
2016-09-13 14:49 ` [Qemu-devel] [RFC PATCH v1 18/22] i386: clear C-bit in SEV guest page table walk Brijesh Singh
2016-09-13 14:49 ` [Qemu-devel] [RFC PATCH v1 19/22] exec: set debug attribute in SEV-enabled guest Brijesh Singh
2016-09-13 23:06 ` Paolo Bonzini
2016-09-13 14:50 ` [Qemu-devel] [RFC PATCH v1 20/22] fw_cfg: sev: disable dma in real mode Brijesh Singh
2016-09-13 18:39 ` Michael S. Tsirkin
2016-09-13 20:46 ` Brijesh Singh
2016-09-13 20:55 ` Michael S. Tsirkin
2016-09-13 22:53 ` Paolo Bonzini
2016-09-14 2:33 ` Michael S. Tsirkin
2016-09-14 8:58 ` Paolo Bonzini
2016-09-21 18:00 ` [Qemu-devel] [RFC PATCH v1 20/22] fw_cfg: sev: disable dma in real mode Message-ID: <20160921205731-mutt-send-email-mst@kernel.org> Michael S. Tsirkin
2016-09-14 12:09 ` [Qemu-devel] [RFC PATCH v1 20/22] fw_cfg: sev: disable dma in real mode Eduardo Habkost
2016-09-14 13:01 ` Paolo Bonzini
2016-09-14 13:14 ` Michael S. Tsirkin
2016-09-14 13:51 ` Eduardo Habkost
2016-09-14 16:10 ` Michael S. Tsirkin
2016-09-14 17:25 ` Eduardo Habkost
2016-09-21 18:03 ` Michael S. Tsirkin
2016-09-21 18:19 ` Brijesh Singh
2016-09-13 14:50 ` [Qemu-devel] [RFC PATCH v1 21/22] hw: add pre and post system reset callback Brijesh Singh
2016-09-13 22:47 ` Paolo Bonzini
2016-09-14 16:19 ` Brijesh Singh
2016-09-13 14:50 ` [Qemu-devel] [RFC PATCH v1 22/22] loader: reload bios image on ROM reset in SEV-enabled guest Brijesh Singh
2016-09-13 18:47 ` Michael S. Tsirkin
2016-09-13 22:59 ` Paolo Bonzini
2016-09-14 2:38 ` Michael S. Tsirkin
2016-09-14 20:29 ` Brijesh Singh
2016-09-14 20:38 ` Paolo Bonzini
2016-09-14 21:09 ` Michael S. Tsirkin
2016-09-14 21:11 ` Paolo Bonzini
2016-09-14 21:24 ` Brijesh Singh
2016-09-13 15:20 ` [Qemu-devel] [RFC PATCH v1 00/22] x86: Secure Encrypted Virtualization (AMD) Eduardo Habkost
[not found] ` <147377816978.11859.942423377333907417.stgit@brijesh-build-machine>
2016-09-13 18:37 ` [Qemu-devel] [RFC PATCH v1 16/22] i386: pc: load OS images at fixed location in SEV-enabled guest Michael S. Tsirkin
2016-09-21 15:55 ` Brijesh Singh
2016-09-21 15:58 ` Paolo Bonzini
2016-09-21 16:08 ` Brijesh Singh
2016-09-21 16:17 ` Paolo Bonzini
2016-09-14 2:55 ` [Qemu-devel] [RFC PATCH v1 00/22] x86: Secure Encrypted Virtualization (AMD) Michael S. Tsirkin
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=147377806784.11859.11149856529336910514.stgit@brijesh-build-machine \
--to=brijesh.singh@amd.com \
--cc=armbru@redhat.com \
--cc=crosthwaite.peter@gmail.com \
--cc=ehabkost@redhat.com \
--cc=lcapitulino@redhat.com \
--cc=mst@redhat.com \
--cc=p.fedin@samsung.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/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).