Linux Audio

Check our new training course

Loading...
v5.9
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
 
 
 
 
 
 
 
 
 
 
 
 
  3 *
  4 * Copyright SUSE Linux Products GmbH 2010
  5 * Copyright 2010-2011 Freescale Semiconductor, Inc.
  6 *
  7 * Authors: Alexander Graf <agraf@suse.de>
  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#include <asm/asm-compat.h>
 
 
 
 
 
 
 
 
 
 16
 17#define KVM_MAGIC_PAGE		(-4096)
 18
 19#ifdef CONFIG_64BIT
 20#define LL64(reg, offs, reg2)	ld	reg, (offs)(reg2)
 21#define STL64(reg, offs, reg2)	std	reg, (offs)(reg2)
 22#else
 23#define LL64(reg, offs, reg2)	lwz	reg, (offs + 4)(reg2)
 24#define STL64(reg, offs, reg2)	stw	reg, (offs + 4)(reg2)
 25#endif
 26
 27#define SCRATCH_SAVE							\
 28	/* Enable critical section. We are critical if			\
 29	   shared->critical == r1 */					\
 30	STL64(r1, KVM_MAGIC_PAGE + KVM_MAGIC_CRITICAL, 0);		\
 31									\
 32	/* Save state */						\
 33	PPC_STL	r31, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH1)(0);		\
 34	PPC_STL	r30, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH2)(0);		\
 35	mfcr	r31;							\
 36	stw	r31, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH3)(0);
 37
 38#define SCRATCH_RESTORE							\
 39	/* Restore state */						\
 40	PPC_LL	r31, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH1)(0);		\
 41	lwz	r30, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH3)(0);		\
 42	mtcr	r30;							\
 43	PPC_LL	r30, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH2)(0);		\
 44									\
 45	/* Disable critical section. We are critical if			\
 46	   shared->critical == r1 and r2 is always != r1 */		\
 47	STL64(r2, KVM_MAGIC_PAGE + KVM_MAGIC_CRITICAL, 0);
 48
 49.global kvm_template_start
 50kvm_template_start:
 51
 52.global kvm_emulate_mtmsrd
 53kvm_emulate_mtmsrd:
 54
 55	SCRATCH_SAVE
 56
 57	/* Put MSR & ~(MSR_EE|MSR_RI) in r31 */
 58	LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
 59	lis	r30, (~(MSR_EE | MSR_RI))@h
 60	ori	r30, r30, (~(MSR_EE | MSR_RI))@l
 61	and	r31, r31, r30
 62
 63	/* OR the register's (MSR_EE|MSR_RI) on MSR */
 64kvm_emulate_mtmsrd_reg:
 65	ori	r30, r0, 0
 66	andi.	r30, r30, (MSR_EE|MSR_RI)
 67	or	r31, r31, r30
 68
 69	/* Put MSR back into magic page */
 70	STL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
 71
 72	/* Check if we have to fetch an interrupt */
 73	lwz	r31, (KVM_MAGIC_PAGE + KVM_MAGIC_INT)(0)
 74	cmpwi	r31, 0
 75	beq+	no_check
 76
 77	/* Check if we may trigger an interrupt */
 78	andi.	r30, r30, MSR_EE
 79	beq	no_check
 80
 81	SCRATCH_RESTORE
 82
 83	/* Nag hypervisor */
 84kvm_emulate_mtmsrd_orig_ins:
 85	tlbsync
 86
 87	b	kvm_emulate_mtmsrd_branch
 88
 89no_check:
 90
 91	SCRATCH_RESTORE
 92
 93	/* Go back to caller */
 94kvm_emulate_mtmsrd_branch:
 95	b	.
 96kvm_emulate_mtmsrd_end:
 97
 98.global kvm_emulate_mtmsrd_branch_offs
 99kvm_emulate_mtmsrd_branch_offs:
