qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Daniel P. Berrange" <berrange@redhat.com>
To: Brijesh Singh <brijesh.singh@amd.com>
Cc: 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: Re: [Qemu-devel] [RFC PATCH v1 06/22] sev: add initial SEV support
Date: Wed, 14 Sep 2016 09:37:15 +0100	[thread overview]
Message-ID: <20160914083715.GD28399@redhat.com> (raw)
In-Reply-To: <147377806784.11859.11149856529336910514.stgit@brijesh-build-machine>

On Tue, Sep 13, 2016 at 10:47:47AM -0400, Brijesh Singh wrote:
> 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"

We do not want to be inventing new config options for this - we should
be using QOM via -object to create this.



> 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;
> +    }

Use 'g_new0' for allocation and dont check the return
value since g_new0 aborts on oom.

> +
> +    if (!strcmp(type, "unencrypted")) {
> +        sev_info->type = UNENCRYPTED_GUEST;
> +    } else if (!strcmp(type, "encrypted")) {
> +        sev_info->type = PRE_ENCRYPTED_GUEST;

You should define an enum in qapi-schema.json for these
values, and use an enum property for 'type' in the QOM
object you then create. This automatically then handles
the string <-> int conversion

> +    } 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;
> +}

All the command line argument handling in this file should be removed.
Instead you should define a user creatable object type to represent
the properties you need to have configured. If you want a simple
example of how to define a QOM object type, take a look at the code
in crypto/secret.c


Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|

  parent reply	other threads:[~2016-09-14  8:37 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 ` [Qemu-devel] [RFC PATCH v1 06/22] sev: add initial SEV support Brijesh Singh
2016-09-13 15:58   ` 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 [this message]
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=20160914083715.GD28399@redhat.com \
    --to=berrange@redhat.com \
    --cc=armbru@redhat.com \
    --cc=brijesh.singh@amd.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).