On 6/21/19 10:38 AM, Marc Zyngier wrote:

> Add the required handling for EL2 and EL02 registers, as
> well as EL1 registers used in the E2H context.
>
> Signed-off-by: Marc Zyngier <[email protected]>
> ---
>  arch/arm64/kvm/sys_regs.c | 72 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 72 insertions(+)
>
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index ba3bcd29c02d..0bd6a66b621e 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -1361,20 +1361,92 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
>  
>       switch (reg) {
>       case SYS_CNTP_TVAL_EL0:
> +             if (vcpu_mode_el2(vcpu) && vcpu_el2_e2h_is_set(vcpu))
> +                     tmr = TIMER_HPTIMER;
> +             else
> +                     tmr = TIMER_PTIMER;
> +             treg = TIMER_REG_TVAL;
> +             break;
> +
>       case SYS_AARCH32_CNTP_TVAL:
> +     case SYS_CNTP_TVAL_EL02:
>               tmr = TIMER_PTIMER;
>               treg = TIMER_REG_TVAL;
>               break;
> +
> +     case SYS_CNTV_TVAL_EL02:
> +             tmr = TIMER_VTIMER;
> +             treg = TIMER_REG_TVAL;
> +             break;
> +
> +     case SYS_CNTHP_TVAL_EL2:
> +             tmr = TIMER_HPTIMER;
> +             treg = TIMER_REG_TVAL;
> +             break;
> +
> +     case SYS_CNTHV_TVAL_EL2:
> +             tmr = TIMER_HVTIMER;
> +             treg = TIMER_REG_TVAL;
> +             break;
> +
>       case SYS_CNTP_CTL_EL0:
> +             if (vcpu_mode_el2(vcpu) && vcpu_el2_e2h_is_set(vcpu))
> +                     tmr = TIMER_HPTIMER;
> +             else
> +                     tmr = TIMER_PTIMER;
> +             treg = TIMER_REG_CTL;
> +             break;
> +
>       case SYS_AARCH32_CNTP_CTL:
> +     case SYS_CNTP_CTL_EL02:
>               tmr = TIMER_PTIMER;
>               treg = TIMER_REG_CTL;
>               break;
> +
> +     case SYS_CNTV_CTL_EL02:
> +             tmr = TIMER_VTIMER;
> +             treg = TIMER_REG_CTL;
> +             break;
> +
> +     case SYS_CNTHP_CTL_EL2:
> +             tmr = TIMER_HPTIMER;
> +             treg = TIMER_REG_CTL;
> +             break;
> +
> +     case SYS_CNTHV_CTL_EL2:
> +             tmr = TIMER_HVTIMER;
> +             treg = TIMER_REG_CTL;
> +             break;
> +             
>       case SYS_CNTP_CVAL_EL0:
> +             if (vcpu_mode_el2(vcpu) && vcpu_el2_e2h_is_set(vcpu))
> +                     tmr = TIMER_HPTIMER;
> +             else
> +                     tmr = TIMER_PTIMER;
> +             treg = TIMER_REG_CVAL;
> +             break;
> +
>       case SYS_AARCH32_CNTP_CVAL:
> +     case SYS_CNTP_CVAL_EL02:
>               tmr = TIMER_PTIMER;
>               treg = TIMER_REG_CVAL;
>               break;
> +
> +     case SYS_CNTV_CVAL_EL02:
> +             tmr = TIMER_VTIMER;
> +             treg = TIMER_REG_CVAL;
> +             break;
> +
> +     case SYS_CNTHP_CVAL_EL2:
> +             tmr = TIMER_HPTIMER;
> +             treg = TIMER_REG_CVAL;
> +             break;
> +
> +     case SYS_CNTHV_CVAL_EL2:
> +             tmr = TIMER_HVTIMER;
> +             treg = TIMER_REG_CVAL;
> +             break;
> +
>       case SYS_CNTVOFF_EL2:
>               tmr = TIMER_VTIMER;
>               treg = TIMER_REG_VOFF;

Shouldn't we forward physical timer traps to the L1 guest hypervisor if
__vcpu_sys_reg(vcpu, CNTHCTL_EL2.EL1PTEN) == 0 (trap access) and
!vcpu_mode_el2(vcpu)? A regular (non-nested) non-vhe hypervisor can set that bit
to emulate the physical timer. If I remember correctly, KVM with VHE used to do
it too until some time ago.

_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to