xref: /qemu/tests/functional/test_virtio_gpu.py (revision f9ba56a03c2e954c37737826203574a8cde0b3e3)
1#!/usr/bin/env python3
2#
3# virtio-gpu tests
4#
5# This work is licensed under the terms of the GNU GPL, version 2 or
6# later.  See the COPYING file in the top-level directory.
7
8
9from qemu_test import QemuSystemTest, Asset
10from qemu_test import wait_for_console_pattern
11from qemu_test import exec_command_and_wait_for_pattern
12from qemu_test import is_readable_executable_file
13
14
15import os
16import socket
17import subprocess
18
19
20def pick_default_vug_bin(test):
21    bld_dir_path = test.build_file("contrib", "vhost-user-gpu", "vhost-user-gpu")
22    if is_readable_executable_file(bld_dir_path):
23        return bld_dir_path
24
25
26class VirtioGPUx86(QemuSystemTest):
27
28    KERNEL_COMMAND_LINE = "printk.time=0 console=ttyS0 rdinit=/bin/bash"
29    ASSET_KERNEL = Asset(
30        ("https://archives.fedoraproject.org/pub/archive/fedora"
31         "/linux/releases/33/Everything/x86_64/os/images"
32         "/pxeboot/vmlinuz"),
33        '2dc5fb5cfe9ac278fa45640f3602d9b7a08cc189ed63fd9b162b07073e4df397')
34    ASSET_INITRD = Asset(
35        ("https://archives.fedoraproject.org/pub/archive/fedora"
36         "/linux/releases/33/Everything/x86_64/os/images"
37         "/pxeboot/initrd.img"),
38        'c49b97f893a5349e4883452178763e402bdc5caa8845b226a2d1329b5f356045')
39
40    def wait_for_console_pattern(self, success_message, vm=None):
41        wait_for_console_pattern(
42            self,
43            success_message,
44            failure_message="Kernel panic - not syncing",
45            vm=vm,
46        )
47
48    def test_virtio_vga_virgl(self):
49        # FIXME: should check presence of virtio, virgl etc
50        self.require_accelerator('kvm')
51
52        kernel_path = self.ASSET_KERNEL.fetch()
53        initrd_path = self.ASSET_INITRD.fetch()
54
55        self.vm.set_console()
56        self.vm.add_args("-cpu", "host")
57        self.vm.add_args("-m", "2G")
58        self.vm.add_args("-machine", "pc,accel=kvm")
59        self.vm.add_args("-device", "virtio-vga-gl")
60        self.vm.add_args("-display", "egl-headless")
61        self.vm.add_args(
62            "-kernel",
63            kernel_path,
64            "-initrd",
65            initrd_path,
66            "-append",
67            self.KERNEL_COMMAND_LINE,
68        )
69        try:
70            self.vm.launch()
71        except:
72            # TODO: probably fails because we are missing the VirGL features
73            self.skipTest("VirGL not enabled?")
74
75        self.wait_for_console_pattern("as init process")
76        exec_command_and_wait_for_pattern(
77            self, "/usr/sbin/modprobe virtio_gpu", "features: +virgl +edid"
78        )
79
80    def test_vhost_user_vga_virgl(self):
81        # FIXME: should check presence of vhost-user-gpu, virgl, memfd etc
82        self.require_accelerator('kvm')
83
84        vug = pick_default_vug_bin(self)
85        if not vug:
86            self.skipTest("Could not find vhost-user-gpu")
87
88        kernel_path = self.ASSET_KERNEL.fetch()
89        initrd_path = self.ASSET_INITRD.fetch()
90
91        # Create socketpair to connect proxy and remote processes
92        qemu_sock, vug_sock = socket.socketpair(
93            socket.AF_UNIX, socket.SOCK_STREAM
94        )
95        os.set_inheritable(qemu_sock.fileno(), True)
96        os.set_inheritable(vug_sock.fileno(), True)
97
98        self._vug_log_path = self.log_file("vhost-user-gpu.log")
99        self._vug_log_file = open(self._vug_log_path, "wb")
100        self.log.info('Complete vhost-user-gpu.log file can be '
101                      'found at %s', self._vug_log_path)
102
103        vugp = subprocess.Popen(
104            [vug, "--virgl", "--fd=%d" % vug_sock.fileno()],
105            stdin=subprocess.DEVNULL,
106            stdout=self._vug_log_file,
107            stderr=subprocess.STDOUT,
108            shell=False,
109            close_fds=False,
110        )
111
112        self.vm.set_console()
113        self.vm.add_args("-cpu", "host")
114        self.vm.add_args("-m", "2G")
115        self.vm.add_args("-object", "memory-backend-memfd,id=mem,size=2G")
116        self.vm.add_args("-machine", "pc,memory-backend=mem,accel=kvm")
117        self.vm.add_args("-chardev", "socket,id=vug,fd=%d" % qemu_sock.fileno())
118        self.vm.add_args("-device", "vhost-user-vga,chardev=vug")
119        self.vm.add_args("-display", "egl-headless")
120        self.vm.add_args(
121            "-kernel",
122            kernel_path,
123            "-initrd",
124            initrd_path,
125            "-append",
126            self.KERNEL_COMMAND_LINE,
127        )
128        try:
129            self.vm.launch()
130        except:
131            # TODO: probably fails because we are missing the VirGL features
132            self.skipTest("VirGL not enabled?")
133        self.wait_for_console_pattern("as init process")
134        exec_command_and_wait_for_pattern(self, "/usr/sbin/modprobe virtio_gpu",
135                                          "features: +virgl +edid")
136        self.vm.shutdown()
137        qemu_sock.close()
138        vugp.terminate()
139        vugp.wait()
140
141if __name__ == '__main__':
142    QemuSystemTest.main()
143