@@ -967,6 +967,22 @@ static int get_pmu_evcntr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
967967 return 0 ;
968968}
969969
970+ static int set_pmu_evcntr (struct kvm_vcpu * vcpu , const struct sys_reg_desc * r ,
971+ u64 val )
972+ {
973+ u64 idx ;
974+
975+ if (r -> CRn == 9 && r -> CRm == 13 && r -> Op2 == 0 )
976+ /* PMCCNTR_EL0 */
977+ idx = ARMV8_PMU_CYCLE_IDX ;
978+ else
979+ /* PMEVCNTRn_EL0 */
980+ idx = ((r -> CRm & 3 ) << 3 ) | (r -> Op2 & 7 );
981+
982+ kvm_pmu_set_counter_value_user (vcpu , idx , val );
983+ return 0 ;
984+ }
985+
970986static bool access_pmu_evcntr (struct kvm_vcpu * vcpu ,
971987 struct sys_reg_params * p ,
972988 const struct sys_reg_desc * r )
@@ -1058,25 +1074,10 @@ static bool access_pmu_evtyper(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
10581074
10591075static int set_pmreg (struct kvm_vcpu * vcpu , const struct sys_reg_desc * r , u64 val )
10601076{
1061- bool set ;
1062-
1063- val &= kvm_pmu_accessible_counter_mask (vcpu );
1064-
1065- switch (r -> reg ) {
1066- case PMOVSSET_EL0 :
1067- /* CRm[1] being set indicates a SET register, and CLR otherwise */
1068- set = r -> CRm & 2 ;
1069- break ;
1070- default :
1071- /* Op2[0] being set indicates a SET register, and CLR otherwise */
1072- set = r -> Op2 & 1 ;
1073- break ;
1074- }
1077+ u64 mask = kvm_pmu_accessible_counter_mask (vcpu );
10751078
1076- if (set )
1077- __vcpu_sys_reg (vcpu , r -> reg ) |= val ;
1078- else
1079- __vcpu_sys_reg (vcpu , r -> reg ) &= ~val ;
1079+ __vcpu_sys_reg (vcpu , r -> reg ) = val & mask ;
1080+ kvm_make_request (KVM_REQ_RELOAD_PMU , vcpu );
10801081
10811082 return 0 ;
10821083}
@@ -1236,6 +1237,8 @@ static int set_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
12361237 val |= ARMV8_PMU_PMCR_LC ;
12371238
12381239 __vcpu_sys_reg (vcpu , r -> reg ) = val ;
1240+ kvm_make_request (KVM_REQ_RELOAD_PMU , vcpu );
1241+
12391242 return 0 ;
12401243}
12411244
@@ -1262,6 +1265,7 @@ static int set_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
12621265#define PMU_PMEVCNTR_EL0 (n ) \
12631266 { PMU_SYS_REG(PMEVCNTRn_EL0(n)), \
12641267 .reset = reset_pmevcntr, .get_user = get_pmu_evcntr, \
1268+ .set_user = set_pmu_evcntr, \
12651269 .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), }
12661270
12671271/* Macro to expand the PMEVTYPERn_EL0 register */
@@ -1880,12 +1884,14 @@ static int set_id_aa64dfr0_el1(struct kvm_vcpu *vcpu,
18801884static u64 read_sanitised_id_dfr0_el1 (struct kvm_vcpu * vcpu ,
18811885 const struct sys_reg_desc * rd )
18821886{
1883- u8 perfmon = pmuver_to_perfmon ( kvm_arm_pmu_get_pmuver_limit ()) ;
1887+ u8 perfmon ;
18841888 u64 val = read_sanitised_ftr_reg (SYS_ID_DFR0_EL1 );
18851889
18861890 val &= ~ID_DFR0_EL1_PerfMon_MASK ;
1887- if (kvm_vcpu_has_pmu (vcpu ))
1891+ if (kvm_vcpu_has_pmu (vcpu )) {
1892+ perfmon = pmuver_to_perfmon (kvm_arm_pmu_get_pmuver_limit ());
18881893 val |= SYS_FIELD_PREP (ID_DFR0_EL1 , PerfMon , perfmon );
1894+ }
18891895
18901896 val = ID_REG_LIMIT_FIELD_ENUM (val , ID_DFR0_EL1 , CopDbg , Debugv8p8 );
18911897
@@ -3052,7 +3058,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
30523058 .access = access_pmceid , .reset = NULL },
30533059 { PMU_SYS_REG (PMCCNTR_EL0 ),
30543060 .access = access_pmu_evcntr , .reset = reset_unknown ,
3055- .reg = PMCCNTR_EL0 , .get_user = get_pmu_evcntr },
3061+ .reg = PMCCNTR_EL0 , .get_user = get_pmu_evcntr ,
3062+ .set_user = set_pmu_evcntr },
30563063 { PMU_SYS_REG (PMXEVTYPER_EL0 ),
30573064 .access = access_pmu_evtyper , .reset = NULL },
30583065 { PMU_SYS_REG (PMXEVCNTR_EL0 ),
@@ -4712,6 +4719,9 @@ void kvm_reset_sys_regs(struct kvm_vcpu *vcpu)
47124719 }
47134720
47144721 set_bit (KVM_ARCH_FLAG_ID_REGS_INITIALIZED , & kvm -> arch .flags );
4722+
4723+ if (kvm_vcpu_has_pmu (vcpu ))
4724+ kvm_make_request (KVM_REQ_RELOAD_PMU , vcpu );
47154725}
47164726
47174727/**
0 commit comments