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.
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.
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.
15 * Copyright IBM Corp. 2007
16 * Copyright 2011 Freescale Semiconductor, Inc.
18 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
21 #include <linux/jiffies.h>
22 #include <linux/hrtimer.h>
23 #include <linux/types.h>
24 #include <linux/string.h>
25 #include <linux/kvm_host.h>
26 #include <linux/clockchips.h>
30 #include <asm/byteorder.h>
31 #include <asm/kvm_ppc.h>
32 #include <asm/disassemble.h>
33 #include <asm/ppc-opcode.h>
38 static bool kvmppc_check_fp_disabled(struct kvm_vcpu *vcpu)
40 if (!(kvmppc_get_msr(vcpu) & MSR_FP)) {
41 kvmppc_core_queue_fpunavail(vcpu);
47 #endif /* CONFIG_PPC_FPU */
50 static bool kvmppc_check_vsx_disabled(struct kvm_vcpu *vcpu)
52 if (!(kvmppc_get_msr(vcpu) & MSR_VSX)) {
53 kvmppc_core_queue_vsx_unavail(vcpu);
59 #endif /* CONFIG_VSX */
64 * vector loads and stores
66 * Instructions that trap when used on cache-inhibited mappings
67 * are not emulated here: multiple and string instructions,
68 * lq/stq, and the load-reserve/store-conditional instructions.
70 int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu)
72 struct kvm_run *run = vcpu->run;
75 enum emulation_result emulated;
78 /* this default type might be overwritten by subcategories */
79 kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
81 emulated = kvmppc_get_last_inst(vcpu, INST_GENERIC, &inst);
82 if (emulated != EMULATE_DONE)
90 * if mmio_vsx_tx_sx_enabled == 0, copy data between
91 * VSR[0..31] and memory
92 * if mmio_vsx_tx_sx_enabled == 1, copy data between
93 * VSR[32..63] and memory
95 vcpu->arch.mmio_vsx_tx_sx_enabled = get_tx_or_sx(inst);
96 vcpu->arch.mmio_vsx_copy_nums = 0;
97 vcpu->arch.mmio_vsx_offset = 0;
98 vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_NONE;
99 vcpu->arch.mmio_sp64_extend = 0;
100 vcpu->arch.mmio_sign_extend = 0;
102 switch (get_op(inst)) {
104 switch (get_xop(inst)) {
106 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
109 case OP_31_XOP_LWZUX:
110 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
111 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
115 emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
118 case OP_31_XOP_LBZUX:
119 emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
120 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
124 emulated = kvmppc_handle_store(run, vcpu,
125 kvmppc_get_gpr(vcpu, rs), 8, 1);
128 case OP_31_XOP_STDUX:
129 emulated = kvmppc_handle_store(run, vcpu,
130 kvmppc_get_gpr(vcpu, rs), 8, 1);
131 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
135 emulated = kvmppc_handle_store(run, vcpu,
136 kvmppc_get_gpr(vcpu, rs), 4, 1);
139 case OP_31_XOP_STWUX:
140 emulated = kvmppc_handle_store(run, vcpu,
141 kvmppc_get_gpr(vcpu, rs), 4, 1);
142 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
146 emulated = kvmppc_handle_store(run, vcpu,
147 kvmppc_get_gpr(vcpu, rs), 1, 1);
150 case OP_31_XOP_STBUX:
151 emulated = kvmppc_handle_store(run, vcpu,
152 kvmppc_get_gpr(vcpu, rs), 1, 1);
153 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
157 emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
160 case OP_31_XOP_LHAUX:
161 emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
162 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
166 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
169 case OP_31_XOP_LHZUX:
170 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
171 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
175 emulated = kvmppc_handle_store(run, vcpu,
176 kvmppc_get_gpr(vcpu, rs), 2, 1);
179 case OP_31_XOP_STHUX:
180 emulated = kvmppc_handle_store(run, vcpu,
181 kvmppc_get_gpr(vcpu, rs), 2, 1);
182 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
185 case OP_31_XOP_DCBST:
188 /* Do nothing. The guest is performing dcbi because
189 * hardware DMA is not snooped by the dcache, but
190 * emulated DMA either goes through the dcache as
191 * normal writes, or the host kernel has handled dcache
195 case OP_31_XOP_LWBRX:
196 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0);
199 case OP_31_XOP_STWBRX:
200 emulated = kvmppc_handle_store(run, vcpu,
201 kvmppc_get_gpr(vcpu, rs), 4, 0);
204 case OP_31_XOP_LHBRX:
205 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0);
208 case OP_31_XOP_STHBRX:
209 emulated = kvmppc_handle_store(run, vcpu,
210 kvmppc_get_gpr(vcpu, rs), 2, 0);
213 case OP_31_XOP_LDBRX:
214 emulated = kvmppc_handle_load(run, vcpu, rt, 8, 0);
217 case OP_31_XOP_STDBRX:
218 emulated = kvmppc_handle_store(run, vcpu,
219 kvmppc_get_gpr(vcpu, rs), 8, 0);
223 emulated = kvmppc_handle_load(run, vcpu, rt, 8, 1);
227 emulated = kvmppc_handle_load(run, vcpu, rt, 8, 1);
228 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
232 emulated = kvmppc_handle_loads(run, vcpu, rt, 4, 1);
235 case OP_31_XOP_LWAUX:
236 emulated = kvmppc_handle_loads(run, vcpu, rt, 4, 1);
237 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
240 #ifdef CONFIG_PPC_FPU
242 if (kvmppc_check_fp_disabled(vcpu))
244 vcpu->arch.mmio_sp64_extend = 1;
245 emulated = kvmppc_handle_load(run, vcpu,
246 KVM_MMIO_REG_FPR|rt, 4, 1);
249 case OP_31_XOP_LFSUX:
250 if (kvmppc_check_fp_disabled(vcpu))
252 vcpu->arch.mmio_sp64_extend = 1;
253 emulated = kvmppc_handle_load(run, vcpu,
254 KVM_MMIO_REG_FPR|rt, 4, 1);
255 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
259 if (kvmppc_check_fp_disabled(vcpu))
261 emulated = kvmppc_handle_load(run, vcpu,
262 KVM_MMIO_REG_FPR|rt, 8, 1);
265 case OP_31_XOP_LFDUX:
266 if (kvmppc_check_fp_disabled(vcpu))
268 emulated = kvmppc_handle_load(run, vcpu,
269 KVM_MMIO_REG_FPR|rt, 8, 1);
270 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
273 case OP_31_XOP_LFIWAX:
274 if (kvmppc_check_fp_disabled(vcpu))
276 emulated = kvmppc_handle_loads(run, vcpu,
277 KVM_MMIO_REG_FPR|rt, 4, 1);
280 case OP_31_XOP_LFIWZX:
281 if (kvmppc_check_fp_disabled(vcpu))
283 emulated = kvmppc_handle_load(run, vcpu,
284 KVM_MMIO_REG_FPR|rt, 4, 1);
287 case OP_31_XOP_STFSX:
288 if (kvmppc_check_fp_disabled(vcpu))
290 vcpu->arch.mmio_sp64_extend = 1;
291 emulated = kvmppc_handle_store(run, vcpu,
292 VCPU_FPR(vcpu, rs), 4, 1);
295 case OP_31_XOP_STFSUX:
296 if (kvmppc_check_fp_disabled(vcpu))
298 vcpu->arch.mmio_sp64_extend = 1;
299 emulated = kvmppc_handle_store(run, vcpu,
300 VCPU_FPR(vcpu, rs), 4, 1);
301 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
304 case OP_31_XOP_STFDX:
305 if (kvmppc_check_fp_disabled(vcpu))
307 emulated = kvmppc_handle_store(run, vcpu,
308 VCPU_FPR(vcpu, rs), 8, 1);
311 case OP_31_XOP_STFDUX:
312 if (kvmppc_check_fp_disabled(vcpu))
314 emulated = kvmppc_handle_store(run, vcpu,
315 VCPU_FPR(vcpu, rs), 8, 1);
316 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
319 case OP_31_XOP_STFIWX:
320 if (kvmppc_check_fp_disabled(vcpu))
322 emulated = kvmppc_handle_store(run, vcpu,
323 VCPU_FPR(vcpu, rs), 4, 1);
328 case OP_31_XOP_LXSDX:
329 if (kvmppc_check_vsx_disabled(vcpu))
331 vcpu->arch.mmio_vsx_copy_nums = 1;
332 vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_DWORD;
333 emulated = kvmppc_handle_vsx_load(run, vcpu,
334 KVM_MMIO_REG_VSX|rt, 8, 1, 0);
337 case OP_31_XOP_LXSSPX:
338 if (kvmppc_check_vsx_disabled(vcpu))
340 vcpu->arch.mmio_vsx_copy_nums = 1;
341 vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_DWORD;
342 vcpu->arch.mmio_sp64_extend = 1;
343 emulated = kvmppc_handle_vsx_load(run, vcpu,
344 KVM_MMIO_REG_VSX|rt, 4, 1, 0);
347 case OP_31_XOP_LXSIWAX:
348 if (kvmppc_check_vsx_disabled(vcpu))
350 vcpu->arch.mmio_vsx_copy_nums = 1;
351 vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_DWORD;
352 emulated = kvmppc_handle_vsx_load(run, vcpu,
353 KVM_MMIO_REG_VSX|rt, 4, 1, 1);
356 case OP_31_XOP_LXSIWZX:
357 if (kvmppc_check_vsx_disabled(vcpu))
359 vcpu->arch.mmio_vsx_copy_nums = 1;
360 vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_DWORD;
361 emulated = kvmppc_handle_vsx_load(run, vcpu,
362 KVM_MMIO_REG_VSX|rt, 4, 1, 0);
365 case OP_31_XOP_LXVD2X:
367 * In this case, the official load/store process is like this:
368 * Step1, exit from vm by page fault isr, then kvm save vsr.
369 * Please see guest_exit_cont->store_fp_state->SAVE_32VSRS
372 * Step2, copy data between memory and VCPU
373 * Notice: for LXVD2X/STXVD2X/LXVW4X/STXVW4X, we use
374 * 2copies*8bytes or 4copies*4bytes
375 * to simulate one copy of 16bytes.
376 * Also there is an endian issue here, we should notice the
378 * Please see MARCO of LXVD2X_ROT/STXVD2X_ROT as more reference.
379 * If host is little-endian, kvm will call XXSWAPD for
380 * LXVD2X_ROT/STXVD2X_ROT.
381 * So, if host is little-endian,
382 * the postion of memeory should be swapped.
384 * Step3, return to guest, kvm reset register.
385 * Please see kvmppc_hv_entry->load_fp_state->REST_32VSRS
388 if (kvmppc_check_vsx_disabled(vcpu))
390 vcpu->arch.mmio_vsx_copy_nums = 2;
391 vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_DWORD;
392 emulated = kvmppc_handle_vsx_load(run, vcpu,
393 KVM_MMIO_REG_VSX|rt, 8, 1, 0);
396 case OP_31_XOP_LXVW4X:
397 if (kvmppc_check_vsx_disabled(vcpu))
399 vcpu->arch.mmio_vsx_copy_nums = 4;
400 vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_WORD;
401 emulated = kvmppc_handle_vsx_load(run, vcpu,
402 KVM_MMIO_REG_VSX|rt, 4, 1, 0);
405 case OP_31_XOP_LXVDSX:
406 if (kvmppc_check_vsx_disabled(vcpu))
408 vcpu->arch.mmio_vsx_copy_nums = 1;
409 vcpu->arch.mmio_vsx_copy_type =
410 KVMPPC_VSX_COPY_DWORD_LOAD_DUMP;
411 emulated = kvmppc_handle_vsx_load(run, vcpu,
412 KVM_MMIO_REG_VSX|rt, 8, 1, 0);
415 case OP_31_XOP_STXSDX:
416 if (kvmppc_check_vsx_disabled(vcpu))
418 vcpu->arch.mmio_vsx_copy_nums = 1;
419 vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_DWORD;
420 emulated = kvmppc_handle_vsx_store(run, vcpu,
424 case OP_31_XOP_STXSSPX:
425 if (kvmppc_check_vsx_disabled(vcpu))
427 vcpu->arch.mmio_vsx_copy_nums = 1;
428 vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_DWORD;
429 vcpu->arch.mmio_sp64_extend = 1;
430 emulated = kvmppc_handle_vsx_store(run, vcpu,
434 case OP_31_XOP_STXSIWX:
435 if (kvmppc_check_vsx_disabled(vcpu))
437 vcpu->arch.mmio_vsx_offset = 1;
438 vcpu->arch.mmio_vsx_copy_nums = 1;
439 vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_WORD;
440 emulated = kvmppc_handle_vsx_store(run, vcpu,
444 case OP_31_XOP_STXVD2X:
445 if (kvmppc_check_vsx_disabled(vcpu))
447 vcpu->arch.mmio_vsx_copy_nums = 2;
448 vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_DWORD;
449 emulated = kvmppc_handle_vsx_store(run, vcpu,
453 case OP_31_XOP_STXVW4X:
454 if (kvmppc_check_vsx_disabled(vcpu))
456 vcpu->arch.mmio_vsx_copy_nums = 4;
457 vcpu->arch.mmio_vsx_copy_type = KVMPPC_VSX_COPY_WORD;
458 emulated = kvmppc_handle_vsx_store(run, vcpu,
461 #endif /* CONFIG_VSX */
463 emulated = EMULATE_FAIL;
469 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
472 #ifdef CONFIG_PPC_FPU
474 if (kvmppc_check_fp_disabled(vcpu))
476 vcpu->arch.mmio_sp64_extend = 1;
477 emulated = kvmppc_handle_store(run, vcpu,
483 if (kvmppc_check_fp_disabled(vcpu))
485 vcpu->arch.mmio_sp64_extend = 1;
486 emulated = kvmppc_handle_store(run, vcpu,
489 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
493 if (kvmppc_check_fp_disabled(vcpu))
495 emulated = kvmppc_handle_store(run, vcpu,
501 if (kvmppc_check_fp_disabled(vcpu))
503 emulated = kvmppc_handle_store(run, vcpu,
506 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
514 emulated = kvmppc_handle_load(run, vcpu, rt, 8, 1);
517 emulated = kvmppc_handle_load(run, vcpu, rt, 8, 1);
518 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
521 emulated = kvmppc_handle_loads(run, vcpu, rt, 4, 1);
524 emulated = EMULATE_FAIL;
529 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
530 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
534 emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
538 emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
539 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
543 emulated = kvmppc_handle_store(run, vcpu,
544 kvmppc_get_gpr(vcpu, rs),
552 emulated = kvmppc_handle_store(run, vcpu,
553 kvmppc_get_gpr(vcpu, rs), 8, 1);
556 emulated = kvmppc_handle_store(run, vcpu,
557 kvmppc_get_gpr(vcpu, rs), 8, 1);
558 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
561 emulated = EMULATE_FAIL;
566 emulated = kvmppc_handle_store(run, vcpu,
567 kvmppc_get_gpr(vcpu, rs), 4, 1);
568 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
572 emulated = kvmppc_handle_store(run, vcpu,
573 kvmppc_get_gpr(vcpu, rs), 1, 1);
577 emulated = kvmppc_handle_store(run, vcpu,
578 kvmppc_get_gpr(vcpu, rs), 1, 1);
579 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
583 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
587 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
588 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
592 emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
596 emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
597 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
601 emulated = kvmppc_handle_store(run, vcpu,
602 kvmppc_get_gpr(vcpu, rs), 2, 1);
606 emulated = kvmppc_handle_store(run, vcpu,
607 kvmppc_get_gpr(vcpu, rs), 2, 1);
608 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
611 #ifdef CONFIG_PPC_FPU
613 if (kvmppc_check_fp_disabled(vcpu))
615 vcpu->arch.mmio_sp64_extend = 1;
616 emulated = kvmppc_handle_load(run, vcpu,
617 KVM_MMIO_REG_FPR|rt, 4, 1);
621 if (kvmppc_check_fp_disabled(vcpu))
623 vcpu->arch.mmio_sp64_extend = 1;
624 emulated = kvmppc_handle_load(run, vcpu,
625 KVM_MMIO_REG_FPR|rt, 4, 1);
626 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
630 if (kvmppc_check_fp_disabled(vcpu))
632 emulated = kvmppc_handle_load(run, vcpu,
633 KVM_MMIO_REG_FPR|rt, 8, 1);
637 if (kvmppc_check_fp_disabled(vcpu))
639 emulated = kvmppc_handle_load(run, vcpu,
640 KVM_MMIO_REG_FPR|rt, 8, 1);
641 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
646 emulated = EMULATE_FAIL;
650 if (emulated == EMULATE_FAIL) {
652 kvmppc_core_queue_program(vcpu, 0);
655 trace_kvm_ppc_instr(inst, kvmppc_get_pc(vcpu), emulated);
657 /* Advance past emulated instruction. */
659 kvmppc_set_pc(vcpu, kvmppc_get_pc(vcpu) + 4);