Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch kvm-arm64/nv-pmu-fixes into kvmarm-master/next

* kvm-arm64/nv-pmu-fixes:
: .
: Fixes for NV PMU emulation. From the cover letter:
:
: "Joey reports that some of his PMU tests do not behave quite as
: expected:
:
: - MDCR_EL2.HPMN is set to 0 out of reset
:
: - PMCR_EL0.P should reset all the counters when written from EL2
:
: Oliver points out that setting PMCR_EL0.N from userspace by writing to
: the register is silly with NV, and that we need a new PMU attribute
: instead.
:
: On top of that, I figured out that we had a number of little gotchas:
:
: - It is possible for a guest to write an HPMN value that is out of
: bound, and it seems valuable to limit it
:
: - PMCR_EL0.N should be the maximum number of counters when read from
: EL2, and MDCR_EL2.HPMN when read from EL0/EL1
:
: - Prevent userspace from updating PMCR_EL0.N when EL2 is available"
: .
KVM: arm64: Let kvm_vcpu_read_pmcr() return an EL-dependent value for PMCR_EL0.N
KVM: arm64: Handle out-of-bound write to MDCR_EL2.HPMN
KVM: arm64: Don't let userspace write to PMCR_EL0.N when the vcpu has EL2
KVM: arm64: Allow userspace to limit the number of PMU counters for EL2 VMs
KVM: arm64: Contextualise the handling of PMCR_EL0.P writes
KVM: arm64: Fix MDCR_EL2.HPMN reset value
KVM: arm64: Repaint pmcr_n into nr_pmu_counters

Signed-off-by: Marc Zyngier <maz@kernel.org>

