19aebdea4SDavid Brazdil // SPDX-License-Identifier: GPL-2.0-only 29aebdea4SDavid Brazdil /* 39aebdea4SDavid Brazdil * Copyright (C) 2012-2015 - ARM Ltd 49aebdea4SDavid Brazdil * Author: Marc Zyngier <marc.zyngier@arm.com> 59aebdea4SDavid Brazdil */ 69aebdea4SDavid Brazdil 79aebdea4SDavid Brazdil #include <clocksource/arm_arch_timer.h> 89aebdea4SDavid Brazdil #include <linux/compiler.h> 99aebdea4SDavid Brazdil #include <linux/kvm_host.h> 109aebdea4SDavid Brazdil 119aebdea4SDavid Brazdil #include <asm/kvm_hyp.h> 12c605ee24SMarc Zyngier #include <asm/kvm_mmu.h> 139aebdea4SDavid Brazdil __kvm_timer_set_cntvoff(u64 cntvoff)149aebdea4SDavid Brazdilvoid __kvm_timer_set_cntvoff(u64 cntvoff) 159aebdea4SDavid Brazdil { 169aebdea4SDavid Brazdil write_sysreg(cntvoff, cntvoff_el2); 179aebdea4SDavid Brazdil } 189aebdea4SDavid Brazdil 199aebdea4SDavid Brazdil /* 20*aca18585SMarc Zyngier * Should only be called on non-VHE or hVHE setups. 219aebdea4SDavid Brazdil * VHE systems use EL2 timers and configure EL1 timers in kvm_timer_init_vhe(). 229aebdea4SDavid Brazdil */ __timer_disable_traps(struct kvm_vcpu * vcpu)23c50cb043SDavid Brazdilvoid __timer_disable_traps(struct kvm_vcpu *vcpu) 249aebdea4SDavid Brazdil { 25*aca18585SMarc Zyngier u64 val, shift = 0; 26*aca18585SMarc Zyngier 27*aca18585SMarc Zyngier if (has_hvhe()) 28*aca18585SMarc Zyngier shift = 10; 299aebdea4SDavid Brazdil 309aebdea4SDavid Brazdil /* Allow physical timer/counter access for the host */ 319aebdea4SDavid Brazdil val = read_sysreg(cnthctl_el2); 32*aca18585SMarc Zyngier val |= (CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN) << shift; 339aebdea4SDavid Brazdil write_sysreg(val, cnthctl_el2); 349aebdea4SDavid Brazdil } 359aebdea4SDavid Brazdil 369aebdea4SDavid Brazdil /* 37*aca18585SMarc Zyngier * Should only be called on non-VHE or hVHE setups. 389aebdea4SDavid Brazdil * VHE systems use EL2 timers and configure EL1 timers in kvm_timer_init_vhe(). 399aebdea4SDavid Brazdil */ __timer_enable_traps(struct kvm_vcpu * vcpu)40c50cb043SDavid Brazdilvoid __timer_enable_traps(struct kvm_vcpu *vcpu) 419aebdea4SDavid Brazdil { 42c605ee24SMarc Zyngier u64 clr = 0, set = 0; 439aebdea4SDavid Brazdil 449aebdea4SDavid Brazdil /* 459aebdea4SDavid Brazdil * Disallow physical timer access for the guest 46c605ee24SMarc Zyngier * Physical counter access is allowed if no offset is enforced 47c605ee24SMarc Zyngier * or running protected (we don't offset anything in this case). 489aebdea4SDavid Brazdil */ 49c605ee24SMarc Zyngier clr = CNTHCTL_EL1PCEN; 50c605ee24SMarc Zyngier if (is_protected_kvm_enabled() || 51c605ee24SMarc Zyngier !kern_hyp_va(vcpu->kvm)->arch.timer_data.poffset) 52c605ee24SMarc Zyngier set |= CNTHCTL_EL1PCTEN; 53c605ee24SMarc Zyngier else 54c605ee24SMarc Zyngier clr |= CNTHCTL_EL1PCTEN; 55c605ee24SMarc Zyngier 56*aca18585SMarc Zyngier if (has_hvhe()) { 57*aca18585SMarc Zyngier clr <<= 10; 58*aca18585SMarc Zyngier set <<= 10; 59*aca18585SMarc Zyngier } 60*aca18585SMarc Zyngier 61c605ee24SMarc Zyngier sysreg_clear_set(cnthctl_el2, clr, set); 629aebdea4SDavid Brazdil } 63