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 14import os 15 16from qemu.machine import machine 17 18from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern 19from qemu_test import wait_for_console_pattern 20 21class KVMXenGuest(QemuSystemTest): 22 23 KERNEL_DEFAULT = 'printk.time=0 root=/dev/xvda console=ttyS0 quiet' 24 25 kernel_path = None 26 kernel_params = None 27 28 # Fetch assets from the kvm-xen-guest subdir of my shared test 29 # images directory on fileserver.linaro.org where you can find 30 # build instructions for how they where assembled. 31 ASSET_KERNEL = Asset( 32 ('https://fileserver.linaro.org/s/kE4nCFLdQcoBF9t/download?' 33 'path=%2Fkvm-xen-guest&files=bzImage'), 34 'ec0ad7bb8c33c5982baee0a75505fe7dbf29d3ff5d44258204d6307c6fe0132a') 35 36 ASSET_ROOTFS = Asset( 37 ('https://fileserver.linaro.org/s/kE4nCFLdQcoBF9t/download?' 38 'path=%2Fkvm-xen-guest&files=rootfs.ext4'), 39 'b11045d649006c649c184e93339aaa41a8fe20a1a86620af70323252eb29e40b') 40 41 def common_vm_setup(self): 42 # We also catch lack of KVM_XEN support if we fail to launch 43 self.require_accelerator("kvm") 44 45 self.vm.set_console() 46 47 self.vm.add_args("-accel", "kvm,xen-version=0x4000a,kernel-irqchip=split") 48 self.vm.add_args("-smp", "2") 49 50 self.kernel_path = self.ASSET_KERNEL.fetch() 51 self.rootfs = self.ASSET_ROOTFS.fetch() 52 53 def run_and_check(self): 54 self.vm.add_args('-kernel', self.kernel_path, 55 '-append', self.kernel_params, 56 '-drive', f"file={self.rootfs},if=none,snapshot=on,format=raw,id=drv0", 57 '-device', 'xen-disk,drive=drv0,vdev=xvda', 58 '-device', 'virtio-net-pci,netdev=unet', 59 '-netdev', 'user,id=unet,hostfwd=:127.0.0.1:0-:22') 60 61 try: 62 self.vm.launch() 63 except machine.VMLaunchFailure as e: 64 if "Xen HVM guest support not present" in e.output: 65 self.skipTest("KVM Xen support is not present " 66 "(need v5.12+ kernel with CONFIG_KVM_XEN)") 67 elif "Property 'kvm-accel.xen-version' not found" in e.output: 68 self.skipTest("QEMU not built with CONFIG_XEN_EMU support") 69 else: 70 raise e 71 72 self.log.info('VM launched, waiting for sshd') 73 console_pattern = 'Starting dropbear sshd: OK' 74 wait_for_console_pattern(self, console_pattern, 'Oops') 75 self.log.info('sshd ready') 76 77 exec_command_and_wait_for_pattern(self, 'cat /proc/cmdline', 'xen') 78 exec_command_and_wait_for_pattern(self, 'dmesg | grep "Grant table"', 79 'Grant table initialized') 80 wait_for_console_pattern(self, '#', 'Oops') 81 82 def test_kvm_xen_guest(self): 83 """ 84 :avocado: tags=kvm_xen_guest 85 """ 86 87 self.common_vm_setup() 88 89 self.kernel_params = (self.KERNEL_DEFAULT + 90 ' xen_emul_unplug=ide-disks') 91 self.run_and_check() 92 exec_command_and_wait_for_pattern(self, 93 'grep xen-pirq.*msi /proc/interrupts', 94 'virtio0-output') 95 96 def test_kvm_xen_guest_nomsi(self): 97 """ 98 :avocado: tags=kvm_xen_guest_nomsi 99 """ 100 101 self.common_vm_setup() 102 103 self.kernel_params = (self.KERNEL_DEFAULT + 104 ' xen_emul_unplug=ide-disks pci=nomsi') 105 self.run_and_check() 106 exec_command_and_wait_for_pattern(self, 107 'grep xen-pirq.* /proc/interrupts', 108 'virtio0') 109 110 def test_kvm_xen_guest_noapic_nomsi(self): 111 """ 112 :avocado: tags=kvm_xen_guest_noapic_nomsi 113 """ 114 115 self.common_vm_setup() 116 117 self.kernel_params = (self.KERNEL_DEFAULT + 118 ' xen_emul_unplug=ide-disks noapic pci=nomsi') 119 self.run_and_check() 120 exec_command_and_wait_for_pattern(self, 121 'grep xen-pirq /proc/interrupts', 122 'virtio0') 123 124 def test_kvm_xen_guest_vapic(self): 125 """ 126 :avocado: tags=kvm_xen_guest_vapic 127 """ 128 129 self.common_vm_setup() 130 self.vm.add_args('-cpu', 'host,+xen-vapic') 131 self.kernel_params = (self.KERNEL_DEFAULT + 132 ' xen_emul_unplug=ide-disks') 133 self.run_and_check() 134 exec_command_and_wait_for_pattern(self, 135 'grep xen-pirq /proc/interrupts', 136 'acpi') 137 wait_for_console_pattern(self, '#') 138 exec_command_and_wait_for_pattern(self, 139 'grep PCI-MSI /proc/interrupts', 140 'virtio0-output') 141 142 def test_kvm_xen_guest_novector(self): 143 """ 144 :avocado: tags=kvm_xen_guest_novector 145 """ 146 147 self.common_vm_setup() 148 self.kernel_params = (self.KERNEL_DEFAULT + 149 ' xen_emul_unplug=ide-disks' + 150 ' xen_no_vector_callback') 151 self.run_and_check() 152 exec_command_and_wait_for_pattern(self, 153 'grep xen-platform-pci /proc/interrupts', 154 'fasteoi') 155 156 def test_kvm_xen_guest_novector_nomsi(self): 157 """ 158 :avocado: tags=kvm_xen_guest_novector_nomsi 159 """ 160 161 self.common_vm_setup() 162 163 self.kernel_params = (self.KERNEL_DEFAULT + 164 ' xen_emul_unplug=ide-disks pci=nomsi' + 165 ' xen_no_vector_callback') 166 self.run_and_check() 167 exec_command_and_wait_for_pattern(self, 168 'grep xen-platform-pci /proc/interrupts', 169 'IO-APIC') 170 171 def test_kvm_xen_guest_novector_noapic(self): 172 """ 173 :avocado: tags=kvm_xen_guest_novector_noapic 174 """ 175 176 self.common_vm_setup() 177 self.kernel_params = (self.KERNEL_DEFAULT + 178 ' xen_emul_unplug=ide-disks' + 179 ' xen_no_vector_callback noapic') 180 self.run_and_check() 181 exec_command_and_wait_for_pattern(self, 182 'grep xen-platform-pci /proc/interrupts', 183 'XT-PIC') 184 185if __name__ == '__main__': 186 QemuSystemTest.main() 187