xref: /openbmc/qemu/tests/functional/test_virtio_gpu.py (revision b8ee011e40e4b83a32ea0e7dca24e1ab089f1e7f)
1239d08aaSThomas Huth#!/usr/bin/env python3
2239d08aaSThomas Huth#
3239d08aaSThomas Huth# virtio-gpu tests
4239d08aaSThomas Huth#
5239d08aaSThomas Huth# This work is licensed under the terms of the GNU GPL, version 2 or
6239d08aaSThomas Huth# later.  See the COPYING file in the top-level directory.
7239d08aaSThomas Huth
8239d08aaSThomas Huth
9239d08aaSThomas Huthfrom qemu_test import BUILD_DIR
10239d08aaSThomas Huthfrom qemu_test import QemuSystemTest, Asset
11239d08aaSThomas Huthfrom qemu_test import wait_for_console_pattern
12239d08aaSThomas Huthfrom qemu_test import exec_command_and_wait_for_pattern
13239d08aaSThomas Huthfrom qemu_test import is_readable_executable_file
14239d08aaSThomas Huth
15239d08aaSThomas Huthfrom qemu.utils import kvm_available
16239d08aaSThomas Huth
17239d08aaSThomas Huthimport os
18239d08aaSThomas Huthimport socket
19239d08aaSThomas Huthimport subprocess
20239d08aaSThomas Huth
21239d08aaSThomas Huth
22239d08aaSThomas Huthdef pick_default_vug_bin():
23239d08aaSThomas Huth    relative_path = "./contrib/vhost-user-gpu/vhost-user-gpu"
24239d08aaSThomas Huth    if is_readable_executable_file(relative_path):
25239d08aaSThomas Huth        return relative_path
26239d08aaSThomas Huth
27239d08aaSThomas Huth    bld_dir_path = os.path.join(BUILD_DIR, relative_path)
28239d08aaSThomas Huth    if is_readable_executable_file(bld_dir_path):
29239d08aaSThomas Huth        return bld_dir_path
30239d08aaSThomas Huth
31239d08aaSThomas Huth
32239d08aaSThomas Huthclass VirtioGPUx86(QemuSystemTest):
33239d08aaSThomas Huth
34239d08aaSThomas Huth    KERNEL_COMMAND_LINE = "printk.time=0 console=ttyS0 rdinit=/bin/bash"
35239d08aaSThomas Huth    ASSET_KERNEL = Asset(
36239d08aaSThomas Huth        ("https://archives.fedoraproject.org/pub/archive/fedora"
37239d08aaSThomas Huth         "/linux/releases/33/Everything/x86_64/os/images"
38239d08aaSThomas Huth         "/pxeboot/vmlinuz"),
39239d08aaSThomas Huth        '2dc5fb5cfe9ac278fa45640f3602d9b7a08cc189ed63fd9b162b07073e4df397')
40239d08aaSThomas Huth    ASSET_INITRD = Asset(
41239d08aaSThomas Huth        ("https://archives.fedoraproject.org/pub/archive/fedora"
42239d08aaSThomas Huth         "/linux/releases/33/Everything/x86_64/os/images"
43239d08aaSThomas Huth         "/pxeboot/initrd.img"),
44239d08aaSThomas Huth        'c49b97f893a5349e4883452178763e402bdc5caa8845b226a2d1329b5f356045')
45239d08aaSThomas Huth
46239d08aaSThomas Huth    def wait_for_console_pattern(self, success_message, vm=None):
47239d08aaSThomas Huth        wait_for_console_pattern(
48239d08aaSThomas Huth            self,
49239d08aaSThomas Huth            success_message,
50239d08aaSThomas Huth            failure_message="Kernel panic - not syncing",
51239d08aaSThomas Huth            vm=vm,
52239d08aaSThomas Huth        )
53239d08aaSThomas Huth
54239d08aaSThomas Huth    def test_virtio_vga_virgl(self):
55239d08aaSThomas Huth        # FIXME: should check presence of virtio, virgl etc
56239d08aaSThomas Huth        self.require_accelerator('kvm')
57239d08aaSThomas Huth
58239d08aaSThomas Huth        kernel_path = self.ASSET_KERNEL.fetch()
59239d08aaSThomas Huth        initrd_path = self.ASSET_INITRD.fetch()
60239d08aaSThomas Huth
61239d08aaSThomas Huth        self.vm.set_console()
62239d08aaSThomas Huth        self.vm.add_args("-cpu", "host")
63239d08aaSThomas Huth        self.vm.add_args("-m", "2G")
64239d08aaSThomas Huth        self.vm.add_args("-machine", "pc,accel=kvm")
65239d08aaSThomas Huth        self.vm.add_args("-device", "virtio-vga-gl")
66239d08aaSThomas Huth        self.vm.add_args("-display", "egl-headless")
67239d08aaSThomas Huth        self.vm.add_args(
68239d08aaSThomas Huth            "-kernel",
69239d08aaSThomas Huth            kernel_path,
70239d08aaSThomas Huth            "-initrd",
71239d08aaSThomas Huth            initrd_path,
72239d08aaSThomas Huth            "-append",
73239d08aaSThomas Huth            self.KERNEL_COMMAND_LINE,
74239d08aaSThomas Huth        )
75239d08aaSThomas Huth        try:
76239d08aaSThomas Huth            self.vm.launch()
77239d08aaSThomas Huth        except:
78239d08aaSThomas Huth            # TODO: probably fails because we are missing the VirGL features
79239d08aaSThomas Huth            self.skipTest("VirGL not enabled?")
80239d08aaSThomas Huth
81239d08aaSThomas Huth        self.wait_for_console_pattern("as init process")
82239d08aaSThomas Huth        exec_command_and_wait_for_pattern(
83*7699e37bSDaniel P. Berrangé            self, "/usr/sbin/modprobe virtio_gpu", "features: +virgl +edid"
84239d08aaSThomas Huth        )
85239d08aaSThomas Huth
86239d08aaSThomas Huth    def test_vhost_user_vga_virgl(self):
87239d08aaSThomas Huth        # FIXME: should check presence of vhost-user-gpu, virgl, memfd etc
88239d08aaSThomas Huth        self.require_accelerator('kvm')
89239d08aaSThomas Huth
90239d08aaSThomas Huth        vug = pick_default_vug_bin()
91239d08aaSThomas Huth        if not vug:
92239d08aaSThomas Huth            self.skipTest("Could not find vhost-user-gpu")
93239d08aaSThomas Huth
94239d08aaSThomas Huth        kernel_path = self.ASSET_KERNEL.fetch()
95239d08aaSThomas Huth        initrd_path = self.ASSET_INITRD.fetch()
96239d08aaSThomas Huth
97239d08aaSThomas Huth        # Create socketpair to connect proxy and remote processes
98239d08aaSThomas Huth        qemu_sock, vug_sock = socket.socketpair(
99239d08aaSThomas Huth            socket.AF_UNIX, socket.SOCK_STREAM
100239d08aaSThomas Huth        )
101239d08aaSThomas Huth        os.set_inheritable(qemu_sock.fileno(), True)
102239d08aaSThomas Huth        os.set_inheritable(vug_sock.fileno(), True)
103239d08aaSThomas Huth
104239d08aaSThomas Huth        self._vug_log_path = os.path.join(
105239d08aaSThomas Huth            self.logdir, "vhost-user-gpu.log"
106239d08aaSThomas Huth        )
107239d08aaSThomas Huth        self._vug_log_file = open(self._vug_log_path, "wb")
108239d08aaSThomas Huth        self.log.info('Complete vhost-user-gpu.log file can be '
109239d08aaSThomas Huth                      'found at %s', self._vug_log_path)
110239d08aaSThomas Huth
111239d08aaSThomas Huth        vugp = subprocess.Popen(
112239d08aaSThomas Huth            [vug, "--virgl", "--fd=%d" % vug_sock.fileno()],
113239d08aaSThomas Huth            stdin=subprocess.DEVNULL,
114239d08aaSThomas Huth            stdout=self._vug_log_file,
115239d08aaSThomas Huth            stderr=subprocess.STDOUT,
116239d08aaSThomas Huth            shell=False,
117239d08aaSThomas Huth            close_fds=False,
118239d08aaSThomas Huth        )
119239d08aaSThomas Huth
120239d08aaSThomas Huth        self.vm.set_console()
121239d08aaSThomas Huth        self.vm.add_args("-cpu", "host")
122239d08aaSThomas Huth        self.vm.add_args("-m", "2G")
123239d08aaSThomas Huth        self.vm.add_args("-object", "memory-backend-memfd,id=mem,size=2G")
124239d08aaSThomas Huth        self.vm.add_args("-machine", "pc,memory-backend=mem,accel=kvm")
125239d08aaSThomas Huth        self.vm.add_args("-chardev", "socket,id=vug,fd=%d" % qemu_sock.fileno())
126239d08aaSThomas Huth        self.vm.add_args("-device", "vhost-user-vga,chardev=vug")
127239d08aaSThomas Huth        self.vm.add_args("-display", "egl-headless")
128239d08aaSThomas Huth        self.vm.add_args(
129239d08aaSThomas Huth            "-kernel",
130239d08aaSThomas Huth            kernel_path,
131239d08aaSThomas Huth            "-initrd",
132239d08aaSThomas Huth            initrd_path,
133239d08aaSThomas Huth            "-append",
134239d08aaSThomas Huth            self.KERNEL_COMMAND_LINE,
135239d08aaSThomas Huth        )
136239d08aaSThomas Huth        try:
137239d08aaSThomas Huth            self.vm.launch()
138239d08aaSThomas Huth        except:
139239d08aaSThomas Huth            # TODO: probably fails because we are missing the VirGL features
140239d08aaSThomas Huth            self.skipTest("VirGL not enabled?")
141239d08aaSThomas Huth        self.wait_for_console_pattern("as init process")
142239d08aaSThomas Huth        exec_command_and_wait_for_pattern(self, "/usr/sbin/modprobe virtio_gpu",
143239d08aaSThomas Huth                                          "features: +virgl +edid")
144239d08aaSThomas Huth        self.vm.shutdown()
145239d08aaSThomas Huth        qemu_sock.close()
146239d08aaSThomas Huth        vugp.terminate()
147239d08aaSThomas Huth        vugp.wait()
148239d08aaSThomas Huth
149239d08aaSThomas Huthif __name__ == '__main__':
150239d08aaSThomas Huth    QemuSystemTest.main()
151