提交 a3389319 编写于 作者: H Hendrik Schwartke 提交者: Michal Privoznik

Added the attribute vendor_id to the cpu model

Introducing the attribute vendor_id to force the CPUID instruction
in a kvm guest to return the specified vendor.
上级 78290b16
...@@ -2854,6 +2854,13 @@ ...@@ -2854,6 +2854,13 @@
</choice> </choice>
</attribute> </attribute>
</optional> </optional>
<optional>
<attribute name="vendor_id">
<data type="string">
<param name='pattern'>[^,]{12}</param>
</data>
</attribute>
</optional>
<choice> <choice>
<text/> <text/>
<empty/> <empty/>
......
...@@ -68,6 +68,7 @@ virCPUDefFreeModel(virCPUDefPtr def) ...@@ -68,6 +68,7 @@ virCPUDefFreeModel(virCPUDefPtr def)
VIR_FREE(def->model); VIR_FREE(def->model);
VIR_FREE(def->vendor); VIR_FREE(def->vendor);
VIR_FREE(def->vendor_id);
for (i = 0; i < def->nfeatures; i++) for (i = 0; i < def->nfeatures; i++)
VIR_FREE(def->features[i].name); VIR_FREE(def->features[i].name);
...@@ -104,6 +105,7 @@ virCPUDefCopyModel(virCPUDefPtr dst, ...@@ -104,6 +105,7 @@ virCPUDefCopyModel(virCPUDefPtr dst,
if ((src->model && !(dst->model = strdup(src->model))) if ((src->model && !(dst->model = strdup(src->model)))
|| (src->vendor && !(dst->vendor = strdup(src->vendor))) || (src->vendor && !(dst->vendor = strdup(src->vendor)))
|| (src->vendor_id && !(dst->vendor_id = strdup(src->vendor_id)))
|| VIR_ALLOC_N(dst->features, src->nfeatures) < 0) || VIR_ALLOC_N(dst->features, src->nfeatures) < 0)
goto no_memory; goto no_memory;
dst->nfeatures_max = dst->nfeatures = src->nfeatures; dst->nfeatures_max = dst->nfeatures = src->nfeatures;
...@@ -288,18 +290,46 @@ virCPUDefParseXML(const xmlNodePtr node, ...@@ -288,18 +290,46 @@ virCPUDefParseXML(const xmlNodePtr node,
} }
if (def->type == VIR_CPU_TYPE_GUEST && if (def->type == VIR_CPU_TYPE_GUEST &&
def->mode != VIR_CPU_MODE_HOST_PASSTHROUGH && def->mode != VIR_CPU_MODE_HOST_PASSTHROUGH) {
virXPathBoolean("boolean(./model[1]/@fallback)", ctxt)) {
const char *fallback; if (virXPathBoolean("boolean(./model[1]/@fallback)", ctxt)) {
const char *fallback;
fallback = virXPathString("string(./model[1]/@fallback)", ctxt);
if (fallback) { fallback = virXPathString("string(./model[1]/@fallback)", ctxt);
def->fallback = virCPUFallbackTypeFromString(fallback); if (fallback) {
VIR_FREE(fallback); def->fallback = virCPUFallbackTypeFromString(fallback);
if (def->fallback < 0) { VIR_FREE(fallback);
virCPUReportError(VIR_ERR_XML_ERROR, "%s", if (def->fallback < 0) {
_("Invalid fallback attribute")); virCPUReportError(VIR_ERR_XML_ERROR, "%s",
goto error; _("Invalid fallback attribute"));
goto error;
}
}
if (virXPathBoolean("boolean(./model[1]/@vendor_id)", ctxt)) {
char *vendor_id;
vendor_id = virXPathString("string(./model[1]/@vendor_id)",
ctxt);
if (!vendor_id ||
strlen(vendor_id) != VIR_CPU_VENDOR_ID_LENGTH) {
virCPUReportError(VIR_ERR_XML_ERROR,
_("vendor_id must be exactly"
" %d characters long"),
VIR_CPU_VENDOR_ID_LENGTH);
VIR_FREE(vendor_id);
goto error;
}
/* ensure that the string can be passed to qemu*/
for (i = 0; i < strlen(vendor_id); i++) {
if (vendor_id[i]==',') {
virCPUReportError(VIR_ERR_XML_ERROR, "%s",
_("vendor id is invalid"));
VIR_FREE(vendor_id);
goto error;
}
}
def->vendor_id = vendor_id;
} }
} }
} }
...@@ -588,6 +618,8 @@ virCPUDefFormatBuf(virBufferPtr buf, ...@@ -588,6 +618,8 @@ virCPUDefFormatBuf(virBufferPtr buf,
return -1; return -1;
} }
virBufferAsprintf(buf, " fallback='%s'", fallback); virBufferAsprintf(buf, " fallback='%s'", fallback);
if (def->vendor_id)
virBufferAsprintf(buf, " vendor_id='%s'", def->vendor_id);
} }
if (formatModel && def->model) { if (formatModel && def->model) {
virBufferAsprintf(buf, ">%s</model>\n", def->model); virBufferAsprintf(buf, ">%s</model>\n", def->model);
...@@ -738,6 +770,13 @@ virCPUDefIsEqual(virCPUDefPtr src, ...@@ -738,6 +770,13 @@ virCPUDefIsEqual(virCPUDefPtr src,
goto cleanup; goto cleanup;
} }
if (STRNEQ_NULLABLE(src->vendor_id, dst->vendor_id)) {
virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target CPU model %s does not match source %s"),
NULLSTR(dst->vendor_id), NULLSTR(src->vendor_id));
goto cleanup;
}
if (src->sockets != dst->sockets) { if (src->sockets != dst->sockets) {
virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED, virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target CPU sockets %d does not match source %d"), _("Target CPU sockets %d does not match source %d"),
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
# include "buf.h" # include "buf.h"
# include "xml.h" # include "xml.h"
# define VIR_CPU_VENDOR_ID_LENGTH 12
enum virCPUType { enum virCPUType {
VIR_CPU_TYPE_HOST, VIR_CPU_TYPE_HOST,
VIR_CPU_TYPE_GUEST, VIR_CPU_TYPE_GUEST,
...@@ -103,6 +105,7 @@ struct _virCPUDef { ...@@ -103,6 +105,7 @@ struct _virCPUDef {
int match; /* enum virCPUMatch */ int match; /* enum virCPUMatch */
char *arch; char *arch;
char *model; char *model;
char *vendor_id; /* vendor id returned by CPUID in the guest */
int fallback; /* enum virCPUFallback */ int fallback; /* enum virCPUFallback */
char *vendor; char *vendor;
unsigned int sockets; unsigned int sockets;
......
...@@ -3913,7 +3913,9 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, ...@@ -3913,7 +3913,9 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver,
} }
virBufferAddLit(&buf, "host"); virBufferAddLit(&buf, "host");
} else { } else {
if (VIR_ALLOC(guest) < 0 || !(guest->arch = strdup(host->arch))) if (VIR_ALLOC(guest) < 0 ||
!(guest->arch = strdup(host->arch)) ||
(cpu->vendor_id && !(guest->vendor_id = strdup(cpu->vendor_id))))
goto no_memory; goto no_memory;
if (cpu->match == VIR_CPU_MATCH_MINIMUM) if (cpu->match == VIR_CPU_MATCH_MINIMUM)
...@@ -3927,6 +3929,8 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, ...@@ -3927,6 +3929,8 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver,
goto cleanup; goto cleanup;
virBufferAdd(&buf, guest->model, -1); virBufferAdd(&buf, guest->model, -1);
if (guest->vendor_id)
virBufferAsprintf(&buf, ",vendor=%s", guest->vendor_id);
for (i = 0; i < guest->nfeatures; i++) { for (i = 0; i < guest->nfeatures; i++) {
char sign; char sign;
if (guest->features[i].policy == VIR_CPU_FEATURE_DISABLE) if (guest->features[i].policy == VIR_CPU_FEATURE_DISABLE)
......
...@@ -116,6 +116,7 @@ virCapsPtr testQemuCapsInit(void) { ...@@ -116,6 +116,7 @@ virCapsPtr testQemuCapsInit(void) {
0, /* match */ 0, /* match */
(char *) "x86_64", /* arch */ (char *) "x86_64", /* arch */
(char *) "core2duo", /* model */ (char *) "core2duo", /* model */
NULL, /* vendor_id */
0, /* fallback */ 0, /* fallback */
(char *) "Intel", /* vendor */ (char *) "Intel", /* vendor */
1, /* sockets */ 1, /* sockets */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册