mbox series

[RFC,00/16] arm: Run Arm CCA VMs with KVM

Message ID 20230127150727.612594-1-jean-philippe@linaro.org (mailing list archive)
Headers show
Series arm: Run Arm CCA VMs with KVM | expand

Message

Jean-Philippe Brucker Jan. 27, 2023, 3:07 p.m. UTC
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.poulose@arm.com/
[2] https://lore.kernel.org/qemu-devel/20221202061347.1070246-1-chao.p.peng@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