blob: 37db61d37041e922c663103c186d2fe44841ab50 [file] [log] [blame]
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001/*
2 * Copyright (C) 2009. SUSE Linux Products GmbH. All rights reserved.
3 *
4 * Authors:
5 * Alexander Graf <agraf@suse.de>
6 * Kevin Wolf <mail@kevin-wolf.de>
7 *
8 * Description:
9 * This file is derived from arch/powerpc/kvm/44x.c,
10 * by Hollis Blanchard <hollisb@us.ibm.com>.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License, version 2, as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/kvm_host.h>
18#include <linux/err.h>
Stephen Rothwell329d20b2010-04-27 15:49:17 +100019#include <linux/slab.h>
Alexander Grafbed1ed92010-08-02 11:06:26 +020020#include "trace.h"
Alexander Graf2f4cf5e2009-10-30 05:47:10 +000021
22#include <asm/reg.h>
23#include <asm/cputable.h>
24#include <asm/cacheflush.h>
25#include <asm/tlbflush.h>
26#include <asm/uaccess.h>
27#include <asm/io.h>
28#include <asm/kvm_ppc.h>
29#include <asm/kvm_book3s.h>
30#include <asm/mmu_context.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090031#include <linux/gfp.h>
Alexander Graf2f4cf5e2009-10-30 05:47:10 +000032#include <linux/sched.h>
33#include <linux/vmalloc.h>
Alexander Graf9fb244a2010-03-24 21:48:32 +010034#include <linux/highmem.h>
Alexander Graf2f4cf5e2009-10-30 05:47:10 +000035
36#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
37
38/* #define EXIT_DEBUG */
Alexander Graf180a34d2010-01-15 14:49:11 +010039/* #define DEBUG_EXT */
40
Alexander Grafc8c0b6f2010-02-19 11:00:34 +010041static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
42 ulong msr);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +000043
Alexander Graf07b09072010-04-16 00:11:53 +020044/* Some compatibility defines */
45#ifdef CONFIG_PPC_BOOK3S_32
46#define MSR_USER32 MSR_USER
47#define MSR_USER64 MSR_USER
48#define HW_PAGE_SIZE PAGE_SIZE
49#endif
50
Alexander Graf2f4cf5e2009-10-30 05:47:10 +000051struct kvm_stats_debugfs_item debugfs_entries[] = {
52 { "exits", VCPU_STAT(sum_exits) },
53 { "mmio", VCPU_STAT(mmio_exits) },
54 { "sig", VCPU_STAT(signal_exits) },
55 { "sysc", VCPU_STAT(syscall_exits) },
56 { "inst_emu", VCPU_STAT(emulated_inst_exits) },
57 { "dec", VCPU_STAT(dec_exits) },
58 { "ext_intr", VCPU_STAT(ext_intr_exits) },
59 { "queue_intr", VCPU_STAT(queue_intr) },
60 { "halt_wakeup", VCPU_STAT(halt_wakeup) },
61 { "pf_storage", VCPU_STAT(pf_storage) },
62 { "sp_storage", VCPU_STAT(sp_storage) },
63 { "pf_instruc", VCPU_STAT(pf_instruc) },
64 { "sp_instruc", VCPU_STAT(sp_instruc) },
65 { "ld", VCPU_STAT(ld) },
66 { "ld_slow", VCPU_STAT(ld_slow) },
67 { "st", VCPU_STAT(st) },
68 { "st_slow", VCPU_STAT(st_slow) },
69 { NULL }
70};
71
72void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu)
73{
74}
75
76void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu)
77{
78}
79
80void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
81{
Alexander Grafc7f38f42010-04-16 00:11:40 +020082#ifdef CONFIG_PPC_BOOK3S_64
83 memcpy(to_svcpu(vcpu)->slb, to_book3s(vcpu)->slb_shadow, sizeof(to_svcpu(vcpu)->slb));
84 memcpy(&get_paca()->shadow_vcpu, to_book3s(vcpu)->shadow_vcpu,
Alexander Graf7e57cba2010-01-08 02:58:03 +010085 sizeof(get_paca()->shadow_vcpu));
Alexander Grafc7f38f42010-04-16 00:11:40 +020086 to_svcpu(vcpu)->slb_max = to_book3s(vcpu)->slb_shadow_max;
87#endif
88
89#ifdef CONFIG_PPC_BOOK3S_32
90 current->thread.kvm_shadow_vcpu = to_book3s(vcpu)->shadow_vcpu;
91#endif
Alexander Graf2f4cf5e2009-10-30 05:47:10 +000092}
93
94void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
95{
Alexander Grafc7f38f42010-04-16 00:11:40 +020096#ifdef CONFIG_PPC_BOOK3S_64
97 memcpy(to_book3s(vcpu)->slb_shadow, to_svcpu(vcpu)->slb, sizeof(to_svcpu(vcpu)->slb));
98 memcpy(to_book3s(vcpu)->shadow_vcpu, &get_paca()->shadow_vcpu,
Alexander Graf7e57cba2010-01-08 02:58:03 +010099 sizeof(get_paca()->shadow_vcpu));
Alexander Grafc7f38f42010-04-16 00:11:40 +0200100 to_book3s(vcpu)->slb_shadow_max = to_svcpu(vcpu)->slb_max;
101#endif
Alexander Graf180a34d2010-01-15 14:49:11 +0100102
103 kvmppc_giveup_ext(vcpu, MSR_FP);
104 kvmppc_giveup_ext(vcpu, MSR_VEC);
105 kvmppc_giveup_ext(vcpu, MSR_VSX);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000106}
107
Alexander Grafa76f8492010-01-15 14:49:14 +0100108static void kvmppc_recalc_shadow_msr(struct kvm_vcpu *vcpu)
109{
Alexander Graf666e7252010-07-29 14:47:43 +0200110 ulong smsr = vcpu->arch.shared->msr;
111
Alexander Grafa76f8492010-01-15 14:49:14 +0100112 /* Guest MSR values */
Alexander Graf666e7252010-07-29 14:47:43 +0200113 smsr &= MSR_FE0 | MSR_FE1 | MSR_SF | MSR_SE | MSR_BE | MSR_DE;
Alexander Grafa76f8492010-01-15 14:49:14 +0100114 /* Process MSR values */
Alexander Graf666e7252010-07-29 14:47:43 +0200115 smsr |= MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_PR | MSR_EE;
Alexander Grafa76f8492010-01-15 14:49:14 +0100116 /* External providers the guest reserved */
Alexander Graf666e7252010-07-29 14:47:43 +0200117 smsr |= (vcpu->arch.shared->msr & vcpu->arch.guest_owned_ext);
Alexander Grafa76f8492010-01-15 14:49:14 +0100118 /* 64-bit Process MSR values */
119#ifdef CONFIG_PPC_BOOK3S_64
Alexander Graf666e7252010-07-29 14:47:43 +0200120 smsr |= MSR_ISF | MSR_HV;
Alexander Grafa76f8492010-01-15 14:49:14 +0100121#endif
Alexander Graf666e7252010-07-29 14:47:43 +0200122 vcpu->arch.shadow_msr = smsr;
Alexander Grafa76f8492010-01-15 14:49:14 +0100123}
124
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000125void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr)
126{
Alexander Graf666e7252010-07-29 14:47:43 +0200127 ulong old_msr = vcpu->arch.shared->msr;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000128
129#ifdef EXIT_DEBUG
130 printk(KERN_INFO "KVM: Set MSR to 0x%llx\n", msr);
131#endif
Alexander Grafa76f8492010-01-15 14:49:14 +0100132
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000133 msr &= to_book3s(vcpu)->msr_mask;
Alexander Graf666e7252010-07-29 14:47:43 +0200134 vcpu->arch.shared->msr = msr;
Alexander Grafa76f8492010-01-15 14:49:14 +0100135 kvmppc_recalc_shadow_msr(vcpu);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000136
137 if (msr & (MSR_WE|MSR_POW)) {
138 if (!vcpu->arch.pending_exceptions) {
139 kvm_vcpu_block(vcpu);
140 vcpu->stat.halt_wakeup++;
141 }
142 }
143
Alexander Graf666e7252010-07-29 14:47:43 +0200144 if ((vcpu->arch.shared->msr & (MSR_PR|MSR_IR|MSR_DR)) !=
Alexander Graff7bc74e2010-04-20 02:49:48 +0200145 (old_msr & (MSR_PR|MSR_IR|MSR_DR))) {
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000146 kvmppc_mmu_flush_segments(vcpu);
Alexander Grafc7f38f42010-04-16 00:11:40 +0200147 kvmppc_mmu_map_segment(vcpu, kvmppc_get_pc(vcpu));
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000148 }
Alexander Grafd1bab742010-02-19 11:00:35 +0100149
150 /* Preload FPU if it's enabled */
Alexander Graf666e7252010-07-29 14:47:43 +0200151 if (vcpu->arch.shared->msr & MSR_FP)
Alexander Grafd1bab742010-02-19 11:00:35 +0100152 kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000153}
154
155void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags)
156{
Alexander Grafde7906c2010-07-29 14:47:46 +0200157 vcpu->arch.shared->srr0 = kvmppc_get_pc(vcpu);
158 vcpu->arch.shared->srr1 = vcpu->arch.shared->msr | flags;
Alexander Grafc7f38f42010-04-16 00:11:40 +0200159 kvmppc_set_pc(vcpu, to_book3s(vcpu)->hior + vec);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000160 vcpu->arch.mmu.reset_msr(vcpu);
161}
162
Alexander Graf583617b2009-12-21 20:21:23 +0100163static int kvmppc_book3s_vec2irqprio(unsigned int vec)
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000164{
165 unsigned int prio;
166
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000167 switch (vec) {
168 case 0x100: prio = BOOK3S_IRQPRIO_SYSTEM_RESET; break;
169 case 0x200: prio = BOOK3S_IRQPRIO_MACHINE_CHECK; break;
170 case 0x300: prio = BOOK3S_IRQPRIO_DATA_STORAGE; break;
171 case 0x380: prio = BOOK3S_IRQPRIO_DATA_SEGMENT; break;
172 case 0x400: prio = BOOK3S_IRQPRIO_INST_STORAGE; break;
173 case 0x480: prio = BOOK3S_IRQPRIO_INST_SEGMENT; break;
174 case 0x500: prio = BOOK3S_IRQPRIO_EXTERNAL; break;
175 case 0x600: prio = BOOK3S_IRQPRIO_ALIGNMENT; break;
176 case 0x700: prio = BOOK3S_IRQPRIO_PROGRAM; break;
177 case 0x800: prio = BOOK3S_IRQPRIO_FP_UNAVAIL; break;
178 case 0x900: prio = BOOK3S_IRQPRIO_DECREMENTER; break;
179 case 0xc00: prio = BOOK3S_IRQPRIO_SYSCALL; break;
180 case 0xd00: prio = BOOK3S_IRQPRIO_DEBUG; break;
181 case 0xf20: prio = BOOK3S_IRQPRIO_ALTIVEC; break;
182 case 0xf40: prio = BOOK3S_IRQPRIO_VSX; break;
183 default: prio = BOOK3S_IRQPRIO_MAX; break;
184 }
185
Alexander Graf583617b2009-12-21 20:21:23 +0100186 return prio;
187}
188
Alexander Graf7706664d2009-12-21 20:21:24 +0100189static void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcpu,
190 unsigned int vec)
191{
192 clear_bit(kvmppc_book3s_vec2irqprio(vec),
193 &vcpu->arch.pending_exceptions);
194}
195
Alexander Graf583617b2009-12-21 20:21:23 +0100196void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
197{
198 vcpu->stat.queue_intr++;
199
200 set_bit(kvmppc_book3s_vec2irqprio(vec),
201 &vcpu->arch.pending_exceptions);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000202#ifdef EXIT_DEBUG
203 printk(KERN_INFO "Queueing interrupt %x\n", vec);
204#endif
205}
206
207
Alexander Graf25a8a022010-01-08 02:58:07 +0100208void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags)
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000209{
Alexander Graf25a8a022010-01-08 02:58:07 +0100210 to_book3s(vcpu)->prog_flags = flags;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000211 kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_PROGRAM);
212}
213
214void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu)
215{
216 kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DECREMENTER);
217}
218
219int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu)
220{
221 return test_bit(BOOK3S_INTERRUPT_DECREMENTER >> 7, &vcpu->arch.pending_exceptions);
222}
223
Alexander Graf7706664d2009-12-21 20:21:24 +0100224void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu)
225{
226 kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_DECREMENTER);
227}
228
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000229void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
230 struct kvm_interrupt *irq)
231{
232 kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL);
233}
234
Alexander Graf18978762010-03-24 21:48:18 +0100235void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu,
236 struct kvm_interrupt *irq)
237{
238 kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL);
239}
240
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000241int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
242{
243 int deliver = 1;
244 int vec = 0;
Alexander Graf25a8a022010-01-08 02:58:07 +0100245 ulong flags = 0ULL;
Alexander Graf5c6cedf2010-07-29 14:47:49 +0200246 ulong crit_raw = vcpu->arch.shared->critical;
247 ulong crit_r1 = kvmppc_get_gpr(vcpu, 1);
248 bool crit;
249
250 /* Truncate crit indicators in 32 bit mode */
251 if (!(vcpu->arch.shared->msr & MSR_SF)) {
252 crit_raw &= 0xffffffff;
253 crit_r1 &= 0xffffffff;
254 }
255
256 /* Critical section when crit == r1 */
257 crit = (crit_raw == crit_r1);
258 /* ... and we're in supervisor mode */
259 crit = crit && !(vcpu->arch.shared->msr & MSR_PR);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000260
261 switch (priority) {
262 case BOOK3S_IRQPRIO_DECREMENTER:
Alexander Graf5c6cedf2010-07-29 14:47:49 +0200263 deliver = (vcpu->arch.shared->msr & MSR_EE) && !crit;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000264 vec = BOOK3S_INTERRUPT_DECREMENTER;
265 break;
266 case BOOK3S_IRQPRIO_EXTERNAL:
Alexander Graf5c6cedf2010-07-29 14:47:49 +0200267 deliver = (vcpu->arch.shared->msr & MSR_EE) && !crit;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000268 vec = BOOK3S_INTERRUPT_EXTERNAL;
269 break;
270 case BOOK3S_IRQPRIO_SYSTEM_RESET:
271 vec = BOOK3S_INTERRUPT_SYSTEM_RESET;
272 break;
273 case BOOK3S_IRQPRIO_MACHINE_CHECK:
274 vec = BOOK3S_INTERRUPT_MACHINE_CHECK;
275 break;
276 case BOOK3S_IRQPRIO_DATA_STORAGE:
277 vec = BOOK3S_INTERRUPT_DATA_STORAGE;
278 break;
279 case BOOK3S_IRQPRIO_INST_STORAGE:
280 vec = BOOK3S_INTERRUPT_INST_STORAGE;
281 break;
282 case BOOK3S_IRQPRIO_DATA_SEGMENT:
283 vec = BOOK3S_INTERRUPT_DATA_SEGMENT;
284 break;
285 case BOOK3S_IRQPRIO_INST_SEGMENT:
286 vec = BOOK3S_INTERRUPT_INST_SEGMENT;
287 break;
288 case BOOK3S_IRQPRIO_ALIGNMENT:
289 vec = BOOK3S_INTERRUPT_ALIGNMENT;
290 break;
291 case BOOK3S_IRQPRIO_PROGRAM:
292 vec = BOOK3S_INTERRUPT_PROGRAM;
Alexander Graf25a8a022010-01-08 02:58:07 +0100293 flags = to_book3s(vcpu)->prog_flags;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000294 break;
295 case BOOK3S_IRQPRIO_VSX:
296 vec = BOOK3S_INTERRUPT_VSX;
297 break;
298 case BOOK3S_IRQPRIO_ALTIVEC:
299 vec = BOOK3S_INTERRUPT_ALTIVEC;
300 break;
301 case BOOK3S_IRQPRIO_FP_UNAVAIL:
302 vec = BOOK3S_INTERRUPT_FP_UNAVAIL;
303 break;
304 case BOOK3S_IRQPRIO_SYSCALL:
305 vec = BOOK3S_INTERRUPT_SYSCALL;
306 break;
307 case BOOK3S_IRQPRIO_DEBUG:
308 vec = BOOK3S_INTERRUPT_TRACE;
309 break;
310 case BOOK3S_IRQPRIO_PERFORMANCE_MONITOR:
311 vec = BOOK3S_INTERRUPT_PERFMON;
312 break;
313 default:
314 deliver = 0;
315 printk(KERN_ERR "KVM: Unknown interrupt: 0x%x\n", priority);
316 break;
317 }
318
319#if 0
320 printk(KERN_INFO "Deliver interrupt 0x%x? %x\n", vec, deliver);
321#endif
322
323 if (deliver)
Alexander Graf25a8a022010-01-08 02:58:07 +0100324 kvmppc_inject_interrupt(vcpu, vec, flags);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000325
326 return deliver;
327}
328
329void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
330{
331 unsigned long *pending = &vcpu->arch.pending_exceptions;
Alexander Graf90bba352010-07-29 14:47:51 +0200332 unsigned long old_pending = vcpu->arch.pending_exceptions;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000333 unsigned int priority;
334
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000335#ifdef EXIT_DEBUG
336 if (vcpu->arch.pending_exceptions)
337 printk(KERN_EMERG "KVM: Check pending: %lx\n", vcpu->arch.pending_exceptions);
338#endif
339 priority = __ffs(*pending);
Alexander Grafada7ba12010-04-16 00:11:56 +0200340 while (priority < BOOK3S_IRQPRIO_MAX) {
Alexander Graf7706664d2009-12-21 20:21:24 +0100341 if (kvmppc_book3s_irqprio_deliver(vcpu, priority) &&
342 (priority != BOOK3S_IRQPRIO_DECREMENTER)) {
343 /* DEC interrupts get cleared by mtdec */
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000344 clear_bit(priority, &vcpu->arch.pending_exceptions);
345 break;
346 }
347
348 priority = find_next_bit(pending,
349 BITS_PER_BYTE * sizeof(*pending),
350 priority + 1);
351 }
Alexander Graf90bba352010-07-29 14:47:51 +0200352
353 /* Tell the guest about our interrupt status */
354 if (*pending)
355 vcpu->arch.shared->int_pending = 1;
356 else if (old_pending)
357 vcpu->arch.shared->int_pending = 0;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000358}
359
360void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr)
361{
Alexander Grafb83d4a92010-04-20 02:49:54 +0200362 u32 host_pvr;
363
Alexander Grafe15a1132009-11-30 03:02:02 +0000364 vcpu->arch.hflags &= ~BOOK3S_HFLAG_SLB;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000365 vcpu->arch.pvr = pvr;
Alexander Graf07b09072010-04-16 00:11:53 +0200366#ifdef CONFIG_PPC_BOOK3S_64
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000367 if ((pvr >= 0x330000) && (pvr < 0x70330000)) {
368 kvmppc_mmu_book3s_64_init(vcpu);
369 to_book3s(vcpu)->hior = 0xfff00000;
370 to_book3s(vcpu)->msr_mask = 0xffffffffffffffffULL;
Alexander Graf07b09072010-04-16 00:11:53 +0200371 } else
372#endif
373 {
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000374 kvmppc_mmu_book3s_32_init(vcpu);
375 to_book3s(vcpu)->hior = 0;
376 to_book3s(vcpu)->msr_mask = 0xffffffffULL;
377 }
378
379 /* If we are in hypervisor level on 970, we can tell the CPU to
380 * treat DCBZ as 32 bytes store */
381 vcpu->arch.hflags &= ~BOOK3S_HFLAG_DCBZ32;
382 if (vcpu->arch.mmu.is_dcbz32(vcpu) && (mfmsr() & MSR_HV) &&
383 !strcmp(cur_cpu_spec->platform, "ppc970"))
384 vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32;
385
Alexander Graf05b0ab12010-03-24 21:48:37 +0100386 /* Cell performs badly if MSR_FEx are set. So let's hope nobody
387 really needs them in a VM on Cell and force disable them. */
388 if (!strcmp(cur_cpu_spec->platform, "ppc-cell-be"))
389 to_book3s(vcpu)->msr_mask &= ~(MSR_FE0 | MSR_FE1);
Alexander Graf07b09072010-04-16 00:11:53 +0200390
391#ifdef CONFIG_PPC_BOOK3S_32
392 /* 32 bit Book3S always has 32 byte dcbz */
393 vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32;
394#endif
Alexander Grafb83d4a92010-04-20 02:49:54 +0200395
396 /* On some CPUs we can execute paired single operations natively */
397 asm ( "mfpvr %0" : "=r"(host_pvr));
398 switch (host_pvr) {
399 case 0x00080200: /* lonestar 2.0 */
400 case 0x00088202: /* lonestar 2.2 */
401 case 0x70000100: /* gekko 1.0 */
402 case 0x00080100: /* gekko 2.0 */
403 case 0x00083203: /* gekko 2.3a */
404 case 0x00083213: /* gekko 2.3b */
405 case 0x00083204: /* gekko 2.4 */
406 case 0x00083214: /* gekko 2.4e (8SE) - retail HW2 */
407 case 0x00087200: /* broadway */
408 vcpu->arch.hflags |= BOOK3S_HFLAG_NATIVE_PS;
409 /* Enable HID2.PSE - in case we need it later */
410 mtspr(SPRN_HID2_GEKKO, mfspr(SPRN_HID2_GEKKO) | (1 << 29));
411 }
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000412}
413
Alexander Grafe8508942010-07-29 14:47:54 +0200414pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn)
415{
416 ulong mp_pa = vcpu->arch.magic_page_pa;
417
418 /* Magic page override */
419 if (unlikely(mp_pa) &&
420 unlikely(((gfn << PAGE_SHIFT) & KVM_PAM) ==
421 ((mp_pa & PAGE_MASK) & KVM_PAM))) {
422 ulong shared_page = ((ulong)vcpu->arch.shared) & PAGE_MASK;
423 pfn_t pfn;
424
425 pfn = (pfn_t)virt_to_phys((void*)shared_page) >> PAGE_SHIFT;
426 get_page(pfn_to_page(pfn));
427 return pfn;
428 }
429
430 return gfn_to_pfn(vcpu->kvm, gfn);
431}
432
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000433/* Book3s_32 CPUs always have 32 bytes cache line size, which Linux assumes. To
434 * make Book3s_32 Linux work on Book3s_64, we have to make sure we trap dcbz to
435 * emulate 32 bytes dcbz length.
436 *
437 * The Book3s_64 inventors also realized this case and implemented a special bit
438 * in the HID5 register, which is a hypervisor ressource. Thus we can't use it.
439 *
440 * My approach here is to patch the dcbz instruction on executing pages.
441 */
442static void kvmppc_patch_dcbz(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte)
443{
Alexander Graf9fb244a2010-03-24 21:48:32 +0100444 struct page *hpage;
445 u64 hpage_offset;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000446 u32 *page;
447 int i;
448
Alexander Graf9fb244a2010-03-24 21:48:32 +0100449 hpage = gfn_to_page(vcpu->kvm, pte->raddr >> PAGE_SHIFT);
Wei Yongjun646bab52010-08-17 10:08:52 +0800450 if (is_error_page(hpage)) {
451 kvm_release_page_clean(hpage);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000452 return;
Wei Yongjun646bab52010-08-17 10:08:52 +0800453 }
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000454
Alexander Graf9fb244a2010-03-24 21:48:32 +0100455 hpage_offset = pte->raddr & ~PAGE_MASK;
456 hpage_offset &= ~0xFFFULL;
457 hpage_offset /= 4;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000458
Alexander Graf9fb244a2010-03-24 21:48:32 +0100459 get_page(hpage);
460 page = kmap_atomic(hpage, KM_USER0);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000461
Alexander Graf9fb244a2010-03-24 21:48:32 +0100462 /* patch dcbz into reserved instruction, so we trap */
463 for (i=hpage_offset; i < hpage_offset + (HW_PAGE_SIZE / 4); i++)
464 if ((page[i] & 0xff0007ff) == INS_DCBZ)
465 page[i] &= 0xfffffff7;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000466
Alexander Graf9fb244a2010-03-24 21:48:32 +0100467 kunmap_atomic(page, KM_USER0);
468 put_page(hpage);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000469}
470
471static int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, bool data,
472 struct kvmppc_pte *pte)
473{
Alexander Graf666e7252010-07-29 14:47:43 +0200474 int relocated = (vcpu->arch.shared->msr & (data ? MSR_DR : MSR_IR));
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000475 int r;
476
477 if (relocated) {
478 r = vcpu->arch.mmu.xlate(vcpu, eaddr, pte, data);
479 } else {
480 pte->eaddr = eaddr;
Alexander Graf28e83b42010-07-29 14:47:52 +0200481 pte->raddr = eaddr & KVM_PAM;
Alexander Graf3eeafd72010-03-24 21:48:17 +0100482 pte->vpage = VSID_REAL | eaddr >> 12;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000483 pte->may_read = true;
484 pte->may_write = true;
485 pte->may_execute = true;
486 r = 0;
487 }
488
489 return r;
490}
491
492static hva_t kvmppc_bad_hva(void)
493{
494 return PAGE_OFFSET;
495}
496
497static hva_t kvmppc_pte_to_hva(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte,
498 bool read)
499{
500 hva_t hpage;
501
502 if (read && !pte->may_read)
503 goto err;
504
505 if (!read && !pte->may_write)
506 goto err;
507
508 hpage = gfn_to_hva(vcpu->kvm, pte->raddr >> PAGE_SHIFT);
509 if (kvm_is_error_hva(hpage))
510 goto err;
511
512 return hpage | (pte->raddr & ~PAGE_MASK);
513err:
514 return kvmppc_bad_hva();
515}
516
Alexander Graf5467a972010-02-19 11:00:38 +0100517int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
518 bool data)
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000519{
520 struct kvmppc_pte pte;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000521
522 vcpu->stat.st++;
523
Alexander Graf5467a972010-02-19 11:00:38 +0100524 if (kvmppc_xlate(vcpu, *eaddr, data, &pte))
Alexander Graf9fb244a2010-03-24 21:48:32 +0100525 return -ENOENT;
Alexander Graf5467a972010-02-19 11:00:38 +0100526
527 *eaddr = pte.raddr;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000528
Alexander Graf9fb244a2010-03-24 21:48:32 +0100529 if (!pte.may_write)
530 return -EPERM;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000531
Alexander Graf9fb244a2010-03-24 21:48:32 +0100532 if (kvm_write_guest(vcpu->kvm, pte.raddr, ptr, size))
533 return EMULATE_DO_MMIO;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000534
Alexander Graf5467a972010-02-19 11:00:38 +0100535 return EMULATE_DONE;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000536}
537
Alexander Graf5467a972010-02-19 11:00:38 +0100538int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000539 bool data)
540{
541 struct kvmppc_pte pte;
Alexander Graf5467a972010-02-19 11:00:38 +0100542 hva_t hva = *eaddr;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000543
544 vcpu->stat.ld++;
545
Alexander Graf5467a972010-02-19 11:00:38 +0100546 if (kvmppc_xlate(vcpu, *eaddr, data, &pte))
547 goto nopte;
548
549 *eaddr = pte.raddr;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000550
551 hva = kvmppc_pte_to_hva(vcpu, &pte, true);
552 if (kvm_is_error_hva(hva))
Alexander Graf5467a972010-02-19 11:00:38 +0100553 goto mmio;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000554
555 if (copy_from_user(ptr, (void __user *)hva, size)) {
556 printk(KERN_INFO "kvmppc_ld at 0x%lx failed\n", hva);
Alexander Graf5467a972010-02-19 11:00:38 +0100557 goto mmio;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000558 }
559
Alexander Graf5467a972010-02-19 11:00:38 +0100560 return EMULATE_DONE;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000561
Alexander Graf5467a972010-02-19 11:00:38 +0100562nopte:
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000563 return -ENOENT;
Alexander Graf5467a972010-02-19 11:00:38 +0100564mmio:
565 return EMULATE_DO_MMIO;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000566}
567
568static int kvmppc_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn)
569{
Alexander Grafe8508942010-07-29 14:47:54 +0200570 ulong mp_pa = vcpu->arch.magic_page_pa;
571
572 if (unlikely(mp_pa) &&
573 unlikely((mp_pa & KVM_PAM) >> PAGE_SHIFT == gfn)) {
574 return 1;
575 }
576
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000577 return kvm_is_visible_gfn(vcpu->kvm, gfn);
578}
579
580int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
581 ulong eaddr, int vec)
582{
583 bool data = (vec == BOOK3S_INTERRUPT_DATA_STORAGE);
584 int r = RESUME_GUEST;
585 int relocated;
586 int page_found = 0;
587 struct kvmppc_pte pte;
588 bool is_mmio = false;
Alexander Graf666e7252010-07-29 14:47:43 +0200589 bool dr = (vcpu->arch.shared->msr & MSR_DR) ? true : false;
590 bool ir = (vcpu->arch.shared->msr & MSR_IR) ? true : false;
Alexander Graff7bc74e2010-04-20 02:49:48 +0200591 u64 vsid;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000592
Alexander Graf3eeafd72010-03-24 21:48:17 +0100593 relocated = data ? dr : ir;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000594
595 /* Resolve real address if translation turned on */
596 if (relocated) {
597 page_found = vcpu->arch.mmu.xlate(vcpu, eaddr, &pte, data);
598 } else {
599 pte.may_execute = true;
600 pte.may_read = true;
601 pte.may_write = true;
Alexander Graf28e83b42010-07-29 14:47:52 +0200602 pte.raddr = eaddr & KVM_PAM;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000603 pte.eaddr = eaddr;
604 pte.vpage = eaddr >> 12;
Alexander Graf3eeafd72010-03-24 21:48:17 +0100605 }
606
Alexander Graf666e7252010-07-29 14:47:43 +0200607 switch (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) {
Alexander Graf3eeafd72010-03-24 21:48:17 +0100608 case 0:
Alexander Graff7bc74e2010-04-20 02:49:48 +0200609 pte.vpage |= ((u64)VSID_REAL << (SID_SHIFT - 12));
Alexander Graf3eeafd72010-03-24 21:48:17 +0100610 break;
611 case MSR_DR:
Alexander Graf3eeafd72010-03-24 21:48:17 +0100612 case MSR_IR:
Alexander Graff7bc74e2010-04-20 02:49:48 +0200613 vcpu->arch.mmu.esid_to_vsid(vcpu, eaddr >> SID_SHIFT, &vsid);
614
Alexander Graf666e7252010-07-29 14:47:43 +0200615 if ((vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) == MSR_DR)
Alexander Graff7bc74e2010-04-20 02:49:48 +0200616 pte.vpage |= ((u64)VSID_REAL_DR << (SID_SHIFT - 12));
617 else
618 pte.vpage |= ((u64)VSID_REAL_IR << (SID_SHIFT - 12));
619 pte.vpage |= vsid;
620
621 if (vsid == -1)
622 page_found = -EINVAL;
Alexander Graf3eeafd72010-03-24 21:48:17 +0100623 break;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000624 }
625
626 if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
627 (!(vcpu->arch.hflags & BOOK3S_HFLAG_DCBZ32))) {
628 /*
629 * If we do the dcbz hack, we have to NX on every execution,
630 * so we can patch the executing code. This renders our guest
631 * NX-less.
632 */
633 pte.may_execute = !data;
634 }
635
636 if (page_found == -ENOENT) {
637 /* Page not found in guest PTE entries */
Alexander Graf5e030182010-07-29 14:47:45 +0200638 vcpu->arch.shared->dar = kvmppc_get_fault_dar(vcpu);
Alexander Grafd562de42010-07-29 14:47:44 +0200639 vcpu->arch.shared->dsisr = to_svcpu(vcpu)->fault_dsisr;
Alexander Graf666e7252010-07-29 14:47:43 +0200640 vcpu->arch.shared->msr |=
641 (to_svcpu(vcpu)->shadow_srr1 & 0x00000000f8000000ULL);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000642 kvmppc_book3s_queue_irqprio(vcpu, vec);
643 } else if (page_found == -EPERM) {
644 /* Storage protection */
Alexander Graf5e030182010-07-29 14:47:45 +0200645 vcpu->arch.shared->dar = kvmppc_get_fault_dar(vcpu);
Alexander Grafd562de42010-07-29 14:47:44 +0200646 vcpu->arch.shared->dsisr =
647 to_svcpu(vcpu)->fault_dsisr & ~DSISR_NOHPTE;
648 vcpu->arch.shared->dsisr |= DSISR_PROTFAULT;
Alexander Graf666e7252010-07-29 14:47:43 +0200649 vcpu->arch.shared->msr |=
650 (to_svcpu(vcpu)->shadow_srr1 & 0x00000000f8000000ULL);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000651 kvmppc_book3s_queue_irqprio(vcpu, vec);
652 } else if (page_found == -EINVAL) {
653 /* Page not found in guest SLB */
Alexander Graf5e030182010-07-29 14:47:45 +0200654 vcpu->arch.shared->dar = kvmppc_get_fault_dar(vcpu);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000655 kvmppc_book3s_queue_irqprio(vcpu, vec + 0x80);
656 } else if (!is_mmio &&
657 kvmppc_visible_gfn(vcpu, pte.raddr >> PAGE_SHIFT)) {
658 /* The guest's PTE is not mapped yet. Map on the host */
659 kvmppc_mmu_map_page(vcpu, &pte);
660 if (data)
661 vcpu->stat.sp_storage++;
662 else if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
663 (!(vcpu->arch.hflags & BOOK3S_HFLAG_DCBZ32)))
664 kvmppc_patch_dcbz(vcpu, &pte);
665 } else {
666 /* MMIO */
667 vcpu->stat.mmio_exits++;
668 vcpu->arch.paddr_accessed = pte.raddr;
669 r = kvmppc_emulate_mmio(run, vcpu);
670 if ( r == RESUME_HOST_NV )
671 r = RESUME_HOST;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000672 }
673
674 return r;
675}
676
Alexander Graf180a34d2010-01-15 14:49:11 +0100677static inline int get_fpr_index(int i)
678{
679#ifdef CONFIG_VSX
680 i *= 2;
681#endif
682 return i;
683}
684
685/* Give up external provider (FPU, Altivec, VSX) */
Alexander Grafaba3bd72010-02-19 11:00:39 +0100686void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr)
Alexander Graf180a34d2010-01-15 14:49:11 +0100687{
688 struct thread_struct *t = &current->thread;
689 u64 *vcpu_fpr = vcpu->arch.fpr;
Alexander Grafa2b07662010-03-24 21:48:31 +0100690#ifdef CONFIG_VSX
Alexander Graf180a34d2010-01-15 14:49:11 +0100691 u64 *vcpu_vsx = vcpu->arch.vsr;
Alexander Grafa2b07662010-03-24 21:48:31 +0100692#endif
Alexander Graf180a34d2010-01-15 14:49:11 +0100693 u64 *thread_fpr = (u64*)t->fpr;
694 int i;
695
696 if (!(vcpu->arch.guest_owned_ext & msr))
697 return;
698
699#ifdef DEBUG_EXT
700 printk(KERN_INFO "Giving up ext 0x%lx\n", msr);
701#endif
702
703 switch (msr) {
704 case MSR_FP:
705 giveup_fpu(current);
706 for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++)
707 vcpu_fpr[i] = thread_fpr[get_fpr_index(i)];
708
709 vcpu->arch.fpscr = t->fpscr.val;
710 break;
711 case MSR_VEC:
712#ifdef CONFIG_ALTIVEC
713 giveup_altivec(current);
714 memcpy(vcpu->arch.vr, t->vr, sizeof(vcpu->arch.vr));
715 vcpu->arch.vscr = t->vscr;
716#endif
717 break;
718 case MSR_VSX:
719#ifdef CONFIG_VSX
720 __giveup_vsx(current);
721 for (i = 0; i < ARRAY_SIZE(vcpu->arch.vsr); i++)
722 vcpu_vsx[i] = thread_fpr[get_fpr_index(i) + 1];
723#endif
724 break;
725 default:
726 BUG();
727 }
728
729 vcpu->arch.guest_owned_ext &= ~msr;
730 current->thread.regs->msr &= ~msr;
Alexander Grafa76f8492010-01-15 14:49:14 +0100731 kvmppc_recalc_shadow_msr(vcpu);
Alexander Graf180a34d2010-01-15 14:49:11 +0100732}
733
Alexander Graf89632212010-03-24 21:48:21 +0100734static int kvmppc_read_inst(struct kvm_vcpu *vcpu)
Alexander Grafc8c0b6f2010-02-19 11:00:34 +0100735{
Alexander Grafc7f38f42010-04-16 00:11:40 +0200736 ulong srr0 = kvmppc_get_pc(vcpu);
737 u32 last_inst = kvmppc_get_last_inst(vcpu);
Alexander Grafc8c0b6f2010-02-19 11:00:34 +0100738 int ret;
739
Alexander Grafc7f38f42010-04-16 00:11:40 +0200740 ret = kvmppc_ld(vcpu, &srr0, sizeof(u32), &last_inst, false);
Alexander Grafc8c0b6f2010-02-19 11:00:34 +0100741 if (ret == -ENOENT) {
Alexander Graf666e7252010-07-29 14:47:43 +0200742 ulong msr = vcpu->arch.shared->msr;
743
744 msr = kvmppc_set_field(msr, 33, 33, 1);
745 msr = kvmppc_set_field(msr, 34, 36, 0);
746 vcpu->arch.shared->msr = kvmppc_set_field(msr, 42, 47, 0);
Alexander Grafc8c0b6f2010-02-19 11:00:34 +0100747 kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_INST_STORAGE);
Alexander Graf89632212010-03-24 21:48:21 +0100748 return EMULATE_AGAIN;
749 }
750
751 return EMULATE_DONE;
752}
753
754static int kvmppc_check_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr)
755{
756
757 /* Need to do paired single emulation? */
758 if (!(vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE))
759 return EMULATE_DONE;
760
761 /* Read out the instruction */
762 if (kvmppc_read_inst(vcpu) == EMULATE_DONE)
Alexander Grafc8c0b6f2010-02-19 11:00:34 +0100763 /* Need to emulate */
764 return EMULATE_FAIL;
Alexander Grafc8c0b6f2010-02-19 11:00:34 +0100765
766 return EMULATE_AGAIN;
767}
768
Alexander Graf180a34d2010-01-15 14:49:11 +0100769/* Handle external providers (FPU, Altivec, VSX) */
770static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
771 ulong msr)
772{
773 struct thread_struct *t = &current->thread;
774 u64 *vcpu_fpr = vcpu->arch.fpr;
Alexander Grafa2b07662010-03-24 21:48:31 +0100775#ifdef CONFIG_VSX
Alexander Graf180a34d2010-01-15 14:49:11 +0100776 u64 *vcpu_vsx = vcpu->arch.vsr;
Alexander Grafa2b07662010-03-24 21:48:31 +0100777#endif
Alexander Graf180a34d2010-01-15 14:49:11 +0100778 u64 *thread_fpr = (u64*)t->fpr;
779 int i;
780
Alexander Graf3c402a72010-02-19 11:00:32 +0100781 /* When we have paired singles, we emulate in software */
782 if (vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE)
783 return RESUME_GUEST;
784
Alexander Graf666e7252010-07-29 14:47:43 +0200785 if (!(vcpu->arch.shared->msr & msr)) {
Alexander Graf180a34d2010-01-15 14:49:11 +0100786 kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
787 return RESUME_GUEST;
788 }
789
Alexander Grafc2453692010-03-24 21:48:22 +0100790 /* We already own the ext */
791 if (vcpu->arch.guest_owned_ext & msr) {
792 return RESUME_GUEST;
793 }
794
Alexander Graf180a34d2010-01-15 14:49:11 +0100795#ifdef DEBUG_EXT
796 printk(KERN_INFO "Loading up ext 0x%lx\n", msr);
797#endif
798
799 current->thread.regs->msr |= msr;
800
801 switch (msr) {
802 case MSR_FP:
803 for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++)
804 thread_fpr[get_fpr_index(i)] = vcpu_fpr[i];
805
806 t->fpscr.val = vcpu->arch.fpscr;
807 t->fpexc_mode = 0;
808 kvmppc_load_up_fpu();
809 break;
810 case MSR_VEC:
811#ifdef CONFIG_ALTIVEC
812 memcpy(t->vr, vcpu->arch.vr, sizeof(vcpu->arch.vr));
813 t->vscr = vcpu->arch.vscr;
814 t->vrsave = -1;
815 kvmppc_load_up_altivec();
816#endif
817 break;
818 case MSR_VSX:
819#ifdef CONFIG_VSX
820 for (i = 0; i < ARRAY_SIZE(vcpu->arch.vsr); i++)
821 thread_fpr[get_fpr_index(i) + 1] = vcpu_vsx[i];
822 kvmppc_load_up_vsx();
823#endif
824 break;
825 default:
826 BUG();
827 }
828
829 vcpu->arch.guest_owned_ext |= msr;
830
Alexander Grafa76f8492010-01-15 14:49:14 +0100831 kvmppc_recalc_shadow_msr(vcpu);
Alexander Graf180a34d2010-01-15 14:49:11 +0100832
833 return RESUME_GUEST;
834}
835
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000836int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
837 unsigned int exit_nr)
838{
839 int r = RESUME_HOST;
840
841 vcpu->stat.sum_exits++;
842
843 run->exit_reason = KVM_EXIT_UNKNOWN;
844 run->ready_for_interrupt_injection = 1;
Alexander Grafbed1ed92010-08-02 11:06:26 +0200845
846 trace_kvm_book3s_exit(exit_nr, vcpu);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000847 kvm_resched(vcpu);
848 switch (exit_nr) {
849 case BOOK3S_INTERRUPT_INST_STORAGE:
850 vcpu->stat.pf_instruc++;
Alexander Graf61db97c2010-04-16 00:11:52 +0200851
852#ifdef CONFIG_PPC_BOOK3S_32
853 /* We set segments as unused segments when invalidating them. So
854 * treat the respective fault as segment fault. */
855 if (to_svcpu(vcpu)->sr[kvmppc_get_pc(vcpu) >> SID_SHIFT]
856 == SR_INVALID) {
857 kvmppc_mmu_map_segment(vcpu, kvmppc_get_pc(vcpu));
858 r = RESUME_GUEST;
859 break;
860 }
861#endif
862
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000863 /* only care about PTEG not found errors, but leave NX alone */
Alexander Grafc7f38f42010-04-16 00:11:40 +0200864 if (to_svcpu(vcpu)->shadow_srr1 & 0x40000000) {
865 r = kvmppc_handle_pagefault(run, vcpu, kvmppc_get_pc(vcpu), exit_nr);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000866 vcpu->stat.sp_instruc++;
867 } else if (vcpu->arch.mmu.is_dcbz32(vcpu) &&
868 (!(vcpu->arch.hflags & BOOK3S_HFLAG_DCBZ32))) {
869 /*
870 * XXX If we do the dcbz hack we use the NX bit to flush&patch the page,
871 * so we can't use the NX bit inside the guest. Let's cross our fingers,
872 * that no guest that needs the dcbz hack does NX.
873 */
Alexander Grafaf7b4d12010-04-20 02:49:46 +0200874 kvmppc_mmu_pte_flush(vcpu, kvmppc_get_pc(vcpu), ~0xFFFUL);
Alexander Graf9fb244a2010-03-24 21:48:32 +0100875 r = RESUME_GUEST;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000876 } else {
Alexander Graf666e7252010-07-29 14:47:43 +0200877 vcpu->arch.shared->msr |=
878 to_svcpu(vcpu)->shadow_srr1 & 0x58000000;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000879 kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
Alexander Grafaf7b4d12010-04-20 02:49:46 +0200880 kvmppc_mmu_pte_flush(vcpu, kvmppc_get_pc(vcpu), ~0xFFFUL);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000881 r = RESUME_GUEST;
882 }
883 break;
884 case BOOK3S_INTERRUPT_DATA_STORAGE:
Alexander Grafc7f38f42010-04-16 00:11:40 +0200885 {
886 ulong dar = kvmppc_get_fault_dar(vcpu);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000887 vcpu->stat.pf_storage++;
Alexander Graf61db97c2010-04-16 00:11:52 +0200888
889#ifdef CONFIG_PPC_BOOK3S_32
890 /* We set segments as unused segments when invalidating them. So
891 * treat the respective fault as segment fault. */
892 if ((to_svcpu(vcpu)->sr[dar >> SID_SHIFT]) == SR_INVALID) {
893 kvmppc_mmu_map_segment(vcpu, dar);
894 r = RESUME_GUEST;
895 break;
896 }
897#endif
898
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000899 /* The only case we need to handle is missing shadow PTEs */
Alexander Grafc7f38f42010-04-16 00:11:40 +0200900 if (to_svcpu(vcpu)->fault_dsisr & DSISR_NOHPTE) {
901 r = kvmppc_handle_pagefault(run, vcpu, dar, exit_nr);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000902 } else {
Alexander Graf5e030182010-07-29 14:47:45 +0200903 vcpu->arch.shared->dar = dar;
Alexander Grafd562de42010-07-29 14:47:44 +0200904 vcpu->arch.shared->dsisr = to_svcpu(vcpu)->fault_dsisr;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000905 kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
Alexander Graf5e030182010-07-29 14:47:45 +0200906 kvmppc_mmu_pte_flush(vcpu, dar, ~0xFFFUL);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000907 r = RESUME_GUEST;
908 }
909 break;
Alexander Grafc7f38f42010-04-16 00:11:40 +0200910 }
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000911 case BOOK3S_INTERRUPT_DATA_SEGMENT:
Alexander Grafc7f38f42010-04-16 00:11:40 +0200912 if (kvmppc_mmu_map_segment(vcpu, kvmppc_get_fault_dar(vcpu)) < 0) {
Alexander Graf5e030182010-07-29 14:47:45 +0200913 vcpu->arch.shared->dar = kvmppc_get_fault_dar(vcpu);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000914 kvmppc_book3s_queue_irqprio(vcpu,
915 BOOK3S_INTERRUPT_DATA_SEGMENT);
916 }
917 r = RESUME_GUEST;
918 break;
919 case BOOK3S_INTERRUPT_INST_SEGMENT:
Alexander Grafc7f38f42010-04-16 00:11:40 +0200920 if (kvmppc_mmu_map_segment(vcpu, kvmppc_get_pc(vcpu)) < 0) {
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000921 kvmppc_book3s_queue_irqprio(vcpu,
922 BOOK3S_INTERRUPT_INST_SEGMENT);
923 }
924 r = RESUME_GUEST;
925 break;
926 /* We're good on these - the host merely wanted to get our attention */
927 case BOOK3S_INTERRUPT_DECREMENTER:
928 vcpu->stat.dec_exits++;
929 r = RESUME_GUEST;
930 break;
931 case BOOK3S_INTERRUPT_EXTERNAL:
932 vcpu->stat.ext_intr_exits++;
933 r = RESUME_GUEST;
934 break;
Alexander Graf7fdaec92010-04-20 02:49:47 +0200935 case BOOK3S_INTERRUPT_PERFMON:
936 r = RESUME_GUEST;
937 break;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000938 case BOOK3S_INTERRUPT_PROGRAM:
939 {
940 enum emulation_result er;
Alexander Grafff1ca3f2010-01-08 02:58:09 +0100941 ulong flags;
942
Alexander Grafc8c0b6f2010-02-19 11:00:34 +0100943program_interrupt:
Alexander Grafc7f38f42010-04-16 00:11:40 +0200944 flags = to_svcpu(vcpu)->shadow_srr1 & 0x1f0000ull;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000945
Alexander Graf666e7252010-07-29 14:47:43 +0200946 if (vcpu->arch.shared->msr & MSR_PR) {
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000947#ifdef EXIT_DEBUG
Alexander Grafc7f38f42010-04-16 00:11:40 +0200948 printk(KERN_INFO "Userspace triggered 0x700 exception at 0x%lx (0x%x)\n", kvmppc_get_pc(vcpu), kvmppc_get_last_inst(vcpu));
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000949#endif
Alexander Grafc7f38f42010-04-16 00:11:40 +0200950 if ((kvmppc_get_last_inst(vcpu) & 0xff0007ff) !=
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000951 (INS_DCBZ & 0xfffffff7)) {
Alexander Grafff1ca3f2010-01-08 02:58:09 +0100952 kvmppc_core_queue_program(vcpu, flags);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000953 r = RESUME_GUEST;
954 break;
955 }
956 }
957
958 vcpu->stat.emulated_inst_exits++;
959 er = kvmppc_emulate_instruction(run, vcpu);
960 switch (er) {
961 case EMULATE_DONE:
Alexander Graf97c4cfb2010-01-04 22:19:25 +0100962 r = RESUME_GUEST_NV;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000963 break;
Alexander Graf37f5bca2010-02-19 11:00:31 +0100964 case EMULATE_AGAIN:
965 r = RESUME_GUEST;
966 break;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000967 case EMULATE_FAIL:
968 printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n",
Alexander Grafc7f38f42010-04-16 00:11:40 +0200969 __func__, kvmppc_get_pc(vcpu), kvmppc_get_last_inst(vcpu));
Alexander Grafff1ca3f2010-01-08 02:58:09 +0100970 kvmppc_core_queue_program(vcpu, flags);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000971 r = RESUME_GUEST;
972 break;
Alexander Grafe5c29e92010-02-19 11:00:43 +0100973 case EMULATE_DO_MMIO:
974 run->exit_reason = KVM_EXIT_MMIO;
975 r = RESUME_HOST_NV;
976 break;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +0000977 default:
978 BUG();
979 }
980 break;
981 }
982 case BOOK3S_INTERRUPT_SYSCALL:
Alexander Grafad0a0482010-03-24 21:48:30 +0100983 if (vcpu->arch.osi_enabled &&
984 (((u32)kvmppc_get_gpr(vcpu, 3)) == OSI_SC_MAGIC_R3) &&
985 (((u32)kvmppc_get_gpr(vcpu, 4)) == OSI_SC_MAGIC_R4)) {
Alexander Graf2a342ed2010-07-29 14:47:48 +0200986 /* MOL hypercalls */
Alexander Grafad0a0482010-03-24 21:48:30 +0100987 u64 *gprs = run->osi.gprs;
988 int i;
989
990 run->exit_reason = KVM_EXIT_OSI;
991 for (i = 0; i < 32; i++)
992 gprs[i] = kvmppc_get_gpr(vcpu, i);
993 vcpu->arch.osi_needed = 1;
994 r = RESUME_HOST_NV;
Alexander Graf2a342ed2010-07-29 14:47:48 +0200995 } else if (!(vcpu->arch.shared->msr & MSR_PR) &&
996 (((u32)kvmppc_get_gpr(vcpu, 0)) == KVM_SC_MAGIC_R0)) {
997 /* KVM PV hypercalls */
998 kvmppc_set_gpr(vcpu, 3, kvmppc_kvm_pv(vcpu));
999 r = RESUME_GUEST;
Alexander Grafad0a0482010-03-24 21:48:30 +01001000 } else {
Alexander Graf2a342ed2010-07-29 14:47:48 +02001001 /* Guest syscalls */
Alexander Grafad0a0482010-03-24 21:48:30 +01001002 vcpu->stat.syscall_exits++;
1003 kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
1004 r = RESUME_GUEST;
1005 }
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001006 break;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001007 case BOOK3S_INTERRUPT_FP_UNAVAIL:
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001008 case BOOK3S_INTERRUPT_ALTIVEC:
1009 case BOOK3S_INTERRUPT_VSX:
Alexander Grafc8c0b6f2010-02-19 11:00:34 +01001010 {
1011 int ext_msr = 0;
1012
1013 switch (exit_nr) {
1014 case BOOK3S_INTERRUPT_FP_UNAVAIL: ext_msr = MSR_FP; break;
1015 case BOOK3S_INTERRUPT_ALTIVEC: ext_msr = MSR_VEC; break;
1016 case BOOK3S_INTERRUPT_VSX: ext_msr = MSR_VSX; break;
1017 }
1018
1019 switch (kvmppc_check_ext(vcpu, exit_nr)) {
1020 case EMULATE_DONE:
1021 /* everything ok - let's enable the ext */
1022 r = kvmppc_handle_ext(vcpu, exit_nr, ext_msr);
1023 break;
1024 case EMULATE_FAIL:
1025 /* we need to emulate this instruction */
1026 goto program_interrupt;
1027 break;
1028 default:
1029 /* nothing to worry about - go again */
1030 break;
1031 }
Alexander Graf180a34d2010-01-15 14:49:11 +01001032 break;
Alexander Grafc8c0b6f2010-02-19 11:00:34 +01001033 }
Alexander Grafca7f4202010-03-24 21:48:28 +01001034 case BOOK3S_INTERRUPT_ALIGNMENT:
1035 if (kvmppc_read_inst(vcpu) == EMULATE_DONE) {
Alexander Grafd562de42010-07-29 14:47:44 +02001036 vcpu->arch.shared->dsisr = kvmppc_alignment_dsisr(vcpu,
Alexander Grafc7f38f42010-04-16 00:11:40 +02001037 kvmppc_get_last_inst(vcpu));
Alexander Graf5e030182010-07-29 14:47:45 +02001038 vcpu->arch.shared->dar = kvmppc_alignment_dar(vcpu,
Alexander Grafc7f38f42010-04-16 00:11:40 +02001039 kvmppc_get_last_inst(vcpu));
Alexander Grafca7f4202010-03-24 21:48:28 +01001040 kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
1041 }
1042 r = RESUME_GUEST;
1043 break;
Alexander Graf180a34d2010-01-15 14:49:11 +01001044 case BOOK3S_INTERRUPT_MACHINE_CHECK:
1045 case BOOK3S_INTERRUPT_TRACE:
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001046 kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
1047 r = RESUME_GUEST;
1048 break;
1049 default:
1050 /* Ugh - bork here! What did we get? */
Alexander Graff7adbba2010-01-15 14:49:13 +01001051 printk(KERN_EMERG "exit_nr=0x%x | pc=0x%lx | msr=0x%lx\n",
Alexander Grafc7f38f42010-04-16 00:11:40 +02001052 exit_nr, kvmppc_get_pc(vcpu), to_svcpu(vcpu)->shadow_srr1);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001053 r = RESUME_HOST;
1054 BUG();
1055 break;
1056 }
1057
1058
1059 if (!(r & RESUME_HOST)) {
1060 /* To avoid clobbering exit_reason, only check for signals if
1061 * we aren't already exiting to userspace for some other
1062 * reason. */
1063 if (signal_pending(current)) {
1064#ifdef EXIT_DEBUG
1065 printk(KERN_EMERG "KVM: Going back to host\n");
1066#endif
1067 vcpu->stat.signal_exits++;
1068 run->exit_reason = KVM_EXIT_INTR;
1069 r = -EINTR;
1070 } else {
1071 /* In case an interrupt came in that was triggered
1072 * from userspace (like DEC), we need to check what
1073 * to inject now! */
1074 kvmppc_core_deliver_interrupts(vcpu);
1075 }
1076 }
1077
Alexander Grafbed1ed92010-08-02 11:06:26 +02001078 trace_kvm_book3s_reenter(r, vcpu);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001079
1080 return r;
1081}
1082
1083int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
1084{
1085 return 0;
1086}
1087
1088int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
1089{
1090 int i;
1091
Alexander Grafc7f38f42010-04-16 00:11:40 +02001092 regs->pc = kvmppc_get_pc(vcpu);
Alexander Graf992b5b22010-01-08 02:58:02 +01001093 regs->cr = kvmppc_get_cr(vcpu);
Alexander Grafc7f38f42010-04-16 00:11:40 +02001094 regs->ctr = kvmppc_get_ctr(vcpu);
1095 regs->lr = kvmppc_get_lr(vcpu);
Alexander Graf992b5b22010-01-08 02:58:02 +01001096 regs->xer = kvmppc_get_xer(vcpu);
Alexander Graf666e7252010-07-29 14:47:43 +02001097 regs->msr = vcpu->arch.shared->msr;
Alexander Grafde7906c2010-07-29 14:47:46 +02001098 regs->srr0 = vcpu->arch.shared->srr0;
1099 regs->srr1 = vcpu->arch.shared->srr1;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001100 regs->pid = vcpu->arch.pid;
Alexander Grafa73a9592010-07-29 14:47:47 +02001101 regs->sprg0 = vcpu->arch.shared->sprg0;
1102 regs->sprg1 = vcpu->arch.shared->sprg1;
1103 regs->sprg2 = vcpu->arch.shared->sprg2;
1104 regs->sprg3 = vcpu->arch.shared->sprg3;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001105 regs->sprg5 = vcpu->arch.sprg4;
1106 regs->sprg6 = vcpu->arch.sprg5;
1107 regs->sprg7 = vcpu->arch.sprg6;
1108
1109 for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
Alexander Graf8e5b26b2010-01-08 02:58:01 +01001110 regs->gpr[i] = kvmppc_get_gpr(vcpu, i);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001111
1112 return 0;
1113}
1114
1115int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
1116{
1117 int i;
1118
Alexander Grafc7f38f42010-04-16 00:11:40 +02001119 kvmppc_set_pc(vcpu, regs->pc);
Alexander Graf992b5b22010-01-08 02:58:02 +01001120 kvmppc_set_cr(vcpu, regs->cr);
Alexander Grafc7f38f42010-04-16 00:11:40 +02001121 kvmppc_set_ctr(vcpu, regs->ctr);
1122 kvmppc_set_lr(vcpu, regs->lr);
Alexander Graf992b5b22010-01-08 02:58:02 +01001123 kvmppc_set_xer(vcpu, regs->xer);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001124 kvmppc_set_msr(vcpu, regs->msr);
Alexander Grafde7906c2010-07-29 14:47:46 +02001125 vcpu->arch.shared->srr0 = regs->srr0;
1126 vcpu->arch.shared->srr1 = regs->srr1;
Alexander Grafa73a9592010-07-29 14:47:47 +02001127 vcpu->arch.shared->sprg0 = regs->sprg0;
1128 vcpu->arch.shared->sprg1 = regs->sprg1;
1129 vcpu->arch.shared->sprg2 = regs->sprg2;
1130 vcpu->arch.shared->sprg3 = regs->sprg3;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001131 vcpu->arch.sprg5 = regs->sprg4;
1132 vcpu->arch.sprg6 = regs->sprg5;
1133 vcpu->arch.sprg7 = regs->sprg6;
1134
Alexander Graf8e5b26b2010-01-08 02:58:01 +01001135 for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
1136 kvmppc_set_gpr(vcpu, i, regs->gpr[i]);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001137
1138 return 0;
1139}
1140
1141int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
1142 struct kvm_sregs *sregs)
1143{
Alexander Grafe15a1132009-11-30 03:02:02 +00001144 struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu);
1145 int i;
1146
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001147 sregs->pvr = vcpu->arch.pvr;
Alexander Grafe15a1132009-11-30 03:02:02 +00001148
1149 sregs->u.s.sdr1 = to_book3s(vcpu)->sdr1;
1150 if (vcpu->arch.hflags & BOOK3S_HFLAG_SLB) {
1151 for (i = 0; i < 64; i++) {
1152 sregs->u.s.ppc64.slb[i].slbe = vcpu3s->slb[i].orige | i;
1153 sregs->u.s.ppc64.slb[i].slbv = vcpu3s->slb[i].origv;
1154 }
1155 } else {
1156 for (i = 0; i < 16; i++) {
1157 sregs->u.s.ppc32.sr[i] = vcpu3s->sr[i].raw;
1158 sregs->u.s.ppc32.sr[i] = vcpu3s->sr[i].raw;
1159 }
1160 for (i = 0; i < 8; i++) {
1161 sregs->u.s.ppc32.ibat[i] = vcpu3s->ibat[i].raw;
1162 sregs->u.s.ppc32.dbat[i] = vcpu3s->dbat[i].raw;
1163 }
1164 }
Avi Kivity98001d82010-05-13 11:05:49 +03001165
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001166 return 0;
1167}
1168
1169int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
1170 struct kvm_sregs *sregs)
1171{
Alexander Grafe15a1132009-11-30 03:02:02 +00001172 struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu);
1173 int i;
1174
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001175 kvmppc_set_pvr(vcpu, sregs->pvr);
Alexander Grafe15a1132009-11-30 03:02:02 +00001176
1177 vcpu3s->sdr1 = sregs->u.s.sdr1;
1178 if (vcpu->arch.hflags & BOOK3S_HFLAG_SLB) {
1179 for (i = 0; i < 64; i++) {
1180 vcpu->arch.mmu.slbmte(vcpu, sregs->u.s.ppc64.slb[i].slbv,
1181 sregs->u.s.ppc64.slb[i].slbe);
1182 }
1183 } else {
1184 for (i = 0; i < 16; i++) {
1185 vcpu->arch.mmu.mtsrin(vcpu, i, sregs->u.s.ppc32.sr[i]);
1186 }
1187 for (i = 0; i < 8; i++) {
1188 kvmppc_set_bat(vcpu, &(vcpu3s->ibat[i]), false,
1189 (u32)sregs->u.s.ppc32.ibat[i]);
1190 kvmppc_set_bat(vcpu, &(vcpu3s->ibat[i]), true,
1191 (u32)(sregs->u.s.ppc32.ibat[i] >> 32));
1192 kvmppc_set_bat(vcpu, &(vcpu3s->dbat[i]), false,
1193 (u32)sregs->u.s.ppc32.dbat[i]);
1194 kvmppc_set_bat(vcpu, &(vcpu3s->dbat[i]), true,
1195 (u32)(sregs->u.s.ppc32.dbat[i] >> 32));
1196 }
1197 }
1198
1199 /* Flush the MMU after messing with the segments */
1200 kvmppc_mmu_pte_flush(vcpu, 0, 0);
Avi Kivity98001d82010-05-13 11:05:49 +03001201
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001202 return 0;
1203}
1204
1205int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
1206{
1207 return -ENOTSUPP;
1208}
1209
1210int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
1211{
1212 return -ENOTSUPP;
1213}
1214
1215int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
1216 struct kvm_translation *tr)
1217{
1218 return 0;
1219}
1220
1221/*
1222 * Get (and clear) the dirty memory log for a memory slot.
1223 */
1224int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
1225 struct kvm_dirty_log *log)
1226{
1227 struct kvm_memory_slot *memslot;
1228 struct kvm_vcpu *vcpu;
1229 ulong ga, ga_end;
1230 int is_dirty = 0;
Takuya Yoshikawa87bf6e72010-04-12 19:35:35 +09001231 int r;
1232 unsigned long n;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001233
Marcelo Tosatti79fac952009-12-23 14:35:26 -02001234 mutex_lock(&kvm->slots_lock);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001235
1236 r = kvm_get_dirty_log(kvm, log, &is_dirty);
1237 if (r)
1238 goto out;
1239
1240 /* If nothing is dirty, don't bother messing with page tables. */
1241 if (is_dirty) {
Marcelo Tosatti46a26bf2009-12-23 14:35:16 -02001242 memslot = &kvm->memslots->memslots[log->slot];
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001243
1244 ga = memslot->base_gfn << PAGE_SHIFT;
1245 ga_end = ga + (memslot->npages << PAGE_SHIFT);
1246
1247 kvm_for_each_vcpu(n, vcpu, kvm)
1248 kvmppc_mmu_pte_pflush(vcpu, ga, ga_end);
1249
Takuya Yoshikawa87bf6e72010-04-12 19:35:35 +09001250 n = kvm_dirty_bitmap_bytes(memslot);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001251 memset(memslot->dirty_bitmap, 0, n);
1252 }
1253
1254 r = 0;
1255out:
Marcelo Tosatti79fac952009-12-23 14:35:26 -02001256 mutex_unlock(&kvm->slots_lock);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001257 return r;
1258}
1259
1260int kvmppc_core_check_processor_compat(void)
1261{
1262 return 0;
1263}
1264
1265struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
1266{
1267 struct kvmppc_vcpu_book3s *vcpu_book3s;
1268 struct kvm_vcpu *vcpu;
Alexander Grafc7f38f42010-04-16 00:11:40 +02001269 int err = -ENOMEM;
Alexander Grafe8508942010-07-29 14:47:54 +02001270 unsigned long p;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001271
Alexander Graf032c3402010-02-19 12:24:33 +01001272 vcpu_book3s = vmalloc(sizeof(struct kvmppc_vcpu_book3s));
Alexander Grafc7f38f42010-04-16 00:11:40 +02001273 if (!vcpu_book3s)
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001274 goto out;
Alexander Grafc7f38f42010-04-16 00:11:40 +02001275
Alexander Graf7e821d32010-02-22 16:52:08 +01001276 memset(vcpu_book3s, 0, sizeof(struct kvmppc_vcpu_book3s));
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001277
Alexander Grafc7f38f42010-04-16 00:11:40 +02001278 vcpu_book3s->shadow_vcpu = (struct kvmppc_book3s_shadow_vcpu *)
1279 kzalloc(sizeof(*vcpu_book3s->shadow_vcpu), GFP_KERNEL);
1280 if (!vcpu_book3s->shadow_vcpu)
1281 goto free_vcpu;
1282
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001283 vcpu = &vcpu_book3s->vcpu;
1284 err = kvm_vcpu_init(vcpu, kvm, id);
1285 if (err)
Alexander Grafc7f38f42010-04-16 00:11:40 +02001286 goto free_shadow_vcpu;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001287
Alexander Grafe8508942010-07-29 14:47:54 +02001288 p = __get_free_page(GFP_KERNEL|__GFP_ZERO);
1289 /* the real shared page fills the last 4k of our page */
1290 vcpu->arch.shared = (void*)(p + PAGE_SIZE - 4096);
1291 if (!p)
Alexander Graf96bc4512010-07-29 14:47:42 +02001292 goto uninit_vcpu;
1293
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001294 vcpu->arch.host_retip = kvm_return_point;
1295 vcpu->arch.host_msr = mfmsr();
Alexander Graf07b09072010-04-16 00:11:53 +02001296#ifdef CONFIG_PPC_BOOK3S_64
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001297 /* default to book3s_64 (970fx) */
1298 vcpu->arch.pvr = 0x3C0301;
Alexander Graf07b09072010-04-16 00:11:53 +02001299#else
1300 /* default to book3s_32 (750) */
1301 vcpu->arch.pvr = 0x84202;
1302#endif
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001303 kvmppc_set_pvr(vcpu, vcpu->arch.pvr);
1304 vcpu_book3s->slb_nr = 64;
1305
1306 /* remember where some real-mode handlers are */
1307 vcpu->arch.trampoline_lowmem = kvmppc_trampoline_lowmem;
1308 vcpu->arch.trampoline_enter = kvmppc_trampoline_enter;
1309 vcpu->arch.highmem_handler = (ulong)kvmppc_handler_highmem;
Alexander Graf07b09072010-04-16 00:11:53 +02001310#ifdef CONFIG_PPC_BOOK3S_64
Alexander Graf021ec9c2010-01-08 02:58:06 +01001311 vcpu->arch.rmcall = *(ulong*)kvmppc_rmcall;
Alexander Graf07b09072010-04-16 00:11:53 +02001312#else
1313 vcpu->arch.rmcall = (ulong)kvmppc_rmcall;
1314#endif
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001315
1316 vcpu->arch.shadow_msr = MSR_USER64;
1317
Alexander Graf9cc5e952010-04-16 00:11:45 +02001318 err = kvmppc_mmu_init(vcpu);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001319 if (err < 0)
Alexander Graf96bc4512010-07-29 14:47:42 +02001320 goto uninit_vcpu;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001321
1322 return vcpu;
1323
Alexander Graf96bc4512010-07-29 14:47:42 +02001324uninit_vcpu:
1325 kvm_vcpu_uninit(vcpu);
Alexander Grafc7f38f42010-04-16 00:11:40 +02001326free_shadow_vcpu:
1327 kfree(vcpu_book3s->shadow_vcpu);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001328free_vcpu:
Alexander Graf032c3402010-02-19 12:24:33 +01001329 vfree(vcpu_book3s);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001330out:
1331 return ERR_PTR(err);
1332}
1333
1334void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
1335{
1336 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
1337
Alexander Grafe8508942010-07-29 14:47:54 +02001338 free_page((unsigned long)vcpu->arch.shared & PAGE_MASK);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001339 kvm_vcpu_uninit(vcpu);
Alexander Grafc7f38f42010-04-16 00:11:40 +02001340 kfree(vcpu_book3s->shadow_vcpu);
Alexander Graf032c3402010-02-19 12:24:33 +01001341 vfree(vcpu_book3s);
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001342}
1343
1344extern int __kvmppc_vcpu_entry(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
1345int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
1346{
1347 int ret;
Andreas Schwab49f6be82010-05-31 21:59:13 +02001348 double fpr[32][TS_FPRWIDTH];
1349 unsigned int fpscr;
1350 int fpexc_mode;
Alexander Grafa2b07662010-03-24 21:48:31 +01001351#ifdef CONFIG_ALTIVEC
Andreas Schwab49f6be82010-05-31 21:59:13 +02001352 vector128 vr[32];
1353 vector128 vscr;
1354 unsigned long uninitialized_var(vrsave);
1355 int used_vr;
Alexander Grafa2b07662010-03-24 21:48:31 +01001356#endif
1357#ifdef CONFIG_VSX
Andreas Schwab49f6be82010-05-31 21:59:13 +02001358 int used_vsr;
Alexander Grafa2b07662010-03-24 21:48:31 +01001359#endif
Alexander Graf180a34d2010-01-15 14:49:11 +01001360 ulong ext_msr;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001361
1362 /* No need to go into the guest when all we do is going out */
1363 if (signal_pending(current)) {
1364 kvm_run->exit_reason = KVM_EXIT_INTR;
1365 return -EINTR;
1366 }
1367
Alexander Graf180a34d2010-01-15 14:49:11 +01001368 /* Save FPU state in stack */
1369 if (current->thread.regs->msr & MSR_FP)
1370 giveup_fpu(current);
Andreas Schwab49f6be82010-05-31 21:59:13 +02001371 memcpy(fpr, current->thread.fpr, sizeof(current->thread.fpr));
1372 fpscr = current->thread.fpscr.val;
1373 fpexc_mode = current->thread.fpexc_mode;
Alexander Graf180a34d2010-01-15 14:49:11 +01001374
1375#ifdef CONFIG_ALTIVEC
1376 /* Save Altivec state in stack */
Andreas Schwab49f6be82010-05-31 21:59:13 +02001377 used_vr = current->thread.used_vr;
1378 if (used_vr) {
Alexander Graf180a34d2010-01-15 14:49:11 +01001379 if (current->thread.regs->msr & MSR_VEC)
1380 giveup_altivec(current);
Andreas Schwab49f6be82010-05-31 21:59:13 +02001381 memcpy(vr, current->thread.vr, sizeof(current->thread.vr));
1382 vscr = current->thread.vscr;
1383 vrsave = current->thread.vrsave;
Alexander Graf180a34d2010-01-15 14:49:11 +01001384 }
Alexander Graf180a34d2010-01-15 14:49:11 +01001385#endif
1386
1387#ifdef CONFIG_VSX
1388 /* Save VSX state in stack */
Andreas Schwab49f6be82010-05-31 21:59:13 +02001389 used_vsr = current->thread.used_vsr;
1390 if (used_vsr && (current->thread.regs->msr & MSR_VSX))
Alexander Graf180a34d2010-01-15 14:49:11 +01001391 __giveup_vsx(current);
Alexander Graf180a34d2010-01-15 14:49:11 +01001392#endif
1393
1394 /* Remember the MSR with disabled extensions */
1395 ext_msr = current->thread.regs->msr;
1396
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001397 /* XXX we get called with irq disabled - change that! */
1398 local_irq_enable();
1399
Alexander Grafd1bab742010-02-19 11:00:35 +01001400 /* Preload FPU if it's enabled */
Alexander Graf666e7252010-07-29 14:47:43 +02001401 if (vcpu->arch.shared->msr & MSR_FP)
Alexander Grafd1bab742010-02-19 11:00:35 +01001402 kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP);
1403
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001404 ret = __kvmppc_vcpu_entry(kvm_run, vcpu);
1405
1406 local_irq_disable();
1407
Alexander Graf180a34d2010-01-15 14:49:11 +01001408 current->thread.regs->msr = ext_msr;
1409
1410 /* Make sure we save the guest FPU/Altivec/VSX state */
1411 kvmppc_giveup_ext(vcpu, MSR_FP);
1412 kvmppc_giveup_ext(vcpu, MSR_VEC);
1413 kvmppc_giveup_ext(vcpu, MSR_VSX);
1414
1415 /* Restore FPU state from stack */
Andreas Schwab49f6be82010-05-31 21:59:13 +02001416 memcpy(current->thread.fpr, fpr, sizeof(current->thread.fpr));
1417 current->thread.fpscr.val = fpscr;
1418 current->thread.fpexc_mode = fpexc_mode;
Alexander Graf180a34d2010-01-15 14:49:11 +01001419
1420#ifdef CONFIG_ALTIVEC
1421 /* Restore Altivec state from stack */
Andreas Schwab49f6be82010-05-31 21:59:13 +02001422 if (used_vr && current->thread.used_vr) {
1423 memcpy(current->thread.vr, vr, sizeof(current->thread.vr));
1424 current->thread.vscr = vscr;
1425 current->thread.vrsave = vrsave;
Alexander Graf180a34d2010-01-15 14:49:11 +01001426 }
Andreas Schwab49f6be82010-05-31 21:59:13 +02001427 current->thread.used_vr = used_vr;
Alexander Graf180a34d2010-01-15 14:49:11 +01001428#endif
1429
1430#ifdef CONFIG_VSX
Andreas Schwab49f6be82010-05-31 21:59:13 +02001431 current->thread.used_vsr = used_vsr;
Alexander Graf180a34d2010-01-15 14:49:11 +01001432#endif
1433
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001434 return ret;
1435}
1436
1437static int kvmppc_book3s_init(void)
1438{
Alexander Graffef093b2010-06-30 15:18:46 +02001439 int r;
1440
1441 r = kvm_init(NULL, sizeof(struct kvmppc_vcpu_book3s), 0,
1442 THIS_MODULE);
1443
1444 if (r)
1445 return r;
1446
1447 r = kvmppc_mmu_hpte_sysinit();
1448
1449 return r;
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001450}
1451
1452static void kvmppc_book3s_exit(void)
1453{
Alexander Graffef093b2010-06-30 15:18:46 +02001454 kvmppc_mmu_hpte_sysexit();
Alexander Graf2f4cf5e2009-10-30 05:47:10 +00001455 kvm_exit();
1456}
1457
1458module_init(kvmppc_book3s_init);
1459module_exit(kvmppc_book3s_exit);