On 11/04/2013 08:55 AM, Peter Krempa wrote: > From: Jiri Denemark <jdenemar@xxxxxxxxxx> > > The qemu monitor supports retrieval of actual CPUID bits presented to > the guest using QMP monitor. Add APIs to extract these information and > tests for them. > > Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> > --- > <...snip...> > diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c > index 05f8aa6..e738fe3 100644 > --- a/src/qemu/qemu_monitor_json.c > +++ b/src/qemu/qemu_monitor_json.c > @@ -42,6 +42,7 @@ > #include "virerror.h" > #include "virjson.h" > #include "virstring.h" > +#include "cpu/cpu_x86.h" > > #ifdef WITH_DTRACE_PROBES > # include "libvirt_qemu_probes.h" > @@ -49,6 +50,7 @@ > > #define VIR_FROM_THIS VIR_FROM_QEMU > > +#define QOM_CPU_PATH "/machine/unattached/device[0]" > > #define LINE_ENDING "\r\n" > > @@ -5454,3 +5456,134 @@ cleanup: > VIR_FREE(paths); > return ret; > } > + > + > +static int > +qemuMonitorJSONParseCPUx86FeatureWord(virJSONValuePtr data, > + virCPUx86CPUID *cpuid) > +{ > + const char *reg; > + unsigned long long fun; > + unsigned long long features; > + > + memset(cpuid, 0, sizeof(*cpuid)); > + > + if (!(reg = virJSONValueObjectGetString(data, "cpuid-register"))) { > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("missing cpuid-register in CPU data")); > + return -1; > + } > + if (virJSONValueObjectGetNumberUlong(data, "cpuid-input-eax", &fun)) { > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("missing or invalid cpuid-input-eax in CPU data")); > + return -1; > + } > + if (virJSONValueObjectGetNumberUlong(data, "features", &features) < 0) { > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("missing or invalid features in CPU data")); > + return -1; > + } > + > + cpuid->function = fun; > + if (STREQ(reg, "EAX")) { > + cpuid->eax = features; > + } else if (STREQ(reg, "EBX")) { > + cpuid->ebx = features; > + } else if (STREQ(reg, "ECX")) { > + cpuid->ecx = features; > + } else if (STREQ(reg, "EDX")) { > + cpuid->edx = features; > + } else { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("unknown CPU register '%s'"), reg); > + return -1; > + } > + > + return 0; > +} > + > + > +static virCPUDataPtr > +qemuMonitorJSONGetCPUx86Data(qemuMonitorPtr mon, > + const char *property) > +{ > + virJSONValuePtr cmd; > + virJSONValuePtr reply = NULL; > + virJSONValuePtr data; > + virCPUx86Data *x86Data = NULL; > + virCPUx86CPUID cpuid; > + size_t i; > + virCPUDataPtr ret = NULL; > + int n; > + > + if (!(cmd = qemuMonitorJSONMakeCommand("qom-get", > + "s:path", QOM_CPU_PATH, > + "s:property", property, > + NULL))) > + return NULL; > + > + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) > + goto cleanup; > + > + if (qemuMonitorJSONCheckError(cmd, reply)) > + goto cleanup; > + > + if (!(data = virJSONValueObjectGet(reply, "return"))) { > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("qom-get reply was missing return data")); > + goto cleanup; > + } > + > + if ((n = virJSONValueArraySize(data)) < 0) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("%s CPU property did not return an array"), > + property); > + goto cleanup; > + } > + > + if (VIR_ALLOC(x86Data) < 0) > + goto cleanup; > + > + for (i = 0; i < n; i++) { > + if (qemuMonitorJSONParseCPUx86FeatureWord(virJSONValueArrayGet(data, i), > + &cpuid) < 0 || > + virCPUx86DataAddCPUID(x86Data, &cpuid) < 0) > + goto cleanup; > + } > + > + if (!(ret = virCPUx86MakeData(VIR_ARCH_X86_64, &x86Data))) > + goto cleanup; > + > +cleanup: > + virJSONValueFree(cmd); > + virJSONValueFree(reply); > + virCPUx86DataFree(x86Data); > + return ret; > +} > + > + > +/** > + * qemuMonitorJSONGetGuestCPU: > + * @mon: Pointer to the monitor > + * @arch: arch of the guest > + * > + * Retrieve the definition of the guest CPU from a running qemu instance. > + * > + * Returns the cpu definition object. On error returns NULL. > + */ > +virCPUDataPtr > +qemuMonitorJSONGetGuestCPU(qemuMonitorPtr mon, > + virArch arch) > +{ > + switch (arch) { > + case VIR_ARCH_X86_64: > + case VIR_ARCH_I686: > + return qemuMonitorJSONGetCPUx86Data(mon, "feature-words"); According to: http://wiki.qemu.org/Features/CPUModels This was added in qemu 1.5, I have qemu 1.4.2 installed right now and VM startups fail: error: Failed to start domain f18 error: internal error: unable to execute QEMU command 'qom-get': Property '.feature-words' not found John > + > + default: > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("CPU definition retrieval isn't supported for '%s'"), > + virArchToString(arch)); > + return NULL; > + } > +} -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list