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