100	.long (kvm_emulate_mtmsrd_branch - kvm_emulate_mtmsrd) / 4
101
102.global kvm_emulate_mtmsrd_reg_offs
103kvm_emulate_mtmsrd_reg_offs:
104	.long (kvm_emulate_mtmsrd_reg - kvm_emulate_mtmsrd) / 4
105
106.global kvm_emulate_mtmsrd_orig_ins_offs
107kvm_emulate_mtmsrd_orig_ins_offs:
108	.long (kvm_emulate_mtmsrd_orig_ins - kvm_emulate_mtmsrd) / 4
109
110.global kvm_emulate_mtmsrd_len
111kvm_emulate_mtmsrd_len:
112	.long (kvm_emulate_mtmsrd_end - kvm_emulate_mtmsrd) / 4
113
114
115#define MSR_SAFE_BITS (MSR_EE | MSR_RI)
116#define MSR_CRITICAL_BITS ~MSR_SAFE_BITS
117
118.global kvm_emulate_mtmsr
119kvm_emulate_mtmsr:
120
121	SCRATCH_SAVE
122
123	/* Fetch old MSR in r31 */
124	LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
125
126	/* Find the changed bits between old and new MSR */
127kvm_emulate_mtmsr_reg1:
128	ori	r30, r0, 0
129	xor	r31, r30, r31
130
131	/* Check if we need to really do mtmsr */
132	LOAD_REG_IMMEDIATE(r30, MSR_CRITICAL_BITS)
133	and.	r31, r31, r30
134
135	/* No critical bits changed? Maybe we can stay in the guest. */
136	beq	maybe_stay_in_guest
137
138do_mtmsr:
139
140	SCRATCH_RESTORE
141
142	/* Just fire off the mtmsr if it's critical */
143kvm_emulate_mtmsr_orig_ins:
144	mtmsr	r0
145
146	b	kvm_emulate_mtmsr_branch
147
148maybe_stay_in_guest:
149
150	/* Get the target register in r30 */
151kvm_emulate_mtmsr_reg2:
152	ori	r30, r0, 0
153
154	/* Put MSR into magic page because we don't call mtmsr */
155	STL64(r30, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
156
157	/* Check if we have to fetch an interrupt */
158	lwz	r31, (KVM_MAGIC_PAGE + KVM_MAGIC_INT)(0)
159	cmpwi	r31, 0
160	beq+	no_mtmsr
161
162	/* Check if we may trigger an interrupt */
163	andi.	r31, r30, MSR_EE
164	bne	do_mtmsr
165
166no_mtmsr:
167
168	SCRATCH_RESTORE
169
170	/* Go back to caller */
171kvm_emulate_mtmsr_branch:
172	b	.
173kvm_emulate_mtmsr_end:
174
175.global kvm_emulate_mtmsr_branch_offs
176kvm_emulate_mtmsr_branch_offs:
177	.long (kvm_emulate_mtmsr_branch - kvm_emulate_mtmsr) / 4
178
179.global kvm_emulate_mtmsr_reg1_offs
180kvm_emulate_mtmsr_reg1_offs:
181	.long (kvm_emulate_mtmsr_reg1 - kvm_emulate_mtmsr) / 4
182
183.global kvm_emulate_mtmsr_reg2_offs
184kvm_emulate_mtmsr_reg2_offs:
185	.long (kvm_emulate_mtmsr_reg2 - kvm_emulate_mtmsr) / 4
186
187.global kvm_emulate_mtmsr_orig_ins_offs
188kvm_emulate_mtmsr_orig_ins_offs:
189	.long (kvm_emulate_mtmsr_orig_ins - kvm_emulate_mtmsr) / 4
190
191.global kvm_emulate_mtmsr_len
192kvm_emulate_mtmsr_len:
193	.long (kvm_emulate_mtmsr_end - kvm_emulate_mtmsr) / 4
194
195#ifdef CONFIG_BOOKE
196
197/* also used for wrteei 1 */
198.global kvm_emulate_wrtee
199kvm_emulate_wrtee:
200
201	SCRATCH_SAVE
202
203	/* Fetch old MSR in r31 */
204	LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
205
206	/* Insert new MSR[EE] */
207kvm_emulate_wrtee_reg:
208	ori	r30, r0, 0
209	rlwimi	r31, r30, 0, MSR_EE
210
211	/*
212	 * If MSR[EE] is now set, check for a pending interrupt.
213	 * We could skip this if MSR[EE] was already on, but that
214	 * should be rare, so don't bother.
215	 */
216	andi.	r30, r30, MSR_EE
217
218	/* Put MSR into magic page because we don't call wrtee */
219	STL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
220
221	beq	no_wrtee
222
223	/* Check if we have to fetch an interrupt */
224	lwz	r30, (KVM_MAGIC_PAGE + KVM_MAGIC_INT)(0)
225	cmpwi	r30, 0
226	bne	do_wrtee
227
228no_wrtee:
229	SCRATCH_RESTORE
230
231	/* Go back to caller */
232kvm_emulate_wrtee_branch:
233	b	.
234
235do_wrtee:
236	SCRATCH_RESTORE
237
238	/* Just fire off the wrtee if it's critical */
239kvm_emulate_wrtee_orig_ins:
240	wrtee	r0
241
242	b	kvm_emulate_wrtee_branch
243
244kvm_emulate_wrtee_end:
245
246.global kvm_emulate_wrtee_branch_offs
247kvm_emulate_wrtee_branch_offs:
248	.long (kvm_emulate_wrtee_branch - kvm_emulate_wrtee) / 4
249
250.global kvm_emulate_wrtee_reg_offs
251kvm_emulate_wrtee_reg_offs:
252	.long (kvm_emulate_wrtee_reg - kvm_emulate_wrtee) / 4
253
254.global kvm_emulate_wrtee_orig_ins_offs
255kvm_emulate_wrtee_orig_ins_offs:
256	.long (kvm_emulate_wrtee_orig_ins - kvm_emulate_wrtee) / 4
257
258.global kvm_emulate_wrtee_len
259kvm_emulate_wrtee_len:
260	.long (kvm_emulate_wrtee_end - kvm_emulate_wrtee) / 4
261
262.global kvm_emulate_wrteei_0
263kvm_emulate_wrteei_0:
264	SCRATCH_SAVE
265
266	/* Fetch old MSR in r31 */
267	LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
268
269	/* Remove MSR_EE from old MSR */
270	rlwinm	r31, r31, 0, ~MSR_EE
271
272	/* Write new MSR value back */
273	STL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
274
275	SCRATCH_RESTORE
276
277	/* Go back to caller */
278kvm_emulate_wrteei_0_branch:
279	b	.
280kvm_emulate_wrteei_0_end:
281
282.global kvm_emulate_wrteei_0_branch_offs
283kvm_emulate_wrteei_0_branch_offs:
284	.long (kvm_emulate_wrteei_0_branch - kvm_emulate_wrteei_0) / 4
285
286.global kvm_emulate_wrteei_0_len
287kvm_emulate_wrteei_0_len:
288	.long (kvm_emulate_wrteei_0_end - kvm_emulate_wrteei_0) / 4
289
290#endif /* CONFIG_BOOKE */
291
292#ifdef CONFIG_PPC_BOOK3S_32
293
294.global kvm_emulate_mtsrin
295kvm_emulate_mtsrin:
296
297	SCRATCH_SAVE
298
299	LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
300	andi.	r31, r31, MSR_DR | MSR_IR
301	beq	kvm_emulate_mtsrin_reg1
302
303	SCRATCH_RESTORE
304
305kvm_emulate_mtsrin_orig_ins:
306	nop
307	b	kvm_emulate_mtsrin_branch
308
309kvm_emulate_mtsrin_reg1:
310	/* rX >> 26 */
311	rlwinm  r30,r0,6,26,29
312
313kvm_emulate_mtsrin_reg2:
314	stw	r0, (KVM_MAGIC_PAGE + KVM_MAGIC_SR)(r30)
315
316	SCRATCH_RESTORE
317
318	/* Go back to caller */
319kvm_emulate_mtsrin_branch:
320	b	.
321kvm_emulate_mtsrin_end:
322
323.global kvm_emulate_mtsrin_branch_offs
324kvm_emulate_mtsrin_branch_offs:
325	.long (kvm_emulate_mtsrin_branch - kvm_emulate_mtsrin) / 4
326
327.global kvm_emulate_mtsrin_reg1_offs
328kvm_emulate_mtsrin_reg1_offs:
329	.long (kvm_emulate_mtsrin_reg1 - kvm_emulate_mtsrin) / 4
330
331.global kvm_emulate_mtsrin_reg2_offs
332kvm_emulate_mtsrin_reg2_offs:
333	.long (kvm_emulate_mtsrin_reg2 - kvm_emulate_mtsrin) / 4
334
335.global kvm_emulate_mtsrin_orig_ins_offs
336kvm_emulate_mtsrin_orig_ins_offs:
337	.long (kvm_emulate_mtsrin_orig_ins - kvm_emulate_mtsrin) / 4
338
339.global kvm_emulate_mtsrin_len
340kvm_emulate_mtsrin_len:
341	.long (kvm_emulate_mtsrin_end - kvm_emulate_mtsrin) / 4
342
343#endif /* CONFIG_PPC_BOOK3S_32 */
344
345	.balign 4
346	.global kvm_tmp
347kvm_tmp:
348	.space	(64 * 1024)
349
350.global kvm_tmp_end
351kvm_tmp_end:
352
353.global kvm_template_end
354kvm_template_end:
v3.5.6
 
  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 2010
 16 * Copyright 2010-2011 Freescale Semiconductor, Inc.
 17 *
 18 * Authors: Alexander Graf <agraf@suse.de>
 19 */
 20
 21#include <asm/ppc_asm.h>
 22#include <asm/kvm_asm.h>
 23#include <asm/reg.h>
 24#include <asm/page.h>
 25#include <asm/asm-offsets.h>
 26
 27/* Hypercall entry point. Will be patched with device tree instructions. */
 28
 29.global kvm_hypercall_start
 30kvm_hypercall_start:
 31	li	r3, -1
 32	nop
 33	nop
 34	nop
 35	blr
 36
 37#define KVM_MAGIC_PAGE		(-4096)
 38
 39#ifdef CONFIG_64BIT
 40#define LL64(reg, offs, reg2)	ld	reg, (offs)(reg2)
 41#define STL64(reg, offs, reg2)	std	reg, (offs)(reg2)
 42#else
 43#define LL64(reg, offs, reg2)	lwz	reg, (offs + 4)(reg2)
 44#define STL64(reg, offs, reg2)	stw	reg, (offs + 4)(reg2)
 45#endif
 46
 47#define SCRATCH_SAVE							\
 48	/* Enable critical section. We are critical if			\
 49	   shared->critical == r1 */					\
 50	STL64(r1, KVM_MAGIC_PAGE + KVM_MAGIC_CRITICAL, 0);		\
 51									\
 52	/* Save state */						\
 53	PPC_STL	r31, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH1)(0);		\
 54	PPC_STL	r30, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH2)(0);		\
 55	mfcr	r31;							\
 56	stw	r31, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH3)(0);
 57
 58#define SCRATCH_RESTORE							\
 59	/* Restore state */						\
 60	PPC_LL	r31, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH1)(0);		\
 61	lwz	r30, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH3)(0);		\
 62	mtcr	r30;							\
 63	PPC_LL	r30, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH2)(0);		\
 64									\
 65	/* Disable critical section. We are critical if			\
 66	   shared->critical == r1 and r2 is always != r1 */		\
 67	STL64(r2, KVM_MAGIC_PAGE + KVM_MAGIC_CRITICAL, 0);
 68
 69.global kvm_template_start
 70kvm_template_start:
 71
 72.global kvm_emulate_mtmsrd
 73kvm_emulate_mtmsrd:
 74
 75	SCRATCH_SAVE
 76
 77	/* Put MSR & ~(MSR_EE|MSR_RI) in r31 */
 78	LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
 79	lis	r30, (~(MSR_EE | MSR_RI))@h
 80	ori	r30, r30, (~(MSR_EE | MSR_RI))@l
 81	and	r31, r31, r30
 82
 83	/* OR the register's (MSR_EE|MSR_RI) on MSR */
 84kvm_emulate_mtmsrd_reg:
 85	ori	r30, r0, 0
 86	andi.	r30, r30, (MSR_EE|MSR_RI)
 87	or	r31, r31, r30
 88
 89	/* Put MSR back into magic page */
 90	STL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
 91
 92	/* Check if we have to fetch an interrupt */
 93	lwz	r31, (KVM_MAGIC_PAGE + KVM_MAGIC_INT)(0)
 94	cmpwi	r31, 0
 95	beq+	no_check
 96
 97	/* Check if we may trigger an interrupt */
 98	andi.	r30, r30, MSR_EE
 99	beq	no_check
