All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brijesh Singh <brijesh.singh@amd.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Brijesh Singh <brijesh.singh@amd.com>,
	kvm@vger.kernel.org, "Michael S. Tsirkin" <mst@redhat.com>,
	Stefan Hajnoczi <stefanha@gmail.com>,
	Alexander Graf <agraf@suse.de>,
	"Edgar E. Iglesias" <edgar.iglesias@xilinx.com>,
	Markus Armbruster <armbru@redhat.com>,
	Bruce Rogers <brogers@suse.com>,
	Christian Borntraeger <borntraeger@de.ibm.com>,
	Marcel Apfelbaum <marcel@redhat.com>,
	Borislav Petkov <bp@suse.de>,
	Thomas Lendacky <Thomas.Lendacky@amd.com>,
	Eduardo Habkost <ehabkost@redhat.com>,
	Richard Henderson <richard.henderson@linaro.org>,
	"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
	Alistair Francis <alistair.francis@xilinx.com>,
	Cornelia Huck <cornelia.huck@de.ibm.com>,
	Richard Henderson <rth@twiddle.net>,
	Peter Crosthwaite <crosthwaite.peter@gmail.com>,
	Paolo Bonzini <pbonzini@redhat.com>
Subject: [PATCH v10 08/28] target/i386: add Secure Encrypted Virtulization (SEV) object
Date: Wed, 28 Feb 2018 15:10:08 -0600	[thread overview]
Message-ID: <20180228211028.83970-9-brijesh.singh@amd.com> (raw)
In-Reply-To: <20180228211028.83970-1-brijesh.singh@amd.com>

Add a new memory encryption object 'sev-guest'. The object will be used
to create enrypted VMs on AMD EPYC CPU. The object provides the properties
to pass guest owner's public Diffie-hellman key, guest policy and session
information required to create the memory encryption context within the
SEV firmware.

e.g to launch SEV guest
 # $QEMU \
    -object sev-guest,id=sev0 \
    -machine ....,memory-encryption=sev0

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 docs/amd-memory-encryption.txt |  17 +++
 qemu-options.hx                |  44 ++++++++
 target/i386/Makefile.objs      |   2 +-
 target/i386/sev.c              | 228 +++++++++++++++++++++++++++++++++++++++++
 target/i386/sev_i386.h         |  61 +++++++++++
 5 files changed, 351 insertions(+), 1 deletion(-)
 create mode 100644 target/i386/sev.c
 create mode 100644 target/i386/sev_i386.h

diff --git a/docs/amd-memory-encryption.txt b/docs/amd-memory-encryption.txt
index 72a92b6c6353..8711da9ed598 100644
--- a/docs/amd-memory-encryption.txt
+++ b/docs/amd-memory-encryption.txt
@@ -35,10 +35,21 @@ in bad measurement). The guest policy is a 4-byte data structure containing
 several flags that restricts what can be done on running SEV guest.
 See KM Spec section 3 and 6.2 for more details.
 
+The guest policy can be provided via the 'policy' property (see below)
+
+# ${QEMU} \
+   sev-guest,id=sev0,policy=0x1...\
+
 Guest owners provided DH certificate and session parameters will be used to
 establish a cryptographic session with the guest owner to negotiate keys used
 for the attestation.
 
