emulate.c revision 544c6761bb05a1dd19a39cb9bed096273f9bdb36
1bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard/*
2bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * This program is free software; you can redistribute it and/or modify
3bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * it under the terms of the GNU General Public License, version 2, as
4bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * published by the Free Software Foundation.
5bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard *
6bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * This program is distributed in the hope that it will be useful,
7bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * but WITHOUT ANY WARRANTY; without even the implied warranty of
8bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * GNU General Public License for more details.
10bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard *
11bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * You should have received a copy of the GNU General Public License
12bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * along with this program; if not, write to the Free Software
13bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
14bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard *
15bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * Copyright IBM Corp. 2007
16bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard *
17bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard */
19bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
20bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <linux/jiffies.h>
21544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf#include <linux/hrtimer.h>
22bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <linux/types.h>
23bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <linux/string.h>
24bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <linux/kvm_host.h>
25bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
2675f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard#include <asm/reg.h>
27bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <asm/time.h>
28bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <asm/byteorder.h>
29bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <asm/kvm_ppc.h>
30c381a04313e7c0fb04246b1ff711e0b5726de6c0Hollis Blanchard#include <asm/disassemble.h>
3173e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard#include "timing.h"
3246f43c6ee022c3aeb9686b104234b9f27fac03c2Marcelo Tosatti#include "trace.h"
33bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
34cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_TRAP 3
35513579e3a391a3874c478a8493080822069976e8Alexander Graf#define OP_TRAP_64 2
36cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard
37cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LWZX      23
38cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LBZX      87
39cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STWX      151
40cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STBX      215
41cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STBUX     247
42cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LHZX      279
43cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LHZUX     311
44cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_MFSPR     339
45cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STHX      407
46cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STHUX     439
47cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_MTSPR     467
48cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_DCBI      470
49cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LWBRX     534
50cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_TLBSYNC   566
51cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STWBRX    662
52cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LHBRX     790
53cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STHBRX    918
54cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard
55cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LWZ  32
56cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LWZU 33
57cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LBZ  34
58cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LBZU 35
59cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STW  36
60cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STWU 37
61cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STB  38
62cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STBU 39
63cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LHZ  40
64cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LHZU 41
65cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STH  44
66cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STHU 45
67cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard
68513579e3a391a3874c478a8493080822069976e8Alexander Graf#ifdef CONFIG_PPC64
69513579e3a391a3874c478a8493080822069976e8Alexander Grafstatic int kvmppc_dec_enabled(struct kvm_vcpu *vcpu)
70513579e3a391a3874c478a8493080822069976e8Alexander Graf{
71513579e3a391a3874c478a8493080822069976e8Alexander Graf	return 1;
72513579e3a391a3874c478a8493080822069976e8Alexander Graf}
73513579e3a391a3874c478a8493080822069976e8Alexander Graf#else
74513579e3a391a3874c478a8493080822069976e8Alexander Grafstatic int kvmppc_dec_enabled(struct kvm_vcpu *vcpu)
75513579e3a391a3874c478a8493080822069976e8Alexander Graf{
76513579e3a391a3874c478a8493080822069976e8Alexander Graf	return vcpu->arch.tcr & TCR_DIE;
77513579e3a391a3874c478a8493080822069976e8Alexander Graf}
78513579e3a391a3874c478a8493080822069976e8Alexander Graf#endif
79513579e3a391a3874c478a8493080822069976e8Alexander Graf
8075f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchardvoid kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
81bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard{
82544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf	unsigned long dec_nsec;
839a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf
84544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf	pr_debug("mtDEC: %x\n", vcpu->arch.dec);
85513579e3a391a3874c478a8493080822069976e8Alexander Graf#ifdef CONFIG_PPC64
86513579e3a391a3874c478a8493080822069976e8Alexander Graf	/* POWER4+ triggers a dec interrupt if the value is < 0 */
87513579e3a391a3874c478a8493080822069976e8Alexander Graf	if (vcpu->arch.dec & 0x80000000) {
88544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
89513579e3a391a3874c478a8493080822069976e8Alexander Graf		kvmppc_core_queue_dec(vcpu);
90513579e3a391a3874c478a8493080822069976e8Alexander Graf		return;
91513579e3a391a3874c478a8493080822069976e8Alexander Graf	}
92513579e3a391a3874c478a8493080822069976e8Alexander Graf#endif
93513579e3a391a3874c478a8493080822069976e8Alexander Graf	if (kvmppc_dec_enabled(vcpu)) {
94bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		/* The decrementer ticks at the same rate as the timebase, so
95bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		 * that's how we convert the guest DEC value to the number of
96bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		 * host ticks. */
97bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
98544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
99544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		dec_nsec = vcpu->arch.dec;
100544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		dec_nsec *= 1000;
101544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		dec_nsec /= tb_ticks_per_usec;
102544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		hrtimer_start(&vcpu->arch.dec_timer, ktime_set(0, dec_nsec),
103544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf			      HRTIMER_MODE_REL);
104513579e3a391a3874c478a8493080822069976e8Alexander Graf		vcpu->arch.dec_jiffies = get_tb();
105bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	} else {
106544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
107bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	}
108bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard}
109bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
110bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard/* XXX to do:
111bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lhax
112bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lhaux
113bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lswx
114bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lswi
115bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * stswx
116bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * stswi
117bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lha
118bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lhau
119bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lmw
120bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * stmw
121bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard *
122bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * XXX is_bigendian should depend on MMU mapping or MSR[LE]
123bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard */
12475f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard/* XXX Should probably auto-generate instruction decoding for a particular core
12575f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard * from opcode tables in the future. */
126bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchardint kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
127bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard{
128bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	u32 inst = vcpu->arch.last_inst;
129bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	u32 ea;
130bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int ra;
131bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int rb;
132bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int rs;
133bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int rt;
134bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int sprn;
135bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	enum emulation_result emulated = EMULATE_DONE;
136bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int advance = 1;
137bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
13873e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard	/* this default type might be overwritten by subcategories */
13973e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard	kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
14073e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard
141513579e3a391a3874c478a8493080822069976e8Alexander Graf	pr_debug(KERN_INFO "Emulating opcode %d / %d\n", get_op(inst), get_xop(inst));
142513579e3a391a3874c478a8493080822069976e8Alexander Graf
143bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	switch (get_op(inst)) {
144cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_TRAP:
145513579e3a391a3874c478a8493080822069976e8Alexander Graf#ifdef CONFIG_PPC64
146513579e3a391a3874c478a8493080822069976e8Alexander Graf	case OP_TRAP_64:
147513579e3a391a3874c478a8493080822069976e8Alexander Graf#else
148fcfdbd266a41d3e41d17666de410a24995fde03aHollis Blanchard		vcpu->arch.esr |= ESR_PTR;
149513579e3a391a3874c478a8493080822069976e8Alexander Graf#endif
1509dd921cfea734409a931ccc6eafd7f09850311e9Hollis Blanchard		kvmppc_core_queue_program(vcpu);
151bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		advance = 0;
152bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
153bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
154bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	case 31:
155bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		switch (get_xop(inst)) {
156bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
157cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LWZX:
158ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			rt = get_rt(inst);
159ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
160ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			break;
161ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard
162cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LBZX:
163bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
164bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
165bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
166bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
167cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STWX:
168ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			rs = get_rs(inst);
169ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
170ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			                               vcpu->arch.gpr[rs],
171ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			                               4, 1);
172ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			break;
173ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard
174cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STBX:
175bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
176bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
177bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               vcpu->arch.gpr[rs],
178bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               1, 1);
179bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
180bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
181cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STBUX:
182bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
183bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
184bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
185bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
186bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ea = vcpu->arch.gpr[rb];
187bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			if (ra)
188bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				ea += vcpu->arch.gpr[ra];
189bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
190bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
191bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               vcpu->arch.gpr[rs],
192bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               1, 1);
193bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			vcpu->arch.gpr[rs] = ea;
194bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
195bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
196cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LHZX:
197bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
198bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
199bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
200bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
201cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LHZUX:
202bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
203bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
204bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
205bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
206bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ea = vcpu->arch.gpr[rb];
207bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			if (ra)
208bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				ea += vcpu->arch.gpr[ra];
209bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
210bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
211bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			vcpu->arch.gpr[ra] = ea;
212bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
213bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
214cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_MFSPR:
215bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			sprn = get_sprn(inst);
216bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
217bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
218bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			switch (sprn) {
219bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR0:
220bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				vcpu->arch.gpr[rt] = vcpu->arch.srr0; break;
221bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR1:
222bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				vcpu->arch.gpr[rt] = vcpu->arch.srr1; break;
223bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_PVR:
224513579e3a391a3874c478a8493080822069976e8Alexander Graf				vcpu->arch.gpr[rt] = vcpu->arch.pvr; break;
22506579dd9c12f36ac575460a226d2020d84a0128bLiu Yu			case SPRN_PIR:
226513579e3a391a3874c478a8493080822069976e8Alexander Graf				vcpu->arch.gpr[rt] = vcpu->vcpu_id; break;
227513579e3a391a3874c478a8493080822069976e8Alexander Graf			case SPRN_MSSSR0:
228513579e3a391a3874c478a8493080822069976e8Alexander Graf				vcpu->arch.gpr[rt] = 0; break;
229bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
230bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* Note: mftb and TBRL/TBWL are user-accessible, so
231bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * the guest can always access the real TB anyways.
232bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * In fact, we probably will never see these traps. */
233bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWL:
234513579e3a391a3874c478a8493080822069976e8Alexander Graf				vcpu->arch.gpr[rt] = get_tb() >> 32; break;
235bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWU:
236513579e3a391a3874c478a8493080822069976e8Alexander Graf				vcpu->arch.gpr[rt] = get_tb(); break;
237bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
238bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG0:
239bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				vcpu->arch.gpr[rt] = vcpu->arch.sprg0; break;
240bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG1:
241bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				vcpu->arch.gpr[rt] = vcpu->arch.sprg1; break;
242bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG2:
243bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				vcpu->arch.gpr[rt] = vcpu->arch.sprg2; break;
244bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG3:
245bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				vcpu->arch.gpr[rt] = vcpu->arch.sprg3; break;
246bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* Note: SPRG4-7 are user-readable, so we don't get
247bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * a trap. */
248bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
2499a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf			case SPRN_DEC:
2509a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf			{
251513579e3a391a3874c478a8493080822069976e8Alexander Graf				u64 jd = get_tb() - vcpu->arch.dec_jiffies;
2529a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf				vcpu->arch.gpr[rt] = vcpu->arch.dec - jd;
253513579e3a391a3874c478a8493080822069976e8Alexander Graf				pr_debug(KERN_INFO "mfDEC: %x - %llx = %lx\n", vcpu->arch.dec, jd, vcpu->arch.gpr[rt]);
2549a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf				break;
2559a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf			}
256bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			default:
25775f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, rt);
25875f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				if (emulated == EMULATE_FAIL) {
25975f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard					printk("mfspr: unknown spr %x\n", sprn);
26075f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard					vcpu->arch.gpr[rt] = 0;
26175f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				}
262bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				break;
263bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			}
264bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
265bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
266cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STHX:
267bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
268bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
269bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
270bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
271bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
272bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               vcpu->arch.gpr[rs],
273bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               2, 1);
274bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
275bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
276cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STHUX:
277bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
278bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
279bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
280bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
281bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ea = vcpu->arch.gpr[rb];
282bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			if (ra)
283bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				ea += vcpu->arch.gpr[ra];
284bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
285bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
286bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               vcpu->arch.gpr[rs],
287bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               2, 1);
288bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			vcpu->arch.gpr[ra] = ea;
289bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
290bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
291cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_MTSPR:
292bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			sprn = get_sprn(inst);
293bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
294bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			switch (sprn) {
295bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR0:
296bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				vcpu->arch.srr0 = vcpu->arch.gpr[rs]; break;
297bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR1:
298bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				vcpu->arch.srr1 = vcpu->arch.gpr[rs]; break;
299bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
300bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* XXX We need to context-switch the timebase for
301bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * watchdog and FIT. */
302bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWL: break;
303bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWU: break;
304bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
305513579e3a391a3874c478a8493080822069976e8Alexander Graf			case SPRN_MSSSR0: break;
306513579e3a391a3874c478a8493080822069976e8Alexander Graf
307bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_DEC:
308bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				vcpu->arch.dec = vcpu->arch.gpr[rs];
309bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				kvmppc_emulate_dec(vcpu);
310bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				break;
311bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
312bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG0:
313bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				vcpu->arch.sprg0 = vcpu->arch.gpr[rs]; break;
314bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG1:
315bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				vcpu->arch.sprg1 = vcpu->arch.gpr[rs]; break;
316bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG2:
317bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				vcpu->arch.sprg2 = vcpu->arch.gpr[rs]; break;
318bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG3:
319bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				vcpu->arch.sprg3 = vcpu->arch.gpr[rs]; break;
320bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
321bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			default:
32275f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				emulated = kvmppc_core_emulate_mtspr(vcpu, sprn, rs);
32375f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				if (emulated == EMULATE_FAIL)
32475f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard					printk("mtspr: unknown spr %x\n", sprn);
325bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				break;
326bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			}
327bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
328bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
329cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_DCBI:
330bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* Do nothing. The guest is performing dcbi because
331bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * hardware DMA is not snooped by the dcache, but
332bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * emulated DMA either goes through the dcache as
333bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * normal writes, or the host kernel has handled dcache
334bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * coherence. */
335bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
336bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
337cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LWBRX:
338bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
339bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0);
340bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
341bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
342cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_TLBSYNC:
343bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
344bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
345cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STWBRX:
346bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
347bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
348bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
349bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
350bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
351bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               vcpu->arch.gpr[rs],
352bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               4, 0);
353bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
354bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
355cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LHBRX:
356bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
357bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0);
358bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
359bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
360cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STHBRX:
361bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
362bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
363bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
364bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
365bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
366bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               vcpu->arch.gpr[rs],
367bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               2, 0);
368bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
369bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
370bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		default:
37175f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			/* Attempt core-specific emulation below. */
372bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = EMULATE_FAIL;
373bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		}
374bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
375bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
376cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LWZ:
377bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
378bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
379bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
380bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
381cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LWZU:
382bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
383bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
384bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
385bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
386bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
387bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
388cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LBZ:
389bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
390bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
391bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
392bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
393cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LBZU:
394bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
395bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
396bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
397bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
398bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
399bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
400cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STW:
401bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
402bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
403bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               4, 1);
404bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
405bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
406cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STWU:
407bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
408bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
409bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
410bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               4, 1);
411bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
412bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
413bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
414cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STB:
415bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
416bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
417bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               1, 1);
418bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
419bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
420cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STBU:
421bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
422bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
423bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
424bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               1, 1);
425bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
426bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
427bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
428cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LHZ:
429bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
430bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
431bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
432bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
433cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LHZU:
434bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
435bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
436bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
437bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
438bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
439bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
440cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STH:
441bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
442bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
443bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               2, 1);
444bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
445bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
446cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STHU:
447bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
448bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
449bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
450bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               2, 1);
451bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
452bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
453bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
454bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	default:
455bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = EMULATE_FAIL;
45675f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard	}
45775f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard
45875f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard	if (emulated == EMULATE_FAIL) {
45975f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard		emulated = kvmppc_core_emulate_op(run, vcpu, inst, &advance);
46075f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard		if (emulated == EMULATE_FAIL) {
46175f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			advance = 0;
46275f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			printk(KERN_ERR "Couldn't emulate instruction 0x%08x "
46375f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			       "(op %d xop %d)\n", inst, get_op(inst), get_xop(inst));
46475f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard		}
465bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	}
466bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
46746f43c6ee022c3aeb9686b104234b9f27fac03c2Marcelo Tosatti	trace_kvm_ppc_instr(inst, vcpu->arch.pc, emulated);
4683b4bd7969f7b61a1ab455bff084ee4f0a2411055Christian Ehrhardt
469bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	if (advance)
470bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		vcpu->arch.pc += 4; /* Advance past emulated instruction. */
471bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
472bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	return emulated;
473bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard}
474