100
101	SCRATCH_RESTORE
102
103	/* Nag hypervisor */
104kvm_emulate_mtmsrd_orig_ins:
105	tlbsync
106
107	b	kvm_emulate_mtmsrd_branch
108
109no_check:
110
111	SCRATCH_RESTORE
112
113	/* Go back to caller */
114kvm_emulate_mtmsrd_branch:
115	b	.
116kvm_emulate_mtmsrd_end:
117
118.global kvm_emulate_mtmsrd_branch_offs
119kvm_emulate_mtmsrd_branch_offs:
120	.long (kvm_emulate_mtmsrd_branch - kvm_emulate_mtmsrd) / 4
121
122.global kvm_emulate_mtmsrd_reg_offs
123kvm_emulate_mtmsrd_reg_offs:
124	.long (kvm_emulate_mtmsrd_reg - kvm_emulate_mtmsrd) / 4
125
126.global kvm_emulate_mtmsrd_orig_ins_offs
127kvm_emulate_mtmsrd_orig_ins_offs:
128	.long (kvm_emulate_mtmsrd_orig_ins - kvm_emulate_mtmsrd) / 4
129
130.global kvm_emulate_mtmsrd_len
131kvm_emulate_mtmsrd_len:
132	.long (kvm_emulate_mtmsrd_end - kvm_emulate_mtmsrd) / 4
133
134
135#define MSR_SAFE_BITS (MSR_EE | MSR_CE | MSR_ME | MSR_RI)
136#define MSR_CRITICAL_BITS ~MSR_SAFE_BITS
137
138.global kvm_emulate_mtmsr
139kvm_emulate_mtmsr:
140
141	SCRATCH_SAVE
142
143	/* Fetch old MSR in r31 */
144	LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
145
146	/* Find the changed bits between old and new MSR */
147kvm_emulate_mtmsr_reg1:
148	ori	r30, r0, 0
149	xor	r31, r30, r31
150
151	/* Check if we need to really do mtmsr */
152	LOAD_REG_IMMEDIATE(r30, MSR_CRITICAL_BITS)
153	and.	r31, r31, r30
154
155	/* No critical bits changed? Maybe we can stay in the guest. */
156	beq	maybe_stay_in_guest
157
158do_mtmsr:
159
160	SCRATCH_RESTORE
161
162	/* Just fire off the mtmsr if it's critical */
163kvm_emulate_mtmsr_orig_ins:
164	mtmsr	r0
165
166	b	kvm_emulate_mtmsr_branch
167
168maybe_stay_in_guest:
169
170	/* Get the target register in r30 */
171kvm_emulate_mtmsr_reg2:
172	ori	r30, r0, 0
173
174	/* Put MSR into magic page because we don't call mtmsr */
175	STL64(r30, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
176
177	/* Check if we have to fetch an interrupt */
178	lwz	r31, (KVM_MAGIC_PAGE + KVM_MAGIC_INT)(0)
179	cmpwi	r31, 0
180	beq+	no_mtmsr
181
182	/* Check if we may trigger an interrupt */
183	andi.	r31, r30, MSR_EE
184	bne	do_mtmsr
185
186no_mtmsr:
187
188	SCRATCH_RESTORE
189
190	/* Go back to caller */
191kvm_emulate_mtmsr_branch:
192	b	.
193kvm_emulate_mtmsr_end:
194
195.global kvm_emulate_mtmsr_branch_offs
196kvm_emulate_mtmsr_branch_offs:
197	.long (kvm_emulate_mtmsr_branch - kvm_emulate_mtmsr) / 4
198
199.global kvm_emulate_mtmsr_reg1_offs
200kvm_emulate_mtmsr_reg1_offs:
201	.long (kvm_emulate_mtmsr_reg1 - kvm_emulate_mtmsr) / 4
202
203.global kvm_emulate_mtmsr_reg2_offs
204kvm_emulate_mtmsr_reg2_offs:
205	.long (kvm_emulate_mtmsr_reg2 - kvm_emulate_mtmsr) / 4
206
207.global kvm_emulate_mtmsr_orig_ins_offs
208kvm_emulate_mtmsr_orig_ins_offs:
209	.long (kvm_emulate_mtmsr_orig_ins - kvm_emulate_mtmsr) / 4
210
211.global kvm_emulate_mtmsr_len
212kvm_emulate_mtmsr_len:
213	.long (kvm_emulate_mtmsr_end - kvm_emulate_mtmsr) / 4
214
 
 
215/* also used for wrteei 1 */
216.global kvm_emulate_wrtee
217kvm_emulate_wrtee:
218
219	SCRATCH_SAVE
220
221	/* Fetch old MSR in r31 */
222	LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
223
224	/* Insert new MSR[EE] */
225kvm_emulate_wrtee_reg:
226	ori	r30, r0, 0
227	rlwimi	r31, r30, 0, MSR_EE
228
229	/*
230	 * If MSR[EE] is now set, check for a pending interrupt.
231	 * We could skip this if MSR[EE] was already on, but that
232	 * should be rare, so don't bother.
233	 */
234	andi.	r30, r30, MSR_EE
235
236	/* Put MSR into magic page because we don't call wrtee */
237	STL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
238
239	beq	no_wrtee
240
241	/* Check if we have to fetch an interrupt */
242	lwz	r30, (KVM_MAGIC_PAGE + KVM_MAGIC_INT)(0)
243	cmpwi	r30, 0
244	bne	do_wrtee
245
246no_wrtee:
247	SCRATCH_RESTORE
248
249	/* Go back to caller */
250kvm_emulate_wrtee_branch:
251	b	.
252
253do_wrtee:
254	SCRATCH_RESTORE
255
256	/* Just fire off the wrtee if it's critical */
257kvm_emulate_wrtee_orig_ins:
258	wrtee	r0
259
260	b	kvm_emulate_wrtee_branch
261
262kvm_emulate_wrtee_end:
263
264.global kvm_emulate_wrtee_branch_offs
265kvm_emulate_wrtee_branch_offs:
266	.long (kvm_emulate_wrtee_branch - kvm_emulate_wrtee) / 4
267
268.global kvm_emulate_wrtee_reg_offs
269kvm_emulate_wrtee_reg_offs:
270	.long (kvm_emulate_wrtee_reg - kvm_emulate_wrtee) / 4
271
272.global kvm_emulate_wrtee_orig_ins_offs
273kvm_emulate_wrtee_orig_ins_offs:
274	.long (kvm_emulate_wrtee_orig_ins - kvm_emulate_wrtee) / 4
275
276.global kvm_emulate_wrtee_len
277kvm_emulate_wrtee_len:
278	.long (kvm_emulate_wrtee_end - kvm_emulate_wrtee) / 4
279
280.global kvm_emulate_wrteei_0
281kvm_emulate_wrteei_0:
282	SCRATCH_SAVE
283
284	/* Fetch old MSR in r31 */
285	LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
286
287	/* Remove MSR_EE from old MSR */
288	rlwinm	r31, r31, 0, ~MSR_EE
289
290	/* Write new MSR value back */
291	STL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
292
293	SCRATCH_RESTORE
294
295	/* Go back to caller */
296kvm_emulate_wrteei_0_branch:
297	b	.
298kvm_emulate_wrteei_0_end:
299
300.global kvm_emulate_wrteei_0_branch_offs
301kvm_emulate_wrteei_0_branch_offs:
302	.long (kvm_emulate_wrteei_0_branch - kvm_emulate_wrteei_0) / 4
303
304.global kvm_emulate_wrteei_0_len
305kvm_emulate_wrteei_0_len:
306	.long (kvm_emulate_wrteei_0_end - kvm_emulate_wrteei_0) / 4
307
 
 
 
 
308.global kvm_emulate_mtsrin
309kvm_emulate_mtsrin:
310
311	SCRATCH_SAVE
312
313	LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
314	andi.	r31, r31, MSR_DR | MSR_IR
315	beq	kvm_emulate_mtsrin_reg1
316
317	SCRATCH_RESTORE
318
319kvm_emulate_mtsrin_orig_ins:
320	nop
321	b	kvm_emulate_mtsrin_branch
322
323kvm_emulate_mtsrin_reg1:
324	/* rX >> 26 */
325	rlwinm  r30,r0,6,26,29
326
327kvm_emulate_mtsrin_reg2:
328	stw	r0, (KVM_MAGIC_PAGE + KVM_MAGIC_SR)(r30)
329
330	SCRATCH_RESTORE
331
332	/* Go back to caller */
333kvm_emulate_mtsrin_branch:
334	b	.
335kvm_emulate_mtsrin_end:
336
337.global kvm_emulate_mtsrin_branch_offs
338kvm_emulate_mtsrin_branch_offs:
339	.long (kvm_emulate_mtsrin_branch - kvm_emulate_mtsrin) / 4
340
341.global kvm_emulate_mtsrin_reg1_offs
342kvm_emulate_mtsrin_reg1_offs:
343	.long (kvm_emulate_mtsrin_reg1 - kvm_emulate_mtsrin) / 4
344
345.global kvm_emulate_mtsrin_reg2_offs
346kvm_emulate_mtsrin_reg2_offs:
347	.long (kvm_emulate_mtsrin_reg2 - kvm_emulate_mtsrin) / 4
348
349.global kvm_emulate_mtsrin_orig_ins_offs
350kvm_emulate_mtsrin_orig_ins_offs:
351	.long (kvm_emulate_mtsrin_orig_ins - kvm_emulate_mtsrin) / 4
352
353.global kvm_emulate_mtsrin_len
354kvm_emulate_mtsrin_len:
355	.long (kvm_emulate_mtsrin_end - kvm_emulate_mtsrin) / 4
 
 
 
 
 
 
 
 
 
 
356
357.global kvm_template_end
358kvm_template_end: