mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-09 05:01:28 +00:00
cpu_x86: Disable TSX on broken models
All Intel Haswell processors (except Xeon E7 v3 with stepping >= 4) have TSX disabled by microcode update. As not all CPUs are guaranteed to be patched with microcode updates we need to explicitly disable TSX on affected CPUs to avoid its accidental usage. https://bugzilla.redhat.com/show_bug.cgi?id=1406791 Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
405affeb07
commit
d60012b4e7
@ -547,6 +547,26 @@ x86MakeSignature(unsigned int family,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
x86DataToSignatureFull(const virCPUx86Data *data,
|
||||||
|
unsigned int *family,
|
||||||
|
unsigned int *model,
|
||||||
|
unsigned int *stepping)
|
||||||
|
{
|
||||||
|
virCPUx86CPUID leaf1 = { .eax_in = 0x1 };
|
||||||
|
virCPUx86CPUID *cpuid;
|
||||||
|
|
||||||
|
*family = *model = *stepping = 0;
|
||||||
|
|
||||||
|
if (!(cpuid = x86DataCpuid(data, &leaf1)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
*family = ((cpuid->eax >> 20) & 0xff) + ((cpuid->eax >> 8) & 0xf);
|
||||||
|
*model = ((cpuid->eax >> 12) & 0xf0) + ((cpuid->eax >> 4) & 0xf);
|
||||||
|
*stepping = cpuid->eax & 0xf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Mask out irrelevant bits (R and Step) from processor signature. */
|
/* Mask out irrelevant bits (R and Step) from processor signature. */
|
||||||
#define SIGNATURE_MASK 0x0fff3ff0
|
#define SIGNATURE_MASK 0x0fff3ff0
|
||||||
|
|
||||||
@ -1784,9 +1804,44 @@ x86DecodeUseCandidate(virCPUx86ModelPtr current,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop broken TSX features.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
x86DataFilterTSX(virCPUx86Data *data,
|
||||||
|
virCPUx86VendorPtr vendor,
|
||||||
|
virCPUx86MapPtr map)
|
||||||
|
{
|
||||||
|
unsigned int family;
|
||||||
|
unsigned int model;
|
||||||
|
unsigned int stepping;
|
||||||
|
|
||||||
|
if (!vendor || STRNEQ(vendor->name, "Intel"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
x86DataToSignatureFull(data, &family, &model, &stepping);
|
||||||
|
|
||||||
|
if (family == 6 &&
|
||||||
|
((model == 63 && stepping < 4) ||
|
||||||
|
model == 60 ||
|
||||||
|
model == 69 ||
|
||||||
|
model == 70)) {
|
||||||
|
virCPUx86FeaturePtr feature;
|
||||||
|
|
||||||
|
VIR_DEBUG("Dropping broken TSX");
|
||||||
|
|
||||||
|
if ((feature = x86FeatureFind(map, "hle")))
|
||||||
|
x86DataSubtract(data, &feature->data);
|
||||||
|
|
||||||
|
if ((feature = x86FeatureFind(map, "rtm")))
|
||||||
|
x86DataSubtract(data, &feature->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
x86Decode(virCPUDefPtr cpu,
|
x86Decode(virCPUDefPtr cpu,
|
||||||
const virCPUx86Data *data,
|
const virCPUx86Data *cpuData,
|
||||||
const char **models,
|
const char **models,
|
||||||
unsigned int nmodels,
|
unsigned int nmodels,
|
||||||
const char *preferred,
|
const char *preferred,
|
||||||
@ -1798,6 +1853,7 @@ x86Decode(virCPUDefPtr cpu,
|
|||||||
virCPUDefPtr cpuCandidate;
|
virCPUDefPtr cpuCandidate;
|
||||||
virCPUx86ModelPtr model = NULL;
|
virCPUx86ModelPtr model = NULL;
|
||||||
virCPUDefPtr cpuModel = NULL;
|
virCPUDefPtr cpuModel = NULL;
|
||||||
|
virCPUx86Data data = VIR_CPU_X86_DATA_INIT;
|
||||||
virCPUx86Data copy = VIR_CPU_X86_DATA_INIT;
|
virCPUx86Data copy = VIR_CPU_X86_DATA_INIT;
|
||||||
virCPUx86Data features = VIR_CPU_X86_DATA_INIT;
|
virCPUx86Data features = VIR_CPU_X86_DATA_INIT;
|
||||||
virCPUx86VendorPtr vendor;
|
virCPUx86VendorPtr vendor;
|
||||||
@ -1808,11 +1864,16 @@ x86Decode(virCPUDefPtr cpu,
|
|||||||
virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES |
|
virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES |
|
||||||
VIR_CONNECT_BASELINE_CPU_MIGRATABLE, -1);
|
VIR_CONNECT_BASELINE_CPU_MIGRATABLE, -1);
|
||||||
|
|
||||||
if (!data || !(map = virCPUx86GetMap()))
|
if (!cpuData || x86DataCopy(&data, cpuData) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
vendor = x86DataToVendor(data, map);
|
if (!(map = virCPUx86GetMap()))
|
||||||
signature = x86DataToSignature(data);
|
goto cleanup;
|
||||||
|
|
||||||
|
vendor = x86DataToVendor(&data, map);
|
||||||
|
signature = x86DataToSignature(&data);
|
||||||
|
|
||||||
|
x86DataFilterTSX(&data, vendor, map);
|
||||||
|
|
||||||
/* Walk through the CPU models in reverse order to check newest
|
/* Walk through the CPU models in reverse order to check newest
|
||||||
* models first.
|
* models first.
|
||||||
@ -1847,7 +1908,7 @@ x86Decode(virCPUDefPtr cpu,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cpuCandidate = x86DataToCPU(data, candidate, map)))
|
if (!(cpuCandidate = x86DataToCPU(&data, candidate, map)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
cpuCandidate->type = cpu->type;
|
cpuCandidate->type = cpu->type;
|
||||||
|
|
||||||
@ -1912,6 +1973,7 @@ x86Decode(virCPUDefPtr cpu,
|
|||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
virCPUDefFree(cpuModel);
|
virCPUDefFree(cpuModel);
|
||||||
|
virCPUx86DataClear(&data);
|
||||||
virCPUx86DataClear(©);
|
virCPUx86DataClear(©);
|
||||||
virCPUx86DataClear(&features);
|
virCPUx86DataClear(&features);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<cpu mode='custom' match='exact'>
|
<cpu mode='custom' match='exact'>
|
||||||
<arch>x86_64</arch>
|
<arch>x86_64</arch>
|
||||||
<model fallback='forbid'>Haswell</model>
|
<model fallback='forbid'>Haswell-noTSX</model>
|
||||||
<vendor>Intel</vendor>
|
<vendor>Intel</vendor>
|
||||||
<feature policy='require' name='vme'/>
|
<feature policy='require' name='vme'/>
|
||||||
<feature policy='require' name='ds'/>
|
<feature policy='require' name='ds'/>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<cpu>
|
<cpu>
|
||||||
<arch>x86_64</arch>
|
<arch>x86_64</arch>
|
||||||
<model>Haswell</model>
|
<model>Haswell-noTSX</model>
|
||||||
<vendor>Intel</vendor>
|
<vendor>Intel</vendor>
|
||||||
<feature name='vme'/>
|
<feature name='vme'/>
|
||||||
<feature name='ds'/>
|
<feature name='ds'/>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<cpu mode='custom' match='exact'>
|
<cpu mode='custom' match='exact'>
|
||||||
<arch>x86_64</arch>
|
<arch>x86_64</arch>
|
||||||
<model fallback='forbid'>Haswell</model>
|
<model fallback='forbid'>Haswell-noTSX</model>
|
||||||
<vendor>Intel</vendor>
|
<vendor>Intel</vendor>
|
||||||
<feature policy='require' name='vme'/>
|
<feature policy='require' name='vme'/>
|
||||||
<feature policy='require' name='ss'/>
|
<feature policy='require' name='ss'/>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user