public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Haoyu Wu <haoyuwu254@gmail.com>
Cc: pbonzini@redhat.com, tglx@linutronix.de, mingo@redhat.com,
	bp@alien8.de,  dave.hansen@linux.intel.com, x86@kernel.org,
	hpa@zytor.com,  kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org, zheyuma97@gmail.com
Subject: Re: [PATCH] KVM: Fix LDR inconsistency warning caused by APIC_ID format error
Date: Fri, 26 Jan 2024 08:55:58 -0800	[thread overview]
Message-ID: <ZbPkHvuJv0EdJhVN@google.com> (raw)
In-Reply-To: <20240126161633.62529-1-haoyuwu254@gmail.com>

On Sat, Jan 27, 2024, Haoyu Wu wrote:
> Syzkaller detected a warning in the kvm_recalculate_logical_map()
> function. This function employs VCPU_ID as the current x2APIC_ID
> following the apic_x2apic_mode() check. However, the LDR value,
> as computed using the current x2APIC_ID,  fails to align with the LDR
> value that is actually set.
> 
> Syzkaller scenario:
> 1) Set up VCPU's
> 2) Set the APIC_BASE to 0xd00
> 3) Set the APIC status for a specific state
> 
> The issue arises within kvm_apic_state_fixup, a function responsible
> for adjusting and correcting the APIC state. Initially, it verifies
> whether the current vcpu operates in x2APIC mode by examining the
> vcpu's mode. Subsequently, the function evaluates
> vcpu->kvm->arch.x2apic_format to ascertain if the preceding kvm version
> supports x2APIC mode. In cases where kvm is compatible with x2APIC mode,
> the function compares APIC_ID and VCPU_ID for equality. If they are not
> equal, it processes APIC_ID according to the set value. The error
> manifests when vcpu->kvm->arch.x2apic_format is false; under these
> circumstances, kvm_apic_state_fixup converts APIC_ID to the xAPIC format
> and invokes kvm_apic_calc_x2apic_ldr to compute the LDR. This leads to by
> passing consistency checks between VCPU_ID and APIC_ID and results in
> calling incorrect functions for LDR calculation.

Please just provide the syzkaller reproducer.

> Obviously, the crux of the issue hinges on the transition of the APIC
> state and the associated operations for transitioning APIC_ID. In the
> current kernel design, APIC_ID defaults to VCPU_ID in x2APIC mode, a
> specification not required in xAPIC mode. kvm_apic_state_fixup initiates
> by assessing the current status of both VCPU and KVM to identify their
> respective APIC modes. However, subsequent evaluations focus solely on
> the APIC mode of VCPU. To address this, a feasible minor modification
> involves advancing the comparison between APIC_ID and VCPU_ID,
> positioning it prior to the evaluation of vcpu→kvm→arch.x2apic_format.
>
> Signed-off-by: Haoyu Wu <haoyuwu254@gmail.com>
> ---
>  arch/x86/kvm/lapic.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> index 3242f3da2..16c97d57d 100644
> --- a/arch/x86/kvm/lapic.c
> +++ b/arch/x86/kvm/lapic.c
> @@ -2933,16 +2933,16 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
>  		u32 *ldr = (u32 *)(s->regs + APIC_LDR);
>  		u64 icr;
>  
> -		if (vcpu->kvm->arch.x2apic_format) {
> -			if (*id != vcpu->vcpu_id)
> -				return -EINVAL;
> -		} else {
> +		if (*id != vcpu->vcpu_id)
> +			return -EINVAL;

This will break userspace.  As shown below, if userspace is using the legacy
format, the incoming ID will be vcpu_id << 24.

This is a known issue[*], and apparently I had/have a patch?  I'll try to dredge
that up.  I suspect what I intended to was this, but I haven't yet found a branch
or stash, or anything else that captured what I intended to do.  *sigh*

diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 3242f3da2457..d25e31c04fbd 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -2933,16 +2933,16 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
                u32 *ldr = (u32 *)(s->regs + APIC_LDR);
                u64 icr;
 
-               if (vcpu->kvm->arch.x2apic_format) {
-                       if (*id != vcpu->vcpu_id)
-                               return -EINVAL;
-               } else {
+               if (!vcpu->kvm->arch.x2apic_format) {
                        if (set)
                                *id >>= 24;
                        else
                                *id <<= 24;
                }
 
+               if (*id != vcpu->vcpu_id)
+                       return -EINVAL;
+
                /*
                 * In x2APIC mode, the LDR is fixed and based on the id.  And
                 * ICR is internally a single 64-bit register, but needs to be

[*] https://lore.kernel.org/all/ZHk3TGyB2Vze4+Ou@google.com

> +		if (!vcpu->kvm->arch.x2apic_format) {
>  			if (set)
>  				*id >>= 24;
>  			else
>  				*id <<= 24;
>  		}
>  
> +

Spurious whitespace.

>  		/*
>  		 * In x2APIC mode, the LDR is fixed and based on the id.  And
>  		 * ICR is internally a single 64-bit register, but needs to be
> -- 
> 2.34.1
> 

      reply	other threads:[~2024-01-26 16:56 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-26 16:16 [PATCH] KVM: Fix LDR inconsistency warning caused by APIC_ID format error Haoyu Wu
2024-01-26 16:55 ` Sean Christopherson [this message]

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=ZbPkHvuJv0EdJhVN@google.com \
    --to=seanjc@google.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=haoyuwu254@gmail.com \
    --cc=hpa@zytor.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    --cc=zheyuma97@gmail.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