xref: /qemu/tests/functional/test_aarch64_tcg_plugins.py (revision 513823e7521a09ed7ad1e32e6454bac3b2cbf52d)
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