+The DH certificate and session blob can be provided via 'dh-cert-file' and
+'session-file' property (see below
+
+# ${QEMU} \
+     sev-guest,id=sev0,dh-cert-file=<file1>,session-file=<file2>
+
 LAUNCH_UPDATE_DATA encrypts the memory region using the cryptographic context
 created via LAUNCH_START command. If required, this command can be called
 multiple times to encrypt different memory regions. The command also calculates
@@ -59,6 +70,12 @@ context.
 See SEV KM API Spec [1] 'Launching a guest' usage flow (Appendix A) for the
 complete flow chart.
 
+To launch a SEV guest
+
+# ${QEMU} \
+    -machine ...,memory-encryption=sev0 \
+    -object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=5
+
 Debugging
 -----------
 Since memory contents of SEV guest is encrypted hence hypervisor access to the
diff --git a/qemu-options.hx b/qemu-options.hx
index a6648ca073f2..f961b62bcbb2 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4313,6 +4313,50 @@ contents of @code{iv.b64} to the second secret
          data=$SECRET,iv=$(<iv.b64)
 @end example
 
+@item -object sev-guest,id=@var{id},cbitpos=@var{cbitpos},reduced-phys-bits=@var{val},[sev-device=@var{string},policy=@var{policy},handle=@var{handle},dh-cert-file=@var{file},session-file=@var{file}]
+
+Create a Secure Encrypted Virtualization (SEV) guest object, which can be used
+to provide the guest memory encryption support on AMD processors.
+
+When memory encryption is enabled, one of the physical address bit (aka the
+C-bit) is utilized to mark if a memory page is protected. The @option{cbitpos}
+is used to provide the C-bit position. The C-bit position is Host family dependent
+hence user must provide this value. On EPYC, the value should be 47.
+
+When memory encryption is enabled, we loose certain bits in physical address space.
+The @option{reduced-phys-bits} is used to provide the number of bits we loose in
+physical address space. Similar to C-bit, the value is Host family dependent.
+On EPYC, the value should be 5.
+
+The @option{sev-device} provides the device file to use for communicating with
+the SEV firmware running inside AMD Secure Processor. The default device is
+'/dev/sev'. If hardware supports memory encryption then /dev/sev devices are
+created by CCP driver.
+
+The @option{policy} provides the guest policy to be enforced by the SEV firmware
+and restrict what configuration and operational commands can be performed on this
+guest by the hypervisor. The policy should be provided by the guest owner and is
+bound to the guest and cannot be changed throughout the lifetime of the guest.
+The default is 0.
+
+If guest @option{policy} allows sharing the key with another SEV guest then
+@option{handle} can be use to provide handle of the guest from which to share
+the key.
+
+The @option{dh-cert-file} and @option{session-file} provides the guest owner's
+Public Diffie-Hillman key defined in SEV spec. The PDH and session parameters
+are used for establishing a cryptographic session with the guest owner to
+negotiate keys used for attestation. The file must be encoded in base64.
+
+e.g to launch a SEV guest
+@example
+ # $QEMU \
+     ......
+     -object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=5 \
+     -machine ...,memory-encryption=sev0
+     .....
+
+@end example
 @end table
 
 ETEXI
diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs
index f5c6ef20a7bb..76aeaeae2750 100644
--- a/target/i386/Makefile.objs
+++ b/target/i386/Makefile.objs
@@ -4,7 +4,7 @@ obj-$(CONFIG_TCG) += bpt_helper.o cc_helper.o excp_helper.o fpu_helper.o
 obj-$(CONFIG_TCG) += int_helper.o mem_helper.o misc_helper.o mpx_helper.o
 obj-$(CONFIG_TCG) += seg_helper.o smm_helper.o svm_helper.o
 obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o monitor.o
-obj-$(CONFIG_KVM) += kvm.o hyperv.o
+obj-$(CONFIG_KVM) += kvm.o hyperv.o sev.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
 # HAX support
 ifdef CONFIG_WIN32
diff --git a/target/i386/sev.c b/target/i386/sev.c
new file mode 100644
index 000000000000..ab42e4a456d2
--- /dev/null
+++ b/target/i386/sev.c
@@ -0,0 +1,228 @@
+/*
+ * QEMU SEV support
+ *
+ * Copyright Advanced Micro Devices 2016-2018
+ *
+ * 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 "qapi/error.h"
+#include "qom/object_interfaces.h"
+#include "qemu/base64.h"
+#include "sysemu/kvm.h"
+#include "sev_i386.h"
+#include "sysemu/sysemu.h"
+
+#define DEFAULT_GUEST_POLICY    0x1 /* disable debug */
+#define DEFAULT_SEV_DEVICE      "/dev/sev"
+
+static void
+qsev_guest_finalize(Object *obj)
+{
+}
+
+static char *
+qsev_guest_get_session_file(Object *obj, Error **errp)
+{
+    QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+
+    return s->session_file ? g_strdup(s->session_file) : NULL;
+}
+
+static void
+qsev_guest_set_session_file(Object *obj, const char *value, Error **errp)
+{
+    QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+
+    s->session_file = g_strdup(value);
+}
+
+static char *
+qsev_guest_get_dh_cert_file(Object *obj, Error **errp)
+{
+    QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+
+    return g_strdup(s->dh_cert_file);
+}
+
+static void
+qsev_guest_set_dh_cert_file(Object *obj, const char *value, Error **errp)
+{
+    QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+
+    s->dh_cert_file = g_strdup(value);
+}
+
+static char *
+qsev_guest_get_sev_device(Object *obj, Error **errp)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    return g_strdup(sev->sev_device);
+}
+
+static void
+qsev_guest_set_sev_device(Object *obj, const char *value, Error **errp)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    sev->sev_device = g_strdup(value);
+}
+
+static void
+qsev_guest_class_init(ObjectClass *oc, void *data)
+{
+    object_class_property_add_str(oc, "sev-device",
+                                  qsev_guest_get_sev_device,
+                                  qsev_guest_set_sev_device,
+                                  NULL);
+    object_class_property_set_description(oc, "sev-device",
+            "SEV device to use", NULL);
+    object_class_property_add_str(oc, "dh-cert-file",
+                                  qsev_guest_get_dh_cert_file,
+                                  qsev_guest_set_dh_cert_file,
+                                  NULL);
+    object_class_property_set_description(oc, "dh-cert-file",
+            "guest owners DH certificate (encoded with base64)", NULL);
+    object_class_property_add_str(oc, "session-file",
+                                  qsev_guest_get_session_file,
+                                  qsev_guest_set_session_file,
+                                  NULL);
+    object_class_property_set_description(oc, "session-file",
+            "guest owners session parameters (encoded with base64)", NULL);
+}
+
+static void
+qsev_guest_set_handle(Object *obj, Visitor *v, const char *name,
+                      void *opaque, Error **errp)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+    uint32_t value;
+
+    visit_type_uint32(v, name, &value, errp);
+    sev->handle = value;
+}
+
+static void
+qsev_guest_set_policy(Object *obj, Visitor *v, const char *name,
+                      void *opaque, Error **errp)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+    uint32_t value;
+
+    visit_type_uint32(v, name, &value, errp);
+    sev->policy = value;
+}
+
+static void
+qsev_guest_set_cbitpos(Object *obj, Visitor *v, const char *name,
+                       void *opaque, Error **errp)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+    uint32_t value;
+
+    visit_type_uint32(v, name, &value, errp);
+    sev->cbitpos = value;
+}
+
+static void
+qsev_guest_set_reduced_phys_bits(Object *obj, Visitor *v, const char *name,
+                                   void *opaque, Error **errp)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+    uint32_t value;
+
+    visit_type_uint32(v, name, &value, errp);
+    sev->reduced_phys_bits = value;
+}
+
+static void
+qsev_guest_get_policy(Object *obj, Visitor *v, const char *name,
+                      void *opaque, Error **errp)
+{
+    uint32_t value;
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    value = sev->policy;
+    visit_type_uint32(v, name, &value, errp);
+}
+
+static void
+qsev_guest_get_handle(Object *obj, Visitor *v, const char *name,
+                      void *opaque, Error **errp)
+{
+    uint32_t value;
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    value = sev->handle;
+    visit_type_uint32(v, name, &value, errp);
+}
+
+static void
+qsev_guest_get_cbitpos(Object *obj, Visitor *v, const char *name,
+                       void *opaque, Error **errp)
+{
+    uint32_t value;
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    value = sev->cbitpos;
+    visit_type_uint32(v, name, &value, errp);
+}
+
+static void
+qsev_guest_get_reduced_phys_bits(Object *obj, Visitor *v, const char *name,
+                                   void *opaque, Error **errp)
+{
+    uint32_t value;
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    value = sev->reduced_phys_bits;
+    visit_type_uint32(v, name, &value, errp);
+}
+
+static void
+qsev_guest_init(Object *obj)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE);
+    sev->policy = DEFAULT_GUEST_POLICY;
+    object_property_add(obj, "policy", "uint32", qsev_guest_get_policy,
+                        qsev_guest_set_policy, NULL, NULL, NULL);
+    object_property_add(obj, "handle", "uint32", qsev_guest_get_handle,
+                        qsev_guest_set_handle, NULL, NULL, NULL);
+    object_property_add(obj, "cbitpos", "uint32", qsev_guest_get_cbitpos,
+                        qsev_guest_set_cbitpos, NULL, NULL, NULL);
+    object_property_add(obj, "reduced-phys-bits", "uint32",
+                        qsev_guest_get_reduced_phys_bits,
+                        qsev_guest_set_reduced_phys_bits, NULL, NULL, NULL);
+}
+
+/* sev guest info */
+static const TypeInfo qsev_guest_info = {
+    .parent = TYPE_OBJECT,
+    .name = TYPE_QSEV_GUEST_INFO,
+    .instance_size = sizeof(QSevGuestInfo),
+    .instance_finalize = qsev_guest_finalize,
+    .class_size = sizeof(QSevGuestInfoClass),
+    .class_init = qsev_guest_class_init,
+    .instance_init = qsev_guest_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+static void
+sev_register_types(void)
+{
+    type_register_static(&qsev_guest_info);
+}
+
+type_init(sev_register_types);
diff --git a/target/i386/sev_i386.h b/target/i386/sev_i386.h
new file mode 100644
index 000000000000..caf879c3b874
--- /dev/null
+++ b/target/i386/sev_i386.h
@@ -0,0 +1,61 @@
+/*
+ * QEMU Secure Encrypted Virutualization (SEV) support
+ *
+ * Copyright: Advanced Micro Devices, 2016-2018
+ *
+ * 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_I386_H
+#define QEMU_SEV_I386_H
+
+#include "qom/object.h"
+#include "qapi/error.h"
+#include "sysemu/kvm.h"
+#include "qemu/error-report.h"
+
+#define SEV_POLICY_NODBG        0x1
+#define SEV_POLICY_NOKS         0x2
+#define SEV_POLICY_ES           0x4
+#define SEV_POLICY_NOSEND       0x8
+#define SEV_POLICY_DOMAIN       0x10
+#define SEV_POLICY_SEV          0x20
+
+#define TYPE_QSEV_GUEST_INFO "sev-guest"
+#define QSEV_GUEST_INFO(obj)                  \
+    OBJECT_CHECK(QSevGuestInfo, (obj), TYPE_QSEV_GUEST_INFO)
+
+typedef struct QSevGuestInfo QSevGuestInfo;
+typedef struct QSevGuestInfoClass QSevGuestInfoClass;
+
+/**
+ * QSevGuestInfo:
+ *
+ * The QSevGuestInfo object is used for creating a SEV guest.
+ *
+ * # $QEMU \
+ *         -object sev-guest,id=sev0 \
+ *         -machine ...,memory-encryption=sev0
+ */
+struct QSevGuestInfo {
+    Object parent_obj;
+
+    char *sev_device;
+    uint32_t policy;
+    uint32_t handle;
+    char *dh_cert_file;
+    char *session_file;
+    uint32_t cbitpos;
+    uint32_t reduced_phys_bits;
+};
+
+struct QSevGuestInfoClass {
+    ObjectClass parent_class;
+};
+
+#endif
-- 
2.14.3

WARNING: multiple messages have this Message-ID (diff)
From: Brijesh Singh <brijesh.singh@amd.com>
To: qemu-devel@nongnu.org
Cc: Alistair Francis <alistair.francis@xilinx.com>,
	Christian Borntraeger <borntraeger@de.ibm.com>,
	Cornelia Huck <cornelia.huck@de.ibm.com>,
	"Daniel P . Berrange" <berrange@redhat.com>,
	"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	"Edgar E. Iglesias" <edgar.iglesias@xilinx.com>,
	Eduardo Habkost <ehabkost@redhat.com>,
	Eric Blake <eblake@redhat.com>,
	kvm@vger.kernel.org, Marcel Apfelbaum <marcel@redhat.com>,
	Markus Armbruster <armbru@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Peter Crosthwaite <crosthwaite.peter@gmail.com>,
	Peter Maydell <peter.maydell@linaro.org>,
	Richard Henderson <richard.henderson@linaro.org>,
	Stefan Hajnoczi <stefanha@gmail.com>,
	Thomas Lendacky <Thomas.Lendacky@amd.com>,
	Borislav Petkov <bp@suse.de>, Alexander Graf <agraf@suse.de>,
	Bruce Rogers <brogers@suse.com>,
	Brijesh Singh <brijesh.singh@amd.com>,
	Richard Henderson <rth@twiddle.net>
Subject: [Qemu-devel] [PATCH v10 08/28] target/i386: add Secure Encrypted Virtulization (SEV) object
Date: Wed, 28 Feb 2018 15:10:08 -0600	[thread overview]
Message-ID: <20180228211028.83970-9-brijesh.singh@amd.com> (raw)
In-Reply-To: <20180228211028.83970-1-brijesh.singh@amd.com>

Add a new memory encryption object 'sev-guest'. The object will be used
to create enrypted VMs on AMD EPYC CPU. The object provides the properties
to pass guest owner's public Diffie-hellman key, guest policy and session
information required to create the memory encryption context within the
SEV firmware.

e.g to launch SEV guest
 # $QEMU \
    -object sev-guest,id=sev0 \
    -machine ....,memory-encryption=sev0

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 docs/amd-memory-encryption.txt |  17 +++
 qemu-options.hx                |  44 ++++++++
 target/i386/Makefile.objs      |   2 +-
 target/i386/sev.c              | 228 +++++++++++++++++++++++++++++++++++++++++
 target/i386/sev_i386.h         |  61 +++++++++++
 5 files changed, 351 insertions(+), 1 deletion(-)
 create mode 100644 target/i386/sev.c
 create mode 100644 target/i386/sev_i386.h

diff --git a/docs/amd-memory-encryption.txt b/docs/amd-memory-encryption.txt
index 72a92b6c6353..8711da9ed598 100644
--- a/docs/amd-memory-encryption.txt
+++ b/docs/amd-memory-encryption.txt
@@ -35,10 +35,21 @@ in bad measurement). The guest policy is a 4-byte data structure containing
 several flags that restricts what can be done on running SEV guest.
 See KM Spec section 3 and 6.2 for more details.
 
