aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/book3s_64_slb.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm/book3s_64_slb.S')
-rw-r--r--arch/powerpc/kvm/book3s_64_slb.S160
1 files changed, 100 insertions, 60 deletions
diff --git a/arch/powerpc/kvm/book3s_64_slb.S b/arch/powerpc/kvm/book3s_64_slb.S
index ecd237a03fd..35b76272218 100644
--- a/arch/powerpc/kvm/book3s_64_slb.S
+++ b/arch/powerpc/kvm/book3s_64_slb.S
@@ -31,7 +31,7 @@
31#define REBOLT_SLB_ENTRY(num) \ 31#define REBOLT_SLB_ENTRY(num) \
32 ld r10, SHADOW_SLB_ESID(num)(r11); \ 32 ld r10, SHADOW_SLB_ESID(num)(r11); \
33 cmpdi r10, 0; \ 33 cmpdi r10, 0; \
34 beq slb_exit_skip_1; \ 34 beq slb_exit_skip_ ## num; \
35 oris r10, r10, SLB_ESID_V@h; \ 35 oris r10, r10, SLB_ESID_V@h; \
36 ld r9, SHADOW_SLB_VSID(num)(r11); \ 36 ld r9, SHADOW_SLB_VSID(num)(r11); \
37 slbmte r9, r10; \ 37 slbmte r9, r10; \
@@ -51,23 +51,21 @@ kvmppc_handler_trampoline_enter:
51 * 51 *
52 * MSR = ~IR|DR 52 * MSR = ~IR|DR
53 * R13 = PACA 53 * R13 = PACA
54 * R1 = host R1
55 * R2 = host R2
54 * R9 = guest IP 56 * R9 = guest IP
55 * R10 = guest MSR 57 * R10 = guest MSR
56 * R11 = free 58 * all other GPRS = free
57 * R12 = free 59 * PACA[KVM_CR] = guest CR
58 * PACA[PACA_EXMC + EX_R9] = guest R9 60 * PACA[KVM_XER] = guest XER
59 * PACA[PACA_EXMC + EX_R10] = guest R10
60 * PACA[PACA_EXMC + EX_R11] = guest R11
61 * PACA[PACA_EXMC + EX_R12] = guest R12
62 * PACA[PACA_EXMC + EX_R13] = guest R13
63 * PACA[PACA_EXMC + EX_CCR] = guest CR
64 * PACA[PACA_EXMC + EX_R3] = guest XER
65 */ 61 */
66 62
67 mtsrr0 r9 63 mtsrr0 r9
68 mtsrr1 r10 64 mtsrr1 r10
69 65
70 mtspr SPRN_SPRG_SCRATCH0, r0 66 /* Activate guest mode, so faults get handled by KVM */
67 li r11, KVM_GUEST_MODE_GUEST
68 stb r11, PACA_KVM_IN_GUEST(r13)
71 69
72 /* Remove LPAR shadow entries */ 70 /* Remove LPAR shadow entries */
73 71
@@ -131,20 +129,27 @@ slb_do_enter:
131 129
132 /* Enter guest */ 130 /* Enter guest */
133 131
134 mfspr r0, SPRN_SPRG_SCRATCH0 132 ld r0, (PACA_KVM_R0)(r13)
135 133 ld r1, (PACA_KVM_R1)(r13)
136 ld r9, (PACA_EXMC+EX_R9)(r13) 134 ld r2, (PACA_KVM_R2)(r13)
137 ld r10, (PACA_EXMC+EX_R10)(r13) 135 ld r3, (PACA_KVM_R3)(r13)
138 ld r12, (PACA_EXMC+EX_R12)(r13) 136 ld r4, (PACA_KVM_R4)(r13)
139 137 ld r5, (PACA_KVM_R5)(r13)
140 lwz r11, (PACA_EXMC+EX_CCR)(r13) 138 ld r6, (PACA_KVM_R6)(r13)
139 ld r7, (PACA_KVM_R7)(r13)
140 ld r8, (PACA_KVM_R8)(r13)
141 ld r9, (PACA_KVM_R9)(r13)
142 ld r10, (PACA_KVM_R10)(r13)
143 ld r12, (PACA_KVM_R12)(r13)
144
145 lwz r11, (PACA_KVM_CR)(r13)
141 mtcr r11 146 mtcr r11
142 147
143 ld r11, (PACA_EXMC+EX_R3)(r13) 148 ld r11, (PACA_KVM_XER)(r13)
144 mtxer r11 149 mtxer r11
145 150
146 ld r11, (PACA_EXMC+EX_R11)(r13) 151 ld r11, (PACA_KVM_R11)(r13)
147 ld r13, (PACA_EXMC+EX_R13)(r13) 152 ld r13, (PACA_KVM_R13)(r13)
148 153
149 RFI 154 RFI
150kvmppc_handler_trampoline_enter_end: 155kvmppc_handler_trampoline_enter_end:
@@ -162,28 +167,54 @@ kvmppc_handler_trampoline_exit:
162 167
163 /* Register usage at this point: 168 /* Register usage at this point:
164 * 169 *
165 * SPRG_SCRATCH0 = guest R13 170 * SPRG_SCRATCH0 = guest R13
166 * R01 = host R1 171 * R12 = exit handler id
167 * R02 = host R2 172 * R13 = PACA
168 * R10 = guest PC 173 * PACA.KVM.SCRATCH0 = guest R12
169 * R11 = guest MSR 174 * PACA.KVM.SCRATCH1 = guest CR
170 * R12 = exit handler id
171 * R13 = PACA
172 * PACA.exmc.CCR = guest CR
173 * PACA.exmc.R9 = guest R1
174 * PACA.exmc.R10 = guest R10
175 * PACA.exmc.R11 = guest R11
176 * PACA.exmc.R12 = guest R12
177 * PACA.exmc.R13 = guest R2
178 * 175 *
179 */ 176 */
180 177
181 /* Save registers */ 178 /* Save registers */
182 179
183 std r0, (PACA_EXMC+EX_SRR0)(r13) 180 std r0, PACA_KVM_R0(r13)
184 std r9, (PACA_EXMC+EX_R3)(r13) 181 std r1, PACA_KVM_R1(r13)
185 std r10, (PACA_EXMC+EX_LR)(r13) 182 std r2, PACA_KVM_R2(r13)
186 std r11, (PACA_EXMC+EX_DAR)(r13) 183 std r3, PACA_KVM_R3(r13)
184 std r4, PACA_KVM_R4(r13)
185 std r5, PACA_KVM_R5(r13)
186 std r6, PACA_KVM_R6(r13)
187 std r7, PACA_KVM_R7(r13)
188 std r8, PACA_KVM_R8(r13)
189 std r9, PACA_KVM_R9(r13)
190 std r10, PACA_KVM_R10(r13)
191 std r11, PACA_KVM_R11(r13)
192
193 /* Restore R1/R2 so we can handle faults */
194 ld r1, PACA_KVM_HOST_R1(r13)
195 ld r2, PACA_KVM_HOST_R2(r13)
196
197 /* Save guest PC and MSR in GPRs */
198 mfsrr0 r3
199 mfsrr1 r4
200
201 /* Get scratch'ed off registers */
202 mfspr r9, SPRN_SPRG_SCRATCH0
203 std r9, PACA_KVM_R13(r13)
204
205 ld r8, PACA_KVM_SCRATCH0(r13)
206 std r8, PACA_KVM_R12(r13)
207
208 lwz r7, PACA_KVM_SCRATCH1(r13)
209 stw r7, PACA_KVM_CR(r13)
210
211 /* Save more register state */
212
213 mfxer r6
214 stw r6, PACA_KVM_XER(r13)
215
216 mfdar r5
217 mfdsisr r6
187 218
188 /* 219 /*
189 * In order for us to easily get the last instruction, 220 * In order for us to easily get the last instruction,
@@ -202,17 +233,28 @@ kvmppc_handler_trampoline_exit:
202 233
203ld_last_inst: 234ld_last_inst:
204 /* Save off the guest instruction we're at */ 235 /* Save off the guest instruction we're at */
236
237 /* Set guest mode to 'jump over instruction' so if lwz faults
238 * we'll just continue at the next IP. */
239 li r9, KVM_GUEST_MODE_SKIP
240 stb r9, PACA_KVM_IN_GUEST(r13)
241
205 /* 1) enable paging for data */ 242 /* 1) enable paging for data */
206 mfmsr r9 243 mfmsr r9
207 ori r11, r9, MSR_DR /* Enable paging for data */ 244 ori r11, r9, MSR_DR /* Enable paging for data */
208 mtmsr r11 245 mtmsr r11
209 /* 2) fetch the instruction */ 246 /* 2) fetch the instruction */
210 lwz r0, 0(r10) 247 li r0, KVM_INST_FETCH_FAILED /* In case lwz faults */
248 lwz r0, 0(r3)
211 /* 3) disable paging again */ 249 /* 3) disable paging again */
212 mtmsr r9 250 mtmsr r9
213 251
214no_ld_last_inst: 252no_ld_last_inst:
215 253
254 /* Unset guest mode */
255 li r9, KVM_GUEST_MODE_NONE
256 stb r9, PACA_KVM_IN_GUEST(r13)
257
216 /* Restore bolted entries from the shadow and fix it along the way */ 258 /* Restore bolted entries from the shadow and fix it along the way */
217 259
218 /* We don't store anything in entry 0, so we don't need to take care of it */ 260 /* We don't store anything in entry 0, so we don't need to take care of it */
@@ -233,29 +275,27 @@ no_ld_last_inst:
233 275
234slb_do_exit: 276slb_do_exit:
235 277
236 /* Restore registers */ 278 /* Register usage at this point:
237 279 *
238 ld r11, (PACA_EXMC+EX_DAR)(r13) 280 * R0 = guest last inst
239 ld r10, (PACA_EXMC+EX_LR)(r13) 281 * R1 = host R1
240 ld r9, (PACA_EXMC+EX_R3)(r13) 282 * R2 = host R2
241 283 * R3 = guest PC
242 /* Save last inst */ 284 * R4 = guest MSR
243 stw r0, (PACA_EXMC+EX_LR)(r13) 285 * R5 = guest DAR
244 286 * R6 = guest DSISR
245 /* Save DAR and DSISR before going to paged mode */ 287 * R12 = exit handler id
246 mfdar r0 288 * R13 = PACA
247 std r0, (PACA_EXMC+EX_DAR)(r13) 289 * PACA.KVM.* = guest *
248 mfdsisr r0 290 *
249 stw r0, (PACA_EXMC+EX_DSISR)(r13) 291 */
250 292
251 /* RFI into the highmem handler */ 293 /* RFI into the highmem handler */
252 mfmsr r0 294 mfmsr r7
253 ori r0, r0, MSR_IR|MSR_DR|MSR_RI /* Enable paging */ 295 ori r7, r7, MSR_IR|MSR_DR|MSR_RI /* Enable paging */
254 mtsrr1 r0 296 mtsrr1 r7
255 ld r0, PACASAVEDMSR(r13) /* Highmem handler address */ 297 ld r8, PACA_KVM_VMHANDLER(r13) /* Highmem handler address */
256 mtsrr0 r0 298 mtsrr0 r8
257
258 mfspr r0, SPRN_SPRG_SCRATCH0
259 299
260 RFI 300 RFI
261kvmppc_handler_trampoline_exit_end: 301kvmppc_handler_trampoline_exit_end: