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