From patchwork Tue Oct 1 05:00:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817465 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 74B261BBBC4; Tue, 1 Oct 2024 05:02:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; cv=none; b=qYIeyjU51Zg+o6zxCXDH3Q4z4xZRXxPXYqVWPAn0q7TPmeT3vXO7WKSWlqHr7mfCvRQyfLl8SYKMGVuhEpPHgAbQdUkjPk0dWArtsYbpYHpn1K7aOKGCIsqe5AwzDivUte8b8oCd9bvw329GmiZ2jYYVe13iA3kT5/H92PFQwVI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; c=relaxed/simple; bh=8YNK9wXy2zsLnEngVFVHxby7YzuTWyx2Tg67i8WAOIM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=suJdcmtyWeN2nrDXkbZQghe4cO+npdfzIOYag551MC61CTI7lfw7B7mmmbxGMz+8XsEJU1JS6nrkflIagBvV5EjQXyZbj4vLoVapu7e6gJ3MuQhykz7DARbDQDQpqdCP0huDqc7nQoddeXVNvVVA3VX0Nv1fS321d0FM4s2ndUA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=ZOcNA0vH; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="ZOcNA0vH" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7Q3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:16 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7Q3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758877; bh=oe8kgmrnvG5dIiA9spE8kuU3AD62wgZ4OuqY/m2GFl0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZOcNA0vHDvW3+FaN4G+KG7d8cCsW738HcbPHSYVgcMKYkYJokcbpNA61t2RLhuORr HTaHVyXBhqCxGGwgtOdR/Zaa4TP/wAOcQK4UsccT6UJuYtRxikvPZiwll18oYi0iaV xoA3hgEdpJh+gkTGkaZ45GG1C1Stoyk2KhRIcNzURCawu+6EbNN2UFEIbrfVyn8of9 8c1trLP6gmutHHuC/SpaYz9zNordD2C4nzfHAEZOGp/8xgXn8MhwYbun/QPMN9wq1F 90qZSxvYSlJ9OOomqUE/NuHUjclKWcS3u6ZQHPSsCJNVV9JnfQuqlz+bbYpCjgqTXl F9xxnp5NMrWTQ== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 01/27] KVM: x86: Use a dedicated flow for queueing re-injected exceptions Date: Mon, 30 Sep 2024 22:00:44 -0700 Message-ID: <20241001050110.3643764-2-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Sean Christopherson Open code the filling of vcpu->arch.exception in kvm_requeue_exception() instead of bouncing through kvm_multiple_exception(), as re-injection doesn't actually share that much code with "normal" injection, e.g. the VM-Exit interception check, payload delivery, and nested exception code is all bypassed as those flows only apply during initial injection. When FRED comes along, the special casing will only get worse, as FRED explicitly tracks nested exceptions and essentially delivers the payload on the stack frame, i.e. re-injection will need more inputs, and normal injection will have yet more code that needs to be bypassed when KVM is re-injecting an exception. No functional change intended. Signed-off-by: Sean Christopherson Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- arch/x86/include/asm/kvm_host.h | 4 +- arch/x86/kvm/svm/svm.c | 15 +++--- arch/x86/kvm/vmx/vmx.c | 16 +++--- arch/x86/kvm/x86.c | 89 ++++++++++++++++----------------- 4 files changed, 63 insertions(+), 61 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 6d9f763a7bb9..43b08d12cb32 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -2112,8 +2112,8 @@ int kvm_emulate_rdpmc(struct kvm_vcpu *vcpu); void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr); void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, unsigned long payload); -void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr); -void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); +void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned int nr, + bool has_error_code, u32 error_code); void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault); void kvm_inject_emulated_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault); diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 9df3e1e5ae81..d9e2568bcd54 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4112,20 +4112,23 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu) vcpu->arch.nmi_injected = true; svm->nmi_l1_to_l2 = nmi_l1_to_l2; break; - case SVM_EXITINTINFO_TYPE_EXEPT: + case SVM_EXITINTINFO_TYPE_EXEPT: { + u32 error_code = 0; + /* * Never re-inject a #VC exception. */ if (vector == X86_TRAP_VC) break; - if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) { - u32 err = svm->vmcb->control.exit_int_info_err; - kvm_requeue_exception_e(vcpu, vector, err); + if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) + error_code = svm->vmcb->control.exit_int_info_err; - } else - kvm_requeue_exception(vcpu, vector); + kvm_requeue_exception(vcpu, vector, + exitintinfo & SVM_EXITINTINFO_VALID_ERR, + error_code); break; + } case SVM_EXITINTINFO_TYPE_INTR: kvm_queue_interrupt(vcpu, vector, false); break; diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 1a4438358c5e..6a93f5edbc0d 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7136,13 +7136,17 @@ static void __vmx_complete_interrupts(struct kvm_vcpu *vcpu, case INTR_TYPE_SOFT_EXCEPTION: vcpu->arch.event_exit_inst_len = vmcs_read32(instr_len_field); fallthrough; - case INTR_TYPE_HARD_EXCEPTION: - if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) { - u32 err = vmcs_read32(error_code_field); - kvm_requeue_exception_e(vcpu, vector, err); - } else - kvm_requeue_exception(vcpu, vector); + case INTR_TYPE_HARD_EXCEPTION: { + u32 error_code = 0; + + if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) + error_code = vmcs_read32(error_code_field); + + kvm_requeue_exception(vcpu, vector, + idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK, + error_code); break; + } case INTR_TYPE_SOFT_INTR: vcpu->arch.event_exit_inst_len = vmcs_read32(instr_len_field); fallthrough; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 83fe0a78146f..e8de9f4734a6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -833,9 +833,9 @@ static void kvm_queue_exception_vmexit(struct kvm_vcpu *vcpu, unsigned int vecto ex->payload = payload; } -static void kvm_multiple_exception(struct kvm_vcpu *vcpu, - unsigned nr, bool has_error, u32 error_code, - bool has_payload, unsigned long payload, bool reinject) +static void kvm_multiple_exception(struct kvm_vcpu *vcpu, unsigned int nr, + bool has_error, u32 error_code, + bool has_payload, unsigned long payload) { u32 prev_nr; int class1, class2; @@ -843,13 +843,10 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu, kvm_make_request(KVM_REQ_EVENT, vcpu); /* - * If the exception is destined for L2 and isn't being reinjected, - * morph it to a VM-Exit if L1 wants to intercept the exception. A - * previously injected exception is not checked because it was checked - * when it was original queued, and re-checking is incorrect if _L1_ - * injected the exception, in which case it's exempt from interception. + * If the exception is destined for L2, morph it to a VM-Exit if L1 + * wants to intercept the exception. */ - if (!reinject && is_guest_mode(vcpu) && + if (is_guest_mode(vcpu) && kvm_x86_ops.nested_ops->is_exception_vmexit(vcpu, nr, error_code)) { kvm_queue_exception_vmexit(vcpu, nr, has_error, error_code, has_payload, payload); @@ -858,28 +855,9 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu, if (!vcpu->arch.exception.pending && !vcpu->arch.exception.injected) { queue: - if (reinject) { - /* - * On VM-Entry, an exception can be pending if and only - * if event injection was blocked by nested_run_pending. - * In that case, however, vcpu_enter_guest() requests an - * immediate exit, and the guest shouldn't proceed far - * enough to need reinjection. - */ - WARN_ON_ONCE(kvm_is_exception_pending(vcpu)); - vcpu->arch.exception.injected = true; - if (WARN_ON_ONCE(has_payload)) { - /* - * A reinjected event has already - * delivered its payload. - */ - has_payload = false; - payload = 0; - } - } else { - vcpu->arch.exception.pending = true; - vcpu->arch.exception.injected = false; - } + vcpu->arch.exception.pending = true; + vcpu->arch.exception.injected = false; + vcpu->arch.exception.has_error_code = has_error; vcpu->arch.exception.vector = nr; vcpu->arch.exception.error_code = error_code; @@ -920,29 +898,52 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu, void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr) { - kvm_multiple_exception(vcpu, nr, false, 0, false, 0, false); + kvm_multiple_exception(vcpu, nr, false, 0, false, 0); } EXPORT_SYMBOL_GPL(kvm_queue_exception); -void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr) -{ - kvm_multiple_exception(vcpu, nr, false, 0, false, 0, true); -} -EXPORT_SYMBOL_GPL(kvm_requeue_exception); void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, unsigned long payload) { - kvm_multiple_exception(vcpu, nr, false, 0, true, payload, false); + kvm_multiple_exception(vcpu, nr, false, 0, true, payload); } EXPORT_SYMBOL_GPL(kvm_queue_exception_p); static void kvm_queue_exception_e_p(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code, unsigned long payload) { - kvm_multiple_exception(vcpu, nr, true, error_code, - true, payload, false); + kvm_multiple_exception(vcpu, nr, true, error_code, true, payload); +} + +void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned int nr, + bool has_error_code, u32 error_code) +{ + + /* + * On VM-Entry, an exception can be pending if and only if event + * injection was blocked by nested_run_pending. In that case, however, + * vcpu_enter_guest() requests an immediate exit, and the guest + * shouldn't proceed far enough to need reinjection. + */ + WARN_ON_ONCE(kvm_is_exception_pending(vcpu)); + + /* + * Do not check for interception when injecting an event for L2, as the + * exception was checked for intercept when it was original queued, and + * re-checking is incorrect if _L1_ injected the exception, in which + * case it's exempt from interception. + */ + kvm_make_request(KVM_REQ_EVENT, vcpu); + + vcpu->arch.exception.injected = true; + vcpu->arch.exception.has_error_code = has_error_code; + vcpu->arch.exception.vector = nr; + vcpu->arch.exception.error_code = error_code; + vcpu->arch.exception.has_payload = false; + vcpu->arch.exception.payload = 0; } +EXPORT_SYMBOL_GPL(kvm_requeue_exception); int kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err) { @@ -1013,16 +1014,10 @@ void kvm_inject_nmi(struct kvm_vcpu *vcpu) void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code) { - kvm_multiple_exception(vcpu, nr, true, error_code, false, 0, false); + kvm_multiple_exception(vcpu, nr, true, error_code, false, 0); } EXPORT_SYMBOL_GPL(kvm_queue_exception_e); -void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code) -{ - kvm_multiple_exception(vcpu, nr, true, error_code, false, 0, true); -} -EXPORT_SYMBOL_GPL(kvm_requeue_exception_e); - /* * Checks if cpl <= required_cpl; if true, return true. Otherwise queue * a #GP and return false. From patchwork Tue Oct 1 05:00:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817474 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 86E1F1BC094; Tue, 1 Oct 2024 05:02:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; cv=none; b=DgHWY6uQfu1Q5YIW7Aq2eRaIiTcEeTtSzcM2kEm22/xLpSXYsodSLQTlCjqlq/bKeDgcjdjWudkQ41MNkFbVlGAp5OU5qNoMNbfMIPgX8WjZEr2YJWvAXJs866uVdw+jvXbCx56aN+38mcx26KzklbXaTlcCGhCdw+Miu+vshTQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; c=relaxed/simple; bh=vBh0fJFgPmYid6l2yKk2mdBw8NaT541Y5D4O8YV15qg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mNSfGxodeR2IGl/Q1uECatGHM5O1KojXg4yuaR2Bup0JaVlK9tPOFNgV3iMf7Too4uXFXPRCQQ8I2d8N9EI/aPemgWnNa5ywrSqMLz+GJSWb8P8cet9txn0n0taQfmctptL9zs9/Axxs6S3TRZHAxniaj76igzUpBXW7SNn63q8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=XauhJKax; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="XauhJKax" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7R3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:17 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7R3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758878; bh=U978N1Id9kULENCyRAQtZo8eJ1d3JeFHDWBAjDeix6M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XauhJKaxr3tacRyngr9pVxuFekbUqCFPl9hAY+QYR/SfLe5KDtpdDg2vZ64WRNecA ecUJPqWznxGkyyxFTysVkYKZLB3ZR7I0jHsLzaZeqQg9EB6Cxk654fFMjRajI7VX2H hmt31gE4WRVXVWnJXKP7YPoIiSfA27gdyczepAMVo7O7l0eRGhHkR8t4ZfHlhzI7HL TMRHE+yCJPOhgrqneKIwEC1tl1ciDJHz78nQ3moi38W0Xtvg6ahcJK3/4XEH0mh4kU O52kjBf/Le28+EXB12tHP+NxOXBAi3Nl8NyqPWSxWZ/TtE4e5FkJtaEylwotYqQLjH Ql2vMRzYZYMsw== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 02/27] KVM: VMX: Don't modify guest XFD_ERR if CR0.TS=1 Date: Mon, 30 Sep 2024 22:00:45 -0700 Message-ID: <20241001050110.3643764-3-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Sean Christopherson Don't update the guest's XFD_ERR MSR if CR0.TS is set; per the SDM, XFD_ERR is not modified if CR0.TS=1. Although it's not explicitly stated in the SDM, conceptually it makes sense the CR0.TS check would be done prior to the XFD_ERR check, e.g. CR0.TS=1 blocks all SIMD state, whereas XFD blocks only XTILE state. Device-not-available exceptions that are not due to XFD - those resulting from setting CR0.TS to 1 - do not modify the IA32_XFD_ERR MSR. Opportunistically update the comment to call out that XFD_ERR is updated before the VM-Exit check occurs. Nothing in the SDM explicitly calls out this behavior, but logically it must be the behavior, otherwise reading XFD_ERR in handle_nm_fault_irqoff() would return stale data, i.e. the to-be-delivered XFD_ERR value would need to be saved in EXIT_QUALIFICATION, a la DR6 for #DB and CR2 for #PF, so that software could capture the guest value. Fixes: ec5be88ab29f ("kvm: x86: Intercept #NM for saving IA32_XFD_ERR") Signed-off-by: Sean Christopherson Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- arch/x86/kvm/vmx/vmx.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 6a93f5edbc0d..3f6257d88ded 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6976,16 +6976,16 @@ static void handle_nm_fault_irqoff(struct kvm_vcpu *vcpu) * MSR value is not clobbered by the host activity before the guest * has chance to consume it. * - * Do not blindly read xfd_err here, since this exception might - * be caused by L1 interception on a platform which doesn't - * support xfd at all. + * Update the guest's XFD_ERR if and only if XFD is enabled, as the #NM + * interception may have been caused by L1 interception. Per the SDM, + * XFD_ERR is not modified if CR0.TS=1. * - * Do it conditionally upon guest_fpu::xfd. xfd_err matters - * only when xfd contains a non-zero value. - * - * Queuing exception is done in vmx_handle_exit. See comment there. + * Note, XFD_ERR is updated _before_ the #NM interception check, i.e. + * unlike CR2 and DR6, the value is not a payload that is attached to + * the #NM exception. */ - if (vcpu->arch.guest_fpu.fpstate->xfd) + if (vcpu->arch.guest_fpu.fpstate->xfd && + !kvm_is_cr0_bit_set(vcpu, X86_CR0_TS)) rdmsrl(MSR_IA32_XFD_ERR, vcpu->arch.guest_fpu.xfd_err); } From patchwork Tue Oct 1 05:00:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817472 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 84637192B9E; Tue, 1 Oct 2024 05:02:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; cv=none; b=T5XwA8wkl9xNC+J6GJHPKAqeCrO5pjztkQSXJ9j7O6f+wXjsjmnJxYifbJsHuIehZ17jweRYZKZ587ZIKmrKz19CgEDiDuvtgWngwyGsZzS5vMfk7mQAPhWOtBwCvXxixLce9ZdYzA2c5hoEgcnUh/SPYrRcDlKlpWrweBIiQCA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; c=relaxed/simple; bh=UGRh/zMAZwnrInVXQfPkIMpEYtSSI/3hMa6vZ6FHZDs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bIh849HQhRQeVtrLmtEtc+Nz64jiOjKPY9PUqraPe6KacUeyaKLvNkYocVkH1zHK8vkPwpnMYZGNtB52Xn6ibVJ8PuQWYlD2fJ3yJ/YJhGI1mL2Ryvt2BMgHxb/rTbH59uu4RrTcfHRRbPWTQGcvwVEI6bYlt0BBqUV/VkC+glU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=SLmvSL2K; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="SLmvSL2K" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7S3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:18 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7S3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758879; bh=xDcBS4DfGuxq9tK1emBB+qc1AMtWqUc6cdoiAVHl0vY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SLmvSL2KpJvzhQUf/fpvdsRePyUzbZX2wP5ShBFqp579ca5u11x+KGhbphoMRxqmN jqPtzhuXWcf4JGnwZtdDHYErcUGrX4vHJzusFxq6Ie8VKIQ6sTXj8BpJU6VR6WvirI sbUAlSH+z82mKyuEwdARUIyPaZlesKJqf82kqyK6e96uHZW237nMD45u5RyI+DNNXD XEwG3irPoAI49mFfC0h7u+Igoj5+guu8T2r6QZ4h1NPtUbukworIl9I3u+Zz0HGkig UsDSit9mhkZg/70OQADvnzlmHjyg1IG2S/iMFD+EuXbNbT9IUS0hJ+RcHOnDl0syib GefpZh8K+FsxQ== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 03/27] KVM: VMX: Add support for the secondary VM exit controls Date: Mon, 30 Sep 2024 22:00:46 -0700 Message-ID: <20241001050110.3643764-4-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Always load the secondary VM exit controls to prepare for FRED enabling. Extend the VM exit/entry consistency check framework to accommodate this newly added secondary VM exit controls. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Reviewed-by: Chao Gao --- Change since v2: * Do FRED controls consistency checks in the VM exit/entry consistency check framework (Sean Christopherson). Change since v1: * Always load the secondary VM exit controls (Sean Christopherson). --- arch/x86/include/asm/msr-index.h | 1 + arch/x86/include/asm/vmx.h | 3 ++ arch/x86/kvm/vmx/capabilities.h | 9 +++++- arch/x86/kvm/vmx/vmcs.h | 1 + arch/x86/kvm/vmx/vmx.c | 51 ++++++++++++++++++++++++++------ arch/x86/kvm/vmx/vmx.h | 7 ++++- 6 files changed, 61 insertions(+), 11 deletions(-) diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 3ae84c3b8e6d..95b6e2749256 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -1178,6 +1178,7 @@ #define MSR_IA32_VMX_TRUE_ENTRY_CTLS 0x00000490 #define MSR_IA32_VMX_VMFUNC 0x00000491 #define MSR_IA32_VMX_PROCBASED_CTLS3 0x00000492 +#define MSR_IA32_VMX_EXIT_CTLS2 0x00000493 /* Resctrl MSRs: */ /* - Intel: */ diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index f7fd4369b821..57a37ea06a17 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -106,6 +106,7 @@ #define VM_EXIT_CLEAR_BNDCFGS 0x00800000 #define VM_EXIT_PT_CONCEAL_PIP 0x01000000 #define VM_EXIT_CLEAR_IA32_RTIT_CTL 0x02000000 +#define VM_EXIT_ACTIVATE_SECONDARY_CONTROLS 0x80000000 #define VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR 0x00036dff @@ -258,6 +259,8 @@ enum vmcs_field { TERTIARY_VM_EXEC_CONTROL_HIGH = 0x00002035, PID_POINTER_TABLE = 0x00002042, PID_POINTER_TABLE_HIGH = 0x00002043, + SECONDARY_VM_EXIT_CONTROLS = 0x00002044, + SECONDARY_VM_EXIT_CONTROLS_HIGH = 0x00002045, GUEST_PHYSICAL_ADDRESS = 0x00002400, GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401, VMCS_LINK_POINTER = 0x00002800, diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h index cb6588238f46..e8f3ad0f79ee 100644 --- a/arch/x86/kvm/vmx/capabilities.h +++ b/arch/x86/kvm/vmx/capabilities.h @@ -59,8 +59,9 @@ struct vmcs_config { u32 cpu_based_exec_ctrl; u32 cpu_based_2nd_exec_ctrl; u64 cpu_based_3rd_exec_ctrl; - u32 vmexit_ctrl; u32 vmentry_ctrl; + u32 vmexit_ctrl; + u64 secondary_vmexit_ctrl; u64 misc; struct nested_vmx_msrs nested; }; @@ -136,6 +137,12 @@ static inline bool cpu_has_tertiary_exec_ctrls(void) CPU_BASED_ACTIVATE_TERTIARY_CONTROLS; } +static inline bool cpu_has_secondary_vmexit_ctrls(void) +{ + return vmcs_config.vmexit_ctrl & + VM_EXIT_ACTIVATE_SECONDARY_CONTROLS; +} + static inline bool cpu_has_vmx_virtualize_apic_accesses(void) { return vmcs_config.cpu_based_2nd_exec_ctrl & diff --git a/arch/x86/kvm/vmx/vmcs.h b/arch/x86/kvm/vmx/vmcs.h index b25625314658..ae152a9d1963 100644 --- a/arch/x86/kvm/vmx/vmcs.h +++ b/arch/x86/kvm/vmx/vmcs.h @@ -47,6 +47,7 @@ struct vmcs_host_state { struct vmcs_controls_shadow { u32 vm_entry; u32 vm_exit; + u64 secondary_vm_exit; u32 pin; u32 exec; u32 secondary_exec; diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 3f6257d88ded..ec548c75c3ef 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2606,6 +2606,7 @@ static int setup_vmcs_config(struct vmcs_config *vmcs_conf, u32 _cpu_based_2nd_exec_control = 0; u64 _cpu_based_3rd_exec_control = 0; u32 _vmexit_control = 0; + u64 _secondary_vmexit_control = 0; u32 _vmentry_control = 0; u64 basic_msr; u64 misc_msr; @@ -2619,7 +2620,8 @@ static int setup_vmcs_config(struct vmcs_config *vmcs_conf, struct { u32 entry_control; u32 exit_control; - } const vmcs_entry_exit_pairs[] = { + u64 exit_2nd_control; + } const vmcs_entry_exit_triplets[] = { { VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL, VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL }, { VM_ENTRY_LOAD_IA32_PAT, VM_EXIT_LOAD_IA32_PAT }, { VM_ENTRY_LOAD_IA32_EFER, VM_EXIT_LOAD_IA32_EFER }, @@ -2713,21 +2715,43 @@ static int setup_vmcs_config(struct vmcs_config *vmcs_conf, &_vmentry_control)) return -EIO; - for (i = 0; i < ARRAY_SIZE(vmcs_entry_exit_pairs); i++) { - u32 n_ctrl = vmcs_entry_exit_pairs[i].entry_control; - u32 x_ctrl = vmcs_entry_exit_pairs[i].exit_control; - - if (!(_vmentry_control & n_ctrl) == !(_vmexit_control & x_ctrl)) + if (_vmexit_control & VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) + _secondary_vmexit_control = + adjust_vmx_controls64(KVM_OPTIONAL_VMX_SECONDARY_VM_EXIT_CONTROLS, + MSR_IA32_VMX_EXIT_CTLS2); + + for (i = 0; i < ARRAY_SIZE(vmcs_entry_exit_triplets); i++) { + u32 n_ctrl = vmcs_entry_exit_triplets[i].entry_control; + u32 x_ctrl = vmcs_entry_exit_triplets[i].exit_control; + u64 x_ctrl_2 = vmcs_entry_exit_triplets[i].exit_2nd_control; + bool has_n = n_ctrl && ((_vmentry_control & n_ctrl) == n_ctrl); + bool has_x = x_ctrl && ((_vmexit_control & x_ctrl) == x_ctrl); + bool has_x_2 = x_ctrl_2 && ((_secondary_vmexit_control & x_ctrl_2) == x_ctrl_2); + + if (x_ctrl_2) { + /* Only activate secondary VM exit control bit should be set */ + if ((_vmexit_control & x_ctrl) == VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) { + if (has_n == has_x_2) + continue; + } else { + /* The feature should not be supported in any control */ + if (!has_n && !has_x && !has_x_2) + continue; + } + } else if (has_n == has_x) { continue; + } - pr_warn_once("Inconsistent VM-Entry/VM-Exit pair, entry = %x, exit = %x\n", - _vmentry_control & n_ctrl, _vmexit_control & x_ctrl); + pr_warn_once("Inconsistent VM-Entry/VM-Exit triplet, entry = %x, exit = %x, secondary_exit = %llx\n", + _vmentry_control & n_ctrl, _vmexit_control & x_ctrl, + _secondary_vmexit_control & x_ctrl_2); if (error_on_inconsistent_vmcs_config) return -EIO; _vmentry_control &= ~n_ctrl; _vmexit_control &= ~x_ctrl; + _secondary_vmexit_control &= ~x_ctrl_2; } rdmsrl(MSR_IA32_VMX_BASIC, basic_msr); @@ -2757,8 +2781,9 @@ static int setup_vmcs_config(struct vmcs_config *vmcs_conf, vmcs_conf->cpu_based_exec_ctrl = _cpu_based_exec_control; vmcs_conf->cpu_based_2nd_exec_ctrl = _cpu_based_2nd_exec_control; vmcs_conf->cpu_based_3rd_exec_ctrl = _cpu_based_3rd_exec_control; - vmcs_conf->vmexit_ctrl = _vmexit_control; vmcs_conf->vmentry_ctrl = _vmentry_control; + vmcs_conf->vmexit_ctrl = _vmexit_control; + vmcs_conf->secondary_vmexit_ctrl = _secondary_vmexit_control; vmcs_conf->misc = misc_msr; #if IS_ENABLED(CONFIG_HYPERV) @@ -4449,6 +4474,11 @@ static u32 vmx_vmexit_ctrl(void) ~(VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | VM_EXIT_LOAD_IA32_EFER); } +static u64 vmx_secondary_vmexit_ctrl(void) +{ + return vmcs_config.secondary_vmexit_ctrl; +} + void vmx_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); @@ -4799,6 +4829,9 @@ static void init_vmcs(struct vcpu_vmx *vmx) vm_exit_controls_set(vmx, vmx_vmexit_ctrl()); + if (cpu_has_secondary_vmexit_ctrls()) + secondary_vm_exit_controls_set(vmx, vmx_secondary_vmexit_ctrl()); + /* 22.2.1, 20.8.1 */ vm_entry_controls_set(vmx, vmx_vmentry_ctrl()); diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index 2325f773a20b..cf3a6c116634 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -507,7 +507,11 @@ static inline u8 vmx_get_rvi(void) VM_EXIT_LOAD_IA32_EFER | \ VM_EXIT_CLEAR_BNDCFGS | \ VM_EXIT_PT_CONCEAL_PIP | \ - VM_EXIT_CLEAR_IA32_RTIT_CTL) + VM_EXIT_CLEAR_IA32_RTIT_CTL | \ + VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) + +#define KVM_REQUIRED_VMX_SECONDARY_VM_EXIT_CONTROLS (0) +#define KVM_OPTIONAL_VMX_SECONDARY_VM_EXIT_CONTROLS (0) #define KVM_REQUIRED_VMX_PIN_BASED_VM_EXEC_CONTROL \ (PIN_BASED_EXT_INTR_MASK | \ @@ -612,6 +616,7 @@ static __always_inline void lname##_controls_clearbit(struct vcpu_vmx *vmx, u##b } BUILD_CONTROLS_SHADOW(vm_entry, VM_ENTRY_CONTROLS, 32) BUILD_CONTROLS_SHADOW(vm_exit, VM_EXIT_CONTROLS, 32) +BUILD_CONTROLS_SHADOW(secondary_vm_exit, SECONDARY_VM_EXIT_CONTROLS, 64) BUILD_CONTROLS_SHADOW(pin, PIN_BASED_VM_EXEC_CONTROL, 32) BUILD_CONTROLS_SHADOW(exec, CPU_BASED_VM_EXEC_CONTROL, 32) BUILD_CONTROLS_SHADOW(secondary_exec, SECONDARY_VM_EXEC_CONTROL, 32) From patchwork Tue Oct 1 05:00:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817464 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 714981BBBC1; Tue, 1 Oct 2024 05:02:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758939; cv=none; b=DXEiV6QvuBt+02fjsmklQTqNJ9w1KM5wB1M15Pu9k9G1N8OKIH6Zh0jKGC8JCZEqYB5/uQWGeI/bM11qDieD9NzXDJLPkYJa1lhQAvQdDXO5WWixXH8L3hj++eWbMuVkD/G1wjEpAY85hleBufsHL2QeHrMwHPWEBeYF5qQz9WY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758939; c=relaxed/simple; bh=nSCsPWI07e44Gv4mTwAMhsfrhTpHF2lygAD99oX7W7o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mg65jG02I2/xI/MbbnIiXG5JjXKxVXsf2TgmQR/ayEJh5ToGzdP5V5nDVhU4rKoP3iTrJBvVUfhR/I74hLVu6WWzwM/qN/QeTkQ4gGCI2Js6asOa9Zk0EPkF2B6gqEuFKGpF22iK6Tlhcfp6It+4BM0gKOE/sNovNQF1w+NSkU8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=msMVXnKq; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="msMVXnKq" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7T3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:19 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7T3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758880; bh=dUvXV5w+H+zZzeQB4HqwxqS06gxJojLbAqK12g74pTA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=msMVXnKqtRoZpvhDB65bqRCAVkKrVYWNPd40JtCnTt8PRvhSHrsBENZFKdt1zakJJ 1nuWKguRWsctJhTQJ1n0j+/VHYNe6DxtaBEBAGF1rfCguYbdXS8GtEwp45J247K7+Z LjZAMXMSNM7fOi5A/RCf0TMeTpAINeppHR42Ewnb7VmIez9dYkRmVO1OaKbVc209o3 f+iK7G+h2KK5qwk591IiShLuTFwfElPniQSooX275Su6+BRjfxEwVKA2DVHYDkULzp g+L8ccjDCqZpKgHFL1Qgmta9WyRD12Tp6P7nmyTeEwsphscMctrH21g4N+Pu830mzc 5DE3V81qk1mdg== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 04/27] KVM: VMX: Initialize FRED VM entry/exit controls in vmcs_config Date: Mon, 30 Sep 2024 22:00:47 -0700 Message-ID: <20241001050110.3643764-5-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Setup FRED VM entry/exit controls in the global vmcs_config for proper FRED VMCS fields management, i.e., load guest FRED state upon VM entry, and save guest/load host FRED state during VM exit. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Reviewed-by: Chao Gao --- Change since v2: * Add FRED VM entry/exit controls consistency checks to the existing consistency check framework (Sean Christopherson). * Just do the unnecessary FRED state load/store on entry/exit (Sean Christopherson). --- arch/x86/include/asm/vmx.h | 4 ++++ arch/x86/kvm/vmx/vmx.c | 2 ++ arch/x86/kvm/vmx/vmx.h | 7 +++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 57a37ea06a17..551f62892e1a 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -108,6 +108,9 @@ #define VM_EXIT_CLEAR_IA32_RTIT_CTL 0x02000000 #define VM_EXIT_ACTIVATE_SECONDARY_CONTROLS 0x80000000 +#define SECONDARY_VM_EXIT_SAVE_IA32_FRED BIT_ULL(0) +#define SECONDARY_VM_EXIT_LOAD_IA32_FRED BIT_ULL(1) + #define VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR 0x00036dff #define VM_ENTRY_LOAD_DEBUG_CONTROLS 0x00000004 @@ -120,6 +123,7 @@ #define VM_ENTRY_LOAD_BNDCFGS 0x00010000 #define VM_ENTRY_PT_CONCEAL_PIP 0x00020000 #define VM_ENTRY_LOAD_IA32_RTIT_CTL 0x00040000 +#define VM_ENTRY_LOAD_IA32_FRED 0x00800000 #define VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR 0x000011ff diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index ec548c75c3ef..efd2ad397ad2 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2627,6 +2627,8 @@ static int setup_vmcs_config(struct vmcs_config *vmcs_conf, { VM_ENTRY_LOAD_IA32_EFER, VM_EXIT_LOAD_IA32_EFER }, { VM_ENTRY_LOAD_BNDCFGS, VM_EXIT_CLEAR_BNDCFGS }, { VM_ENTRY_LOAD_IA32_RTIT_CTL, VM_EXIT_CLEAR_IA32_RTIT_CTL }, + { VM_ENTRY_LOAD_IA32_FRED, VM_EXIT_ACTIVATE_SECONDARY_CONTROLS, + SECONDARY_VM_EXIT_SAVE_IA32_FRED | SECONDARY_VM_EXIT_LOAD_IA32_FRED }, }; memset(vmcs_conf, 0, sizeof(*vmcs_conf)); diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index cf3a6c116634..e0d76d2460ef 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -485,7 +485,8 @@ static inline u8 vmx_get_rvi(void) VM_ENTRY_LOAD_IA32_EFER | \ VM_ENTRY_LOAD_BNDCFGS | \ VM_ENTRY_PT_CONCEAL_PIP | \ - VM_ENTRY_LOAD_IA32_RTIT_CTL) + VM_ENTRY_LOAD_IA32_RTIT_CTL | \ + VM_ENTRY_LOAD_IA32_FRED) #define __KVM_REQUIRED_VMX_VM_EXIT_CONTROLS \ (VM_EXIT_SAVE_DEBUG_CONTROLS | \ @@ -511,7 +512,9 @@ static inline u8 vmx_get_rvi(void) VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) #define KVM_REQUIRED_VMX_SECONDARY_VM_EXIT_CONTROLS (0) -#define KVM_OPTIONAL_VMX_SECONDARY_VM_EXIT_CONTROLS (0) +#define KVM_OPTIONAL_VMX_SECONDARY_VM_EXIT_CONTROLS \ + (SECONDARY_VM_EXIT_SAVE_IA32_FRED | \ + SECONDARY_VM_EXIT_LOAD_IA32_FRED) #define KVM_REQUIRED_VMX_PIN_BASED_VM_EXEC_CONTROL \ (PIN_BASED_EXT_INTR_MASK | \ From patchwork Tue Oct 1 05:00:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817452 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 898A4194C6F; Tue, 1 Oct 2024 05:02:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758938; cv=none; b=Zp4ER3tUfj1ZBNJvYgK56AFx65O72pWgWHzXLEeva8SYL0Mtk4KBJ7vu6K51vMyGSb5ZinB/2bcAFtO1yQ0NC2hDEsLokbp8me3qwPx5xLwrYkjj0Wv9hIKcpKiC70hUG7FN82tpeB02hINMagMQ5E20yX5X7ZwhmWp1Z9ZmigE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758938; c=relaxed/simple; bh=YIIbLf4qdG7AU+f5qBzxFWcJMGnrhQrGSC4hpt3H4E0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=m5JeLYAHwXJiFKDCbEFdAAXEpV/asPaOIFnJXNcTXnfTGUf4MOBypAPWRrjm+R91BLCBwuIVFm3zKZb0wE1mAUuxqN98mK+kQe2gP9GpFB/thBpk1AVWIHt8v6AB6/x9KirKgrjO1Rjd+dhjKIqcYl9jTWZcgCFR/G94cu/cCHI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=W7Ui37rY; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="W7Ui37rY" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7U3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:20 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7U3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758881; bh=wUrzrWGpTqCY4Lj4JpPdteFqkI+gH/O0UwIUfMWFr9E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=W7Ui37rYLUI+8sRBFZ4gyb6YVm0DShi4xBJoWopYLmg82DLitPnqZ4HTJVVR760m0 ZsNXq/zi5JujBJGzA6SYKNHfbc3H90IsOX8EOMMAheWdMvW4xh/OknM3qcNnpe/ihv AEz/sSUUywZuRPFcod3ivCWk0z0EXwX+KJRj7MqkMAxKtPeX4ltzIhBZakAo1Qa8Fw oOp7wElAcvva6meIUAQnfybONAmd9pwj0JfPf3cZBBaeDpmd1hZZ2OfCutsev3ALmH XaFpjz2Mq1XVCD928SluF4InwrHrfFh+WstkGkwnqxaJmXNzSWMgTL0jhEILBRTuf6 0sfwPLHvEymqw== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 05/27] KVM: VMX: Disable FRED if FRED consistency checks fail Date: Mon, 30 Sep 2024 22:00:48 -0700 Message-ID: <20241001050110.3643764-6-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Do not virtualize FRED if FRED consistency checks fail. Either on broken hardware, or when run KVM on top of another hypervisor before the underlying hypervisor implements nested FRED correctly. Suggested-by: Chao Gao Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Reviewed-by: Chao Gao --- arch/x86/kvm/vmx/capabilities.h | 7 +++++++ arch/x86/kvm/vmx/vmx.c | 3 +++ 2 files changed, 10 insertions(+) diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h index e8f3ad0f79ee..2962a3bb9747 100644 --- a/arch/x86/kvm/vmx/capabilities.h +++ b/arch/x86/kvm/vmx/capabilities.h @@ -400,6 +400,13 @@ static inline bool vmx_pebs_supported(void) return boot_cpu_has(X86_FEATURE_PEBS) && kvm_pmu_cap.pebs_ept; } +static inline bool cpu_has_vmx_fred(void) +{ + /* No need to check FRED VM exit controls. */ + return boot_cpu_has(X86_FEATURE_FRED) && + (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_FRED); +} + static inline bool cpu_has_notify_vmexit(void) { return vmcs_config.cpu_based_2nd_exec_ctrl & diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index efd2ad397ad2..9b4c30db911f 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -8001,6 +8001,9 @@ static __init void vmx_set_cpu_caps(void) kvm_cpu_cap_check_and_set(X86_FEATURE_DTES64); } + if (!cpu_has_vmx_fred()) + kvm_cpu_cap_clear(X86_FEATURE_FRED); + if (!enable_pmu) kvm_cpu_cap_clear(X86_FEATURE_PDCM); kvm_caps.supported_perf_cap = vmx_get_perf_capabilities(); From patchwork Tue Oct 1 05:00:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817460 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 8AD181A3BDA; Tue, 1 Oct 2024 05:02:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758939; cv=none; b=IucSap/jv0sqAEufqkysAveyZtpa3QHUB7n14Sm8dB9dwksxzPc1TMCuNx1evQ6Khjag25O660BgXengZrUqoxct8/uhH34kqZMOGdSolMrtJoxZI6lHKpCdjQKq/FGhmaQUadnYWoLeDJIhhQWSOby/zqpiPTQPDgCSgPEvd78= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758939; c=relaxed/simple; bh=D0M8MUphEJDzt0DhRWl6jjrN238HMRnD/K9ryJpI3N4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IalPto9jy2L87LrivdAvxIlrTyJtS+kH2VAJk3M84QP90TAzfjEhqimzVxMsWake+RHuzUXlKKyLs7tcmxQ98I7m7EUKgKKpY5xhdxqa3bnGXzruJ+O+zLmoT+iY6gJq/XtEdwEOuyHpqA5jNfK5DLHrNv7E+rBMlCu2SY9z8eE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=W6bw8Nid; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="W6bw8Nid" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7V3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:21 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7V3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758882; bh=9fOauzGby+rPmCjUXvj6urYAJT7PhTs9glaZ68z8kxs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=W6bw8NidU/8g0afX5F7UrR84tBgi/aIhFmJnSwqaANZ3dnAsl8yNSMcv8rwT3kE51 QhnOT1CT/dKFOr0CYmL+s8MRxUyFbmZgny5LX9fL+Pb5+EyIsvN2h5zeb9tg6AC2oL X5xIyfVZAyFGSjRYa0vKYoWjQcF7ZuqemSipFrZ+R1I6/6++M0yFHf4mF2TPaDHVJq pHl9J3Qf7KooHgnhihh0RpetfXzYYADDaYyiurm7qgplwct6ihEz+DspZ31KSX9QgK +AYNB8kcef9l8y5gKQPpHU8MHbPaZfDrPTR02uj5/OdhpuDc3RosKNc6ZrEonaDWSz qtSHPHc98Evtg== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 06/27] x86/cea: Export per CPU variable cea_exception_stacks Date: Mon, 30 Sep 2024 22:00:49 -0700 Message-ID: <20241001050110.3643764-7-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The per CPU variable cea_exception_stacks contains per CPU stacks for NMI, #DB and #DF, which is referenced in KVM to set host FRED RSP[123] each time a vCPU is loaded onto a CPU, thus it needs to be exported. Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- arch/x86/mm/cpu_entry_area.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/mm/cpu_entry_area.c b/arch/x86/mm/cpu_entry_area.c index 575f863f3c75..b8af71b67d9a 100644 --- a/arch/x86/mm/cpu_entry_area.c +++ b/arch/x86/mm/cpu_entry_area.c @@ -17,6 +17,7 @@ static DEFINE_PER_CPU_PAGE_ALIGNED(struct entry_stack_page, entry_stack_storage) #ifdef CONFIG_X86_64 static DEFINE_PER_CPU_PAGE_ALIGNED(struct exception_stacks, exception_stacks); DEFINE_PER_CPU(struct cea_exception_stacks*, cea_exception_stacks); +EXPORT_PER_CPU_SYMBOL(cea_exception_stacks); static DEFINE_PER_CPU_READ_MOSTLY(unsigned long, _cea_offset); From patchwork Tue Oct 1 05:00:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817467 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 A27D01BBBF8; Tue, 1 Oct 2024 05:02:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; cv=none; b=jFVRxOICcerJXKZQfHFYnrvTcvTaM98fXHp+pG0LdHueNj3dQINq0Vpl5NNgKLIS/yHQS7mZrioVUM6cdlRwa4YKEF/eVA2VrbQt8i2gh/vcWO5c5wn2c0K+MEK+AlgIsG+oi5HPNyT6nGIknjXonqZDOynVeGI3YbhR3FLv8XY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; c=relaxed/simple; bh=zeMVBh2t6rcmcSMPFekgQDkjP5ip/YKm00vUimMWlqs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=alvT+hBcxHfUeCtHEYqnO4vfcMQvdIVubUewWibjX7Dyd+gWnLSaOk41wRGjhMT/jgIndqJZsb3Lkq/OP3KFTtsMpZ0dOpqtBbpTIz7wRz1VjlZrPfBf9Slo2tKbuSHTJgdqfxIAJupB8alJJ7TmeSaiOdpeX6fuXnictqlw4TE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=birV8BbQ; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="birV8BbQ" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7W3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:22 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7W3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758883; bh=a8ZJAxBUc5v7ZGwYUvEF4rZopLKK9vaa9w31JixcidI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=birV8BbQrRrLGG2v557/z70/N9yieIBNgYIuXn9c4ue1o6HQ3aJ7/Aw44yPe+Z3uJ 4T44cSG6OvqjeAV9maaYafXNPXKygLJhgdHbQdhTjrdJPtPq9zZ1xpYRQghGNq+w17 J70y19woPpLrpZCuA6PTfAW84VsM4rlpZeqYkj11vDCzMK6OXbgC5JA6ib3kLsbJVR QOjJB8QCnOvtg1dy4VjSlKNS8gXeiRsrbOZnosiBhEH/BbXKmIG7L81mHzCk0efadM TXYAcnDn5UxHOxGNSkm5YJZ4cfdmm9pzFRzokhWNjaiGrwqIECRyK2jRujujG3fxML DCifVuoCDMhsQ== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 07/27] KVM: VMX: Initialize VMCS FRED fields Date: Mon, 30 Sep 2024 22:00:50 -0700 Message-ID: <20241001050110.3643764-8-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Initialize host VMCS FRED fields with host FRED MSRs' value and guest VMCS FRED fields to 0. FRED CPU states are managed in 9 new FRED MSRs, as well as a few existing CPU registers and MSRs, e.g., CR4.FRED. To support FRED context management, new VMCS fields corresponding to most of FRED CPU state MSRs are added to both the host-state and guest-state areas of VMCS. Specifically no VMCS fields are added for FRED RSP0 and SSP0 MSRs, because the 2 FRED MSRs are used during ring 3 event delivery only, thus KVM can run safely even with guest FRED RSP0 and SSP0. Thus save and restore of FRED RSP0 and SSP0 are deferred. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- Change since v2: * Use structure kvm_host_values to keep host fred config & stack levels (Sean Christopherson). Changes since v1: * Use kvm_cpu_cap_has() instead of cpu_feature_enabled() to decouple KVM's capability to virtualize a feature and host's enabling of a feature (Chao Gao). * Move guest FRED states init into __vmx_vcpu_reset() (Chao Gao). --- arch/x86/include/asm/vmx.h | 16 ++++++++++++++++ arch/x86/kvm/vmx/vmx.c | 34 ++++++++++++++++++++++++++++++++++ arch/x86/kvm/x86.h | 3 +++ 3 files changed, 53 insertions(+) diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 551f62892e1a..5184e03945dd 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -289,12 +289,28 @@ enum vmcs_field { GUEST_BNDCFGS_HIGH = 0x00002813, GUEST_IA32_RTIT_CTL = 0x00002814, GUEST_IA32_RTIT_CTL_HIGH = 0x00002815, + GUEST_IA32_FRED_CONFIG = 0x0000281a, + GUEST_IA32_FRED_RSP1 = 0x0000281c, + GUEST_IA32_FRED_RSP2 = 0x0000281e, + GUEST_IA32_FRED_RSP3 = 0x00002820, + GUEST_IA32_FRED_STKLVLS = 0x00002822, + GUEST_IA32_FRED_SSP1 = 0x00002824, + GUEST_IA32_FRED_SSP2 = 0x00002826, + GUEST_IA32_FRED_SSP3 = 0x00002828, HOST_IA32_PAT = 0x00002c00, HOST_IA32_PAT_HIGH = 0x00002c01, HOST_IA32_EFER = 0x00002c02, HOST_IA32_EFER_HIGH = 0x00002c03, HOST_IA32_PERF_GLOBAL_CTRL = 0x00002c04, HOST_IA32_PERF_GLOBAL_CTRL_HIGH = 0x00002c05, + HOST_IA32_FRED_CONFIG = 0x00002c08, + HOST_IA32_FRED_RSP1 = 0x00002c0a, + HOST_IA32_FRED_RSP2 = 0x00002c0c, + HOST_IA32_FRED_RSP3 = 0x00002c0e, + HOST_IA32_FRED_STKLVLS = 0x00002c10, + HOST_IA32_FRED_SSP1 = 0x00002c12, + HOST_IA32_FRED_SSP2 = 0x00002c14, + HOST_IA32_FRED_SSP3 = 0x00002c16, PIN_BASED_VM_EXEC_CONTROL = 0x00004000, CPU_BASED_VM_EXEC_CONTROL = 0x00004002, EXCEPTION_BITMAP = 0x00004004, diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 9b4c30db911f..fee0df93e07c 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1503,6 +1503,18 @@ void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu, (unsigned long)(cpu_entry_stack(cpu) + 1)); } + /* Per-CPU FRED MSRs */ + if (kvm_cpu_cap_has(X86_FEATURE_FRED)) { +#ifdef CONFIG_X86_64 + vmcs_write64(HOST_IA32_FRED_RSP1, __this_cpu_ist_top_va(DB)); + vmcs_write64(HOST_IA32_FRED_RSP2, __this_cpu_ist_top_va(NMI)); + vmcs_write64(HOST_IA32_FRED_RSP3, __this_cpu_ist_top_va(DF)); +#endif + vmcs_write64(HOST_IA32_FRED_SSP1, 0); + vmcs_write64(HOST_IA32_FRED_SSP2, 0); + vmcs_write64(HOST_IA32_FRED_SSP3, 0); + } + vmx->loaded_vmcs->cpu = cpu; } } @@ -4366,6 +4378,12 @@ void vmx_set_constant_host_state(struct vcpu_vmx *vmx) */ vmcs_write16(HOST_DS_SELECTOR, 0); vmcs_write16(HOST_ES_SELECTOR, 0); + + /* FRED CONFIG and STKLVLS are the same on all CPUs. */ + if (kvm_cpu_cap_has(X86_FEATURE_FRED)) { + vmcs_write64(HOST_IA32_FRED_CONFIG, kvm_host.fred_config); + vmcs_write64(HOST_IA32_FRED_STKLVLS, kvm_host.fred_stklvls); + } #else vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */ @@ -4876,6 +4894,17 @@ static void init_vmcs(struct vcpu_vmx *vmx) } vmx_setup_uret_msrs(vmx); + + if (kvm_cpu_cap_has(X86_FEATURE_FRED)) { + vmcs_write64(GUEST_IA32_FRED_CONFIG, 0); + vmcs_write64(GUEST_IA32_FRED_RSP1, 0); + vmcs_write64(GUEST_IA32_FRED_RSP2, 0); + vmcs_write64(GUEST_IA32_FRED_RSP3, 0); + vmcs_write64(GUEST_IA32_FRED_STKLVLS, 0); + vmcs_write64(GUEST_IA32_FRED_SSP1, 0); + vmcs_write64(GUEST_IA32_FRED_SSP2, 0); + vmcs_write64(GUEST_IA32_FRED_SSP3, 0); + } } static void __vmx_vcpu_reset(struct kvm_vcpu *vcpu) @@ -8614,6 +8643,11 @@ __init int vmx_hardware_setup(void) kvm_set_posted_intr_wakeup_handler(pi_wakeup_handler); + if (kvm_cpu_cap_has(X86_FEATURE_FRED)) { + rdmsrl(MSR_IA32_FRED_CONFIG, kvm_host.fred_config); + rdmsrl(MSR_IA32_FRED_STKLVLS, kvm_host.fred_stklvls); + } + return r; } diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index a84c48ef5278..578fea05ff18 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -45,6 +45,9 @@ struct kvm_host_values { u64 xcr0; u64 xss; u64 arch_capabilities; + + u64 fred_config; + u64 fred_stklvls; }; void kvm_spurious_fault(void); From patchwork Tue Oct 1 05:00:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817450 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 6C3C1BA33; Tue, 1 Oct 2024 05:02:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758937; cv=none; b=cen8Lelqy/dCCXngaNmGHcuGfdDhMRclIKCxsMvOWvO4BllUtxNIz7CZYaXZ8CPjSiorjNPtXyftJmtX/CFZWL6YxiInx9WGwU5226mM29sg617pKzE2xQmPfSokRIDYjtwhnB2jxbOCAtQZml/rvVUyE0/VcV4JO7MPqs0JiCw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758937; c=relaxed/simple; bh=RhauUTszJT38MEGfJXe2bv1mBmYS8SmpwVKY7ixGzZM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YdKYd0LEmh8f1yA+fVflX+webzpG9ortTfzwgAxidBf7zVejPF94bI3UB6N9DvaTjGUUGgjdBeW244Jdn4Y+XOmTu8R+wAgCeDxAyyaqVbxOexrKLd4g1PdPGhPvO0nwnCQeST6GFQdn0o/1mycBGYk+l4EgIJ0SXtaodxXhEio= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=TH/7/M+R; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="TH/7/M+R" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7X3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:23 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7X3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758884; bh=7ekHwX+9vPpzrP/GM9TRol8TuZtm5qS1xrVUy97xcGE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TH/7/M+Rt877lJsSxKnUxshJhnChiLUHBtRASBjvHv76Nz3lubuM5nsBxRftKf+4E SC59EDwAJ3nHVoryx1fohLTUo6SQ8wKLJ6F1IDdVZcBozQgpeJKOxZl9svUH44g6/R ShLuHVGR3GILGYDTj13M1wtoMXH7Y+M2xeNz14mwXftVGR8/fEj/oWj/Gxi7BrZ9Xs tE1D9M1jX9K6fp1ipVPOzWWTbd04mRQy3SJTP6+OH7fVWd+T8m6g65mV/e2/YIjcup PSaJ827DCQTtzHaJQP56OzRN/O6sjulBSsO1iTJ+XEijhd7ZXR83KQ/kDoShAeWeIi 95CNW3tJXHH1A== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 08/27] KVM: x86: Use KVM-governed feature framework to track "FRED enabled" Date: Mon, 30 Sep 2024 22:00:51 -0700 Message-ID: <20241001050110.3643764-9-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Track "FRED enabled" via a governed feature flag to avoid the guest CPUID lookups at runtime. Suggested-by: Chao Gao Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- arch/x86/kvm/governed_features.h | 1 + arch/x86/kvm/vmx/vmx.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/x86/kvm/governed_features.h b/arch/x86/kvm/governed_features.h index ad463b1ed4e4..507ca73e52e9 100644 --- a/arch/x86/kvm/governed_features.h +++ b/arch/x86/kvm/governed_features.h @@ -17,6 +17,7 @@ KVM_GOVERNED_X86_FEATURE(PFTHRESHOLD) KVM_GOVERNED_X86_FEATURE(VGIF) KVM_GOVERNED_X86_FEATURE(VNMI) KVM_GOVERNED_X86_FEATURE(LAM) +KVM_GOVERNED_X86_FEATURE(FRED) #undef KVM_GOVERNED_X86_FEATURE #undef KVM_GOVERNED_FEATURE diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index fee0df93e07c..9acc9661fdb2 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7893,6 +7893,7 @@ void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) kvm_governed_feature_check_and_set(vcpu, X86_FEATURE_VMX); kvm_governed_feature_check_and_set(vcpu, X86_FEATURE_LAM); + kvm_governed_feature_check_and_set(vcpu, X86_FEATURE_FRED); vmx_setup_uret_msrs(vmx); From patchwork Tue Oct 1 05:00:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817461 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 74D0E1BBBC5; Tue, 1 Oct 2024 05:02:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758939; cv=none; b=Ed2SGh3byOxSwgnZQRNWgQm+kqHzQWTCuD0LVKEdh/Oty9GlrSyBpFh4FXqjpB+oy5UoBPINDiiHeHLuT+IBmP7Qx8gwPAAcRrErT59mgcsUBbCm2AJpdq8vDtiR9kAarz+q/xLtMFUNPqi6JP37wQjYIVoAZePvGVLW8rji3q4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758939; c=relaxed/simple; bh=1HHdCROku9KHCkOxCVa1BFpb20qNw59Ovg2AGy/Du+4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=d9TAar1Jatz1kkhBzzTXdQENo1AHaX75Xw4z6HpAAiPBL2+Jqa2WcZArFPVVIHqBZ0y0EgddJwdGnuNQHLIWlEzfKi2VxGy+jCeidAYVhywQWDEzICK4qkgsgrnp2MRi5sEmRviY9h46hHzdIz3R2zaxTTevhERJdS2Xa4+eVzU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=f1VGdrSp; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="f1VGdrSp" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7Y3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:24 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7Y3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758885; bh=Fcrp8N3TnQ5gyW//6qj6v/cEutthr7kh/dHXKU3Du2A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f1VGdrSpiCBltxKZzChcSXZe8GeIPuQ0zCA3HfrrxzLcAQIBemWBvmYa4b1IILykZ +UFSmA+UAkXevkPqFoSovwq9jVRQ1eVuNj1dZ0cLiUQMpRckfdfAAZOdPaiIHIVZYp mbKbuSgcFtfUKxyN6czyokwNTIjInoVdOW1rgOgEhh9R+/6W9+aSQlf/BtVFe+6OWk avX+T+betHL69ibYAsmbTL4mopnrMN7Kx+q1t1NRzVknTFJdkHdxfteJnAKeXsP0QX GGGYiLqEsOOqdZKIfpZsHpQGcwJ4WH/M2ytx4lEsRJOzffZG48ShOXUSCdngiUh2E/ PEKnQxhz6IPXQ== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 09/27] KVM: VMX: Do not use MAX_POSSIBLE_PASSTHROUGH_MSRS in array definition Date: Mon, 30 Sep 2024 22:00:52 -0700 Message-ID: <20241001050110.3643764-10-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 No need to use MAX_POSSIBLE_PASSTHROUGH_MSRS in the definition of array vmx_possible_passthrough_msrs, as the macro name indicates the _possible_ maximum size of passthrough MSRs. Use ARRAY_SIZE instead of MAX_POSSIBLE_PASSTHROUGH_MSRS when the size of the array is needed and add a BUILD_BUG_ON to make sure the actual array size does not exceed the possible maximum size of passthrough MSRs. Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- arch/x86/kvm/vmx/vmx.c | 8 +++++--- arch/x86/kvm/vmx/vmx.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 9acc9661fdb2..28cf89c97bda 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -167,7 +167,7 @@ module_param(allow_smaller_maxphyaddr, bool, S_IRUGO); * List of MSRs that can be directly passed to the guest. * In addition to these x2apic, PT and LBR MSRs are handled specially. */ -static u32 vmx_possible_passthrough_msrs[MAX_POSSIBLE_PASSTHROUGH_MSRS] = { +static u32 vmx_possible_passthrough_msrs[] = { MSR_IA32_SPEC_CTRL, MSR_IA32_PRED_CMD, MSR_IA32_FLUSH_CMD, @@ -4182,6 +4182,8 @@ void vmx_msr_filter_changed(struct kvm_vcpu *vcpu) if (!cpu_has_vmx_msr_bitmap()) return; + BUILD_BUG_ON(ARRAY_SIZE(vmx_possible_passthrough_msrs) > MAX_POSSIBLE_PASSTHROUGH_MSRS); + /* * Redo intercept permissions for MSRs that KVM is passing through to * the guest. Disabling interception will check the new MSR filter and @@ -7626,8 +7628,8 @@ int vmx_vcpu_create(struct kvm_vcpu *vcpu) } /* The MSR bitmap starts with all ones */ - bitmap_fill(vmx->shadow_msr_intercept.read, MAX_POSSIBLE_PASSTHROUGH_MSRS); - bitmap_fill(vmx->shadow_msr_intercept.write, MAX_POSSIBLE_PASSTHROUGH_MSRS); + bitmap_fill(vmx->shadow_msr_intercept.read, ARRAY_SIZE(vmx_possible_passthrough_msrs)); + bitmap_fill(vmx->shadow_msr_intercept.write, ARRAY_SIZE(vmx_possible_passthrough_msrs)); vmx_disable_intercept_for_msr(vcpu, MSR_IA32_TSC, MSR_TYPE_R); #ifdef CONFIG_X86_64 diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index e0d76d2460ef..e7409f8f28b1 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -356,7 +356,7 @@ struct vcpu_vmx { struct lbr_desc lbr_desc; /* Save desired MSR intercept (read: pass-through) state */ -#define MAX_POSSIBLE_PASSTHROUGH_MSRS 16 +#define MAX_POSSIBLE_PASSTHROUGH_MSRS 64 struct { DECLARE_BITMAP(read, MAX_POSSIBLE_PASSTHROUGH_MSRS); DECLARE_BITMAP(write, MAX_POSSIBLE_PASSTHROUGH_MSRS); From patchwork Tue Oct 1 05:00:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817475 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 78D9E1BBBC9; Tue, 1 Oct 2024 05:02:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758941; cv=none; b=VjWoInlTX4SU60eOirtP5hNVUCOsaeRhg+gwjW6hyH+TNx7EQmy0pLoc0N05E8XlVgco60A1dztTSUAg2FLRlEdlq8Wh9HhsW0MpoUBGo5mNQFBj4L6Q5UfIOFbMIIw6agR79BalQID3KLrUPM2AYrAhti8LfwrReclXZcOi/wc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758941; c=relaxed/simple; bh=XHFnI85DETCTZUsMiaMjTMhzUM8tB5OPWcBH8WtEpB0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iLCkNhQ8JFc9XQ6xWjWAzKQHECI9+OecL/+0pcIMy9XoX1LnmTI2va0xlp8MyT306cN2eyotDvwoDW51lFKJIffPjn2jh1dHPRn1exrVtGk+lzMsljcvfP0Pi4VOM2QDL71WMMbKbOgBH1V18axyVyuLri9WeYeHen+jUIiyr0I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=phlplVaG; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="phlplVaG" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7Z3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:25 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7Z3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758886; bh=SjNhSZbcKGusmLjwXANGU7MqZ8m12LMeSX+punktfiM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=phlplVaGiCSI5D3kXFxsiMtEGU9zI3UNif41GiNqCtYU7U2Mkaf8M3Eba2v9+Kvx+ dfF6WhOz3CH7s652NFXR3/evZNy3BCcDkiPUu+juMC6dGwD9NbD8izYzrgGzFqP2El 69KQaiplOhd4VW02YZrKT8znZC3ev6ZAnpaiNaJBbODdUnaHqsZS8ixNFwu4W0xXFo ajoEqkQBHZpSh85iGWq63lAUpoP3qcKX4wJkQbHp7D3/jtV3ckcXykgz7o3Bah5PtU /5jFXDGeYHN1n1kYhYu3gJgEidSYpcn+b8lA2HWK3yfFrTSnKahwcfuFp/FfXib37N u745axsU1PUjg== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 10/27] KVM: VMX: Set FRED MSR interception Date: Mon, 30 Sep 2024 22:00:53 -0700 Message-ID: <20241001050110.3643764-11-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Add FRED MSRs to the VMX passthrough MSR list and set FRED MSRs interception. 8 FRED MSRs, i.e., MSR_IA32_FRED_RSP[123], MSR_IA32_FRED_STKLVLS, MSR_IA32_FRED_SSP[123] and MSR_IA32_FRED_CONFIG, are all safe to be passthrough, because they all have a pair of corresponding host and guest VMCS fields. Both MSR_IA32_FRED_RSP0 and MSR_IA32_FRED_SSP0 are dedicated for user level event delivery only, IOW they are NOT used in any kernel event delivery and the execution of ERETS. Thus KVM can run safely with guest values in the 2 MSRs. As a result, save and restore of their guest values are postponed until vCPU context switching and their host values are restored on returning to userspace. Save/restore of MSR_IA32_FRED_RSP0 is done in the next patch. Note, as MSR_IA32_FRED_SSP0 is an alias of MSR_IA32_PL0_SSP, its save and restore is done through the CET supervisor context management. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- arch/x86/kvm/vmx/vmx.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 28cf89c97bda..c10c955722a3 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -176,6 +176,16 @@ static u32 vmx_possible_passthrough_msrs[] = { MSR_FS_BASE, MSR_GS_BASE, MSR_KERNEL_GS_BASE, + MSR_IA32_FRED_RSP0, + MSR_IA32_FRED_RSP1, + MSR_IA32_FRED_RSP2, + MSR_IA32_FRED_RSP3, + MSR_IA32_FRED_STKLVLS, + MSR_IA32_FRED_SSP1, + MSR_IA32_FRED_SSP2, + MSR_IA32_FRED_SSP3, + MSR_IA32_FRED_CONFIG, + MSR_IA32_FRED_SSP0, /* Should be added through CET */ MSR_IA32_XFD, MSR_IA32_XFD_ERR, #endif @@ -7880,6 +7890,28 @@ static void update_intel_pt_cfg(struct kvm_vcpu *vcpu) vmx->pt_desc.ctl_bitmask &= ~(0xfULL << (32 + i * 4)); } +static void vmx_set_intercept_for_fred_msr(struct kvm_vcpu *vcpu) +{ + bool flag = !guest_can_use(vcpu, X86_FEATURE_FRED); + + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_RSP0, MSR_TYPE_RW, flag); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_RSP1, MSR_TYPE_RW, flag); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_RSP2, MSR_TYPE_RW, flag); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_RSP3, MSR_TYPE_RW, flag); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_STKLVLS, MSR_TYPE_RW, flag); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_SSP1, MSR_TYPE_RW, flag); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_SSP2, MSR_TYPE_RW, flag); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_SSP3, MSR_TYPE_RW, flag); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_CONFIG, MSR_TYPE_RW, flag); + + /* + * flag = !(CET.SUPERVISOR_SHADOW_STACK || FRED) + * + * A possible optimization is to intercept SSPs when FRED && !CET.SUPERVISOR_SHADOW_STACK. + */ + vmx_set_intercept_for_msr(vcpu, MSR_IA32_FRED_SSP0, MSR_TYPE_RW, flag); +} + void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); @@ -7957,6 +7989,8 @@ void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) /* Refresh #PF interception to account for MAXPHYADDR changes. */ vmx_update_exception_bitmap(vcpu); + + vmx_set_intercept_for_fred_msr(vcpu); } static __init u64 vmx_get_perf_capabilities(void) From patchwork Tue Oct 1 05:00:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817473 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 7BFD11BBBED; Tue, 1 Oct 2024 05:02:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; cv=none; b=sx4pHR0/9QKDYleT3dLN/brSLhXZPyZN12ETm67sarivr6OCL7k0eqo1mG8QVdoQPkbycth9OP19Up4Q6kZh3/e12W3DInjaQysEESKEB9wRclCHOqlOKtjFAFCx+JtcI3PZaoc5DQCSwGMyfARTEbZyQ7WhF7qAfVjGchpjsoE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; c=relaxed/simple; bh=29tSKrCbeAOlx9UJj6AeDJapdDmlRGBi0sBmlWQo0l8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WnJoVl4RqrZonhtubEyrRNlMqy8K+p9Zshsk6Dch1hI5Swj/OncqsT/ol75CeqJQP21bnWITcGeghTV/pLloXp13xgL9+c6gACiUU04K2cREkYxT/IeSecYm5GSTK1wiGddw9ipTJtXR/GRZRHVAef7zikD+iGZ8jJz1fSMZrtk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=PKlEfkeK; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="PKlEfkeK" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7a3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:26 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7a3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758887; bh=jX5u5mN2GSQ5NDH8yxCY+M0uBUF/2YuarNFQDDjk5ss=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PKlEfkeKiuaYX66ZDL5aJViQaBlAf9NBg4cvh4G1j8f5TZXv+nmSRFxiFWW6TAWlS 0zLLrenFftlQDNRIYpqEun7Yz9vgkrfhA/haSXSWSHKwCTyIu4UoRvlczLmZEfbBOU lyMHMHS0Yx7rAYZIW9Ra+s2glJPWQwZpRMo/s7u5xOw43nMNqNOFDkREWve2RssHkW N0MXcP3CwadHzweyAZFzYmrnnKAv1sX2C5i+IRDx4ZodBu2oTd8ua7DDlDuJ+8RECQ xlRykqk2QRpFfXjHPl+kh/BjYyCQ+NVaqGrEiD4E74hVw9HZYu6Fno3+qfLC0DS3cc qjLiD8GdLEFxQ== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 11/27] KVM: VMX: Save/restore guest FRED RSP0 Date: Mon, 30 Sep 2024 22:00:54 -0700 Message-ID: <20241001050110.3643764-12-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Save guest FRED RSP0 in vmx_prepare_switch_to_host() and restore it in vmx_prepare_switch_to_guest() because MSR_IA32_FRED_RSP0 is passed through to the guest, the guest value is volatile/unknown. Note, host FRED RSP0 is restored in arch_exit_to_user_mode_prepare(), regardless of whether it is modified in KVM. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- Changes since v2: * KVM only needs to save/restore guest FRED RSP0 now as host FRED RSP0 is restored in arch_exit_to_user_mode_prepare() (Sean Christopherson). Changes since v1: * Don't use guest_cpuid_has() in vmx_prepare_switch_to_{host,guest}(), which are called from IRQ-disabled context (Chao Gao). * Reset msr_guest_fred_rsp0 in __vmx_vcpu_reset() (Chao Gao). --- arch/x86/kvm/vmx/vmx.c | 8 ++++++++ arch/x86/kvm/vmx/vmx.h | 1 + 2 files changed, 9 insertions(+) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index c10c955722a3..c638492ebd59 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1348,6 +1348,9 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) } wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); + + if (cpu_feature_enabled(X86_FEATURE_FRED) && guest_can_use(vcpu, X86_FEATURE_FRED)) + wrmsrns(MSR_IA32_FRED_RSP0, vmx->msr_guest_fred_rsp0); #else savesegment(fs, fs_sel); savesegment(gs, gs_sel); @@ -1392,6 +1395,11 @@ static void vmx_prepare_switch_to_host(struct vcpu_vmx *vmx) invalidate_tss_limit(); #ifdef CONFIG_X86_64 wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); + + if (cpu_feature_enabled(X86_FEATURE_FRED) && guest_can_use(&vmx->vcpu, X86_FEATURE_FRED)) { + vmx->msr_guest_fred_rsp0 = read_msr(MSR_IA32_FRED_RSP0); + fred_sync_rsp0(vmx->msr_guest_fred_rsp0); + } #endif load_fixmap_gdt(raw_smp_processor_id()); vmx->guest_state_loaded = false; diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index e7409f8f28b1..9ba960472c5f 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -277,6 +277,7 @@ struct vcpu_vmx { #ifdef CONFIG_X86_64 u64 msr_host_kernel_gs_base; u64 msr_guest_kernel_gs_base; + u64 msr_guest_fred_rsp0; #endif u64 spec_ctrl; From patchwork Tue Oct 1 05:00:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817454 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 85AA6192D74; Tue, 1 Oct 2024 05:02:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758938; cv=none; b=LrB3W8eoo+/Zz/kf+Hm9eDOIejNXTzBU/CIwavZ+vimlT2Tt/UuMIgIbaiIJkLEiBs+j+YrT7jv7+AOEEw1fCbyMi1j+S9PyY6xleGd68X7DOxXLEZhEM5yXq2oOjQc37fQSGrpFPMwRsdf5qVghw8/acru2Svt/4BB+tC7K9Jc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758938; c=relaxed/simple; bh=CWtx/mRP+r/mpwJiXi9nnsoAzgAb0wK805v+GpUvK9c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W3wWWnuFGFBHep4UmSDIWJ5dPPvRuH4ToFInj6q+l9HGhe6FoSlxDomtg5couHg/9Uxes3PJdrR1dhln3I5TPlS/zf/CIDOp171zmYT6dyyA0djm4hKOVgFwo7fooSHFJ3G8ttvFcM+5HBAouUryHwGAg0ubEEIf+7/OC/1KVHE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=ppYG5tdY; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="ppYG5tdY" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7b3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:27 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7b3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758888; bh=u/W8FqIpYceGvlBt/jZhU4dFvclVcZ1Loz/v27Qn560=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ppYG5tdYC6LWKuXaep3CoURrWaYQ2AxPSYW638XW2OBMIBxWvdsyYHzzPQ/h0fR+2 gTaXD0r8ohyx/UBvMGGyT8UnW+OuLN3WRqu2anExDeHphOSADdbKOXlnCYDGSX0J9q Nm3/XHGrHDQGpWdKxeUEBOKThMW00rkdGE9nrryNjbWPvAjDqNpZtbKBpqg7FjX1IP 738h6WZPqfYLy3okX5Fem2RyRuthyDuXvmoM7A+j9HlwRf4XkRKfXPCbTnDZx+4VCF /zZE6/lDModSx266Y3fB8tJ57tOz3die1Zz5hNLbFDLA/maaZWpl1q+WCBZZ8Hik1q ZTjKhhkz9YhmA== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 12/27] KVM: VMX: Add support for FRED context save/restore Date: Mon, 30 Sep 2024 22:00:55 -0700 Message-ID: <20241001050110.3643764-13-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Handle FRED MSR access requests, allowing FRED context to be set/get from both host and guest. During VM save/restore and live migration, FRED context needs to be saved/restored, which requires FRED MSRs to be accessed from userspace, e.g., Qemu. Note, handling of MSR_IA32_FRED_SSP0, i.e., MSR_IA32_PL0_SSP, is not added yet, which is done in the KVM CET patch set. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- Changes since v2: * Add a helper to convert FRED MSR index to VMCS field encoding to make the code more compact (Chao Gao). * Get rid of the "host_initiated" check because userspace has to set CPUID before MSRs (Chao Gao & Sean Christopherson). * Address a few cleanup comments (Sean Christopherson). Changes since v1: * Use kvm_cpu_cap_has() instead of cpu_feature_enabled() (Chao Gao). * Fail host requested FRED MSRs access if KVM cannot virtualize FRED (Chao Gao). * Handle the case FRED MSRs are valid but KVM cannot virtualize FRED (Chao Gao). * Add sanity checks when writing to FRED MSRs. --- arch/x86/kvm/vmx/vmx.c | 48 ++++++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/x86.c | 25 ++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index c638492ebd59..65ab26b13d24 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1424,6 +1424,24 @@ static void vmx_write_guest_kernel_gs_base(struct vcpu_vmx *vmx, u64 data) preempt_enable(); vmx->msr_guest_kernel_gs_base = data; } + +static u64 vmx_read_guest_fred_rsp0(struct vcpu_vmx *vmx) +{ + preempt_disable(); + if (vmx->guest_state_loaded) + vmx->msr_guest_fred_rsp0 = read_msr(MSR_IA32_FRED_RSP0); + preempt_enable(); + return vmx->msr_guest_fred_rsp0; +} + +static void vmx_write_guest_fred_rsp0(struct vcpu_vmx *vmx, u64 data) +{ + preempt_disable(); + if (vmx->guest_state_loaded) + wrmsrns(MSR_IA32_FRED_RSP0, data); + preempt_enable(); + vmx->msr_guest_fred_rsp0 = data; +} #endif static void grow_ple_window(struct kvm_vcpu *vcpu) @@ -2036,6 +2054,24 @@ int vmx_get_feature_msr(u32 msr, u64 *data) } } +#ifdef CONFIG_X86_64 +static u32 fred_msr_vmcs_fields[] = { + GUEST_IA32_FRED_RSP1, + GUEST_IA32_FRED_RSP2, + GUEST_IA32_FRED_RSP3, + GUEST_IA32_FRED_STKLVLS, + GUEST_IA32_FRED_SSP1, + GUEST_IA32_FRED_SSP2, + GUEST_IA32_FRED_SSP3, + GUEST_IA32_FRED_CONFIG, +}; + +static u32 fred_msr_to_vmcs(u32 msr) +{ + return fred_msr_vmcs_fields[msr - MSR_IA32_FRED_RSP1]; +} +#endif + /* * Reads an msr value (of 'msr_info->index') into 'msr_info->data'. * Returns 0 on success, non-0 otherwise. @@ -2058,6 +2094,12 @@ int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_KERNEL_GS_BASE: msr_info->data = vmx_read_guest_kernel_gs_base(vmx); break; + case MSR_IA32_FRED_RSP0: + msr_info->data = vmx_read_guest_fred_rsp0(vmx); + break; + case MSR_IA32_FRED_RSP1 ... MSR_IA32_FRED_CONFIG: + msr_info->data = vmcs_read64(fred_msr_to_vmcs(msr_info->index)); + break; #endif case MSR_EFER: return kvm_get_msr_common(vcpu, msr_info); @@ -2265,6 +2307,12 @@ int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) vmx_update_exception_bitmap(vcpu); } break; + case MSR_IA32_FRED_RSP0: + vmx_write_guest_fred_rsp0(vmx, data); + break; + case MSR_IA32_FRED_RSP1 ... MSR_IA32_FRED_CONFIG: + vmcs_write64(fred_msr_to_vmcs(msr_index), data); + break; #endif case MSR_IA32_SYSENTER_CS: if (is_guest_mode(vcpu)) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e8de9f4734a6..b31ebafbe0bc 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -320,6 +320,9 @@ static const u32 msrs_to_save_base[] = { MSR_STAR, #ifdef CONFIG_X86_64 MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, + MSR_IA32_FRED_RSP0, MSR_IA32_FRED_RSP1, MSR_IA32_FRED_RSP2, + MSR_IA32_FRED_RSP3, MSR_IA32_FRED_STKLVLS, MSR_IA32_FRED_SSP1, + MSR_IA32_FRED_SSP2, MSR_IA32_FRED_SSP3, MSR_IA32_FRED_CONFIG, #endif MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA, MSR_IA32_FEAT_CTL, MSR_IA32_BNDCFGS, MSR_TSC_AUX, @@ -1891,6 +1894,20 @@ static int __kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data, data = (u32)data; break; + case MSR_IA32_FRED_RSP0 ... MSR_IA32_FRED_CONFIG: + if (!guest_can_use(vcpu, X86_FEATURE_FRED)) + return 1; + + if (index != MSR_IA32_FRED_STKLVLS && is_noncanonical_address(data, vcpu)) + return 1; + if ((index >= MSR_IA32_FRED_RSP0 && index <= MSR_IA32_FRED_RSP3) && + (data & GENMASK_ULL(5, 0))) + return 1; + if ((index >= MSR_IA32_FRED_SSP1 && index <= MSR_IA32_FRED_SSP3) && + (data & GENMASK_ULL(2, 0))) + return 1; + + break; } msr.data = data; @@ -1935,6 +1952,10 @@ int __kvm_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data, !guest_cpuid_has(vcpu, X86_FEATURE_RDPID)) return 1; break; + case MSR_IA32_FRED_RSP0 ... MSR_IA32_FRED_CONFIG: + if (!guest_can_use(vcpu, X86_FEATURE_FRED)) + return 1; + break; } msr.index = index; @@ -7460,6 +7481,10 @@ static void kvm_probe_msr_to_save(u32 msr_index) if (!(kvm_get_arch_capabilities() & ARCH_CAP_TSX_CTRL_MSR)) return; break; + case MSR_IA32_FRED_RSP0 ... MSR_IA32_FRED_CONFIG: + if (!kvm_cpu_cap_has(X86_FEATURE_FRED)) + return; + break; default: break; } From patchwork Tue Oct 1 05:00:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817448 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 6C301322E; Tue, 1 Oct 2024 05:02:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758936; cv=none; b=ixqzn25kVbx3rvpOfuDkMh3kNCAZWxVgfJ77xqqsVa2fHOzQKD2OJpExtRVDsBLCqq0mGIUXRo6hssNbyOFjA6lwjqdFGo75RMmqMHzIEPZUCnXwyU+RHeRIZPxNqcpyUodkiMxopNOvCkONIJtecMN22T4X9YmI9oLCVKmkYx8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758936; c=relaxed/simple; bh=WcA6m/Yx90+CLRQ2TAp3UxKRvYuyJoHgvwfYIpMVil8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=r30TSYo44B/sDc3ItiTmgKoIN8DrNCRI5UlXgbMIyM+xQypXBLBKbsSrUv7uTcEIu5IAWSwuJzdtNJdOkS9itSFTjyPcBF6BMP5InETH0Fdkm5XWxghL1JYUDFJi+w22KLSe7Ehz6pos423uZn0stj1UfIIemWaAnuv/EIoUBNE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=fywBXWQT; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="fywBXWQT" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7c3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:28 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7c3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758889; bh=S2anEe6gVhX8RpVekZcYrZwLDqpmlt2eOrTn5hH3hT4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fywBXWQTEL2POH0qz4N+/pCr/+ptIZUSOkqy3nVYI4gf3Ldo0f78XDYsv3HJSKJM0 y23vl6htUKaJ8OooodQM1DhCD7fccqBGLH0nljmJAPl3ZEljsbNCN/zBt7Imfa6SLF g+WEvZb2QTWK+d9l1fzYr5NFuD2s0/VDIpdPGo/9PaHqZk772ykz/LozxSuMrjrFOj zthEYc7mH7lXU50AcVEZCQZKFTgMOmpyyctJvRk5V+iuxQwI1S0mo/pG94dB27uAC+ DRiJSdbiG/CiyHek6aXi7E2xZTTrBbrhAcTHBXeQRrnTaPwJ8kJLQ90rAofOqCsIOq O7ESO8FTUmoGg== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 13/27] KVM: x86: Add a helper to detect if FRED is enabled for a vCPU Date: Mon, 30 Sep 2024 22:00:56 -0700 Message-ID: <20241001050110.3643764-14-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Add is_fred_enabled() to detect if FRED is enabled on a vCPU. Signed-off-by: Xin Li [ Sean: removed the "kvm_" prefix from the function name ] Signed-off-by: Sean Christopherson Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- arch/x86/kvm/kvm_cache_regs.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h index b1eb46e26b2e..386c79f5dcb8 100644 --- a/arch/x86/kvm/kvm_cache_regs.h +++ b/arch/x86/kvm/kvm_cache_regs.h @@ -187,6 +187,21 @@ static __always_inline bool kvm_is_cr4_bit_set(struct kvm_vcpu *vcpu, return !!kvm_read_cr4_bits(vcpu, cr4_bit); } +/* + * It's enough to check just CR4.FRED (X86_CR4_FRED) to tell if + * a vCPU is running with FRED enabled, because: + * 1) CR4.FRED can be set to 1 only _after_ IA32_EFER.LMA = 1. + * 2) To leave IA-32e mode, CR4.FRED must be cleared first. + */ +static inline bool is_fred_enabled(struct kvm_vcpu *vcpu) +{ +#ifdef CONFIG_X86_64 + return kvm_is_cr4_bit_set(vcpu, X86_CR4_FRED); +#else + return false; +#endif +} + static inline ulong kvm_read_cr3(struct kvm_vcpu *vcpu) { if (!kvm_register_is_available(vcpu, VCPU_EXREG_CR3)) From patchwork Tue Oct 1 05:00:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817462 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 6F7151BBBC0; Tue, 1 Oct 2024 05:02:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758939; cv=none; b=efcs0SW1hTI8QD7An6+ITH3241QxeJB3Avll6gFDZvDu8pzwFr8DoxcyjLR6K08lMCoiURFnFQmXSO9LfyE66GaobP8rxVyoCv3k2XJ5YZptku4buO7iFOIfF2W89Jh9nDKdjcwJbByQBN+EDCyYf5uG3rWh86CZaeh/4VXwkc4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758939; c=relaxed/simple; bh=FaOy2OKqH01C/5KaZwl3BA3eqU5CpRgqgJfpSRXqSFQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rzRApy5iyVFW/vyxiIMRpz8EwXyGxkBLwkWCnMEPl2YeAeA/o0668otvQ7adseuBzLbZuSdg0oQ5Vi7b7TP+2MtsYtLHK+C7se6Wd8TBpOq39h/jrLiDNztmhm4GbQrKrwkLEyGY7hEjgnKlCpk+uPWKEu1UTQ/wvVU+94MJzbI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=oWgBmdBM; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="oWgBmdBM" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7d3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:29 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7d3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758890; bh=aFNnDSBwVY5YKUBEj/le6GcdKhI3wUL+k7nBIu5vESQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oWgBmdBMjl2otaU1XfWCC+8W37HzOFp98bNixS5+a9Eg5MnudDAsElV/ZdksaXSB5 s/qyiQuKDdSSTKJZzJEe53Tzl03GHPc19boFabExtOrj/kYQQnDqQK2O+zXl0PDoLm mPuCY9miR5z0zhQ0WhDl6zxdqBdDpzNLsgJGozNpu0QVEVC3QuWd6E88zX4ZfuBFtW IfU4YOYh+E29+d5ECQOkT/T43Nb6S1je2O1eaVP6ik6ZiTE19sBKgx3StAl1m1Q29Q vbUsw4805zTTN2Xj1pmiOO65IDh0wtBDWsy1nHVrC2JwOckfdC0Kt5hPILE4cXfoWn yvNsJWQZs2E9g== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 14/27] KVM: VMX: Pass XFD_ERR as pseudo-payload when injecting #NM Date: Mon, 30 Sep 2024 22:00:57 -0700 Message-ID: <20241001050110.3643764-15-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Sean Christopherson Pass XFD_ERR via KVM's exception payload mechanism when injecting an #NM after interception so that XFD_ERR can be propagated to FRED's event_data field without needing a dedicated field (which would need to be migrated). For non-FRED vCPUs, this is a glorified NOP as kvm_deliver_exception_payload() will simply do nothing (which is desirable and correct). Signed-off-by: Sean Christopherson Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- arch/x86/kvm/vmx/vmx.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 65ab26b13d24..686006fe6d45 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -5336,6 +5336,12 @@ bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu) (kvm_get_rflags(vcpu) & X86_EFLAGS_AC); } +static bool is_xfd_nm_fault(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.guest_fpu.fpstate->xfd && + !kvm_is_cr0_bit_set(vcpu, X86_CR0_TS); +} + static int handle_exception_nmi(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); @@ -5362,7 +5368,8 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu) * point. */ if (is_nm_fault(intr_info)) { - kvm_queue_exception(vcpu, NM_VECTOR); + kvm_queue_exception_p(vcpu, NM_VECTOR, + is_xfd_nm_fault(vcpu) ? vcpu->arch.guest_fpu.xfd_err : 0); return 1; } @@ -7110,14 +7117,13 @@ static void handle_nm_fault_irqoff(struct kvm_vcpu *vcpu) * * Update the guest's XFD_ERR if and only if XFD is enabled, as the #NM * interception may have been caused by L1 interception. Per the SDM, - * XFD_ERR is not modified if CR0.TS=1. + * XFD_ERR is not modified for non-XFD #NM, i.e. if CR0.TS=1. * * Note, XFD_ERR is updated _before_ the #NM interception check, i.e. * unlike CR2 and DR6, the value is not a payload that is attached to * the #NM exception. */ - if (vcpu->arch.guest_fpu.fpstate->xfd && - !kvm_is_cr0_bit_set(vcpu, X86_CR0_TS)) + if (is_xfd_nm_fault(vcpu)) rdmsrl(MSR_IA32_XFD_ERR, vcpu->arch.guest_fpu.xfd_err); } From patchwork Tue Oct 1 05:00:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817468 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 730D61BBBC3; Tue, 1 Oct 2024 05:02:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; cv=none; b=oA4GRiVf0AByRYqTNvJPTR/7wMCz4NhjGj627lbj56vQH8Hcyzaj4TX/3dnkUnvy86GA5fBbRusCafvCWS0NpR/uheMVKiFl1WlUN3MN521jFVyNOnpi3KOA3680KDaWN3z5i0BR4JPWb0dOUbwSLi0bpwwfg7YLtYaiEwA4Apo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; c=relaxed/simple; bh=FfvwUJmcqygfmVKQuKsVdG12zBfzQdS9GdIiRdLxCEo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EDD8vegjtB7Gw1p1AFkQn9uBxaHo/6VPjvX+mP3cuoUj8DIVomABl4om4PMnj2/AKYYt3Ocedykml0FNtvszaUx+DOX1H1GZHazRX8Hsdwj7QIfbjbdjfcrgwhSEMptILVUz7jHsvXUfKJstVtdz/ZywOkbevP9ITz2n0KIDI/g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=DgH7tILr; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="DgH7tILr" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7e3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:30 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7e3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758891; bh=YujS5b0tGKkjcZEYpGNmcwRivEXkaOGjJ/hmns7x13Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DgH7tILrnCwPruR0DC3hezUipz+S3fq+P6gX/RZcZYAJkYKu91PZfBYsgb1EEs/gb IhUZX4zOm/qSbNMkMobzIDuej371qllk6f2XEr+qRiKc6ImntELzBykMKGNPmO8Tpo LdK+yWXQ4FekEeoVRC+Vaf8ZxAeH0j+9ha8zZb850RSVVk5l+hidKFzOI1Ee+A8N19 04Xwe4RrDBOWtTmX+rleTIga4umn/E6ox8FhzLs8rGxCpgQCf1dqNVLHRySBqrBoSL 9YtX/cXzeSgRiYySKzFWZMMe6rLL91g0WNYLC6+9WHv21OXmGF6gzvaY/R4FOBkCxH 5ENZwgI/+0Qeg== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 15/27] KVM: VMX: Virtualize FRED event_data Date: Mon, 30 Sep 2024 22:00:58 -0700 Message-ID: <20241001050110.3643764-16-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Set injected-event data when injecting a #PF, #DB, or #NM caused by extended feature disable using FRED event delivery, and save original-event data for being used as injected-event data. Unlike IDT using some extra CPU register as part of an event context, e.g., %cr2 for #PF, FRED saves a complete event context in its stack frame, e.g., FRED saves the faulting linear address of a #PF into the event data field defined in its stack frame. Thus a new VMX control field called injected-event data is added to provide the event data that will be pushed into a FRED stack frame for VM entries that inject an event using FRED event delivery. In addition, a new VM exit information field called original-event data is added to store the event data that would have saved into a FRED stack frame for VM exits that occur during FRED event delivery. After such a VM exit is handled to allow the original-event to be delivered, the data in the original-event data VMCS field needs to be set into the injected-event data VMCS field for the injection of the original event. Signed-off-by: Xin Li [ Sean: reworked event data injection for nested ] Signed-off-by: Sean Christopherson Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- Changes since v2: * Rework event data injection for nested (Chao Gao & Sean Christopherson). Changes since v1: * Document event data should be equal to CR2/DR6/IA32_XFD_ERR instead of using WARN_ON() (Chao Gao). * Zero event data if a #NM was not caused by extended feature disable (Chao Gao). --- arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/include/asm/vmx.h | 4 ++++ arch/x86/kvm/svm/svm.c | 2 +- arch/x86/kvm/vmx/vmx.c | 22 ++++++++++++++++++---- arch/x86/kvm/x86.c | 16 +++++++++++++++- 5 files changed, 40 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 43b08d12cb32..b9b82aaea9a3 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -736,6 +736,7 @@ struct kvm_queued_exception { u32 error_code; unsigned long payload; bool has_payload; + u64 event_data; }; struct kvm_vcpu_arch { @@ -2113,7 +2114,7 @@ void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr); void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, unsigned long payload); void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned int nr, - bool has_error_code, u32 error_code); + bool has_error_code, u32 error_code, u64 event_data); void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault); void kvm_inject_emulated_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault); diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 5184e03945dd..3696e763c231 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -265,8 +265,12 @@ enum vmcs_field { PID_POINTER_TABLE_HIGH = 0x00002043, SECONDARY_VM_EXIT_CONTROLS = 0x00002044, SECONDARY_VM_EXIT_CONTROLS_HIGH = 0x00002045, + INJECTED_EVENT_DATA = 0x00002052, + INJECTED_EVENT_DATA_HIGH = 0x00002053, GUEST_PHYSICAL_ADDRESS = 0x00002400, GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401, + ORIGINAL_EVENT_DATA = 0x00002404, + ORIGINAL_EVENT_DATA_HIGH = 0x00002405, VMCS_LINK_POINTER = 0x00002800, VMCS_LINK_POINTER_HIGH = 0x00002801, GUEST_IA32_DEBUGCTL = 0x00002802, diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index d9e2568bcd54..7fa8f842f116 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4126,7 +4126,7 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu) kvm_requeue_exception(vcpu, vector, exitintinfo & SVM_EXITINTINFO_VALID_ERR, - error_code); + error_code, 0); break; } case SVM_EXITINTINFO_TYPE_INTR: diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 686006fe6d45..d81144bd648f 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1915,6 +1915,9 @@ void vmx_inject_exception(struct kvm_vcpu *vcpu) vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info); + if (is_fred_enabled(vcpu)) + vmcs_write64(INJECTED_EVENT_DATA, ex->event_data); + vmx_clear_hlt(vcpu); } @@ -7241,7 +7244,8 @@ static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx) static void __vmx_complete_interrupts(struct kvm_vcpu *vcpu, u32 idt_vectoring_info, int instr_len_field, - int error_code_field) + int error_code_field, + int event_data_field) { u8 vector; int type; @@ -7276,13 +7280,17 @@ static void __vmx_complete_interrupts(struct kvm_vcpu *vcpu, fallthrough; case INTR_TYPE_HARD_EXCEPTION: { u32 error_code = 0; + u64 event_data = 0; if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) error_code = vmcs_read32(error_code_field); + if (is_fred_enabled(vcpu)) + event_data = vmcs_read64(event_data_field); kvm_requeue_exception(vcpu, vector, idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK, - error_code); + error_code, + event_data); break; } case INTR_TYPE_SOFT_INTR: @@ -7300,7 +7308,8 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx) { __vmx_complete_interrupts(&vmx->vcpu, vmx->idt_vectoring_info, VM_EXIT_INSTRUCTION_LEN, - IDT_VECTORING_ERROR_CODE); + IDT_VECTORING_ERROR_CODE, + ORIGINAL_EVENT_DATA); } void vmx_cancel_injection(struct kvm_vcpu *vcpu) @@ -7308,7 +7317,8 @@ void vmx_cancel_injection(struct kvm_vcpu *vcpu) __vmx_complete_interrupts(vcpu, vmcs_read32(VM_ENTRY_INTR_INFO_FIELD), VM_ENTRY_INSTRUCTION_LEN, - VM_ENTRY_EXCEPTION_ERROR_CODE); + VM_ENTRY_EXCEPTION_ERROR_CODE, + INJECTED_EVENT_DATA); vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0); } @@ -7439,6 +7449,10 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu, vmx_disable_fb_clear(vmx); + /* + * Note, even though FRED delivers the faulting linear address via the + * event data field on the stack, CR2 is still updated. + */ if (vcpu->arch.cr2 != native_read_cr2()) native_write_cr2(vcpu->arch.cr2); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index b31ebafbe0bc..7a55c1eb5297 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -810,9 +810,22 @@ void kvm_deliver_exception_payload(struct kvm_vcpu *vcpu, * breakpoint), it is reserved and must be zero in DR6. */ vcpu->arch.dr6 &= ~BIT(12); + + /* + * FRED #DB event data matches DR6, but follows the polarity of + * VMX's pending debug exceptions, not DR6. + */ + ex->event_data = ex->payload & ~BIT(12); + break; + case NM_VECTOR: + ex->event_data = ex->payload; break; case PF_VECTOR: vcpu->arch.cr2 = ex->payload; + ex->event_data = ex->payload; + break; + default: + ex->event_data = 0; break; } @@ -920,7 +933,7 @@ static void kvm_queue_exception_e_p(struct kvm_vcpu *vcpu, unsigned nr, } void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned int nr, - bool has_error_code, u32 error_code) + bool has_error_code, u32 error_code, u64 event_data) { /* @@ -945,6 +958,7 @@ void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned int nr, vcpu->arch.exception.error_code = error_code; vcpu->arch.exception.has_payload = false; vcpu->arch.exception.payload = 0; + vcpu->arch.exception.event_data = event_data; } EXPORT_SYMBOL_GPL(kvm_requeue_exception); From patchwork Tue Oct 1 05:00:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817455 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 8316C1925B6; Tue, 1 Oct 2024 05:02:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758938; cv=none; b=KsTuucEGPwmTLxygKJKXUyS8iMMdqOmr/evpGhGqi/Dq8XAh82gcumT5owPTHT7ezYGbdNeo3L1zL/tZGXXDgYiTIxVmg69TqHuv/pE7rxglMTQAena5yV5CqaEvJaOMe9o6p+RcSHKABoQN+MmHwDkfKFCNttwjEczQEEjBtEA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758938; c=relaxed/simple; bh=mCkohbTcQM3OhnebCYH4eSDKx8rcuiPi7jM7ZLpzKgA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=q0jZH1yF/9xm7T3ZnZe3a1RWTY/KOl0N+wzvCtcKwqXhDfG+73v9vMEXPuNlj8AnIyprEsWFwC0lknA+kRwWsgDdW8TOtqGrmHMpRQkDePRe/sohGLqUiwGXhxbXgbIlo+5a6N3WDR1KOk0qcCGlvKlNHX5Di12tLxcMjSXOvQE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=dBgJ/U8q; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="dBgJ/U8q" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7f3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:31 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7f3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758892; bh=9kW2gZpTOB82/3a1Ui+rKwBVrrwaTpl5XFZLMCcWnSA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dBgJ/U8q1CgC7kCrLZ5Pikz2FJ43vOI6RQxOxDgejzgAB4+eMtroKDWvRFGDICYRk X5NhMTpxznv0CG+vYxx/kVN6oDfAPNv+jjNNFuUBk6en81M5q3YeGbPse4zkOKd34j 3fe1tVQQSDy8xFm4RG0lV6B6UuxVd4D5uauZUyGNVKVRhKGVuhZ9EZyT9I04JpQZAq xrugSLt2JXNNeBhV4+4sU2lxZZv7MoVEIxMw/kjkCjmJVyyQMtMQMzvZNch4IGwosz wrAw5h5AQfovt1gQdq1FtzHY5g0zLOw6cIPfwPHm/wL5pQybWXlzy8ZNHiJHoAo38p bdmkClw1YRTRw== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 16/27] KVM: VMX: Virtualize FRED nested exception tracking Date: Mon, 30 Sep 2024 22:00:59 -0700 Message-ID: <20241001050110.3643764-17-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Set VMX nested exception bit in the VM-entry interruption information VMCS field when injecting a nested exception using FRED event delivery to ensure: 1) The nested exception is injected on a correct stack level. 2) The nested bit defined in FRED stack frame is set. The event stack level used by FRED event delivery depends on whether the event was a nested exception encountered during delivery of another event, because a nested exception is "regarded" as happening on ring 0. E.g., when #PF is configured to use stack level 1 in IA32_FRED_STKLVLS MSR: - nested #PF will be delivered on stack level 1 when encountered in ring 3. - normal #PF will be delivered on stack level 0 when encountered in ring 3. The VMX nested-exception support ensures the correct event stack level is chosen when a VM entry injects a nested exception. Signed-off-by: Xin Li [ Sean: reworked kvm_requeue_exception() to simply the code changes ] Signed-off-by: Sean Christopherson Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- Change since v2: * Rework kvm_requeue_exception() to simply the code changes (Sean Christopherson). Change since v1: * Set the nested flag when there is an original interrupt (Chao Gao). --- arch/x86/include/asm/kvm_host.h | 4 +++- arch/x86/include/asm/vmx.h | 5 ++++- arch/x86/kvm/svm/svm.c | 2 +- arch/x86/kvm/vmx/vmx.c | 6 +++++- arch/x86/kvm/x86.c | 14 +++++++++++++- arch/x86/kvm/x86.h | 1 + 6 files changed, 27 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index b9b82aaea9a3..3830084b569b 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -736,6 +736,7 @@ struct kvm_queued_exception { u32 error_code; unsigned long payload; bool has_payload; + bool nested; u64 event_data; }; @@ -2114,7 +2115,8 @@ void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr); void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr, unsigned long payload); void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned int nr, - bool has_error_code, u32 error_code, u64 event_data); + bool has_error_code, u32 error_code, bool nested, + u64 event_data); void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault); void kvm_inject_emulated_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault); diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 3696e763c231..06c52fee5dcd 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -137,6 +137,7 @@ #define VMX_BASIC_DUAL_MONITOR_TREATMENT BIT_ULL(49) #define VMX_BASIC_INOUT BIT_ULL(54) #define VMX_BASIC_TRUE_CTLS BIT_ULL(55) +#define VMX_BASIC_NESTED_EXCEPTION BIT_ULL(58) static inline u32 vmx_basic_vmcs_revision_id(u64 vmx_basic) { @@ -416,13 +417,15 @@ enum vmcs_field { #define INTR_INFO_INTR_TYPE_MASK 0x700 /* 10:8 */ #define INTR_INFO_DELIVER_CODE_MASK 0x800 /* 11 */ #define INTR_INFO_UNBLOCK_NMI 0x1000 /* 12 */ +#define INTR_INFO_NESTED_EXCEPTION_MASK 0x2000 /* 13 */ #define INTR_INFO_VALID_MASK 0x80000000 /* 31 */ -#define INTR_INFO_RESVD_BITS_MASK 0x7ffff000 +#define INTR_INFO_RESVD_BITS_MASK 0x7fffd000 #define VECTORING_INFO_VECTOR_MASK INTR_INFO_VECTOR_MASK #define VECTORING_INFO_TYPE_MASK INTR_INFO_INTR_TYPE_MASK #define VECTORING_INFO_DELIVER_CODE_MASK INTR_INFO_DELIVER_CODE_MASK #define VECTORING_INFO_VALID_MASK INTR_INFO_VALID_MASK +#define VECTORING_INFO_NESTED_EXCEPTION_MASK INTR_INFO_NESTED_EXCEPTION_MASK #define INTR_TYPE_EXT_INTR (EVENT_TYPE_EXTINT << 8) /* external interrupt */ #define INTR_TYPE_RESERVED (EVENT_TYPE_RESERVED << 8) /* reserved */ diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 7fa8f842f116..e479e0208efe 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4126,7 +4126,7 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu) kvm_requeue_exception(vcpu, vector, exitintinfo & SVM_EXITINTINFO_VALID_ERR, - error_code, 0); + error_code, false, 0); break; } case SVM_EXITINTINFO_TYPE_INTR: diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index d81144bd648f..03f42b218554 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1910,8 +1910,11 @@ void vmx_inject_exception(struct kvm_vcpu *vcpu) vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, vmx->vcpu.arch.event_exit_inst_len); intr_info |= INTR_TYPE_SOFT_EXCEPTION; - } else + } else { intr_info |= INTR_TYPE_HARD_EXCEPTION; + if (ex->nested) + intr_info |= INTR_INFO_NESTED_EXCEPTION_MASK; + } vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info); @@ -7290,6 +7293,7 @@ static void __vmx_complete_interrupts(struct kvm_vcpu *vcpu, kvm_requeue_exception(vcpu, vector, idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK, error_code, + idt_vectoring_info & VECTORING_INFO_NESTED_EXCEPTION_MASK, event_data); break; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 7a55c1eb5297..8546629166e9 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -874,6 +874,11 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu, unsigned int nr, vcpu->arch.exception.pending = true; vcpu->arch.exception.injected = false; + vcpu->arch.exception.nested = vcpu->arch.exception.nested || + (is_fred_enabled(vcpu) && + (vcpu->arch.nmi_injected || + vcpu->arch.interrupt.injected)); + vcpu->arch.exception.has_error_code = has_error; vcpu->arch.exception.vector = nr; vcpu->arch.exception.error_code = error_code; @@ -903,8 +908,13 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu, unsigned int nr, vcpu->arch.exception.injected = false; vcpu->arch.exception.pending = false; + /* #DF is NOT a nested event, per its definition. */ + vcpu->arch.exception.nested = false; + kvm_queue_exception_e(vcpu, DF_VECTOR, 0); } else { + vcpu->arch.exception.nested = is_fred_enabled(vcpu); + /* replace previous exception with a new one in a hope that instruction re-execution will regenerate lost exception */ @@ -933,7 +943,8 @@ static void kvm_queue_exception_e_p(struct kvm_vcpu *vcpu, unsigned nr, } void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned int nr, - bool has_error_code, u32 error_code, u64 event_data) + bool has_error_code, u32 error_code, bool nested, + u64 event_data) { /* @@ -958,6 +969,7 @@ void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned int nr, vcpu->arch.exception.error_code = error_code; vcpu->arch.exception.has_payload = false; vcpu->arch.exception.payload = 0; + vcpu->arch.exception.nested = nested; vcpu->arch.exception.event_data = event_data; } EXPORT_SYMBOL_GPL(kvm_requeue_exception); diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 578fea05ff18..992e73ee2ec5 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -134,6 +134,7 @@ static inline void kvm_clear_exception_queue(struct kvm_vcpu *vcpu) { vcpu->arch.exception.pending = false; vcpu->arch.exception.injected = false; + vcpu->arch.exception.nested = false; vcpu->arch.exception_vmexit.pending = false; } From patchwork Tue Oct 1 05:01:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817470 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 4F4BF1BC091; Tue, 1 Oct 2024 05:02:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; cv=none; b=qeA05Kjkq5TEzst1elHostm8t2BDer/TWUIR5KqzXQXDEgsH9o+DoySEnwTUyng++WgmwPlaVh8yKLrYScfVpjpCRPjhlNbidr7V69VpxdY/rfe7JLrj6hsy/WcVo5PWXla+nV83aFZpg5Snq6b1wGvLs9wcOtEBEyfhHp3I4dQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; c=relaxed/simple; bh=cCXS3QGJ3gGL/feyhUz/mholtXE/la9yMJrsJIIa3Z8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BFoTfrXXXUul3Zt3RPvTKyXS/c+vAVgcG+9fFZnSL5WpvHhD8TXqpxAQqHv/7UL1t2DH31k8ZrqhepFX/E87i5lDMaObiOfm1pNpvfbiXB7pFmasQi4pjQ+ItS89wr5NBsghaOsE/y90fP3J21Fl3M3x91D+zJNUoSd8xGFReVk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=QITtegD9; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="QITtegD9" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7g3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:32 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7g3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758893; bh=UYAkdDGgqqEL7Q7x/r0wK+q8dSQmiECINofEe79ZVk4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QITtegD9RMAjCLagc7MIyxSEcq6XAQBaZEjdFbyKoYl5jNyirtuGTieqtNlwWM8xD DAKv3wccYOa66wR1PHKWBIHjos1AX3coG1V8z8zyGnrwsrbhoGG/L6bDSk7VTxG/kO HEFRhw/PP0uiLMdUtgGhaCUqhkjSbwkhqwZ7ei+o6ko+MtmFSxO7c3JkOXPzC9tc5I SBtQ+De1WSSWx0/FM3K8XFJgBiL34ErT1fZa3fAhqEQWLNMM91g9L/NkZrju1KOxP+ an27O7U/AAj/AH22Y8cFNYGgKrd1Mde2VSZtmUQKuKDDo20gQYWRVlTUo8el76pDoT plDhi9IadUp2Q== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 17/27] KVM: x86: Mark CR4.FRED as not reserved when guest can use FRED Date: Mon, 30 Sep 2024 22:01:00 -0700 Message-ID: <20241001050110.3643764-18-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li The CR4.FRED bit, i.e., CR4[32], is no longer a reserved bit when guest can use FRED, i.e., 1) All of FRED KVM support is in place. 2) Guest enumerates FRED. Otherwise it is still a reserved bit. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- Changes since v2: * Don't allow CR4.FRED=1 before all of FRED KVM support is in place (Sean Christopherson). --- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/vmx/vmx.c | 4 ++++ arch/x86/kvm/x86.h | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 3830084b569b..87f9f0b6cf3c 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -136,7 +136,7 @@ | X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \ | X86_CR4_OSXMMEXCPT | X86_CR4_LA57 | X86_CR4_VMXE \ | X86_CR4_SMAP | X86_CR4_PKE | X86_CR4_UMIP \ - | X86_CR4_LAM_SUP)) + | X86_CR4_LAM_SUP | X86_CR4_FRED)) #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 03f42b218554..bfdd10773136 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -8009,6 +8009,10 @@ void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) kvm_governed_feature_check_and_set(vcpu, X86_FEATURE_LAM); kvm_governed_feature_check_and_set(vcpu, X86_FEATURE_FRED); + /* Don't allow CR4.FRED=1 before all of FRED KVM support is in place. */ + if (!guest_can_use(vcpu, X86_FEATURE_FRED)) + vcpu->arch.cr4_guest_rsvd_bits |= X86_CR4_FRED; + vmx_setup_uret_msrs(vmx); if (cpu_has_secondary_exec_ctrls()) diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 992e73ee2ec5..0ed91512b757 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -561,6 +561,8 @@ enum kvm_msr_access { __reserved_bits |= X86_CR4_PCIDE; \ if (!__cpu_has(__c, X86_FEATURE_LAM)) \ __reserved_bits |= X86_CR4_LAM_SUP; \ + if (!__cpu_has(__c, X86_FEATURE_FRED)) \ + __reserved_bits |= X86_CR4_FRED; \ __reserved_bits; \ }) From patchwork Tue Oct 1 05:01:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817458 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 86F1519307D; Tue, 1 Oct 2024 05:02:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758938; cv=none; b=kGfm0Ee47BPtRmHDUSYFEUe5gxH0kZaJ25srouOdxjW+Tws9GErfowoMUwUnKDQCyIZIaDSNHd7Z0yDn2hQgw4tdEunpZgC1nl3H0p/g9D15WqUQ66kWnH5zScnznfibDuUjYwPxgckHMZZwLc5W9HjZUpxCv+QzOnh2H8YfVzs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758938; c=relaxed/simple; bh=PJ0Ruvlhl5M8W6RSvcvYhSrLqloxjrMLxWnQr2qse80=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XzFbG0Qpc7PPmIuTOTEPhNlfR7KgwYirSh+M8H7oDArZZnoCKFwqFMQAEWf+Bg5gPnpNL2hxc90JWQEs0YXJu9N47lH1VlNDvKFhU7Riti8YdLuyf4sA3XEDlJV4jm3O2JNfBsoLNfvrEZ0bLn+fqnMV8HcikzsMBnDCGPz/hz0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=jFou4zmL; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="jFou4zmL" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7h3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:33 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7h3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758894; bh=CpAjqAnGmOHBrw112EUU3ecVY9Z5DDNeNfmxMbaNmvs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jFou4zmLraTdJHufGkOsayw4l/aOSyJ4anTJ2B064rz9sIG1j+h8IB7/xEHGK1bkZ KbJogd6IqMOpuBaT/mYK+yB/q/AsPADrF8hxDXA565IC+5HDgNOG3TE2SNxhmBVXZQ fTYJG9jtiT+XpGzY58BPoO5bPwl4IpjLIGSIXR0XB8SIKmgNUw0+WpvpaNxdFEf1GJ sDbV+GN/lQEoy5eoOUR1b+PZPeQKBuIIJgj6Yb8fMmpWdQSRrGcvx7mPzba9LaySIR sFw8cOtl1oFeP7JyFhl8VdNh7hyZTq/SS5pXLOqVDdcSNSga54+TU1ZEKpw6ZS3X2h sgz1njE6VIJAQ== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 18/27] KVM: VMX: Dump FRED context in dump_vmcs() Date: Mon, 30 Sep 2024 22:01:01 -0700 Message-ID: <20241001050110.3643764-19-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Add FRED related VMCS fields to dump_vmcs() to dump FRED context. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- Change since v2: * Use (vmentry_ctrl & VM_ENTRY_LOAD_IA32_FRED) instead of is_fred_enabled() (Chao Gao). Change since v1: * Use kvm_cpu_cap_has() instead of cpu_feature_enabled() (Chao Gao). * Dump guest FRED states only if guest has FRED enabled (Nikolay Borisov). --- arch/x86/kvm/vmx/vmx.c | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index bfdd10773136..ef807194ccbd 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6399,7 +6399,7 @@ void dump_vmcs(struct kvm_vcpu *vcpu) struct vcpu_vmx *vmx = to_vmx(vcpu); u32 vmentry_ctl, vmexit_ctl; u32 cpu_based_exec_ctrl, pin_based_exec_ctrl, secondary_exec_control; - u64 tertiary_exec_control; + u64 tertiary_exec_control, secondary_vmexit_ctl; unsigned long cr4; int efer_slot; @@ -6410,6 +6410,8 @@ void dump_vmcs(struct kvm_vcpu *vcpu) vmentry_ctl = vmcs_read32(VM_ENTRY_CONTROLS); vmexit_ctl = vmcs_read32(VM_EXIT_CONTROLS); + secondary_vmexit_ctl = cpu_has_secondary_vmexit_ctrls() ? + vmcs_read64(SECONDARY_VM_EXIT_CONTROLS) : 0; cpu_based_exec_ctrl = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); pin_based_exec_ctrl = vmcs_read32(PIN_BASED_VM_EXEC_CONTROL); cr4 = vmcs_readl(GUEST_CR4); @@ -6456,6 +6458,16 @@ void dump_vmcs(struct kvm_vcpu *vcpu) vmx_dump_sel("LDTR:", GUEST_LDTR_SELECTOR); vmx_dump_dtsel("IDTR:", GUEST_IDTR_LIMIT); vmx_dump_sel("TR: ", GUEST_TR_SELECTOR); + if (vmentry_ctl & VM_ENTRY_LOAD_IA32_FRED) + pr_err("FRED guest: config=0x%016llx, stack_levels=0x%016llx\n" + "RSP0=0x%016llx, RSP1=0x%016llx\n" + "RSP2=0x%016llx, RSP3=0x%016llx\n", + vmcs_read64(GUEST_IA32_FRED_CONFIG), + vmcs_read64(GUEST_IA32_FRED_STKLVLS), + __rdmsr(MSR_IA32_FRED_RSP0), + vmcs_read64(GUEST_IA32_FRED_RSP1), + vmcs_read64(GUEST_IA32_FRED_RSP2), + vmcs_read64(GUEST_IA32_FRED_RSP3)); efer_slot = vmx_find_loadstore_msr_slot(&vmx->msr_autoload.guest, MSR_EFER); if (vmentry_ctl & VM_ENTRY_LOAD_IA32_EFER) pr_err("EFER= 0x%016llx\n", vmcs_read64(GUEST_IA32_EFER)); @@ -6503,6 +6515,16 @@ void dump_vmcs(struct kvm_vcpu *vcpu) vmcs_readl(HOST_TR_BASE)); pr_err("GDTBase=%016lx IDTBase=%016lx\n", vmcs_readl(HOST_GDTR_BASE), vmcs_readl(HOST_IDTR_BASE)); + if (vmexit_ctl & SECONDARY_VM_EXIT_LOAD_IA32_FRED) + pr_err("FRED host: config=0x%016llx, stack_levels=0x%016llx\n" + "RSP0=0x%016lx, RSP1=0x%016llx\n" + "RSP2=0x%016llx, RSP3=0x%016llx\n", + vmcs_read64(HOST_IA32_FRED_CONFIG), + vmcs_read64(HOST_IA32_FRED_STKLVLS), + (unsigned long)task_stack_page(current) + THREAD_SIZE, + vmcs_read64(HOST_IA32_FRED_RSP1), + vmcs_read64(HOST_IA32_FRED_RSP2), + vmcs_read64(HOST_IA32_FRED_RSP3)); pr_err("CR0=%016lx CR3=%016lx CR4=%016lx\n", vmcs_readl(HOST_CR0), vmcs_readl(HOST_CR3), vmcs_readl(HOST_CR4)); @@ -6524,25 +6546,29 @@ void dump_vmcs(struct kvm_vcpu *vcpu) pr_err("*** Control State ***\n"); pr_err("CPUBased=0x%08x SecondaryExec=0x%08x TertiaryExec=0x%016llx\n", cpu_based_exec_ctrl, secondary_exec_control, tertiary_exec_control); - pr_err("PinBased=0x%08x EntryControls=%08x ExitControls=%08x\n", - pin_based_exec_ctrl, vmentry_ctl, vmexit_ctl); + pr_err("PinBased=0x%08x EntryControls=0x%08x\n", + pin_based_exec_ctrl, vmentry_ctl); + pr_err("ExitControls=0x%08x SecondaryExitControls=0x%016llx\n", + vmexit_ctl, secondary_vmexit_ctl); pr_err("ExceptionBitmap=%08x PFECmask=%08x PFECmatch=%08x\n", vmcs_read32(EXCEPTION_BITMAP), vmcs_read32(PAGE_FAULT_ERROR_CODE_MASK), vmcs_read32(PAGE_FAULT_ERROR_CODE_MATCH)); - pr_err("VMEntry: intr_info=%08x errcode=%08x ilen=%08x\n", + pr_err("VMEntry: intr_info=%08x errcode=%08x ilen=%08x event_data=%016llx\n", vmcs_read32(VM_ENTRY_INTR_INFO_FIELD), vmcs_read32(VM_ENTRY_EXCEPTION_ERROR_CODE), - vmcs_read32(VM_ENTRY_INSTRUCTION_LEN)); + vmcs_read32(VM_ENTRY_INSTRUCTION_LEN), + kvm_cpu_cap_has(X86_FEATURE_FRED) ? vmcs_read64(INJECTED_EVENT_DATA) : 0); pr_err("VMExit: intr_info=%08x errcode=%08x ilen=%08x\n", vmcs_read32(VM_EXIT_INTR_INFO), vmcs_read32(VM_EXIT_INTR_ERROR_CODE), vmcs_read32(VM_EXIT_INSTRUCTION_LEN)); pr_err(" reason=%08x qualification=%016lx\n", vmcs_read32(VM_EXIT_REASON), vmcs_readl(EXIT_QUALIFICATION)); - pr_err("IDTVectoring: info=%08x errcode=%08x\n", + pr_err("IDTVectoring: info=%08x errcode=%08x event_data=%016llx\n", vmcs_read32(IDT_VECTORING_INFO_FIELD), - vmcs_read32(IDT_VECTORING_ERROR_CODE)); + vmcs_read32(IDT_VECTORING_ERROR_CODE), + kvm_cpu_cap_has(X86_FEATURE_FRED) ? vmcs_read64(ORIGINAL_EVENT_DATA) : 0); pr_err("TSC Offset = 0x%016llx\n", vmcs_read64(TSC_OFFSET)); if (secondary_exec_control & SECONDARY_EXEC_TSC_SCALING) pr_err("TSC Multiplier = 0x%016llx\n", From patchwork Tue Oct 1 05:01:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817469 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 40FDC1BC088; Tue, 1 Oct 2024 05:02:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; cv=none; b=Dq0o2sXVhOY3Aej20hx/idDhG1DVonkBPMho8nhz6iJLuzqey/ZtOWTEzWMh7Bxpd1esduQHY10viundOC7c428F5scJ3lsD+yZxM2zSW1NBTEMOoFrkRU6TVlvgnKWa/Nwi3XHdMrJ/8HGwXlSVYK+xUYCmBeU937krQyhT3pg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; c=relaxed/simple; bh=bxMqGlquB+5/gFkcnWJ3tbk2bgaubHhBM76puYSzRNc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=kQ9IVeC+Govc7HnKgTfsDjf+IGEv7vYySEmcLh8K3Cdc+W1jJWyoviuM2vnDfqq0+cHiAOyYrKT+PHzRBJ6EqbrovOvN53aeX8FfMYouZXdJPi2Y0MekwEK7X+ku94D3O9xSJyzAoI51R1l/6vJIYS6i5FBm6v/zzYmrRX/1V6g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=d10jYEWK; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="d10jYEWK" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7i3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:34 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7i3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758895; bh=xQodHnfpAbPVaqx+NU+32uYAoWdUOl8JXZpStYObbcE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=d10jYEWKiY19fP0HluEjpDGx8Ishhc2Ytn5m9W8Ekr/Pvgp7NECsF44B0+FpVLT8w tHwrfs1pRjZQNhJs/X3VCbOb9YNFAb/z+u1I02Dqy88/Aq/N3Ueb4Z6evC4eXmXH6e GUYOTZY+QHHt/Mrpk4i1Eyowyxu/2j+jVUQxQaspneaV1hsKKYQmsro3dgg0VWe6rr aFpBnQNHZNn0ceiIGZTso+80u8lSs31BoQ3dma3C5Fks/e274i1X5naSkuYQ90mRNR 2H+6iWoNRzI3ibHmDVt9RSves48yxe6tqVtOlt1e/Sn7ikbBPEgJBiFxB7kZ+MjIgF rdpT4KPZRIfkQ== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 19/27] KVM: x86: Allow FRED/LKGS to be advertised to guests Date: Mon, 30 Sep 2024 22:01:02 -0700 Message-ID: <20241001050110.3643764-20-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Allow FRED/LKGS to be advertised to guests after changes required to enable FRED in a KVM guest are in place. LKGS is introduced with FRED to completely eliminate the need to swapgs explicilty, because 1) FRED transitions ensure that an operating system can always operate with its own GS base address. 2) LKGS behaves like the MOV to GS instruction except that it loads the base address into the IA32_KERNEL_GS_BASE MSR instead of the GS segment’s descriptor cache, which is exactly what Linux kernel does to load a user level GS base. Thus there is no need to SWAPGS away from the kernel GS base and an execution of SWAPGS causes #UD if FRED transitions are enabled. A FRED CPU must enumerate LKGS. When LKGS is not available, FRED must not be enabled. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- arch/x86/kvm/cpuid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 41786b834b16..c55d150ece8d 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -699,7 +699,7 @@ void kvm_set_cpu_caps(void) kvm_cpu_cap_mask(CPUID_7_1_EAX, F(AVX_VNNI) | F(AVX512_BF16) | F(CMPCCXADD) | - F(FZRM) | F(FSRS) | F(FSRC) | + F(FZRM) | F(FSRS) | F(FSRC) | F(FRED) | F(LKGS) | F(AMX_FP16) | F(AVX_IFMA) | F(LAM) ); From patchwork Tue Oct 1 05:01:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817471 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 865551BBBFC; Tue, 1 Oct 2024 05:02:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; cv=none; b=j1ZHHRt0xgFHb7wFsBwTVYt7w+5H1oGi5ALKPCEUWizR8HHjl7sFH3R6aU9OsbbKGJXCyk3eNuQY/MPwa1RZcdFzyeASGyF+/hECmI/xwPjI2Lb/bePIb5ckhFwdMyVND9FwJAyhThLGCgesEgEF88Cajso52qUXIzpoVpkbA28= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758940; c=relaxed/simple; bh=8NwOtEgXFXbccpyKBCaKNF/+A8akEbIhiKyud8HIOrY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TRxebXvP6cnVihgALfsdSGJeRtszfTQsJhYS5rioY6JL7xqLC6/JTnGhae7KboQ1cXDanktYqL2jWfTHwEBw1hQWw98p03QFMiyKutfGSpY7uoLMpGtm3k8djiMP23hdGJQK7lBvgkJ/9fJcmfv9B98xTkEHKdlCYQQtn47L6bk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=HKYM0QUV; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="HKYM0QUV" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7j3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:35 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7j3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758896; bh=sULUFEzl3r3MZGUBZyiAQe7f5ktOY3K1CWLQ4Ja4sN8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HKYM0QUV2DyCIgCdDwErfc+MbiGCsL4o0o0sFKYSfZr+Nt/8pIYVdw2OZMm81W4/d AR/vRseg3sBf9FtrTlGviT9AUnjr1IycMu8mWTNFfteP6ue6Csrpd9RWFiQpxyhTh6 +PzUlaZv37Jly9EJWgwXwkqbn1fi6j11nbcTj88zG9QLo4zuntXQxoT5lBK9RdksU4 TlyukvBkamMdzZNS03P0kLoj6mI7lIhaeMbpmFhlXdDv/5t94IKRNBln8thDS4vNmr mQOTnImZT60ooIGnxwyuIMQ2RAQPBnirBpaUBk7C+ue2N/AkgzY97k1YfMhAmihcRS o+Zjifa1IpVDw== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 20/27] KVM: x86: Allow WRMSRNS to be advertised to guests Date: Mon, 30 Sep 2024 22:01:03 -0700 Message-ID: <20241001050110.3643764-21-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Allow WRMSRNS to be advertised to guests. WRMSRNS behaves exactly like WRMSR with the only difference being that it is not a serializing instruction by default. It improves performance when being used in a hot path, e.g., setting FRED RSP0. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- arch/x86/kvm/cpuid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index c55d150ece8d..63a78ebf9482 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -700,7 +700,7 @@ void kvm_set_cpu_caps(void) kvm_cpu_cap_mask(CPUID_7_1_EAX, F(AVX_VNNI) | F(AVX512_BF16) | F(CMPCCXADD) | F(FZRM) | F(FSRS) | F(FSRC) | F(FRED) | F(LKGS) | - F(AMX_FP16) | F(AVX_IFMA) | F(LAM) + F(WRMSRNS) | F(AMX_FP16) | F(AVX_IFMA) | F(LAM) ); kvm_cpu_cap_init_kvm_defined(CPUID_7_1_EDX, From patchwork Tue Oct 1 05:01:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817463 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 78FE11BBBEB; Tue, 1 Oct 2024 05:02:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758939; cv=none; b=snJiBbl+A4iCO0tksvN5qEr7dHG1huIAj5LQ++Jr/HsGCwMP2SUcCG5v2ZHFLLnpu9k7R4X9f74AAV6FcVRBumF8zedQipAaCBhE3rqHtMYr3kHwGLnaSFStUdFyF7334uqyCEdaPHDH+51XQc/dFI/3mww0iLf1q5NXlu3HoiI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758939; c=relaxed/simple; bh=LRG9ZLTJGb1kbujI26m79Oe7Kb0Z4AA/H5tMveOXNdM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jZch4r5G3+DCvsZ4YtnN4471KuAk8Tm2UEb0TKiNXSelpvNHY+RR4w1l7FzP6PpwSZfp9qcm/9Z2Y5axRmOL3IRnvI4wvAk4c+2c/sidpnTEV+58etzp8KQPl8559gvvFannH6xXfhKr2OUjWsBfqF+Vocqv+WUrdeXLll9tIas= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=Nprt8NK8; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="Nprt8NK8" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7k3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:36 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7k3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758897; bh=RPhFfy2zSZru20q1Ob2vvvbmoygA5l+/VjghCwP2ILE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Nprt8NK8Ij25W0/Ds+RHl2uuWji4EmoQRja+k9MCKZJASd2B2r0nAwTd8mu/j4aGI v8O0CbhnhNKONJZl+K5UE+H42tr8Ni1rjpzrBmfCbkPkkZpCZzaJ2rxrl5c9KO29eW dMF0E6LpoeCzG6q1nYGtcA2Qnk97CvX/W+SDU+FJP2IvhY0M/SY56JvGC1qQE1aWje bhkL9oXJz4Ei/QVEiollXJ0Dkvr6hOIfRvSIaWQ/A+kCVlsfzgeQpfbi74CWDaJViq 6vUlbRRZOahU7QYm+vzlnm6MAQWBhJcWTyeGwXuui9gsYB0EIR7cGHrhLEA4aXm10C gf436e1BSEyGQ== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 21/27] KVM: VMX: Invoke vmx_set_cpu_caps() before nested setup Date: Mon, 30 Sep 2024 22:01:04 -0700 Message-ID: <20241001050110.3643764-22-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Set VMX CPU capabilities before initializing nested instead of after, as it needs to check VMX CPU capabilities to setup the VMX basic MSR for nested. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- arch/x86/kvm/vmx/vmx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index ef807194ccbd..522ee27a4655 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -8774,6 +8774,12 @@ __init int vmx_hardware_setup(void) setup_default_sgx_lepubkeyhash(); + /* + * VMX CPU capabilities are required to setup the VMX basic MSR for + * nested, so this must be done before nested_vmx_setup_ctls_msrs(). + */ + vmx_set_cpu_caps(); + if (nested) { nested_vmx_setup_ctls_msrs(&vmcs_config, vmx_capability.ept); @@ -8782,8 +8788,6 @@ __init int vmx_hardware_setup(void) return r; } - vmx_set_cpu_caps(); - r = alloc_kvm_area(); if (r && nested) nested_vmx_hardware_unsetup(); From patchwork Tue Oct 1 05:01:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817457 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 883B919309C; Tue, 1 Oct 2024 05:02:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758938; cv=none; b=t2XOrTS+kVhzDKlH48AFrmwqPTvHWC4pBTch0oRlSVcmopRgD5dEzdsYSJjFq21bi7UMLQuE7bmBeybrojs+gqRN2NDctVlWiCopYjsed3YXTFDDYZlsppTiWQ99jFYrkRo9V5ik+Fbc9n8ZcDpW6wMRdGh9oPpJD9+zr1XMySw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758938; c=relaxed/simple; bh=zvaRZRA/DRQ9xLaRnwsO3ZrZNl5ciooyMbPHWdHOw+E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rJXIlkWfRp+7vlNWgIrfWKof2UvozaWEpgS/Ytd20jqb1lk2VFGmiLRkyZwjt5HyTNksTWbTTlq/FOnaFQ4+sTbAkyxeRVaXZ7CAB/n5+rY6NMOGIrj2UZGCbB6+yxvdTFVLmKs6nBsr7FD/BzWJ85r2neheFetFAc1YsGX+04s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=T7a5ePra; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="T7a5ePra" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7l3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:37 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7l3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758898; bh=qzvu60W6NQb8KVFLqmCzK1DwmY79Zr7QZJjLnO14se4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=T7a5ePra+mmb6gkvbwl7glmEfla6+iaA7uQO/qBeQyJZR3vhUEDttPOhIPpU6Pbwp VMWr1oGGxmwetHhwiv7gsOxdXHqgOwY2uQjQye87+HeKtGVkC+TJ5h4eOUl3cXgj9a zzQCSb1fF2WnVbYP2dEBSFKgxMQ6AGFIscUTXvOyD9FANWsesYlzLrdxpGvAU8a8/5 t2t5yPjIOQbNLxFhWx5gHT6zKHSKSUuZ0TZf2+tY9pF1Yt7OHaTIo7MpbaQr/6VpKm EKls8puQ+vuebIZfXThASRGflPRiy3vnW32o0F6dP1Al+dotE4ZLfs8sfNsrVURIVX llU+ULS2lTKHA== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 22/27] KVM: nVMX: Add support for the secondary VM exit controls Date: Mon, 30 Sep 2024 22:01:05 -0700 Message-ID: <20241001050110.3643764-23-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Enable the secondary VM exit controls to prepare for nested FRED. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- Change since v2: * Read secondary VM exit controls from vmcs_conf insteasd of the hardware MSR MSR_IA32_VMX_EXIT_CTLS2 to avoid advertising features to L1 that KVM itself doesn't support, e.g. because the expected entry+exit pairs aren't supported. (Sean Christopherson) --- Documentation/virt/kvm/x86/nested-vmx.rst | 1 + arch/x86/kvm/vmx/capabilities.h | 1 + arch/x86/kvm/vmx/nested.c | 21 ++++++++++++++++++++- arch/x86/kvm/vmx/vmcs12.c | 1 + arch/x86/kvm/vmx/vmcs12.h | 2 ++ arch/x86/kvm/x86.h | 2 +- 6 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Documentation/virt/kvm/x86/nested-vmx.rst b/Documentation/virt/kvm/x86/nested-vmx.rst index ac2095d41f02..e64ef231f310 100644 --- a/Documentation/virt/kvm/x86/nested-vmx.rst +++ b/Documentation/virt/kvm/x86/nested-vmx.rst @@ -217,6 +217,7 @@ struct shadow_vmcs is ever changed. u16 host_fs_selector; u16 host_gs_selector; u16 host_tr_selector; + u64 secondary_vm_exit_controls; }; diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h index 2962a3bb9747..c96e6cb18c9a 100644 --- a/arch/x86/kvm/vmx/capabilities.h +++ b/arch/x86/kvm/vmx/capabilities.h @@ -38,6 +38,7 @@ struct nested_vmx_msrs { u32 pinbased_ctls_high; u32 exit_ctls_low; u32 exit_ctls_high; + u64 secondary_exit_ctls; u32 entry_ctls_low; u32 entry_ctls_high; u32 misc_low; diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index a8e7bc04d9bf..42e43eb7561f 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -1454,6 +1454,7 @@ int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) case MSR_IA32_VMX_PINBASED_CTLS: case MSR_IA32_VMX_PROCBASED_CTLS: case MSR_IA32_VMX_EXIT_CTLS: + case MSR_IA32_VMX_EXIT_CTLS2: case MSR_IA32_VMX_ENTRY_CTLS: /* * The "non-true" VMX capability MSRs are generated from the @@ -1532,6 +1533,9 @@ int vmx_get_vmx_msr(struct nested_vmx_msrs *msrs, u32 msr_index, u64 *pdata) if (msr_index == MSR_IA32_VMX_EXIT_CTLS) *pdata |= VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR; break; + case MSR_IA32_VMX_EXIT_CTLS2: + *pdata = msrs->secondary_exit_ctls; + break; case MSR_IA32_VMX_TRUE_ENTRY_CTLS: case MSR_IA32_VMX_ENTRY_CTLS: *pdata = vmx_control_msr( @@ -2471,6 +2475,11 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0 exec_control &= ~VM_EXIT_LOAD_IA32_EFER; vm_exit_controls_set(vmx, exec_control); + if (exec_control & VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) { + exec_control = __secondary_vm_exit_controls_get(vmcs01); + secondary_vm_exit_controls_set(vmx, exec_control); + } + /* * Interrupt/Exception Fields */ @@ -6956,7 +6965,7 @@ static void nested_vmx_setup_exit_ctls(struct vmcs_config *vmcs_conf, VM_EXIT_HOST_ADDR_SPACE_SIZE | #endif VM_EXIT_LOAD_IA32_PAT | VM_EXIT_SAVE_IA32_PAT | - VM_EXIT_CLEAR_BNDCFGS; + VM_EXIT_CLEAR_BNDCFGS | VM_EXIT_ACTIVATE_SECONDARY_CONTROLS; msrs->exit_ctls_high |= VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER | @@ -6965,6 +6974,16 @@ static void nested_vmx_setup_exit_ctls(struct vmcs_config *vmcs_conf, /* We support free control of debug control saving. */ msrs->exit_ctls_low &= ~VM_EXIT_SAVE_DEBUG_CONTROLS; + + if (msrs->exit_ctls_high & VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) { + msrs->secondary_exit_ctls = vmcs_conf->secondary_vmexit_ctrl; + /* + * As the secondary VM exit control is always loaded, do not + * advertise any feature in it to nVMX until its nVMX support + * is ready. + */ + msrs->secondary_exit_ctls &= 0; + } } static void nested_vmx_setup_entry_ctls(struct vmcs_config *vmcs_conf, diff --git a/arch/x86/kvm/vmx/vmcs12.c b/arch/x86/kvm/vmx/vmcs12.c index 106a72c923ca..98457d7b2b23 100644 --- a/arch/x86/kvm/vmx/vmcs12.c +++ b/arch/x86/kvm/vmx/vmcs12.c @@ -73,6 +73,7 @@ const unsigned short vmcs12_field_offsets[] = { FIELD(PAGE_FAULT_ERROR_CODE_MATCH, page_fault_error_code_match), FIELD(CR3_TARGET_COUNT, cr3_target_count), FIELD(VM_EXIT_CONTROLS, vm_exit_controls), + FIELD(SECONDARY_VM_EXIT_CONTROLS, secondary_vm_exit_controls), FIELD(VM_EXIT_MSR_STORE_COUNT, vm_exit_msr_store_count), FIELD(VM_EXIT_MSR_LOAD_COUNT, vm_exit_msr_load_count), FIELD(VM_ENTRY_CONTROLS, vm_entry_controls), diff --git a/arch/x86/kvm/vmx/vmcs12.h b/arch/x86/kvm/vmx/vmcs12.h index 56fd150a6f24..1fe3ed9108aa 100644 --- a/arch/x86/kvm/vmx/vmcs12.h +++ b/arch/x86/kvm/vmx/vmcs12.h @@ -185,6 +185,7 @@ struct __packed vmcs12 { u16 host_gs_selector; u16 host_tr_selector; u16 guest_pml_index; + u64 secondary_vm_exit_controls; }; /* @@ -360,6 +361,7 @@ static inline void vmx_check_vmcs12_offsets(void) CHECK_OFFSET(host_gs_selector, 992); CHECK_OFFSET(host_tr_selector, 994); CHECK_OFFSET(guest_pml_index, 996); + CHECK_OFFSET(secondary_vm_exit_controls, 998); } extern const unsigned short vmcs12_field_offsets[]; diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 0ed91512b757..890b7a6554d5 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -66,7 +66,7 @@ void kvm_spurious_fault(void); * associated feature that KVM supports for nested virtualization. */ #define KVM_FIRST_EMULATED_VMX_MSR MSR_IA32_VMX_BASIC -#define KVM_LAST_EMULATED_VMX_MSR MSR_IA32_VMX_VMFUNC +#define KVM_LAST_EMULATED_VMX_MSR MSR_IA32_VMX_EXIT_CTLS2 #define KVM_DEFAULT_PLE_GAP 128 #define KVM_VMX_DEFAULT_PLE_WINDOW 4096 From patchwork Tue Oct 1 05:01:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817449 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 D55B92A1D3; Tue, 1 Oct 2024 05:02:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758936; cv=none; b=GnAEd0/fua8uaP4ggdWq1v7Iz6f7FVRqhwBOOA2SUlOnOAT3KhAMc4dkCPfbkQsT5WdJS8OARQw2SdRG5I3JOuuH7kzlQvpcYZ3Sx8XZCXgno2OqKHdG+aEymeqKf9F7TyG2Kp6MzlXvM4dBx6sSF4CW8pFxyygV0JC7aDuWdog= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758936; c=relaxed/simple; bh=djLB7Rj6NPgjtYO2mRlTTQdUlBIFHjqdhb6ye+9VhrY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VG0clNiZsz0ZnLeHMJ3EG4s10N2O8BM4NNL53Gg5gcURbQlVZHkrnRpqYe2qXoC6ZRj+3FJE+3CFion+cPGUdS5pmRMadjYZY8fiDrVsdZBtiQeTBXXlt4eth21HWLXJzEeEKf0G62uwp7DTi2JMYth2eAw0fLZSw2DxgayylWI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=NyKXnJ73; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="NyKXnJ73" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7m3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:38 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7m3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758899; bh=LdpXBq+ySLW3ZQnFZoTLUMI52vrNRKAKxmjYLJalSmw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NyKXnJ73CgOP6fCLSSj7L+XVO6S30UpFT4vg5WGqn8wkRm1RWxXeMBzEUmhJwObr1 lpoel2/RHHGaeAx0V+jr+pzQ1ZVE9ylaVgkLZ3wyvZiKPGp1WkAd+N6ca61KMRVYZI CrzWdh4EKMOWjYgtCo4mNim2iqLf9zvzK/W7VW91vlLKZx3h0XNrtKJsVI5oHXTuLJ 8DdFKX/vn+upILmthl7vFeBjcUOdohKOot/xUUWVRJjCtv9UInSSieilQrjr9KbR8b Ryag20vetY6mGYQaUavN8pLYFiMyANtYHRxH3WkFuZiHWmhLh1UXsWbGZrBoKpaAmQ kCJ3FkbBL9ESw== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 23/27] KVM: nVMX: Add a prerequisite to SHADOW_FIELD_R[OW] macros Date: Mon, 30 Sep 2024 22:01:06 -0700 Message-ID: <20241001050110.3643764-24-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Add a prerequisite for accessing VMCS fields referenced in macros SHADOW_FIELD_R[OW], because a VMCS field may not exist on some CPUs. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- Change since v2: * Add __SHADOW_FIELD_R[OW] for better readability or maintability (Sean). --- arch/x86/kvm/vmx/nested.c | 79 +++++++++++++++++++-------- arch/x86/kvm/vmx/vmcs_shadow_fields.h | 33 ++++++++--- 2 files changed, 79 insertions(+), 33 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 42e43eb7561f..7f3ac558ace5 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -54,14 +54,14 @@ struct shadow_vmcs_field { u16 offset; }; static struct shadow_vmcs_field shadow_read_only_fields[] = { -#define SHADOW_FIELD_RO(x, y) { x, offsetof(struct vmcs12, y) }, +#define __SHADOW_FIELD_RO(x, y, c) { x, offsetof(struct vmcs12, y) }, #include "vmcs_shadow_fields.h" }; static int max_shadow_read_only_fields = ARRAY_SIZE(shadow_read_only_fields); static struct shadow_vmcs_field shadow_read_write_fields[] = { -#define SHADOW_FIELD_RW(x, y) { x, offsetof(struct vmcs12, y) }, +#define __SHADOW_FIELD_RW(x, y, c) { x, offsetof(struct vmcs12, y) }, #include "vmcs_shadow_fields.h" }; static int max_shadow_read_write_fields = @@ -84,6 +84,17 @@ static void init_vmcs_shadow_fields(void) pr_err("Missing field from shadow_read_only_field %x\n", field + 1); + switch (field) { +#define __SHADOW_FIELD_RO(x, y, c) \ + case x: \ + if (!(c)) \ + continue; \ + break; +#include "vmcs_shadow_fields.h" + default: + break; + } + clear_bit(field, vmx_vmread_bitmap); if (field & 1) #ifdef CONFIG_X86_64 @@ -109,24 +120,13 @@ static void init_vmcs_shadow_fields(void) field <= GUEST_TR_AR_BYTES, "Update vmcs12_write_any() to drop reserved bits from AR_BYTES"); - /* - * PML and the preemption timer can be emulated, but the - * processor cannot vmwrite to fields that don't exist - * on bare metal. - */ switch (field) { - case GUEST_PML_INDEX: - if (!cpu_has_vmx_pml()) - continue; - break; - case VMX_PREEMPTION_TIMER_VALUE: - if (!cpu_has_vmx_preemption_timer()) - continue; - break; - case GUEST_INTR_STATUS: - if (!cpu_has_vmx_apicv()) - continue; +#define __SHADOW_FIELD_RW(x, y, c) \ + case x: \ + if (!(c)) \ + continue; \ break; +#include "vmcs_shadow_fields.h" default: break; } @@ -1586,8 +1586,8 @@ int vmx_get_vmx_msr(struct nested_vmx_msrs *msrs, u32 msr_index, u64 *pdata) /* * Copy the writable VMCS shadow fields back to the VMCS12, in case they have * been modified by the L1 guest. Note, "writable" in this context means - * "writable by the guest", i.e. tagged SHADOW_FIELD_RW; the set of - * fields tagged SHADOW_FIELD_RO may or may not align with the "read-only" + * "writable by the guest", i.e. tagged __SHADOW_FIELD_RW; the set of + * fields tagged __SHADOW_FIELD_RO may or may not align with the "read-only" * VM-exit information fields (which are actually writable if the vCPU is * configured to support "VMWRITE to any supported field in the VMCS"). */ @@ -1608,6 +1608,18 @@ static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx) for (i = 0; i < max_shadow_read_write_fields; i++) { field = shadow_read_write_fields[i]; + + switch (field.encoding) { +#define __SHADOW_FIELD_RW(x, y, c) \ + case x: \ + if (!(c)) \ + continue; \ + break; +#include "vmcs_shadow_fields.h" + default: + break; + } + val = __vmcs_readl(field.encoding); vmcs12_write_any(vmcs12, field.encoding, field.offset, val); } @@ -1642,6 +1654,23 @@ static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx) for (q = 0; q < ARRAY_SIZE(fields); q++) { for (i = 0; i < max_fields[q]; i++) { field = fields[q][i]; + + switch (field.encoding) { +#define __SHADOW_FIELD_RO(x, y, c) \ + case x: \ + if (!(c)) \ + continue; \ + break; +#define __SHADOW_FIELD_RW(x, y, c) \ + case x: \ + if (!(c)) \ + continue; \ + break; +#include "vmcs_shadow_fields.h" + default: + break; + } + val = vmcs12_read_any(vmcs12, field.encoding, field.offset); __vmcs_writel(field.encoding, val); @@ -5590,9 +5619,10 @@ static int handle_vmread(struct kvm_vcpu *vcpu) static bool is_shadow_field_rw(unsigned long field) { switch (field) { -#define SHADOW_FIELD_RW(x, y) case x: +#define __SHADOW_FIELD_RW(x, y, c) \ + case x: \ + return c; #include "vmcs_shadow_fields.h" - return true; default: break; } @@ -5602,9 +5632,10 @@ static bool is_shadow_field_rw(unsigned long field) static bool is_shadow_field_ro(unsigned long field) { switch (field) { -#define SHADOW_FIELD_RO(x, y) case x: +#define __SHADOW_FIELD_RO(x, y, c) \ + case x: \ + return c; #include "vmcs_shadow_fields.h" - return true; default: break; } diff --git a/arch/x86/kvm/vmx/vmcs_shadow_fields.h b/arch/x86/kvm/vmx/vmcs_shadow_fields.h index cad128d1657b..53b64dce1309 100644 --- a/arch/x86/kvm/vmx/vmcs_shadow_fields.h +++ b/arch/x86/kvm/vmx/vmcs_shadow_fields.h @@ -1,14 +1,17 @@ -#if !defined(SHADOW_FIELD_RO) && !defined(SHADOW_FIELD_RW) +#if !defined(__SHADOW_FIELD_RO) && !defined(__SHADOW_FIELD_RW) BUILD_BUG_ON(1) #endif -#ifndef SHADOW_FIELD_RO -#define SHADOW_FIELD_RO(x, y) +#ifndef __SHADOW_FIELD_RO +#define __SHADOW_FIELD_RO(x, y, c) #endif -#ifndef SHADOW_FIELD_RW -#define SHADOW_FIELD_RW(x, y) +#ifndef __SHADOW_FIELD_RW +#define __SHADOW_FIELD_RW(x, y, c) #endif +#define SHADOW_FIELD_RO(x, y) __SHADOW_FIELD_RO(x, y, true) +#define SHADOW_FIELD_RW(x, y) __SHADOW_FIELD_RW(x, y, true) + /* * We do NOT shadow fields that are modified when L0 * traps and emulates any vmx instruction (e.g. VMPTRLD, @@ -32,8 +35,12 @@ BUILD_BUG_ON(1) */ /* 16-bits */ -SHADOW_FIELD_RW(GUEST_INTR_STATUS, guest_intr_status) -SHADOW_FIELD_RW(GUEST_PML_INDEX, guest_pml_index) +__SHADOW_FIELD_RW(GUEST_INTR_STATUS, guest_intr_status, cpu_has_vmx_apicv()) +/* + * PML can be emulated, but the processor cannot vmwrite to the VMCS field + * GUEST_PML_INDEX that doesn't exist on bare metal. + */ +__SHADOW_FIELD_RW(GUEST_PML_INDEX, guest_pml_index, cpu_has_vmx_pml()) SHADOW_FIELD_RW(HOST_FS_SELECTOR, host_fs_selector) SHADOW_FIELD_RW(HOST_GS_SELECTOR, host_gs_selector) @@ -41,9 +48,9 @@ SHADOW_FIELD_RW(HOST_GS_SELECTOR, host_gs_selector) SHADOW_FIELD_RO(VM_EXIT_REASON, vm_exit_reason) SHADOW_FIELD_RO(VM_EXIT_INTR_INFO, vm_exit_intr_info) SHADOW_FIELD_RO(VM_EXIT_INSTRUCTION_LEN, vm_exit_instruction_len) +SHADOW_FIELD_RO(VM_EXIT_INTR_ERROR_CODE, vm_exit_intr_error_code) SHADOW_FIELD_RO(IDT_VECTORING_INFO_FIELD, idt_vectoring_info_field) SHADOW_FIELD_RO(IDT_VECTORING_ERROR_CODE, idt_vectoring_error_code) -SHADOW_FIELD_RO(VM_EXIT_INTR_ERROR_CODE, vm_exit_intr_error_code) SHADOW_FIELD_RO(GUEST_CS_AR_BYTES, guest_cs_ar_bytes) SHADOW_FIELD_RO(GUEST_SS_AR_BYTES, guest_ss_ar_bytes) SHADOW_FIELD_RW(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control) @@ -54,7 +61,12 @@ SHADOW_FIELD_RW(VM_ENTRY_INTR_INFO_FIELD, vm_entry_intr_info_field) SHADOW_FIELD_RW(VM_ENTRY_INSTRUCTION_LEN, vm_entry_instruction_len) SHADOW_FIELD_RW(TPR_THRESHOLD, tpr_threshold) SHADOW_FIELD_RW(GUEST_INTERRUPTIBILITY_INFO, guest_interruptibility_info) -SHADOW_FIELD_RW(VMX_PREEMPTION_TIMER_VALUE, vmx_preemption_timer_value) +/* + * The preemption timer can be emulated, but the processor cannot vmwrite to + * the VMCS field VMX_PREEMPTION_TIMER_VALUE that doesn't exist on bare metal. + */ +__SHADOW_FIELD_RW(VMX_PREEMPTION_TIMER_VALUE, vmx_preemption_timer_value, + cpu_has_vmx_preemption_timer()) /* Natural width */ SHADOW_FIELD_RO(EXIT_QUALIFICATION, exit_qualification) @@ -77,3 +89,6 @@ SHADOW_FIELD_RO(GUEST_PHYSICAL_ADDRESS_HIGH, guest_physical_address) #undef SHADOW_FIELD_RO #undef SHADOW_FIELD_RW + +#undef __SHADOW_FIELD_RO +#undef __SHADOW_FIELD_RW From patchwork Tue Oct 1 05:01:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817459 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 74E031BBBC6; Tue, 1 Oct 2024 05:02:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758939; cv=none; b=dxi+smaR281v9CfzgWUZoVcytxZQiV5kyNF5RaIXuhxit110TK7EcWuczbkP7VXJ4UTDFQx8EgZUTrJyMNau3QMS9Jz3D9HxOD4Vb/kMuTYcpfZVa0NuyafEdlWXLjaFzV168qyebvC8PTR2JpksAdE8Xv+gGFIPzpded4OtNXQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758939; c=relaxed/simple; bh=5TG94s28ejMPLZuTN+ZSw/em4KzqzULOEqado4Xkwyg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=coOPBZN2UEbZAiOM4NYv0L1VeMxzDcItZ68K+ij8jRZIx4wnO3NSfx8d8nIJzfQsaE1S6zmDrQhYyeJKz+Z9OhmHOa+uZM6QUEjACQMJ81a7mV5I76QwcKHriLbu14odGLINv8LZ646EdIJv2GU81h9HrLzhQ4uKJhswSRxZRIM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=Y2NJOuIO; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="Y2NJOuIO" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7n3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:39 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7n3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758900; bh=4qMitadCZcAtQoU+ROJIy5ikCk5LW8rpQXESx5x0i2g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Y2NJOuIONP/G6SdlqrTJ+naSPF1HFQYdqe+ls6nhoc1CC0Jo032goOMUyj94dKaIr rr7z1lTdtXOAPoE3lcCbJDG0PGt7diIxJsZS3OuUEMfjCcaJCrHiTesQV1SEfi7cBX eK80gDns0/1+FgFIRcAw/bOL7maXNyLEWwsTVoHzUfzj9HBHCIouEHI+M+ILxO0OQo 7wRPKukrfishIjOpiqXj01BwkXy+qZ6NS8SrQNPM/9DUMybuK3f+lHw5cc9D29j4Ud q2gEUHySFQ1dJFoCwTigqeh9gJdnrBanpdwKHd4D/VnXTKSTI6F1xhyZUO0wdjoPPw u2qTGgnsyskqg== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 24/27] KVM: nVMX: Add a prerequisite to existence of VMCS fields Date: Mon, 30 Sep 2024 22:01:07 -0700 Message-ID: <20241001050110.3643764-25-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add a prerequisite to existence of VMCS fields as some of them exist only on processors that support certain CPU features. This is required to fix KVM unit test VMX_VMCS_ENUM.MAX_INDEX. Originally-by: Lei Wang Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- arch/x86/kvm/vmx/nested.c | 19 +++++++++++++++++-- arch/x86/kvm/vmx/nested_vmcs_fields.h | 13 +++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 arch/x86/kvm/vmx/nested_vmcs_fields.h diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 7f3ac558ace5..4529fd635385 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -49,6 +49,21 @@ static unsigned long *vmx_bitmap[VMX_BITMAP_NR]; #define vmx_vmread_bitmap (vmx_bitmap[VMX_VMREAD_BITMAP]) #define vmx_vmwrite_bitmap (vmx_bitmap[VMX_VMWRITE_BITMAP]) +static bool nested_cpu_has_vmcs_field(struct kvm_vcpu *vcpu, u16 vmcs_field_encoding) +{ + switch (vmcs_field_encoding) { +#define HAS_VMCS_FIELD(x, c) \ + case x: \ + return c; +#define HAS_VMCS_FIELD_RANGE(x, y, c) \ + case x...y: \ + return c; +#include "nested_vmcs_fields.h" + default: + return true; + } +} + struct shadow_vmcs_field { u16 encoding; u16 offset; @@ -5565,7 +5580,7 @@ static int handle_vmread(struct kvm_vcpu *vcpu) return nested_vmx_failInvalid(vcpu); offset = get_vmcs12_field_offset(field); - if (offset < 0) + if (offset < 0 || !nested_cpu_has_vmcs_field(vcpu, field)) return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); if (!is_guest_mode(vcpu) && is_vmcs12_ext_field(field)) @@ -5691,7 +5706,7 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) field = kvm_register_read(vcpu, (((instr_info) >> 28) & 0xf)); offset = get_vmcs12_field_offset(field); - if (offset < 0) + if (offset < 0 || !nested_cpu_has_vmcs_field(vcpu, field)) return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); /* diff --git a/arch/x86/kvm/vmx/nested_vmcs_fields.h b/arch/x86/kvm/vmx/nested_vmcs_fields.h new file mode 100644 index 000000000000..fcd6c32dce31 --- /dev/null +++ b/arch/x86/kvm/vmx/nested_vmcs_fields.h @@ -0,0 +1,13 @@ +#if !defined(HAS_VMCS_FIELD) && !defined(HAS_VMCS_FIELD_RANGE) +BUILD_BUG_ON(1) +#endif + +#ifndef HAS_VMCS_FIELD +#define HAS_VMCS_FIELD(x, c) +#endif +#ifndef HAS_VMCS_FIELD_RANGE +#define HAS_VMCS_FIELD_RANGE(x, y, c) +#endif + +#undef HAS_VMCS_FIELD +#undef HAS_VMCS_FIELD_RANGE From patchwork Tue Oct 1 05:01:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817466 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 81CAD19258C; Tue, 1 Oct 2024 05:02:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758939; cv=none; b=cRUth4AXG8doeCpsYVIYZO5Izp4zC5dtTEMJ01uBqGqBKsjyy7X83U09EK1QoXUdD1S/fzN6349Hu3bMta9v56s60UEgy0OOJd/JAu9mDiB3a5jNeQSLwlcOqJuVpjBMqtcwMiGdAACRpcRqiUqqp23yj6a1by3pKU6KXj9cnU4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758939; c=relaxed/simple; bh=BYP7dppUvcpso1fpT9aeTu3FRv6XtV3QfXbCxS4dT04=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OuAQWoeiFAQHwEp7I4AR/sAlohdZALThzdluHn+cqEqiJ5/AMJGXmbbQOn8j7zHYddNMGT1Csmx1O1gZLE7KycmJUUI7JOIiiywLrPZbZ5oNsizhcGIdiCRdpi4whweqvLYkOs2Pih05cvZiHyH1GyWvlvgw1iKWXmqCipMv1R4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=ALoL9fAy; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="ALoL9fAy" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7o3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:40 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7o3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758901; bh=Qri2p8/HmUrshvMeaSaTaHtV42yUJ+VhDEmxNNA1YXI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ALoL9fAySHX8I0o5ltLzC35S0/FCOHlpkkaWxP32KHMgutiJ3rFkOjKnoJe2TgMuK Ctfmew+HhwG9W3x10Gs0peaDudW4oDtpyDXYo+UBIfUBkMKw08XIXbss7FgZJDHPS1 RO6urC2URZhwBimc2GEdUzz4PYTPVi2E1V/766UKDoZtXJ2jc4NLCEg8mupPXoXd9K M01BKgfoyJnFyMQYWgBOV+MP7aMiZQCsMEiB3Dfp+JHVarUDpgAI3Yy0Q8kHpsSbqB g6j74GX9c1kZFXYHwJeBnHKi7Gf7lpxNath5FYqb7hP63qrgXCSzuXc0p9cegmx37N ez8cPTgCS03pw== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 25/27] KVM: nVMX: Add FRED VMCS fields Date: Mon, 30 Sep 2024 22:01:08 -0700 Message-ID: <20241001050110.3643764-26-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Add FRED VMCS fields to nested VMX context management. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- Change since v2: * Add and use nested_cpu_has_fred(vmcs12) because vmcs02 should be set from vmcs12 if and only if the field is enabled in L1's VMX config (Sean Christopherson). * Fix coding style (Sean Christopherson). Change since v1: * Remove hyperv TLFS related changes (Jeremi Piotrowski). * Use kvm_cpu_cap_has() instead of cpu_feature_enabled() (Chao Gao). --- Documentation/virt/kvm/x86/nested-vmx.rst | 18 +++++ arch/x86/kvm/vmx/nested.c | 88 ++++++++++++++++++----- arch/x86/kvm/vmx/nested.h | 8 +++ arch/x86/kvm/vmx/nested_vmcs_fields.h | 12 ++++ arch/x86/kvm/vmx/vmcs12.c | 18 +++++ arch/x86/kvm/vmx/vmcs12.h | 36 ++++++++++ arch/x86/kvm/vmx/vmcs_shadow_fields.h | 4 ++ 7 files changed, 168 insertions(+), 16 deletions(-) diff --git a/Documentation/virt/kvm/x86/nested-vmx.rst b/Documentation/virt/kvm/x86/nested-vmx.rst index e64ef231f310..87fa9f3877ab 100644 --- a/Documentation/virt/kvm/x86/nested-vmx.rst +++ b/Documentation/virt/kvm/x86/nested-vmx.rst @@ -218,6 +218,24 @@ struct shadow_vmcs is ever changed. u16 host_gs_selector; u16 host_tr_selector; u64 secondary_vm_exit_controls; + u64 guest_ia32_fred_config; + u64 guest_ia32_fred_rsp1; + u64 guest_ia32_fred_rsp2; + u64 guest_ia32_fred_rsp3; + u64 guest_ia32_fred_stklvls; + u64 guest_ia32_fred_ssp1; + u64 guest_ia32_fred_ssp2; + u64 guest_ia32_fred_ssp3; + u64 host_ia32_fred_config; + u64 host_ia32_fred_rsp1; + u64 host_ia32_fred_rsp2; + u64 host_ia32_fred_rsp3; + u64 host_ia32_fred_stklvls; + u64 host_ia32_fred_ssp1; + u64 host_ia32_fred_ssp2; + u64 host_ia32_fred_ssp3; + u64 injected_event_data; + u64 original_event_data; }; diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 4529fd635385..45a5ffa51e60 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -719,6 +719,12 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu, nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, MSR_KERNEL_GS_BASE, MSR_TYPE_RW); + + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_IA32_FRED_RSP0, MSR_TYPE_RW); + + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_IA32_FRED_SSP0, MSR_TYPE_RW); #endif nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, MSR_IA32_SPEC_CTRL, MSR_TYPE_RW); @@ -1268,9 +1274,11 @@ static int vmx_restore_vmx_basic(struct vcpu_vmx *vmx, u64 data) { const u64 feature_bits = VMX_BASIC_DUAL_MONITOR_TREATMENT | VMX_BASIC_INOUT | - VMX_BASIC_TRUE_CTLS; + VMX_BASIC_TRUE_CTLS | + VMX_BASIC_NESTED_EXCEPTION; - const u64 reserved_bits = GENMASK_ULL(63, 56) | + const u64 reserved_bits = GENMASK_ULL(63, 59) | + GENMASK_ULL(57, 56) | GENMASK_ULL(47, 45) | BIT_ULL(31); @@ -2536,6 +2544,8 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0 vmcs12->vm_entry_instruction_len); vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, vmcs12->guest_interruptibility_info); + if (nested_cpu_has_fred(vmcs12)) + vmcs_write64(INJECTED_EVENT_DATA, vmcs12->injected_event_data); vmx->loaded_vmcs->nmi_known_unmasked = !(vmcs12->guest_interruptibility_info & GUEST_INTR_STATE_NMI); } else { @@ -2588,6 +2598,17 @@ static void prepare_vmcs02_rare(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) vmcs_writel(GUEST_IDTR_BASE, vmcs12->guest_idtr_base); vmx_segment_cache_clear(vmx); + + if (nested_cpu_has_fred(vmcs12)) { + vmcs_write64(GUEST_IA32_FRED_CONFIG, vmcs12->guest_ia32_fred_config); + vmcs_write64(GUEST_IA32_FRED_RSP1, vmcs12->guest_ia32_fred_rsp1); + vmcs_write64(GUEST_IA32_FRED_RSP2, vmcs12->guest_ia32_fred_rsp2); + vmcs_write64(GUEST_IA32_FRED_RSP3, vmcs12->guest_ia32_fred_rsp3); + vmcs_write64(GUEST_IA32_FRED_STKLVLS, vmcs12->guest_ia32_fred_stklvls); + vmcs_write64(GUEST_IA32_FRED_SSP1, vmcs12->guest_ia32_fred_ssp1); + vmcs_write64(GUEST_IA32_FRED_SSP2, vmcs12->guest_ia32_fred_ssp2); + vmcs_write64(GUEST_IA32_FRED_SSP3, vmcs12->guest_ia32_fred_ssp3); + } } if (!hv_evmcs || !(hv_evmcs->hv_clean_fields & @@ -3881,6 +3902,8 @@ static void vmcs12_save_pending_event(struct kvm_vcpu *vcpu, u32 idt_vectoring; unsigned int nr; + vmcs12->original_event_data = 0; + /* * Per the SDM, VM-Exits due to double and triple faults are never * considered to occur during event delivery, even if the double/triple @@ -3919,6 +3942,11 @@ static void vmcs12_save_pending_event(struct kvm_vcpu *vcpu, vcpu->arch.exception.error_code; } + if (vcpu->arch.exception.nested) + idt_vectoring |= INTR_INFO_NESTED_EXCEPTION_MASK; + + vmcs12->original_event_data = vcpu->arch.exception.event_data; + vmcs12->idt_vectoring_info_field = idt_vectoring; } else if (vcpu->arch.nmi_injected) { vmcs12->idt_vectoring_info_field = @@ -4009,19 +4037,10 @@ static void nested_vmx_inject_exception_vmexit(struct kvm_vcpu *vcpu) struct kvm_queued_exception *ex = &vcpu->arch.exception_vmexit; u32 intr_info = ex->vector | INTR_INFO_VALID_MASK; struct vmcs12 *vmcs12 = get_vmcs12(vcpu); - unsigned long exit_qual; + unsigned long exit_qual = 0; - if (ex->has_payload) { - exit_qual = ex->payload; - } else if (ex->vector == PF_VECTOR) { - exit_qual = vcpu->arch.cr2; - } else if (ex->vector == DB_VECTOR) { - exit_qual = vcpu->arch.dr6; - exit_qual &= ~DR6_BT; - exit_qual ^= DR6_ACTIVE_LOW; - } else { - exit_qual = 0; - } + if (ex->vector != NM_VECTOR) + exit_qual = ex->event_data; /* * Unlike AMD's Paged Real Mode, which reports an error code on #PF @@ -4042,10 +4061,13 @@ static void nested_vmx_inject_exception_vmexit(struct kvm_vcpu *vcpu) intr_info |= INTR_INFO_DELIVER_CODE_MASK; } - if (kvm_exception_is_soft(ex->vector)) + if (kvm_exception_is_soft(ex->vector)) { intr_info |= INTR_TYPE_SOFT_EXCEPTION; - else + } else { intr_info |= INTR_TYPE_HARD_EXCEPTION; + if (ex->nested) + intr_info |= INTR_INFO_NESTED_EXCEPTION_MASK; + } if (!(vmcs12->idt_vectoring_info_field & VECTORING_INFO_VALID_MASK) && vmx_get_nmi_mask(vcpu)) @@ -4468,6 +4490,14 @@ static bool is_vmcs12_ext_field(unsigned long field) case GUEST_TR_BASE: case GUEST_GDTR_BASE: case GUEST_IDTR_BASE: + case GUEST_IA32_FRED_CONFIG: + case GUEST_IA32_FRED_RSP1: + case GUEST_IA32_FRED_RSP2: + case GUEST_IA32_FRED_RSP3: + case GUEST_IA32_FRED_STKLVLS: + case GUEST_IA32_FRED_SSP1: + case GUEST_IA32_FRED_SSP2: + case GUEST_IA32_FRED_SSP3: case GUEST_PENDING_DBG_EXCEPTIONS: case GUEST_BNDCFGS: return true; @@ -4517,6 +4547,18 @@ static void sync_vmcs02_to_vmcs12_rare(struct kvm_vcpu *vcpu, vmcs12->guest_tr_base = vmcs_readl(GUEST_TR_BASE); vmcs12->guest_gdtr_base = vmcs_readl(GUEST_GDTR_BASE); vmcs12->guest_idtr_base = vmcs_readl(GUEST_IDTR_BASE); + + if (nested_cpu_has_fred(vmcs12)) { + vmcs12->guest_ia32_fred_config = vmcs_read64(GUEST_IA32_FRED_CONFIG); + vmcs12->guest_ia32_fred_rsp1 = vmcs_read64(GUEST_IA32_FRED_RSP1); + vmcs12->guest_ia32_fred_rsp2 = vmcs_read64(GUEST_IA32_FRED_RSP2); + vmcs12->guest_ia32_fred_rsp3 = vmcs_read64(GUEST_IA32_FRED_RSP3); + vmcs12->guest_ia32_fred_stklvls = vmcs_read64(GUEST_IA32_FRED_STKLVLS); + vmcs12->guest_ia32_fred_ssp1 = vmcs_read64(GUEST_IA32_FRED_SSP1); + vmcs12->guest_ia32_fred_ssp2 = vmcs_read64(GUEST_IA32_FRED_SSP2); + vmcs12->guest_ia32_fred_ssp3 = vmcs_read64(GUEST_IA32_FRED_SSP3); + } + vmcs12->guest_pending_dbg_exceptions = vmcs_readl(GUEST_PENDING_DBG_EXCEPTIONS); @@ -4741,6 +4783,17 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, vmcs_write32(GUEST_IDTR_LIMIT, 0xFFFF); vmcs_write32(GUEST_GDTR_LIMIT, 0xFFFF); + if (nested_cpu_has_fred(vmcs12)) { + vmcs_write64(GUEST_IA32_FRED_CONFIG, vmcs12->host_ia32_fred_config); + vmcs_write64(GUEST_IA32_FRED_RSP1, vmcs12->host_ia32_fred_rsp1); + vmcs_write64(GUEST_IA32_FRED_RSP2, vmcs12->host_ia32_fred_rsp2); + vmcs_write64(GUEST_IA32_FRED_RSP3, vmcs12->host_ia32_fred_rsp3); + vmcs_write64(GUEST_IA32_FRED_STKLVLS, vmcs12->host_ia32_fred_stklvls); + vmcs_write64(GUEST_IA32_FRED_SSP1, vmcs12->host_ia32_fred_ssp1); + vmcs_write64(GUEST_IA32_FRED_SSP2, vmcs12->host_ia32_fred_ssp2); + vmcs_write64(GUEST_IA32_FRED_SSP3, vmcs12->host_ia32_fred_ssp3); + } + /* If not VM_EXIT_CLEAR_BNDCFGS, the L2 value propagates to L1. */ if (vmcs12->vm_exit_controls & VM_EXIT_CLEAR_BNDCFGS) vmcs_write64(GUEST_BNDCFGS, 0); @@ -7197,6 +7250,9 @@ static void nested_vmx_setup_basic(struct nested_vmx_msrs *msrs) msrs->basic |= VMX_BASIC_TRUE_CTLS; if (cpu_has_vmx_basic_inout()) msrs->basic |= VMX_BASIC_INOUT; + + if (cpu_has_vmx_fred()) + msrs->basic |= VMX_BASIC_NESTED_EXCEPTION; } static void nested_vmx_setup_cr_fixed(struct nested_vmx_msrs *msrs) diff --git a/arch/x86/kvm/vmx/nested.h b/arch/x86/kvm/vmx/nested.h index 2c296b6abb8c..5272f617fcef 100644 --- a/arch/x86/kvm/vmx/nested.h +++ b/arch/x86/kvm/vmx/nested.h @@ -251,6 +251,14 @@ static inline bool nested_cpu_has_encls_exit(struct vmcs12 *vmcs12) return nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENCLS_EXITING); } +static inline bool nested_cpu_has_fred(struct vmcs12 *vmcs12) +{ + return vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_FRED && + vmcs12->vm_exit_controls & VM_EXIT_ACTIVATE_SECONDARY_CONTROLS && + vmcs12->secondary_vm_exit_controls & SECONDARY_VM_EXIT_SAVE_IA32_FRED && + vmcs12->secondary_vm_exit_controls & SECONDARY_VM_EXIT_LOAD_IA32_FRED; +} + /* * if fixed0[i] == 1: val[i] must be 1 * if fixed1[i] == 0: val[i] must be 0 diff --git a/arch/x86/kvm/vmx/nested_vmcs_fields.h b/arch/x86/kvm/vmx/nested_vmcs_fields.h index fcd6c32dce31..dea22279d008 100644 --- a/arch/x86/kvm/vmx/nested_vmcs_fields.h +++ b/arch/x86/kvm/vmx/nested_vmcs_fields.h @@ -9,5 +9,17 @@ BUILD_BUG_ON(1) #define HAS_VMCS_FIELD_RANGE(x, y, c) #endif +HAS_VMCS_FIELD(SECONDARY_VM_EXIT_CONTROLS, guest_can_use(vcpu, X86_FEATURE_FRED)) +HAS_VMCS_FIELD(SECONDARY_VM_EXIT_CONTROLS_HIGH, guest_can_use(vcpu, X86_FEATURE_FRED)) + +HAS_VMCS_FIELD_RANGE(GUEST_IA32_FRED_CONFIG, GUEST_IA32_FRED_SSP3, guest_can_use(vcpu, X86_FEATURE_FRED)) +HAS_VMCS_FIELD_RANGE(HOST_IA32_FRED_CONFIG, HOST_IA32_FRED_SSP3, guest_can_use(vcpu, X86_FEATURE_FRED)) + +HAS_VMCS_FIELD(INJECTED_EVENT_DATA, guest_can_use(vcpu, X86_FEATURE_FRED)) +HAS_VMCS_FIELD(INJECTED_EVENT_DATA_HIGH, guest_can_use(vcpu, X86_FEATURE_FRED)) + +HAS_VMCS_FIELD(ORIGINAL_EVENT_DATA, guest_can_use(vcpu, X86_FEATURE_FRED)) +HAS_VMCS_FIELD(ORIGINAL_EVENT_DATA_HIGH, guest_can_use(vcpu, X86_FEATURE_FRED)) + #undef HAS_VMCS_FIELD #undef HAS_VMCS_FIELD_RANGE diff --git a/arch/x86/kvm/vmx/vmcs12.c b/arch/x86/kvm/vmx/vmcs12.c index 98457d7b2b23..59f17fdfad11 100644 --- a/arch/x86/kvm/vmx/vmcs12.c +++ b/arch/x86/kvm/vmx/vmcs12.c @@ -80,6 +80,7 @@ const unsigned short vmcs12_field_offsets[] = { FIELD(VM_ENTRY_MSR_LOAD_COUNT, vm_entry_msr_load_count), FIELD(VM_ENTRY_INTR_INFO_FIELD, vm_entry_intr_info_field), FIELD(VM_ENTRY_EXCEPTION_ERROR_CODE, vm_entry_exception_error_code), + FIELD(INJECTED_EVENT_DATA, injected_event_data), FIELD(VM_ENTRY_INSTRUCTION_LEN, vm_entry_instruction_len), FIELD(TPR_THRESHOLD, tpr_threshold), FIELD(SECONDARY_VM_EXEC_CONTROL, secondary_vm_exec_control), @@ -89,6 +90,7 @@ const unsigned short vmcs12_field_offsets[] = { FIELD(VM_EXIT_INTR_ERROR_CODE, vm_exit_intr_error_code), FIELD(IDT_VECTORING_INFO_FIELD, idt_vectoring_info_field), FIELD(IDT_VECTORING_ERROR_CODE, idt_vectoring_error_code), + FIELD(ORIGINAL_EVENT_DATA, original_event_data), FIELD(VM_EXIT_INSTRUCTION_LEN, vm_exit_instruction_len), FIELD(VMX_INSTRUCTION_INFO, vmx_instruction_info), FIELD(GUEST_ES_LIMIT, guest_es_limit), @@ -152,5 +154,21 @@ const unsigned short vmcs12_field_offsets[] = { FIELD(HOST_IA32_SYSENTER_EIP, host_ia32_sysenter_eip), FIELD(HOST_RSP, host_rsp), FIELD(HOST_RIP, host_rip), + FIELD(GUEST_IA32_FRED_CONFIG, guest_ia32_fred_config), + FIELD(GUEST_IA32_FRED_RSP1, guest_ia32_fred_rsp1), + FIELD(GUEST_IA32_FRED_RSP2, guest_ia32_fred_rsp2), + FIELD(GUEST_IA32_FRED_RSP3, guest_ia32_fred_rsp3), + FIELD(GUEST_IA32_FRED_STKLVLS, guest_ia32_fred_stklvls), + FIELD(GUEST_IA32_FRED_SSP1, guest_ia32_fred_ssp1), + FIELD(GUEST_IA32_FRED_SSP2, guest_ia32_fred_ssp2), + FIELD(GUEST_IA32_FRED_SSP3, guest_ia32_fred_ssp3), + FIELD(HOST_IA32_FRED_CONFIG, host_ia32_fred_config), + FIELD(HOST_IA32_FRED_RSP1, host_ia32_fred_rsp1), + FIELD(HOST_IA32_FRED_RSP2, host_ia32_fred_rsp2), + FIELD(HOST_IA32_FRED_RSP3, host_ia32_fred_rsp3), + FIELD(HOST_IA32_FRED_STKLVLS, host_ia32_fred_stklvls), + FIELD(HOST_IA32_FRED_SSP1, host_ia32_fred_ssp1), + FIELD(HOST_IA32_FRED_SSP2, host_ia32_fred_ssp2), + FIELD(HOST_IA32_FRED_SSP3, host_ia32_fred_ssp3), }; const unsigned int nr_vmcs12_fields = ARRAY_SIZE(vmcs12_field_offsets); diff --git a/arch/x86/kvm/vmx/vmcs12.h b/arch/x86/kvm/vmx/vmcs12.h index 1fe3ed9108aa..f2a33d7007c9 100644 --- a/arch/x86/kvm/vmx/vmcs12.h +++ b/arch/x86/kvm/vmx/vmcs12.h @@ -186,6 +186,24 @@ struct __packed vmcs12 { u16 host_tr_selector; u16 guest_pml_index; u64 secondary_vm_exit_controls; + u64 guest_ia32_fred_config; + u64 guest_ia32_fred_rsp1; + u64 guest_ia32_fred_rsp2; + u64 guest_ia32_fred_rsp3; + u64 guest_ia32_fred_stklvls; + u64 guest_ia32_fred_ssp1; + u64 guest_ia32_fred_ssp2; + u64 guest_ia32_fred_ssp3; + u64 host_ia32_fred_config; + u64 host_ia32_fred_rsp1; + u64 host_ia32_fred_rsp2; + u64 host_ia32_fred_rsp3; + u64 host_ia32_fred_stklvls; + u64 host_ia32_fred_ssp1; + u64 host_ia32_fred_ssp2; + u64 host_ia32_fred_ssp3; + u64 injected_event_data; + u64 original_event_data; }; /* @@ -362,6 +380,24 @@ static inline void vmx_check_vmcs12_offsets(void) CHECK_OFFSET(host_tr_selector, 994); CHECK_OFFSET(guest_pml_index, 996); CHECK_OFFSET(secondary_vm_exit_controls, 998); + CHECK_OFFSET(guest_ia32_fred_config, 1006); + CHECK_OFFSET(guest_ia32_fred_rsp1, 1014); + CHECK_OFFSET(guest_ia32_fred_rsp2, 1022); + CHECK_OFFSET(guest_ia32_fred_rsp3, 1030); + CHECK_OFFSET(guest_ia32_fred_stklvls, 1038); + CHECK_OFFSET(guest_ia32_fred_ssp1, 1046); + CHECK_OFFSET(guest_ia32_fred_ssp2, 1054); + CHECK_OFFSET(guest_ia32_fred_ssp3, 1062); + CHECK_OFFSET(host_ia32_fred_config, 1070); + CHECK_OFFSET(host_ia32_fred_rsp1, 1078); + CHECK_OFFSET(host_ia32_fred_rsp2, 1086); + CHECK_OFFSET(host_ia32_fred_rsp3, 1094); + CHECK_OFFSET(host_ia32_fred_stklvls, 1102); + CHECK_OFFSET(host_ia32_fred_ssp1, 1110); + CHECK_OFFSET(host_ia32_fred_ssp2, 1118); + CHECK_OFFSET(host_ia32_fred_ssp3, 1126); + CHECK_OFFSET(injected_event_data, 1134); + CHECK_OFFSET(original_event_data, 1142); } extern const unsigned short vmcs12_field_offsets[]; diff --git a/arch/x86/kvm/vmx/vmcs_shadow_fields.h b/arch/x86/kvm/vmx/vmcs_shadow_fields.h index 53b64dce1309..607945ada35f 100644 --- a/arch/x86/kvm/vmx/vmcs_shadow_fields.h +++ b/arch/x86/kvm/vmx/vmcs_shadow_fields.h @@ -86,6 +86,10 @@ SHADOW_FIELD_RW(HOST_GS_BASE, host_gs_base) /* 64-bit */ SHADOW_FIELD_RO(GUEST_PHYSICAL_ADDRESS, guest_physical_address) SHADOW_FIELD_RO(GUEST_PHYSICAL_ADDRESS_HIGH, guest_physical_address) +__SHADOW_FIELD_RO(ORIGINAL_EVENT_DATA, original_event_data, cpu_has_vmx_fred()) +__SHADOW_FIELD_RO(ORIGINAL_EVENT_DATA_HIGH, original_event_data, cpu_has_vmx_fred()) +__SHADOW_FIELD_RW(INJECTED_EVENT_DATA, injected_event_data, cpu_has_vmx_fred()) +__SHADOW_FIELD_RW(INJECTED_EVENT_DATA_HIGH, injected_event_data, cpu_has_vmx_fred()) #undef SHADOW_FIELD_RO #undef SHADOW_FIELD_RW From patchwork Tue Oct 1 05:01:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817453 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 7CD0C4F881; Tue, 1 Oct 2024 05:02:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758937; cv=none; b=ntnK5mDw3llvG1El7HwTpnipdJcvE+4JnY+3rPRGkqIDeYyOxcOY9Y3AdooqI0K2xRm6qu3IMS93AnAbYu5h6IQdgwgBPxqaq5b4AysvHjsGb7he4Mxftc8ZmljpkwtDzSUDe8mvNplI0d1L7OVj7Rk2/0lxL1DC84UxKqC2YoU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758937; c=relaxed/simple; bh=rZxZItYgG7kfxoyaaKMJ5o98t4Va4yAjZu0SXMYKnLg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rs1q7Oiu0u1FPt5BKMeHDuDY8A+c41P+FfqOGvKWBPW9e8LGHQj/WjwSTILGwJczTRnuU1NE2Tp49lV+AntToxD/dnehLKB7UiXETxa47r/sPuEy59u8MxVIwSjRGmJNGQyqF7bSgUAl/M0XfYaa+GuzR7VgeeEQl8wE/nnpmfc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=JMkujZ0E; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="JMkujZ0E" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7p3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:41 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7p3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758902; bh=iM1mgYlg6p30DH2JJGY1oZ4PtPipkI4OLu6ROopnMM8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JMkujZ0EN1mLLl2siZGOg5JdmmZUd5yhuxvxfjzHB3wvyXa0XpBhRNNK2HTVbWUBB GpebN2W6aOZN3vcsAXMDKuftnm87+F6VK4pU1vowjHSUIfeQ8LYyY4rHikuMUpfwRr CqyTNxNEiUlExiL3ZVeEEPeGIwpCLZ+x4ZuMDmzldMyIxS9TOUcZpfvk2MY0pIWfTp yF23wAc6Ze3XvTubr70q/hKeLJJYFL74KdNNTmFGD+o0tzQRHw8ahDDJO3lVbzsICV TWNGfsOhUCdIuUlkcml6GM7E/jD1I6W6Mj49CMqwav9nmAciSwKEat36DOLNkju7x4 wTnVMbGGXfXQg== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 26/27] KVM: nVMX: Add VMCS FRED states checking Date: Mon, 30 Sep 2024 22:01:09 -0700 Message-ID: <20241001050110.3643764-27-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li As real hardware, nested VMX performs checks on various VMCS fields, including both controls and guest/host states. Add FRED related VMCS field checkings with the addition of nested FRED. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) 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 45a5ffa51e60..1fbdeea32c98 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2975,6 +2975,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, @@ -2993,6 +2995,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; @@ -3006,7 +3009,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 */ @@ -3025,6 +3030,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: @@ -3034,6 +3048,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; } } @@ -3096,9 +3116,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; } @@ -3242,6 +3283,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; From patchwork Tue Oct 1 05:01:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Li X-Patchwork-Id: 13817451 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (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 7F20974E09; Tue, 1 Oct 2024 05:02:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758937; cv=none; b=lfZUZynoYnAToQsUeKXrILm7VT83e1gRXuevpoGwd8lsHKlON4KkdzpsC0IXcKb09kfG6cIwJ8Oxf9xhfzAOGbaUuuuVYpkU72aij7BviTrjcBQzvvaKGUzilaeqQg8yiMy7JTaq0575QfdmJGO4uk/nSTCI2cRCYnLzqD+1kno= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727758937; c=relaxed/simple; bh=OC9q8/0WaJQ1ajKPZH3KXjpXhUhvJLWl9lJoncDMjjQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=boHyS62LR+ayc8KVq8aI1rvPUX4BenZrYpUyXQpk+nSwqpX+jUUWKzutGSASUPUcKI/ryiI+CdeGuluPZ5pZv766m40gDcBhduaR6w8e3+t1zq6QPDCnYRg6RF83/ce7wrgqc9tcA+sVnuF0HOPNjYSQ6LmLqimjBXAbdZDPFJU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=A6fSaZ5J; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="A6fSaZ5J" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 49151A7q3643828 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 30 Sep 2024 22:01:42 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 49151A7q3643828 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024091601; t=1727758903; bh=aB86Wj6xLWMx6vbkl7mBHvGR5iFDZ82fM7jlvBlgm1s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=A6fSaZ5JysraQ0FAZ0EH7VyJxJspiHugaIbKVEgtwGMhqrWErsRtN/0+mveyoMUG/ DchoyhVYetJrgWNHiqrbwMuvVd81uFbdKK+LCtXqWFhBzX9Lqr69rLvGtQSG5fuErs 0G6/HSCI2eUiM32w0cURjShEw/D8Zieiq/TGSQVOG8YrAas5XaM/ALgPMU4QqwIVkW 5wDTx6v3CEjQwkkat+aVD2GSKGQgiX3EAfwpGKDn6SadTDkdvMjGglg9oc3sqc/PtJ VUKEnuBd0+1BBzfvu4z7UmsnuBSLu+Z0W4tAzhpPha/G4EYm0PEWUowb7HgyGYMxEo c1P0QEXnCcK5g== From: "Xin Li (Intel)" To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@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, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, xin@zytor.com Subject: [PATCH v3 27/27] KVM: nVMX: Allow VMX FRED controls Date: Mon, 30 Sep 2024 22:01:10 -0700 Message-ID: <20241001050110.3643764-28-xin@zytor.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241001050110.3643764-1-xin@zytor.com> References: <20241001050110.3643764-1-xin@zytor.com> Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Xin Li Allow nVMX FRED controls as nested FRED support is in place. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang --- arch/x86/kvm/vmx/nested.c | 6 ++++-- arch/x86/kvm/vmx/vmx.c | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 1fbdeea32c98..b1b4483afcda 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -7159,7 +7159,8 @@ static void nested_vmx_setup_exit_ctls(struct vmcs_config *vmcs_conf, * advertise any feature in it to nVMX until its nVMX support * is ready. */ - msrs->secondary_exit_ctls &= 0; + msrs->secondary_exit_ctls &= SECONDARY_VM_EXIT_SAVE_IA32_FRED | + SECONDARY_VM_EXIT_LOAD_IA32_FRED; } } @@ -7174,7 +7175,8 @@ static void nested_vmx_setup_entry_ctls(struct vmcs_config *vmcs_conf, #ifdef CONFIG_X86_64 VM_ENTRY_IA32E_MODE | #endif - VM_ENTRY_LOAD_IA32_PAT | VM_ENTRY_LOAD_BNDCFGS; + VM_ENTRY_LOAD_IA32_PAT | VM_ENTRY_LOAD_BNDCFGS | + VM_ENTRY_LOAD_IA32_FRED; msrs->entry_ctls_high |= (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | VM_ENTRY_LOAD_IA32_EFER | VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 522ee27a4655..ba6a7c6b6727 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7923,6 +7923,7 @@ static void nested_vmx_cr_fixed1_bits_update(struct kvm_vcpu *vcpu) entry = kvm_find_cpuid_entry_index(vcpu, 0x7, 1); cr4_fixed1_update(X86_CR4_LAM_SUP, eax, feature_bit(LAM)); + cr4_fixed1_update(X86_CR4_FRED, eax, feature_bit(FRED)); #undef cr4_fixed1_update }