xref: /openbmc/qemu/tests/functional/test_x86_64_kvm_xen.py (revision 3a0ff62431d297eadc7213cc5b2abda9d1bfce7a)
10a8b4fd5SThomas Huth#!/usr/bin/env python3
20a8b4fd5SThomas Huth#
30a8b4fd5SThomas Huth# KVM Xen guest functional tests
40a8b4fd5SThomas Huth#
50a8b4fd5SThomas Huth# Copyright © 2021 Red Hat, Inc.
60a8b4fd5SThomas Huth# Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
70a8b4fd5SThomas Huth#
80a8b4fd5SThomas Huth# Author:
90a8b4fd5SThomas Huth#  David Woodhouse <dwmw2@infradead.org>
100a8b4fd5SThomas Huth#  Alex Bennée <alex.bennee@linaro.org>
110a8b4fd5SThomas Huth#
120a8b4fd5SThomas Huth# SPDX-License-Identifier: GPL-2.0-or-later
130a8b4fd5SThomas Huth
140a8b4fd5SThomas Huthimport os
150a8b4fd5SThomas Huth
160a8b4fd5SThomas Huthfrom qemu.machine import machine
170a8b4fd5SThomas Huth
180a8b4fd5SThomas Huthfrom qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern
190a8b4fd5SThomas Huthfrom qemu_test import wait_for_console_pattern
200a8b4fd5SThomas Huth
210a8b4fd5SThomas Huthclass KVMXenGuest(QemuSystemTest):
220a8b4fd5SThomas Huth
230a8b4fd5SThomas Huth    KERNEL_DEFAULT = 'printk.time=0 root=/dev/xvda console=ttyS0 quiet'
240a8b4fd5SThomas Huth
250a8b4fd5SThomas Huth    kernel_path = None
260a8b4fd5SThomas Huth    kernel_params = None
270a8b4fd5SThomas Huth
280a8b4fd5SThomas Huth    # Fetch assets from the kvm-xen-guest subdir of my shared test
290a8b4fd5SThomas Huth    # images directory on fileserver.linaro.org where you can find
300a8b4fd5SThomas Huth    # build instructions for how they where assembled.
310a8b4fd5SThomas Huth    ASSET_KERNEL = Asset(
320a8b4fd5SThomas Huth        ('https://fileserver.linaro.org/s/kE4nCFLdQcoBF9t/download?'
330a8b4fd5SThomas Huth         'path=%2Fkvm-xen-guest&files=bzImage'),
340a8b4fd5SThomas Huth        'ec0ad7bb8c33c5982baee0a75505fe7dbf29d3ff5d44258204d6307c6fe0132a')
350a8b4fd5SThomas Huth
360a8b4fd5SThomas Huth    ASSET_ROOTFS = Asset(
370a8b4fd5SThomas Huth        ('https://fileserver.linaro.org/s/kE4nCFLdQcoBF9t/download?'
380a8b4fd5SThomas Huth         'path=%2Fkvm-xen-guest&files=rootfs.ext4'),
390a8b4fd5SThomas Huth        'b11045d649006c649c184e93339aaa41a8fe20a1a86620af70323252eb29e40b')
400a8b4fd5SThomas Huth
410a8b4fd5SThomas Huth    def common_vm_setup(self):
420a8b4fd5SThomas Huth        # We also catch lack of KVM_XEN support if we fail to launch
430a8b4fd5SThomas Huth        self.require_accelerator("kvm")
44*dba0752fSThomas Huth        self.require_netdev('user')
450a8b4fd5SThomas Huth
460a8b4fd5SThomas Huth        self.vm.set_console()
470a8b4fd5SThomas Huth
480a8b4fd5SThomas Huth        self.vm.add_args("-accel", "kvm,xen-version=0x4000a,kernel-irqchip=split")
490a8b4fd5SThomas Huth        self.vm.add_args("-smp", "2")
500a8b4fd5SThomas Huth
510a8b4fd5SThomas Huth        self.kernel_path = self.ASSET_KERNEL.fetch()
520a8b4fd5SThomas Huth        self.rootfs = self.ASSET_ROOTFS.fetch()
530a8b4fd5SThomas Huth
540a8b4fd5SThomas Huth    def run_and_check(self):
550a8b4fd5SThomas Huth        self.vm.add_args('-kernel', self.kernel_path,
560a8b4fd5SThomas Huth                         '-append', self.kernel_params,
570a8b4fd5SThomas Huth                         '-drive',  f"file={self.rootfs},if=none,snapshot=on,format=raw,id=drv0",
580a8b4fd5SThomas Huth                         '-device', 'xen-disk,drive=drv0,vdev=xvda',
590a8b4fd5SThomas Huth                         '-device', 'virtio-net-pci,netdev=unet',
600a8b4fd5SThomas Huth                         '-netdev', 'user,id=unet,hostfwd=:127.0.0.1:0-:22')
610a8b4fd5SThomas Huth
620a8b4fd5SThomas Huth        try:
630a8b4fd5SThomas Huth            self.vm.launch()
640a8b4fd5SThomas Huth        except machine.VMLaunchFailure as e:
650a8b4fd5SThomas Huth            if "Xen HVM guest support not present" in e.output:
660a8b4fd5SThomas Huth                self.skipTest("KVM Xen support is not present "
670a8b4fd5SThomas Huth                              "(need v5.12+ kernel with CONFIG_KVM_XEN)")
680a8b4fd5SThomas Huth            elif "Property 'kvm-accel.xen-version' not found" in e.output:
690a8b4fd5SThomas Huth                self.skipTest("QEMU not built with CONFIG_XEN_EMU support")
700a8b4fd5SThomas Huth            else:
710a8b4fd5SThomas Huth                raise e
720a8b4fd5SThomas Huth
730a8b4fd5SThomas Huth        self.log.info('VM launched, waiting for sshd')
740a8b4fd5SThomas Huth        console_pattern = 'Starting dropbear sshd: OK'
750a8b4fd5SThomas Huth        wait_for_console_pattern(self, console_pattern, 'Oops')
760a8b4fd5SThomas Huth        self.log.info('sshd ready')
770a8b4fd5SThomas Huth
780a8b4fd5SThomas Huth        exec_command_and_wait_for_pattern(self, 'cat /proc/cmdline', 'xen')
790a8b4fd5SThomas Huth        exec_command_and_wait_for_pattern(self, 'dmesg | grep "Grant table"',
800a8b4fd5SThomas Huth                                          'Grant table initialized')
810a8b4fd5SThomas Huth        wait_for_console_pattern(self, '#', 'Oops')
820a8b4fd5SThomas Huth
830a8b4fd5SThomas Huth    def test_kvm_xen_guest(self):
840a8b4fd5SThomas Huth        self.common_vm_setup()
850a8b4fd5SThomas Huth
860a8b4fd5SThomas Huth        self.kernel_params = (self.KERNEL_DEFAULT +
870a8b4fd5SThomas Huth                              ' xen_emul_unplug=ide-disks')
880a8b4fd5SThomas Huth        self.run_and_check()
890a8b4fd5SThomas Huth        exec_command_and_wait_for_pattern(self,
900a8b4fd5SThomas Huth                                'grep xen-pirq.*msi /proc/interrupts',
910a8b4fd5SThomas Huth                                'virtio0-output')
920a8b4fd5SThomas Huth
930a8b4fd5SThomas Huth    def test_kvm_xen_guest_nomsi(self):
940a8b4fd5SThomas Huth        self.common_vm_setup()
950a8b4fd5SThomas Huth
960a8b4fd5SThomas Huth        self.kernel_params = (self.KERNEL_DEFAULT +
970a8b4fd5SThomas Huth                              ' xen_emul_unplug=ide-disks pci=nomsi')
980a8b4fd5SThomas Huth        self.run_and_check()
990a8b4fd5SThomas Huth        exec_command_and_wait_for_pattern(self,
1000a8b4fd5SThomas Huth                                'grep xen-pirq.* /proc/interrupts',
1010a8b4fd5SThomas Huth                                'virtio0')
1020a8b4fd5SThomas Huth
1030a8b4fd5SThomas Huth    def test_kvm_xen_guest_noapic_nomsi(self):
1040a8b4fd5SThomas Huth        self.common_vm_setup()
1050a8b4fd5SThomas Huth
1060a8b4fd5SThomas Huth        self.kernel_params = (self.KERNEL_DEFAULT +
1070a8b4fd5SThomas Huth                              ' xen_emul_unplug=ide-disks noapic pci=nomsi')
1080a8b4fd5SThomas Huth        self.run_and_check()
1090a8b4fd5SThomas Huth        exec_command_and_wait_for_pattern(self,
1100a8b4fd5SThomas Huth                                'grep xen-pirq /proc/interrupts',
1110a8b4fd5SThomas Huth                                'virtio0')
1120a8b4fd5SThomas Huth
1130a8b4fd5SThomas Huth    def test_kvm_xen_guest_vapic(self):
1140a8b4fd5SThomas Huth        self.common_vm_setup()
1150a8b4fd5SThomas Huth        self.vm.add_args('-cpu', 'host,+xen-vapic')
1160a8b4fd5SThomas Huth        self.kernel_params = (self.KERNEL_DEFAULT +
1170a8b4fd5SThomas Huth                              ' xen_emul_unplug=ide-disks')
1180a8b4fd5SThomas Huth        self.run_and_check()
1190a8b4fd5SThomas Huth        exec_command_and_wait_for_pattern(self,
1200a8b4fd5SThomas Huth                                'grep xen-pirq /proc/interrupts',
1210a8b4fd5SThomas Huth                                'acpi')
1220a8b4fd5SThomas Huth        wait_for_console_pattern(self, '#')
1230a8b4fd5SThomas Huth        exec_command_and_wait_for_pattern(self,
1240a8b4fd5SThomas Huth                                'grep PCI-MSI /proc/interrupts',
1250a8b4fd5SThomas Huth                                'virtio0-output')
1260a8b4fd5SThomas Huth
1270a8b4fd5SThomas Huth    def test_kvm_xen_guest_novector(self):
1280a8b4fd5SThomas Huth        self.common_vm_setup()
1290a8b4fd5SThomas Huth        self.kernel_params = (self.KERNEL_DEFAULT +
1300a8b4fd5SThomas Huth                              ' xen_emul_unplug=ide-disks' +
1310a8b4fd5SThomas Huth                              ' xen_no_vector_callback')
1320a8b4fd5SThomas Huth        self.run_and_check()
1330a8b4fd5SThomas Huth        exec_command_and_wait_for_pattern(self,
1340a8b4fd5SThomas Huth                                'grep xen-platform-pci /proc/interrupts',
1350a8b4fd5SThomas Huth                                'fasteoi')
1360a8b4fd5SThomas Huth
1370a8b4fd5SThomas Huth    def test_kvm_xen_guest_novector_nomsi(self):
1380a8b4fd5SThomas Huth        self.common_vm_setup()
1390a8b4fd5SThomas Huth
1400a8b4fd5SThomas Huth        self.kernel_params = (self.KERNEL_DEFAULT +
1410a8b4fd5SThomas Huth                              ' xen_emul_unplug=ide-disks pci=nomsi' +
1420a8b4fd5SThomas Huth                              ' xen_no_vector_callback')
1430a8b4fd5SThomas Huth        self.run_and_check()
1440a8b4fd5SThomas Huth        exec_command_and_wait_for_pattern(self,
1450a8b4fd5SThomas Huth                                'grep xen-platform-pci /proc/interrupts',
1460a8b4fd5SThomas Huth                                'IO-APIC')
1470a8b4fd5SThomas Huth
1480a8b4fd5SThomas Huth    def test_kvm_xen_guest_novector_noapic(self):
1490a8b4fd5SThomas Huth        self.common_vm_setup()
1500a8b4fd5SThomas Huth        self.kernel_params = (self.KERNEL_DEFAULT +
1510a8b4fd5SThomas Huth                              ' xen_emul_unplug=ide-disks' +
1520a8b4fd5SThomas Huth                              ' xen_no_vector_callback noapic')
1530a8b4fd5SThomas Huth        self.run_and_check()
1540a8b4fd5SThomas Huth        exec_command_and_wait_for_pattern(self,
1550a8b4fd5SThomas Huth                                'grep xen-platform-pci /proc/interrupts',
1560a8b4fd5SThomas Huth                                'XT-PIC')
1570a8b4fd5SThomas Huth
1580a8b4fd5SThomas Huthif __name__ == '__main__':
1590a8b4fd5SThomas Huth    QemuSystemTest.main()
160