public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Chao Gao <chao.gao@intel.com>
To: Like Xu <like.xu.linux@gmail.com>
Cc: <kvm@vger.kernel.org>, Jim Mattson <jmattson@google.com>,
	<seanjc@google.com>, <pbonzini@redhat.com>
Subject: Re: [kvm-unit-tests PATCH 0/5] nVMX: Simple posted interrupts test
Date: Mon, 14 Oct 2024 16:56:46 +0800	[thread overview]
Message-ID: <ZwzczkIlYGX+QXJz@intel.com> (raw)
In-Reply-To: <7fe8970c-ecb7-4e46-be76-488d7697d8db@gmail.com>

On Wed, Oct 09, 2024 at 02:48:28PM +0800, Like Xu wrote:
>On 12/12/23 2:55 AM, Jim Mattson wrote:
>> I reported recently that commit 26844fee6ade ("KVM: x86: never write to
>> memory from kvm_vcpu_check_block()") broke delivery of a virtualized posted
>> interrupt from an L1 vCPU to a halted L2 vCPU (see
>> https://lore.kernel.org/all/20231207010302.2240506-1-jmattson@google.com/).
>> The test that exposed the regression is the final patch of this series. The
>> others are prerequisites.
>> 
>> It would make sense to add "vmx_posted_interrupts_test" to the set of tests
>> to be run under the unit test name, "vmx_apicv_test," but that is
>> non-trivial. The vmx_posted_interrupts_test requires "smp = 2," but I find
>> that adding that to the vmx_apicv_tests causes virt_x2apic_mode_test to
>> fail with:
>> 
>> FAIL: x2apic - reading 0x310: x86/vmx_tests.c:2151: Assertion failed: (expected) == (actual)
>> 	LHS: 0x0000000000000012 - 0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0001'0010 - 18
>> 	RHS: 0x0000000000000001 - 0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0001 - 1
>> Expected VMX_VMCALL, got VMX_EXTINT.
>> 	STACK: 406ef8 40725a 41299f 402036 403f59 4001bd
>> 
>> I haven't investigated.
>
>This vmx_apicv_test test still fails when 'ept=N' (SPR + v6.12-rc2):
>
>--- Virtualize APIC accesses + Use TPR shadow test ---
>FAIL: xapic - reading 0x080: read 0x0, expected 0x70.
>FAIL: xapic - writing 0x12345678 to 0x080: exitless write; val is 0x0, want
>0x70
>
>--- APIC-register virtualization test ---
>FAIL: xapic - reading 0x020: read 0x0, expected 0x12345678.
>FAIL: xapic - writing 0x12345678 to 0x020: x86/vmx_tests.c:2164: Assertion
>failed: (expected) == (actual)
>	LHS: 0x0000000000000038 - 0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0011'1000
>- 56
>	RHS: 0x0000000000000012 - 0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0001'0010
>- 18
>Expected VMX_APIC_WRITE, got VMX_VMCALL.
>	STACK: 406f7f 40d178 40202f 403f54 4001bd

These failures occur because KVM flushes TLB with the wrong VPID, causing TLB
for the 'APIC-access page' to be retained across nested transitions. This TLB
entry exists because L1 writes to that page before entering the guest, see
test_xapic_rd():

        /* Setup virtual APIC page */
        if (!expectation->virtualize_apic_accesses) {
                apic_access_address[apic_reg_index(reg)] = val;
                virtual_apic_page[apic_reg_index(reg)] = 0;
        } else if (exit_reason_want == VMX_VMCALL) {
                apic_access_address[apic_reg_index(reg)] = 0;
                virtual_apic_page[apic_reg_index(reg)] = val;
        }


Specifically, in the failing scenario, EPT is disabled, and VPID is enabled in
L0 but disabled in L1. As a result, vmcs01 and vmcs02 share the same VPID
(vmx->vpid, see prepare_vmcs02_early_rare()), and vmx->nested.vpid02 is never
used. But during nested transitions, KVM incorrectly flushes TLB using
vmx->nested.vpid02. The sequence is as follows:

	nested_vmx_transition_tlb_flush ->
	  kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu) ->
	    kvm_vcpu_flush_tlb_guest ->	
	      vmx_flush_tlb_guest ->
		vmx_get_current_vpid ->

With the diff below applied, these failures disappear.

diff --git a/arch/x86/kvm/vmx/nested.h b/arch/x86/kvm/vmx/nested.h
index cce4e2aa30fb..246d9c6e20d0 100644
--- a/arch/x86/kvm/vmx/nested.h
+++ b/arch/x86/kvm/vmx/nested.h
@@ -61,13 +61,6 @@ static inline int vmx_has_valid_vmcs12(struct kvm_vcpu *vcpu)
 		nested_vmx_is_evmptr12_set(vmx);
 }
 
-static inline u16 nested_get_vpid02(struct kvm_vcpu *vcpu)
-{
-	struct vcpu_vmx *vmx = to_vmx(vcpu);
-
-	return vmx->nested.vpid02 ? vmx->nested.vpid02 : vmx->vpid;
-}
-
 static inline unsigned long nested_ept_get_eptp(struct kvm_vcpu *vcpu)
 {
 	/* return the page table to be shadowed - in our case, EPT12 */
@@ -187,6 +180,16 @@ static inline bool nested_cpu_has_vpid(struct vmcs12 *vmcs12)
 	return nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENABLE_VPID);
 }
 
+static inline u16 nested_get_vpid02(struct kvm_vcpu *vcpu)
+{
+	struct vcpu_vmx *vmx = to_vmx(vcpu);
+
+	if (nested_cpu_has_vpid(get_vmcs12(vcpu)) && vmx->nested.vpid02)
+		return vmx->nested.vpid02;
+
+	return vmx->vpid;
+}
+
 static inline bool nested_cpu_has_apic_reg_virt(struct vmcs12 *vmcs12)
 {
 	return nested_cpu_has2(vmcs12, SECONDARY_EXEC_APIC_REGISTER_VIRT);

  reply	other threads:[~2024-10-14  8:56 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-11 18:55 [kvm-unit-tests PATCH 0/5] nVMX: Simple posted interrupts test Jim Mattson
2023-12-11 18:55 ` [kvm-unit-tests PATCH 1/5] nVMX: Enable x2APIC mode for virtual-interrupt delivery tests Jim Mattson
2023-12-11 18:55 ` [kvm-unit-tests PATCH 2/5] nVMX: test nested "virtual-interrupt delivery" Jim Mattson
2023-12-11 18:55 ` [kvm-unit-tests PATCH 3/5] nVMX: test nested EOI virtualization Jim Mattson
2023-12-11 18:55 ` [kvm-unit-tests PATCH 4/5] nVMX: add self-IPI tests to vmx_basic_vid_test Jim Mattson
2023-12-11 18:55 ` [kvm-unit-tests PATCH 5/5] nVMX: add test for posted interrupts Jim Mattson
2024-06-05 23:20 ` [kvm-unit-tests PATCH 0/5] nVMX: Simple posted interrupts test Sean Christopherson
2024-10-09  6:48 ` Like Xu
2024-10-14  8:56   ` Chao Gao [this message]
2024-10-16 15:59     ` Sean Christopherson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZwzczkIlYGX+QXJz@intel.com \
    --to=chao.gao@intel.com \
    --cc=jmattson@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=like.xu.linux@gmail.com \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox