43
43
* 64bit interface.
44
44
*/
45
45
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
+
46
50
static bool read_from_write_only (struct kvm_vcpu * vcpu ,
47
51
struct sys_reg_params * params ,
48
52
const struct sys_reg_desc * r )
@@ -273,8 +277,7 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
273
277
const struct sys_reg_desc * r )
274
278
{
275
279
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 );
278
281
279
282
if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT ))) {
280
283
kvm_inject_undefined (vcpu );
@@ -590,6 +593,15 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
590
593
vcpu_write_sys_reg (vcpu , (1ULL << 31 ) | mpidr , MPIDR_EL1 );
591
594
}
592
595
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
+
593
605
static void reset_pmcr (struct kvm_vcpu * vcpu , const struct sys_reg_desc * r )
594
606
{
595
607
u64 pmcr , val ;
@@ -613,9 +625,8 @@ static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
613
625
static bool check_pmu_access_disabled (struct kvm_vcpu * vcpu , u64 flags )
614
626
{
615
627
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 );
617
629
618
- enabled &= (reg & flags ) || vcpu_mode_priv (vcpu );
619
630
if (!enabled )
620
631
kvm_inject_undefined (vcpu );
621
632
@@ -900,11 +911,6 @@ static bool access_pmswinc(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
900
911
static bool access_pmuserenr (struct kvm_vcpu * vcpu , struct sys_reg_params * p ,
901
912
const struct sys_reg_desc * r )
902
913
{
903
- if (!kvm_vcpu_has_pmu (vcpu )) {
904
- kvm_inject_undefined (vcpu );
905
- return false;
906
- }
907
-
908
914
if (p -> is_write ) {
909
915
if (!vcpu_mode_priv (vcpu )) {
910
916
kvm_inject_undefined (vcpu );
@@ -921,10 +927,6 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
921
927
return true;
922
928
}
923
929
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
-
928
930
/* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
929
931
#define DBG_BCR_BVR_WCR_WVR_EL1 (n ) \
930
932
{ SYS_DESC(SYS_DBGBVRn_EL1(n)), \
@@ -936,15 +938,18 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
936
938
{ SYS_DESC(SYS_DBGWCRn_EL1(n)), \
937
939
trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr }
938
940
941
+ #define PMU_SYS_REG (r ) \
942
+ SYS_DESC(r), .reset = reset_unknown, .visibility = pmu_visibility
943
+
939
944
/* Macro to expand the PMEVCNTRn_EL0 register */
940
945
#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), }
943
948
944
949
/* Macro to expand the PMEVTYPERn_EL0 register */
945
950
#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), }
948
953
949
954
static bool undef_access (struct kvm_vcpu * vcpu , struct sys_reg_params * p ,
950
955
const struct sys_reg_desc * r )
@@ -1020,8 +1025,7 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
1020
1025
static u64 read_id_reg (const struct kvm_vcpu * vcpu ,
1021
1026
struct sys_reg_desc const * r , bool raz )
1022
1027
{
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 );
1025
1029
u64 val = raz ? 0 : read_sanitised_ftr_reg (id );
1026
1030
1027
1031
if (id == SYS_ID_AA64PFR0_EL1 ) {
@@ -1062,8 +1066,7 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
1062
1066
static unsigned int id_visibility (const struct kvm_vcpu * vcpu ,
1063
1067
const struct sys_reg_desc * r )
1064
1068
{
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 );
1067
1070
1068
1071
switch (id ) {
1069
1072
case SYS_ID_AA64ZFR0_EL1 :
@@ -1486,8 +1489,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
1486
1489
{ SYS_DESC (SYS_FAR_EL1 ), access_vm_reg , reset_unknown , FAR_EL1 },
1487
1490
{ SYS_DESC (SYS_PAR_EL1 ), NULL , reset_unknown , PAR_EL1 },
1488
1491
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 },
1491
1496
1492
1497
{ SYS_DESC (SYS_MAIR_EL1 ), access_vm_reg , reset_unknown , MAIR_EL1 },
1493
1498
{ 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[] = {
1526
1531
{ SYS_DESC (SYS_CSSELR_EL1 ), access_csselr , reset_unknown , CSSELR_EL1 },
1527
1532
{ SYS_DESC (SYS_CTR_EL0 ), access_ctr },
1528
1533
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 },
1540
1556
/*
1541
1557
* PMUSERENR_EL0 resets as unknown in 64bit mode while it resets as zero
1542
1558
* in 32bit mode. Here we choose to reset it as zero for consistency.
1543
1559
*/
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 },
1546
1564
1547
1565
{ SYS_DESC (SYS_TPIDR_EL0 ), NULL , reset_unknown , TPIDR_EL0 },
1548
1566
{ SYS_DESC (SYS_TPIDRRO_EL0 ), NULL , reset_unknown , TPIDRRO_EL0 },
@@ -1694,7 +1712,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
1694
1712
* PMCCFILTR_EL0 resets as unknown in 64bit mode while it resets as zero
1695
1713
* in 32bit mode. Here we choose to reset it as zero for consistency.
1696
1714
*/
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 },
1698
1717
1699
1718
{ SYS_DESC (SYS_DACR32_EL2 ), NULL , reset_unknown , DACR32_EL2 },
1700
1719
{ SYS_DESC (SYS_IFSR32_EL2 ), NULL , reset_unknown , IFSR32_EL2 },
0 commit comments