1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
34
35
36
37
38
39#define FUNC(name) GLUE(.,name)
40
41 .globl kvmppc_skip_interrupt
42kvmppc_skip_interrupt:
43
44
45
46
47 mfspr r13, SPRN_SRR0
48 addi r13, r13, 4
49 mtspr SPRN_SRR0, r13
50 GET_SCRATCH0(r13)
51 rfid
52 b .
53
54 .globl kvmppc_skip_Hinterrupt
55kvmppc_skip_Hinterrupt:
56
57
58
59
60 mfspr r13, SPRN_HSRR0
61 addi r13, r13, 4
62 mtspr SPRN_HSRR0, r13
63 GET_SCRATCH0(r13)
64 hrfid
65 b .
66
67
68
69#define FUNC(name) name
70
71.macro INTERRUPT_TRAMPOLINE intno
72
73.global kvmppc_trampoline_\intno
74kvmppc_trampoline_\intno:
75
76 mtspr SPRN_SPRG_SCRATCH0, r13
77
78
79
80
81
82
83
84 mfspr r13, SPRN_SPRG_THREAD
85 lwz r13, THREAD_KVM_SVCPU(r13)
86
87 mtspr SPRN_SPRG_SCRATCH1, r12
88 mfcr r12
89 cmpwi r13, 0
90 bne 1f
912: mtcr r12
92 mfspr r12, SPRN_SPRG_SCRATCH1
93 mfspr r13, SPRN_SPRG_SCRATCH0
94 b kvmppc_resume_\intno
95
961: tophys(r13, r13)
97 stw r12, HSTATE_SCRATCH1(r13)
98 mfspr r12, SPRN_SPRG_SCRATCH1
99 stw r12, HSTATE_SCRATCH0(r13)
100 lbz r12, HSTATE_IN_GUEST(r13)
101 cmpwi r12, KVM_GUEST_MODE_NONE
102 bne ..kvmppc_handler_hasmagic_\intno
103
104 lwz r12, HSTATE_SCRATCH1(r13)
105 b 2b
106
107
108..kvmppc_handler_hasmagic_\intno:
109
110
111 cmpwi r12, KVM_GUEST_MODE_SKIP
112 beq kvmppc_handler_skip_ins
113
114
115 li r12, \intno
116
117
118 b kvmppc_handler_trampoline_exit
119
120.endm
121
122INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSTEM_RESET
123INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_MACHINE_CHECK
124INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DATA_STORAGE
125INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_INST_STORAGE
126INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_EXTERNAL
127INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALIGNMENT
128INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PROGRAM
129INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_FP_UNAVAIL
130INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_DECREMENTER
131INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_SYSCALL
132INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_TRACE
133INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_PERFMON
134INTERRUPT_TRAMPOLINE BOOK3S_INTERRUPT_ALTIVEC
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152kvmppc_handler_skip_ins:
153
154
155 mfsrr0 r12
156 addi r12, r12, 4
157 mtsrr0 r12
158
159
160 lwz r12, HSTATE_SCRATCH1(r13)
161 mtcr r12
162 PPC_LL r12, HSTATE_SCRATCH0(r13)
163 GET_SCRATCH0(r13)
164
165
166 RFI
167#endif
168
169
170
171
172
173
174
175_GLOBAL(kvmppc_entry_trampoline)
176 mfmsr r5
177 LOAD_REG_ADDR(r7, kvmppc_handler_trampoline_enter)
178 toreal(r7)
179
180 li r6, MSR_IR | MSR_DR
181 andc r6, r5, r6
182
183
184
185
186 ori r5, r5, MSR_EE
187 mtsrr0 r7
188 mtsrr1 r6
189 RFI
190
191
192#define STACK_LR INT_FRAME_SIZE+4
193
194
195#define MSR_EXT_START \
196 PPC_STL r20, _NIP(r1); \
197 mfmsr r20; \
198 LOAD_REG_IMMEDIATE(r3, MSR_DR|MSR_EE); \
199 andc r3,r20,r3; \
200 mtmsr r3; \
201 sync
202
203#define MSR_EXT_END \
204 mtmsr r20; \
205 sync; \
206 PPC_LL r20, _NIP(r1)
207
208
209#define STACK_LR _LINK
210#define MSR_EXT_START
211#define MSR_EXT_END
212#endif
213
214
215
216
217#define define_load_up(what) \
218 \
219_GLOBAL(kvmppc_load_up_
220 PPC_STLU r1, -INT_FRAME_SIZE(r1); \
221 mflr r3; \
222 PPC_STL r3, STACK_LR(r1); \
223 MSR_EXT_START; \
224 \
225 bl FUNC(load_up_
226 \
227 MSR_EXT_END; \
228 PPC_LL r3, STACK_LR(r1); \
229 mtlr r3; \
230 addi r1, r1, INT_FRAME_SIZE; \
231 blr
232
233define_load_up(fpu)
234#ifdef CONFIG_ALTIVEC
235define_load_up(altivec)
236#endif
237
238#include "book3s_segment.S"
239