diff mbox

[RFC,v1,09/22] sev: add SEV launch finish command

Message ID 147377809806.11859.4375323376894641953.stgit@brijesh-build-machine (mailing list archive)
State New, archived
Headers show

Commit Message

Brijesh Singh Sept. 13, 2016, 2:48 p.m. UTC
The SEV LAUNCH_FINISH command is used for finalizing the guest launch
process. The commad returned a measurement value that can be handed to
the guest owner to validate the guest before vmrun.

For more information see [1], section 6.3

[1] http://support.amd.com/TechDocs/55766_SEV-KM%20API_Spec.pdf

The following KVM RFC patches defines and implements this command
http://marc.info/?l=kvm&m=147190852423972&w=2
http://marc.info/?l=kvm&m=147190856623987&w=2

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 include/sysemu/sev.h |   17 +++++++++++++-
 sev.c                |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+), 1 deletion(-)

Comments

Eduardo Habkost Sept. 13, 2016, 10:15 p.m. UTC | #1
On Tue, Sep 13, 2016 at 10:48:18AM -0400, Brijesh Singh wrote:
> The SEV LAUNCH_FINISH command is used for finalizing the guest launch
> process. The commad returned a measurement value that can be handed to
> the guest owner to validate the guest before vmrun.
> 
> For more information see [1], section 6.3
> 
> [1] http://support.amd.com/TechDocs/55766_SEV-KM%20API_Spec.pdf
> 
> The following KVM RFC patches defines and implements this command
> http://marc.info/?l=kvm&m=147190852423972&w=2
> http://marc.info/?l=kvm&m=147190856623987&w=2
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
[...]
> +int kvm_sev_guest_measurement(uint8_t *out)

I don't see any code calling this function yet. Do you have any
plans on how exactly this will be handed back to the guest owner?
A QMP command?

> +{
> +    SEVInfo *s = sev_info;
> +    struct kvm_sev_launch_finish *finish = s->launch_finish;
> +
> +    if (!s) {
> +        return 1;
> +    }
> +
> +    if (s->type == UNENCRYPTED_GUEST &&
> +            s->state == SEV_LAUNCH_FINISH) {
> +        memcpy(out, finish->measurement, 32);
> +    } else {
> +        return 1;

Probably it would be more appropriate to use Error** to report
errors in most of the code in this series.

> +    }
> +
> +    return 0;
> +}
>
diff mbox

Patch

diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
index b58a9d7..ab03c5d 100644
--- a/include/sysemu/sev.h
+++ b/include/sysemu/sev.h
@@ -39,5 +39,20 @@  int kvm_sev_guest_start(void);
  */
 int kvm_sev_guest_update(uint8_t *address, uint32_t len);
 
-#endif
+/**
+ * kvm_sev_guest_finish - finialize launching guest into SEV mode.
+ */
+int kvm_sev_guest_finish(void);
 
+/**
+ * kvm_sev_guest_get_measurement - get measurement from launch finish command.
+ *
+ * @measurement: measurement values returned from the SEV. Its 32-byte value
+ * and buffer must be allocated by caller.
+ *
+ * Returns: 0 on success and @measurement will contain the value, or
+ *          1 on failure.
+ */
+int kvm_sev_guest_measurement(uint8_t *measurement);
+
+#endif
diff --git a/sev.c b/sev.c
index a451dc0..055ed83 100644
--- a/sev.c
+++ b/sev.c
@@ -48,6 +48,7 @@ 
 
 enum {
     SEV_LAUNCH_START = 0x1,
+    SEV_LAUNCH_FINISH,
 };
 
 struct SEVInfo {
@@ -326,6 +327,32 @@  static int sev_launch_update(uint8_t *addr, uint32_t len)
     return 0;
 }
 
+static int sev_launch_finish(void)
+{
+    int i, ret;
+    SEVInfo *s = sev_info;
+    struct kvm_sev_issue_cmd input;
+    struct kvm_sev_launch_finish *finish = s->launch_finish;
+
+    input.cmd = KVM_SEV_LAUNCH_FINISH;
+    input.opaque = (__u64)finish;
+    ret = kvm_vm_ioctl(kvm_state, KVM_SEV_ISSUE_CMD, &input);
+    if (ret) {
+        fprintf(stderr, "SEV: launch_finish failed ret=%d(%#010x)\n",
+                ret, input.ret_code);
+        exit(EXIT_FAILURE);
+    }
+
+    DPRINTF("SEV: LAUNCH finish measurement=0x");
+    for (i = 0; i < 32; i++) {
+        DPRINTF("%02x", finish->measurement[i]);
+    }
+    DPRINTF("\n");
+
+    s->state = SEV_LAUNCH_FINISH;
+    return 0;
+}
+
 int kvm_sev_guest_start(void)
 {
     SEVInfo *s = sev_info;
@@ -371,3 +398,37 @@  int kvm_sev_guest_update(uint8_t *addr, uint32_t len)
 
     return 1;
 }
+
+int kvm_sev_guest_finish(void)
+{
+    SEVInfo *s = sev_info;
+
+    if (!s) {
+        return 1;
+    }
+
+    if (s->state == SEV_LAUNCH_START) {
+        return sev_launch_finish();
+    }
+
+    return 1;
+}
+
+int kvm_sev_guest_measurement(uint8_t *out)
+{
+    SEVInfo *s = sev_info;
+    struct kvm_sev_launch_finish *finish = s->launch_finish;
+
+    if (!s) {
+        return 1;
+    }
+
+    if (s->type == UNENCRYPTED_GUEST &&
+            s->state == SEV_LAUNCH_FINISH) {
+        memcpy(out, finish->measurement, 32);
+    } else {
+        return 1;
+    }
+
+    return 0;
+}