1#!/usr/bin/env python3 2# 3# TCG Plugins tests 4# 5# These are a little more involved than the basic tests run by check-tcg. 6# 7# Copyright (c) 2021 Linaro 8# 9# Author: 10# Alex Bennée <alex.bennee@linaro.org> 11# 12# SPDX-License-Identifier: GPL-2.0-or-later 13 14import tempfile 15import mmap 16import re 17 18from qemu_test import LinuxKernelTest, Asset 19 20 21class PluginKernelBase(LinuxKernelTest): 22 """ 23 Boots a Linux kernel with a TCG plugin enabled. 24 """ 25 26 timeout = 120 27 KERNEL_COMMON_COMMAND_LINE = 'printk.time=1 panic=-1 ' 28 29 def run_vm(self, kernel_path, kernel_command_line, 30 plugin, plugin_log, console_pattern, args=None): 31 32 vm = self.get_vm() 33 vm.set_console() 34 vm.add_args('-kernel', kernel_path, 35 '-append', kernel_command_line, 36 '-plugin', plugin, 37 '-d', 'plugin', 38 '-D', plugin_log, 39 '-net', 'none', 40 '-no-reboot') 41 if args: 42 vm.add_args(*args) 43 44 try: 45 vm.launch() 46 except: 47 # TODO: probably fails because plugins not enabled but we 48 # can't currently probe for the feature. 49 self.cancel("TCG Plugins not enabled?") 50 51 self.wait_for_console_pattern(console_pattern, vm) 52 # ensure logs are flushed 53 vm.shutdown() 54 55 56class PluginKernelNormal(PluginKernelBase): 57 58 ASSET_KERNEL = Asset( 59 ('https://storage.tuxboot.com/20230331/arm64/Image'), 60 'ce95a7101a5fecebe0fe630deee6bd97b32ba41bc8754090e9ad8961ea8674c7') 61 62 def test_aarch64_virt_insn(self): 63 self.set_machine('virt') 64 self.cpu='cortex-a53' 65 kernel_path = self.ASSET_KERNEL.fetch() 66 kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + 67 'console=ttyAMA0') 68 console_pattern = 'Kernel panic - not syncing: VFS:' 69 70 plugin_log = tempfile.NamedTemporaryFile(mode="r+t", prefix="plugin", 71 suffix=".log") 72 73 self.run_vm(kernel_path, kernel_command_line, 74 "tests/tcg/plugins/libinsn.so", plugin_log.name, 75 console_pattern) 76 77 with plugin_log as lf, \ 78 mmap.mmap(lf.fileno(), 0, access=mmap.ACCESS_READ) as s: 79 80 m = re.search(br"insns: (?P<count>\d+)", s) 81 if "count" not in m.groupdict(): 82 self.fail("Failed to find instruction count") 83 else: 84 count = int(m.group("count")) 85 self.log.info(f"Counted: {count} instructions") 86 87 88 def test_aarch64_virt_insn_icount(self): 89 self.set_machine('virt') 90 self.cpu='cortex-a53' 91 kernel_path = self.ASSET_KERNEL.fetch() 92 kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + 93 'console=ttyAMA0') 94 console_pattern = 'Kernel panic - not syncing: VFS:' 95 96 plugin_log = tempfile.NamedTemporaryFile(mode="r+t", prefix="plugin", 97 suffix=".log") 98 99 self.run_vm(kernel_path, kernel_command_line, 100 "tests/tcg/plugins/libinsn.so", plugin_log.name, 101 console_pattern, 102 args=('-icount', 'shift=1')) 103 104 with plugin_log as lf, \ 105 mmap.mmap(lf.fileno(), 0, access=mmap.ACCESS_READ) as s: 106 107 m = re.search(br"insns: (?P<count>\d+)", s) 108 if "count" not in m.groupdict(): 109 self.fail("Failed to find instruction count") 110 else: 111 count = int(m.group("count")) 112 self.log.info(f"Counted: {count} instructions") 113 114if __name__ == '__main__': 115 LinuxKernelTest.main() 116