at v4.12 78 lines 2.3 kB view raw
1/* 2 * Copyright (C) 2012-2015 - ARM Ltd 3 * Author: Marc Zyngier <marc.zyngier@arm.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18#include <clocksource/arm_arch_timer.h> 19#include <linux/compiler.h> 20#include <linux/kvm_host.h> 21 22#include <asm/kvm_hyp.h> 23 24/* vcpu is already in the HYP VA space */ 25void __hyp_text __timer_save_state(struct kvm_vcpu *vcpu) 26{ 27 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 28 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); 29 u64 val; 30 31 if (timer->enabled) { 32 vtimer->cnt_ctl = read_sysreg_el0(cntv_ctl); 33 vtimer->cnt_cval = read_sysreg_el0(cntv_cval); 34 } 35 36 /* Disable the virtual timer */ 37 write_sysreg_el0(0, cntv_ctl); 38 39 /* 40 * We don't need to do this for VHE since the host kernel runs in EL2 41 * with HCR_EL2.TGE ==1, which makes those bits have no impact. 42 */ 43 if (!has_vhe()) { 44 /* Allow physical timer/counter access for the host */ 45 val = read_sysreg(cnthctl_el2); 46 val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN; 47 write_sysreg(val, cnthctl_el2); 48 } 49 50 /* Clear cntvoff for the host */ 51 write_sysreg(0, cntvoff_el2); 52} 53 54void __hyp_text __timer_restore_state(struct kvm_vcpu *vcpu) 55{ 56 struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; 57 struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); 58 u64 val; 59 60 /* Those bits are already configured at boot on VHE-system */ 61 if (!has_vhe()) { 62 /* 63 * Disallow physical timer access for the guest 64 * Physical counter access is allowed 65 */ 66 val = read_sysreg(cnthctl_el2); 67 val &= ~CNTHCTL_EL1PCEN; 68 val |= CNTHCTL_EL1PCTEN; 69 write_sysreg(val, cnthctl_el2); 70 } 71 72 if (timer->enabled) { 73 write_sysreg(vtimer->cntvoff, cntvoff_el2); 74 write_sysreg_el0(vtimer->cnt_cval, cntv_cval); 75 isb(); 76 write_sysreg_el0(vtimer->cnt_ctl, cntv_ctl); 77 } 78}