^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright SUSE Linux Products GmbH 2009
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Authors: Alexander Graf <agraf@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <asm/ppc_asm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/kvm_asm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/reg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/mmu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/asm-offsets.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/asm-compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #ifdef CONFIG_PPC_BOOK3S_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/exception-64s.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /*****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Real Mode handlers that need to be in low physical memory *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) ****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #if defined(CONFIG_PPC_BOOK3S_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #ifdef PPC64_ELF_ABI_v2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define FUNC(name) name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define FUNC(name) GLUE(.,name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #elif defined(CONFIG_PPC_BOOK3S_32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define FUNC(name) name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define RFI_TO_KERNEL RFI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define RFI_TO_GUEST RFI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .macro INTERRUPT_TRAMPOLINE intno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .global kvmppc_trampoline_\intno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) kvmppc_trampoline_\intno:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) mtspr SPRN_SPRG_SCRATCH0, r13 /* Save r13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * First thing to do is to find out if we're coming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * from a KVM guest or a Linux process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * To distinguish, we check a magic byte in the PACA/current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) mfspr r13, SPRN_SPRG_THREAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) lwz r13, THREAD_KVM_SVCPU(r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* PPC32 can have a NULL pointer - let's check for that */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) mtspr SPRN_SPRG_SCRATCH1, r12 /* Save r12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) mfcr r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) cmpwi r13, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) bne 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 2: mtcr r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) mfspr r12, SPRN_SPRG_SCRATCH1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) mfspr r13, SPRN_SPRG_SCRATCH0 /* r13 = original r13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) b kvmppc_resume_\intno /* Get back original handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 1: tophys(r13, r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) stw r12, HSTATE_SCRATCH1(r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) mfspr r12, SPRN_SPRG_SCRATCH1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) stw r12, HSTATE_SCRATCH0(r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) lbz r12, HSTATE_IN_GUEST(r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) cmpwi r12, KVM_GUEST_MODE_NONE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) bne ..kvmppc_handler_hasmagic_\intno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* No KVM guest? Then jump back to the Linux handler! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) lwz r12, HSTATE_SCRATCH1(r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) b 2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Now we know we're handling a KVM guest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ..kvmppc_handler_hasmagic_\intno:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* Should we just skip the faulting instruction? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) cmpwi r12, KVM_GUEST_MODE_SKIP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) beq kvmppc_handler_skip_ins
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* Let's store which interrupt we're handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) li r12, \intno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* Jump into the SLB exit code that goes to the highmem handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) b kvmppc_handler_trampoline_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSTEM_RESET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_MACHINE_CHECK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DATA_STORAGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_INST_STORAGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_EXTERNAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALIGNMENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PROGRAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_FP_UNAVAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DECREMENTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_TRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PERFMON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALTIVEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * Bring us back to the faulting code, but skip the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * faulting instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * This is a generic exit path from the interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * trampolines above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * Input Registers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * R12 = free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * R13 = Shadow VCPU (PACA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * HSTATE.SCRATCH0 = guest R12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * HSTATE.SCRATCH1 = guest CR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * SPRG_SCRATCH0 = guest R13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) kvmppc_handler_skip_ins:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* Patch the IP to the next instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) mfsrr0 r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) addi r12, r12, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) mtsrr0 r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* Clean up all state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) lwz r12, HSTATE_SCRATCH1(r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) mtcr r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) PPC_LL r12, HSTATE_SCRATCH0(r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) GET_SCRATCH0(r13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* And get back into the code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) RFI_TO_KERNEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * Call kvmppc_handler_trampoline_enter in real mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * On entry, r4 contains the guest shadow MSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * MSR.EE has to be 0 when calling this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) _GLOBAL_TOC(kvmppc_entry_trampoline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) mfmsr r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) LOAD_REG_ADDR(r7, kvmppc_handler_trampoline_enter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) toreal(r7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) li r6, MSR_IR | MSR_DR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) andc r6, r5, r6 /* Clear DR and IR in MSR value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * Set EE in HOST_MSR so that it's enabled when we get into our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * C exit handler function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ori r5, r5, MSR_EE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) mtsrr0 r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) mtsrr1 r6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) RFI_TO_KERNEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #include "book3s_segment.S"