blob: c78ceb9d5605a1d2fc66441f686e1052148e137d [file] [log] [blame]
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -05001/*
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 IBM Corp. 2007
16 *
17 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18 * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
19 */
20
21#include <linux/errno.h>
22#include <linux/err.h>
23#include <linux/kvm_host.h>
24#include <linux/module.h>
25#include <linux/vmalloc.h>
Alexander Graf544c6762009-11-02 12:02:31 +000026#include <linux/hrtimer.h>
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -050027#include <linux/fs.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090028#include <linux/slab.h>
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -050029#include <asm/cputable.h>
30#include <asm/uaccess.h>
31#include <asm/kvm_ppc.h>
Hollis Blanchard83aae4a2008-07-25 13:54:52 -050032#include <asm/tlbflush.h>
Hollis Blanchard73e75b42008-12-02 15:51:57 -060033#include "timing.h"
Paul Mackerrasfad7b9b2008-12-23 14:57:26 +110034#include "../mm/mmu_decl.h"
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -050035
Marcelo Tosatti46f43c62009-06-18 11:47:27 -030036#define CREATE_TRACE_POINTS
37#include "trace.h"
38
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -050039int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
40{
Paul Mackerrasde56a942011-06-29 00:21:34 +000041#ifndef CONFIG_KVM_BOOK3S_64_HV
Alexander Graf666e7252010-07-29 14:47:43 +020042 return !(v->arch.shared->msr & MSR_WE) ||
43 !!(v->arch.pending_exceptions);
Paul Mackerrasde56a942011-06-29 00:21:34 +000044#else
Paul Mackerrasa8606e22011-06-29 00:22:05 +000045 return !(v->arch.ceded) || !!(v->arch.pending_exceptions);
Paul Mackerrasde56a942011-06-29 00:21:34 +000046#endif
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -050047}
48
Alexander Graf2a342ed2010-07-29 14:47:48 +020049int kvmppc_kvm_pv(struct kvm_vcpu *vcpu)
50{
51 int nr = kvmppc_get_gpr(vcpu, 11);
52 int r;
53 unsigned long __maybe_unused param1 = kvmppc_get_gpr(vcpu, 3);
54 unsigned long __maybe_unused param2 = kvmppc_get_gpr(vcpu, 4);
55 unsigned long __maybe_unused param3 = kvmppc_get_gpr(vcpu, 5);
56 unsigned long __maybe_unused param4 = kvmppc_get_gpr(vcpu, 6);
57 unsigned long r2 = 0;
58
59 if (!(vcpu->arch.shared->msr & MSR_SF)) {
60 /* 32 bit mode */
61 param1 &= 0xffffffff;
62 param2 &= 0xffffffff;
63 param3 &= 0xffffffff;
64 param4 &= 0xffffffff;
65 }
66
67 switch (nr) {
Alexander Graf5fc87402010-07-29 14:47:55 +020068 case HC_VENDOR_KVM | KVM_HC_PPC_MAP_MAGIC_PAGE:
69 {
70 vcpu->arch.magic_page_pa = param1;
71 vcpu->arch.magic_page_ea = param2;
72
Alexander Grafdf1bfa22010-08-03 02:29:27 +020073 r2 = KVM_MAGIC_FEAT_SR;
Alexander Graf7508e162010-08-03 11:32:56 +020074
Alexander Graf5fc87402010-07-29 14:47:55 +020075 r = HC_EV_SUCCESS;
76 break;
77 }
Alexander Graf2a342ed2010-07-29 14:47:48 +020078 case HC_VENDOR_KVM | KVM_HC_FEATURES:
79 r = HC_EV_SUCCESS;
Scott Wooda4cd8b22011-06-14 18:34:41 -050080#if defined(CONFIG_PPC_BOOK3S) || defined(CONFIG_KVM_E500)
81 /* XXX Missing magic page on 44x */
Alexander Graf5fc87402010-07-29 14:47:55 +020082 r2 |= (1 << KVM_FEATURE_MAGIC_PAGE);
83#endif
Alexander Graf2a342ed2010-07-29 14:47:48 +020084
85 /* Second return value is in r4 */
Alexander Graf2a342ed2010-07-29 14:47:48 +020086 break;
87 default:
88 r = HC_EV_UNIMPLEMENTED;
89 break;
90 }
91
Alexander Graf7508e162010-08-03 11:32:56 +020092 kvmppc_set_gpr(vcpu, 4, r2);
93
Alexander Graf2a342ed2010-07-29 14:47:48 +020094 return r;
95}
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -050096
97int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu)
98{
99 enum emulation_result er;
100 int r;
101
102 er = kvmppc_emulate_instruction(run, vcpu);
103 switch (er) {
104 case EMULATE_DONE:
105 /* Future optimization: only reload non-volatiles if they were
106 * actually modified. */
107 r = RESUME_GUEST_NV;
108 break;
109 case EMULATE_DO_MMIO:
110 run->exit_reason = KVM_EXIT_MMIO;
111 /* We must reload nonvolatiles because "update" load/store
112 * instructions modify register state. */
113 /* Future optimization: only reload non-volatiles if they were
114 * actually modified. */
115 r = RESUME_HOST_NV;
116 break;
117 case EMULATE_FAIL:
118 /* XXX Deliver Program interrupt to guest. */
119 printk(KERN_EMERG "%s: emulation failed (%08x)\n", __func__,
Alexander Grafc7f38f42010-04-16 00:11:40 +0200120 kvmppc_get_last_inst(vcpu));
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500121 r = RESUME_HOST;
122 break;
123 default:
124 BUG();
125 }
126
127 return r;
128}
129
Alexander Graf10474ae2009-09-15 11:37:46 +0200130int kvm_arch_hardware_enable(void *garbage)
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500131{
Alexander Graf10474ae2009-09-15 11:37:46 +0200132 return 0;
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500133}
134
135void kvm_arch_hardware_disable(void *garbage)
136{
137}
138
139int kvm_arch_hardware_setup(void)
140{
141 return 0;
142}
143
144void kvm_arch_hardware_unsetup(void)
145{
146}
147
148void kvm_arch_check_processor_compat(void *rtn)
149{
Hollis Blanchard9dd921c2008-11-05 09:36:14 -0600150 *(int *)rtn = kvmppc_core_check_processor_compat();
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500151}
152
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100153int kvm_arch_init_vm(struct kvm *kvm)
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500154{
Paul Mackerrasf9e05542011-06-29 00:19:22 +0000155 return kvmppc_core_init_vm(kvm);
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500156}
157
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100158void kvm_arch_destroy_vm(struct kvm *kvm)
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500159{
160 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300161 struct kvm_vcpu *vcpu;
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500162
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300163 kvm_for_each_vcpu(i, vcpu, kvm)
164 kvm_arch_vcpu_free(vcpu);
165
166 mutex_lock(&kvm->lock);
167 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
168 kvm->vcpus[i] = NULL;
169
170 atomic_set(&kvm->online_vcpus, 0);
Paul Mackerrasf9e05542011-06-29 00:19:22 +0000171
172 kvmppc_core_destroy_vm(kvm);
173
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300174 mutex_unlock(&kvm->lock);
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500175}
176
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800177void kvm_arch_sync_events(struct kvm *kvm)
178{
179}
180
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500181int kvm_dev_ioctl_check_extension(long ext)
182{
183 int r;
184
185 switch (ext) {
Scott Wood5ce941e2011-04-27 17:24:21 -0500186#ifdef CONFIG_BOOKE
187 case KVM_CAP_PPC_BOOKE_SREGS:
188#else
Alexander Grafe15a1132009-11-30 03:02:02 +0000189 case KVM_CAP_PPC_SEGSTATE:
Scott Wood5ce941e2011-04-27 17:24:21 -0500190#endif
Alexander Graf18978762010-03-24 21:48:18 +0100191 case KVM_CAP_PPC_UNSET_IRQ:
Alexander Graf7b4203e2010-08-30 13:50:45 +0200192 case KVM_CAP_PPC_IRQ_LEVEL:
Alexander Graf71fbfd52010-03-24 21:48:29 +0100193 case KVM_CAP_ENABLE_CAP:
Paul Mackerrasde56a942011-06-29 00:21:34 +0000194 r = 1;
195 break;
196#ifndef CONFIG_KVM_BOOK3S_64_HV
197 case KVM_CAP_PPC_PAIRED_SINGLES:
Alexander Grafad0a0482010-03-24 21:48:30 +0100198 case KVM_CAP_PPC_OSI:
Alexander Graf15711e92010-07-29 14:48:08 +0200199 case KVM_CAP_PPC_GET_PVINFO:
Alexander Grafe15a1132009-11-30 03:02:02 +0000200 r = 1;
201 break;
Laurent Vivier588968b2008-05-30 16:05:56 +0200202 case KVM_CAP_COALESCED_MMIO:
203 r = KVM_COALESCED_MMIO_PAGE_OFFSET;
204 break;
Paul Mackerrasde56a942011-06-29 00:21:34 +0000205#endif
David Gibson54738c02011-06-29 00:22:41 +0000206#ifdef CONFIG_KVM_BOOK3S_64_HV
207 case KVM_CAP_SPAPR_TCE:
208 r = 1;
209 break;
210#endif
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500211 default:
212 r = 0;
213 break;
214 }
215 return r;
216
217}
218
219long kvm_arch_dev_ioctl(struct file *filp,
220 unsigned int ioctl, unsigned long arg)
221{
222 return -EINVAL;
223}
224
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200225int kvm_arch_prepare_memory_region(struct kvm *kvm,
226 struct kvm_memory_slot *memslot,
227 struct kvm_memory_slot old,
228 struct kvm_userspace_memory_region *mem,
229 int user_alloc)
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500230{
Paul Mackerrasf9e05542011-06-29 00:19:22 +0000231 return kvmppc_core_prepare_memory_region(kvm, mem);
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500232}
233
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200234void kvm_arch_commit_memory_region(struct kvm *kvm,
235 struct kvm_userspace_memory_region *mem,
236 struct kvm_memory_slot old,
237 int user_alloc)
238{
Paul Mackerrasf9e05542011-06-29 00:19:22 +0000239 kvmppc_core_commit_memory_region(kvm, mem);
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200240}
241
242
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300243void kvm_arch_flush_shadow(struct kvm *kvm)
244{
245}
246
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500247struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
248{
Hollis Blanchard73e75b42008-12-02 15:51:57 -0600249 struct kvm_vcpu *vcpu;
250 vcpu = kvmppc_core_vcpu_create(kvm, id);
Wei Yongjun06056bf2010-03-09 14:13:43 +0800251 if (!IS_ERR(vcpu))
252 kvmppc_create_vcpu_debugfs(vcpu, id);
Hollis Blanchard73e75b42008-12-02 15:51:57 -0600253 return vcpu;
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500254}
255
256void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
257{
Alexander Grafa5954052010-02-22 16:52:14 +0100258 /* Make sure we're not using the vcpu anymore */
259 hrtimer_cancel(&vcpu->arch.dec_timer);
260 tasklet_kill(&vcpu->arch.tasklet);
261
Hollis Blanchard73e75b42008-12-02 15:51:57 -0600262 kvmppc_remove_vcpu_debugfs(vcpu);
Hollis Blancharddb93f572008-11-05 09:36:18 -0600263 kvmppc_core_vcpu_free(vcpu);
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500264}
265
266void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
267{
268 kvm_arch_vcpu_free(vcpu);
269}
270
271int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
272{
Hollis Blanchard9dd921c2008-11-05 09:36:14 -0600273 return kvmppc_core_pending_dec(vcpu);
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500274}
275
276static void kvmppc_decrementer_func(unsigned long data)
277{
278 struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data;
279
Hollis Blanchard9dd921c2008-11-05 09:36:14 -0600280 kvmppc_core_queue_dec(vcpu);
Hollis Blanchard45c5eb62008-04-25 17:55:49 -0500281
282 if (waitqueue_active(&vcpu->wq)) {
283 wake_up_interruptible(&vcpu->wq);
284 vcpu->stat.halt_wakeup++;
285 }
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500286}
287
Alexander Graf544c6762009-11-02 12:02:31 +0000288/*
289 * low level hrtimer wake routine. Because this runs in hardirq context
290 * we schedule a tasklet to do the real work.
291 */
292enum hrtimer_restart kvmppc_decrementer_wakeup(struct hrtimer *timer)
293{
294 struct kvm_vcpu *vcpu;
295
296 vcpu = container_of(timer, struct kvm_vcpu, arch.dec_timer);
297 tasklet_schedule(&vcpu->arch.tasklet);
298
299 return HRTIMER_NORESTART;
300}
301
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500302int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
303{
Alexander Graf544c6762009-11-02 12:02:31 +0000304 hrtimer_init(&vcpu->arch.dec_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
305 tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu);
306 vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup;
Paul Mackerrasde56a942011-06-29 00:21:34 +0000307 vcpu->arch.dec_expires = ~(u64)0;
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500308
Bharat Bhushan09000ad2011-03-25 10:32:13 +0530309#ifdef CONFIG_KVM_EXIT_TIMING
310 mutex_init(&vcpu->arch.exit_timing_lock);
311#endif
312
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500313 return 0;
314}
315
316void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
317{
Hollis Blanchardecc09812009-01-03 16:22:59 -0600318 kvmppc_mmu_destroy(vcpu);
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500319}
320
321void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
322{
Scott Woodeab17672011-04-27 17:24:10 -0500323#ifdef CONFIG_BOOKE
324 /*
325 * vrsave (formerly usprg0) isn't used by Linux, but may
326 * be used by the guest.
327 *
328 * On non-booke this is associated with Altivec and
329 * is handled by code in book3s.c.
330 */
331 mtspr(SPRN_VRSAVE, vcpu->arch.vrsave);
332#endif
Hollis Blanchard9dd921c2008-11-05 09:36:14 -0600333 kvmppc_core_vcpu_load(vcpu, cpu);
Paul Mackerrasde56a942011-06-29 00:21:34 +0000334 vcpu->cpu = smp_processor_id();
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500335}
336
337void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
338{
Hollis Blanchard9dd921c2008-11-05 09:36:14 -0600339 kvmppc_core_vcpu_put(vcpu);
Scott Woodeab17672011-04-27 17:24:10 -0500340#ifdef CONFIG_BOOKE
341 vcpu->arch.vrsave = mfspr(SPRN_VRSAVE);
342#endif
Paul Mackerrasde56a942011-06-29 00:21:34 +0000343 vcpu->cpu = -1;
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500344}
345
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100346int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
Hollis Blanchardf5d09062009-01-04 13:51:09 -0600347 struct kvm_guest_debug *dbg)
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500348{
Hollis Blanchardf5d09062009-01-04 13:51:09 -0600349 return -EINVAL;
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500350}
351
352static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu,
353 struct kvm_run *run)
354{
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100355 kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, run->dcr.data);
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500356}
357
358static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu,
359 struct kvm_run *run)
360{
Denis Kirjanov69b61832010-06-11 11:23:26 +0000361 u64 uninitialized_var(gpr);
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500362
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100363 if (run->mmio.len > sizeof(gpr)) {
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500364 printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len);
365 return;
366 }
367
368 if (vcpu->arch.mmio_is_bigendian) {
369 switch (run->mmio.len) {
Alexander Grafb104d062010-02-19 11:00:29 +0100370 case 8: gpr = *(u64 *)run->mmio.data; break;
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100371 case 4: gpr = *(u32 *)run->mmio.data; break;
372 case 2: gpr = *(u16 *)run->mmio.data; break;
373 case 1: gpr = *(u8 *)run->mmio.data; break;
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500374 }
375 } else {
376 /* Convert BE data from userland back to LE. */
377 switch (run->mmio.len) {
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100378 case 4: gpr = ld_le32((u32 *)run->mmio.data); break;
379 case 2: gpr = ld_le16((u16 *)run->mmio.data); break;
380 case 1: gpr = *(u8 *)run->mmio.data; break;
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500381 }
382 }
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100383
Alexander Graf3587d532010-02-19 11:00:30 +0100384 if (vcpu->arch.mmio_sign_extend) {
385 switch (run->mmio.len) {
386#ifdef CONFIG_PPC64
387 case 4:
388 gpr = (s64)(s32)gpr;
389 break;
390#endif
391 case 2:
392 gpr = (s64)(s16)gpr;
393 break;
394 case 1:
395 gpr = (s64)(s8)gpr;
396 break;
397 }
398 }
399
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100400 kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr);
Alexander Grafb104d062010-02-19 11:00:29 +0100401
402 switch (vcpu->arch.io_gpr & KVM_REG_EXT_MASK) {
403 case KVM_REG_GPR:
404 kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr);
405 break;
406 case KVM_REG_FPR:
407 vcpu->arch.fpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr;
408 break;
Alexander Graf287d5612010-04-01 15:33:21 +0200409#ifdef CONFIG_PPC_BOOK3S
Alexander Grafb104d062010-02-19 11:00:29 +0100410 case KVM_REG_QPR:
411 vcpu->arch.qpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr;
412 break;
413 case KVM_REG_FQPR:
414 vcpu->arch.fpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr;
415 vcpu->arch.qpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr;
416 break;
Alexander Graf287d5612010-04-01 15:33:21 +0200417#endif
Alexander Grafb104d062010-02-19 11:00:29 +0100418 default:
419 BUG();
420 }
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500421}
422
423int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
424 unsigned int rt, unsigned int bytes, int is_bigendian)
425{
426 if (bytes > sizeof(run->mmio.data)) {
427 printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__,
428 run->mmio.len);
429 }
430
431 run->mmio.phys_addr = vcpu->arch.paddr_accessed;
432 run->mmio.len = bytes;
433 run->mmio.is_write = 0;
434
435 vcpu->arch.io_gpr = rt;
436 vcpu->arch.mmio_is_bigendian = is_bigendian;
437 vcpu->mmio_needed = 1;
438 vcpu->mmio_is_write = 0;
Alexander Graf3587d532010-02-19 11:00:30 +0100439 vcpu->arch.mmio_sign_extend = 0;
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500440
441 return EMULATE_DO_MMIO;
442}
443
Alexander Graf3587d532010-02-19 11:00:30 +0100444/* Same as above, but sign extends */
445int kvmppc_handle_loads(struct kvm_run *run, struct kvm_vcpu *vcpu,
446 unsigned int rt, unsigned int bytes, int is_bigendian)
447{
448 int r;
449
450 r = kvmppc_handle_load(run, vcpu, rt, bytes, is_bigendian);
451 vcpu->arch.mmio_sign_extend = 1;
452
453 return r;
454}
455
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500456int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
Alexander Grafb104d062010-02-19 11:00:29 +0100457 u64 val, unsigned int bytes, int is_bigendian)
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500458{
459 void *data = run->mmio.data;
460
461 if (bytes > sizeof(run->mmio.data)) {
462 printk(KERN_ERR "%s: bad MMIO length: %d\n", __func__,
463 run->mmio.len);
464 }
465
466 run->mmio.phys_addr = vcpu->arch.paddr_accessed;
467 run->mmio.len = bytes;
468 run->mmio.is_write = 1;
469 vcpu->mmio_needed = 1;
470 vcpu->mmio_is_write = 1;
471
472 /* Store the value at the lowest bytes in 'data'. */
473 if (is_bigendian) {
474 switch (bytes) {
Alexander Grafb104d062010-02-19 11:00:29 +0100475 case 8: *(u64 *)data = val; break;
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500476 case 4: *(u32 *)data = val; break;
477 case 2: *(u16 *)data = val; break;
478 case 1: *(u8 *)data = val; break;
479 }
480 } else {
481 /* Store LE value into 'data'. */
482 switch (bytes) {
483 case 4: st_le32(data, val); break;
484 case 2: st_le16(data, val); break;
485 case 1: *(u8 *)data = val; break;
486 }
487 }
488
489 return EMULATE_DO_MMIO;
490}
491
492int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
493{
494 int r;
495 sigset_t sigsaved;
496
497 if (vcpu->sigset_active)
498 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
499
500 if (vcpu->mmio_needed) {
501 if (!vcpu->mmio_is_write)
502 kvmppc_complete_mmio_load(vcpu, run);
503 vcpu->mmio_needed = 0;
504 } else if (vcpu->arch.dcr_needed) {
505 if (!vcpu->arch.dcr_is_write)
506 kvmppc_complete_dcr_load(vcpu, run);
507 vcpu->arch.dcr_needed = 0;
Alexander Grafad0a0482010-03-24 21:48:30 +0100508 } else if (vcpu->arch.osi_needed) {
509 u64 *gprs = run->osi.gprs;
510 int i;
511
512 for (i = 0; i < 32; i++)
513 kvmppc_set_gpr(vcpu, i, gprs[i]);
514 vcpu->arch.osi_needed = 0;
Paul Mackerrasde56a942011-06-29 00:21:34 +0000515 } else if (vcpu->arch.hcall_needed) {
516 int i;
517
518 kvmppc_set_gpr(vcpu, 3, run->papr_hcall.ret);
519 for (i = 0; i < 9; ++i)
520 kvmppc_set_gpr(vcpu, 4 + i, run->papr_hcall.args[i]);
521 vcpu->arch.hcall_needed = 0;
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500522 }
523
Hollis Blanchard9dd921c2008-11-05 09:36:14 -0600524 kvmppc_core_deliver_interrupts(vcpu);
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500525
Paul Mackerrasdf6909e52011-06-29 00:19:50 +0000526 r = kvmppc_vcpu_run(run, vcpu);
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500527
528 if (vcpu->sigset_active)
529 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
530
531 return r;
532}
533
534int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
535{
Alexander Graf18978762010-03-24 21:48:18 +0100536 if (irq->irq == KVM_INTERRUPT_UNSET)
537 kvmppc_core_dequeue_external(vcpu, irq);
538 else
539 kvmppc_core_queue_external(vcpu, irq);
Hollis Blanchard45c5eb62008-04-25 17:55:49 -0500540
541 if (waitqueue_active(&vcpu->wq)) {
542 wake_up_interruptible(&vcpu->wq);
543 vcpu->stat.halt_wakeup++;
Paul Mackerrasde56a942011-06-29 00:21:34 +0000544 } else if (vcpu->cpu != -1) {
545 smp_send_reschedule(vcpu->cpu);
Hollis Blanchard45c5eb62008-04-25 17:55:49 -0500546 }
547
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500548 return 0;
549}
550
Alexander Graf71fbfd52010-03-24 21:48:29 +0100551static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
552 struct kvm_enable_cap *cap)
553{
554 int r;
555
556 if (cap->flags)
557 return -EINVAL;
558
559 switch (cap->cap) {
Alexander Grafad0a0482010-03-24 21:48:30 +0100560 case KVM_CAP_PPC_OSI:
561 r = 0;
562 vcpu->arch.osi_enabled = true;
563 break;
Alexander Graf71fbfd52010-03-24 21:48:29 +0100564 default:
565 r = -EINVAL;
566 break;
567 }
568
569 return r;
570}
571
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500572int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
573 struct kvm_mp_state *mp_state)
574{
575 return -EINVAL;
576}
577
578int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
579 struct kvm_mp_state *mp_state)
580{
581 return -EINVAL;
582}
583
584long kvm_arch_vcpu_ioctl(struct file *filp,
585 unsigned int ioctl, unsigned long arg)
586{
587 struct kvm_vcpu *vcpu = filp->private_data;
588 void __user *argp = (void __user *)arg;
589 long r;
590
Avi Kivity93736622010-05-13 12:35:17 +0300591 switch (ioctl) {
592 case KVM_INTERRUPT: {
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500593 struct kvm_interrupt irq;
594 r = -EFAULT;
595 if (copy_from_user(&irq, argp, sizeof(irq)))
Avi Kivity93736622010-05-13 12:35:17 +0300596 goto out;
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500597 r = kvm_vcpu_ioctl_interrupt(vcpu, &irq);
Avi Kivity93736622010-05-13 12:35:17 +0300598 goto out;
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500599 }
Avi Kivity19483d12010-05-13 12:30:43 +0300600
Alexander Graf71fbfd52010-03-24 21:48:29 +0100601 case KVM_ENABLE_CAP:
602 {
603 struct kvm_enable_cap cap;
604 r = -EFAULT;
605 if (copy_from_user(&cap, argp, sizeof(cap)))
606 goto out;
607 r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap);
608 break;
609 }
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500610 default:
611 r = -EINVAL;
612 }
613
614out:
615 return r;
616}
617
Alexander Graf15711e92010-07-29 14:48:08 +0200618static int kvm_vm_ioctl_get_pvinfo(struct kvm_ppc_pvinfo *pvinfo)
619{
620 u32 inst_lis = 0x3c000000;
621 u32 inst_ori = 0x60000000;
622 u32 inst_nop = 0x60000000;
623 u32 inst_sc = 0x44000002;
624 u32 inst_imm_mask = 0xffff;
625
626 /*
627 * The hypercall to get into KVM from within guest context is as
628 * follows:
629 *
630 * lis r0, r0, KVM_SC_MAGIC_R0@h
631 * ori r0, KVM_SC_MAGIC_R0@l
632 * sc
633 * nop
634 */
635 pvinfo->hcall[0] = inst_lis | ((KVM_SC_MAGIC_R0 >> 16) & inst_imm_mask);
636 pvinfo->hcall[1] = inst_ori | (KVM_SC_MAGIC_R0 & inst_imm_mask);
637 pvinfo->hcall[2] = inst_sc;
638 pvinfo->hcall[3] = inst_nop;
639
640 return 0;
641}
642
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500643long kvm_arch_vm_ioctl(struct file *filp,
644 unsigned int ioctl, unsigned long arg)
645{
Alexander Graf15711e92010-07-29 14:48:08 +0200646 void __user *argp = (void __user *)arg;
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500647 long r;
648
649 switch (ioctl) {
Alexander Graf15711e92010-07-29 14:48:08 +0200650 case KVM_PPC_GET_PVINFO: {
651 struct kvm_ppc_pvinfo pvinfo;
Vasiliy Kulikovd8cdddc2010-10-30 13:04:24 +0400652 memset(&pvinfo, 0, sizeof(pvinfo));
Alexander Graf15711e92010-07-29 14:48:08 +0200653 r = kvm_vm_ioctl_get_pvinfo(&pvinfo);
654 if (copy_to_user(argp, &pvinfo, sizeof(pvinfo))) {
655 r = -EFAULT;
656 goto out;
657 }
658
659 break;
660 }
David Gibson54738c02011-06-29 00:22:41 +0000661#ifdef CONFIG_KVM_BOOK3S_64_HV
662 case KVM_CREATE_SPAPR_TCE: {
663 struct kvm_create_spapr_tce create_tce;
664 struct kvm *kvm = filp->private_data;
665
666 r = -EFAULT;
667 if (copy_from_user(&create_tce, argp, sizeof(create_tce)))
668 goto out;
669 r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce);
670 goto out;
671 }
672#endif /* CONFIG_KVM_BOOK3S_64_HV */
673
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500674 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300675 r = -ENOTTY;
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500676 }
677
Alexander Graf15711e92010-07-29 14:48:08 +0200678out:
Hollis Blanchardbbf45ba2008-04-16 23:28:09 -0500679 return r;
680}
681
682int kvm_arch_init(void *opaque)
683{
684 return 0;
685}
686
687void kvm_arch_exit(void)
688{
689}