Received: by 2002:a05:7412:2a8a:b0:fc:a2b0:25d7 with SMTP id u10csp481616rdh; Wed, 7 Feb 2024 10:10:21 -0800 (PST) X-Google-Smtp-Source: AGHT+IFe5Uxf6RIQKTwljhHEsKPV7Qc7I9f741oxoHQ9LsKyftEIvhm1z1f0BwOnpCKkszZUm4cn X-Received: by 2002:a17:903:25d3:b0:1d9:8d17:87b8 with SMTP id jc19-20020a17090325d300b001d98d1787b8mr5624933plb.34.1707329420935; Wed, 07 Feb 2024 10:10:20 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707329420; cv=pass; d=google.com; s=arc-20160816; b=nwKT/3+/A3YtxuKCXiLlPRyDOEoQj+32XAR0XVcpn/t7Ci9mdEeonVkM+zc+zzkiLs quuc7yeWNXL/wX35LKIFf8kAQL/ETVHHxF3D8L6P8vecuqUnhLMXE5qrGJuFx6OBLIV6 UERqsB2WIDjstDd5AxPFyvH7Xa2okeLMzrzAeIWmB5JBmxe8z+A2nvkMbcKZuXwPA0to 5hINye/ejlj2VxnZMLH3MrYR0vzd3c0a29MMQA2Nhdyx/AjR0VO0NHI3YLNC7ZKm6yRX YRQRmUOPbsuoqDMvZbp8e9TDmxt17nyFD+zOzICamAWfK9VHbz3q8FzGOaDYYtnJAWLs oIQA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=uMO1Y+oL/XrkJbW76cF112alMXp1WOf3yaXz6ZXeQhg=; fh=cWGIregYZU5BJ5RNMTZn94OnPjkJIirdMca7OyFa35I=; b=tBLUj9JfThpgo/TwDaBWWJrtMzZ4buDwEzqb3tG+LSLA+8JtrrUAXWkIbtTB+23RLS 9/PJ6DAUm1QHY66RkCJBsysK75N2he7wY35AsEBNxc69fYee3GqE5qZCS8yaUKNyoHXT w4ok14wGKK5UWwXJEQW4TNY2VQrjbhj3FqrQ/Mb13moGhd7PAw66IahTrvs/UknyoKG/ TVdiu2JeuyBDMjDEdTPpzEbxQGH92lgSpwdnQwV45DSEe+DvSU6+53GqydTloyP6VMW9 VsB7k+RQ64VMRNee0l36yKk1YIKMhbsmZNSEqfxmrjlzhhf+0xUhh9ITheLpxmiVP4jW wXLA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=gRavKVRV; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-56879-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-56879-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Forwarded-Encrypted: i=2; AJvYcCWOfhyavG1BWbzj9H0QbWL5XzBv1lirJnZOnkG0OQOSp+PM8ZDafAiTtWxU7108/lhBJvEAVTaBX2smeuf/d27QrganCC6EpdY/RpqKXg== Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id n9-20020a170902d2c900b001d99acc35b8si2362065plc.573.2024.02.07.10.10.20 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Feb 2024 10:10:20 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-56879-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=gRavKVRV; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-56879-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-56879-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id D09CD28501A for ; Wed, 7 Feb 2024 18:09:17 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1A4AA1386B1; Wed, 7 Feb 2024 17:59:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="gRavKVRV" Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7F3DA135400; Wed, 7 Feb 2024 17:59:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.11 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707328767; cv=none; b=Ux9iTZfhROBcqiYqIYCr6nLbHPg1GDddBbqSPTiEQzNJf/d+wAgpwdtLk4EBGW30xeGwY0vYboEuL0XoTgVLMaeStY/TUIMp2u8VYaw0MtyBWAfb8a16glWKnb0Va7sgQjKNollBLTEuxlsWs2D6H1sBXqc0ESFF0/ADD6LoLsA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707328767; c=relaxed/simple; bh=8BZSbnRLnmeG5U3FhWc8N6oHSSHjwpiY4v6RG2oTEPU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Tuq3na8c8z14G9q0/gEdrqPKEKX8CbidNTIbW26JkbcGy2qIxQfuYYii55B9p7FMiEUX0vpD3cWd6hxJFYDrup8ts/AbmiVa2DAmfnyCpF3HMZK5MNbHg1vOy4HQB7KZsNc6VnWkgmr8pvE0aFuvv6fYWoJ3oLGyddCzBW+0UOk= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=gRavKVRV; arc=none smtp.client-ip=198.175.65.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1707328762; x=1738864762; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=8BZSbnRLnmeG5U3FhWc8N6oHSSHjwpiY4v6RG2oTEPU=; b=gRavKVRVYLF5Y1IJIGGdYroeqglKfJBzP3K/c3JGbwQQyj17SoFPkybk qRJZcopbgzT6Y/XRJfETHY4q7VsqVjT2IMUwldJfYU42ZrQlXfQB+AQ4N oKVwyIumgAppac5cLjjxzH53BVFeth6X9ldafNR9uhQ95qg0GkdG2OmAi FDrTEpeef/R7YKgnemkqefmhu8xdqnlc1OK6s3BjBfNSaY5ZCxzqu63ZT qH5WY1a6UzPPcEpXt20VSpj/TXCxPd/EkYvmJaV/e3Lsdu32jT4uuiY4U 9JDfoKjAclZvo/3dzmVRyE2eyu0T/ft2OzZN8bwI3zOPbmCYtIBRyIsoS w==; X-IronPort-AV: E=McAfee;i="6600,9927,10977"; a="11622668" X-IronPort-AV: E=Sophos;i="6.05,251,1701158400"; d="scan'208";a="11622668" Received: from fmviesa004.fm.intel.com ([10.60.135.144]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Feb 2024 09:59:00 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,251,1701158400"; d="scan'208";a="6020762" Received: from unknown (HELO fred..) ([172.25.112.68]) by fmviesa004.fm.intel.com with ESMTP; 07 Feb 2024 09:58:59 -0800 From: Xin Li To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: seanjc@google.com, pbonzini@redhat.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, shuah@kernel.org, vkuznets@redhat.com, peterz@infradead.org, ravi.v.shankar@intel.com, xin@zytor.com Subject: [PATCH v2 21/25] KVM: nVMX: Add VMCS FRED states checking Date: Wed, 7 Feb 2024 09:26:41 -0800 Message-ID: <20240207172646.3981-22-xin3.li@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240207172646.3981-1-xin3.li@intel.com> References: <20240207172646.3981-1-xin3.li@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Add FRED related VMCS fields checkings. As real hardware, nested VMX performs checks on various VMCS fields, including both controls and guest/host states. With the introduction of VMX FRED, add FRED related VMCS fields checkings. Signed-off-by: Xin Li Tested-by: Shan Kang --- arch/x86/kvm/vmx/nested.c | 80 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 04a9cdb0361f..ef0bd46eb0ce 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2933,6 +2933,8 @@ static int nested_check_vm_entry_controls(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) { struct vcpu_vmx *vmx = to_vmx(vcpu); + bool fred_enabled = (vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) && + (vmcs12->guest_cr4 & X86_CR4_FRED); if (CC(!vmx_control_verify(vmcs12->vm_entry_controls, vmx->nested.msrs.entry_ctls_low, @@ -2951,6 +2953,7 @@ static int nested_check_vm_entry_controls(struct kvm_vcpu *vcpu, u32 intr_type = intr_info & INTR_INFO_INTR_TYPE_MASK; bool has_error_code = intr_info & INTR_INFO_DELIVER_CODE_MASK; bool should_have_error_code; + bool has_nested_exception = vmx->nested.msrs.basic & VMX_BASIC_NESTED_EXCEPTION; bool urg = nested_cpu_has2(vmcs12, SECONDARY_EXEC_UNRESTRICTED_GUEST); bool prot_mode = !urg || vmcs12->guest_cr0 & X86_CR0_PE; @@ -2964,7 +2967,9 @@ static int nested_check_vm_entry_controls(struct kvm_vcpu *vcpu, /* VM-entry interruption-info field: vector */ if (CC(intr_type == INTR_TYPE_NMI_INTR && vector != NMI_VECTOR) || CC(intr_type == INTR_TYPE_HARD_EXCEPTION && vector > 31) || - CC(intr_type == INTR_TYPE_OTHER_EVENT && vector != 0)) + CC(intr_type == INTR_TYPE_OTHER_EVENT && + ((!fred_enabled && vector > 0) || + (fred_enabled && vector > 2)))) return -EINVAL; /* VM-entry interruption-info field: deliver error code */ @@ -2983,6 +2988,15 @@ static int nested_check_vm_entry_controls(struct kvm_vcpu *vcpu, if (CC(intr_info & INTR_INFO_RESVD_BITS_MASK)) return -EINVAL; + /* + * When the CPU enumerates VMX nested-exception support, bit 13 + * (set to indicate a nested exception) of the intr info field + * may have value 1. Otherwise bit 13 is reserved. + */ + if (CC(!has_nested_exception && + (intr_info & INTR_INFO_NESTED_EXCEPTION_MASK))) + return -EINVAL; + /* VM-entry instruction length */ switch (intr_type) { case INTR_TYPE_SOFT_EXCEPTION: @@ -2992,6 +3006,12 @@ static int nested_check_vm_entry_controls(struct kvm_vcpu *vcpu, CC(vmcs12->vm_entry_instruction_len == 0 && CC(!nested_cpu_has_zero_length_injection(vcpu)))) return -EINVAL; + break; + case INTR_TYPE_OTHER_EVENT: + if (fred_enabled && (vector == 1 || vector == 2)) + if (CC(vmcs12->vm_entry_instruction_len > 15)) + return -EINVAL; + break; } } @@ -3054,9 +3074,30 @@ static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu, if (ia32e) { if (CC(!(vmcs12->host_cr4 & X86_CR4_PAE))) return -EINVAL; + if (vmcs12->vm_exit_controls & VM_EXIT_ACTIVATE_SECONDARY_CONTROLS && + vmcs12->secondary_vm_exit_controls & SECONDARY_VM_EXIT_LOAD_IA32_FRED) { + /* Bit 11, bits 5:4, and bit 2 of the IA32_FRED_CONFIG must be zero */ + if (CC(vmcs12->host_ia32_fred_config & + (BIT_ULL(11) | GENMASK_ULL(5, 4) | BIT_ULL(2))) || + CC(vmcs12->host_ia32_fred_rsp1 & GENMASK_ULL(5, 0)) || + CC(vmcs12->host_ia32_fred_rsp2 & GENMASK_ULL(5, 0)) || + CC(vmcs12->host_ia32_fred_rsp3 & GENMASK_ULL(5, 0)) || + CC(vmcs12->host_ia32_fred_ssp1 & GENMASK_ULL(2, 0)) || + CC(vmcs12->host_ia32_fred_ssp2 & GENMASK_ULL(2, 0)) || + CC(vmcs12->host_ia32_fred_ssp3 & GENMASK_ULL(2, 0)) || + CC(is_noncanonical_address(vmcs12->host_ia32_fred_config & PAGE_MASK, vcpu)) || + CC(is_noncanonical_address(vmcs12->host_ia32_fred_rsp1, vcpu)) || + CC(is_noncanonical_address(vmcs12->host_ia32_fred_rsp2, vcpu)) || + CC(is_noncanonical_address(vmcs12->host_ia32_fred_rsp3, vcpu)) || + CC(is_noncanonical_address(vmcs12->host_ia32_fred_ssp1, vcpu)) || + CC(is_noncanonical_address(vmcs12->host_ia32_fred_ssp2, vcpu)) || + CC(is_noncanonical_address(vmcs12->host_ia32_fred_ssp3, vcpu))) + return -EINVAL; + } } else { if (CC(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) || CC(vmcs12->host_cr4 & X86_CR4_PCIDE) || + CC(vmcs12->host_cr4 & X86_CR4_FRED) || CC((vmcs12->host_rip) >> 32)) return -EINVAL; } @@ -3200,6 +3241,43 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu, CC((vmcs12->guest_bndcfgs & MSR_IA32_BNDCFGS_RSVD)))) return -EINVAL; + if (ia32e) { + if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_FRED) { + /* Bit 11, bits 5:4, and bit 2 of the IA32_FRED_CONFIG must be zero */ + if (CC(vmcs12->guest_ia32_fred_config & + (BIT_ULL(11) | GENMASK_ULL(5, 4) | BIT_ULL(2))) || + CC(vmcs12->guest_ia32_fred_rsp1 & GENMASK_ULL(5, 0)) || + CC(vmcs12->guest_ia32_fred_rsp2 & GENMASK_ULL(5, 0)) || + CC(vmcs12->guest_ia32_fred_rsp3 & GENMASK_ULL(5, 0)) || + CC(vmcs12->guest_ia32_fred_ssp1 & GENMASK_ULL(2, 0)) || + CC(vmcs12->guest_ia32_fred_ssp2 & GENMASK_ULL(2, 0)) || + CC(vmcs12->guest_ia32_fred_ssp3 & GENMASK_ULL(2, 0)) || + CC(is_noncanonical_address(vmcs12->guest_ia32_fred_config & PAGE_MASK, vcpu)) || + CC(is_noncanonical_address(vmcs12->guest_ia32_fred_rsp1, vcpu)) || + CC(is_noncanonical_address(vmcs12->guest_ia32_fred_rsp2, vcpu)) || + CC(is_noncanonical_address(vmcs12->guest_ia32_fred_rsp3, vcpu)) || + CC(is_noncanonical_address(vmcs12->guest_ia32_fred_ssp1, vcpu)) || + CC(is_noncanonical_address(vmcs12->guest_ia32_fred_ssp2, vcpu)) || + CC(is_noncanonical_address(vmcs12->guest_ia32_fred_ssp3, vcpu))) + return -EINVAL; + } + if (vmcs12->guest_cr4 & X86_CR4_FRED) { + unsigned int ss_dpl = VMX_AR_DPL(vmcs12->guest_ss_ar_bytes); + if (CC(ss_dpl == 1 || ss_dpl == 2)) + return -EINVAL; + if (ss_dpl == 0 && + CC(!(vmcs12->guest_cs_ar_bytes & VMX_AR_L_MASK))) + return -EINVAL; + if (ss_dpl == 3 && + (CC(vmcs12->guest_rflags & X86_EFLAGS_IOPL) || + CC(vmcs12->guest_interruptibility_info & GUEST_INTR_STATE_STI))) + return -EINVAL; + } + } else { + if (CC(vmcs12->guest_cr4 & X86_CR4_FRED)) + return -EINVAL; + } + if (nested_check_guest_non_reg_state(vmcs12)) return -EINVAL; -- 2.43.0