On Mon, Nov 04, 2013 at 14:55:03 +0100, 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> > --- > > Notes: > Version 3: > - removed unneeded error state > - fixed typo in error message > > Version 2: > - unified global and JSON monitor func signatures > - changed return values so that errors can be differenitated from lack of support > - code is conditionally run only when architecture matches > > src/qemu/qemu_monitor.c | 31 +++++ > src/qemu/qemu_monitor.h | 4 + > src/qemu/qemu_monitor_json.c | 133 +++++++++++++++++++++ > src/qemu/qemu_monitor_json.h | 2 + > tests/Makefile.am | 1 + > .../qemumonitorjson-getcpu-full.data | 5 + > .../qemumonitorjson-getcpu-full.json | 46 +++++++ > .../qemumonitorjson-getcpu-host.data | 6 + > .../qemumonitorjson-getcpu-host.json | 45 +++++++ > tests/qemumonitorjsontest.c | 75 ++++++++++++ > 10 files changed, 348 insertions(+) > create mode 100644 tests/qemumonitorjsondata/qemumonitorjson-getcpu-full.data > create mode 100644 tests/qemumonitorjsondata/qemumonitorjson-getcpu-full.json > create mode 100644 tests/qemumonitorjsondata/qemumonitorjson-getcpu-host.data > create mode 100644 tests/qemumonitorjsondata/qemumonitorjson-getcpu-host.json > > diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c > index 2bafe28..e865808 100644 > --- a/src/qemu/qemu_monitor.c > +++ b/src/qemu/qemu_monitor.c > @@ -3926,3 +3926,34 @@ qemuMonitorSetDomainLog(qemuMonitorPtr mon, int logfd) > > return 0; > } > + > + > +/** > + * 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 > +qemuMonitorGetGuestCPU(qemuMonitorPtr mon, > + virArch arch) > +{ > + VIR_DEBUG("mon=%p, arch='%s'", mon, virArchToString(arch)); > + > + if (!mon) { > + virReportError(VIR_ERR_INVALID_ARG, "%s", > + _("monitor must not be NULL")); > + return NULL; > + } > + > + if (!mon->json) { > + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", > + _("JSON monitor is required")); > + return NULL; > + } > + > + return qemuMonitorJSONGetGuestCPU(mon, arch); > +} > diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h > index 06ba7e8..ecc6d7b 100644 > --- a/src/qemu/qemu_monitor.h > +++ b/src/qemu/qemu_monitor.h > @@ -32,6 +32,7 @@ > # include "virhash.h" > # include "virjson.h" > # include "device_conf.h" > +# include "cpu/cpu.h" > > typedef struct _qemuMonitor qemuMonitor; > typedef qemuMonitor *qemuMonitorPtr; > @@ -763,6 +764,9 @@ int qemuMonitorGetDeviceAliases(qemuMonitorPtr mon, > > int qemuMonitorSetDomainLog(qemuMonitorPtr mon, int logfd); > > +virCPUDataPtr qemuMonitorGetGuestCPU(qemuMonitorPtr mon, > + virArch arch); > + > /** > * When running two dd process and using <> redirection, we need a > * shell that will not truncate files. These two strings serve that > 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)) { I guess this should have been "if (... < 0)", right? > + 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; > + } ... ACK Jirka -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list