From patchwork Thu Nov 4 18:30:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Durrant X-Patchwork-Id: 12603703 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CF14DC433F5 for ; Thu, 4 Nov 2021 19:08:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AB07C61216 for ; Thu, 4 Nov 2021 19:08:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234064AbhKDTLA (ORCPT ); Thu, 4 Nov 2021 15:11:00 -0400 Received: from mail.xenproject.org ([104.130.215.37]:54986 "EHLO mail.xenproject.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232340AbhKDTK7 (ORCPT ); Thu, 4 Nov 2021 15:10:59 -0400 X-Greylist: delayed 2243 seconds by postgrey-1.27 at vger.kernel.org; Thu, 04 Nov 2021 15:10:58 EDT DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:Message-Id:Date: Subject:Cc:To:From; bh=VV56b86sER65QVEVQ0sGmEBrBOeAbsDWmGNCpdGcDkg=; b=eVusLe hXkUIGnaOP5FUhQF8OV7IBTqULrJzB/kXhALbSrGXdCxlfjz+zaUjgJo0I+WlI4q2C5/fi3z3NH2x //riluIZTYKkwympILrIU1Djav+yJNhfNCTQsQ15W58csbpRVrP0H/yGHOaCz3mZu9zSKi/T+xN4V LCmR6X0K+Ys=; Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1mihVY-0001zT-7F; Thu, 04 Nov 2021 18:30:40 +0000 Received: from host86-165-42-146.range86-165.btcentralplus.com ([86.165.42.146] helo=debian.home) by xenbits.xenproject.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mihVX-0001RA-Ul; Thu, 04 Nov 2021 18:30:40 +0000 From: Paul Durrant To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Paul Durrant , Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel Subject: [PATCH] KVM: x86: Make sure KVM_CPUID_FEATURES really are KVM_CPUID_FEATURES Date: Thu, 4 Nov 2021 18:30:20 +0000 Message-Id: <20211104183020.4341-1-paul@xen.org> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Paul Durrant Currently when kvm_update_cpuid_runtime() runs, it assumes that the KVM_CPUID_FEATURES leaf is located at 0x40000001. This is not true, however, if Hyper-V support is enabled. In this case the KVM leaves will be offset. This patch introdues as new 'kvm_cpuid_base' field into struct kvm_vcpu_arch to track the location of the KVM leaves and function kvm_update_cpuid_base() (called from kvm_update_cpuid_runtime()) to locate the leaves using the 'KVMKVMKVM\0\0\0' signature. Adjustment of KVM_CPUID_FEATURES will hence now target the correct leaf. Signed-off-by: Paul Durrant Signed-off-by: Sean Christopherson --- Cc: Paolo Bonzini Cc: Sean Christopherson Cc: Vitaly Kuznetsov Cc: Wanpeng Li Cc: Jim Mattson Cc: Joerg Roedel --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/cpuid.c | 50 +++++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 88fce6ab4bbd..21133ffa23e9 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -725,6 +725,7 @@ struct kvm_vcpu_arch { int cpuid_nent; struct kvm_cpuid_entry2 *cpuid_entries; + u32 kvm_cpuid_base; u64 reserved_gpa_bits; int maxphyaddr; diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 2d70edb0f323..2cfb8ec4f570 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -99,11 +99,46 @@ static int kvm_check_cpuid(struct kvm_cpuid_entry2 *entries, int nent) return 0; } +static void kvm_update_cpuid_base(struct kvm_vcpu *vcpu) +{ + u32 function; + + for (function = 0x40000000; function < 0x40010000; function += 0x100) { + struct kvm_cpuid_entry2 *best = kvm_find_cpuid_entry(vcpu, function, 0); + + if (best) { + char signature[12]; + + *(u32 *)&signature[0] = best->ebx; + *(u32 *)&signature[4] = best->ecx; + *(u32 *)&signature[8] = best->edx; + + if (!memcmp(signature, "KVMKVMKVM\0\0\0", 12)) + break; + } + } + vcpu->arch.kvm_cpuid_base = function; +} + +static inline bool kvm_get_cpuid_base(struct kvm_vcpu *vcpu, u32 *function) +{ + if (vcpu->arch.kvm_cpuid_base < 0x40000000 || + vcpu->arch.kvm_cpuid_base >= 0x40010000) + return false; + + *function = vcpu->arch.kvm_cpuid_base; + return true; +} + void kvm_update_pv_runtime(struct kvm_vcpu *vcpu) { + u32 base; struct kvm_cpuid_entry2 *best; - best = kvm_find_cpuid_entry(vcpu, KVM_CPUID_FEATURES, 0); + if (!kvm_get_cpuid_base(vcpu, &base)) + return; + + best = kvm_find_cpuid_entry(vcpu, base + KVM_CPUID_FEATURES, 0); /* * save the feature bitmap to avoid cpuid lookup for every PV @@ -116,6 +151,7 @@ void kvm_update_pv_runtime(struct kvm_vcpu *vcpu) void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu) { struct kvm_cpuid_entry2 *best; + u32 base; best = kvm_find_cpuid_entry(vcpu, 1, 0); if (best) { @@ -142,10 +178,14 @@ void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu) cpuid_entry_has(best, X86_FEATURE_XSAVEC))) best->ebx = xstate_required_size(vcpu->arch.xcr0, true); - best = kvm_find_cpuid_entry(vcpu, KVM_CPUID_FEATURES, 0); - if (kvm_hlt_in_guest(vcpu->kvm) && best && - (best->eax & (1 << KVM_FEATURE_PV_UNHALT))) - best->eax &= ~(1 << KVM_FEATURE_PV_UNHALT); + kvm_update_cpuid_base(vcpu); + + if (kvm_get_cpuid_base(vcpu, &base)) { + best = kvm_find_cpuid_entry(vcpu, base + KVM_CPUID_FEATURES, 0); + if (kvm_hlt_in_guest(vcpu->kvm) && best && + (best->eax & (1 << KVM_FEATURE_PV_UNHALT))) + best->eax &= ~(1 << KVM_FEATURE_PV_UNHALT); + } if (!kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT)) { best = kvm_find_cpuid_entry(vcpu, 0x1, 0);