4
4
* Author: Marc Zyngier <[email protected] >
5
5
*/
6
6
7
+ #ifndef __ARM64_KVM_HYP_SYSREG_SR_H__
8
+ #define __ARM64_KVM_HYP_SYSREG_SR_H__
9
+
7
10
#include <linux/compiler.h>
8
11
#include <linux/kvm_host.h>
9
12
12
15
#include <asm/kvm_emulate.h>
13
16
#include <asm/kvm_hyp.h>
14
17
15
- /*
16
- * Non-VHE: Both host and guest must save everything.
17
- *
18
- * VHE: Host and guest must save mdscr_el1 and sp_el0 (and the PC and
19
- * pstate, which are handled as part of the el2 return state) on every
20
- * switch (sp_el0 is being dealt with in the assembly code).
21
- * tpidr_el0 and tpidrro_el0 only need to be switched when going
22
- * to host userspace or a different VCPU. EL1 registers only need to be
23
- * switched when potentially going to run a different VCPU. The latter two
24
- * classes are handled as part of kvm_arch_vcpu_load and kvm_arch_vcpu_put.
25
- */
26
-
27
- static void __hyp_text __sysreg_save_common_state (struct kvm_cpu_context * ctxt )
18
+ static inline void __hyp_text __sysreg_save_common_state (struct kvm_cpu_context * ctxt )
28
19
{
29
20
ctxt -> sys_regs [MDSCR_EL1 ] = read_sysreg (mdscr_el1 );
30
21
}
31
22
32
- static void __hyp_text __sysreg_save_user_state (struct kvm_cpu_context * ctxt )
23
+ static inline void __hyp_text __sysreg_save_user_state (struct kvm_cpu_context * ctxt )
33
24
{
34
25
ctxt -> sys_regs [TPIDR_EL0 ] = read_sysreg (tpidr_el0 );
35
26
ctxt -> sys_regs [TPIDRRO_EL0 ] = read_sysreg (tpidrro_el0 );
36
27
}
37
28
38
- static void __hyp_text __sysreg_save_el1_state (struct kvm_cpu_context * ctxt )
29
+ static inline void __hyp_text __sysreg_save_el1_state (struct kvm_cpu_context * ctxt )
39
30
{
40
31
ctxt -> sys_regs [CSSELR_EL1 ] = read_sysreg (csselr_el1 );
41
32
ctxt -> sys_regs [SCTLR_EL1 ] = read_sysreg_el1 (SYS_SCTLR );
@@ -60,7 +51,7 @@ static void __hyp_text __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
60
51
ctxt -> gp_regs .spsr [KVM_SPSR_EL1 ]= read_sysreg_el1 (SYS_SPSR );
61
52
}
62
53
63
- static void __hyp_text __sysreg_save_el2_return_state (struct kvm_cpu_context * ctxt )
54
+ static inline void __hyp_text __sysreg_save_el2_return_state (struct kvm_cpu_context * ctxt )
64
55
{
65
56
ctxt -> gp_regs .regs .pc = read_sysreg_el2 (SYS_ELR );
66
57
ctxt -> gp_regs .regs .pstate = read_sysreg_el2 (SYS_SPSR );
@@ -69,39 +60,18 @@ static void __hyp_text __sysreg_save_el2_return_state(struct kvm_cpu_context *ct
69
60
ctxt -> sys_regs [DISR_EL1 ] = read_sysreg_s (SYS_VDISR_EL2 );
70
61
}
71
62
72
- void __hyp_text __sysreg_save_state_nvhe (struct kvm_cpu_context * ctxt )
73
- {
74
- __sysreg_save_el1_state (ctxt );
75
- __sysreg_save_common_state (ctxt );
76
- __sysreg_save_user_state (ctxt );
77
- __sysreg_save_el2_return_state (ctxt );
78
- }
79
-
80
- void sysreg_save_host_state_vhe (struct kvm_cpu_context * ctxt )
81
- {
82
- __sysreg_save_common_state (ctxt );
83
- }
84
- NOKPROBE_SYMBOL (sysreg_save_host_state_vhe );
85
-
86
- void sysreg_save_guest_state_vhe (struct kvm_cpu_context * ctxt )
87
- {
88
- __sysreg_save_common_state (ctxt );
89
- __sysreg_save_el2_return_state (ctxt );
90
- }
91
- NOKPROBE_SYMBOL (sysreg_save_guest_state_vhe );
92
-
93
- static void __hyp_text __sysreg_restore_common_state (struct kvm_cpu_context * ctxt )
63
+ static inline void __hyp_text __sysreg_restore_common_state (struct kvm_cpu_context * ctxt )
94
64
{
95
65
write_sysreg (ctxt -> sys_regs [MDSCR_EL1 ], mdscr_el1 );
96
66
}
97
67
98
- static void __hyp_text __sysreg_restore_user_state (struct kvm_cpu_context * ctxt )
68
+ static inline void __hyp_text __sysreg_restore_user_state (struct kvm_cpu_context * ctxt )
99
69
{
100
70
write_sysreg (ctxt -> sys_regs [TPIDR_EL0 ], tpidr_el0 );
101
71
write_sysreg (ctxt -> sys_regs [TPIDRRO_EL0 ], tpidrro_el0 );
102
72
}
103
73
104
- static void __hyp_text __sysreg_restore_el1_state (struct kvm_cpu_context * ctxt )
74
+ static inline void __hyp_text __sysreg_restore_el1_state (struct kvm_cpu_context * ctxt )
105
75
{
106
76
write_sysreg (ctxt -> sys_regs [MPIDR_EL1 ], vmpidr_el2 );
107
77
write_sysreg (ctxt -> sys_regs [CSSELR_EL1 ], csselr_el1 );
@@ -160,8 +130,7 @@ static void __hyp_text __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
160
130
write_sysreg_el1 (ctxt -> gp_regs .spsr [KVM_SPSR_EL1 ],SYS_SPSR );
161
131
}
162
132
163
- static void __hyp_text
164
- __sysreg_restore_el2_return_state (struct kvm_cpu_context * ctxt )
133
+ static inline void __hyp_text __sysreg_restore_el2_return_state (struct kvm_cpu_context * ctxt )
165
134
{
166
135
u64 pstate = ctxt -> gp_regs .regs .pstate ;
167
136
u64 mode = pstate & PSR_AA32_MODE_MASK ;
@@ -187,28 +156,7 @@ __sysreg_restore_el2_return_state(struct kvm_cpu_context *ctxt)
187
156
write_sysreg_s (ctxt -> sys_regs [DISR_EL1 ], SYS_VDISR_EL2 );
188
157
}
189
158
190
- void __hyp_text __sysreg_restore_state_nvhe (struct kvm_cpu_context * ctxt )
191
- {
192
- __sysreg_restore_el1_state (ctxt );
193
- __sysreg_restore_common_state (ctxt );
194
- __sysreg_restore_user_state (ctxt );
195
- __sysreg_restore_el2_return_state (ctxt );
196
- }
197
-
198
- void sysreg_restore_host_state_vhe (struct kvm_cpu_context * ctxt )
199
- {
200
- __sysreg_restore_common_state (ctxt );
201
- }
202
- NOKPROBE_SYMBOL (sysreg_restore_host_state_vhe );
203
-
204
- void sysreg_restore_guest_state_vhe (struct kvm_cpu_context * ctxt )
205
- {
206
- __sysreg_restore_common_state (ctxt );
207
- __sysreg_restore_el2_return_state (ctxt );
208
- }
209
- NOKPROBE_SYMBOL (sysreg_restore_guest_state_vhe );
210
-
211
- void __hyp_text __sysreg32_save_state (struct kvm_vcpu * vcpu )
159
+ static inline void __hyp_text __sysreg32_save_state (struct kvm_vcpu * vcpu )
212
160
{
213
161
u64 * spsr , * sysreg ;
214
162
@@ -230,7 +178,7 @@ void __hyp_text __sysreg32_save_state(struct kvm_vcpu *vcpu)
230
178
sysreg [DBGVCR32_EL2 ] = read_sysreg (dbgvcr32_el2 );
231
179
}
232
180
233
- void __hyp_text __sysreg32_restore_state (struct kvm_vcpu * vcpu )
181
+ static inline void __hyp_text __sysreg32_restore_state (struct kvm_vcpu * vcpu )
234
182
{
235
183
u64 * spsr , * sysreg ;
236
184
@@ -252,82 +200,4 @@ void __hyp_text __sysreg32_restore_state(struct kvm_vcpu *vcpu)
252
200
write_sysreg (sysreg [DBGVCR32_EL2 ], dbgvcr32_el2 );
253
201
}
254
202
255
- /**
256
- * kvm_vcpu_load_sysregs - Load guest system registers to the physical CPU
257
- *
258
- * @vcpu: The VCPU pointer
259
- *
260
- * Load system registers that do not affect the host's execution, for
261
- * example EL1 system registers on a VHE system where the host kernel
262
- * runs at EL2. This function is called from KVM's vcpu_load() function
263
- * and loading system register state early avoids having to load them on
264
- * every entry to the VM.
265
- */
266
- void kvm_vcpu_load_sysregs (struct kvm_vcpu * vcpu )
267
- {
268
- struct kvm_cpu_context * guest_ctxt = & vcpu -> arch .ctxt ;
269
- struct kvm_cpu_context * host_ctxt ;
270
-
271
- if (!has_vhe ())
272
- return ;
273
-
274
- host_ctxt = & __hyp_this_cpu_ptr (kvm_host_data )-> host_ctxt ;
275
- __sysreg_save_user_state (host_ctxt );
276
-
277
- /*
278
- * Load guest EL1 and user state
279
- *
280
- * We must restore the 32-bit state before the sysregs, thanks
281
- * to erratum #852523 (Cortex-A57) or #853709 (Cortex-A72).
282
- */
283
- __sysreg32_restore_state (vcpu );
284
- __sysreg_restore_user_state (guest_ctxt );
285
- __sysreg_restore_el1_state (guest_ctxt );
286
-
287
- vcpu -> arch .sysregs_loaded_on_cpu = true;
288
-
289
- activate_traps_vhe_load (vcpu );
290
- }
291
-
292
- /**
293
- * kvm_vcpu_put_sysregs - Restore host system registers to the physical CPU
294
- *
295
- * @vcpu: The VCPU pointer
296
- *
297
- * Save guest system registers that do not affect the host's execution, for
298
- * example EL1 system registers on a VHE system where the host kernel
299
- * runs at EL2. This function is called from KVM's vcpu_put() function
300
- * and deferring saving system register state until we're no longer running the
301
- * VCPU avoids having to save them on every exit from the VM.
302
- */
303
- void kvm_vcpu_put_sysregs (struct kvm_vcpu * vcpu )
304
- {
305
- struct kvm_cpu_context * guest_ctxt = & vcpu -> arch .ctxt ;
306
- struct kvm_cpu_context * host_ctxt ;
307
-
308
- if (!has_vhe ())
309
- return ;
310
-
311
- host_ctxt = & __hyp_this_cpu_ptr (kvm_host_data )-> host_ctxt ;
312
- deactivate_traps_vhe_put ();
313
-
314
- __sysreg_save_el1_state (guest_ctxt );
315
- __sysreg_save_user_state (guest_ctxt );
316
- __sysreg32_save_state (vcpu );
317
-
318
- /* Restore host user state */
319
- __sysreg_restore_user_state (host_ctxt );
320
-
321
- vcpu -> arch .sysregs_loaded_on_cpu = false;
322
- }
323
-
324
- void __hyp_text __kvm_enable_ssbs (void )
325
- {
326
- u64 tmp ;
327
-
328
- asm volatile (
329
- "mrs %0, sctlr_el2\n"
330
- "orr %0, %0, %1\n"
331
- "msr sctlr_el2, %0"
332
- : "=&r" (tmp ) : "L" (SCTLR_ELx_DSSBS ));
333
- }
203
+ #endif /* __ARM64_KVM_HYP_SYSREG_SR_H__ */
0 commit comments