diff options
Diffstat (limited to 'arch/arm64/kvm/sys_regs.c')
| -rw-r--r-- | arch/arm64/kvm/sys_regs.c | 32 | 
1 files changed, 29 insertions, 3 deletions
| diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 53749d3a0996..71b12094d613 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -794,7 +794,6 @@ static bool access_pmcr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,  		if (!kvm_supports_32bit_el0())  			val |= ARMV8_PMU_PMCR_LC;  		kvm_pmu_handle_pmcr(vcpu, val); -		kvm_vcpu_pmu_restore_guest(vcpu);  	} else {  		/* PMCR.P & PMCR.C are RAZ */  		val = __vcpu_sys_reg(vcpu, PMCR_EL0) @@ -856,6 +855,22 @@ static bool pmu_counter_idx_valid(struct kvm_vcpu *vcpu, u64 idx)  	return true;  } +static int get_pmu_evcntr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, +			  u64 *val) +{ +	u64 idx; + +	if (r->CRn == 9 && r->CRm == 13 && r->Op2 == 0) +		/* PMCCNTR_EL0 */ +		idx = ARMV8_PMU_CYCLE_IDX; +	else +		/* PMEVCNTRn_EL0 */ +		idx = ((r->CRm & 3) << 3) | (r->Op2 & 7); + +	*val = kvm_pmu_get_counter_value(vcpu, idx); +	return 0; +} +  static bool access_pmu_evcntr(struct kvm_vcpu *vcpu,  			      struct sys_reg_params *p,  			      const struct sys_reg_desc *r) @@ -1072,7 +1087,7 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,  /* Macro to expand the PMEVCNTRn_EL0 register */  #define PMU_PMEVCNTR_EL0(n)						\  	{ PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)),				\ -	  .reset = reset_pmevcntr,					\ +	  .reset = reset_pmevcntr, .get_user = get_pmu_evcntr,		\  	  .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), }  /* Macro to expand the PMEVTYPERn_EL0 register */ @@ -1139,6 +1154,12 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,  		tmr = TIMER_PTIMER;  		treg = TIMER_REG_CVAL;  		break; +	case SYS_CNTPCT_EL0: +	case SYS_CNTPCTSS_EL0: +	case SYS_AARCH32_CNTPCT: +		tmr = TIMER_PTIMER; +		treg = TIMER_REG_CNT; +		break;  	default:  		print_sys_reg_msg(p, "%s", "Unhandled trapped timer register");  		kvm_inject_undefined(vcpu); @@ -1982,7 +2003,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {  	{ PMU_SYS_REG(SYS_PMCEID1_EL0),  	  .access = access_pmceid, .reset = NULL },  	{ PMU_SYS_REG(SYS_PMCCNTR_EL0), -	  .access = access_pmu_evcntr, .reset = reset_unknown, .reg = PMCCNTR_EL0 }, +	  .access = access_pmu_evcntr, .reset = reset_unknown, +	  .reg = PMCCNTR_EL0, .get_user = get_pmu_evcntr},  	{ PMU_SYS_REG(SYS_PMXEVTYPER_EL0),  	  .access = access_pmu_evtyper, .reset = NULL },  	{ PMU_SYS_REG(SYS_PMXEVCNTR_EL0), @@ -2075,6 +2097,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {  	AMU_AMEVTYPER1_EL0(14),  	AMU_AMEVTYPER1_EL0(15), +	{ SYS_DESC(SYS_CNTPCT_EL0), access_arch_timer }, +	{ SYS_DESC(SYS_CNTPCTSS_EL0), access_arch_timer },  	{ SYS_DESC(SYS_CNTP_TVAL_EL0), access_arch_timer },  	{ SYS_DESC(SYS_CNTP_CTL_EL0), access_arch_timer },  	{ SYS_DESC(SYS_CNTP_CVAL_EL0), access_arch_timer }, @@ -2525,10 +2549,12 @@ static const struct sys_reg_desc cp15_64_regs[] = {  	{ Op1( 0), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, TTBR0_EL1 },  	{ CP15_PMU_SYS_REG(DIRECT, 0, 0, 9, 0), .access = access_pmu_evcntr },  	{ Op1( 0), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_SGI1R */ +	{ SYS_DESC(SYS_AARCH32_CNTPCT),	      access_arch_timer },  	{ Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, TTBR1_EL1 },  	{ Op1( 1), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_ASGI1R */  	{ Op1( 2), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_SGI0R */  	{ SYS_DESC(SYS_AARCH32_CNTP_CVAL),    access_arch_timer }, +	{ SYS_DESC(SYS_AARCH32_CNTPCTSS),     access_arch_timer },  };  static bool check_sysreg_table(const struct sys_reg_desc *table, unsigned int n, | 
