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)