0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <asm/ppc_asm.h>
0010 #include <asm/kvm_asm.h>
0011 #include <asm/reg.h>
0012 #include <asm/mmu.h>
0013 #include <asm/page.h>
0014 #include <asm/asm-offsets.h>
0015 #include <asm/asm-compat.h>
0016
0017 #ifdef CONFIG_PPC_BOOK3S_64
0018 #include <asm/exception-64s.h>
0019 #endif
0020
0021
0022
0023
0024
0025
0026
0027 #if defined(CONFIG_PPC_BOOK3S_64)
0028
0029 #ifdef CONFIG_PPC64_ELF_ABI_V2
0030 #define FUNC(name) name
0031 #else
0032 #define FUNC(name) GLUE(.,name)
0033 #endif
0034
0035 #elif defined(CONFIG_PPC_BOOK3S_32)
0036
0037 #define FUNC(name) name
0038
0039 #define RFI_TO_KERNEL rfi
0040 #define RFI_TO_GUEST rfi
0041
0042 .macro INTERRUPT_TRAMPOLINE intno
0043
0044 .global kvmppc_trampoline_\intno
0045 kvmppc_trampoline_\intno:
0046
0047 mtspr SPRN_SPRG_SCRATCH0, r13
0048
0049
0050
0051
0052
0053
0054
0055 mfspr r13, SPRN_SPRG_THREAD
0056 lwz r13, THREAD_KVM_SVCPU(r13)
0057
0058 mtspr SPRN_SPRG_SCRATCH1, r12
0059 mfcr r12
0060 cmpwi r13, 0
0061 bne 1f
0062 2: mtcr r12
0063 mfspr r12, SPRN_SPRG_SCRATCH1
0064 mfspr r13, SPRN_SPRG_SCRATCH0
0065 b kvmppc_resume_\intno
0066
0067 1: tophys(r13, r13)
0068 stw r12, HSTATE_SCRATCH1(r13)
0069 mfspr r12, SPRN_SPRG_SCRATCH1
0070 stw r12, HSTATE_SCRATCH0(r13)
0071 lbz r12, HSTATE_IN_GUEST(r13)
0072 cmpwi r12, KVM_GUEST_MODE_NONE
0073 bne ..kvmppc_handler_hasmagic_\intno
0074
0075 lwz r12, HSTATE_SCRATCH1(r13)
0076 b 2b
0077
0078
0079 ..kvmppc_handler_hasmagic_\intno:
0080
0081
0082 cmpwi r12, KVM_GUEST_MODE_SKIP
0083 beq kvmppc_handler_skip_ins
0084
0085
0086 li r12, \intno
0087
0088
0089 b kvmppc_handler_trampoline_exit
0090
0091 .endm
0092
0093 INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSTEM_RESET
0094 INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_MACHINE_CHECK
0095 INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DATA_STORAGE
0096 INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_INST_STORAGE
0097 INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_EXTERNAL
0098 INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALIGNMENT
0099 INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PROGRAM
0100 INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_FP_UNAVAIL
0101 INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DECREMENTER
0102 INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSCALL
0103 INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_TRACE
0104 INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PERFMON
0105 INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALTIVEC
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123 kvmppc_handler_skip_ins:
0124
0125
0126 mfsrr0 r12
0127 addi r12, r12, 4
0128 mtsrr0 r12
0129
0130
0131 lwz r12, HSTATE_SCRATCH1(r13)
0132 mtcr r12
0133 PPC_LL r12, HSTATE_SCRATCH0(r13)
0134 GET_SCRATCH0(r13)
0135
0136
0137 RFI_TO_KERNEL
0138 #endif
0139
0140
0141
0142
0143
0144
0145
0146 _GLOBAL_TOC(kvmppc_entry_trampoline)
0147 mfmsr r5
0148 LOAD_REG_ADDR(r7, kvmppc_handler_trampoline_enter)
0149 toreal(r7)
0150
0151 li r6, MSR_IR | MSR_DR
0152 andc r6, r5, r6
0153
0154
0155
0156
0157 ori r5, r5, MSR_EE
0158 mtsrr0 r7
0159 mtsrr1 r6
0160 RFI_TO_KERNEL
0161
0162 #include "book3s_segment.S"