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.machine.machine import VMLaunchFailure 19from qemu_test import LinuxKernelTest, Asset 20 21 22class PluginKernelBase(LinuxKernelTest): 23 """ 24 Boots a Linux kernel with a TCG plugin enabled. 25 """ 26 27 timeout = 120 28 KERNEL_COMMON_COMMAND_LINE = 'printk.time=1 panic=-1 ' 29 30 def run_vm(self, kernel_path, kernel_command_line, 31 plugin, plugin_log, console_pattern, args=None): 32 33 vm = self.get_vm() 34 vm.set_console() 35 vm.add_args('-kernel', kernel_path, 36 '-append', kernel_command_line, 37 '-plugin', plugin, 38 '-d', 'plugin', 39 '-D', plugin_log, 40 '-net', 'none', 41 '-no-reboot') 42 if args: 43 vm.add_args(*args) 44 45 try: 46 vm.launch() 47 except VMLaunchFailure as excp: 48 if "plugin interface not enabled in this build" in excp.output: 49 self.skipTest("TCG plugins not enabled") 50 else: 51 self.log.info(f"unhandled launch failure: {excp.output}") 52 raise excp 53 54 self.wait_for_console_pattern(console_pattern, vm) 55 # ensure logs are flushed 56 vm.shutdown() 57 58 59class PluginKernelNormal(PluginKernelBase): 60 61 ASSET_KERNEL = Asset( 62 ('https://storage.tuxboot.com/20230331/arm64/Image'), 63 'ce95a7101a5fecebe0fe630deee6bd97b32ba41bc8754090e9ad8961ea8674c7') 64 65 def test_aarch64_virt_insn(self): 66 self.set_machine('virt') 67 self.cpu='cortex-a53' 68 kernel_path = self.ASSET_KERNEL.fetch() 69 kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + 70 'console=ttyAMA0') 71 console_pattern = 'Please append a correct "root=" boot option' 72 73 plugin_log = tempfile.NamedTemporaryFile(mode="r+t", prefix="plugin", 74 suffix=".log") 75 76 self.run_vm(kernel_path, kernel_command_line, 77 "tests/tcg/plugins/libinsn.so", plugin_log.name, 78 console_pattern) 79 80 with plugin_log as lf, \ 81 mmap.mmap(lf.fileno(), 0, access=mmap.ACCESS_READ) as s: 82 83 m = re.search(br"insns: (?P<count>\d+)", s) 84 if "count" not in m.groupdict(): 85 self.fail("Failed to find instruction count") 86 else: 87 count = int(m.group("count")) 88 self.log.info(f"Counted: {count} instructions") 89 90 91 def test_aarch64_virt_insn_icount(self): 92 self.set_machine('virt') 93 self.cpu='cortex-a53' 94 kernel_path = self.ASSET_KERNEL.fetch() 95 kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + 96 'console=ttyAMA0') 97 console_pattern = 'Please append a correct "root=" boot option' 98 99 plugin_log = tempfile.NamedTemporaryFile(mode="r+t", prefix="plugin", 100 suffix=".log") 101 102 self.run_vm(kernel_path, kernel_command_line, 103 "tests/tcg/plugins/libinsn.so", plugin_log.name, 104 console_pattern, 105 args=('-icount', 'shift=1')) 106 107 with plugin_log as lf, \ 108 mmap.mmap(lf.fileno(), 0, access=mmap.ACCESS_READ) as s: 109 110 m = re.search(br"insns: (?P<count>\d+)", s) 111 if "count" not in m.groupdict(): 112 self.fail("Failed to find instruction count") 113 else: 114 count = int(m.group("count")) 115 self.log.info(f"Counted: {count} instructions") 116 117if __name__ == '__main__': 118 LinuxKernelTest.main() 119