From nobody Mon Jun 8 05:26:40 2026 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1C6653B2D0D; Fri, 5 Jun 2026 14:30:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.50.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669849; cv=none; b=CFUKk325Vm3U1E+HG5wk7Lmaawc30+9REk+8uCP5U7RPj9q5HQEnZteKc42Drnc8TE3QoSvGNeIq9r/YGHS7KnLiCFJobnqaAij1k6S74MXO3qAAT3NgHTKfKsbq7GT870BdS2alYOa8JDqpQbPLAEIpt21A17MEORmC5I+H+6k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669849; c=relaxed/simple; bh=AuIY14KqiA9W3u1TFh2kocuQhHEOHteA96oXska4omM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XvAK1nrSDiG157fAXsOGxmtHsNXFY9xtI6XDtl0Cfg0ldllC2cxJueusmxQPif0+mVwGXOviYR8iFTn8MhTgwuDiX+5REbBTEJCGCRL0Am6psRLQCjrByYmO3L3deZ7x1gf/6KNZDvSu32Rh+JAAS9spl9gBBrfGKx10u++RHs4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=casper.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=Ur83SHeg; arc=none smtp.client-ip=90.155.50.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=casper.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="Ur83SHeg" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=HMHMnLtmFEnlXHeN04ELPbsc86c69hiUTB5mzlEYiuA=; b=Ur83SHegAnHFOaSy89pWD1Xt2w CMsOW06tEiYKjfo0l8xt/2WpVccZ2WJ0Q80LWIq/Tqq4YjvimVmv+Q4RmB1kqbHNlBzEVcOnaW127 YGhjHxkIwWluaZ9Ch15O/xKR9D6hgzNDmi9UiOahJWHd79Z9thavcuRbW8ng6QZBWuThPJx5zcbOr 90zALbdLsB0hUwo98dq7JxaSORyV47vOP4qdT6Flq9YXomBpAhUfMdRpRutu++1Tx2va7V2WVUgJ/ prI/KLZq025wCnd7vCl/OI/h7vSFAApysvsgH8HTGlp9TNLD2FMN6rq6Yntru2nk+dxZI1zsyNQDy JlcDaXnA==; Received: from [2001:8b0:10b:1::425] (helo=i7.infradead.org) by casper.infradead.org with esmtpsa (Exim 4.99.1 #2 (Red Hat Linux)) id 1wVVZE-0000000848c-26Pw; Fri, 05 Jun 2026 14:30:37 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.99.2 #2 (Red Hat Linux)) id 1wVVZE-0000000013P-0z7g; Fri, 05 Jun 2026 15:30:36 +0100 From: David Woodhouse To: Sean Christopherson Cc: Paul Durrant , Hyunwoo Kim , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/8] KVM: x86/xen: Rename 'longmode' to 'is_64bit' in hypercall handling Date: Fri, 5 Jun 2026 15:17:26 +0100 Message-ID: <20260605143034.3603-2-dwmw2@infradead.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260605143034.3603-1-dwmw2@infradead.org> References: <20260605143034.3603-1-dwmw2@infradead.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: David Woodhouse X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Content-Type: text/plain; charset="utf-8" From: David Woodhouse Rename the local 'longmode' variable and function parameter to 'is_64bit' throughout the Xen hypercall handling code. This distinguishes it from the VM-wide kvm->arch.xen.long_mode which represents the Xen shared_info layout mode. The 'is_64bit' parameter indicates whether the vCPU was in 64-bit mode when it made the hypercall, which determines how to parse the hypercall arguments. The UAPI field name (vcpu->run->xen.u.hcall.longmode) is unchanged. Assisted-by: Kiro:claude-opus-4.6-1m Signed-off-by: David Woodhouse --- arch/x86/kvm/xen.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c index 91fd3673c09a..a7ab19f38b59 100644 --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -1468,7 +1468,7 @@ static bool wait_pending_event(struct kvm_vcpu *vcpu,= int nr_ports, return ret; } =20 -static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool longmode, +static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool is_64bit, u64 param, u64 *r) { struct sched_poll sched_poll; @@ -1480,7 +1480,7 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcp= u, bool longmode, !(vcpu->kvm->arch.xen.hvm_config.flags & KVM_XEN_HVM_CONFIG_EVTCHN_SE= ND)) return false; =20 - if (IS_ENABLED(CONFIG_64BIT) && !longmode) { + if (IS_ENABLED(CONFIG_64BIT) && !is_64bit) { struct compat_sched_poll sp32; =20 /* Sanity check that the compat struct definition is correct */ @@ -1577,12 +1577,12 @@ static void cancel_evtchn_poll(struct timer_list *t) kvm_vcpu_kick(vcpu); } =20 -static bool kvm_xen_hcall_sched_op(struct kvm_vcpu *vcpu, bool longmode, +static bool kvm_xen_hcall_sched_op(struct kvm_vcpu *vcpu, bool is_64bit, int cmd, u64 param, u64 *r) { switch (cmd) { case SCHEDOP_poll: - if (kvm_xen_schedop_poll(vcpu, longmode, param, r)) + if (kvm_xen_schedop_poll(vcpu, is_64bit, param, r)) return true; fallthrough; case SCHEDOP_yield: @@ -1601,7 +1601,7 @@ struct compat_vcpu_set_singleshot_timer { uint32_t flags; } __attribute__((packed)); =20 -static bool kvm_xen_hcall_vcpu_op(struct kvm_vcpu *vcpu, bool longmode, in= t cmd, +static bool kvm_xen_hcall_vcpu_op(struct kvm_vcpu *vcpu, bool is_64bit, in= t cmd, int vcpu_id, u64 param, u64 *r) { struct vcpu_set_singleshot_timer oneshot; @@ -1633,7 +1633,7 @@ static bool kvm_xen_hcall_vcpu_op(struct kvm_vcpu *vc= pu, bool longmode, int cmd, BUILD_BUG_ON(sizeof_field(struct compat_vcpu_set_singleshot_timer, flags= ) !=3D sizeof_field(struct vcpu_set_singleshot_timer, flags)); =20 - if (kvm_read_guest_virt(vcpu, param, &oneshot, longmode ? sizeof(oneshot= ) : + if (kvm_read_guest_virt(vcpu, param, &oneshot, is_64bit ? sizeof(oneshot= ) : sizeof(struct compat_vcpu_set_singleshot_timer), &e)) { *r =3D -EFAULT; return true; @@ -1673,7 +1673,7 @@ static bool kvm_xen_hcall_set_timer_op(struct kvm_vcp= u *vcpu, uint64_t timeout, =20 int kvm_xen_hypercall(struct kvm_vcpu *vcpu) { - bool longmode; + bool is_64bit; u64 input, params[6], r =3D -ENOSYS; bool handled =3D false; u8 cpl; @@ -1685,8 +1685,8 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) kvm_hv_hypercall_enabled(vcpu)) return kvm_hv_hypercall(vcpu); =20 - longmode =3D is_64_bit_hypercall(vcpu); - if (!longmode) { + is_64bit =3D is_64_bit_hypercall(vcpu); + if (!is_64bit) { params[0] =3D (u32)kvm_rbx_read(vcpu); params[1] =3D (u32)kvm_rcx_read(vcpu); params[2] =3D (u32)kvm_rdx_read(vcpu); @@ -1727,17 +1727,17 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) handled =3D kvm_xen_hcall_evtchn_send(vcpu, params[1], &r); break; case __HYPERVISOR_sched_op: - handled =3D kvm_xen_hcall_sched_op(vcpu, longmode, params[0], + handled =3D kvm_xen_hcall_sched_op(vcpu, is_64bit, params[0], params[1], &r); break; case __HYPERVISOR_vcpu_op: - handled =3D kvm_xen_hcall_vcpu_op(vcpu, longmode, params[0], params[1], + handled =3D kvm_xen_hcall_vcpu_op(vcpu, is_64bit, params[0], params[1], params[2], &r); break; case __HYPERVISOR_set_timer_op: { u64 timeout =3D params[0]; /* In 32-bit mode, the 64-bit timeout is in two 32-bit params. */ - if (!longmode) + if (!is_64bit) timeout |=3D params[1] << 32; handled =3D kvm_xen_hcall_set_timer_op(vcpu, timeout, &r); break; @@ -1752,7 +1752,7 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) handle_in_userspace: vcpu->run->exit_reason =3D KVM_EXIT_XEN; vcpu->run->xen.type =3D KVM_EXIT_XEN_HCALL; - vcpu->run->xen.u.hcall.longmode =3D longmode; + vcpu->run->xen.u.hcall.longmode =3D is_64bit; vcpu->run->xen.u.hcall.cpl =3D cpl; vcpu->run->xen.u.hcall.input =3D input; vcpu->run->xen.u.hcall.params[0] =3D params[0]; --=20 2.54.0 From nobody Mon Jun 8 05:26:40 2026 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1C4C43B19CA; Fri, 5 Jun 2026 14:30:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.50.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669850; cv=none; b=iGDZ3CL4QANdkG1INfPd5R69JL5kjxyVuZbpOPpdzBbE2t9KmhBaPU8PMeSjI0u7nFsD/E2/O+Ds5WWyoduuAC+EtW0mFGvVd9t1UjbYMKzdLPj0QNL8OL9be7URjIod9hF4Qbjyee3wmMx6920VrOvgWdU5olsjaIvDPFNA3XQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669850; c=relaxed/simple; bh=DNnGn2OnfpPBVTZZIweivJoAdbtiO5JytDbfWNhUziE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VGtlMS2rnSqstv5vi2CkavYJU27tXPkC5oYVALvYWtbG64Cb/p/7ngIXHmhcGi5h9ISOlPgQmkYSPWT3ZthvmTl/7c8ZLWkciFQD09sH8bBxaLZUIZG2JTT2f4M0o1RAxCR1xQ1WZ0GEv7e9KdJWBg9uNU73n8/54RTLmjCrPkY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=casper.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=bMT/MRk6; arc=none smtp.client-ip=90.155.50.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=casper.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="bMT/MRk6" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=YCyxV+ifjXIAhZC0d0vp2nQWP3P1f4jws00DSBIbGQY=; b=bMT/MRk6B5CMIVz0D9bt6Te6Da FkviKAIEwIpfMINoNl/YFiuB/FAfgq4uOACoWvVIGZPgfZTst7IPR7jab6t//mas+f0Him7pENPDW Cg6pytAv8e8gitZVsP1MGLMyjKWQaVh6wfqR2f91MV998Vojt/sIHCGdy33UGdAtRITuLSI4PneRS e+ciR6uohbFQlN1Hrp1U/uCj8NMtlLvVascJfZJFvjKfEaf6vZL7F2E0ipyG9L1Zx8k14eRFZSnSC /Lb723w1gSDGatiztA5qdHUtVJ2nDaQAr5CrsXBoT/kBXKaZBYr0gn1Jcyz95THp8EWJdABMdbmBh NSHeyk+g==; Received: from [2001:8b0:10b:1::425] (helo=i7.infradead.org) by casper.infradead.org with esmtpsa (Exim 4.99.1 #2 (Red Hat Linux)) id 1wVVZE-0000000848d-26wE; Fri, 05 Jun 2026 14:30:37 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.99.2 #2 (Red Hat Linux)) id 1wVVZE-0000000013U-1Ij3; Fri, 05 Jun 2026 15:30:36 +0100 From: David Woodhouse To: Sean Christopherson Cc: Paul Durrant , Hyunwoo Kim , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/8] KVM: x86/xen: Introduce kvm_xen_has_64bit_shinfo() macro Date: Fri, 5 Jun 2026 15:17:27 +0100 Message-ID: <20260605143034.3603-3-dwmw2@infradead.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260605143034.3603-1-dwmw2@infradead.org> References: <20260605143034.3603-1-dwmw2@infradead.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: David Woodhouse X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Content-Type: text/plain; charset="utf-8" From: David Woodhouse Add a kvm_xen_has_64bit_shinfo() helper macro to replace the repeated pattern of 'IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode' throughout the Xen emulation code. The macro uses READ_ONCE() to ensure a consistent snapshot of the flag, which can be changed by another vCPU at any time. This is the KVM equivalent of Xen's !has_32bit_shinfo(). Assisted-by: Kiro:claude-opus-4.6-1m Signed-off-by: David Woodhouse --- arch/x86/kvm/xen.c | 16 ++++++++-------- arch/x86/kvm/xen.h | 5 +++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c index a7ab19f38b59..acd3cd87dd2f 100644 --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -72,7 +72,7 @@ static int kvm_xen_shared_info_init(struct kvm *kvm) BUILD_BUG_ON(offsetof(struct shared_info, wc) !=3D 0xc00); BUILD_BUG_ON(offsetof(struct shared_info, wc_sec_hi) !=3D 0xc0c); =20 - if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode) { + if (kvm_xen_has_64bit_shinfo(kvm)) { struct shared_info *shinfo =3D gpc->khva; =20 wc_sec_hi =3D &shinfo->wc_sec_hi; @@ -390,7 +390,7 @@ static void kvm_xen_update_runstate_guest(struct kvm_vc= pu *v, bool atomic) BUILD_BUG_ON(sizeof_field(struct vcpu_runstate_info, time) !=3D sizeof(vx->runstate_times)); =20 - if (IS_ENABLED(CONFIG_64BIT) && v->kvm->arch.xen.long_mode) { + if (kvm_xen_has_64bit_shinfo(v->kvm)) { user_len =3D sizeof(struct vcpu_runstate_info); times_ofs =3D offsetof(struct vcpu_runstate_info, state_entry_time); @@ -661,7 +661,7 @@ void kvm_xen_inject_pending_events(struct kvm_vcpu *v) } =20 /* Now gpc->khva is a valid kernel address for the vcpu_info */ - if (IS_ENABLED(CONFIG_64BIT) && v->kvm->arch.xen.long_mode) { + if (kvm_xen_has_64bit_shinfo(v->kvm)) { struct vcpu_info *vi =3D gpc->khva; =20 asm volatile(LOCK_PREFIX "orq %0, %1\n" @@ -978,7 +978,7 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct= kvm_xen_vcpu_attr *data) * address, that's actually OK. kvm_xen_update_runstate_guest() * will cope. */ - if (IS_ENABLED(CONFIG_64BIT) && vcpu->kvm->arch.xen.long_mode) + if (kvm_xen_has_64bit_shinfo(vcpu->kvm)) sz =3D sizeof(struct vcpu_runstate_info); else sz =3D sizeof(struct compat_vcpu_runstate_info); @@ -1424,7 +1424,7 @@ static int kvm_xen_hypercall_complete_userspace(struc= t kvm_vcpu *vcpu) =20 static inline int max_evtchn_port(struct kvm *kvm) { - if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode) + if (kvm_xen_has_64bit_shinfo(kvm)) return EVTCHN_2L_NR_CHANNELS; else return COMPAT_EVTCHN_2L_NR_CHANNELS; @@ -1446,7 +1446,7 @@ static bool wait_pending_event(struct kvm_vcpu *vcpu,= int nr_ports, goto out_rcu; =20 ret =3D false; - if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode) { + if (kvm_xen_has_64bit_shinfo(kvm)) { struct shared_info *shinfo =3D gpc->khva; pending_bits =3D (unsigned long *)&shinfo->evtchn_pending; } else { @@ -1820,7 +1820,7 @@ int kvm_xen_set_evtchn_fast(struct kvm_xen_evtchn *xe= , struct kvm *kvm) if (!kvm_gpc_check(gpc, PAGE_SIZE)) goto out_rcu; =20 - if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode) { + if (kvm_xen_has_64bit_shinfo(kvm)) { struct shared_info *shinfo =3D gpc->khva; pending_bits =3D (unsigned long *)&shinfo->evtchn_pending; mask_bits =3D (unsigned long *)&shinfo->evtchn_mask; @@ -1861,7 +1861,7 @@ int kvm_xen_set_evtchn_fast(struct kvm_xen_evtchn *xe= , struct kvm *kvm) goto out_rcu; } =20 - if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode) { + if (kvm_xen_has_64bit_shinfo(kvm)) { struct vcpu_info *vcpu_info =3D gpc->khva; if (!test_and_set_bit(port_word_bit, &vcpu_info->evtchn_pending_sel)) { WRITE_ONCE(vcpu_info->evtchn_upcall_pending, 1); diff --git a/arch/x86/kvm/xen.h b/arch/x86/kvm/xen.h index 59e6128a7bd3..3e8c9306eb89 100644 --- a/arch/x86/kvm/xen.h +++ b/arch/x86/kvm/xen.h @@ -248,6 +248,11 @@ struct compat_shared_info { #define COMPAT_EVTCHN_2L_NR_CHANNELS (8 * \ sizeof_field(struct compat_shared_info, \ evtchn_pending)) + +/* Latched VM-wide mode; the KVM equivalent of Xen's !has_32bit_shinfo(). = */ +#define kvm_xen_has_64bit_shinfo(kvm) \ + (IS_ENABLED(CONFIG_64BIT) && READ_ONCE((kvm)->arch.xen.long_mode)) + struct compat_vcpu_runstate_info { int state; uint64_t state_entry_time; --=20 2.54.0 From nobody Mon Jun 8 05:26:40 2026 Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2E82F3B583B; Fri, 5 Jun 2026 14:30:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.92.199 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669850; cv=none; b=ou/t5GLsj9GWzttjtT1Vned6Abms9qM5KX4drNNGf5OKN/fVGoFBeLxhsqhQLN/5GNk1fsg0nATaJ87fr5lrbGQyL6o9AsA6Qnm4svp4Oox+O3TfS1oMZma+ejenniez0Oa+70yvtkYDpxC1FdYSWV2TXThwvWQcYV21I2TkHXs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669850; c=relaxed/simple; bh=bUkvs7OGc8AI0KurhOR6aOMS+2timvB/zbujog2GalY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LqZkn4qYkPtYBzOnH++/nXknLaGeHRcpqfE4sJzheuTRhoLrHbQ4f/lYA43/GylWN1I3fAWYu7I7l8xPTmLZ57UGZEz6oytigV4mVrUc6e0dBNtI4ZcEUUR1z5Tm5OlY8to1DLAW5X1j5RnOZNngQCmrsLjapEp0O5OHkNakmIE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=desiato.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=PLigA4Gh; arc=none smtp.client-ip=90.155.92.199 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=desiato.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="PLigA4Gh" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=nPV8RT5KYfuVWBKmymaButWOTatlGYNx7OrrYblu+Mw=; b=PLigA4GhLLVYz89l2Y9rRPODiH LZYMJDQT15NI9R54EGO0fW4pKOmP0PGaTYoXIDaNrI7FXumwh5e23/46tNOza+vZYD07ffI38GyTU DJfoqf3rUbfw+EX14NOEMCi59bgfgCg7z+Cvv7V3ozTgaVyBYuKJotI4FaHFFFT+YvRtZj87GgDVu CtWfXzbM6qTMJAnGB9l+NPHcRlK0m7qk8ydzov5wg8G0VNGBz57tIEFC843uDaVOVXS6d9u3ALapX rttqqwknWV88vAwEQUnnm2Q6LVs923yPtTxPDZmbMy2jGvdPxZk+BgCvQviY0ZWfc6qUBsgGrQu3Z tuU+ZNXQ==; Received: from [2001:8b0:10b:1::425] (helo=i7.infradead.org) by desiato.infradead.org with esmtpsa (Exim 4.99.2 #2 (Red Hat Linux)) id 1wVVZG-0000000Fhrn-2HLH; Fri, 05 Jun 2026 14:30:38 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.99.2 #2 (Red Hat Linux)) id 1wVVZE-0000000013X-1Wy0; Fri, 05 Jun 2026 15:30:36 +0100 From: David Woodhouse To: Sean Christopherson Cc: Paul Durrant , Hyunwoo Kim , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/8] KVM: x86/xen: Rename max_evtchn_port() to kvm_max_evtchn_port() Date: Fri, 5 Jun 2026 15:17:28 +0100 Message-ID: <20260605143034.3603-4-dwmw2@infradead.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260605143034.3603-1-dwmw2@infradead.org> References: <20260605143034.3603-1-dwmw2@infradead.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: David Woodhouse X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Content-Type: text/plain; charset="utf-8" From: David Woodhouse Rename in preparation for adding a variant that takes a latched bool argument for use in paths that need a consistent snapshot of the shinfo mode. No functional change. Assisted-by: Kiro:claude-opus-4.6-1m Signed-off-by: David Woodhouse --- arch/x86/kvm/xen.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c index acd3cd87dd2f..2c432fcfab15 100644 --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -1422,7 +1422,7 @@ static int kvm_xen_hypercall_complete_userspace(struc= t kvm_vcpu *vcpu) return kvm_xen_hypercall_set_result(vcpu, run->xen.u.hcall.result); } =20 -static inline int max_evtchn_port(struct kvm *kvm) +static inline int kvm_max_evtchn_port(struct kvm *kvm) { if (kvm_xen_has_64bit_shinfo(kvm)) return EVTCHN_2L_NR_CHANNELS; @@ -1529,7 +1529,7 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcp= u, bool is_64bit, } =20 for (i =3D 0; i < sched_poll.nr_ports; i++) { - if (ports[i] >=3D max_evtchn_port(vcpu->kvm)) { + if (ports[i] >=3D kvm_max_evtchn_port(vcpu->kvm)) { *r =3D -EINVAL; goto out; } @@ -1809,7 +1809,7 @@ int kvm_xen_set_evtchn_fast(struct kvm_xen_evtchn *xe= , struct kvm *kvm) WRITE_ONCE(xe->vcpu_idx, vcpu->vcpu_idx); } =20 - if (xe->port >=3D max_evtchn_port(kvm)) + if (xe->port >=3D kvm_max_evtchn_port(kvm)) return -EINVAL; =20 rc =3D -EWOULDBLOCK; @@ -1971,7 +1971,7 @@ int kvm_xen_setup_evtchn(struct kvm *kvm, struct kvm_vcpu *vcpu; =20 /* - * Don't check for the port being within range of max_evtchn_port(). + * Don't check for the port being within range of kvm_max_evtchn_port(). * Userspace can configure what ever targets it likes; events just won't * be delivered if/while the target is invalid, just like userspace can * configure MSIs which target non-existent APICs. @@ -1980,8 +1980,8 @@ int kvm_xen_setup_evtchn(struct kvm *kvm, * can be restored *independently* of other things like creating vCPUs, * without imposing an ordering dependency on userspace. In this * particular case, the problematic ordering would be with setting the - * Xen 'long mode' flag, which changes max_evtchn_port() to allow 4096 - * instead of 1024 event channels. + * Xen 'long mode' flag, which changes kvm_max_evtchn_port() to allow + * 4096 instead of 1024 event channels. */ =20 /* We only support 2 level event channels for now */ @@ -2018,7 +2018,7 @@ int kvm_xen_hvm_evtchn_send(struct kvm *kvm, struct k= vm_irq_routing_xen_evtchn * struct kvm_xen_evtchn e; int ret; =20 - if (!uxe->port || uxe->port >=3D max_evtchn_port(kvm)) + if (!uxe->port || uxe->port >=3D kvm_max_evtchn_port(kvm)) return -EINVAL; =20 /* We only support 2 level event channels for now */ @@ -2128,7 +2128,7 @@ static int kvm_xen_eventfd_assign(struct kvm *kvm, =20 case EVTCHNSTAT_interdomain: if (data->u.evtchn.deliver.port.port) { - if (data->u.evtchn.deliver.port.port >=3D max_evtchn_port(kvm)) + if (data->u.evtchn.deliver.port.port >=3D kvm_max_evtchn_port(kvm)) goto out_noeventfd; /* -EINVAL */ } else { eventfd =3D eventfd_ctx_fdget(data->u.evtchn.deliver.eventfd.fd); @@ -2246,7 +2246,7 @@ static int kvm_xen_setattr_evtchn(struct kvm *kvm, st= ruct kvm_xen_hvm_attr *data if (data->u.evtchn.flags =3D=3D KVM_XEN_EVTCHN_RESET) return kvm_xen_eventfd_reset(kvm); =20 - if (!port || port >=3D max_evtchn_port(kvm)) + if (!port || port >=3D kvm_max_evtchn_port(kvm)) return -EINVAL; =20 if (data->u.evtchn.flags =3D=3D KVM_XEN_EVTCHN_DEASSIGN) --=20 2.54.0 From nobody Mon Jun 8 05:26:40 2026 Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 82A74236A73; Fri, 5 Jun 2026 14:30:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.92.199 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669851; cv=none; b=oEogP1QrnxgG7lpaQeS8dH3ElObVy+Y3/W1fA/FVZkrF1DGyce9oaV8WNeWRo/q+qiklBBo9heIoonJYbqPJosP+lhUQtjDF59eMpEpIa4dQCTJ6qN48lzJV60vgptHjSoNQTSzWHWDW0k8pd80SLE0c7gSr2icQSKLi/G889Rw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669851; c=relaxed/simple; bh=h1GHtxQ2LS2GyBG7+ZY/ckD9ZkHuCv1h4k2ZvsUyPMw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=qbqR9v2oUdVSEqNKyWfgG61L2P8KDDZWNGREaRAI23JLkH6ID1IZBpPe+pVX/UmUz6A4GOMoe2LEZHvcbmCvwyMPlnvLHhb4Q+Kl0KWGrJynpY2LXVq9RDQAHuIZK390KfbJ6nJ29kmjQ44TCxY7Ye1+R5NmgYnt35bXgQEQBw0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=desiato.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=SZahnms7; arc=none smtp.client-ip=90.155.92.199 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=desiato.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="SZahnms7" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description; bh=ziIt1x1rqMK84pqdnMq+0P24wyN4pQRHLv2MTtM/nxs=; b=SZahnms7Njc9oh3KqoyBJd0PmX aOSBZTwIwgRSieDnTsIlnBe64jEG2xCll+r+rrWKN0OSb1QZBiTZikEDD/AqyEl7kkbxprEvIJQnS hDgysIIM/THhTyDwNNn4l9Xl6WxZ0WAJvWj+2fBYJPP95lwt+gYjKmmeKXI4Pv+PicMif9QqnZKe3 N4GYIMGnb+YWyPOtHPhrhIFhM6nch6mTtExsf9RQETUz5BJjnJNXwz5HzKSrbS5fJeqdPsj70BOBI H5A5xbLFwEvmgiC0nWdxijNCKgoyLm2YOv8i8pXaDMq6O2upz7399g/n+CBmE54aC2xAZ9Pp4A3Tc FqWn+99A==; Received: from [2001:8b0:10b:1::425] (helo=i7.infradead.org) by desiato.infradead.org with esmtpsa (Exim 4.99.2 #2 (Red Hat Linux)) id 1wVVZG-0000000Fhrm-2HLN; Fri, 05 Jun 2026 14:30:38 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.99.2 #2 (Red Hat Linux)) id 1wVVZE-0000000013a-1ft5; Fri, 05 Jun 2026 15:30:36 +0100 From: David Woodhouse To: Sean Christopherson Cc: Paul Durrant , Hyunwoo Kim , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/8] KVM: x86/xen: Latch shinfo mode in kvm_xen_set_evtchn_fast() Date: Fri, 5 Jun 2026 15:17:29 +0100 Message-ID: <20260605143034.3603-5-dwmw2@infradead.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260605143034.3603-1-dwmw2@infradead.org> References: <20260605143034.3603-1-dwmw2@infradead.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: David Woodhouse X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html From: Hyunwoo Kim kvm_xen_set_evtchn_fast() assumes the port range check in max_evtchn_port() and the bitmap layout selection observe the same shinfo mode, but each calls kvm_xen_has_64bit_shinfo() separately. If the guest changes the mode in between, a port accepted by the 64-bit range check is handled with the 32-bit layout, and port_word_bit falls outside evtchn_pending_sel. Latch kvm_xen_has_64bit_shinfo() once on entry so the range check and both layout computations use the same value. In practice this is harmless: the evtchn_pending bitmap is at the same offset in both native and compat shared_info layouts, so a stale mode just results in setting a bit in what the guest (in its new compat mode) considers the evtchn_mask, wallclock, or the arch_shared_info fields which follow it =E2=80=94 all of which are in the guest's own page. Even wi= th this fix, the same corruption can occur if 64-bit mode is latched and the guest switches to 32-bit mode immediately afterward. Like Xen, KVM makes no attempt to *convert* when shinfo mode is changed. Only the wallclock field is updated in the new location. This fix is for internal consistency rather than correcting any observable bug. Fixes: 14243b387137 ("KVM: x86/xen: Add KVM_IRQ_ROUTING_XEN_EVTCHN and even= t channel delivery") Reported-by: Hyunwoo Kim Signed-off-by: Hyunwoo Kim [dwmw2: Rework on top of long_mode/has_64bit_shinfo cleanups] Signed-off-by: David Woodhouse --- arch/x86/kvm/xen.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c index 2c432fcfab15..60bdf65216c2 100644 --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -1422,14 +1422,19 @@ static int kvm_xen_hypercall_complete_userspace(str= uct kvm_vcpu *vcpu) return kvm_xen_hypercall_set_result(vcpu, run->xen.u.hcall.result); } =20 -static inline int kvm_max_evtchn_port(struct kvm *kvm) +static inline int max_evtchn_port(bool has_64bit_shinfo) { - if (kvm_xen_has_64bit_shinfo(kvm)) + if (has_64bit_shinfo) return EVTCHN_2L_NR_CHANNELS; else return COMPAT_EVTCHN_2L_NR_CHANNELS; } =20 +static inline int kvm_max_evtchn_port(struct kvm *kvm) +{ + return max_evtchn_port(kvm_xen_has_64bit_shinfo(kvm)); +} + static bool wait_pending_event(struct kvm_vcpu *vcpu, int nr_ports, evtchn_port_t *ports) { @@ -1792,8 +1797,9 @@ static void kvm_xen_check_poller(struct kvm_vcpu *vcp= u, int port) int kvm_xen_set_evtchn_fast(struct kvm_xen_evtchn *xe, struct kvm *kvm) { struct gfn_to_pfn_cache *gpc =3D &kvm->arch.xen.shinfo_cache; - struct kvm_vcpu *vcpu; + bool has_64bit_shinfo =3D kvm_xen_has_64bit_shinfo(kvm); unsigned long *pending_bits, *mask_bits; + struct kvm_vcpu *vcpu; unsigned long flags; int port_word_bit; bool kick_vcpu =3D false; @@ -1809,7 +1815,7 @@ int kvm_xen_set_evtchn_fast(struct kvm_xen_evtchn *xe= , struct kvm *kvm) WRITE_ONCE(xe->vcpu_idx, vcpu->vcpu_idx); } =20 - if (xe->port >=3D kvm_max_evtchn_port(kvm)) + if (xe->port >=3D max_evtchn_port(has_64bit_shinfo)) return -EINVAL; =20 rc =3D -EWOULDBLOCK; @@ -1820,7 +1826,7 @@ int kvm_xen_set_evtchn_fast(struct kvm_xen_evtchn *xe= , struct kvm *kvm) if (!kvm_gpc_check(gpc, PAGE_SIZE)) goto out_rcu; =20 - if (kvm_xen_has_64bit_shinfo(kvm)) { + if (has_64bit_shinfo) { struct shared_info *shinfo =3D gpc->khva; pending_bits =3D (unsigned long *)&shinfo->evtchn_pending; mask_bits =3D (unsigned long *)&shinfo->evtchn_mask; @@ -1861,7 +1867,7 @@ int kvm_xen_set_evtchn_fast(struct kvm_xen_evtchn *xe= , struct kvm *kvm) goto out_rcu; } =20 - if (kvm_xen_has_64bit_shinfo(kvm)) { + if (has_64bit_shinfo) { struct vcpu_info *vcpu_info =3D gpc->khva; if (!test_and_set_bit(port_word_bit, &vcpu_info->evtchn_pending_sel)) { WRITE_ONCE(vcpu_info->evtchn_upcall_pending, 1); --=20 2.54.0 From nobody Mon Jun 8 05:26:40 2026 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 92D50369D41; Fri, 5 Jun 2026 14:30:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.50.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669850; cv=none; b=JCyirLDGQwwAm9qqY4UtDGlAyyn2/747TFT2SbhkTAdvDGTrqsr7Jjl/fKIoxEx8lNLiy7azYLMSkr3Bjcfq+EcdoUwHvYNxvP9B4JiuraYF2Mon7GK1R1pwDkAM4knoMEJY+QMTbSGy+kcs/vZijMG6uI01CHHMjsw+oGSQDY0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669850; c=relaxed/simple; bh=025sW0FGYjyVqoVNeJrYul48aMH/JEhkA5qcWuIYSdg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ntfRPXyNJnCm7ErSTSUJKaxGOtCA5sBTfkGf9NiUrRtHjwmVWJYBNet/mlsiiW37rAd3lGbFvxZ8CytoK4xUp9xeZONV9SMeM6O4+teVxTZ+Rd+7Yj2XeR3wNS711FnSsoMm2571o6+rbtFqfEQsfHsetsdmb8+S/I2p1CFeAGk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=casper.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=LrD3psS4; arc=none smtp.client-ip=90.155.50.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=casper.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="LrD3psS4" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=bRR0kvtbCYP0k1nDOdZajZm1rJH8Z50FVxMF+nSNB9A=; b=LrD3psS4m6CmCAoZXQQ7OnSHhe 9U1qXcqw6ZGFUDnnoROY+VVevitE4keD2+fg16L3wKruNGM8MUVmrRhUpsMkS8VtNSTR6an159NVO rOPNE4o44HvDAdxmLwPG3wu5k0F1U8dQigZvACJAzbqxT8RcN8DwgmNIbheJT7gqMVW010mtAK9eF 6Pxhc4Ba+bpNu1rhgqSBJmFRnXbow5B3jtLBG7WRv29TAyi0nVSTvcn9u7DMf1OebxFH2v8znYw6m 0LZ8XJSKUj3m4S+pNUupyV6XodQjL1unyKG3/7ThgMlWJgqERAsg+0uf0ZjVqJlkyvBNmftUzTfUC QFpawxGg==; Received: from [2001:8b0:10b:1::425] (helo=i7.infradead.org) by casper.infradead.org with esmtpsa (Exim 4.99.1 #2 (Red Hat Linux)) id 1wVVZE-0000000848b-22g7; Fri, 05 Jun 2026 14:30:37 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.99.2 #2 (Red Hat Linux)) id 1wVVZE-0000000013d-1ocO; Fri, 05 Jun 2026 15:30:36 +0100 From: David Woodhouse To: Sean Christopherson Cc: Paul Durrant , Hyunwoo Kim , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 5/8] KVM: x86/xen: Latch shinfo mode in kvm_xen_schedop_poll() Date: Fri, 5 Jun 2026 15:17:30 +0100 Message-ID: <20260605143034.3603-6-dwmw2@infradead.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260605143034.3603-1-dwmw2@infradead.org> References: <20260605143034.3603-1-dwmw2@infradead.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: David Woodhouse X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Content-Type: text/plain; charset="utf-8" From: David Woodhouse kvm_xen_schedop_poll() validates port numbers against kvm_max_evtchn_port() and then calls wait_pending_event() which reads the shinfo mode again to select the bitmap layout. Latch kvm_xen_has_64bit_shinfo() once and pass it to both max_evtchn_port() and wait_pending_event(). As with the previous fix to kvm_xen_set_evtchn_fast(), this is harmless in practice for the same reasons: the inconsistency can only corrupt fields in the guest's own shared_info page, and the same corruption can occur anyway if the mode changes immediately after the latch. Fixes: d518b9d0fc80 ("KVM: x86/xen: handle PV spinlocks slowpath") Assisted-by: Kiro:claude-opus-4.6-1m Signed-off-by: David Woodhouse --- arch/x86/kvm/xen.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c index 60bdf65216c2..f9085612e7df 100644 --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -1435,8 +1435,8 @@ static inline int kvm_max_evtchn_port(struct kvm *kvm) return max_evtchn_port(kvm_xen_has_64bit_shinfo(kvm)); } =20 -static bool wait_pending_event(struct kvm_vcpu *vcpu, int nr_ports, - evtchn_port_t *ports) +static bool wait_pending_event(struct kvm_vcpu *vcpu, bool has_64bit_shinf= o, + int nr_ports, evtchn_port_t *ports) { struct kvm *kvm =3D vcpu->kvm; struct gfn_to_pfn_cache *gpc =3D &kvm->arch.xen.shinfo_cache; @@ -1451,7 +1451,7 @@ static bool wait_pending_event(struct kvm_vcpu *vcpu,= int nr_ports, goto out_rcu; =20 ret =3D false; - if (kvm_xen_has_64bit_shinfo(kvm)) { + if (has_64bit_shinfo) { struct shared_info *shinfo =3D gpc->khva; pending_bits =3D (unsigned long *)&shinfo->evtchn_pending; } else { @@ -1476,6 +1476,7 @@ static bool wait_pending_event(struct kvm_vcpu *vcpu,= int nr_ports, static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool is_64bit, u64 param, u64 *r) { + bool has_64bit_shinfo =3D kvm_xen_has_64bit_shinfo(vcpu->kvm); struct sched_poll sched_poll; evtchn_port_t port, *ports; struct x86_exception e; @@ -1534,7 +1535,7 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcp= u, bool is_64bit, } =20 for (i =3D 0; i < sched_poll.nr_ports; i++) { - if (ports[i] >=3D kvm_max_evtchn_port(vcpu->kvm)) { + if (ports[i] >=3D max_evtchn_port(has_64bit_shinfo)) { *r =3D -EINVAL; goto out; } @@ -1547,7 +1548,7 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcp= u, bool is_64bit, =20 set_bit(vcpu->vcpu_idx, vcpu->kvm->arch.xen.poll_mask); =20 - if (!wait_pending_event(vcpu, sched_poll.nr_ports, ports)) { + if (!wait_pending_event(vcpu, has_64bit_shinfo, sched_poll.nr_ports, port= s)) { kvm_set_mp_state(vcpu, KVM_MP_STATE_HALTED); =20 if (sched_poll.timeout) --=20 2.54.0 From nobody Mon Jun 8 05:26:40 2026 Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 065753C73E5; Fri, 5 Jun 2026 14:30:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.92.199 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669854; cv=none; b=UMazw33FXSfcet7G9Z22fd9zW0h6q7GdOBGKoKV5k5pvvbtZa4L0zlVrPT6JbOUX4SojlRAjc9f4DyjJul32Ks3B33C3cUdHHikYqWy1acBiLrG7+/SdpJ0lMn0QntvcPoNYQkgrT3lATc3yMLWpk6rve0XqKTrRXuRk70OOQC8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669854; c=relaxed/simple; bh=N+3z0mVSciqHtHuMOt12FJAryfFDA/1ly86ZaC5Sm3A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RpFGg4pD1GJJsKqbjSOQTG+BCkAdGR89FqN3m+5tMTZsDu+AEX1RQXwFCu9kqeFMHyu3KjwZuwwOBPOo86/y5TF8GGdY0ssr/M2qnFu8Qfn77dLnMhMQ2gfW+S/9iYgbD3QiACXJ9wwb9DQo0e/PAiMkvQ21druVApZCN+Ztcls= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=desiato.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=CLCoCM2/; arc=none smtp.client-ip=90.155.92.199 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=desiato.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="CLCoCM2/" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=s5dGgb2KywZyukUWTXvEMf+VLfy7xHDKLSJ2Rh8KmBc=; b=CLCoCM2/f9aP/w6r3/PcmVsmST c+wmL8IBbrWCw952nnw+yASzzf0IKO8w0hiIsF8R/HAub6ZN4tpccRwrwSFC501xsjLNyQxfqKl7x KpdHZN8PblgSQVJuE6W/12WVGmNZXWj6tTbM7PF6zO0++ZGYScFuIupMScxRcDWgJyYs773MBBfe6 hwTtW+IUoLdTe7Plr8D70NNaaRuvlRcyzvEQzHrIXpC4ZIpFXrQasz6RPZYEFQBPyxIyFNxAybWXZ GBdbETGbKCZQFUzi9hP3w1CI1irBcfLj2scBqVkpjsuZqMF/0JnP8D50VtrHk1KClLMa0X1jroZ+A //6dHwjw==; Received: from [2001:8b0:10b:1::425] (helo=i7.infradead.org) by desiato.infradead.org with esmtpsa (Exim 4.99.2 #2 (Red Hat Linux)) id 1wVVZG-0000000Fhro-2HKx; Fri, 05 Jun 2026 14:30:38 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.99.2 #2 (Red Hat Linux)) id 1wVVZE-0000000013g-1x4R; Fri, 05 Jun 2026 15:30:36 +0100 From: David Woodhouse To: Sean Christopherson Cc: Paul Durrant , Hyunwoo Kim , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 6/8] KVM: x86/xen: Enforce alignment of vcpu_info registration Date: Fri, 5 Jun 2026 15:17:31 +0100 Message-ID: <20260605143034.3603-7-dwmw2@infradead.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260605143034.3603-1-dwmw2@infradead.org> References: <20260605143034.3603-1-dwmw2@infradead.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: David Woodhouse X-SRS-Rewrite: SMTP reverse-path rewritten from by desiato.infradead.org. See http://www.infradead.org/rpr.html Content-Type: text/plain; charset="utf-8" From: David Woodhouse Xen enforces that the vcpu_info GPA is aligned to sizeof(xen_ulong_t) (8 bytes in 64-bit mode, 4 bytes in 32-bit mode) in map_guest_area(). KVM has no such check, allowing a guest to register a vcpu_info at an arbitrary byte alignment. This can cause split-lock #AC exceptions on hosts with split_lock_detect=3Dfatal, since the event channel delivery paths use locked atomic operations on evtchn_pending_sel within the vcpu_info. Add the same alignment check that Xen performs at vcpu_info registration time, based on the current long_mode state. Return -ENXIO on failure, matching Xen's map_guest_area() behaviour for unaligned requests. Like Xen, this allows a guest to register vcpu_info at a 4-byte (but not 8-byte) aligned address while in 32-bit mode and then switch to 64-bit mode. Xen copes with this because it only uses 32-bit atomics on vcpu_info fields, which is what subsequent commits will do where necessary for KVM too. Originally observed in review of an unrelated patch: https://lore.kernel.org/all/20260604193554.1BA311F00893@smtp.kernel.org/ Cc: stable@vger.kernel.org Fixes: 73e69a86347a ("KVM: x86/xen: register vcpu info") Reported-by: sashiko-bot@kernel.org Assisted-by: Kiro:claude-opus-4.6-1m Signed-off-by: David Woodhouse --- arch/x86/kvm/xen.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c index f9085612e7df..ae0713718367 100644 --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -926,6 +926,12 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struc= t kvm_xen_vcpu_attr *data) break; } =20 + r =3D -ENXIO; + if (!IS_ALIGNED(data->u.gpa, + kvm_xen_has_64bit_shinfo(vcpu->kvm) ? + sizeof(unsigned long) : sizeof(u32))) + break; + r =3D kvm_gpc_activate(&vcpu->arch.xen.vcpu_info_cache, data->u.gpa, sizeof(struct vcpu_info)); } else { @@ -935,6 +941,12 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struc= t kvm_xen_vcpu_attr *data) break; } =20 + r =3D -ENXIO; + if (!IS_ALIGNED(data->u.hva, + kvm_xen_has_64bit_shinfo(vcpu->kvm) ? + sizeof(unsigned long) : sizeof(u32))) + break; + r =3D kvm_gpc_activate_hva(&vcpu->arch.xen.vcpu_info_cache, data->u.hva, sizeof(struct vcpu_info)); } --=20 2.54.0 From nobody Mon Jun 8 05:26:40 2026 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1C5693B27C9; Fri, 5 Jun 2026 14:30:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.50.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669849; cv=none; b=P+wHSP1IRnpLYiumoTg/kw25rC1oD0n2oWLAXKkDjCNmPA2p/+8DOriPRj4kQh5eIMPfpAH1YOV/Hkktzf43vjSV0rPjPDDNcdzEzrtfDvYxGdh2/e8MVaW7QhmBi8XF5eFQil6Ty72Go5E1TVzbPn5D9fltIxEwsZ2Nn17fFPU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669849; c=relaxed/simple; bh=nQwTxl/c6hNyrtiK3GLaUFGTWu1Pq98jPNhLZoIJG3M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rGyD9Ryjkue+zFMM2uYIajRBWCvvMyASRKzSQp8OKQnrToOBm7Ro+rooGiGG0PQuStYQkdT98up9DjPQUvwa3eoKk0fWfsqPrPoGr7hWheeWNuy1VGOMhmGCbFi/lLy6pOdfTcLW6B28mWBN4lAxmvLF+uwuWwBwCUb4ocF/FYA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=casper.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=g5feNJgw; arc=none smtp.client-ip=90.155.50.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=casper.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="g5feNJgw" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=R6m97oGyXM5wXsX6tvDVPhETAHa89nqtaU5+VWjI5uc=; b=g5feNJgwhDGuG2kuNZGDeoTN2W GKj6+bDAnZd7rNxG85FV9je8QVi/iJrEBnNhjJWLX7aEPdcm7NcdVAuLU2n3N8ubqqB1X08X8S8T7 c/UUVNSMS5fyq1ilpXuuSt3yatJuPLyPI5BmEgtW8le2Eb7RRA1aDcUGB6FJibrTqnGfT2SNMdlS6 6j1CuaXNeMoJzL6WvD//KM6ZPRhsjceHJ931CkQTS+I/A+6vVZ2J7bM4gXohOj9LMIWb1LVFCblRq d08Gydt6+OCfyI1RGJFX9OJjh+Ec1Wv+y85TWGhyECLRLzeMGlFPw6IRs88b4kRZmSc2LRkoybCvf d+KXStVQ==; Received: from [2001:8b0:10b:1::425] (helo=i7.infradead.org) by casper.infradead.org with esmtpsa (Exim 4.99.1 #2 (Red Hat Linux)) id 1wVVZE-0000000848Z-2367; Fri, 05 Jun 2026 14:30:37 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.99.2 #2 (Red Hat Linux)) id 1wVVZE-0000000013k-2Ath; Fri, 05 Jun 2026 15:30:36 +0100 From: David Woodhouse To: Sean Christopherson Cc: Paul Durrant , Hyunwoo Kim , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 7/8] KVM: x86/xen: Use 32-bit locked bts for vcpu_info evtchn_pending_sel Date: Fri, 5 Jun 2026 15:17:32 +0100 Message-ID: <20260605143034.3603-8-dwmw2@infradead.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260605143034.3603-1-dwmw2@infradead.org> References: <20260605143034.3603-1-dwmw2@infradead.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: David Woodhouse X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Content-Type: text/plain; charset="utf-8" From: David Woodhouse Replace test_and_set_bit() on vcpu_info->evtchn_pending_sel with an explicit 'lock btsl' in kvm_xen_set_evtchn_fast(). The generic test_and_set_bit() uses a 64-bit locked operation ('lock btsq') on x86-64, which requires 8-byte alignment to avoid split-lock #AC exceptions. Since evtchn_pending_sel is at most 64 bits wide and port_word_bit ranges 0-63, a 32-bit 'lock btsl' suffices for both native and compat vcpu_info layouts, and only requires the 4-byte alignment that is already guaranteed by the registration path. This also eliminates the bogus cast of compat_vcpu_info's 32-bit evtchn_pending_sel to 'unsigned long *' which was the original source of the split-lock hazard. Fixes: 14243b387137 ("KVM: x86/xen: Add KVM_IRQ_ROUTING_XEN_EVTCHN and even= t channel delivery") Reported-by: sashiko-bot@kernel.org Assisted-by: Kiro:claude-opus-4.6-1m Signed-off-by: David Woodhouse --- arch/x86/kvm/xen.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c index ae0713718367..24e939ef5d64 100644 --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -1811,7 +1811,7 @@ int kvm_xen_set_evtchn_fast(struct kvm_xen_evtchn *xe= , struct kvm *kvm) { struct gfn_to_pfn_cache *gpc =3D &kvm->arch.xen.shinfo_cache; bool has_64bit_shinfo =3D kvm_xen_has_64bit_shinfo(kvm); - unsigned long *pending_bits, *mask_bits; + unsigned long *pending_bits, *mask_bits, vi_pending_sel_ofs; struct kvm_vcpu *vcpu; unsigned long flags; int port_word_bit; @@ -1844,11 +1844,18 @@ int kvm_xen_set_evtchn_fast(struct kvm_xen_evtchn *= xe, struct kvm *kvm) pending_bits =3D (unsigned long *)&shinfo->evtchn_pending; mask_bits =3D (unsigned long *)&shinfo->evtchn_mask; port_word_bit =3D xe->port / 64; + + vi_pending_sel_ofs =3D offsetof(struct vcpu_info, evtchn_pending_sel); } else { struct compat_shared_info *shinfo =3D gpc->khva; pending_bits =3D (unsigned long *)&shinfo->evtchn_pending; mask_bits =3D (unsigned long *)&shinfo->evtchn_mask; port_word_bit =3D xe->port / 32; + + vi_pending_sel_ofs =3D offsetof(struct compat_vcpu_info, evtchn_pending_= sel); + + /* test_and_set_bit() needs 64-bit alignment, but that's OK */ + BUILD_BUG_ON(offsetof(struct compat_shared_info, evtchn_pending) & 7); } =20 /* @@ -1864,6 +1871,8 @@ int kvm_xen_set_evtchn_fast(struct kvm_xen_evtchn *xe= , struct kvm *kvm) rc =3D -ENOTCONN; /* Masked */ kvm_xen_check_poller(vcpu, xe->port); } else { + bool old; + rc =3D 1; /* Delivered to the bitmap in shared_info. */ /* Now switch to the vCPU's vcpu_info to set the index and pending_sel */ read_unlock_irqrestore(&gpc->lock, flags); @@ -1880,19 +1889,24 @@ int kvm_xen_set_evtchn_fast(struct kvm_xen_evtchn *= xe, struct kvm *kvm) goto out_rcu; } =20 - if (has_64bit_shinfo) { - struct vcpu_info *vcpu_info =3D gpc->khva; - if (!test_and_set_bit(port_word_bit, &vcpu_info->evtchn_pending_sel)) { - WRITE_ONCE(vcpu_info->evtchn_upcall_pending, 1); - kick_vcpu =3D true; - } - } else { - struct compat_vcpu_info *vcpu_info =3D gpc->khva; - if (!test_and_set_bit(port_word_bit, - (unsigned long *)&vcpu_info->evtchn_pending_sel)) { - WRITE_ONCE(vcpu_info->evtchn_upcall_pending, 1); - kick_vcpu =3D true; - } + /* + * Explicitly use btsl instead of test_and_set_bit() because + * a 32-bit guest is not required to align to 64 bits, and + * that might cause splitlock exceptions. + */ + asm volatile(LOCK_PREFIX "btsl %[bit], %[sel]" + : [sel] "+m" (*(u32 *)(gpc->khva + vi_pending_sel_ofs)), + "=3D@ccc" (old) + : [bit] "Ir" (port_word_bit) : "memory"); + if (!old) { + struct vcpu_info *vi =3D gpc->khva; + + /* No need for compat handling */ + BUILD_BUG_ON(offsetof(struct vcpu_info, evtchn_upcall_pending) !=3D + offsetof(struct compat_vcpu_info, evtchn_upcall_pending)); + + WRITE_ONCE(vi->evtchn_upcall_pending, 1); + kick_vcpu =3D true; } =20 /* For the per-vCPU lapic vector, deliver it as MSI. */ --=20 2.54.0 From nobody Mon Jun 8 05:26:40 2026 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5C8553B1ECD; Fri, 5 Jun 2026 14:30:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.50.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669849; cv=none; b=K8l2AviuDuGjfVGoOJzBN4g1CuH43ir62VYBs5fu45WFESq0elN6XatJ0imE0UnmVLW5F6q+UEle4ZB0g4FS2SE+0RcUwqYX438qmswGraXhgwHTmmraM+6ul6YJRy/Ld/ZXxJFLFu0QGs8lJ5rySLTku+ViEEfrhmc8sdRbTuQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780669849; c=relaxed/simple; bh=8T/5nsA/wlFXpvI3Www5yBG2dEEzVOH2TyRuWxqN+3o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FnBFgK+sTtRZd0JRqd/kR6AnQWGWbVAvbMesr+VgNgX9Upv/E+FVKMpbUElkMxKJUEGpLOWB6r19ZG/CQv3fgod5uukxibtKSKEZva8PdNqO03+1OOiuak/8zV2BNiBPnviH5t9OSNmHRFmtrKQgfDhvXIT1RL9Vg0n1vNUaCBY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=casper.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=cKqqx7Lp; arc=none smtp.client-ip=90.155.50.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=casper.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="cKqqx7Lp" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=S1+xA5OPImNvZdyaYwZzy4uNneY+HSte6Mte2bTUqTk=; b=cKqqx7Lp20LWJNAf4Cn5XN+pvI FuJ/qqJOGvotmewxho4Hivl3hMZWNurfBle+v6NUQRudQ+5XdFdcZ2/KBYZW0Wn4zvsj9yMI/mdSf c1xjloqFZ4l1ZPGgwsgd4ZR87ekVLUUDd4UFu3kDzx5DzuYnS+owVBqaERLwfTwnWWmZrcyGYVO92 MRYKaDzsmA4hRlXsYJg4gpFK0X5imdbLlPNiPdcELqZvuBvlUZH2r7dWVxks2X4aJSrUJFJUbyZtE HA6pNdDKakMQQiFZGsX9wSkxPnTMfFcCU1bFGl9DznQh4m6+zh82frAC02dOiNPZ9Lb7ExjKka7N0 yGmVc4ZA==; Received: from [2001:8b0:10b:1::425] (helo=i7.infradead.org) by casper.infradead.org with esmtpsa (Exim 4.99.1 #2 (Red Hat Linux)) id 1wVVZE-0000000848a-24kV; Fri, 05 Jun 2026 14:30:37 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.99.2 #2 (Red Hat Linux)) id 1wVVZE-0000000013n-2Not; Fri, 05 Jun 2026 15:30:36 +0100 From: David Woodhouse To: Sean Christopherson Cc: Paul Durrant , Hyunwoo Kim , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 8/8] KVM: x86/xen: Use 32-bit locked ops in kvm_xen_inject_pending_events() Date: Fri, 5 Jun 2026 15:17:33 +0100 Message-ID: <20260605143034.3603-9-dwmw2@infradead.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260605143034.3603-1-dwmw2@infradead.org> References: <20260605143034.3603-1-dwmw2@infradead.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: David Woodhouse X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Content-Type: text/plain; charset="utf-8" From: David Woodhouse The 64-bit path in kvm_xen_inject_pending_events() uses 'lock orq' and 'lock andq' on vcpu_info->evtchn_pending_sel. If the vcpu_info was registered with only 4-byte alignment (valid for a 32-bit guest that later switches to 64-bit mode), this 8-byte locked operation can cause split-lock #AC exceptions on hosts with split_lock_detect=3Dfatal. Use the original 64-bit atomics when the vcpu_info is 8-byte aligned (the common case). Fall back to a 32-bit loop for the rare case where vcpu_info was registered at only 4-byte alignment. For compat guests (32-bit evtchn_pending_sel) the loop executes once. For native guests it executes a second iteration only if the high half has bits to deliver. Fixes: 14243b387137 ("KVM: x86/xen: Add KVM_IRQ_ROUTING_XEN_EVTCHN and even= t channel delivery") Reported-by: sashiko-bot@kernel.org Assisted-by: Kiro:claude-opus-4.6-1m Signed-off-by: David Woodhouse --- arch/x86/kvm/xen.c | 63 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c index 24e939ef5d64..e7b0263d5143 100644 --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -638,11 +638,17 @@ void kvm_xen_inject_vcpu_vector(struct kvm_vcpu *v) */ void kvm_xen_inject_pending_events(struct kvm_vcpu *v) { - unsigned long evtchn_pending_sel =3D READ_ONCE(v->arch.xen.evtchn_pending= _sel); struct gfn_to_pfn_cache *gpc =3D &v->arch.xen.vcpu_info_cache; + bool has_64bit_shinfo =3D kvm_xen_has_64bit_shinfo(v->kvm); + union evtchn_pending_sel { + u64 sel64; + u32 sel32[2]; + } pending, *sel_addr; + struct vcpu_info *vi; unsigned long flags; =20 - if (!evtchn_pending_sel) + pending.sel64 =3D READ_ONCE(v->arch.xen.evtchn_pending_sel); + if (!pending.sel64) return; =20 /* @@ -661,31 +667,50 @@ void kvm_xen_inject_pending_events(struct kvm_vcpu *v) } =20 /* Now gpc->khva is a valid kernel address for the vcpu_info */ - if (kvm_xen_has_64bit_shinfo(v->kvm)) { - struct vcpu_info *vi =3D gpc->khva; + vi =3D gpc->khva; + sel_addr =3D gpc->khva + (has_64bit_shinfo ? + offsetof(struct vcpu_info, evtchn_pending_sel) : + offsetof(struct compat_vcpu_info, evtchn_pending_sel)); =20 + if (has_64bit_shinfo && IS_ALIGNED((unsigned long)sel_addr, sizeof(u64)))= { + /* + * 64-bit shinfo with 8-byte aligned vcpu_info (the common + * case): use a single 64-bit atomic. + */ asm volatile(LOCK_PREFIX "orq %0, %1\n" "notq %0\n" LOCK_PREFIX "andq %0, %2\n" - : "=3Dr" (evtchn_pending_sel), - "+m" (vi->evtchn_pending_sel), + : "=3Dr" (pending.sel64), + "+m" (sel_addr->sel64), "+m" (v->arch.xen.evtchn_pending_sel) - : "0" (evtchn_pending_sel)); - WRITE_ONCE(vi->evtchn_upcall_pending, 1); + : "0" (pending.sel64)); } else { - u32 evtchn_pending_sel32 =3D evtchn_pending_sel; - struct compat_vcpu_info *vi =3D gpc->khva; - - asm volatile(LOCK_PREFIX "orl %0, %1\n" - "notl %0\n" - LOCK_PREFIX "andl %0, %2\n" - : "=3Dr" (evtchn_pending_sel32), - "+m" (vi->evtchn_pending_sel), - "+m" (v->arch.xen.evtchn_pending_sel) - : "0" (evtchn_pending_sel32)); - WRITE_ONCE(vi->evtchn_upcall_pending, 1); + /* + * Use 32-bit operations to avoid splitlock on a vcpu_info + * that is only 4-byte aligned (registered in 32-bit mode). + * The loop copes with the extremely rare case that the + * vcpu_info was registered in 32-bit mode and only enforced + * 4-byte alignment, and then the VM was latched to 64-bit + * mode afterwards. Which Xen tolerates, so so should KVM. + */ + int i =3D 0; + do { + asm volatile(LOCK_PREFIX "orl %0, %1\n" + "notl %0\n" + LOCK_PREFIX "andl %0, %2\n" + : "=3Dr" (pending.sel32[i]), + "+m" (sel_addr->sel32[i]), + "+m" (((u32 *)&v->arch.xen.evtchn_pending_sel)[i]) + : "0" (pending.sel32[i])); + i++; + } while (has_64bit_shinfo && i < 2 && pending.sel32[i]); } =20 + /* Assert that there is no need for compat for evtchn_upcall_pending */ + BUILD_BUG_ON(offsetof(struct vcpu_info, evtchn_upcall_pending) !=3D + offsetof(struct compat_vcpu_info, evtchn_upcall_pending)); + WRITE_ONCE(vi->evtchn_upcall_pending, 1); + kvm_gpc_mark_dirty_in_slot(gpc); read_unlock_irqrestore(&gpc->lock, flags); =20 --=20 2.54.0