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