aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/book3s_64_slb.S
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2010-01-07 20:58:03 -0500
committerMarcelo Tosatti <mtosatti@redhat.com>2010-03-01 10:35:48 -0500
commit7e57cba06074da84d7c24d8c3f44040d2d8c88ac (patch)
treee99519ca301b887de4d689421e7a954f1c7792e4 /arch/powerpc/kvm/book3s_64_slb.S
parent992b5b29b5ae254c416c62faf98d59a6cf970027 (diff)
KVM: PPC: Use PACA backed shadow vcpu
We're being horribly racy right now. All the entry and exit code hijacks random fields from the PACA that could easily be used by different code in case we get interrupted, for example by a #MC or even page fault. After discussing this with Ben, we figured it's best to reserve some more space in the PACA and just shove off some vcpu state to there. That way we can drastically improve the readability of the code, make it less racy and less complex. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/powerpc/kvm/book3s_64_slb.S')
-rw-r--r--arch/powerpc/kvm/book3s_64_slb.S150
1 files changed, 90 insertions, 60 deletions
diff --git a/arch/powerpc/kvm/book3s_64_slb.S b/arch/powerpc/kvm/book3s_64_slb.S
index 8e4478866669..7188c11ed7d1 100644
--- a/arch/powerpc/kvm/book3s_64_slb.S
+++ b/arch/powerpc/kvm/book3s_64_slb.S
@@ -51,24 +51,18 @@ 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
71
72 /* Remove LPAR shadow entries */ 66 /* Remove LPAR shadow entries */
73 67
74#if SLB_NUM_BOLTED == 3 68#if SLB_NUM_BOLTED == 3
@@ -131,20 +125,27 @@ slb_do_enter:
131 125
132 /* Enter guest */ 126 /* Enter guest */
133 127
134 mfspr r0, SPRN_SPRG_SCRATCH0 128 ld r0, (PACA_KVM_R0)(r13)
135 129 ld r1, (PACA_KVM_R1)(r13)
136 ld r9, (PACA_EXMC+EX_R9)(r13) 130 ld r2, (PACA_KVM_R2)(r13)
137 ld r10, (PACA_EXMC+EX_R10)(r13) 131 ld r3, (PACA_KVM_R3)(r13)
138 ld r12, (PACA_EXMC+EX_R12)(r13) 132 ld r4, (PACA_KVM_R4)(r13)
139 133 ld r5, (PACA_KVM_R5)(r13)
140 lwz r11, (PACA_EXMC+EX_CCR)(r13) 134 ld r6, (PACA_KVM_R6)(r13)
135 ld r7, (PACA_KVM_R7)(r13)
136 ld r8, (PACA_KVM_R8)(r13)
137 ld r9, (PACA_KVM_R9)(r13)
138 ld r10, (PACA_KVM_R10)(r13)
139 ld r12, (PACA_KVM_R12)(r13)
140
141 lwz r11, (PACA_KVM_CR)(r13)
141 mtcr r11 142 mtcr r11
142 143
143 ld r11, (PACA_EXMC+EX_R3)(r13) 144 ld r11, (PACA_KVM_XER)(r13)
144 mtxer r11 145 mtxer r11
145 146
146 ld r11, (PACA_EXMC+EX_R11)(r13) 147 ld r11, (PACA_KVM_R11)(r13)
147 ld r13, (PACA_EXMC+EX_R13)(r13) 148 ld r13, (PACA_KVM_R13)(r13)
148 149
149 RFI 150 RFI
150kvmppc_handler_trampoline_enter_end: 151kvmppc_handler_trampoline_enter_end:
@@ -162,28 +163,58 @@ kvmppc_handler_trampoline_exit:
162 163
163 /* Register usage at this point: 164 /* Register usage at this point:
164 * 165 *
165 * SPRG_SCRATCH0 = guest R13 166 * SPRG_SCRATCH0 = guest R13
166 * R01 = host R1 167 * R12 = exit handler id
167 * R02 = host R2 168 * R13 = PACA
168 * R10 = guest PC 169 * PACA.KVM.SCRATCH0 = guest R12
169 * R11 = guest MSR 170 * 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 * 171 *
179 */ 172 */
180 173
181 /* Save registers */ 174 /* Save registers */
182 175
183 std r0, (PACA_EXMC+EX_SRR0)(r13) 176 std r0, PACA_KVM_R0(r13)
184 std r9, (PACA_EXMC+EX_R3)(r13) 177 std r1, PACA_KVM_R1(r13)
185 std r10, (PACA_EXMC+EX_LR)(r13) 178 std r2, PACA_KVM_R2(r13)
186 std r11, (PACA_EXMC+EX_DAR)(r13) 179 std r3, PACA_KVM_R3(r13)
180 std r4, PACA_KVM_R4(r13)
181 std r5, PACA_KVM_R5(r13)
182 std r6, PACA_KVM_R6(r13)
183 std r7, PACA_KVM_R7(r13)
184 std r8, PACA_KVM_R8(r13)
185 std r9, PACA_KVM_R9(r13)
186 std r10, PACA_KVM_R10(r13)
187 std r11, PACA_KVM_R11(r13)
188
189 /* Restore R1/R2 so we can handle faults */
190 ld r1, PACA_KVM_HOST_R1(r13)
191 ld r2, PACA_KVM_HOST_R2(r13)
192
193 /* Save guest PC and MSR in GPRs */
194 mfsrr0 r3
195 mfsrr1 r4
196
197 /* Get scratch'ed off registers */
198 mfspr r9, SPRN_SPRG_SCRATCH0
199 std r9, PACA_KVM_R13(r13)
200
201 ld r8, PACA_KVM_SCRATCH0(r13)
202 std r8, PACA_KVM_R12(r13)
203
204 lwz r7, PACA_KVM_SCRATCH1(r13)
205 stw r7, PACA_KVM_CR(r13)
206
207 /* Save more register state */
208
209 mfxer r6
210 stw r6, PACA_KVM_XER(r13)
211
212 mfdar r5
213 mfdsisr r6
214
215 /* Unset guest state */
216 li r9, 0
217 stb r9, PACA_KVM_IN_GUEST(r13)
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,
@@ -207,7 +238,8 @@ ld_last_inst:
207 ori r11, r9, MSR_DR /* Enable paging for data */ 238 ori r11, r9, MSR_DR /* Enable paging for data */
208 mtmsr r11 239 mtmsr r11
209 /* 2) fetch the instruction */ 240 /* 2) fetch the instruction */
210 lwz r0, 0(r10) 241 /* XXX implement PACA_KVM_IN_GUEST=2 path to safely jump over this */
242 lwz r0, 0(r3)
211 /* 3) disable paging again */ 243 /* 3) disable paging again */
212 mtmsr r9 244 mtmsr r9
213 245
@@ -233,29 +265,27 @@ no_ld_last_inst:
233 265
234slb_do_exit: 266slb_do_exit:
235 267
236 /* Restore registers */ 268 /* Register usage at this point:
237 269 *
238 ld r11, (PACA_EXMC+EX_DAR)(r13) 270 * R0 = guest last inst
239 ld r10, (PACA_EXMC+EX_LR)(r13) 271 * R1 = host R1
240 ld r9, (PACA_EXMC+EX_R3)(r13) 272 * R2 = host R2
241 273 * R3 = guest PC
242 /* Save last inst */ 274 * R4 = guest MSR
243 stw r0, (PACA_EXMC+EX_LR)(r13) 275 * R5 = guest DAR
244 276 * R6 = guest DSISR
245 /* Save DAR and DSISR before going to paged mode */ 277 * R12 = exit handler id
246 mfdar r0 278 * R13 = PACA
247 std r0, (PACA_EXMC+EX_DAR)(r13) 279 * PACA.KVM.* = guest *
248 mfdsisr r0 280 *
249 stw r0, (PACA_EXMC+EX_DSISR)(r13) 281 */
250 282
251 /* RFI into the highmem handler */ 283 /* RFI into the highmem handler */
252 mfmsr r0 284 mfmsr r7
253 ori r0, r0, MSR_IR|MSR_DR|MSR_RI /* Enable paging */ 285 ori r7, r7, MSR_IR|MSR_DR|MSR_RI /* Enable paging */
254 mtsrr1 r0 286 mtsrr1 r7
255 ld r0, PACASAVEDMSR(r13) /* Highmem handler address */ 287 ld r8, PACA_KVM_VMHANDLER(r13) /* Highmem handler address */
256 mtsrr0 r0 288 mtsrr0 r8
257
258 mfspr r0, SPRN_SPRG_SCRATCH0
259 289
260 RFI 290 RFI
261kvmppc_handler_trampoline_exit_end: 291kvmppc_handler_trampoline_exit_end: