From patchwork Fri Jul 24 02:57:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11681927 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BAE46722 for ; Fri, 24 Jul 2020 02:58:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A1887207FC for ; Fri, 24 Jul 2020 02:58:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="I8R/r6K0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726783AbgGXC5u (ORCPT ); Thu, 23 Jul 2020 22:57:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52370 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726381AbgGXC5t (ORCPT ); Thu, 23 Jul 2020 22:57:49 -0400 Received: from ozlabs.org (bilbo.ozlabs.org [IPv6:2401:3900:2:1::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BB05AC0619D3 for ; Thu, 23 Jul 2020 19:57:49 -0700 (PDT) Received: by ozlabs.org (Postfix, from userid 1007) id 4BCYlv33w0z9sSt; Fri, 24 Jul 2020 12:57:47 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1595559467; bh=aXMwhPSEkPHTpzErQPz4f4zNkJ2AVJxzRI0h3KgdOaE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I8R/r6K0P/IZg9wSKSjVg8EjaXlXMJmGktM9HhxalYdYd1gB7LXXgFxkcmHIyQHqn yxPqtlhIW670eVcVZpL3C3m1uB0rstBiBaYembN8TPTdsKUsNqvjo+wNjHOe5V8GXt lrZfMdVdBphNf6F/mciBlXPWMn31lLx5pZr4iUis= From: David Gibson To: dgilbert@redhat.com, frankja@linux.ibm.com, pair@us.ibm.com, qemu-devel@nongnu.org, pbonzini@redhat.com, brijesh.singh@amd.com Cc: ehabkost@redhat.com, marcel.apfelbaum@gmail.com, "Michael S. Tsirkin" , qemu-ppc@nongnu.org, kvm@vger.kernel.org, pasic@linux.ibm.com, qemu-s390x@nongnu.org, David Gibson , David Hildenbrand , Christian Borntraeger , Richard Henderson , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , mdroth@linux.vnet.ibm.com, Thomas Huth , Cornelia Huck , Richard Henderson Subject: [for-5.2 v4 01/10] host trust limitation: Introduce new host trust limitation interface Date: Fri, 24 Jul 2020 12:57:35 +1000 Message-Id: <20200724025744.69644-2-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200724025744.69644-1-david@gibson.dropbear.id.au> References: <20200724025744.69644-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org 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 has a similar mechanism. 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 HostTrustLimitation QOM interface. Signed-off-by: David Gibson Acked-by: Dr. David Alan Gilbert Reviewed-by: Richard Henderson --- backends/Makefile.objs | 2 ++ backends/host-trust-limitation.c | 29 ++++++++++++++++++++++++ include/exec/host-trust-limitation.h | 33 ++++++++++++++++++++++++++++ include/qemu/typedefs.h | 1 + 4 files changed, 65 insertions(+) create mode 100644 backends/host-trust-limitation.c create mode 100644 include/exec/host-trust-limitation.h diff --git a/backends/Makefile.objs b/backends/Makefile.objs index 22d204cb48..dcb8f58d31 100644 --- a/backends/Makefile.objs +++ b/backends/Makefile.objs @@ -21,3 +21,5 @@ common-obj-$(CONFIG_LINUX) += hostmem-memfd.o common-obj-$(CONFIG_GIO) += dbus-vmstate.o dbus-vmstate.o-cflags = $(GIO_CFLAGS) dbus-vmstate.o-libs = $(GIO_LIBS) + +common-obj-y += host-trust-limitation.o diff --git a/backends/host-trust-limitation.c b/backends/host-trust-limitation.c new file mode 100644 index 0000000000..96a381cd8a --- /dev/null +++ b/backends/host-trust-limitation.c @@ -0,0 +1,29 @@ +/* + * QEMU Host Trust Limitation interface + * + * Copyright: David Gibson, Red Hat Inc. 2020 + * + * Authors: + * David Gibson + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" + +#include "exec/host-trust-limitation.h" + +static const TypeInfo host_trust_limitation_info = { + .name = TYPE_HOST_TRUST_LIMITATION, + .parent = TYPE_INTERFACE, + .class_size = sizeof(HostTrustLimitationClass), +}; + +static void host_trust_limitation_register_types(void) +{ + type_register_static(&host_trust_limitation_info); +} + +type_init(host_trust_limitation_register_types) diff --git a/include/exec/host-trust-limitation.h b/include/exec/host-trust-limitation.h new file mode 100644 index 0000000000..03887b1be1 --- /dev/null +++ b/include/exec/host-trust-limitation.h @@ -0,0 +1,33 @@ +/* + * QEMU Host Trust Limitation interface + * + * Copyright: David Gibson, Red Hat Inc. 2020 + * + * Authors: + * David Gibson + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + * + */ +#ifndef QEMU_HOST_TRUST_LIMITATION_H +#define QEMU_HOST_TRUST_LIMITATION_H + +#include "qom/object.h" + +#define TYPE_HOST_TRUST_LIMITATION "host-trust-limitation" +#define HOST_TRUST_LIMITATION(obj) \ + INTERFACE_CHECK(HostTrustLimitation, (obj), \ + TYPE_HOST_TRUST_LIMITATION) +#define HOST_TRUST_LIMITATION_CLASS(klass) \ + OBJECT_CLASS_CHECK(HostTrustLimitationClass, (klass), \ + TYPE_HOST_TRUST_LIMITATION) +#define HOST_TRUST_LIMITATION_GET_CLASS(obj) \ + OBJECT_GET_CLASS(HostTrustLimitationClass, (obj), \ + TYPE_HOST_TRUST_LIMITATION) + +typedef struct HostTrustLimitationClass { + InterfaceClass parent; +} HostTrustLimitationClass; + +#endif /* QEMU_HOST_TRUST_LIMITATION_H */ diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 427027a970..624d59c037 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -51,6 +51,7 @@ typedef struct FWCfgIoState FWCfgIoState; typedef struct FWCfgMemState FWCfgMemState; typedef struct FWCfgState FWCfgState; typedef struct HostMemoryBackend HostMemoryBackend; +typedef struct HostTrustLimitation HostTrustLimitation; typedef struct I2CBus I2CBus; typedef struct I2SCodec I2SCodec; typedef struct IOMMUMemoryRegion IOMMUMemoryRegion; From patchwork Fri Jul 24 02:57:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11681911 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A0D9813B4 for ; Fri, 24 Jul 2020 02:57:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8287E20737 for ; Fri, 24 Jul 2020 02:57:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="Ax3uyoL3" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726800AbgGXC5v (ORCPT ); Thu, 23 Jul 2020 22:57:51 -0400 Received: from ozlabs.org ([203.11.71.1]:42497 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726178AbgGXC5t (ORCPT ); Thu, 23 Jul 2020 22:57:49 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4BCYlv27sJz9sPB; Fri, 24 Jul 2020 12:57:47 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1595559467; bh=jOh302ICMvqv+PqzmEYZM/FeEcTqLZlPD0brgAjYmLU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ax3uyoL3DMEDQU+kVdFw8ajofr1GheaEnjnjIqAGJGYNMleUsjmoLbYhZzERr9Hrz 5vN4FtGUUHrslBUodzGTv7vDUKks96VKaM81LyhwdgpZc+qSNrWeS07B+dm529q23H fvQW8SXUEyh7QkdbgnqXIqNv+HRpNpP4GYum0vgQ= From: David Gibson To: dgilbert@redhat.com, frankja@linux.ibm.com, pair@us.ibm.com, qemu-devel@nongnu.org, pbonzini@redhat.com, brijesh.singh@amd.com Cc: ehabkost@redhat.com, marcel.apfelbaum@gmail.com, "Michael S. Tsirkin" , qemu-ppc@nongnu.org, kvm@vger.kernel.org, pasic@linux.ibm.com, qemu-s390x@nongnu.org, David Gibson , David Hildenbrand , Christian Borntraeger , Richard Henderson , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , mdroth@linux.vnet.ibm.com, Thomas Huth , Cornelia Huck , Richard Henderson Subject: [for-5.2 v4 02/10] host trust limitation: Handle memory encryption via interface Date: Fri, 24 Jul 2020 12:57:36 +1000 Message-Id: <20200724025744.69644-3-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200724025744.69644-1-david@gibson.dropbear.id.au> References: <20200724025744.69644-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org At the moment AMD SEV sets a special function pointer, plus an opaque handle in KVMState to let things know how to encrypt guest memory. Now that we have a QOM interface for handling things related to host trust limitation, use a QOM method on that interface, rather than a bare function pointer for this. Signed-off-by: David Gibson Reviewed-by: Richard Henderson --- accel/kvm/kvm-all.c | 38 ++++++--- accel/kvm/sev-stub.c | 7 +- include/exec/host-trust-limitation.h | 3 + include/sysemu/sev.h | 4 +- target/i386/sev.c | 119 +++++++++++---------------- 5 files changed, 80 insertions(+), 91 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 63ef6af9a1..d7d95eacc7 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -39,11 +39,11 @@ #include "qemu/main-loop.h" #include "trace.h" #include "hw/irq.h" -#include "sysemu/sev.h" #include "qapi/visitor.h" #include "qapi/qapi-types-common.h" #include "qapi/qapi-visit-common.h" #include "sysemu/reset.h" +#include "exec/host-trust-limitation.h" #include "hw/boards.h" @@ -117,9 +117,8 @@ struct KVMState KVMMemoryListener memory_listener; QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus; - /* memory encryption */ - void *memcrypt_handle; - int (*memcrypt_encrypt_data)(void *handle, uint8_t *ptr, uint64_t len); + /* host trust limitation (e.g. by guest memory encryption) */ + HostTrustLimitation *htl; /* For "info mtree -f" to tell if an MR is registered in KVM */ int nr_as; @@ -221,7 +220,7 @@ int kvm_get_max_memslots(void) bool kvm_memcrypt_enabled(void) { - if (kvm_state && kvm_state->memcrypt_handle) { + if (kvm_state && kvm_state->htl) { return true; } @@ -230,10 +229,12 @@ bool kvm_memcrypt_enabled(void) int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len) { - if (kvm_state->memcrypt_handle && - kvm_state->memcrypt_encrypt_data) { - return kvm_state->memcrypt_encrypt_data(kvm_state->memcrypt_handle, - ptr, len); + HostTrustLimitation *htl = kvm_state->htl; + + if (htl) { + HostTrustLimitationClass *htlc = HOST_TRUST_LIMITATION_GET_CLASS(htl); + + return htlc->encrypt_data(htl, ptr, len); } return 1; @@ -2186,13 +2187,24 @@ static int kvm_init(MachineState *ms) * encryption context. */ if (ms->memory_encryption) { - kvm_state->memcrypt_handle = sev_guest_init(ms->memory_encryption); - if (!kvm_state->memcrypt_handle) { + Object *obj = object_resolve_path_component(object_get_objects_root(), + ms->memory_encryption); + + if (object_dynamic_cast(obj, TYPE_HOST_TRUST_LIMITATION)) { + HostTrustLimitation *htl = HOST_TRUST_LIMITATION(obj); + HostTrustLimitationClass *htlc + = HOST_TRUST_LIMITATION_GET_CLASS(htl); + + ret = htlc->kvm_init(htl); + if (ret < 0) { + goto err; + } + + kvm_state->htl = htl; + } else { ret = -1; goto err; } - - kvm_state->memcrypt_encrypt_data = sev_encrypt_data; } ret = kvm_arch_init(ms, s); diff --git a/accel/kvm/sev-stub.c b/accel/kvm/sev-stub.c index 4f97452585..9c7c897593 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) -{ - abort(); -} - -void *sev_guest_init(const char *id) +HostTrustLimitation *sev_guest_init(const char *id) { return NULL; } diff --git a/include/exec/host-trust-limitation.h b/include/exec/host-trust-limitation.h index 03887b1be1..a19f12ae14 100644 --- a/include/exec/host-trust-limitation.h +++ b/include/exec/host-trust-limitation.h @@ -28,6 +28,9 @@ typedef struct HostTrustLimitationClass { InterfaceClass parent; + + int (*kvm_init)(HostTrustLimitation *); + int (*encrypt_data)(HostTrustLimitation *, uint8_t *, uint64_t); } HostTrustLimitationClass; #endif /* QEMU_HOST_TRUST_LIMITATION_H */ diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h index 98c1ec8d38..a4aee6a87d 100644 --- a/include/sysemu/sev.h +++ b/include/sysemu/sev.h @@ -16,6 +16,6 @@ #include "sysemu/kvm.h" -void *sev_guest_init(const char *id); -int sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len); +HostTrustLimitation *sev_guest_init(const char *id); + #endif diff --git a/target/i386/sev.c b/target/i386/sev.c index c3ecf86704..8e3c9dcc2c 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -28,6 +28,7 @@ #include "sysemu/runstate.h" #include "trace.h" #include "migration/blocker.h" +#include "exec/host-trust-limitation.h" #define TYPE_SEV_GUEST "sev-guest" #define SEV_GUEST(obj) \ @@ -281,26 +282,6 @@ sev_guest_set_sev_device(Object *obj, const char *value, Error **errp) sev->sev_device = g_strdup(value); } -static void -sev_guest_class_init(ObjectClass *oc, void *data) -{ - object_class_property_add_str(oc, "sev-device", - sev_guest_get_sev_device, - sev_guest_set_sev_device); - object_class_property_set_description(oc, "sev-device", - "SEV device to use"); - object_class_property_add_str(oc, "dh-cert-file", - sev_guest_get_dh_cert_file, - sev_guest_set_dh_cert_file); - object_class_property_set_description(oc, "dh-cert-file", - "guest owners DH certificate (encoded with base64)"); - object_class_property_add_str(oc, "session-file", - sev_guest_get_session_file, - sev_guest_set_session_file); - object_class_property_set_description(oc, "session-file", - "guest owners session parameters (encoded with base64)"); -} - static void sev_guest_instance_init(Object *obj) { @@ -319,40 +300,6 @@ sev_guest_instance_init(Object *obj) OBJ_PROP_FLAG_READWRITE); } -/* sev guest info */ -static const TypeInfo sev_guest_info = { - .parent = TYPE_OBJECT, - .name = TYPE_SEV_GUEST, - .instance_size = sizeof(SevGuestState), - .instance_finalize = sev_guest_finalize, - .class_init = sev_guest_class_init, - .instance_init = sev_guest_instance_init, - .interfaces = (InterfaceInfo[]) { - { TYPE_USER_CREATABLE }, - { } - } -}; - -static SevGuestState * -lookup_sev_guest_info(const char *id) -{ - Object *obj; - SevGuestState *info; - - obj = object_resolve_path_component(object_get_objects_root(), id); - if (!obj) { - return NULL; - } - - info = (SevGuestState *) - object_dynamic_cast(obj, TYPE_SEV_GUEST); - if (!info) { - return NULL; - } - - return info; -} - bool sev_enabled(void) { @@ -679,10 +626,9 @@ sev_vm_state_change(void *opaque, int running, RunState state) } } -void * -sev_guest_init(const char *id) +static int sev_kvm_init(HostTrustLimitation *htl) { - SevGuestState *sev; + SevGuestState *sev = SEV_GUEST(htl); char *devname; int ret, fw_error; uint32_t ebx; @@ -692,14 +638,7 @@ sev_guest_init(const char *id) ret = ram_block_discard_disable(true); if (ret) { error_report("%s: cannot disable RAM discard", __func__); - return NULL; - } - - sev = lookup_sev_guest_info(id); - if (!sev) { - error_report("%s: '%s' is not a valid '%s' object", - __func__, id, TYPE_SEV_GUEST); - goto err; + return -1; } sev_guest = sev; @@ -763,17 +702,17 @@ sev_guest_init(const char *id) qemu_add_machine_init_done_notifier(&sev_machine_done_notify); qemu_add_vm_change_state_handler(sev_vm_state_change, sev); - return sev; + return 0; err: sev_guest = NULL; ram_block_discard_disable(false); - return NULL; + return -1; } -int -sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len) +static int +sev_encrypt_data(HostTrustLimitation *opaque, uint8_t *ptr, uint64_t len) { - SevGuestState *sev = handle; + SevGuestState *sev = SEV_GUEST(opaque); assert(sev); @@ -785,6 +724,46 @@ sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len) return 0; } +static void +sev_guest_class_init(ObjectClass *oc, void *data) +{ + HostTrustLimitationClass *htlc = HOST_TRUST_LIMITATION_CLASS(oc); + + object_class_property_add_str(oc, "sev-device", + sev_guest_get_sev_device, + sev_guest_set_sev_device); + object_class_property_set_description(oc, "sev-device", + "SEV device to use"); + object_class_property_add_str(oc, "dh-cert-file", + sev_guest_get_dh_cert_file, + sev_guest_set_dh_cert_file); + object_class_property_set_description(oc, "dh-cert-file", + "guest owners DH certificate (encoded with base64)"); + object_class_property_add_str(oc, "session-file", + sev_guest_get_session_file, + sev_guest_set_session_file); + object_class_property_set_description(oc, "session-file", + "guest owners session parameters (encoded with base64)"); + + htlc->kvm_init = sev_kvm_init; + htlc->encrypt_data = sev_encrypt_data; +} + +/* sev guest info */ +static const TypeInfo sev_guest_info = { + .parent = TYPE_OBJECT, + .name = TYPE_SEV_GUEST, + .instance_size = sizeof(SevGuestState), + .instance_finalize = sev_guest_finalize, + .class_init = sev_guest_class_init, + .instance_init = sev_guest_instance_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_HOST_TRUST_LIMITATION }, + { TYPE_USER_CREATABLE }, + { } + } +}; + static void sev_register_types(void) { From patchwork Fri Jul 24 02:57:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11681909 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5E202722 for ; Fri, 24 Jul 2020 02:57:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D1373206C1 for ; Fri, 24 Jul 2020 02:57:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="n+0JQilQ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726667AbgGXC5t (ORCPT ); Thu, 23 Jul 2020 22:57:49 -0400 Received: from ozlabs.org ([203.11.71.1]:53183 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726381AbgGXC5t (ORCPT ); Thu, 23 Jul 2020 22:57:49 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4BCYlv5VC5z9sTC; Fri, 24 Jul 2020 12:57:47 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1595559467; bh=HmcdQhqv6u0WvbSTqY3hEVc0yzPwYsuoT3bUsWyJi1A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n+0JQilQDIIAqWIav0HdtD8GraIx0bzBq46AppmC0VpVi9JpX1ocIHF453u/sZEj+ KZm03zv0/a5pF6t4mrGFmXShx35yH7G+SO1peo8tUOVUlc0AzoFSC6IgJi18fgSyp1 X4ejxuJxqNWUobrouQrOCxr/nMMaiaqWZ+ITBYz8= From: David Gibson To: dgilbert@redhat.com, frankja@linux.ibm.com, pair@us.ibm.com, qemu-devel@nongnu.org, pbonzini@redhat.com, brijesh.singh@amd.com Cc: ehabkost@redhat.com, marcel.apfelbaum@gmail.com, "Michael S. Tsirkin" , qemu-ppc@nongnu.org, kvm@vger.kernel.org, pasic@linux.ibm.com, qemu-s390x@nongnu.org, David Gibson , David Hildenbrand , Christian Borntraeger , Richard Henderson , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , mdroth@linux.vnet.ibm.com, Thomas Huth , Cornelia Huck , Richard Henderson Subject: [for-5.2 v4 03/10] host trust limitation: Move side effect out of machine_set_memory_encryption() Date: Fri, 24 Jul 2020 12:57:37 +1000 Message-Id: <20200724025744.69644-4-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200724025744.69644-1-david@gibson.dropbear.id.au> References: <20200724025744.69644-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org When the "memory-encryption" property is set, we also disable KSM merging for the guest, since it won't accomplish anything. We want that, but doing it in the property set function itself is thereoretically incorrect, in the unlikely event of some configuration environment that set the property then cleared it again before constructing the guest. More importantly, it makes some other cleanups we want more difficult. So, instead move this logic to machine_run_board_init() conditional on the final value of the property. Signed-off-by: David Gibson Reviewed-by: Richard Henderson --- hw/core/machine.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/hw/core/machine.c b/hw/core/machine.c index 2f881d6d75..035a1fc631 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -432,14 +432,6 @@ static void machine_set_memory_encryption(Object *obj, const char *value, g_free(ms->memory_encryption); ms->memory_encryption = g_strdup(value); - - /* - * With memory encryption, the host can't see the real contents of RAM, - * so there's no point in it trying to merge areas. - */ - if (value) { - machine_set_mem_merge(obj, false, errp); - } } static bool machine_get_nvdimm(Object *obj, Error **errp) @@ -1131,6 +1123,15 @@ void machine_run_board_init(MachineState *machine) } } + if (machine->memory_encryption) { + /* + * With host trust limitation, the host can't see the real + * contents of RAM, so there's no point in it trying to merge + * areas. + */ + machine_set_mem_merge(OBJECT(machine), false, &error_abort); + } + machine_class->init(machine); } From patchwork Fri Jul 24 02:57:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11681913 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E9E1514E3 for ; Fri, 24 Jul 2020 02:57:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D20BC207FC for ; Fri, 24 Jul 2020 02:57:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="nfyg+H1j" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726817AbgGXC5v (ORCPT ); Thu, 23 Jul 2020 22:57:51 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:39313 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726543AbgGXC5u (ORCPT ); Thu, 23 Jul 2020 22:57:50 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4BCYlv4Z8Sz9sSn; Fri, 24 Jul 2020 12:57:47 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1595559467; bh=R0fgLYiXYKzsBYFKyppNWeAvNHP70nX+ch1lmvuKdkA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nfyg+H1j2J84kBQamTgGTxcM7EJvrRZ+dLtwvoISyZJ9FIF3BwuTfOeq7x76/C0/W U4DTmGjwwPKE+0UwUR5DhjQcFxzLuHbN3JuJLtbWPvhqdT8k9qOKkbDOFpBjyR9HvI TRE7xA2fFVoIgxJ5fW2b5jvI2Y9BuFFLrtcEkyIc= From: David Gibson To: dgilbert@redhat.com, frankja@linux.ibm.com, pair@us.ibm.com, qemu-devel@nongnu.org, pbonzini@redhat.com, brijesh.singh@amd.com Cc: ehabkost@redhat.com, marcel.apfelbaum@gmail.com, "Michael S. Tsirkin" , qemu-ppc@nongnu.org, kvm@vger.kernel.org, pasic@linux.ibm.com, qemu-s390x@nongnu.org, David Gibson , David Hildenbrand , Christian Borntraeger , Richard Henderson , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , mdroth@linux.vnet.ibm.com, Thomas Huth , Cornelia Huck , Richard Henderson Subject: [for-5.2 v4 04/10] host trust limitation: Rework the "memory-encryption" property Date: Fri, 24 Jul 2020 12:57:38 +1000 Message-Id: <20200724025744.69644-5-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200724025744.69644-1-david@gibson.dropbear.id.au> References: <20200724025744.69644-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org 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 "host-trust-limitation" link property which sets this QOM interface link directly in the machine. For compatibility we keep the "memory-encryption" property, but now implemented in terms of the new property. Signed-off-by: David Gibson Reviewed-by: Richard Henderson --- accel/kvm/kvm-all.c | 23 +++++++---------------- hw/core/machine.c | 41 ++++++++++++++++++++++++++++++++++++----- include/hw/boards.h | 2 +- 3 files changed, 44 insertions(+), 22 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index d7d95eacc7..e2d8f47f93 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2186,25 +2186,16 @@ static int kvm_init(MachineState *ms) * if memory encryption object is specified then initialize the memory * encryption context. */ - if (ms->memory_encryption) { - Object *obj = object_resolve_path_component(object_get_objects_root(), - ms->memory_encryption); - - if (object_dynamic_cast(obj, TYPE_HOST_TRUST_LIMITATION)) { - HostTrustLimitation *htl = HOST_TRUST_LIMITATION(obj); - HostTrustLimitationClass *htlc - = HOST_TRUST_LIMITATION_GET_CLASS(htl); - - ret = htlc->kvm_init(htl); - if (ret < 0) { - goto err; - } + if (ms->htl) { + HostTrustLimitationClass *htlc = + HOST_TRUST_LIMITATION_GET_CLASS(ms->htl); - kvm_state->htl = htl; - } else { - ret = -1; + ret = htlc->kvm_init(ms->htl); + if (ret < 0) { goto err; } + + kvm_state->htl = ms->htl; } ret = kvm_arch_init(ms, s); diff --git a/hw/core/machine.c b/hw/core/machine.c index 035a1fc631..b599b0ba65 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -27,6 +27,7 @@ #include "hw/pci/pci.h" #include "hw/mem/nvdimm.h" #include "migration/vmstate.h" +#include "exec/host-trust-limitation.h" GlobalProperty hw_compat_5_0[] = { { "virtio-balloon-device", "page-poison", "false" }, @@ -422,16 +423,37 @@ static char *machine_get_memory_encryption(Object *obj, Error **errp) { MachineState *ms = MACHINE(obj); - return g_strdup(ms->memory_encryption); + if (ms->htl) { + return g_strdup(object_get_canonical_path_component(OBJECT(ms->htl))); + } + + return NULL; } static void machine_set_memory_encryption(Object *obj, const char *value, Error **errp) { - MachineState *ms = MACHINE(obj); + Object *htl = + object_resolve_path_component(object_get_objects_root(), value); + + if (!htl) { + 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, "host-trust-limitation", htl, errp); +} + +static void machine_check_host_trust_limitation(const Object *obj, + const char *name, + Object *new_target, + Error **errp) +{ + /* + * So far the only constraint is that the target has the + * TYPE_HOST_TRUST_LIMITATION interface, and that's checked by the + * QOM core + */ } static bool machine_get_nvdimm(Object *obj, Error **errp) @@ -852,6 +874,15 @@ static void machine_class_init(ObjectClass *oc, void *data) object_class_property_set_description(oc, "enforce-config-section", "Set on to enforce configuration section migration"); + object_class_property_add_link(oc, "host-trust-limitation", + TYPE_HOST_TRUST_LIMITATION, + offsetof(MachineState, htl), + machine_check_host_trust_limitation, + OBJ_PROP_LINK_STRONG); + object_class_property_set_description(oc, "host-trust-limitation", + "Set host trust limitation object to use"); + + /* For compatibility */ object_class_property_add_str(oc, "memory-encryption", machine_get_memory_encryption, machine_set_memory_encryption); object_class_property_set_description(oc, "memory-encryption", @@ -1123,7 +1154,7 @@ void machine_run_board_init(MachineState *machine) } } - if (machine->memory_encryption) { + if (machine->htl) { /* * With host trust limitation, the host can't see the real * contents of RAM, so there's no point in it trying to merge diff --git a/include/hw/boards.h b/include/hw/boards.h index 426ce5f625..c70fb8bd9f 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -278,7 +278,7 @@ struct MachineState { bool suppress_vmdesc; bool enforce_config_section; bool enable_graphics; - char *memory_encryption; + HostTrustLimitation *htl; char *ram_memdev_id; /* * convenience alias to ram_memdev_id backend memory region From patchwork Fri Jul 24 02:57:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11681923 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2F76713B4 for ; Fri, 24 Jul 2020 02:57:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 11FCA207FC for ; Fri, 24 Jul 2020 02:57:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="DC+6Qtnf" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726838AbgGXC5w (ORCPT ); Thu, 23 Jul 2020 22:57:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52380 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726543AbgGXC5v (ORCPT ); Thu, 23 Jul 2020 22:57:51 -0400 Received: from ozlabs.org (ozlabs.org [IPv6:2401:3900:2:1::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 71955C0619D3 for ; Thu, 23 Jul 2020 19:57:51 -0700 (PDT) Received: by ozlabs.org (Postfix, from userid 1007) id 4BCYlv6Cjvz9sSy; Fri, 24 Jul 2020 12:57:47 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1595559467; bh=JRbdSSqaG0liT/aslzU3m1hnjce6fptMd9RZ6TZwddU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DC+6Qtnf39Aai/D6H6P+axBMx2XtA8CqUBXghtuGqnWLCxlAl8ULsWtB8yeiWgOTr BgzzWGWvgW7tYg6H4e7aTsYsTVgI6T2WFB0Qh+TozWdOKmI00eLAPxHPt2RIRw0H4Z 9kOu41/eZJKnbw5YFCo7cYkulVBqhQCoMdYj5/ms= From: David Gibson To: dgilbert@redhat.com, frankja@linux.ibm.com, pair@us.ibm.com, qemu-devel@nongnu.org, pbonzini@redhat.com, brijesh.singh@amd.com Cc: ehabkost@redhat.com, marcel.apfelbaum@gmail.com, "Michael S. Tsirkin" , qemu-ppc@nongnu.org, kvm@vger.kernel.org, pasic@linux.ibm.com, qemu-s390x@nongnu.org, David Gibson , David Hildenbrand , Christian Borntraeger , Richard Henderson , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , mdroth@linux.vnet.ibm.com, Thomas Huth , Cornelia Huck , Richard Henderson Subject: [for-5.2 v4 05/10] host trust limitation: Decouple kvm_memcrypt_*() helpers from KVM Date: Fri, 24 Jul 2020 12:57:39 +1000 Message-Id: <20200724025744.69644-6-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200724025744.69644-1-david@gibson.dropbear.id.au> References: <20200724025744.69644-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The kvm_memcrypt_enabled() and kvm_memcrypt_encrypt_data() helper functions don't conceptually have any connection to KVM (although it's not possible in practice to use them without it). They also rely on looking at the global KVMState. But the same information is available from the machine, and the only existing callers have natural access to the machine state. Therefore, move and rename them to helpers in host-trust-limitation.h, taking an explicit machine parameter. Signed-off-by: David Gibson Reviewed-by: Richard Henderson --- accel/kvm/kvm-all.c | 27 --------------------- accel/stubs/kvm-stub.c | 10 -------- hw/i386/pc_sysfw.c | 6 +++-- include/exec/host-trust-limitation.h | 36 ++++++++++++++++++++++++++++ include/sysemu/kvm.h | 17 ------------- 5 files changed, 40 insertions(+), 56 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index e2d8f47f93..4b6402c12c 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -117,9 +117,6 @@ struct KVMState KVMMemoryListener memory_listener; QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus; - /* host trust limitation (e.g. by guest memory encryption) */ - HostTrustLimitation *htl; - /* For "info mtree -f" to tell if an MR is registered in KVM */ int nr_as; struct KVMAs { @@ -218,28 +215,6 @@ int kvm_get_max_memslots(void) return s->nr_slots; } -bool kvm_memcrypt_enabled(void) -{ - if (kvm_state && kvm_state->htl) { - return true; - } - - return false; -} - -int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len) -{ - HostTrustLimitation *htl = kvm_state->htl; - - if (htl) { - HostTrustLimitationClass *htlc = HOST_TRUST_LIMITATION_GET_CLASS(htl); - - return htlc->encrypt_data(htl, ptr, len); - } - - return 1; -} - /* Called with KVMMemoryListener.slots_lock held */ static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml) { @@ -2194,8 +2169,6 @@ static int kvm_init(MachineState *ms) if (ret < 0) { goto err; } - - kvm_state->htl = ms->htl; } ret = kvm_arch_init(ms, s); diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c index 82f118d2df..78b3eef117 100644 --- a/accel/stubs/kvm-stub.c +++ b/accel/stubs/kvm-stub.c @@ -104,16 +104,6 @@ int kvm_on_sigbus(int code, void *addr) return 1; } -bool kvm_memcrypt_enabled(void) -{ - return false; -} - -int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len) -{ - return 1; -} - #ifndef CONFIG_USER_ONLY int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev) { diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c index b6c0822fe3..e8d3b795a1 100644 --- a/hw/i386/pc_sysfw.c +++ b/hw/i386/pc_sysfw.c @@ -38,6 +38,7 @@ #include "sysemu/sysemu.h" #include "hw/block/flash.h" #include "sysemu/kvm.h" +#include "exec/host-trust-limitation.h" /* * We don't have a theoretically justifiable exact lower bound on the base @@ -201,10 +202,11 @@ static void pc_system_flash_map(PCMachineState *pcms, pc_isa_bios_init(rom_memory, flash_mem, size); /* Encrypt the pflash boot ROM */ - if (kvm_memcrypt_enabled()) { + if (host_trust_limitation_enabled(MACHINE(pcms))) { flash_ptr = memory_region_get_ram_ptr(flash_mem); flash_size = memory_region_size(flash_mem); - ret = kvm_memcrypt_encrypt_data(flash_ptr, flash_size); + ret = host_trust_limitation_encrypt(MACHINE(pcms), + flash_ptr, flash_size); if (ret) { error_report("failed to encrypt pflash rom"); exit(1); diff --git a/include/exec/host-trust-limitation.h b/include/exec/host-trust-limitation.h index a19f12ae14..fc30ea3f78 100644 --- a/include/exec/host-trust-limitation.h +++ b/include/exec/host-trust-limitation.h @@ -14,6 +14,7 @@ #define QEMU_HOST_TRUST_LIMITATION_H #include "qom/object.h" +#include "hw/boards.h" #define TYPE_HOST_TRUST_LIMITATION "host-trust-limitation" #define HOST_TRUST_LIMITATION(obj) \ @@ -33,4 +34,39 @@ typedef struct HostTrustLimitationClass { int (*encrypt_data)(HostTrustLimitation *, uint8_t *, uint64_t); } HostTrustLimitationClass; +/** + * host_trust_limitation_enabled - return whether guest memory is protected + * from hypervisor access (with memory + * encryption or otherwise) + * Returns: true guest memory is not directly accessible to qemu + * false guest memory is directly accessible to qemu + */ +static inline bool host_trust_limitation_enabled(MachineState *machine) +{ + return !!machine->htl; +} + +/** + * host_trust_limitation_encrypt: encrypt the memory range to make + * it guest accessible + * + * Return: 1 failed to encrypt the range + * 0 succesfully encrypted memory region + */ +static inline int host_trust_limitation_encrypt(MachineState *machine, + uint8_t *ptr, uint64_t len) +{ + HostTrustLimitation *htl = machine->htl; + + if (htl) { + HostTrustLimitationClass *htlc = HOST_TRUST_LIMITATION_GET_CLASS(htl); + + if (htlc->encrypt_data) { + return htlc->encrypt_data(htl, ptr, len); + } + } + + return 1; +} + #endif /* QEMU_HOST_TRUST_LIMITATION_H */ diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index b4174d941c..c7b9739609 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -231,23 +231,6 @@ int kvm_destroy_vcpu(CPUState *cpu); */ bool kvm_arm_supports_user_irq(void); -/** - * kvm_memcrypt_enabled - return boolean indicating whether memory encryption - * is enabled - * Returns: 1 memory encryption is enabled - * 0 memory encryption is disabled - */ -bool kvm_memcrypt_enabled(void); - -/** - * kvm_memcrypt_encrypt_data: encrypt the memory range - * - * Return: 1 failed to encrypt the range - * 0 succesfully encrypted memory region - */ -int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len); - - #ifdef NEED_CPU_H #include "cpu.h" From patchwork Fri Jul 24 02:57:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11681919 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3478F722 for ; Fri, 24 Jul 2020 02:57:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1B87B206C1 for ; Fri, 24 Jul 2020 02:57:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="OGBTdOPi" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726892AbgGXC5z (ORCPT ); Thu, 23 Jul 2020 22:57:55 -0400 Received: from ozlabs.org ([203.11.71.1]:49133 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726760AbgGXC5x (ORCPT ); Thu, 23 Jul 2020 22:57:53 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4BCYlw00Rzz9sTF; Fri, 24 Jul 2020 12:57:47 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1595559468; bh=xgmDQa3udk5W0XmmFTnrKQDvJ/BjSvIb0v09eBORE70=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OGBTdOPiL8Nuu2cNvQr4R0hIaMZJWJVN7ZYOOU1+Jy0huQdGQy/w2e1zDJi8inGMI sfXsFRM+wueL5uASQSTxss6FU3dO287ugy3GwG20FzTIJmZBhmgeHhy9l/aCGLs3To iO87zT9VzxIzMNoBplOdxlcOc+iAP26IC9fuwfF0= From: David Gibson To: dgilbert@redhat.com, frankja@linux.ibm.com, pair@us.ibm.com, qemu-devel@nongnu.org, pbonzini@redhat.com, brijesh.singh@amd.com Cc: ehabkost@redhat.com, marcel.apfelbaum@gmail.com, "Michael S. Tsirkin" , qemu-ppc@nongnu.org, kvm@vger.kernel.org, pasic@linux.ibm.com, qemu-s390x@nongnu.org, David Gibson , David Hildenbrand , Christian Borntraeger , Richard Henderson , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , mdroth@linux.vnet.ibm.com, Thomas Huth , Cornelia Huck , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , Richard Henderson Subject: [for-5.2 v4 06/10] host trust limitation: Add Error ** to HostTrustLimitation::kvm_init Date: Fri, 24 Jul 2020 12:57:40 +1000 Message-Id: <20200724025744.69644-7-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200724025744.69644-1-david@gibson.dropbear.id.au> References: <20200724025744.69644-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org 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 --- accel/kvm/kvm-all.c | 4 +++- include/exec/host-trust-limitation.h | 2 +- target/i386/sev.c | 31 ++++++++++++++-------------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 4b6402c12c..3f98c6be7c 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2164,9 +2164,11 @@ static int kvm_init(MachineState *ms) if (ms->htl) { HostTrustLimitationClass *htlc = HOST_TRUST_LIMITATION_GET_CLASS(ms->htl); + Error *local_err = NULL; - ret = htlc->kvm_init(ms->htl); + ret = htlc->kvm_init(ms->htl, &local_err); if (ret < 0) { + error_report_err(local_err); goto err; } } diff --git a/include/exec/host-trust-limitation.h b/include/exec/host-trust-limitation.h index fc30ea3f78..d93b537280 100644 --- a/include/exec/host-trust-limitation.h +++ b/include/exec/host-trust-limitation.h @@ -30,7 +30,7 @@ typedef struct HostTrustLimitationClass { InterfaceClass parent; - int (*kvm_init)(HostTrustLimitation *); + int (*kvm_init)(HostTrustLimitation *, Error **); int (*encrypt_data)(HostTrustLimitation *, uint8_t *, uint64_t); } HostTrustLimitationClass; diff --git a/target/i386/sev.c b/target/i386/sev.c index 8e3c9dcc2c..0d06976da5 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -626,7 +626,7 @@ sev_vm_state_change(void *opaque, int running, RunState state) } } -static int sev_kvm_init(HostTrustLimitation *htl) +static int sev_kvm_init(HostTrustLimitation *htl, Error **errp) { SevGuestState *sev = SEV_GUEST(htl); char *devname; @@ -648,14 +648,14 @@ static int sev_kvm_init(HostTrustLimitation *htl) host_cbitpos = ebx & 0x3f; if (host_cbitpos != sev->cbitpos) { - error_report("%s: cbitpos check failed, host '%d' requested '%d'", - __func__, host_cbitpos, sev->cbitpos); + error_setg(errp, "%s: cbitpos check failed, host '%d' requested '%d'", + __func__, host_cbitpos, sev->cbitpos); goto err; } if (sev->reduced_phys_bits < 1) { - error_report("%s: reduced_phys_bits check failed, it should be >=1," - " requested '%d'", __func__, sev->reduced_phys_bits); + error_setg(errp, "%s: reduced_phys_bits check failed, it should be >=1," + " requested '%d'", __func__, sev->reduced_phys_bits); goto err; } @@ -664,20 +664,19 @@ static int sev_kvm_init(HostTrustLimitation *htl) devname = object_property_get_str(OBJECT(sev), "sev-device", NULL); sev->sev_fd = open(devname, O_RDWR); if (sev->sev_fd < 0) { - error_report("%s: Failed to open %s '%s'", __func__, - devname, strerror(errno)); - } - g_free(devname); - if (sev->sev_fd < 0) { + error_setg(errp, "%s: Failed to open %s '%s'", __func__, + devname, strerror(errno)); + g_free(devname); goto err; } + g_free(devname); ret = sev_platform_ioctl(sev->sev_fd, SEV_PLATFORM_STATUS, &status, &fw_error); if (ret) { - error_report("%s: failed to get platform status ret=%d " - "fw_error='%d: %s'", __func__, ret, fw_error, - fw_error_to_str(fw_error)); + error_setg(errp, "%s: failed to get platform status ret=%d " + "fw_error='%d: %s'", __func__, ret, fw_error, + fw_error_to_str(fw_error)); goto err; } sev->build_id = status.build; @@ -687,14 +686,14 @@ static int sev_kvm_init(HostTrustLimitation *htl) trace_kvm_sev_init(); ret = sev_ioctl(sev->sev_fd, KVM_SEV_INIT, NULL, &fw_error); if (ret) { - error_report("%s: failed to initialize ret=%d fw_error=%d '%s'", - __func__, ret, fw_error, fw_error_to_str(fw_error)); + error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'", + __func__, ret, fw_error, fw_error_to_str(fw_error)); goto err; } ret = sev_launch_start(sev); if (ret) { - error_report("%s: failed to create encryption context", __func__); + error_setg(errp, "%s: failed to create encryption context", __func__); goto err; } From patchwork Fri Jul 24 02:57:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11681917 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5C87714E3 for ; Fri, 24 Jul 2020 02:57:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 437FB20737 for ; Fri, 24 Jul 2020 02:57:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="n0zBs27t" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726884AbgGXC5x (ORCPT ); Thu, 23 Jul 2020 22:57:53 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:52245 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726801AbgGXC5w (ORCPT ); Thu, 23 Jul 2020 22:57:52 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4BCYlw0lN1z9sTH; Fri, 24 Jul 2020 12:57:47 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1595559468; bh=Oy4RlJb/Bjycm/HhrLyUbyYuUJPIz3gMN+mQh6H8/u4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n0zBs27t5hcUyQFkH4E/1ktWWBZ+c3ZmHt0tdrUktlpOzPYjZvwh6q2aO3c0+v1tK ur1QYvSNzrnjuElvIEy3qTA68pRjKgy7lEzRHqYhl1AHevAdpjaopdo5cs7FxslqeL At78BKwQczW28ygQEUul8Bsr9hU4sTErkSIFmxX0= From: David Gibson To: dgilbert@redhat.com, frankja@linux.ibm.com, pair@us.ibm.com, qemu-devel@nongnu.org, pbonzini@redhat.com, brijesh.singh@amd.com Cc: ehabkost@redhat.com, marcel.apfelbaum@gmail.com, "Michael S. Tsirkin" , qemu-ppc@nongnu.org, kvm@vger.kernel.org, pasic@linux.ibm.com, qemu-s390x@nongnu.org, David Gibson , David Hildenbrand , Christian Borntraeger , Richard Henderson , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , mdroth@linux.vnet.ibm.com, Thomas Huth , Cornelia Huck , Ram Pai Subject: [for-5.2 v4 07/10] spapr: Add PEF based host trust limitation Date: Fri, 24 Jul 2020 12:57:41 +1000 Message-Id: <20200724025744.69644-8-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200724025744.69644-1-david@gibson.dropbear.id.au> References: <20200724025744.69644-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org 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 host-trust-limitation machine property to point to it. Note that this just *allows* secure guests, the architecture of PEF is such that the guest still needs to talk to the ultravisor to enter secure mode. Qemu has no directly 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 host-trust-limitation=pef0 Signed-off-by: David Gibson Acked-by: Ram Pai --- target/ppc/Makefile.objs | 2 +- target/ppc/pef.c | 83 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 target/ppc/pef.c diff --git a/target/ppc/Makefile.objs b/target/ppc/Makefile.objs index e8fa18ce13..ac93b9700e 100644 --- a/target/ppc/Makefile.objs +++ b/target/ppc/Makefile.objs @@ -6,7 +6,7 @@ obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o arch_dump.o obj-$(TARGET_PPC64) += mmu-hash64.o mmu-book3s-v3.o compat.o obj-$(TARGET_PPC64) += mmu-radix64.o endif -obj-$(CONFIG_KVM) += kvm.o +obj-$(CONFIG_KVM) += kvm.o pef.o obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o obj-y += dfp_helper.o obj-y += excp_helper.o diff --git a/target/ppc/pef.c b/target/ppc/pef.c new file mode 100644 index 0000000000..53a6af0347 --- /dev/null +++ b/target/ppc/pef.c @@ -0,0 +1,83 @@ +/* + * 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/host-trust-limitation.h" + +#define TYPE_PEF_GUEST "pef-guest" +#define PEF_GUEST(obj) \ + OBJECT_CHECK(PefGuestState, (obj), TYPE_PEF_GUEST) + +typedef struct PefGuestState PefGuestState; + +/** + * PefGuestState: + * + * The PefGuestState object is used for creating and managing a PEF + * guest. + * + * # $QEMU \ + * -object pef-guest,id=pef0 \ + * -machine ...,host-trust-limitation=pef0 + */ +struct PefGuestState { + Object parent_obj; +}; + +static int pef_kvm_init(HostTrustLimitation *gmpo, 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; +} + +static void pef_guest_class_init(ObjectClass *oc, void *data) +{ + HostTrustLimitationClass *gmpc = HOST_TRUST_LIMITATION_CLASS(oc); + + gmpc->kvm_init = pef_kvm_init; +} + +static const TypeInfo pef_guest_info = { + .parent = TYPE_OBJECT, + .name = TYPE_PEF_GUEST, + .instance_size = sizeof(PefGuestState), + .class_init = pef_guest_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_HOST_TRUST_LIMITATION }, + { TYPE_USER_CREATABLE }, + { } + } +}; + +static void +pef_register_types(void) +{ + type_register_static(&pef_guest_info); +} + +type_init(pef_register_types); From patchwork Fri Jul 24 02:57:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11681925 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D676313B4 for ; Fri, 24 Jul 2020 02:58:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B37DC207FC for ; Fri, 24 Jul 2020 02:58:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="YAM+uwL/" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726904AbgGXC6A (ORCPT ); Thu, 23 Jul 2020 22:58:00 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:35687 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726178AbgGXC5w (ORCPT ); Thu, 23 Jul 2020 22:57:52 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4BCYlw1T28z9sTK; Fri, 24 Jul 2020 12:57:48 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1595559468; bh=oUlu8u5TiukpYL5YY0i+HjSckV5d3NnHfXBN6cEFoNM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YAM+uwL/E+M/lqPo6JwEV3OirVdPwoH0YUjmphFtXRnwwwmqxPNOtpZXt6UKp+3y2 kVvh0eEmXx8oPDzXuZjXDRfW1jIUhPJ/GeNmPPagmkoRSudKOBfc+1SUViCmyhbYOT k/e5svfcGURMKHpEqITtS1JU8RUB0oQRn4sjEifo= From: David Gibson To: dgilbert@redhat.com, frankja@linux.ibm.com, pair@us.ibm.com, qemu-devel@nongnu.org, pbonzini@redhat.com, brijesh.singh@amd.com Cc: ehabkost@redhat.com, marcel.apfelbaum@gmail.com, "Michael S. Tsirkin" , qemu-ppc@nongnu.org, kvm@vger.kernel.org, pasic@linux.ibm.com, qemu-s390x@nongnu.org, David Gibson , David Hildenbrand , Christian Borntraeger , Richard Henderson , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , mdroth@linux.vnet.ibm.com, Thomas Huth , Cornelia Huck Subject: [for-5.2 v4 08/10] spapr: PEF: block migration Date: Fri, 24 Jul 2020 12:57:42 +1000 Message-Id: <20200724025744.69644-9-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200724025744.69644-1-david@gibson.dropbear.id.au> References: <20200724025744.69644-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org 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 --- target/ppc/pef.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/target/ppc/pef.c b/target/ppc/pef.c index 53a6af0347..6a50efd580 100644 --- a/target/ppc/pef.c +++ b/target/ppc/pef.c @@ -36,6 +36,8 @@ struct PefGuestState { Object parent_obj; }; +static Error *pef_mig_blocker; + static int pef_kvm_init(HostTrustLimitation *gmpo, Error **errp) { if (!kvm_check_extension(kvm_state, KVM_CAP_PPC_SECURE_GUEST)) { @@ -52,6 +54,10 @@ static int pef_kvm_init(HostTrustLimitation *gmpo, Error **errp) } } + /* add migration blocker */ + error_setg(&pef_mig_blocker, "PEF: Migration is not implemented"); + migrate_add_blocker(pef_mig_blocker, &error_abort); + return 0; } From patchwork Fri Jul 24 02:57:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11681915 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E8EF613B4 for ; Fri, 24 Jul 2020 02:57:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C6EAC207FC for ; Fri, 24 Jul 2020 02:57:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="Fsw/pl4E" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726863AbgGXC5x (ORCPT ); Thu, 23 Jul 2020 22:57:53 -0400 Received: from ozlabs.org ([203.11.71.1]:37083 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726807AbgGXC5w (ORCPT ); Thu, 23 Jul 2020 22:57:52 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4BCYlw2CWGz9sTR; Fri, 24 Jul 2020 12:57:48 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1595559468; bh=S0SoxbGMoHrm4nxccN2FECIGesfK+qvLP0XWEh7c1/Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Fsw/pl4ETCgZRnUMnWoMvWLxPNqj0W0aX0j5oGnZxcSxibV0Nu6T7QHmXii5ZyiXd gwcHi8Gw1/rAeCHONaMwMfFat3Kj/nmQxVEVXbnIC3hWgbdO8VZRrKsxwbkkzFOO7K fD6aaWybXL1omHTDqn5vbbG9IPhzpY7SOwrln0IM= From: David Gibson To: dgilbert@redhat.com, frankja@linux.ibm.com, pair@us.ibm.com, qemu-devel@nongnu.org, pbonzini@redhat.com, brijesh.singh@amd.com Cc: ehabkost@redhat.com, marcel.apfelbaum@gmail.com, "Michael S. Tsirkin" , qemu-ppc@nongnu.org, kvm@vger.kernel.org, pasic@linux.ibm.com, qemu-s390x@nongnu.org, David Gibson , David Hildenbrand , Christian Borntraeger , Richard Henderson , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , mdroth@linux.vnet.ibm.com, Thomas Huth , Cornelia Huck Subject: [for-5.2 v4 09/10] host trust limitation: Alter virtio default properties for protected guests Date: Fri, 24 Jul 2020 12:57:43 +1000 Message-Id: <20200724025744.69644-10-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200724025744.69644-1-david@gibson.dropbear.id.au> References: <20200724025744.69644-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org 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 host trust limitation 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: Halil Pasic --- hw/core/machine.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hw/core/machine.c b/hw/core/machine.c index b599b0ba65..2a723bf07b 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -28,6 +28,8 @@ #include "hw/mem/nvdimm.h" #include "migration/vmstate.h" #include "exec/host-trust-limitation.h" +#include "hw/virtio/virtio.h" +#include "hw/virtio/virtio-pci.h" GlobalProperty hw_compat_5_0[] = { { "virtio-balloon-device", "page-poison", "false" }, @@ -1161,6 +1163,15 @@ 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 disabling legacy virtio support + * for virtio pci devices + */ + object_register_sugar_prop(TYPE_VIRTIO_PCI, "disable-legacy", "on"); + object_register_sugar_prop(TYPE_VIRTIO_DEVICE, "iommu_platform", "on"); } machine_class->init(machine); From patchwork Fri Jul 24 02:57:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11681921 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 10B0C722 for ; Fri, 24 Jul 2020 02:57:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EAAAF206C1 for ; Fri, 24 Jul 2020 02:57:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="pSuzO9oG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726891AbgGXC55 (ORCPT ); Thu, 23 Jul 2020 22:57:57 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:51671 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726814AbgGXC5w (ORCPT ); Thu, 23 Jul 2020 22:57:52 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4BCYlw2nzSz9sTT; Fri, 24 Jul 2020 12:57:48 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1595559468; bh=/o46AHd29VbcsNq9WcZf6nE94CsdYc+R5nZVL/Rr/HI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pSuzO9oG4N0zQaZIvbeJU7FN70QP4ZKEEpvcOr/jb4KRvrGtL4GgERFkyKACeAnXN C3V2s+HwQakiko3lp4TBXkrCi7CoBZhihn8CuBdR0/9T1ELAjFSeGV7tcu2j5wPuxC 6hX7tzTwsR/GqgVUfC1xdRMGLpbwYxSnB6k/qEEE= From: David Gibson To: dgilbert@redhat.com, frankja@linux.ibm.com, pair@us.ibm.com, qemu-devel@nongnu.org, pbonzini@redhat.com, brijesh.singh@amd.com Cc: ehabkost@redhat.com, marcel.apfelbaum@gmail.com, "Michael S. Tsirkin" , qemu-ppc@nongnu.org, kvm@vger.kernel.org, pasic@linux.ibm.com, qemu-s390x@nongnu.org, David Gibson , David Hildenbrand , Christian Borntraeger , Richard Henderson , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , mdroth@linux.vnet.ibm.com, Thomas Huth , Cornelia Huck Subject: [for-5.2 v4 10/10] s390: Recognize host-trust-limitation option Date: Fri, 24 Jul 2020 12:57:44 +1000 Message-Id: <20200724025744.69644-11-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200724025744.69644-1-david@gibson.dropbear.id.au> References: <20200724025744.69644-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org At least some s390 cpu models support "Protected Virtualization" (PV), a mechanism to protect guests from eavesdropping by a compromised hypervisor. This is similar in function to other mechanisms like AMD's SEV and POWER's PEF, which are controlled bythe "host-trust-limitation" 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 host-trust-limitation 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 host-trust-limitation is set, we will either create a guest capable of entering PV mode, or fail outright - If host-trust-limitation is not set, guest's might still be able to enter PV mode, if the CPU has the right model. This may be a little surprising, but shouldn't actually be harmful. To start a guest supporting Protected Virtualization using the new option use the command line arguments: -object s390-pv-guest,id=pv0 -machine host-trust-limitation=pv0 Signed-off-by: David Gibson Signed-off-by: Halil Pasic --- hw/s390x/pv.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c index ab3a2482aa..4bf3b345b6 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/host-trust-limitation.h" #include "hw/s390x/ipl.h" #include "hw/s390x/pv.h" @@ -111,3 +114,61 @@ void s390_pv_inject_reset_error(CPUState *cs) /* Report that we are unable to enter protected mode */ env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV; } + +#define TYPE_S390_PV_GUEST "s390-pv-guest" +#define S390_PV_GUEST(obj) \ + OBJECT_CHECK(S390PVGuestState, (obj), TYPE_S390_PV_GUEST) + +typedef struct S390PVGuestState S390PVGuestState; + +/** + * S390PVGuestState: + * + * The S390PVGuestState object is basically a dummy used to tell the + * host trust limitation system to use s390's PV mechanism. guest. + * + * # $QEMU \ + * -object s390-pv-guest,id=pv0 \ + * -machine ...,host-trust-limitation=pv0 + */ +struct S390PVGuestState { + Object parent_obj; +}; + +static int s390_pv_kvm_init(HostTrustLimitation *gmpo, Error **errp) +{ + if (!s390_has_feat(S390_FEAT_UNPACK)) { + error_setg(errp, + "CPU model does not support Protected Virtualization"); + return -1; + } + + return 0; +} + +static void s390_pv_guest_class_init(ObjectClass *oc, void *data) +{ + HostTrustLimitationClass *gmpc = HOST_TRUST_LIMITATION_CLASS(oc); + + gmpc->kvm_init = s390_pv_kvm_init; +} + +static const TypeInfo s390_pv_guest_info = { + .parent = TYPE_OBJECT, + .name = TYPE_S390_PV_GUEST, + .instance_size = sizeof(S390PVGuestState), + .class_init = s390_pv_guest_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_HOST_TRUST_LIMITATION }, + { TYPE_USER_CREATABLE }, + { } + } +}; + +static void +s390_pv_register_types(void) +{ + type_register_static(&s390_pv_guest_info); +} + +type_init(s390_pv_register_types);