提交 64f5236f 编写于 作者: E Eduardo Habkost 提交者: Lucas Meneghel Rodrigues

test case to compare full CPUID dump for unexpected ABI changes

This adds a new test function to the cpuid.py test module, where the
CPUID data exposed by QEMU is compared with a full CPUID dump extracted
previously.

The new test code ensures that there are no ABI changes for a given
machine-type + CPU model combination, between QEMU versions.

The reference dumps were generated using the build-qemu-and-dump-cpus,
and copied using the copy-ref-dumps script.

There are some known QEMU bugs and past ABI changes that require
ignoring some differences. Those cases handled as rules that set
ignore_cpuid_leaves on qemu_cpu.cfg.
Signed-off-by: NEduardo Habkost <ehabkost@redhat.com>
上级 1987da58
......@@ -117,6 +117,139 @@
# 486 is excluded due to not supporting cpuid
no 486
variants:
- full_dump:
# machine types:
# parameter is named "machine_type_to_check" because
# somehow "machine_type" is being overwritten by another
# config file section somewhere
variants:
- machine.rhel:
only (qemu_flavor = rhel)
variants:
- rhel600:
machine_type_to_check = "rhel6.0.0"
- rhel610:
machine_type_to_check = "rhel6.1.0"
- rhel620:
machine_type_to_check = "rhel6.2.0"
- rhel630:
machine_type_to_check = "rhel6.3.0"
- rhel640:
machine_type_to_check = "rhel6.4.0"
- machine.upstream:
only (qemu_flavor = upstream)
variants:
- pc_1_0:
machine_type_to_check = "pc-1.0"
- pc_1_1:
machine_type_to_check = "pc-1.1"
- pc_1_2:
machine_type_to_check = "pc-1.2"
- pc_1_3:
machine_type_to_check = "pc-1.3"
- pc_q35_1_4:
machine_type_to_check = "pc-q35-1.4"
- pc_i440fx_1_4:
machine_type_to_check = "pc-i440fx-1.4"
- pc_q35_1_5:
machine_type_to_check = "pc-q35-1.5"
- pc_i440fx_1_5:
machine_type_to_check = "pc-i440fx-1.5"
test_type = "check_cpuid_dump"
no cpu.unset
#FEATURE: Ignore vendor string on KVM because it depends on host
# CPU vendor:
kvm:
ignore_cpuid_leaves += " 0,0,ebx 0,0,ecx 0,0,edx"
#KNOWN BUG: Processor Extended State leaf depends on host,
# currently:
ignore_cpuid_leaves += " 0xd,0"
#KNOWN BUG: ignore brand string on those CPU models because
# they change depending on QEMU version:
cpu.intel.qemu32:
ignore_cpuid_leaves += " 0x80000002 0x80000003 0x80000004"
cpu.amd.qemu64:
ignore_cpuid_leaves += " 0x80000002 0x80000003 0x80000004"
cpu.amd.athlon:
ignore_cpuid_leaves += " 0x80000002 0x80000003 0x80000004"
#FIXED BUG: QEMU v1.1 and older have unstable host-dependent
# data on the KVM leaf, so we will ignore it by now:
machine.upstream.pc_1_0:
ignore_cpuid_leaves += " 0x40000001,0x00,eax"
machine.upstream.pc_1_1:
ignore_cpuid_leaves += " 0x40000001,0x00,eax"
#FIXED BUG: QEMU v1.0 had broken feature aliases on
# 0x80000001.EDX, so ignore it:
machine.upstream.pc_1_0:
cpu.intel:
ignore_cpuid_leaves += " 0x80000001,0x00,edx"
#KNOWN BUG: the PMU CPUID leaf is unstable on QEMU 1.5 and
# older, so ignore it:
# (to be fixed on QEMU 1.6.0)
ignore_cpuid_leaves += " 0xA"
#KNOWN BUG: PCLMULQDQ compatibility on pc-1.4 and older is
# known to be broken since v1.5.0, as the bit was enabled
# without machine-type compatibility code
# (see commit 41cb383f42d0cb51d8e3e25e3ecebc954dd4196f)
cpu.intel.Westmere:
machine.upstream.pc_i440fx_1_4:
ignore_cpuid_leaves += " 1,0,ecx,1"
machine.upstream.pc_q35_1_4:
ignore_cpuid_leaves += " 1,0,ecx,1"
machine.upstream.pc_1_3:
ignore_cpuid_leaves += " 1,0,ecx,1"
machine.upstream.pc_1_2:
ignore_cpuid_leaves += " 1,0,ecx,1"
machine.upstream.pc_1_1:
ignore_cpuid_leaves += " 1,0,ecx,1"
machine.upstream.pc_1_0:
ignore_cpuid_leaves += " 1,0,ecx,1"
# CPU models without the "apic" feature can't boot
# using RHEL-6 Seabios
machine.rhel:
no cpu.intel.pentium, cpu.intel.pentium2, cpu.intel.pentium3
# known RHEL-6 ABI breakage bugs:
machine.rhel:
# Max physical address depends on host:
ignore_cpuid_leaves += " 0x80000008,0,eax"
# KVM features depend on host kernel, as well:
ignore_cpuid_leaves += " 0x40000001,0,eax"
# SEP bit depended on host kernel on 6.3 and older:
machine.rhel.rhel630:
ignore_cpuid_leaves += " 1,0,edx,11"
machine.rhel.rhel620:
ignore_cpuid_leaves += " 1,0,edx,11"
machine.rhel.rhel610:
ignore_cpuid_leaves += " 1,0,edx,11"
machine.rhel.rhel600:
ignore_cpuid_leaves += " 1,0,edx,11"
# unsupported-bits behavior changed between some RHEL-6
# versions, and 0xC0000000 looks different now:
machine.rhel:
ignore_cpuid_leaves += " 0xc0000000,0x0"
# RHEL-6.0 QEMU had broken feature aliases on
# 0x80000001.EDX, so ignore it:
machine.rhel.rhel600:
cpu.intel:
ignore_cpuid_leaves += " 0x80000001,0x00,edx"
# bz#819562: broken passthrough mode of CPUID leaf 7
machine.rhel.rhel620:
ignore_cpuid_leaves += " 7,0"
- default.vendor:
test_type = "default_vendor"
kvm:
......
......@@ -4,7 +4,7 @@ Group of cpuid tests for X86 CPU
import re, sys, os, string
from autotest.client.shared import error, utils
from autotest.client.shared import test as test_module
from virttest import utils_misc, env_process
from virttest import utils_misc, env_process, virt_vm
import logging
logger = logging.getLogger(__name__)
......@@ -480,6 +480,73 @@ def run_cpuid(test, params, env):
if (has_error is False) and (xfail is True):
raise error.TestFail("Test was expected to fail, but it didn't")
def check_cpuid_dump(self):
"""
Compare full CPUID dump data
"""
machine_type = params.get("machine_type_to_check","")
kvm_enabled = params.get("enable_kvm", "yes") == "yes"
ignore_cpuid_leaves = params.get("ignore_cpuid_leaves", "")
ignore_cpuid_leaves = ignore_cpuid_leaves.split()
whitelist = []
for l in ignore_cpuid_leaves:
l = l.split(',')
# syntax of ignore_cpuid_leaves:
# <in_eax>[,<in_ecx>[,<register>[ ,<bit>]]] ...
for i in 0,1,3: # integer fields:
if len(l) > i:
l[i] = int(l[i], 0)
whitelist.append(tuple(l))
if not machine_type:
raise error.TestNAError("No machine_type_to_check defined")
ref_file = os.path.join(test.virtdir, "deps",
"cpuid_dumps",
kvm_enabled and "kvm" or "nokvm",
machine_type, '%s-dump.txt' % (cpu_model))
if not os.path.exists(ref_file):
raise error.TestNAError("no cpuid dump file: %s" % (ref_file))
reference = open(ref_file, 'r').read()
if not reference:
raise error.TestNAError("no cpuid dump data on file: %s" % (ref_file))
reference = parse_cpuid_dump(reference)
if reference is None:
raise error.TestNAError("couldn't parse reference cpuid dump from file; %s" % (ref_file))
try:
out = get_guest_cpuid(self, cpu_model, 'enforce',
extra_params=dict(machine_type=machine_type, smp=1))
except virt_vm.VMCreateError,e:
if "host doesn't support requested feature:" in e.output \
or ("host cpuid" in e.output and \
"lacks requested flag" in e.output):
raise error.TestNAError("Can't run CPU model %s on this host" % (cpu_model))
else:
raise
dbg('ref_file: %r', ref_file)
dbg('ref: %r', reference)
dbg('out: %r', out)
ok = True
for k in reference.keys():
in_eax,in_ecx = k
if k not in out:
info("Missing CPUID data from output: CPUID[0x%x,0x%x]", in_eax, in_ecx)
ok = False
continue
diffs = compare_cpuid_output(reference[k], out[k])
for d in diffs:
reg, bit, vreference, vout =d
whitelisted = (in_eax,) in whitelist \
or (in_eax, in_ecx) in whitelist \
or (in_eax, in_ecx, reg) in whitelist \
or (in_eax, in_ecx, reg, bit) in whitelist
info("Non-matching bit: CPUID[0x%x,0x%x].%s[%d]: found %s instead of %s%s",
in_eax, in_ecx, reg, bit, vout, vreference,
whitelisted and " (whitelisted)" or "")
if not whitelisted:
ok = False
if not ok:
raise error.TestFail("Unexpected CPUID data")
# subtests runner
test_type = params["test_type"]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册