From nobody Sat Oct 11 08:27:39 2025 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 79120283CA0 for ; Tue, 10 Jun 2025 23:20:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597616; cv=none; b=em3RfW7R/doc2SN+z1HMIbzVqcrcyO3ALGUBRqrTVNMieiBbnYW4PXykxP318AzIk+jhmXbw59ZQBpFCNcv6jAITL2cmKemRGtA3GI5zb4Sx+tRY4XhINwyB6ak9NoOTR+Je2OwEZ4VbImr1k4Trqq5hAVSDRQ28ZfpjAJpj3N8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597616; c=relaxed/simple; bh=MmISEUVAZkAYO+3tppVzE59BztQ7B47DiT8C5/3AK3I=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=giiiMfKFZQ4zOCLLh5rvsH6F/OoTuOHlBZwrW2n0kbUEVGwSdI33J0H74KNVYWWrrZvZvDLaEYh3IGMzVbMaGIzMrk/bLp1W1EckK/6tdTy8Vx9jRHZhXSTYze2xpiqvz4mzUMPE97dIhDA2xgFytyCjHxeDl1UNtLxOnVFR0Vc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=wAJhDQJG; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="wAJhDQJG" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-b0e0c573531so3632272a12.3 for ; Tue, 10 Jun 2025 16:20:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1749597615; x=1750202415; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=Ku4Jlo0vfxtFTgd99p+Ks+SleUGyUmQc0U3V1r1cPLo=; b=wAJhDQJGBwDbE/mLGnLGJr2k7bjlRThyjy2hh1U/WTtSNHd8b7HVCxvsaLXt8Es7za 5CH1Ff9naNoOJpq1BLvI1LyN+RzryjyhKXj5LqDlrzPIMNoFJPpDcjZM4oWT+gYb9Bq2 3tGIrBxhHhJtB51V/s/iUnYuyz/RtYnZhL8Bf7qu56+miOmJhuRv0/UkRDDiENcqtm6y r4+EPPPZqnEnIvSaHspgvzXjqbCqpUSqluuspkx8FIJy/FKEozBfYK+mO/MNJ1WWsmHe 0XhFZIL6Pl7+lv+ABwuAng8WstexBomyQpGgLP0sevA5jG8QhrICj63vIglQg8nEVKCG ud+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749597615; x=1750202415; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Ku4Jlo0vfxtFTgd99p+Ks+SleUGyUmQc0U3V1r1cPLo=; b=MFFigkYdPCSxdZ7c9QC6PRoKDbHq24RwVIiHk0aYnZsUXDUHeuD6icauW+iJXw44/u /AQdIhzYt3K+HMYGevZEiNui3gf6CYb30frHFP07nmULHilZHysUrZ+KI5W4bQzoTym6 Li3BOY7WRUEVI9YTZBsKB2svr0gDBgXuA2jtg1xgnbfpcrbI7z6Z1YFv7bZwZFpzlvqg 9pT7QprDVcp4T6N2RKdrCxFcGy4UOMkrH/ao/YNN5z8/Ik0jwGff8e47pQYqozqH4K6C JE0sm7qwKx/ZPLfgcizyFKciJ29i/+YW2LR+d2NtW/zhi1srhZ1hW68j476xQu96M+H1 C0pw== X-Forwarded-Encrypted: i=1; AJvYcCUpmyoWNU0mTxlPOFObUqIxFy7rc0qlkqmnWmMMWijdTSZ7ZrxkohZbt+ED1eiH+meK7CIyyP4RVUYK9iI=@vger.kernel.org X-Gm-Message-State: AOJu0Yz1GQwLE392TbULogtbQUkAKmVAHmcGea/pWo2/dcjb9ZQR8dTM eitj3/nvLNYzJVYtnbLnVw/PpnCPT0VKnkJDC3jlOYRlaP04HxYq8CZX4oDGUVjWsCqwbKS4aLS Ek3gbvQ== X-Google-Smtp-Source: AGHT+IHskFiLR9R0/+qB03P2oZJfiwIk2UJIC6FsIlh4oCPhGlI2xBclplA11XHeDq3Z7tAlav5E6cfk8vE= X-Received: from pjbos11.prod.google.com ([2002:a17:90b:1ccb:b0:311:4201:4021]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3c4f:b0:311:e8cc:425d with SMTP id 98e67ed59e1d1-313af11cbb2mr1636619a91.10.1749597614808; Tue, 10 Jun 2025 16:20:14 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 10 Jun 2025 16:20:03 -0700 In-Reply-To: <20250610232010.162191-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250610232010.162191-1-seanjc@google.com> X-Mailer: git-send-email 2.50.0.rc0.642.g800a2b2222-goog Message-ID: <20250610232010.162191-2-seanjc@google.com> Subject: [PATCH v6 1/8] KVM: TDX: Use kvm_arch_vcpu.host_debugctl to restore the host's DEBUGCTL From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Adrian Hunter , Maxim Levitsky Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use the kvm_arch_vcpu.host_debugctl snapshot to restore DEBUGCTL after running a TD vCPU. The final TDX series rebase was mishandled, likely due to commit fb71c7959356 ("KVM: x86: Snapshot the host's DEBUGCTL in common x86") deleting the same line of code from vmx.h, i.e. creating a semantic conflict of sorts, but no syntactic conflict. Using the version in kvm_vcpu_arch picks up the ulong =3D> u64 fix (which isn't relevant to TDX) as well as the IRQ fix from commit 189ecdb3e112 ("KVM: x86: Snapshot the host's DEBUGCTL after disabling IRQs"). Link: https://lore.kernel.org/all/20250307212053.2948340-10-pbonzini@redhat= .com Cc: Adrian Hunter Fixes: 8af099037527 ("KVM: TDX: Save and restore IA32_DEBUGCTL") Signed-off-by: Sean Christopherson Reviewed-by: Adrian Hunter --- arch/x86/kvm/vmx/common.h | 2 -- arch/x86/kvm/vmx/tdx.c | 6 ++---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/vmx/common.h b/arch/x86/kvm/vmx/common.h index a0c5e8781c33..bc5ece76533a 100644 --- a/arch/x86/kvm/vmx/common.h +++ b/arch/x86/kvm/vmx/common.h @@ -53,8 +53,6 @@ struct vcpu_vt { #ifdef CONFIG_X86_64 u64 msr_host_kernel_gs_base; #endif - - unsigned long host_debugctlmsr; }; =20 #ifdef CONFIG_KVM_INTEL_TDX diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index b952bc673271..3cfe89aad68e 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -778,8 +778,6 @@ void tdx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) else vt->msr_host_kernel_gs_base =3D read_msr(MSR_KERNEL_GS_BASE); =20 - vt->host_debugctlmsr =3D get_debugctlmsr(); - vt->guest_state_loaded =3D true; } =20 @@ -1055,8 +1053,8 @@ fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, bool f= orce_immediate_exit) =20 tdx_vcpu_enter_exit(vcpu); =20 - if (vt->host_debugctlmsr & ~TDX_DEBUGCTL_PRESERVED) - update_debugctlmsr(vt->host_debugctlmsr); + if (vcpu->arch.host_debugctl & ~TDX_DEBUGCTL_PRESERVED) + update_debugctlmsr(vcpu->arch.host_debugctl); =20 tdx_load_host_xsave_state(vcpu); tdx->guest_entered =3D true; --=20 2.50.0.rc0.642.g800a2b2222-goog From nobody Sat Oct 11 08:27:39 2025 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5F7CB28C028 for ; Tue, 10 Jun 2025 23:20:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597619; cv=none; b=kyczJZaP/mS0eB34bgeBuUk6nKs9fr0oBwcCcLcUqKhqfS/79ph/fP/m+yKA4qkIqhmhoD2vkUZnI9O33anch4x9zJ5iwQw13A7YcauNys1obNWkqP8MZge0JSXkrdwx7PqlkilXO47/jQIsdVEBsX3S1eHKKYg8u1CPjf8+hlw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597619; c=relaxed/simple; bh=8juvKaK4gaqWtgLvKQn3nug6qZB3xKNgz/vWlcEhitY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=XwsIDjN5Pc/3zfosU3KFLFDXQlXapkUCEqjFVxXeJuLt5IJGstqwQa/ye/Ef+xmntTYIfVVEzpPRXFk+SdvbEgu2apKzKtvw/O7o9C5wbSA2sqmQMmu/fYxoeTd7H+1v6b2H2yS8TC8VmK+6xA3GgRnzBXNud4iMf7j7D/E64ZM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=JaeO/zUW; arc=none smtp.client-ip=209.85.216.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="JaeO/zUW" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-31171a736b2so10020255a91.1 for ; Tue, 10 Jun 2025 16:20:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1749597616; x=1750202416; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=bxuye0qblmsaY3g2XAA5/C7McrkA7bbVijWz0WdKsNA=; b=JaeO/zUWQSMDZqETOEjGiOGVGCdJ+Km7EmCDwvbVMCtC58xHp3uOfN2tGuqB6Oracb ewkd9vTwER/ZrelafOVgbm3wAeRKikDp2udkcbKpi4rgSdgHOJHK7GJlQjR8W4Pb5ahu pzbXRGq8fDcEN9SNM3dpIbnkddckTiyqWF+ipZG48sPQGDFNJgwY6lBFYB5qirUXMgzQ +TPQGIBZxB/F51ZTFOi67Rp3Gs9NOTUk7Tk2zSbu6vLR+EXZ1/1M3cR48TQoTbnxeM1z VZxjVXDQ5jQPkmuWo7uWQrk0xdXOLPgaiY77WKSyqpvXEk9ZpmfLChiGteN6r0WBGOmA w15Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749597616; x=1750202416; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=bxuye0qblmsaY3g2XAA5/C7McrkA7bbVijWz0WdKsNA=; b=ZwKSuelAkW5TyjeERZnvXYj7H++zhuYlV5nfMzZGUzOtDiYwkN2++0rSYkidQdL9tK W24q8zhzsRASiOw5xo2GER6Yrwm3Xi+dVKKlQe9upJSASCFRYQWYkn5AB4mQrlKJw2DD 67lYogVCuM0Z2yvCfG7D+D+Cz35PZ+Bzlt5NrvX+FkVrYMGFm99+J/fJGvD4NP9R7wng A3v8h7cV+KbQkSL/WOWrCb36kkLMP7of/jNmol6dmdPFds+ldl6t6eReuT9PsSKxNMkN o+W1veg544vwGJrPiBUqvH1esGrb7cfVhlvy+HuD2kPOt8vIw0eau3IlTgUZCorZd3AV x+Eg== X-Forwarded-Encrypted: i=1; AJvYcCWbA3qx4+ssHh0Mp127bCTs86rtfL/25ZKuxX1AexHtFSvU4jgn2DmMxLJQnPhICwrxKBoYFRKsP3ziIw0=@vger.kernel.org X-Gm-Message-State: AOJu0Yw01GTzo9UlltA1K22Pz5uDHax/fIDG2HzX+MjUrc5YwgB0UfLD TGXNc1HlI1iiQBVCOzlztR9BtaGQM/EWlafwrkiCpvJ9EL44vHKC32Za6iSTAcPIZoI6oudfxBl GMohA9w== X-Google-Smtp-Source: AGHT+IHiJ9IQTadLJLpNjGdfaVB6tLlZK+VgXBKKERwWbBc7g/drIRFxbgcFuE6XmjHBARQVFNP3/jDVGAk= X-Received: from pjh6.prod.google.com ([2002:a17:90b:3f86:b0:30e:6bb2:6855]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:4b92:b0:312:eaea:afa1 with SMTP id 98e67ed59e1d1-313af267226mr1496770a91.29.1749597616670; Tue, 10 Jun 2025 16:20:16 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 10 Jun 2025 16:20:04 -0700 In-Reply-To: <20250610232010.162191-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250610232010.162191-1-seanjc@google.com> X-Mailer: git-send-email 2.50.0.rc0.642.g800a2b2222-goog Message-ID: <20250610232010.162191-3-seanjc@google.com> Subject: [PATCH v6 2/8] KVM: x86: Convert vcpu_run()'s immediate exit param into a generic bitmap From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Adrian Hunter , Maxim Levitsky Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Convert kvm_x86_ops.vcpu_run()'s "force_immediate_exit" boolean parameter into an a generic bitmap so that similar "take action" information can be passed to vendor code without creating a pile of boolean parameters. This will allow dropping kvm_x86_ops.set_dr6() in favor of a new flag, and will also allow for adding similar functionality for re-loading debugctl in the active VMCS. Opportunistically massage the TDX WARN and comment to prepare for adding more run_flags, all of which are expected to be mutually exclusive with TDX, i.e. should be WARNed on. No functional change intended. Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson --- arch/x86/include/asm/kvm_host.h | 6 +++++- arch/x86/kvm/svm/svm.c | 4 ++-- arch/x86/kvm/vmx/main.c | 6 +++--- arch/x86/kvm/vmx/tdx.c | 18 +++++++++--------- arch/x86/kvm/vmx/vmx.c | 3 ++- arch/x86/kvm/vmx/x86_ops.h | 4 ++-- arch/x86/kvm/x86.c | 11 ++++++++--- 7 files changed, 31 insertions(+), 21 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 330cdcbed1a6..3b5871ebd7e4 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1673,6 +1673,10 @@ static inline u16 kvm_lapic_irq_dest_mode(bool dest_= mode_logical) return dest_mode_logical ? APIC_DEST_LOGICAL : APIC_DEST_PHYSICAL; } =20 +enum kvm_x86_run_flags { + KVM_RUN_FORCE_IMMEDIATE_EXIT =3D BIT(0), +}; + struct kvm_x86_ops { const char *name; =20 @@ -1754,7 +1758,7 @@ struct kvm_x86_ops { =20 int (*vcpu_pre_run)(struct kvm_vcpu *vcpu); enum exit_fastpath_completion (*vcpu_run)(struct kvm_vcpu *vcpu, - bool force_immediate_exit); + u64 run_flags); int (*handle_exit)(struct kvm_vcpu *vcpu, enum exit_fastpath_completion exit_fastpath); int (*skip_emulated_instruction)(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 0ad1a6d4fb6d..00d78090de3d 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4402,9 +4402,9 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vc= pu *vcpu, bool spec_ctrl_in guest_state_exit_irqoff(); } =20 -static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu, - bool force_immediate_exit) +static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu, u64 run_f= lags) { + bool force_immediate_exit =3D run_flags & KVM_RUN_FORCE_IMMEDIATE_EXIT; struct vcpu_svm *svm =3D to_svm(vcpu); bool spec_ctrl_intercepted =3D msr_write_intercepted(vcpu, MSR_IA32_SPEC_= CTRL); =20 diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c index d1e02e567b57..fef3e3803707 100644 --- a/arch/x86/kvm/vmx/main.c +++ b/arch/x86/kvm/vmx/main.c @@ -175,12 +175,12 @@ static int vt_vcpu_pre_run(struct kvm_vcpu *vcpu) return vmx_vcpu_pre_run(vcpu); } =20 -static fastpath_t vt_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_= exit) +static fastpath_t vt_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags) { if (is_td_vcpu(vcpu)) - return tdx_vcpu_run(vcpu, force_immediate_exit); + return tdx_vcpu_run(vcpu, run_flags); =20 - return vmx_vcpu_run(vcpu, force_immediate_exit); + return vmx_vcpu_run(vcpu, run_flags); } =20 static int vt_handle_exit(struct kvm_vcpu *vcpu, diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 3cfe89aad68e..9a758d8b38ea 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -1018,20 +1018,20 @@ static void tdx_load_host_xsave_state(struct kvm_vc= pu *vcpu) DEBUGCTLMSR_FREEZE_PERFMON_ON_PMI | \ DEBUGCTLMSR_FREEZE_IN_SMM) =20 -fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit) +fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags) { struct vcpu_tdx *tdx =3D to_tdx(vcpu); struct vcpu_vt *vt =3D to_vt(vcpu); =20 /* - * force_immediate_exit requires vCPU entering for events injection with - * an immediately exit followed. But The TDX module doesn't guarantee - * entry, it's already possible for KVM to _think_ it completely entry - * to the guest without actually having done so. - * Since KVM never needs to force an immediate exit for TDX, and can't - * do direct injection, just warn on force_immediate_exit. + * WARN if KVM wants to force an immediate exit, as the TDX module does + * not guarantee entry into the guest, i.e. it's possible for KVM to + * _think_ it completed entry to the guest and forced an immediate exit + * without actually having done so. Luckily, KVM never needs to force + * an immediate exit for TDX (KVM can't do direct event injection, so + * just WARN and continue on. */ - WARN_ON_ONCE(force_immediate_exit); + WARN_ON_ONCE(run_flags); =20 /* * Wait until retry of SEPT-zap-related SEAMCALL completes before @@ -1041,7 +1041,7 @@ fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, bool f= orce_immediate_exit) if (unlikely(READ_ONCE(to_kvm_tdx(vcpu->kvm)->wait_for_sept_zap))) return EXIT_FASTPATH_EXIT_HANDLED; =20 - trace_kvm_entry(vcpu, force_immediate_exit); + trace_kvm_entry(vcpu, run_flags & KVM_RUN_FORCE_IMMEDIATE_EXIT); =20 if (pi_test_on(&vt->pi_desc)) { apic->send_IPI_self(POSTED_INTR_VECTOR); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 9ff00ae9f05a..e66f5ffa8716 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7317,8 +7317,9 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vc= pu *vcpu, guest_state_exit_irqoff(); } =20 -fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit) +fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags) { + bool force_immediate_exit =3D run_flags & KVM_RUN_FORCE_IMMEDIATE_EXIT; struct vcpu_vmx *vmx =3D to_vmx(vcpu); unsigned long cr3, cr4; =20 diff --git a/arch/x86/kvm/vmx/x86_ops.h b/arch/x86/kvm/vmx/x86_ops.h index b4596f651232..0b4f5c5558d0 100644 --- a/arch/x86/kvm/vmx/x86_ops.h +++ b/arch/x86/kvm/vmx/x86_ops.h @@ -21,7 +21,7 @@ void vmx_vm_destroy(struct kvm *kvm); int vmx_vcpu_precreate(struct kvm *kvm); int vmx_vcpu_create(struct kvm_vcpu *vcpu); int vmx_vcpu_pre_run(struct kvm_vcpu *vcpu); -fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit); +fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags); void vmx_vcpu_free(struct kvm_vcpu *vcpu); void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event); void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu); @@ -133,7 +133,7 @@ void tdx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_ev= ent); void tdx_vcpu_free(struct kvm_vcpu *vcpu); void tdx_vcpu_load(struct kvm_vcpu *vcpu, int cpu); int tdx_vcpu_pre_run(struct kvm_vcpu *vcpu); -fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit); +fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags); void tdx_prepare_switch_to_guest(struct kvm_vcpu *vcpu); void tdx_vcpu_put(struct kvm_vcpu *vcpu); bool tdx_protected_apic_has_interrupt(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index dd34a2ec854c..d4a51b263d6b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10779,6 +10779,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; =20 bool req_immediate_exit =3D false; =20 @@ -11023,8 +11024,11 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) goto cancel_injection; } =20 - if (req_immediate_exit) + run_flags =3D 0; + if (req_immediate_exit) { + run_flags |=3D KVM_RUN_FORCE_IMMEDIATE_EXIT; kvm_make_request(KVM_REQ_EVENT, vcpu); + } =20 fpregs_assert_state_consistent(); if (test_thread_flag(TIF_NEED_FPU_LOAD)) @@ -11061,8 +11065,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) WARN_ON_ONCE((kvm_vcpu_apicv_activated(vcpu) !=3D kvm_vcpu_apicv_active(= vcpu)) && (kvm_get_apic_mode(vcpu) !=3D LAPIC_MODE_DISABLED)); =20 - exit_fastpath =3D kvm_x86_call(vcpu_run)(vcpu, - req_immediate_exit); + exit_fastpath =3D kvm_x86_call(vcpu_run)(vcpu, run_flags); if (likely(exit_fastpath !=3D EXIT_FASTPATH_REENTER_GUEST)) break; =20 @@ -11074,6 +11077,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) break; } =20 + run_flags =3D 0; + /* Note, VM-Exits that go down the "slow" path are accounted below. */ ++vcpu->stat.exits; } --=20 2.50.0.rc0.642.g800a2b2222-goog From nobody Sat Oct 11 08:27:39 2025 Received: from mail-pl1-f201.google.com (mail-pl1-f201.google.com [209.85.214.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D224128C84F for ; Tue, 10 Jun 2025 23:20:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597620; cv=none; b=MLcBBvTmaejg1TKoc2Z+lSYAJelDUa8PRsDmpwU1jdpKWXF3hMXbIcx9tx6Qh/teclABh0toRfDyEbBEfdbYXMBt/rvWs8HhAU4YFO6jZw4saWolNqAUDdk3EJvW2ucGwt5b8QMbl2imv2+Bgk8HFA0wFY78JCRdgG4yB1jM3dA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597620; c=relaxed/simple; bh=/GrueF4/4VzX9HvePqDLJQotf6MibkUeriiIghERhAc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=pB9UDGm4yJ2S9cz+Q+r2IkKMpsf6Vik6RT1FKzwcTgKBuQUS7TFPHLrCllvX0qguyUMACVNxV8HoLtdMGBpc/qUHYMu7dImzSd3OiusAMTjHTXwGKLMvMnjspmgAXNhhjE65UbTgfSu+q+MXj9SQAyN4MwLgNB2hBLXrIrWa3i8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=K76Kca1r; arc=none smtp.client-ip=209.85.214.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="K76Kca1r" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-2363bb41664so2127535ad.0 for ; Tue, 10 Jun 2025 16:20:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1749597618; x=1750202418; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=ZD2zb4VRV90wfolGMekjxO+vJFvmvxscHZ+rJPfgPeU=; b=K76Kca1ra+uwmpJYsFEENYhCcz0NowI7WZWMtLeP68sthCz36eTL2Vgsw3HB1NsutB uHfFWL2j/iL5k2lDRHl1/0Mb4S6hKpXZ4jBOrK50M8rvQCsqobZ454lg2FlJ0VN0A1Bv im4hdfnoTIkoM1JqcOlany/47RZK/TVCmhI/pj7aX/yQ3/QHfsuexjFBHOd1Iic+hT15 JbrdEGc6siY+8vAjxHVLuzmb2+HGMpO46DLbO9keXzZ7Zrm7SQJiqK4+z0adAGGVQYXC wa7AhNVGaH1Z1bGFmIzRstf5DugNg1PKsc9I5VAfaZaV2AlPKKa1tee9yfCkYZsESuob jBcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749597618; x=1750202418; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=ZD2zb4VRV90wfolGMekjxO+vJFvmvxscHZ+rJPfgPeU=; b=dKdG4KGMI3Xntn6ikbepuAn19FKfGVjj0HyOPIaIAO1soXzeXQXKB8ZW8h5SCay11G YcyhLwd+pCWA+PeVAH2YwRTtsrikfAMadQSeCac4IPT8LxqK1JIB/Mkd3aPjr7Et2pN0 Gq/aXddagLQwzpSzMxyCTRo8iIFOdYP/gGQXtG9BbbR50sp53fBKtZ67Sv3LPrR/V/ij 1XMpvJbWzSNrBhlkQyrW24UfTB/wMQGDKDMY/T6tx0qQ04be9P7ssPLTezrTuKa6Domv C+uRNUGY6/0Wd2c0VnA8oF6O+7DfsceHXixOYqGHzzNydVo92/kt+49HdXFadigywnNn STkQ== X-Forwarded-Encrypted: i=1; AJvYcCW0MseqSkJgDNaonchhTPWB9+vXYoM5I8mL/oVTLxb6tBy7nhIWSezqJihHmC/MGI2uc7lPQkSvldUMNU4=@vger.kernel.org X-Gm-Message-State: AOJu0Yz0iMWW7iJHKz5MCqsamFkWo24SfkGnG+PE1hMXMCsuq1Ype8IL 1o43RmRIQACjf4dhdRT72ecfmWJ+e1J4QG/6RfjPtfYqw9YKVbOAbgHnZi3Br8BxZ8xpk2ErxX6 hQSlk1A== X-Google-Smtp-Source: AGHT+IEaqCAdZAzPWEw+OpJegnHgNVKOWzrYf9ueLpyQqeg013/p+WjHffoVHQu35bujuPyEWye3Pd4Ouvw= X-Received: from pjbos11.prod.google.com ([2002:a17:90b:1ccb:b0:311:4201:4021]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:948:b0:234:5ea1:6041 with SMTP id d9443c01a7336-236416ba5f4mr16534565ad.10.1749597618154; Tue, 10 Jun 2025 16:20:18 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 10 Jun 2025 16:20:05 -0700 In-Reply-To: <20250610232010.162191-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250610232010.162191-1-seanjc@google.com> X-Mailer: git-send-email 2.50.0.rc0.642.g800a2b2222-goog Message-ID: <20250610232010.162191-4-seanjc@google.com> Subject: [PATCH v6 3/8] KVM: x86: Drop kvm_x86_ops.set_dr6() in favor of a new KVM_RUN flag From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Adrian Hunter , Maxim Levitsky Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Instruct vendor code to load the guest's DR6 into hardware via a new KVM_RUN flag, and remove kvm_x86_ops.set_dr6(), whose sole purpose was to load vcpu->arch.dr6 into hardware when DR6 can be read/written directly by the guest. Note, TDX already WARNs on any run_flag being set, i.e. will yell if KVM thinks DR6 needs to be reloaded. TDX vCPUs force KVM_DEBUGREG_AUTO_SWITCH and never clear the flag, i.e. should never observe KVM_RUN_LOAD_GUEST_DR6. Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson --- arch/x86/include/asm/kvm-x86-ops.h | 1 - arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/svm/svm.c | 10 ++++++---- arch/x86/kvm/vmx/main.c | 9 --------- arch/x86/kvm/vmx/vmx.c | 9 +++------ arch/x86/kvm/x86.c | 2 +- 6 files changed, 11 insertions(+), 22 deletions(-) diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-= x86-ops.h index 8d50e3e0a19b..9e0c37ea267e 100644 --- a/arch/x86/include/asm/kvm-x86-ops.h +++ b/arch/x86/include/asm/kvm-x86-ops.h @@ -49,7 +49,6 @@ KVM_X86_OP(set_idt) KVM_X86_OP(get_gdt) KVM_X86_OP(set_gdt) KVM_X86_OP(sync_dirty_debug_regs) -KVM_X86_OP(set_dr6) KVM_X86_OP(set_dr7) KVM_X86_OP(cache_reg) KVM_X86_OP(get_rflags) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 3b5871ebd7e4..3d6325369a4b 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1675,6 +1675,7 @@ static inline u16 kvm_lapic_irq_dest_mode(bool dest_m= ode_logical) =20 enum kvm_x86_run_flags { KVM_RUN_FORCE_IMMEDIATE_EXIT =3D BIT(0), + KVM_RUN_LOAD_GUEST_DR6 =3D BIT(1), }; =20 struct kvm_x86_ops { @@ -1727,7 +1728,6 @@ struct kvm_x86_ops { void (*get_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); void (*set_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); void (*sync_dirty_debug_regs)(struct kvm_vcpu *vcpu); - void (*set_dr6)(struct kvm_vcpu *vcpu, unsigned long value); void (*set_dr7)(struct kvm_vcpu *vcpu, unsigned long value); void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); unsigned long (*get_rflags)(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 00d78090de3d..171e5be16802 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4451,10 +4451,13 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kv= m_vcpu *vcpu, u64 run_flags) svm_hv_update_vp_id(svm->vmcb, vcpu); =20 /* - * Run with all-zero DR6 unless needed, so that we can get the exact cause - * of a #DB. + * Run with all-zero DR6 unless the guest can write DR6 freely, so that + * KVM can get the exact cause of a #DB. Note, loading guest DR6 from + * KVM's snapshot is only necessary when DR accesses won't exit. */ - if (likely(!(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT))) + if (unlikely(run_flags & KVM_RUN_LOAD_GUEST_DR6)) + svm_set_dr6(vcpu, vcpu->arch.dr6); + else if (likely(!(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT))) svm_set_dr6(vcpu, DR6_ACTIVE_LOW); =20 clgi(); @@ -5265,7 +5268,6 @@ static struct kvm_x86_ops svm_x86_ops __initdata =3D { .set_idt =3D svm_set_idt, .get_gdt =3D svm_get_gdt, .set_gdt =3D svm_set_gdt, - .set_dr6 =3D svm_set_dr6, .set_dr7 =3D svm_set_dr7, .sync_dirty_debug_regs =3D svm_sync_dirty_debug_regs, .cache_reg =3D svm_cache_reg, diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c index fef3e3803707..c85cbce6d2f6 100644 --- a/arch/x86/kvm/vmx/main.c +++ b/arch/x86/kvm/vmx/main.c @@ -489,14 +489,6 @@ static void vt_set_gdt(struct kvm_vcpu *vcpu, struct d= esc_ptr *dt) vmx_set_gdt(vcpu, dt); } =20 -static void vt_set_dr6(struct kvm_vcpu *vcpu, unsigned long val) -{ - if (is_td_vcpu(vcpu)) - return; - - vmx_set_dr6(vcpu, val); -} - static void vt_set_dr7(struct kvm_vcpu *vcpu, unsigned long val) { if (is_td_vcpu(vcpu)) @@ -943,7 +935,6 @@ struct kvm_x86_ops vt_x86_ops __initdata =3D { .set_idt =3D vt_op(set_idt), .get_gdt =3D vt_op(get_gdt), .set_gdt =3D vt_op(set_gdt), - .set_dr6 =3D vt_op(set_dr6), .set_dr7 =3D vt_op(set_dr7), .sync_dirty_debug_regs =3D vt_op(sync_dirty_debug_regs), .cache_reg =3D vt_op(cache_reg), diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index e66f5ffa8716..49bf58ca9ffd 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -5604,12 +5604,6 @@ void vmx_sync_dirty_debug_regs(struct kvm_vcpu *vcpu) set_debugreg(DR6_RESERVED, 6); } =20 -void vmx_set_dr6(struct kvm_vcpu *vcpu, unsigned long val) -{ - lockdep_assert_irqs_disabled(); - set_debugreg(vcpu->arch.dr6, 6); -} - void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val) { vmcs_writel(GUEST_DR7, val); @@ -7364,6 +7358,9 @@ fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, u64 ru= n_flags) vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]); vcpu->arch.regs_dirty =3D 0; =20 + if (run_flags & KVM_RUN_LOAD_GUEST_DR6) + set_debugreg(vcpu->arch.dr6, 6); + /* * 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/x86.c b/arch/x86/kvm/x86.c index d4a51b263d6b..6742eb556d91 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -11046,7 +11046,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) set_debugreg(vcpu->arch.eff_db[3], 3); /* When KVM_DEBUGREG_WONT_EXIT, dr6 is accessible in guest. */ if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) - kvm_x86_call(set_dr6)(vcpu, vcpu->arch.dr6); + run_flags |=3D KVM_RUN_LOAD_GUEST_DR6; } else if (unlikely(hw_breakpoint_active())) { set_debugreg(0, 7); } --=20 2.50.0.rc0.642.g800a2b2222-goog From nobody Sat Oct 11 08:27:39 2025 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6C40A28BAA1 for ; Tue, 10 Jun 2025 23:20:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597621; cv=none; b=bLOmyWPXsiaYHqjq9CBCX9LdscCGY/zjM7W/9s6xDgVNSphavLcUvNruLpQZT0rAk/1hYFIhOhVcI88JgzfimGsaMMgD6uoF9qJ6nG4CwdXsZvb4aTFr9i0NWJBPtBZYrPibaVjScN1aJrp49jDV/FsCVejRvh4NLBy1EdKpcUs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597621; c=relaxed/simple; bh=lXPkeIDdbhFAfpOJJ2C/Lh95pW+2tzzpPk+8BOhZXcs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=IkMpPsw/S6MII6nJ+u1A8oUWlUWsOn9lri0VL0sz3QiljQT+uiZQvvYsoWSn9zll3QwOZYXfY+zjokEWEBpWDAgVxqKtp6XPeF4hh2l1QpOW62NWkeCiHFfbHt+kI3PzSbCregEekX0VCu8i+MX8NELg6acLQQxLVOc0BnLwskI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Hen0PwyX; arc=none smtp.client-ip=209.85.216.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Hen0PwyX" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-31215090074so8278378a91.0 for ; Tue, 10 Jun 2025 16:20:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1749597620; x=1750202420; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=/+XzMzGMwW1mTSC7isLrm0UkjItZs/9XrzbKK280m3s=; b=Hen0PwyXf8bK84Em2C0TUTEpevtA44Byd/WHtHXgRzDfXcYqOMVto35W7Peeko5rd5 IO0In1fzwBC/aQDBZBz9HKeGI7UnHBNJdNm7Lq0ImvpLgL8AJLMBJ7fLES4oWhFz9oRM yR9ToBy+FIiR4UdjkWUjhB7Lch56BPvPWgGIHBnAuZmwgjY6svQPRndKsisfN1nE1vMI irrv+jfKxeyJWC4oDgIZ2cYPiK45ZtsONLZuvs7jk8TZGkDNbRI118Fpsu27Euey5C/e iAiGlvLwJlZ4e0PYleeJQiWUO4lPK0+2zpieB5DF+27funxNydN0vk3O8mHQ/1/TSYHd DTRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749597620; x=1750202420; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=/+XzMzGMwW1mTSC7isLrm0UkjItZs/9XrzbKK280m3s=; b=clmNzhPCRqgsQ4SgordPVTI+817ZXmeHI2cvJ4wM8aFanSuTX5MUvv5VaMJU9GF75N 9SpF7sTF8MGo/RZgmtd3cUvVlR3Hte0E52httFrPvP7dihCA6nfY53S8Ju5MJ6BoYkKV vJT0E20EM5B7hg95T0OO9mZx/+hvlncraLeXRSoul5vbKfcSriM1zyYiB50BVcYXeCuP Bl6mYtbw9zOxSVAr2kIC8h2tMVmu6VwE0zIq8jFrlUGAGN8TGFxfDBap1CHYcaj59wvF CZB2xXuNFuK44UxpyAeuQkLXTmNQhWmus52FQAyfgF6v6esa2e0h2eLKk2Eo9Yr8vkFK i/oA== X-Forwarded-Encrypted: i=1; AJvYcCWVieZ5Ny1ifhIodvCTztkfxjBqLKgiz3sytOFveLHwHdBG+BkN2DTCQ2H0EQAFK319PkpzBEJP7zCkQzA=@vger.kernel.org X-Gm-Message-State: AOJu0YxfkjQQ/aRYG7dYUzkVATPY+ScNI7HTHB3jgLblKn9b4f+Xg4Ja 78lJEzHHeNyiFNk5BUcNdlcwyj3OkPxTgEzz+3vxJbNxuWYKVniGybIN7J5eatIF7BseBPCc5qn euxp+xA== X-Google-Smtp-Source: AGHT+IGjBSpF+t9nRnBE2yjDswB3i2/tgdFb8nESgCpkvF6L+lDEma6Rbjm27J6NcdvQSxbgv2QO3ChvtY4= X-Received: from pjk13.prod.google.com ([2002:a17:90b:558d:b0:311:b3fb:9f74]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:53cf:b0:311:df4b:4b91 with SMTP id 98e67ed59e1d1-313af14a46emr1906302a91.7.1749597619931; Tue, 10 Jun 2025 16:20:19 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 10 Jun 2025 16:20:06 -0700 In-Reply-To: <20250610232010.162191-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250610232010.162191-1-seanjc@google.com> X-Mailer: git-send-email 2.50.0.rc0.642.g800a2b2222-goog Message-ID: <20250610232010.162191-5-seanjc@google.com> Subject: [PATCH v6 4/8] KVM: VMX: Allow guest to set DEBUGCTL.RTM_DEBUG if RTM is supported From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Adrian Hunter , Maxim Levitsky Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Let the guest set DEBUGCTL.RTM_DEBUG if RTM is supported according to the guest CPUID model, as debug support is supposed to be available if RTM is supported, and there are no known downsides to letting the guest debug RTM aborts. Note, there are no known bug reports related to RTM_DEBUG, the primary motivation is to reduce the probability of breaking existing guests when a future change adds a missing consistency check on vmcs12.GUEST_DEBUGCTL (KVM currently lets L2 run with whatever hardware supports; whoops). Note #2, KVM already emulates DR6.RTM, and doesn't restrict access to DR7.RTM. Fixes: 83c529151ab0 ("KVM: x86: expose Intel cpu new features (HLE, RTM) to= guest") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson --- arch/x86/include/asm/msr-index.h | 1 + arch/x86/kvm/vmx/vmx.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-in= dex.h index e7d2f460fcc6..1229396a059f 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -419,6 +419,7 @@ #define DEBUGCTLMSR_FREEZE_PERFMON_ON_PMI (1UL << 12) #define DEBUGCTLMSR_FREEZE_IN_SMM_BIT 14 #define DEBUGCTLMSR_FREEZE_IN_SMM (1UL << DEBUGCTLMSR_FREEZE_IN_SMM_BIT) +#define DEBUGCTLMSR_RTM_DEBUG BIT(15) =20 #define MSR_PEBS_FRONTEND 0x000003f7 =20 diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 49bf58ca9ffd..ab5c742db140 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2184,6 +2184,10 @@ static u64 vmx_get_supported_debugctl(struct kvm_vcp= u *vcpu, bool host_initiated (host_initiated || intel_pmu_lbr_is_enabled(vcpu))) debugctl |=3D DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI; =20 + if (boot_cpu_has(X86_FEATURE_RTM) && + (host_initiated || guest_cpu_cap_has(vcpu, X86_FEATURE_RTM))) + debugctl |=3D DEBUGCTLMSR_RTM_DEBUG; + return debugctl; } =20 --=20 2.50.0.rc0.642.g800a2b2222-goog From nobody Sat Oct 11 08:27:39 2025 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C740296177 for ; Tue, 10 Jun 2025 23:20:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597623; cv=none; b=NZH6VQI49Q9dnBouKGfQMZAD7T19gZqYJCl7i8QtpCthq9S/UNE32Q54lMupeOYJcPh+TmsX8H7ccgZxfyE4r7rIwrv688vXl8x0Qo7JsEqfNeJEsDeMSapetUxg5DGXrFluOqzh8CxC6I22nWnVEaPdVORsM/cCYyuBvdOEV5o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597623; c=relaxed/simple; bh=d6ch4wFyzgD/snzZgnO2eV+6ES7j1OumzJhm7QshG3Q=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Y8Fm2ITNZEHAWBDd2ElQmJtIMfShwLEddCmxm8F+lYV3alh6u1umo64iHuc1Mri3ff4YzNKW09yZcOy41ljO1KNcXgzSqhWCF4qEscWGEch5PTxr6EWkpAIEix8y+0Z8aGrA4jxBxteA9f2xoAsC2XLwe0RwM4EEXQgqCWb/KBg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Sd6763k8; arc=none smtp.client-ip=209.85.215.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Sd6763k8" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-af59547f55bso3303177a12.0 for ; Tue, 10 Jun 2025 16:20:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1749597621; x=1750202421; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=HHsuZnF4V8CqTjAQoLQV6ObUx/gLCkMj4Na53qEjTK8=; b=Sd6763k879hkqyUR5tOqLpcJAAa1leLxkbn91nPI31pl2AviKwUift7cMnEppxNLT2 mNcxWOCLtZvkVZGCn5RDSVU03uLn3kviTepROplSNu8LbuG6qSUeoIwQcSko+F7B5+vP KC1D5DQKew0hAfoiXwGj55rBNirIjODeKgmABWvsBxjDMVlZUqznNoonCjSPrwI5buM8 dskmcnObbJPI0w2gFScSDk3tX9BAUKEkfSKKZx36+dpw5IBDFd0tZIZXv+SGwncRzrbx JUVAKPe916vUidiPcM8MvqDX2BKYdOWdP3R1yEikgHNUOFk2JW3B1Tzd/HJS4QQ6BUM5 9SCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749597621; x=1750202421; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=HHsuZnF4V8CqTjAQoLQV6ObUx/gLCkMj4Na53qEjTK8=; b=Yg6Yz2VjVb91TFXs9btA3VtIvagLKJ9Hx2VInKnbz9eSzbAWaMVdEdV0RUX2JSrpX7 ftjHUAy93ojKqRPYX3aMxMTQR9f8g+CDa7CgyGqtaVDGsNFU1JAL3Qxi5nSBN2oEuqSR RwF0pbxn/riPfNzHCO6alx6CgTUNV2LtzMF42F7r5JQIjMmziTb76p+HqTcYl+YIHiPA MMl/e6h7I4eZrqRq8bsw1+bmQYGXu0U04uDeMwiGcJDjW67rPBsBXFQkdgoCbf5/imfu IfBthi8DHYWIT1Eo0RjTYWIw5oKecP0U03Qd5+TcGP+woYCqH4UMWyGC9Z2lLEOIMnJF Kt7Q== X-Forwarded-Encrypted: i=1; AJvYcCUuAf4tZ3c2JBYtJt/utFSlD1SJ98g3nZNkpfgdkYrEvIKiBCxlFKpnqpOdHhcb6/T/b15IVCS6TWpNQOY=@vger.kernel.org X-Gm-Message-State: AOJu0Yxm7nFs+4qW2Y+QCkNpGvFQR3JBdQBmpzSHWGJVcWHXggFKgJn5 nouuj59cPFsADyLgk3kXMzqL0X/QeC0VxKXU7TA00Tzlv7GwYLvHq2FA6I5AJ7aY7E0r9WM2Ftf tzDTfcw== X-Google-Smtp-Source: AGHT+IE421/JEGwRo8d9Ea0QC6Ps3NvN/Iwm9+D8SNEcgSRCuj3kTU86U0uXrHJRxcs4U5fyl1urJM88xFg= X-Received: from plbmt8.prod.google.com ([2002:a17:903:b08:b0:235:c96e:dd92]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:d4cc:b0:234:f4da:7eed with SMTP id d9443c01a7336-236426b5630mr8666335ad.44.1749597621540; Tue, 10 Jun 2025 16:20:21 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 10 Jun 2025 16:20:07 -0700 In-Reply-To: <20250610232010.162191-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250610232010.162191-1-seanjc@google.com> X-Mailer: git-send-email 2.50.0.rc0.642.g800a2b2222-goog Message-ID: <20250610232010.162191-6-seanjc@google.com> Subject: [PATCH v6 5/8] KVM: VMX: Extract checking of guest's DEBUGCTL into helper From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Adrian Hunter , Maxim Levitsky Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move VMX's logic to check DEBUGCTL values into a standalone helper so that the code can be used by nested VM-Enter to apply the same logic to the value being loaded from vmcs12. KVM needs to explicitly check vmcs12->guest_ia32_debugctl on nested VM-Enter, as hardware may support features that KVM does not, i.e. relying on hardware to detect invalid guest state will result in false negatives. Unfortunately, that means applying KVM's funky suppression of BTF and LBR to vmcs12 so as not to break existing guests. No functional change intended. Signed-off-by: Sean Christopherson Reviewed-by: Dapeng Mi --- arch/x86/kvm/vmx/vmx.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index ab5c742db140..358c7036272a 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2191,6 +2191,19 @@ static u64 vmx_get_supported_debugctl(struct kvm_vcp= u *vcpu, bool host_initiated return debugctl; } =20 +static bool vmx_is_valid_debugctl(struct kvm_vcpu *vcpu, u64 data, + bool host_initiated) +{ + u64 invalid; + + invalid =3D data & ~vmx_get_supported_debugctl(vcpu, host_initiated); + if (invalid & (DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR)) { + kvm_pr_unimpl_wrmsr(vcpu, MSR_IA32_DEBUGCTLMSR, data); + invalid &=3D ~(DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR); + } + return !invalid; +} + /* * Writes msr value into the appropriate "register". * Returns 0 on success, non-0 otherwise. @@ -2259,19 +2272,12 @@ int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_d= ata *msr_info) } vmcs_writel(GUEST_SYSENTER_ESP, data); break; - case MSR_IA32_DEBUGCTLMSR: { - u64 invalid; - - invalid =3D data & ~vmx_get_supported_debugctl(vcpu, msr_info->host_init= iated); - if (invalid & (DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR)) { - kvm_pr_unimpl_wrmsr(vcpu, msr_index, data); - data &=3D ~(DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR); - invalid &=3D ~(DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR); - } - - if (invalid) + case MSR_IA32_DEBUGCTLMSR: + if (!vmx_is_valid_debugctl(vcpu, data, msr_info->host_initiated)) return 1; =20 + data &=3D vmx_get_supported_debugctl(vcpu, msr_info->host_initiated); + if (is_guest_mode(vcpu) && get_vmcs12(vcpu)->vm_exit_controls & VM_EXIT_SAVE_DEBUG_CONTROLS) get_vmcs12(vcpu)->guest_ia32_debugctl =3D data; @@ -2281,7 +2287,6 @@ int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_dat= a *msr_info) (data & DEBUGCTLMSR_LBR)) intel_pmu_create_guest_lbr_event(vcpu); return 0; - } case MSR_IA32_BNDCFGS: if (!kvm_mpx_supported() || (!msr_info->host_initiated && --=20 2.50.0.rc0.642.g800a2b2222-goog From nobody Sat Oct 11 08:27:39 2025 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 958D0283FD7 for ; Tue, 10 Jun 2025 23:20:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597625; cv=none; b=ETTtisy43rLgEW0f78wWYjyhMsftZ+zHw5EjxJPW+wMrFco2RqXeOPFQhOtzfKR0CIb3yp+193RHIAmT1yd47Vo7ondOG9mowptPGwDpnTOmm7Ddu+VPry29G68nl1BeOgrBwsMQn2/7ZG+OsBw+jWHGOXUPAQMAFiTU0EHdjG4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597625; c=relaxed/simple; bh=blKNi5/eVsDYzPDTuqtVcEpW6PWWX74NKc4L5DVUPJY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=nZoOjyb3eRR/Ey7rERgE3ylN7k5PgGdtUlEpsmqWVx8oTWIPgo6vjuJRaGZvtmSvZE52IJvjSpdcRS7vMLYQ4BdoMtASTw+KkXLJwvu5Rl9KRhaZuNkFNy6g6CwyCHP5exorTDnougSJDA6ZNdLwOQK42pq/WqH8RZSPg/WkAl8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=4JqQAo08; arc=none smtp.client-ip=209.85.216.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="4JqQAo08" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-31332dc2b59so5387074a91.0 for ; Tue, 10 Jun 2025 16:20:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1749597623; x=1750202423; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=wZCT8jtEOBxZLskW7DzyAfTB5wFIiDwQQWq62UPKKVg=; b=4JqQAo08u2hGRcks6/x6B/sQVj9InjeEo5HPxxFuvOxhgiifG1EXoWlomv9wa4Znex c7ui/WqWvhGP0eRvMDWYhETKUbyh8EokMfEzqk8dLHBjkOvJzfWw7YXwheUhOX6vRvXh uW77tBl//24PB0VVtuEKcu2kYZmWHTMxVpgRocjjni9OR32QY6ts73OiPqbucc6ty/Tq NgurfzcWM94dCN/pAKOV5FwS4mNNnQaR1pnFUreyZYL2KTUD7VamlDMzuZmdwU0zuiCh YdtfaabzywpxOhNZYOZEbxzsLTp45rVtaWpaqOwvhWfLTbgAZrnIi58yOWwvLTEkA2EI rJQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749597623; x=1750202423; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=wZCT8jtEOBxZLskW7DzyAfTB5wFIiDwQQWq62UPKKVg=; b=YNyx3ELEDmiiaxxg1MbkoKDXBHNHi/96K0U77rSaN9EJq5aaGMzSw/p2YIwFpqGzhe EXjiO80vdA5otOBk2g5TH6lkk/AhjLjPro3VTBRuT+3XPOS/xO56W+rQ/iTaAoehFGBl SbL6zuVWaf1J43p5/9YAlVb7dENoiV0GLnIi255UVbQEVjqQcL8Btaz2MzV4mVSoyZxw fC1Atvkmk5+bai8S9dItsLs7Mq9fMRKlvsTMw576CjH9mkP311io791g4MrgBR2LT3Kp eZQh1oWzgLHJxMxdMECoJZY2gb+gfTRCHX1y3GAOPwf3DEFSogJG7sWyzhFQMzHwMCgM gmSQ== X-Forwarded-Encrypted: i=1; AJvYcCUvYINQ6R9/r/641e2mt/k+jcPNMd9EwnL/r3WNyFFme+UcdorE1n05exFULzVCviu3wzQqZ2OPawiPrAU=@vger.kernel.org X-Gm-Message-State: AOJu0YwGlIA3boekNu1DfTKjfaY96PpxLsbGSbgTJtIO5mqds0lvymZl Gfv0VsE4r22q8Sl9trT7yHLXF4sla49F/1J51aCeCur0rktj/9ZquzvXZBj1+rLKkUuVAQ7zz0b yP9LTRw== X-Google-Smtp-Source: AGHT+IEL/2DWvsmanYGnlyH/VBJzsS50gjIHQSz73qDhYyQ6YVFD4WjKbq6DoY3OuDN2ZWC6VE6hOcH0qFI= X-Received: from pjbpx2.prod.google.com ([2002:a17:90b:2702:b0:313:230:89ed]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:4d07:b0:311:c970:c9bc with SMTP id 98e67ed59e1d1-313af21d9bfmr1797129a91.30.1749597623152; Tue, 10 Jun 2025 16:20:23 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 10 Jun 2025 16:20:08 -0700 In-Reply-To: <20250610232010.162191-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250610232010.162191-1-seanjc@google.com> X-Mailer: git-send-email 2.50.0.rc0.642.g800a2b2222-goog Message-ID: <20250610232010.162191-7-seanjc@google.com> Subject: [PATCH v6 6/8] KVM: nVMX: Check vmcs12->guest_ia32_debugctl on nested VM-Enter From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Adrian Hunter , Maxim Levitsky Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maxim Levitsky Add a consistency check for L2's guest_ia32_debugctl, as KVM only supports a subset of hardware functionality, i.e. KVM can't rely on hardware to detect illegal/unsupported values. Failure to check the vmcs12 value would allow the guest to load any harware-supported value while running L2. Take care to exempt BTF and LBR from the validity check in order to match KVM's behavior for writes via WRMSR, but without clobbering vmcs12. Even if VM_EXIT_SAVE_DEBUG_CONTROLS is set in vmcs12, L1 can reasonably expect that vmcs12->guest_ia32_debugctl will not be modified if writes to the MSR are being intercepted. Arguably, KVM _should_ update vmcs12 if VM_EXIT_SAVE_DEBUG_CONTROLS is set *and* writes to MSR_IA32_DEBUGCTLMSR are not being intercepted by L1, but that would incur non-trivial complexity and wouldn't change the fact that KVM's handling of DEBUGCTL is blatantly broken. I.e. the extra complexity is not worth carrying. Cc: stable@vger.kernel.org Signed-off-by: Maxim Levitsky Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson --- arch/x86/kvm/vmx/nested.c | 12 ++++++++++-- arch/x86/kvm/vmx/vmx.c | 5 ++--- arch/x86/kvm/vmx/vmx.h | 3 +++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index b50f9c894ab8..5a6c636954eb 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2662,7 +2662,8 @@ 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); + vmcs_write64(GUEST_IA32_DEBUGCTL, vmcs12->guest_ia32_debugctl & + vmx_get_supported_debugctl(vcpu, false)); } else { kvm_set_dr(vcpu, 7, vcpu->arch.dr7); vmcs_write64(GUEST_IA32_DEBUGCTL, vmx->nested.pre_vmenter_debugctl); @@ -3155,7 +3156,8 @@ static int nested_vmx_check_guest_state(struct kvm_vc= pu *vcpu, return -EINVAL; =20 if ((vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS) && - CC(!kvm_dr7_valid(vmcs12->guest_dr7))) + (CC(!kvm_dr7_valid(vmcs12->guest_dr7)) || + CC(!vmx_is_valid_debugctl(vcpu, vmcs12->guest_ia32_debugctl, false))= )) return -EINVAL; =20 if ((vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PAT) && @@ -4607,6 +4609,12 @@ static void sync_vmcs02_to_vmcs12(struct kvm_vcpu *v= cpu, struct vmcs12 *vmcs12) (vmcs12->vm_entry_controls & ~VM_ENTRY_IA32E_MODE) | (vm_entry_controls_get(to_vmx(vcpu)) & VM_ENTRY_IA32E_MODE); =20 + /* + * Note! Save DR7, but intentionally don't grab DEBUGCTL from vmcs02. + * Writes to DEBUGCTL that aren't intercepted by L1 are immediately + * propagated to vmcs12 (see vmx_set_msr()), as the value loaded into + * vmcs02 doesn't strictly track vmcs12. + */ if (vmcs12->vm_exit_controls & VM_EXIT_SAVE_DEBUG_CONTROLS) vmcs12->guest_dr7 =3D vcpu->arch.dr7; =20 diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 358c7036272a..b685e43de4e9 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2172,7 +2172,7 @@ static u64 nested_vmx_truncate_sysenter_addr(struct k= vm_vcpu *vcpu, return (unsigned long)data; } =20 -static u64 vmx_get_supported_debugctl(struct kvm_vcpu *vcpu, bool host_ini= tiated) +u64 vmx_get_supported_debugctl(struct kvm_vcpu *vcpu, bool host_initiated) { u64 debugctl =3D 0; =20 @@ -2191,8 +2191,7 @@ static u64 vmx_get_supported_debugctl(struct kvm_vcpu= *vcpu, bool host_initiated return debugctl; } =20 -static bool vmx_is_valid_debugctl(struct kvm_vcpu *vcpu, u64 data, - bool host_initiated) +bool vmx_is_valid_debugctl(struct kvm_vcpu *vcpu, u64 data, bool host_init= iated) { u64 invalid; =20 diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index b5758c33c60f..392e66c7e5fe 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -414,6 +414,9 @@ 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); =20 +u64 vmx_get_supported_debugctl(struct kvm_vcpu *vcpu, bool host_initiated); +bool vmx_is_valid_debugctl(struct kvm_vcpu *vcpu, u64 data, bool host_init= iated); + /* * Note, early Intel manuals have the write-low and read-high bitmap offse= ts * the wrong way round. The bitmaps control MSRs 0x00000000-0x00001fff and --=20 2.50.0.rc0.642.g800a2b2222-goog From nobody Sat Oct 11 08:27:39 2025 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 73AFF286D62 for ; Tue, 10 Jun 2025 23:20:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597627; cv=none; b=BTu1KK/mPAVRmv2fQs1JNf3HcC90G+VP5OhHHf/5mzQdQwdttNTcuy32Y9iE8Ig2rxatQW0GI8Q8XVY5y7doyY05uY8C5Jn2AViaAiPTGQ+Kv+CI++Wshub1Ahbj4sLXMnszcG/elYt/C4JBDOoSYgsbA6HjCyEHqDLHEw4C+no= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597627; c=relaxed/simple; bh=GNOyxW1SytwEj4+h3gEIfqwnB6VMjLWxhbQovCAzrec=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Ku32bqPUOyERcMuB6d/S2e2/GIbHE37uqrDiJQk+TcfIOJJMMpZYrwTUhA4V97y5Zpg5p+oA/QIYvCyrcHZMwjfdKsAK09kz7P5AhSrZVmaIKWi8JqLi1y6vZ6OgOyE1TcwXIHE79Eoayo3Ox9GXhVwLI4c1E0JUQy9ahPo9XKU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=npC1CXB5; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="npC1CXB5" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-b1442e039eeso3760380a12.0 for ; Tue, 10 Jun 2025 16:20:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1749597625; x=1750202425; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=KQ/8WZhuTg5FjxxTRupMp19TYSftGyyuU4wfKee6pEQ=; b=npC1CXB5hwFC3VJxC1RWTSmnivB/w7Zrl5TZdHDeJbV+O4xzL+UrI5rqqKdWucW/q2 KzHSXVothtVml6ynpxmrx/hK0T9F38UNd+qNfbvAziTz/HrZCq3tpSDwnHfGrCnawpZU R8fyr9M6GDl+taICbcYpCovkRvAFTAqSoEiukUlvkk4GWUc6LkGsv/pOcga2FcJ3mzsQ 0IHjvH80iMKk/OzW7HIG7aNLaz61TPe3GxxClvRu3jI7wNJQgPVF9GWSTz+/5ClmxpxY GIFg+FLPALDnvc7o3oJ+G6Of/GNnEkUzOLiUBQ6lVYY/blDW7aVIzpE6TAd3a6HB0pVe Worg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749597625; x=1750202425; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=KQ/8WZhuTg5FjxxTRupMp19TYSftGyyuU4wfKee6pEQ=; b=vBfpM0oupxtv5/ipLIwJm3MDVjo29CZ1K301+6nB9S9Wjnv0+stgiz5CPxco6XvLPB Lfdd+DZgJdRcx7BoiqYqr2L7nQs/O8MBQc/Oiddi3X8lWSyhH9chrJ3trn0aghSP17ut kCbKzAb01OQsPrf6l6sjP6sPUF9gdGRuYVF6oCcu1GEXltnRVu3x5QC9iIhFhYvLFlfw y1Qr9OH8W5T14Gm0+1XCW0lkJ/fMHi5FYxtmBTLPIEX8YIoCCBvDhP5SYesXEQej+UnQ 7sjLJgp3/SiV4B6mUPI4ojPxQfzK/1sWMNsIHwqdm/tO7plFzHo8lpHyiSkYYZTQcQ6X LW4Q== X-Forwarded-Encrypted: i=1; AJvYcCURrYZYtMgL8SBSz2UGVDKFGZWNRcRXLTjgfRuPB1cTErYm8ctOba8agldolC5g2kLvZ9eZfdnrcbqXCCw=@vger.kernel.org X-Gm-Message-State: AOJu0Yw1RUnPQwcvIP+BoxIweWQloAy3YD2XSMd93V6ifcSd+tQN4HSL aanaiPVWhSE8sl5oF1wPksMrOnkDpy4HrMTa02g6MPBoVjtzdegC/huznAssxjrMKlK6yVxbHzn Ue7IB2Q== X-Google-Smtp-Source: AGHT+IGbj0+cctzd4GKSNL5dVe1ppyWvyLHGggIYnZ8TsVYDtCUXRFBhMN0AlDspipvVcnIAana36HT7Yxg= X-Received: from pjbsk1.prod.google.com ([2002:a17:90b:2dc1:b0:308:6685:55e6]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:1c8d:b0:312:dbcd:b931 with SMTP id 98e67ed59e1d1-313af21ce8emr1953802a91.18.1749597624800; Tue, 10 Jun 2025 16:20:24 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 10 Jun 2025 16:20:09 -0700 In-Reply-To: <20250610232010.162191-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250610232010.162191-1-seanjc@google.com> X-Mailer: git-send-email 2.50.0.rc0.642.g800a2b2222-goog Message-ID: <20250610232010.162191-8-seanjc@google.com> Subject: [PATCH v6 7/8] KVM: VMX: Wrap all accesses to IA32_DEBUGCTL with getter/setter APIs From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Adrian Hunter , Maxim Levitsky Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maxim Levitsky Introduce vmx_guest_debugctl_{read,write}() to handle all accesses to vmcs.GUEST_IA32_DEBUGCTL. This will allow stuffing FREEZE_IN_SMM into GUEST_IA32_DEBUGCTL based on the host setting without bleeding the state into the guest, and without needing to copy+paste the FREEZE_IN_SMM logic into every patch that accesses GUEST_IA32_DEBUGCTL. No functional change intended. Cc: stable@vger.kernel.org Signed-off-by: Maxim Levitsky [sean: massage changelog, make inline, use in all prepare_vmcs02() cases] Signed-off-by: Sean Christopherson Reviewed-by: Dapeng Mi --- arch/x86/kvm/vmx/nested.c | 10 +++++----- arch/x86/kvm/vmx/pmu_intel.c | 8 ++++---- arch/x86/kvm/vmx/vmx.c | 8 +++++--- arch/x86/kvm/vmx/vmx.h | 10 ++++++++++ 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 5a6c636954eb..9edce9f411a3 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2662,11 +2662,11 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, st= ruct 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_get_supported_debugctl(vcpu, false)); + vmx_guest_debugctl_write(vcpu, vmcs12->guest_ia32_debugctl & + vmx_get_supported_debugctl(vcpu, false)); } else { kvm_set_dr(vcpu, 7, vcpu->arch.dr7); - vmcs_write64(GUEST_IA32_DEBUGCTL, vmx->nested.pre_vmenter_debugctl); + vmx_guest_debugctl_write(vcpu, vmx->nested.pre_vmenter_debugctl); } if (kvm_mpx_supported() && (!vmx->nested.nested_run_pending || !(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS))) @@ -3531,7 +3531,7 @@ enum nvmx_vmentry_status nested_vmx_enter_non_root_mo= de(struct kvm_vcpu *vcpu, =20 if (!vmx->nested.nested_run_pending || !(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS)) - vmx->nested.pre_vmenter_debugctl =3D vmcs_read64(GUEST_IA32_DEBUGCTL); + vmx->nested.pre_vmenter_debugctl =3D vmx_guest_debugctl_read(); if (kvm_mpx_supported() && (!vmx->nested.nested_run_pending || !(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS))) @@ -4805,7 +4805,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/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index 8a94b52c5731..578b4ef58260 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -652,11 +652,11 @@ static void intel_pmu_reset(struct kvm_vcpu *vcpu) */ static void intel_pmu_legacy_freezing_lbrs_on_pmi(struct kvm_vcpu *vcpu) { - u64 data =3D vmcs_read64(GUEST_IA32_DEBUGCTL); + u64 data =3D vmx_guest_debugctl_read(); =20 if (data & DEBUGCTLMSR_FREEZE_LBRS_ON_PMI) { data &=3D ~DEBUGCTLMSR_LBR; - vmcs_write64(GUEST_IA32_DEBUGCTL, data); + vmx_guest_debugctl_write(vcpu, data); } } =20 @@ -729,7 +729,7 @@ void vmx_passthrough_lbr_msrs(struct kvm_vcpu *vcpu) =20 if (!lbr_desc->event) { vmx_disable_lbr_msrs_passthrough(vcpu); - if (vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR) + if (vmx_guest_debugctl_read() & DEBUGCTLMSR_LBR) goto warn; if (test_bit(INTEL_PMC_IDX_FIXED_VLBR, pmu->pmc_in_use)) goto warn; @@ -751,7 +751,7 @@ void vmx_passthrough_lbr_msrs(struct kvm_vcpu *vcpu) =20 static void intel_pmu_cleanup(struct kvm_vcpu *vcpu) { - if (!(vmcs_read64(GUEST_IA32_DEBUGCTL) & DEBUGCTLMSR_LBR)) + if (!(vmx_guest_debugctl_read() & DEBUGCTLMSR_LBR)) intel_pmu_release_guest_lbr_event(vcpu); } =20 diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index b685e43de4e9..196f33d934d3 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2147,7 +2147,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: @@ -2281,7 +2281,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); @@ -4796,7 +4797,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); diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index 392e66c7e5fe..c20a4185d10a 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -417,6 +417,16 @@ void vmx_update_cpu_dirty_logging(struct kvm_vcpu *vcp= u); u64 vmx_get_supported_debugctl(struct kvm_vcpu *vcpu, bool host_initiated); bool vmx_is_valid_debugctl(struct kvm_vcpu *vcpu, u64 data, bool host_init= iated); =20 +static inline void vmx_guest_debugctl_write(struct kvm_vcpu *vcpu, u64 val) +{ + vmcs_write64(GUEST_IA32_DEBUGCTL, val); +} + +static inline u64 vmx_guest_debugctl_read(void) +{ + return vmcs_read64(GUEST_IA32_DEBUGCTL); +} + /* * Note, early Intel manuals have the write-low and read-high bitmap offse= ts * the wrong way round. The bitmaps control MSRs 0x00000000-0x00001fff and --=20 2.50.0.rc0.642.g800a2b2222-goog From nobody Sat Oct 11 08:27:39 2025 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 300FA2BCF7B for ; Tue, 10 Jun 2025 23:20:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597629; cv=none; b=leFqT2c+Rx4hqb/yFDqUR99oGMB7O2nagPm6PcgbAkZKJX46eEEPTtstowF2maSPgTNbvD3sqFcY3LG2Gs69jPuVSe/EJLIRgiEGsREERdJSkBZIZrEx009UCavsVqgD44IEe1jrw7uXz9jIANMH+yP2SqgPFOI1eUJgrnBpIwk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749597629; c=relaxed/simple; bh=U9TdJ5dnV3lclh4QAIAOWqjQBTJpB4tN7q1ZxPdJyEs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=T5ZIqFkDzwx+t3rCXQFVKwgR0/uWxvLKRLTakvFO/GF7LHVmV8vyplfMqmi8a0UXwvjJJqn23QBuVsappURMIiFuUftdcNljH9B+Rhf84GpUo3OOsr6WRW+KVh0iiq8L1PDy6+xE1eIfzLOUptYNX7Gh1bRZTX3zcE2w4Zk76Eo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=c+RHbD5I; arc=none smtp.client-ip=209.85.216.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="c+RHbD5I" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-30a59538b17so5741999a91.3 for ; Tue, 10 Jun 2025 16:20:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1749597626; x=1750202426; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=dnkynuEbsoZ6x128ufwAbrtOFl8ZXNBXsNIoNBRMd1M=; b=c+RHbD5IYtalgjYyveE/ysaE/RIMkaZg773AT0cUJaFg2fNcBjAU96Ue0hBpRpNRR4 dY6KZAbIjWg0m3w7e1T/6rJiIueL9uhDHh0a/qgj6blwXtFu48gKkM8PE7HOfgDd++b0 SMTf7H+jSuvRldFy19dRqIYhJ8BrEGA6XI+/6mCP5yQffSpQXI+6xWkPBTUfZzjjWeZM beIgTrcGsKnfEUWwfPf9RDYdOn4S9KbK/qJxPKyBeXsAhlSw9myXBK+Hjnh28k6VuR9/ CEXAaW8MiBCjrDBBrmG3CFf6tqAM3ivXO+vYCwl1sdZ07ES+LxO0GZToE7oGDAPk6cue RuuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749597626; x=1750202426; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=dnkynuEbsoZ6x128ufwAbrtOFl8ZXNBXsNIoNBRMd1M=; b=sCbdQpupUy0xsGchHDxbdj8RaN/eK97TiGr3OZEZKytXbbhgl0PNX+HX0lcnlAkocb +LXEga/BOHyv+1BJ4ckJD6RMlfs7H6C4XJ779DZoZdc2mhdQSFERmgU0NjSSuSrLCWwH j6ccFdY8RkpS1YjhCWbjREkfr6kj7gsJO23VPRLzJZd2i4ZBHnNTbUOu0th38FVri9aq 19G5zInYZkuIy6qsJInVSf46NAefLIixUKGplNssXm07KTbkO30IRkGgkoEIrXa6m5o5 O8wPx1mbNrcy9MHaQQFkoeHlhOTKJy48i3Z/SYzkWrckbPS9qIt/mab3nh6p14njzsxZ 60/g== X-Forwarded-Encrypted: i=1; AJvYcCXnE6U7xaIprWATamVSco7HOb8r8m8r1Y7A69A+r4lVP6AzcHmDpgelJDoMxkOUYFkUE8L0WYoUASrQJX4=@vger.kernel.org X-Gm-Message-State: AOJu0YwrfX2cMcR98pJt39mZE4L7t/k3zinR8Iq47DE1c6nntWBhIrDl X/pBoyhFlt5z3yRAsQDet/1+23u5W7V9Q0HLwQgPUe1VMkX8ng85ET0MIq0FHyfdhh7u9Ps5CIe 8yKiDbg== X-Google-Smtp-Source: AGHT+IE5oVQjlW9T1nTalOL0Mk3cl72oHyuKu7TFlX0faUEZxNSKKMlJpL1ygA1CbXgjeNjcYgIw40YqexM= X-Received: from pjbsu12.prod.google.com ([2002:a17:90b:534c:b0:313:246f:8d54]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3510:b0:313:176b:7384 with SMTP id 98e67ed59e1d1-313af12b099mr1782572a91.11.1749597626599; Tue, 10 Jun 2025 16:20:26 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 10 Jun 2025 16:20:10 -0700 In-Reply-To: <20250610232010.162191-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250610232010.162191-1-seanjc@google.com> X-Mailer: git-send-email 2.50.0.rc0.642.g800a2b2222-goog Message-ID: <20250610232010.162191-9-seanjc@google.com> Subject: [PATCH v6 8/8] KVM: VMX: Preserve host's DEBUGCTLMSR_FREEZE_IN_SMM while running the guest From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Adrian Hunter , Maxim Levitsky Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Maxim Levitsky Set/clear DEBUGCTLMSR_FREEZE_IN_SMM in GUEST_IA32_DEBUGCTL based on the host's pre-VM-Enter value, i.e. preserve the host's FREEZE_IN_SMM setting while running the guest. When running with the "default treatment of SMIs" in effect (the only mode KVM supports), SMIs do not generate a VM-Exit that is visible to host (non-SMM) software, and instead transitions directly from VMX non-root to SMM. And critically, DEBUGCTL isn't context switched by hardware on SMI or RSM, i.e. SMM will run with whatever value was resident in hardware at the time of the SMI. Failure to preserve FREEZE_IN_SMM results in the PMU unexpectedly counting events while the CPU is executing in SMM, which can pollute profiling and potentially leak information into the guest. Check for changes in FREEZE_IN_SMM prior to every entry into KVM's inner run loop, as the bit can be toggled in IRQ context via IPI callback (SMP function call), by way of /sys/devices/cpu/freeze_on_smi. Add a field in kvm_x86_ops to communicate which DEBUGCTL bits need to be preserved, as FREEZE_IN_SMM is only supported and defined for Intel CPUs, i.e. explicitly checking FREEZE_IN_SMM in common x86 is at best weird, and at worst could lead to undesirable behavior in the future if AMD CPUs ever happened to pick up a collision with the bit. Exempt TDX vCPUs, i.e. protected guests, from the check, as the TDX Module owns and controls GUEST_IA32_DEBUGCTL. WARN in SVM if KVM_RUN_LOAD_DEBUGCTL is set, mostly to document that the lack of handling isn't a KVM bug (TDX already WARNs on any run_flag). Lastly, explicitly reload GUEST_IA32_DEBUGCTL on a VM-Fail that is missed by KVM but detected by hardware, i.e. in nested_vmx_restore_host_state(). Doing so avoids the need to track host_debugctl on a per-VMCS basis, as GUEST_IA32_DEBUGCTL is unconditionally written by prepare_vmcs02() and load_vmcs12_host_state(). For the VM-Fail case, even though KVM won't have actually entered the guest, vcpu_enter_guest() will have run with vmcs02 active and thus could result in vmcs01 being run with a stale value. Cc: stable@vger.kernel.org Signed-off-by: Maxim Levitsky Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson Reviewed-by: Maxim Levitsky Suggested-by: Maxim Levitsky --- arch/x86/include/asm/kvm_host.h | 7 +++++++ arch/x86/kvm/vmx/main.c | 2 ++ arch/x86/kvm/vmx/nested.c | 3 +++ arch/x86/kvm/vmx/vmx.c | 3 +++ arch/x86/kvm/vmx/vmx.h | 15 ++++++++++++++- arch/x86/kvm/x86.c | 14 ++++++++++++-- 6 files changed, 41 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 3d6325369a4b..e59527dd5a0b 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1676,6 +1676,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 { @@ -1706,6 +1707,12 @@ struct kvm_x86_ops { void (*vcpu_load)(struct kvm_vcpu *vcpu, int cpu); void (*vcpu_put)(struct kvm_vcpu *vcpu); =20 + /* + * Mask of DEBUGCTL bits that are owned by the host, i.e. that need to + * match the host's value even while the guest is active. + */ + const u64 HOST_OWNED_DEBUGCTL; + void (*update_exception_bitmap)(struct kvm_vcpu *vcpu); int (*get_msr)(struct kvm_vcpu *vcpu, struct msr_data *msr); int (*set_msr)(struct kvm_vcpu *vcpu, struct msr_data *msr); diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c index c85cbce6d2f6..4a6d4460f947 100644 --- a/arch/x86/kvm/vmx/main.c +++ b/arch/x86/kvm/vmx/main.c @@ -915,6 +915,8 @@ struct kvm_x86_ops vt_x86_ops __initdata =3D { .vcpu_load =3D vt_op(vcpu_load), .vcpu_put =3D vt_op(vcpu_put), =20 + .HOST_OWNED_DEBUGCTL =3D DEBUGCTLMSR_FREEZE_IN_SMM, + .update_exception_bitmap =3D vt_op(update_exception_bitmap), .get_feature_msr =3D vmx_get_feature_msr, .get_msr =3D vt_op(get_msr), diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 9edce9f411a3..756c42e2d038 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -4860,6 +4860,9 @@ static void nested_vmx_restore_host_state(struct kvm_= vcpu *vcpu) WARN_ON(kvm_set_dr(vcpu, 7, vmcs_readl(GUEST_DR7))); } =20 + /* Reload DEBUGCTL to ensure vmcs01 has a fresh FREEZE_IN_SMM value. */ + vmx_reload_guest_debugctl(vcpu); + /* * Note that calling vmx_set_{efer,cr0,cr4} is important as they * handle a variety of side effects to KVM's software model. diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 196f33d934d3..70a115d99530 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7371,6 +7371,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_reload_guest_debugctl(vcpu); + /* * 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 c20a4185d10a..076af78af151 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -419,12 +419,25 @@ bool vmx_is_valid_debugctl(struct kvm_vcpu *vcpu, u64= data, bool host_initiated) =20 static inline void vmx_guest_debugctl_write(struct kvm_vcpu *vcpu, u64 val) { + WARN_ON_ONCE(val & DEBUGCTLMSR_FREEZE_IN_SMM); + + val |=3D vcpu->arch.host_debugctl & DEBUGCTLMSR_FREEZE_IN_SMM; vmcs_write64(GUEST_IA32_DEBUGCTL, val); } =20 static inline u64 vmx_guest_debugctl_read(void) { - return vmcs_read64(GUEST_IA32_DEBUGCTL); + return vmcs_read64(GUEST_IA32_DEBUGCTL) & ~DEBUGCTLMSR_FREEZE_IN_SMM; +} + +static inline void vmx_reload_guest_debugctl(struct kvm_vcpu *vcpu) +{ + u64 val =3D vmcs_read64(GUEST_IA32_DEBUGCTL); + + if (!((val ^ vcpu->arch.host_debugctl) & DEBUGCTLMSR_FREEZE_IN_SMM)) + return; + + vmx_guest_debugctl_write(vcpu, val & ~DEBUGCTLMSR_FREEZE_IN_SMM); } =20 /* diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 6742eb556d91..811f4db824ab 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10779,7 +10779,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, debug_ctl; =20 bool req_immediate_exit =3D false; =20 @@ -11051,7 +11051,17 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) set_debugreg(0, 7); } =20 - vcpu->arch.host_debugctl =3D get_debugctlmsr(); + /* + * Refresh the host DEBUGCTL snapshot after disabling IRQs, as DEBUGCTL + * can be modified in IRQ context, e.g. via SMP function calls. Inform + * vendor code if any host-owned bits were changed, e.g. so that the + * value loaded into hardware while running the guest can be updated. + */ + debug_ctl =3D get_debugctlmsr(); + if ((debug_ctl ^ vcpu->arch.host_debugctl) & kvm_x86_ops.HOST_OWNED_DEBUG= CTL && + !vcpu->arch.guest_state_protected) + run_flags |=3D KVM_RUN_LOAD_DEBUGCTL; + vcpu->arch.host_debugctl =3D debug_ctl; =20 guest_timing_enter_irqoff(); =20 --=20 2.50.0.rc0.642.g800a2b2222-goog