xref: /qemu/tests/functional/test_x86_64_kvm_xen.py (revision c07cd110a1824e2d046581af7375f16dac26e96f)
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        self.require_netdev('user')
45
46        self.vm.set_console()
47
48        self.vm.add_args("-accel", "kvm,xen-version=0x4000a,kernel-irqchip=split")
49        self.vm.add_args("-smp", "2")
50
51        self.kernel_path = self.ASSET_KERNEL.fetch()
52        self.rootfs = self.ASSET_ROOTFS.fetch()
53
54    def run_and_check(self):
55        self.vm.add_args('-kernel', self.kernel_path,
56                         '-append', self.kernel_params,
57                         '-drive',  f"file={self.rootfs},if=none,snapshot=on,format=raw,id=drv0",
58                         '-device', 'xen-disk,drive=drv0,vdev=xvda',
59                         '-device', 'virtio-net-pci,netdev=unet',
60                         '-netdev', 'user,id=unet,hostfwd=:127.0.0.1:0-:22')
61
62        try:
63            self.vm.launch()
64        except machine.VMLaunchFailure as e:
65            if "Xen HVM guest support not present" in e.output:
66                self.skipTest("KVM Xen support is not present "
67                              "(need v5.12+ kernel with CONFIG_KVM_XEN)")
68            elif "Property 'kvm-accel.xen-version' not found" in e.output:
69                self.skipTest("QEMU not built with CONFIG_XEN_EMU support")
70            else:
71                raise e
72
73        self.log.info('VM launched, waiting for sshd')
74        console_pattern = 'Starting dropbear sshd: OK'
75        wait_for_console_pattern(self, console_pattern, 'Oops')
76        self.log.info('sshd ready')
77
78        exec_command_and_wait_for_pattern(self, 'cat /proc/cmdline', 'xen')
79        exec_command_and_wait_for_pattern(self, 'dmesg | grep "Grant table"',
80                                          'Grant table initialized')
81        wait_for_console_pattern(self, '#', 'Oops')
82
83    def test_kvm_xen_guest(self):
84        self.common_vm_setup()
85
86        self.kernel_params = (self.KERNEL_DEFAULT +
87                              ' xen_emul_unplug=ide-disks')
88        self.run_and_check()
89        exec_command_and_wait_for_pattern(self,
90                                'grep xen-pirq.*msi /proc/interrupts',
91                                'virtio0-output')
92
93    def test_kvm_xen_guest_nomsi(self):
94        self.common_vm_setup()
95
96        self.kernel_params = (self.KERNEL_DEFAULT +
97                              ' xen_emul_unplug=ide-disks pci=nomsi')
98        self.run_and_check()
99        exec_command_and_wait_for_pattern(self,
100                                'grep xen-pirq.* /proc/interrupts',
101                                'virtio0')
102
103    def test_kvm_xen_guest_noapic_nomsi(self):
104        self.common_vm_setup()
105
106        self.kernel_params = (self.KERNEL_DEFAULT +
107                              ' xen_emul_unplug=ide-disks noapic pci=nomsi')
108        self.run_and_check()
109        exec_command_and_wait_for_pattern(self,
110                                'grep xen-pirq /proc/interrupts',
111                                'virtio0')
112
113    def test_kvm_xen_guest_vapic(self):
114        self.common_vm_setup()
115        self.vm.add_args('-cpu', 'host,+xen-vapic')
116        self.kernel_params = (self.KERNEL_DEFAULT +
117                              ' xen_emul_unplug=ide-disks')
118        self.run_and_check()
119        exec_command_and_wait_for_pattern(self,
120                                'grep xen-pirq /proc/interrupts',
121                                'acpi')
122        wait_for_console_pattern(self, '#')
123        exec_command_and_wait_for_pattern(self,
124                                'grep PCI-MSI /proc/interrupts',
125                                'virtio0-output')
126
127    def test_kvm_xen_guest_novector(self):
128        self.common_vm_setup()
129        self.kernel_params = (self.KERNEL_DEFAULT +
130                              ' xen_emul_unplug=ide-disks' +
131                              ' xen_no_vector_callback')
132        self.run_and_check()
133        exec_command_and_wait_for_pattern(self,
134                                'grep xen-platform-pci /proc/interrupts',
135                                'fasteoi')
136
137    def test_kvm_xen_guest_novector_nomsi(self):
138        self.common_vm_setup()
139
140        self.kernel_params = (self.KERNEL_DEFAULT +
141                              ' xen_emul_unplug=ide-disks pci=nomsi' +
142                              ' xen_no_vector_callback')
143        self.run_and_check()
144        exec_command_and_wait_for_pattern(self,
145                                'grep xen-platform-pci /proc/interrupts',
146                                'IO-APIC')
147
148    def test_kvm_xen_guest_novector_noapic(self):
149        self.common_vm_setup()
150        self.kernel_params = (self.KERNEL_DEFAULT +
151                              ' xen_emul_unplug=ide-disks' +
152                              ' xen_no_vector_callback noapic')
153        self.run_and_check()
154        exec_command_and_wait_for_pattern(self,
155                                'grep xen-platform-pci /proc/interrupts',
156                                'XT-PIC')
157
158if __name__ == '__main__':
159    QemuSystemTest.main()
160