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