Linux Perf Users
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Colton Lewis" <coltonlewis@google.com>
Cc: kvm@vger.kernel.org, "Marc Zyngier" <maz@kernel.org>,
	"Oliver Upton" <oupton@kernel.org>,
	kvmarm@lists.linux.dev, linux-perf-users@vger.kernel.org
Subject: Re: [PATCH 17/21] KVM: arm64: Detect overflows for the Partitioned PMU
Date: Fri, 12 Jun 2026 19:58:06 +0000	[thread overview]
Message-ID: <20260612195806.82C5A1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260612192909.1153907-18-coltonlewis@google.com>

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

New issues:
- [High] Missing return and failure to synchronize hardware registers when transitioning to VCPU_PMU_ACCESS_GUEST_OWNED drops interrupts and corrupts guest PMU state.
- [High] kvm_pmu_part_overflow_status() evaluates overflow using stale software PMOVSSET_EL0 instead of the physical register when the PMU is guest-owned, missing hardware overflows.
- [Low] Unused prototype for `kvm_pmu_overflow_status` left in header.

Pre-existing issues:
- [High] Non-atomic read-modify-write of PMOVSSET_EL0 in hardirq context corrupts concurrent process-context writes.
- [High] Missing required `isb()` synchronization immediately following a write to the `pmcr_el0` control-plane system register.
--

commit df42d2108e88f67258ce6c2dfa8340d8d1ee7a87
Author: Colton Lewis <coltonlewis@google.com>

KVM: arm64: Detect overflows for the Partitioned PMU
    
When we re-enter the VM after handling a PMU interrupt, calculate
whether it was any of the guest counters that overflowed and inject an
interrupt into the guest if so.

> diff --git a/arch/arm64/kvm/pmu-direct.c b/arch/arm64/kvm/pmu-direct.c
> index 64f40cfb31012..0062d1d8e1999 100644
> --- a/arch/arm64/kvm/pmu-direct.c
> +++ b/arch/arm64/kvm/pmu-direct.c

[Severity: High]
This isn't a bug introduced by this patch, but looking at
kvm_pmu_direct_pmcr_write() in this file, is there a missing isb() after
writing the control register?

