From nobody Tue Jun 30 17:47:36 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 36650C433F5 for ; Wed, 12 Jan 2022 17:01:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355425AbiALRBs (ORCPT ); Wed, 12 Jan 2022 12:01:48 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:60429 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349830AbiALRBp (ORCPT ); Wed, 12 Jan 2022 12:01:45 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1642006904; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=fYwcy9T5j2tyPY3dtw1jyrpRN5F1PPuTsoc1LTJIhuQ=; b=M4o5Ae7bEZKquHKBSbHHpBu7ucnu2vcvQCjKI7JdXwqaBrjLHsZCZPjfVotuhhp20WPvXp hCzEdiTu02wy4L06n6pOMSn3H0bQd2tt8YCN/8jto6ovO2VLA15ekyPVs/rH34Ekik7f8I 28hoCT2UtKhyjXXvb3GSQMmvJMDFYno= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-668-yVWBAXCNOCKC4MHYYRLeoQ-1; Wed, 12 Jan 2022 12:01:41 -0500 X-MC-Unique: yVWBAXCNOCKC4MHYYRLeoQ-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8518A100CCC1; Wed, 12 Jan 2022 17:01:40 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.40.194.48]) by smtp.corp.redhat.com (Postfix) with ESMTP id 58DC92B45F; Wed, 12 Jan 2022 17:01:38 +0000 (UTC) From: Vitaly Kuznetsov To: kvm@vger.kernel.org, Paolo Bonzini Cc: Sean Christopherson , Wanpeng Li , Jim Mattson , Maxim Levitsky , linux-kernel@vger.kernel.org Subject: [PATCH v3 1/5] KVM: nVMX: Also filter MSR_IA32_VMX_TRUE_PINBASED_CTLS when eVMCS Date: Wed, 12 Jan 2022 18:01:30 +0100 Message-Id: <20220112170134.1904308-2-vkuznets@redhat.com> In-Reply-To: <20220112170134.1904308-1-vkuznets@redhat.com> References: <20220112170134.1904308-1-vkuznets@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Similar to MSR_IA32_VMX_EXIT_CTLS/MSR_IA32_VMX_TRUE_EXIT_CTLS, MSR_IA32_VMX_ENTRY_CTLS/MSR_IA32_VMX_TRUE_ENTRY_CTLS pair, MSR_IA32_VMX_TRUE_PINBASED_CTLS needs to be filtered the same way MSR_IA32_VMX_PINBASED_CTLS is currently filtered as guests may solely rely on 'true' MSR data. Note, none of the currently existing Windows/Hyper-V versions are known to stumble upon the unfiltered MSR_IA32_VMX_TRUE_PINBASED_CTLS, the change is aimed at making the filtering future proof. Signed-off-by: Vitaly Kuznetsov --- arch/x86/kvm/vmx/evmcs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kvm/vmx/evmcs.c b/arch/x86/kvm/vmx/evmcs.c index ba6f99f584ac..a7ed30d5647a 100644 --- a/arch/x86/kvm/vmx/evmcs.c +++ b/arch/x86/kvm/vmx/evmcs.c @@ -362,6 +362,7 @@ void nested_evmcs_filter_control_msr(u32 msr_index, u64= *pdata) case MSR_IA32_VMX_PROCBASED_CTLS2: ctl_high &=3D ~EVMCS1_UNSUPPORTED_2NDEXEC; break; + case MSR_IA32_VMX_TRUE_PINBASED_CTLS: case MSR_IA32_VMX_PINBASED_CTLS: ctl_high &=3D ~EVMCS1_UNSUPPORTED_PINCTRL; break; --=20 2.34.1 From nobody Tue Jun 30 17:47:36 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F08D9C43217 for ; Wed, 12 Jan 2022 17:01:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355453AbiALRBx (ORCPT ); Wed, 12 Jan 2022 12:01:53 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:26168 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355424AbiALRBs (ORCPT ); Wed, 12 Jan 2022 12:01:48 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1642006907; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=D6IXJlDqizWeo54+8z6zzciDQhLWhFcuUSJKVg6qjks=; b=XNkBYwa2XuZ2UgW6l0qKQT1diXl3QjKl7TTP5KNf8y2b/tW5evgu7ah7sMx+ogjGwG6/6y Iw956a53kCFr5Jyf0DJXdekGd2pJuPSdx2juYtrlL9ueHNO3uTAOiwkPZ5FaGueHkMvXkD iGEN9tsgvHdaxLz6vJooJefqwwqjS4M= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-111-RsM4B_BgN0ORPwpYBmt-XQ-1; Wed, 12 Jan 2022 12:01:44 -0500 X-MC-Unique: RsM4B_BgN0ORPwpYBmt-XQ-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1845880573B; Wed, 12 Jan 2022 17:01:43 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.40.194.48]) by smtp.corp.redhat.com (Postfix) with ESMTP id E15E326DE0; Wed, 12 Jan 2022 17:01:40 +0000 (UTC) From: Vitaly Kuznetsov To: kvm@vger.kernel.org, Paolo Bonzini Cc: Sean Christopherson , Wanpeng Li , Jim Mattson , Maxim Levitsky , linux-kernel@vger.kernel.org Subject: [PATCH v3 2/5] KVM: nVMX: eVMCS: Filter out VM_EXIT_SAVE_VMX_PREEMPTION_TIMER Date: Wed, 12 Jan 2022 18:01:31 +0100 Message-Id: <20220112170134.1904308-3-vkuznets@redhat.com> In-Reply-To: <20220112170134.1904308-1-vkuznets@redhat.com> References: <20220112170134.1904308-1-vkuznets@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Enlightened VMCS v1 doesn't have VMX_PREEMPTION_TIMER_VALUE field, PIN_BASED_VMX_PREEMPTION_TIMER is also filtered out already so it makes sense to filter out VM_EXIT_SAVE_VMX_PREEMPTION_TIMER too. Note, none of the currently existing Windows/Hyper-V versions are known to enable 'save VMX-preemption timer value' when eVMCS is in use, the change is aimed at making the filtering future proof. Signed-off-by: Vitaly Kuznetsov --- arch/x86/kvm/vmx/evmcs.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx/evmcs.h b/arch/x86/kvm/vmx/evmcs.h index 16731d2cf231..3a461a32128b 100644 --- a/arch/x86/kvm/vmx/evmcs.h +++ b/arch/x86/kvm/vmx/evmcs.h @@ -59,7 +59,9 @@ DECLARE_STATIC_KEY_FALSE(enable_evmcs); SECONDARY_EXEC_SHADOW_VMCS | \ SECONDARY_EXEC_TSC_SCALING | \ SECONDARY_EXEC_PAUSE_LOOP_EXITING) -#define EVMCS1_UNSUPPORTED_VMEXIT_CTRL (VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL) +#define EVMCS1_UNSUPPORTED_VMEXIT_CTRL \ + (VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | \ + VM_EXIT_SAVE_VMX_PREEMPTION_TIMER) #define EVMCS1_UNSUPPORTED_VMENTRY_CTRL (VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CT= RL) #define EVMCS1_UNSUPPORTED_VMFUNC (VMX_VMFUNC_EPTP_SWITCHING) =20 --=20 2.34.1 From nobody Tue Jun 30 17:47:36 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C0B33C433F5 for ; Wed, 12 Jan 2022 17:02:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355455AbiALRCA (ORCPT ); Wed, 12 Jan 2022 12:02:00 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:33109 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355445AbiALRBw (ORCPT ); Wed, 12 Jan 2022 12:01:52 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1642006911; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6czKIoWCNyfxTJT0CrfhNFIB0LIHDipWGzlMZf/F2OI=; b=Cz7MuArS0/vVTiAMJW0qVBvfQOq+Y2NyLFnQOgMYESoS1MuEuBwpRQDgBUm1/dvWscoq48 cKdcaU9pRy/96ySUT53q3ZBiZSY+tvv4Ro1ieRycP7KjXqtzDkk08D5vu1Sny72po5UNkj OXB626Fll4HsdpvFUXGopEDZ3W8qw4k= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-407-F4QEcQTZNhe-yZOSH3haiQ-1; Wed, 12 Jan 2022 12:01:48 -0500 X-MC-Unique: F4QEcQTZNhe-yZOSH3haiQ-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 86CF480573B; Wed, 12 Jan 2022 17:01:45 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.40.194.48]) by smtp.corp.redhat.com (Postfix) with ESMTP id 75EDA26DE0; Wed, 12 Jan 2022 17:01:43 +0000 (UTC) From: Vitaly Kuznetsov To: kvm@vger.kernel.org, Paolo Bonzini Cc: Sean Christopherson , Wanpeng Li , Jim Mattson , Maxim Levitsky , linux-kernel@vger.kernel.org Subject: [PATCH v3 3/5] KVM: nVMX: Rename vmcs_to_field_offset{,_table} Date: Wed, 12 Jan 2022 18:01:32 +0100 Message-Id: <20220112170134.1904308-4-vkuznets@redhat.com> In-Reply-To: <20220112170134.1904308-1-vkuznets@redhat.com> References: <20220112170134.1904308-1-vkuznets@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" vmcs_to_field_offset{,_table} may sound misleading as VMCS is an opaque blob which is not supposed to be accessed directly. In fact, vmcs_to_field_offset{,_table} are related to KVM defined VMCS12 structure. Rename vmcs_field_to_offset() to get_vmcs12_field_offset() for clarity. No functional change intended. Reviewed-by: Sean Christopherson Signed-off-by: Vitaly Kuznetsov --- arch/x86/kvm/vmx/nested.c | 6 +++--- arch/x86/kvm/vmx/vmcs12.c | 4 ++-- arch/x86/kvm/vmx/vmcs12.h | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index f235f77cbc03..5941ba05b509 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -5111,7 +5111,7 @@ static int handle_vmread(struct kvm_vcpu *vcpu) /* Decode instruction info and find the field to read */ field =3D kvm_register_read(vcpu, (((instr_info) >> 28) & 0xf)); =20 - offset =3D vmcs_field_to_offset(field); + offset =3D get_vmcs12_field_offset(field); if (offset < 0) return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); =20 @@ -5214,7 +5214,7 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) =20 field =3D kvm_register_read(vcpu, (((instr_info) >> 28) & 0xf)); =20 - offset =3D vmcs_field_to_offset(field); + offset =3D get_vmcs12_field_offset(field); if (offset < 0) return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); =20 @@ -6462,7 +6462,7 @@ static u64 nested_vmx_calc_vmcs_enum_msr(void) max_idx =3D 0; for (i =3D 0; i < nr_vmcs12_fields; i++) { /* The vmcs12 table is very, very sparsely populated. */ - if (!vmcs_field_to_offset_table[i]) + if (!vmcs12_field_offsets[i]) continue; =20 idx =3D vmcs_field_index(VMCS12_IDX_TO_ENC(i)); diff --git a/arch/x86/kvm/vmx/vmcs12.c b/arch/x86/kvm/vmx/vmcs12.c index cab6ba7a5005..2251b60920f8 100644 --- a/arch/x86/kvm/vmx/vmcs12.c +++ b/arch/x86/kvm/vmx/vmcs12.c @@ -8,7 +8,7 @@ FIELD(number, name), \ [ROL16(number##_HIGH, 6)] =3D VMCS12_OFFSET(name) + sizeof(u32) =20 -const unsigned short vmcs_field_to_offset_table[] =3D { +const unsigned short vmcs12_field_offsets[] =3D { FIELD(VIRTUAL_PROCESSOR_ID, virtual_processor_id), FIELD(POSTED_INTR_NV, posted_intr_nv), FIELD(GUEST_ES_SELECTOR, guest_es_selector), @@ -151,4 +151,4 @@ const unsigned short vmcs_field_to_offset_table[] =3D { FIELD(HOST_RSP, host_rsp), FIELD(HOST_RIP, host_rip), }; -const unsigned int nr_vmcs12_fields =3D ARRAY_SIZE(vmcs_field_to_offset_ta= ble); +const unsigned int nr_vmcs12_fields =3D ARRAY_SIZE(vmcs12_field_offsets); diff --git a/arch/x86/kvm/vmx/vmcs12.h b/arch/x86/kvm/vmx/vmcs12.h index 2a45f026ee11..746129ddd5ae 100644 --- a/arch/x86/kvm/vmx/vmcs12.h +++ b/arch/x86/kvm/vmx/vmcs12.h @@ -361,10 +361,10 @@ static inline void vmx_check_vmcs12_offsets(void) CHECK_OFFSET(guest_pml_index, 996); } =20 -extern const unsigned short vmcs_field_to_offset_table[]; +extern const unsigned short vmcs12_field_offsets[]; extern const unsigned int nr_vmcs12_fields; =20 -static inline short vmcs_field_to_offset(unsigned long field) +static inline short get_vmcs12_field_offset(unsigned long field) { unsigned short offset; unsigned int index; @@ -377,7 +377,7 @@ static inline short vmcs_field_to_offset(unsigned long = field) return -ENOENT; =20 index =3D array_index_nospec(index, nr_vmcs12_fields); - offset =3D vmcs_field_to_offset_table[index]; + offset =3D vmcs12_field_offsets[index]; if (offset =3D=3D 0) return -ENOENT; return offset; --=20 2.34.1 From nobody Tue Jun 30 17:47:36 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D2E10C4332F for ; Wed, 12 Jan 2022 17:02:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355481AbiALRCD (ORCPT ); Wed, 12 Jan 2022 12:02:03 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:27260 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355435AbiALRBy (ORCPT ); Wed, 12 Jan 2022 12:01:54 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1642006913; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ZgYej9XbZ+Xa/X6Uh7UhuWNezHk2QG3G7eDzov+zY+E=; b=Hm48/Hgqx7gk4XU1yTc7c0Ex5yDysVAxZDNqEgmwBKzIHE3NoOew6GD/afpzOAclSvOeQF ceowJUEX/QTu5rM+yckZtQsGsTlklS3oNmMFhqD6XUFUmcez96aabd87ywJLKDhVBIxCbM rXFFPUWTfC3N9jbW7AXmVm3A6FehzyE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-590-J_5RRZwaN8maCVNhxIMYww-1; Wed, 12 Jan 2022 12:01:50 -0500 X-MC-Unique: J_5RRZwaN8maCVNhxIMYww-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 031F780574C; Wed, 12 Jan 2022 17:01:48 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.40.194.48]) by smtp.corp.redhat.com (Postfix) with ESMTP id E5C5A2B45F; Wed, 12 Jan 2022 17:01:45 +0000 (UTC) From: Vitaly Kuznetsov To: kvm@vger.kernel.org, Paolo Bonzini Cc: Sean Christopherson , Wanpeng Li , Jim Mattson , Maxim Levitsky , linux-kernel@vger.kernel.org Subject: [PATCH v3 4/5] KVM: nVMX: Implement evmcs_field_offset() suitable for handle_vmread() Date: Wed, 12 Jan 2022 18:01:33 +0100 Message-Id: <20220112170134.1904308-5-vkuznets@redhat.com> In-Reply-To: <20220112170134.1904308-1-vkuznets@redhat.com> References: <20220112170134.1904308-1-vkuznets@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In preparation to allowing reads from Enlightened VMCS from handle_vmread(), implement evmcs_field_offset() to get the correct read offset. get_evmcs_offset(), which is being used by KVM-on-Hyper-V, is almost what's needed but a few things need to be adjusted. First, WARN_ON() is unacceptable for handle_vmread() as any field can (in theory) be supplied by the guest and not all fields are defined in eVMCS v1. Second, we need to handle 'holes' in eVMCS (missing fields). It also sounds like a good idea to WARN_ON() if such fields are ever accessed by KVM-on-Hyper-V. Implement dedicated evmcs_field_offset() helper. No functional change intended. Signed-off-by: Vitaly Kuznetsov --- arch/x86/kvm/vmx/evmcs.c | 3 +-- arch/x86/kvm/vmx/evmcs.h | 32 ++++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/vmx/evmcs.c b/arch/x86/kvm/vmx/evmcs.c index a7ed30d5647a..87e3dc10edf4 100644 --- a/arch/x86/kvm/vmx/evmcs.c +++ b/arch/x86/kvm/vmx/evmcs.c @@ -12,8 +12,6 @@ =20 DEFINE_STATIC_KEY_FALSE(enable_evmcs); =20 -#if IS_ENABLED(CONFIG_HYPERV) - #define EVMCS1_OFFSET(x) offsetof(struct hv_enlightened_vmcs, x) #define EVMCS1_FIELD(number, name, clean_field)[ROL16(number, 6)] =3D \ {EVMCS1_OFFSET(name), clean_field} @@ -296,6 +294,7 @@ const struct evmcs_field vmcs_field_to_evmcs_1[] =3D { }; const unsigned int nr_evmcs_1_fields =3D ARRAY_SIZE(vmcs_field_to_evmcs_1); =20 +#if IS_ENABLED(CONFIG_HYPERV) __init void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf) { vmcs_conf->pin_based_exec_ctrl &=3D ~EVMCS1_UNSUPPORTED_PINCTRL; diff --git a/arch/x86/kvm/vmx/evmcs.h b/arch/x86/kvm/vmx/evmcs.h index 3a461a32128b..9bc2521b159e 100644 --- a/arch/x86/kvm/vmx/evmcs.h +++ b/arch/x86/kvm/vmx/evmcs.h @@ -65,8 +65,6 @@ DECLARE_STATIC_KEY_FALSE(enable_evmcs); #define EVMCS1_UNSUPPORTED_VMENTRY_CTRL (VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CT= RL) #define EVMCS1_UNSUPPORTED_VMFUNC (VMX_VMFUNC_EPTP_SWITCHING) =20 -#if IS_ENABLED(CONFIG_HYPERV) - struct evmcs_field { u16 offset; u16 clean_field; @@ -75,26 +73,44 @@ struct evmcs_field { extern const struct evmcs_field vmcs_field_to_evmcs_1[]; extern const unsigned int nr_evmcs_1_fields; =20 -static __always_inline int get_evmcs_offset(unsigned long field, - u16 *clean_field) +static __always_inline int evmcs_field_offset(unsigned long field, + u16 *clean_field) { unsigned int index =3D ROL16(field, 6); const struct evmcs_field *evmcs_field; =20 - if (unlikely(index >=3D nr_evmcs_1_fields)) { - WARN_ONCE(1, "KVM: accessing unsupported EVMCS field %lx\n", - field); + if (unlikely(index >=3D nr_evmcs_1_fields)) return -ENOENT; - } =20 evmcs_field =3D &vmcs_field_to_evmcs_1[index]; =20 + /* + * Use offset=3D0 to detect holes in eVMCS. This offset belongs to + * 'revision_id' but this field has no encoding and is supposed to + * be accessed directly. + */ + if (unlikely(!evmcs_field->offset)) + return -ENOENT; + if (clean_field) *clean_field =3D evmcs_field->clean_field; =20 return evmcs_field->offset; } =20 +#if IS_ENABLED(CONFIG_HYPERV) + +static __always_inline int get_evmcs_offset(unsigned long field, + u16 *clean_field) +{ + int offset =3D evmcs_field_offset(field, clean_field); + + WARN_ONCE(offset < 0, "KVM: accessing unsupported EVMCS field %lx\n", + field); + + return offset; +} + static __always_inline void evmcs_write64(unsigned long field, u64 value) { u16 clean_field; --=20 2.34.1 From nobody Tue Jun 30 17:47:36 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 37F52C433EF for ; Wed, 12 Jan 2022 17:02:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355474AbiALRCC (ORCPT ); Wed, 12 Jan 2022 12:02:02 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:46945 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355421AbiALRBx (ORCPT ); Wed, 12 Jan 2022 12:01:53 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1642006912; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ckf4WGo4i4lnL9AHjNXuCyeOV9H88Iioo8xqSOOYCz8=; b=HLBa41P8+sYT1e2SpaIhJo2t8GE+gxDXPw0lqIAkZKmQo/W5fYXI9A4fydZm22xYamvj0j lv5q2PjSDP4Y3qAG6CNtlKnj+8uhAb7tIPrV9EKnOgWKbAy68DRJSegNuS8JjhBD7WGlC/ 0AZK+dnpvYzbbXPGSeSLE1OlxVV7sfk= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-62-JKn_c-JTPaWkXM-1pdRcCA-1; Wed, 12 Jan 2022 12:01:51 -0500 X-MC-Unique: JKn_c-JTPaWkXM-1pdRcCA-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 73B89760C4; Wed, 12 Jan 2022 17:01:50 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.40.194.48]) by smtp.corp.redhat.com (Postfix) with ESMTP id 538C526DE0; Wed, 12 Jan 2022 17:01:48 +0000 (UTC) From: Vitaly Kuznetsov To: kvm@vger.kernel.org, Paolo Bonzini Cc: Sean Christopherson , Wanpeng Li , Jim Mattson , Maxim Levitsky , linux-kernel@vger.kernel.org Subject: [PATCH v3 5/5] KVM: nVMX: Allow VMREAD when Enlightened VMCS is in use Date: Wed, 12 Jan 2022 18:01:34 +0100 Message-Id: <20220112170134.1904308-6-vkuznets@redhat.com> In-Reply-To: <20220112170134.1904308-1-vkuznets@redhat.com> References: <20220112170134.1904308-1-vkuznets@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Hyper-V TLFS explicitly forbids VMREAD and VMWRITE instructions when Enlightened VMCS interface is in use: "Any VMREAD or VMWRITE instructions while an enlightened VMCS is active is unsupported and can result in unexpected behavior."" Windows 11 + WSL2 seems to ignore this, attempts to VMREAD VMCS field 0x4404 ("VM-exit interruption information") are observed. Failing these attempts with nested_vmx_failInvalid() makes such guests unbootable. Microsoft confirms this is a Hyper-V bug and claims that it'll get fixed eventually but for the time being we need a workaround. (Temporary) allow VMREAD to get data from the currently loaded Enlightened VMCS. Note: VMWRITE instructions remain forbidden, it is not clear how to handle them properly and hopefully won't ever be needed. Reviewed-by: Sean Christopherson Signed-off-by: Vitaly Kuznetsov --- arch/x86/kvm/vmx/evmcs.h | 12 +++++++++ arch/x86/kvm/vmx/nested.c | 55 +++++++++++++++++++++++++++------------ 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/arch/x86/kvm/vmx/evmcs.h b/arch/x86/kvm/vmx/evmcs.h index 9bc2521b159e..8d70f9aea94b 100644 --- a/arch/x86/kvm/vmx/evmcs.h +++ b/arch/x86/kvm/vmx/evmcs.h @@ -98,6 +98,18 @@ static __always_inline int evmcs_field_offset(unsigned l= ong field, return evmcs_field->offset; } =20 +static inline u64 evmcs_read_any(struct hv_enlightened_vmcs *evmcs, + unsigned long field, u16 offset) +{ + /* + * vmcs12_read_any() doesn't care whether the supplied structure + * is 'struct vmcs12' or 'struct hv_enlightened_vmcs' as it takes + * the exact offset of the required field, use it for convenience + * here. + */ + return vmcs12_read_any((void *)evmcs, field, offset); +} + #if IS_ENABLED(CONFIG_HYPERV) =20 static __always_inline int get_evmcs_offset(unsigned long field, diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 5941ba05b509..9758448479b4 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -7,6 +7,7 @@ #include =20 #include "cpuid.h" +#include "evmcs.h" #include "hyperv.h" #include "mmu.h" #include "nested.h" @@ -5099,27 +5100,49 @@ static int handle_vmread(struct kvm_vcpu *vcpu) if (!nested_vmx_check_permission(vcpu)) return 1; =20 - /* - * In VMX non-root operation, when the VMCS-link pointer is INVALID_GPA, - * any VMREAD sets the ALU flags for VMfailInvalid. - */ - if (vmx->nested.current_vmptr =3D=3D INVALID_GPA || - (is_guest_mode(vcpu) && - get_vmcs12(vcpu)->vmcs_link_pointer =3D=3D INVALID_GPA)) - return nested_vmx_failInvalid(vcpu); - /* Decode instruction info and find the field to read */ field =3D kvm_register_read(vcpu, (((instr_info) >> 28) & 0xf)); =20 - offset =3D get_vmcs12_field_offset(field); - if (offset < 0) - return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); + if (!evmptr_is_valid(vmx->nested.hv_evmcs_vmptr)) { + /* + * In VMX non-root operation, when the VMCS-link pointer is INVALID_GPA, + * any VMREAD sets the ALU flags for VMfailInvalid. + */ + if (vmx->nested.current_vmptr =3D=3D INVALID_GPA || + (is_guest_mode(vcpu) && + get_vmcs12(vcpu)->vmcs_link_pointer =3D=3D INVALID_GPA)) + return nested_vmx_failInvalid(vcpu); =20 - if (!is_guest_mode(vcpu) && is_vmcs12_ext_field(field)) - copy_vmcs02_to_vmcs12_rare(vcpu, vmcs12); + offset =3D get_vmcs12_field_offset(field); + if (offset < 0) + return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); + + if (!is_guest_mode(vcpu) && is_vmcs12_ext_field(field)) + copy_vmcs02_to_vmcs12_rare(vcpu, vmcs12); + + /* Read the field, zero-extended to a u64 value */ + value =3D vmcs12_read_any(vmcs12, field, offset); + } else { + /* + * Hyper-V TLFS (as of 6.0b) explicitly states, that while an + * enlightened VMCS is active VMREAD/VMWRITE instructions are + * unsupported. Unfortunately, certain versions of Windows 11 + * don't comply with this requirement which is not enforced in + * genuine Hyper-V. Allow VMREAD from an enlightened VMCS as a + * workaround, as misbehaving guests will panic on VM-Fail. + * Note, enlightened VMCS is incompatible with shadow VMCS so + * all VMREADs from L2 should go to L1. + */ + if (WARN_ON_ONCE(is_guest_mode(vcpu))) + return nested_vmx_failInvalid(vcpu); =20 - /* Read the field, zero-extended to a u64 value */ - value =3D vmcs12_read_any(vmcs12, field, offset); + offset =3D evmcs_field_offset(field, NULL); + if (offset < 0) + return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); + + /* Read the field, zero-extended to a u64 value */ + value =3D evmcs_read_any(vmx->nested.hv_evmcs, field, offset); + } =20 /* * Now copy part of this value to register or memory, as requested. --=20 2.34.1