blob: f81a921e08652fbd531fef9b6eddc5b50e5b3844 [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"
Alexander Grafc215c6e2009-10-30 05:47:14 +000027
28#define OP_19_XOP_RFID 18
29#define OP_19_XOP_RFI 50
30
31#define OP_31_XOP_MFMSR 83
32#define OP_31_XOP_MTMSR 146
33#define OP_31_XOP_MTMSRD 178
Alexander Graf71db4082010-02-19 11:00:37 +010034#define OP_31_XOP_MTSR 210
Alexander Grafc215c6e2009-10-30 05:47:14 +000035#define OP_31_XOP_MTSRIN 242
36#define OP_31_XOP_TLBIEL 274
37#define OP_31_XOP_TLBIE 306
Alexander Graf50c7bb82012-12-14 23:42:05 +010038/* Opcode is officially reserved, reuse it as sc 1 when sc 1 doesn't trap */
39#define OP_31_XOP_FAKE_SC1 308
Alexander Grafc215c6e2009-10-30 05:47:14 +000040#define OP_31_XOP_SLBMTE 402
41#define OP_31_XOP_SLBIE 434
42#define OP_31_XOP_SLBIA 498
Alexander Grafc6648762010-03-24 21:48:24 +010043#define OP_31_XOP_MFSR 595
Alexander Grafc215c6e2009-10-30 05:47:14 +000044#define OP_31_XOP_MFSRIN 659
Alexander Grafbd7cdbb2010-03-24 21:48:33 +010045#define OP_31_XOP_DCBA 758
Alexander Grafc215c6e2009-10-30 05:47:14 +000046#define OP_31_XOP_SLBMFEV 851
47#define OP_31_XOP_EIOIO 854
48#define OP_31_XOP_SLBMFEE 915
49
50/* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */
51#define OP_31_XOP_DCBZ 1010
52
Alexander Grafca7f4202010-03-24 21:48:28 +010053#define OP_LFS 48
54#define OP_LFD 50
55#define OP_STFS 52
56#define OP_STFD 54
57
Alexander Grafd6d549b2010-02-19 11:00:33 +010058#define SPRN_GQR0 912
59#define SPRN_GQR1 913
60#define SPRN_GQR2 914
61#define SPRN_GQR3 915
62#define SPRN_GQR4 916
63#define SPRN_GQR5 917
64#define SPRN_GQR6 918
65#define SPRN_GQR7 919
66
Alexander Graf07b09072010-04-16 00:11:53 +020067/* Book3S_32 defines mfsrin(v) - but that messes up our abstract
68 * function pointers, so let's just disable the define. */
69#undef mfsrin
70
Alexander Graf317a8fa2011-08-08 16:07:16 +020071enum priv_level {
72 PRIV_PROBLEM = 0,
73 PRIV_SUPER = 1,
74 PRIV_HYPER = 2,
75};
76
77static bool spr_allowed(struct kvm_vcpu *vcpu, enum priv_level level)
78{
79 /* PAPR VMs only access supervisor SPRs */
80 if (vcpu->arch.papr_enabled && (level > PRIV_SUPER))
81 return false;
82
83 /* Limit user space to its own small SPR set */
Alexander Graf5deb8e72014-04-24 13:46:24 +020084 if ((kvmppc_get_msr(vcpu) & MSR_PR) && level > PRIV_PROBLEM)
Alexander Graf317a8fa2011-08-08 16:07:16 +020085 return false;
86
87 return true;
88}
89
Simon Guode7ad932018-05-23 15:01:56 +080090#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
91static inline void kvmppc_copyto_vcpu_tm(struct kvm_vcpu *vcpu)
92{
93 memcpy(&vcpu->arch.gpr_tm[0], &vcpu->arch.regs.gpr[0],
94 sizeof(vcpu->arch.gpr_tm));
95 memcpy(&vcpu->arch.fp_tm, &vcpu->arch.fp,
96 sizeof(struct thread_fp_state));
97 memcpy(&vcpu->arch.vr_tm, &vcpu->arch.vr,
98 sizeof(struct thread_vr_state));
99 vcpu->arch.ppr_tm = vcpu->arch.ppr;
100 vcpu->arch.dscr_tm = vcpu->arch.dscr;
101 vcpu->arch.amr_tm = vcpu->arch.amr;
102 vcpu->arch.ctr_tm = vcpu->arch.regs.ctr;
103 vcpu->arch.tar_tm = vcpu->arch.tar;
104 vcpu->arch.lr_tm = vcpu->arch.regs.link;
105 vcpu->arch.cr_tm = vcpu->arch.cr;
106 vcpu->arch.xer_tm = vcpu->arch.regs.xer;
107 vcpu->arch.vrsave_tm = vcpu->arch.vrsave;
108}
109
110static inline void kvmppc_copyfrom_vcpu_tm(struct kvm_vcpu *vcpu)
111{
112 memcpy(&vcpu->arch.regs.gpr[0], &vcpu->arch.gpr_tm[0],
113 sizeof(vcpu->arch.regs.gpr));
114 memcpy(&vcpu->arch.fp, &vcpu->arch.fp_tm,
115 sizeof(struct thread_fp_state));
116 memcpy(&vcpu->arch.vr, &vcpu->arch.vr_tm,
117 sizeof(struct thread_vr_state));
118 vcpu->arch.ppr = vcpu->arch.ppr_tm;
119 vcpu->arch.dscr = vcpu->arch.dscr_tm;
120 vcpu->arch.amr = vcpu->arch.amr_tm;
121 vcpu->arch.regs.ctr = vcpu->arch.ctr_tm;
122 vcpu->arch.tar = vcpu->arch.tar_tm;
123 vcpu->arch.regs.link = vcpu->arch.lr_tm;
124 vcpu->arch.cr = vcpu->arch.cr_tm;
125 vcpu->arch.regs.xer = vcpu->arch.xer_tm;
126 vcpu->arch.vrsave = vcpu->arch.vrsave_tm;
127}
128
129#endif
130
Aneesh Kumar K.V3a167bea2013-10-07 22:17:53 +0530131int kvmppc_core_emulate_op_pr(struct kvm_run *run, struct kvm_vcpu *vcpu,
132 unsigned int inst, int *advance)
Alexander Grafc215c6e2009-10-30 05:47:14 +0000133{
134 int emulated = EMULATE_DONE;
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200135 int rt = get_rt(inst);
136 int rs = get_rs(inst);
137 int ra = get_ra(inst);
138 int rb = get_rb(inst);
Alexander Graf42188362014-05-13 17:05:51 +0200139 u32 inst_sc = 0x44000002;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000140
141 switch (get_op(inst)) {
Alexander Graf42188362014-05-13 17:05:51 +0200142 case 0:
143 emulated = EMULATE_FAIL;
144 if ((kvmppc_get_msr(vcpu) & MSR_LE) &&
145 (inst == swab32(inst_sc))) {
146 /*
147 * This is the byte reversed syscall instruction of our
148 * hypercall handler. Early versions of LE Linux didn't
149 * swap the instructions correctly and ended up in
150 * illegal instructions.
151 * Just always fail hypercalls on these broken systems.
152 */
153 kvmppc_set_gpr(vcpu, 3, EV_UNIMPLEMENTED);
154 kvmppc_set_pc(vcpu, kvmppc_get_pc(vcpu) + 4);
155 emulated = EMULATE_DONE;
156 }
157 break;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000158 case 19:
159 switch (get_xop(inst)) {
160 case OP_19_XOP_RFID:
Simon Guo401a89e2018-05-23 15:01:54 +0800161 case OP_19_XOP_RFI: {
162 unsigned long srr1 = kvmppc_get_srr1(vcpu);
163#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
164 unsigned long cur_msr = kvmppc_get_msr(vcpu);
165
166 /*
167 * add rules to fit in ISA specification regarding TM
168 * state transistion in TM disable/Suspended state,
169 * and target TM state is TM inactive(00) state. (the
170 * change should be suppressed).
171 */
172 if (((cur_msr & MSR_TM) == 0) &&
173 ((srr1 & MSR_TM) == 0) &&
174 MSR_TM_SUSPENDED(cur_msr) &&
175 !MSR_TM_ACTIVE(srr1))
176 srr1 |= MSR_TS_S;
177#endif
Alexander Graf5deb8e72014-04-24 13:46:24 +0200178 kvmppc_set_pc(vcpu, kvmppc_get_srr0(vcpu));
Simon Guo401a89e2018-05-23 15:01:54 +0800179 kvmppc_set_msr(vcpu, srr1);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000180 *advance = 0;
181 break;
Simon Guo401a89e2018-05-23 15:01:54 +0800182 }
Alexander Grafc215c6e2009-10-30 05:47:14 +0000183
184 default:
185 emulated = EMULATE_FAIL;
186 break;
187 }
188 break;
189 case 31:
190 switch (get_xop(inst)) {
191 case OP_31_XOP_MFMSR:
Alexander Graf5deb8e72014-04-24 13:46:24 +0200192 kvmppc_set_gpr(vcpu, rt, kvmppc_get_msr(vcpu));
Alexander Grafc215c6e2009-10-30 05:47:14 +0000193 break;
194 case OP_31_XOP_MTMSRD:
195 {
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200196 ulong rs_val = kvmppc_get_gpr(vcpu, rs);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000197 if (inst & 0x10000) {
Alexander Graf5deb8e72014-04-24 13:46:24 +0200198 ulong new_msr = kvmppc_get_msr(vcpu);
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200199 new_msr &= ~(MSR_RI | MSR_EE);
200 new_msr |= rs_val & (MSR_RI | MSR_EE);
Alexander Graf5deb8e72014-04-24 13:46:24 +0200201 kvmppc_set_msr_fast(vcpu, new_msr);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000202 } else
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200203 kvmppc_set_msr(vcpu, rs_val);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000204 break;
205 }
206 case OP_31_XOP_MTMSR:
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200207 kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, rs));
Alexander Grafc215c6e2009-10-30 05:47:14 +0000208 break;
Alexander Grafc6648762010-03-24 21:48:24 +0100209 case OP_31_XOP_MFSR:
210 {
211 int srnum;
212
213 srnum = kvmppc_get_field(inst, 12 + 32, 15 + 32);
214 if (vcpu->arch.mmu.mfsrin) {
215 u32 sr;
216 sr = vcpu->arch.mmu.mfsrin(vcpu, srnum);
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200217 kvmppc_set_gpr(vcpu, rt, sr);
Alexander Grafc6648762010-03-24 21:48:24 +0100218 }
219 break;
220 }
Alexander Grafc215c6e2009-10-30 05:47:14 +0000221 case OP_31_XOP_MFSRIN:
222 {
223 int srnum;
224
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200225 srnum = (kvmppc_get_gpr(vcpu, rb) >> 28) & 0xf;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000226 if (vcpu->arch.mmu.mfsrin) {
227 u32 sr;
228 sr = vcpu->arch.mmu.mfsrin(vcpu, srnum);
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200229 kvmppc_set_gpr(vcpu, rt, sr);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000230 }
231 break;
232 }
Alexander Graf71db4082010-02-19 11:00:37 +0100233 case OP_31_XOP_MTSR:
234 vcpu->arch.mmu.mtsrin(vcpu,
235 (inst >> 16) & 0xf,
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200236 kvmppc_get_gpr(vcpu, rs));
Alexander Graf71db4082010-02-19 11:00:37 +0100237 break;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000238 case OP_31_XOP_MTSRIN:
239 vcpu->arch.mmu.mtsrin(vcpu,
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200240 (kvmppc_get_gpr(vcpu, rb) >> 28) & 0xf,
241 kvmppc_get_gpr(vcpu, rs));
Alexander Grafc215c6e2009-10-30 05:47:14 +0000242 break;
243 case OP_31_XOP_TLBIE:
244 case OP_31_XOP_TLBIEL:
245 {
246 bool large = (inst & 0x00200000) ? true : false;
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200247 ulong addr = kvmppc_get_gpr(vcpu, rb);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000248 vcpu->arch.mmu.tlbie(vcpu, addr, large);
249 break;
250 }
Aneesh Kumar K.V2ba9f0d2013-10-07 22:17:59 +0530251#ifdef CONFIG_PPC_BOOK3S_64
Alexander Graf50c7bb82012-12-14 23:42:05 +0100252 case OP_31_XOP_FAKE_SC1:
253 {
254 /* SC 1 papr hypercalls */
255 ulong cmd = kvmppc_get_gpr(vcpu, 3);
256 int i;
257
Alexander Graf5deb8e72014-04-24 13:46:24 +0200258 if ((kvmppc_get_msr(vcpu) & MSR_PR) ||
Alexander Graf50c7bb82012-12-14 23:42:05 +0100259 !vcpu->arch.papr_enabled) {
260 emulated = EMULATE_FAIL;
261 break;
262 }
263
264 if (kvmppc_h_pr(vcpu, cmd) == EMULATE_DONE)
265 break;
266
267 run->papr_hcall.nr = cmd;
268 for (i = 0; i < 9; ++i) {
269 ulong gpr = kvmppc_get_gpr(vcpu, 4 + i);
270 run->papr_hcall.args[i] = gpr;
271 }
272
Bharat Bhushan0f47f9b2013-04-08 00:32:14 +0000273 run->exit_reason = KVM_EXIT_PAPR_HCALL;
274 vcpu->arch.hcall_needed = 1;
Bharat Bhushanc402a3f2013-04-08 00:32:13 +0000275 emulated = EMULATE_EXIT_USER;
Alexander Graf50c7bb82012-12-14 23:42:05 +0100276 break;
277 }
278#endif
Alexander Grafc215c6e2009-10-30 05:47:14 +0000279 case OP_31_XOP_EIOIO:
280 break;
281 case OP_31_XOP_SLBMTE:
282 if (!vcpu->arch.mmu.slbmte)
283 return EMULATE_FAIL;
284
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100285 vcpu->arch.mmu.slbmte(vcpu,
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200286 kvmppc_get_gpr(vcpu, rs),
287 kvmppc_get_gpr(vcpu, rb));
Alexander Grafc215c6e2009-10-30 05:47:14 +0000288 break;
289 case OP_31_XOP_SLBIE:
290 if (!vcpu->arch.mmu.slbie)
291 return EMULATE_FAIL;
292
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100293 vcpu->arch.mmu.slbie(vcpu,
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200294 kvmppc_get_gpr(vcpu, rb));
Alexander Grafc215c6e2009-10-30 05:47:14 +0000295 break;
296 case OP_31_XOP_SLBIA:
297 if (!vcpu->arch.mmu.slbia)
298 return EMULATE_FAIL;
299
300 vcpu->arch.mmu.slbia(vcpu);
301 break;
302 case OP_31_XOP_SLBMFEE:
303 if (!vcpu->arch.mmu.slbmfee) {
304 emulated = EMULATE_FAIL;
305 } else {
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200306 ulong t, rb_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000307
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200308 rb_val = kvmppc_get_gpr(vcpu, rb);
309 t = vcpu->arch.mmu.slbmfee(vcpu, rb_val);
310 kvmppc_set_gpr(vcpu, rt, t);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000311 }
312 break;
313 case OP_31_XOP_SLBMFEV:
314 if (!vcpu->arch.mmu.slbmfev) {
315 emulated = EMULATE_FAIL;
316 } else {
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200317 ulong t, rb_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000318
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200319 rb_val = kvmppc_get_gpr(vcpu, rb);
320 t = vcpu->arch.mmu.slbmfev(vcpu, rb_val);
321 kvmppc_set_gpr(vcpu, rt, t);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000322 }
323 break;
Alexander Grafbd7cdbb2010-03-24 21:48:33 +0100324 case OP_31_XOP_DCBA:
325 /* Gets treated as NOP */
326 break;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000327 case OP_31_XOP_DCBZ:
328 {
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200329 ulong rb_val = kvmppc_get_gpr(vcpu, rb);
330 ulong ra_val = 0;
Alexander Graf5467a972010-02-19 11:00:38 +0100331 ulong addr, vaddr;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000332 u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
Alexander Graf9fb244a2010-03-24 21:48:32 +0100333 u32 dsisr;
334 int r;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000335
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200336 if (ra)
337 ra_val = kvmppc_get_gpr(vcpu, ra);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000338
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200339 addr = (ra_val + rb_val) & ~31ULL;
Alexander Graf5deb8e72014-04-24 13:46:24 +0200340 if (!(kvmppc_get_msr(vcpu) & MSR_SF))
Alexander Grafc215c6e2009-10-30 05:47:14 +0000341 addr &= 0xffffffff;
Alexander Graf5467a972010-02-19 11:00:38 +0100342 vaddr = addr;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000343
Alexander Graf9fb244a2010-03-24 21:48:32 +0100344 r = kvmppc_st(vcpu, &addr, 32, zeros, true);
345 if ((r == -ENOENT) || (r == -EPERM)) {
346 *advance = 0;
Alexander Graf5deb8e72014-04-24 13:46:24 +0200347 kvmppc_set_dar(vcpu, vaddr);
Paul Mackerrasa2d56022013-09-20 14:52:43 +1000348 vcpu->arch.fault_dar = vaddr;
Alexander Graf9fb244a2010-03-24 21:48:32 +0100349
350 dsisr = DSISR_ISSTORE;
351 if (r == -ENOENT)
352 dsisr |= DSISR_NOHPTE;
353 else if (r == -EPERM)
354 dsisr |= DSISR_PROTFAULT;
355
Alexander Graf5deb8e72014-04-24 13:46:24 +0200356 kvmppc_set_dsisr(vcpu, dsisr);
Paul Mackerrasa2d56022013-09-20 14:52:43 +1000357 vcpu->arch.fault_dsisr = dsisr;
Alexander Graf9fb244a2010-03-24 21:48:32 +0100358
Alexander Grafc215c6e2009-10-30 05:47:14 +0000359 kvmppc_book3s_queue_irqprio(vcpu,
360 BOOK3S_INTERRUPT_DATA_STORAGE);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000361 }
362
363 break;
364 }
365 default:
366 emulated = EMULATE_FAIL;
367 }
368 break;
369 default:
370 emulated = EMULATE_FAIL;
371 }
372
Alexander Graf831317b2010-02-19 11:00:44 +0100373 if (emulated == EMULATE_FAIL)
374 emulated = kvmppc_emulate_paired_single(run, vcpu);
375
Alexander Grafc215c6e2009-10-30 05:47:14 +0000376 return emulated;
377}
378
Alexander Grafe15a1132009-11-30 03:02:02 +0000379void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper,
380 u32 val)
381{
382 if (upper) {
383 /* Upper BAT */
384 u32 bl = (val >> 2) & 0x7ff;
385 bat->bepi_mask = (~bl << 17);
386 bat->bepi = val & 0xfffe0000;
387 bat->vs = (val & 2) ? 1 : 0;
388 bat->vp = (val & 1) ? 1 : 0;
389 bat->raw = (bat->raw & 0xffffffff00000000ULL) | val;
390 } else {
391 /* Lower BAT */
392 bat->brpn = val & 0xfffe0000;
393 bat->wimg = (val >> 3) & 0xf;
394 bat->pp = val & 3;
395 bat->raw = (bat->raw & 0x00000000ffffffffULL) | ((u64)val << 32);
396 }
397}
398
Alexander Grafc1c88e22010-08-02 23:23:04 +0200399static struct kvmppc_bat *kvmppc_find_bat(struct kvm_vcpu *vcpu, int sprn)
Alexander Grafc04a6952010-03-24 21:48:25 +0100400{
401 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
402 struct kvmppc_bat *bat;
403
404 switch (sprn) {
405 case SPRN_IBAT0U ... SPRN_IBAT3L:
406 bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2];
407 break;
408 case SPRN_IBAT4U ... SPRN_IBAT7L:
409 bat = &vcpu_book3s->ibat[4 + ((sprn - SPRN_IBAT4U) / 2)];
410 break;
411 case SPRN_DBAT0U ... SPRN_DBAT3L:
412 bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2];
413 break;
414 case SPRN_DBAT4U ... SPRN_DBAT7L:
415 bat = &vcpu_book3s->dbat[4 + ((sprn - SPRN_DBAT4U) / 2)];
416 break;
417 default:
418 BUG();
419 }
420
Alexander Grafc1c88e22010-08-02 23:23:04 +0200421 return bat;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000422}
423
Aneesh Kumar K.V3a167bea2013-10-07 22:17:53 +0530424int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
Alexander Grafc215c6e2009-10-30 05:47:14 +0000425{
426 int emulated = EMULATE_DONE;
427
428 switch (sprn) {
429 case SPRN_SDR1:
Alexander Graf317a8fa2011-08-08 16:07:16 +0200430 if (!spr_allowed(vcpu, PRIV_HYPER))
431 goto unprivileged;
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100432 to_book3s(vcpu)->sdr1 = spr_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000433 break;
434 case SPRN_DSISR:
Alexander Graf5deb8e72014-04-24 13:46:24 +0200435 kvmppc_set_dsisr(vcpu, spr_val);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000436 break;
437 case SPRN_DAR:
Alexander Graf5deb8e72014-04-24 13:46:24 +0200438 kvmppc_set_dar(vcpu, spr_val);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000439 break;
440 case SPRN_HIOR:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100441 to_book3s(vcpu)->hior = spr_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000442 break;
443 case SPRN_IBAT0U ... SPRN_IBAT3L:
444 case SPRN_IBAT4U ... SPRN_IBAT7L:
445 case SPRN_DBAT0U ... SPRN_DBAT3L:
446 case SPRN_DBAT4U ... SPRN_DBAT7L:
Alexander Grafc1c88e22010-08-02 23:23:04 +0200447 {
448 struct kvmppc_bat *bat = kvmppc_find_bat(vcpu, sprn);
449
450 kvmppc_set_bat(vcpu, bat, !(sprn % 2), (u32)spr_val);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000451 /* BAT writes happen so rarely that we're ok to flush
452 * everything here */
453 kvmppc_mmu_pte_flush(vcpu, 0, 0);
Alexander Grafc04a6952010-03-24 21:48:25 +0100454 kvmppc_mmu_flush_segments(vcpu);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000455 break;
Alexander Grafc1c88e22010-08-02 23:23:04 +0200456 }
Alexander Grafc215c6e2009-10-30 05:47:14 +0000457 case SPRN_HID0:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100458 to_book3s(vcpu)->hid[0] = spr_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000459 break;
460 case SPRN_HID1:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100461 to_book3s(vcpu)->hid[1] = spr_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000462 break;
463 case SPRN_HID2:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100464 to_book3s(vcpu)->hid[2] = spr_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000465 break;
Alexander Grafd6d549b2010-02-19 11:00:33 +0100466 case SPRN_HID2_GEKKO:
467 to_book3s(vcpu)->hid[2] = spr_val;
468 /* HID2.PSE controls paired single on gekko */
469 switch (vcpu->arch.pvr) {
470 case 0x00080200: /* lonestar 2.0 */
471 case 0x00088202: /* lonestar 2.2 */
472 case 0x70000100: /* gekko 1.0 */
473 case 0x00080100: /* gekko 2.0 */
474 case 0x00083203: /* gekko 2.3a */
475 case 0x00083213: /* gekko 2.3b */
476 case 0x00083204: /* gekko 2.4 */
477 case 0x00083214: /* gekko 2.4e (8SE) - retail HW2 */
Alexander Grafb83d4a92010-04-20 02:49:54 +0200478 case 0x00087200: /* broadway */
479 if (vcpu->arch.hflags & BOOK3S_HFLAG_NATIVE_PS) {
480 /* Native paired singles */
481 } else if (spr_val & (1 << 29)) { /* HID2.PSE */
Alexander Grafd6d549b2010-02-19 11:00:33 +0100482 vcpu->arch.hflags |= BOOK3S_HFLAG_PAIRED_SINGLE;
483 kvmppc_giveup_ext(vcpu, MSR_FP);
484 } else {
485 vcpu->arch.hflags &= ~BOOK3S_HFLAG_PAIRED_SINGLE;
486 }
487 break;
488 }
489 break;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000490 case SPRN_HID4:
Alexander Grafd6d549b2010-02-19 11:00:33 +0100491 case SPRN_HID4_GEKKO:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100492 to_book3s(vcpu)->hid[4] = spr_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000493 break;
494 case SPRN_HID5:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100495 to_book3s(vcpu)->hid[5] = spr_val;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000496 /* guest HID5 set can change is_dcbz32 */
497 if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
498 (mfmsr() & MSR_HV))
499 vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32;
500 break;
Alexander Grafd6d549b2010-02-19 11:00:33 +0100501 case SPRN_GQR0:
502 case SPRN_GQR1:
503 case SPRN_GQR2:
504 case SPRN_GQR3:
505 case SPRN_GQR4:
506 case SPRN_GQR5:
507 case SPRN_GQR6:
508 case SPRN_GQR7:
509 to_book3s(vcpu)->gqr[sprn - SPRN_GQR0] = spr_val;
510 break;
Alexander Graf2e23f542014-04-29 13:36:21 +0200511#ifdef CONFIG_PPC_BOOK3S_64
Alexander Graf8e6afa32014-07-31 10:21:59 +0200512 case SPRN_FSCR:
513 kvmppc_set_fscr(vcpu, spr_val);
514 break;
Alexander Graf2e23f542014-04-29 13:36:21 +0200515 case SPRN_BESCR:
516 vcpu->arch.bescr = spr_val;
517 break;
518 case SPRN_EBBHR:
519 vcpu->arch.ebbhr = spr_val;
520 break;
521 case SPRN_EBBRR:
522 vcpu->arch.ebbrr = spr_val;
523 break;
Alexander Graf9916d572014-04-29 17:54:40 +0200524#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
525 case SPRN_TFHAR:
526 vcpu->arch.tfhar = spr_val;
527 break;
528 case SPRN_TEXASR:
529 vcpu->arch.texasr = spr_val;
530 break;
531 case SPRN_TFIAR:
532 vcpu->arch.tfiar = spr_val;
533 break;
534#endif
Alexander Graf2e23f542014-04-29 13:36:21 +0200535#endif
Alexander Grafc215c6e2009-10-30 05:47:14 +0000536 case SPRN_ICTC:
537 case SPRN_THRM1:
538 case SPRN_THRM2:
539 case SPRN_THRM3:
540 case SPRN_CTRLF:
541 case SPRN_CTRLT:
Alexander Grafd6d549b2010-02-19 11:00:33 +0100542 case SPRN_L2CR:
Paul Mackerrasb0a94d42012-11-04 18:15:43 +0000543 case SPRN_DSCR:
Alexander Grafd6d549b2010-02-19 11:00:33 +0100544 case SPRN_MMCR0_GEKKO:
545 case SPRN_MMCR1_GEKKO:
546 case SPRN_PMC1_GEKKO:
547 case SPRN_PMC2_GEKKO:
548 case SPRN_PMC3_GEKKO:
549 case SPRN_PMC4_GEKKO:
550 case SPRN_WPAR_GEKKO:
Mihai Caramanf2be6552012-12-20 04:52:39 +0000551 case SPRN_MSSSR0:
Alexander Graff3532022013-07-02 16:15:10 +0200552 case SPRN_DABR:
Alexander Graff8f6eb02014-04-22 12:41:06 +0200553#ifdef CONFIG_PPC_BOOK3S_64
554 case SPRN_MMCRS:
555 case SPRN_MMCRA:
556 case SPRN_MMCR0:
557 case SPRN_MMCR1:
558 case SPRN_MMCR2:
Thomas Huthfa73c3b2016-09-21 15:06:45 +0200559 case SPRN_UMMCR2:
Alexander Graff8f6eb02014-04-22 12:41:06 +0200560#endif
Alexander Grafc215c6e2009-10-30 05:47:14 +0000561 break;
Alexander Graf317a8fa2011-08-08 16:07:16 +0200562unprivileged:
Alexander Grafc215c6e2009-10-30 05:47:14 +0000563 default:
Thomas Huthfeafd132017-04-05 15:58:51 +0200564 pr_info_ratelimited("KVM: invalid SPR write: %d\n", sprn);
565 if (sprn & 0x10) {
566 if (kvmppc_get_msr(vcpu) & MSR_PR) {
567 kvmppc_core_queue_program(vcpu, SRR1_PROGPRIV);
568 emulated = EMULATE_AGAIN;
569 }
570 } else {
571 if ((kvmppc_get_msr(vcpu) & MSR_PR) || sprn == 0) {
572 kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
573 emulated = EMULATE_AGAIN;
574 }
575 }
Alexander Grafc215c6e2009-10-30 05:47:14 +0000576 break;
577 }
578
579 return emulated;
580}
581
Aneesh Kumar K.V3a167bea2013-10-07 22:17:53 +0530582int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
Alexander Grafc215c6e2009-10-30 05:47:14 +0000583{
584 int emulated = EMULATE_DONE;
585
586 switch (sprn) {
Alexander Grafc04a6952010-03-24 21:48:25 +0100587 case SPRN_IBAT0U ... SPRN_IBAT3L:
588 case SPRN_IBAT4U ... SPRN_IBAT7L:
589 case SPRN_DBAT0U ... SPRN_DBAT3L:
590 case SPRN_DBAT4U ... SPRN_DBAT7L:
Alexander Grafc1c88e22010-08-02 23:23:04 +0200591 {
592 struct kvmppc_bat *bat = kvmppc_find_bat(vcpu, sprn);
593
594 if (sprn % 2)
Alexander Graf54771e62012-05-04 14:55:12 +0200595 *spr_val = bat->raw >> 32;
Alexander Grafc1c88e22010-08-02 23:23:04 +0200596 else
Alexander Graf54771e62012-05-04 14:55:12 +0200597 *spr_val = bat->raw;
Alexander Grafc1c88e22010-08-02 23:23:04 +0200598
Alexander Grafc04a6952010-03-24 21:48:25 +0100599 break;
Alexander Grafc1c88e22010-08-02 23:23:04 +0200600 }
Alexander Grafc215c6e2009-10-30 05:47:14 +0000601 case SPRN_SDR1:
Alexander Graf317a8fa2011-08-08 16:07:16 +0200602 if (!spr_allowed(vcpu, PRIV_HYPER))
603 goto unprivileged;
Alexander Graf54771e62012-05-04 14:55:12 +0200604 *spr_val = to_book3s(vcpu)->sdr1;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000605 break;
606 case SPRN_DSISR:
Alexander Graf5deb8e72014-04-24 13:46:24 +0200607 *spr_val = kvmppc_get_dsisr(vcpu);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000608 break;
609 case SPRN_DAR:
Alexander Graf5deb8e72014-04-24 13:46:24 +0200610 *spr_val = kvmppc_get_dar(vcpu);
Alexander Grafc215c6e2009-10-30 05:47:14 +0000611 break;
612 case SPRN_HIOR:
Alexander Graf54771e62012-05-04 14:55:12 +0200613 *spr_val = to_book3s(vcpu)->hior;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000614 break;
615 case SPRN_HID0:
Alexander Graf54771e62012-05-04 14:55:12 +0200616 *spr_val = to_book3s(vcpu)->hid[0];
Alexander Grafc215c6e2009-10-30 05:47:14 +0000617 break;
618 case SPRN_HID1:
Alexander Graf54771e62012-05-04 14:55:12 +0200619 *spr_val = to_book3s(vcpu)->hid[1];
Alexander Grafc215c6e2009-10-30 05:47:14 +0000620 break;
621 case SPRN_HID2:
Alexander Grafd6d549b2010-02-19 11:00:33 +0100622 case SPRN_HID2_GEKKO:
Alexander Graf54771e62012-05-04 14:55:12 +0200623 *spr_val = to_book3s(vcpu)->hid[2];
Alexander Grafc215c6e2009-10-30 05:47:14 +0000624 break;
625 case SPRN_HID4:
Alexander Grafd6d549b2010-02-19 11:00:33 +0100626 case SPRN_HID4_GEKKO:
Alexander Graf54771e62012-05-04 14:55:12 +0200627 *spr_val = to_book3s(vcpu)->hid[4];
Alexander Grafc215c6e2009-10-30 05:47:14 +0000628 break;
629 case SPRN_HID5:
Alexander Graf54771e62012-05-04 14:55:12 +0200630 *spr_val = to_book3s(vcpu)->hid[5];
Alexander Grafc215c6e2009-10-30 05:47:14 +0000631 break;
Alexander Grafaacf9aa2011-08-08 17:22:59 +0200632 case SPRN_CFAR:
Paul Mackerrasb0a94d42012-11-04 18:15:43 +0000633 case SPRN_DSCR:
Alexander Graf54771e62012-05-04 14:55:12 +0200634 *spr_val = 0;
Alexander Grafaacf9aa2011-08-08 17:22:59 +0200635 break;
Paul Mackerrasb0a94d42012-11-04 18:15:43 +0000636 case SPRN_PURR:
Aneesh Kumar K.V3cd60e32014-06-04 16:47:55 +0530637 /*
638 * On exit we would have updated purr
639 */
640 *spr_val = vcpu->arch.purr;
Paul Mackerrasb0a94d42012-11-04 18:15:43 +0000641 break;
642 case SPRN_SPURR:
Aneesh Kumar K.V3cd60e32014-06-04 16:47:55 +0530643 /*
644 * On exit we would have updated spurr
645 */
646 *spr_val = vcpu->arch.spurr;
Paul Mackerrasb0a94d42012-11-04 18:15:43 +0000647 break;
Aneesh Kumar K.V8f42ab22014-06-05 17:38:02 +0530648 case SPRN_VTB:
Paul Mackerras88b02cf92016-09-15 13:42:52 +1000649 *spr_val = to_book3s(vcpu)->vtb;
Aneesh Kumar K.V8f42ab22014-06-05 17:38:02 +0530650 break;
Aneesh Kumar K.V06da28e2014-06-05 17:38:05 +0530651 case SPRN_IC:
652 *spr_val = vcpu->arch.ic;
653 break;
Alexander Grafd6d549b2010-02-19 11:00:33 +0100654 case SPRN_GQR0:
655 case SPRN_GQR1:
656 case SPRN_GQR2:
657 case SPRN_GQR3:
658 case SPRN_GQR4:
659 case SPRN_GQR5:
660 case SPRN_GQR6:
661 case SPRN_GQR7:
Alexander Graf54771e62012-05-04 14:55:12 +0200662 *spr_val = to_book3s(vcpu)->gqr[sprn - SPRN_GQR0];
Alexander Grafd6d549b2010-02-19 11:00:33 +0100663 break;
Alexander Graf8e6afa32014-07-31 10:21:59 +0200664#ifdef CONFIG_PPC_BOOK3S_64
Alexander Graf616dff82014-04-29 16:48:44 +0200665 case SPRN_FSCR:
666 *spr_val = vcpu->arch.fscr;
667 break;
Alexander Graf2e23f542014-04-29 13:36:21 +0200668 case SPRN_BESCR:
669 *spr_val = vcpu->arch.bescr;
670 break;
671 case SPRN_EBBHR:
672 *spr_val = vcpu->arch.ebbhr;
673 break;
674 case SPRN_EBBRR:
675 *spr_val = vcpu->arch.ebbrr;
676 break;
Alexander Graf9916d572014-04-29 17:54:40 +0200677#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
678 case SPRN_TFHAR:
679 *spr_val = vcpu->arch.tfhar;
680 break;
681 case SPRN_TEXASR:
682 *spr_val = vcpu->arch.texasr;
683 break;
684 case SPRN_TFIAR:
685 *spr_val = vcpu->arch.tfiar;
686 break;
687#endif
Alexander Graf2e23f542014-04-29 13:36:21 +0200688#endif
Alexander Grafc215c6e2009-10-30 05:47:14 +0000689 case SPRN_THRM1:
690 case SPRN_THRM2:
691 case SPRN_THRM3:
692 case SPRN_CTRLF:
693 case SPRN_CTRLT:
Alexander Grafd6d549b2010-02-19 11:00:33 +0100694 case SPRN_L2CR:
695 case SPRN_MMCR0_GEKKO:
696 case SPRN_MMCR1_GEKKO:
697 case SPRN_PMC1_GEKKO:
698 case SPRN_PMC2_GEKKO:
699 case SPRN_PMC3_GEKKO:
700 case SPRN_PMC4_GEKKO:
701 case SPRN_WPAR_GEKKO:
Mihai Caramanf2be6552012-12-20 04:52:39 +0000702 case SPRN_MSSSR0:
Alexander Graff3532022013-07-02 16:15:10 +0200703 case SPRN_DABR:
Alexander Graff8f6eb02014-04-22 12:41:06 +0200704#ifdef CONFIG_PPC_BOOK3S_64
705 case SPRN_MMCRS:
706 case SPRN_MMCRA:
707 case SPRN_MMCR0:
708 case SPRN_MMCR1:
709 case SPRN_MMCR2:
Thomas Huthfa73c3b2016-09-21 15:06:45 +0200710 case SPRN_UMMCR2:
Alexander Grafa5948fa2014-04-25 16:07:21 +0200711 case SPRN_TIR:
Alexander Graff8f6eb02014-04-22 12:41:06 +0200712#endif
Alexander Graf54771e62012-05-04 14:55:12 +0200713 *spr_val = 0;
Alexander Grafc215c6e2009-10-30 05:47:14 +0000714 break;
715 default:
Alexander Graf317a8fa2011-08-08 16:07:16 +0200716unprivileged:
Thomas Huthfeafd132017-04-05 15:58:51 +0200717 pr_info_ratelimited("KVM: invalid SPR read: %d\n", sprn);
718 if (sprn & 0x10) {
719 if (kvmppc_get_msr(vcpu) & MSR_PR) {
720 kvmppc_core_queue_program(vcpu, SRR1_PROGPRIV);
721 emulated = EMULATE_AGAIN;
722 }
723 } else {
724 if ((kvmppc_get_msr(vcpu) & MSR_PR) || sprn == 0 ||
725 sprn == 4 || sprn == 5 || sprn == 6) {
726 kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
727 emulated = EMULATE_AGAIN;
728 }
729 }
730
Alexander Grafc215c6e2009-10-30 05:47:14 +0000731 break;
732 }
733
734 return emulated;
735}
736
Alexander Grafca7f4202010-03-24 21:48:28 +0100737u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst)
738{
Aneesh Kumar K.Vddca1562014-05-12 17:04:06 +0530739 return make_dsisr(inst);
Alexander Grafca7f4202010-03-24 21:48:28 +0100740}
741
742ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst)
743{
Aneesh Kumar K.V7310f3a2014-05-12 17:04:05 +0530744#ifdef CONFIG_PPC_BOOK3S_64
745 /*
746 * Linux's fix_alignment() assumes that DAR is valid, so can we
747 */
748 return vcpu->arch.fault_dar;
749#else
Alexander Grafca7f4202010-03-24 21:48:28 +0100750 ulong dar = 0;
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200751 ulong ra = get_ra(inst);
752 ulong rb = get_rb(inst);
Alexander Grafca7f4202010-03-24 21:48:28 +0100753
754 switch (get_op(inst)) {
755 case OP_LFS:
756 case OP_LFD:
757 case OP_STFD:
758 case OP_STFS:
Alexander Grafca7f4202010-03-24 21:48:28 +0100759 if (ra)
760 dar = kvmppc_get_gpr(vcpu, ra);
761 dar += (s32)((s16)inst);
762 break;
763 case 31:
Alexander Grafca7f4202010-03-24 21:48:28 +0100764 if (ra)
765 dar = kvmppc_get_gpr(vcpu, ra);
Alexander Grafc46dc9a2012-05-04 14:01:33 +0200766 dar += kvmppc_get_gpr(vcpu, rb);
Alexander Grafca7f4202010-03-24 21:48:28 +0100767 break;
768 default:
769 printk(KERN_INFO "KVM: Unaligned instruction 0x%x\n", inst);
770 break;
771 }
772
773 return dar;
Aneesh Kumar K.V7310f3a2014-05-12 17:04:05 +0530774#endif
Alexander Grafca7f4202010-03-24 21:48:28 +0100775}