From nobody Wed Apr 29 02:00:47 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 7C715C433FE for ; Wed, 25 May 2022 21:05:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345335AbiEYVFJ (ORCPT ); Wed, 25 May 2022 17:05:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51480 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240401AbiEYVEy (ORCPT ); Wed, 25 May 2022 17:04:54 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 43936BA575 for ; Wed, 25 May 2022 14:04:53 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id r1-20020a17090a0ac100b001e0ab5fc247so1370644pje.8 for ; Wed, 25 May 2022 14:04:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=rTk+kQv/DhUHKGEj1i4pX5+LtvnOz973xS0Whw/Q98g=; b=RFtPtJn9KDxsUbYxBjoB3gJDcTmRaiAfkqkiwg+RwPIwB6CJ4e7iZh7yUn8BTUiW/n sV+k9a0mUcslhj/xWFHXpdycRBH4k5GJmfbk95lyRyexQwuqDHuQrjlC5M9AWTjIx6fS kUr+9Qu1+XCKOWAIlpRwgA8AgXNKj2CdUWOQD72mclcXL5Yrarf9WWWY2mhSWcNS6JEi yz0VhohFOBovWUcwmMexirtUzLx18ont4vb+rhPl/kRhl3NkZ1E5c9fFyfisHkRtz1cp a64wVfYirqM/bY9RHf3EImPbCJfkwjKGt/8zH6yhXKCnYnwGipQNZAy3GVT4skpcASES Wnow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=rTk+kQv/DhUHKGEj1i4pX5+LtvnOz973xS0Whw/Q98g=; b=gUq5OGoANFVYL7dZmS2eDfsCEaewTizo+X77+fxLJkaohdeLIGMMtNtdcU8iryDbpm CJW24irrwTLZXVqw96T7kzkhpkFuaavtaSlRiI2edliAm97eTZ11MEOUqofUIiiLgPvO c7wyehcevQFvU7XLr6QZsCue3ZI1vG1bXXn/FlMnHrgDmgItcPls05jqZ2pI0A9qKJna 0h5QMZ7mu6QbLLGP4AHyDUay1D8SUmIuJYCEkU9yWmGoU81hOdNPvdBzHnY2xh0jDxnc zdo4wWFAhk4qa+dCAOFSeIy0CoGBn1Oj17pQuH0+n/iPMhH1gpyjj+kc6q4l/UoUT1EU yg1w== X-Gm-Message-State: AOAM532zEjfdEQqYntQSeHbCOU72gkesKjGW5dZUY2n8ezIWDBCSribt LVcH2Pu99ezzbXD66J1uYzlmKFKhX0c= X-Google-Smtp-Source: ABdhPJyjHo0RNZ+CWfGHH+uOuTDcz2WuFcVLTXIUiG3R7JG7ghn5fEyPuW9gCYA0Zho5BOlksmCXUfYqfBk= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:90a:249:b0:1e0:a8a3:3c6c with SMTP id t9-20020a17090a024900b001e0a8a33c6cmr26303pje.0.1653512692196; Wed, 25 May 2022 14:04:52 -0700 (PDT) Reply-To: Sean Christopherson Date: Wed, 25 May 2022 21:04:46 +0000 In-Reply-To: <20220525210447.2758436-1-seanjc@google.com> Message-Id: <20220525210447.2758436-2-seanjc@google.com> Mime-Version: 1.0 References: <20220525210447.2758436-1-seanjc@google.com> X-Mailer: git-send-email 2.36.1.124.g0e6072fb45-goog Subject: [PATCH 1/2] KVM: VMX: Sanitize VM-Entry/VM-Exit control pairs at kvm_intel load time From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Chenyi Qiang , Lei Wang Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Sanitize the VM-Entry/VM-Exit control pairs (load+load or load+clear) during setup instead of checking both controls in a pair at runtime. If only one control is supported, KVM will report the associated feature as not available, but will leave the supported control bit set in the VMCS config, which could lead to corruption of host state. E.g. if only the VM-Entry control is supported and the feature is not dynamically toggled, KVM will set the control in all VMCSes and load zeros without restoring host state. Note, while this is technically a bug fix, practically speaking no sane CPU or VMM would support only one control. KVM's behavior of checking both controls is mostly pedantry. Cc: Chenyi Qiang Cc: Lei Wang Signed-off-by: Sean Christopherson --- arch/x86/kvm/vmx/capabilities.h | 13 ++++-------- arch/x86/kvm/vmx/vmx.c | 35 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilitie= s.h index dc2cb8a16e76..464bf39e4835 100644 --- a/arch/x86/kvm/vmx/capabilities.h +++ b/arch/x86/kvm/vmx/capabilities.h @@ -97,20 +97,17 @@ static inline bool cpu_has_vmx_posted_intr(void) =20 static inline bool cpu_has_load_ia32_efer(void) { - return (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_EFER) && - (vmcs_config.vmexit_ctrl & VM_EXIT_LOAD_IA32_EFER); + return vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_EFER; } =20 static inline bool cpu_has_load_perf_global_ctrl(void) { - return (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL) && - (vmcs_config.vmexit_ctrl & VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL); + return vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL; } =20 static inline bool cpu_has_vmx_mpx(void) { - return (vmcs_config.vmexit_ctrl & VM_EXIT_CLEAR_BNDCFGS) && - (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_BNDCFGS); + return vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_BNDCFGS; } =20 static inline bool cpu_has_vmx_tpr_shadow(void) @@ -377,7 +374,6 @@ static inline bool cpu_has_vmx_intel_pt(void) rdmsrl(MSR_IA32_VMX_MISC, vmx_msr); return (vmx_msr & MSR_IA32_VMX_MISC_INTEL_PT) && (vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_PT_USE_GPA) && - (vmcs_config.vmexit_ctrl & VM_EXIT_CLEAR_IA32_RTIT_CTL) && (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_RTIT_CTL); } =20 @@ -406,8 +402,7 @@ static inline bool vmx_pebs_supported(void) =20 static inline bool cpu_has_vmx_arch_lbr(void) { - return (vmcs_config.vmexit_ctrl & VM_EXIT_CLEAR_IA32_LBR_CTL) && - (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_LBR_CTL); + return vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_LBR_CTL; } =20 static inline u64 vmx_get_perf_capabilities(void) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 6927f6e8ec31..2ea256de9aba 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2462,6 +2462,9 @@ static __init u64 adjust_vmx_controls64(u64 ctl_opt, = u32 msr) return ctl_opt & allowed; } =20 +#define VMCS_ENTRY_EXIT_PAIR(name, entry_action, exit_action) \ + { VM_ENTRY_##entry_action##_##name, VM_EXIT_##exit_action##_##name } + static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, struct vmx_capability *vmx_cap) { @@ -2473,6 +2476,24 @@ static __init int setup_vmcs_config(struct vmcs_conf= ig *vmcs_conf, u64 _cpu_based_3rd_exec_control =3D 0; u32 _vmexit_control =3D 0; u32 _vmentry_control =3D 0; + int i; + + /* + * LOAD/SAVE_DEBUG_CONTROLS are absent because both are mandatory. + * SAVE_IA32_PAT and SAVE_IA32_EFER are absent because KVM always + * intercepts writes to PAT and EFER, i.e. never enables those controls. + */ + struct { + u32 entry_control; + u32 exit_control; + } vmcs_entry_exit_pairs[] =3D { + VMCS_ENTRY_EXIT_PAIR(IA32_PERF_GLOBAL_CTRL, LOAD, LOAD), + VMCS_ENTRY_EXIT_PAIR(IA32_PAT, LOAD, LOAD), + VMCS_ENTRY_EXIT_PAIR(IA32_EFER, LOAD, LOAD), + VMCS_ENTRY_EXIT_PAIR(BNDCFGS, LOAD, CLEAR), + VMCS_ENTRY_EXIT_PAIR(IA32_RTIT_CTL, LOAD, CLEAR), + VMCS_ENTRY_EXIT_PAIR(IA32_LBR_CTL, LOAD, CLEAR), + }; =20 memset(vmcs_conf, 0, sizeof(*vmcs_conf)); min =3D CPU_BASED_HLT_EXITING | @@ -2614,6 +2635,20 @@ static __init int setup_vmcs_config(struct vmcs_conf= ig *vmcs_conf, &_vmentry_control) < 0) return -EIO; =20 + for (i =3D 0; i < ARRAY_SIZE(vmcs_entry_exit_pairs); i++) { + u32 n_ctrl =3D vmcs_entry_exit_pairs[i].entry_control; + u32 x_ctrl =3D vmcs_entry_exit_pairs[i].exit_control; + + if (!(_vmentry_control & n_ctrl) =3D=3D !(_vmexit_control & x_ctrl)) + continue; + + pr_warn_once("Inconsistent VM-Entry/VM-Exit pair, entry =3D %x, exit =3D= %x\n", + _vmentry_control & n_ctrl, _vmexit_control & x_ctrl); + + _vmentry_control &=3D ~n_ctrl; + _vmexit_control &=3D ~x_ctrl; + } + /* * Some cpus support VM_{ENTRY,EXIT}_IA32_PERF_GLOBAL_CTRL but they * can't be used due to an errata where VM Exit may incorrectly clear --=20 2.36.1.124.g0e6072fb45-goog From nobody Wed Apr 29 02:00:47 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 D7E3AC433F5 for ; Wed, 25 May 2022 21:05:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345344AbiEYVFL (ORCPT ); Wed, 25 May 2022 17:05:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51536 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345306AbiEYVE4 (ORCPT ); Wed, 25 May 2022 17:04:56 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EBADDBA987 for ; Wed, 25 May 2022 14:04:54 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id s2-20020a17090302c200b00158ea215fa2so12025278plk.3 for ; Wed, 25 May 2022 14:04:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=MhaLoQZ1Fyr7auQaaGwZIF1CIB1ncwG+XDZ6YBvLp+8=; b=pOU+xT+m1FY14bCe7Wn4C4cI9rQ2r/blGdne2/f1klpaNUKUs7LnB6EVqakiS2Gy3F akMTb7DrECv/A/2MLwJu6D1rkU9WpYBzEWTX5wrR0SI7oPiiLK+yrgDH7XbN2Xh0FQhv 1m4+/7pYJU8YBip/CF6SWftM0QNjn5QTBLSYfFr3n6rclTrMcoFMIja25VrVWNLIYf8t UcB5Vl+2Ejo46pltBVjijJZp4D70OpiIkKjfDJYoKil4HzXqZZo2x3bwAKzeRdOT1QiN eoo1IEbsT1rMlH9cp5aesyQTkEupmjefEHCQOpi3aXVIQLujcuKTiJtOil5vE+zYFQvs 8GrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=MhaLoQZ1Fyr7auQaaGwZIF1CIB1ncwG+XDZ6YBvLp+8=; b=gCfavBCvEzzi6vZ/LvOJNY6Ht5yD1QVkt2T8alWy1cIq7jyahMGgxTZJBWO+MMjI5N AnlofseZ7aLynA1D4cRNgycHbWPV4S0i4oaLLiwuxXeqVid7zVFvogYtWiezzuQgx/A5 g8RyY8kHpf+ogA5oqZMed9TJ+NhbP92s0eKSTQt4GM88oFVC1wy57rq+nx50McR0YZ3K jLf9Uhy8AbVyT30u7SPmsuTJRy4TY07mdfC3jRNuFtB4Xv265H9FjMKM+i2nou/ijPc4 mDV6pldgX6NY3A2bD1W76JUeV5fN9UbvktH362rKeg/x8oNJh5FExrYoo0OVG+N88RH7 s5Ag== X-Gm-Message-State: AOAM532l/zfDBseRtpMYDVmSiyUrz+UsOfGvU/YLgtFb23ZVsrhb7lFM 1fkb4ZKbSKAxisEvXxrfNglWAVU6ZEc= X-Google-Smtp-Source: ABdhPJy8yjwRd0sOfqXZIqlFPLl4fjOVh9U/pVVwxzIHTqp/Fmtviv7/AnGVk6DF1xCKPLg+D8Yz+A/vrZc= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a63:4:0:b0:3c6:cce2:8457 with SMTP id 4-20020a630004000000b003c6cce28457mr29605276pga.612.1653512694310; Wed, 25 May 2022 14:04:54 -0700 (PDT) Reply-To: Sean Christopherson Date: Wed, 25 May 2022 21:04:47 +0000 In-Reply-To: <20220525210447.2758436-1-seanjc@google.com> Message-Id: <20220525210447.2758436-3-seanjc@google.com> Mime-Version: 1.0 References: <20220525210447.2758436-1-seanjc@google.com> X-Mailer: git-send-email 2.36.1.124.g0e6072fb45-goog Subject: [PATCH 2/2] KVM: VMX: Add knob to allow rejecting kvm_intel on inconsistent VMCS config From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Chenyi Qiang , Lei Wang Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add an off-by-default module param, reject_inconsistent_vmcs_config, to allow rejecting the load of kvm_intel if an inconsistent VMCS config is detected. Continuing on with an inconsistent, degraded config is undesirable when the CPU is expected to support a given set of features, e.g. can result in a misconfigured VM if userspace doesn't cross-check KVM_GET_SUPPORTED_CPUID, and/or can result in poor performance due to lack of fast MSR switching. Signed-off-by: Sean Christopherson --- arch/x86/kvm/vmx/vmx.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 2ea256de9aba..11413a8cc57f 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -119,6 +119,9 @@ module_param(nested, bool, S_IRUGO); bool __read_mostly enable_pml =3D 1; module_param_named(pml, enable_pml, bool, S_IRUGO); =20 +static bool __read_mostly reject_inconsistent_vmcs_config; +module_param(reject_inconsistent_vmcs_config, bool, 0444); + static bool __read_mostly dump_invalid_vmcs =3D 0; module_param(dump_invalid_vmcs, bool, 0644); =20 @@ -2577,15 +2580,23 @@ static __init int setup_vmcs_config(struct vmcs_con= fig *vmcs_conf, CPU_BASED_CR3_STORE_EXITING | CPU_BASED_INVLPG_EXITING); } else if (vmx_cap->ept) { - vmx_cap->ept =3D 0; pr_warn_once("EPT CAP should not exist if not support " "1-setting enable EPT VM-execution control\n"); + + if (reject_inconsistent_vmcs_config) + return -EIO; + + vmx_cap->ept =3D 0; } if (!(_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_VPID) && - vmx_cap->vpid) { - vmx_cap->vpid =3D 0; + vmx_cap->vpid) { pr_warn_once("VPID CAP should not exist if not support " "1-setting enable VPID VM-execution control\n"); + + if (reject_inconsistent_vmcs_config) + return -EIO; + + vmx_cap->vpid =3D 0; } =20 if (_cpu_based_exec_control & CPU_BASED_ACTIVATE_TERTIARY_CONTROLS) { @@ -2645,6 +2656,9 @@ static __init int setup_vmcs_config(struct vmcs_confi= g *vmcs_conf, pr_warn_once("Inconsistent VM-Entry/VM-Exit pair, entry =3D %x, exit =3D= %x\n", _vmentry_control & n_ctrl, _vmexit_control & x_ctrl); =20 + if (reject_inconsistent_vmcs_config) + return -EIO; + _vmentry_control &=3D ~n_ctrl; _vmexit_control &=3D ~x_ctrl; } --=20 2.36.1.124.g0e6072fb45-goog