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> 12*c605ee24SMarc 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 /* 209aebdea4SDavid Brazdil * 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 { 259aebdea4SDavid Brazdil u64 val, shift = 0; 269aebdea4SDavid Brazdil 279aebdea4SDavid Brazdil if (has_hvhe()) 289aebdea4SDavid Brazdil shift = 10; 299aebdea4SDavid Brazdil 309aebdea4SDavid Brazdil /* Allow physical timer/counter access for the host */ 319aebdea4SDavid Brazdil val = read_sysreg(cnthctl_el2); 329aebdea4SDavid Brazdil val |= (CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN) << shift; 339aebdea4SDavid Brazdil write_sysreg(val, cnthctl_el2); 349aebdea4SDavid Brazdil } 359aebdea4SDavid Brazdil 369aebdea4SDavid Brazdil /* 37c50cb043SDavid Brazdil * 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(). 39*c605ee24SMarc Zyngier */ __timer_enable_traps(struct kvm_vcpu * vcpu)409aebdea4SDavid Brazdilvoid __timer_enable_traps(struct kvm_vcpu *vcpu) 419aebdea4SDavid Brazdil { 429aebdea4SDavid Brazdil u64 clr = 0, set = 0; 43*c605ee24SMarc Zyngier 44*c605ee24SMarc Zyngier /* 459aebdea4SDavid Brazdil * Disallow physical timer access for the guest 46*c605ee24SMarc Zyngier * Physical counter access is allowed if no offset is enforced 47*c605ee24SMarc Zyngier * or running protected (we don't offset anything in this case). 48*c605ee24SMarc Zyngier */ 49*c605ee24SMarc Zyngier clr = CNTHCTL_EL1PCEN; 50*c605ee24SMarc Zyngier if (is_protected_kvm_enabled() || 51*c605ee24SMarc Zyngier !kern_hyp_va(vcpu->kvm)->arch.timer_data.poffset) 52*c605ee24SMarc Zyngier set |= CNTHCTL_EL1PCTEN; 53*c605ee24SMarc Zyngier else 549aebdea4SDavid Brazdil clr |= CNTHCTL_EL1PCTEN; 55 56 if (has_hvhe()) { 57 clr <<= 10; 58 set <<= 10; 59 } 60 61 sysreg_clear_set(cnthctl_el2, clr, set); 62 } 63