mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-24 04:12:20 +00:00
cpu_map: Add libcpuinfo as optional data source
This adds an option to use libcpuinfo [1] as data source for libvirt's list of x86 cpu features. This is purely optional and does not change the script's behavior if libcpuinfo is not installed. libcpuinfo is a cross-vendor, cross-architecture source for CPU related information that has the capability to replace libvirt's dependence on qemu's cpu feature list. [1] https://gitlab.com/twiederh/libcpuinfo Signed-off-by: Tim Wiederhake <twiederh@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
b3edf03c31
commit
a18b232712
75
src/cpu_map/libcpuinfo_aliases.xml
Normal file
75
src/cpu_map/libcpuinfo_aliases.xml
Normal file
@ -0,0 +1,75 @@
|
||||
<!--
|
||||
libvirt uses slightly different names for some cpu features than other
|
||||
software does. Install this file into libcpuinfo's alias directory
|
||||
(e.g. /usr/share/libcpuinfo/aliases/libvirt.xml) to have libcpuinfo
|
||||
automatically translate feature names into the names libvirt uses.
|
||||
-->
|
||||
|
||||
<external_aliases>
|
||||
<external_alias>
|
||||
<type>feature</type>
|
||||
<canonical>pclmulqdq</canonical>
|
||||
<name>pclmuldq</name>
|
||||
<domain>libvirt</domain>
|
||||
</external_alias>
|
||||
<external_alias>
|
||||
<type>feature</type>
|
||||
<canonical>ds-cpl</canonical>
|
||||
<name>ds_cpl</name>
|
||||
<domain>libvirt</domain>
|
||||
</external_alias>
|
||||
<external_alias>
|
||||
<type>feature</type>
|
||||
<canonical>sse4-1</canonical>
|
||||
<name>sse4.1</name>
|
||||
<domain>libvirt</domain>
|
||||
</external_alias>
|
||||
<external_alias>
|
||||
<type>feature</type>
|
||||
<canonical>sse4-2</canonical>
|
||||
<name>sse4.2</name>
|
||||
<domain>libvirt</domain>
|
||||
</external_alias>
|
||||
<external_alias>
|
||||
<type>feature</type>
|
||||
<canonical>tsc-adjust</canonical>
|
||||
<name>tsc_adjust</name>
|
||||
<domain>libvirt</domain>
|
||||
</external_alias>
|
||||
<external_alias>
|
||||
<type>feature</type>
|
||||
<canonical>lahf-lm</canonical>
|
||||
<name>lahf_lm</name>
|
||||
<domain>libvirt</domain>
|
||||
</external_alias>
|
||||
<external_alias>
|
||||
<type>feature</type>
|
||||
<canonical>cmp-legacy</canonical>
|
||||
<name>cmp_legacy</name>
|
||||
<domain>libvirt</domain>
|
||||
</external_alias>
|
||||
<external_alias>
|
||||
<type>feature</type>
|
||||
<canonical>nodeid-msr</canonical>
|
||||
<name>nodeid_msr</name>
|
||||
<domain>libvirt</domain>
|
||||
</external_alias>
|
||||
<external_alias>
|
||||
<type>feature</type>
|
||||
<canonical>perfctr-core</canonical>
|
||||
<name>perfctr_core</name>
|
||||
<domain>libvirt</domain>
|
||||
</external_alias>
|
||||
<external_alias>
|
||||
<type>feature</type>
|
||||
<canonical>perfctr-nb</canonical>
|
||||
<name>perfctr_nb</name>
|
||||
<domain>libvirt</domain>
|
||||
</external_alias>
|
||||
<external_alias>
|
||||
<type>feature</type>
|
||||
<canonical>fxsr-opt</canonical>
|
||||
<name>fxsr_opt</name>
|
||||
<domain>libvirt</domain>
|
||||
</external_alias>
|
||||
</external_aliases>
|
@ -4,6 +4,11 @@ import argparse
|
||||
import os
|
||||
import re
|
||||
|
||||
try:
|
||||
import pycpuinfo
|
||||
except ImportError:
|
||||
pycpuinfo = None
|
||||
|
||||
|
||||
# features in qemu that we do not want in libvirt
|
||||
FEATURES_IGNORE = (
|
||||
@ -23,6 +28,7 @@ FEATURES_IGNORE = (
|
||||
"kvm-steal-time",
|
||||
"kvmclock",
|
||||
"kvmclock-stable-bit",
|
||||
"kvmclock2",
|
||||
|
||||
"xstore",
|
||||
"xstore-en",
|
||||
@ -296,6 +302,53 @@ def add_feature_qemu(query, data):
|
||||
add_feature_cpuid(eax, ecx, reg, bit, name)
|
||||
|
||||
|
||||
def add_features_cpuinfo():
|
||||
def decode_bit(value):
|
||||
for i in range(0, 64):
|
||||
if value == (1 << i):
|
||||
return i
|
||||
|
||||
def decode_cpuid(v):
|
||||
if v[0] != 0 and v[1] == 0 and v[2] == 0 and v[3] == 0:
|
||||
reg, val = "eax", v[0]
|
||||
if v[0] == 0 and v[1] != 0 and v[2] == 0 and v[3] == 0:
|
||||
reg, val = "ebx", v[1]
|
||||
if v[0] == 0 and v[1] == 0 and v[2] != 0 and v[3] == 0:
|
||||
reg, val = "ecx", v[2]
|
||||
if v[0] == 0 and v[1] == 0 and v[2] == 0 and v[3] != 0:
|
||||
reg, val = "edx", v[3]
|
||||
|
||||
return reg, decode_bit(val)
|
||||
|
||||
x86 = pycpuinfo.Family.find("x86", "")
|
||||
|
||||
for feature in pycpuinfo.features():
|
||||
if feature.family() != x86:
|
||||
continue
|
||||
|
||||
if list(feature.features()):
|
||||
continue
|
||||
|
||||
name = feature.name("libvirt")
|
||||
if name in FEATURES_IGNORE:
|
||||
continue
|
||||
|
||||
cpuid = feature.extra_x86_cpuid()
|
||||
if cpuid:
|
||||
eax = cpuid[0]
|
||||
ecx = cpuid[1]
|
||||
if ecx == pycpuinfo.x86.CPUINFO_X86_CPUID_ECX_NONE:
|
||||
ecx = None
|
||||
reg, bit = decode_cpuid(cpuid[2:])
|
||||
add_feature_cpuid(eax, ecx, reg, bit, name)
|
||||
|
||||
msr = feature.extra_x86_msr()
|
||||
if msr:
|
||||
index = msr[0]
|
||||
bit = decode_bit(msr[1] | (msr[2] << 32))
|
||||
add_feature_msr(index, bit, name)
|
||||
|
||||
|
||||
# read the `feature_word_info` struct from qemu's cpu.c into a list of strings
|
||||
def read_cpu_c(path):
|
||||
pattern_comment = re.compile("/\\*.*?\\*/")
|
||||
@ -451,6 +504,12 @@ def main():
|
||||
nargs="?",
|
||||
type=os.path.realpath,
|
||||
)
|
||||
if pycpuinfo:
|
||||
parser.add_argument(
|
||||
"--libcpuinfo",
|
||||
help="Use libcpuinfo as data source instead",
|
||||
action="store_true",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output",
|
||||
"-o",
|
||||
@ -460,14 +519,18 @@ def main():
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if not os.path.isdir(args.qemu):
|
||||
parser.print_help()
|
||||
exit("qemu source directory not found")
|
||||
if pycpuinfo and args.libcpuinfo:
|
||||
add_features_cpuinfo()
|
||||
else:
|
||||
if not os.path.isdir(args.qemu):
|
||||
parser.print_help()
|
||||
exit("qemu source directory not found")
|
||||
|
||||
read_headers(args.qemu)
|
||||
lines = read_cpu_c(args.qemu)
|
||||
parse_feature_words(lines)
|
||||
add_extra_features()
|
||||
|
||||
read_headers(args.qemu)
|
||||
lines = read_cpu_c(args.qemu)
|
||||
parse_feature_words(lines)
|
||||
add_extra_features()
|
||||
write_output(args.output)
|
||||
|
||||
print(
|
||||
|
Loading…
x
Reference in New Issue
Block a user