mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
cpu_x86: Replace 32b signatures in virCPUx86Model with a struct
The CPU models in our cpu_map define their signatures using separate family and model numbers. Let's store the signatures in the same way in our runtime representation of the cpu_map. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
3b474c1f8f
commit
22bded201f
@ -121,6 +121,19 @@ static virCPUx86Feature x86_kvm_features[] =
|
|||||||
KVM_FEATURE(VIR_CPU_x86_HV_STIMER_DIRECT),
|
KVM_FEATURE(VIR_CPU_x86_HV_STIMER_DIRECT),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _virCPUx86Signature virCPUx86Signature;
|
||||||
|
struct _virCPUx86Signature {
|
||||||
|
unsigned int family;
|
||||||
|
unsigned int model;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _virCPUx86Signatures virCPUx86Signatures;
|
||||||
|
typedef virCPUx86Signatures *virCPUx86SignaturesPtr;
|
||||||
|
struct _virCPUx86Signatures {
|
||||||
|
size_t count;
|
||||||
|
virCPUx86Signature *items;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct _virCPUx86Model virCPUx86Model;
|
typedef struct _virCPUx86Model virCPUx86Model;
|
||||||
typedef virCPUx86Model *virCPUx86ModelPtr;
|
typedef virCPUx86Model *virCPUx86ModelPtr;
|
||||||
struct _virCPUx86Model {
|
struct _virCPUx86Model {
|
||||||
@ -128,8 +141,7 @@ struct _virCPUx86Model {
|
|||||||
bool decodeHost;
|
bool decodeHost;
|
||||||
bool decodeGuest;
|
bool decodeGuest;
|
||||||
virCPUx86VendorPtr vendor;
|
virCPUx86VendorPtr vendor;
|
||||||
size_t nsignatures;
|
virCPUx86SignaturesPtr signatures;
|
||||||
uint32_t *signatures;
|
|
||||||
virCPUx86Data data;
|
virCPUx86Data data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -717,6 +729,13 @@ x86MakeSignature(unsigned int family,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
virCPUx86SignatureToCPUID(virCPUx86Signature *sig)
|
||||||
|
{
|
||||||
|
return x86MakeSignature(sig->family, sig->model, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
virCPUx86SignatureFromCPUID(uint32_t sig,
|
virCPUx86SignatureFromCPUID(uint32_t sig,
|
||||||
unsigned int *family,
|
unsigned int *family,
|
||||||
@ -1099,41 +1118,65 @@ x86FeatureParse(xmlXPathContextPtr ctxt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static virCPUx86SignaturesPtr
|
||||||
virCPUx86SignaturesFree(uint32_t *signatures)
|
virCPUx86SignaturesNew(size_t count)
|
||||||
{
|
{
|
||||||
g_free(signatures);
|
virCPUx86SignaturesPtr sigs;
|
||||||
|
|
||||||
|
sigs = g_new0(virCPUx86Signatures, 1);
|
||||||
|
sigs->items = g_new0(virCPUx86Signature, count);
|
||||||
|
sigs->count = count;
|
||||||
|
|
||||||
|
return sigs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static void
|
||||||
virCPUx86SignaturesCopy(virCPUx86ModelPtr dst,
|
virCPUx86SignaturesFree(virCPUx86SignaturesPtr sigs)
|
||||||
virCPUx86ModelPtr src)
|
|
||||||
{
|
{
|
||||||
|
if (!sigs)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_free(sigs->items);
|
||||||
|
g_free(sigs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static virCPUx86SignaturesPtr
|
||||||
|
virCPUx86SignaturesCopy(virCPUx86SignaturesPtr src)
|
||||||
|
{
|
||||||
|
virCPUx86SignaturesPtr dst;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (src->nsignatures == 0)
|
if (!src || src->count == 0)
|
||||||
return 0;
|
return NULL;
|
||||||
|
|
||||||
if (VIR_ALLOC_N(dst->signatures, src->nsignatures) < 0)
|
dst = virCPUx86SignaturesNew(src->count);
|
||||||
return -1;
|
|
||||||
|
|
||||||
dst->nsignatures = src->nsignatures;
|
for (i = 0; i < src->count; i++)
|
||||||
for (i = 0; i < src->nsignatures; i++)
|
dst->items[i] = src->items[i];
|
||||||
dst->signatures[i] = src->signatures[i];
|
|
||||||
|
|
||||||
return 0;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
virCPUx86SignaturesMatch(virCPUx86ModelPtr model,
|
virCPUx86SignaturesMatch(virCPUx86SignaturesPtr sigs,
|
||||||
uint32_t signature)
|
uint32_t signature)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
unsigned int family;
|
||||||
|
unsigned int model;
|
||||||
|
unsigned int stepping;
|
||||||
|
|
||||||
for (i = 0; i < model->nsignatures; i++) {
|
if (!sigs)
|
||||||
if (model->signatures[i] == signature)
|
return false;
|
||||||
|
|
||||||
|
virCPUx86SignatureFromCPUID(signature, &family, &model, &stepping);
|
||||||
|
|
||||||
|
for (i = 0; i < sigs->count; i++) {
|
||||||
|
if (sigs->items[i].family == family &&
|
||||||
|
sigs->items[i].model == model)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1142,17 +1185,21 @@ virCPUx86SignaturesMatch(virCPUx86ModelPtr model,
|
|||||||
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
virCPUx86SignaturesFormat(virCPUx86ModelPtr model)
|
virCPUx86SignaturesFormat(virCPUx86SignaturesPtr sigs)
|
||||||
{
|
{
|
||||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < model->nsignatures; i++) {
|
if (!sigs)
|
||||||
virBufferAsprintf(&buf, "%06lx,",
|
return virBufferContentAndReset(&buf);
|
||||||
(unsigned long)model->signatures[i]);
|
|
||||||
|
for (i = 0; i < sigs->count; i++) {
|
||||||
|
virBufferAsprintf(&buf, "(%u,%u,0), ",
|
||||||
|
sigs->items[i].family,
|
||||||
|
sigs->items[i].model);
|
||||||
}
|
}
|
||||||
|
|
||||||
virBufferTrim(&buf, ",");
|
virBufferTrim(&buf, ", ");
|
||||||
|
|
||||||
return virBufferContentAndReset(&buf);
|
return virBufferContentAndReset(&buf);
|
||||||
}
|
}
|
||||||
@ -1179,16 +1226,11 @@ x86ModelCopy(virCPUx86ModelPtr model)
|
|||||||
|
|
||||||
copy = g_new0(virCPUx86Model, 1);
|
copy = g_new0(virCPUx86Model, 1);
|
||||||
copy->name = g_strdup(model->name);
|
copy->name = g_strdup(model->name);
|
||||||
|
copy->signatures = virCPUx86SignaturesCopy(model->signatures);
|
||||||
if (virCPUx86SignaturesCopy(copy, model) < 0) {
|
|
||||||
x86ModelFree(copy);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
x86DataCopy(©->data, &model->data);
|
x86DataCopy(©->data, &model->data);
|
||||||
|
|
||||||
copy->vendor = model->vendor;
|
copy->vendor = model->vendor;
|
||||||
|
|
||||||
return copy;
|
return g_steal_pointer(©);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1408,9 +1450,7 @@ x86ModelParseAncestor(virCPUx86ModelPtr model,
|
|||||||
}
|
}
|
||||||
|
|
||||||
model->vendor = ancestor->vendor;
|
model->vendor = ancestor->vendor;
|
||||||
if (virCPUx86SignaturesCopy(model, ancestor) < 0)
|
model->signatures = virCPUx86SignaturesCopy(ancestor->signatures);
|
||||||
return -1;
|
|
||||||
|
|
||||||
x86DataCopy(&model->data, &ancestor->data);
|
x86DataCopy(&model->data, &ancestor->data);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1432,34 +1472,29 @@ x86ModelParseSignatures(virCPUx86ModelPtr model,
|
|||||||
/* Remove inherited signatures. */
|
/* Remove inherited signatures. */
|
||||||
virCPUx86SignaturesFree(model->signatures);
|
virCPUx86SignaturesFree(model->signatures);
|
||||||
|
|
||||||
model->nsignatures = n;
|
model->signatures = virCPUx86SignaturesNew(n);
|
||||||
if (VIR_ALLOC_N(model->signatures, n) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
unsigned int sigFamily = 0;
|
virCPUx86Signature *sig = &model->signatures->items[i];
|
||||||
unsigned int sigModel = 0;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
ctxt->node = nodes[i];
|
ctxt->node = nodes[i];
|
||||||
|
|
||||||
rc = virXPathUInt("string(@family)", ctxt, &sigFamily);
|
rc = virXPathUInt("string(@family)", ctxt, &sig->family);
|
||||||
if (rc < 0 || sigFamily == 0) {
|
if (rc < 0 || sig->family == 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Invalid CPU signature family in model %s"),
|
_("Invalid CPU signature family in model %s"),
|
||||||
model->name);
|
model->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = virXPathUInt("string(@model)", ctxt, &sigModel);
|
rc = virXPathUInt("string(@model)", ctxt, &sig->model);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Invalid CPU signature model in model %s"),
|
_("Invalid CPU signature model in model %s"),
|
||||||
model->name);
|
model->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
model->signatures[i] = x86MakeSignature(sigFamily, sigModel, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxt->node = root;
|
ctxt->node = root;
|
||||||
@ -1865,9 +1900,12 @@ x86Compute(virCPUDefPtr host,
|
|||||||
&host_model->vendor->data) < 0)
|
&host_model->vendor->data) < 0)
|
||||||
return VIR_CPU_COMPARE_ERROR;
|
return VIR_CPU_COMPARE_ERROR;
|
||||||
|
|
||||||
if (host_model->signatures &&
|
if (host_model->signatures && host_model->signatures->count > 0) {
|
||||||
x86DataAddSignature(&guest_model->data, *host_model->signatures) < 0)
|
virCPUx86Signature *sig = &host_model->signatures->items[0];
|
||||||
|
if (x86DataAddSignature(&guest_model->data,
|
||||||
|
virCPUx86SignatureToCPUID(sig)) < 0)
|
||||||
return VIR_CPU_COMPARE_ERROR;
|
return VIR_CPU_COMPARE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (cpu->type == VIR_CPU_TYPE_GUEST
|
if (cpu->type == VIR_CPU_TYPE_GUEST
|
||||||
&& cpu->match == VIR_CPU_MATCH_EXACT)
|
&& cpu->match == VIR_CPU_MATCH_EXACT)
|
||||||
@ -1977,8 +2015,8 @@ x86DecodeUseCandidate(virCPUx86ModelPtr current,
|
|||||||
* consider candidates with matching family/model.
|
* consider candidates with matching family/model.
|
||||||
*/
|
*/
|
||||||
if (signature &&
|
if (signature &&
|
||||||
virCPUx86SignaturesMatch(current, signature) &&
|
virCPUx86SignaturesMatch(current->signatures, signature) &&
|
||||||
!virCPUx86SignaturesMatch(candidate, signature)) {
|
!virCPUx86SignaturesMatch(candidate->signatures, signature)) {
|
||||||
VIR_DEBUG("%s differs in signature from matching %s",
|
VIR_DEBUG("%s differs in signature from matching %s",
|
||||||
cpuCandidate->model, cpuCurrent->model);
|
cpuCandidate->model, cpuCurrent->model);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1994,8 +2032,8 @@ x86DecodeUseCandidate(virCPUx86ModelPtr current,
|
|||||||
* result in longer list of features.
|
* result in longer list of features.
|
||||||
*/
|
*/
|
||||||
if (signature &&
|
if (signature &&
|
||||||
virCPUx86SignaturesMatch(candidate, signature) &&
|
virCPUx86SignaturesMatch(candidate->signatures, signature) &&
|
||||||
!virCPUx86SignaturesMatch(current, signature)) {
|
!virCPUx86SignaturesMatch(current->signatures, signature)) {
|
||||||
VIR_DEBUG("%s provides matching signature", cpuCandidate->model);
|
VIR_DEBUG("%s provides matching signature", cpuCandidate->model);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -2150,7 +2188,7 @@ x86Decode(virCPUDefPtr cpu,
|
|||||||
if (vendor)
|
if (vendor)
|
||||||
cpu->vendor = g_strdup(vendor->name);
|
cpu->vendor = g_strdup(vendor->name);
|
||||||
|
|
||||||
sigs = virCPUx86SignaturesFormat(model);
|
sigs = virCPUx86SignaturesFormat(model->signatures);
|
||||||
|
|
||||||
VIR_DEBUG("Using CPU model %s (signatures %s) for CPU with signature %06lx",
|
VIR_DEBUG("Using CPU model %s (signatures %s) for CPU with signature %06lx",
|
||||||
model->name, NULLSTR(sigs), (unsigned long)signature);
|
model->name, NULLSTR(sigs), (unsigned long)signature);
|
||||||
@ -3046,9 +3084,12 @@ virCPUx86Translate(virCPUDefPtr cpu,
|
|||||||
virCPUx86DataAddItem(&model->data, &model->vendor->data) < 0)
|
virCPUx86DataAddItem(&model->data, &model->vendor->data) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (model->signatures &&
|
if (model->signatures && model->signatures->count > 0) {
|
||||||
x86DataAddSignature(&model->data, model->signatures[0]) < 0)
|
virCPUx86Signature *sig = &model->signatures->items[0];
|
||||||
|
if (x86DataAddSignature(&model->data,
|
||||||
|
virCPUx86SignatureToCPUID(sig)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(translated = virCPUDefCopyWithoutModel(cpu)))
|
if (!(translated = virCPUDefCopyWithoutModel(cpu)))
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user