@@ -1594,6 +1594,23 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
15941594 return true;
15951595}
15961596
1597+ static int arch_timer_set_user (struct kvm_vcpu * vcpu ,
1598+ const struct sys_reg_desc * rd ,
1599+ u64 val )
1600+ {
1601+ switch (reg_to_encoding (rd )) {
1602+ case SYS_CNTV_CTL_EL0 :
1603+ case SYS_CNTP_CTL_EL0 :
1604+ case SYS_CNTHV_CTL_EL2 :
1605+ case SYS_CNTHP_CTL_EL2 :
1606+ val &= ~ARCH_TIMER_CTRL_IT_STAT ;
1607+ break ;
1608+ }
1609+
1610+ __vcpu_assign_sys_reg (vcpu , rd -> reg , val );
1611+ return 0 ;
1612+ }
1613+
15971614static s64 kvm_arm64_ftr_safe_value (u32 id , const struct arm64_ftr_bits * ftrp ,
15981615 s64 new , s64 cur )
15991616{
@@ -2496,15 +2513,20 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu,
24962513 "trap of EL2 register redirected to EL1" );
24972514}
24982515
2499- #define EL2_REG_FILTERED (name , acc , rst , v , filter ) { \
2516+ #define SYS_REG_USER_FILTER (name , acc , rst , v , gu , su , filter ) { \
25002517 SYS_DESC(SYS_##name), \
25012518 .access = acc, \
25022519 .reset = rst, \
25032520 .reg = name, \
2521+ .get_user = gu, \
2522+ .set_user = su, \
25042523 .visibility = filter, \
25052524 .val = v, \
25062525}
25072526
2527+ #define EL2_REG_FILTERED (name , acc , rst , v , filter ) \
2528+ SYS_REG_USER_FILTER(name, acc, rst, v, NULL, NULL, filter)
2529+
25082530#define EL2_REG (name , acc , rst , v ) \
25092531 EL2_REG_FILTERED(name, acc, rst, v, el2_visibility)
25102532
@@ -2515,6 +2537,10 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu,
25152537 EL2_REG_VNCR_FILT(name, hidden_visibility)
25162538#define EL2_REG_REDIR (name , rst , v ) EL2_REG(name, bad_redir_trap, rst, v)
25172539
2540+ #define TIMER_REG (name , vis ) \
2541+ SYS_REG_USER_FILTER(name, access_arch_timer, reset_val, 0, \
2542+ NULL, arch_timer_set_user, vis)
2543+
25182544/*
25192545 * Since reset() callback and field val are not used for idregs, they will be
25202546 * used for specific purposes for idregs.
@@ -3485,11 +3511,11 @@ static const struct sys_reg_desc sys_reg_descs[] = {
34853511 { SYS_DESC (SYS_CNTPCTSS_EL0 ), access_arch_timer },
34863512 { SYS_DESC (SYS_CNTVCTSS_EL0 ), access_arch_timer },
34873513 { SYS_DESC (SYS_CNTP_TVAL_EL0 ), access_arch_timer },
3488- { SYS_DESC ( SYS_CNTP_CTL_EL0 ), access_arch_timer } ,
3514+ TIMER_REG ( CNTP_CTL_EL0 , NULL ) ,
34893515 { SYS_DESC (SYS_CNTP_CVAL_EL0 ), access_arch_timer },
34903516
34913517 { SYS_DESC (SYS_CNTV_TVAL_EL0 ), access_arch_timer },
3492- { SYS_DESC ( SYS_CNTV_CTL_EL0 ), access_arch_timer } ,
3518+ TIMER_REG ( CNTV_CTL_EL0 , NULL ) ,
34933519 { SYS_DESC (SYS_CNTV_CVAL_EL0 ), access_arch_timer },
34943520
34953521 /* PMEVCNTRn_EL0 */
@@ -3688,11 +3714,11 @@ static const struct sys_reg_desc sys_reg_descs[] = {
36883714 EL2_REG_VNCR (CNTVOFF_EL2 , reset_val , 0 ),
36893715 EL2_REG (CNTHCTL_EL2 , access_rw , reset_val , 0 ),
36903716 { SYS_DESC (SYS_CNTHP_TVAL_EL2 ), access_arch_timer },
3691- EL2_REG (CNTHP_CTL_EL2 , access_arch_timer , reset_val , 0 ),
3717+ TIMER_REG (CNTHP_CTL_EL2 , el2_visibility ),
36923718 EL2_REG (CNTHP_CVAL_EL2 , access_arch_timer , reset_val , 0 ),
36933719
36943720 { SYS_DESC (SYS_CNTHV_TVAL_EL2 ), access_arch_timer , .visibility = cnthv_visibility },
3695- EL2_REG_FILTERED (CNTHV_CTL_EL2 , access_arch_timer , reset_val , 0 , cnthv_visibility ),
3721+ TIMER_REG (CNTHV_CTL_EL2 , cnthv_visibility ),
36963722 EL2_REG_FILTERED (CNTHV_CVAL_EL2 , access_arch_timer , reset_val , 0 , cnthv_visibility ),
36973723
36983724 { SYS_DESC (SYS_CNTKCTL_EL12 ), access_cntkctl_el12 },
0 commit comments