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