+The guest policy can be provided via the 'policy' property (see below)
+
+# ${QEMU} \
+   sev-guest,id=sev0,policy=0x1...\
+
 Guest owners provided DH certificate and session parameters will be used to
 establish a cryptographic session with the guest owner to negotiate keys used
 for the attestation.
 
+The DH certificate and session blob can be provided via 'dh-cert-file' and
+'session-file' property (see below
+
+# ${QEMU} \
+     sev-guest,id=sev0,dh-cert-file=<file1>,session-file=<file2>
+
 LAUNCH_UPDATE_DATA encrypts the memory region using the cryptographic context
 created via LAUNCH_START command. If required, this command can be called
 multiple times to encrypt different memory regions. The command also calculates
@@ -59,6 +70,12 @@ context.
 See SEV KM API Spec [1] 'Launching a guest' usage flow (Appendix A) for the
 complete flow chart.
 
+To launch a SEV guest
+
+# ${QEMU} \
+    -machine ...,memory-encryption=sev0 \
+    -object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=5
+
 Debugging
 -----------
 Since memory contents of SEV guest is encrypted hence hypervisor access to the
diff --git a/qemu-options.hx b/qemu-options.hx
index a6648ca073f2..f961b62bcbb2 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4313,6 +4313,50 @@ contents of @code{iv.b64} to the second secret
          data=$SECRET,iv=$(<iv.b64)
 @end example
 
+@item -object sev-guest,id=@var{id},cbitpos=@var{cbitpos},reduced-phys-bits=@var{val},[sev-device=@var{string},policy=@var{policy},handle=@var{handle},dh-cert-file=@var{file},session-file=@var{file}]
+
+Create a Secure Encrypted Virtualization (SEV) guest object, which can be used
+to provide the guest memory encryption support on AMD processors.
+
+When memory encryption is enabled, one of the physical address bit (aka the
+C-bit) is utilized to mark if a memory page is protected. The @option{cbitpos}
+is used to provide the C-bit position. The C-bit position is Host family dependent
+hence user must provide this value. On EPYC, the value should be 47.
+
+When memory encryption is enabled, we loose certain bits in physical address space.
+The @option{reduced-phys-bits} is used to provide the number of bits we loose in
+physical address space. Similar to C-bit, the value is Host family dependent.
+On EPYC, the value should be 5.
+
+The @option{sev-device} provides the device file to use for communicating with
+the SEV firmware running inside AMD Secure Processor. The default device is
+'/dev/sev'. If hardware supports memory encryption then /dev/sev devices are
+created by CCP driver.
+
+The @option{policy} provides the guest policy to be enforced by the SEV firmware
+and restrict what configuration and operational commands can be performed on this
+guest by the hypervisor. The policy should be provided by the guest owner and is
+bound to the guest and cannot be changed throughout the lifetime of the guest.
+The default is 0.
+
+If guest @option{policy} allows sharing the key with another SEV guest then
+@option{handle} can be use to provide handle of the guest from which to share
+the key.
+
+The @option{dh-cert-file} and @option{session-file} provides the guest owner's
+Public Diffie-Hillman key defined in SEV spec. The PDH and session parameters
+are used for establishing a cryptographic session with the guest owner to
+negotiate keys used for attestation. The file must be encoded in base64.
+
+e.g to launch a SEV guest
+@example
+ # $QEMU \
+     ......
+     -object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=5 \
+     -machine ...,memory-encryption=sev0
+     .....
+
+@end example
 @end table
 
 ETEXI
diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs
index f5c6ef20a7bb..76aeaeae2750 100644
--- a/target/i386/Makefile.objs
+++ b/target/i386/Makefile.objs
@@ -4,7 +4,7 @@ obj-$(CONFIG_TCG) += bpt_helper.o cc_helper.o excp_helper.o fpu_helper.o
 obj-$(CONFIG_TCG) += int_helper.o mem_helper.o misc_helper.o mpx_helper.o
 obj-$(CONFIG_TCG) += seg_helper.o smm_helper.o svm_helper.o
 obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o monitor.o
-obj-$(CONFIG_KVM) += kvm.o hyperv.o
+obj-$(CONFIG_KVM) += kvm.o hyperv.o sev.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
 # HAX support
 ifdef CONFIG_WIN32
diff --git a/target/i386/sev.c b/target/i386/sev.c
new file mode 100644
index 000000000000..ab42e4a456d2
--- /dev/null
+++ b/target/i386/sev.c
@@ -0,0 +1,228 @@
+/*
+ * QEMU SEV support
+ *
+ * Copyright Advanced Micro Devices 2016-2018
+ *
+ * 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 "qapi/error.h"
+#include "qom/object_interfaces.h"
+#include "qemu/base64.h"
+#include "sysemu/kvm.h"
+#include "sev_i386.h"
+#include "sysemu/sysemu.h"
+
+#define DEFAULT_GUEST_POLICY    0x1 /* disable debug */
+#define DEFAULT_SEV_DEVICE      "/dev/sev"
+
+static void
+qsev_guest_finalize(Object *obj)
+{
+}
+
+static char *
+qsev_guest_get_session_file(Object *obj, Error **errp)
+{
+    QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+
+    return s->session_file ? g_strdup(s->session_file) : NULL;
+}
+
+static void
+qsev_guest_set_session_file(Object *obj, const char *value, Error **errp)
+{
+    QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+
+    s->session_file = g_strdup(value);
+}
+
+static char *
+qsev_guest_get_dh_cert_file(Object *obj, Error **errp)
+{
+    QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+
+    return g_strdup(s->dh_cert_file);
+}
+
+static void
+qsev_guest_set_dh_cert_file(Object *obj, const char *value, Error **errp)
+{
+    QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+
+    s->dh_cert_file = g_strdup(value);
+}
+
+static char *
+qsev_guest_get_sev_device(Object *obj, Error **errp)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    return g_strdup(sev->sev_device);
+}
+
+static void
+qsev_guest_set_sev_device(Object *obj, const char *value, Error **errp)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    sev->sev_device = g_strdup(value);
+}
+
+static void
+qsev_guest_class_init(ObjectClass *oc, void *data)
+{
+    object_class_property_add_str(oc, "sev-device",
+                                  qsev_guest_get_sev_device,
+                                  qsev_guest_set_sev_device,
+                                  NULL);
+    object_class_property_set_description(oc, "sev-device",
+            "SEV device to use", NULL);
+    object_class_property_add_str(oc, "dh-cert-file",
+                                  qsev_guest_get_dh_cert_file,
+                                  qsev_guest_set_dh_cert_file,
+                                  NULL);
+    object_class_property_set_description(oc, "dh-cert-file",
+            "guest owners DH certificate (encoded with base64)", NULL);
+    object_class_property_add_str(oc, "session-file",
+                                  qsev_guest_get_session_file,
+                                  qsev_guest_set_session_file,
+                                  NULL);
+    object_class_property_set_description(oc, "session-file",
+            "guest owners session parameters (encoded with base64)", NULL);
+}
+
+static void
+qsev_guest_set_handle(Object *obj, Visitor *v, const char *name,
+                      void *opaque, Error **errp)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+    uint32_t value;
+
+    visit_type_uint32(v, name, &value, errp);
+    sev->handle = value;
+}
+
+static void
+qsev_guest_set_policy(Object *obj, Visitor *v, const char *name,
+                      void *opaque, Error **errp)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+    uint32_t value;
+
+    visit_type_uint32(v, name, &value, errp);
+    sev->policy = value;
+}
+
+static void
+qsev_guest_set_cbitpos(Object *obj, Visitor *v, const char *name,
+                       void *opaque, Error **errp)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+    uint32_t value;
+
+    visit_type_uint32(v, name, &value, errp);
+    sev->cbitpos = value;
+}
+
+static void
+qsev_guest_set_reduced_phys_bits(Object *obj, Visitor *v, const char *name,
+                                   void *opaque, Error **errp)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+    uint32_t value;
+
+    visit_type_uint32(v, name, &value, errp);
+    sev->reduced_phys_bits = value;
+}
+
+static void
+qsev_guest_get_policy(Object *obj, Visitor *v, const char *name,
+                      void *opaque, Error **errp)
+{
+    uint32_t value;
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    value = sev->policy;
+    visit_type_uint32(v, name, &value, errp);
+}
+
+static void
+qsev_guest_get_handle(Object *obj, Visitor *v, const char *name,
+                      void *opaque, Error **errp)
+{
+    uint32_t value;
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    value = sev->handle;
+    visit_type_uint32(v, name, &value, errp);
+}
+
+static void
+qsev_guest_get_cbitpos(Object *obj, Visitor *v, const char *name,
+                       void *opaque, Error **errp)
+{
+    uint32_t value;
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    value = sev->cbitpos;
+    visit_type_uint32(v, name, &value, errp);
+}
+
+static void
+qsev_guest_get_reduced_phys_bits(Object *obj, Visitor *v, const char *name,
+                                   void *opaque, Error **errp)
+{
+    uint32_t value;
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    value = sev->reduced_phys_bits;
+    visit_type_uint32(v, name, &value, errp);
+}
+
+static void
+qsev_guest_init(Object *obj)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE);
+    sev->policy = DEFAULT_GUEST_POLICY;
+    object_property_add(obj, "policy", "uint32", qsev_guest_get_policy,
+                        qsev_guest_set_policy, NULL, NULL, NULL);
+    object_property_add(obj, "handle", "uint32", qsev_guest_get_handle,
+                        qsev_guest_set_handle, NULL, NULL, NULL);
+    object_property_add(obj, "cbitpos", "uint32", qsev_guest_get_cbitpos,
+                        qsev_guest_set_cbitpos, NULL, NULL, NULL);
+    object_property_add(obj, "reduced-phys-bits", "uint32",
+                        qsev_guest_get_reduced_phys_bits,
+                        qsev_guest_set_reduced_phys_bits, NULL, NULL, NULL);
+}
+
+/* sev guest info */
+static const TypeInfo qsev_guest_info = {
+    .parent = TYPE_OBJECT,
+    .name = TYPE_QSEV_GUEST_INFO,
+    .instance_size = sizeof(QSevGuestInfo),
+    .instance_finalize = qsev_guest_finalize,
+    .class_size = sizeof(QSevGuestInfoClass),
+    .class_init = qsev_guest_class_init,
+    .instance_init = qsev_guest_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+static void
+sev_register_types(void)
+{
+    type_register_static(&qsev_guest_info);
+}
+
+type_init(sev_register_types);
diff --git a/target/i386/sev_i386.h b/target/i386/sev_i386.h
new file mode 100644
index 000000000000..caf879c3b874
--- /dev/null
+++ b/target/i386/sev_i386.h
@@ -0,0 +1,61 @@
+/*
+ * QEMU Secure Encrypted Virutualization (SEV) support
+ *
+ * Copyright: Advanced Micro Devices, 2016-2018
+ *
+ * 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_I386_H
+#define QEMU_SEV_I386_H
+
+#include "qom/object.h"
+#include "qapi/error.h"
+#include "sysemu/kvm.h"
+#include "qemu/error-report.h"
+
+#define SEV_POLICY_NODBG        0x1
+#define SEV_POLICY_NOKS         0x2
+#define SEV_POLICY_ES           0x4
+#define SEV_POLICY_NOSEND       0x8
+#define SEV_POLICY_DOMAIN       0x10
+#define SEV_POLICY_SEV          0x20
+
+#define TYPE_QSEV_GUEST_INFO "sev-guest"
+#define QSEV_GUEST_INFO(obj)                  \
+    OBJECT_CHECK(QSevGuestInfo, (obj), TYPE_QSEV_GUEST_INFO)
+
+typedef struct QSevGuestInfo QSevGuestInfo;
+typedef struct QSevGuestInfoClass QSevGuestInfoClass;
+
+/**
+ * QSevGuestInfo:
+ *
+ * The QSevGuestInfo object is used for creating a SEV guest.
+ *
+ * # $QEMU \
+ *         -object sev-guest,id=sev0 \
+ *         -machine ...,memory-encryption=sev0
+ */
+struct QSevGuestInfo {
+    Object parent_obj;
+
+    char *sev_device;
+    uint32_t policy;
+    uint32_t handle;
+    char *dh_cert_file;
+    char *session_file;
+    uint32_t cbitpos;
+    uint32_t reduced_phys_bits;
+};
+
+struct QSevGuestInfoClass {
+    ObjectClass parent_class;
+};
+
+#endif
-- 
2.14.3

  parent reply	other threads:[~2018-02-28 21:10 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-28 21:10 [PATCH v10 00/29] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
2018-02-28 21:10 ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 01/28] memattrs: add debug attribute Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 02/28] exec: add ram_debug_ops support Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 03/28] exec: add debug version of physical memory read and write API Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 04/28] monitor/i386: use debug APIs when accessing guest memory Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 05/28] machine: add -memory-encryption property Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 06/28] kvm: update kvm.h to include memory encryption ioctls Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 07/28] docs: add AMD Secure Encrypted Virtualization (SEV) Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` Brijesh Singh [this message]
2018-02-28 21:10   ` [Qemu-devel] [PATCH v10 08/28] target/i386: add Secure Encrypted Virtulization (SEV) object Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 09/28] qmp: add query-sev command Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-03-01 20:09   ` Eric Blake
2018-03-01 20:09     ` [Qemu-devel] " Eric Blake
2018-02-28 21:10 ` [PATCH v10 10/28] include: add psp-sev.h header file Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 11/28] sev/i386: add command to initialize the memory encryption context Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-03-05 13:37   ` Laszlo Ersek
2018-03-05 13:37     ` [Qemu-devel] " Laszlo Ersek
2018-03-07 13:19     ` Brijesh Singh
2018-03-07 13:19       ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 12/28] sev/i386: register the guest memory range which may contain encrypted data Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 13/28] kvm: introduce memory encryption APIs Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 14/28] hmp: add 'info sev' command Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-03-02 11:31   ` Dr. David Alan Gilbert
2018-03-02 11:31     ` [Qemu-devel] " Dr. David Alan Gilbert
2018-02-28 21:10 ` [PATCH v10 15/28] sev/i386: add command to create launch memory encryption context Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 16/28] sev/i386: add command to encrypt guest memory region Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 17/28] target/i386: encrypt bios rom Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 18/28] sev/i386: add support to LAUNCH_MEASURE command Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 19/28] sev/i386: finalize the SEV guest launch flow Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 20/28] hw/i386: set ram_debug_ops when memory encryption is enabled Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 21/28] sev/i386: add debug encrypt and decrypt commands Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 22/28] target/i386: clear C-bit when walking SEV guest page table Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 23/28] qmp: add query-sev-launch-measure command Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-03-01 20:11   ` Eric Blake
2018-03-01 20:11     ` [Qemu-devel] " Eric Blake
2018-02-28 21:10 ` [PATCH v10 24/28] sev/i386: add migration blocker Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 25/28] cpu/i386: populate CPUID 0x8000_001F when SEV is active Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-03-06 12:39   ` Eduardo Habkost
2018-03-06 12:39     ` [Qemu-devel] " Eduardo Habkost
2018-02-28 21:10 ` [PATCH v10 26/28] qmp: add query-sev-capabilities command Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-03-01 20:13   ` Eric Blake
2018-03-01 20:13     ` [Qemu-devel] " Eric Blake
2018-03-05 17:35     ` Brijesh Singh
2018-03-05 17:35       ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 27/28] sev/i386: add sev_get_capabilities() Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:10 ` [PATCH v10 28/28] tests/qmp-test: blacklist sev specific qmp commands Brijesh Singh
2018-02-28 21:10   ` [Qemu-devel] " Brijesh Singh
2018-02-28 21:43 ` [PATCH v10 00/29] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
2018-02-28 21:43   ` [Qemu-devel] " Brijesh Singh

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=20180228211028.83970-9-brijesh.singh@amd.com \
    --to=brijesh.singh@amd.com \
    --cc=Thomas.Lendacky@amd.com \
    --cc=agraf@suse.de \
    --cc=alistair.francis@xilinx.com \
    --cc=armbru@redhat.com \
    --cc=borntraeger@de.ibm.com \
    --cc=bp@suse.de \
    --cc=brogers@suse.com \
    --cc=cornelia.huck@de.ibm.com \
    --cc=crosthwaite.peter@gmail.com \
    --cc=dgilbert@redhat.com \
    --cc=edgar.iglesias@xilinx.com \
    --cc=ehabkost@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=marcel@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=rth@twiddle.net \
    --cc=stefanha@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.