On Thu, 21 May 2020 13:43:03 +1000 David Gibson <david@xxxxxxxxxxxxxxxxxxxxx> wrote: > Some upcoming POWER machines have a system called PEF (Protected > Execution Framework) which uses a small ultravisor to allow guests to s/Framework/Facility > 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 havint the right hardware and firmware, we don't s/havint/having > enable this by default. In order to run a secure guest you need to > create a "pef-guest" object and set the guest-memory-protection machine property to point to it. > Wrap line after "machine" maybe ? > 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, so we can't know if the guest actually is secure until > well after machine creation time. > Maybe worth mentioning that this is for KVM only. Also, this is silently ignored with TCG since pef_kvm_init() isn't called in this case. Would it make sense to print some warning like we do for these spapr caps that we don't support with TCG ? > Signed-off-by: David Gibson <david@xxxxxxxxxxxxxxxxxxxxx> > --- > target/ppc/Makefile.objs | 2 +- > target/ppc/pef.c | 81 ++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 82 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..823daf3e9c > --- /dev/null > +++ b/target/ppc/pef.c > @@ -0,0 +1,81 @@ > +/* > + * PEF (Protected Execution Framework) for POWER support s/Framework/Facility > + * > + * 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" > + I had to include some more headers to build this. #include "exec/guest-memory-protection.h" #include "qapi/error.h" #include "qom/object_interfaces.h" #include "sysemu/kvm.h" > +#define TYPE_PEF_GUEST "pef-guest" > +#define PEF_GUEST(obj) \ > + OBJECT_CHECK(PefGuestState, (obj), TYPE_SEV_GUEST) s/TYPE_SEV_GUEST/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 ...,guest-memory-protection=pef0 > + */ > +struct PefGuestState { > + Object parent_obj; > +}; > + > +static Error *pef_mig_blocker; Unused. > + > +static int pef_kvm_init(GuestMemoryProtection *gmpo, Error **errp) > +{ > + PefGuestState *pef = PEF_GUEST(gmpo); Unused. > + > + 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) > +{ > + GuestMemoryProtectionClass *gmpc = GUEST_MEMORY_PROTECTION_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_GUEST_MEMORY_PROTECTION }, > + { TYPE_USER_CREATABLE }, > + { } > + } > +}; > + > +static void > +pef_register_types(void) > +{ > + type_register_static(&pef_guest_info); > +} > + > +type_init(pef_register_types);