[PATCH] util: directly query KVM for TSC scaling support

Michal Prívozník mprivozn at redhat.com
Thu Aug 5 12:13:47 UTC 2021


On 8/4/21 7:09 PM, Daniel P. Berrangé wrote:
> We currently query the host MSRs to determine if TSC scaling is
> supported. This works OK when running privileged and can open
> the /dev/cpu/0/msr. When unprivileged we fallback to querying
> MSRs from /dev/kvm. This is incorrect because /dev/kvm only
> reports accurate info for MSRs that are valid to use from inside
> a guest.  The TSC scaling support MSR is not, thus we always end
> up reporting lack of TSC scaling when unprivileged.
> 
> The solution to this is easy, because KVM can directly report
> whether TSC scaling is available, which matches what QEMU will
> do at startup.
> 
> https://gitlab.com/libvirt/libvirt/-/issues/188

Perhaps, Closes: https://gitlab.com/... ?

> Reported-by: Roman Mohr <rmohr at redhat.com>
> Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
> ---
>  src/util/virhostcpu.c | 19 +++++++------------
>  1 file changed, 7 insertions(+), 12 deletions(-)
> 
> diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
> index 7aa92ad11d..f140610b47 100644
> --- a/src/util/virhostcpu.c
> +++ b/src/util/virhostcpu.c
> @@ -1349,11 +1349,10 @@ virHostCPUGetMSR(unsigned long index,
>  virHostCPUTscInfo *
>  virHostCPUGetTscInfo(void)
>  {
> -    virHostCPUTscInfo *info;
> +    g_autofree virHostCPUTscInfo *info = g_new0(virHostCPUTscInfo, 1);
>      VIR_AUTOCLOSE kvmFd = -1;
>      VIR_AUTOCLOSE vmFd = -1;
>      VIR_AUTOCLOSE vcpuFd = -1;
> -    uint64_t msr = 0;
>      int rc;
>  
>      if ((kvmFd = open(KVM_DEVICE, O_RDONLY)) < 0) {
> @@ -1378,23 +1377,19 @@ virHostCPUGetTscInfo(void)
>                               _("Unable to probe TSC frequency"));
>          return NULL;
>      }
> -
> -    info = g_new0(virHostCPUTscInfo, 1);
> -
>      info->frequency = rc * 1000ULL;
>  
> -    if (virHostCPUGetMSR(VMX_PROCBASED_CTLS2_MSR, &msr) == 0) {
> -        /* High 32 bits of the MSR value indicate whether specific control
> -         * can be set to 1. */
> -        msr >>= 32;
> -
> -        info->scaling = virTristateBoolFromBool(!!(msr & VMX_USE_TSC_SCALING));
> +    if ((rc = ioctl(kvmFd, KVM_CHECK_EXTENSION, KVM_CAP_TSC_CONTROL)) < 0) {
> +        virReportSystemError(errno, "%s",
> +                             _("Unable to query TSC scaling support"));
> +        return NULL;
>      }
> +    info->scaling = rc ? VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_BOOL_NO;
>  
>      VIR_DEBUG("Detected TSC frequency %llu Hz, scaling %s",
>                info->frequency, virTristateBoolTypeToString(info->scaling));
>  
> -    return info;
> +    return g_steal_pointer(&info);
>  }
>  
>  #else
> 

I think you can also remove defines of those VMX_ macros that are being
removed:

# define VMX_PROCBASED_CTLS2_MSR 0x48b
# define VMX_USE_TSC_SCALING (1 << 25)

Reviewed-by: Michal Privoznik <mprivozn at redhat.com>

Michal




More information about the libvir-list mailing list