+116 -23
+24
Documentation/virt/kvm/devices/vcpu.rst
··· 137 137 hardare_entry_failure_reason field to KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED and 138 138 the cpu field to the processor id. 139 139 140 + 1.5 ATTRIBUTE: KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS 141 + -------------------------------------------------- 142 + 143 + :Parameters: in kvm_device_attr.addr the address to an unsigned int 144 + representing the maximum value taken by PMCR_EL0.N 145 + 146 + :Returns: 147 + 148 + ======= ==================================================== 149 + -EBUSY PMUv3 already initialized, a VCPU has already run or 150 + an event filter has already been set 151 + -EFAULT Error accessing the value pointed to by addr 152 + -ENODEV PMUv3 not supported or GIC not initialized 153 + -EINVAL No PMUv3 explicitly selected, or value of N out of 154 + range 155 + ======= ==================================================== 156 + 157 + Set the number of implemented event counters in the virtual PMU. This 158 + mandates that a PMU has explicitly been selected via 159 + KVM_ARM_VCPU_PMU_V3_SET_PMU, and will fail when no PMU has been 160 + explicitly selected, or the number of counters is out of range for the 161 + selected PMU. Selecting a new PMU cancels the effect of setting this 162 + attribute. 163 + 140 164 2. GROUP: KVM_ARM_VCPU_TIMER_CTRL 141 165 ================================= 142 166
+2 -2
arch/arm64/include/asm/kvm_host.h
··· 359 359 360 360 cpumask_var_t supported_cpus; 361 361 362 - /* PMCR_EL0.N value for the guest */ 363 - u8 pmcr_n; 362 + /* Maximum number of counters for the guest */ 363 + u8 nr_pmu_counters; 364 364 365 365 /* Iterator for idreg debugfs */ 366 366 u8 idreg_debugfs_iter;
+5 -4
arch/arm64/include/uapi/asm/kvm.h
··· 431 431 432 432 /* Device Control API on vcpu fd */ 433 433 #define KVM_ARM_VCPU_PMU_V3_CTRL 0 434 - #define KVM_ARM_VCPU_PMU_V3_IRQ 0 435 - #define KVM_ARM_VCPU_PMU_V3_INIT 1 436 - #define KVM_ARM_VCPU_PMU_V3_FILTER 2 437 - #define KVM_ARM_VCPU_PMU_V3_SET_PMU 3 434 + #define KVM_ARM_VCPU_PMU_V3_IRQ 0 435 + #define KVM_ARM_VCPU_PMU_V3_INIT 1 436 + #define KVM_ARM_VCPU_PMU_V3_FILTER 2 437 + #define KVM_ARM_VCPU_PMU_V3_SET_PMU 3 438 + #define KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS 4 438 439 #define KVM_ARM_VCPU_TIMER_CTRL 1 439 440 #define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0 440 441 #define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1
+52 -8
arch/arm64/kvm/pmu-emul.c
··· 280 280 return 0; 281 281 282 282 hpmn = SYS_FIELD_GET(MDCR_EL2, HPMN, __vcpu_sys_reg(vcpu, MDCR_EL2)); 283 - n = vcpu->kvm->arch.pmcr_n; 283 + n = vcpu->kvm->arch.nr_pmu_counters; 284 284 285 285 /* 286 286 * Programming HPMN to a value greater than PMCR_EL0.N is ··· 608 608 kvm_pmu_set_counter_value(vcpu, ARMV8_PMU_CYCLE_IDX, 0); 609 609 610 610 if (val & ARMV8_PMU_PMCR_P) { 611 - /* 612 - * Unlike other PMU sysregs, the controls in PMCR_EL0 always apply 613 - * to the 'guest' range of counters and never the 'hyp' range. 614 - */ 615 611 unsigned long mask = kvm_pmu_implemented_counter_mask(vcpu) & 616 - ~kvm_pmu_hyp_counter_mask(vcpu) & 617 612 ~BIT(ARMV8_PMU_CYCLE_IDX); 613 + 614 + if (!vcpu_is_el2(vcpu)) 615 + mask &= ~kvm_pmu_hyp_counter_mask(vcpu); 618 616 619 617 for_each_set_bit(i, &mask, 32) 620 618 kvm_pmu_set_pmc_value(kvm_vcpu_idx_to_pmc(vcpu, i), 0, true); ··· 1025 1027 return bitmap_weight(arm_pmu->cntr_mask, ARMV8_PMU_MAX_GENERAL_COUNTERS); 1026 1028 } 1027 1029 1030 + static void kvm_arm_set_nr_counters(struct kvm *kvm, unsigned int nr) 1031 + { 1032 + kvm->arch.nr_pmu_counters = nr; 1033 + 1034 + /* Reset MDCR_EL2.HPMN behind the vcpus' back... */ 1035 + if (test_bit(KVM_ARM_VCPU_HAS_EL2, kvm->arch.vcpu_features)) { 1036 + struct kvm_vcpu *vcpu; 1037 + unsigned long i; 1038 + 1039 + kvm_for_each_vcpu(i, vcpu, kvm) { 1040 + u64 val = __vcpu_sys_reg(vcpu, MDCR_EL2); 1041 + val &= ~MDCR_EL2_HPMN; 1042 + val |= FIELD_PREP(MDCR_EL2_HPMN, kvm->arch.nr_pmu_counters); 1043 + __vcpu_sys_reg(vcpu, MDCR_EL2) = val; 1044 + } 1045 + } 1046 + } 1047 + 1028 1048 static void kvm_arm_set_pmu(struct kvm *kvm, struct arm_pmu *arm_pmu) 1029 1049 { 1030 1050 lockdep_assert_held(&kvm->arch.config_lock); 1031 1051 1032 1052 kvm->arch.arm_pmu = arm_pmu; 1033 - kvm->arch.pmcr_n = kvm_arm_pmu_get_max_counters(kvm); 1053 + kvm_arm_set_nr_counters(kvm, kvm_arm_pmu_get_max_counters(kvm)); 1034 1054 } 1035 1055 1036 1056 /** ··· 1102 1086 1103 1087 mutex_unlock(&arm_pmus_lock); 1104 1088 return ret; 1089 + } 1090 + 1091 + static int kvm_arm_pmu_v3_set_nr_counters(struct kvm_vcpu *vcpu, unsigned int n) 1092 + { 1093 + struct kvm *kvm = vcpu->kvm; 1094 + 1095 + if (!kvm->arch.arm_pmu) 1096 + return -EINVAL; 1097 + 1098 + if (n > kvm_arm_pmu_get_max_counters(kvm)) 1099 + return -EINVAL; 1100 + 1101 + kvm_arm_set_nr_counters(kvm, n); 1102 + return 0; 1105 1103 } 1106 1104 1107 1105 int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) ··· 1214 1184 1215 1185 return kvm_arm_pmu_v3_set_pmu(vcpu, pmu_id); 1216 1186 } 1187 + case KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS: { 1188 + unsigned int __user *uaddr = (unsigned int __user *)(long)attr->addr; 1189 + unsigned int n; 1190 + 1191 + if (get_user(n, uaddr)) 1192 + return -EFAULT; 1193 + 1194 + return kvm_arm_pmu_v3_set_nr_counters(vcpu, n); 1195 + } 1217 1196 case KVM_ARM_VCPU_PMU_V3_INIT: 1218 1197 return kvm_arm_pmu_v3_init(vcpu); 1219 1198 } ··· 1261 1222 case KVM_ARM_VCPU_PMU_V3_INIT: 1262 1223 case KVM_ARM_VCPU_PMU_V3_FILTER: 1263 1224 case KVM_ARM_VCPU_PMU_V3_SET_PMU: 1225 + case KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS: 1264 1226 if (kvm_vcpu_has_pmu(vcpu)) 1265 1227 return 0; 1266 1228 } ··· 1300 1260 u64 kvm_vcpu_read_pmcr(struct kvm_vcpu *vcpu) 1301 1261 { 1302 1262 u64 pmcr = __vcpu_sys_reg(vcpu, PMCR_EL0); 1263 + u64 n = vcpu->kvm->arch.nr_pmu_counters; 1303 1264 1304 - return u64_replace_bits(pmcr, vcpu->kvm->arch.pmcr_n, ARMV8_PMU_PMCR_N); 1265 + if (vcpu_has_nv(vcpu) && !vcpu_is_el2(vcpu)) 1266 + n = FIELD_GET(MDCR_EL2_HPMN, __vcpu_sys_reg(vcpu, MDCR_EL2)); 1267 + 1268 + return u64_replace_bits(pmcr, n, ARMV8_PMU_PMCR_N); 1305 1269 } 1306 1270 1307 1271 void kvm_pmu_nested_transition(struct kvm_vcpu *vcpu)
+33 -9
arch/arm64/kvm/sys_regs.c
··· 785 785 static u64 reset_pmu_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) 786 786 { 787 787 u64 mask = BIT(ARMV8_PMU_CYCLE_IDX); 788 - u8 n = vcpu->kvm->arch.pmcr_n; 788 + u8 n = vcpu->kvm->arch.nr_pmu_counters; 789 789 790 790 if (n) 791 791 mask |= GENMASK(n - 1, 0); ··· 1216 1216 * with the existing KVM behavior. 1217 1217 */ 1218 1218 if (!kvm_vm_has_ran_once(kvm) && 1219 + !vcpu_has_nv(vcpu) && 1219 1220 new_n <= kvm_arm_pmu_get_max_counters(kvm)) 1220 - kvm->arch.pmcr_n = new_n; 1221 + kvm->arch.nr_pmu_counters = new_n; 1221 1222 1222 1223 mutex_unlock(&kvm->arch.config_lock); 1223 1224 ··· 2571 2570 struct sys_reg_params *p, 2572 2571 const struct sys_reg_desc *r) 2573 2572 { 2574 - u64 old = __vcpu_sys_reg(vcpu, MDCR_EL2); 2573 + u64 hpmn, val, old = __vcpu_sys_reg(vcpu, MDCR_EL2); 2575 2574 2576 - if (!access_rw(vcpu, p, r)) 2577 - return false; 2575 + if (!p->is_write) { 2576 + p->regval = old; 2577 + return true; 2578 + } 2579 + 2580 + val = p->regval; 2581 + hpmn = FIELD_GET(MDCR_EL2_HPMN, val); 2578 2582 2579 2583 /* 2580 - * Request a reload of the PMU to enable/disable the counters affected 2581 - * by HPME. 2584 + * If HPMN is out of bounds, limit it to what we actually 2585 + * support. This matches the UNKNOWN definition of the field 2586 + * in that case, and keeps the emulation simple. Sort of. 2582 2587 */ 2583 - if ((old ^ __vcpu_sys_reg(vcpu, MDCR_EL2)) & MDCR_EL2_HPME) 2588 + if (hpmn > vcpu->kvm->arch.nr_pmu_counters) { 2589 + hpmn = vcpu->kvm->arch.nr_pmu_counters; 2590 + u64_replace_bits(val, hpmn, MDCR_EL2_HPMN); 2591 + } 2592 + 2593 + __vcpu_sys_reg(vcpu, MDCR_EL2) = val; 2594 + 2595 + /* 2596 + * Request a reload of the PMU to enable/disable the counters 2597 + * affected by HPME. 2598 + */ 2599 + if ((old ^ val) & MDCR_EL2_HPME) 2584 2600 kvm_make_request(KVM_REQ_RELOAD_PMU, vcpu); 2585 2601 2586 2602 return true; ··· 2716 2698 .set_user = set_imp_id_reg, \ 2717 2699 .reset = reset_imp_id_reg, \ 2718 2700 .val = mask, \ 2701 + } 2702 + 2703 + static u64 reset_mdcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) 2704 + { 2705 + __vcpu_sys_reg(vcpu, r->reg) = vcpu->kvm->arch.nr_pmu_counters; 2706 + return vcpu->kvm->arch.nr_pmu_counters; 2719 2707 } 2720 2708 2721 2709 /* ··· 3267 3243 EL2_REG(SCTLR_EL2, access_rw, reset_val, SCTLR_EL2_RES1), 3268 3244 EL2_REG(ACTLR_EL2, access_rw, reset_val, 0), 3269 3245 EL2_REG_VNCR(HCR_EL2, reset_hcr, 0), 3270 - EL2_REG(MDCR_EL2, access_mdcr, reset_val, 0), 3246 + EL2_REG(MDCR_EL2, access_mdcr, reset_mdcr, 0), 3271 3247 EL2_REG(CPTR_EL2, access_rw, reset_val, CPTR_NVHE_EL2_RES1), 3272 3248 EL2_REG_VNCR(HSTR_EL2, reset_val, 0), 3273 3249 EL2_REG_VNCR(HFGRTR_EL2, reset_val, 0),