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