From patchwork Fri Dec 4 05:44:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11950623 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A17D2C0018C for ; Fri, 4 Dec 2020 05:45:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4C9BA224BE for ; Fri, 4 Dec 2020 05:45:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728121AbgLDFpA (ORCPT ); Fri, 4 Dec 2020 00:45:00 -0500 Received: from bilbo.ozlabs.org ([203.11.71.1]:51703 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728108AbgLDFpA (ORCPT ); Fri, 4 Dec 2020 00:45:00 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 4CnM8f6LNcz9sSs; Fri, 4 Dec 2020 16:44:18 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1607060658; bh=TI0InttZ4cpldxy+Is/TnhjLzGIsGHaeLN81S9U7Zsg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D2OoZAh2yLriCG90unCBwKyMskSc/APR+ROuvB7A5a/UzSm3GKMPtumVEk+EN8dF9 1N41Mi1ebQNPsiZtXIIjgDar2WWHr27OOQW+E/ox29F+dxRDxo7hORY+JZp+Vtkh7d bot4qHvcnMbfOtshTQnIjVYFywa38eiC5mOK9V7I= From: David Gibson To: pair@us.ibm.com, pbonzini@redhat.com, frankja@linux.ibm.com, brijesh.singh@amd.com, dgilbert@redhat.com, qemu-devel@nongnu.org Cc: Eduardo Habkost , qemu-ppc@nongnu.org, rth@twiddle.net, thuth@redhat.com, berrange@redhat.com, mdroth@linux.vnet.ibm.com, Marcelo Tosatti , "Michael S. Tsirkin" , Marcel Apfelbaum , david@redhat.com, Richard Henderson , borntraeger@de.ibm.com, David Gibson , cohuck@redhat.com, kvm@vger.kernel.org, qemu-s390x@nongnu.org, pasic@linux.ibm.com, Greg Kurz Subject: [for-6.0 v5 01/13] qom: Allow optional sugar props Date: Fri, 4 Dec 2020 16:44:03 +1100 Message-Id: <20201204054415.579042-2-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201204054415.579042-1-david@gibson.dropbear.id.au> References: <20201204054415.579042-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Greg Kurz Global properties have an @optional field, which allows to apply a given property to a given type even if one of its subclasses doesn't support it. This is especially used in the compat code when dealing with the "disable-modern" and "disable-legacy" properties and the "virtio-pci" type. Allow object_register_sugar_prop() to set this field as well. Signed-off-by: Greg Kurz Message-Id: <159738953558.377274.16617742952571083440.stgit@bahia.lan> Signed-off-by: David Gibson Reviewed-by: Cornelia Huck Reviewed-by: Eduardo Habkost Reviewed-by: Philippe Mathieu-Daudé --- include/qom/object.h | 3 ++- qom/object.c | 4 +++- softmmu/vl.c | 16 ++++++++++------ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/include/qom/object.h b/include/qom/object.h index d378f13a11..6721cd312e 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -638,7 +638,8 @@ bool object_apply_global_props(Object *obj, const GPtrArray *props, Error **errp); void object_set_machine_compat_props(GPtrArray *compat_props); void object_set_accelerator_compat_props(GPtrArray *compat_props); -void object_register_sugar_prop(const char *driver, const char *prop, const char *value); +void object_register_sugar_prop(const char *driver, const char *prop, + const char *value, bool optional); void object_apply_compat_props(Object *obj); /** diff --git a/qom/object.c b/qom/object.c index 1065355233..62218bb17d 100644 --- a/qom/object.c +++ b/qom/object.c @@ -442,7 +442,8 @@ static GPtrArray *object_compat_props[3]; * other than "-global". These are generally used for syntactic * sugar and legacy command line options. */ -void object_register_sugar_prop(const char *driver, const char *prop, const char *value) +void object_register_sugar_prop(const char *driver, const char *prop, + const char *value, bool optional) { GlobalProperty *g; if (!object_compat_props[2]) { @@ -452,6 +453,7 @@ void object_register_sugar_prop(const char *driver, const char *prop, const char g->driver = g_strdup(driver); g->property = g_strdup(prop); g->value = g_strdup(value); + g->optional = optional; g_ptr_array_add(object_compat_props[2], g); } diff --git a/softmmu/vl.c b/softmmu/vl.c index e6e0ad5a92..cf4a9dc198 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -884,7 +884,7 @@ static void configure_rtc(QemuOpts *opts) if (!strcmp(value, "slew")) { object_register_sugar_prop("mc146818rtc", "lost_tick_policy", - "slew"); + "slew", false); } else if (!strcmp(value, "none")) { /* discard is default */ } else { @@ -2498,12 +2498,14 @@ static int machine_set_property(void *opaque, return 0; } if (g_str_equal(qom_name, "igd-passthru")) { - object_register_sugar_prop(ACCEL_CLASS_NAME("xen"), qom_name, value); + object_register_sugar_prop(ACCEL_CLASS_NAME("xen"), qom_name, value, + false); return 0; } if (g_str_equal(qom_name, "kvm-shadow-mem") || g_str_equal(qom_name, "kernel-irqchip")) { - object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), qom_name, value); + object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), qom_name, value, + false); return 0; } @@ -3645,7 +3647,8 @@ void qemu_init(int argc, char **argv, char **envp) exit(1); #endif warn_report("The -tb-size option is deprecated, use -accel tcg,tb-size instead"); - object_register_sugar_prop(ACCEL_CLASS_NAME("tcg"), "tb-size", optarg); + object_register_sugar_prop(ACCEL_CLASS_NAME("tcg"), "tb-size", + optarg, false); break; case QEMU_OPTION_icount: icount_opts = qemu_opts_parse_noisily(qemu_find_opts("icount"), @@ -3996,9 +3999,10 @@ void qemu_init(int argc, char **argv, char **envp) char *val; val = g_strdup_printf("%d", current_machine->smp.cpus); - object_register_sugar_prop("memory-backend", "prealloc-threads", val); + object_register_sugar_prop("memory-backend", "prealloc-threads", val, + false); g_free(val); - object_register_sugar_prop("memory-backend", "prealloc", "on"); + object_register_sugar_prop("memory-backend", "prealloc", "on", false); } /* From patchwork Fri Dec 4 05:44:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11950617 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2A4C3C1B087 for ; Fri, 4 Dec 2020 05:45:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DB395224BE for ; Fri, 4 Dec 2020 05:45:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728142AbgLDFpC (ORCPT ); Fri, 4 Dec 2020 00:45:02 -0500 Received: from bilbo.ozlabs.org ([203.11.71.1]:54907 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727038AbgLDFpC (ORCPT ); Fri, 4 Dec 2020 00:45:02 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 4CnM8g0J6bz9sVH; Fri, 4 Dec 2020 16:44:18 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1607060659; bh=JCKtB0CAUo5qRhgGPlJh6hWPpcLzzkSJ/S2kZoA7KMQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UK+tvDTtyfxmDLRI1BAo0CZOnx4vxpzL2ZSR9EavNEYV8rsCiD4Ahf6FzorpORjPR 5iq+XMnBiZjBVkSaBKRqvbQdUmMhG9Le7wBJAyBPVRvKIDDi+T4IlayTd/RhuvWBbH vB7aVZL1gPhz5FhRTPgdufirAHWHgPqjTZAQXP64= From: David Gibson To: pair@us.ibm.com, pbonzini@redhat.com, frankja@linux.ibm.com, brijesh.singh@amd.com, dgilbert@redhat.com, qemu-devel@nongnu.org Cc: Eduardo Habkost , qemu-ppc@nongnu.org, rth@twiddle.net, thuth@redhat.com, berrange@redhat.com, mdroth@linux.vnet.ibm.com, Marcelo Tosatti , "Michael S. Tsirkin" , Marcel Apfelbaum , david@redhat.com, Richard Henderson , borntraeger@de.ibm.com, David Gibson , cohuck@redhat.com, kvm@vger.kernel.org, qemu-s390x@nongnu.org, pasic@linux.ibm.com Subject: [for-6.0 v5 02/13] securable guest memory: Introduce new securable guest memory base class Date: Fri, 4 Dec 2020 16:44:04 +1100 Message-Id: <20201204054415.579042-3-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201204054415.579042-1-david@gibson.dropbear.id.au> References: <20201204054415.579042-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Several architectures have mechanisms which are designed to protect guest memory from interference or eavesdropping by a compromised hypervisor. AMD SEV does this with in-chip memory encryption and Intel's MKTME can do similar things. POWER's Protected Execution Framework (PEF) accomplishes a similar goal using an ultravisor and new memory protection features, instead of encryption. To (partially) unify handling for these, this introduces a new SecurableGuestMemoryState QOM base class. "Securable" is kind of vague, but "secure memory" or "secure guest" seems to be a common theme in the lexicon around these schemes, so it's the best name I've managed to find so far. It's "securable" rather than "secure", because in at least some of the cases it requires the guest to take specific actions in order to protect itself from hypervisor eavesdropping. Signed-off-by: David Gibson --- backends/meson.build | 1 + backends/securable-guest-memory.c | 30 +++++++++++++++++ include/exec/securable-guest-memory.h | 46 +++++++++++++++++++++++++++ include/qemu/typedefs.h | 1 + target/i386/sev.c | 3 +- 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 backends/securable-guest-memory.c create mode 100644 include/exec/securable-guest-memory.h diff --git a/backends/meson.build b/backends/meson.build index 484456ece7..781594af86 100644 --- a/backends/meson.build +++ b/backends/meson.build @@ -6,6 +6,7 @@ softmmu_ss.add([files( 'rng-builtin.c', 'rng-egd.c', 'rng.c', + 'securable-guest-memory.c', ), numa]) softmmu_ss.add(when: 'CONFIG_POSIX', if_true: files('rng-random.c')) diff --git a/backends/securable-guest-memory.c b/backends/securable-guest-memory.c new file mode 100644 index 0000000000..5bf380fd84 --- /dev/null +++ b/backends/securable-guest-memory.c @@ -0,0 +1,30 @@ +/* + * QEMU Securable Guest Memory interface + * + * Copyright: David Gibson, Red Hat Inc. 2020 + * + * Authors: + * David Gibson + * + * 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 "exec/securable-guest-memory.h" + +static const TypeInfo securable_guest_memory_info = { + .parent = TYPE_OBJECT, + .name = TYPE_SECURABLE_GUEST_MEMORY, + .class_size = sizeof(SecurableGuestMemoryClass), + .instance_size = sizeof(SecurableGuestMemory), +}; + +static void securable_guest_memory_register_types(void) +{ + type_register_static(&securable_guest_memory_info); +} + +type_init(securable_guest_memory_register_types) diff --git a/include/exec/securable-guest-memory.h b/include/exec/securable-guest-memory.h new file mode 100644 index 0000000000..0d5ecfb681 --- /dev/null +++ b/include/exec/securable-guest-memory.h @@ -0,0 +1,46 @@ +/* + * QEMU Securable Guest Memory interface + * This interface describes the common pieces between various + * schemes for protecting guest memory against a compromised + * hypervisor. This includes memory encryption (AMD's SEV and + * Intel's MKTME) or special protection modes (PEF on POWER, or PV + * on s390x). + * + * Copyright: David Gibson, Red Hat Inc. 2020 + * + * Authors: + * David Gibson + * + * 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_SECURABLE_GUEST_MEMORY_H +#define QEMU_SECURABLE_GUEST_MEMORY_H + +#ifndef CONFIG_USER_ONLY + +#include "qom/object.h" + +#define TYPE_SECURABLE_GUEST_MEMORY "securable-guest-memory" +#define SECURABLE_GUEST_MEMORY(obj) \ + OBJECT_CHECK(SecurableGuestMemory, (obj), \ + TYPE_SECURABLE_GUEST_MEMORY) +#define SECURABLE_GUEST_MEMORY_CLASS(klass) \ + OBJECT_CLASS_CHECK(SecurableGuestMemoryClass, (klass), \ + TYPE_SECURABLE_GUEST_MEMORY) +#define SECURABLE_GUEST_MEMORY_GET_CLASS(obj) \ + OBJECT_GET_CLASS(SecurableGuestMemoryClass, (obj), \ + TYPE_SECURABLE_GUEST_MEMORY) + +struct SecurableGuestMemory { + Object parent; +}; + +typedef struct SecurableGuestMemoryClass { + ObjectClass parent; +} SecurableGuestMemoryClass; + +#endif /* !CONFIG_USER_ONLY */ + +#endif /* QEMU_SECURABLE_GUEST_MEMORY_H */ diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 6281eae3b5..79d53746f1 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -116,6 +116,7 @@ typedef struct QString QString; typedef struct RAMBlock RAMBlock; typedef struct Range Range; typedef struct SavedIOTLB SavedIOTLB; +typedef struct SecurableGuestMemory SecurableGuestMemory; typedef struct SHPCDevice SHPCDevice; typedef struct SSIBus SSIBus; typedef struct VirtIODevice VirtIODevice; diff --git a/target/i386/sev.c b/target/i386/sev.c index 93c4d60b82..53f00a24cf 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -29,6 +29,7 @@ #include "trace.h" #include "migration/blocker.h" #include "qom/object.h" +#include "exec/securable-guest-memory.h" #define TYPE_SEV_GUEST "sev-guest" OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState, SEV_GUEST) @@ -320,7 +321,7 @@ sev_guest_instance_init(Object *obj) /* sev guest info */ static const TypeInfo sev_guest_info = { - .parent = TYPE_OBJECT, + .parent = TYPE_SECURABLE_GUEST_MEMORY, .name = TYPE_SEV_GUEST, .instance_size = sizeof(SevGuestState), .instance_finalize = sev_guest_finalize, From patchwork Fri Dec 4 05:44:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11950619 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 39741C1B0D8 for ; Fri, 4 Dec 2020 05:45:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 07EF822581 for ; Fri, 4 Dec 2020 05:45:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728145AbgLDFpD (ORCPT ); Fri, 4 Dec 2020 00:45:03 -0500 Received: from ozlabs.org ([203.11.71.1]:33121 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728110AbgLDFpB (ORCPT ); Fri, 4 Dec 2020 00:45:01 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 4CnM8g1c39z9sVM; Fri, 4 Dec 2020 16:44:19 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1607060659; bh=EqOeasdeFKvYiMfFo9qpcp5aqrwe2rucqzfY62bqd/Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OKzPjWmGd2EU3oSM+VSBLLWO+Ut+mIbLWGSdkd9OI9OMvqpcfYTsE72rZK4irMiYS pmBnnTYUGdnuinOkPe5JE9ScRaKUFUXrtVNNSI2zNwhsesBwaahn32oL3ByP1mj6sn SBMR5/zcFfk7DCJCtvaADFgvoyEnlDmYuR8Gjtqw= From: David Gibson To: pair@us.ibm.com, pbonzini@redhat.com, frankja@linux.ibm.com, brijesh.singh@amd.com, dgilbert@redhat.com, qemu-devel@nongnu.org Cc: Eduardo Habkost , qemu-ppc@nongnu.org, rth@twiddle.net, thuth@redhat.com, berrange@redhat.com, mdroth@linux.vnet.ibm.com, Marcelo Tosatti , "Michael S. Tsirkin" , Marcel Apfelbaum , david@redhat.com, Richard Henderson , borntraeger@de.ibm.com, David Gibson , cohuck@redhat.com, kvm@vger.kernel.org, qemu-s390x@nongnu.org, pasic@linux.ibm.com Subject: [for-6.0 v5 03/13] securable guest memory: Handle memory encryption via interface Date: Fri, 4 Dec 2020 16:44:05 +1100 Message-Id: <20201204054415.579042-4-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201204054415.579042-1-david@gibson.dropbear.id.au> References: <20201204054415.579042-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org At the moment AMD SEV sets a special function pointer, plus an opaque handle in KVMState to let things know how to encrypt guest memory. Now that we have a QOM interface for handling things related to securable guest memory, use a QOM method on that interface, rather than a bare function pointer for this. Signed-off-by: David Gibson Reviewed-by: Richard Henderson --- accel/kvm/kvm-all.c | 36 +++++--- accel/kvm/sev-stub.c | 9 +- include/exec/securable-guest-memory.h | 2 + include/sysemu/sev.h | 5 +- target/i386/monitor.c | 1 - target/i386/sev.c | 116 ++++++++++---------------- 6 files changed, 77 insertions(+), 92 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index baaa54249d..9e7cea64d6 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -47,6 +47,7 @@ #include "qemu/guest-random.h" #include "sysemu/hw_accel.h" #include "kvm-cpus.h" +#include "exec/securable-guest-memory.h" #include "hw/boards.h" @@ -120,9 +121,8 @@ struct KVMState KVMMemoryListener memory_listener; QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus; - /* memory encryption */ - void *memcrypt_handle; - int (*memcrypt_encrypt_data)(void *handle, uint8_t *ptr, uint64_t len); + /* securable guest memory (e.g. by guest memory encryption) */ + SecurableGuestMemory *sgm; /* For "info mtree -f" to tell if an MR is registered in KVM */ int nr_as; @@ -224,7 +224,7 @@ int kvm_get_max_memslots(void) bool kvm_memcrypt_enabled(void) { - if (kvm_state && kvm_state->memcrypt_handle) { + if (kvm_state && kvm_state->sgm) { return true; } @@ -233,10 +233,12 @@ bool kvm_memcrypt_enabled(void) int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len) { - if (kvm_state->memcrypt_handle && - kvm_state->memcrypt_encrypt_data) { - return kvm_state->memcrypt_encrypt_data(kvm_state->memcrypt_handle, - ptr, len); + SecurableGuestMemory *sgm = kvm_state->sgm; + + if (sgm) { + SecurableGuestMemoryClass *sgmc = SECURABLE_GUEST_MEMORY_GET_CLASS(sgm); + + return sgmc->encrypt_data(sgm, ptr, len); } return 1; @@ -2206,13 +2208,23 @@ static int kvm_init(MachineState *ms) * encryption context. */ if (ms->memory_encryption) { - kvm_state->memcrypt_handle = sev_guest_init(ms->memory_encryption); - if (!kvm_state->memcrypt_handle) { + Object *obj = object_resolve_path_component(object_get_objects_root(), + ms->memory_encryption); + + if (object_dynamic_cast(obj, TYPE_SECURABLE_GUEST_MEMORY)) { + SecurableGuestMemory *sgm = SECURABLE_GUEST_MEMORY(obj); + + /* FIXME handle mechanisms other than SEV */ + ret = sev_kvm_init(sgm); + if (ret < 0) { + goto err; + } + + kvm_state->sgm = sgm; + } else { ret = -1; goto err; } - - kvm_state->memcrypt_encrypt_data = sev_encrypt_data; } ret = kvm_arch_init(ms, s); diff --git a/accel/kvm/sev-stub.c b/accel/kvm/sev-stub.c index 4f97452585..3df3c88eeb 100644 --- a/accel/kvm/sev-stub.c +++ b/accel/kvm/sev-stub.c @@ -15,12 +15,7 @@ #include "qemu-common.h" #include "sysemu/sev.h" -int sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len) +int sev_kvm_init(SecurableGuestMemory *sgm) { - abort(); -} - -void *sev_guest_init(const char *id) -{ - return NULL; + return -1; } diff --git a/include/exec/securable-guest-memory.h b/include/exec/securable-guest-memory.h index 0d5ecfb681..4e2ae27040 100644 --- a/include/exec/securable-guest-memory.h +++ b/include/exec/securable-guest-memory.h @@ -39,6 +39,8 @@ struct SecurableGuestMemory { typedef struct SecurableGuestMemoryClass { ObjectClass parent; + + int (*encrypt_data)(SecurableGuestMemory *, uint8_t *, uint64_t); } SecurableGuestMemoryClass; #endif /* !CONFIG_USER_ONLY */ diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h index 98c1ec8d38..36d038a36f 100644 --- a/include/sysemu/sev.h +++ b/include/sysemu/sev.h @@ -15,7 +15,8 @@ #define QEMU_SEV_H #include "sysemu/kvm.h" +#include "exec/securable-guest-memory.h" + +int sev_kvm_init(SecurableGuestMemory *sgm); -void *sev_guest_init(const char *id); -int sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len); #endif diff --git a/target/i386/monitor.c b/target/i386/monitor.c index 9f9e1c42f4..db6aeaf43a 100644 --- a/target/i386/monitor.c +++ b/target/i386/monitor.c @@ -29,7 +29,6 @@ #include "monitor/hmp.h" #include "qapi/qmp/qdict.h" #include "sysemu/kvm.h" -#include "sysemu/sev.h" #include "qapi/error.h" #include "sev_i386.h" #include "qapi/qapi-commands-misc-target.h" diff --git a/target/i386/sev.c b/target/i386/sev.c index 53f00a24cf..7b8ce590f7 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -281,26 +281,6 @@ sev_guest_set_sev_device(Object *obj, const char *value, Error **errp) sev->sev_device = g_strdup(value); } -static void -sev_guest_class_init(ObjectClass *oc, void *data) -{ - object_class_property_add_str(oc, "sev-device", - sev_guest_get_sev_device, - sev_guest_set_sev_device); - object_class_property_set_description(oc, "sev-device", - "SEV device to use"); - object_class_property_add_str(oc, "dh-cert-file", - sev_guest_get_dh_cert_file, - sev_guest_set_dh_cert_file); - object_class_property_set_description(oc, "dh-cert-file", - "guest owners DH certificate (encoded with base64)"); - object_class_property_add_str(oc, "session-file", - sev_guest_get_session_file, - sev_guest_set_session_file); - object_class_property_set_description(oc, "session-file", - "guest owners session parameters (encoded with base64)"); -} - static void sev_guest_instance_init(Object *obj) { @@ -319,40 +299,6 @@ sev_guest_instance_init(Object *obj) OBJ_PROP_FLAG_READWRITE); } -/* sev guest info */ -static const TypeInfo sev_guest_info = { - .parent = TYPE_SECURABLE_GUEST_MEMORY, - .name = TYPE_SEV_GUEST, - .instance_size = sizeof(SevGuestState), - .instance_finalize = sev_guest_finalize, - .class_init = sev_guest_class_init, - .instance_init = sev_guest_instance_init, - .interfaces = (InterfaceInfo[]) { - { TYPE_USER_CREATABLE }, - { } - } -}; - -static SevGuestState * -lookup_sev_guest_info(const char *id) -{ - Object *obj; - SevGuestState *info; - - obj = object_resolve_path_component(object_get_objects_root(), id); - if (!obj) { - return NULL; - } - - info = (SevGuestState *) - object_dynamic_cast(obj, TYPE_SEV_GUEST); - if (!info) { - return NULL; - } - - return info; -} - bool sev_enabled(void) { @@ -680,10 +626,9 @@ sev_vm_state_change(void *opaque, int running, RunState state) } } -void * -sev_guest_init(const char *id) +int sev_kvm_init(SecurableGuestMemory *sgm) { - SevGuestState *sev; + SevGuestState *sev = SEV_GUEST(sgm); char *devname; int ret, fw_error; uint32_t ebx; @@ -693,14 +638,7 @@ sev_guest_init(const char *id) ret = ram_block_discard_disable(true); if (ret) { error_report("%s: cannot disable RAM discard", __func__); - return NULL; - } - - sev = lookup_sev_guest_info(id); - if (!sev) { - error_report("%s: '%s' is not a valid '%s' object", - __func__, id, TYPE_SEV_GUEST); - goto err; + return -1; } sev_guest = sev; @@ -764,17 +702,17 @@ sev_guest_init(const char *id) qemu_add_machine_init_done_notifier(&sev_machine_done_notify); qemu_add_vm_change_state_handler(sev_vm_state_change, sev); - return sev; + return 0; err: sev_guest = NULL; ram_block_discard_disable(false); - return NULL; + return -1; } -int -sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len) +static int +sev_encrypt_data(SecurableGuestMemory *opaque, uint8_t *ptr, uint64_t len) { - SevGuestState *sev = handle; + SevGuestState *sev = SEV_GUEST(opaque); assert(sev); @@ -786,6 +724,44 @@ sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len) return 0; } +static void +sev_guest_class_init(ObjectClass *oc, void *data) +{ + SecurableGuestMemoryClass *sgmc = SECURABLE_GUEST_MEMORY_CLASS(oc); + + object_class_property_add_str(oc, "sev-device", + sev_guest_get_sev_device, + sev_guest_set_sev_device); + object_class_property_set_description(oc, "sev-device", + "SEV device to use"); + object_class_property_add_str(oc, "dh-cert-file", + sev_guest_get_dh_cert_file, + sev_guest_set_dh_cert_file); + object_class_property_set_description(oc, "dh-cert-file", + "guest owners DH certificate (encoded with base64)"); + object_class_property_add_str(oc, "session-file", + sev_guest_get_session_file, + sev_guest_set_session_file); + object_class_property_set_description(oc, "session-file", + "guest owners session parameters (encoded with base64)"); + + sgmc->encrypt_data = sev_encrypt_data; +} + +/* sev guest info */ +static const TypeInfo sev_guest_info = { + .parent = TYPE_SECURABLE_GUEST_MEMORY, + .name = TYPE_SEV_GUEST, + .instance_size = sizeof(SevGuestState), + .instance_finalize = sev_guest_finalize, + .class_init = sev_guest_class_init, + .instance_init = sev_guest_instance_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_USER_CREATABLE }, + { } + } +}; + static void sev_register_types(void) { From patchwork Fri Dec 4 05:44:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11950615 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DD250C4361A for ; Fri, 4 Dec 2020 05:45:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AE72E22582 for ; Fri, 4 Dec 2020 05:45:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728139AbgLDFpB (ORCPT ); Fri, 4 Dec 2020 00:45:01 -0500 Received: from bilbo.ozlabs.org ([203.11.71.1]:47925 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728113AbgLDFpB (ORCPT ); Fri, 4 Dec 2020 00:45:01 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 4CnM8g2SpYz9sVJ; Fri, 4 Dec 2020 16:44:19 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1607060659; bh=DufNN2QoL+zHTOOyZYmyfMEyCVasGlyYWJnPGHio2xg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ItGcEFo1XBNx33iOEaxvPtN8BFkaP68l7f632RBP0H7PHCnzcqj96bfTri/+kd6sy Y8aPJpdQNgQhEeInf12R05GozKTxQpBFn4xLXcN/rh1/qh6mFaUf7R2h1bVsyvrQfQ 0u2TR5JUp3BQacZCcMtlZwWmSdG3aHjQIiXwtSo4= From: David Gibson To: pair@us.ibm.com, pbonzini@redhat.com, frankja@linux.ibm.com, brijesh.singh@amd.com, dgilbert@redhat.com, qemu-devel@nongnu.org Cc: Eduardo Habkost , qemu-ppc@nongnu.org, rth@twiddle.net, thuth@redhat.com, berrange@redhat.com, mdroth@linux.vnet.ibm.com, Marcelo Tosatti , "Michael S. Tsirkin" , Marcel Apfelbaum , david@redhat.com, Richard Henderson , borntraeger@de.ibm.com, David Gibson , cohuck@redhat.com, kvm@vger.kernel.org, qemu-s390x@nongnu.org, pasic@linux.ibm.com Subject: [for-6.0 v5 04/13] securable guest memory: Move side effect out of machine_set_memory_encryption() Date: Fri, 4 Dec 2020 16:44:06 +1100 Message-Id: <20201204054415.579042-5-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201204054415.579042-1-david@gibson.dropbear.id.au> References: <20201204054415.579042-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org When the "memory-encryption" property is set, we also disable KSM merging for the guest, since it won't accomplish anything. We want that, but doing it in the property set function itself is thereoretically incorrect, in the unlikely event of some configuration environment that set the property then cleared it again before constructing the guest. More importantly, it makes some other cleanups we want more difficult. So, instead move this logic to machine_run_board_init() conditional on the final value of the property. Signed-off-by: David Gibson Reviewed-by: Richard Henderson --- hw/core/machine.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/hw/core/machine.c b/hw/core/machine.c index d0408049b5..cb0711508d 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -427,14 +427,6 @@ static void machine_set_memory_encryption(Object *obj, const char *value, g_free(ms->memory_encryption); ms->memory_encryption = g_strdup(value); - - /* - * With memory encryption, the host can't see the real contents of RAM, - * so there's no point in it trying to merge areas. - */ - if (value) { - machine_set_mem_merge(obj, false, errp); - } } static bool machine_get_nvdimm(Object *obj, Error **errp) @@ -1131,6 +1123,15 @@ void machine_run_board_init(MachineState *machine) cc->deprecation_note); } + if (machine->memory_encryption) { + /* + * With memory encryption, the host can't see the real + * contents of RAM, so there's no point in it trying to merge + * areas. + */ + machine_set_mem_merge(OBJECT(machine), false, &error_abort); + } + machine_class->init(machine); } From patchwork Fri Dec 4 05:44:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11950679 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E9BF9C1B0E3 for ; Fri, 4 Dec 2020 05:46:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C0212224BE for ; Fri, 4 Dec 2020 05:46:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728326AbgLDFpu (ORCPT ); Fri, 4 Dec 2020 00:45:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41036 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728203AbgLDFpo (ORCPT ); Fri, 4 Dec 2020 00:45:44 -0500 Received: from ozlabs.org (ozlabs.org [IPv6:2401:3900:2:1::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A2D20C061A52 for ; Thu, 3 Dec 2020 21:45:03 -0800 (PST) Received: by ozlabs.org (Postfix, from userid 1007) id 4CnM8g4ZGpz9sVS; Fri, 4 Dec 2020 16:44:19 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1607060659; bh=kdYvFLKM63q+FlqswmpyvW9PA1nGgs8gSeZCixeRoWI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eClbQXzs/c6c4HuFl4LzxegJDpJf85x/cwcWPj7nAcbbTTwime4OvFGJdL59mXx54 HzPQyeK1ID37Co+Q5w5bCkPtImzoohOtJ0eSYvB9wy64nv5h6iREEOuTuqrlF5eU4w qf3PSN6hhUcXPo0Eqc8idtr4Yme6Llsrzjm4xKlc= From: David Gibson To: pair@us.ibm.com, pbonzini@redhat.com, frankja@linux.ibm.com, brijesh.singh@amd.com, dgilbert@redhat.com, qemu-devel@nongnu.org Cc: Eduardo Habkost , qemu-ppc@nongnu.org, rth@twiddle.net, thuth@redhat.com, berrange@redhat.com, mdroth@linux.vnet.ibm.com, Marcelo Tosatti , "Michael S. Tsirkin" , Marcel Apfelbaum , david@redhat.com, Richard Henderson , borntraeger@de.ibm.com, David Gibson , cohuck@redhat.com, kvm@vger.kernel.org, qemu-s390x@nongnu.org, pasic@linux.ibm.com Subject: [for-6.0 v5 05/13] securable guest memory: Rework the "memory-encryption" property Date: Fri, 4 Dec 2020 16:44:07 +1100 Message-Id: <20201204054415.579042-6-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201204054415.579042-1-david@gibson.dropbear.id.au> References: <20201204054415.579042-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Currently the "memory-encryption" property is only looked at once we get to kvm_init(). Although protection of guest memory from the hypervisor isn't something that could really ever work with TCG, it's not conceptually tied to the KVM accelerator. In addition, the way the string property is resolved to an object is almost identical to how a QOM link property is handled. So, create a new "securable-guest-memory" link property which sets this QOM interface link directly in the machine. For compatibility we keep the "memory-encryption" property, but now implemented in terms of the new property. Signed-off-by: David Gibson Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé --- accel/kvm/kvm-all.c | 22 ++++++---------------- hw/core/machine.c | 43 +++++++++++++++++++++++++++++++++++++------ include/hw/boards.h | 2 +- 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 9e7cea64d6..92a49b328a 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2207,24 +2207,14 @@ static int kvm_init(MachineState *ms) * if memory encryption object is specified then initialize the memory * encryption context. */ - if (ms->memory_encryption) { - Object *obj = object_resolve_path_component(object_get_objects_root(), - ms->memory_encryption); - - if (object_dynamic_cast(obj, TYPE_SECURABLE_GUEST_MEMORY)) { - SecurableGuestMemory *sgm = SECURABLE_GUEST_MEMORY(obj); - - /* FIXME handle mechanisms other than SEV */ - ret = sev_kvm_init(sgm); - if (ret < 0) { - goto err; - } - - kvm_state->sgm = sgm; - } else { - ret = -1; + if (ms->sgm) { + /* FIXME handle mechanisms other than SEV */ + ret = sev_kvm_init(ms->sgm); + if (ret < 0) { goto err; } + + kvm_state->sgm = ms->sgm; } ret = kvm_arch_init(ms, s); diff --git a/hw/core/machine.c b/hw/core/machine.c index cb0711508d..816ea3ae3e 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -27,6 +27,7 @@ #include "hw/pci/pci.h" #include "hw/mem/nvdimm.h" #include "migration/vmstate.h" +#include "exec/securable-guest-memory.h" GlobalProperty hw_compat_5_1[] = { { "vhost-scsi", "num_queues", "1"}, @@ -417,16 +418,37 @@ static char *machine_get_memory_encryption(Object *obj, Error **errp) { MachineState *ms = MACHINE(obj); - return g_strdup(ms->memory_encryption); + if (ms->sgm) { + return g_strdup(object_get_canonical_path_component(OBJECT(ms->sgm))); + } + + return NULL; } static void machine_set_memory_encryption(Object *obj, const char *value, Error **errp) { - MachineState *ms = MACHINE(obj); + Object *sgm = + object_resolve_path_component(object_get_objects_root(), value); + + if (!sgm) { + error_setg(errp, "No such memory encryption object '%s'", value); + return; + } - g_free(ms->memory_encryption); - ms->memory_encryption = g_strdup(value); + object_property_set_link(obj, "securable-guest-memory", sgm, errp); +} + +static void machine_check_securable_guest_memory(const Object *obj, + const char *name, + Object *new_target, + Error **errp) +{ + /* + * So far the only constraint is that the target has the + * TYPE_SECURABLE_GUEST_MEMORY interface, and that's checked by + * the QOM core + */ } static bool machine_get_nvdimm(Object *obj, Error **errp) @@ -833,6 +855,15 @@ static void machine_class_init(ObjectClass *oc, void *data) object_class_property_set_description(oc, "suppress-vmdesc", "Set on to disable self-describing migration"); + object_class_property_add_link(oc, "securable-guest-memory", + TYPE_SECURABLE_GUEST_MEMORY, + offsetof(MachineState, sgm), + machine_check_securable_guest_memory, + OBJ_PROP_LINK_STRONG); + object_class_property_set_description(oc, "securable-guest-memory", + "Set securable guest memory scheme to use"); + + /* For compatibility */ object_class_property_add_str(oc, "memory-encryption", machine_get_memory_encryption, machine_set_memory_encryption); object_class_property_set_description(oc, "memory-encryption", @@ -1123,9 +1154,9 @@ void machine_run_board_init(MachineState *machine) cc->deprecation_note); } - if (machine->memory_encryption) { + if (machine->sgm) { /* - * With memory encryption, the host can't see the real + * With securable guest memory, the host can't see the real * contents of RAM, so there's no point in it trying to merge * areas. */ diff --git a/include/hw/boards.h b/include/hw/boards.h index a49e3a6b44..2ea9790183 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -269,7 +269,7 @@ struct MachineState { bool iommu; bool suppress_vmdesc; bool enable_graphics; - char *memory_encryption; + SecurableGuestMemory *sgm; char *ram_memdev_id; /* * convenience alias to ram_memdev_id backend memory region From patchwork Fri Dec 4 05:44:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11950669 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 00027C0018C for ; Fri, 4 Dec 2020 05:46:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C4C0322581 for ; Fri, 4 Dec 2020 05:46:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728245AbgLDFpo (ORCPT ); Fri, 4 Dec 2020 00:45:44 -0500 Received: from bilbo.ozlabs.org ([203.11.71.1]:53565 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728177AbgLDFpn (ORCPT ); Fri, 4 Dec 2020 00:45:43 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 4CnM8g6bfwz9sVp; Fri, 4 Dec 2020 16:44:19 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1607060659; bh=Xn1Ehv+oTCo3XiURURCvz/JFFB+ow4VAF1+V7lqlNS4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ed9o9wKFPM0s5Mo6zA5fSCi5uRSwLvtpYzjtCgaVHt7BW6ImDSZX0Gbyu3g6gOcIB WGrL398jc4G4ePzohkUWw+5INq7Fpjpi/+fFmr/gLzJDZ0+Wk/XWsmAcwvtppSVUAZ YLDm6JQVpnGfbC+vdWj85/oznV+REBNtZDCI45VU= From: David Gibson To: pair@us.ibm.com, pbonzini@redhat.com, frankja@linux.ibm.com, brijesh.singh@amd.com, dgilbert@redhat.com, qemu-devel@nongnu.org Cc: Eduardo Habkost , qemu-ppc@nongnu.org, rth@twiddle.net, thuth@redhat.com, berrange@redhat.com, mdroth@linux.vnet.ibm.com, Marcelo Tosatti , "Michael S. Tsirkin" , Marcel Apfelbaum , david@redhat.com, Richard Henderson , borntraeger@de.ibm.com, David Gibson , cohuck@redhat.com, kvm@vger.kernel.org, qemu-s390x@nongnu.org, pasic@linux.ibm.com Subject: [for-6.0 v5 06/13] securable guest memory: Decouple kvm_memcrypt_*() helpers from KVM Date: Fri, 4 Dec 2020 16:44:08 +1100 Message-Id: <20201204054415.579042-7-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201204054415.579042-1-david@gibson.dropbear.id.au> References: <20201204054415.579042-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The kvm_memcrypt_enabled() and kvm_memcrypt_encrypt_data() helper functions don't conceptually have any connection to KVM (although it's not possible in practice to use them without it). They also rely on looking at the global KVMState. But the same information is available from the machine, and the only existing callers have natural access to the machine state. Therefore, move and rename them to helpers in securable-guest-memory.h, taking an explicit machine parameter. Signed-off-by: David Gibson Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé --- accel/kvm/kvm-all.c | 27 -------------------- accel/stubs/kvm-stub.c | 10 -------- hw/i386/pc_sysfw.c | 6 +++-- include/exec/securable-guest-memory.h | 36 +++++++++++++++++++++++++++ include/sysemu/kvm.h | 17 ------------- 5 files changed, 40 insertions(+), 56 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 92a49b328a..c6bd7b9d02 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -121,9 +121,6 @@ struct KVMState KVMMemoryListener memory_listener; QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus; - /* securable guest memory (e.g. by guest memory encryption) */ - SecurableGuestMemory *sgm; - /* For "info mtree -f" to tell if an MR is registered in KVM */ int nr_as; struct KVMAs { @@ -222,28 +219,6 @@ int kvm_get_max_memslots(void) return s->nr_slots; } -bool kvm_memcrypt_enabled(void) -{ - if (kvm_state && kvm_state->sgm) { - return true; - } - - return false; -} - -int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len) -{ - SecurableGuestMemory *sgm = kvm_state->sgm; - - if (sgm) { - SecurableGuestMemoryClass *sgmc = SECURABLE_GUEST_MEMORY_GET_CLASS(sgm); - - return sgmc->encrypt_data(sgm, ptr, len); - } - - return 1; -} - /* Called with KVMMemoryListener.slots_lock held */ static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml) { @@ -2213,8 +2188,6 @@ static int kvm_init(MachineState *ms) if (ret < 0) { goto err; } - - kvm_state->sgm = ms->sgm; } ret = kvm_arch_init(ms, s); diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c index 680e099463..0f17acfac0 100644 --- a/accel/stubs/kvm-stub.c +++ b/accel/stubs/kvm-stub.c @@ -81,16 +81,6 @@ int kvm_on_sigbus(int code, void *addr) return 1; } -bool kvm_memcrypt_enabled(void) -{ - return false; -} - -int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len) -{ - return 1; -} - #ifndef CONFIG_USER_ONLY int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev) { diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c index b6c0822fe3..439ac78970 100644 --- a/hw/i386/pc_sysfw.c +++ b/hw/i386/pc_sysfw.c @@ -38,6 +38,7 @@ #include "sysemu/sysemu.h" #include "hw/block/flash.h" #include "sysemu/kvm.h" +#include "exec/securable-guest-memory.h" /* * We don't have a theoretically justifiable exact lower bound on the base @@ -201,10 +202,11 @@ static void pc_system_flash_map(PCMachineState *pcms, pc_isa_bios_init(rom_memory, flash_mem, size); /* Encrypt the pflash boot ROM */ - if (kvm_memcrypt_enabled()) { + if (securable_guest_memory_enabled(MACHINE(pcms))) { flash_ptr = memory_region_get_ram_ptr(flash_mem); flash_size = memory_region_size(flash_mem); - ret = kvm_memcrypt_encrypt_data(flash_ptr, flash_size); + ret = securable_guest_memory_encrypt(MACHINE(pcms), + flash_ptr, flash_size); if (ret) { error_report("failed to encrypt pflash rom"); exit(1); diff --git a/include/exec/securable-guest-memory.h b/include/exec/securable-guest-memory.h index 4e2ae27040..7325b504ba 100644 --- a/include/exec/securable-guest-memory.h +++ b/include/exec/securable-guest-memory.h @@ -21,6 +21,7 @@ #ifndef CONFIG_USER_ONLY #include "qom/object.h" +#include "hw/boards.h" #define TYPE_SECURABLE_GUEST_MEMORY "securable-guest-memory" #define SECURABLE_GUEST_MEMORY(obj) \ @@ -43,6 +44,41 @@ typedef struct SecurableGuestMemoryClass { int (*encrypt_data)(SecurableGuestMemory *, uint8_t *, uint64_t); } SecurableGuestMemoryClass; +/** + * securable_guest_memory_enabled - return whether guest memory is protected + * from hypervisor access (with memory + * encryption or otherwise) + * Returns: true guest memory is not directly accessible to qemu + * false guest memory is directly accessible to qemu + */ +static inline bool securable_guest_memory_enabled(MachineState *machine) +{ + return !!machine->sgm; +} + +/** + * securable_guest_memory_encrypt: encrypt the memory range to make + * it guest accessible + * + * Return: 1 failed to encrypt the range + * 0 succesfully encrypted memory region + */ +static inline int securable_guest_memory_encrypt(MachineState *machine, + uint8_t *ptr, uint64_t len) +{ + SecurableGuestMemory *sgm = machine->sgm; + + if (sgm) { + SecurableGuestMemoryClass *sgmc = SECURABLE_GUEST_MEMORY_GET_CLASS(sgm); + + if (sgmc->encrypt_data) { + return sgmc->encrypt_data(sgm, ptr, len); + } + } + + return 1; +} + #endif /* !CONFIG_USER_ONLY */ #endif /* QEMU_SECURABLE_GUEST_MEMORY_H */ diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index bb5d5cf497..0e163c2c9d 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -233,23 +233,6 @@ int kvm_has_intx_set_mask(void); */ bool kvm_arm_supports_user_irq(void); -/** - * kvm_memcrypt_enabled - return boolean indicating whether memory encryption - * is enabled - * Returns: 1 memory encryption is enabled - * 0 memory encryption is disabled - */ -bool kvm_memcrypt_enabled(void); - -/** - * kvm_memcrypt_encrypt_data: encrypt the memory range - * - * Return: 1 failed to encrypt the range - * 0 succesfully encrypted memory region - */ -int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len); - - #ifdef NEED_CPU_H #include "cpu.h" From patchwork Fri Dec 4 05:44:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11950673 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 57511C1B0D8 for ; Fri, 4 Dec 2020 05:46:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 26A6222582 for ; Fri, 4 Dec 2020 05:46:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728285AbgLDFpp (ORCPT ); Fri, 4 Dec 2020 00:45:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41034 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728199AbgLDFpo (ORCPT ); Fri, 4 Dec 2020 00:45:44 -0500 Received: from ozlabs.org (ozlabs.org [IPv6:2401:3900:2:1::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9D242C061A51 for ; Thu, 3 Dec 2020 21:45:03 -0800 (PST) Received: by ozlabs.org (Postfix, from userid 1007) id 4CnM8h0LnTz9sVm; Fri, 4 Dec 2020 16:44:19 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1607060660; bh=hbtdc5TUdS3/8sHWROwOs5A6oAM6BTjePKWUtzAj9NQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZUC4GpdCtc/BzDd3JSxH2aETJSUskwK2DJH/4Pgwun1X28TM1dovNRARnmITGqJFd VQxJKDBaCFyUGtDiIz4c4KbdVPeg03PGYC5wN054mNjZh+lw9FPceLLs2JS226Bk5e Qx9Pjur7WxCUh527rGxLNrQ8fbxXjcyIF6CI/XfQ= From: David Gibson To: pair@us.ibm.com, pbonzini@redhat.com, frankja@linux.ibm.com, brijesh.singh@amd.com, dgilbert@redhat.com, qemu-devel@nongnu.org Cc: Eduardo Habkost , qemu-ppc@nongnu.org, rth@twiddle.net, thuth@redhat.com, berrange@redhat.com, mdroth@linux.vnet.ibm.com, Marcelo Tosatti , "Michael S. Tsirkin" , Marcel Apfelbaum , david@redhat.com, Richard Henderson , borntraeger@de.ibm.com, David Gibson , cohuck@redhat.com, kvm@vger.kernel.org, qemu-s390x@nongnu.org, pasic@linux.ibm.com, =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Subject: [for-6.0 v5 07/13] sev: Add Error ** to sev_kvm_init() Date: Fri, 4 Dec 2020 16:44:09 +1100 Message-Id: <20201204054415.579042-8-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201204054415.579042-1-david@gibson.dropbear.id.au> References: <20201204054415.579042-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org This allows failures to be reported richly and idiomatically. Signed-off-by: David Gibson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Cornelia Huck --- accel/kvm/kvm-all.c | 4 +++- accel/kvm/sev-stub.c | 5 +++-- include/sysemu/sev.h | 2 +- target/i386/sev.c | 31 +++++++++++++++---------------- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index c6bd7b9d02..724e9294d0 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2183,9 +2183,11 @@ static int kvm_init(MachineState *ms) * encryption context. */ if (ms->sgm) { + Error *local_err = NULL; /* FIXME handle mechanisms other than SEV */ - ret = sev_kvm_init(ms->sgm); + ret = sev_kvm_init(ms->sgm, &local_err); if (ret < 0) { + error_report_err(local_err); goto err; } } diff --git a/accel/kvm/sev-stub.c b/accel/kvm/sev-stub.c index 3df3c88eeb..537c91d9f8 100644 --- a/accel/kvm/sev-stub.c +++ b/accel/kvm/sev-stub.c @@ -15,7 +15,8 @@ #include "qemu-common.h" #include "sysemu/sev.h" -int sev_kvm_init(SecurableGuestMemory *sgm) +int sev_kvm_init(SecurableGuestMemory *sgm, Error **errp) { - return -1; + /* SEV can't be selected if it's not compiled */ + g_assert_not_reached(); } diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h index 36d038a36f..7aa35821f0 100644 --- a/include/sysemu/sev.h +++ b/include/sysemu/sev.h @@ -17,6 +17,6 @@ #include "sysemu/kvm.h" #include "exec/securable-guest-memory.h" -int sev_kvm_init(SecurableGuestMemory *sgm); +int sev_kvm_init(SecurableGuestMemory *sgm, Error **errp); #endif diff --git a/target/i386/sev.c b/target/i386/sev.c index 7b8ce590f7..7333a60dc0 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -626,7 +626,7 @@ sev_vm_state_change(void *opaque, int running, RunState state) } } -int sev_kvm_init(SecurableGuestMemory *sgm) +int sev_kvm_init(SecurableGuestMemory *sgm, Error **errp) { SevGuestState *sev = SEV_GUEST(sgm); char *devname; @@ -648,14 +648,14 @@ int sev_kvm_init(SecurableGuestMemory *sgm) host_cbitpos = ebx & 0x3f; if (host_cbitpos != sev->cbitpos) { - error_report("%s: cbitpos check failed, host '%d' requested '%d'", - __func__, host_cbitpos, sev->cbitpos); + error_setg(errp, "%s: cbitpos check failed, host '%d' requested '%d'", + __func__, host_cbitpos, sev->cbitpos); goto err; } if (sev->reduced_phys_bits < 1) { - error_report("%s: reduced_phys_bits check failed, it should be >=1," - " requested '%d'", __func__, sev->reduced_phys_bits); + error_setg(errp, "%s: reduced_phys_bits check failed, it should be >=1," + " requested '%d'", __func__, sev->reduced_phys_bits); goto err; } @@ -664,20 +664,19 @@ int sev_kvm_init(SecurableGuestMemory *sgm) devname = object_property_get_str(OBJECT(sev), "sev-device", NULL); sev->sev_fd = open(devname, O_RDWR); if (sev->sev_fd < 0) { - error_report("%s: Failed to open %s '%s'", __func__, - devname, strerror(errno)); - } - g_free(devname); - if (sev->sev_fd < 0) { + error_setg(errp, "%s: Failed to open %s '%s'", __func__, + devname, strerror(errno)); + g_free(devname); goto err; } + g_free(devname); ret = sev_platform_ioctl(sev->sev_fd, SEV_PLATFORM_STATUS, &status, &fw_error); if (ret) { - error_report("%s: failed to get platform status ret=%d " - "fw_error='%d: %s'", __func__, ret, fw_error, - fw_error_to_str(fw_error)); + error_setg(errp, "%s: failed to get platform status ret=%d " + "fw_error='%d: %s'", __func__, ret, fw_error, + fw_error_to_str(fw_error)); goto err; } sev->build_id = status.build; @@ -687,14 +686,14 @@ int sev_kvm_init(SecurableGuestMemory *sgm) trace_kvm_sev_init(); ret = sev_ioctl(sev->sev_fd, KVM_SEV_INIT, NULL, &fw_error); if (ret) { - error_report("%s: failed to initialize ret=%d fw_error=%d '%s'", - __func__, ret, fw_error, fw_error_to_str(fw_error)); + error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'", + __func__, ret, fw_error, fw_error_to_str(fw_error)); goto err; } ret = sev_launch_start(sev); if (ret) { - error_report("%s: failed to create encryption context", __func__); + error_setg(errp, "%s: failed to create encryption context", __func__); goto err; } From patchwork Fri Dec 4 05:44:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11950625 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 68200C433FE for ; Fri, 4 Dec 2020 05:46:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1EC76224BE for ; Fri, 4 Dec 2020 05:46:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728187AbgLDFpm (ORCPT ); Fri, 4 Dec 2020 00:45:42 -0500 Received: from bilbo.ozlabs.org ([203.11.71.1]:54153 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728110AbgLDFpm (ORCPT ); Fri, 4 Dec 2020 00:45:42 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 4CnM8h1L2wz9sVt; Fri, 4 Dec 2020 16:44:20 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1607060660; bh=4EauSkQD4kf3/NsUuIz4zpH/jdlckopP7jBdsIJNjEc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YgPXfOzAOuOoBPOHOWWpAFUyEbqE8iXKps8pTVpnfIiP5ObF/yHua3SZ3sUmfYMoD jSmIGUjtGGFkOFYcN/eQWJlzcSqATpYn8vMbKlIvzXdhPnr4oKlEd5kiV2BaMe05Uk a58wlRW+tkhPrViITJm+BG+uQNK0RKsROy/tGTeY= From: David Gibson To: pair@us.ibm.com, pbonzini@redhat.com, frankja@linux.ibm.com, brijesh.singh@amd.com, dgilbert@redhat.com, qemu-devel@nongnu.org Cc: Eduardo Habkost , qemu-ppc@nongnu.org, rth@twiddle.net, thuth@redhat.com, berrange@redhat.com, mdroth@linux.vnet.ibm.com, Marcelo Tosatti , "Michael S. Tsirkin" , Marcel Apfelbaum , david@redhat.com, Richard Henderson , borntraeger@de.ibm.com, David Gibson , cohuck@redhat.com, kvm@vger.kernel.org, qemu-s390x@nongnu.org, pasic@linux.ibm.com Subject: [for-6.0 v5 08/13] securable guest memory: Introduce sgm "ready" flag Date: Fri, 4 Dec 2020 16:44:10 +1100 Message-Id: <20201204054415.579042-9-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201204054415.579042-1-david@gibson.dropbear.id.au> References: <20201204054415.579042-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The platform specific details of mechanisms for implementing securable guest memory may require setup at various points during initialization. Thus, it's not really feasible to have a single sgm initialization hook, but instead each mechanism needs its own initialization calls in arch or machine specific code. However, to make it harder to have a bug where a mechanism isn't properly initialized under some circumstances, we want to have a common place, relatively late in boot, where we verify that sgm has been initialized if it was requested. This patch introduces a ready flag to the SecurableGuestMemory base type to accomplish this, which we verify just before the machine specific initialization function. Signed-off-by: David Gibson --- hw/core/machine.c | 8 ++++++++ include/exec/securable-guest-memory.h | 2 ++ target/i386/sev.c | 2 ++ 3 files changed, 12 insertions(+) diff --git a/hw/core/machine.c b/hw/core/machine.c index 816ea3ae3e..a67a27d03c 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -1155,6 +1155,14 @@ void machine_run_board_init(MachineState *machine) } if (machine->sgm) { + /* + * Where securable guest memory is initialized depends on the + * specific mechanism in use. But, we need to make sure it's + * ready by now. If it isn't, that's a bug in the + * implementation of that sgm mechanism. + */ + assert(machine->sgm->ready); + /* * With securable guest memory, the host can't see the real * contents of RAM, so there's no point in it trying to merge diff --git a/include/exec/securable-guest-memory.h b/include/exec/securable-guest-memory.h index 7325b504ba..20cf13777b 100644 --- a/include/exec/securable-guest-memory.h +++ b/include/exec/securable-guest-memory.h @@ -36,6 +36,8 @@ struct SecurableGuestMemory { Object parent; + + bool ready; }; typedef struct SecurableGuestMemoryClass { diff --git a/target/i386/sev.c b/target/i386/sev.c index 7333a60dc0..022ce5fc3a 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -701,6 +701,8 @@ int sev_kvm_init(SecurableGuestMemory *sgm, Error **errp) qemu_add_machine_init_done_notifier(&sev_machine_done_notify); qemu_add_vm_change_state_handler(sev_vm_state_change, sev); + sgm->ready = true; + return 0; err: sev_guest = NULL; From patchwork Fri Dec 4 05:44:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11950665 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A22FDC4361A for ; Fri, 4 Dec 2020 05:46:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 49C6322581 for ; Fri, 4 Dec 2020 05:46:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728193AbgLDFpn (ORCPT ); Fri, 4 Dec 2020 00:45:43 -0500 Received: from ozlabs.org ([203.11.71.1]:48203 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728178AbgLDFpm (ORCPT ); Fri, 4 Dec 2020 00:45:42 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 4CnM8h3nJ0z9sVw; Fri, 4 Dec 2020 16:44:20 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1607060660; bh=pnJf0W657ZqIQCAsU+SbMXMq/ij/zS+RJqdmVHy+dx0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UKkxc8iV11JrVmF6RVkWAi412yYd8//9vWGcbEhH6VeDetkjlJIxok/U4bUqGlqTV GHcdr5a2Mw0HrE0iN5YtpCspvp/t43OqHQoOMh8fgEiRUu2CJlB1mFe0PEaAzuONkT 4WwL1hKy7zWBcwkc/m2dv6QUtcQoNgVEeTzNztEE= From: David Gibson To: pair@us.ibm.com, pbonzini@redhat.com, frankja@linux.ibm.com, brijesh.singh@amd.com, dgilbert@redhat.com, qemu-devel@nongnu.org Cc: Eduardo Habkost , qemu-ppc@nongnu.org, rth@twiddle.net, thuth@redhat.com, berrange@redhat.com, mdroth@linux.vnet.ibm.com, Marcelo Tosatti , "Michael S. Tsirkin" , Marcel Apfelbaum , david@redhat.com, Richard Henderson , borntraeger@de.ibm.com, David Gibson , cohuck@redhat.com, kvm@vger.kernel.org, qemu-s390x@nongnu.org, pasic@linux.ibm.com Subject: [for-6.0 v5 09/13] securable guest memory: Move SEV initialization into arch specific code Date: Fri, 4 Dec 2020 16:44:11 +1100 Message-Id: <20201204054415.579042-10-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201204054415.579042-1-david@gibson.dropbear.id.au> References: <20201204054415.579042-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org While we've abstracted some (potential) differences between mechanisms for securing guest memory, the initialization is still specific to SEV. Given that, move it into x86's kvm_arch_init() code, rather than the generic kvm_init() code. Signed-off-by: David Gibson --- accel/kvm/kvm-all.c | 14 -------------- target/i386/kvm.c | 12 ++++++++++++ target/i386/sev.c | 7 ++++++- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 724e9294d0..1b676da6c2 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2178,20 +2178,6 @@ static int kvm_init(MachineState *ms) kvm_state = s; - /* - * if memory encryption object is specified then initialize the memory - * encryption context. - */ - if (ms->sgm) { - Error *local_err = NULL; - /* FIXME handle mechanisms other than SEV */ - ret = sev_kvm_init(ms->sgm, &local_err); - if (ret < 0) { - error_report_err(local_err); - goto err; - } - } - ret = kvm_arch_init(ms, s); if (ret < 0) { goto err; diff --git a/target/i386/kvm.c b/target/i386/kvm.c index a2934dda02..8e3617f3cd 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -42,6 +42,7 @@ #include "hw/i386/intel_iommu.h" #include "hw/i386/x86-iommu.h" #include "hw/i386/e820_memory_layout.h" +#include "sysemu/sev.h" #include "hw/pci/pci.h" #include "hw/pci/msi.h" @@ -2110,6 +2111,17 @@ int kvm_arch_init(MachineState *ms, KVMState *s) uint64_t shadow_mem; int ret; struct utsname utsname; + Error *local_err = NULL; + + /* + * if memory encryption object is specified then initialize the + * memory encryption context (no-op otherwise) + */ + ret = sev_kvm_init(ms->sgm, &local_err); + if (ret < 0) { + error_report_err(local_err); + return ret; + } if (!kvm_check_extension(s, KVM_CAP_IRQ_ROUTING)) { error_report("kvm: KVM_CAP_IRQ_ROUTING not supported by KVM"); diff --git a/target/i386/sev.c b/target/i386/sev.c index 022ce5fc3a..8c19f4aea6 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -628,13 +628,18 @@ sev_vm_state_change(void *opaque, int running, RunState state) int sev_kvm_init(SecurableGuestMemory *sgm, Error **errp) { - SevGuestState *sev = SEV_GUEST(sgm); + SevGuestState *sev + = (SevGuestState *)object_dynamic_cast(OBJECT(sgm), TYPE_SEV_GUEST); char *devname; int ret, fw_error; uint32_t ebx; uint32_t host_cbitpos; struct sev_user_data_status status = {}; + if (!sev) { + return 0; + } + ret = ram_block_discard_disable(true); if (ret) { error_report("%s: cannot disable RAM discard", __func__); From patchwork Fri Dec 4 05:44:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11950677 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2BDB2C19437 for ; Fri, 4 Dec 2020 05:46:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EFA20224BE for ; Fri, 4 Dec 2020 05:46:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728222AbgLDFpo (ORCPT ); Fri, 4 Dec 2020 00:45:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41032 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728181AbgLDFpn (ORCPT ); Fri, 4 Dec 2020 00:45:43 -0500 Received: from ozlabs.org (bilbo.ozlabs.org [IPv6:2401:3900:2:1::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F8F7C061A4F for ; Thu, 3 Dec 2020 21:45:03 -0800 (PST) Received: by ozlabs.org (Postfix, from userid 1007) id 4CnM8h73V6z9sWB; Fri, 4 Dec 2020 16:44:20 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1607060661; bh=l7oNIOTM8IaM6054OYmH+xyQea5im/8alI0goaX7NZY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WwQ8lvIwtdHR+Hk9TJJtb/vYMawRrb5D8NYdX2aOFZSk8I5t2T6aXyBVV7rnLihRX dq7Vf0oCDEfiWNGe33zzh43mb28ukkl/b5jK+skpcdmsRfuBgPVvPuhIyv1TELpomK 6D5HsFqO9vqHsxcG08tLnRMMXXyH5c65GvhEXyDc= From: David Gibson To: pair@us.ibm.com, pbonzini@redhat.com, frankja@linux.ibm.com, brijesh.singh@amd.com, dgilbert@redhat.com, qemu-devel@nongnu.org Cc: Eduardo Habkost , qemu-ppc@nongnu.org, rth@twiddle.net, thuth@redhat.com, berrange@redhat.com, mdroth@linux.vnet.ibm.com, Marcelo Tosatti , "Michael S. Tsirkin" , Marcel Apfelbaum , david@redhat.com, Richard Henderson , borntraeger@de.ibm.com, David Gibson , cohuck@redhat.com, kvm@vger.kernel.org, qemu-s390x@nongnu.org, pasic@linux.ibm.com, Ram Pai Subject: [for-6.0 v5 10/13] spapr: Add PEF based securable guest memory Date: Fri, 4 Dec 2020 16:44:12 +1100 Message-Id: <20201204054415.579042-11-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201204054415.579042-1-david@gibson.dropbear.id.au> References: <20201204054415.579042-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Some upcoming POWER machines have a system called PEF (Protected Execution Facility) which uses a small ultravisor to allow guests to run in a way that they can't be eavesdropped by the hypervisor. The effect is roughly similar to AMD SEV, although the mechanisms are quite different. Most of the work of this is done between the guest, KVM and the ultravisor, with little need for involvement by qemu. However qemu does need to tell KVM to allow secure VMs. Because the availability of secure mode is a guest visible difference which depends on having the right hardware and firmware, we don't enable this by default. In order to run a secure guest you need to create a "pef-guest" object and set the securable-guest-memory machine property to point to it. Note that this just *allows* secure guests, the architecture of PEF is such that the guest still needs to talk to the ultravisor to enter secure mode. Qemu has no directl way of knowing if the guest is in secure mode, and certainly can't know until well after machine creation time. To start a PEF-capable guest, use the command line options: -object pef-guest,id=pef0 -machine securable-guest-memory=pef0 Signed-off-by: David Gibson Acked-by: Ram Pai --- hw/ppc/meson.build | 1 + hw/ppc/pef.c | 115 +++++++++++++++++++++++++++++++++++++++++++ hw/ppc/spapr.c | 10 ++++ include/hw/ppc/pef.h | 26 ++++++++++ target/ppc/kvm.c | 18 ------- target/ppc/kvm_ppc.h | 6 --- 6 files changed, 152 insertions(+), 24 deletions(-) create mode 100644 hw/ppc/pef.c create mode 100644 include/hw/ppc/pef.h diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build index ffa2ec37fa..218631c883 100644 --- a/hw/ppc/meson.build +++ b/hw/ppc/meson.build @@ -27,6 +27,7 @@ ppc_ss.add(when: 'CONFIG_PSERIES', if_true: files( 'spapr_nvdimm.c', 'spapr_rtas_ddw.c', 'spapr_numa.c', + 'pef.c', )) ppc_ss.add(when: 'CONFIG_SPAPR_RNG', if_true: files('spapr_rng.c')) ppc_ss.add(when: ['CONFIG_PSERIES', 'CONFIG_LINUX'], if_true: files( diff --git a/hw/ppc/pef.c b/hw/ppc/pef.c new file mode 100644 index 0000000000..3ae3059cfe --- /dev/null +++ b/hw/ppc/pef.c @@ -0,0 +1,115 @@ +/* + * PEF (Protected Execution Facility) for POWER support + * + * Copyright David Gibson, Redhat Inc. 2020 + * + * 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 "sysemu/kvm.h" +#include "migration/blocker.h" +#include "exec/securable-guest-memory.h" +#include "hw/ppc/pef.h" + +#define TYPE_PEF_GUEST "pef-guest" +#define PEF_GUEST(obj) \ + OBJECT_CHECK(PefGuestState, (obj), TYPE_PEF_GUEST) + +typedef struct PefGuestState PefGuestState; + +/** + * PefGuestState: + * + * The PefGuestState object is used for creating and managing a PEF + * guest. + * + * # $QEMU \ + * -object pef-guest,id=pef0 \ + * -machine ...,securable-guest-memory=pef0 + */ +struct PefGuestState { + Object parent_obj; +}; + +#ifdef CONFIG_KVM +static int kvmppc_svm_init(Error **errp) +{ + if (!kvm_check_extension(kvm_state, KVM_CAP_PPC_SECURABLE_GUEST)) { + error_setg(errp, + "KVM implementation does not support Secure VMs (is an ultravisor running?)"); + return -1; + } else { + int ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_PPC_SECURE_GUEST, 0, 1); + + if (ret < 0) { + error_setg(errp, + "Error enabling PEF with KVM"); + return -1; + } + } + + return 0; +} + +/* + * Don't set error if KVM_PPC_SVM_OFF ioctl is invoked on kernels + * that don't support this ioctl. + */ +void kvmppc_svm_off(Error **errp) +{ + int rc; + + if (!kvm_enabled()) { + return; + } + + rc = kvm_vm_ioctl(KVM_STATE(current_accel()), KVM_PPC_SVM_OFF); + if (rc && rc != -ENOTTY) { + error_setg_errno(errp, -rc, "KVM_PPC_SVM_OFF ioctl failed"); + } +} +#else +static int kvmppc_svm_init(Error **errp) +{ + g_assert_not_reached(); +} +#endif + +int pef_kvm_init(SecurableGuestMemory *sgm, Error **errp) +{ + if (!object_dynamic_cast(OBJECT(sgm), TYPE_PEF_GUEST)) { + return 0; + } + + if (!kvm_enabled()) { + error_setg(errp, "PEF requires KVM"); + return -1; + } + + return kvmppc_svm_init(errp); +} + +static const TypeInfo pef_guest_info = { + .parent = TYPE_OBJECT, + .name = TYPE_PEF_GUEST, + .instance_size = sizeof(PefGuestState), + .interfaces = (InterfaceInfo[]) { + { TYPE_SECURABLE_GUEST_MEMORY }, + { TYPE_USER_CREATABLE }, + { } + } +}; + +static void +pef_register_types(void) +{ + type_register_static(&pef_guest_info); +} + +type_init(pef_register_types); diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 12a012d9dd..d95b60f712 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -82,6 +82,7 @@ #include "hw/ppc/spapr_tpm_proxy.h" #include "hw/ppc/spapr_nvdimm.h" #include "hw/ppc/spapr_numa.h" +#include "hw/ppc/pef.h" #include "monitor/monitor.h" @@ -2665,6 +2666,15 @@ static void spapr_machine_init(MachineState *machine) long load_limit, fw_size; char *filename; Error *resize_hpt_err = NULL; + Error *local_err = NULL; + + /* + * if Secure VM (PEF) support is configured, then initialize it + */ + if (pef_kvm_init(machine->sgm, &local_err) < 0) { + error_report_err(local_err); + exit(1); + } msi_nonbroken = true; diff --git a/include/hw/ppc/pef.h b/include/hw/ppc/pef.h new file mode 100644 index 0000000000..63c3475859 --- /dev/null +++ b/include/hw/ppc/pef.h @@ -0,0 +1,26 @@ +/* + * PEF (Protected Execution Facility) for POWER support + * + * Copyright David Gibson, Redhat Inc. 2020 + * + * 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 HW_PPC_PEF_H +#define HW_PPC_PEF_H + +int pef_kvm_init(SecurableGuestMemory *sgm, Error **errp); + +#ifdef CONFIG_KVM +void kvmppc_svm_off(Error **errp); +#else +static inline void kvmppc_svm_off(Error **errp) +{ +} +#endif + + +#endif /* HW_PPC_PEF_H */ + diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index daf690a678..0c5056dd5b 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -2929,21 +2929,3 @@ void kvmppc_set_reg_tb_offset(PowerPCCPU *cpu, int64_t tb_offset) kvm_set_one_reg(cs, KVM_REG_PPC_TB_OFFSET, &tb_offset); } } - -/* - * Don't set error if KVM_PPC_SVM_OFF ioctl is invoked on kernels - * that don't support this ioctl. - */ -void kvmppc_svm_off(Error **errp) -{ - int rc; - - if (!kvm_enabled()) { - return; - } - - rc = kvm_vm_ioctl(KVM_STATE(current_accel()), KVM_PPC_SVM_OFF); - if (rc && rc != -ENOTTY) { - error_setg_errno(errp, -rc, "KVM_PPC_SVM_OFF ioctl failed"); - } -} diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index 73ce2bc951..989f61ace0 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -39,7 +39,6 @@ int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu); target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu, bool radix, bool gtse, uint64_t proc_tbl); -void kvmppc_svm_off(Error **errp); #ifndef CONFIG_USER_ONLY bool kvmppc_spapr_use_multitce(void); int kvmppc_spapr_enable_inkernel_multitce(void); @@ -216,11 +215,6 @@ static inline target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu, return 0; } -static inline void kvmppc_svm_off(Error **errp) -{ - return; -} - static inline void kvmppc_set_reg_ppc_online(PowerPCCPU *cpu, unsigned int online) { From patchwork Fri Dec 4 05:44:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11950667 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B3D5DC4167B for ; Fri, 4 Dec 2020 05:46:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7276022582 for ; Fri, 4 Dec 2020 05:46:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728195AbgLDFpn (ORCPT ); Fri, 4 Dec 2020 00:45:43 -0500 Received: from bilbo.ozlabs.org ([203.11.71.1]:52235 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728181AbgLDFpn (ORCPT ); Fri, 4 Dec 2020 00:45:43 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 4CnM8h5R7zz9sVv; Fri, 4 Dec 2020 16:44:20 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1607060660; bh=lCwJ3O4sNiYS7HxagCxP/NpsI9RVLllMh2C+EBE4vKE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IEw6C4v8bZxI94lZhAlLyeTaiqyeRSbJP2VK4KmnizsQ4wpJIFV8F0t+kCUmUVVBZ fmveDgtGjDJq/JuBqzuaCQG3ZK2M448N1+Qfe4RBotNgppJ5TIjMwbb/1q9RUCl8iM +sx71e29CEN1FADUNXJ37lo3oJ0yueV7XLjQ2UUg= From: David Gibson To: pair@us.ibm.com, pbonzini@redhat.com, frankja@linux.ibm.com, brijesh.singh@amd.com, dgilbert@redhat.com, qemu-devel@nongnu.org Cc: Eduardo Habkost , qemu-ppc@nongnu.org, rth@twiddle.net, thuth@redhat.com, berrange@redhat.com, mdroth@linux.vnet.ibm.com, Marcelo Tosatti , "Michael S. Tsirkin" , Marcel Apfelbaum , david@redhat.com, Richard Henderson , borntraeger@de.ibm.com, David Gibson , cohuck@redhat.com, kvm@vger.kernel.org, qemu-s390x@nongnu.org, pasic@linux.ibm.com Subject: [for-6.0 v5 11/13] spapr: PEF: prevent migration Date: Fri, 4 Dec 2020 16:44:13 +1100 Message-Id: <20201204054415.579042-12-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201204054415.579042-1-david@gibson.dropbear.id.au> References: <20201204054415.579042-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org We haven't yet implemented the fairly involved handshaking that will be needed to migrate PEF protected guests. For now, just use a migration blocker so we get a meaningful error if someone attempts this (this is the same approach used by AMD SEV). Signed-off-by: David Gibson Reviewed-by: Dr. David Alan Gilbert --- hw/ppc/pef.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hw/ppc/pef.c b/hw/ppc/pef.c index 3ae3059cfe..edc3e744ba 100644 --- a/hw/ppc/pef.c +++ b/hw/ppc/pef.c @@ -38,7 +38,11 @@ struct PefGuestState { }; #ifdef CONFIG_KVM +static Error *pef_mig_blocker; + static int kvmppc_svm_init(Error **errp) + +int kvmppc_svm_init(SecurableGuestMemory *sgm, Error **errp) { if (!kvm_check_extension(kvm_state, KVM_CAP_PPC_SECURABLE_GUEST)) { error_setg(errp, @@ -54,6 +58,11 @@ static int kvmppc_svm_init(Error **errp) } } + /* add migration blocker */ + error_setg(&pef_mig_blocker, "PEF: Migration is not implemented"); + /* NB: This can fail if --only-migratable is used */ + migrate_add_blocker(pef_mig_blocker, &error_fatal); + return 0; } From patchwork Fri Dec 4 05:44:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11950671 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CB85BC4361B for ; Fri, 4 Dec 2020 05:46:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 98B81224BE for ; Fri, 4 Dec 2020 05:46:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728260AbgLDFpo (ORCPT ); Fri, 4 Dec 2020 00:45:44 -0500 Received: from ozlabs.org ([203.11.71.1]:38533 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728191AbgLDFpn (ORCPT ); Fri, 4 Dec 2020 00:45:43 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 4CnM8j2ctRz9sWD; Fri, 4 Dec 2020 16:44:21 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1607060661; bh=VJ+LxQJOkUVbhfEUmAX9VA/bXYtOMYSQX40lQmDmveM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n/hPt3e/EfOiifh/tLDcORyx4cp37QBDhJC+dZIUX84hluIDTzl9WSZvn2hpjXPci iutHioNHKh8PvMKfetFpm85FIdF3HrtE9XlCKmt8JHPB0ePHauUOLRQyH6eq8Y1d0P K3T3aL3fPzr4KyCGKJ9rj8SPkzOU8TG8bRBuz+E0= From: David Gibson To: pair@us.ibm.com, pbonzini@redhat.com, frankja@linux.ibm.com, brijesh.singh@amd.com, dgilbert@redhat.com, qemu-devel@nongnu.org Cc: Eduardo Habkost , qemu-ppc@nongnu.org, rth@twiddle.net, thuth@redhat.com, berrange@redhat.com, mdroth@linux.vnet.ibm.com, Marcelo Tosatti , "Michael S. Tsirkin" , Marcel Apfelbaum , david@redhat.com, Richard Henderson , borntraeger@de.ibm.com, David Gibson , cohuck@redhat.com, kvm@vger.kernel.org, qemu-s390x@nongnu.org, pasic@linux.ibm.com Subject: [for-6.0 v5 12/13] securable guest memory: Alter virtio default properties for protected guests Date: Fri, 4 Dec 2020 16:44:14 +1100 Message-Id: <20201204054415.579042-13-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201204054415.579042-1-david@gibson.dropbear.id.au> References: <20201204054415.579042-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The default behaviour for virtio devices is not to use the platforms normal DMA paths, but instead to use the fact that it's running in a hypervisor to directly access guest memory. That doesn't work if the guest's memory is protected from hypervisor access, such as with AMD's SEV or POWER's PEF. So, if a securable guest memory mechanism is enabled, then apply the iommu_platform=on option so it will go through normal DMA mechanisms. Those will presumably have some way of marking memory as shared with the hypervisor or hardware so that DMA will work. Signed-off-by: David Gibson Reviewed-by: Dr. David Alan Gilbert Reviewed-by: Cornelia Huck --- hw/core/machine.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/hw/core/machine.c b/hw/core/machine.c index a67a27d03c..d16273d75d 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -28,6 +28,8 @@ #include "hw/mem/nvdimm.h" #include "migration/vmstate.h" #include "exec/securable-guest-memory.h" +#include "hw/virtio/virtio.h" +#include "hw/virtio/virtio-pci.h" GlobalProperty hw_compat_5_1[] = { { "vhost-scsi", "num_queues", "1"}, @@ -1169,6 +1171,17 @@ void machine_run_board_init(MachineState *machine) * areas. */ machine_set_mem_merge(OBJECT(machine), false, &error_abort); + + /* + * Virtio devices can't count on directly accessing guest + * memory, so they need iommu_platform=on to use normal DMA + * mechanisms. That requires also disabling legacy virtio + * support for those virtio pci devices which allow it. + */ + object_register_sugar_prop(TYPE_VIRTIO_PCI, "disable-legacy", + "on", true); + object_register_sugar_prop(TYPE_VIRTIO_DEVICE, "iommu_platform", + "on", false); } machine_class->init(machine); From patchwork Fri Dec 4 05:44:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11950675 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BD6BFC1B0D9 for ; Fri, 4 Dec 2020 05:46:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 74BA1225AA for ; Fri, 4 Dec 2020 05:46:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728305AbgLDFpq (ORCPT ); Fri, 4 Dec 2020 00:45:46 -0500 Received: from bilbo.ozlabs.org ([203.11.71.1]:33849 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728235AbgLDFpp (ORCPT ); Fri, 4 Dec 2020 00:45:45 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 4CnM8j514Dz9sW4; Fri, 4 Dec 2020 16:44:21 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1607060661; bh=Ss0/gyChKQh9v9b5oqQ2eHsb/Tt4Sz/UV/uYFn9GoUc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I3Swji869vaIndr29WCGkXaX3pv4+TriCUjN91KVHbbEPL/U2S765TyVI5FH5SBX/ 04QN8gecLaouNCanj61BJkfbYVETHLdKxxJqIeDZ7xQwXpDyPf0xXuJEDw9YKYeDVF rthyO1kCCUbwI92cirwwZ3wDDMMXRiXZgjNJrjYE= From: David Gibson To: pair@us.ibm.com, pbonzini@redhat.com, frankja@linux.ibm.com, brijesh.singh@amd.com, dgilbert@redhat.com, qemu-devel@nongnu.org Cc: Eduardo Habkost , qemu-ppc@nongnu.org, rth@twiddle.net, thuth@redhat.com, berrange@redhat.com, mdroth@linux.vnet.ibm.com, Marcelo Tosatti , "Michael S. Tsirkin" , Marcel Apfelbaum , david@redhat.com, Richard Henderson , borntraeger@de.ibm.com, David Gibson , cohuck@redhat.com, kvm@vger.kernel.org, qemu-s390x@nongnu.org, pasic@linux.ibm.com Subject: [for-6.0 v5 13/13] s390: Recognize securable-guest-memory option Date: Fri, 4 Dec 2020 16:44:15 +1100 Message-Id: <20201204054415.579042-14-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201204054415.579042-1-david@gibson.dropbear.id.au> References: <20201204054415.579042-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org At least some s390 cpu models support "Protected Virtualization" (PV), a mechanism to protect guests from eavesdropping by a compromised hypervisor. This is similar in function to other mechanisms like AMD's SEV and POWER's PEF, which are controlled bythe "securable-guest-memory" machine option. s390 is a slightly special case, because we already supported PV, simply by using a CPU model with the required feature (S390_FEAT_UNPACK). To integrate this with the option used by other platforms, we implement the following compromise: - When the securable-guest-memory option is set, s390 will recognize it, verify that the CPU can support PV (failing if not) and set virtio default options necessary for encrypted or protected guests, as on other platforms. i.e. if securable-guest-memory is set, we will either create a guest capable of entering PV mode, or fail outright - If securable-guest-memory is not set, guest's might still be able to enter PV mode, if the CPU has the right model. This may be a little surprising, but shouldn't actually be harmful. To start a guest supporting Protected Virtualization using the new option use the command line arguments: -object s390-pv-guest,id=pv0 -machine securable-guest-memory=pv0 Signed-off-by: David Gibson --- hw/s390x/pv.c | 58 +++++++++++++++++++++++++++++++++++++++++++ include/hw/s390x/pv.h | 1 + target/s390x/kvm.c | 3 +++ 3 files changed, 62 insertions(+) diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c index ab3a2482aa..9fddc196a3 100644 --- a/hw/s390x/pv.c +++ b/hw/s390x/pv.c @@ -14,8 +14,11 @@ #include #include "cpu.h" +#include "qapi/error.h" #include "qemu/error-report.h" #include "sysemu/kvm.h" +#include "qom/object_interfaces.h" +#include "exec/securable-guest-memory.h" #include "hw/s390x/ipl.h" #include "hw/s390x/pv.h" @@ -111,3 +114,58 @@ void s390_pv_inject_reset_error(CPUState *cs) /* Report that we are unable to enter protected mode */ env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV; } + +#define TYPE_S390_PV_GUEST "s390-pv-guest" +#define S390_PV_GUEST(obj) \ + OBJECT_CHECK(S390PVGuestState, (obj), TYPE_S390_PV_GUEST) + +typedef struct S390PVGuestState S390PVGuestState; + +/** + * S390PVGuestState: + * + * The S390PVGuestState object is basically a dummy used to tell the + * securable guest memory system to use s390's PV mechanism. + * + * # $QEMU \ + * -object s390-pv-guest,id=pv0 \ + * -machine ...,securable-guest-memory=pv0 + */ +struct S390PVGuestState { + Object parent_obj; +}; + +int s390_pv_init(SecurableGuestMemory *sgm, Error **errp) +{ + if (!object_dynamic_cast(OBJECT(sgm), TYPE_S390_PV_GUEST)) { + return 0; + } + + if (!s390_has_feat(S390_FEAT_UNPACK)) { + error_setg(errp, + "CPU model does not support Protected Virtualization"); + return -1; + } + + sgm->ready = true; + + return 0; +} + +static const TypeInfo s390_pv_guest_info = { + .parent = TYPE_SECURABLE_GUEST_MEMORY, + .name = TYPE_S390_PV_GUEST, + .instance_size = sizeof(S390PVGuestState), + .interfaces = (InterfaceInfo[]) { + { TYPE_USER_CREATABLE }, + { } + } +}; + +static void +s390_pv_register_types(void) +{ + type_register_static(&s390_pv_guest_info); +} + +type_init(s390_pv_register_types); diff --git a/include/hw/s390x/pv.h b/include/hw/s390x/pv.h index aee758bc2d..4250af699b 100644 --- a/include/hw/s390x/pv.h +++ b/include/hw/s390x/pv.h @@ -43,6 +43,7 @@ void s390_pv_prep_reset(void); int s390_pv_verify(void); void s390_pv_unshare(void); void s390_pv_inject_reset_error(CPUState *cs); +int s390_pv_init(SecurableGuestMemory *sgm, Error **errp); #else /* CONFIG_KVM */ static inline bool s390_is_pv(void) { return false; } static inline int s390_pv_vm_enable(void) { return 0; } diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c index b8385e6b95..3383487463 100644 --- a/target/s390x/kvm.c +++ b/target/s390x/kvm.c @@ -387,6 +387,9 @@ int kvm_arch_init(MachineState *ms, KVMState *s) } kvm_set_max_memslot_size(KVM_SLOT_MAX_BYTES); + + s390_pv_init(ms->sgm, &error_fatal); + return 0; }