diff --git a/DEVELOPERS b/DEVELOPERS index 66ef2adf9e..b4c9b6e618 100644 --- a/DEVELOPERS +++ b/DEVELOPERS @@ -1934,6 +1934,8 @@ F: support/testing/tests/package/test_kmod.py F: support/testing/tests/package/test_kmod/ F: support/testing/tests/package/test_kmscube.py F: support/testing/tests/package/test_kmscube/ +F: support/testing/tests/package/test_kvmtool.py +F: support/testing/tests/package/test_kvmtool/ F: support/testing/tests/package/test_lame.py F: support/testing/tests/package/test_less.py F: support/testing/tests/package/test_libcamera.py diff --git a/support/testing/tests/package/test_kvmtool.py b/support/testing/tests/package/test_kvmtool.py new file mode 100644 index 0000000000..d6859172bd --- /dev/null +++ b/support/testing/tests/package/test_kvmtool.py @@ -0,0 +1,97 @@ +import os + +import infra.basetest + + +class TestKvmTool(infra.basetest.BRTest): + # This test passes the Buildroot image directory to the emulated + # guest using the 9p virtiofs. This guest enables the + # virtualization support. It will start a nested KVM virtual + # machine, using the same Kernel/initramfs images. For these + # reasons, we need a specific kernel configuration that enables + # KVM and 9P. + kern_frag = \ + infra.filepath("tests/package/test_kvmtool/linux-kvm.fragment") + rootfs_overlay = \ + infra.filepath("tests/package/test_kvmtool/rootfs-overlay") + config = \ + f""" + BR2_aarch64=y + BR2_TOOLCHAIN_EXTERNAL=y + BR2_LINUX_KERNEL=y + BR2_LINUX_KERNEL_CUSTOM_VERSION=y + BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.1" + BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y + BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/aarch64-virt/linux.config" + BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="{kern_frag}" + BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y + BR2_PACKAGE_KVMTOOL=y + BR2_ROOTFS_OVERLAY="{rootfs_overlay}" + BR2_TARGET_ROOTFS_CPIO=y + # BR2_TARGET_ROOTFS_TAR is not set + """ + + def test_run(self): + img = os.path.join(self.builddir, "images", "rootfs.cpio") + kern = os.path.join(self.builddir, "images", "Image") + img_dir = os.path.join(self.builddir, "images") + virtfs_tag = "br-imgs" + virtfs_opts = [ + f"local,path={img_dir}", + f"mount_tag={virtfs_tag}", + "security_model=mapped-xattr", + "readonly" + ] + qemu_opts = ["-M", "virt,gic-version=3,virtualization=on", + "-cpu", "cortex-a57", + "-smp", "4", + "-m", "1G", + "-virtfs", ','.join(virtfs_opts), + "-initrd", img] + self.emulator.boot(arch="aarch64", + kernel=kern, + options=qemu_opts) + self.emulator.login() + + # Test the program can execute. + self.assertRunOk("lkvm --version") + + # We mount the virtfs to get the Kernel and initramfs from the + # test host. + self.assertRunOk(f"mount -t 9p {virtfs_tag} /mnt/") + + # We define an arbitrary kernel command line argument that we + # will use to detect we are in our virtual machine. + kvm_karg = "br-kvm" + + # The number of CPU of our virtual machine + kvm_nproc = 2 + + # We run the KVM virtual machine + cmd = "lkvm run" + cmd += " --kernel /mnt/Image" + cmd += " --initrd /mnt/rootfs.cpio" + cmd += f" --cpus {kvm_nproc}" + cmd += " --mem 320M" + cmd += " --console virtio" + cmd += " --irqchip gicv3" + cmd += f" --params {kvm_karg}" + + # We use qemu.sendline() to run the command because the + # program will not return an exit code. The command "lkvm run" + # will spawn the new virtual machine console. The login is + # expected to be reached after the command is issued. + self.emulator.qemu.sendline(cmd) + + # We login in the virtual machine. + self.emulator.login() + + # We check we can see our kernel argument. + out, ret = self.emulator.run("cat /proc/cmdline") + self.assertEqual(ret, 0) + self.assertIn(kvm_karg, out[0]) + + # We check the virtual machine has the expected number of CPU. + out, ret = self.emulator.run("nproc") + self.assertEqual(ret, 0) + self.assertEqual(int(out[0]), kvm_nproc) diff --git a/support/testing/tests/package/test_kvmtool/linux-kvm.fragment b/support/testing/tests/package/test_kvmtool/linux-kvm.fragment new file mode 100644 index 0000000000..8058ac41c3 --- /dev/null +++ b/support/testing/tests/package/test_kvmtool/linux-kvm.fragment @@ -0,0 +1,6 @@ +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=y +CONFIG_NET_9P=y +CONFIG_NET_9P_VIRTIO=y +CONFIG_9P_FS=y +CONFIG_9P_FS_POSIX_ACL=y diff --git a/support/testing/tests/package/test_kvmtool/rootfs-overlay/etc/profile.d/stty-raw.sh b/support/testing/tests/package/test_kvmtool/rootfs-overlay/etc/profile.d/stty-raw.sh new file mode 100644 index 0000000000..24d72995e6 --- /dev/null +++ b/support/testing/tests/package/test_kvmtool/rootfs-overlay/etc/profile.d/stty-raw.sh @@ -0,0 +1,3 @@ +# Avoid double-cooking the terminal, otherwise the test infrastructure +# would not be able to retrieve return codes properly. +grep -Fq br-kvm /proc/cmdline && stty raw