1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/compiler.h>
19#include <linux/kvm_host.h>
20
21#include <asm/kvm_asm.h>
22#include <asm/kvm_mmu.h>
23
24#include "hyp.h"
25
26#define read_debug(r,n) read_sysreg(r##n##_el1)
27#define write_debug(v,r,n) write_sysreg(v, r##n##_el1)
28
29#define save_debug(ptr,reg,nr) \
30 switch (nr) { \
31 case 15: ptr[15] = read_debug(reg, 15); \
32 case 14: ptr[14] = read_debug(reg, 14); \
33 case 13: ptr[13] = read_debug(reg, 13); \
34 case 12: ptr[12] = read_debug(reg, 12); \
35 case 11: ptr[11] = read_debug(reg, 11); \
36 case 10: ptr[10] = read_debug(reg, 10); \
37 case 9: ptr[9] = read_debug(reg, 9); \
38 case 8: ptr[8] = read_debug(reg, 8); \
39 case 7: ptr[7] = read_debug(reg, 7); \
40 case 6: ptr[6] = read_debug(reg, 6); \
41 case 5: ptr[5] = read_debug(reg, 5); \
42 case 4: ptr[4] = read_debug(reg, 4); \
43 case 3: ptr[3] = read_debug(reg, 3); \
44 case 2: ptr[2] = read_debug(reg, 2); \
45 case 1: ptr[1] = read_debug(reg, 1); \
46 default: ptr[0] = read_debug(reg, 0); \
47 }
48
49#define restore_debug(ptr,reg,nr) \
50 switch (nr) { \
51 case 15: write_debug(ptr[15], reg, 15); \
52 case 14: write_debug(ptr[14], reg, 14); \
53 case 13: write_debug(ptr[13], reg, 13); \
54 case 12: write_debug(ptr[12], reg, 12); \
55 case 11: write_debug(ptr[11], reg, 11); \
56 case 10: write_debug(ptr[10], reg, 10); \
57 case 9: write_debug(ptr[9], reg, 9); \
58 case 8: write_debug(ptr[8], reg, 8); \
59 case 7: write_debug(ptr[7], reg, 7); \
60 case 6: write_debug(ptr[6], reg, 6); \
61 case 5: write_debug(ptr[5], reg, 5); \
62 case 4: write_debug(ptr[4], reg, 4); \
63 case 3: write_debug(ptr[3], reg, 3); \
64 case 2: write_debug(ptr[2], reg, 2); \
65 case 1: write_debug(ptr[1], reg, 1); \
66 default: write_debug(ptr[0], reg, 0); \
67 }
68
69void __hyp_text __debug_save_state(struct kvm_vcpu *vcpu,
70 struct kvm_guest_debug_arch *dbg,
71 struct kvm_cpu_context *ctxt)
72{
73 u64 aa64dfr0;
74 int brps, wrps;
75
76 if (!(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY))
77 return;
78
79 aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
80 brps = (aa64dfr0 >> 12) & 0xf;
81 wrps = (aa64dfr0 >> 20) & 0xf;
82
83 save_debug(dbg->dbg_bcr, dbgbcr, brps);
84 save_debug(dbg->dbg_bvr, dbgbvr, brps);
85 save_debug(dbg->dbg_wcr, dbgwcr, wrps);
86 save_debug(dbg->dbg_wvr, dbgwvr, wrps);
87
88 ctxt->sys_regs[MDCCINT_EL1] = read_sysreg(mdccint_el1);
89}
90
91void __hyp_text __debug_restore_state(struct kvm_vcpu *vcpu,
92 struct kvm_guest_debug_arch *dbg,
93 struct kvm_cpu_context *ctxt)
94{
95 u64 aa64dfr0;
96 int brps, wrps;
97
98 if (!(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY))
99 return;
100
101 aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
102
103 brps = (aa64dfr0 >> 12) & 0xf;
104 wrps = (aa64dfr0 >> 20) & 0xf;
105
106 restore_debug(dbg->dbg_bcr, dbgbcr, brps);
107 restore_debug(dbg->dbg_bvr, dbgbvr, brps);
108 restore_debug(dbg->dbg_wcr, dbgwcr, wrps);
109 restore_debug(dbg->dbg_wvr, dbgwvr, wrps);
110
111 write_sysreg(ctxt->sys_regs[MDCCINT_EL1], mdccint_el1);
112}
113
114void __hyp_text __debug_cond_save_host_state(struct kvm_vcpu *vcpu)
115{
116
117
118 if ((vcpu->arch.ctxt.sys_regs[MDSCR_EL1] & DBG_MDSCR_KDE) ||
119 (vcpu->arch.ctxt.sys_regs[MDSCR_EL1] & DBG_MDSCR_MDE))
120 vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
121
122 __debug_save_state(vcpu, &vcpu->arch.host_debug_state,
123 kern_hyp_va(vcpu->arch.host_cpu_context));
124}
125
126void __hyp_text __debug_cond_restore_host_state(struct kvm_vcpu *vcpu)
127{
128 __debug_restore_state(vcpu, &vcpu->arch.host_debug_state,
129 kern_hyp_va(vcpu->arch.host_cpu_context));
130
131 if (vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY)
132 vcpu->arch.debug_flags &= ~KVM_ARM64_DEBUG_DIRTY;
133}
134
135static u32 __hyp_text __debug_read_mdcr_el2(void)
136{
137 return read_sysreg(mdcr_el2);
138}
139
140__alias(__debug_read_mdcr_el2) u32 __kvm_get_mdcr_el2(void);
141