File 5df2c492-use-kvm-for-tsc-scaling.patch of Package libvirt
xxxxxxxxxx
1
commit 5df2c49263338da7221f24b3ad67ffd21d88047c
2
Author: Daniel P. Berrangé <berrange@redhat.com>
3
Date: Wed Aug 4 18:05:59 2021 +0100
4
5
util: directly query KVM for TSC scaling support
6
7
We currently query the host MSRs to determine if TSC scaling is
8
supported. This works OK when running privileged and can open
9
the /dev/cpu/0/msr. When unprivileged we fallback to querying
10
MSRs from /dev/kvm. This is incorrect because /dev/kvm only
11
reports accurate info for MSRs that are valid to use from inside
12
a guest. The TSC scaling support MSR is not, thus we always end
13
up reporting lack of TSC scaling when unprivileged.
14
15
The solution to this is easy, because KVM can directly report
16
whether TSC scaling is available, which matches what QEMU will
17
do at startup.
18
19
Closes: https://gitlab.com/libvirt/libvirt/-/issues/188
20
Reported-by: Roman Mohr <rmohr@redhat.com>
21
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
22
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
23
24
Index: libvirt-7.1.0/src/util/virhostcpu.c
25
===================================================================
26
--- libvirt-7.1.0.orig/src/util/virhostcpu.c
27
+++ libvirt-7.1.0/src/util/virhostcpu.c
28
29
}
30
31
32
-# define VMX_PROCBASED_CTLS2_MSR 0x48b
33
-# define VMX_USE_TSC_SCALING (1 << 25)
34
-
35
/*
36
* This function should only be called when the host CPU supports invariant TSC
37
* (invtsc CPUID feature).
38
39
virHostCPUTscInfoPtr
40
virHostCPUGetTscInfo(void)
41
{
42
- virHostCPUTscInfoPtr info;
43
+ g_autofree virHostCPUTscInfoPtr info = g_new0(virHostCPUTscInfo, 1);
44
VIR_AUTOCLOSE kvmFd = -1;
45
VIR_AUTOCLOSE vmFd = -1;
46
VIR_AUTOCLOSE vcpuFd = -1;
47
- uint64_t msr = 0;
48
int rc;
49
50
if ((kvmFd = open(KVM_DEVICE, O_RDONLY)) < 0) {
51
52
_("Unable to probe TSC frequency"));
53
return NULL;
54
}
55
-
56
- info = g_new0(virHostCPUTscInfo, 1);
57
-
58
info->frequency = rc * 1000ULL;
59
60
- if (virHostCPUGetMSR(VMX_PROCBASED_CTLS2_MSR, &msr) == 0) {
61
- /* High 32 bits of the MSR value indicate whether specific control
62
- * can be set to 1. */
63
- msr >>= 32;
64
-
65
- info->scaling = virTristateBoolFromBool(!!(msr & VMX_USE_TSC_SCALING));
66
+ if ((rc = ioctl(kvmFd, KVM_CHECK_EXTENSION, KVM_CAP_TSC_CONTROL)) < 0) {
67
+ virReportSystemError(errno, "%s",
68
+ _("Unable to query TSC scaling support"));
69
+ return NULL;
70
}
71
+ info->scaling = rc ? VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_BOOL_NO;
72
73
VIR_DEBUG("Detected TSC frequency %llu Hz, scaling %s",
74
info->frequency, virTristateBoolTypeToString(info->scaling));
75
76
- return info;
77
+ return g_steal_pointer(&info);
78
}
79
80
#else
81