emulate.c revision 8e5b26b55a8b6aee2c789b1d20ec715f9e4bea5c
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
867706664d39a8eb8555408a24b1f17bd2086189c6Alexander Graf	/* mtdec lowers the interrupt line when positive. */
877706664d39a8eb8555408a24b1f17bd2086189c6Alexander Graf	kvmppc_core_dequeue_dec(vcpu);
887706664d39a8eb8555408a24b1f17bd2086189c6Alexander Graf
89513579e3a391a3874c478a8493080822069976e8Alexander Graf	/* POWER4+ triggers a dec interrupt if the value is < 0 */
90513579e3a391a3874c478a8493080822069976e8Alexander Graf	if (vcpu->arch.dec & 0x80000000) {
91544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
92513579e3a391a3874c478a8493080822069976e8Alexander Graf		kvmppc_core_queue_dec(vcpu);
93513579e3a391a3874c478a8493080822069976e8Alexander Graf		return;
94513579e3a391a3874c478a8493080822069976e8Alexander Graf	}
95513579e3a391a3874c478a8493080822069976e8Alexander Graf#endif
96513579e3a391a3874c478a8493080822069976e8Alexander Graf	if (kvmppc_dec_enabled(vcpu)) {
97bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		/* The decrementer ticks at the same rate as the timebase, so
98bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		 * that's how we convert the guest DEC value to the number of
99bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		 * host ticks. */
100bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
101544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
102544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		dec_nsec = vcpu->arch.dec;
103544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		dec_nsec *= 1000;
104544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		dec_nsec /= tb_ticks_per_usec;
105544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		hrtimer_start(&vcpu->arch.dec_timer, ktime_set(0, dec_nsec),
106544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf			      HRTIMER_MODE_REL);
107513579e3a391a3874c478a8493080822069976e8Alexander Graf		vcpu->arch.dec_jiffies = get_tb();
108bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	} else {
109544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
110bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	}
111bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard}
112bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
113bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard/* XXX to do:
114bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lhax
115bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lhaux
116bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lswx
117bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lswi
118bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * stswx
119bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * stswi
120bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lha
121bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lhau
122bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lmw
123bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * stmw
124bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard *
125bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * XXX is_bigendian should depend on MMU mapping or MSR[LE]
126bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard */
12775f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard/* XXX Should probably auto-generate instruction decoding for a particular core
12875f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard * from opcode tables in the future. */
129bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchardint kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
130bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard{
131bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	u32 inst = vcpu->arch.last_inst;
132bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	u32 ea;
133bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int ra;
134bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int rb;
135bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int rs;
136bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int rt;
137bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int sprn;
138bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	enum emulation_result emulated = EMULATE_DONE;
139bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int advance = 1;
140bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
14173e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard	/* this default type might be overwritten by subcategories */
14273e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard	kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
14373e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard
144513579e3a391a3874c478a8493080822069976e8Alexander Graf	pr_debug(KERN_INFO "Emulating opcode %d / %d\n", get_op(inst), get_xop(inst));
145513579e3a391a3874c478a8493080822069976e8Alexander Graf
146bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	switch (get_op(inst)) {
147cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_TRAP:
148513579e3a391a3874c478a8493080822069976e8Alexander Graf#ifdef CONFIG_PPC64
149513579e3a391a3874c478a8493080822069976e8Alexander Graf	case OP_TRAP_64:
150513579e3a391a3874c478a8493080822069976e8Alexander Graf#else
151fcfdbd266a41d3e41d17666de410a24995fde03aHollis Blanchard		vcpu->arch.esr |= ESR_PTR;
152513579e3a391a3874c478a8493080822069976e8Alexander Graf#endif
1539dd921cfea734409a931ccc6eafd7f09850311e9Hollis Blanchard		kvmppc_core_queue_program(vcpu);
154bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		advance = 0;
155bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
156bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
157bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	case 31:
158bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		switch (get_xop(inst)) {
159bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
160cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LWZX:
161ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			rt = get_rt(inst);
162ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
163ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			break;
164ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard
165cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LBZX:
166bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
167bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
168bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
169bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
170cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STWX:
171ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			rs = get_rs(inst);
172ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
1738e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
174ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			                               4, 1);
175ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			break;
176ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard
177cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STBX:
178bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
179bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
1808e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
181bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               1, 1);
182bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
183bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
184cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STBUX:
185bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
186bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
187bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
188bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
1898e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			ea = kvmppc_get_gpr(vcpu, rb);
190bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			if (ra)
1918e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				ea += kvmppc_get_gpr(vcpu, ra);
192bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
193bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
1948e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
195bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               1, 1);
1968e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			kvmppc_set_gpr(vcpu, rs, ea);
197bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
198bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
199cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LHZX:
200bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
201bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
202bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
203bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
204cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LHZUX:
205bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
206bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
207bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
208bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
2098e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			ea = kvmppc_get_gpr(vcpu, rb);
210bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			if (ra)
2118e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				ea += kvmppc_get_gpr(vcpu, ra);
212bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
213bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
2148e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			kvmppc_set_gpr(vcpu, ra, ea);
215bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
216bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
217cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_MFSPR:
218bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			sprn = get_sprn(inst);
219bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
220bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
221bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			switch (sprn) {
222bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR0:
2238e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.srr0); break;
224bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR1:
2258e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.srr1); break;
226bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_PVR:
2278e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.pvr); break;
22806579dd9c12f36ac575460a226d2020d84a0128bLiu Yu			case SPRN_PIR:
2298e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->vcpu_id); break;
230513579e3a391a3874c478a8493080822069976e8Alexander Graf			case SPRN_MSSSR0:
2318e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, 0); break;
232bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
233bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* Note: mftb and TBRL/TBWL are user-accessible, so
234bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * the guest can always access the real TB anyways.
235bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * In fact, we probably will never see these traps. */
236bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWL:
2378e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, get_tb() >> 32); break;
238bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWU:
2398e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, get_tb()); break;
240bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
241bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG0:
2428e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg0); break;
243bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG1:
2448e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg1); break;
245bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG2:
2468e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg2); break;
247bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG3:
2488e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg3); break;
249bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* Note: SPRG4-7 are user-readable, so we don't get
250bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * a trap. */
251bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
2529a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf			case SPRN_DEC:
2539a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf			{
254513579e3a391a3874c478a8493080822069976e8Alexander Graf				u64 jd = get_tb() - vcpu->arch.dec_jiffies;
2558e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.dec - jd);
2568e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				pr_debug(KERN_INFO "mfDEC: %x - %llx = %lx\n",
2578e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					 vcpu->arch.dec, jd,
2588e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					 kvmppc_get_gpr(vcpu, rt));
2599a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf				break;
2609a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf			}
261bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			default:
26275f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, rt);
26375f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				if (emulated == EMULATE_FAIL) {
26475f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard					printk("mfspr: unknown spr %x\n", sprn);
2658e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					kvmppc_set_gpr(vcpu, rt, 0);
26675f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				}
267bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				break;
268bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			}
269bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
270bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
271cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STHX:
272bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
273bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
274bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
275bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
276bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
2778e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
278bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               2, 1);
279bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
280bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
281cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STHUX:
282bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
283bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
284bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
285bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
2868e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			ea = kvmppc_get_gpr(vcpu, rb);
287bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			if (ra)
2888e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				ea += kvmppc_get_gpr(vcpu, ra);
289bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
290bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
2918e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
292bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               2, 1);
2938e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			kvmppc_set_gpr(vcpu, ra, ea);
294bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
295bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
296cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_MTSPR:
297bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			sprn = get_sprn(inst);
298bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
299bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			switch (sprn) {
300bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR0:
3018e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				vcpu->arch.srr0 = kvmppc_get_gpr(vcpu, rs); break;
302bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR1:
3038e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				vcpu->arch.srr1 = kvmppc_get_gpr(vcpu, rs); break;
304bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
305bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* XXX We need to context-switch the timebase for
306bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * watchdog and FIT. */
307bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWL: break;
308bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWU: break;
309bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
310513579e3a391a3874c478a8493080822069976e8Alexander Graf			case SPRN_MSSSR0: break;
311513579e3a391a3874c478a8493080822069976e8Alexander Graf
312bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_DEC:
3138e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				vcpu->arch.dec = kvmppc_get_gpr(vcpu, rs);
314bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				kvmppc_emulate_dec(vcpu);
315bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				break;
316bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
317bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG0:
3188e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				vcpu->arch.sprg0 = kvmppc_get_gpr(vcpu, rs); break;
319bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG1:
3208e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				vcpu->arch.sprg1 = kvmppc_get_gpr(vcpu, rs); break;
321bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG2:
3228e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				vcpu->arch.sprg2 = kvmppc_get_gpr(vcpu, rs); break;
323bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG3:
3248e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				vcpu->arch.sprg3 = kvmppc_get_gpr(vcpu, rs); break;
325bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
326bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			default:
32775f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				emulated = kvmppc_core_emulate_mtspr(vcpu, sprn, rs);
32875f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				if (emulated == EMULATE_FAIL)
32975f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard					printk("mtspr: unknown spr %x\n", sprn);
330bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				break;
331bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			}
332bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
333bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
334cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_DCBI:
335bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* Do nothing. The guest is performing dcbi because
336bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * hardware DMA is not snooped by the dcache, but
337bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * emulated DMA either goes through the dcache as
338bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * normal writes, or the host kernel has handled dcache
339bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * coherence. */
340bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
341bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
342cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LWBRX:
343bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
344bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0);
345bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
346bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
347cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_TLBSYNC:
348bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
349bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
350cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STWBRX:
351bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
352bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
353bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
354bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
355bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
3568e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
357bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               4, 0);
358bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
359bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
360cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LHBRX:
361bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
362bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0);
363bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
364bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
365cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STHBRX:
366bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
367bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
368bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
369bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
370bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
3718e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
372bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               2, 0);
373bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
374bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
375bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		default:
37675f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			/* Attempt core-specific emulation below. */
377bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = EMULATE_FAIL;
378bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		}
379bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
380bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
381cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LWZ:
382bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
383bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
384bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
385bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
386cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LWZU:
387bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
388bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
389bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
3908e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
391bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
392bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
393cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LBZ:
394bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
395bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
396bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
397bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
398cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LBZU:
399bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
400bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
401bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
4028e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
403bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
404bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
405cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STW:
406bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4078e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4088e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
409bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               4, 1);
410bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
411bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
412cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STWU:
413bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
414bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4158e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4168e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
417bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               4, 1);
4188e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
419bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
420bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
421cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STB:
422bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4238e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4248e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
425bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               1, 1);
426bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
427bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
428cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STBU:
429bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
430bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4318e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4328e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
433bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               1, 1);
4348e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
435bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
436bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
437cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LHZ:
438bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
439bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
440bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
441bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
442cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LHZU:
443bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
444bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
445bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
4468e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
447bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
448bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
449cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STH:
450bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4518e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4528e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
453bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               2, 1);
454bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
455bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
456cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STHU:
457bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
458bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4598e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4608e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
461bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               2, 1);
4628e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
463bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
464bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
465bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	default:
466bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = EMULATE_FAIL;
46775f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard	}
46875f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard
46975f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard	if (emulated == EMULATE_FAIL) {
47075f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard		emulated = kvmppc_core_emulate_op(run, vcpu, inst, &advance);
47175f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard		if (emulated == EMULATE_FAIL) {
47275f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			advance = 0;
47375f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			printk(KERN_ERR "Couldn't emulate instruction 0x%08x "
47475f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			       "(op %d xop %d)\n", inst, get_op(inst), get_xop(inst));
47575f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard		}
476bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	}
477bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
47846f43c6ee022c3aeb9686b104234b9f27fac03c2Marcelo Tosatti	trace_kvm_ppc_instr(inst, vcpu->arch.pc, emulated);
4793b4bd7969f7b61a1ab455bff084ee4f0a2411055Christian Ehrhardt
480bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	if (advance)
481bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		vcpu->arch.pc += 4; /* Advance past emulated instruction. */
482bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
483bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	return emulated;
484bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard}
485