This series implements the proper use of FEAT_MEC MECID registers in
QEMU for all translation regimes. In physical hardware, MECID registers
are used to select an encryption engine that transparently encrypts
memory data per Realm (as FEAT_MEC is an extension of FEAT_RME).

The main idea of this series is to avoid actual data encryption.
Instead, we store the MECID associated with each page during guest data
store operations. On subsequent memory accesses, we verify whether the
MECID in the register matches the stored MECID.

If a MECID mismatch occurs, rather than returning encrypted data as on
physical hardware, a substitute page filled with 0xdeadbeef is returned
to mimic the hardware's behavior.

I tested this series by booting Linux on up to three VMs simultaneously
and verified that the MECIDs for each were set correctly.

There is one remaining issue tho: when a VM is destroyed and another is
launched in sequence, a MECID mismatch occurs, leading to an
"Unexpected exception on CPU" in the host. Since the software stack is
still under development, I cannot yet exclude this is not a firmware or
KVM-related issue. Regardless, this needs to be addressed; however,
before I dig further, I would appreciate feedback on the implementation
proposed in this series.

For testing this series you can:

Get the stack to test FEAT_MEC either:
Download the artifacts (tf-a + tf-rmm + linux/kvm + kvmtool) from:
https://github.com/gromero/qemu-linux-stack/actions/runs/23274571242/artifacts/5998250548

Then unzip and untar in QEMU's build dir:
$ unzip ./build.zip
$ tar xvf build.tar.xz

Or build them from scratch:
$ git clone https://github.com/gromero/qemu-linux-stack.git --branch rme_mec 
--single-branch --depth 1
$ cd qemu-linux-stack && ./build.sh
Files will be in ./out and should be copied to QEMU's build dir:
4.1M    out/flash.bin
167M    out/guest.ext4
167M    out/host.ext4
38M     out/Image
3.1M    out/lkvm

Build QEMU with this series applied

Run QEMU system with FEAT_MEC enabled (mec=on) from the build dir:
./qemu-system-aarch64 -display none -vga none -chardev stdio,id=console -serial 
chardev:console -machine virt -cpu max,x-rme=on -smp 2 -m 2G -M 
virt,acpi=off,virtualization=on,secure=on,gic-version=3,mec=on -bios 
./out/flash.bin -kernel ./out/Image -drive 
format=raw,file=./out/host.ext4,if=virtio -virtfs 
local,path=./,mount_tag=host,security_model=mapped,readonly=off -append 
'nokaslr root=/dev/vda rw init=/init -- /bin/bash'

Once in Linux, do (for 2 VMs, for example):

# apt-get install tmux 
# tmux
Use [CTRL-b] " [SPACE] to split the terminal horizontally
Use [CTRL-b] UP/DOWN to move between the two windows
In one window run:
# /host/out/lkvm run --realm -m 256m --shared-mec 0 --restricted_mem --kernel 
/host/out/Image --disk /host/out/guest.ext4 --params "root=/dev/vda rw 
init=/init"
Then [CTRL-B] UP to move to the other window
Then boot another VM:
# /host/out/lkvm run --realm -m 256m --shared-mec 0 --restricted_mem --kernel 
/host/out/Image --disk /host/out/guest.ext4 --params "root=/dev/vda rw 
init=/init"
Wait for the VMs to boot

I added a patch to the series, 
"Print MECID if not zero [TO BE DISCARDED]", that can be used for
printing the MECIDs used by the VMs. It will print a bunch of messages
like: 

MECID (in register) stored for va = fffffffffffa7000 pa = 630d5000 is 3 [...]

where one can observe different MECIDs being used the VMs, like 3 and 4.
Just mind that the prints can slow down QEMU and cause CPU stalls on
Linux.


Cheers,
Gustavo

Gustavo Romero (7):
  target/arm: Flush TLB on MECID write
  target/cpu: Add two new address spaces for FEAT_MEC
  memattrs: Add new attribute 'encrypted'
  target/arm/cpu: Add FEAT_MEC object properties
  hw/arm/virt: Add machine option 'mec'
  target/arm/ptw: Add MECID checks
  target/arm/ptw: Print MECID if not zero [TO BE DISCARDED]

 hw/arm/virt.c           |  76 ++++++++++++++
 include/exec/memattrs.h |   7 ++
 include/hw/arm/virt.h   |   1 +
 target/arm/cpu.c        |  20 ++++
 target/arm/cpu.h        |  14 ++-
 target/arm/helper.c     |   2 +
 target/arm/internals.h  |   2 +
 target/arm/ptw.c        | 218 +++++++++++++++++++++++++++++++++++++++-
 8 files changed, 337 insertions(+), 3 deletions(-)

-- 
2.34.1


Reply via email to