From patchwork Wed Jan 13 23:57:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12018197 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,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 5C58AC072AF for ; Thu, 14 Jan 2021 01:53:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 25D8F206C0 for ; Thu, 14 Jan 2021 01:53:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728261AbhANBxo (ORCPT ); Wed, 13 Jan 2021 20:53:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47232 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729678AbhAMX7I (ORCPT ); Wed, 13 Jan 2021 18:59:08 -0500 Received: from ozlabs.org (ozlabs.org [IPv6:2401:3900:2:1::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A1B38C0617A3 for ; Wed, 13 Jan 2021 15:58:20 -0800 (PST) Received: by ozlabs.org (Postfix, from userid 1007) id 4DGPXQ0Kttz9sVy; Thu, 14 Jan 2021 10:58:13 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1610582294; bh=PMr7j5j8OSe0AP5kUuFMOJLePX4fph0iQtNNjr88kFA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WOU/Nolj6jlStIr4NRM6WXyowwAzxfu41mUBsAt2hjacUVyKfMzCuBeg3nnoRXdhH hz2tPK9t7Dy95n4vvy1Ul/4WMa/beNDURAUo0XociRRNmbNIiWM7vgaXJPhjxnXS8J E1NNnb87UwZo6RN48TQLEmCj5ir03CdkKQRyk5r4= From: David Gibson To: brijesh.singh@amd.com, pair@us.ibm.com, dgilbert@redhat.com, pasic@linux.ibm.com, qemu-devel@nongnu.org Cc: cohuck@redhat.com, Richard Henderson , Marcelo Tosatti , David Hildenbrand , borntraeger@de.ibm.com, Marcel Apfelbaum , Paolo Bonzini , mst@redhat.com, jun.nakajima@intel.com, thuth@redhat.com, pragyansri.pathi@intel.com, kvm@vger.kernel.org, Eduardo Habkost , qemu-s390x@nongnu.org, qemu-ppc@nongnu.org, frankja@linux.ibm.com, Greg Kurz , mdroth@linux.vnet.ibm.com, David Gibson , berrange@redhat.com, andi.kleen@intel.com, =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PATCH v7 01/13] qom: Allow optional sugar props Date: Thu, 14 Jan 2021 10:57:59 +1100 Message-Id: <20210113235811.1909610-2-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210113235811.1909610-1-david@gibson.dropbear.id.au> References: <20210113235811.1909610-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: Eduardo Habkost Reviewed-by: Cornelia Huck Reviewed-by: Philippe Mathieu-Daudé --- include/qom/object.h | 3 ++- qom/object.c | 4 +++- softmmu/rtc.c | 3 ++- softmmu/vl.c | 17 +++++++++++------ 4 files changed, 18 insertions(+), 9 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 2fa0119647..491823db4a 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/rtc.c b/softmmu/rtc.c index e1e15ef613..5632684fc9 100644 --- a/softmmu/rtc.c +++ b/softmmu/rtc.c @@ -179,7 +179,8 @@ 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 { diff --git a/softmmu/vl.c b/softmmu/vl.c index 7ddf405d76..3f7721b83e 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -1663,16 +1663,20 @@ 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")) { - 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; } if (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("whpx"), qom_name, value); + object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), qom_name, value, + false); + object_register_sugar_prop(ACCEL_CLASS_NAME("whpx"), qom_name, value, + false); return 0; } @@ -2297,9 +2301,10 @@ static void qemu_process_sugar_options(void) val = g_strdup_printf("%d", (uint32_t) qemu_opt_get_number(qemu_find_opts_singleton("smp-opts"), "cpus", 1)); - 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); } if (watchdog) { From patchwork Wed Jan 13 23:58:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12018211 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,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 3E820C43381 for ; Thu, 14 Jan 2021 01:54:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0171A2343B for ; Thu, 14 Jan 2021 01:54:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727780AbhANBxu (ORCPT ); Wed, 13 Jan 2021 20:53:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47230 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729668AbhAMX7I (ORCPT ); Wed, 13 Jan 2021 18:59:08 -0500 Received: from ozlabs.org (ozlabs.org [IPv6:2401:3900:2:1::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9B28FC0617A2 for ; Wed, 13 Jan 2021 15:58:20 -0800 (PST) Received: by ozlabs.org (Postfix, from userid 1007) id 4DGPXQ3Lt5z9sWS; Thu, 14 Jan 2021 10:58:14 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1610582294; bh=mHVxcrGGzYrCfA9rYxmOKa3RCA68YZNhZxMoJegXBdo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TsT92BTdo138QHl6Cg7+TQApgSL/NEvo6wqGTTgwn6YEuc83GqzBEXmPEIT7jWkSP aC2xhsT4+q5YDYfL3aecES7WC/DdqqDsJmJeYo+1IdePO+RIaPY/L/QxJXFKO2tAGm HnEbNdKjeTrsr7PZn/6HwzWPWde8vSVrMLJReynk= From: David Gibson To: brijesh.singh@amd.com, pair@us.ibm.com, dgilbert@redhat.com, pasic@linux.ibm.com, qemu-devel@nongnu.org Cc: cohuck@redhat.com, Richard Henderson , Marcelo Tosatti , David Hildenbrand , borntraeger@de.ibm.com, Marcel Apfelbaum , Paolo Bonzini , mst@redhat.com, jun.nakajima@intel.com, thuth@redhat.com, pragyansri.pathi@intel.com, kvm@vger.kernel.org, Eduardo Habkost , qemu-s390x@nongnu.org, qemu-ppc@nongnu.org, frankja@linux.ibm.com, Greg Kurz , mdroth@linux.vnet.ibm.com, David Gibson , berrange@redhat.com, andi.kleen@intel.com Subject: [PATCH v7 02/13] confidential guest support: Introduce new confidential guest support class Date: Thu, 14 Jan 2021 10:58:00 +1100 Message-Id: <20210113235811.1909610-3-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210113235811.1909610-1-david@gibson.dropbear.id.au> References: <20210113235811.1909610-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 ConfidentialGuestSupport QOM base class. "Confidential" is kind of vague, but "confidential computing" seems to be the buzzword about these schemes, and "secure" or "protected" are often used in connection to unrelated things (such as hypervisor-from-guest or guest-from-guest security). The "support" in the name is significant 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/confidential-guest-support.c | 33 ++++++++++++++++++++ backends/meson.build | 1 + include/exec/confidential-guest-support.h | 38 +++++++++++++++++++++++ include/qemu/typedefs.h | 1 + target/i386/sev.c | 3 +- 5 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 backends/confidential-guest-support.c create mode 100644 include/exec/confidential-guest-support.h diff --git a/backends/confidential-guest-support.c b/backends/confidential-guest-support.c new file mode 100644 index 0000000000..9b0ded0db4 --- /dev/null +++ b/backends/confidential-guest-support.c @@ -0,0 +1,33 @@ +/* + * QEMU Confidential Guest support + * + * 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/confidential-guest-support.h" + +OBJECT_DEFINE_ABSTRACT_TYPE(ConfidentialGuestSupport, + confidential_guest_support, + CONFIDENTIAL_GUEST_SUPPORT, + OBJECT) + +static void confidential_guest_support_class_init(ObjectClass *oc, void *data) +{ +} + +static void confidential_guest_support_init(Object *obj) +{ +} + +static void confidential_guest_support_finalize(Object *obj) +{ +} diff --git a/backends/meson.build b/backends/meson.build index 484456ece7..d4221831fc 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', + 'confidential-guest-support.c', ), numa]) softmmu_ss.add(when: 'CONFIG_POSIX', if_true: files('rng-random.c')) diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h new file mode 100644 index 0000000000..5f131023ba --- /dev/null +++ b/include/exec/confidential-guest-support.h @@ -0,0 +1,38 @@ +/* + * QEMU Confidential Guest support + * This interface describes the common pieces between various + * schemes for protecting guest memory or other state 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_CONFIDENTIAL_GUEST_SUPPORT_H +#define QEMU_CONFIDENTIAL_GUEST_SUPPORT_H + +#ifndef CONFIG_USER_ONLY + +#include "qom/object.h" + +#define TYPE_CONFIDENTIAL_GUEST_SUPPORT "confidential-guest-support" +OBJECT_DECLARE_SIMPLE_TYPE(ConfidentialGuestSupport, CONFIDENTIAL_GUEST_SUPPORT) + +struct ConfidentialGuestSupport { + Object parent; +}; + +typedef struct ConfidentialGuestSupportClass { + ObjectClass parent; +} ConfidentialGuestSupportClass; + +#endif /* !CONFIG_USER_ONLY */ + +#endif /* QEMU_CONFIDENTIAL_GUEST_SUPPORT_H */ diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 976b529dfb..33685c79ed 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -36,6 +36,7 @@ typedef struct BusState BusState; typedef struct Chardev Chardev; typedef struct CompatProperty CompatProperty; typedef struct CoMutex CoMutex; +typedef struct ConfidentialGuestSupport ConfidentialGuestSupport; typedef struct CPUAddressSpace CPUAddressSpace; typedef struct CPUState CPUState; typedef struct DeviceListener DeviceListener; diff --git a/target/i386/sev.c b/target/i386/sev.c index 1546606811..6b49925f51 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -31,6 +31,7 @@ #include "qom/object.h" #include "exec/address-spaces.h" #include "monitor/monitor.h" +#include "exec/confidential-guest-support.h" #define TYPE_SEV_GUEST "sev-guest" OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState, SEV_GUEST) @@ -322,7 +323,7 @@ sev_guest_instance_init(Object *obj) /* sev guest info */ static const TypeInfo sev_guest_info = { - .parent = TYPE_OBJECT, + .parent = TYPE_CONFIDENTIAL_GUEST_SUPPORT, .name = TYPE_SEV_GUEST, .instance_size = sizeof(SevGuestState), .instance_finalize = sev_guest_finalize, From patchwork Wed Jan 13 23:58:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12018203 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,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 D5ACEC43142 for ; Thu, 14 Jan 2021 01:53:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AA6372074A for ; Thu, 14 Jan 2021 01:53:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727646AbhANBxl (ORCPT ); Wed, 13 Jan 2021 20:53:41 -0500 Received: from ozlabs.org ([203.11.71.1]:53889 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729608AbhAMX7L (ORCPT ); Wed, 13 Jan 2021 18:59:11 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 4DGPXQ2cc7z9sWK; Thu, 14 Jan 2021 10:58:14 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1610582294; bh=thJIxYImNDEGyMXfz3IxBysZDEAVYAA8TpCNd/GoFv4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LUZSZpzHhIh+aQUgZMNAMYDGFjl7hsS01f0a3uX7lhdjtvXrisZHo1rOogRdbuRiW BtbO570Xc5xpifpHqCzpxxOhK2p/O/7Gd+6APuxF3O0Ld+eC75Je+/+Ue+y4xSQg6Y ZgSuWtdbUYUrsLal9vikkfBewsMyn7xkHfIb0oao= From: David Gibson To: brijesh.singh@amd.com, pair@us.ibm.com, dgilbert@redhat.com, pasic@linux.ibm.com, qemu-devel@nongnu.org Cc: cohuck@redhat.com, Richard Henderson , Marcelo Tosatti , David Hildenbrand , borntraeger@de.ibm.com, Marcel Apfelbaum , Paolo Bonzini , mst@redhat.com, jun.nakajima@intel.com, thuth@redhat.com, pragyansri.pathi@intel.com, kvm@vger.kernel.org, Eduardo Habkost , qemu-s390x@nongnu.org, qemu-ppc@nongnu.org, frankja@linux.ibm.com, Greg Kurz , mdroth@linux.vnet.ibm.com, David Gibson , berrange@redhat.com, andi.kleen@intel.com Subject: [PATCH v7 03/13] sev: Remove false abstraction of flash encryption Date: Thu, 14 Jan 2021 10:58:01 +1100 Message-Id: <20210113235811.1909610-4-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210113235811.1909610-1-david@gibson.dropbear.id.au> References: <20210113235811.1909610-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org When AMD's SEV memory encryption is in use, flash memory banks (which are initialed by pc_system_flash_map()) need to be encrypted with the guest's key, so that the guest can read them. That's abstracted via the kvm_memcrypt_encrypt_data() callback in the KVM state.. except, that it doesn't really abstract much at all. For starters, the only called is in code specific to the 'pc' family of machine types, so it's obviously specific to those and to x86 to begin with. But it makes a bunch of further assumptions that need not be true about an arbitrary confidential guest system based on memory encryption, let alone one based on other mechanisms: * it assumes that the flash memory is defined to be encrypted with the guest key, rather than being shared with hypervisor * it assumes that that hypervisor has some mechanism to encrypt data into the guest, even though it can't decrypt it out, since that's the whole point * the interface assumes that this encrypt can be done in place, which implies that the hypervisor can write into a confidential guests's memory, even if what it writes isn't meaningful So really, this "abstraction" is actually pretty specific to the way SEV works. So, this patch removes it and instead has the PC flash initialization code call into a SEV specific callback. Signed-off-by: David Gibson Reviewed-by: Cornelia Huck --- accel/kvm/kvm-all.c | 31 ++----------------------------- accel/kvm/sev-stub.c | 9 ++------- accel/stubs/kvm-stub.c | 10 ---------- hw/i386/pc_sysfw.c | 17 ++++++----------- include/sysemu/kvm.h | 16 ---------------- include/sysemu/sev.h | 4 ++-- target/i386/sev-stub.c | 5 +++++ target/i386/sev.c | 24 ++++++++++++++---------- 8 files changed, 31 insertions(+), 85 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 389eaace72..260ed73ffe 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -120,10 +120,6 @@ 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); - /* For "info mtree -f" to tell if an MR is registered in KVM */ int nr_as; struct KVMAs { @@ -222,26 +218,6 @@ int kvm_get_max_memslots(void) return s->nr_slots; } -bool kvm_memcrypt_enabled(void) -{ - if (kvm_state && kvm_state->memcrypt_handle) { - return true; - } - - return false; -} - -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); - } - - return 1; -} - /* Called with KVMMemoryListener.slots_lock held */ static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml) { @@ -2206,13 +2182,10 @@ 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) { - ret = -1; + ret = sev_guest_init(ms->memory_encryption); + if (ret < 0) { 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..5db9ab8f00 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_guest_init(const char *id) { - abort(); -} - -void *sev_guest_init(const char *id) -{ - return NULL; + return -1; } 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 92e90ff013..11172214f1 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 "sysemu/sev.h" #define FLASH_SECTOR_SIZE 4096 @@ -147,7 +148,7 @@ static void pc_system_flash_map(PCMachineState *pcms, PFlashCFI01 *system_flash; MemoryRegion *flash_mem; void *flash_ptr; - int ret, flash_size; + int flash_size; assert(PC_MACHINE_GET_CLASS(pcms)->pci_enabled); @@ -191,16 +192,10 @@ static void pc_system_flash_map(PCMachineState *pcms, flash_mem = pflash_cfi01_get_memory(system_flash); pc_isa_bios_init(rom_memory, flash_mem, size); - /* Encrypt the pflash boot ROM */ - if (kvm_memcrypt_enabled()) { - 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); - if (ret) { - error_report("failed to encrypt pflash rom"); - exit(1); - } - } + /* Encrypt the pflash boot ROM, if necessary */ + flash_ptr = memory_region_get_ram_ptr(flash_mem); + flash_size = memory_region_size(flash_mem); + sev_encrypt_flash(flash_ptr, flash_size, &error_fatal); } } } diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index bb5d5cf497..11cf0b875d 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -233,22 +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" diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h index 7ab6e3e31d..7335e59867 100644 --- a/include/sysemu/sev.h +++ b/include/sysemu/sev.h @@ -16,8 +16,8 @@ #include "sysemu/kvm.h" -void *sev_guest_init(const char *id); -int sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len); +int sev_guest_init(const char *id); +int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp); int sev_inject_launch_secret(const char *hdr, const char *secret, uint64_t gpa, Error **errp); #endif diff --git a/target/i386/sev-stub.c b/target/i386/sev-stub.c index c1fecc2101..1ac1fd5b94 100644 --- a/target/i386/sev-stub.c +++ b/target/i386/sev-stub.c @@ -54,3 +54,8 @@ int sev_inject_launch_secret(const char *hdr, const char *secret, { return 1; } + +int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp) +{ + return 0; +} diff --git a/target/i386/sev.c b/target/i386/sev.c index 6b49925f51..2a4b2187d6 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -682,7 +682,7 @@ sev_vm_state_change(void *opaque, int running, RunState state) } } -void * +int sev_guest_init(const char *id) { SevGuestState *sev; @@ -695,7 +695,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; + return -1; } sev = lookup_sev_guest_info(id); @@ -766,23 +766,27 @@ 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) +sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp) { - SevGuestState *sev = handle; - - assert(sev); + if (!sev_guest) { + return 0; + } /* if SEV is in update state then encrypt the data else do nothing */ - if (sev_check_state(sev, SEV_STATE_LAUNCH_UPDATE)) { - return sev_launch_update_data(sev, ptr, len); + if (sev_check_state(sev_guest, SEV_STATE_LAUNCH_UPDATE)) { + int ret = sev_launch_update_data(sev_guest, ptr, len); + if (ret < 0) { + error_setg(errp, "failed to encrypt pflash rom"); + return ret; + } } return 0; From patchwork Wed Jan 13 23:58:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12018185 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,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 6CC0BC43381 for ; Thu, 14 Jan 2021 01:53:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2B43A2074A for ; Thu, 14 Jan 2021 01:53:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728104AbhANBxQ (ORCPT ); Wed, 13 Jan 2021 20:53:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47518 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729550AbhANABP (ORCPT ); Wed, 13 Jan 2021 19:01:15 -0500 Received: from ozlabs.org (ozlabs.org [IPv6:2401:3900:2:1::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D09FDC0617A5 for ; Wed, 13 Jan 2021 15:58:23 -0800 (PST) Received: by ozlabs.org (Postfix, from userid 1007) id 4DGPXQ5D5fz9sWd; Thu, 14 Jan 2021 10:58:14 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1610582294; bh=lmXvmEt0/qEDekwjJo+m9ott2kpnTrEBhRR6dc7AzfU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dyuLBFF+Gf344EZ7cUI8JJbiLd5ucniv8+ujDAn3fsU0H6dphtdEuQpQfvn+8ZuZA XDq3UJxuOLCCxVHnDNUac45PV4jI4dJgQ+yDO2kIirI7gqurwfpsBX1yLaKa9TOvfF 6OFEBhX/vjhqLISBbUN8BBoj127pgFwsdpnqjH2s= From: David Gibson To: brijesh.singh@amd.com, pair@us.ibm.com, dgilbert@redhat.com, pasic@linux.ibm.com, qemu-devel@nongnu.org Cc: cohuck@redhat.com, Richard Henderson , Marcelo Tosatti , David Hildenbrand , borntraeger@de.ibm.com, Marcel Apfelbaum , Paolo Bonzini , mst@redhat.com, jun.nakajima@intel.com, thuth@redhat.com, pragyansri.pathi@intel.com, kvm@vger.kernel.org, Eduardo Habkost , qemu-s390x@nongnu.org, qemu-ppc@nongnu.org, frankja@linux.ibm.com, Greg Kurz , mdroth@linux.vnet.ibm.com, David Gibson , berrange@redhat.com, andi.kleen@intel.com Subject: [PATCH v7 04/13] confidential guest support: Move side effect out of machine_set_memory_encryption() Date: Thu, 14 Jan 2021 10:58:02 +1100 Message-Id: <20210113235811.1909610-5-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210113235811.1909610-1-david@gibson.dropbear.id.au> References: <20210113235811.1909610-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 Reviewed-by: Greg Kurz Reviewed-by: Cornelia Huck --- 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 de3b8f1b31..8909117d80 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -437,14 +437,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) @@ -1166,6 +1158,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); phase_advance(PHASE_MACHINE_INITIALIZED); } From patchwork Wed Jan 13 23:58:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12018199 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,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 F334CC4160E for ; Thu, 14 Jan 2021 01:53:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C872F206C0 for ; Thu, 14 Jan 2021 01:53:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728229AbhANBxn (ORCPT ); Wed, 13 Jan 2021 20:53:43 -0500 Received: from bilbo.ozlabs.org ([203.11.71.1]:52005 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729681AbhAMX7K (ORCPT ); Wed, 13 Jan 2021 18:59:10 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 4DGPXQ4TQBz9sWP; Thu, 14 Jan 2021 10:58:14 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1610582294; bh=/3Q4sEeOR4X9dZi9ZTw3f3cnX096S2u0KkWUMX2X/VM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I4F2+9SCDPHP/lj6U2abnDcLOFwrhDDaPAp4o6MoPh3C59YMMjrz4C9y2L/c8NLh5 e0r/4kUKRT0hSN5v0X6laDc48kdrVzAHUbrzcPzB+x2AiPG09h+y/p8CvrXGiETISL VaEGB6D5YM8GL47ZBYFCGW9aB+2IuNL6F4XRmF9g= From: David Gibson To: brijesh.singh@amd.com, pair@us.ibm.com, dgilbert@redhat.com, pasic@linux.ibm.com, qemu-devel@nongnu.org Cc: cohuck@redhat.com, Richard Henderson , Marcelo Tosatti , David Hildenbrand , borntraeger@de.ibm.com, Marcel Apfelbaum , Paolo Bonzini , mst@redhat.com, jun.nakajima@intel.com, thuth@redhat.com, pragyansri.pathi@intel.com, kvm@vger.kernel.org, Eduardo Habkost , qemu-s390x@nongnu.org, qemu-ppc@nongnu.org, frankja@linux.ibm.com, Greg Kurz , mdroth@linux.vnet.ibm.com, David Gibson , berrange@redhat.com, andi.kleen@intel.com Subject: [PATCH v7 05/13] confidential guest support: Rework the "memory-encryption" property Date: Thu, 14 Jan 2021 10:58:03 +1100 Message-Id: <20210113235811.1909610-6-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210113235811.1909610-1-david@gibson.dropbear.id.au> References: <20210113235811.1909610-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 "confidential-guest-support" 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: Greg Kurz Reviewed-by: Cornelia Huck --- accel/kvm/kvm-all.c | 5 +++-- accel/kvm/sev-stub.c | 5 +++-- hw/core/machine.c | 43 +++++++++++++++++++++++++++++++++++++------ include/hw/boards.h | 2 +- include/sysemu/sev.h | 2 +- target/i386/sev.c | 32 ++------------------------------ 6 files changed, 47 insertions(+), 42 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 260ed73ffe..28ab126f70 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2181,8 +2181,9 @@ static int kvm_init(MachineState *ms) * if memory encryption object is specified then initialize the memory * encryption context. */ - if (ms->memory_encryption) { - ret = sev_guest_init(ms->memory_encryption); + if (ms->cgs) { + /* FIXME handle mechanisms other than SEV */ + ret = sev_kvm_init(ms->cgs); if (ret < 0) { goto err; } diff --git a/accel/kvm/sev-stub.c b/accel/kvm/sev-stub.c index 5db9ab8f00..3d4787ae4a 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_guest_init(const char *id) +int sev_kvm_init(ConfidentialGuestSupport *cgs) { - return -1; + /* SEV can't be selected if it's not compiled */ + g_assert_not_reached(); } diff --git a/hw/core/machine.c b/hw/core/machine.c index 8909117d80..94194ab82d 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -32,6 +32,7 @@ #include "hw/mem/nvdimm.h" #include "migration/global_state.h" #include "migration/vmstate.h" +#include "exec/confidential-guest-support.h" GlobalProperty hw_compat_5_2[] = {}; const size_t hw_compat_5_2_len = G_N_ELEMENTS(hw_compat_5_2); @@ -427,16 +428,37 @@ static char *machine_get_memory_encryption(Object *obj, Error **errp) { MachineState *ms = MACHINE(obj); - return g_strdup(ms->memory_encryption); + if (ms->cgs) { + return g_strdup(object_get_canonical_path_component(OBJECT(ms->cgs))); + } + + return NULL; } static void machine_set_memory_encryption(Object *obj, const char *value, Error **errp) { - MachineState *ms = MACHINE(obj); + Object *cgs = + object_resolve_path_component(object_get_objects_root(), value); + + if (!cgs) { + 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, "confidential-guest-support", cgs, errp); +} + +static void machine_check_confidential_guest_support(const Object *obj, + const char *name, + Object *new_target, + Error **errp) +{ + /* + * So far the only constraint is that the target has the + * TYPE_CONFIDENTIAL_GUEST_SUPPORT interface, and that's checked + * by the QOM core + */ } static bool machine_get_nvdimm(Object *obj, Error **errp) @@ -836,6 +858,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, "confidential-guest-support", + TYPE_CONFIDENTIAL_GUEST_SUPPORT, + offsetof(MachineState, cgs), + machine_check_confidential_guest_support, + OBJ_PROP_LINK_STRONG); + object_class_property_set_description(oc, "confidential-guest-support", + "Set confidential guest scheme to support"); + + /* 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", @@ -1158,9 +1189,9 @@ void machine_run_board_init(MachineState *machine) cc->deprecation_note); } - if (machine->memory_encryption) { + if (machine->cgs) { /* - * With memory encryption, the host can't see the real + * With confidential guests, 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 17b1f3f0b9..1acd662fa5 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -270,7 +270,7 @@ struct MachineState { bool iommu; bool suppress_vmdesc; bool enable_graphics; - char *memory_encryption; + ConfidentialGuestSupport *cgs; char *ram_memdev_id; /* * convenience alias to ram_memdev_id backend memory region diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h index 7335e59867..3b5b1aacf1 100644 --- a/include/sysemu/sev.h +++ b/include/sysemu/sev.h @@ -16,7 +16,7 @@ #include "sysemu/kvm.h" -int sev_guest_init(const char *id); +int sev_kvm_init(ConfidentialGuestSupport *cgs); int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp); int sev_inject_launch_secret(const char *hdr, const char *secret, uint64_t gpa, Error **errp); diff --git a/target/i386/sev.c b/target/i386/sev.c index 2a4b2187d6..5399a136ad 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -335,26 +335,6 @@ static const TypeInfo sev_guest_info = { } }; -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) { @@ -682,10 +662,9 @@ sev_vm_state_change(void *opaque, int running, RunState state) } } -int -sev_guest_init(const char *id) +int sev_kvm_init(ConfidentialGuestSupport *cgs) { - SevGuestState *sev; + SevGuestState *sev = SEV_GUEST(cgs); char *devname; int ret, fw_error; uint32_t ebx; @@ -698,13 +677,6 @@ sev_guest_init(const char *id) return -1; } - 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; - } - sev_guest = sev; sev->state = SEV_STATE_UNINIT; From patchwork Wed Jan 13 23:58:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12018205 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=unavailable 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 7CCECC41620 for ; Thu, 14 Jan 2021 01:53:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 448F22074A for ; Thu, 14 Jan 2021 01:53:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728273AbhANBxp (ORCPT ); Wed, 13 Jan 2021 20:53:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47246 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729683AbhAMX7I (ORCPT ); Wed, 13 Jan 2021 18:59:08 -0500 Received: from ozlabs.org (ozlabs.org [IPv6:2401:3900:2:1::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CC9A1C0617A4 for ; Wed, 13 Jan 2021 15:58:23 -0800 (PST) Received: by ozlabs.org (Postfix, from userid 1007) id 4DGPXQ66Hrz9sWX; Thu, 14 Jan 2021 10:58:14 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1610582294; bh=Dv66XL0Xu5XiFw4ZQdSY1TGdKn45Up+V2jY+iQE5wYQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JdKn1pyUgh8JG5peE6mRyJ64v8KTjhz72BvdOgs5QU/LfMlPjPuWaw8GqxGDlCXqq 3SWntlvSbE+ZZfh0iqWAKIyw0C0KCBeYMTMAuY5p2+wLto1rqq5NSs4Nt/JYMwaXuf k0ewiEFCG4zhlVaFaS/0U7y7gmboRPSLhFpjQyJs= From: David Gibson To: brijesh.singh@amd.com, pair@us.ibm.com, dgilbert@redhat.com, pasic@linux.ibm.com, qemu-devel@nongnu.org Cc: cohuck@redhat.com, Richard Henderson , Marcelo Tosatti , David Hildenbrand , borntraeger@de.ibm.com, Marcel Apfelbaum , Paolo Bonzini , mst@redhat.com, jun.nakajima@intel.com, thuth@redhat.com, pragyansri.pathi@intel.com, kvm@vger.kernel.org, Eduardo Habkost , qemu-s390x@nongnu.org, qemu-ppc@nongnu.org, frankja@linux.ibm.com, Greg Kurz , mdroth@linux.vnet.ibm.com, David Gibson , berrange@redhat.com, andi.kleen@intel.com, =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PATCH v7 06/13] sev: Add Error ** to sev_kvm_init() Date: Thu, 14 Jan 2021 10:58:04 +1100 Message-Id: <20210113235811.1909610-7-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210113235811.1909610-1-david@gibson.dropbear.id.au> References: <20210113235811.1909610-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 | 2 +- include/sysemu/sev.h | 2 +- target/i386/sev.c | 31 +++++++++++++++---------------- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 28ab126f70..c5b0750fd0 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2182,9 +2182,11 @@ static int kvm_init(MachineState *ms) * encryption context. */ if (ms->cgs) { + Error *local_err = NULL; /* FIXME handle mechanisms other than SEV */ - ret = sev_kvm_init(ms->cgs); + ret = sev_kvm_init(ms->cgs, &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 3d4787ae4a..512e205f7f 100644 --- a/accel/kvm/sev-stub.c +++ b/accel/kvm/sev-stub.c @@ -15,7 +15,7 @@ #include "qemu-common.h" #include "sysemu/sev.h" -int sev_kvm_init(ConfidentialGuestSupport *cgs) +int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) { /* 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 3b5b1aacf1..5c5a13c6ca 100644 --- a/include/sysemu/sev.h +++ b/include/sysemu/sev.h @@ -16,7 +16,7 @@ #include "sysemu/kvm.h" -int sev_kvm_init(ConfidentialGuestSupport *cgs); +int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp); int sev_inject_launch_secret(const char *hdr, const char *secret, uint64_t gpa, Error **errp); diff --git a/target/i386/sev.c b/target/i386/sev.c index 5399a136ad..e2b41ef342 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -662,7 +662,7 @@ sev_vm_state_change(void *opaque, int running, RunState state) } } -int sev_kvm_init(ConfidentialGuestSupport *cgs) +int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) { SevGuestState *sev = SEV_GUEST(cgs); char *devname; @@ -684,14 +684,14 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs) 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; } @@ -700,20 +700,19 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs) 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; @@ -723,14 +722,14 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs) 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 Wed Jan 13 23:58:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12018201 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=unavailable 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 11F32C072AD for ; Thu, 14 Jan 2021 01:53:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E45A72074A for ; Thu, 14 Jan 2021 01:53:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728253AbhANBxo (ORCPT ); Wed, 13 Jan 2021 20:53:44 -0500 Received: from bilbo.ozlabs.org ([203.11.71.1]:35947 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729680AbhAMX7J (ORCPT ); Wed, 13 Jan 2021 18:59:09 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 4DGPXQ6v7Cz9sWk; Thu, 14 Jan 2021 10:58:14 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1610582294; bh=idJr0chYvjooRoA3aqKnU601BZd17+94MhdcU47V62A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZL+y3MKlNgB5V+HRIddau2xZRc6ivsKrn3t/xFPR8WxiViIiH2Xk6XkGU+p50nzp3 9PiQflWHy4l7o9AMlYI6cuxI6Ra0IMEMQUAlves2Zjz6icBTX85QlI1njCPu4/yEZ+ 0oS6eZN8sQ8K+HEg3dVIKHxSHipa8jKx9IAI+y9E= From: David Gibson To: brijesh.singh@amd.com, pair@us.ibm.com, dgilbert@redhat.com, pasic@linux.ibm.com, qemu-devel@nongnu.org Cc: cohuck@redhat.com, Richard Henderson , Marcelo Tosatti , David Hildenbrand , borntraeger@de.ibm.com, Marcel Apfelbaum , Paolo Bonzini , mst@redhat.com, jun.nakajima@intel.com, thuth@redhat.com, pragyansri.pathi@intel.com, kvm@vger.kernel.org, Eduardo Habkost , qemu-s390x@nongnu.org, qemu-ppc@nongnu.org, frankja@linux.ibm.com, Greg Kurz , mdroth@linux.vnet.ibm.com, David Gibson , berrange@redhat.com, andi.kleen@intel.com Subject: [PATCH v7 07/13] confidential guest support: Introduce cgs "ready" flag Date: Thu, 14 Jan 2021 10:58:05 +1100 Message-Id: <20210113235811.1909610-8-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210113235811.1909610-1-david@gibson.dropbear.id.au> References: <20210113235811.1909610-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 confidential guest support may require setup at various points during initialization. Thus, it's not really feasible to have a single cgs 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 cgs has been initialized if it was requested. This patch introduces a ready flag to the ConfidentialGuestSupport base type to accomplish this, which we verify just before the machine specific initialization function. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cornelia Huck --- hw/core/machine.c | 8 ++++++++ include/exec/confidential-guest-support.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 94194ab82d..5a7433332b 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -1190,6 +1190,14 @@ void machine_run_board_init(MachineState *machine) } if (machine->cgs) { + /* + * Where confidential guest support 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 cgs mechanism. + */ + assert(machine->cgs->ready); + /* * With confidential guests, 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/confidential-guest-support.h b/include/exec/confidential-guest-support.h index 5f131023ba..bcaf6c9f49 100644 --- a/include/exec/confidential-guest-support.h +++ b/include/exec/confidential-guest-support.h @@ -27,6 +27,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(ConfidentialGuestSupport, CONFIDENTIAL_GUEST_SUPPORT) struct ConfidentialGuestSupport { Object parent; + + bool ready; }; typedef struct ConfidentialGuestSupportClass { diff --git a/target/i386/sev.c b/target/i386/sev.c index e2b41ef342..3d94635397 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -737,6 +737,8 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) qemu_add_machine_init_done_notifier(&sev_machine_done_notify); qemu_add_vm_change_state_handler(sev_vm_state_change, sev); + cgs->ready = true; + return 0; err: sev_guest = NULL; From patchwork Wed Jan 13 23:58:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12018195 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,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 7EE02C43219 for ; Thu, 14 Jan 2021 01:53:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5BBED2074A for ; Thu, 14 Jan 2021 01:53:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728164AbhANBxV (ORCPT ); Wed, 13 Jan 2021 20:53:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47516 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729702AbhANABN (ORCPT ); Wed, 13 Jan 2021 19:01:13 -0500 Received: from ozlabs.org (bilbo.ozlabs.org [IPv6:2401:3900:2:1::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CF957C0617A9 for ; Wed, 13 Jan 2021 15:58:25 -0800 (PST) Received: by ozlabs.org (Postfix, from userid 1007) id 4DGPXR1Tr1z9sXb; Thu, 14 Jan 2021 10:58:14 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1610582295; bh=DVHvwIFYF5zIwyyGLWDcCato2JVKksJgBlh9j+VQqL0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jTlVEvch3zry53tRmBDlCkK4cf+QcvmCRDcfLu/b5oIXVVQY5077CPMkSyEjN3U8s g5PBBzdxOqRo3z+l7T9m+S4pqmIV3le8DKxYkdbteZXEytSD9p7MbM1Evo3zsytRN8 jrfQK8ZJtUmeLoUSk8ZvXAY/Jr6RG6t2NX0tH6lg= From: David Gibson To: brijesh.singh@amd.com, pair@us.ibm.com, dgilbert@redhat.com, pasic@linux.ibm.com, qemu-devel@nongnu.org Cc: cohuck@redhat.com, Richard Henderson , Marcelo Tosatti , David Hildenbrand , borntraeger@de.ibm.com, Marcel Apfelbaum , Paolo Bonzini , mst@redhat.com, jun.nakajima@intel.com, thuth@redhat.com, pragyansri.pathi@intel.com, kvm@vger.kernel.org, Eduardo Habkost , qemu-s390x@nongnu.org, qemu-ppc@nongnu.org, frankja@linux.ibm.com, Greg Kurz , mdroth@linux.vnet.ibm.com, David Gibson , berrange@redhat.com, andi.kleen@intel.com Subject: [PATCH v7 08/13] confidential guest support: Move SEV initialization into arch specific code Date: Thu, 14 Jan 2021 10:58:06 +1100 Message-Id: <20210113235811.1909610-9-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210113235811.1909610-1-david@gibson.dropbear.id.au> References: <20210113235811.1909610-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 Reviewed-by: Cornelia Huck --- accel/kvm/kvm-all.c | 14 -------------- accel/kvm/sev-stub.c | 4 ++-- target/i386/kvm/kvm.c | 12 ++++++++++++ target/i386/sev.c | 7 ++++++- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index c5b0750fd0..adf27c1864 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2177,20 +2177,6 @@ static int kvm_init(MachineState *ms) kvm_state = s; - /* - * if memory encryption object is specified then initialize the memory - * encryption context. - */ - if (ms->cgs) { - Error *local_err = NULL; - /* FIXME handle mechanisms other than SEV */ - ret = sev_kvm_init(ms->cgs, &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/accel/kvm/sev-stub.c b/accel/kvm/sev-stub.c index 512e205f7f..9587d1b2a3 100644 --- a/accel/kvm/sev-stub.c +++ b/accel/kvm/sev-stub.c @@ -17,6 +17,6 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) { - /* SEV can't be selected if it's not compiled */ - g_assert_not_reached(); + /* If we get here, cgs must be some non-SEV thing */ + return 0; } diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 6dc1ee052d..e8b9dc48a2 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/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" @@ -2135,6 +2136,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->cgs, &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 3d94635397..aa79cacabe 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -664,13 +664,18 @@ sev_vm_state_change(void *opaque, int running, RunState state) int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) { - SevGuestState *sev = SEV_GUEST(cgs); + SevGuestState *sev + = (SevGuestState *)object_dynamic_cast(OBJECT(cgs), 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 Wed Jan 13 23:58:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12018189 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,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 35514C43332 for ; Thu, 14 Jan 2021 01:53:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F3A4F2074A for ; Thu, 14 Jan 2021 01:53:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728223AbhANBxW (ORCPT ); Wed, 13 Jan 2021 20:53:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47514 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729703AbhANABN (ORCPT ); Wed, 13 Jan 2021 19:01:13 -0500 Received: from ozlabs.org (bilbo.ozlabs.org [IPv6:2401:3900:2:1::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB7F7C0617A6 for ; Wed, 13 Jan 2021 15:58:25 -0800 (PST) Received: by ozlabs.org (Postfix, from userid 1007) id 4DGPXR0hDnz9sX1; Thu, 14 Jan 2021 10:58:15 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1610582295; bh=XAe7Xx+YpNUPHcyhxW/cHKgMuEbgQoNbc1c/1ol/ah8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WHrQo0CpGmuAyajbdwUMx7qgn9Kr7iTclU8Uk3Goi3mgJfMWU9Nzex3+mn0SUfPIy xecXjdlhCJ1+mTEjl5fbqWu0n2T0lKHXdsVYiVX+tGC9y732Yulz2rRkTGA0sx0BfA V3fI8nw9ocNIb/PNhEsP0m0vgGwV8LbBBaXzbDoM= From: David Gibson To: brijesh.singh@amd.com, pair@us.ibm.com, dgilbert@redhat.com, pasic@linux.ibm.com, qemu-devel@nongnu.org Cc: cohuck@redhat.com, Richard Henderson , Marcelo Tosatti , David Hildenbrand , borntraeger@de.ibm.com, Marcel Apfelbaum , Paolo Bonzini , mst@redhat.com, jun.nakajima@intel.com, thuth@redhat.com, pragyansri.pathi@intel.com, kvm@vger.kernel.org, Eduardo Habkost , qemu-s390x@nongnu.org, qemu-ppc@nongnu.org, frankja@linux.ibm.com, Greg Kurz , mdroth@linux.vnet.ibm.com, David Gibson , berrange@redhat.com, andi.kleen@intel.com Subject: [PATCH v7 09/13] confidential guest support: Update documentation Date: Thu, 14 Jan 2021 10:58:07 +1100 Message-Id: <20210113235811.1909610-10-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210113235811.1909610-1-david@gibson.dropbear.id.au> References: <20210113235811.1909610-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Now that we've implemented a generic machine option for configuring various confidential guest support mechanisms: 1. Update docs/amd-memory-encryption.txt to reference this rather than the earlier SEV specific option 2. Add a docs/confidential-guest-support.txt to cover the generalities of the confidential guest support scheme Signed-off-by: David Gibson Reviewed-by: Greg Kurz --- docs/amd-memory-encryption.txt | 2 +- docs/confidential-guest-support.txt | 43 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 docs/confidential-guest-support.txt diff --git a/docs/amd-memory-encryption.txt b/docs/amd-memory-encryption.txt index 80b8eb00e9..145896aec7 100644 --- a/docs/amd-memory-encryption.txt +++ b/docs/amd-memory-encryption.txt @@ -73,7 +73,7 @@ complete flow chart. To launch a SEV guest # ${QEMU} \ - -machine ...,memory-encryption=sev0 \ + -machine ...,confidential-guest-support=sev0 \ -object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1 Debugging diff --git a/docs/confidential-guest-support.txt b/docs/confidential-guest-support.txt new file mode 100644 index 0000000000..2790425b38 --- /dev/null +++ b/docs/confidential-guest-support.txt @@ -0,0 +1,43 @@ +Confidential Guest Support +========================== + +Traditionally, hypervisors such as qemu have complete access to a +guest's memory and other state, meaning that a compromised hypervisor +can compromise any of its guests. A number of platforms have added +mechanisms in hardware and/or firmware which give guests at least some +protection from a compromised hypervisor. This is obviously +especially desirable for public cloud environments. + +These mechanisms have different names and different modes of +operation, but are often referred to as Secure Guests or Confidential +Guests. We use the term "Confidential Guest Support" to distinguish +this from other aspects of guest security (such as security against +attacks from other guests, or from network sources). + +Running a Confidential Guest +---------------------------- + +To run a confidential guest you need to add two command line parameters: + +1. Use "-object" to create a "confidential guest support" object. The + type and parameters will vary with the specific mechanism to be + used +2. Set the "confidential-guest-support" machine parameter to the ID of + the object from (1). + +Example (for AMD SEV):: + + qemu-system-x86_64 \ + \ + -machine ...,confidential-guest-support=sev0 \ + -object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1 + +Supported mechanisms +-------------------- + +Currently supported confidential guest mechanisms are: + +AMD Secure Encrypted Virtualization (SEV) + docs/amd-memory-encryption.txt + +Other mechanisms may be supported in future. From patchwork Wed Jan 13 23:58:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12018207 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,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 8EC13C07548 for ; Thu, 14 Jan 2021 01:53:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6933E206C0 for ; Thu, 14 Jan 2021 01:53:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728250AbhANBxo (ORCPT ); Wed, 13 Jan 2021 20:53:44 -0500 Received: from bilbo.ozlabs.org ([203.11.71.1]:45729 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729682AbhAMX7K (ORCPT ); Wed, 13 Jan 2021 18:59:10 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 4DGPXR2NGfz9sXH; Thu, 14 Jan 2021 10:58:15 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1610582295; bh=RYQUxxrIJnb6U4ZslRMJnpr5hI4pN7/28Mmn1jMp/TQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GZYtAx3Tsn2Zv63D3+yKoYKjXkQFC96WF3p1PfEJgfcsY9rATNj4Yf3bo3UbhkIw8 Vgtgj8pzC/JjAcoJkedkDlX25UlFtWLQiIDiTZ1MZ9X6Q1Ac7v5o1TZyGdo9UP6X4P JSms9Sb4i68oSTj4UuC/pLFi0k/wH/D3t49HhAhg= From: David Gibson To: brijesh.singh@amd.com, pair@us.ibm.com, dgilbert@redhat.com, pasic@linux.ibm.com, qemu-devel@nongnu.org Cc: cohuck@redhat.com, Richard Henderson , Marcelo Tosatti , David Hildenbrand , borntraeger@de.ibm.com, Marcel Apfelbaum , Paolo Bonzini , mst@redhat.com, jun.nakajima@intel.com, thuth@redhat.com, pragyansri.pathi@intel.com, kvm@vger.kernel.org, Eduardo Habkost , qemu-s390x@nongnu.org, qemu-ppc@nongnu.org, frankja@linux.ibm.com, Greg Kurz , mdroth@linux.vnet.ibm.com, David Gibson , berrange@redhat.com, andi.kleen@intel.com Subject: [PATCH v7 10/13] spapr: Add PEF based confidential guest support Date: Thu, 14 Jan 2021 10:58:08 +1100 Message-Id: <20210113235811.1909610-11-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210113235811.1909610-1-david@gibson.dropbear.id.au> References: <20210113235811.1909610-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 confidential-guest-support 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 confidential-guest-support=pef0 Signed-off-by: David Gibson --- docs/confidential-guest-support.txt | 3 + docs/papr-pef.txt | 30 +++++++ hw/ppc/meson.build | 1 + hw/ppc/pef.c | 119 ++++++++++++++++++++++++++++ hw/ppc/spapr.c | 6 ++ include/hw/ppc/pef.h | 25 ++++++ target/ppc/kvm.c | 18 ----- target/ppc/kvm_ppc.h | 6 -- 8 files changed, 184 insertions(+), 24 deletions(-) create mode 100644 docs/papr-pef.txt create mode 100644 hw/ppc/pef.c create mode 100644 include/hw/ppc/pef.h diff --git a/docs/confidential-guest-support.txt b/docs/confidential-guest-support.txt index 2790425b38..f0801814ff 100644 --- a/docs/confidential-guest-support.txt +++ b/docs/confidential-guest-support.txt @@ -40,4 +40,7 @@ Currently supported confidential guest mechanisms are: AMD Secure Encrypted Virtualization (SEV) docs/amd-memory-encryption.txt +POWER Protected Execution Facility (PEF) + docs/papr-pef.txt + Other mechanisms may be supported in future. diff --git a/docs/papr-pef.txt b/docs/papr-pef.txt new file mode 100644 index 0000000000..6419e995cf --- /dev/null +++ b/docs/papr-pef.txt @@ -0,0 +1,30 @@ +POWER (PAPR) Protected Execution Facility (PEF) +=============================================== + +Protected Execution Facility (PEF), also known as Secure Guest support +is a feature found on IBM POWER9 and POWER10 processors. + +If a suitable firmware including an Ultravisor is installed, it adds +an extra memory protection mode to the CPU. The ultravisor manages a +pool of secure memory which cannot be accessed by the hypervisor. + +When this feature is enabled in qemu, a guest can use ultracalls to +enter "secure mode". This transfers most of its memory to secure +memory, where it cannot be eavesdropped by a compromised hypervisor. + +Launching +--------- + +To launch a guest which will be permitted to enter PEF secure mode: + +# ${QEMU} \ + -object pef-guest,id=pef0 \ + -machine confidential-guest-support=pef0 \ + ... + +Live Migration +---------------- + +Live migration is not yet implemented for PEF guests. For +consistency, we currently prevent migration if the PEF feature is +enabled, whether or not the guest has actually entered secure mode. 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..02b9b3b460 --- /dev/null +++ b/hw/ppc/pef.c @@ -0,0 +1,119 @@ +/* + * 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/confidential-guest-support.h" +#include "hw/ppc/pef.h" + +#define TYPE_PEF_GUEST "pef-guest" +OBJECT_DECLARE_SIMPLE_TYPE(PefGuest, PEF_GUEST) + +typedef struct PefGuest PefGuest; +typedef struct PefGuestClass PefGuestClass; + +struct PefGuestClass { + ConfidentialGuestSupportClass parent_class; +}; + +/** + * PefGuest: + * + * The PefGuest object is used for creating and managing a PEF + * guest. + * + * # $QEMU \ + * -object pef-guest,id=pef0 \ + * -machine ...,confidential-guest-support=pef0 + */ +struct PefGuest { + ConfidentialGuestSupport parent_obj; +}; + +#ifdef CONFIG_KVM +static int kvmppc_svm_init(Error **errp) +{ + if (!kvm_check_extension(kvm_state, KVM_CAP_PPC_SECURE_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(ConfidentialGuestSupport *cgs, Error **errp) +{ + if (!object_dynamic_cast(OBJECT(cgs), TYPE_PEF_GUEST)) { + return 0; + } + + if (!kvm_enabled()) { + error_setg(errp, "PEF requires KVM"); + return -1; + } + + return kvmppc_svm_init(errp); +} + +OBJECT_DEFINE_TYPE_WITH_INTERFACES(PefGuest, + pef_guest, + PEF_GUEST, + CONFIDENTIAL_GUEST_SUPPORT, + { TYPE_USER_CREATABLE }, + { NULL }) + +static void pef_guest_class_init(ObjectClass *oc, void *data) +{ +} + +static void pef_guest_init(Object *obj) +{ +} + +static void pef_guest_finalize(Object *obj) +{ +} diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 2c403b574e..accf7a834b 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -83,6 +83,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" @@ -2658,6 +2659,11 @@ static void spapr_machine_init(MachineState *machine) char *filename; Error *resize_hpt_err = NULL; + /* + * if Secure VM (PEF) support is configured, then initialize it + */ + pef_kvm_init(machine->cgs, &error_fatal); + msi_nonbroken = true; QLIST_INIT(&spapr->phbs); diff --git a/include/hw/ppc/pef.h b/include/hw/ppc/pef.h new file mode 100644 index 0000000000..57d4ec9fe6 --- /dev/null +++ b/include/hw/ppc/pef.h @@ -0,0 +1,25 @@ +/* + * 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(ConfidentialGuestSupport *cgs, 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 Wed Jan 13 23:58:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12018193 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,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 1428BC43331 for ; Thu, 14 Jan 2021 01:53:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C3CCC206C0 for ; Thu, 14 Jan 2021 01:53:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728196AbhANBxV (ORCPT ); Wed, 13 Jan 2021 20:53:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729701AbhANABN (ORCPT ); Wed, 13 Jan 2021 19:01:13 -0500 Received: from ozlabs.org (ozlabs.org [IPv6:2401:3900:2:1::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D94DDC0617B0 for ; Wed, 13 Jan 2021 15:58:25 -0800 (PST) Received: by ozlabs.org (Postfix, from userid 1007) id 4DGPXR3Gm0z9sj5; Thu, 14 Jan 2021 10:58:15 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1610582295; bh=NmD42X0WsHRqDVYpVVbDz7PiUpDumAPsjTSKm/2tvCs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eHnrJQZ9Z4likHKrb5Kig2JSXFW0K06BO15ZxTUk6xEr/KwURm9e9/XjyUT8EI6lB iY3L/J4gGwpnSp8p8o/6ndTeJ+yr82C+aujC7PsR2jVMwSVeh/t5Y3M4BvxM29ePok 8hzRL5a/WrMh32T/jRpiEVR+JaU30Vjhv16FKmP4= From: David Gibson To: brijesh.singh@amd.com, pair@us.ibm.com, dgilbert@redhat.com, pasic@linux.ibm.com, qemu-devel@nongnu.org Cc: cohuck@redhat.com, Richard Henderson , Marcelo Tosatti , David Hildenbrand , borntraeger@de.ibm.com, Marcel Apfelbaum , Paolo Bonzini , mst@redhat.com, jun.nakajima@intel.com, thuth@redhat.com, pragyansri.pathi@intel.com, kvm@vger.kernel.org, Eduardo Habkost , qemu-s390x@nongnu.org, qemu-ppc@nongnu.org, frankja@linux.ibm.com, Greg Kurz , mdroth@linux.vnet.ibm.com, David Gibson , berrange@redhat.com, andi.kleen@intel.com Subject: [PATCH v7 11/13] spapr: PEF: prevent migration Date: Thu, 14 Jan 2021 10:58:09 +1100 Message-Id: <20210113235811.1909610-12-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210113235811.1909610-1-david@gibson.dropbear.id.au> References: <20210113235811.1909610-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 Reviewed-by: Greg Kurz --- hw/ppc/pef.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hw/ppc/pef.c b/hw/ppc/pef.c index 02b9b3b460..d7a49ef337 100644 --- a/hw/ppc/pef.c +++ b/hw/ppc/pef.c @@ -42,6 +42,8 @@ struct PefGuest { }; #ifdef CONFIG_KVM +static Error *pef_mig_blocker; + static int kvmppc_svm_init(Error **errp) { if (!kvm_check_extension(kvm_state, KVM_CAP_PPC_SECURE_GUEST)) { @@ -58,6 +60,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 Wed Jan 13 23:58:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12018187 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,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable 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 9A031C4332E for ; Thu, 14 Jan 2021 01:53:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6E9522075E for ; Thu, 14 Jan 2021 01:53:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727937AbhANBxQ (ORCPT ); Wed, 13 Jan 2021 20:53:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47522 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729616AbhANABP (ORCPT ); Wed, 13 Jan 2021 19:01:15 -0500 Received: from ozlabs.org (ozlabs.org [IPv6:2401:3900:2:1::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DAE4AC0617B1 for ; Wed, 13 Jan 2021 15:58:25 -0800 (PST) Received: by ozlabs.org (Postfix, from userid 1007) id 4DGPXR4BBWz9sjB; Thu, 14 Jan 2021 10:58:15 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1610582295; bh=cJPi6/8rIQ8cwCcDD17pu1Q0OOK2AVCJGI2N7uMc4L4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=js6IfPg2vCEVsr0cG7Nxp8qFRit3WOJkeDIsZ8aQeKhwDiqQPOb3AGyScr2AmcdAp KWqhmn1YJ74MYBKVi7g7d1CbNZE1gWPrhThn8PocuUl2refDqTV35XG5Rlhqzr6CWg FVRgbPz7EsmIRCa/VafgxuLxHw4yvB53y/TSD/dc= From: David Gibson To: brijesh.singh@amd.com, pair@us.ibm.com, dgilbert@redhat.com, pasic@linux.ibm.com, qemu-devel@nongnu.org Cc: cohuck@redhat.com, Richard Henderson , Marcelo Tosatti , David Hildenbrand , borntraeger@de.ibm.com, Marcel Apfelbaum , Paolo Bonzini , mst@redhat.com, jun.nakajima@intel.com, thuth@redhat.com, pragyansri.pathi@intel.com, kvm@vger.kernel.org, Eduardo Habkost , qemu-s390x@nongnu.org, qemu-ppc@nongnu.org, frankja@linux.ibm.com, Greg Kurz , mdroth@linux.vnet.ibm.com, David Gibson , berrange@redhat.com, andi.kleen@intel.com Subject: [PATCH v7 12/13] confidential guest support: Alter virtio default properties for protected guests Date: Thu, 14 Jan 2021 10:58:10 +1100 Message-Id: <20210113235811.1909610-13-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210113235811.1909610-1-david@gibson.dropbear.id.au> References: <20210113235811.1909610-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 confidential guest 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 Reviewed-by: Greg Kurz --- hw/core/machine.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/hw/core/machine.c b/hw/core/machine.c index 5a7433332b..61ae363559 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -33,6 +33,8 @@ #include "migration/global_state.h" #include "migration/vmstate.h" #include "exec/confidential-guest-support.h" +#include "hw/virtio/virtio.h" +#include "hw/virtio/virtio-pci.h" GlobalProperty hw_compat_5_2[] = {}; const size_t hw_compat_5_2_len = G_N_ELEMENTS(hw_compat_5_2); @@ -1204,6 +1206,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 Wed Jan 13 23:58:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12018191 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=unavailable 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 C661EC4332D for ; Thu, 14 Jan 2021 01:53:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 984FF2074A for ; Thu, 14 Jan 2021 01:53:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728136AbhANBxU (ORCPT ); Wed, 13 Jan 2021 20:53:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47524 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729704AbhANABN (ORCPT ); Wed, 13 Jan 2021 19:01:13 -0500 Received: from ozlabs.org (ozlabs.org [IPv6:2401:3900:2:1::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 74516C0617B9 for ; Wed, 13 Jan 2021 15:58:28 -0800 (PST) Received: by ozlabs.org (Postfix, from userid 1007) id 4DGPXR55cYz9sjD; Thu, 14 Jan 2021 10:58:15 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1610582295; bh=Vj1RSGtq3tXPDmBRhrrfnvI3/OQqRk1glYDp8Wuofx4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EMcifB8rGQ7bJ4C/bNq90cgIoKZ4gnlKZL7TKYI7fAWaQ17H9yHCBVqnnWlprnO2d 6q4Dnm7Is7OKZRL0lWjza6ZGKJbWnwJ5v0rxsQCU3T4U1QjX/MbUnCJSmllDyKwxp0 XJpp9zIfXm0eMZmBrSu8zjHCPwk6BEtyvZyHntdw= From: David Gibson To: brijesh.singh@amd.com, pair@us.ibm.com, dgilbert@redhat.com, pasic@linux.ibm.com, qemu-devel@nongnu.org Cc: cohuck@redhat.com, Richard Henderson , Marcelo Tosatti , David Hildenbrand , borntraeger@de.ibm.com, Marcel Apfelbaum , Paolo Bonzini , mst@redhat.com, jun.nakajima@intel.com, thuth@redhat.com, pragyansri.pathi@intel.com, kvm@vger.kernel.org, Eduardo Habkost , qemu-s390x@nongnu.org, qemu-ppc@nongnu.org, frankja@linux.ibm.com, Greg Kurz , mdroth@linux.vnet.ibm.com, David Gibson , berrange@redhat.com, andi.kleen@intel.com Subject: [PATCH v7 13/13] s390: Recognize confidential-guest-support option Date: Thu, 14 Jan 2021 10:58:11 +1100 Message-Id: <20210113235811.1909610-14-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210113235811.1909610-1-david@gibson.dropbear.id.au> References: <20210113235811.1909610-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 by the "confidential-guest-support" 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 confidential-guest-support 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 confidential-guest-support is set, we will either create a guest capable of entering PV mode, or fail outright. - If confidential-guest-support is not set, guests 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 confidential-guest-support=pv0 Signed-off-by: David Gibson --- docs/confidential-guest-support.txt | 3 ++ docs/system/s390x/protvirt.rst | 19 ++++++--- hw/s390x/pv.c | 62 +++++++++++++++++++++++++++++ include/hw/s390x/pv.h | 1 + target/s390x/kvm.c | 3 ++ 5 files changed, 82 insertions(+), 6 deletions(-) diff --git a/docs/confidential-guest-support.txt b/docs/confidential-guest-support.txt index f0801814ff..50b976a082 100644 --- a/docs/confidential-guest-support.txt +++ b/docs/confidential-guest-support.txt @@ -43,4 +43,7 @@ AMD Secure Encrypted Virtualization (SEV) POWER Protected Execution Facility (PEF) docs/papr-pef.txt +s390x Protected Virtualization (PV) + docs/system/s390x/protvirt.rst + Other mechanisms may be supported in future. diff --git a/docs/system/s390x/protvirt.rst b/docs/system/s390x/protvirt.rst index 712974ad87..0f481043d9 100644 --- a/docs/system/s390x/protvirt.rst +++ b/docs/system/s390x/protvirt.rst @@ -22,15 +22,22 @@ If those requirements are met, the capability `KVM_CAP_S390_PROTECTED` will indicate that KVM can support PVMs on that LPAR. -QEMU Settings -------------- +Running a Protected Virtual Machine +----------------------------------- -To indicate to the VM that it can transition into protected mode, the +To run a PVM you will need to select a CPU model which includes the `Unpack facility` (stfle bit 161 represented by the feature -`unpack`/`S390_FEAT_UNPACK`) needs to be part of the cpu model of -the VM. +`unpack`/`S390_FEAT_UNPACK`), and add these options to the command line:: + + -object s390-pv-guest,id=pv0 \ + -machine confidential-guest-support=pv0 + +Adding these options will: + +* Ensure the `unpack` facility is available +* Enable the IOMMU by default for all I/O devices +* Initialize the PV mechanism -All I/O devices need to use the IOMMU. Passthrough (vfio) devices are currently not supported. Host huge page backings are not supported. However guests can use huge diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c index ab3a2482aa..319d74dfcf 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/confidential-guest-support.h" #include "hw/s390x/ipl.h" #include "hw/s390x/pv.h" @@ -111,3 +114,62 @@ 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" +OBJECT_DECLARE_SIMPLE_TYPE(S390PVGuest, S390_PV_GUEST) + +/** + * S390PVGuest: + * + * The S390PVGuest object is basically a dummy used to tell the + * confidential guest support system to use s390's PV mechanism. + * + * # $QEMU \ + * -object s390-pv-guest,id=pv0 \ + * -machine ...,confidential-guest-support=pv0 + */ +struct S390PVGuest { + ConfidentialGuestSupport parent_obj; +}; + +typedef struct S390PVGuestClass S390PVGuestClass; + +struct S390PVGuestClass { + ConfidentialGuestSupportClass parent_class; +}; + +int s390_pv_init(ConfidentialGuestSupport *cgs, Error **errp) +{ + if (!object_dynamic_cast(OBJECT(cgs), 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; + } + + cgs->ready = true; + + return 0; +} + +OBJECT_DEFINE_TYPE_WITH_INTERFACES(S390PVGuest, + s390_pv_guest, + S390_PV_GUEST, + CONFIDENTIAL_GUEST_SUPPORT, + { TYPE_USER_CREATABLE }, + { NULL }) + +static void s390_pv_guest_class_init(ObjectClass *oc, void *data) +{ +} + +static void s390_pv_guest_init(Object *obj) +{ +} + +static void s390_pv_guest_finalize(Object *obj) +{ +} diff --git a/include/hw/s390x/pv.h b/include/hw/s390x/pv.h index aee758bc2d..9bbf66f356 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(ConfidentialGuestSupport *cgs, 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..d2435664dc 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->cgs, &error_fatal); + return 0; }