From nobody Sat Feb 7 23:47:48 2026 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 C69722C11E1 for ; Fri, 9 Jan 2026 03:45: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=1767930338; cv=none; b=PH5bk6lVLrtt6UWLj7wDjirRITRCFA22KQYd+DV2WA5eokhAErRC/1n4S5SlHUcBvQyybg4VvhQKloco+p+UXEiOePR470pclucG4uenFVyMDE7ACMtE8yRisWvQRvV88sZq48cDV12tACcFeXQseTtntF/akbfE7knFZgU6OEU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767930338; c=relaxed/simple; bh=HrbrtY53Z04do46sxpdw6vWSFMqntMt3jnTtKj1ZEjI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=sRHpeJOJVV6s1QTArmUalKjeh/P7x0ch8WfwIBjtarxeGjDyhxfC5zH6wC3NcIcg1BqjYHxZuLDJg2Gt1/HPN1nkTIiGCrWxQpi+RftakgvjQMaNhLWLBrp/gHXlmLh9bJ+dJ3bqiPMCBwFQaEQNiK3IsrfcxHD4a6d4/swY3f8= 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=3ePBwrgc; 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="3ePBwrgc" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-34a9bb41009so5427786a91.3 for ; Thu, 08 Jan 2026 19:45:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1767930336; x=1768535136; 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=V9I2P65QJ5ZJ2Hyc5FjqLOkel5dKeneY79WO6C867VY=; b=3ePBwrgcUdUPpwRCDp8Kujq98cce6gtLla2DX0eDOmnUjy+ZKOq4382JkRbsOqhF4X WkqwgPc7+LkhSSK8OZ9Z2BMhD3f7rUg7hlse7APgKIz5EhEr1LcQMWr/sMjtPwZ6vynB COSDEg+1XgSrdjg/3EwkWP6LnI1k3t/bOXZZ0UIabF+vxAp4/a1CWN9pPSiZ21IpBgnw oSQn2X6meVocTAwY6UKlIolybwgFuHFXjDAFztHcnJ41KZoU/wqK8o0MZjaPFnG0069U XDrzyl83eD6IYh6dRH92ZC4oOzNIM7H8d90vXiesgvq2Lt5ImNwJuITgC20fGyRfH9hN 6rKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767930336; x=1768535136; 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=V9I2P65QJ5ZJ2Hyc5FjqLOkel5dKeneY79WO6C867VY=; b=dMsqAQ7EAXZmJ27+W+jfaNoV4Z6zrfEq+9xKHG5nXkBIt+5qI19V9s3MpAEyTRUlzF HKDH+vnnLPgndLbwjExfpEZSbJ9ZVekUF7dwT/2Y6RJX/YZFEYJELApHhmq94wEFkTH0 RzRXwzO6XJSrkF6B3uDGv9ed/vKZKkhKy3wjw+xf1jfPC1dnD+NkMnzBAbznaDo+YQKZ cv+6CEag6BqsULbPGmW0eqgoGZf0REPGT712bpQlNBDRx8bGr/RdATzgA56zWTcbx6jc xYTjxhD/AwxapQFqNhjmpVv2JablO7Eir/zKSb765m9l7FszFf+wU/oHQoWZnf5Zm0c1 DlNw== X-Forwarded-Encrypted: i=1; AJvYcCW18wxBDStipsBqyYDNDF4UGZXmwiOPJUFvXdEcN7SWgFnGGdvVfd1QQxOwJ1Egra4j1VMr3xid0tzpqng=@vger.kernel.org X-Gm-Message-State: AOJu0YzFW/ezxZq+zNCoGf2MDWZ6lvL+nnDbMAHMlewG6IXp7gf+HZJF 6K9bq6zoQqly3KgPZlDi1doPRndS/2oSO/cZ9DGAadzY3Mv7zJrOOERxqeYOMGo5nnj2jPmit/7 T+MB48g== X-Google-Smtp-Source: AGHT+IGjfh13G42GvqwGhcOnriZ4ua0Sp3Hzs3dXYEb6lNNyEaUavHEUfDRF7BVDjasM8X/DwOhg+yHd1I4= X-Received: from pjbha5.prod.google.com ([2002:a17:90a:f3c5:b0:34b:fe89:512c]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:2fc8:b0:341:88c9:6eb2 with SMTP id 98e67ed59e1d1-34f68c7a6bbmr7439400a91.1.1767930336140; Thu, 08 Jan 2026 19:45:36 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 8 Jan 2026 19:45:25 -0800 In-Reply-To: <20260109034532.1012993-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: <20260109034532.1012993-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260109034532.1012993-2-seanjc@google.com> Subject: [PATCH v4 1/8] 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, 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. Reviewed-by: Chao Gao Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/Makefile.kvm | 1 + .../testing/selftests/kvm/include/x86/apic.h | 4 + .../kvm/x86/vmx_apicv_updates_test.c | 155 ++++++++++++++++++ 3 files changed, 160 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..337c53fddeff --- /dev/null +++ b/tools/testing/selftests/kvm/x86/vmx_apicv_updates_test.c @@ -0,0 +1,155 @@ +// 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) +{ + GUEST_FAIL("Received \"bad\" IPI; ICR MMIO write should have been ignored= "); +} + +static void l2_guest_code(void) +{ + x2apic_enable(); + vmcall(); + + xapic_enable(); + xapic_write_reg(APIC_ID, 1 << 24); + 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, 1, 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.457.g6b5491de43-goog From nobody Sat Feb 7 23:47:48 2026 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 B75772DB79E for ; Fri, 9 Jan 2026 03:45:38 +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=1767930340; cv=none; b=UUHLBh1W5w/tc4Yv083y5x94LWG/sXmmGAYIJxwgYOnr3W3hdU9c927pysSKi0nIozRMvWfgMW5Zua5HrgCaPUKQfPKIyxO5N+6+vdRmItasKvXGRVLPbGHdmESPJ4PFMbT1aosXWB+mTHjyILbwzmZF+5zY4z1L1RLTuVFtfO4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767930340; c=relaxed/simple; bh=orWaPkiAuW5dWdX6xCjlTadYJ3ABx54C6lKaFm93YOI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ACbZC3FuK+a73zEOzrkZlL7TXqXVnzN4fopU/7AfknPGNnhuUE5+ByVc3QxxrqzOvcawmrsziE7d5nkw4iMiBERivcVPtJyBIIZjwgBvFf9R/P6INTSvTauWLbTVodj0xfu5jvxjRSCRccFblP1i7LtCTQ6RAJc50LTH0glKJSA= 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=azFhIlUD; 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="azFhIlUD" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-34e70e2e363so5213004a91.1 for ; Thu, 08 Jan 2026 19:45:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1767930338; x=1768535138; 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=NikTKJr2vdZDsmzh4h4fhl6av/cM1UMaxZuL4gTL4pg=; b=azFhIlUDLrRcRPimszwVs5/AmDCOfJOitIbXwrHhXzfsdRfnBQfdOUKcOkBjeYz9Wc VTQLNPdHCjt9G43PBVe4GV4GYzcEwp0/IxkzfLwoHYE8wFIYROp3DqXYYqChU27QC1sj xw100e3d/Fncgs7k68Is1XFrvkeqkj4GR1xauYeyR41HsGZFJkN9UoalpoJoh8LBkkWG vDkkpWmF71dR4oDr1m4leSaaPif0UEkkouose7Ue/UHxdraGhjTRS+Lkq7DRa9aU0psA HwZ3HZ3fp4YvaDh3Mfy1/yv/nlwcc5qyPbVM4iC9G62OWvApVqZcuG2VEo/emF/kDhL6 O3vQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767930338; x=1768535138; 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=NikTKJr2vdZDsmzh4h4fhl6av/cM1UMaxZuL4gTL4pg=; b=UChx7i/69HKA4SuDidypziRZjeAEHNkFw+Dy5/7rucocP36r4YtY3QHMU9HmAVJint rtXlrCXDOXZfVAUQjtN1JgEi2gjg+RdtSNuAF3sAd85URQ4IIb+O72fB/QWKZlrnzjyk FGk8yhXpWyYB1aP7SNg2AM63txWPR/nSmocRBHWXwwtYCEah4eAnK5yqa4bCYA4OPJPk +0nsARZBG2jygrOfdKmCl9RN7Ol29+OlfNv7APpur/4Q0V3/agRxY9pSMwhkq4DvE87H Gf46TSZk33oxLMouDZCUFXmISpRIfyv+zxbkthTYX2CPakZoin15+gwvt2JiRGPfW9Yw v9BA== X-Forwarded-Encrypted: i=1; AJvYcCWo1HojRhikxTVXjVUJk3UkyyZuTWU8dZ+s0N23ZxTHYHseRT2fW30VfEFmG7gzEQUP+jsTSVz0X8XGqLU=@vger.kernel.org X-Gm-Message-State: AOJu0Ywn9n0Pa/YUuOasii+tiXsmJKbPrlvrLHB7yV77lL4imTjENsYb 1UXC11O0kpXx1wYfdNRBiB1/GoT2NMy21W1Go1aNJ/Vfc+14DAPx3T3DTupCNXqe6luE9OSGpq5 FiEcTjA== X-Google-Smtp-Source: AGHT+IFQrJmdgyIMjO3aabN+GefhkhIHSPxGlLvPD9SKtJfdIwMArFhB//EsefNEDdNzyQmaMbWvHQOv21c= X-Received: from pjbch23.prod.google.com ([2002:a17:90a:f417:b0:34c:d9a0:3bf6]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6300:218c:b0:364:1318:caaf with SMTP id adf61e73a8af0-3898fa38c61mr7540200637.58.1767930337960; Thu, 08 Jan 2026 19:45:37 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 8 Jan 2026 19:45:26 -0800 In-Reply-To: <20260109034532.1012993-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: <20260109034532.1012993-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260109034532.1012993-3-seanjc@google.com> Subject: [PATCH v4 2/8] 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, 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. Reviewed-by: Chao Gao 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.457.g6b5491de43-goog From nobody Sat Feb 7 23:47:48 2026 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 8C39527FB32 for ; Fri, 9 Jan 2026 03:45:40 +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=1767930341; cv=none; b=Wt0l2DHF/v2rhvqPV+O2JHy0FJ33SXhcnyDchvU0e2MxPM6QmZSOvKzVaEI9XgrGBaqGiR/B+Oy1OIN7yfYc/QmvsKNSBz/1kamWT8EeYGWb1s8ukrMyO9L8vV8yiP5++dyQW+Pjbw9v8Y0YeXg7U8sesRofwqMOQwF7sl2ctjw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767930341; c=relaxed/simple; bh=ZT0U0x+9g09xqjPT/0E35x3IQPyKy+0Y8xFgFIMYoxo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=o08bp1z632s47o/QZMiv+r3uulhtzz0Ky+ekLxakduT2fdXsbik38l7DIr0KGlGiLVR/nGGvlGJxJNV6AQOTU4wWJEjt+Kw7/b3N8oKwMkvc41yDhlixoxEA3hQABFGSaPpW/IbY2NJbbRB+GyIC/ji2gCKXN2kC5DBmfPR/XMA= 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=w9W5jnfE; 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="w9W5jnfE" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-c52743b781eso1143920a12.2 for ; Thu, 08 Jan 2026 19:45:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1767930340; x=1768535140; 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=Tw76Itas1ms0nm/HkT0Q/pAxr8UdkEkAfo1cZSDlWBs=; b=w9W5jnfE+T415AKFUGHcuKSAeTkvlo0+LAFr14Y99zvK3R1x6zcrdPoPbzDEocSTaI tHd5K8hPynUiUqBU6xbv5ogviVB5npm3EQM0e/C/LHGf51oMLA0oNN5RescOC4batHqf P5kr04tPYDsI0OpBV+RdURKSY7JX4kx3hmfomj1z60bTV6oflki7bMi4AyWTuHYKrc3A rWdpseGIYCOc8CCH3cjffJrzqPkPg9lVwpjTxEJfHOS33XM20nQpNPNZ7DfDyX0TLgHz 4u2R9xH4UNAwBrJAJ2e7dCImU0gI35JahLa2dqiEbpcBciPsHLuJcVQCK8lKM5t1Jm1c bhmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767930340; x=1768535140; 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=Tw76Itas1ms0nm/HkT0Q/pAxr8UdkEkAfo1cZSDlWBs=; b=OFT69kAhzNrTczwDlYrisPahsomdbJJuyoeihR0cUtAc/HZEW/AbqKqvrunC06J0+i cbrSa0pCEFTesWJ2GbPKPlpOltlP281p2vSbzpkz4UXRm7IPulFSQwETMJu2rMMVD1CM kIiBMr7EzEpry5Nh3w9vbLjYk+Y7v7e3BCueRyYS7udN8CN7klvzKZTFGJUII3nkiYR+ HhPBhdC9QZxZE6hmYaipOUGlVbmyhp+41wk1StqirtJzy15DJqVtIJZOLChM0Aa+tYl4 iTdPKirOua99j6IQWiVkQdjx3qY2DN9VEautQJM06D8H8sy4FrFH6LyqG5SNlfwcm1dg RLBA== X-Forwarded-Encrypted: i=1; AJvYcCUWyA4xzI1Yp0CzvoOAvluzwODLU9IVXi4pPsSABZIkupn2I1j/dr3oJitTkPuTenwJmJx9Ph3TcHCEXyw=@vger.kernel.org X-Gm-Message-State: AOJu0YzxyXVESWj4tJQjovCevPU2JlIwlkyUA7nayX5aCkyC9fXWS1Io wNCntLt7mYMoLpl+YKWbLAME42HwiF205B4Os1PqZfFvQw/Uo/IkFeSfVmfjoxkTX5HGcQjfcgo gL9xT4A== X-Google-Smtp-Source: AGHT+IH/lW5NmDB9qcwr9rHXLQVjyDc1n512c0xaZbcjMwhrpfdV6CUAlAwGHdo+o0oKSpFcJVKDWx1AYVI= X-Received: from pjbgb18.prod.google.com ([2002:a17:90b:612:b0:343:af64:f654]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:7f9c:b0:364:134a:2bc1 with SMTP id adf61e73a8af0-3898f8cb991mr7774812637.18.1767930339801; Thu, 08 Jan 2026 19:45:39 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 8 Jan 2026 19:45:27 -0800 In-Reply-To: <20260109034532.1012993-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: <20260109034532.1012993-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260109034532.1012993-4-seanjc@google.com> Subject: [PATCH v4 3/8] 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, 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. Reviewed-by: Chao Gao 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.457.g6b5491de43-goog From nobody Sat Feb 7 23:47:48 2026 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 7A1CE2FDC4D for ; Fri, 9 Jan 2026 03:45:42 +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=1767930343; cv=none; b=dHDIe8OOt0W7GqU/27eBVCZLqqau3czGDil6rR9tHybCQWhCyZP2k6etZ19EJd4cUvp2O3bO1V48Hx+4t4u8tBbS+Wc+taxAK+z9eQEbkCQ+Uo+61uYTBcltvfCWcwvX18GaGnPM8aYyPrO+KcztS7DNby8ZrL4hgpGIk+trgGw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767930343; c=relaxed/simple; bh=JNTMhgYGQgtyJNjtw8vToWb4WTH4XkkwCy6YSvLCHJI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=GQ5ITMLXYFMkbHZKFKYH7lx1lNrmgWXAVFG7mAicmzOFST5o4UVSp0M9gfmwggZf3ePbkfR5vy/m4pl/YgUH2VrKeeVqKCb320POYn0MHil6dKrbhUPbrI83JvmzU5yfnVK8XcKVq7fwU9lKwwcNQaYtLIjgmgD6jitemuIyt98= 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=wzIKMCA6; 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="wzIKMCA6" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-c52743b781eso1143935a12.2 for ; Thu, 08 Jan 2026 19:45:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1767930342; x=1768535142; 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=riEO8rGkVD0LWXz3K6AdDhJyUv23hQGge3Scgd6g82Q=; b=wzIKMCA610x743KzO8Hozl2IoG93V+igQBCeERb0dzVW7vxtJZBjKBYwWBegCmYP4s 5NPYwP5JPrARfWrjIiCrxo5kGmv44PiHf+cplmp0K2IDz16plHo3L0NIWmrZG21cofdF fz885Fmx0R8qsddMPC1KeEHs0svlVXlJryQNqhhTeAlE5HkY5g0I7eryFnGx5DOEVhCR mb+3sVf9EsqTNVuZfQR/kcwXu3/F80TdHL1aJNmQub+zPqB6KCAJ3t4Yc0rcfHpBNlnr Q7FxwjQhJXgYjW26JA/amMUWy5gCbRFUCJKnXW1X8kIg4IvVydRCjjtF8CUhXUHxbT5C 3S+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767930342; x=1768535142; 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=riEO8rGkVD0LWXz3K6AdDhJyUv23hQGge3Scgd6g82Q=; b=JiqhKYFWiV9jlvwgVW+cyDYVVIRiJuVsD/wDqEay2pFMYIQhjVJz6NCofnpc/itOBj HorXwGx4dNB7xXiRwKCweY6pehhEE6lzasRlWTAoM6uoJQg1pZx8RptGisjtvkTs6Ilv js0mbrniIexO5ZQfEuXsPwIqHo5Xgt4baLivbNoOQ3q08cWw2jz1dX2gP77HiOV3cdMO TS6rWWcXblGvamvQE5gPlB2WYQZyTtIgQGBEEvqiAflfgcn7x9dbT9pPWqBKglL6tHYQ 2Wx5eUratSjABC1bBMLgLB5coUHIWCuHUByUhgxIIZQrtGjmot23vLa3w0hkAmwL8xhl 471g== X-Forwarded-Encrypted: i=1; AJvYcCWmqvPPlFPQCDboCjA8lcbUSri9thg1Imo1jpNgstfpALhT4gC1+cP1S1MgZjcKD1Wk89A9KxO1j0oKGUk=@vger.kernel.org X-Gm-Message-State: AOJu0YzpaHtLKI5kZ0lI+dmqkbkrAg1dTJRQWm7ZBnXpuotoKNoEK51x vWnuqjlj+IVgj4zz7RCdMO1LN7eL9vSH9TsbvLYbyipW7KJ2i/GSadl2CMCJT5w9kA3fS+2i6UL rO+FCqQ== X-Google-Smtp-Source: AGHT+IE0rWF4oD9F9ZCOJh0KeVUbkzSQAwujDJRsVmOEh0vsbQxymaB5ScAy3POMHmzqBRcqwUw8ZJ+5w5I= X-Received: from pgkh12.prod.google.com ([2002:a63:e14c:0:b0:c09:15e9:db3d]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:339b:b0:33f:4e3d:aff0 with SMTP id adf61e73a8af0-3898f8cbb87mr8987404637.21.1767930341668; Thu, 08 Jan 2026 19:45:41 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 8 Jan 2026 19:45:28 -0800 In-Reply-To: <20260109034532.1012993-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: <20260109034532.1012993-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260109034532.1012993-5-seanjc@google.com> Subject: [PATCH v4 4/8] 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, 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. Reviewed-by: Chao Gao 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.457.g6b5491de43-goog From nobody Sat Feb 7 23:47:48 2026 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 698712D7DC1 for ; Fri, 9 Jan 2026 03:45:44 +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=1767930345; cv=none; b=FyYJouAYFN5Vaku5PTBre5AtwsfL7Np1Pn9qGYn0jWyZnkkj2jrzQxJiRNmXyDlPg32fOO5v4Hj8CkMymPZrrxVKZp44r9yT4EdOKUe1yxCcw6oOZF4zcm3MjTRusAanZvhPCbS5SYNfiV7F+g75I+mpY+d7y3xtuaTrMEKPjas= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767930345; c=relaxed/simple; bh=OHCeNRp1wt9IbXCaJRqofsAtvp1Jfc8eqsNolsnerWU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=erIVqpyvKrsLq4662K5myjySTrZd8hL57hBQSJ7XWwuAAjFgolvHnbE+CZRzz6itIic72nQsDeq7QQk80lZ+/4Rwk8Jl411KLZIitE042rE3f+UzIU+pehkN0Eyj/MRmLbtLGIvK1b7Ipmcz+QjYmFaoem6kldpDGvb7Pe7ax4s= 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=K4/YmLM6; 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="K4/YmLM6" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-2a13cd9a784so36161405ad.2 for ; Thu, 08 Jan 2026 19:45:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1767930343; x=1768535143; 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=97rvvcgreI792oaYEzu9bWB1KLSBFwBggjm3Kg+Hq/c=; b=K4/YmLM6ZC6n5kuC5MD95G4CkfodphF/qjthFNP6hajh0uQMQPpZDbnExocV3x9JfX UY/crhtqjscX7j0DNgm+8Xu+85fHQnp8mrZq3XzydyIsR/NaYABDAN09LKv7PdGMjYkH IBnnDGnqWvrTz/XJRU7+TGUpD4HqwbTSGB5SZDholU68WNk0/irGPvUIpfMuEUcH4TP/ /3rmIGsSOhb1ByVqTLn92mI+nNYFzxA1pbst5F62MRUcYpbPjU4F4O5g3T3LqVB+woOX U+O3HT76kHQGBMfcgKZcitWp6uC9LwowfE6DriICqefsln/kgSA+ff3FrAEbB/VvpSmo sPJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767930343; x=1768535143; 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=97rvvcgreI792oaYEzu9bWB1KLSBFwBggjm3Kg+Hq/c=; b=Khj7MK3GDqfQewhynczmQrQAt/WsFYwod7X6/R+rqzo1IPMWavNh7evQgdd7CuhMc5 bsSzkHSoPPpSCraE+Ykf6JPF1a6YK85qvGhP8DyM/OIrK1ApUsO6Zpk3VXEGoW0N2B5V 7IPGtkVInMfSpA8gaKh0XD0MDZDduU2VnoJZsN/m1Vbnwj8dMcKKU+Z+dAJK7ReV+XGG JPFdpbFGh+kvZAtiSSVgnvAyZkFKSJ4HNai4/YFIWO5pzN+o352MC0iyQw6bTp8ka7TB AC5RTd/chbNrFIyV8SsG1WEoA0ehxt+xqRWQJ4NE6xTH/oiRMoDRFNZyCJQpUbslHXFK S5Tg== X-Forwarded-Encrypted: i=1; AJvYcCVabLfuvj9AHZ08nI13EZtBSxte63FsqT5tFJFjq0duTlDjW5AHoLXJ5XjNXn+fWT9hAQJTwdJH26BhhYw=@vger.kernel.org X-Gm-Message-State: AOJu0YxcLyHJlyZgyd2hL9HUSm0zz28LJ/lQvCsvNJsvrSEJ25dCJ1Or h+Kho8Z6lRVR0FENSA5R7AHwTEEE0oX/x05FYm/7ejYcktjMXYvrcw/hVE9H3jomAMZwiDycVti HN0wM7A== X-Google-Smtp-Source: AGHT+IHotUYH3uDHB5Qxo6BCx8dLSPdORnpJvhVILsX7PibbCEz7iBu1MHUFsX9Ywu0PHxLG7Hpl7nTv1K4= X-Received: from plv9.prod.google.com ([2002:a17:903:bc9:b0:29d:5afa:2d4]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:40ca:b0:2a0:bb11:9072 with SMTP id d9443c01a7336-2a3ee4bfe1dmr77575225ad.55.1767930343574; Thu, 08 Jan 2026 19:45:43 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 8 Jan 2026 19:45:29 -0800 In-Reply-To: <20260109034532.1012993-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: <20260109034532.1012993-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260109034532.1012993-6-seanjc@google.com> Subject: [PATCH v4 5/8] 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, 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. Reviewed-by: Chao Gao 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.457.g6b5491de43-goog From nobody Sat Feb 7 23:47:48 2026 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 F1C273033F8 for ; Fri, 9 Jan 2026 03:45:45 +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=1767930347; cv=none; b=u3LIXllyfwyGHxOzV1uzYS8nhfl51E9/oEVCWY+peQOeu3F39hLNCKQaBIQK0zNh9rqSj34swo44GtN9qRGOk3A1EK2K+KDSZ73hc09KPbHymya2AqeAm2vE8NJV1H4y4gD6jJfG0GLHd15LRH8o+EBvcmUXRi/kEKMyQHztkmI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767930347; c=relaxed/simple; bh=o1kKEv4y9G1l1AcUONDgAB0YJoa373EmyRiTlcErh/0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=QgGYy5I81ZE9hUY74pbtavDWzH//vtVa9QMv3btBvs0wbHvrkVWBtu0+C6PtCp3IJZ1t5XCqvd0ueNETjQyRfr0rI1HYsAMPM8HV67A8Ak4wEVGW1yczWpwG0BSRKT3I8XXdCQoWQnSC5xLODBHoc8mqFKgZF2AP+F3WeL05f/U= 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=jdftKX3b; 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="jdftKX3b" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2a13be531b2so46593975ad.2 for ; Thu, 08 Jan 2026 19:45:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1767930345; x=1768535145; 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=J6s9SI/r2bnHM1n7Bm/zP7cWS7ymjW9gwaRGx74RRrI=; b=jdftKX3bPcP9Aatvy4S9m/0nOLlmJdi2RpXf3cqmBcpW121DWJLyiTgemnK//zuap9 n10G6Lm+2FzzDUolhbvaPDApabreY+iwz5YfOnu5RngS2m7DzQO4vRPNSegcRr5vB4b5 fNhbI155U3HP8VUmliScSlcEwW+v2J0v4Cu+VvmHHu8qx9qfmruVWUyTsYJEu9DWRklV CwIsUP221js2c80ejPdIudPiLiQBujFwtzXS/UP6AAkEcXze+qPORyDImQEaRIByefq2 9M6uuWhsoCXy++syUN7I7B67GKOT/6j62C9Zj8zEcEQeL/U1cSPyRToLYQ8nCHO47biL d6jQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767930345; x=1768535145; 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=J6s9SI/r2bnHM1n7Bm/zP7cWS7ymjW9gwaRGx74RRrI=; b=Df+sYWMTR/K/CfY0SbgTCBCWYErAp5TJQqBDnD7f4m2d6DLVvwpjJLsTmUsOR8Ifk8 ni/50g9omvltJPQM2Cy2GkT460xvceZUWNcgtU1Fvd1hr5Z3M8VSTLaCEmw3GSPa0dUM KTORIuZddAdqvQ5mF0m3ow/uJGKJhp9+CTEhnmBiF6GMmR6MYYD7AUh0hr5PlHvlMDq7 /ItmWnw9NASv4ihpHMiM5c6pnMzfd792UzRB9YrHQmMiHDOZaOZdjieTguZIB65/aEZB bc0J/UKo9NlKYBFflHbD9GUkYz1HwVoOdEX6WzfoM0z3sYnjjq04ez6VFklVrwKVfXlX e9zA== X-Forwarded-Encrypted: i=1; AJvYcCUtvdh4PNK/I0MqebZraVFlV6fJ5hzvzhEpRtg96aElKowMZjkmOP1jRKIXr2JlR1FnFXrBWpRRM6U7zC4=@vger.kernel.org X-Gm-Message-State: AOJu0Yy9CxpqmubIqoRqDifiP0WQ9XiZ72c+7u0K3HRpGVc9Z/zL5oNt /97HwB8+oL4t3k9ejK6GEr7yHCWRyPTlqhl+bQdv4LCsFtmjdweESvGJ9yNpYhdbnKJUaRlmQD6 gKlT5MQ== X-Google-Smtp-Source: AGHT+IGOKgPXbL3Nx4d+n28wqdscdI7eBJGYNqyaTNz7Nh7KHW8RUVrTgLfwaO8PWz8RoWeT5QsLFUa2oZs= X-Received: from plkn7.prod.google.com ([2002:a17:902:6a87:b0:2a1:4291:bc8e]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:40c9:b0:298:3aa6:c03d with SMTP id d9443c01a7336-2a3ee51bdd6mr87464325ad.57.1767930345433; Thu, 08 Jan 2026 19:45:45 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 8 Jan 2026 19:45:30 -0800 In-Reply-To: <20260109034532.1012993-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: <20260109034532.1012993-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260109034532.1012993-7-seanjc@google.com> Subject: [PATCH v4 6/8] 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, 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. Reviewed-by: Chao Gao 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.457.g6b5491de43-goog From nobody Sat Feb 7 23:47:48 2026 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 AB08E2DB788 for ; Fri, 9 Jan 2026 03:45:47 +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=1767930349; cv=none; b=fEcyR/ELcj/IFoX75KGZnPjM5xqyI9McYaG5gAWBzaFWBPace4scO5moSwbKr62JBV2Fa/qEga6ohyDvTzvirKZw6mUNsGbzDonWSl2hu3b2muouG8e/Y8xAN/O+agbN4MnsBXqXtSt0axTGPPW7fhVG/zjLRhffsAHaB0gjW+k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767930349; c=relaxed/simple; bh=JXh0ie+obtWocTYMsoUxD71I9Ghckom7SaJFDbVOF8c=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=FSKjkcXMuQkZz87Ty+wYzQaRdzz67L6Jjcz4DA+Qb4gnGjIU1B1AKs6A5Q7gUl9tPq550MVekcZvxKwv7ynnOlmt4HchaTgANtUUyHBY0lpg/8AW0MyrWQXRAnHYDzhW5wNZ+W9znYWUiOIOmtEa8yPHsyjzwPQc9PWJPKiw8UQ= 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=vBm+ai4n; 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="vBm+ai4n" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-29f1f69eec6so41726055ad.1 for ; Thu, 08 Jan 2026 19:45:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1767930347; x=1768535147; 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=BAkYuiqwP0nictwbePl0dBrZdxmnnDy80TEFALD0j3o=; b=vBm+ai4nRmS9Wq3AQJs3/E27OWNHW/2LUz7nJVGr/z8wQIVlpq3+qK5J2OM+dtv6go TVyQ1r52ewt+7P3JVD/P/273kKfowExsLqJ7XBlH/1otZTIhHCKqf9q7x04s/4VTCcG6 g84wIi+wMDhsA459ZP+9TimnffU45Tt4fCu2X8n/tQjNx3emcGzIhmMsclKPhnV+aT2Z CqQkdH2AScGIH0hiPpxhN25on3j+199leBhEKG2/NrRMKJdtkYg+N9/SJUsC0aYNF/NM xk19QvibGqnX61sMqcwTeYbkgSJ0RODtw08HtdLEcBBeXZwbSNHxgJW+zfWgdfAk0/Ma NG+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767930347; x=1768535147; 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=BAkYuiqwP0nictwbePl0dBrZdxmnnDy80TEFALD0j3o=; b=wyZFkFPEtr/jZhR1JcoJ+CymJAw3JabzxoyWyUV+4aRCBp6rgDrKLLxKqLrJ0l5LPj 4mtg76utfKdLRM4mX8sea6SQdn6fgo72VBA9/XgqRe6AAcbvWOj3/qotlpXuhERZrkxv gh/26KwaXqs5h4Ux6R5bp9HJB6IPwbB5mvsiRSBMIJZEh8Luc6qfxhBAkOSqgks8bFBI an2PEWiEerIWhfaf1BLH+jIPX4P87RmtjP4xHqj4RpZHDuSM4ini0C8xQ4D1yIg9G4y8 lwStWNUkt+MBvGbEZatgIrv2Ng/Pzqp+HwtD7EryjPv0fYX94d3GxiJc/5dVbuaB1JbW Epig== X-Forwarded-Encrypted: i=1; AJvYcCWtLg9/hqLMHKYsqJkyzvEpq0/bN4tgQJDavDEiSxxl1g1I347IMC18PqEwiFqXCu1PcM4fJIJB/SX4aBY=@vger.kernel.org X-Gm-Message-State: AOJu0Yw0FHN1dnaTiLDO5U4oLTd8diYvy7BD0U9NYia9IatWx2nwFYWb r0QevP2WY2I7iEckSxDg+15NbGeckG8mOxFAh4IU4Gr/X1jMx62AgFJcwVAQuHgDqXjfooHp3uj PNEFYfA== X-Google-Smtp-Source: AGHT+IH+44EtSFhcUAG8z3rdDTxFhPX9bO2zMP3KOY2VBO2VeBgYp28++elygt9mi7qCit9q8JNn5XCb1YM= X-Received: from pleq17.prod.google.com ([2002:a17:902:f351:b0:29f:25b4:4dc4]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:1a83:b0:2a0:d629:9032 with SMTP id d9443c01a7336-2a3ee40eea0mr83243145ad.3.1767930347215; Thu, 08 Jan 2026 19:45:47 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 8 Jan 2026 19:45:31 -0800 In-Reply-To: <20260109034532.1012993-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: <20260109034532.1012993-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260109034532.1012993-8-seanjc@google.com> Subject: [PATCH v4 7/8] 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, 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. Reviewed-by: Chao Gao 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..54701bb815eb 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(vmx->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.457.g6b5491de43-goog From nobody Sat Feb 7 23:47:48 2026 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.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 01EB232E72B for ; Fri, 9 Jan 2026 03:45:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767930352; cv=none; b=Q4ZQ1c7ZgyXfmjX0HbMSH00caGNR+i7KjEKn4w3z+e+lm8yyiKvxLZ24fzqolacAnE5g+BuMTcijbYpir2TXnSgqCRNJtlN2Gxq16CeFRzuyCfHn/JGuMfzeW9rQKa6AHegdqoE8uvTcVfzgDBijG+Jos8PqFOHQDzoQ3KsjDzk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767930352; c=relaxed/simple; bh=4msjTg1i7XaDvd1QuEQZzoFMT5VhByOA6HB8ET5wU8E=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=pWLBPUoae+6a4MBD04kRZJf9GJ5j4YM2TDE6qxTfb1KIw3vn68MK6JaDrfjbKg5SE6h3H05r0iSbq8Q+ObtgPxZOKYI/WpgDusu4FTbvLrPVXaxz8wVi672ModWbk7nk6cBBCVjGrc/FyMZBixsVGD+ny45uLn4InpMA1KwfkL8= 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=MEi6CxWY; arc=none smtp.client-ip=209.85.210.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="MEi6CxWY" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7b952a966d7so7162115b3a.3 for ; Thu, 08 Jan 2026 19:45:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1767930349; x=1768535149; 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=10FjfRsFdnZmF34U5UFQ1XPMg3h7zF2rzmscv7r4ebk=; b=MEi6CxWYSrZUATblUJEQFEBw2DTr2kvmNakvWIfnqaFeh9bqypJtPCz8sr1xodZRFb dd4AYJIPsRenDI4w9Y0mItoXh30I6FHdMK2KNedSObGReqTAFfuFG77GBwd5UrFd8OpJ zQ/nDOSo2CPTAkX1TpZtbgbRCre37otXr2oleRmOROm0k5Q0qh7NF3dmCTLfqOC4EoBQ lPqYu+tvFLwbyve7Azi19jIJbMJRtJ2XxVPZHkwoSd3W4VMFU1W7oUBvAoSpU85j77Tb 0E43J4lPOFQUTGkJdp17HO/CRd7t3icWxF4aKvOGntIBTj2abBG3kXmJEblOF1r+lIjH g+6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767930349; x=1768535149; 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=10FjfRsFdnZmF34U5UFQ1XPMg3h7zF2rzmscv7r4ebk=; b=j2UMPx6tvQvNwUxJgCCpMkWFLbEHeG9PyfqDElWBOUloC7GAT0Q+2ouJqvVpDH99QL P8zMaBfKD0p3rHYvR7BQGLKGR5pUmDDo6Leg4IqIHeVBIBoaVLxijiuedtOzFQDrsCEL FnVWhLiTmk5zheHYSqBS1nUOrOg0mrJhaZC6dM/Hd9VzOetqKyytl3LrgY1LMTYMRwx8 EPGbfpKJ7QsvkNB2Rpxs62BA+fPe03yRVN4EJh95/xg9CJ9/qhL39u4wm8Hs7mC1K5qg tkL31mg5FN10OS9yu4+SFrWhgqz1LIG+bhpjjWyPbE4Z/FFrrmgzj9GJvCh9xhLwe7Qs ncgA== X-Forwarded-Encrypted: i=1; AJvYcCU3xIu8ZGzOn+fbAXNcSpk2SNArYSKH/UOVQX5Bq5gsPExwq2epR3dCn4GEmYEZsHpHdbUVQ1YaUe4jieY=@vger.kernel.org X-Gm-Message-State: AOJu0YzoLhEisAgfIxUD9XLQ64H2OJX1oeKGjyus64yAFuhbJti2SMUy JjyLEIu83kNpXy/qmOZl58g1e53smyNEOzlJx3XrkDstS9GLQsBebntcmGG/Lmj87119jZkttVb QhTgOCg== X-Google-Smtp-Source: AGHT+IF+n8CHKQkZPkcMtUGYOluM0zEQvfHMGi/MUBUCyGUaDQhoy6jg4em+1v2tpH7hoYL3Xe3tU7uY0dk= X-Received: from pfblh1.prod.google.com ([2002:a05:6a00:7101:b0:7a9:968d:6b38]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:299a:b0:817:9a85:549f with SMTP id d2e1a72fcca58-81b7d850288mr8307437b3a.20.1767930349149; Thu, 08 Jan 2026 19:45:49 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 8 Jan 2026 19:45:32 -0800 In-Reply-To: <20260109034532.1012993-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: <20260109034532.1012993-1-seanjc@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260109034532.1012993-9-seanjc@google.com> Subject: [PATCH v4 8/8] 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, 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(), kvm_lapic_reset(), 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 benign side effects, as doing so changes the orders of the calls in kvm_lapic_reset() and kvm_apic_set_state(), specifically with respect to to the order between .hwapic_isr_update() and .apicv_post_state_restore(). However, the changes in ordering are glorified nops as the former hook is VMX-only and the latter is SVM-only. Reviewed-by: Chao Gao Signed-off-by: Sean Christopherson --- arch/x86/kvm/lapic.c | 31 ++++++++++++------------------- arch/x86/kvm/lapic.h | 1 - arch/x86/kvm/x86.c | 7 ------- 3 files changed, 12 insertions(+), 27 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 1597dd0b0cc6..9b791e728ec1 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,18 @@ void kvm_apic_update_apicv(struct kvm_vcpu *vcpu) */ apic->irr_pending =3D true; =20 - if (apic->apicv_active) + /* + * 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) { 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; } @@ -2916,10 +2913,8 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool ini= t_event) =20 vcpu->arch.pv_eoi.msr_val =3D 0; apic_update_ppr(apic); - if (apic->apicv_active) { + if (apic->apicv_active) kvm_x86_call(apicv_post_state_restore)(vcpu); - kvm_x86_call(hwapic_isr_update)(vcpu, -1); - } =20 vcpu->arch.apic_arb_prio =3D 0; vcpu->arch.apic_attention =3D 0; @@ -3232,10 +3227,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..0c6d899d53dd 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10886,16 +10886,9 @@ 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.457.g6b5491de43-goog