From nobody Tue Dec 16 08:33:59 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 3FC8024A04D for ; Thu, 15 May 2025 00:54:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747270454; cv=none; b=d/rtW73TjJEkwdwW/P7d0PVahUxxkVg6CpFREzhI4Yh3APeR/oI/LwcBi9LZSPhmvOzxQdaBb1528c/Pvt5nHacAVnWcpncLgYSkWxVbGNfGwKf0Timh39pCzuH6JPcfiRCM3Rf0pqBbQIATNf2zQhqBUlZ+I7biuwfBHuvU5hM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747270454; c=relaxed/simple; bh=XIT9X6z9tNCqLtz+c0aFqZhfgEcHpUn7EzAR/X64sxQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=S/ig4OYRE0Ufb2Ve/dB0Q8T5NHzHQN9mR1l/F68cQLEk2AxqO4QpBqg+5eLGno1DMtXyh6GAf3WlbS7ueyun92cl09gzBT5YzL3SF1GtU/U6NANMnTn+N0L3ToBO+ye5/zEK6tu7ujoeS9TOvsIrq8Do4D4tHKkF/ZRTvxH2R2g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=TWa9GOYq; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="TWa9GOYq" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747270452; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wG2REckrWlDMRtU3eTh+Y7dHbzwqS83QmmyH4v1KO2Q=; b=TWa9GOYq8M7buc3Tl37Ahle/y2ng2wYyrv/zv8INJ1EVjnVd2IadNnsfCjAtUDoju+WJwz 4pmM9OicvAmSyzass/GKL/BlW2J69budBCu5PKlQt8J0jVxtibIoKWrk+WVNFQmfrVtuGt XfNAzLkVoPvMid7Oqk/xJ/MgAf0cCY8= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-362-M7jkT3hdM-qewT4N9U52Qw-1; Wed, 14 May 2025 20:54:09 -0400 X-MC-Unique: M7jkT3hdM-qewT4N9U52Qw-1 X-Mimecast-MFC-AGG-ID: M7jkT3hdM-qewT4N9U52Qw_1747270448 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3C86718004A7; Thu, 15 May 2025 00:54:08 +0000 (UTC) Received: from intellaptop.lan (unknown [10.22.80.5]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D86ED19560A7; Thu, 15 May 2025 00:54:05 +0000 (UTC) From: Maxim Levitsky To: kvm@vger.kernel.org Cc: Thomas Gleixner , Sean Christopherson , Borislav Petkov , x86@kernel.org, Ingo Molnar , linux-kernel@vger.kernel.org, "H. Peter Anvin" , Paolo Bonzini , Dave Hansen , Maxim Levitsky Subject: [PATCH v4 4/4] x86: KVM: VMX: preserve DEBUGCTLMSR_FREEZE_IN_SMM Date: Wed, 14 May 2025 20:53:53 -0400 Message-ID: <20250515005353.952707-5-mlevitsk@redhat.com> In-Reply-To: <20250515005353.952707-1-mlevitsk@redhat.com> References: <20250515005353.952707-1-mlevitsk@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" Pass through the host's DEBUGCTL.DEBUGCTLMSR_FREEZE_IN_SMM to the guest GUEST_IA32_DEBUGCTL without the guest seeing this value. Since the value of the host DEBUGCTL can in theory change between VM runs, check if has changed, and if yes, then reload the GUEST_IA32_DEBUGCTL with the new value. Signed-off-by: Maxim Levitsky --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/vmx/nested.c | 4 ++-- arch/x86/kvm/vmx/vmx.c | 22 +++++++++++++++++++--- arch/x86/kvm/vmx/vmx.h | 2 ++ arch/x86/kvm/x86.c | 7 +++++-- 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index d2ad31a1628e..2e7e4a8b392e 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1673,6 +1673,7 @@ static inline u16 kvm_lapic_irq_dest_mode(bool dest_m= ode_logical) enum kvm_x86_run_flags { KVM_RUN_FORCE_IMMEDIATE_EXIT =3D BIT(0), KVM_RUN_LOAD_GUEST_DR6 =3D BIT(1), + KVM_RUN_LOAD_DEBUGCTL =3D BIT(2), }; =20 struct kvm_x86_ops { diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 0bda6400e30a..0a572356119f 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2653,7 +2653,7 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, stru= ct vmcs12 *vmcs12, if (vmx->nested.nested_run_pending && (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS)) { kvm_set_dr(vcpu, 7, vmcs12->guest_dr7); - vmcs_write64(GUEST_IA32_DEBUGCTL, vmcs12->guest_ia32_debugctl); + vmx_guest_debugctl_write(vcpu, vmcs12->guest_ia32_debugctl); } else { kvm_set_dr(vcpu, 7, vcpu->arch.dr7); vmcs_write64(GUEST_IA32_DEBUGCTL, vmx->nested.pre_vmenter_debugctl); @@ -4792,7 +4792,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *v= cpu, __vmx_set_segment(vcpu, &seg, VCPU_SREG_LDTR); =20 kvm_set_dr(vcpu, 7, 0x400); - vmcs_write64(GUEST_IA32_DEBUGCTL, 0); + vmx_guest_debugctl_write(vcpu, 0); =20 if (nested_vmx_load_msr(vcpu, vmcs12->vm_exit_msr_load_addr, vmcs12->vm_exit_msr_load_count)) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 9046ee2e9a04..c70fe7cbede6 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2154,7 +2154,7 @@ int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_dat= a *msr_info) msr_info->data =3D vmx->pt_desc.guest.addr_a[index / 2]; break; case MSR_IA32_DEBUGCTLMSR: - msr_info->data =3D vmcs_read64(GUEST_IA32_DEBUGCTL); + msr_info->data =3D vmx_guest_debugctl_read(); break; default: find_uret_msr: @@ -2194,6 +2194,17 @@ u64 vmx_get_supported_debugctl(struct kvm_vcpu *vcpu= , bool host_initiated) return debugctl; } =20 +void vmx_guest_debugctl_write(struct kvm_vcpu *vcpu, u64 val) +{ + val |=3D vcpu->arch.host_debugctl & DEBUGCTLMSR_FREEZE_IN_SMM; + vmcs_write64(GUEST_IA32_DEBUGCTL, val); +} + +u64 vmx_guest_debugctl_read(void) +{ + return vmcs_read64(GUEST_IA32_DEBUGCTL) & ~DEBUGCTLMSR_FREEZE_IN_SMM; +} + /* * Writes msr value into the appropriate "register". * Returns 0 on success, non-0 otherwise. @@ -2279,7 +2290,8 @@ int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_dat= a *msr_info) VM_EXIT_SAVE_DEBUG_CONTROLS) get_vmcs12(vcpu)->guest_ia32_debugctl =3D data; =20 - vmcs_write64(GUEST_IA32_DEBUGCTL, data); + vmx_guest_debugctl_write(vcpu, data); + if (intel_pmu_lbr_is_enabled(vcpu) && !to_vmx(vcpu)->lbr_desc.event && (data & DEBUGCTLMSR_LBR)) intel_pmu_create_guest_lbr_event(vcpu); @@ -4795,7 +4807,8 @@ static void init_vmcs(struct vcpu_vmx *vmx) vmcs_write32(GUEST_SYSENTER_CS, 0); vmcs_writel(GUEST_SYSENTER_ESP, 0); vmcs_writel(GUEST_SYSENTER_EIP, 0); - vmcs_write64(GUEST_IA32_DEBUGCTL, 0); + + vmx_guest_debugctl_write(&vmx->vcpu, 0); =20 if (cpu_has_vmx_tpr_shadow()) { vmcs_write64(VIRTUAL_APIC_PAGE_ADDR, 0); @@ -7368,6 +7381,9 @@ fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, u64 ru= n_flags) if (run_flags & KVM_RUN_LOAD_GUEST_DR6) set_debugreg(vcpu->arch.dr6, 6); =20 + if (run_flags & KVM_RUN_LOAD_DEBUGCTL) + vmx_guest_debugctl_write(vcpu, vmx_guest_debugctl_read()); + /* * Refresh vmcs.HOST_CR3 if necessary. This must be done immediately * prior to VM-Enter, as the kernel may load a new ASID (PCID) any time diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index 1b80479505d3..5ddedf73392b 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -416,6 +416,8 @@ static inline void vmx_set_intercept_for_msr(struct kvm= _vcpu *vcpu, u32 msr, =20 void vmx_update_cpu_dirty_logging(struct kvm_vcpu *vcpu); u64 vmx_get_supported_debugctl(struct kvm_vcpu *vcpu, bool host_initiated); +void vmx_guest_debugctl_write(struct kvm_vcpu *vcpu, u64 val); +u64 vmx_guest_debugctl_read(void); =20 /* * Note, early Intel manuals have the write-low and read-high bitmap offse= ts diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 684b8047e0f2..a85078dfa36d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10752,7 +10752,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) dm_request_for_irq_injection(vcpu) && kvm_cpu_accept_dm_intr(vcpu); fastpath_t exit_fastpath; - u64 run_flags; + u64 run_flags, host_debug_ctl; =20 bool req_immediate_exit =3D false; =20 @@ -11024,7 +11024,10 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) set_debugreg(0, 7); } =20 - vcpu->arch.host_debugctl =3D get_debugctlmsr(); + host_debug_ctl =3D get_debugctlmsr(); + if (host_debug_ctl !=3D vcpu->arch.host_debugctl) + run_flags |=3D KVM_RUN_LOAD_DEBUGCTL; + vcpu->arch.host_debugctl =3D host_debug_ctl; =20 guest_timing_enter_irqoff(); =20 --=20 2.46.0