1#!/usr/bin/env python3 2# 3# KVM Xen guest functional tests 4# 5# Copyright © 2021 Red Hat, Inc. 6# Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. 7# 8# Author: 9# David Woodhouse <dwmw2@infradead.org> 10# Alex Bennée <alex.bennee@linaro.org> 11# 12# SPDX-License-Identifier: GPL-2.0-or-later 13 14from qemu.machine import machine 15 16from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern 17from qemu_test import wait_for_console_pattern 18 19class KVMXenGuest(QemuSystemTest): 20 21 KERNEL_DEFAULT = 'printk.time=0 root=/dev/xvda console=ttyS0 quiet' 22 23 kernel_path = None 24 kernel_params = None 25 26 ASSET_KERNEL = Asset('https://share.linaro.org/downloadFile?id=UG0V8dzzHrrHb9X', 27 'ec0ad7bb8c33c5982baee0a75505fe7dbf29d3ff5d44258204d6307c6fe0132a') 28 29 ASSET_ROOTFS = Asset('https://share.linaro.org/downloadFile?id=VwLRKDXKFl6oKti', 30 'b11045d649006c649c184e93339aaa41a8fe20a1a86620af70323252eb29e40b') 31 32 def common_vm_setup(self): 33 # We also catch lack of KVM_XEN support if we fail to launch 34 self.require_accelerator("kvm") 35 self.require_netdev('user') 36 37 self.vm.set_console() 38 39 self.vm.add_args("-accel", "kvm,xen-version=0x4000a,kernel-irqchip=split") 40 self.vm.add_args("-smp", "2") 41 42 self.kernel_path = self.ASSET_KERNEL.fetch() 43 self.rootfs = self.ASSET_ROOTFS.fetch() 44 45 def run_and_check(self): 46 self.vm.add_args('-kernel', self.kernel_path, 47 '-append', self.kernel_params, 48 '-drive', f"file={self.rootfs},if=none,snapshot=on,format=raw,id=drv0", 49 '-device', 'xen-disk,drive=drv0,vdev=xvda', 50 '-device', 'virtio-net-pci,netdev=unet', 51 '-netdev', 'user,id=unet,hostfwd=:127.0.0.1:0-:22') 52 53 try: 54 self.vm.launch() 55 except machine.VMLaunchFailure as e: 56 if "Xen HVM guest support not present" in e.output: 57 self.skipTest("KVM Xen support is not present " 58 "(need v5.12+ kernel with CONFIG_KVM_XEN)") 59 elif "Property 'kvm-accel.xen-version' not found" in e.output: 60 self.skipTest("QEMU not built with CONFIG_XEN_EMU support") 61 else: 62 raise e 63 64 self.log.info('VM launched, waiting for sshd') 65 console_pattern = 'Starting dropbear sshd: OK' 66 wait_for_console_pattern(self, console_pattern, 'Oops') 67 self.log.info('sshd ready') 68 69 exec_command_and_wait_for_pattern(self, 'cat /proc/cmdline', 'xen') 70 exec_command_and_wait_for_pattern(self, 'dmesg | grep "Grant table"', 71 'Grant table initialized') 72 wait_for_console_pattern(self, '#', 'Oops') 73 74 def test_kvm_xen_guest(self): 75 self.common_vm_setup() 76 77 self.kernel_params = (self.KERNEL_DEFAULT + 78 ' xen_emul_unplug=ide-disks') 79 self.run_and_check() 80 exec_command_and_wait_for_pattern(self, 81 'grep xen-pirq.*msi /proc/interrupts', 82 'virtio0-output') 83 84 def test_kvm_xen_guest_nomsi(self): 85 self.common_vm_setup() 86 87 self.kernel_params = (self.KERNEL_DEFAULT + 88 ' xen_emul_unplug=ide-disks pci=nomsi') 89 self.run_and_check() 90 exec_command_and_wait_for_pattern(self, 91 'grep xen-pirq.* /proc/interrupts', 92 'virtio0') 93 94 def test_kvm_xen_guest_noapic_nomsi(self): 95 self.common_vm_setup() 96 97 self.kernel_params = (self.KERNEL_DEFAULT + 98 ' xen_emul_unplug=ide-disks noapic pci=nomsi') 99 self.run_and_check() 100 exec_command_and_wait_for_pattern(self, 101 'grep xen-pirq /proc/interrupts', 102 'virtio0') 103 104 def test_kvm_xen_guest_vapic(self): 105 self.common_vm_setup() 106 self.vm.add_args('-cpu', 'host,+xen-vapic') 107 self.kernel_params = (self.KERNEL_DEFAULT + 108 ' xen_emul_unplug=ide-disks') 109 self.run_and_check() 110 exec_command_and_wait_for_pattern(self, 111 'grep xen-pirq /proc/interrupts', 112 'acpi') 113 wait_for_console_pattern(self, '#') 114 exec_command_and_wait_for_pattern(self, 115 'grep PCI-MSI /proc/interrupts', 116 'virtio0-output') 117 118 def test_kvm_xen_guest_novector(self): 119 self.common_vm_setup() 120 self.kernel_params = (self.KERNEL_DEFAULT + 121 ' xen_emul_unplug=ide-disks' + 122 ' xen_no_vector_callback') 123 self.run_and_check() 124 exec_command_and_wait_for_pattern(self, 125 'grep xen-platform-pci /proc/interrupts', 126 'fasteoi') 127 128 def test_kvm_xen_guest_novector_nomsi(self): 129 self.common_vm_setup() 130 131 self.kernel_params = (self.KERNEL_DEFAULT + 132 ' xen_emul_unplug=ide-disks pci=nomsi' + 133 ' xen_no_vector_callback') 134 self.run_and_check() 135 exec_command_and_wait_for_pattern(self, 136 'grep xen-platform-pci /proc/interrupts', 137 'IO-APIC') 138 139 def test_kvm_xen_guest_novector_noapic(self): 140 self.common_vm_setup() 141 self.kernel_params = (self.KERNEL_DEFAULT + 142 ' xen_emul_unplug=ide-disks' + 143 ' xen_no_vector_callback noapic') 144 self.run_and_check() 145 exec_command_and_wait_for_pattern(self, 146 'grep xen-platform-pci /proc/interrupts', 147 'XT-PIC') 148 149if __name__ == '__main__': 150 QemuSystemTest.main() 151