| 1 | #!/usr/bin/env python3 |
| 2 | # |
| 3 | # Functional test that runs subsets of kvm-unit-tests on Aarch64. |
| 4 | # These can run on TCG and any accelerator supporting nested |
| 5 | # virtualisation. |
| 6 | # |
| 7 | # Copyright (c) 2025 Linaro |
| 8 | # |
| 9 | # Author: |
| 10 | # Alex Bennée <alex.bennee@linaro.org> |
| 11 | # |
| 12 | # SPDX-License-Identifier: GPL-2.0-or-later |
| 13 | |
| 14 | from qemu_test import Asset |
| 15 | from qemu_test import exec_command_and_wait_for_pattern as ec_and_wait |
| 16 | from qemu_test.linuxkernel import LinuxKernelTest |
| 17 | from qemu.machine.machine import VMLaunchFailure |
| 18 | |
| 19 | |
| 20 | class Aarch64VirtKVMTests(LinuxKernelTest): |
| 21 | |
| 22 | ASSET_KVM_TEST_KERNEL = Asset( |
| 23 | 'https://share.linaro.org/downloadFile?id=Bs8Eb2Wb7yWtkTA', |
| 24 | '34de4aaea90db5da42729e7d28b77f392c37a2f4da859f889a5234aaf0970696') |
| 25 | |
| 26 | # make it easier to detect successful return to shell |
| 27 | PS1 = 'RES=[$?] # ' |
| 28 | OK_CMD = 'RES=[0] # ' |
| 29 | |
| 30 | # base of tests |
| 31 | KUT_BASE = "/usr/share/kvm-unit-tests/" |
| 32 | |
| 33 | def _launch_guest(self, kvm_mode="nvhe"): |
| 34 | |
| 35 | self.set_machine('virt') |
| 36 | kernel_path = self.ASSET_KVM_TEST_KERNEL.fetch() |
| 37 | |
| 38 | self.vm.set_console() |
| 39 | kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + |
| 40 | f"console=ttyAMA0 kvm-arm.mode={kvm_mode}") |
| 41 | |
| 42 | self.vm.add_args("-cpu", "max") |
| 43 | self.vm.add_args("-machine", "virt,gic-version=3,virtualization=on", |
| 44 | '-kernel', kernel_path, |
| 45 | '-append', kernel_command_line) |
| 46 | self.vm.add_args("-smp", "2", "-m", "320") |
| 47 | |
| 48 | try: |
| 49 | self.vm.launch() |
| 50 | except VMLaunchFailure as excp: |
| 51 | if "does not support providing Virtualization" in excp.output: |
| 52 | self.skipTest("accelerator has no virtualization support") |
| 53 | else: |
| 54 | self.log.info("unhandled launch failure: %s", excp.output) |
| 55 | raise excp |
| 56 | |
| 57 | self.wait_for_console_pattern('buildroot login:') |
| 58 | ec_and_wait(self, 'root', '#') |
| 59 | ec_and_wait(self, f"export PS1='{self.PS1}'", self.OK_CMD) |
| 60 | |
| 61 | # this is just a smoketest, we don't run all the tests in the image |
| 62 | def _smoketest_kvm(self): |
| 63 | ec_and_wait(self, f"{self.KUT_BASE}/selftest-setup", self.OK_CMD) |
| 64 | ec_and_wait(self, f"{self.KUT_BASE}/selftest-smp", self.OK_CMD) |
| 65 | ec_and_wait(self, f"{self.KUT_BASE}/selftest-vectors-kernel", self.OK_CMD) |
| 66 | ec_and_wait(self, f"{self.KUT_BASE}/selftest-vectors-user", self.OK_CMD) |
| 67 | |
| 68 | def test_aarch64_nvhe_selftest(self): |
| 69 | self._launch_guest("nvhe") |
| 70 | self._smoketest_kvm() |
| 71 | |
| 72 | def test_aarch64_vhe_selftest(self): |
| 73 | self._launch_guest("vhe") |
| 74 | self._smoketest_kvm() |
| 75 | |
| 76 | if __name__ == '__main__': |
| 77 | LinuxKernelTest.main() |