15
15
#include <asm/kvm_hyp.h>
16
16
#include <asm/kvm_nested.h>
17
17
18
+ static void __sysreg_save_vel2_state (struct kvm_vcpu * vcpu )
19
+ {
20
+ /* These registers are common with EL1 */
21
+ __vcpu_sys_reg (vcpu , PAR_EL1 ) = read_sysreg (par_el1 );
22
+ __vcpu_sys_reg (vcpu , TPIDR_EL1 ) = read_sysreg (tpidr_el1 );
23
+
24
+ __vcpu_sys_reg (vcpu , ESR_EL2 ) = read_sysreg_el1 (SYS_ESR );
25
+ __vcpu_sys_reg (vcpu , AFSR0_EL2 ) = read_sysreg_el1 (SYS_AFSR0 );
26
+ __vcpu_sys_reg (vcpu , AFSR1_EL2 ) = read_sysreg_el1 (SYS_AFSR1 );
27
+ __vcpu_sys_reg (vcpu , FAR_EL2 ) = read_sysreg_el1 (SYS_FAR );
28
+ __vcpu_sys_reg (vcpu , MAIR_EL2 ) = read_sysreg_el1 (SYS_MAIR );
29
+ __vcpu_sys_reg (vcpu , VBAR_EL2 ) = read_sysreg_el1 (SYS_VBAR );
30
+ __vcpu_sys_reg (vcpu , CONTEXTIDR_EL2 ) = read_sysreg_el1 (SYS_CONTEXTIDR );
31
+ __vcpu_sys_reg (vcpu , AMAIR_EL2 ) = read_sysreg_el1 (SYS_AMAIR );
32
+
33
+ /*
34
+ * In VHE mode those registers are compatible between EL1 and EL2,
35
+ * and the guest uses the _EL1 versions on the CPU naturally.
36
+ * So we save them into their _EL2 versions here.
37
+ * For nVHE mode we trap accesses to those registers, so our
38
+ * _EL2 copy in sys_regs[] is always up-to-date and we don't need
39
+ * to save anything here.
40
+ */
41
+ if (vcpu_el2_e2h_is_set (vcpu )) {
42
+ u64 val ;
43
+
44
+ /*
45
+ * We don't save CPTR_EL2, as accesses to CPACR_EL1
46
+ * are always trapped, ensuring that the in-memory
47
+ * copy is always up-to-date. A small blessing...
48
+ */
49
+ __vcpu_sys_reg (vcpu , SCTLR_EL2 ) = read_sysreg_el1 (SYS_SCTLR );
50
+ __vcpu_sys_reg (vcpu , TTBR0_EL2 ) = read_sysreg_el1 (SYS_TTBR0 );
51
+ __vcpu_sys_reg (vcpu , TTBR1_EL2 ) = read_sysreg_el1 (SYS_TTBR1 );
52
+ __vcpu_sys_reg (vcpu , TCR_EL2 ) = read_sysreg_el1 (SYS_TCR );
53
+
54
+ /*
55
+ * The EL1 view of CNTKCTL_EL1 has a bunch of RES0 bits where
56
+ * the interesting CNTHCTL_EL2 bits live. So preserve these
57
+ * bits when reading back the guest-visible value.
58
+ */
59
+ val = read_sysreg_el1 (SYS_CNTKCTL );
60
+ val &= CNTKCTL_VALID_BITS ;
61
+ __vcpu_sys_reg (vcpu , CNTHCTL_EL2 ) &= ~CNTKCTL_VALID_BITS ;
62
+ __vcpu_sys_reg (vcpu , CNTHCTL_EL2 ) |= val ;
63
+ }
64
+
65
+ __vcpu_sys_reg (vcpu , SP_EL2 ) = read_sysreg (sp_el1 );
66
+ __vcpu_sys_reg (vcpu , ELR_EL2 ) = read_sysreg_el1 (SYS_ELR );
67
+ __vcpu_sys_reg (vcpu , SPSR_EL2 ) = read_sysreg_el1 (SYS_SPSR );
68
+ }
69
+
70
+ static void __sysreg_restore_vel2_state (struct kvm_vcpu * vcpu )
71
+ {
72
+ u64 val ;
73
+
74
+ /* These registers are common with EL1 */
75
+ write_sysreg (__vcpu_sys_reg (vcpu , PAR_EL1 ), par_el1 );
76
+ write_sysreg (__vcpu_sys_reg (vcpu , TPIDR_EL1 ), tpidr_el1 );
77
+
78
+ write_sysreg (__vcpu_sys_reg (vcpu , MPIDR_EL1 ), vmpidr_el2 );
79
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , MAIR_EL2 ), SYS_MAIR );
80
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , VBAR_EL2 ), SYS_VBAR );
81
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , CONTEXTIDR_EL2 ), SYS_CONTEXTIDR );
82
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , AMAIR_EL2 ), SYS_AMAIR );
83
+
84
+ if (vcpu_el2_e2h_is_set (vcpu )) {
85
+ /*
86
+ * In VHE mode those registers are compatible between
87
+ * EL1 and EL2.
88
+ */
89
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , SCTLR_EL2 ), SYS_SCTLR );
90
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , CPTR_EL2 ), SYS_CPACR );
91
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , TTBR0_EL2 ), SYS_TTBR0 );
92
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , TTBR1_EL2 ), SYS_TTBR1 );
93
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , TCR_EL2 ), SYS_TCR );
94
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , CNTHCTL_EL2 ), SYS_CNTKCTL );
95
+ } else {
96
+ /*
97
+ * CNTHCTL_EL2 only affects EL1 when running nVHE, so
98
+ * no need to restore it.
99
+ */
100
+ val = translate_sctlr_el2_to_sctlr_el1 (__vcpu_sys_reg (vcpu , SCTLR_EL2 ));
101
+ write_sysreg_el1 (val , SYS_SCTLR );
102
+ val = translate_cptr_el2_to_cpacr_el1 (__vcpu_sys_reg (vcpu , CPTR_EL2 ));
103
+ write_sysreg_el1 (val , SYS_CPACR );
104
+ val = translate_ttbr0_el2_to_ttbr0_el1 (__vcpu_sys_reg (vcpu , TTBR0_EL2 ));
105
+ write_sysreg_el1 (val , SYS_TTBR0 );
106
+ val = translate_tcr_el2_to_tcr_el1 (__vcpu_sys_reg (vcpu , TCR_EL2 ));
107
+ write_sysreg_el1 (val , SYS_TCR );
108
+ }
109
+
110
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , ESR_EL2 ), SYS_ESR );
111
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , AFSR0_EL2 ), SYS_AFSR0 );
112
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , AFSR1_EL2 ), SYS_AFSR1 );
113
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , FAR_EL2 ), SYS_FAR );
114
+ write_sysreg (__vcpu_sys_reg (vcpu , SP_EL2 ), sp_el1 );
115
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , ELR_EL2 ), SYS_ELR );
116
+ write_sysreg_el1 (__vcpu_sys_reg (vcpu , SPSR_EL2 ), SYS_SPSR );
117
+ }
118
+
18
119
/*
19
120
* VHE: Host and guest must save mdscr_el1 and sp_el0 (and the PC and
20
121
* pstate, which are handled as part of the el2 return state) on every
@@ -66,6 +167,7 @@ void __vcpu_load_switch_sysregs(struct kvm_vcpu *vcpu)
66
167
{
67
168
struct kvm_cpu_context * guest_ctxt = & vcpu -> arch .ctxt ;
68
169
struct kvm_cpu_context * host_ctxt ;
170
+ u64 mpidr ;
69
171
70
172
host_ctxt = host_data_ptr (host_ctxt );
71
173
__sysreg_save_user_state (host_ctxt );
@@ -89,7 +191,29 @@ void __vcpu_load_switch_sysregs(struct kvm_vcpu *vcpu)
89
191
*/
90
192
__sysreg32_restore_state (vcpu );
91
193
__sysreg_restore_user_state (guest_ctxt );
92
- __sysreg_restore_el1_state (guest_ctxt );
194
+
195
+ if (unlikely (__is_hyp_ctxt (guest_ctxt ))) {
196
+ __sysreg_restore_vel2_state (vcpu );
197
+ } else {
198
+ if (vcpu_has_nv (vcpu )) {
199
+ /*
200
+ * Use the guest hypervisor's VPIDR_EL2 when in a
201
+ * nested state. The hardware value of MIDR_EL1 gets
202
+ * restored on put.
203
+ */
204
+ write_sysreg (ctxt_sys_reg (guest_ctxt , VPIDR_EL2 ), vpidr_el2 );
205
+
206
+ /*
207
+ * As we're restoring a nested guest, set the value
208
+ * provided by the guest hypervisor.
209
+ */
210
+ mpidr = ctxt_sys_reg (guest_ctxt , VMPIDR_EL2 );
211
+ } else {
212
+ mpidr = ctxt_sys_reg (guest_ctxt , MPIDR_EL1 );
213
+ }
214
+
215
+ __sysreg_restore_el1_state (guest_ctxt , mpidr );
216
+ }
93
217
94
218
vcpu_set_flag (vcpu , SYSREGS_ON_CPU );
95
219
}
@@ -112,12 +236,20 @@ void __vcpu_put_switch_sysregs(struct kvm_vcpu *vcpu)
112
236
113
237
host_ctxt = host_data_ptr (host_ctxt );
114
238
115
- __sysreg_save_el1_state (guest_ctxt );
239
+ if (unlikely (__is_hyp_ctxt (guest_ctxt )))
240
+ __sysreg_save_vel2_state (vcpu );
241
+ else
242
+ __sysreg_save_el1_state (guest_ctxt );
243
+
116
244
__sysreg_save_user_state (guest_ctxt );
117
245
__sysreg32_save_state (vcpu );
118
246
119
247
/* Restore host user state */
120
248
__sysreg_restore_user_state (host_ctxt );
121
249
250
+ /* If leaving a nesting guest, restore MIDR_EL1 default view */
251
+ if (vcpu_has_nv (vcpu ))
252
+ write_sysreg (read_cpuid_id (), vpidr_el2 );
253
+
122
254
vcpu_clear_flag (vcpu , SYSREGS_ON_CPU );
123
255
}
0 commit comments