cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

booke_interrupts.S (14589B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 *
      4 * Copyright IBM Corp. 2007
      5 * Copyright 2011 Freescale Semiconductor, Inc.
      6 *
      7 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
      8 */
      9
     10#include <asm/ppc_asm.h>
     11#include <asm/kvm_asm.h>
     12#include <asm/reg.h>
     13#include <asm/page.h>
     14#include <asm/asm-offsets.h>
     15
     16/* The host stack layout: */
     17#define HOST_R1         0 /* Implied by stwu. */
     18#define HOST_CALLEE_LR  4
     19#define HOST_RUN        8
     20/* r2 is special: it holds 'current', and it made nonvolatile in the
     21 * kernel with the -ffixed-r2 gcc option. */
     22#define HOST_R2         12
     23#define HOST_CR         16
     24#define HOST_NV_GPRS    20
     25#define __HOST_NV_GPR(n)  (HOST_NV_GPRS + ((n - 14) * 4))
     26#define HOST_NV_GPR(n)  __HOST_NV_GPR(__REG_##n)
     27#define HOST_MIN_STACK_SIZE (HOST_NV_GPR(R31) + 4)
     28#define HOST_STACK_SIZE (((HOST_MIN_STACK_SIZE + 15) / 16) * 16) /* Align. */
     29#define HOST_STACK_LR   (HOST_STACK_SIZE + 4) /* In caller stack frame. */
     30
     31#define NEED_INST_MASK ((1<<BOOKE_INTERRUPT_PROGRAM) | \
     32                        (1<<BOOKE_INTERRUPT_DTLB_MISS) | \
     33                        (1<<BOOKE_INTERRUPT_DEBUG))
     34
     35#define NEED_DEAR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \
     36                        (1<<BOOKE_INTERRUPT_DTLB_MISS) | \
     37                        (1<<BOOKE_INTERRUPT_ALIGNMENT))
     38
     39#define NEED_ESR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \
     40                       (1<<BOOKE_INTERRUPT_INST_STORAGE) | \
     41                       (1<<BOOKE_INTERRUPT_PROGRAM) | \
     42                       (1<<BOOKE_INTERRUPT_DTLB_MISS) | \
     43                       (1<<BOOKE_INTERRUPT_ALIGNMENT))
     44
     45.macro __KVM_HANDLER ivor_nr scratch srr0
     46	/* Get pointer to vcpu and record exit number. */
     47	mtspr	\scratch , r4
     48	mfspr   r4, SPRN_SPRG_THREAD
     49	lwz     r4, THREAD_KVM_VCPU(r4)
     50	stw	r3, VCPU_GPR(R3)(r4)
     51	stw	r5, VCPU_GPR(R5)(r4)
     52	stw	r6, VCPU_GPR(R6)(r4)
     53	mfspr	r3, \scratch
     54	mfctr	r5
     55	stw	r3, VCPU_GPR(R4)(r4)
     56	stw	r5, VCPU_CTR(r4)
     57	mfspr	r3, \srr0
     58	lis	r6, kvmppc_resume_host@h
     59	stw	r3, VCPU_PC(r4)
     60	li	r5, \ivor_nr
     61	ori	r6, r6, kvmppc_resume_host@l
     62	mtctr	r6
     63	bctr
     64.endm
     65
     66.macro KVM_HANDLER ivor_nr scratch srr0
     67_GLOBAL(kvmppc_handler_\ivor_nr)
     68	__KVM_HANDLER \ivor_nr \scratch \srr0
     69.endm
     70
     71.macro KVM_DBG_HANDLER ivor_nr scratch srr0
     72_GLOBAL(kvmppc_handler_\ivor_nr)
     73	mtspr   \scratch, r4
     74	mfspr	r4, SPRN_SPRG_THREAD
     75	lwz	r4, THREAD_KVM_VCPU(r4)
     76	stw	r3, VCPU_CRIT_SAVE(r4)
     77	mfcr	r3
     78	mfspr	r4, SPRN_CSRR1
     79	andi.	r4, r4, MSR_PR
     80	bne	1f
     81	/* debug interrupt happened in enter/exit path */
     82	mfspr   r4, SPRN_CSRR1
     83	rlwinm  r4, r4, 0, ~MSR_DE
     84	mtspr   SPRN_CSRR1, r4
     85	lis	r4, 0xffff
     86	ori	r4, r4, 0xffff
     87	mtspr	SPRN_DBSR, r4
     88	mfspr	r4, SPRN_SPRG_THREAD
     89	lwz	r4, THREAD_KVM_VCPU(r4)
     90	mtcr	r3
     91	lwz     r3, VCPU_CRIT_SAVE(r4)
     92	mfspr   r4, \scratch
     93	rfci
     941:	/* debug interrupt happened in guest */
     95	mtcr	r3
     96	mfspr	r4, SPRN_SPRG_THREAD
     97	lwz	r4, THREAD_KVM_VCPU(r4)
     98	lwz     r3, VCPU_CRIT_SAVE(r4)
     99	mfspr   r4, \scratch
    100	__KVM_HANDLER \ivor_nr \scratch \srr0
    101.endm
    102
    103.macro KVM_HANDLER_ADDR ivor_nr
    104	.long	kvmppc_handler_\ivor_nr
    105.endm
    106
    107.macro KVM_HANDLER_END
    108	.long	kvmppc_handlers_end
    109.endm
    110
    111_GLOBAL(kvmppc_handlers_start)
    112KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
    113KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK  SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0
    114KVM_HANDLER BOOKE_INTERRUPT_DATA_STORAGE SPRN_SPRG_RSCRATCH0 SPRN_SRR0
    115KVM_HANDLER BOOKE_INTERRUPT_INST_STORAGE SPRN_SPRG_RSCRATCH0 SPRN_SRR0
    116KVM_HANDLER BOOKE_INTERRUPT_EXTERNAL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
    117KVM_HANDLER BOOKE_INTERRUPT_ALIGNMENT SPRN_SPRG_RSCRATCH0 SPRN_SRR0
    118KVM_HANDLER BOOKE_INTERRUPT_PROGRAM SPRN_SPRG_RSCRATCH0 SPRN_SRR0
    119KVM_HANDLER BOOKE_INTERRUPT_FP_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
    120KVM_HANDLER BOOKE_INTERRUPT_SYSCALL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
    121KVM_HANDLER BOOKE_INTERRUPT_AP_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
    122KVM_HANDLER BOOKE_INTERRUPT_DECREMENTER SPRN_SPRG_RSCRATCH0 SPRN_SRR0
    123KVM_HANDLER BOOKE_INTERRUPT_FIT SPRN_SPRG_RSCRATCH0 SPRN_SRR0
    124KVM_HANDLER BOOKE_INTERRUPT_WATCHDOG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
    125KVM_HANDLER BOOKE_INTERRUPT_DTLB_MISS SPRN_SPRG_RSCRATCH0 SPRN_SRR0
    126KVM_HANDLER BOOKE_INTERRUPT_ITLB_MISS SPRN_SPRG_RSCRATCH0 SPRN_SRR0
    127KVM_DBG_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0
    128KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0
    129KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0
    130KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0
    131_GLOBAL(kvmppc_handlers_end)
    132
    133/* Registers:
    134 *  SPRG_SCRATCH0: guest r4
    135 *  r4: vcpu pointer
    136 *  r5: KVM exit number
    137 */
    138_GLOBAL(kvmppc_resume_host)
    139	mfcr	r3
    140	stw	r3, VCPU_CR(r4)
    141	stw	r7, VCPU_GPR(R7)(r4)
    142	stw	r8, VCPU_GPR(R8)(r4)
    143	stw	r9, VCPU_GPR(R9)(r4)
    144
    145	li	r6, 1
    146	slw	r6, r6, r5
    147
    148#ifdef CONFIG_KVM_EXIT_TIMING
    149	/* save exit time */
    1501:
    151	mfspr	r7, SPRN_TBRU
    152	mfspr	r8, SPRN_TBRL
    153	mfspr	r9, SPRN_TBRU
    154	cmpw	r9, r7
    155	bne	1b
    156	stw	r8, VCPU_TIMING_EXIT_TBL(r4)
    157	stw	r9, VCPU_TIMING_EXIT_TBU(r4)
    158#endif
    159
    160	/* Save the faulting instruction and all GPRs for emulation. */
    161	andi.	r7, r6, NEED_INST_MASK
    162	beq	..skip_inst_copy
    163	mfspr	r9, SPRN_SRR0
    164	mfmsr	r8
    165	ori	r7, r8, MSR_DS
    166	mtmsr	r7
    167	isync
    168	lwz	r9, 0(r9)
    169	mtmsr	r8
    170	isync
    171	stw	r9, VCPU_LAST_INST(r4)
    172
    173	stw	r15, VCPU_GPR(R15)(r4)
    174	stw	r16, VCPU_GPR(R16)(r4)
    175	stw	r17, VCPU_GPR(R17)(r4)
    176	stw	r18, VCPU_GPR(R18)(r4)
    177	stw	r19, VCPU_GPR(R19)(r4)
    178	stw	r20, VCPU_GPR(R20)(r4)
    179	stw	r21, VCPU_GPR(R21)(r4)
    180	stw	r22, VCPU_GPR(R22)(r4)
    181	stw	r23, VCPU_GPR(R23)(r4)
    182	stw	r24, VCPU_GPR(R24)(r4)
    183	stw	r25, VCPU_GPR(R25)(r4)
    184	stw	r26, VCPU_GPR(R26)(r4)
    185	stw	r27, VCPU_GPR(R27)(r4)
    186	stw	r28, VCPU_GPR(R28)(r4)
    187	stw	r29, VCPU_GPR(R29)(r4)
    188	stw	r30, VCPU_GPR(R30)(r4)
    189	stw	r31, VCPU_GPR(R31)(r4)
    190..skip_inst_copy:
    191
    192	/* Also grab DEAR and ESR before the host can clobber them. */
    193
    194	andi.	r7, r6, NEED_DEAR_MASK
    195	beq	..skip_dear
    196	mfspr	r9, SPRN_DEAR
    197	stw	r9, VCPU_FAULT_DEAR(r4)
    198..skip_dear:
    199
    200	andi.	r7, r6, NEED_ESR_MASK
    201	beq	..skip_esr
    202	mfspr	r9, SPRN_ESR
    203	stw	r9, VCPU_FAULT_ESR(r4)
    204..skip_esr:
    205
    206	/* Save remaining volatile guest register state to vcpu. */
    207	stw	r0, VCPU_GPR(R0)(r4)
    208	stw	r1, VCPU_GPR(R1)(r4)
    209	stw	r2, VCPU_GPR(R2)(r4)
    210	stw	r10, VCPU_GPR(R10)(r4)
    211	stw	r11, VCPU_GPR(R11)(r4)
    212	stw	r12, VCPU_GPR(R12)(r4)
    213	stw	r13, VCPU_GPR(R13)(r4)
    214	stw	r14, VCPU_GPR(R14)(r4) /* We need a NV GPR below. */
    215	mflr	r3
    216	stw	r3, VCPU_LR(r4)
    217	mfxer	r3
    218	stw	r3, VCPU_XER(r4)
    219
    220	/* Restore host stack pointer and PID before IVPR, since the host
    221	 * exception handlers use them. */
    222	lwz	r1, VCPU_HOST_STACK(r4)
    223	lwz	r3, VCPU_HOST_PID(r4)
    224	mtspr	SPRN_PID, r3
    225
    226#ifdef CONFIG_FSL_BOOKE
    227	/* we cheat and know that Linux doesn't use PID1 which is always 0 */
    228	lis	r3, 0
    229	mtspr	SPRN_PID1, r3
    230#endif
    231
    232	/* Restore host IVPR before re-enabling interrupts. We cheat and know
    233	 * that Linux IVPR is always 0xc0000000. */
    234	lis	r3, 0xc000
    235	mtspr	SPRN_IVPR, r3
    236
    237	/* Switch to kernel stack and jump to handler. */
    238	LOAD_REG_ADDR(r3, kvmppc_handle_exit)
    239	mtctr	r3
    240	mr	r3, r4
    241	lwz	r2, HOST_R2(r1)
    242	mr	r14, r4 /* Save vcpu pointer. */
    243
    244	bctrl	/* kvmppc_handle_exit() */
    245
    246	/* Restore vcpu pointer and the nonvolatiles we used. */
    247	mr	r4, r14
    248	lwz	r14, VCPU_GPR(R14)(r4)
    249
    250	/* Sometimes instruction emulation must restore complete GPR state. */
    251	andi.	r5, r3, RESUME_FLAG_NV
    252	beq	..skip_nv_load
    253	lwz	r15, VCPU_GPR(R15)(r4)
    254	lwz	r16, VCPU_GPR(R16)(r4)
    255	lwz	r17, VCPU_GPR(R17)(r4)
    256	lwz	r18, VCPU_GPR(R18)(r4)
    257	lwz	r19, VCPU_GPR(R19)(r4)
    258	lwz	r20, VCPU_GPR(R20)(r4)
    259	lwz	r21, VCPU_GPR(R21)(r4)
    260	lwz	r22, VCPU_GPR(R22)(r4)
    261	lwz	r23, VCPU_GPR(R23)(r4)
    262	lwz	r24, VCPU_GPR(R24)(r4)
    263	lwz	r25, VCPU_GPR(R25)(r4)
    264	lwz	r26, VCPU_GPR(R26)(r4)
    265	lwz	r27, VCPU_GPR(R27)(r4)
    266	lwz	r28, VCPU_GPR(R28)(r4)
    267	lwz	r29, VCPU_GPR(R29)(r4)
    268	lwz	r30, VCPU_GPR(R30)(r4)
    269	lwz	r31, VCPU_GPR(R31)(r4)
    270..skip_nv_load:
    271
    272	/* Should we return to the guest? */
    273	andi.	r5, r3, RESUME_FLAG_HOST
    274	beq	lightweight_exit
    275
    276	srawi	r3, r3, 2 /* Shift -ERR back down. */
    277
    278heavyweight_exit:
    279	/* Not returning to guest. */
    280
    281#ifdef CONFIG_SPE
    282	/* save guest SPEFSCR and load host SPEFSCR */
    283	mfspr	r9, SPRN_SPEFSCR
    284	stw	r9, VCPU_SPEFSCR(r4)
    285	lwz	r9, VCPU_HOST_SPEFSCR(r4)
    286	mtspr	SPRN_SPEFSCR, r9
    287#endif
    288
    289	/* We already saved guest volatile register state; now save the
    290	 * non-volatiles. */
    291	stw	r15, VCPU_GPR(R15)(r4)
    292	stw	r16, VCPU_GPR(R16)(r4)
    293	stw	r17, VCPU_GPR(R17)(r4)
    294	stw	r18, VCPU_GPR(R18)(r4)
    295	stw	r19, VCPU_GPR(R19)(r4)
    296	stw	r20, VCPU_GPR(R20)(r4)
    297	stw	r21, VCPU_GPR(R21)(r4)
    298	stw	r22, VCPU_GPR(R22)(r4)
    299	stw	r23, VCPU_GPR(R23)(r4)
    300	stw	r24, VCPU_GPR(R24)(r4)
    301	stw	r25, VCPU_GPR(R25)(r4)
    302	stw	r26, VCPU_GPR(R26)(r4)
    303	stw	r27, VCPU_GPR(R27)(r4)
    304	stw	r28, VCPU_GPR(R28)(r4)
    305	stw	r29, VCPU_GPR(R29)(r4)
    306	stw	r30, VCPU_GPR(R30)(r4)
    307	stw	r31, VCPU_GPR(R31)(r4)
    308
    309	/* Load host non-volatile register state from host stack. */
    310	lwz	r14, HOST_NV_GPR(R14)(r1)
    311	lwz	r15, HOST_NV_GPR(R15)(r1)
    312	lwz	r16, HOST_NV_GPR(R16)(r1)
    313	lwz	r17, HOST_NV_GPR(R17)(r1)
    314	lwz	r18, HOST_NV_GPR(R18)(r1)
    315	lwz	r19, HOST_NV_GPR(R19)(r1)
    316	lwz	r20, HOST_NV_GPR(R20)(r1)
    317	lwz	r21, HOST_NV_GPR(R21)(r1)
    318	lwz	r22, HOST_NV_GPR(R22)(r1)
    319	lwz	r23, HOST_NV_GPR(R23)(r1)
    320	lwz	r24, HOST_NV_GPR(R24)(r1)
    321	lwz	r25, HOST_NV_GPR(R25)(r1)
    322	lwz	r26, HOST_NV_GPR(R26)(r1)
    323	lwz	r27, HOST_NV_GPR(R27)(r1)
    324	lwz	r28, HOST_NV_GPR(R28)(r1)
    325	lwz	r29, HOST_NV_GPR(R29)(r1)
    326	lwz	r30, HOST_NV_GPR(R30)(r1)
    327	lwz	r31, HOST_NV_GPR(R31)(r1)
    328
    329	/* Return to kvm_vcpu_run(). */
    330	lwz	r4, HOST_STACK_LR(r1)
    331	lwz	r5, HOST_CR(r1)
    332	addi	r1, r1, HOST_STACK_SIZE
    333	mtlr	r4
    334	mtcr	r5
    335	/* r3 still contains the return code from kvmppc_handle_exit(). */
    336	blr
    337
    338
    339/* Registers:
    340 *  r3: vcpu pointer
    341 */
    342_GLOBAL(__kvmppc_vcpu_run)
    343	stwu	r1, -HOST_STACK_SIZE(r1)
    344	stw	r1, VCPU_HOST_STACK(r3)	/* Save stack pointer to vcpu. */
    345
    346	/* Save host state to stack. */
    347	mr	r4, r3
    348	mflr	r3
    349	stw	r3, HOST_STACK_LR(r1)
    350	mfcr	r5
    351	stw	r5, HOST_CR(r1)
    352
    353	/* Save host non-volatile register state to stack. */
    354	stw	r14, HOST_NV_GPR(R14)(r1)
    355	stw	r15, HOST_NV_GPR(R15)(r1)
    356	stw	r16, HOST_NV_GPR(R16)(r1)
    357	stw	r17, HOST_NV_GPR(R17)(r1)
    358	stw	r18, HOST_NV_GPR(R18)(r1)
    359	stw	r19, HOST_NV_GPR(R19)(r1)
    360	stw	r20, HOST_NV_GPR(R20)(r1)
    361	stw	r21, HOST_NV_GPR(R21)(r1)
    362	stw	r22, HOST_NV_GPR(R22)(r1)
    363	stw	r23, HOST_NV_GPR(R23)(r1)
    364	stw	r24, HOST_NV_GPR(R24)(r1)
    365	stw	r25, HOST_NV_GPR(R25)(r1)
    366	stw	r26, HOST_NV_GPR(R26)(r1)
    367	stw	r27, HOST_NV_GPR(R27)(r1)
    368	stw	r28, HOST_NV_GPR(R28)(r1)
    369	stw	r29, HOST_NV_GPR(R29)(r1)
    370	stw	r30, HOST_NV_GPR(R30)(r1)
    371	stw	r31, HOST_NV_GPR(R31)(r1)
    372
    373	/* Load guest non-volatiles. */
    374	lwz	r14, VCPU_GPR(R14)(r4)
    375	lwz	r15, VCPU_GPR(R15)(r4)
    376	lwz	r16, VCPU_GPR(R16)(r4)
    377	lwz	r17, VCPU_GPR(R17)(r4)
    378	lwz	r18, VCPU_GPR(R18)(r4)
    379	lwz	r19, VCPU_GPR(R19)(r4)
    380	lwz	r20, VCPU_GPR(R20)(r4)
    381	lwz	r21, VCPU_GPR(R21)(r4)
    382	lwz	r22, VCPU_GPR(R22)(r4)
    383	lwz	r23, VCPU_GPR(R23)(r4)
    384	lwz	r24, VCPU_GPR(R24)(r4)
    385	lwz	r25, VCPU_GPR(R25)(r4)
    386	lwz	r26, VCPU_GPR(R26)(r4)
    387	lwz	r27, VCPU_GPR(R27)(r4)
    388	lwz	r28, VCPU_GPR(R28)(r4)
    389	lwz	r29, VCPU_GPR(R29)(r4)
    390	lwz	r30, VCPU_GPR(R30)(r4)
    391	lwz	r31, VCPU_GPR(R31)(r4)
    392
    393#ifdef CONFIG_SPE
    394	/* save host SPEFSCR and load guest SPEFSCR */
    395	mfspr	r3, SPRN_SPEFSCR
    396	stw	r3, VCPU_HOST_SPEFSCR(r4)
    397	lwz	r3, VCPU_SPEFSCR(r4)
    398	mtspr	SPRN_SPEFSCR, r3
    399#endif
    400
    401lightweight_exit:
    402	stw	r2, HOST_R2(r1)
    403
    404	mfspr	r3, SPRN_PID
    405	stw	r3, VCPU_HOST_PID(r4)
    406	lwz	r3, VCPU_SHADOW_PID(r4)
    407	mtspr	SPRN_PID, r3
    408
    409#ifdef CONFIG_FSL_BOOKE
    410	lwz	r3, VCPU_SHADOW_PID1(r4)
    411	mtspr	SPRN_PID1, r3
    412#endif
    413
    414	/* Load some guest volatiles. */
    415	lwz	r0, VCPU_GPR(R0)(r4)
    416	lwz	r2, VCPU_GPR(R2)(r4)
    417	lwz	r9, VCPU_GPR(R9)(r4)
    418	lwz	r10, VCPU_GPR(R10)(r4)
    419	lwz	r11, VCPU_GPR(R11)(r4)
    420	lwz	r12, VCPU_GPR(R12)(r4)
    421	lwz	r13, VCPU_GPR(R13)(r4)
    422	lwz	r3, VCPU_LR(r4)
    423	mtlr	r3
    424	lwz	r3, VCPU_XER(r4)
    425	mtxer	r3
    426
    427	/* Switch the IVPR. XXX If we take a TLB miss after this we're screwed,
    428	 * so how do we make sure vcpu won't fault? */
    429	lis	r8, kvmppc_booke_handlers@ha
    430	lwz	r8, kvmppc_booke_handlers@l(r8)
    431	mtspr	SPRN_IVPR, r8
    432
    433	lwz	r5, VCPU_SHARED(r4)
    434
    435	/* Can't switch the stack pointer until after IVPR is switched,
    436	 * because host interrupt handlers would get confused. */
    437	lwz	r1, VCPU_GPR(R1)(r4)
    438
    439	/*
    440	 * Host interrupt handlers may have clobbered these
    441	 * guest-readable SPRGs, or the guest kernel may have
    442	 * written directly to the shared area, so we
    443	 * need to reload them here with the guest's values.
    444	 */
    445	PPC_LD(r3, VCPU_SHARED_SPRG4, r5)
    446	mtspr	SPRN_SPRG4W, r3
    447	PPC_LD(r3, VCPU_SHARED_SPRG5, r5)
    448	mtspr	SPRN_SPRG5W, r3
    449	PPC_LD(r3, VCPU_SHARED_SPRG6, r5)
    450	mtspr	SPRN_SPRG6W, r3
    451	PPC_LD(r3, VCPU_SHARED_SPRG7, r5)
    452	mtspr	SPRN_SPRG7W, r3
    453
    454#ifdef CONFIG_KVM_EXIT_TIMING
    455	/* save enter time */
    4561:
    457	mfspr	r6, SPRN_TBRU
    458	mfspr	r7, SPRN_TBRL
    459	mfspr	r8, SPRN_TBRU
    460	cmpw	r8, r6
    461	bne	1b
    462	stw	r7, VCPU_TIMING_LAST_ENTER_TBL(r4)
    463	stw	r8, VCPU_TIMING_LAST_ENTER_TBU(r4)
    464#endif
    465
    466	/* Finish loading guest volatiles and jump to guest. */
    467	lwz	r3, VCPU_CTR(r4)
    468	lwz	r5, VCPU_CR(r4)
    469	lwz	r6, VCPU_PC(r4)
    470	lwz	r7, VCPU_SHADOW_MSR(r4)
    471	mtctr	r3
    472	mtcr	r5
    473	mtsrr0	r6
    474	mtsrr1	r7
    475	lwz	r5, VCPU_GPR(R5)(r4)
    476	lwz	r6, VCPU_GPR(R6)(r4)
    477	lwz	r7, VCPU_GPR(R7)(r4)
    478	lwz	r8, VCPU_GPR(R8)(r4)
    479
    480	/* Clear any debug events which occurred since we disabled MSR[DE].
    481	 * XXX This gives us a 3-instruction window in which a breakpoint
    482	 * intended for guest context could fire in the host instead. */
    483	lis	r3, 0xffff
    484	ori	r3, r3, 0xffff
    485	mtspr	SPRN_DBSR, r3
    486
    487	lwz	r3, VCPU_GPR(R3)(r4)
    488	lwz	r4, VCPU_GPR(R4)(r4)
    489	rfi
    490
    491	.data
    492	.align	4
    493	.globl	kvmppc_booke_handler_addr
    494kvmppc_booke_handler_addr:
    495KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL
    496KVM_HANDLER_ADDR BOOKE_INTERRUPT_MACHINE_CHECK
    497KVM_HANDLER_ADDR BOOKE_INTERRUPT_DATA_STORAGE
    498KVM_HANDLER_ADDR BOOKE_INTERRUPT_INST_STORAGE
    499KVM_HANDLER_ADDR BOOKE_INTERRUPT_EXTERNAL
    500KVM_HANDLER_ADDR BOOKE_INTERRUPT_ALIGNMENT
    501KVM_HANDLER_ADDR BOOKE_INTERRUPT_PROGRAM
    502KVM_HANDLER_ADDR BOOKE_INTERRUPT_FP_UNAVAIL
    503KVM_HANDLER_ADDR BOOKE_INTERRUPT_SYSCALL
    504KVM_HANDLER_ADDR BOOKE_INTERRUPT_AP_UNAVAIL
    505KVM_HANDLER_ADDR BOOKE_INTERRUPT_DECREMENTER
    506KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT
    507KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG
    508KVM_HANDLER_ADDR BOOKE_INTERRUPT_DTLB_MISS
    509KVM_HANDLER_ADDR BOOKE_INTERRUPT_ITLB_MISS
    510KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG
    511KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL
    512KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_DATA
    513KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_ROUND
    514KVM_HANDLER_END /*Always keep this in end*/
    515
    516#ifdef CONFIG_SPE
    517_GLOBAL(kvmppc_save_guest_spe)
    518	cmpi	0,r3,0
    519	beqlr-
    520	SAVE_32EVRS(0, r4, r3, VCPU_EVR)
    521	evxor   evr6, evr6, evr6
    522	evmwumiaa evr6, evr6, evr6
    523	li	r4,VCPU_ACC
    524	evstddx evr6, r4, r3		/* save acc */
    525	blr
    526
    527_GLOBAL(kvmppc_load_guest_spe)
    528	cmpi	0,r3,0
    529	beqlr-
    530	li      r4,VCPU_ACC
    531	evlddx  evr6,r4,r3
    532	evmra   evr6,evr6		/* load acc */
    533	REST_32EVRS(0, r4, r3, VCPU_EVR)
    534	blr
    535#endif