1f4672752SMarc Zyngier /* 2f4672752SMarc Zyngier * Copyright (C) 2012,2013 - ARM Ltd 3f4672752SMarc Zyngier * Author: Marc Zyngier <marc.zyngier@arm.com> 4f4672752SMarc Zyngier * 5f4672752SMarc Zyngier * Derived from arch/arm/kvm/reset.c 6f4672752SMarc Zyngier * Copyright (C) 2012 - Virtual Open Systems and Columbia University 7f4672752SMarc Zyngier * Author: Christoffer Dall <c.dall@virtualopensystems.com> 8f4672752SMarc Zyngier * 9f4672752SMarc Zyngier * This program is free software; you can redistribute it and/or modify 10f4672752SMarc Zyngier * it under the terms of the GNU General Public License, version 2, as 11f4672752SMarc Zyngier * published by the Free Software Foundation. 12f4672752SMarc Zyngier * 13f4672752SMarc Zyngier * This program is distributed in the hope that it will be useful, 14f4672752SMarc Zyngier * but WITHOUT ANY WARRANTY; without even the implied warranty of 15f4672752SMarc Zyngier * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16f4672752SMarc Zyngier * GNU General Public License for more details. 17f4672752SMarc Zyngier * 18f4672752SMarc Zyngier * You should have received a copy of the GNU General Public License 19f4672752SMarc Zyngier * along with this program. If not, see <http://www.gnu.org/licenses/>. 20f4672752SMarc Zyngier */ 21f4672752SMarc Zyngier 22f4672752SMarc Zyngier #include <linux/errno.h> 23f4672752SMarc Zyngier #include <linux/kvm_host.h> 24f4672752SMarc Zyngier #include <linux/kvm.h> 25834bf887SAlex Bennée #include <linux/hw_breakpoint.h> 26f4672752SMarc Zyngier 27003300deSMarc Zyngier #include <kvm/arm_arch_timer.h> 28003300deSMarc Zyngier 29f4672752SMarc Zyngier #include <asm/cputype.h> 30f4672752SMarc Zyngier #include <asm/ptrace.h> 31f4672752SMarc Zyngier #include <asm/kvm_arm.h> 32f4672752SMarc Zyngier #include <asm/kvm_coproc.h> 33f4672752SMarc Zyngier 34f4672752SMarc Zyngier /* 35f4672752SMarc Zyngier * ARMv8 Reset Values 36f4672752SMarc Zyngier */ 37f4672752SMarc Zyngier static const struct kvm_regs default_regs_reset = { 38f4672752SMarc Zyngier .regs.pstate = (PSR_MODE_EL1h | PSR_A_BIT | PSR_I_BIT | 39f4672752SMarc Zyngier PSR_F_BIT | PSR_D_BIT), 40f4672752SMarc Zyngier }; 41f4672752SMarc Zyngier 420d854a60SMarc Zyngier static const struct kvm_regs default_regs_reset32 = { 430d854a60SMarc Zyngier .regs.pstate = (COMPAT_PSR_MODE_SVC | COMPAT_PSR_A_BIT | 440d854a60SMarc Zyngier COMPAT_PSR_I_BIT | COMPAT_PSR_F_BIT), 450d854a60SMarc Zyngier }; 460d854a60SMarc Zyngier 47003300deSMarc Zyngier static const struct kvm_irq_level default_vtimer_irq = { 48003300deSMarc Zyngier .irq = 27, 49003300deSMarc Zyngier .level = 1, 50003300deSMarc Zyngier }; 51003300deSMarc Zyngier 520d854a60SMarc Zyngier static bool cpu_has_32bit_el1(void) 530d854a60SMarc Zyngier { 540d854a60SMarc Zyngier u64 pfr0; 550d854a60SMarc Zyngier 564db8e5eaSSuzuki K. Poulose pfr0 = read_system_reg(SYS_ID_AA64PFR0_EL1); 570d854a60SMarc Zyngier return !!(pfr0 & 0x20); 580d854a60SMarc Zyngier } 590d854a60SMarc Zyngier 60834bf887SAlex Bennée /** 61834bf887SAlex Bennée * kvm_arch_dev_ioctl_check_extension 62834bf887SAlex Bennée * 63834bf887SAlex Bennée * We currently assume that the number of HW registers is uniform 64834bf887SAlex Bennée * across all CPUs (see cpuinfo_sanity_check). 65834bf887SAlex Bennée */ 66f4672752SMarc Zyngier int kvm_arch_dev_ioctl_check_extension(long ext) 67f4672752SMarc Zyngier { 68f4672752SMarc Zyngier int r; 69f4672752SMarc Zyngier 70f4672752SMarc Zyngier switch (ext) { 710d854a60SMarc Zyngier case KVM_CAP_ARM_EL1_32BIT: 720d854a60SMarc Zyngier r = cpu_has_32bit_el1(); 730d854a60SMarc Zyngier break; 74834bf887SAlex Bennée case KVM_CAP_GUEST_DEBUG_HW_BPS: 75834bf887SAlex Bennée r = get_num_brps(); 76834bf887SAlex Bennée break; 77834bf887SAlex Bennée case KVM_CAP_GUEST_DEBUG_HW_WPS: 78834bf887SAlex Bennée r = get_num_wrps(); 79834bf887SAlex Bennée break; 80808e7381SShannon Zhao case KVM_CAP_ARM_PMU_V3: 81808e7381SShannon Zhao r = kvm_arm_support_pmu_v3(); 82808e7381SShannon Zhao break; 83834bf887SAlex Bennée case KVM_CAP_SET_GUEST_DEBUG: 84834bf887SAlex Bennée r = 1; 85834bf887SAlex Bennée break; 86f4672752SMarc Zyngier default: 87f4672752SMarc Zyngier r = 0; 88f4672752SMarc Zyngier } 89f4672752SMarc Zyngier 90f4672752SMarc Zyngier return r; 91f4672752SMarc Zyngier } 92f4672752SMarc Zyngier 93f4672752SMarc Zyngier /** 94f4672752SMarc Zyngier * kvm_reset_vcpu - sets core registers and sys_regs to reset value 95f4672752SMarc Zyngier * @vcpu: The VCPU pointer 96f4672752SMarc Zyngier * 97f4672752SMarc Zyngier * This function finds the right table above and sets the registers on 98f4672752SMarc Zyngier * the virtual CPU struct to their architectually defined reset 99f4672752SMarc Zyngier * values. 100f4672752SMarc Zyngier */ 101f4672752SMarc Zyngier int kvm_reset_vcpu(struct kvm_vcpu *vcpu) 102f4672752SMarc Zyngier { 103003300deSMarc Zyngier const struct kvm_irq_level *cpu_vtimer_irq; 104f4672752SMarc Zyngier const struct kvm_regs *cpu_reset; 105f4672752SMarc Zyngier 106f4672752SMarc Zyngier switch (vcpu->arch.target) { 107f4672752SMarc Zyngier default: 1080d854a60SMarc Zyngier if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) { 1090d854a60SMarc Zyngier if (!cpu_has_32bit_el1()) 1100d854a60SMarc Zyngier return -EINVAL; 1110d854a60SMarc Zyngier cpu_reset = &default_regs_reset32; 1120d854a60SMarc Zyngier } else { 113f4672752SMarc Zyngier cpu_reset = &default_regs_reset; 1140d854a60SMarc Zyngier } 1150d854a60SMarc Zyngier 116003300deSMarc Zyngier cpu_vtimer_irq = &default_vtimer_irq; 117f4672752SMarc Zyngier break; 118f4672752SMarc Zyngier } 119f4672752SMarc Zyngier 120f4672752SMarc Zyngier /* Reset core registers */ 121f4672752SMarc Zyngier memcpy(vcpu_gp_regs(vcpu), cpu_reset, sizeof(*cpu_reset)); 122f4672752SMarc Zyngier 123f4672752SMarc Zyngier /* Reset system registers */ 124f4672752SMarc Zyngier kvm_reset_sys_regs(vcpu); 125f4672752SMarc Zyngier 1262aa36e98SShannon Zhao /* Reset PMU */ 1272aa36e98SShannon Zhao kvm_pmu_vcpu_reset(vcpu); 1282aa36e98SShannon Zhao 129003300deSMarc Zyngier /* Reset timer */ 130f120cd65SMarc Zyngier return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq); 131f4672752SMarc Zyngier } 132