mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 19:41:16 +00:00
vircpuhost: Add support for reading MSRs
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@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
1c0ff5df07
commit
df4b46737f
@ -2027,6 +2027,7 @@ virHostCPUGetInfo;
|
|||||||
virHostCPUGetKVMMaxVCPUs;
|
virHostCPUGetKVMMaxVCPUs;
|
||||||
virHostCPUGetMap;
|
virHostCPUGetMap;
|
||||||
virHostCPUGetMicrocodeVersion;
|
virHostCPUGetMicrocodeVersion;
|
||||||
|
virHostCPUGetMSR;
|
||||||
virHostCPUGetOnline;
|
virHostCPUGetOnline;
|
||||||
virHostCPUGetOnlineBitmap;
|
virHostCPUGetOnlineBitmap;
|
||||||
virHostCPUGetPresentBitmap;
|
virHostCPUGetPresentBitmap;
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
VIR_LOG_INIT("util.hostcpu");
|
VIR_LOG_INIT("util.hostcpu");
|
||||||
|
|
||||||
#define KVM_DEVICE "/dev/kvm"
|
#define KVM_DEVICE "/dev/kvm"
|
||||||
|
#define MSR_DEVICE "/dev/cpu/0/msr"
|
||||||
|
|
||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||||
@ -1254,3 +1255,82 @@ virHostCPUGetMicrocodeVersion(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __linux__ */
|
#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);
|
||||||
|
}
|
||||||
|
@ -66,4 +66,7 @@ int virHostCPUGetOnline(unsigned int cpu, bool *online);
|
|||||||
|
|
||||||
unsigned int virHostCPUGetMicrocodeVersion(void);
|
unsigned int virHostCPUGetMicrocodeVersion(void);
|
||||||
|
|
||||||
|
int virHostCPUGetMSR(unsigned long index,
|
||||||
|
uint64_t *msr);
|
||||||
|
|
||||||
#endif /* LIBVIRT_VIRHOSTCPU_H */
|
#endif /* LIBVIRT_VIRHOSTCPU_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user