|
|
99cbc7 |
From 70fd0697564f6a1f9588f4f795956863959d04eb Mon Sep 17 00:00:00 2001
|
|
|
99cbc7 |
Message-Id: <70fd0697564f6a1f9588f4f795956863959d04eb@dist-git>
|
|
|
99cbc7 |
From: Jiri Denemark <jdenemar@redhat.com>
|
|
|
99cbc7 |
Date: Tue, 4 Jun 2019 13:04:25 +0200
|
|
|
99cbc7 |
Subject: [PATCH] vircpuhost: Add support for reading MSRs
|
|
|
99cbc7 |
MIME-Version: 1.0
|
|
|
99cbc7 |
Content-Type: text/plain; charset=UTF-8
|
|
|
99cbc7 |
Content-Transfer-Encoding: 8bit
|
|
|
99cbc7 |
|
|
|
99cbc7 |
The new virHostCPUGetMSR internal API will try to read the MSR from
|
|
|
99cbc7 |
/dev/cpu/0/msr and if it is not possible (the device does not exist or
|
|
|
99cbc7 |
libvirt is running unprivileged), it will fallback to asking KVM for the
|
|
|
99cbc7 |
MSR using KVM_GET_MSRS ioctl.
|
|
|
99cbc7 |
|
|
|
99cbc7 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
99cbc7 |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
99cbc7 |
(cherry picked from commit df4b46737f43a1a67f9b5de2840213a1bd2b3cce)
|
|
|
99cbc7 |
|
|
|
99cbc7 |
https://bugzilla.redhat.com/show_bug.cgi?id=1641702
|
|
|
99cbc7 |
|
|
|
99cbc7 |
Conflicts:
|
|
|
99cbc7 |
src/util/virhostcpu.h
|
|
|
99cbc7 |
- context: the comment after #endif changed upstream
|
|
|
99cbc7 |
|
|
|
99cbc7 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
99cbc7 |
Message-Id: <696430bedbef1fd8f1f65339173eda0e0b042e9c.1559646067.git.jdenemar@redhat.com>
|
|
|
99cbc7 |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
99cbc7 |
---
|
|
|
99cbc7 |
src/libvirt_private.syms | 1 +
|
|
|
99cbc7 |
src/util/virhostcpu.c | 80 ++++++++++++++++++++++++++++++++++++++++
|
|
|
99cbc7 |
src/util/virhostcpu.h | 3 ++
|
|
|
99cbc7 |
3 files changed, 84 insertions(+)
|
|
|
99cbc7 |
|
|
|
99cbc7 |
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|
|
99cbc7 |
index 984a9be18f..3a99cb6774 100644
|
|
|
99cbc7 |
--- a/src/libvirt_private.syms
|
|
|
99cbc7 |
+++ b/src/libvirt_private.syms
|
|
|
99cbc7 |
@@ -1961,6 +1961,7 @@ virHostCPUGetInfo;
|
|
|
99cbc7 |
virHostCPUGetKVMMaxVCPUs;
|
|
|
99cbc7 |
virHostCPUGetMap;
|
|
|
99cbc7 |
virHostCPUGetMicrocodeVersion;
|
|
|
99cbc7 |
+virHostCPUGetMSR;
|
|
|
99cbc7 |
virHostCPUGetOnline;
|
|
|
99cbc7 |
virHostCPUGetOnlineBitmap;
|
|
|
99cbc7 |
virHostCPUGetPresentBitmap;
|
|
|
99cbc7 |
diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
|
|
|
99cbc7 |
index 3f7d70b87b..2c1404b07a 100644
|
|
|
99cbc7 |
--- a/src/util/virhostcpu.c
|
|
|
99cbc7 |
+++ b/src/util/virhostcpu.c
|
|
|
99cbc7 |
@@ -64,6 +64,7 @@
|
|
|
99cbc7 |
VIR_LOG_INIT("util.hostcpu");
|
|
|
99cbc7 |
|
|
|
99cbc7 |
#define KVM_DEVICE "/dev/kvm"
|
|
|
99cbc7 |
+#define MSR_DEVICE "/dev/cpu/0/msr"
|
|
|
99cbc7 |
|
|
|
99cbc7 |
|
|
|
99cbc7 |
#if defined(__FreeBSD__) || defined(__APPLE__)
|
|
|
99cbc7 |
@@ -1294,3 +1295,82 @@ virHostCPUGetMicrocodeVersion(void)
|
|
|
99cbc7 |
}
|
|
|
99cbc7 |
|
|
|
99cbc7 |
#endif /* __linux__ */
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+#if HAVE_LINUX_KVM_H && defined(KVM_GET_MSRS)
|
|
|
99cbc7 |
+static int
|
|
|
99cbc7 |
+virHostCPUGetMSRFromKVM(unsigned long index,
|
|
|
99cbc7 |
+ uint64_t *result)
|
|
|
99cbc7 |
+{
|
|
|
99cbc7 |
+ VIR_AUTOCLOSE fd = -1;
|
|
|
99cbc7 |
+ struct {
|
|
|
99cbc7 |
+ struct kvm_msrs header;
|
|
|
99cbc7 |
+ struct kvm_msr_entry entry;
|
|
|
99cbc7 |
+ } msr = {
|
|
|
99cbc7 |
+ .header = { .nmsrs = 1 },
|
|
|
99cbc7 |
+ .entry = { .index = index },
|
|
|
99cbc7 |
+ };
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ if ((fd = open(KVM_DEVICE, O_RDONLY)) < 0) {
|
|
|
99cbc7 |
+ virReportSystemError(errno, _("Unable to open %s"), KVM_DEVICE);
|
|
|
99cbc7 |
+ return -1;
|
|
|
99cbc7 |
+ }
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ if (ioctl(fd, KVM_GET_MSRS, &msr) < 0) {
|
|
|
99cbc7 |
+ VIR_DEBUG("Cannot get MSR 0x%lx from KVM", index);
|
|
|
99cbc7 |
+ return 1;
|
|
|
99cbc7 |
+ }
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ *result = msr.entry.data;
|
|
|
99cbc7 |
+ return 0;
|
|
|
99cbc7 |
+}
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+#else
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+static int
|
|
|
99cbc7 |
+virHostCPUGetMSRFromKVM(unsigned long index ATTRIBUTE_UNUSED,
|
|
|
99cbc7 |
+ uint64_t *result ATTRIBUTE_UNUSED)
|
|
|
99cbc7 |
+{
|
|
|
99cbc7 |
+ virReportSystemError(ENOSYS, "%s",
|
|
|
99cbc7 |
+ _("Reading MSRs via KVM is not supported on this platform"));
|
|
|
99cbc7 |
+ return -1;
|
|
|
99cbc7 |
+}
|
|
|
99cbc7 |
+#endif /* HAVE_LINUX_KVM_H && defined(KVM_GET_MSRS) */
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+/*
|
|
|
99cbc7 |
+ * Returns 0 on success,
|
|
|
99cbc7 |
+ * 1 when the MSR is not supported by the host CPU,
|
|
|
99cbc7 |
+* -1 on error.
|
|
|
99cbc7 |
+ */
|
|
|
99cbc7 |
+int
|
|
|
99cbc7 |
+virHostCPUGetMSR(unsigned long index,
|
|
|
99cbc7 |
+ uint64_t *msr)
|
|
|
99cbc7 |
+{
|
|
|
99cbc7 |
+ VIR_AUTOCLOSE fd = -1;
|
|
|
99cbc7 |
+ char ebuf[1024];
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ *msr = 0;
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ if ((fd = open(MSR_DEVICE, O_RDONLY)) < 0) {
|
|
|
99cbc7 |
+ VIR_DEBUG("Unable to open %s: %s",
|
|
|
99cbc7 |
+ MSR_DEVICE, virStrerror(errno, ebuf, sizeof(ebuf)));
|
|
|
99cbc7 |
+ } else {
|
|
|
99cbc7 |
+ int rc = pread(fd, msr, sizeof(*msr), index);
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ if (rc == sizeof(*msr))
|
|
|
99cbc7 |
+ return 0;
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ if (rc < 0 && errno == EIO) {
|
|
|
99cbc7 |
+ VIR_DEBUG("CPU does not support MSR 0x%lx", index);
|
|
|
99cbc7 |
+ return 1;
|
|
|
99cbc7 |
+ }
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ VIR_DEBUG("Cannot read MSR 0x%lx from %s: %s",
|
|
|
99cbc7 |
+ index, MSR_DEVICE, virStrerror(errno, ebuf, sizeof(ebuf)));
|
|
|
99cbc7 |
+ }
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ VIR_DEBUG("Falling back to KVM ioctl");
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
+ return virHostCPUGetMSRFromKVM(index, msr);
|
|
|
99cbc7 |
+}
|
|
|
99cbc7 |
diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h
|
|
|
99cbc7 |
index f9f3359288..e705623d4f 100644
|
|
|
99cbc7 |
--- a/src/util/virhostcpu.h
|
|
|
99cbc7 |
+++ b/src/util/virhostcpu.h
|
|
|
99cbc7 |
@@ -68,4 +68,7 @@ int virHostCPUGetOnline(unsigned int cpu, bool *online);
|
|
|
99cbc7 |
|
|
|
99cbc7 |
unsigned int virHostCPUGetMicrocodeVersion(void);
|
|
|
99cbc7 |
|
|
|
99cbc7 |
+int virHostCPUGetMSR(unsigned long index,
|
|
|
99cbc7 |
+ uint64_t *msr);
|
|
|
99cbc7 |
+
|
|
|
99cbc7 |
#endif /* __VIR_HOSTCPU_H__*/
|
|
|
99cbc7 |
--
|
|
|
99cbc7 |
2.21.0
|
|
|
99cbc7 |
|