blob: c4e3ec63f253802a6475329cc463a62fbbe8dbdc [file] [log] [blame]
Alexander Grafc215c6e2009-10-30 05:47:14 +00001/*
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 2009
16 *
17 * Authors: Alexander Graf <agraf@suse.de>
18 */
19
20#include <asm/kvm_ppc.h>
21#include <asm/disassemble.h>
22#include <asm/kvm_book3s.h>
23#include <asm/reg.h>
Benjamin Herrenschmidt95327d02012-04-01 17:35:53 +000024#include <asm/switch_to.h>
Paul Mackerrasb0a94d42012-11-04 18:15:43 +000025#include <asm/time.h>
Thomas Huth5358a962015-05-22 09:25:02 +020026#include "book3s.h"
Simon Guo533082a2018-05-23 15:02:00 +080027#include <asm/asm-prototypes.h>
Alexander Grafc215c6e2009-10-30 05:47:14 +000028
29#define OP_19_XOP_RFID 18
30#define OP_19_XOP_RFI 50
31
32#define OP_31_XOP_MFMSR 83
33#define OP_31_XOP_MTMSR 146
34#define OP_31_XOP_MTMSRD 178
Alexander Graf71db4082010-02-19 11:00:37 +010035#define OP_31_XOP_MTSR 210
Alexander Grafc215c6e2009-10-30 05:47:14 +000036#define OP_31_XOP_MTSRIN 242
37#define OP_31_XOP_TLBIEL 274
38#define OP_31_XOP_TLBIE 306
Alexander Graf50c7bb82012-12-14 23:42:05 +010039/* Opcode is officially reserved, reuse it as sc 1 when sc 1 doesn't trap */
40#define OP_31_XOP_FAKE_SC1 308
Alexander Grafc215c6e2009-10-30 05:47:14 +000041#define OP_31_XOP_SLBMTE 402
42#define OP_31_XOP_SLBIE 434
43#define OP_31_XOP_SLBIA 498
Alexander Grafc6648762010-03-24 21:48:24 +010044#define OP_31_XOP_MFSR 595
Alexander Grafc215c6e2009-10-30 05:47:14 +000045#define OP_31_XOP_MFSRIN 659
Alexander Grafbd7cdbb2010-03-24 21:48:33 +010046#define OP_31_XOP_DCBA 758
Alexander Grafc215c6e2009-10-30 05:47:14 +000047#define OP_31_XOP_SLBMFEV 851
48#define OP_31_XOP_EIOIO 854
49#define OP_31_XOP_SLBMFEE 915
50
51/* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */
52#define OP_31_XOP_DCBZ 1010
53
Alexander Grafca7f4202010-03-24 21:48:28 +010054#define OP_LFS 48
55#define OP_LFD 50
56#define OP_STFS 52
57#define OP_STFD 54
58
Alexander Grafd6d549b2010-02-19 11:00:33 +010059#define SPRN_GQR0 912
60#define SPRN_GQR1 913
61#define SPRN_GQR2 914
62#define SPRN_GQR3 915
63#define SPRN_GQR4 916
64#define SPRN_GQR5 917
65#define SPRN_GQR6 918
66#define SPRN_GQR7 919
67
Alexander Graf07b09072010-04-16 00:11:53 +020068/* Book3S_32 defines mfsrin(v) - but that messes up our abstract
69 * function pointers, so let's just disable the define. */
70#undef mfsrin
71
Alexander Graf317a8fa2011-08-08 16:07:16 +020072enum priv_level {
73 PRIV_PROBLEM = 0,
74 PRIV_SUPER = 1,
75 PRIV_HYPER = 2,
76};
77
78static bool spr_allowed(struct kvm_vcpu *vcpu, enum priv_level level)
79{
80 /* PAPR VMs only access supervisor SPRs */
81 if (vcpu->arch.papr_enabled && (level > PRIV_SUPER))
82 return false;
83
84 /* Limit user space to its own small SPR set */
Alexander Graf5deb8e72014-04-24 13:46:24 +020085 if ((kvmppc_get_msr(vcpu) & MSR_PR) && level > PRIV_PROBLEM)
Alexander Graf317a8fa2011-08-08 16:07:16 +020086 return false;
87
88 return true;
89}
90
Simon Guode7ad932018-05-23 15:01:56 +080091#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
92static inline void kvmppc_copyto_vcpu_tm(struct kvm_vcpu *vcpu)
93{
94 memcpy(&vcpu->arch.gpr_tm[0], &vcpu->arch.regs.gpr[0],
95 sizeof(vcpu->arch.gpr_tm));
96 memcpy(&vcpu->arch.fp_tm, &vcpu->arch.fp,
97 sizeof(struct thread_fp_state));
98 memcpy(&vcpu->arch.vr_tm, &vcpu->arch.vr,
99 sizeof(struct thread_vr_state));
100 vcpu->arch.ppr_tm = vcpu->arch.ppr;
101 vcpu->arch.dscr_tm = vcpu->arch.dscr;
102 vcpu->arch.amr_tm = vcpu->arch.amr;
103 vcpu->arch.ctr_tm = vcpu->arch.regs.ctr;
104 vcpu->arch.tar_tm = vcpu->arch.tar;
105 vcpu->arch.lr_tm = vcpu->arch.regs.link;
106 vcpu->arch.cr_tm = vcpu->arch.cr;
107 vcpu->arch.xer_tm = vcpu->arch.regs.xer;
108 vcpu->arch.vrsave_tm = vcpu->arch.vrsave;
109}
110
111static inline void kvmppc_copyfrom_vcpu_tm(struct kvm_vcpu *vcpu)
112{
113 memcpy(&vcpu->arch.regs.gpr[0], &vcpu->arch.gpr_tm[0],
114 sizeof(vcpu->arch.regs.gpr));
115 memcpy(&vcpu->arch.fp, &vcpu->arch.fp_tm,
116 sizeof(struct thread_fp_state));
117 memcpy(&vcpu->arch.vr, &vcpu->arch.vr_tm,
118 sizeof(struct thread_vr_state));
119 vcpu->arch.ppr = vcpu->arch.ppr_tm;
120 vcpu->arch.dscr = vcpu->arch.dscr_tm;
121 vcpu->arch.amr = vcpu->arch.amr_tm;
122 vcpu->arch.regs.ctr = vcpu->arch.ctr_tm;
123 vcpu->arch.tar = vcpu->arch.tar_tm;
124 vcpu->arch.regs.link = vcpu->arch.lr_tm;
125 vcpu->arch.cr = vcpu->arch.cr_tm;
126 vcpu->arch.regs.xer = vcpu->arch.xer_tm;
127 vcpu->arch.vrsave = vcpu->arch.vrsave_tm;
128}
129
130#endif
131
Aneesh Kumar K.V3a167bea2013-10-07 22:17:53 +0530132int kvmppc_core_emulate_op_pr(struct kvm_run *run, struct kvm_vcpu *vcpu,
133 unsigned int inst, int *advance)
Alexander Grafc215c6e2009-10-30 05:47:14 +0000134{
135 int emulated = EMULATE_DONE;
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200136 int rt = get_rt(inst);
137 int rs = get_rs(inst);
138 int ra = get_ra(inst);
139 int rb = get_rb(inst);
Alexander Graf42188362014-05-13 17:05:51 +0200140 u32 inst_sc = 0x44000002;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000141
142 switch (get_op(inst)) {
Alexander Graf42188362014-05-13 17:05:51 +0200143 case 0:
144 emulated = EMULATE_FAIL;
145 if ((kvmppc_get_msr(vcpu) & MSR_LE) &&
146 (inst == swab32(inst_sc))) {
147 /*
148 * This is the byte reversed syscall instruction of our
149 * hypercall handler. Early versions of LE Linux didn't
150 * swap the instructions correctly and ended up in
151 * illegal instructions.
152 * Just always fail hypercalls on these broken systems.
153 */
154 kvmppc_set_gpr(vcpu, 3, EV_UNIMPLEMENTED);
155 kvmppc_set_pc(vcpu, kvmppc_get_pc(vcpu) + 4);
156 emulated = EMULATE_DONE;
157 }
158 break;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000159 case 19:
160 switch (get_xop(inst)) {
161 case OP_19_XOP_RFID:
Simon Guo401a89e2018-05-23 15:01:54 +0800162 case OP_19_XOP_RFI: {
163 unsigned long srr1 = kvmppc_get_srr1(vcpu);
164#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
165 unsigned long cur_msr = kvmppc_get_msr(vcpu);
166
167 /*
168 * add rules to fit in ISA specification regarding TM
169 * state transistion in TM disable/Suspended state,
170 * and target TM state is TM inactive(00) state. (the
171 * change should be suppressed).
172 */
173 if (((cur_msr & MSR_TM) == 0) &&
174 ((srr1 & MSR_TM) == 0) &&
175 MSR_TM_SUSPENDED(cur_msr) &&
176 !MSR_TM_ACTIVE(srr1))
177 srr1 |= MSR_TS_S;
178#endif
Alexander Graf5deb8e72014-04-24 13:46:24 +0200179 kvmppc_set_pc(vcpu, kvmppc_get_srr0(vcpu));
Simon Guo401a89e2018-05-23 15:01:54 +0800180 kvmppc_set_msr(vcpu, srr1);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000181 *advance = 0;
182 break;
Simon Guo401a89e2018-05-23 15:01:54 +0800183 }
Alexander Grafc215c6e2009-10-30 05:47:14 +0000184
185 default:
186 emulated = EMULATE_FAIL;
187 break;
188 }
189 break;
190 case 31:
191 switch (get_xop(inst)) {
192 case OP_31_XOP_MFMSR:
Alexander Graf5deb8e72014-04-24 13:46:24 +0200193 kvmppc_set_gpr(vcpu, rt, kvmppc_get_msr(vcpu));
Alexander Grafc215c6e2009-10-30 05:47:14 +0000194 break;
195 case OP_31_XOP_MTMSRD:
196 {
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200197 ulong rs_val = kvmppc_get_gpr(vcpu, rs);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000198 if (inst & 0x10000) {
Alexander Graf5deb8e72014-04-24 13:46:24 +0200199 ulong new_msr = kvmppc_get_msr(vcpu);
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200200 new_msr &= ~(MSR_RI | MSR_EE);
201 new_msr |= rs_val & (MSR_RI | MSR_EE);
Alexander Graf5deb8e72014-04-24 13:46:24 +0200202 kvmppc_set_msr_fast(vcpu, new_msr);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000203 } else
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200204 kvmppc_set_msr(vcpu, rs_val);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000205 break;
206 }
207 case OP_31_XOP_MTMSR:
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200208 kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, rs));
Alexander Grafc215c6e2009-10-30 05:47:14 +0000209 break;
Alexander Grafc6648762010-03-24 21:48:24 +0100210 case OP_31_XOP_MFSR:
211 {
212 int srnum;
213
214 srnum = kvmppc_get_field(inst, 12 + 32, 15 + 32);
215 if (vcpu->arch.mmu.mfsrin) {
216 u32 sr;
217 sr = vcpu->arch.mmu.mfsrin(vcpu, srnum);
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200218 kvmppc_set_gpr(vcpu, rt, sr);
Alexander Grafc6648762010-03-24 21:48:24 +0100219 }
220 break;
221 }
Alexander Grafc215c6e2009-10-30 05:47:14 +0000222 case OP_31_XOP_MFSRIN:
223 {
224 int srnum;
225
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200226 srnum = (kvmppc_get_gpr(vcpu, rb) >> 28) & 0xf;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000227 if (vcpu->arch.mmu.mfsrin) {
228 u32 sr;
229 sr = vcpu->arch.mmu.mfsrin(vcpu, srnum);
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200230 kvmppc_set_gpr(vcpu, rt, sr);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000231 }
232 break;
233 }
Alexander Graf71db4082010-02-19 11:00:37 +0100234 case OP_31_XOP_MTSR:
235 vcpu->arch.mmu.mtsrin(vcpu,
236 (inst >> 16) & 0xf,
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200237 kvmppc_get_gpr(vcpu, rs));
Alexander Graf71db4082010-02-19 11:00:37 +0100238 break;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000239 case OP_31_XOP_MTSRIN:
240 vcpu->arch.mmu.mtsrin(vcpu,
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200241 (kvmppc_get_gpr(vcpu, rb) >> 28) & 0xf,
242 kvmppc_get_gpr(vcpu, rs));
Alexander Grafc215c6e2009-10-30 05:47:14 +0000243 break;
244 case OP_31_XOP_TLBIE:
245 case OP_31_XOP_TLBIEL:
246 {
247 bool large = (inst & 0x00200000) ? true : false;
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200248 ulong addr = kvmppc_get_gpr(vcpu, rb);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000249 vcpu->arch.mmu.tlbie(vcpu, addr, large);
250 break;
251 }
Aneesh Kumar K.V2ba9f0d2013-10-07 22:17:59 +0530252#ifdef CONFIG_PPC_BOOK3S_64
Alexander Graf50c7bb82012-12-14 23:42:05 +0100253 case OP_31_XOP_FAKE_SC1:
254 {
255 /* SC 1 papr hypercalls */
256 ulong cmd = kvmppc_get_gpr(vcpu, 3);
257 int i;
258
Alexander Graf5deb8e72014-04-24 13:46:24 +0200259 if ((kvmppc_get_msr(vcpu) & MSR_PR) ||
Alexander Graf50c7bb82012-12-14 23:42:05 +0100260 !vcpu->arch.papr_enabled) {
261 emulated = EMULATE_FAIL;
262 break;
263 }
264
265 if (kvmppc_h_pr(vcpu, cmd) == EMULATE_DONE)
266 break;
267
268 run->papr_hcall.nr = cmd;
269 for (i = 0; i < 9; ++i) {
270 ulong gpr = kvmppc_get_gpr(vcpu, 4 + i);
271 run->papr_hcall.args[i] = gpr;
272 }
273
Bharat Bhushan0f47f9b2013-04-08 00:32:14 +0000274 run->exit_reason = KVM_EXIT_PAPR_HCALL;
275 vcpu->arch.hcall_needed = 1;
Bharat Bhushanc402a3f2013-04-08 00:32:13 +0000276 emulated = EMULATE_EXIT_USER;
Alexander Graf50c7bb82012-12-14 23:42:05 +0100277 break;
278 }
279#endif
Alexander Grafc215c6e2009-10-30 05:47:14 +0000280 case OP_31_XOP_EIOIO:
281 break;
282 case OP_31_XOP_SLBMTE:
283 if (!vcpu->arch.mmu.slbmte)
284 return EMULATE_FAIL;
285
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100286 vcpu->arch.mmu.slbmte(vcpu,
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200287 kvmppc_get_gpr(vcpu, rs),
288 kvmppc_get_gpr(vcpu, rb));
Alexander Grafc215c6e2009-10-30 05:47:14 +0000289 break;
290 case OP_31_XOP_SLBIE:
291 if (!vcpu->arch.mmu.slbie)
292 return EMULATE_FAIL;
293
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100294 vcpu->arch.mmu.slbie(vcpu,
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200295 kvmppc_get_gpr(vcpu, rb));
Alexander Grafc215c6e2009-10-30 05:47:14 +0000296 break;
297 case OP_31_XOP_SLBIA:
298 if (!vcpu->arch.mmu.slbia)
299 return EMULATE_FAIL;
300
301 vcpu->arch.mmu.slbia(vcpu);
302 break;
303 case OP_31_XOP_SLBMFEE:
304 if (!vcpu->arch.mmu.slbmfee) {
305 emulated = EMULATE_FAIL;
306 } else {
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200307 ulong t, rb_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000308
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200309 rb_val = kvmppc_get_gpr(vcpu, rb);
310 t = vcpu->arch.mmu.slbmfee(vcpu, rb_val);
311 kvmppc_set_gpr(vcpu, rt, t);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000312 }
313 break;
314 case OP_31_XOP_SLBMFEV:
315 if (!vcpu->arch.mmu.slbmfev) {
316 emulated = EMULATE_FAIL;
317 } else {
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200318 ulong t, rb_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000319
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200320 rb_val = kvmppc_get_gpr(vcpu, rb);
321 t = vcpu->arch.mmu.slbmfev(vcpu, rb_val);
322 kvmppc_set_gpr(vcpu, rt, t);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000323 }
324 break;
Alexander Grafbd7cdbb2010-03-24 21:48:33 +0100325 case OP_31_XOP_DCBA:
326 /* Gets treated as NOP */
327 break;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000328 case OP_31_XOP_DCBZ:
329 {
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200330 ulong rb_val = kvmppc_get_gpr(vcpu, rb);
331 ulong ra_val = 0;
Alexander Graf5467a972010-02-19 11:00:38 +0100332 ulong addr, vaddr;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000333 u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
Alexander Graf9fb244a2010-03-24 21:48:32 +0100334 u32 dsisr;
335 int r;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000336
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200337 if (ra)
338 ra_val = kvmppc_get_gpr(vcpu, ra);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000339
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200340 addr = (ra_val + rb_val) & ~31ULL;
Alexander Graf5deb8e72014-04-24 13:46:24 +0200341 if (!(kvmppc_get_msr(vcpu) & MSR_SF))
Alexander Grafc215c6e2009-10-30 05:47:14 +0000342 addr &= 0xffffffff;
Alexander Graf5467a972010-02-19 11:00:38 +0100343 vaddr = addr;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000344
Alexander Graf9fb244a2010-03-24 21:48:32 +0100345 r = kvmppc_st(vcpu, &addr, 32, zeros, true);
346 if ((r == -ENOENT) || (r == -EPERM)) {
347 *advance = 0;
Alexander Graf5deb8e72014-04-24 13:46:24 +0200348 kvmppc_set_dar(vcpu, vaddr);
Paul Mackerrasa2d56022013-09-20 14:52:43 +1000349 vcpu->arch.fault_dar = vaddr;
Alexander Graf9fb244a2010-03-24 21:48:32 +0100350
351 dsisr = DSISR_ISSTORE;
352 if (r == -ENOENT)
353 dsisr |= DSISR_NOHPTE;
354 else if (r == -EPERM)
355 dsisr |= DSISR_PROTFAULT;
356
Alexander Graf5deb8e72014-04-24 13:46:24 +0200357 kvmppc_set_dsisr(vcpu, dsisr);
Paul Mackerrasa2d56022013-09-20 14:52:43 +1000358 vcpu->arch.fault_dsisr = dsisr;
Alexander Graf9fb244a2010-03-24 21:48:32 +0100359
Alexander Grafc215c6e2009-10-30 05:47:14 +0000360 kvmppc_book3s_queue_irqprio(vcpu,
361 BOOK3S_INTERRUPT_DATA_STORAGE);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000362 }
363
364 break;
365 }
366 default:
367 emulated = EMULATE_FAIL;
368 }
369 break;
370 default:
371 emulated = EMULATE_FAIL;
372 }
373
Alexander Graf831317b2010-02-19 11:00:44 +0100374 if (emulated == EMULATE_FAIL)
375 emulated = kvmppc_emulate_paired_single(run, vcpu);
376
Alexander Grafc215c6e2009-10-30 05:47:14 +0000377 return emulated;
378}
379
Alexander Grafe15a1132009-11-30 03:02:02 +0000380void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper,
381 u32 val)
382{
383 if (upper) {
384 /* Upper BAT */
385 u32 bl = (val >> 2) & 0x7ff;
386 bat->bepi_mask = (~bl << 17);
387 bat->bepi = val & 0xfffe0000;
388 bat->vs = (val & 2) ? 1 : 0;
389 bat->vp = (val & 1) ? 1 : 0;
390 bat->raw = (bat->raw & 0xffffffff00000000ULL) | val;
391 } else {
392 /* Lower BAT */
393 bat->brpn = val & 0xfffe0000;
394 bat->wimg = (val >> 3) & 0xf;
395 bat->pp = val & 3;
396 bat->raw = (bat->raw & 0x00000000ffffffffULL) | ((u64)val << 32);
397 }
398}
399
Alexander Grafc1c88e22010-08-02 23:23:04 +0200400static struct kvmppc_bat *kvmppc_find_bat(struct kvm_vcpu *vcpu, int sprn)
Alexander Grafc04a6952010-03-24 21:48:25 +0100401{
402 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
403 struct kvmppc_bat *bat;
404
405 switch (sprn) {
406 case SPRN_IBAT0U ... SPRN_IBAT3L:
407 bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2];
408 break;
409 case SPRN_IBAT4U ... SPRN_IBAT7L:
410 bat = &vcpu_book3s->ibat[4 + ((sprn - SPRN_IBAT4U) / 2)];
411 break;
412 case SPRN_DBAT0U ... SPRN_DBAT3L:
413 bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2];
414 break;
415 case SPRN_DBAT4U ... SPRN_DBAT7L:
416 bat = &vcpu_book3s->dbat[4 + ((sprn - SPRN_DBAT4U) / 2)];
417 break;
418 default:
419 BUG();
420 }
421
Alexander Grafc1c88e22010-08-02 23:23:04 +0200422 return bat;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000423}
424
Aneesh Kumar K.V3a167bea2013-10-07 22:17:53 +0530425int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
Alexander Grafc215c6e2009-10-30 05:47:14 +0000426{
427 int emulated = EMULATE_DONE;
428
429 switch (sprn) {
430 case SPRN_SDR1:
Alexander Graf317a8fa2011-08-08 16:07:16 +0200431 if (!spr_allowed(vcpu, PRIV_HYPER))
432 goto unprivileged;
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100433 to_book3s(vcpu)->sdr1 = spr_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000434 break;
435 case SPRN_DSISR:
Alexander Graf5deb8e72014-04-24 13:46:24 +0200436 kvmppc_set_dsisr(vcpu, spr_val);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000437 break;
438 case SPRN_DAR:
Alexander Graf5deb8e72014-04-24 13:46:24 +0200439 kvmppc_set_dar(vcpu, spr_val);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000440 break;
441 case SPRN_HIOR:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100442 to_book3s(vcpu)->hior = spr_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000443 break;
444 case SPRN_IBAT0U ... SPRN_IBAT3L:
445 case SPRN_IBAT4U ... SPRN_IBAT7L:
446 case SPRN_DBAT0U ... SPRN_DBAT3L:
447 case SPRN_DBAT4U ... SPRN_DBAT7L:
Alexander Grafc1c88e22010-08-02 23:23:04 +0200448 {
449 struct kvmppc_bat *bat = kvmppc_find_bat(vcpu, sprn);
450
451 kvmppc_set_bat(vcpu, bat, !(sprn % 2), (u32)spr_val);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000452 /* BAT writes happen so rarely that we're ok to flush
453 * everything here */
454 kvmppc_mmu_pte_flush(vcpu, 0, 0);
Alexander Grafc04a6952010-03-24 21:48:25 +0100455 kvmppc_mmu_flush_segments(vcpu);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000456 break;
Alexander Grafc1c88e22010-08-02 23:23:04 +0200457 }
Alexander Grafc215c6e2009-10-30 05:47:14 +0000458 case SPRN_HID0:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100459 to_book3s(vcpu)->hid[0] = spr_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000460 break;
461 case SPRN_HID1:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100462 to_book3s(vcpu)->hid[1] = spr_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000463 break;
464 case SPRN_HID2:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100465 to_book3s(vcpu)->hid[2] = spr_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000466 break;
Alexander Grafd6d549b2010-02-19 11:00:33 +0100467 case SPRN_HID2_GEKKO:
468 to_book3s(vcpu)->hid[2] = spr_val;
469 /* HID2.PSE controls paired single on gekko */
470 switch (vcpu->arch.pvr) {
471 case 0x00080200: /* lonestar 2.0 */
472 case 0x00088202: /* lonestar 2.2 */
473 case 0x70000100: /* gekko 1.0 */
474 case 0x00080100: /* gekko 2.0 */
475 case 0x00083203: /* gekko 2.3a */
476 case 0x00083213: /* gekko 2.3b */
477 case 0x00083204: /* gekko 2.4 */
478 case 0x00083214: /* gekko 2.4e (8SE) - retail HW2 */
Alexander Grafb83d4a92010-04-20 02:49:54 +0200479 case 0x00087200: /* broadway */
480 if (vcpu->arch.hflags & BOOK3S_HFLAG_NATIVE_PS) {
481 /* Native paired singles */
482 } else if (spr_val & (1 << 29)) { /* HID2.PSE */
Alexander Grafd6d549b2010-02-19 11:00:33 +0100483 vcpu->arch.hflags |= BOOK3S_HFLAG_PAIRED_SINGLE;
484 kvmppc_giveup_ext(vcpu, MSR_FP);
485 } else {
486 vcpu->arch.hflags &= ~BOOK3S_HFLAG_PAIRED_SINGLE;
487 }
488 break;
489 }
490 break;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000491 case SPRN_HID4:
Alexander Grafd6d549b2010-02-19 11:00:33 +0100492 case SPRN_HID4_GEKKO:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100493 to_book3s(vcpu)->hid[4] = spr_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000494 break;
495 case SPRN_HID5:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100496 to_book3s(vcpu)->hid[5] = spr_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000497 /* guest HID5 set can change is_dcbz32 */
498 if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
499 (mfmsr() & MSR_HV))
500 vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32;
501 break;
Alexander Grafd6d549b2010-02-19 11:00:33 +0100502 case SPRN_GQR0:
503 case SPRN_GQR1:
504 case SPRN_GQR2:
505 case SPRN_GQR3:
506 case SPRN_GQR4:
507 case SPRN_GQR5:
508 case SPRN_GQR6:
509 case SPRN_GQR7:
510 to_book3s(vcpu)->gqr[sprn - SPRN_GQR0] = spr_val;
511 break;
Alexander Graf2e23f542014-04-29 13:36:21 +0200512#ifdef CONFIG_PPC_BOOK3S_64
Alexander Graf8e6afa32014-07-31 10:21:59 +0200513 case SPRN_FSCR:
514 kvmppc_set_fscr(vcpu, spr_val);
515 break;
Alexander Graf2e23f542014-04-29 13:36:21 +0200516 case SPRN_BESCR:
517 vcpu->arch.bescr = spr_val;
518 break;
519 case SPRN_EBBHR:
520 vcpu->arch.ebbhr = spr_val;
521 break;
522 case SPRN_EBBRR:
523 vcpu->arch.ebbrr = spr_val;
524 break;
Alexander Graf9916d572014-04-29 17:54:40 +0200525#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
526 case SPRN_TFHAR:
Alexander Graf9916d572014-04-29 17:54:40 +0200527 case SPRN_TEXASR:
Alexander Graf9916d572014-04-29 17:54:40 +0200528 case SPRN_TFIAR:
Simon Guo533082a2018-05-23 15:02:00 +0800529 if (!cpu_has_feature(CPU_FTR_TM))
530 break;
531
532 if (!(kvmppc_get_msr(vcpu) & MSR_TM)) {
533 kvmppc_trigger_fac_interrupt(vcpu, FSCR_TM_LG);
534 emulated = EMULATE_AGAIN;
535 break;
536 }
537
538 if (MSR_TM_ACTIVE(kvmppc_get_msr(vcpu)) &&
539 !((MSR_TM_SUSPENDED(kvmppc_get_msr(vcpu))) &&
540 (sprn == SPRN_TFHAR))) {
541 /* it is illegal to mtspr() TM regs in
542 * other than non-transactional state, with
543 * the exception of TFHAR in suspend state.
544 */
545 kvmppc_core_queue_program(vcpu, SRR1_PROGTM);
546 emulated = EMULATE_AGAIN;
547 break;
548 }
549
550 tm_enable();
551 if (sprn == SPRN_TFHAR)
552 mtspr(SPRN_TFHAR, spr_val);
553 else if (sprn == SPRN_TEXASR)
554 mtspr(SPRN_TEXASR, spr_val);
555 else
556 mtspr(SPRN_TFIAR, spr_val);
557 tm_disable();
558
Alexander Graf9916d572014-04-29 17:54:40 +0200559 break;
560#endif
Alexander Graf2e23f542014-04-29 13:36:21 +0200561#endif
Alexander Grafc215c6e2009-10-30 05:47:14 +0000562 case SPRN_ICTC:
563 case SPRN_THRM1:
564 case SPRN_THRM2:
565 case SPRN_THRM3:
566 case SPRN_CTRLF:
567 case SPRN_CTRLT:
Alexander Grafd6d549b2010-02-19 11:00:33 +0100568 case SPRN_L2CR:
Paul Mackerrasb0a94d42012-11-04 18:15:43 +0000569 case SPRN_DSCR:
Alexander Grafd6d549b2010-02-19 11:00:33 +0100570 case SPRN_MMCR0_GEKKO:
571 case SPRN_MMCR1_GEKKO:
572 case SPRN_PMC1_GEKKO:
573 case SPRN_PMC2_GEKKO:
574 case SPRN_PMC3_GEKKO:
575 case SPRN_PMC4_GEKKO:
576 case SPRN_WPAR_GEKKO:
Mihai Caramanf2be6552012-12-20 04:52:39 +0000577 case SPRN_MSSSR0:
Alexander Graff3532022013-07-02 16:15:10 +0200578 case SPRN_DABR:
Alexander Graff8f6eb02014-04-22 12:41:06 +0200579#ifdef CONFIG_PPC_BOOK3S_64
580 case SPRN_MMCRS:
581 case SPRN_MMCRA:
582 case SPRN_MMCR0:
583 case SPRN_MMCR1:
584 case SPRN_MMCR2:
Thomas Huthfa73c3b2016-09-21 15:06:45 +0200585 case SPRN_UMMCR2:
Alexander Graff8f6eb02014-04-22 12:41:06 +0200586#endif
Alexander Grafc215c6e2009-10-30 05:47:14 +0000587 break;
Alexander Graf317a8fa2011-08-08 16:07:16 +0200588unprivileged:
Alexander Grafc215c6e2009-10-30 05:47:14 +0000589 default:
Thomas Huthfeafd132017-04-05 15:58:51 +0200590 pr_info_ratelimited("KVM: invalid SPR write: %d\n", sprn);
591 if (sprn & 0x10) {
592 if (kvmppc_get_msr(vcpu) & MSR_PR) {
593 kvmppc_core_queue_program(vcpu, SRR1_PROGPRIV);
594 emulated = EMULATE_AGAIN;
595 }
596 } else {
597 if ((kvmppc_get_msr(vcpu) & MSR_PR) || sprn == 0) {
598 kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
599 emulated = EMULATE_AGAIN;
600 }
601 }
Alexander Grafc215c6e2009-10-30 05:47:14 +0000602 break;
603 }
604
605 return emulated;
606}
607
Aneesh Kumar K.V3a167bea2013-10-07 22:17:53 +0530608int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
Alexander Grafc215c6e2009-10-30 05:47:14 +0000609{
610 int emulated = EMULATE_DONE;
611
612 switch (sprn) {
Alexander Grafc04a6952010-03-24 21:48:25 +0100613 case SPRN_IBAT0U ... SPRN_IBAT3L:
614 case SPRN_IBAT4U ... SPRN_IBAT7L:
615 case SPRN_DBAT0U ... SPRN_DBAT3L:
616 case SPRN_DBAT4U ... SPRN_DBAT7L:
Alexander Grafc1c88e22010-08-02 23:23:04 +0200617 {
618 struct kvmppc_bat *bat = kvmppc_find_bat(vcpu, sprn);
619
620 if (sprn % 2)
Alexander Graf54771e62012-05-04 14:55:12 +0200621 *spr_val = bat->raw >> 32;
Alexander Grafc1c88e22010-08-02 23:23:04 +0200622 else
Alexander Graf54771e62012-05-04 14:55:12 +0200623 *spr_val = bat->raw;
Alexander Grafc1c88e22010-08-02 23:23:04 +0200624
Alexander Grafc04a6952010-03-24 21:48:25 +0100625 break;
Alexander Grafc1c88e22010-08-02 23:23:04 +0200626 }
Alexander Grafc215c6e2009-10-30 05:47:14 +0000627 case SPRN_SDR1:
Alexander Graf317a8fa2011-08-08 16:07:16 +0200628 if (!spr_allowed(vcpu, PRIV_HYPER))
629 goto unprivileged;
Alexander Graf54771e62012-05-04 14:55:12 +0200630 *spr_val = to_book3s(vcpu)->sdr1;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000631 break;
632 case SPRN_DSISR:
Alexander Graf5deb8e72014-04-24 13:46:24 +0200633 *spr_val = kvmppc_get_dsisr(vcpu);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000634 break;
635 case SPRN_DAR:
Alexander Graf5deb8e72014-04-24 13:46:24 +0200636 *spr_val = kvmppc_get_dar(vcpu);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000637 break;
638 case SPRN_HIOR:
Alexander Graf54771e62012-05-04 14:55:12 +0200639 *spr_val = to_book3s(vcpu)->hior;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000640 break;
641 case SPRN_HID0:
Alexander Graf54771e62012-05-04 14:55:12 +0200642 *spr_val = to_book3s(vcpu)->hid[0];
Alexander Grafc215c6e2009-10-30 05:47:14 +0000643 break;
644 case SPRN_HID1:
Alexander Graf54771e62012-05-04 14:55:12 +0200645 *spr_val = to_book3s(vcpu)->hid[1];
Alexander Grafc215c6e2009-10-30 05:47:14 +0000646 break;
647 case SPRN_HID2:
Alexander Grafd6d549b2010-02-19 11:00:33 +0100648 case SPRN_HID2_GEKKO:
Alexander Graf54771e62012-05-04 14:55:12 +0200649 *spr_val = to_book3s(vcpu)->hid[2];
Alexander Grafc215c6e2009-10-30 05:47:14 +0000650 break;
651 case SPRN_HID4:
Alexander Grafd6d549b2010-02-19 11:00:33 +0100652 case SPRN_HID4_GEKKO:
Alexander Graf54771e62012-05-04 14:55:12 +0200653 *spr_val = to_book3s(vcpu)->hid[4];
Alexander Grafc215c6e2009-10-30 05:47:14 +0000654 break;
655 case SPRN_HID5:
Alexander Graf54771e62012-05-04 14:55:12 +0200656 *spr_val = to_book3s(vcpu)->hid[5];
Alexander Grafc215c6e2009-10-30 05:47:14 +0000657 break;
Alexander Grafaacf9aa2011-08-08 17:22:59 +0200658 case SPRN_CFAR:
Paul Mackerrasb0a94d42012-11-04 18:15:43 +0000659 case SPRN_DSCR:
Alexander Graf54771e62012-05-04 14:55:12 +0200660 *spr_val = 0;
Alexander Grafaacf9aa2011-08-08 17:22:59 +0200661 break;
Paul Mackerrasb0a94d42012-11-04 18:15:43 +0000662 case SPRN_PURR:
Aneesh Kumar K.V3cd60e32014-06-04 16:47:55 +0530663 /*
664 * On exit we would have updated purr
665 */
666 *spr_val = vcpu->arch.purr;
Paul Mackerrasb0a94d42012-11-04 18:15:43 +0000667 break;
668 case SPRN_SPURR:
Aneesh Kumar K.V3cd60e32014-06-04 16:47:55 +0530669 /*
670 * On exit we would have updated spurr
671 */
672 *spr_val = vcpu->arch.spurr;
Paul Mackerrasb0a94d42012-11-04 18:15:43 +0000673 break;
Aneesh Kumar K.V8f42ab22014-06-05 17:38:02 +0530674 case SPRN_VTB:
Paul Mackerras88b02cf92016-09-15 13:42:52 +1000675 *spr_val = to_book3s(vcpu)->vtb;
Aneesh Kumar K.V8f42ab22014-06-05 17:38:02 +0530676 break;
Aneesh Kumar K.V06da28e2014-06-05 17:38:05 +0530677 case SPRN_IC:
678 *spr_val = vcpu->arch.ic;
679 break;
Alexander Grafd6d549b2010-02-19 11:00:33 +0100680 case SPRN_GQR0:
681 case SPRN_GQR1:
682 case SPRN_GQR2:
683 case SPRN_GQR3:
684 case SPRN_GQR4:
685 case SPRN_GQR5:
686 case SPRN_GQR6:
687 case SPRN_GQR7:
Alexander Graf54771e62012-05-04 14:55:12 +0200688 *spr_val = to_book3s(vcpu)->gqr[sprn - SPRN_GQR0];
Alexander Grafd6d549b2010-02-19 11:00:33 +0100689 break;
Alexander Graf8e6afa32014-07-31 10:21:59 +0200690#ifdef CONFIG_PPC_BOOK3S_64
Alexander Graf616dff82014-04-29 16:48:44 +0200691 case SPRN_FSCR:
692 *spr_val = vcpu->arch.fscr;
693 break;
Alexander Graf2e23f542014-04-29 13:36:21 +0200694 case SPRN_BESCR:
695 *spr_val = vcpu->arch.bescr;
696 break;
697 case SPRN_EBBHR:
698 *spr_val = vcpu->arch.ebbhr;
699 break;
700 case SPRN_EBBRR:
701 *spr_val = vcpu->arch.ebbrr;
702 break;
Alexander Graf9916d572014-04-29 17:54:40 +0200703#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
704 case SPRN_TFHAR:
Alexander Graf9916d572014-04-29 17:54:40 +0200705 case SPRN_TEXASR:
Alexander Graf9916d572014-04-29 17:54:40 +0200706 case SPRN_TFIAR:
Simon Guo533082a2018-05-23 15:02:00 +0800707 if (!cpu_has_feature(CPU_FTR_TM))
708 break;
709
710 if (!(kvmppc_get_msr(vcpu) & MSR_TM)) {
711 kvmppc_trigger_fac_interrupt(vcpu, FSCR_TM_LG);
712 emulated = EMULATE_AGAIN;
713 break;
714 }
715
716 tm_enable();
717 if (sprn == SPRN_TFHAR)
718 *spr_val = mfspr(SPRN_TFHAR);
719 else if (sprn == SPRN_TEXASR)
720 *spr_val = mfspr(SPRN_TEXASR);
721 else if (sprn == SPRN_TFIAR)
722 *spr_val = mfspr(SPRN_TFIAR);
723 tm_disable();
Alexander Graf9916d572014-04-29 17:54:40 +0200724 break;
725#endif
Alexander Graf2e23f542014-04-29 13:36:21 +0200726#endif
Alexander Grafc215c6e2009-10-30 05:47:14 +0000727 case SPRN_THRM1:
728 case SPRN_THRM2:
729 case SPRN_THRM3:
730 case SPRN_CTRLF:
731 case SPRN_CTRLT:
Alexander Grafd6d549b2010-02-19 11:00:33 +0100732 case SPRN_L2CR:
733 case SPRN_MMCR0_GEKKO:
734 case SPRN_MMCR1_GEKKO:
735 case SPRN_PMC1_GEKKO:
736 case SPRN_PMC2_GEKKO:
737 case SPRN_PMC3_GEKKO:
738 case SPRN_PMC4_GEKKO:
739 case SPRN_WPAR_GEKKO:
Mihai Caramanf2be6552012-12-20 04:52:39 +0000740 case SPRN_MSSSR0:
Alexander Graff3532022013-07-02 16:15:10 +0200741 case SPRN_DABR:
Alexander Graff8f6eb02014-04-22 12:41:06 +0200742#ifdef CONFIG_PPC_BOOK3S_64
743 case SPRN_MMCRS:
744 case SPRN_MMCRA:
745 case SPRN_MMCR0:
746 case SPRN_MMCR1:
747 case SPRN_MMCR2:
Thomas Huthfa73c3b2016-09-21 15:06:45 +0200748 case SPRN_UMMCR2:
Alexander Grafa5948fa2014-04-25 16:07:21 +0200749 case SPRN_TIR:
Alexander Graff8f6eb02014-04-22 12:41:06 +0200750#endif
Alexander Graf54771e62012-05-04 14:55:12 +0200751 *spr_val = 0;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000752 break;
753 default:
Alexander Graf317a8fa2011-08-08 16:07:16 +0200754unprivileged:
Thomas Huthfeafd132017-04-05 15:58:51 +0200755 pr_info_ratelimited("KVM: invalid SPR read: %d\n", sprn);
756 if (sprn & 0x10) {
757 if (kvmppc_get_msr(vcpu) & MSR_PR) {
758 kvmppc_core_queue_program(vcpu, SRR1_PROGPRIV);
759 emulated = EMULATE_AGAIN;
760 }
761 } else {
762 if ((kvmppc_get_msr(vcpu) & MSR_PR) || sprn == 0 ||
763 sprn == 4 || sprn == 5 || sprn == 6) {
764 kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
765 emulated = EMULATE_AGAIN;
766 }
767 }
768
Alexander Grafc215c6e2009-10-30 05:47:14 +0000769 break;
770 }
771
772 return emulated;
773}
774
Alexander Grafca7f4202010-03-24 21:48:28 +0100775u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst)
776{
Aneesh Kumar K.Vddca1562014-05-12 17:04:06 +0530777 return make_dsisr(inst);
Alexander Grafca7f4202010-03-24 21:48:28 +0100778}
779
780ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst)
781{
Aneesh Kumar K.V7310f3a2014-05-12 17:04:05 +0530782#ifdef CONFIG_PPC_BOOK3S_64
783 /*
784 * Linux's fix_alignment() assumes that DAR is valid, so can we
785 */
786 return vcpu->arch.fault_dar;
787#else
Alexander Grafca7f4202010-03-24 21:48:28 +0100788 ulong dar = 0;
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200789 ulong ra = get_ra(inst);
790 ulong rb = get_rb(inst);
Alexander Grafca7f4202010-03-24 21:48:28 +0100791
792 switch (get_op(inst)) {
793 case OP_LFS:
794 case OP_LFD:
795 case OP_STFD:
796 case OP_STFS:
Alexander Grafca7f4202010-03-24 21:48:28 +0100797 if (ra)
798 dar = kvmppc_get_gpr(vcpu, ra);
799 dar += (s32)((s16)inst);
800 break;
801 case 31:
Alexander Grafca7f4202010-03-24 21:48:28 +0100802 if (ra)
803 dar = kvmppc_get_gpr(vcpu, ra);
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200804 dar += kvmppc_get_gpr(vcpu, rb);
Alexander Grafca7f4202010-03-24 21:48:28 +0100805 break;
806 default:
807 printk(KERN_INFO "KVM: Unaligned instruction 0x%x\n", inst);
808 break;
809 }
810
811 return dar;
Aneesh Kumar K.V7310f3a2014-05-12 17:04:05 +0530812#endif
Alexander Grafca7f4202010-03-24 21:48:28 +0100813}