xref: /qemu/tests/functional/test_x86_64_kvm_xen.py (revision 513823e7521a09ed7ad1e32e6454bac3b2cbf52d)
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