All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Akihiko Odaki" <odaki@rsg.ci.i.u-tokyo.ac.jp>
Cc: kvmarm@lists.linux.dev, kvm@vger.kernel.org,
	"Marc Zyngier" <maz@kernel.org>,
	"Oliver Upton" <oupton@kernel.org>
Subject: Re: [PATCH v8 01/11] KVM: arm64: Serialize userspace MDCR_EL2 access
Date: Fri, 10 Jul 2026 11:36:51 +0000	[thread overview]
Message-ID: <20260710113651.CACAF1F00ACA@smtp.kernel.org> (raw)
In-Reply-To: <20260710-hybrid-v8-1-621409f3a592@rsg.ci.i.u-tokyo.ac.jp>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [High] Missing kvm_vm_has_ran_once() check allows KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS to cause data races on MDCR_EL2 for running vCPUs.
- [High] Changes to MDCR_EL2 fields (HPMN, HPMD, HLP) fail to trigger a PMU reload, leaving active perf events with a stale configuration.
- [High] Secondary KVM_ARM_VCPU_INIT calls bypass config_lock, causing data races with PMU configuration on MDCR_EL2.
--

--- Patch [1]: [PATCH v8 01/11] KVM: arm64: Serialize userspace MDCR_EL2 access ---
commit baa2d20fcb9f1e3b0daa7a4b72d1709acdab0380
Author: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>

KVM: arm64: Serialize userspace MDCR_EL2 access

This patch addresses a race condition between PMU configuration and register
restore by adding explicit userspace accessors for MDCR_EL2. It serializes
these accesses using config_lock to ensure whole-register writes do not
conflict with HPMN rewrites.

> kvm_arm_set_nr_counters() updates MDCR_EL2.HPMN for every vCPU while
> holding kvm->arch.config_lock. However, KVM_SET_ONE_REG currently writes
> MDCR_EL2 through the generic sysreg path without taking the same lock.
> Concurrent PMU configuration and register restore can therefore race and
> lose updates to unrelated MDCR_EL2 bits.

[Severity: High]
This isn't a bug introduced by this patch, but does kvm_arm_set_nr_counters()
still have a race with running vCPUs?

Userspace can invoke KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS on an uninitialized
vCPU while another vCPU in the same VM is running. The ioctl handler in
arch/arm64/kvm/pmu-emul.c:kvm_arm_pmu_v3_set_attr() does not check
kvm_vm_has_ran_once(kvm).

It proceeds to call kvm_arm_set_nr_counters(), which performs a read-modify-write
of MDCR_EL2 across all vCPUs without acquiring their vcpu->mutex:

arch/arm64/kvm/pmu-emul.c:kvm_arm_set_nr_counters() {
	kvm_for_each_vcpu(i, vcpu, kvm) {
		u64 val = __vcpu_sys_reg(vcpu, MDCR_EL2);
		val &= ~MDCR_EL2_HPMN;
		val |= FIELD_PREP(MDCR_EL2_HPMN, kvm->arch.nr_pmu_counters);
		__vcpu_assign_sys_reg(vcpu, MDCR_EL2, val);
	}
}

If a running vCPU concurrently traps on MDCR_EL2, access_mdcr() will perform a
racing read-modify-write. Could this cause data corruption of the guest's
MDCR_EL2 sysreg?

> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 33c921df19b54..6ab46f21aa614 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c

[ ... ]

