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 297665f3a8SSuzuki K Poulose #include <asm/cpufeature.h> 30f4672752SMarc Zyngier #include <asm/cputype.h> 31f4672752SMarc Zyngier #include <asm/ptrace.h> 32f4672752SMarc Zyngier #include <asm/kvm_arm.h> 3367f69197SAKASHI Takahiro #include <asm/kvm_asm.h> 34f4672752SMarc Zyngier #include <asm/kvm_coproc.h> 3567f69197SAKASHI Takahiro #include <asm/kvm_mmu.h> 36f4672752SMarc Zyngier 37f4672752SMarc Zyngier /* 38f4672752SMarc Zyngier * ARMv8 Reset Values 39f4672752SMarc Zyngier */ 40f4672752SMarc Zyngier static const struct kvm_regs default_regs_reset = { 41f4672752SMarc Zyngier .regs.pstate = (PSR_MODE_EL1h | PSR_A_BIT | PSR_I_BIT | 42f4672752SMarc Zyngier PSR_F_BIT | PSR_D_BIT), 43f4672752SMarc Zyngier }; 44f4672752SMarc Zyngier 450d854a60SMarc Zyngier static const struct kvm_regs default_regs_reset32 = { 46256c0960SMark Rutland .regs.pstate = (PSR_AA32_MODE_SVC | PSR_AA32_A_BIT | 47256c0960SMark Rutland PSR_AA32_I_BIT | PSR_AA32_F_BIT), 480d854a60SMarc Zyngier }; 490d854a60SMarc Zyngier 500d854a60SMarc Zyngier static bool cpu_has_32bit_el1(void) 510d854a60SMarc Zyngier { 520d854a60SMarc Zyngier u64 pfr0; 530d854a60SMarc Zyngier 5446823dd1SDave Martin pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1); 550d854a60SMarc Zyngier return !!(pfr0 & 0x20); 560d854a60SMarc Zyngier } 570d854a60SMarc Zyngier 58834bf887SAlex Bennée /** 59834bf887SAlex Bennée * kvm_arch_dev_ioctl_check_extension 60834bf887SAlex Bennée * 61834bf887SAlex Bennée * We currently assume that the number of HW registers is uniform 62834bf887SAlex Bennée * across all CPUs (see cpuinfo_sanity_check). 63834bf887SAlex Bennée */ 64b46f01ceSAndre Przywara int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext) 65f4672752SMarc Zyngier { 66f4672752SMarc Zyngier int r; 67f4672752SMarc Zyngier 68f4672752SMarc Zyngier switch (ext) { 690d854a60SMarc Zyngier case KVM_CAP_ARM_EL1_32BIT: 700d854a60SMarc Zyngier r = cpu_has_32bit_el1(); 710d854a60SMarc Zyngier break; 72834bf887SAlex Bennée case KVM_CAP_GUEST_DEBUG_HW_BPS: 73834bf887SAlex Bennée r = get_num_brps(); 74834bf887SAlex Bennée break; 75834bf887SAlex Bennée case KVM_CAP_GUEST_DEBUG_HW_WPS: 76834bf887SAlex Bennée r = get_num_wrps(); 77834bf887SAlex Bennée break; 78808e7381SShannon Zhao case KVM_CAP_ARM_PMU_V3: 79808e7381SShannon Zhao r = kvm_arm_support_pmu_v3(); 80808e7381SShannon Zhao break; 81be26b3a7SDongjiu Geng case KVM_CAP_ARM_INJECT_SERROR_ESR: 82be26b3a7SDongjiu Geng r = cpus_have_const_cap(ARM64_HAS_RAS_EXTN); 83be26b3a7SDongjiu Geng break; 84834bf887SAlex Bennée case KVM_CAP_SET_GUEST_DEBUG: 85f577f6c2SShannon Zhao case KVM_CAP_VCPU_ATTRIBUTES: 86b7b27facSDongjiu Geng case KVM_CAP_VCPU_EVENTS: 87834bf887SAlex Bennée r = 1; 88834bf887SAlex Bennée break; 89f4672752SMarc Zyngier default: 90f4672752SMarc Zyngier r = 0; 91f4672752SMarc Zyngier } 92f4672752SMarc Zyngier 93f4672752SMarc Zyngier return r; 94f4672752SMarc Zyngier } 95f4672752SMarc Zyngier 96f4672752SMarc Zyngier /** 97f4672752SMarc Zyngier * kvm_reset_vcpu - sets core registers and sys_regs to reset value 98f4672752SMarc Zyngier * @vcpu: The VCPU pointer 99f4672752SMarc Zyngier * 100f4672752SMarc Zyngier * This function finds the right table above and sets the registers on 101edce2292SAndrea Gelmini * the virtual CPU struct to their architecturally defined reset 102f4672752SMarc Zyngier * values. 103f4672752SMarc Zyngier */ 104f4672752SMarc Zyngier int kvm_reset_vcpu(struct kvm_vcpu *vcpu) 105f4672752SMarc Zyngier { 106f4672752SMarc Zyngier const struct kvm_regs *cpu_reset; 107f4672752SMarc Zyngier 108f4672752SMarc Zyngier switch (vcpu->arch.target) { 109f4672752SMarc Zyngier default: 1100d854a60SMarc Zyngier if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) { 1110d854a60SMarc Zyngier if (!cpu_has_32bit_el1()) 1120d854a60SMarc Zyngier return -EINVAL; 1130d854a60SMarc Zyngier cpu_reset = &default_regs_reset32; 1140d854a60SMarc Zyngier } else { 115f4672752SMarc Zyngier cpu_reset = &default_regs_reset; 1160d854a60SMarc Zyngier } 1170d854a60SMarc Zyngier 118f4672752SMarc Zyngier break; 119f4672752SMarc Zyngier } 120f4672752SMarc Zyngier 121f4672752SMarc Zyngier /* Reset core registers */ 122f4672752SMarc Zyngier memcpy(vcpu_gp_regs(vcpu), cpu_reset, sizeof(*cpu_reset)); 123f4672752SMarc Zyngier 124f4672752SMarc Zyngier /* Reset system registers */ 125f4672752SMarc Zyngier kvm_reset_sys_regs(vcpu); 126f4672752SMarc Zyngier 1272aa36e98SShannon Zhao /* Reset PMU */ 1282aa36e98SShannon Zhao kvm_pmu_vcpu_reset(vcpu); 1292aa36e98SShannon Zhao 1305d81f7dcSMarc Zyngier /* Default workaround setup is enabled (if supported) */ 1315d81f7dcSMarc Zyngier if (kvm_arm_have_ssbd() == KVM_SSBD_KERNEL) 1325d81f7dcSMarc Zyngier vcpu->arch.workaround_flags |= VCPU_WORKAROUND_2_FLAG; 1335d81f7dcSMarc Zyngier 134003300deSMarc Zyngier /* Reset timer */ 13585e69ad7SChristoffer Dall return kvm_timer_vcpu_reset(vcpu); 136f4672752SMarc Zyngier } 1375b6c6742SSuzuki K Poulose 1387665f3a8SSuzuki K Poulose /* 1397665f3a8SSuzuki K Poulose * Configure the VTCR_EL2 for this VM. The VTCR value is common 1407665f3a8SSuzuki K Poulose * across all the physical CPUs on the system. We use system wide 1417665f3a8SSuzuki K Poulose * sanitised values to fill in different fields, except for Hardware 1427665f3a8SSuzuki K Poulose * Management of Access Flags. HA Flag is set unconditionally on 1437665f3a8SSuzuki K Poulose * all CPUs, as it is safe to run with or without the feature and 1447665f3a8SSuzuki K Poulose * the bit is RES0 on CPUs that don't support it. 1457665f3a8SSuzuki K Poulose */ 1465b6c6742SSuzuki K Poulose int kvm_arm_config_vm(struct kvm *kvm, unsigned long type) 1475b6c6742SSuzuki K Poulose { 1487665f3a8SSuzuki K Poulose u64 vtcr = VTCR_EL2_FLAGS; 1497665f3a8SSuzuki K Poulose u32 parange, phys_shift; 1507665f3a8SSuzuki K Poulose 1515b6c6742SSuzuki K Poulose if (type) 1525b6c6742SSuzuki K Poulose return -EINVAL; 1537665f3a8SSuzuki K Poulose 1547665f3a8SSuzuki K Poulose parange = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1) & 7; 1557665f3a8SSuzuki K Poulose if (parange > ID_AA64MMFR0_PARANGE_MAX) 1567665f3a8SSuzuki K Poulose parange = ID_AA64MMFR0_PARANGE_MAX; 1577665f3a8SSuzuki K Poulose vtcr |= parange << VTCR_EL2_PS_SHIFT; 1587665f3a8SSuzuki K Poulose 1597665f3a8SSuzuki K Poulose phys_shift = id_aa64mmfr0_parange_to_phys_shift(parange); 1607665f3a8SSuzuki K Poulose if (phys_shift > KVM_PHYS_SHIFT) 1617665f3a8SSuzuki K Poulose phys_shift = KVM_PHYS_SHIFT; 1627665f3a8SSuzuki K Poulose vtcr |= VTCR_EL2_T0SZ(phys_shift); 1637665f3a8SSuzuki K Poulose 1647665f3a8SSuzuki K Poulose /* 1657665f3a8SSuzuki K Poulose * Enable the Hardware Access Flag management, unconditionally 1667665f3a8SSuzuki K Poulose * on all CPUs. The features is RES0 on CPUs without the support 1677665f3a8SSuzuki K Poulose * and must be ignored by the CPUs. 1687665f3a8SSuzuki K Poulose */ 1697665f3a8SSuzuki K Poulose vtcr |= VTCR_EL2_HA; 1707665f3a8SSuzuki K Poulose 1717665f3a8SSuzuki K Poulose /* Set the vmid bits */ 1727665f3a8SSuzuki K Poulose vtcr |= (kvm_get_vmid_bits() == 16) ? 1737665f3a8SSuzuki K Poulose VTCR_EL2_VS_16BIT : 1747665f3a8SSuzuki K Poulose VTCR_EL2_VS_8BIT; 1757665f3a8SSuzuki K Poulose kvm->arch.vtcr = vtcr; 1765b6c6742SSuzuki K Poulose return 0; 1775b6c6742SSuzuki K Poulose } 178