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 SUSE Linux Products GmbH 2009 16 * 17 * Authors: Alexander Graf <agraf@suse.de> 18 */ 19 20#include <asm/ppc_asm.h> 21#include <asm/kvm_asm.h> 22#include <asm/reg.h> 23#include <asm/mmu.h> 24#include <asm/page.h> 25#include <asm/asm-offsets.h> 26 27#ifdef CONFIG_PPC_BOOK3S_64 28#include <asm/exception-64s.h> 29#endif 30 31/***************************************************************************** 32 * * 33 * Real Mode handlers that need to be in low physical memory * 34 * * 35 ****************************************************************************/ 36 37#if defined(CONFIG_PPC_BOOK3S_64) 38 39#define FUNC(name) GLUE(.,name) 40 41#elif defined(CONFIG_PPC_BOOK3S_32) 42 43#define FUNC(name) name 44 45.macro INTERRUPT_TRAMPOLINE intno 46 47.global kvmppc_trampoline_\intno 48kvmppc_trampoline_\intno: 49 50 mtspr SPRN_SPRG_SCRATCH0, r13 /* Save r13 */ 51 52 /* 53 * First thing to do is to find out if we're coming 54 * from a KVM guest or a Linux process. 55 * 56 * To distinguish, we check a magic byte in the PACA/current 57 */ 58 mfspr r13, SPRN_SPRG_THREAD 59 lwz r13, THREAD_KVM_SVCPU(r13) 60 /* PPC32 can have a NULL pointer - let's check for that */ 61 mtspr SPRN_SPRG_SCRATCH1, r12 /* Save r12 */ 62 mfcr r12 63 cmpwi r13, 0 64 bne 1f 652: mtcr r12 66 mfspr r12, SPRN_SPRG_SCRATCH1 67 mfspr r13, SPRN_SPRG_SCRATCH0 /* r13 = original r13 */ 68 b kvmppc_resume_\intno /* Get back original handler */ 69 701: tophys(r13, r13) 71 stw r12, HSTATE_SCRATCH1(r13) 72 mfspr r12, SPRN_SPRG_SCRATCH1 73 stw r12, HSTATE_SCRATCH0(r13) 74 lbz r12, HSTATE_IN_GUEST(r13) 75 cmpwi r12, KVM_GUEST_MODE_NONE 76 bne ..kvmppc_handler_hasmagic_\intno 77 /* No KVM guest? Then jump back to the Linux handler! */ 78 lwz r12, HSTATE_SCRATCH1(r13) 79 b 2b 80 81 /* Now we know we're handling a KVM guest */ 82..kvmppc_handler_hasmagic_\intno: 83 84 /* Should we just skip the faulting instruction? */ 85 cmpwi r12, KVM_GUEST_MODE_SKIP 86 beq kvmppc_handler_skip_ins 87 88 /* Let's store which interrupt we're handling */ 89 li r12, \intno 90 91 /* Jump into the SLB exit code that goes to the highmem handler */ 92 b kvmppc_handler_trampoline_exit 93 94.endm 95 96INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSTEM_RESET 97INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_MACHINE_CHECK 98INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DATA_STORAGE 99INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_INST_STORAGE 100INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_EXTERNAL 101INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALIGNMENT 102INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PROGRAM 103INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_FP_UNAVAIL 104INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DECREMENTER 105INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSCALL 106INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_TRACE 107INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PERFMON 108INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALTIVEC 109 110/* 111 * Bring us back to the faulting code, but skip the 112 * faulting instruction. 113 * 114 * This is a generic exit path from the interrupt 115 * trampolines above. 116 * 117 * Input Registers: 118 * 119 * R12 = free 120 * R13 = Shadow VCPU (PACA) 121 * HSTATE.SCRATCH0 = guest R12 122 * HSTATE.SCRATCH1 = guest CR 123 * SPRG_SCRATCH0 = guest R13 124 * 125 */ 126kvmppc_handler_skip_ins: 127 128 /* Patch the IP to the next instruction */ 129 mfsrr0 r12 130 addi r12, r12, 4 131 mtsrr0 r12 132 133 /* Clean up all state */ 134 lwz r12, HSTATE_SCRATCH1(r13) 135 mtcr r12 136 PPC_LL r12, HSTATE_SCRATCH0(r13) 137 GET_SCRATCH0(r13) 138 139 /* And get back into the code */ 140 RFI 141#endif 142 143/* 144 * Call kvmppc_handler_trampoline_enter in real mode 145 * 146 * On entry, r4 contains the guest shadow MSR 147 * MSR.EE has to be 0 when calling this function 148 */ 149_GLOBAL(kvmppc_entry_trampoline) 150 mfmsr r5 151 LOAD_REG_ADDR(r7, kvmppc_handler_trampoline_enter) 152 toreal(r7) 153 154 li r6, MSR_IR | MSR_DR 155 andc r6, r5, r6 /* Clear DR and IR in MSR value */ 156 /* 157 * Set EE in HOST_MSR so that it's enabled when we get into our 158 * C exit handler function. 159 */ 160 ori r5, r5, MSR_EE 161 mtsrr0 r7 162 mtsrr1 r6 163 RFI 164 165#if defined(CONFIG_PPC_BOOK3S_32) 166#define STACK_LR INT_FRAME_SIZE+4 167 168/* load_up_xxx have to run with MSR_DR=0 on Book3S_32 */ 169#define MSR_EXT_START \ 170 PPC_STL r20, _NIP(r1); \ 171 mfmsr r20; \ 172 LOAD_REG_IMMEDIATE(r3, MSR_DR|MSR_EE); \ 173 andc r3,r20,r3; /* Disable DR,EE */ \ 174 mtmsr r3; \ 175 sync 176 177#define MSR_EXT_END \ 178 mtmsr r20; /* Enable DR,EE */ \ 179 sync; \ 180 PPC_LL r20, _NIP(r1) 181 182#elif defined(CONFIG_PPC_BOOK3S_64) 183#define STACK_LR _LINK 184#define MSR_EXT_START 185#define MSR_EXT_END 186#endif 187 188/* 189 * Activate current's external feature (FPU/Altivec/VSX) 190 */ 191#define define_load_up(what) \ 192 \ 193_GLOBAL(kvmppc_load_up_ ## what); \ 194 PPC_STLU r1, -INT_FRAME_SIZE(r1); \ 195 mflr r3; \ 196 PPC_STL r3, STACK_LR(r1); \ 197 MSR_EXT_START; \ 198 \ 199 bl FUNC(load_up_ ## what); \ 200 \ 201 MSR_EXT_END; \ 202 PPC_LL r3, STACK_LR(r1); \ 203 mtlr r3; \ 204 addi r1, r1, INT_FRAME_SIZE; \ 205 blr 206 207define_load_up(fpu) 208#ifdef CONFIG_ALTIVEC 209define_load_up(altivec) 210#endif 211 212#include "book3s_segment.S" 213