qemu: Parse CPU stepping from query-cpu-model-expansion

Even though only family and model are used for matching CPUID data with
CPU models from cpu_map.xml, stepping is used by x86DataFilterTSX which
is supposed to disable TSX on CPU models with broken TSX support. Thus
we need to start parsing stepping from QEMU to make sure we don't
disable TSX on CPUs which provide working TSX implementation. See the
following patch for a real world example of such CPU.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
Jiri Denemark 2017-10-10 13:34:28 +02:00
parent 921d61575d
commit c1a63a5f7b
3 changed files with 15 additions and 9 deletions

View File

@ -531,7 +531,8 @@ virCPUx86VendorToCPUID(const char *vendor,
static uint32_t static uint32_t
x86MakeSignature(unsigned int family, x86MakeSignature(unsigned int family,
unsigned int model) unsigned int model,
unsigned int stepping)
{ {
uint32_t sig = 0; uint32_t sig = 0;
@ -551,6 +552,7 @@ x86MakeSignature(unsigned int family,
* *
* family = eax[27:20] + eax[11:8] * family = eax[27:20] + eax[11:8]
* model = eax[19:16] << 4 + eax[7:4] * model = eax[19:16] << 4 + eax[7:4]
* stepping = eax[3:0]
*/ */
/* extFam */ /* extFam */
@ -570,9 +572,8 @@ x86MakeSignature(unsigned int family,
/* Mod */ /* Mod */
sig |= (model & 0xf) << 4; sig |= (model & 0xf) << 4;
/* Step is irrelevant, it is used to distinguish different revisions /* Step */
* of the same CPU model sig |= stepping & 0xf;
*/
return sig; return sig;
} }
@ -1248,7 +1249,7 @@ x86ModelParse(xmlXPathContextPtr ctxt,
goto cleanup; goto cleanup;
} }
model->signature = x86MakeSignature(sigFamily, sigModel); model->signature = x86MakeSignature(sigFamily, sigModel, 0);
} }
if (virXPathBoolean("boolean(./vendor)", ctxt)) { if (virXPathBoolean("boolean(./vendor)", ctxt)) {
@ -2971,9 +2972,10 @@ virCPUx86DataAddCPUID(virCPUDataPtr cpuData,
int int
virCPUx86DataSetSignature(virCPUDataPtr cpuData, virCPUx86DataSetSignature(virCPUDataPtr cpuData,
unsigned int family, unsigned int family,
unsigned int model) unsigned int model,
unsigned int stepping)
{ {
uint32_t signature = x86MakeSignature(family, model); uint32_t signature = x86MakeSignature(family, model, stepping);
return x86DataAddSignature(&cpuData->data.x86, signature); return x86DataAddSignature(&cpuData->data.x86, signature);
} }

View File

@ -34,7 +34,8 @@ int virCPUx86DataAddCPUID(virCPUDataPtr cpuData,
int virCPUx86DataSetSignature(virCPUDataPtr cpuData, int virCPUx86DataSetSignature(virCPUDataPtr cpuData,
unsigned int family, unsigned int family,
unsigned int model); unsigned int model,
unsigned int stepping);
int virCPUx86DataSetVendor(virCPUDataPtr cpuData, int virCPUx86DataSetVendor(virCPUDataPtr cpuData,
const char *vendor); const char *vendor);

View File

@ -3353,6 +3353,7 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
virCPUDataPtr data = NULL; virCPUDataPtr data = NULL;
unsigned long long sigFamily = 0; unsigned long long sigFamily = 0;
unsigned long long sigModel = 0; unsigned long long sigModel = 0;
unsigned long long sigStepping = 0;
int ret = -1; int ret = -1;
size_t i; size_t i;
@ -3387,6 +3388,8 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
sigFamily = prop->value.number; sigFamily = prop->value.number;
else if (STREQ(prop->name, "model")) else if (STREQ(prop->name, "model"))
sigModel = prop->value.number; sigModel = prop->value.number;
else if (STREQ(prop->name, "stepping"))
sigStepping = prop->value.number;
break; break;
case QEMU_MONITOR_CPU_PROPERTY_LAST: case QEMU_MONITOR_CPU_PROPERTY_LAST:
@ -3394,7 +3397,7 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
} }
} }
if (virCPUx86DataSetSignature(data, sigFamily, sigModel) < 0) if (virCPUx86DataSetSignature(data, sigFamily, sigModel, sigStepping) < 0)
goto cleanup; goto cleanup;
if (cpuDecode(cpu, data, virQEMUCapsGetCPUDefinitions(qemuCaps, type)) < 0) if (cpuDecode(cpu, data, virQEMUCapsGetCPUDefinitions(qemuCaps, type)) < 0)