The Arm Realm Management Extension (RME), part of the Arm Confidential Computing Architecture (CCA), enables running confidential virtual machines in a new "Realm" security state. While the host still manages the resources of a guest running in a Realm, it cannot access them.
This series adds some support to QEMU for launching a guest in a Realm with KVM. The KVM changes for CCA have been posted at [1]. Patches 2-4 introduce a new RmeGuest object that inherits from ConfidentialGuestSupport and enable it for the virt machine. Like other confidential guest architectures, launching a Realm VM requires two command-line parameters: -object rme-guest,id=<id>,<parameters> -M confidential-guest-support=<id> Patches 5-6 modify the KVM vCPU support. With CCA, KVM does not sit atop the VM anymore but talks to a new component, the Realm Management Monitor (RMM) which deals with the Realm stage-2 page tables and CPU state. So KVM cannot access most vCPU registers anymore except for passing parameters to RMM when handling VM exits. Likewise, the host must not access any memory assigned to the guest (or else it gets a granule protection fault). The private memfd work [2] by Chao Peng will help with this. Patches 8-9 deal with loading images into the Realm. Those are measured by the RMM and part of the initial measurement, which allows a Realm owner to attest that the Realm is running what it expects. Patches 10-14 pass parameters described in the RMM specification. This initial posting only provides direct kernel boot with DTB, not firmware boot. There is ongoing work to extend edk2 to run in a Realm, which will require changes to QEMU. A few problems will come up: * The FwCfg device provides kernel images, initrd, ACPI tables etc. This isn't an option for CCA because the guest does not trust what the host provides at runtime. I suggest to load all those things in Realm memory before boot, and pass their address in the device tree which is always present at the start of RAM. This will require new properties in the device-tree's chosen section. * The guest firmware probably shouldn't be on an emulated flash device. For one thing, it doesn't need flash because it will store all variable in RAM. The flash device also relies on read-only mappings which are not supported by KVM RME at the moment, and trapping reads would break integrity. I suggest to either replace the flash device (address 0 of the virt machine) by RAM when RmeGuest is enabled, or load the firmware somewhere else in RAM. Please see [1] for additional resource, including instructions for building and running the CCA software stack on a model. An example command-line: qemu-system-aarch64 -M virt -cpu host -enable-kvm -M gic-version=3 -smp 2 -m 256M -nographic -M confidential-guest-support=rme0 -object rme-guest,id=rme0,measurement-algo=sha512 -kernel Image -initrd rootfs.cpio -append 'console=ttyAMA0 earlycon' -overcommit mem-lock=on A branch with these patches is available at [3]. [1] https://lore.kernel.org/kvm/20230127112248.136810-1-suzuki.poul...@arm.com/ [2] https://lore.kernel.org/qemu-devel/20221202061347.1070246-1-chao.p.p...@linux.intel.com/ [3] https://jpbrucker.net/git/qemu cca/rfc-v1 Jean-Philippe Brucker (16): NOMERGE: Add KVM Arm RME definitions to Linux headers target/arm: Add confidential guest support target/arm/kvm-rme: Initialize realm hw/arm/virt: Add support for Arm RME target/arm/kvm: Split kvm_arch_get/put_registers target/arm/kvm-rme: Initialize vCPU target/arm/kvm: Select RME VM type for the scratch VM target/arm/kvm-rme: Populate the realm with boot images hw/arm/boot: Populate realm memory with boot images target/arm/kvm-rme: Add measurement algorithm property target/arm/kvm-rme: Add Realm Personalization Value parameter target/arm/kvm-rme: Add Realm SVE vector length target/arm/kvm-rme: Add breakpoints and watchpoints parameters target/arm/kvm-rme: Add PMU num counters parameters target/arm/kvm: Disable Realm reboot target/arm/kvm-rme: Disable readonly mappings docs/system/confidential-guest-support.rst | 1 + qapi/qom.json | 32 +- include/sysemu/kvm.h | 2 + linux-headers/asm-arm64/kvm.h | 63 +++ linux-headers/linux/kvm.h | 21 +- target/arm/cpu.h | 3 + target/arm/kvm_arm.h | 21 + accel/kvm/kvm-all.c | 8 +- hw/arm/boot.c | 10 +- hw/arm/virt.c | 48 +- target/arm/helper.c | 8 + target/arm/kvm-rme.c | 505 +++++++++++++++++++++ target/arm/kvm.c | 20 +- target/arm/kvm64.c | 91 +++- target/arm/meson.build | 7 +- 15 files changed, 822 insertions(+), 18 deletions(-) create mode 100644 target/arm/kvm-rme.c -- 2.39.0