> +static int set_mdcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
> +		    u64 val)
> +{
> +	struct kvm *kvm = vcpu->kvm;
> +	u64 old, hpmn = FIELD_GET(MDCR_EL2_HPMN, val);
> +
> +	guard(mutex)(&kvm->arch.config_lock);

[Severity: High]
This isn't a bug introduced by this patch, but does the use of config_lock here
completely prevent races with KVM_ARM_VCPU_INIT?

While this patch adds config_lock to serialize userspace writes against
kvm_arm_set_nr_counters(), MDCR_EL2 is also updated during KVM_ARM_VCPU_INIT.

For secondary inits (already initialized vCPUs), the config_lock is bypassed:

arch/arm64/kvm/arm.c:kvm_vcpu_set_target() {
	if (!kvm_vcpu_initialized(vcpu))
		return __kvm_vcpu_set_target(vcpu, init);

	if (kvm_vcpu_init_changed(vcpu, init))
		return -EINVAL;

	kvm_reset_vcpu(vcpu);
	return 0;
}

This allows reset_mdcr() to read nr_pmu_counters and write MDCR_EL2 without
config_lock, which could race with kvm_arm_set_nr_counters() modifying all
vCPUs' MDCR_EL2 registers.

> +
> +	if (hpmn > vcpu->kvm->arch.nr_pmu_counters)
> +		return -EINVAL;
> +
> +	old = __vcpu_sys_reg(vcpu, MDCR_EL2);
> +	__vcpu_assign_sys_reg(vcpu, MDCR_EL2, val);
> +
> +	/*
> +	 * Request a reload of the PMU to enable/disable the counters
> +	 * affected by HPME.
> +	 */
> +	if ((old ^ val) & MDCR_EL2_HPME)
> +		kvm_make_request(KVM_REQ_RELOAD_PMU, vcpu);
> +
> +	return 0;
> +}

[Severity: High]
This is a pre-existing issue, but does checking only HPME leave the PMU in a
stale configuration if other fields change?

Both the newly added set_mdcr() and the existing access_mdcr() only request a
PMU reload when the MDCR_EL2_HPME bit toggles. However, if fields like HPMN,
HPMD, or HLP change, shouldn't active perf events be re-evaluated to reflect
the new semantics?

If a guest or userspace modifies these fields but leaves HPME unchanged, could
host perf events count incorrectly or run with stale privilege exclusion
semantics?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260710-hybrid-v8-0-621409f3a592@rsg.ci.i.u-tokyo.ac.jp?part=1

  reply	other threads:[~2026-07-10 11:37 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-10 11:14 [PATCH v8 00/11] KVM: arm64: PMU: Use multiple host PMUs Akihiko Odaki
2026-07-10 11:14 ` [PATCH v8 01/11] KVM: arm64: Serialize userspace MDCR_EL2 access Akihiko Odaki
2026-07-10 11:36   ` sashiko-bot [this message]
2026-07-13  7:33   ` Oliver Upton
2026-07-13 21:31     ` Akihiko Odaki
2026-07-10 11:14 ` [PATCH v8 02/11] tools headers: Sync bitfield.h with the kernel Akihiko Odaki
2026-07-10 11:14 ` [PATCH v8 03/11] KVM: arm64: selftests: Cover PMU state in MDCR_EL2 Akihiko Odaki
2026-07-10 11:14 ` [PATCH v8 04/11] arm64: errata: Require Apple IMPDEF PMUv3 traps on all CPUs Akihiko Odaki
2026-07-10 11:40   ` sashiko-bot
2026-07-10 11:14 ` [PATCH v8 05/11] KVM: arm64: Don't clear vcpu->cpu in kvm_arch_vcpu_put() Akihiko Odaki
2026-07-10 11:15 ` [PATCH v8 06/11] KVM: arm64: PMU: Protect the list of PMUs with RCU Akihiko Odaki
2026-07-10 11:15 ` [PATCH v8 07/11] KVM: arm64: PMU: Pass the pPMU to kvm_map_pmu_event() Akihiko Odaki
2026-07-10 11:15 ` [PATCH v8 08/11] KVM: arm64: PMU: Pass the target CPU to kvm_pmu_probe_armpmu() Akihiko Odaki
2026-07-10 11:15 ` [PATCH v8 09/11] KVM: arm64: PMU: Implement fixed-counters-only emulation Akihiko Odaki
2026-07-10 11:48   ` sashiko-bot
2026-07-13  7:41   ` Oliver Upton
2026-07-13 21:50     ` Akihiko Odaki
2026-07-10 11:15 ` [PATCH v8 10/11] KVM: arm64: PMU: Introduce FIXED_COUNTERS_ONLY Akihiko Odaki
2026-07-10 11:15 ` [PATCH v8 11/11] KVM: arm64: selftests: Test PMU_V3_FIXED_COUNTERS_ONLY Akihiko Odaki

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=20260710113651.CACAF1F00ACA@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=maz@kernel.org \
    --cc=odaki@rsg.ci.i.u-tokyo.ac.jp \
    --cc=oupton@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.