Loading arch/arm/include/asm/kvm_coproc.h +2 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,8 @@ void kvm_register_target_coproc_table(struct kvm_coproc_target_table *table); int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp_0_13_access(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run); Loading arch/arm/kvm/coproc.c +74 −32 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <asm/vfp.h> #include "../vfp/vfpinstr.h" #define CREATE_TRACE_POINTS #include "trace.h" #include "coproc.h" Loading Loading @@ -111,12 +112,6 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run) return 1; } int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run) { kvm_inject_undefined(vcpu); return 1; } static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r) { /* Loading Loading @@ -284,7 +279,7 @@ static bool access_gic_sre(struct kvm_vcpu *vcpu, * must always support PMCCNTR (the cycle counter): we just RAZ/WI for * all PM registers, which doesn't crash the guest kernel at least. */ static bool pm_fake(struct kvm_vcpu *vcpu, static bool trap_raz_wi(struct kvm_vcpu *vcpu, const struct coproc_params *p, const struct coproc_reg *r) { Loading @@ -294,19 +289,19 @@ static bool pm_fake(struct kvm_vcpu *vcpu, return read_zero(vcpu, p); } #define access_pmcr pm_fake #define access_pmcntenset pm_fake #define access_pmcntenclr pm_fake #define access_pmovsr pm_fake #define access_pmselr pm_fake #define access_pmceid0 pm_fake #define access_pmceid1 pm_fake #define access_pmccntr pm_fake #define access_pmxevtyper pm_fake #define access_pmxevcntr pm_fake #define access_pmuserenr pm_fake #define access_pmintenset pm_fake #define access_pmintenclr pm_fake #define access_pmcr trap_raz_wi #define access_pmcntenset trap_raz_wi #define access_pmcntenclr trap_raz_wi #define access_pmovsr trap_raz_wi #define access_pmselr trap_raz_wi #define access_pmceid0 trap_raz_wi #define access_pmceid1 trap_raz_wi #define access_pmccntr trap_raz_wi #define access_pmxevtyper trap_raz_wi #define access_pmxevcntr trap_raz_wi #define access_pmuserenr trap_raz_wi #define access_pmintenset trap_raz_wi #define access_pmintenclr trap_raz_wi /* Architected CP15 registers. * CRn denotes the primary register number, but is copied to the CRm in the Loading Loading @@ -532,12 +527,7 @@ static int emulate_cp15(struct kvm_vcpu *vcpu, return 1; } /** * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) static struct coproc_params decode_64bit_hsr(struct kvm_vcpu *vcpu) { struct coproc_params params; Loading @@ -551,9 +541,38 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) params.Rt2 = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf; params.CRm = 0; return params; } /** * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) { struct coproc_params params = decode_64bit_hsr(vcpu); return emulate_cp15(vcpu, ¶ms); } /** * kvm_handle_cp14_64 -- handles a mrrc/mcrr trap on a guest CP14 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run) { struct coproc_params params = decode_64bit_hsr(vcpu); /* raz_wi cp14 */ trap_raz_wi(vcpu, ¶ms, NULL); /* handled */ kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); return 1; } static void reset_coproc_regs(struct kvm_vcpu *vcpu, const struct coproc_reg *table, size_t num) { Loading @@ -564,12 +583,7 @@ static void reset_coproc_regs(struct kvm_vcpu *vcpu, table[i].reset(vcpu, &table[i]); } /** * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) static struct coproc_params decode_32bit_hsr(struct kvm_vcpu *vcpu) { struct coproc_params params; Loading @@ -583,9 +597,37 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) params.Op2 = (kvm_vcpu_get_hsr(vcpu) >> 17) & 0x7; params.Rt2 = 0; return params; } /** * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) { struct coproc_params params = decode_32bit_hsr(vcpu); return emulate_cp15(vcpu, ¶ms); } /** * kvm_handle_cp14_32 -- handles a mrc/mcr trap on a guest CP14 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run) { struct coproc_params params = decode_32bit_hsr(vcpu); /* raz_wi cp14 */ trap_raz_wi(vcpu, ¶ms, NULL); /* handled */ kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); return 1; } /****************************************************************************** * Userspace API *****************************************************************************/ Loading arch/arm/kvm/handle_exit.c +2 −2 Original line number Diff line number Diff line Loading @@ -96,9 +96,9 @@ static exit_handle_fn arm_exit_handlers[] = { [HSR_EC_WFI] = kvm_handle_wfx, [HSR_EC_CP15_32] = kvm_handle_cp15_32, [HSR_EC_CP15_64] = kvm_handle_cp15_64, [HSR_EC_CP14_MR] = kvm_handle_cp14_access, [HSR_EC_CP14_MR] = kvm_handle_cp14_32, [HSR_EC_CP14_LS] = kvm_handle_cp14_load_store, [HSR_EC_CP14_64] = kvm_handle_cp14_access, [HSR_EC_CP14_64] = kvm_handle_cp14_64, [HSR_EC_CP_0_13] = kvm_handle_cp_0_13_access, [HSR_EC_CP10_ID] = kvm_handle_cp10_id, [HSR_EC_HVC] = handle_hvc, Loading arch/arm/kvm/hyp/Makefile +2 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ # Makefile for Kernel-based Virtual Machine module, HYP part # ccflags-y += -fno-stack-protector KVM=../../../../virt/kvm obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o Loading arch/arm/kvm/hyp/switch.c +3 −1 Original line number Diff line number Diff line Loading @@ -48,7 +48,9 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu, u32 *fpexc_host) write_sysreg(HSTR_T(15), HSTR); write_sysreg(HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11), HCPTR); val = read_sysreg(HDCR); write_sysreg(val | HDCR_TPM | HDCR_TPMCR, HDCR); val |= HDCR_TPM | HDCR_TPMCR; /* trap performance monitors */ val |= HDCR_TDRA | HDCR_TDOSA | HDCR_TDA; /* trap debug regs */ write_sysreg(val, HDCR); } static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu) Loading Loading
arch/arm/include/asm/kvm_coproc.h +2 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,8 @@ void kvm_register_target_coproc_table(struct kvm_coproc_target_table *table); int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp_0_13_access(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run); int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run); Loading
arch/arm/kvm/coproc.c +74 −32 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <asm/vfp.h> #include "../vfp/vfpinstr.h" #define CREATE_TRACE_POINTS #include "trace.h" #include "coproc.h" Loading Loading @@ -111,12 +112,6 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run) return 1; } int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run) { kvm_inject_undefined(vcpu); return 1; } static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r) { /* Loading Loading @@ -284,7 +279,7 @@ static bool access_gic_sre(struct kvm_vcpu *vcpu, * must always support PMCCNTR (the cycle counter): we just RAZ/WI for * all PM registers, which doesn't crash the guest kernel at least. */ static bool pm_fake(struct kvm_vcpu *vcpu, static bool trap_raz_wi(struct kvm_vcpu *vcpu, const struct coproc_params *p, const struct coproc_reg *r) { Loading @@ -294,19 +289,19 @@ static bool pm_fake(struct kvm_vcpu *vcpu, return read_zero(vcpu, p); } #define access_pmcr pm_fake #define access_pmcntenset pm_fake #define access_pmcntenclr pm_fake #define access_pmovsr pm_fake #define access_pmselr pm_fake #define access_pmceid0 pm_fake #define access_pmceid1 pm_fake #define access_pmccntr pm_fake #define access_pmxevtyper pm_fake #define access_pmxevcntr pm_fake #define access_pmuserenr pm_fake #define access_pmintenset pm_fake #define access_pmintenclr pm_fake #define access_pmcr trap_raz_wi #define access_pmcntenset trap_raz_wi #define access_pmcntenclr trap_raz_wi #define access_pmovsr trap_raz_wi #define access_pmselr trap_raz_wi #define access_pmceid0 trap_raz_wi #define access_pmceid1 trap_raz_wi #define access_pmccntr trap_raz_wi #define access_pmxevtyper trap_raz_wi #define access_pmxevcntr trap_raz_wi #define access_pmuserenr trap_raz_wi #define access_pmintenset trap_raz_wi #define access_pmintenclr trap_raz_wi /* Architected CP15 registers. * CRn denotes the primary register number, but is copied to the CRm in the Loading Loading @@ -532,12 +527,7 @@ static int emulate_cp15(struct kvm_vcpu *vcpu, return 1; } /** * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) static struct coproc_params decode_64bit_hsr(struct kvm_vcpu *vcpu) { struct coproc_params params; Loading @@ -551,9 +541,38 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) params.Rt2 = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf; params.CRm = 0; return params; } /** * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run) { struct coproc_params params = decode_64bit_hsr(vcpu); return emulate_cp15(vcpu, ¶ms); } /** * kvm_handle_cp14_64 -- handles a mrrc/mcrr trap on a guest CP14 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run) { struct coproc_params params = decode_64bit_hsr(vcpu); /* raz_wi cp14 */ trap_raz_wi(vcpu, ¶ms, NULL); /* handled */ kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); return 1; } static void reset_coproc_regs(struct kvm_vcpu *vcpu, const struct coproc_reg *table, size_t num) { Loading @@ -564,12 +583,7 @@ static void reset_coproc_regs(struct kvm_vcpu *vcpu, table[i].reset(vcpu, &table[i]); } /** * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) static struct coproc_params decode_32bit_hsr(struct kvm_vcpu *vcpu) { struct coproc_params params; Loading @@ -583,9 +597,37 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) params.Op2 = (kvm_vcpu_get_hsr(vcpu) >> 17) & 0x7; params.Rt2 = 0; return params; } /** * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run) { struct coproc_params params = decode_32bit_hsr(vcpu); return emulate_cp15(vcpu, ¶ms); } /** * kvm_handle_cp14_32 -- handles a mrc/mcr trap on a guest CP14 access * @vcpu: The VCPU pointer * @run: The kvm_run struct */ int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run) { struct coproc_params params = decode_32bit_hsr(vcpu); /* raz_wi cp14 */ trap_raz_wi(vcpu, ¶ms, NULL); /* handled */ kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu)); return 1; } /****************************************************************************** * Userspace API *****************************************************************************/ Loading
arch/arm/kvm/handle_exit.c +2 −2 Original line number Diff line number Diff line Loading @@ -96,9 +96,9 @@ static exit_handle_fn arm_exit_handlers[] = { [HSR_EC_WFI] = kvm_handle_wfx, [HSR_EC_CP15_32] = kvm_handle_cp15_32, [HSR_EC_CP15_64] = kvm_handle_cp15_64, [HSR_EC_CP14_MR] = kvm_handle_cp14_access, [HSR_EC_CP14_MR] = kvm_handle_cp14_32, [HSR_EC_CP14_LS] = kvm_handle_cp14_load_store, [HSR_EC_CP14_64] = kvm_handle_cp14_access, [HSR_EC_CP14_64] = kvm_handle_cp14_64, [HSR_EC_CP_0_13] = kvm_handle_cp_0_13_access, [HSR_EC_CP10_ID] = kvm_handle_cp10_id, [HSR_EC_HVC] = handle_hvc, Loading
arch/arm/kvm/hyp/Makefile +2 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ # Makefile for Kernel-based Virtual Machine module, HYP part # ccflags-y += -fno-stack-protector KVM=../../../../virt/kvm obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o Loading
arch/arm/kvm/hyp/switch.c +3 −1 Original line number Diff line number Diff line Loading @@ -48,7 +48,9 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu, u32 *fpexc_host) write_sysreg(HSTR_T(15), HSTR); write_sysreg(HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11), HCPTR); val = read_sysreg(HDCR); write_sysreg(val | HDCR_TPM | HDCR_TPMCR, HDCR); val |= HDCR_TPM | HDCR_TPMCR; /* trap performance monitors */ val |= HDCR_TDRA | HDCR_TDOSA | HDCR_TDA; /* trap debug regs */ write_sysreg(val, HDCR); } static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu) Loading