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