Skip to content

Commit b86fc21

Browse files
author
Marc Zyngier
committed
KVM: arm64: Handle counter access early in non-HYP context
We already deal with CNTPCT_EL0 accesses in non-HYP context. Let's add CNTVCT_EL0 as a good measure. This is also an opportunity to simplify things and make it plain that this code is only for non-HYP context handling. Acked-by: Oliver Upton <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
1 parent 9b3b2f0 commit b86fc21

File tree

1 file changed

+21
-13
lines changed

1 file changed

+21
-13
lines changed

arch/arm64/kvm/hyp/include/hyp/switch.h

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ static inline u64 compute_counter_value(struct arch_timer_context *ctxt)
506506
return arch_timer_read_cntpct_el0() - timer_get_offset(ctxt);
507507
}
508508

509-
static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
509+
static bool kvm_handle_cntxct(struct kvm_vcpu *vcpu)
510510
{
511511
struct arch_timer_context *ctxt;
512512
u32 sysreg;
@@ -516,18 +516,19 @@ static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
516516
* We only get here for 64bit guests, 32bit guests will hit
517517
* the long and winding road all the way to the standard
518518
* handling. Yes, it sucks to be irrelevant.
519+
*
520+
* Also, we only deal with non-hypervisor context here (either
521+
* an EL1 guest, or a non-HYP context of an EL2 guest).
519522
*/
523+
if (is_hyp_ctxt(vcpu))
524+
return false;
525+
520526
sysreg = esr_sys64_to_sysreg(kvm_vcpu_get_esr(vcpu));
521527

522528
switch (sysreg) {
523529
case SYS_CNTPCT_EL0:
524530
case SYS_CNTPCTSS_EL0:
525531
if (vcpu_has_nv(vcpu)) {
526-
if (is_hyp_ctxt(vcpu)) {
527-
ctxt = vcpu_hptimer(vcpu);
528-
break;
529-
}
530-
531532
/* Check for guest hypervisor trapping */
532533
val = __vcpu_sys_reg(vcpu, CNTHCTL_EL2);
533534
if (!vcpu_el2_e2h_is_set(vcpu))
@@ -539,16 +540,23 @@ static bool kvm_hyp_handle_cntpct(struct kvm_vcpu *vcpu)
539540

540541
ctxt = vcpu_ptimer(vcpu);
541542
break;
543+
case SYS_CNTVCT_EL0:
544+
case SYS_CNTVCTSS_EL0:
545+
if (vcpu_has_nv(vcpu)) {
546+
/* Check for guest hypervisor trapping */
547+
val = __vcpu_sys_reg(vcpu, CNTHCTL_EL2);
548+
549+
if (val & CNTHCTL_EL1TVCT)
550+
return false;
551+
}
552+
553+
ctxt = vcpu_vtimer(vcpu);
554+
break;
542555
default:
543556
return false;
544557
}
545558

546-
val = arch_timer_read_cntpct_el0();
547-
548-
if (ctxt->offset.vm_offset)
549-
val -= *kern_hyp_va(ctxt->offset.vm_offset);
550-
if (ctxt->offset.vcpu_offset)
551-
val -= *kern_hyp_va(ctxt->offset.vcpu_offset);
559+
val = compute_counter_value(ctxt);
552560

553561
vcpu_set_reg(vcpu, kvm_vcpu_sys_get_rt(vcpu), val);
554562
__kvm_skip_instr(vcpu);
@@ -593,7 +601,7 @@ static bool kvm_hyp_handle_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code)
593601
__vgic_v3_perform_cpuif_access(vcpu) == 1)
594602
return true;
595603

596-
if (kvm_hyp_handle_cntpct(vcpu))
604+
if (kvm_handle_cntxct(vcpu))
597605
return true;
598606

599607
return false;

0 commit comments

Comments
 (0)