arch/arm64/kvm/pmu-direct.c:kvm_pmu_direct_pmcr_write() {
    write_sysreg(val, pmcr_el0);
    if (reset_p) {
...
}

Architectural rules require every write to a control-plane system register
to be followed by an isb() as the very next instruction. Since it is followed
immediately by a conditional branch, can the pipeline observe undefined state?

> @@ -426,4 +426,52 @@ void kvm_pmu_handle_guest_irq(struct arm_pmu *pmu, u64 pmovsr)
>  		return;
>  
>  	__vcpu_rmw_sys_reg(vcpu, PMOVSSET_EL0, |=, govf);

[Severity: High]
This is a pre-existing issue, but does this non-atomic read-modify-write
in hardirq context corrupt concurrent process-context writes?

When the physical PMU interrupt handler calls kvm_pmu_handle_guest_irq(), it
executes this macro in hardirq context. Concurrently, the VM-exit path
(access_pmovs()) can execute the same macro in process context with
interrupts enabled.

If the hardware interrupt preempts the process context between the read and
write phases, could the process context overwrite the sysreg with its stale
read and silently drop the overflow bits?

> +
> +	if (kvm_pmu_part_overflow_status(vcpu)) {
> +		kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu);
> +
> +		if (!in_nmi())
> +			kvm_vcpu_kick(vcpu);
> +		else
> +			irq_work_queue(&vcpu->arch.pmu.overflow_work);
> +	}
> +}
> +
> +/**
> + * kvm_pmu_part_overflow_status() - Determine if any guest counters have overflowed
[ ... ]
> +bool kvm_pmu_part_overflow_status(struct kvm_vcpu *vcpu)
> +{
> +	struct arm_pmu *pmu;
> +	u64 mask, pmovs, pmint, pmcr;
> +	bool overflow;
> +
> +	pmu = vcpu->kvm->arch.arm_pmu;
> +	mask = kvm_pmu_guest_counter_mask(pmu);
> +
> +	if (vcpu->arch.pmu.access == VCPU_PMU_ACCESS_FREE) {
> +		pmovs = __vcpu_sys_reg(vcpu, PMOVSSET_EL0);
> +		pmint = __vcpu_sys_reg(vcpu, PMINTENSET_EL1);
> +		pmcr = __vcpu_sys_reg(vcpu, PMCR_EL0);
> +
> +		if ((pmcr & ARMV8_PMU_PMCR_E) && (mask & pmovs & pmint))
> +			kvm_pmu_set_guest_owned(vcpu);
> +		else
> +			return false;
> +	}
> +

[Severity: High]
Does this fall through to read uninitialized hardware state?

When a virtual overflow is detected and kvm_pmu_set_guest_owned() is called,
it transitions the state but there is no return true; here. Execution falls
through to unconditionally read the physical hardware registers below.

Additionally, looking at kvm_pmu_set_guest_owned(), it grants direct
hardware access via MDCR_EL2 but fails to invoke kvm_pmu_load() to populate
the hardware PMU with the guest's context.

Since the hardware wasn't loaded, could these reads return host state,
causing the calculation to evaluate to false and drop the pending interrupt?

> +	pmovs = __vcpu_sys_reg(vcpu, PMOVSSET_EL0);
> +	pmint = read_pmintenset();
> +	pmcr = read_pmcr();

[Severity: High]
Does this evaluate overflow using stale software state instead of the
physical register when the PMU is guest-owned?

When the PMU is guest-owned, physical hardware overflows update the physical
register. The software context is only synchronized during kvm_pmu_put().

Since this is called during guest exit via kvm_pmu_sync_hwstate() before
kvm_pmu_put() runs, could unconditionally reading the software context via
__vcpu_sys_reg() evaluate against stale state and miss physical hardware
overflows?

> +	overflow = (pmcr & ARMV8_PMU_PMCR_E) && (mask & pmovs & pmint);
> +
> +	return overflow;
>  }

[ ... ]

> diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
> index 25163a689ae80..f72d080ee7ba2 100644
> --- a/include/kvm/arm_pmu.h
> +++ b/include/kvm/arm_pmu.h
> @@ -93,6 +93,8 @@ bool kvm_set_pmuserenr(u64 val);
>  void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu);
>  void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu);
>  void kvm_vcpu_pmu_resync_el0(void);
> +bool kvm_pmu_emul_overflow_status(struct kvm_vcpu *vcpu);
> +bool kvm_pmu_part_overflow_status(struct kvm_vcpu *vcpu);

[Severity: Low]
Since kvm_pmu_overflow_status() was renamed to kvm_pmu_emul_overflow_status()
in this patch, should the old prototype be removed from this header file?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260612192909.1153907-1-coltonlewis@google.com?part=17

  reply	other threads:[~2026-06-12 19:58 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-12 19:28 [PATCH v8 00/21] ARM64 PMU Partitioning Colton Lewis
2026-06-12 19:28 ` [PATCH 01/21] arm64: cpufeature: Add cpucap for HPMN0 Colton Lewis
2026-06-12 19:28 ` [PATCH 02/21] KVM: arm64: Reorganize PMU includes Colton Lewis
2026-06-12 19:28 ` [PATCH 03/21] KVM: arm64: Reorganize PMU functions Colton Lewis
2026-06-12 19:56   ` sashiko-bot
2026-06-12 19:28 ` [PATCH 04/21] perf: arm_pmuv3: Generalize counter bitmasks Colton Lewis
2026-06-12 19:28 ` [PATCH 05/21] perf: arm_pmuv3: Check cntr_mask before using pmccntr Colton Lewis
2026-06-12 19:42   ` sashiko-bot
2026-06-12 19:28 ` [PATCH 06/21] perf: arm_pmuv3: Allocate counter indices from high to low Colton Lewis
2026-06-12 19:28 ` [PATCH 07/21] perf: arm_pmuv3: Add method to partition the PMU Colton Lewis
2026-06-12 19:28 ` [PATCH 08/21] KVM: arm64: Set up FGT for Partitioned PMU Colton Lewis
2026-06-12 19:45   ` sashiko-bot
2026-06-12 19:28 ` [PATCH 09/21] KVM: arm64: Add Partitioned PMU register trap handlers Colton Lewis
2026-06-12 19:51   ` sashiko-bot
2026-06-12 19:28 ` [PATCH 10/21] KVM: arm64: Set up MDCR_EL2 to handle a Partitioned PMU Colton Lewis
2026-06-12 19:52   ` sashiko-bot
2026-06-12 19:28 ` [PATCH 11/21] KVM: arm64: Context swap Partitioned PMU guest registers Colton Lewis
2026-06-12 19:51   ` sashiko-bot
2026-06-12 19:29 ` [PATCH 12/21] KVM: arm64: Enforce PMU event filter at vcpu_load() Colton Lewis
2026-06-12 19:53   ` sashiko-bot
2026-06-12 19:29 ` [PATCH 13/21] perf: Add perf_pmu_resched_update() Colton Lewis
2026-06-12 19:29 ` [PATCH 14/21] KVM: arm64: Apply dynamic guest counter reservations Colton Lewis
2026-06-12 19:50   ` sashiko-bot
2026-06-12 19:29 ` [PATCH 15/21] KVM: arm64: Implement lazy PMU context swaps Colton Lewis
2026-06-12 19:50   ` sashiko-bot
2026-06-12 19:29 ` [PATCH 16/21] perf: arm_pmuv3: Handle IRQs for Partitioned PMU guest counters Colton Lewis
2026-06-12 19:57   ` sashiko-bot
2026-06-12 19:29 ` [PATCH 17/21] KVM: arm64: Detect overflows for the Partitioned PMU Colton Lewis
2026-06-12 19:58   ` sashiko-bot [this message]
2026-06-12 19:29 ` [PATCH 18/21] KVM: arm64: Add vCPU device attr to partition the PMU Colton Lewis
2026-06-12 19:54   ` sashiko-bot
2026-06-12 19:29 ` [PATCH 19/21] KVM: selftests: Add find_bit to KVM library Colton Lewis
2026-06-12 20:01   ` sashiko-bot
2026-06-12 19:29 ` [PATCH 20/21] KVM: arm64: selftests: Add test case for Partitioned PMU Colton Lewis
2026-06-12 19:29 ` [PATCH 21/21] KVM: arm64: selftests: Relax testing for exceptions when partitioned Colton Lewis

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=20260612195806.82C5A1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=coltonlewis@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=maz@kernel.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox