From nobody Tue Dec 16 07:34:27 2025 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.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 6632818DB1F for ; Fri, 5 Dec 2025 23:19:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764976763; cv=none; b=rXsr+L6CUDy25XaT2OhzOJy9a0CkdwZ3sIFB2ETgUWmySy3TMrqJ5CLgLo0z5WGwyZDe+4ZQLM6UKbMMWnSf/5RS8DyEjK32mnimkzotCiPLGxV/+LMbhWEob8GB35rk5XKWjDx1cB1MEkMG6X2w7G4EBoP4ZSAHtQgwS+Jk2v4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764976763; c=relaxed/simple; bh=UN8GPCeve/DEnaWE5Eh7JLbjimevNK5VLubSfh1kBU8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=k0XY00iWQFs6uhJ3RKbJKASlHF4CSB5W8nOniFdEb1hfEWxHe1fFOYM12yc6LIrZeOIf1fsjzkyvoO6bVdMxzPgFaVwWYbpng2CV2cgv+5HkwzIEF8DSQySKQ54GJCWP7Q6oqsP/cllLg3AUEq1B+ZDmFYgKbLw0leYv8ZSIaTk= 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=lEyX1Tqk; arc=none smtp.client-ip=209.85.214.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="lEyX1Tqk" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2982b47ce35so36471775ad.2 for ; Fri, 05 Dec 2025 15:19:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764976759; x=1765581559; 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=5vbjlflukCzgVx857+Uo6D3SgSV5wlnI4XqtN/GelQI=; b=lEyX1TqkC4K4hUnFftOScGlCrB9m7gEv1y0gFoYjhLBBHJy4mORsxdvx3vYQaDPjXr myQEUjIM4DVnU3c5n6hrN/JlnzxFtwQOWzg0O0t1Sj6MukDwIqc/xxmcMsOMjcFesQ7w p9wjvhwSajHWy/s1OvhhbDYNdNGpwKQR7ICXsVrmrXwaDiJYES0wXRZRBjU/cfjcVHM0 R/3rKawYsWnOIdGODh253d3aktC++Tb5Jk3qhWaAWiuk1tMjycGpBrddPBWEGUcJzjnT lMTcWTAkbc3wtHQAtM5mjC1yatXi6G1aqwqsUZrb81ROYK/TaEQNNLBGEOXz2lkfTqlm ogtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764976759; x=1765581559; 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=5vbjlflukCzgVx857+Uo6D3SgSV5wlnI4XqtN/GelQI=; b=TGCyetPLFh81xgNG2yLJ0WT2MkUc84P9sVk8iUKa3nBwiu0XDwFq+SBPs99TYnnkFa bTXLzwCoEEvp9Qu+4hxDBgOPZ4g+Fih4ilbMogFiUcOuZdvQ+JRmawksP3wtB5KQJjTu HJ1pPHmauiD7kbKL4PO93sNMN5ZuDlvXzCok8srl3y0W0gZ1WUDgTW/wo2dl60kBncmI PK0QT4PqBXPmS2n360weDUZq88Id1riVGxCAYgB0K2/Y03z3smieElSoeMjrO8K0UApJ +E6ElaouXii4LUly3R/qlW9nyxPx1yzRM5cas71IAxABisaC7+YLwrAQGJckK+TGbMHc DPVg== X-Forwarded-Encrypted: i=1; AJvYcCVGbg3w76mbuw1gKcMvyuIGFzcU4EiLCAnHfrQUtaYrPA2HPqF7rMJWtWVbZQuQuvlLU24ELt9CSlojwgY=@vger.kernel.org X-Gm-Message-State: AOJu0YwROmRhSyAWXOc8hsi+qOWNsLHFixQTBrunbjDDMvIUfMcL6zQk VtCG8RlS0/yDBX0cCaQRK49PkTH/FEfHKlBuEzZOjkoVbxFVpMLVVuLhY8kjuJRLZb2J4Sjhk0e X3Zwnmw== X-Google-Smtp-Source: AGHT+IGGGWzlhukNf7o4/R3m070bOr/gayV996esIb+fsIzTzw7B9dy/9JvMrkqeE6xa0MpUeOsIyRkHwJI= X-Received: from plpf8.prod.google.com ([2002:a17:903:3c48:b0:297:fd8b:fe1e]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:f60b:b0:297:db6a:a82f with SMTP id d9443c01a7336-29df5572c21mr4075325ad.24.1764976759407; Fri, 05 Dec 2025 15:19:19 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 5 Dec 2025 15:19:04 -0800 In-Reply-To: <20251205231913.441872-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: <20251205231913.441872-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.223.gf5cc29aaa4-goog Message-ID: <20251205231913.441872-2-seanjc@google.com> Subject: [PATCH v3 01/10] KVM: VMX: Update SVI during runtime APICv activation From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Dongli Zhang , Chao Gao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Dongli Zhang The APICv (apic->apicv_active) can be activated or deactivated at runtime, for instance, because of APICv inhibit reasons. Intel VMX employs different mechanisms to virtualize LAPIC based on whether APICv is active. When APICv is activated at runtime, GUEST_INTR_STATUS is used to configure and report the current pending IRR and ISR states. Unless a specific vector is explicitly included in EOI_EXIT_BITMAP, its EOI will not be trapped to KVM. Intel VMX automatically clears the corresponding ISR bit based on the GUEST_INTR_STATUS.SVI field. When APICv is deactivated at runtime, the VM_ENTRY_INTR_INFO_FIELD is used to specify the next interrupt vector to invoke upon VM-entry. The VMX IDT_VECTORING_INFO_FIELD is used to report un-invoked vectors on VM-exit. EOIs are always trapped to KVM, so the software can manually clear pending ISR bits. There are scenarios where, with APICv activated at runtime, a guest-issued EOI may not be able to clear the pending ISR bit. Taking vector 236 as an example, here is one scenario. 1. Suppose APICv is inactive. Vector 236 is pending in the IRR. 2. To handle KVM_REQ_EVENT, KVM moves vector 236 from the IRR to the ISR, and configures the VM_ENTRY_INTR_INFO_FIELD via vmx_inject_irq(). 3. After VM-entry, vector 236 is invoked through the guest IDT. At this point, the data in VM_ENTRY_INTR_INFO_FIELD is no longer valid. The guest interrupt handler for vector 236 is invoked. 4. Suppose a VM exit occurs very early in the guest interrupt handler, before the EOI is issued. 5. Nothing is reported through the IDT_VECTORING_INFO_FIELD because vector 236 has already been invoked in the guest. 6. Now, suppose APICv is activated. Before the next VM-entry, KVM calls kvm_vcpu_update_apicv() to activate APICv. 7. Unfortunately, GUEST_INTR_STATUS.SVI is not configured, although vector 236 is still pending in the ISR. 8. After VM-entry, the guest finally issues the EOI for vector 236. However, because SVI is not configured, vector 236 is not cleared. 9. ISR is stalled forever on vector 236. Here is another scenario. 1. Suppose APICv is inactive. Vector 236 is pending in the IRR. 2. To handle KVM_REQ_EVENT, KVM moves vector 236 from the IRR to the ISR, and configures the VM_ENTRY_INTR_INFO_FIELD via vmx_inject_irq(). 3. VM-exit occurs immediately after the next VM-entry. The vector 236 is not invoked through the guest IDT. Instead, it is saved to the IDT_VECTORING_INFO_FIELD during the VM-exit. 4. KVM calls kvm_queue_interrupt() to re-queue the un-invoked vector 236 into vcpu->arch.interrupt. A KVM_REQ_EVENT is requested. 5. Now, suppose APICv is activated. Before the next VM-entry, KVM calls kvm_vcpu_update_apicv() to activate APICv. 6. Although APICv is now active, KVM still uses the legacy VM_ENTRY_INTR_INFO_FIELD to re-inject vector 236. GUEST_INTR_STATUS.SVI is not configured. 7. After the next VM-entry, vector 236 is invoked through the guest IDT. Finally, an EOI occurs. However, due to the lack of GUEST_INTR_STATUS.SVI configuration, vector 236 is not cleared from the ISR. 8. ISR is stalled forever on vector 236. Using QEMU as an example, vector 236 is stuck in ISR forever. (qemu) info lapic 1 dumping local APIC state for CPU 1 LVT0 0x00010700 active-hi edge masked ExtINT (vec 0) LVT1 0x00010400 active-hi edge masked NMI LVTPC 0x00000400 active-hi edge NMI LVTERR 0x000000fe active-hi edge Fixed (vec = 254) LVTTHMR 0x00010000 active-hi edge masked Fixed (vec= 0) LVTT 0x000400ec active-hi edge tsc-deadline Fixed (vec 23= 6) Timer DCR=3D0x0 (divide by 2) initial_count =3D 0 current_count =3D 0 SPIV 0x000001ff APIC enabled, focus=3Doff, spurious vec 255 ICR 0x000000fd physical edge de-assert no-shorthand ICR2 0x00000000 cpu 0 (X2APIC ID) ESR 0x00000000 ISR 236 IRR 37(level) 236 The issue isn't applicable to AMD SVM as KVM simply writes vmcb01 directly irrespective of whether L1 (vmcs01) or L2 (vmcb02) is active (unlike VMX, there is no need/cost to switch between VMCBs). In addition, APICV_INHIBIT_REASON_IRQWIN ensures AMD SVM AVIC is not activated until the last interrupt is EOI'd. Fix the bug by configuring Intel VMX GUEST_INTR_STATUS.SVI if APICv is activated at runtime. Signed-off-by: Dongli Zhang Reviewed-by: Chao Gao Link: https://patch.msgid.link/20251110063212.34902-1-dongli.zhang@oracle.c= om [sean: call out that SVM writes vmcb01 directly, tweak comment] Signed-off-by: Sean Christopherson --- arch/x86/kvm/vmx/vmx.c | 9 --------- arch/x86/kvm/x86.c | 7 +++++++ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 4cbe8c84b636..6b96f7aea20b 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6937,15 +6937,6 @@ void vmx_hwapic_isr_update(struct kvm_vcpu *vcpu, in= t max_isr) * VM-Exit, otherwise L1 with run with a stale SVI. */ if (is_guest_mode(vcpu)) { - /* - * KVM is supposed to forward intercepted L2 EOIs to L1 if VID - * is enabled in vmcs12; as above, the EOIs affect L2's vAPIC. - * Note, userspace can stuff state while L2 is active; assert - * that VID is disabled if and only if the vCPU is in KVM_RUN - * to avoid false positives if userspace is setting APIC state. - */ - WARN_ON_ONCE(vcpu->wants_to_run && - nested_cpu_has_vid(get_vmcs12(vcpu))); to_vmx(vcpu)->nested.update_vmcs01_hwapic_isr =3D true; return; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0c6d899d53dd..ff8812f3a129 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10886,9 +10886,16 @@ void __kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu) * pending. At the same time, KVM_REQ_EVENT may not be set as APICv was * still active when the interrupt got accepted. Make sure * kvm_check_and_inject_events() is called to check for that. + * + * Update SVI when APICv gets enabled, otherwise SVI won't reflect the + * highest bit in vISR and the next accelerated EOI in the guest won't + * be virtualized correctly (the CPU uses SVI to determine which vISR + * vector to clear). */ if (!apic->apicv_active) kvm_make_request(KVM_REQ_EVENT, vcpu); + else + kvm_apic_update_hwapic_isr(vcpu); =20 out: preempt_enable(); --=20 2.52.0.223.gf5cc29aaa4-goog From nobody Tue Dec 16 07:34:27 2025 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.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 154662FF173 for ; Fri, 5 Dec 2025 23:19:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764976768; cv=none; b=joQC0B43qSGRE57H7lk+aTDM/icuy7tR1QGSr8twFgdt6uTIQhXUVxF8d8GSmJduC9cMR8rHUq/RcYY5mnbvOtP08uscIwXMv47A9C57NmHLxFJhMG1KXojUr04CztIrvs7JqlqGJRPznfhKwNSlhybBCFYxsu20FEj0D2Y9BEo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764976768; c=relaxed/simple; bh=exo09ceDmXypfTxtCerCEjZOA8vfVIz2MO3bU0BfyqM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=jeBVD+eqPLRPo6jRJzFeSDimYuKWNGThemwJzuvidjIKIHOvxWs1aRHw5CJt4mxdaxhAoD/Qxx1eOo1AQo9pTjTXlyVcHrrCtPstDAQbXhi5fWeyOEchAp0X5kremyQlmSUzJU3Q4FWVWY282+fViqKMttkzMiNGNE4ekb0jsXw= 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=Q/1uz9Xi; arc=none smtp.client-ip=209.85.210.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="Q/1uz9Xi" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7be94e1a073so4887512b3a.2 for ; Fri, 05 Dec 2025 15:19:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764976761; x=1765581561; 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=ZcJtGX0VmRX2lzBpy3LVmAgEJDoeGm/VKWbOEKmvPbc=; b=Q/1uz9XivDHtxidfZatlGz3AlOkrPxeNxWEOD8cuNTAKLc+PmwMHG0/1tldCQ54uQn gkIKuLpntMG766ZSjv0NhaNv5t7QfuvIoobCwaaMjunWUoWGOBr9CUmltTeo/RY9bd3M m/uHmzl4pGkM8f1K0jcaxE1XVEGz87MBvWx2c/hYWwhucBEfpuk1pHJayz0K9nfz10AI pwUDhSHVpj5Tu94Ulh+bfqmIacP4l2vBsNAXw1i0g003jKMyueZx/GqyGnT/Km8oC7IA cj8TsGWWR0TaIwj9BF/c+fpC/kf/KocyC486MOKFOCfmHdJRiGpMtRXHMUCsARtnzZT/ IlVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764976761; x=1765581561; 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=ZcJtGX0VmRX2lzBpy3LVmAgEJDoeGm/VKWbOEKmvPbc=; b=UppDb33RcrDBBY5c3jvN5QRvZMPh5tH/EXO/Z9uqLpuIvAHYwD0yUpmmY4EOnPMuP9 bFVJsauXUBiIdUkpnL+SKc8gQqHvW/DSzmJlixm6YBJTHkdCsAxQIQvlIDVDs6/vXpEx nVL8i8iXMWkwk4obaoh0rIcCvhD26XPeuQCGHDRwPkrJTBlgtC2lp/LH5Suhb+MEIWa6 ZYFz9I21TZkBaqYaTA86oQ1k/3X8RW8SLnawHqkYqSbvUNG+AfWz8eGt/YfnhjgkY/M1 1qsbktKygWfPyrS2v9h+vq4oYPBIYpHJObO4kRyY0Eb0TXVG/glpRmdUBALI8HnHA7Q/ y6jQ== X-Forwarded-Encrypted: i=1; AJvYcCWM4losQQN+rpUzjBM8uGMYWvvGeifA43XC7BZk6QGOHYlXsbmJeIN5RDAqmGJFyrxrI2VHw9+vDz6xVCA=@vger.kernel.org X-Gm-Message-State: AOJu0Ywodp390qYg84HGx4UhqIJWGbUqcXnUvMMGfSkPiUyFKEuP8bKL 80TX1YMARNjFb2ABfndm07Xfvu3qqG+spL/wR4pyvspIpEQXBBQ/qg9ifNON1YMZLu+lIOqukdJ R+IUz1g== X-Google-Smtp-Source: AGHT+IH0SYz00lEf7HVPssFZvqoZIZN/mMz1YTgzQllfd0G4FhVaPgZKdiRo2+ZPkMMERZPCk7sSwMWCPk4= X-Received: from pgam21.prod.google.com ([2002:a05:6a02:2b55:b0:bc1:99a7:3f1b]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:e211:b0:366:14af:9bb8 with SMTP id adf61e73a8af0-36618017e9cmr908273637.66.1764976761202; Fri, 05 Dec 2025 15:19:21 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 5 Dec 2025 15:19:05 -0800 In-Reply-To: <20251205231913.441872-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: <20251205231913.441872-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.223.gf5cc29aaa4-goog Message-ID: <20251205231913.441872-3-seanjc@google.com> Subject: [PATCH v3 02/10] KVM: nVMX: Immediately refresh APICv controls as needed on nested VM-Exit From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Dongli Zhang , Chao Gao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Dongli Zhang If an APICv status updated was pended while L2 was active, immediately refresh vmcs01's controls instead of pending KVM_REQ_APICV_UPDATE as kvm_vcpu_update_apicv() only calls into vendor code if a change is necessary. E.g. if APICv is inhibited, and then activated while L2 is running: kvm_vcpu_update_apicv() | -> __kvm_vcpu_update_apicv() | -> apic->apicv_active =3D true | -> vmx_refresh_apicv_exec_ctrl() | -> vmx->nested.update_vmcs01_apicv_status =3D true | -> return Then L2 exits to L1: __nested_vmx_vmexit() | -> kvm_make_request(KVM_REQ_APICV_UPDATE) vcpu_enter_guest(): KVM_REQ_APICV_UPDATE -> kvm_vcpu_update_apicv() | -> __kvm_vcpu_update_apicv() | -> return // because if (apic->apicv_active =3D=3D activate) Reported-by: Chao Gao Closes: https://lore.kernel.org/all/aQ2jmnN8wUYVEawF@intel.com Fixes: 7c69661e225c ("KVM: nVMX: Defer APICv updates while L2 is active unt= il L1 is active") Cc: stable@vger.kernel.org Signed-off-by: Dongli Zhang [sean: write changelog] Signed-off-by: Sean Christopherson --- arch/x86/kvm/vmx/nested.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 40777278eabb..6137e5307d0f 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -19,6 +19,7 @@ #include "trace.h" #include "vmx.h" #include "smm.h" +#include "x86_ops.h" =20 static bool __read_mostly enable_shadow_vmcs =3D 1; module_param_named(enable_shadow_vmcs, enable_shadow_vmcs, bool, S_IRUGO); @@ -5165,7 +5166,7 @@ void __nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 v= m_exit_reason, =20 if (vmx->nested.update_vmcs01_apicv_status) { vmx->nested.update_vmcs01_apicv_status =3D false; - kvm_make_request(KVM_REQ_APICV_UPDATE, vcpu); + vmx_refresh_apicv_exec_ctrl(vcpu); } =20 if (vmx->nested.update_vmcs01_hwapic_isr) { --=20 2.52.0.223.gf5cc29aaa4-goog From nobody Tue Dec 16 07:34:27 2025 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (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 23C442FFF9A for ; Fri, 5 Dec 2025 23:19:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764976768; cv=none; b=ReUP7N14llb0Xrwh0MAt1NBIXT9k43Di55wBV1CMZSfLSevzmcTmZTxokAS6EtJxPdJiUTa6WvMgnKk4I2Pe9884I4nvVsjHsitETfcPOvKz5OPhR0evg7rRkrsBN8qG0FM+cG68NrGcEsWI+Q5U2RYV0Blgu7PXZ3X480co0B8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764976768; c=relaxed/simple; bh=4Fex+pgpP3q+w5hfQVpkoaW6L1kXWK3VkJDR6p+t18Y=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=kX5M4WF2goXUUNVN3qy7CBcoDxKE/OV0kZc2EH8VC2xh23UBcp7j/G8NBBhqeVuLyxAJQ8bMhojf2XpgcnvT9CBvqeC53ux1NG0w+QGPixv+m4q/oexaNP/CYlJ6qMToDFUJh/+lbXRzZKR5QGw38ApIAgXdg2D1CL/bBEeGWKw= 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=NDy9MtUd; arc=none smtp.client-ip=209.85.216.73 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="NDy9MtUd" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-349a2f509acso307145a91.1 for ; Fri, 05 Dec 2025 15:19:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764976763; x=1765581563; 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=qE7acRBvhgKVAvezYXIFc6q852EVZn4fTd5PsAQBmnY=; b=NDy9MtUd0gOXkDF+VoxVC8I+f9mvqPkBc0VsN5w7mROH0y8qijcbYBmmfUo8qFqION GYLREFKv5D95G6gdFsfR3HyvRoozRLsjrJbB0XidOL0ZdRky4BcSBwSC46lyWXgIXEkn 3+ruiWYRB+l49/wSQYOKklYSxSeFhzwWokiaD4HgK0pmvUoKJF509pHLnnr5+ha+kjGI ZxKQV3+LzGoXhS7aX4/c1hiRJoJISD3/ZOhIB+c7v6HZeO3AEDO8WRBJ9DUPehHriRP5 HXqvZ37MfYn0eufdSwOOhRqMAL3caGd31bAw+5QeodH+3zZme8d+As07s0NySaWFQXRp Q28A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764976763; x=1765581563; 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=qE7acRBvhgKVAvezYXIFc6q852EVZn4fTd5PsAQBmnY=; b=DPXPr9zbZUEemTn0I8cfwvtN1i8DzMQUceOy8pf+/PLNYRZwjBAtDIaJN5Ukrrj0Qy 4ekFT4h2dsWA2UblD9PVIdRkYwefwXcUy98hyjgU5P6q29MjLInwe9zqZ22Vy/h0doj/ 1oI2RykXLa9j4ioL+2vPgv3UyMKVp4pgGjb/MZlGyKNKEtcEnz04yhK7Kaf+KrW+canD K4gB0U2hfMwmsRUhmdgvjmvfBArCn8Y//DOrBEdjW0fS/5TwDQ6xAox6PpjF7tNOoFMH Et/UNvlquWA+C5EDFmHpH/79swsX08uRUZHPkph+LZKqZbHkV4v0F434FMH14XFkqyis LJnA== X-Forwarded-Encrypted: i=1; AJvYcCXElyeVxlEAVV5zaRLS+5hlnMS2qspUwdZ58Ax9WyoMIaJvbjP6TXu8PzDi1klDnDHa4rpp1sEpPPzr/Xc=@vger.kernel.org X-Gm-Message-State: AOJu0Yy7qK0Rpypl/AbJ+fzK0ky+MgrvoTztnQ2sSyIY3N+XBcpqRF7A OrwzF9xb8I5r1aamO8phdB/zNdlOvZhCXqGGeo3O7KtkA46ArQ4tPmhZKmZlq7pkzpIksR69HWI f9cKgFw== X-Google-Smtp-Source: AGHT+IF8s0h1mmxocVPZHPd28nJzW0w+Qv5m/PrzhL2RdH7GTDs1Qpw6V6jl3Fd5c6lEV/iFc4ugbJdTgKI= X-Received: from pjbsb13.prod.google.com ([2002:a17:90b:50cd:b0:340:c0e9:24b6]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:388b:b0:349:30b4:6367 with SMTP id 98e67ed59e1d1-349a25e5544mr580362a91.30.1764976762698; Fri, 05 Dec 2025 15:19:22 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 5 Dec 2025 15:19:06 -0800 In-Reply-To: <20251205231913.441872-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: <20251205231913.441872-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.223.gf5cc29aaa4-goog Message-ID: <20251205231913.441872-4-seanjc@google.com> Subject: [PATCH v3 03/10] KVM: selftests: Add a test to verify APICv updates (while L2 is active) From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Dongli Zhang , Chao Gao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a test to verify KVM correctly handles a variety of edge cases related to APICv updates, and in particular updates that are triggered while L2 is actively running. Signed-off-by: Sean Christopherson Reviewed-by: Chao Gao --- tools/testing/selftests/kvm/Makefile.kvm | 1 + .../testing/selftests/kvm/include/x86/apic.h | 4 + .../kvm/x86/vmx_apicv_updates_test.c | 181 ++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index ba5c2b643efa..6f00bd8271c2 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -115,6 +115,7 @@ TEST_GEN_PROGS_x86 +=3D x86/ucna_injection_test TEST_GEN_PROGS_x86 +=3D x86/userspace_io_test TEST_GEN_PROGS_x86 +=3D x86/userspace_msr_exit_test TEST_GEN_PROGS_x86 +=3D x86/vmx_apic_access_test +TEST_GEN_PROGS_x86 +=3D x86/vmx_apicv_updates_test TEST_GEN_PROGS_x86 +=3D x86/vmx_dirty_log_test TEST_GEN_PROGS_x86 +=3D x86/vmx_exception_with_invalid_guest_state TEST_GEN_PROGS_x86 +=3D x86/vmx_msrs_test diff --git a/tools/testing/selftests/kvm/include/x86/apic.h b/tools/testing= /selftests/kvm/include/x86/apic.h index 80fe9f69b38d..d42a0998d868 100644 --- a/tools/testing/selftests/kvm/include/x86/apic.h +++ b/tools/testing/selftests/kvm/include/x86/apic.h @@ -32,6 +32,7 @@ #define APIC_SPIV 0xF0 #define APIC_SPIV_FOCUS_DISABLED (1 << 9) #define APIC_SPIV_APIC_ENABLED (1 << 8) +#define APIC_ISR 0x100 #define APIC_IRR 0x200 #define APIC_ICR 0x300 #define APIC_LVTCMCI 0x2f0 @@ -68,6 +69,9 @@ #define APIC_TMCCT 0x390 #define APIC_TDCR 0x3E0 =20 +#define APIC_VECTOR_TO_BIT_NUMBER(v) ((unsigned int)(v) % 32) +#define APIC_VECTOR_TO_REG_OFFSET(v) ((unsigned int)(v) / 32 * 0x10) + void apic_disable(void); void xapic_enable(void); void x2apic_enable(void); diff --git a/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c b/too= ls/testing/selftests/kvm/x86/vmx_apicv_updates_test.c new file mode 100644 index 000000000000..907d226fd0fd --- /dev/null +++ b/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include "test_util.h" +#include "kvm_util.h" +#include "processor.h" +#include "vmx.h" + +#define GOOD_IPI_VECTOR 0xe0 +#define BAD_IPI_VECTOR 0xf0 + +static volatile int good_ipis_received; + +static void good_ipi_handler(struct ex_regs *regs) +{ + good_ipis_received++; +} + +static void bad_ipi_handler(struct ex_regs *regs) +{ + TEST_FAIL("Received \"bad\" IPI; ICR MMIO write should have been ignored"= ); +} + +static void l2_vmcall(void) +{ + /* + * Exit to L1. Assume all registers may be clobbered as selftests's + * VM-Enter code doesn't preserve L2 GPRs. + */ + asm volatile("push %%rbp\n\t" + "push %%r15\n\t" + "push %%r14\n\t" + "push %%r13\n\t" + "push %%r12\n\t" + "push %%rbx\n\t" + "push %%rdx\n\t" + "push %%rdi\n\t" + "vmcall\n\t" + "pop %%rdi\n\t" + "pop %%rdx\n\t" + "pop %%rbx\n\t" + "pop %%r12\n\t" + "pop %%r13\n\t" + "pop %%r14\n\t" + "pop %%r15\n\t" + "pop %%rbp\n\t" + ::: "rax", "rcx", "rdx", "rsi", "rdx", "r8", "r9", "r10", "r11", "memory= "); +} + +static void l2_guest_code(void) +{ + x2apic_enable(); + l2_vmcall(); + + xapic_enable(); + xapic_write_reg(APIC_ID, 1 << 24); + l2_vmcall(); +} + +static void l1_guest_code(struct vmx_pages *vmx_pages) +{ +#define L2_GUEST_STACK_SIZE 64 + unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; + uint32_t control; + + GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages)); + GUEST_ASSERT(load_vmcs(vmx_pages)); + + /* Prepare the VMCS for L2 execution. */ + prepare_vmcs(vmx_pages, l2_guest_code, &l2_guest_stack[L2_GUEST_STACK_SIZ= E]); + control =3D vmreadz(CPU_BASED_VM_EXEC_CONTROL); + control |=3D CPU_BASED_USE_MSR_BITMAPS; + vmwrite(CPU_BASED_VM_EXEC_CONTROL, control); + + /* Modify APIC ID to coerce KVM into inhibiting APICv. */ + xapic_enable(); + xapic_write_reg(APIC_ID, 1 << 24); + + /* + * Generate+receive an IRQ without doing EOI to get an IRQ set in vISR + * but not SVI. APICv should be inhibited due to running with a + * modified APIC ID. + */ + xapic_write_reg(APIC_ICR, APIC_DEST_SELF | APIC_DM_FIXED | GOOD_IPI_VECTO= R); + GUEST_ASSERT_EQ(xapic_read_reg(APIC_ID), 1 << 24); + + /* Enable IRQs and verify the IRQ was received. */ + sti_nop(); + GUEST_ASSERT_EQ(good_ipis_received, 1); + + /* + * Run L2 to switch to x2APIC mode, which in turn will uninhibit APICv, + * as KVM should force the APIC ID back to its default. + */ + GUEST_ASSERT(!vmlaunch()); + GUEST_ASSERT(vmreadz(VM_EXIT_REASON) =3D=3D EXIT_REASON_VMCALL); + vmwrite(GUEST_RIP, vmreadz(GUEST_RIP) + vmreadz(VM_EXIT_INSTRUCTION_LEN)); + GUEST_ASSERT(rdmsr(MSR_IA32_APICBASE) & MSR_IA32_APICBASE_EXTD); + + /* + * Scribble the APIC access page to verify KVM disabled xAPIC + * virtualization in vmcs01, and to verify that KVM flushes L1's TLB + * when L2 switches back to accelerated xAPIC mode. + */ + xapic_write_reg(APIC_ICR2, 0xdeadbeefu); + xapic_write_reg(APIC_ICR, APIC_DEST_SELF | APIC_DM_FIXED | BAD_IPI_VECTOR= ); + + /* + * Verify the IRQ is still in-service and emit an EOI to verify KVM + * propagates the highest vISR vector to SVI when APICv is activated + * (and does so even if APICv was uninhibited while L2 was active). + */ + GUEST_ASSERT_EQ(x2apic_read_reg(APIC_ISR + APIC_VECTOR_TO_REG_OFFSET(GOOD= _IPI_VECTOR)), + BIT(APIC_VECTOR_TO_BIT_NUMBER(GOOD_IPI_VECTOR))); + x2apic_write_reg(APIC_EOI, 0); + GUEST_ASSERT_EQ(x2apic_read_reg(APIC_ISR + APIC_VECTOR_TO_REG_OFFSET(GOOD= _IPI_VECTOR)), 0); + + /* + * Run L2 one more time to switch back to xAPIC mode to verify that KVM + * handles the x2APIC =3D> xAPIC transition and inhibits APICv while L2 + * is active. + */ + GUEST_ASSERT(!vmresume()); + GUEST_ASSERT(vmreadz(VM_EXIT_REASON) =3D=3D EXIT_REASON_VMCALL); + GUEST_ASSERT(!(rdmsr(MSR_IA32_APICBASE) & MSR_IA32_APICBASE_EXTD)); + + xapic_write_reg(APIC_ICR, APIC_DEST_SELF | APIC_DM_FIXED | GOOD_IPI_VECTO= R); + /* Re-enable IRQs, as VM-Exit clears RFLAGS.IF. */ + sti_nop(); + GUEST_ASSERT_EQ(good_ipis_received, 2); + + GUEST_ASSERT_EQ(xapic_read_reg(APIC_ISR + APIC_VECTOR_TO_REG_OFFSET(GOOD_= IPI_VECTOR)), + BIT(APIC_VECTOR_TO_BIT_NUMBER(GOOD_IPI_VECTOR))); + xapic_write_reg(APIC_EOI, 0); + GUEST_ASSERT_EQ(xapic_read_reg(APIC_ISR + APIC_VECTOR_TO_REG_OFFSET(GOOD_= IPI_VECTOR)), 0); + GUEST_DONE(); +} + +int main(int argc, char *argv[]) +{ + vm_vaddr_t vmx_pages_gva; + struct vmx_pages *vmx; + struct kvm_vcpu *vcpu; + struct kvm_vm *vm; + struct ucall uc; + + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX)); + + vm =3D vm_create_with_one_vcpu(&vcpu, l1_guest_code); + + vmx =3D vcpu_alloc_vmx(vm, &vmx_pages_gva); + prepare_virtualize_apic_accesses(vmx, vm); + vcpu_args_set(vcpu, 2, vmx_pages_gva); + + virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA); + vm_install_exception_handler(vm, BAD_IPI_VECTOR, bad_ipi_handler); + vm_install_exception_handler(vm, GOOD_IPI_VECTOR, good_ipi_handler); + + vcpu_run(vcpu); + TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO); + + switch (get_ucall(vcpu, &uc)) { + case UCALL_ABORT: + REPORT_GUEST_ASSERT(uc); + /* NOT REACHED */ + case UCALL_DONE: + break; + default: + TEST_FAIL("Unexpected ucall %lu", uc.cmd); + } + + /* + * Verify at least two IRQs were injected. Unfortunately, KVM counts + * re-injected IRQs (e.g. if delivering the IRQ hits an EPT violation), + * so being more precise isn't possible given the current stats. + */ + TEST_ASSERT(vcpu_get_stat(vcpu, irq_injections) >=3D 2, + "Wanted at least 2 IRQ injections, got %lu\n", + vcpu_get_stat(vcpu, irq_injections)); + + kvm_vm_free(vm); + return 0; +} --=20 2.52.0.223.gf5cc29aaa4-goog From nobody Tue Dec 16 07:34:27 2025 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.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 7CF59199931 for ; Fri, 5 Dec 2025 23:19:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764976769; cv=none; b=toA7wyKLo9u5VyuFCDan1WO5iueVzWqCgp87fGfg8z7r1SknK1yN1r/SjTPl1ectkgwcJrzJDWGB9lhkGqYB+SBX/Pz1IPtBY70fuPe9R/VxAuW0Tix/3hQ1/EhfpWGO5JN+OnVbH3P4+lCQwHcvPrdumN1wfkt6I7N3M/ux3P0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764976769; c=relaxed/simple; bh=JZFCAVE8KHQyo10EbULFfjgFlLhIrbp0ClGa9OqgEO0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=BN+53nSfFIYzUd7QBp2h9gNmXdG6LZ/djVfGzOrMN5UhVP0XEgiVdDcuTFp73yYMTqUlTXeaKjnTN7PPKZIvNh/6bPHXpfqctfPR2E07s4XDAlurgk7kF18MV78YNTjXrQqqugQFXPTk4KB5qKkYAOi+GHpwPxLRKhrzZ/znRHE= 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=4Z8DcuV7; arc=none smtp.client-ip=209.85.214.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="4Z8DcuV7" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-298535ef0ccso33741415ad.3 for ; Fri, 05 Dec 2025 15:19:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764976764; x=1765581564; 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=Mvq9EwNuVt/uRDW4qk+DItZf7McZ3rUgRJ5xdyR4olA=; b=4Z8DcuV7M/pXTI9xnqEcXVojGpPfDfXdlQ0LJl7YgmqodRB5vv1/MDnUOwAfGqu/VP Su7wRrvEJBAP9xXT5iK9ChmfUMkD5bXh22e8D1JeQpgBrpqO4f2DtHg+vsxZNI9BCb5n w9cHUZZPKHr6FIGVOgPn4bhEizRBjkwcOwntY59WWNB1nnVfiMvw2l3GbGMcgUWEBaAf c3c+ocPl701ieur1Sjksn9a56Qdhw96u0qUs4OYnjctOJ/gVd4UyTJdWEOVEesVAG3Vj I8lvaRnqxyaVwe1ZxVCzQpJ6xDHSE51tgRO6u111ktnaQARRCLkx+nYXhwJgePqSEBEd YvVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764976764; x=1765581564; 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=Mvq9EwNuVt/uRDW4qk+DItZf7McZ3rUgRJ5xdyR4olA=; b=vJPbt0VF9++38V4XNvNoS26NYMOwDNE38r1dbw4NSFmCwtsCrpfQ+yDiX9fug+QNIw kxl92O4WjE51stVuc+LMU2zUucTDX/8517DCthXntdIJMCKXdj2Rc93tuCbO145Q3ffI zJxqgEiIvY5ksghq6QmpVD2JPVHdWFYS39aU9gpwtGKpvIWtpzHpOjUS0XNkirdtAFfj dnhksktk5dH8f94YoT/6Wxe/OtlfcCxe5Cv1wjdAlYzxbWrmz+U91pQgwr+wsmqfQ7xi e63TjNtRS2PAWCXvgmlvBkBuDqkFL05K8d9e4c4pQqjDUOlw6w2E23FOea/4r6hvSnv8 9TPw== X-Forwarded-Encrypted: i=1; AJvYcCV+dfQuKj++0Jme2cq3DSy/gNcyVAZEWy5wLFt9D0MD0EC2A+PW3uVQwQTRcd37DQZ76SP7oLl0ZLfdTxw=@vger.kernel.org X-Gm-Message-State: AOJu0YympQeXr3JOOhe0wOxUWPLyuf9juHVB5sdmD71lEDKKB64cBfQj 6NnMF4htocavXWQv9yB22UYHs+TMhDJk54Aw9ZqVMrlOztbMLB8lMh4xXSWIbpGSenepWrxanlM gSI5vLg== X-Google-Smtp-Source: AGHT+IGaqtsQIlRIt8dhC6XhjoLt1eLpPH33jgp2ob6v9qBUcmBPpf0biCLwuxLzldqH2TDHNchN+IL7vp8= X-Received: from pgbee7.prod.google.com ([2002:a05:6a02:4587:b0:bc0:d9a9:8a8e]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:1584:b0:361:2c56:fca8 with SMTP id adf61e73a8af0-36618164900mr850783637.50.1764976764391; Fri, 05 Dec 2025 15:19:24 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 5 Dec 2025 15:19:07 -0800 In-Reply-To: <20251205231913.441872-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: <20251205231913.441872-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.223.gf5cc29aaa4-goog Message-ID: <20251205231913.441872-5-seanjc@google.com> Subject: [PATCH v3 04/10] KVM: nVMX: Switch to vmcs01 to update PML controls on-demand if L2 is active From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Dongli Zhang , Chao Gao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If KVM toggles "CPU dirty logging", a.k.a. Page-Modification Logging (PML), while L2 is active, temporarily load vmcs01 and immediately update the relevant controls instead of deferring the update until the next nested VM-Exit. For PML, deferring the update is relatively straightforward, but for several APICv related updates, deferring updates creates ordering and state consistency problems, e.g. KVM at-large thinks APICv is enabled, but vmcs01 is still running with stale (and effectively unknown) state. Convert PML first precisely because it's the simplest case to handle: if something is broken with the vmcs01 <=3D> vmcs02 dance, then hopefully bugs will bisect here. Signed-off-by: Sean Christopherson --- arch/x86/kvm/vmx/nested.c | 5 ----- arch/x86/kvm/vmx/vmx.c | 40 +++++++++++++++++++++++++++++++++++---- arch/x86/kvm/vmx/vmx.h | 1 - 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 6137e5307d0f..920a925bb46f 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -5152,11 +5152,6 @@ void __nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 = vm_exit_reason, vmx_set_virtual_apic_mode(vcpu); } =20 - if (vmx->nested.update_vmcs01_cpu_dirty_logging) { - vmx->nested.update_vmcs01_cpu_dirty_logging =3D false; - vmx_update_cpu_dirty_logging(vcpu); - } - nested_put_vmcs12_pages(vcpu); =20 if (vmx->nested.reload_vmcs01_apic_access_page) { diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 6b96f7aea20b..1420665fbb66 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1594,6 +1594,41 @@ void vmx_vcpu_put(struct kvm_vcpu *vcpu) vmx_prepare_switch_to_host(to_vmx(vcpu)); } =20 +static void vmx_switch_loaded_vmcs(struct kvm_vcpu *vcpu, + struct loaded_vmcs *vmcs) +{ + struct vcpu_vmx *vmx =3D to_vmx(vcpu); + int cpu; + + cpu =3D get_cpu(); + vmx->loaded_vmcs =3D vmcs; + vmx_vcpu_load_vmcs(vcpu, cpu); + put_cpu(); +} + +static void vmx_load_vmcs01(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx =3D to_vmx(vcpu); + + if (!is_guest_mode(vcpu)) { + WARN_ON_ONCE(vmx->loaded_vmcs !=3D &vmx->vmcs01); + return; + } + + WARN_ON_ONCE(vmx->loaded_vmcs !=3D &vmx->nested.vmcs02); + vmx_switch_loaded_vmcs(vcpu, &vmx->vmcs01); +} + +static void vmx_put_vmcs01(struct kvm_vcpu *vcpu) +{ + if (!is_guest_mode(vcpu)) + return; + + vmx_switch_loaded_vmcs(vcpu, &to_vmx(vcpu)->nested.vmcs02); +} +DEFINE_GUARD(vmx_vmcs01, struct kvm_vcpu *, + vmx_load_vmcs01(_T), vmx_put_vmcs01(_T)) + bool vmx_emulation_required(struct kvm_vcpu *vcpu) { return emulate_invalid_guest_state && !vmx_guest_state_valid(vcpu); @@ -8267,10 +8302,7 @@ void vmx_update_cpu_dirty_logging(struct kvm_vcpu *v= cpu) if (WARN_ON_ONCE(!enable_pml)) return; =20 - if (is_guest_mode(vcpu)) { - vmx->nested.update_vmcs01_cpu_dirty_logging =3D true; - return; - } + guard(vmx_vmcs01)(vcpu); =20 /* * Note, nr_memslots_dirty_logging can be changed concurrent with this diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index bc3ed3145d7e..b44eda6225f4 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -133,7 +133,6 @@ struct nested_vmx { =20 bool change_vmcs01_virtual_apic_mode; bool reload_vmcs01_apic_access_page; - bool update_vmcs01_cpu_dirty_logging; bool update_vmcs01_apicv_status; bool update_vmcs01_hwapic_isr; =20 --=20 2.52.0.223.gf5cc29aaa4-goog From nobody Tue Dec 16 07:34:27 2025 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.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 2D4F82DF128 for ; Fri, 5 Dec 2025 23:19:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764976771; cv=none; b=dYd6Y8SXO2yVj7z7kH59aHQgaPn/bm4Fe/0NSMz2oWUwUF1S7smoZt8fEOrUihCUYOaFOj+Z8Du8M/5sn8WTf9ze5y1exEqwk4+yiRvOi0m6/5CJvCGokuBed0XhrGQ15uk+Vv4Z2QBVY0QosJXNpHe2b+PSdYGNePYaxyzNuq0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764976771; c=relaxed/simple; bh=Iz/PdNNvwiToa3bILkudY0rFq88iIR9xc2DDP4kGkh8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=kWIr9hesw3f8FGTmz3M5FQ5dRtDjFGZfFO6GTJPwx83om/uhAbUiQkV4qISrSgu5m4HaTyFFwRDeHwv3Ja8pjhRcy0MP1npkSeW4MayHJmcGlwIcooPArSh8YBTy5uos1/B9oPc6NhcSq2VrWIQI9AfGHOlOeepHKDeoCKN5yI0= 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=gE/QjKne; arc=none smtp.client-ip=209.85.210.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="gE/QjKne" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-7b89c1ce9cfso2633871b3a.2 for ; Fri, 05 Dec 2025 15:19:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764976766; x=1765581566; 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=uei+FBCp6XSbN3s6wo1y2mN6ct0eKDDXjuxrLY/MXh4=; b=gE/QjKneIbRRLyCDWr1jewAjR3v0jgFyPultOww+DNkb7JHyCGhqT6L0XiHi64AO8e LOSfC0Oez+p6i/xUMOPDcj4s1zOTQf44Pl7oZuI78jQ7r4ymaCOyJMTiaOv9eNelo8ik 8ym3/jR/zRc3/2tC2V13s0ckUcDxtGrr/rkys6z/0Vrfbq17lWlqwaU4pQZ82wgpk5GR TL5VcIwujuXw2xTz/J97lS0XC6TmijWRwSpFSLXf7KcuasbzbQs3DcU/NrwVQ8bu5icx F5IO11Whe2CkgQGOY5z+Kjz5HWjDYuA6T48SoSAc0x1F46yrHhDpfLAZtmNc+YKnHPkD dRqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764976766; x=1765581566; 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=uei+FBCp6XSbN3s6wo1y2mN6ct0eKDDXjuxrLY/MXh4=; b=sgEcM96vg2Bkrpj00HPMF/ZoxvDl+RBQz3QWwXOoi6CJr4mVnQCnNREkxoI+jN3z+r kwqNIO6UVeT9prphKoxXTQUSvYfBJv5EHmOQlkkEo5iSQGbzD2MzeSm/BlDr0ZCQS2Ez wgyVyI01wtRCOLDQI4OviTyfS3OVZOsObzLpGg02kkBJDPnzK3Oi7NLDthvFyCbX45gM pwm9tS7nO0syhMiL05Y/3tLpwUhqKHPXFmgyHTsktG+1u6/tpSO+7K5QiAoc5pGIYy1l ZiL3V9JeAPCBvtbxMo/Q8SaHUfpAK9kLaqG1sODRis2dmI3Z+HdvlrNjM8DCkW5OMf34 QQLg== X-Forwarded-Encrypted: i=1; AJvYcCU/y+cxJ1TZC74Xb5lKSscfGmqb5X23lFVpCjB4LAA12eYmkTBaE/tTpx1Jdl8U1u+vPhZwB5RZcwbtGJ4=@vger.kernel.org X-Gm-Message-State: AOJu0YyL14Iwg7au6Hujh60ehBIadUsnNzH31whL7xm87xXAwpKFTYVP fxQN0bkbh5OTGuvM1yBM+Mmm30qqbB6qCrewMJmsAKlkdievNS4v19bgOv4MulbMwhfb58NJ6st LvfJCqg== X-Google-Smtp-Source: AGHT+IHvwjR/m6NdvCSTi9F88Nx4U6tu2ksUiv6cW14/aypzQz62E6H2QrvIw9QHUoJfvHKc1gUxiy78M6M= X-Received: from pfbfa36.prod.google.com ([2002:a05:6a00:2d24:b0:7dd:8bba:63a2]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:1ace:b0:7b6:ebcb:51eb with SMTP id d2e1a72fcca58-7e8c02094c9mr708360b3a.17.1764976766283; Fri, 05 Dec 2025 15:19:26 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 5 Dec 2025 15:19:08 -0800 In-Reply-To: <20251205231913.441872-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: <20251205231913.441872-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.223.gf5cc29aaa4-goog Message-ID: <20251205231913.441872-6-seanjc@google.com> Subject: [PATCH v3 05/10] KVM: nVMX: Switch to vmcs01 to update TPR threshold on-demand if L2 is active From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Dongli Zhang , Chao Gao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If KVM updates L1's TPR Threshold while L2 is active, temporarily load vmcs01 and immediately update TPR_THRESHOLD instead of deferring the update until the next nested VM-Exit. Deferring the TPR Threshold update is relatively straightforward, but for several APICv related updates, deferring updates creates ordering and state consistency problems, e.g. KVM at-large thinks APICv is enabled, but vmcs01 is still running with stale (and effectively unknown) state. Signed-off-by: Sean Christopherson --- arch/x86/kvm/vmx/nested.c | 4 ---- arch/x86/kvm/vmx/vmx.c | 7 +++---- arch/x86/kvm/vmx/vmx.h | 3 --- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 920a925bb46f..8efab1cf833f 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2402,7 +2402,6 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx= , struct loaded_vmcs *vmcs0 exec_control &=3D ~CPU_BASED_TPR_SHADOW; exec_control |=3D vmcs12->cpu_based_vm_exec_control; =20 - vmx->nested.l1_tpr_threshold =3D -1; if (exec_control & CPU_BASED_TPR_SHADOW) vmcs_write32(TPR_THRESHOLD, vmcs12->tpr_threshold); #ifdef CONFIG_X86_64 @@ -5144,9 +5143,6 @@ void __nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 v= m_exit_reason, if (kvm_caps.has_tsc_control) vmcs_write64(TSC_MULTIPLIER, vcpu->arch.tsc_scaling_ratio); =20 - if (vmx->nested.l1_tpr_threshold !=3D -1) - vmcs_write32(TPR_THRESHOLD, vmx->nested.l1_tpr_threshold); - if (vmx->nested.change_vmcs01_virtual_apic_mode) { vmx->nested.change_vmcs01_virtual_apic_mode =3D false; vmx_set_virtual_apic_mode(vcpu); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 1420665fbb66..3ee86665d8de 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6827,11 +6827,10 @@ void vmx_update_cr8_intercept(struct kvm_vcpu *vcpu= , int tpr, int irr) nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW)) return; =20 + guard(vmx_vmcs01)(vcpu); + tpr_threshold =3D (irr =3D=3D -1 || tpr < irr) ? 0 : irr; - if (is_guest_mode(vcpu)) - to_vmx(vcpu)->nested.l1_tpr_threshold =3D tpr_threshold; - else - vmcs_write32(TPR_THRESHOLD, tpr_threshold); + vmcs_write32(TPR_THRESHOLD, tpr_threshold); } =20 void vmx_set_virtual_apic_mode(struct kvm_vcpu *vcpu) diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index b44eda6225f4..36f48c4b39c0 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -184,9 +184,6 @@ struct nested_vmx { u64 pre_vmenter_ssp; u64 pre_vmenter_ssp_tbl; =20 - /* to migrate it to L1 if L2 writes to L1's CR8 directly */ - int l1_tpr_threshold; - u16 vpid02; u16 last_vpid; =20 --=20 2.52.0.223.gf5cc29aaa4-goog From nobody Tue Dec 16 07:34:27 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 B6E602FFF81 for ; Fri, 5 Dec 2025 23:19:31 +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=1764976775; cv=none; b=uwAnYPU2ZGGkRMBrgyo4AI9/jBqO6DEgQCzpyKrgpYtnqyC8v7oTl5aG3mN6UGoiReIzpg6ZYx9aOYgSjmzLkhVcGpu1e3vNfUKqgDOEHKvHSDayDssmIkSNbTCudo1ditbwD/5BeFCq4W3t0vEAsZfgjTDs80nyHZYvHx7n1gQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764976775; c=relaxed/simple; bh=F9ad1wjbwQOARvbkDcajWfewiLy5rWUDB66kZlDmZ60=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=hN39Fvc7FIHkuDtxUg+Mel6l5ZFXGtScmDZgUhCpoyXG6bj5iMvhZiKouNuooT3Y0ztT2YZ/Krq2FzcmWIu3zn8QolQ5P6pzkUwT8Q/RRyvOSOR5oHma9rQ6sSmThnE0Z21UOgoA27wrlaHa5flOLUEO5ZOx9EVixMhUYGpg0Y8= 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=0uCEu18Y; 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="0uCEu18Y" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-349aadb8ab9so34189a91.3 for ; Fri, 05 Dec 2025 15:19:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764976768; x=1765581568; 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=r75KP3MfE3xvB8M90mZtNcH7CuSSTaOPShGdGL5u5R8=; b=0uCEu18YIJe417Jps0aU4Xep7Jcz/n77HR2rItyibhuSDSjmHqvTM2/x2AzPgbPSsx DcBGyBJXxGAAJ2Yfig0f9bLvMVSLvGH6GfpqoO9wPS6Da8YEI+C1U20p3TZIkCed80dO qlsc91qa/Lq+TZd9eCo6O3WhSOns//GD9k7HhsL+Sefc5RMP5WvskEpUj+4CMbt0iLvJ zR/uIIfEJmaRTTHPbfTHvxmHDveC6Z2TmEh+sH6rxqEanEcgt9zGEA7jJcx6XaF/E2kd hfT2aYDy+Cc4EONSNPJhMV0j3nKEJmwKwjWTsqSngpW++zEv5GD2Q1hPtQkhUb5j1H2B aMHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764976768; x=1765581568; 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=r75KP3MfE3xvB8M90mZtNcH7CuSSTaOPShGdGL5u5R8=; b=mOiVKQjDdlyP9PRzEz4GlvAoHpe7YQLWJOYqwU374Luz1q19wPZr8BrPz60HNjl56Y 7gYEuYeoAGFPprWYPpa5u0NxbPhYb5UJwEGl/YnRpR79EMd1mebLfwZXN2dRoKpczfX6 iOKGp+ZttRSI1num79iNT1MPWSaPuWHrPpZ6CDTOoyKx9scdbnqDW7/XzHf06dkFUYEt YqsEbV3UY1vGbNrt7aRAR9lAtcht/os/qpV1fIbEwfedtx0AnklMtMsnVzsmimKsbMxS vLU4f1P1cv+qaQ5Ohpr/tfKJGkmVvSeIa/p6keu5Fdd0cCYBHSalkfpNi7hveHGe3WAT 7ptg== X-Forwarded-Encrypted: i=1; AJvYcCXmQMpnCD6DkD+fHbU85AOVvCSJYUKPCBYpmFa6RfvrPzHNXx2QhIu33cptKwKhn5U2h1Bm7n6RdQdnG8s=@vger.kernel.org X-Gm-Message-State: AOJu0YxF2lZMWjLtrDgH+udANXK82oEjoCr9XDdeOCLy4KqR9wYQUxJN 6F0511KGO0e57kveCklHW8P1DHS2zeKD9IPBlC4lC4HA8p6BSOKm6y3b9ZV6sCQihS3486RwVkJ JtI71WA== X-Google-Smtp-Source: AGHT+IFIPU3ezuGe142lObXM6m/a25sKwMQh+YMXUKaG0a4fm8UgxypvPkcF9Z9j64FfB0DY5nuDnt5zf3k= X-Received: from pjbmv10.prod.google.com ([2002:a17:90b:198a:b0:349:2946:c225]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:4a08:b0:339:d1f0:c740 with SMTP id 98e67ed59e1d1-349a24e48a9mr522061a91.1.1764976768536; Fri, 05 Dec 2025 15:19:28 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 5 Dec 2025 15:19:09 -0800 In-Reply-To: <20251205231913.441872-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: <20251205231913.441872-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.223.gf5cc29aaa4-goog Message-ID: <20251205231913.441872-7-seanjc@google.com> Subject: [PATCH v3 06/10] KVM: nVMX: Switch to vmcs01 to update SVI on-demand if L2 is active From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Dongli Zhang , Chao Gao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If APICv is activated while L2 is running and triggers an SVI update, temporarily load vmcs01 and immediately update SVI instead of deferring the update until the next nested VM-Exit. This will eventually allow killing off kvm_apic_update_hwapic_isr(), and all of nVMX's deferred APICv updates. Signed-off-by: Sean Christopherson --- arch/x86/kvm/vmx/nested.c | 5 ----- arch/x86/kvm/vmx/vmx.c | 19 +++++++------------ arch/x86/kvm/vmx/vmx.h | 1 - 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 8efab1cf833f..c2c96e4fe20e 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -5160,11 +5160,6 @@ void __nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 = vm_exit_reason, vmx_refresh_apicv_exec_ctrl(vcpu); } =20 - if (vmx->nested.update_vmcs01_hwapic_isr) { - vmx->nested.update_vmcs01_hwapic_isr =3D false; - kvm_apic_update_hwapic_isr(vcpu); - } - if ((vm_exit_reason !=3D -1) && (enable_shadow_vmcs || nested_vmx_is_evmptr12_valid(vmx))) vmx->nested.need_vmcs12_to_shadow_sync =3D true; diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 3ee86665d8de..74a815cddd37 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6963,21 +6963,16 @@ void vmx_hwapic_isr_update(struct kvm_vcpu *vcpu, i= nt max_isr) u16 status; u8 old; =20 - /* - * If L2 is active, defer the SVI update until vmcs01 is loaded, as SVI - * is only relevant for if and only if Virtual Interrupt Delivery is - * enabled in vmcs12, and if VID is enabled then L2 EOIs affect L2's - * vAPIC, not L1's vAPIC. KVM must update vmcs01 on the next nested - * VM-Exit, otherwise L1 with run with a stale SVI. - */ - if (is_guest_mode(vcpu)) { - to_vmx(vcpu)->nested.update_vmcs01_hwapic_isr =3D true; - return; - } - if (max_isr =3D=3D -1) max_isr =3D 0; =20 + /* + * Always update SVI in vmcs01, as SVI is only relevant for L2 if and + * only if Virtual Interrupt Delivery is enabled in vmcs12, and if VID + * is enabled then L2 EOIs affect L2's vAPIC, not L1's vAPIC. + */ + guard(vmx_vmcs01)(vcpu); + status =3D vmcs_read16(GUEST_INTR_STATUS); old =3D status >> 8; if (max_isr !=3D old) { diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index 36f48c4b39c0..53969e49d9d1 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -134,7 +134,6 @@ struct nested_vmx { bool change_vmcs01_virtual_apic_mode; bool reload_vmcs01_apic_access_page; bool update_vmcs01_apicv_status; - bool update_vmcs01_hwapic_isr; =20 /* * Enlightened VMCS has been enabled. It does not mean that L1 has to --=20 2.52.0.223.gf5cc29aaa4-goog From nobody Tue Dec 16 07:34:27 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 0DCCF158538 for ; Fri, 5 Dec 2025 23:19:31 +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=1764976774; cv=none; b=MocR0xrXWEa9mhzKRlOqE6RKM6hIF3hoib+MLyiIP+YGrIWgj/XpUlJ8bGngBykji83PUxwBS9+f/4ntAw5CJHMl38ancyX2zbONazBeWMwmHGsW5KhDO+6bMoYEanwDhLF6MctU0FoK5pHjXiCRtYo2XLTaUo6MULJkWnJcafQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764976774; c=relaxed/simple; bh=Y3y9z5Dem+sGP084lKmrwtv8wTb9CyaL0moHFIEpymE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=HANKm1ctVS3lAR0bUaYULLmDfYO+NXOjiKZGfBCz9aZsA+aXTSidvGO738BRq6icsT7XKVsCO4EUJ08K1gOJsc/vtPuIby6GmIECKlCGPUe+l9bgfFAVj5JZ0etgPhntt5kaCHECnUkCUzMSGt7xIoNvm3Z4sBFTffwalbq+l8w= 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=ADTPRA4/; 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="ADTPRA4/" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-2982b47ce35so36472235ad.2 for ; Fri, 05 Dec 2025 15:19:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764976770; x=1765581570; 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=zRgsu7txhPlymPyldYkGSmbzB+dNiAxZ1OO2LYHMK9o=; b=ADTPRA4/xH7V9qUeu+cvCU9Yl1pJSmYZqoKfG65JZcUBuQNNKAm8UopIPb6touMDSm P2uIBOe9cWtzLo6JtW8T5rsK7TXKCR6SINWprT6LUImShJPZ0iJxDyW4DgSssoA6Lg/w EOQqVHN6T9KCcDoKrUbbGIjpoUR9cKw2i8XzgjaTl2z6bogVN58NKtVnVbm+4E0uJTew a87gcGRt3/Yo2SWszRA/2He3sOavYNGvXcR7umi/ueV1D9z2Z7R8yM5IkPDtsQTPJCa+ 0XCtl+Hk8valmv/sBGF8OnTR/leBjjiUClVZbX+tCODHEJvHhOf3nG5gNCLuM60RDyy+ h73Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764976770; x=1765581570; 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=zRgsu7txhPlymPyldYkGSmbzB+dNiAxZ1OO2LYHMK9o=; b=RHWE/0khUy9EiV8Fdd6ararYrzP3QG+pgaoCLRgbGuPBqGB01pfOTLpbyZ9kFe4NGD pTUsqz27q81HvrqGINmGJ9MzNc7QZT1BxNxi8e16C8xczayPCIqsixBTVmzm5515b9P8 eLb/8iLW/2bMnOHRYVpptvWpI7J5X4ePRD3Ut0I6c2Arhto+5p0zfYXHStTTyMLYtNOp rkf13alU4VjIlFM1yElHpfxHqBbg3DtnztYAVghE2hEenhtv9DX9FvLBB3tpZRfVAvM/ 1OiKLSyJzU2bGFnT/qoaT6744EcxC9Ud7wGZPdKT3hhnqAvZ5P78V83vojFLhu+LjKtF A3Dg== X-Forwarded-Encrypted: i=1; AJvYcCWkauW1Q8p9hRA2VE7Jwf7G8Ftl1GT+n40uT0PsmIQ/yeQf/WKZ8XeRbX9tpANqHoj29dD9AqBkexVmAlw=@vger.kernel.org X-Gm-Message-State: AOJu0Yy3PZos4ygb2LP1kjCfUFyqcqswpi9TWUQNhj0mL84UD0E1AkmG iqXffx2xyEewEH9Q4YKalS1bmNCA9BwKd7nAmGTRInCu3JseX4YinmYmQQsx3rs2Wx2J2dIJ35Y 7aA6uog== X-Google-Smtp-Source: AGHT+IFTYHrkH7tC3zMkHferO+2I19/FJ006vgRJJ1FgLAVFgB7GWM6536sdWq1jx6EJRqwNjneRG2Nv/4o= X-Received: from plld18.prod.google.com ([2002:a17:902:7292:b0:297:d4ca:8805]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:b0e:b0:295:8a21:155a with SMTP id d9443c01a7336-29df5bb4030mr5967455ad.35.1764976770121; Fri, 05 Dec 2025 15:19:30 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 5 Dec 2025 15:19:10 -0800 In-Reply-To: <20251205231913.441872-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: <20251205231913.441872-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.223.gf5cc29aaa4-goog Message-ID: <20251205231913.441872-8-seanjc@google.com> Subject: [PATCH v3 07/10] KVM: nVMX: Switch to vmcs01 to refresh APICv controls on-demand if L2 is active From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Dongli Zhang , Chao Gao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If APICv is (un)inhibited while L2 is running, temporarily load vmcs01 and immediately refresh the APICv controls in vmcs01 instead of deferring the update until the next nested VM-Exit. This all but eliminates potential ordering issues due to vmcs01 not being synchronized with kvm_lapic.apicv_active, e.g. where KVM _thinks_ it refreshed APICv, but vmcs01 still contains stale state. Signed-off-by: Sean Christopherson --- arch/x86/kvm/vmx/nested.c | 5 ----- arch/x86/kvm/vmx/vmx.c | 5 +---- arch/x86/kvm/vmx/vmx.h | 1 - 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index c2c96e4fe20e..2b0702349aa1 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -5155,11 +5155,6 @@ void __nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 = vm_exit_reason, kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu); } =20 - if (vmx->nested.update_vmcs01_apicv_status) { - vmx->nested.update_vmcs01_apicv_status =3D false; - vmx_refresh_apicv_exec_ctrl(vcpu); - } - if ((vm_exit_reason !=3D -1) && (enable_shadow_vmcs || nested_vmx_is_evmptr12_valid(vmx))) vmx->nested.need_vmcs12_to_shadow_sync =3D true; diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 74a815cddd37..90e167f296d0 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -4578,10 +4578,7 @@ void vmx_refresh_apicv_exec_ctrl(struct kvm_vcpu *vc= pu) { struct vcpu_vmx *vmx =3D to_vmx(vcpu); =20 - if (is_guest_mode(vcpu)) { - vmx->nested.update_vmcs01_apicv_status =3D true; - return; - } + guard(vmx_vmcs01)(vcpu); =20 pin_controls_set(vmx, vmx_pin_based_exec_ctrl(vmx)); =20 diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index 53969e49d9d1..dfc9766a7fa3 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -133,7 +133,6 @@ struct nested_vmx { =20 bool change_vmcs01_virtual_apic_mode; bool reload_vmcs01_apic_access_page; - bool update_vmcs01_apicv_status; =20 /* * Enlightened VMCS has been enabled. It does not mean that L1 has to --=20 2.52.0.223.gf5cc29aaa4-goog From nobody Tue Dec 16 07:34:27 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 87EAB30148D for ; Fri, 5 Dec 2025 23:19:34 +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=1764976776; cv=none; b=YoBAO9gU9xjyLFr+ThiCwOVhB1xEaTrBPSr0Gy/LjCSS6rG+zZiTGdOUiMitPZHFeX414mzKYq5XYGgqutmWpngLzjI6pAqO0FgM/Najth9GLtAGK2eKSTxpJtuc+OSjVYH1jGjFU+x41MAHUrVBIHcOpVvg1lGMThLul7x/tc4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764976776; c=relaxed/simple; bh=XbPk5Zu3tIL1j399oAQsxtB7EnPcWv++KAizvepSQe8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=G+AXtYgEdBTVrWMlzffqK1JUn3U87amCl/IuswJAYubauPNSYgfHIZsf4nhX1zB7ia8rgynSE3ZBuU7XwC3tCZ6N25UYRt2iuzJ3kTLYUBjuz3i/f3i2Tjn/IT9G1l+dyn48fWrMojRa7DA7vmiC8hqad8XNXWnaWsmj86RxT1g= 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=hq+ookEE; 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="hq+ookEE" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-29da1ea0b97so53066575ad.3 for ; Fri, 05 Dec 2025 15:19:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764976772; x=1765581572; 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=lP72w5ANPVDKsXEE/wDJK3tXHkJNHOZxvL9A3UxnMuQ=; b=hq+ookEEOYL89/PbkmUhAMAMayac2mPlX7fXKvRwz3m59Ip3DVTFhj2pbN6W/88hJ5 MCZdyTxG5D9dA2Q2UlB50UUo93Q1xH8gfCIYwWadBa2p/3UHOe+wZfln9CHpOCk3z4nI 3AZTc/Ll1MqVKIcEUs/mMbWOpW8WFxkN/4AWeEKWztVTlUO+WX7qiryYYunWy3kZWq2+ BplS99JTomyhDV1OKFCOfNBBJw3hj1TBhJu0Uf0DNe/nUYwzSKWg+x00YE4VxE3Ow3xR xPuMp+yOIbNubU/zkVc5C+HJSeBUh6OKImTCGVMLME+E/QySPLYrCMqlcbQYAEnGlKzp J9Cg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764976772; x=1765581572; 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=lP72w5ANPVDKsXEE/wDJK3tXHkJNHOZxvL9A3UxnMuQ=; b=e0dnUS1sfTsjA4CCwPIAdMSGoLJHZdhqMiEOhkISAucRzKefC55GFT7ErGtzjQ3Fq+ M/PXkuKT11jiGSpco99XPjOpWXfKHjLzB44HjQdqrmlflgo24BO9qm4QtWZTH+o5c008 9d/TF2H3Amm1R7j7OS8PfQjOxD5sN8afRy2aLGDSHHDur9bV76eNBPsFvZXt68nndhkw xnDVlAJzn4pBWHHId4liExkp7Js4A0ypmuow9393NEpo/RZE0J/fbvfYwbt1Xb5+pTqI g5vXaH/O/XlUIrnQmIfQaeHbqyssYRvgwRIt0WrKkVrzsMiEX+p8m77Gj9UtOSE4gmTV K65Q== X-Forwarded-Encrypted: i=1; AJvYcCXbVE6j9A/mZXLUacagqEeOvBCvqiRL6r/Guig0YOwcbaaiTrosuneav+4HZa6xtqelWZ/aARfK4zEDpZs=@vger.kernel.org X-Gm-Message-State: AOJu0YyuZI+sFPc6DwuK34zRmlzLhdk7t6pPeZ3QrQeEAjmS6ZSUzimZ hsQgnzIG8Ni3fJKVJfV5b+ak6ffpvcsLPHd3ZH1GuXsOgx1anvtVMf52SvkwAtOeXp4LGKLWP2C 4DfP/qg== X-Google-Smtp-Source: AGHT+IEcncbfzY4bTcbh3luKcr7xp+BgCYnZ3O4gVPcdWIBEayevCgcT/VujQOwDhDSxPh7S+ZSKPXOjFXg= X-Received: from plpo17.prod.google.com ([2002:a17:903:3e11:b0:29b:89b3:77b5]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:2f8c:b0:294:9813:4512 with SMTP id d9443c01a7336-29df5472d05mr5187925ad.3.1764976772004; Fri, 05 Dec 2025 15:19:32 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 5 Dec 2025 15:19:11 -0800 In-Reply-To: <20251205231913.441872-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: <20251205231913.441872-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.223.gf5cc29aaa4-goog Message-ID: <20251205231913.441872-9-seanjc@google.com> Subject: [PATCH v3 08/10] KVM: nVMX: Switch to vmcs01 to update APIC page on-demand if L2 is active From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Dongli Zhang , Chao Gao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If the KVM-owned APIC-access page is migrated while L2 is running, temporarily load vmcs01 and immediately update APIC_ACCESS_ADDR instead of deferring the update until the next nested VM-Exit. Once changing the virtual APIC mode is converted to always do on-demand updates, all of the "defer until vmcs01 is active" logic will be gone. Signed-off-by: Sean Christopherson --- arch/x86/kvm/vmx/nested.c | 5 ----- arch/x86/kvm/vmx/vmx.c | 7 ++----- arch/x86/kvm/vmx/vmx.h | 1 - 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 2b0702349aa1..8196a1ac22e1 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -5150,11 +5150,6 @@ void __nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 = vm_exit_reason, =20 nested_put_vmcs12_pages(vcpu); =20 - if (vmx->nested.reload_vmcs01_apic_access_page) { - vmx->nested.reload_vmcs01_apic_access_page =3D false; - kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu); - } - if ((vm_exit_reason !=3D -1) && (enable_shadow_vmcs || nested_vmx_is_evmptr12_valid(vmx))) vmx->nested.need_vmcs12_to_shadow_sync =3D true; diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 90e167f296d0..af8ec72e8ebf 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6895,11 +6895,8 @@ void vmx_set_apic_access_page_addr(struct kvm_vcpu *= vcpu) kvm_pfn_t pfn; bool writable; =20 - /* Defer reload until vmcs01 is the current VMCS. */ - if (is_guest_mode(vcpu)) { - to_vmx(vcpu)->nested.reload_vmcs01_apic_access_page =3D true; - return; - } + /* Note, the VIRTUALIZE_APIC_ACCESSES check needs to query vmcs01. */ + guard(vmx_vmcs01)(vcpu); =20 if (!(secondary_exec_controls_get(to_vmx(vcpu)) & SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index dfc9766a7fa3..078bc6fef7e6 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -132,7 +132,6 @@ struct nested_vmx { bool vmcs02_initialized; =20 bool change_vmcs01_virtual_apic_mode; - bool reload_vmcs01_apic_access_page; =20 /* * Enlightened VMCS has been enabled. It does not mean that L1 has to --=20 2.52.0.223.gf5cc29aaa4-goog From nobody Tue Dec 16 07:34:27 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 E099A2E06E4 for ; Fri, 5 Dec 2025 23:19:34 +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=1764976777; cv=none; b=L+nz/WDTvVqeo+gsp3NLQaa9gJ4JjZFSOxAJTB1b97jTC888uaGdpgGfO4QU52cgrrarGYoDiuCevN67XGRIcyHYg0seuRWJT6pmAWtjzXNl0WagNh8Wx4ntoJlDOH2IuVDHOSCOG2/8vYBjAQV6Dxyjeply1W2COo50CEJIb/g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764976777; c=relaxed/simple; bh=nyBOMcsqOad7IoLOo0q40mFK6aPw3NvQd2nvH1ocBgQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=fLmWz9fTRXDWwY6gzC8uiAkn8eAhA719htUBK/kOwcEurbhwFA9D0FalhPMf5iVDa14TMB1JaQf1P6k4NozzEPA1dasj4ZRDNrRIAmKbmbO2N+YKKKRGBsdu7lF50EV3ACdSFhOcmKaiFqL4M8SG+Hz3Qhkj3vSTJv0K79j3ntA= 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=puAV1KyX; 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="puAV1KyX" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-3436e9e3569so4520642a91.2 for ; Fri, 05 Dec 2025 15:19:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764976774; x=1765581574; 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=IsexBN3HLqIzHAM1sNf2bQBLDWiAlBctQuC9XLUheco=; b=puAV1KyXlshPVQIIEhd543D5HpWnCzsGuKgXTa6dIJMC5vF62Etto68ZY8HMMkoLxK Kf7BCDK8cS0chXEi7YKaZgsluetwERqSlvcOiXxNbdKgu0heivAQn2xuAsV1hEY0eaP+ j11Lkpg+I5UfLI6T27fkYgvaVjYYsWRbolPlOP118tgXfPCWSJriicYR085xBUhwje92 xTTv5HQ34jr9+HB3DXa4ajLhuUgtCDIVmUYUOzz9heNLJv0ysQ0EISPuUcE3h2DSAODr oalOaSEccBZCK6Rjvmc6Plbw1/NfofAyKoWKsdGbyOn9k1YcJAIAzBcMPasGdj3ZSj17 rV4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764976774; x=1765581574; 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=IsexBN3HLqIzHAM1sNf2bQBLDWiAlBctQuC9XLUheco=; b=aw2/cfJ/TnGnqmHQMmwudyJCHnGIqDJXNyo1Ghwrarvq0l2GF+0h0d2V/I5jYMGw/G S3KUxnFD38knIrlATNPhrxAD4y1YgKlN5RgtxttsXPmIPMU8z9AO7YSeSKgJD5snsA2t ci5PgID3V+3NTzgaIh8hX/yl7XFXwwg5PWofUQLyZXKDRMRgSec5lAieFKhO2HI+ZdvD JEkEs0RKULmSEZMfA/DzMFlRsfKkNIrAolB07mnuHU7A+hDfLFwmH1xsEuBA8cmWCV5J 6AZ4iFdCoVYY1HMSlyenN7oWzXW50a+oeISMZBY3eUjZZdt0IXcheD6iLMfqo3uA8Iak JRJg== X-Forwarded-Encrypted: i=1; AJvYcCUeRmmoK2559dRqCPSPhQ+tdbyyacNXH+ZbU57JZsJCACnv+XyVgVA63H5LjMjUKriJIP5hh7cfwg3Im0Y=@vger.kernel.org X-Gm-Message-State: AOJu0Yy+2uyyny4TZ+cg/YeBGvw8WosQjGH085x1v0wgs/Xh9NMTAc1m 5dEgHcvb2zBJ6ngtPy+G83NyXuc82AZoSBSPaBQ6sIW04OhHQdQolyXp1JHU4QFtqUUgDlZ0tih nT4ekfQ== X-Google-Smtp-Source: AGHT+IF9TcyPCg1udOgDVkvfEtBjujDFLUwg7kUIcspQ/gscSHWTd+z00f00CIgGLLi0UWiscML0Yh1hEnY= X-Received: from pjbfw22.prod.google.com ([2002:a17:90b:1296:b0:340:b14b:de78]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:2886:b0:339:a243:e96d with SMTP id 98e67ed59e1d1-349a2610ecfmr427297a91.36.1764976773801; Fri, 05 Dec 2025 15:19:33 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 5 Dec 2025 15:19:12 -0800 In-Reply-To: <20251205231913.441872-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: <20251205231913.441872-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.223.gf5cc29aaa4-goog Message-ID: <20251205231913.441872-10-seanjc@google.com> Subject: [PATCH v3 09/10] KVM: nVMX: Switch to vmcs01 to set virtual APICv mode on-demand if L2 is active From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Dongli Zhang , Chao Gao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If L1's virtual APIC mode changes while L2 is active, e.g. because L1 doesn't intercept writes to the APIC_BASE MSR and L2 changes the mode, temporarily load vmcs01 and do all of the necessary actions instead of deferring the update until the next nested VM-Exit. This will help in fixing yet more issues related to updates while L2 is active, e.g. KVM neglects to update vmcs02 MSR intercepts if vmcs01's MSR intercepts are modified while L2 is active. Not updating x2APIC MSRs is benign because vmcs01's settings are not factored into vmcs02's bitmap, but deferring the x2APIC MSR updates would create a weird, inconsistent state. Signed-off-by: Sean Christopherson --- arch/x86/kvm/vmx/nested.c | 5 ----- arch/x86/kvm/vmx/vmx.c | 17 +++++++++++------ arch/x86/kvm/vmx/vmx.h | 2 -- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 8196a1ac22e1..b99e3c80d43e 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -5143,11 +5143,6 @@ void __nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 = vm_exit_reason, if (kvm_caps.has_tsc_control) vmcs_write64(TSC_MULTIPLIER, vcpu->arch.tsc_scaling_ratio); =20 - if (vmx->nested.change_vmcs01_virtual_apic_mode) { - vmx->nested.change_vmcs01_virtual_apic_mode =3D false; - vmx_set_virtual_apic_mode(vcpu); - } - nested_put_vmcs12_pages(vcpu); =20 if ((vm_exit_reason !=3D -1) && diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index af8ec72e8ebf..ef8d29c677b9 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6842,11 +6842,7 @@ void vmx_set_virtual_apic_mode(struct kvm_vcpu *vcpu) !cpu_has_vmx_virtualize_x2apic_mode()) return; =20 - /* Postpone execution until vmcs01 is the current VMCS. */ - if (is_guest_mode(vcpu)) { - vmx->nested.change_vmcs01_virtual_apic_mode =3D true; - return; - } + guard(vmx_vmcs01)(vcpu); =20 sec_exec_control =3D secondary_exec_controls_get(vmx); sec_exec_control &=3D ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | @@ -6869,8 +6865,17 @@ void vmx_set_virtual_apic_mode(struct kvm_vcpu *vcpu) * only do so if its physical address has changed, but * the guest may have inserted a non-APIC mapping into * the TLB while the APIC access page was disabled. + * + * If L2 is active, immediately flush L1's TLB instead + * of requesting a flush of the current TLB, because + * the current TLB context is L2's. */ - kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu); + if (!is_guest_mode(vcpu)) + kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu); + else if (!enable_ept) + vpid_sync_context(to_vmx(vcpu)->vpid); + else if (VALID_PAGE(vcpu->arch.root_mmu.root.hpa)) + vmx_flush_tlb_ept_root(vcpu->arch.root_mmu.root.hpa); } break; case LAPIC_MODE_X2APIC: diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index 078bc6fef7e6..a926ce43ad40 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -131,8 +131,6 @@ struct nested_vmx { */ bool vmcs02_initialized; =20 - bool change_vmcs01_virtual_apic_mode; - /* * Enlightened VMCS has been enabled. It does not mean that L1 has to * use it. However, VMX features available to L1 will be limited based --=20 2.52.0.223.gf5cc29aaa4-goog From nobody Tue Dec 16 07:34:27 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 A1D71302CB1 for ; Fri, 5 Dec 2025 23:19:36 +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=1764976779; cv=none; b=fA41LEc/zc7//iSPnLhyXKd0Sm80fcMwSfscwKLMXkqTTpYtnXRumYMP7k7kPXOTbJUfWdXHSciJwZfaQGr/dZLbPWSYuciE+PUEJeXTypuxAprTULM3EUB/rC1S6Zfl3uXMJMKtjC4trO5hNy4d8yQ4p6k1IRbq2dmMt3rJg6o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764976779; c=relaxed/simple; bh=fQs9AfY4pm0GPg9NaBoZ2jNCluwsJfr8qcla3WFMQ5U=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=JHw2PQ3Kh6pgjEeO0LHU/neAOV+fatru2i6kdD7Mi1io+tLgkrdbZm09ciej3mgJlVqVwWFBe5y06nauYOzBQTCte7X83pkY0Yu0Sg8BG7VGY/VtjwJKzjsPbiwW2Dp4K/XVd9zDyMODH3sl3Jw9eW6kDodGeYeF0A9bCIyCOYM= 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=14jDRNeM; 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="14jDRNeM" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-34374bfbcccso2279619a91.0 for ; Fri, 05 Dec 2025 15:19:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764976776; x=1765581576; 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=R6Kh5m2LegPUGsggLmMPv+v4opTfSNM4AlIRI1Wku5c=; b=14jDRNeMGHFHePsgl6Bf120m09Clveii24iiT00fajV9FuohrW8AJRiIryYxLiWzxz R0UwvwpI0MjTUFCpsEFx7X6WnH115uA2ZskBVrl62oorCCzYAQ2FWjUTos/mSQZL6LyO XEq74B115Ox5bmeCiRUVJFqLx39BkvrmoiV4h4g8n8iGZWso95YaQANL9RufxPMvir0a iDnlevPTmIldE4qUcwlqO0Ud8K/cdi+qVlZ5jHhr1oGuQJL/QmQyXTMjYSXWlegtXiTf 17rQn8ZD0Vuu+o8qiWoUKL9X7sl2Ue5pXMUjD5I1MnpN5/kZU6Ub89nU2Iw67XOkhCHG a3PA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764976776; x=1765581576; 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=R6Kh5m2LegPUGsggLmMPv+v4opTfSNM4AlIRI1Wku5c=; b=Xxv5hvNsRst/whBw7YLLAdOmk/7f3JedXHllsvwE0muvFvH1Bk4yJ+2GTVwV17RZNC 9pXBA6di/LmEZJWF3gGu4BklX28XnY2auOXLlls1rMonYFuDOlRfiiWGxA72keNIUkuo Txw1sf50V5+XRQmHX5jK7OkdFummHV+6sTDbwmMteQPCmrdqI8BklrQ8ZUVr0jeH2X5j dX0kAALlJ85bz4Tiq1EGAbqmQOW6SoZqEdmaCk1Hg7I+qMuKMWTljq94XGCjY7xX9Adb s+mj4BOS0GlOed2ow447pzW7SCWS9tNqx0mbWS0LoPck0WYnXxOVzYNixx6sOIWQn+N6 URXw== X-Forwarded-Encrypted: i=1; AJvYcCWXDOTVQv8HcTJPUwd7ZplTit5mYf8KTo9gl9dPFg4MvLpE00lAP2gX63uBEa8t3n0d+Gh3/bY+X1plx9g=@vger.kernel.org X-Gm-Message-State: AOJu0YzkqPir0YwlsFVJqsgfQiwa6kJn46AN3fakEUozP8en+dVI4B+x 2LoykzWPGYbFZqh7s9GXfkE6Th1vazhU4q5i5r+stjK5r5WHhNfMAfSLcVQUdb4EoUm0XIykpi0 KZNqpOA== X-Google-Smtp-Source: AGHT+IFHszwzJY+d/pKFPd2umP7/T4Pfq1HZsW4vbjXxV03FbJa0O3laYvMbjqBNzPWcHszIzGKJzLfhTxQ= X-Received: from pjis4.prod.google.com ([2002:a17:90a:5d04:b0:340:b1b5:eb5e]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:1d12:b0:330:7a32:3290 with SMTP id 98e67ed59e1d1-349a26ea323mr429506a91.37.1764976775849; Fri, 05 Dec 2025 15:19:35 -0800 (PST) Reply-To: Sean Christopherson Date: Fri, 5 Dec 2025 15:19:13 -0800 In-Reply-To: <20251205231913.441872-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: <20251205231913.441872-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.223.gf5cc29aaa4-goog Message-ID: <20251205231913.441872-11-seanjc@google.com> Subject: [PATCH v3 10/10] KVM: x86: Update APICv ISR (a.k.a. SVI) as part of kvm_apic_update_apicv() From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Dongli Zhang , Chao Gao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Fold the calls to .hwapic_isr_update() in kvm_apic_set_state() and __kvm_vcpu_update_apicv() into kvm_apic_update_apicv(), as updating SVI is directly related to updating KVM's own cache of ISR information, e.g. SVI is more or less the APICv equivalent of highest_isr_cache. Note, calling .hwapic_isr_update() during kvm_apic_update_apicv() has two benign side effects. First, it adds a call during kvm_lapic_reset(), but that's a glorified nop as the ISR has already been zeroed. Second, it changes the order between .hwapic_isr_update() and .apicv_post_state_restore() in kvm_apic_set_state(), but the former is VMX-only and the latter is SVM-only, i.e. is also a glorified nop. Signed-off-by: Sean Christopherson --- arch/x86/kvm/lapic.c | 21 +++++---------------- arch/x86/kvm/lapic.h | 1 - arch/x86/kvm/x86.c | 2 -- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 1597dd0b0cc6..7be4d759884c 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -770,17 +770,6 @@ static inline void apic_clear_isr(int vec, struct kvm_= lapic *apic) } } =20 -void kvm_apic_update_hwapic_isr(struct kvm_vcpu *vcpu) -{ - struct kvm_lapic *apic =3D vcpu->arch.apic; - - if (WARN_ON_ONCE(!lapic_in_kernel(vcpu)) || !apic->apicv_active) - return; - - kvm_x86_call(hwapic_isr_update)(vcpu, apic_find_highest_isr(apic)); -} -EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_apic_update_hwapic_isr); - int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu) { /* This may race with setting of irr in __apic_accept_irq() and @@ -2785,10 +2774,12 @@ void kvm_apic_update_apicv(struct kvm_vcpu *vcpu) */ apic->irr_pending =3D true; =20 - if (apic->apicv_active) + if (apic->apicv_active) { apic->isr_count =3D 1; - else + kvm_x86_call(hwapic_isr_update)(vcpu, apic_find_highest_isr(apic)); + } else { apic->isr_count =3D count_vectors(apic->regs + APIC_ISR); + } =20 apic->highest_isr_cache =3D -1; } @@ -3232,10 +3223,8 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct= kvm_lapic_state *s) __start_apic_timer(apic, APIC_TMCCT); kvm_lapic_set_reg(apic, APIC_TMCCT, 0); kvm_apic_update_apicv(vcpu); - if (apic->apicv_active) { + if (apic->apicv_active) kvm_x86_call(apicv_post_state_restore)(vcpu); - kvm_x86_call(hwapic_isr_update)(vcpu, apic_find_highest_isr(apic)); - } kvm_make_request(KVM_REQ_EVENT, vcpu); =20 #ifdef CONFIG_KVM_IOAPIC diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 282b9b7da98c..aa0a9b55dbb7 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -126,7 +126,6 @@ void kvm_apic_send_ipi(struct kvm_lapic *apic, u32 icr_= low, u32 icr_high); int kvm_apic_set_base(struct kvm_vcpu *vcpu, u64 value, bool host_initiate= d); int kvm_apic_get_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s); int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s); -void kvm_apic_update_hwapic_isr(struct kvm_vcpu *vcpu); int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu); =20 u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ff8812f3a129..66c5edbbda2b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10894,8 +10894,6 @@ void __kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu) */ if (!apic->apicv_active) kvm_make_request(KVM_REQ_EVENT, vcpu); - else - kvm_apic_update_hwapic_isr(vcpu); =20 out: preempt_enable(); --=20 2.52.0.223.gf5cc29aaa4-goog