aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/kvm/hyp/hyp-entry.S11
-rw-r--r--arch/arm64/kvm/hyp/hyp.h1
-rw-r--r--arch/arm64/kvm/hyp/switch.c30
3 files changed, 41 insertions, 1 deletions
diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index 818731a5f61c..8e58a3ba6139 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -155,7 +155,16 @@ el1_irq:
155 mov x1, #ARM_EXCEPTION_IRQ 155 mov x1, #ARM_EXCEPTION_IRQ
156 b __guest_exit 156 b __guest_exit
157 157
158.macro invalid_vector label, target = __kvm_hyp_panic 158ENTRY(__hyp_do_panic)
159 mov lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
160 PSR_MODE_EL1h)
161 msr spsr_el2, lr
162 ldr lr, =panic
163 msr elr_el2, lr
164 eret
165ENDPROC(__hyp_do_panic)
166
167.macro invalid_vector label, target = __hyp_panic
159 .align 2 168 .align 2
160\label: 169\label:
161 b \target 170 b \target
diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h
index 70d4f696c862..fb275178b6af 100644
--- a/arch/arm64/kvm/hyp/hyp.h
+++ b/arch/arm64/kvm/hyp/hyp.h
@@ -84,6 +84,7 @@ static inline bool __fpsimd_enabled(void)
84} 84}
85 85
86u64 __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host_ctxt); 86u64 __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host_ctxt);
87void __noreturn __hyp_do_panic(unsigned long, ...);
87 88
88#endif /* __ARM64_KVM_HYP_H__ */ 89#endif /* __ARM64_KVM_HYP_H__ */
89 90
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 608155f5b856..b012870a92e7 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -141,3 +141,33 @@ int __hyp_text __guest_run(struct kvm_vcpu *vcpu)
141 141
142 return exit_code; 142 return exit_code;
143} 143}
144
145static const char __hyp_panic_string[] = "HYP panic:\nPS:%08llx PC:%016llx ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%p\n";
146
147void __hyp_text __noreturn __hyp_panic(void)
148{
149 unsigned long str_va = (unsigned long)__hyp_panic_string;
150 u64 spsr = read_sysreg(spsr_el2);
151 u64 elr = read_sysreg(elr_el2);
152 u64 par = read_sysreg(par_el1);
153
154 if (read_sysreg(vttbr_el2)) {
155 struct kvm_vcpu *vcpu;
156 struct kvm_cpu_context *host_ctxt;
157
158 vcpu = (struct kvm_vcpu *)read_sysreg(tpidr_el2);
159 host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
160 __deactivate_traps(vcpu);
161 __deactivate_vm(vcpu);
162 __sysreg_restore_state(host_ctxt);
163 }
164
165 /* Call panic for real */
166 __hyp_do_panic(hyp_kern_va(str_va),
167 spsr, elr,
168 read_sysreg(esr_el2), read_sysreg(far_el2),
169 read_sysreg(hpfar_el2), par,
170 (void *)read_sysreg(tpidr_el2));
171
172 unreachable();
173}