mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
KVM: riscv: PMU: Bound counter mask scan to BITS_PER_LONG
The PMU SBI handler passes the guest argument registers directly to
the PMU start/stop helpers:
kvm_riscv_vcpu_pmu_ctr_start(vcpu, cp->a0, cp->a1, cp->a2, ...)
kvm_riscv_vcpu_pmu_ctr_stop(vcpu, cp->a0, cp->a1, cp->a2, ...)
which map to:
unsigned long ctr_base
unsigned long ctr_mask
unsigned long flags
Thus cp->a1 is a single unsigned long ctr_mask, not a bitmap array
sized for RISCV_MAX_COUNTERS.
On RV32, RISCV_MAX_COUNTERS is 64 while BITS_PER_LONG is 32. Using
for_each_set_bit() with RISCV_MAX_COUNTERS can therefore make
find_next_bit() access bits beyond the storage of ctr_mask on RV32.
Limit the scan to BITS_PER_LONG. The requested counter range is already
validated by kvm_pmu_validate_counter_mask(), so this preserves RV64
behavior and avoids an out-of-bounds bitmap read on RV32.
Fixes: 0cb74b65d2 ("RISC-V: KVM: Implement perf support without sampling")
Signed-off-by: Shengwen Cheng <shengwen1997.tw@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260626054051.3360865-1-shengwen1997.tw@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
parent
b8aa7571e9
commit
0cc15f2c7a
|
|
@ -586,7 +586,7 @@ int kvm_riscv_vcpu_pmu_ctr_start(struct kvm_vcpu *vcpu, unsigned long ctr_base,
|
|||
}
|
||||
}
|
||||
/* Start the counters that have been configured and requested by the guest */
|
||||
for_each_set_bit(i, &ctr_mask, RISCV_MAX_COUNTERS) {
|
||||
for_each_set_bit(i, &ctr_mask, BITS_PER_LONG) {
|
||||
pmc_index = array_index_nospec(i + ctr_base,
|
||||
RISCV_KVM_MAX_COUNTERS);
|
||||
if (!test_bit(pmc_index, kvpmu->pmc_in_use))
|
||||
|
|
@ -658,7 +658,7 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
|
|||
}
|
||||
|
||||
/* Stop the counters that have been configured and requested by the guest */
|
||||
for_each_set_bit(i, &ctr_mask, RISCV_MAX_COUNTERS) {
|
||||
for_each_set_bit(i, &ctr_mask, BITS_PER_LONG) {
|
||||
pmc_index = array_index_nospec(i + ctr_base,
|
||||
RISCV_KVM_MAX_COUNTERS);
|
||||
if (!test_bit(pmc_index, kvpmu->pmc_in_use))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user