xref: /openbmc/qemu/python/qemu/utils/accel.py (revision 9516034d)
1beb6b57bSJohn Snow"""
2beb6b57bSJohn SnowQEMU accel module:
3beb6b57bSJohn Snow
4beb6b57bSJohn SnowThis module provides utilities for discover and check the availability of
5beb6b57bSJohn Snowaccelerators.
6beb6b57bSJohn Snow"""
7beb6b57bSJohn Snow# Copyright (C) 2015-2016 Red Hat Inc.
8beb6b57bSJohn Snow# Copyright (C) 2012 IBM Corp.
9beb6b57bSJohn Snow#
10beb6b57bSJohn Snow# Authors:
11beb6b57bSJohn Snow#  Fam Zheng <famz@redhat.com>
12beb6b57bSJohn Snow#
13beb6b57bSJohn Snow# This work is licensed under the terms of the GNU GPL, version 2.  See
14beb6b57bSJohn Snow# the COPYING file in the top-level directory.
15beb6b57bSJohn Snow#
16beb6b57bSJohn Snow
17beb6b57bSJohn Snowimport logging
18beb6b57bSJohn Snowimport os
19beb6b57bSJohn Snowimport subprocess
20beb6b57bSJohn Snowfrom typing import List, Optional
21beb6b57bSJohn Snow
22beb6b57bSJohn Snow
23beb6b57bSJohn SnowLOG = logging.getLogger(__name__)
24beb6b57bSJohn Snow
25beb6b57bSJohn Snow# Mapping host architecture to any additional architectures it can
26beb6b57bSJohn Snow# support which often includes its 32 bit cousin.
27beb6b57bSJohn SnowADDITIONAL_ARCHES = {
28beb6b57bSJohn Snow    "x86_64": "i386",
29beb6b57bSJohn Snow    "aarch64": "armhf",
30beb6b57bSJohn Snow    "ppc64le": "ppc64",
31beb6b57bSJohn Snow}
32beb6b57bSJohn Snow
33beb6b57bSJohn Snow
34beb6b57bSJohn Snowdef list_accel(qemu_bin: str) -> List[str]:
35beb6b57bSJohn Snow    """
36beb6b57bSJohn Snow    List accelerators enabled in the QEMU binary.
37beb6b57bSJohn Snow
38beb6b57bSJohn Snow    @param qemu_bin (str): path to the QEMU binary.
39*5c02c865SJohn Snow    @raise Exception: if failed to run ``qemu -accel help``
40beb6b57bSJohn Snow    @return a list of accelerator names.
41beb6b57bSJohn Snow    """
42beb6b57bSJohn Snow    if not qemu_bin:
43beb6b57bSJohn Snow        return []
44beb6b57bSJohn Snow    try:
45beb6b57bSJohn Snow        out = subprocess.check_output([qemu_bin, '-accel', 'help'],
46beb6b57bSJohn Snow                                      universal_newlines=True)
47beb6b57bSJohn Snow    except:
48beb6b57bSJohn Snow        LOG.debug("Failed to get the list of accelerators in %s", qemu_bin)
49beb6b57bSJohn Snow        raise
50beb6b57bSJohn Snow    # Skip the first line which is the header.
51beb6b57bSJohn Snow    return [acc.strip() for acc in out.splitlines()[1:]]
52beb6b57bSJohn Snow
53beb6b57bSJohn Snow
54beb6b57bSJohn Snowdef kvm_available(target_arch: Optional[str] = None,
55beb6b57bSJohn Snow                  qemu_bin: Optional[str] = None) -> bool:
56beb6b57bSJohn Snow    """
57beb6b57bSJohn Snow    Check if KVM is available using the following heuristic:
58beb6b57bSJohn Snow      - Kernel module is present in the host;
59beb6b57bSJohn Snow      - Target and host arches don't mismatch;
60beb6b57bSJohn Snow      - KVM is enabled in the QEMU binary.
61beb6b57bSJohn Snow
62beb6b57bSJohn Snow    @param target_arch (str): target architecture
63beb6b57bSJohn Snow    @param qemu_bin (str): path to the QEMU binary
64beb6b57bSJohn Snow    @return True if kvm is available, otherwise False.
65beb6b57bSJohn Snow    """
66beb6b57bSJohn Snow    if not os.access("/dev/kvm", os.R_OK | os.W_OK):
67beb6b57bSJohn Snow        return False
68beb6b57bSJohn Snow    if target_arch:
69beb6b57bSJohn Snow        host_arch = os.uname()[4]
70beb6b57bSJohn Snow        if target_arch != host_arch:
71beb6b57bSJohn Snow            if target_arch != ADDITIONAL_ARCHES.get(host_arch):
72beb6b57bSJohn Snow                return False
73beb6b57bSJohn Snow    if qemu_bin and "kvm" not in list_accel(qemu_bin):
74beb6b57bSJohn Snow        return False
75beb6b57bSJohn Snow    return True
76beb6b57bSJohn Snow
77beb6b57bSJohn Snow
78beb6b57bSJohn Snowdef tcg_available(qemu_bin: str) -> bool:
79beb6b57bSJohn Snow    """
80beb6b57bSJohn Snow    Check if TCG is available.
81beb6b57bSJohn Snow
82beb6b57bSJohn Snow    @param qemu_bin (str): path to the QEMU binary
83beb6b57bSJohn Snow    """
84beb6b57bSJohn Snow    return 'tcg' in list_accel(qemu_bin)
85