GNU Linux-libre 4.14.290-gnu1
[releases.git] / arch / powerpc / kvm / bookehv_interrupts.S
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License, version 2, as
4  * published by the Free Software Foundation.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software
13  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
14  *
15  * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
16  *
17  * Author: Varun Sethi <varun.sethi@freescale.com>
18  * Author: Scott Wood <scotwood@freescale.com>
19  * Author: Mihai Caraman <mihai.caraman@freescale.com>
20  *
21  * This file is derived from arch/powerpc/kvm/booke_interrupts.S
22  */
23
24 #include <asm/ppc_asm.h>
25 #include <asm/kvm_asm.h>
26 #include <asm/reg.h>
27 #include <asm/page.h>
28 #include <asm/asm-compat.h>
29 #include <asm/asm-offsets.h>
30 #include <asm/bitsperlong.h>
31
32 #ifdef CONFIG_64BIT
33 #include <asm/exception-64e.h>
34 #include <asm/hw_irq.h>
35 #include <asm/irqflags.h>
36 #else
37 #include "../kernel/head_booke.h" /* for THREAD_NORMSAVE() */
38 #endif
39
40 #define LONGBYTES               (BITS_PER_LONG / 8)
41
42 #define VCPU_GUEST_SPRG(n)      (VCPU_GUEST_SPRGS + (n * LONGBYTES))
43
44 /* The host stack layout: */
45 #define HOST_R1         0 /* Implied by stwu. */
46 #define HOST_CALLEE_LR  PPC_LR_STKOFF
47 #define HOST_RUN        (HOST_CALLEE_LR + LONGBYTES)
48 /*
49  * r2 is special: it holds 'current', and it made nonvolatile in the
50  * kernel with the -ffixed-r2 gcc option.
51  */
52 #define HOST_R2         (HOST_RUN + LONGBYTES)
53 #define HOST_CR         (HOST_R2 + LONGBYTES)
54 #define HOST_NV_GPRS    (HOST_CR + LONGBYTES)
55 #define __HOST_NV_GPR(n)  (HOST_NV_GPRS + ((n - 14) * LONGBYTES))
56 #define HOST_NV_GPR(n)  __HOST_NV_GPR(__REG_##n)
57 #define HOST_MIN_STACK_SIZE (HOST_NV_GPR(R31) + LONGBYTES)
58 #define HOST_STACK_SIZE ((HOST_MIN_STACK_SIZE + 15) & ~15) /* Align. */
59 /* LR in caller stack frame. */
60 #define HOST_STACK_LR   (HOST_STACK_SIZE + PPC_LR_STKOFF)
61
62 #define NEED_EMU                0x00000001 /* emulation -- save nv regs */
63 #define NEED_DEAR               0x00000002 /* save faulting DEAR */
64 #define NEED_ESR                0x00000004 /* save faulting ESR */
65
66 /*
67  * On entry:
68  * r4 = vcpu, r5 = srr0, r6 = srr1
69  * saved in vcpu: cr, ctr, r3-r13
70  */
71 .macro kvm_handler_common intno, srr0, flags
72         /* Restore host stack pointer */
73         PPC_STL r1, VCPU_GPR(R1)(r4)
74         PPC_STL r2, VCPU_GPR(R2)(r4)
75         PPC_LL  r1, VCPU_HOST_STACK(r4)
76         PPC_LL  r2, HOST_R2(r1)
77
78 START_BTB_FLUSH_SECTION
79         BTB_FLUSH(r10)
80 END_BTB_FLUSH_SECTION
81
82         mfspr   r10, SPRN_PID
83         lwz     r8, VCPU_HOST_PID(r4)
84         PPC_LL  r11, VCPU_SHARED(r4)
85         PPC_STL r14, VCPU_GPR(R14)(r4) /* We need a non-volatile GPR. */
86         li      r14, \intno
87
88         stw     r10, VCPU_GUEST_PID(r4)
89         mtspr   SPRN_PID, r8
90
91 #ifdef CONFIG_KVM_EXIT_TIMING
92         /* save exit time */
93 1:      mfspr   r7, SPRN_TBRU
94         mfspr   r8, SPRN_TBRL
95         mfspr   r9, SPRN_TBRU
96         cmpw    r9, r7
97         stw     r8, VCPU_TIMING_EXIT_TBL(r4)
98         bne-    1b
99         stw     r9, VCPU_TIMING_EXIT_TBU(r4)
100 #endif
101
102         oris    r8, r6, MSR_CE@h
103         PPC_STD(r6, VCPU_SHARED_MSR, r11)
104         ori     r8, r8, MSR_ME | MSR_RI
105         PPC_STL r5, VCPU_PC(r4)
106
107         /*
108          * Make sure CE/ME/RI are set (if appropriate for exception type)
109          * whether or not the guest had it set.  Since mfmsr/mtmsr are
110          * somewhat expensive, skip in the common case where the guest
111          * had all these bits set (and thus they're still set if
112          * appropriate for the exception type).
113          */
114         cmpw    r6, r8
115         beq     1f
116         mfmsr   r7
117         .if     \srr0 != SPRN_MCSRR0 && \srr0 != SPRN_CSRR0
118         oris    r7, r7, MSR_CE@h
119         .endif
120         .if     \srr0 != SPRN_MCSRR0
121         ori     r7, r7, MSR_ME | MSR_RI
122         .endif
123         mtmsr   r7
124 1:
125
126         .if     \flags & NEED_EMU
127         PPC_STL r15, VCPU_GPR(R15)(r4)
128         PPC_STL r16, VCPU_GPR(R16)(r4)
129         PPC_STL r17, VCPU_GPR(R17)(r4)
130         PPC_STL r18, VCPU_GPR(R18)(r4)
131         PPC_STL r19, VCPU_GPR(R19)(r4)
132         PPC_STL r20, VCPU_GPR(R20)(r4)
133         PPC_STL r21, VCPU_GPR(R21)(r4)
134         PPC_STL r22, VCPU_GPR(R22)(r4)
135         PPC_STL r23, VCPU_GPR(R23)(r4)
136         PPC_STL r24, VCPU_GPR(R24)(r4)
137         PPC_STL r25, VCPU_GPR(R25)(r4)
138         PPC_STL r26, VCPU_GPR(R26)(r4)
139         PPC_STL r27, VCPU_GPR(R27)(r4)
140         PPC_STL r28, VCPU_GPR(R28)(r4)
141         PPC_STL r29, VCPU_GPR(R29)(r4)
142         PPC_STL r30, VCPU_GPR(R30)(r4)
143         PPC_STL r31, VCPU_GPR(R31)(r4)
144
145         /*
146          * We don't use external PID support. lwepx faults would need to be
147          * handled by KVM and this implies aditional code in DO_KVM (for
148          * DTB_MISS, DSI and LRAT) to check ESR[EPID] and EPLC[EGS] which
149          * is too intrusive for the host. Get last instuction in
150          * kvmppc_get_last_inst().
151          */
152         li      r9, KVM_INST_FETCH_FAILED
153         stw     r9, VCPU_LAST_INST(r4)
154         .endif
155
156         .if     \flags & NEED_ESR
157         mfspr   r8, SPRN_ESR
158         PPC_STL r8, VCPU_FAULT_ESR(r4)
159         .endif
160
161         .if     \flags & NEED_DEAR
162         mfspr   r9, SPRN_DEAR
163         PPC_STL r9, VCPU_FAULT_DEAR(r4)
164         .endif
165
166         b       kvmppc_resume_host
167 .endm
168
169 #ifdef CONFIG_64BIT
170 /* Exception types */
171 #define EX_GEN                  1
172 #define EX_GDBELL               2
173 #define EX_DBG                  3
174 #define EX_MC                   4
175 #define EX_CRIT                 5
176 #define EX_TLB                  6
177
178 /*
179  * For input register values, see arch/powerpc/include/asm/kvm_booke_hv_asm.h
180  */
181 .macro kvm_handler intno type scratch, paca_ex, ex_r10, ex_r11, srr0, srr1, flags
182  _GLOBAL(kvmppc_handler_\intno\()_\srr1)
183         mr      r11, r4
184         /*
185          * Get vcpu from Paca: paca->__current.thread->kvm_vcpu
186          */
187         PPC_LL  r4, PACACURRENT(r13)
188         PPC_LL  r4, (THREAD + THREAD_KVM_VCPU)(r4)
189         stw     r10, VCPU_CR(r4)
190         PPC_STL r11, VCPU_GPR(R4)(r4)
191         PPC_STL r5, VCPU_GPR(R5)(r4)
192         PPC_STL r6, VCPU_GPR(R6)(r4)
193         PPC_STL r8, VCPU_GPR(R8)(r4)
194         PPC_STL r9, VCPU_GPR(R9)(r4)
195         .if \type == EX_TLB
196         PPC_LL  r5, EX_TLB_R13(r12)
197         PPC_LL  r6, EX_TLB_R10(r12)
198         PPC_LL  r8, EX_TLB_R11(r12)
199         mfspr   r12, \scratch
200         .else
201         mfspr   r5, \scratch
202         PPC_LL  r6, (\paca_ex + \ex_r10)(r13)
203         PPC_LL  r8, (\paca_ex + \ex_r11)(r13)
204         .endif
205         PPC_STL r5, VCPU_GPR(R13)(r4)
206         PPC_STL r3, VCPU_GPR(R3)(r4)
207         PPC_STL r7, VCPU_GPR(R7)(r4)
208         PPC_STL r12, VCPU_GPR(R12)(r4)
209         PPC_STL r6, VCPU_GPR(R10)(r4)
210         PPC_STL r8, VCPU_GPR(R11)(r4)
211         mfctr   r5
212         PPC_STL r5, VCPU_CTR(r4)
213         mfspr   r5, \srr0
214         mfspr   r6, \srr1
215         kvm_handler_common \intno, \srr0, \flags
216 .endm
217
218 #define EX_PARAMS(type) \
219         EX_##type, \
220         SPRN_SPRG_##type##_SCRATCH, \
221         PACA_EX##type, \
222         EX_R10, \
223         EX_R11
224
225 #define EX_PARAMS_TLB \
226         EX_TLB, \
227         SPRN_SPRG_GEN_SCRATCH, \
228         PACA_EXTLB, \
229         EX_TLB_R10, \
230         EX_TLB_R11
231
232 kvm_handler BOOKE_INTERRUPT_CRITICAL, EX_PARAMS(CRIT), \
233         SPRN_CSRR0, SPRN_CSRR1, 0
234 kvm_handler BOOKE_INTERRUPT_MACHINE_CHECK, EX_PARAMS(MC), \
235         SPRN_MCSRR0, SPRN_MCSRR1, 0
236 kvm_handler BOOKE_INTERRUPT_DATA_STORAGE, EX_PARAMS(GEN), \
237         SPRN_SRR0, SPRN_SRR1,(NEED_EMU | NEED_DEAR | NEED_ESR)
238 kvm_handler BOOKE_INTERRUPT_INST_STORAGE, EX_PARAMS(GEN), \
239         SPRN_SRR0, SPRN_SRR1, NEED_ESR
240 kvm_handler BOOKE_INTERRUPT_EXTERNAL, EX_PARAMS(GEN), \
241         SPRN_SRR0, SPRN_SRR1, 0
242 kvm_handler BOOKE_INTERRUPT_ALIGNMENT, EX_PARAMS(GEN), \
243         SPRN_SRR0, SPRN_SRR1,(NEED_DEAR | NEED_ESR)
244 kvm_handler BOOKE_INTERRUPT_PROGRAM, EX_PARAMS(GEN), \
245         SPRN_SRR0, SPRN_SRR1, (NEED_ESR | NEED_EMU)
246 kvm_handler BOOKE_INTERRUPT_FP_UNAVAIL, EX_PARAMS(GEN), \
247         SPRN_SRR0, SPRN_SRR1, 0
248 kvm_handler BOOKE_INTERRUPT_AP_UNAVAIL, EX_PARAMS(GEN), \
249         SPRN_SRR0, SPRN_SRR1, 0
250 kvm_handler BOOKE_INTERRUPT_DECREMENTER, EX_PARAMS(GEN), \
251         SPRN_SRR0, SPRN_SRR1, 0
252 kvm_handler BOOKE_INTERRUPT_FIT, EX_PARAMS(GEN), \
253         SPRN_SRR0, SPRN_SRR1, 0
254 kvm_handler BOOKE_INTERRUPT_WATCHDOG, EX_PARAMS(CRIT),\
255         SPRN_CSRR0, SPRN_CSRR1, 0
256 /*
257  * Only bolted TLB miss exception handlers are supported for now
258  */
259 kvm_handler BOOKE_INTERRUPT_DTLB_MISS, EX_PARAMS_TLB, \
260         SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR | NEED_ESR)
261 kvm_handler BOOKE_INTERRUPT_ITLB_MISS, EX_PARAMS_TLB, \
262         SPRN_SRR0, SPRN_SRR1, 0
263 kvm_handler BOOKE_INTERRUPT_ALTIVEC_UNAVAIL, EX_PARAMS(GEN), \
264         SPRN_SRR0, SPRN_SRR1, 0
265 kvm_handler BOOKE_INTERRUPT_ALTIVEC_ASSIST, EX_PARAMS(GEN), \
266         SPRN_SRR0, SPRN_SRR1, 0
267 kvm_handler BOOKE_INTERRUPT_PERFORMANCE_MONITOR, EX_PARAMS(GEN), \
268         SPRN_SRR0, SPRN_SRR1, 0
269 kvm_handler BOOKE_INTERRUPT_DOORBELL, EX_PARAMS(GEN), \
270         SPRN_SRR0, SPRN_SRR1, 0
271 kvm_handler BOOKE_INTERRUPT_DOORBELL_CRITICAL, EX_PARAMS(CRIT), \
272         SPRN_CSRR0, SPRN_CSRR1, 0
273 kvm_handler BOOKE_INTERRUPT_HV_PRIV, EX_PARAMS(GEN), \
274         SPRN_SRR0, SPRN_SRR1, NEED_EMU
275 kvm_handler BOOKE_INTERRUPT_HV_SYSCALL, EX_PARAMS(GEN), \
276         SPRN_SRR0, SPRN_SRR1, 0
277 kvm_handler BOOKE_INTERRUPT_GUEST_DBELL, EX_PARAMS(GDBELL), \
278         SPRN_GSRR0, SPRN_GSRR1, 0
279 kvm_handler BOOKE_INTERRUPT_GUEST_DBELL_CRIT, EX_PARAMS(CRIT), \
280         SPRN_CSRR0, SPRN_CSRR1, 0
281 kvm_handler BOOKE_INTERRUPT_DEBUG, EX_PARAMS(DBG), \
282         SPRN_DSRR0, SPRN_DSRR1, 0
283 kvm_handler BOOKE_INTERRUPT_DEBUG, EX_PARAMS(CRIT), \
284         SPRN_CSRR0, SPRN_CSRR1, 0
285 kvm_handler BOOKE_INTERRUPT_LRAT_ERROR, EX_PARAMS(GEN), \
286         SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR | NEED_ESR)
287 #else
288 /*
289  * For input register values, see arch/powerpc/include/asm/kvm_booke_hv_asm.h
290  */
291 .macro kvm_handler intno srr0, srr1, flags
292 _GLOBAL(kvmppc_handler_\intno\()_\srr1)
293         PPC_LL  r11, THREAD_KVM_VCPU(r10)
294         PPC_STL r3, VCPU_GPR(R3)(r11)
295         mfspr   r3, SPRN_SPRG_RSCRATCH0
296         PPC_STL r4, VCPU_GPR(R4)(r11)
297         PPC_LL  r4, THREAD_NORMSAVE(0)(r10)
298         PPC_STL r5, VCPU_GPR(R5)(r11)
299         stw     r13, VCPU_CR(r11)
300         mfspr   r5, \srr0
301         PPC_STL r3, VCPU_GPR(R10)(r11)
302         PPC_LL  r3, THREAD_NORMSAVE(2)(r10)
303         PPC_STL r6, VCPU_GPR(R6)(r11)
304         PPC_STL r4, VCPU_GPR(R11)(r11)
305         mfspr   r6, \srr1
306         PPC_STL r7, VCPU_GPR(R7)(r11)
307         PPC_STL r8, VCPU_GPR(R8)(r11)
308         PPC_STL r9, VCPU_GPR(R9)(r11)
309         PPC_STL r3, VCPU_GPR(R13)(r11)
310         mfctr   r7
311         PPC_STL r12, VCPU_GPR(R12)(r11)
312         PPC_STL r7, VCPU_CTR(r11)
313         mr      r4, r11
314         kvm_handler_common \intno, \srr0, \flags
315 .endm
316
317 .macro kvm_lvl_handler intno scratch srr0, srr1, flags
318 _GLOBAL(kvmppc_handler_\intno\()_\srr1)
319         mfspr   r10, SPRN_SPRG_THREAD
320         PPC_LL  r11, THREAD_KVM_VCPU(r10)
321         PPC_STL r3, VCPU_GPR(R3)(r11)
322         mfspr   r3, \scratch
323         PPC_STL r4, VCPU_GPR(R4)(r11)
324         PPC_LL  r4, GPR9(r8)
325         PPC_STL r5, VCPU_GPR(R5)(r11)
326         stw     r9, VCPU_CR(r11)
327         mfspr   r5, \srr0
328         PPC_STL r3, VCPU_GPR(R8)(r11)
329         PPC_LL  r3, GPR10(r8)
330         PPC_STL r6, VCPU_GPR(R6)(r11)
331         PPC_STL r4, VCPU_GPR(R9)(r11)
332         mfspr   r6, \srr1
333         PPC_LL  r4, GPR11(r8)
334         PPC_STL r7, VCPU_GPR(R7)(r11)
335         PPC_STL r3, VCPU_GPR(R10)(r11)
336         mfctr   r7
337         PPC_STL r12, VCPU_GPR(R12)(r11)
338         PPC_STL r13, VCPU_GPR(R13)(r11)
339         PPC_STL r4, VCPU_GPR(R11)(r11)
340         PPC_STL r7, VCPU_CTR(r11)
341         mr      r4, r11
342         kvm_handler_common \intno, \srr0, \flags
343 .endm
344
345 kvm_lvl_handler BOOKE_INTERRUPT_CRITICAL, \
346         SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
347 kvm_lvl_handler BOOKE_INTERRUPT_MACHINE_CHECK, \
348         SPRN_SPRG_RSCRATCH_MC, SPRN_MCSRR0, SPRN_MCSRR1, 0
349 kvm_handler BOOKE_INTERRUPT_DATA_STORAGE, \
350         SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR | NEED_ESR)
351 kvm_handler BOOKE_INTERRUPT_INST_STORAGE, SPRN_SRR0, SPRN_SRR1, NEED_ESR
352 kvm_handler BOOKE_INTERRUPT_EXTERNAL, SPRN_SRR0, SPRN_SRR1, 0
353 kvm_handler BOOKE_INTERRUPT_ALIGNMENT, \
354         SPRN_SRR0, SPRN_SRR1, (NEED_DEAR | NEED_ESR)
355 kvm_handler BOOKE_INTERRUPT_PROGRAM, SPRN_SRR0, SPRN_SRR1, (NEED_ESR | NEED_EMU)
356 kvm_handler BOOKE_INTERRUPT_FP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0
357 kvm_handler BOOKE_INTERRUPT_SYSCALL, SPRN_SRR0, SPRN_SRR1, 0
358 kvm_handler BOOKE_INTERRUPT_AP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0
359 kvm_handler BOOKE_INTERRUPT_DECREMENTER, SPRN_SRR0, SPRN_SRR1, 0
360 kvm_handler BOOKE_INTERRUPT_FIT, SPRN_SRR0, SPRN_SRR1, 0
361 kvm_lvl_handler BOOKE_INTERRUPT_WATCHDOG, \
362         SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
363 kvm_handler BOOKE_INTERRUPT_DTLB_MISS, \
364         SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR | NEED_ESR)
365 kvm_handler BOOKE_INTERRUPT_ITLB_MISS, SPRN_SRR0, SPRN_SRR1, 0
366 kvm_handler BOOKE_INTERRUPT_PERFORMANCE_MONITOR, SPRN_SRR0, SPRN_SRR1, 0
367 kvm_handler BOOKE_INTERRUPT_DOORBELL, SPRN_SRR0, SPRN_SRR1, 0
368 kvm_lvl_handler BOOKE_INTERRUPT_DOORBELL_CRITICAL, \
369         SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
370 kvm_handler BOOKE_INTERRUPT_HV_PRIV, SPRN_SRR0, SPRN_SRR1, NEED_EMU
371 kvm_handler BOOKE_INTERRUPT_HV_SYSCALL, SPRN_SRR0, SPRN_SRR1, 0
372 kvm_handler BOOKE_INTERRUPT_GUEST_DBELL, SPRN_GSRR0, SPRN_GSRR1, 0
373 kvm_lvl_handler BOOKE_INTERRUPT_GUEST_DBELL_CRIT, \
374         SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
375 kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \
376         SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
377 kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \
378         SPRN_SPRG_RSCRATCH_DBG, SPRN_DSRR0, SPRN_DSRR1, 0
379 #endif
380
381 /* Registers:
382  *  SPRG_SCRATCH0: guest r10
383  *  r4: vcpu pointer
384  *  r11: vcpu->arch.shared
385  *  r14: KVM exit number
386  */
387 _GLOBAL(kvmppc_resume_host)
388         /* Save remaining volatile guest register state to vcpu. */
389         mfspr   r3, SPRN_VRSAVE
390         PPC_STL r0, VCPU_GPR(R0)(r4)
391         mflr    r5
392         mfspr   r6, SPRN_SPRG4
393         PPC_STL r5, VCPU_LR(r4)
394         mfspr   r7, SPRN_SPRG5
395         stw     r3, VCPU_VRSAVE(r4)
396 #ifdef CONFIG_64BIT
397         PPC_LL  r3, PACA_SPRG_VDSO(r13)
398 #endif
399         mfspr   r5, SPRN_SPRG9
400         PPC_STD(r6, VCPU_SHARED_SPRG4, r11)
401         mfspr   r8, SPRN_SPRG6
402         PPC_STD(r7, VCPU_SHARED_SPRG5, r11)
403         mfspr   r9, SPRN_SPRG7
404 #ifdef CONFIG_64BIT
405         mtspr   SPRN_SPRG_VDSO_WRITE, r3
406 #endif
407         PPC_STD(r5, VCPU_SPRG9, r4)
408         PPC_STD(r8, VCPU_SHARED_SPRG6, r11)
409         mfxer   r3
410         PPC_STD(r9, VCPU_SHARED_SPRG7, r11)
411
412         /* save guest MAS registers and restore host mas4 & mas6 */
413         mfspr   r5, SPRN_MAS0
414         PPC_STL r3, VCPU_XER(r4)
415         mfspr   r6, SPRN_MAS1
416         stw     r5, VCPU_SHARED_MAS0(r11)
417         mfspr   r7, SPRN_MAS2
418         stw     r6, VCPU_SHARED_MAS1(r11)
419         PPC_STD(r7, VCPU_SHARED_MAS2, r11)
420         mfspr   r5, SPRN_MAS3
421         mfspr   r6, SPRN_MAS4
422         stw     r5, VCPU_SHARED_MAS7_3+4(r11)
423         mfspr   r7, SPRN_MAS6
424         stw     r6, VCPU_SHARED_MAS4(r11)
425         mfspr   r5, SPRN_MAS7
426         lwz     r6, VCPU_HOST_MAS4(r4)
427         stw     r7, VCPU_SHARED_MAS6(r11)
428         lwz     r8, VCPU_HOST_MAS6(r4)
429         mtspr   SPRN_MAS4, r6
430         stw     r5, VCPU_SHARED_MAS7_3+0(r11)
431         mtspr   SPRN_MAS6, r8
432         /* Enable MAS register updates via exception */
433         mfspr   r3, SPRN_EPCR
434         rlwinm  r3, r3, 0, ~SPRN_EPCR_DMIUH
435         mtspr   SPRN_EPCR, r3
436         isync
437
438 #ifdef CONFIG_64BIT
439         /*
440          * We enter with interrupts disabled in hardware, but
441          * we need to call RECONCILE_IRQ_STATE to ensure
442          * that the software state is kept in sync.
443          */
444         RECONCILE_IRQ_STATE(r3,r5)
445 #endif
446
447         /* Switch to kernel stack and jump to handler. */
448         PPC_LL  r3, HOST_RUN(r1)
449         mr      r5, r14 /* intno */
450         mr      r14, r4 /* Save vcpu pointer. */
451         bl      kvmppc_handle_exit
452
453         /* Restore vcpu pointer and the nonvolatiles we used. */
454         mr      r4, r14
455         PPC_LL  r14, VCPU_GPR(R14)(r4)
456
457         andi.   r5, r3, RESUME_FLAG_NV
458         beq     skip_nv_load
459         PPC_LL  r15, VCPU_GPR(R15)(r4)
460         PPC_LL  r16, VCPU_GPR(R16)(r4)
461         PPC_LL  r17, VCPU_GPR(R17)(r4)
462         PPC_LL  r18, VCPU_GPR(R18)(r4)
463         PPC_LL  r19, VCPU_GPR(R19)(r4)
464         PPC_LL  r20, VCPU_GPR(R20)(r4)
465         PPC_LL  r21, VCPU_GPR(R21)(r4)
466         PPC_LL  r22, VCPU_GPR(R22)(r4)
467         PPC_LL  r23, VCPU_GPR(R23)(r4)
468         PPC_LL  r24, VCPU_GPR(R24)(r4)
469         PPC_LL  r25, VCPU_GPR(R25)(r4)
470         PPC_LL  r26, VCPU_GPR(R26)(r4)
471         PPC_LL  r27, VCPU_GPR(R27)(r4)
472         PPC_LL  r28, VCPU_GPR(R28)(r4)
473         PPC_LL  r29, VCPU_GPR(R29)(r4)
474         PPC_LL  r30, VCPU_GPR(R30)(r4)
475         PPC_LL  r31, VCPU_GPR(R31)(r4)
476 skip_nv_load:
477         /* Should we return to the guest? */
478         andi.   r5, r3, RESUME_FLAG_HOST
479         beq     lightweight_exit
480
481         srawi   r3, r3, 2 /* Shift -ERR back down. */
482
483 heavyweight_exit:
484         /* Not returning to guest. */
485         PPC_LL  r5, HOST_STACK_LR(r1)
486         lwz     r6, HOST_CR(r1)
487
488         /*
489          * We already saved guest volatile register state; now save the
490          * non-volatiles.
491          */
492
493         PPC_STL r15, VCPU_GPR(R15)(r4)
494         PPC_STL r16, VCPU_GPR(R16)(r4)
495         PPC_STL r17, VCPU_GPR(R17)(r4)
496         PPC_STL r18, VCPU_GPR(R18)(r4)
497         PPC_STL r19, VCPU_GPR(R19)(r4)
498         PPC_STL r20, VCPU_GPR(R20)(r4)
499         PPC_STL r21, VCPU_GPR(R21)(r4)
500         PPC_STL r22, VCPU_GPR(R22)(r4)
501         PPC_STL r23, VCPU_GPR(R23)(r4)
502         PPC_STL r24, VCPU_GPR(R24)(r4)
503         PPC_STL r25, VCPU_GPR(R25)(r4)
504         PPC_STL r26, VCPU_GPR(R26)(r4)
505         PPC_STL r27, VCPU_GPR(R27)(r4)
506         PPC_STL r28, VCPU_GPR(R28)(r4)
507         PPC_STL r29, VCPU_GPR(R29)(r4)
508         PPC_STL r30, VCPU_GPR(R30)(r4)
509         PPC_STL r31, VCPU_GPR(R31)(r4)
510
511         /* Load host non-volatile register state from host stack. */
512         PPC_LL  r14, HOST_NV_GPR(R14)(r1)
513         PPC_LL  r15, HOST_NV_GPR(R15)(r1)
514         PPC_LL  r16, HOST_NV_GPR(R16)(r1)
515         PPC_LL  r17, HOST_NV_GPR(R17)(r1)
516         PPC_LL  r18, HOST_NV_GPR(R18)(r1)
517         PPC_LL  r19, HOST_NV_GPR(R19)(r1)
518         PPC_LL  r20, HOST_NV_GPR(R20)(r1)
519         PPC_LL  r21, HOST_NV_GPR(R21)(r1)
520         PPC_LL  r22, HOST_NV_GPR(R22)(r1)
521         PPC_LL  r23, HOST_NV_GPR(R23)(r1)
522         PPC_LL  r24, HOST_NV_GPR(R24)(r1)
523         PPC_LL  r25, HOST_NV_GPR(R25)(r1)
524         PPC_LL  r26, HOST_NV_GPR(R26)(r1)
525         PPC_LL  r27, HOST_NV_GPR(R27)(r1)
526         PPC_LL  r28, HOST_NV_GPR(R28)(r1)
527         PPC_LL  r29, HOST_NV_GPR(R29)(r1)
528         PPC_LL  r30, HOST_NV_GPR(R30)(r1)
529         PPC_LL  r31, HOST_NV_GPR(R31)(r1)
530
531         /* Return to kvm_vcpu_run(). */
532         mtlr    r5
533         mtcr    r6
534         addi    r1, r1, HOST_STACK_SIZE
535         /* r3 still contains the return code from kvmppc_handle_exit(). */
536         blr
537
538 /* Registers:
539  *  r3: kvm_run pointer
540  *  r4: vcpu pointer
541  */
542 _GLOBAL(__kvmppc_vcpu_run)
543         stwu    r1, -HOST_STACK_SIZE(r1)
544         PPC_STL r1, VCPU_HOST_STACK(r4) /* Save stack pointer to vcpu. */
545
546         /* Save host state to stack. */
547         PPC_STL r3, HOST_RUN(r1)
548         mflr    r3
549         mfcr    r5
550         PPC_STL r3, HOST_STACK_LR(r1)
551
552         stw     r5, HOST_CR(r1)
553
554         /* Save host non-volatile register state to stack. */
555         PPC_STL r14, HOST_NV_GPR(R14)(r1)
556         PPC_STL r15, HOST_NV_GPR(R15)(r1)
557         PPC_STL r16, HOST_NV_GPR(R16)(r1)
558         PPC_STL r17, HOST_NV_GPR(R17)(r1)
559         PPC_STL r18, HOST_NV_GPR(R18)(r1)
560         PPC_STL r19, HOST_NV_GPR(R19)(r1)
561         PPC_STL r20, HOST_NV_GPR(R20)(r1)
562         PPC_STL r21, HOST_NV_GPR(R21)(r1)
563         PPC_STL r22, HOST_NV_GPR(R22)(r1)
564         PPC_STL r23, HOST_NV_GPR(R23)(r1)
565         PPC_STL r24, HOST_NV_GPR(R24)(r1)
566         PPC_STL r25, HOST_NV_GPR(R25)(r1)
567         PPC_STL r26, HOST_NV_GPR(R26)(r1)
568         PPC_STL r27, HOST_NV_GPR(R27)(r1)
569         PPC_STL r28, HOST_NV_GPR(R28)(r1)
570         PPC_STL r29, HOST_NV_GPR(R29)(r1)
571         PPC_STL r30, HOST_NV_GPR(R30)(r1)
572         PPC_STL r31, HOST_NV_GPR(R31)(r1)
573
574         /* Load guest non-volatiles. */
575         PPC_LL  r14, VCPU_GPR(R14)(r4)
576         PPC_LL  r15, VCPU_GPR(R15)(r4)
577         PPC_LL  r16, VCPU_GPR(R16)(r4)
578         PPC_LL  r17, VCPU_GPR(R17)(r4)
579         PPC_LL  r18, VCPU_GPR(R18)(r4)
580         PPC_LL  r19, VCPU_GPR(R19)(r4)
581         PPC_LL  r20, VCPU_GPR(R20)(r4)
582         PPC_LL  r21, VCPU_GPR(R21)(r4)
583         PPC_LL  r22, VCPU_GPR(R22)(r4)
584         PPC_LL  r23, VCPU_GPR(R23)(r4)
585         PPC_LL  r24, VCPU_GPR(R24)(r4)
586         PPC_LL  r25, VCPU_GPR(R25)(r4)
587         PPC_LL  r26, VCPU_GPR(R26)(r4)
588         PPC_LL  r27, VCPU_GPR(R27)(r4)
589         PPC_LL  r28, VCPU_GPR(R28)(r4)
590         PPC_LL  r29, VCPU_GPR(R29)(r4)
591         PPC_LL  r30, VCPU_GPR(R30)(r4)
592         PPC_LL  r31, VCPU_GPR(R31)(r4)
593
594
595 lightweight_exit:
596         PPC_STL r2, HOST_R2(r1)
597
598         mfspr   r3, SPRN_PID
599         stw     r3, VCPU_HOST_PID(r4)
600         lwz     r3, VCPU_GUEST_PID(r4)
601         mtspr   SPRN_PID, r3
602
603         PPC_LL  r11, VCPU_SHARED(r4)
604         /* Disable MAS register updates via exception */
605         mfspr   r3, SPRN_EPCR
606         oris    r3, r3, SPRN_EPCR_DMIUH@h
607         mtspr   SPRN_EPCR, r3
608         isync
609         /* Save host mas4 and mas6 and load guest MAS registers */
610         mfspr   r3, SPRN_MAS4
611         stw     r3, VCPU_HOST_MAS4(r4)
612         mfspr   r3, SPRN_MAS6
613         stw     r3, VCPU_HOST_MAS6(r4)
614         lwz     r3, VCPU_SHARED_MAS0(r11)
615         lwz     r5, VCPU_SHARED_MAS1(r11)
616         PPC_LD(r6, VCPU_SHARED_MAS2, r11)
617         lwz     r7, VCPU_SHARED_MAS7_3+4(r11)
618         lwz     r8, VCPU_SHARED_MAS4(r11)
619         mtspr   SPRN_MAS0, r3
620         mtspr   SPRN_MAS1, r5
621         mtspr   SPRN_MAS2, r6
622         mtspr   SPRN_MAS3, r7
623         mtspr   SPRN_MAS4, r8
624         lwz     r3, VCPU_SHARED_MAS6(r11)
625         lwz     r5, VCPU_SHARED_MAS7_3+0(r11)
626         mtspr   SPRN_MAS6, r3
627         mtspr   SPRN_MAS7, r5
628
629         /*
630          * Host interrupt handlers may have clobbered these guest-readable
631          * SPRGs, so we need to reload them here with the guest's values.
632          */
633         lwz     r3, VCPU_VRSAVE(r4)
634         PPC_LD(r5, VCPU_SHARED_SPRG4, r11)
635         mtspr   SPRN_VRSAVE, r3
636         PPC_LD(r6, VCPU_SHARED_SPRG5, r11)
637         mtspr   SPRN_SPRG4W, r5
638         PPC_LD(r7, VCPU_SHARED_SPRG6, r11)
639         mtspr   SPRN_SPRG5W, r6
640         PPC_LD(r8, VCPU_SHARED_SPRG7, r11)
641         mtspr   SPRN_SPRG6W, r7
642         PPC_LD(r5, VCPU_SPRG9, r4)
643         mtspr   SPRN_SPRG7W, r8
644         mtspr   SPRN_SPRG9, r5
645
646         /* Load some guest volatiles. */
647         PPC_LL  r3, VCPU_LR(r4)
648         PPC_LL  r5, VCPU_XER(r4)
649         PPC_LL  r6, VCPU_CTR(r4)
650         lwz     r7, VCPU_CR(r4)
651         PPC_LL  r8, VCPU_PC(r4)
652         PPC_LD(r9, VCPU_SHARED_MSR, r11)
653         PPC_LL  r0, VCPU_GPR(R0)(r4)
654         PPC_LL  r1, VCPU_GPR(R1)(r4)
655         PPC_LL  r2, VCPU_GPR(R2)(r4)
656         PPC_LL  r10, VCPU_GPR(R10)(r4)
657         PPC_LL  r11, VCPU_GPR(R11)(r4)
658         PPC_LL  r12, VCPU_GPR(R12)(r4)
659         PPC_LL  r13, VCPU_GPR(R13)(r4)
660         mtlr    r3
661         mtxer   r5
662         mtctr   r6
663         mtsrr0  r8
664         mtsrr1  r9
665
666 #ifdef CONFIG_KVM_EXIT_TIMING
667         /* save enter time */
668 1:
669         mfspr   r6, SPRN_TBRU
670         mfspr   r9, SPRN_TBRL
671         mfspr   r8, SPRN_TBRU
672         cmpw    r8, r6
673         stw     r9, VCPU_TIMING_LAST_ENTER_TBL(r4)
674         bne     1b
675         stw     r8, VCPU_TIMING_LAST_ENTER_TBU(r4)
676 #endif
677
678         /*
679          * Don't execute any instruction which can change CR after
680          * below instruction.
681          */
682         mtcr    r7
683
684         /* Finish loading guest volatiles and jump to guest. */
685         PPC_LL  r5, VCPU_GPR(R5)(r4)
686         PPC_LL  r6, VCPU_GPR(R6)(r4)
687         PPC_LL  r7, VCPU_GPR(R7)(r4)
688         PPC_LL  r8, VCPU_GPR(R8)(r4)
689         PPC_LL  r9, VCPU_GPR(R9)(r4)
690
691         PPC_LL  r3, VCPU_GPR(R3)(r4)
692         PPC_LL  r4, VCPU_GPR(R4)(r4)
693         rfi