On Mon, Apr 08, 2019 at 10:42:38AM +0200, Jiri Denemark wrote: > The new virHostCPUGetMSR internal API will try to read the MSR from > /dev/cpu/0/msr and if it is not possible (the device does not exist or > libvirt is running unprivileged), it will fallback to asking KVM for the > MSR using KVM_GET_MSRS ioctl. > > Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> > --- > src/libvirt_private.syms | 1 + > src/util/virhostcpu.c | 80 ++++++++++++++++++++++++++++++++++++++++ > src/util/virhostcpu.h | 3 ++ > 3 files changed, 84 insertions(+) > > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index 132ee3cae9..59a9a6f093 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -2016,6 +2016,7 @@ virHostCPUGetInfo; > virHostCPUGetKVMMaxVCPUs; > virHostCPUGetMap; > virHostCPUGetMicrocodeVersion; > +virHostCPUGetMSR; Hi, This breaks build on powerpc too. CC util/libvirt_util_la-virhook.lo CC util/libvirt_util_la-virhostcpu.lo util/virhostcpu.c: In function 'virHostCPUGetMSRFromKVM': util/virhostcpu.c:1267:25: error: field 'header' has incomplete type 1267 | struct kvm_msrs header; 2019-04-15 01:06:28,740 process L0458 DEBUG| [stdout] make[3]: Leaving directory '/usr/share/avocado-plugins-vt/build/libvirt/src' | ^~~~~~ 2019-04-15 01:06:28,741 process L0458 DEBUG| [stdout] make[2]: Leaving directory '/usr/share/avocado-plugins-vt/build/libvirt/src' util/virhostcpu.c:1268:30: error: field 'entry' has incomplete type 2019-04-15 01:06:28,742 process L0714 INFO | Command 'make' finished with 2 after 27.617787838s 2019-04-15 01:06:28,742 process L0458 DEBUG| [stdout] make[1]: Leaving directory '/usr/share/avocado-plugins-vt/build/libvirt' 1268 | struct kvm_msr_entry entry; | ^~~~~ util/virhostcpu.c:1270:21: error: field name not in record or union initializer 1270 | .header = { .nmsrs = 1 }, | ^ util/virhostcpu.c:1270:21: note: (near initialization for 'msr.header') util/virhostcpu.c:1271:20: error: field name not in record or union initializer 1271 | .entry = { .index = index }, | ^ util/virhostcpu.c:1271:20: note: (near initialization for 'msr.entry') In file included from /usr/include/asm/ioctl.h:12, from /usr/include/asm/ioctls.h:5, from /usr/include/bits/ioctls.h:23, from /usr/include/sys/ioctl.h:26, from ../gnulib/lib/sys/ioctl.h:27, from util/virhostcpu.c:27: util/virhostcpu.c:1279:19: error: invalid application of 'sizeof' to incomplete type 'struct kvm_msrs' 1279 | if (ioctl(fd, KVM_GET_MSRS, &msr) < 0) { | ^~~~~~~~~~~~ make[3]: *** [Makefile:11963: util/libvirt_util_la-virhostcpu.lo] Error 1 make[2]: *** [Makefile:7128: all] Error 2 make[1]: *** [Makefile:2257: all-recursive] Error 1 make: *** [Makefile:2149: all] Error 2 Regards, -Satheesh > virHostCPUGetOnline; > virHostCPUGetOnlineBitmap; > virHostCPUGetPresentBitmap; > diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c > index 6514c3d765..10bf3a93d5 100644 > --- a/src/util/virhostcpu.c > +++ b/src/util/virhostcpu.c > @@ -58,6 +58,7 @@ > VIR_LOG_INIT("util.hostcpu"); > > #define KVM_DEVICE "/dev/kvm" > +#define MSR_DEVICE "/dev/cpu/0/msr" > > > #if defined(__FreeBSD__) || defined(__APPLE__) > @@ -1254,3 +1255,82 @@ virHostCPUGetMicrocodeVersion(void) > } > > #endif /* __linux__ */ > + > + > +#if HAVE_LINUX_KVM_H && defined(KVM_GET_MSRS) > +static int > +virHostCPUGetMSRFromKVM(unsigned long index, > + uint64_t *result) > +{ > + VIR_AUTOCLOSE fd = -1; > + struct { > + struct kvm_msrs header; > + struct kvm_msr_entry entry; > + } msr = { > + .header = { .nmsrs = 1 }, > + .entry = { .index = index }, > + }; > + > + if ((fd = open(KVM_DEVICE, O_RDONLY)) < 0) { > + virReportSystemError(errno, _("Unable to open %s"), KVM_DEVICE); > + return -1; > + } > + > + if (ioctl(fd, KVM_GET_MSRS, &msr) < 0) { > + VIR_DEBUG("Cannot get MSR 0x%lx from KVM", index); > + return 1; > + } > + > + *result = msr.entry.data; > + return 0; > +} > + > +#else > + > +static int > +virHostCPUGetMSRFromKVM(unsigned long index ATTRIBUTE_UNUSED, > + uint64_t *result ATTRIBUTE_UNUSED) > +{ > + virReportSystemError(ENOSYS, "%s", > + _("Reading MSRs via KVM is not supported on this platform")); > + return -1; > +} > +#endif /* HAVE_LINUX_KVM_H && defined(KVM_GET_MSRS) */ > + > + > +/* > + * Returns 0 on success, > + * 1 when the MSR is not supported by the host CPU, > +* -1 on error. > + */ > +int > +virHostCPUGetMSR(unsigned long index, > + uint64_t *msr) > +{ > + VIR_AUTOCLOSE fd = -1; > + char ebuf[1024]; > + > + *msr = 0; > + > + if ((fd = open(MSR_DEVICE, O_RDONLY)) < 0) { > + VIR_DEBUG("Unable to open %s: %s", > + MSR_DEVICE, virStrerror(errno, ebuf, sizeof(ebuf))); > + } else { > + int rc = pread(fd, msr, sizeof(*msr), index); > + > + if (rc == sizeof(*msr)) > + return 0; > + > + if (rc < 0 && errno == EIO) { > + VIR_DEBUG("CPU does not support MSR 0x%lx", index); > + return 1; > + } > + > + VIR_DEBUG("Cannot read MSR 0x%lx from %s: %s", > + index, MSR_DEVICE, virStrerror(errno, ebuf, sizeof(ebuf))); > + } > + > + VIR_DEBUG("Falling back to KVM ioctl"); > + > + return virHostCPUGetMSRFromKVM(index, msr); > +} > diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h > index df6a7e789d..0d20dbef61 100644 > --- a/src/util/virhostcpu.h > +++ b/src/util/virhostcpu.h > @@ -66,4 +66,7 @@ int virHostCPUGetOnline(unsigned int cpu, bool *online); > > unsigned int virHostCPUGetMicrocodeVersion(void); > > +int virHostCPUGetMSR(unsigned long index, > + uint64_t *msr); > + > #endif /* LIBVIRT_VIRHOSTCPU_H */ > -- > 2.21.0 > > -- > libvir-list mailing list > libvir-list@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/libvir-list > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list