4343 * 64bit interface.
4444 */
4545
46+ #define reg_to_encoding (x ) \
47+ sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \
48+ (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2)
49+
4650static bool read_from_write_only (struct kvm_vcpu * vcpu ,
4751 struct sys_reg_params * params ,
4852 const struct sys_reg_desc * r )
@@ -273,8 +277,7 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
273277 const struct sys_reg_desc * r )
274278{
275279 u64 val = read_sanitised_ftr_reg (SYS_ID_AA64MMFR1_EL1 );
276- u32 sr = sys_reg ((u32 )r -> Op0 , (u32 )r -> Op1 ,
277- (u32 )r -> CRn , (u32 )r -> CRm , (u32 )r -> Op2 );
280+ u32 sr = reg_to_encoding (r );
278281
279282 if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT ))) {
280283 kvm_inject_undefined (vcpu );
@@ -590,6 +593,15 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
590593 vcpu_write_sys_reg (vcpu , (1ULL << 31 ) | mpidr , MPIDR_EL1 );
591594}
592595
596+ static unsigned int pmu_visibility (const struct kvm_vcpu * vcpu ,
597+ const struct sys_reg_desc * r )
598+ {
599+ if (kvm_vcpu_has_pmu (vcpu ))
600+ return 0 ;
601+
602+ return REG_HIDDEN ;
603+ }
604+
593605static void reset_pmcr (struct kvm_vcpu * vcpu , const struct sys_reg_desc * r )
594606{
595607 u64 pmcr , val ;
@@ -613,9 +625,8 @@ static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
613625static bool check_pmu_access_disabled (struct kvm_vcpu * vcpu , u64 flags )
614626{
615627 u64 reg = __vcpu_sys_reg (vcpu , PMUSERENR_EL0 );
616- bool enabled = kvm_vcpu_has_pmu (vcpu );
628+ bool enabled = ( reg & flags ) || vcpu_mode_priv (vcpu );
617629
618- enabled &= (reg & flags ) || vcpu_mode_priv (vcpu );
619630 if (!enabled )
620631 kvm_inject_undefined (vcpu );
621632
@@ -900,11 +911,6 @@ static bool access_pmswinc(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
900911static bool access_pmuserenr (struct kvm_vcpu * vcpu , struct sys_reg_params * p ,
901912 const struct sys_reg_desc * r )
902913{
903- if (!kvm_vcpu_has_pmu (vcpu )) {
904- kvm_inject_undefined (vcpu );
905- return false;
906- }
907-
908914 if (p -> is_write ) {
909915 if (!vcpu_mode_priv (vcpu )) {
910916 kvm_inject_undefined (vcpu );
@@ -921,10 +927,6 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
921927 return true;
922928}
923929
924- #define reg_to_encoding (x ) \
925- sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \
926- (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2)
927-
928930/* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
929931#define DBG_BCR_BVR_WCR_WVR_EL1 (n ) \
930932 { SYS_DESC(SYS_DBGBVRn_EL1(n)), \
@@ -936,15 +938,18 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
936938 { SYS_DESC(SYS_DBGWCRn_EL1(n)), \
937939 trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr }
938940
941+ #define PMU_SYS_REG (r ) \
942+ SYS_DESC(r), .reset = reset_unknown, .visibility = pmu_visibility
943+
939944/* Macro to expand the PMEVCNTRn_EL0 register */
940945#define PMU_PMEVCNTR_EL0 (n ) \
941- { SYS_DESC (SYS_PMEVCNTRn_EL0(n)), \
942- access_pmu_evcntr, reset_unknown, (PMEVCNTR0_EL0 + n), }
946+ { PMU_SYS_REG (SYS_PMEVCNTRn_EL0(n)), \
947+ .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), }
943948
944949/* Macro to expand the PMEVTYPERn_EL0 register */
945950#define PMU_PMEVTYPER_EL0 (n ) \
946- { SYS_DESC (SYS_PMEVTYPERn_EL0(n)), \
947- access_pmu_evtyper, reset_unknown, (PMEVTYPER0_EL0 + n), }
951+ { PMU_SYS_REG (SYS_PMEVTYPERn_EL0(n)), \
952+ .access = access_pmu_evtyper, .reg = (PMEVTYPER0_EL0 + n), }
948953
949954static bool undef_access (struct kvm_vcpu * vcpu , struct sys_reg_params * p ,
950955 const struct sys_reg_desc * r )
@@ -1020,8 +1025,7 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
10201025static u64 read_id_reg (const struct kvm_vcpu * vcpu ,
10211026 struct sys_reg_desc const * r , bool raz )
10221027{
1023- u32 id = sys_reg ((u32 )r -> Op0 , (u32 )r -> Op1 ,
1024- (u32 )r -> CRn , (u32 )r -> CRm , (u32 )r -> Op2 );
1028+ u32 id = reg_to_encoding (r );
10251029 u64 val = raz ? 0 : read_sanitised_ftr_reg (id );
10261030
10271031 if (id == SYS_ID_AA64PFR0_EL1 ) {
@@ -1062,8 +1066,7 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
10621066static unsigned int id_visibility (const struct kvm_vcpu * vcpu ,
10631067 const struct sys_reg_desc * r )
10641068{
1065- u32 id = sys_reg ((u32 )r -> Op0 , (u32 )r -> Op1 ,
1066- (u32 )r -> CRn , (u32 )r -> CRm , (u32 )r -> Op2 );
1069+ u32 id = reg_to_encoding (r );
10671070
10681071 switch (id ) {
10691072 case SYS_ID_AA64ZFR0_EL1 :
@@ -1486,8 +1489,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
14861489 { SYS_DESC (SYS_FAR_EL1 ), access_vm_reg , reset_unknown , FAR_EL1 },
14871490 { SYS_DESC (SYS_PAR_EL1 ), NULL , reset_unknown , PAR_EL1 },
14881491
1489- { SYS_DESC (SYS_PMINTENSET_EL1 ), access_pminten , reset_unknown , PMINTENSET_EL1 },
1490- { SYS_DESC (SYS_PMINTENCLR_EL1 ), access_pminten , reset_unknown , PMINTENSET_EL1 },
1492+ { PMU_SYS_REG (SYS_PMINTENSET_EL1 ),
1493+ .access = access_pminten , .reg = PMINTENSET_EL1 },
1494+ { PMU_SYS_REG (SYS_PMINTENCLR_EL1 ),
1495+ .access = access_pminten , .reg = PMINTENSET_EL1 },
14911496
14921497 { SYS_DESC (SYS_MAIR_EL1 ), access_vm_reg , reset_unknown , MAIR_EL1 },
14931498 { SYS_DESC (SYS_AMAIR_EL1 ), access_vm_reg , reset_amair_el1 , AMAIR_EL1 },
@@ -1526,23 +1531,36 @@ static const struct sys_reg_desc sys_reg_descs[] = {
15261531 { SYS_DESC (SYS_CSSELR_EL1 ), access_csselr , reset_unknown , CSSELR_EL1 },
15271532 { SYS_DESC (SYS_CTR_EL0 ), access_ctr },
15281533
1529- { SYS_DESC (SYS_PMCR_EL0 ), access_pmcr , reset_pmcr , PMCR_EL0 },
1530- { SYS_DESC (SYS_PMCNTENSET_EL0 ), access_pmcnten , reset_unknown , PMCNTENSET_EL0 },
1531- { SYS_DESC (SYS_PMCNTENCLR_EL0 ), access_pmcnten , reset_unknown , PMCNTENSET_EL0 },
1532- { SYS_DESC (SYS_PMOVSCLR_EL0 ), access_pmovs , reset_unknown , PMOVSSET_EL0 },
1533- { SYS_DESC (SYS_PMSWINC_EL0 ), access_pmswinc , reset_unknown , PMSWINC_EL0 },
1534- { SYS_DESC (SYS_PMSELR_EL0 ), access_pmselr , reset_unknown , PMSELR_EL0 },
1535- { SYS_DESC (SYS_PMCEID0_EL0 ), access_pmceid },
1536- { SYS_DESC (SYS_PMCEID1_EL0 ), access_pmceid },
1537- { SYS_DESC (SYS_PMCCNTR_EL0 ), access_pmu_evcntr , reset_unknown , PMCCNTR_EL0 },
1538- { SYS_DESC (SYS_PMXEVTYPER_EL0 ), access_pmu_evtyper },
1539- { SYS_DESC (SYS_PMXEVCNTR_EL0 ), access_pmu_evcntr },
1534+ { PMU_SYS_REG (SYS_PMCR_EL0 ), .access = access_pmcr ,
1535+ .reset = reset_pmcr , .reg = PMCR_EL0 },
1536+ { PMU_SYS_REG (SYS_PMCNTENSET_EL0 ),
1537+ .access = access_pmcnten , .reg = PMCNTENSET_EL0 },
1538+ { PMU_SYS_REG (SYS_PMCNTENCLR_EL0 ),
1539+ .access = access_pmcnten , .reg = PMCNTENSET_EL0 },
1540+ { PMU_SYS_REG (SYS_PMOVSCLR_EL0 ),
1541+ .access = access_pmovs , .reg = PMOVSSET_EL0 },
1542+ { PMU_SYS_REG (SYS_PMSWINC_EL0 ),
1543+ .access = access_pmswinc , .reg = PMSWINC_EL0 },
1544+ { PMU_SYS_REG (SYS_PMSELR_EL0 ),
1545+ .access = access_pmselr , .reg = PMSELR_EL0 },
1546+ { PMU_SYS_REG (SYS_PMCEID0_EL0 ),
1547+ .access = access_pmceid , .reset = NULL },
1548+ { PMU_SYS_REG (SYS_PMCEID1_EL0 ),
1549+ .access = access_pmceid , .reset = NULL },
1550+ { PMU_SYS_REG (SYS_PMCCNTR_EL0 ),
1551+ .access = access_pmu_evcntr , .reg = PMCCNTR_EL0 },
1552+ { PMU_SYS_REG (SYS_PMXEVTYPER_EL0 ),
1553+ .access = access_pmu_evtyper , .reset = NULL },
1554+ { PMU_SYS_REG (SYS_PMXEVCNTR_EL0 ),
1555+ .access = access_pmu_evcntr , .reset = NULL },
15401556 /*
15411557 * PMUSERENR_EL0 resets as unknown in 64bit mode while it resets as zero
15421558 * in 32bit mode. Here we choose to reset it as zero for consistency.
15431559 */
1544- { SYS_DESC (SYS_PMUSERENR_EL0 ), access_pmuserenr , reset_val , PMUSERENR_EL0 , 0 },
1545- { SYS_DESC (SYS_PMOVSSET_EL0 ), access_pmovs , reset_unknown , PMOVSSET_EL0 },
1560+ { PMU_SYS_REG (SYS_PMUSERENR_EL0 ), .access = access_pmuserenr ,
1561+ .reset = reset_val , .reg = PMUSERENR_EL0 , .val = 0 },
1562+ { PMU_SYS_REG (SYS_PMOVSSET_EL0 ),
1563+ .access = access_pmovs , .reg = PMOVSSET_EL0 },
15461564
15471565 { SYS_DESC (SYS_TPIDR_EL0 ), NULL , reset_unknown , TPIDR_EL0 },
15481566 { SYS_DESC (SYS_TPIDRRO_EL0 ), NULL , reset_unknown , TPIDRRO_EL0 },
@@ -1694,7 +1712,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
16941712 * PMCCFILTR_EL0 resets as unknown in 64bit mode while it resets as zero
16951713 * in 32bit mode. Here we choose to reset it as zero for consistency.
16961714 */
1697- { SYS_DESC (SYS_PMCCFILTR_EL0 ), access_pmu_evtyper , reset_val , PMCCFILTR_EL0 , 0 },
1715+ { PMU_SYS_REG (SYS_PMCCFILTR_EL0 ), .access = access_pmu_evtyper ,
1716+ .reset = reset_val , .reg = PMCCFILTR_EL0 , .val = 0 },
16981717
16991718 { SYS_DESC (SYS_DACR32_EL2 ), NULL , reset_unknown , DACR32_EL2 },
17001719 { SYS_DESC (SYS_IFSR32_EL2 ), NULL , reset_unknown , IFSR32_EL2 },
0 commit comments