AArch64 QEMU VM with SME

by Simon Marchi on 1 August 2024

A while ago, I pushed a patch to GDB that broke the SME support. There aren't physical machines that support SME yet, or at least, I don't have access to one. QEMU supports it though (not sure which version, but it has to be recent enough), and I managed to set up a VM to run the tests I broke.

I used a Debian Cloud "nocloud" image, the latest of which can be found here.

The magic command-line to launch the VM is:

$ qemu-system-aarch64 \
~   -m 8G \
~   -machine virt \
~   -cpu max \
~   -smp 8 \
~   -bios /usr/share/edk2/aarch64/QEMU_EFI.fd \
~   -drive if=none,file=debian-12-nocloud-arm64-daily-20231108-1558.qcow2,id=hd0 \
~   -device virtio-blk-device,drive=hd0 \
~   -device e1000,netdev=net0 \
~   -netdev user,id=net0,hostfwd=tcp:127.0.0.1:5555-:22 \
~   -nographic

An explanation of the flags used:

-m 8G
8 gigabytes of memory
-machine virt
Use the virt machine, a QEMU machine type that doesn't try to emulate any existing hardware. It's just its own thing.
-cpu max
This makes QEMU emulate a CPU with all possible features enabled, so that should include SME
-bios /usr/share/edk2/aarch64/QEMU_EFI.fd
My understanding is that this specifies the program the machine initially runs, which will eventually find and run the bootloader (grub) installed in our image. This file is packaged by most Linux distros, but its location changes.
-drive [...]
-device virtio-blk-device,drive=hd0
Not sure what does what, but it ends up telling qemu to use our qcow2 image as a disk
-device e1000,netdev=net0
Add a network interface
-netdev [...]
Use "user mode" networking, which is slow but easy to set up. Forward port 5555 on the host to port 22 in the VM, to make it easier to ssh in. With user mode networking, there won't be a bridge device on the host that will magically allow to connect from the outside of the VM.
-nographic
Make the output just go to the terminal

When I run this magic command, I see a nice grub screen in my terminal, the guest Linux system booting, and eventually a login prompt:

Login prompt

The username is root, and there is no password.

The next step is to increase the image size, so we have enough room to build GDB (the image initially has a size of 2G). Shut down the guest, then:

$ qemu-img resize debian-12-nocloud-arm64-daily.qcow2 100G
Image resized.

To resize the filesystem inside the image, start by mounting the image to a device on the host:

$ sudo modprobe nbd
$ sudo qemu-nbd -c /dev/nbd0 debian-12-nocloud-arm64-daily.qcow2

I then use gparted on /dev/nbd0 to actually resize the filesystem, because it's so easy and I don't have to look up the equivalent commands.

Then, unmount the image:

$ sudo qemu-nbd -d /dev/nbd0

Restart the guest using the magic command above. From there, it's a regular Debian system. It is slow, but usable. A Raspberry Pi-like experience. Create a simark user, install an ssh server, and connect from the host with:

$ ssh localhost -p 5555 -l simark