aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/powerpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm/powerpc.c')
-rw-r--r--arch/powerpc/kvm/powerpc.c74
1 files changed, 51 insertions, 23 deletions
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 2a4551f78f60..297fcd2ff7d0 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -23,7 +23,9 @@
23#include <linux/kvm_host.h> 23#include <linux/kvm_host.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/vmalloc.h> 25#include <linux/vmalloc.h>
26#include <linux/hrtimer.h>
26#include <linux/fs.h> 27#include <linux/fs.h>
28#include <linux/slab.h>
27#include <asm/cputable.h> 29#include <asm/cputable.h>
28#include <asm/uaccess.h> 30#include <asm/uaccess.h>
29#include <asm/kvm_ppc.h> 31#include <asm/kvm_ppc.h>
@@ -78,8 +80,9 @@ int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu)
78 return r; 80 return r;
79} 81}
80 82
81void kvm_arch_hardware_enable(void *garbage) 83int kvm_arch_hardware_enable(void *garbage)
82{ 84{
85 return 0;
83} 86}
84 87
85void kvm_arch_hardware_disable(void *garbage) 88void kvm_arch_hardware_disable(void *garbage)
@@ -135,6 +138,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
135{ 138{
136 kvmppc_free_vcpus(kvm); 139 kvmppc_free_vcpus(kvm);
137 kvm_free_physmem(kvm); 140 kvm_free_physmem(kvm);
141 cleanup_srcu_struct(&kvm->srcu);
138 kfree(kvm); 142 kfree(kvm);
139} 143}
140 144
@@ -143,6 +147,9 @@ int kvm_dev_ioctl_check_extension(long ext)
143 int r; 147 int r;
144 148
145 switch (ext) { 149 switch (ext) {
150 case KVM_CAP_PPC_SEGSTATE:
151 r = 1;
152 break;
146 case KVM_CAP_COALESCED_MMIO: 153 case KVM_CAP_COALESCED_MMIO:
147 r = KVM_COALESCED_MMIO_PAGE_OFFSET; 154 r = KVM_COALESCED_MMIO_PAGE_OFFSET;
148 break; 155 break;
@@ -160,14 +167,24 @@ long kvm_arch_dev_ioctl(struct file *filp,
160 return -EINVAL; 167 return -EINVAL;
161} 168}
162 169
163int kvm_arch_set_memory_region(struct kvm *kvm, 170int kvm_arch_prepare_memory_region(struct kvm *kvm,
164 struct kvm_userspace_memory_region *mem, 171 struct kvm_memory_slot *memslot,
165 struct kvm_memory_slot old, 172 struct kvm_memory_slot old,
166 int user_alloc) 173 struct kvm_userspace_memory_region *mem,
174 int user_alloc)
167{ 175{
168 return 0; 176 return 0;
169} 177}
170 178
179void kvm_arch_commit_memory_region(struct kvm *kvm,
180 struct kvm_userspace_memory_region *mem,
181 struct kvm_memory_slot old,
182 int user_alloc)
183{
184 return;
185}
186
187
171void kvm_arch_flush_shadow(struct kvm *kvm) 188void kvm_arch_flush_shadow(struct kvm *kvm)
172{ 189{
173} 190}
@@ -208,10 +225,25 @@ static void kvmppc_decrementer_func(unsigned long data)
208 } 225 }
209} 226}
210 227
228/*
229 * low level hrtimer wake routine. Because this runs in hardirq context
230 * we schedule a tasklet to do the real work.
231 */
232enum hrtimer_restart kvmppc_decrementer_wakeup(struct hrtimer *timer)
233{
234 struct kvm_vcpu *vcpu;
235
236 vcpu = container_of(timer, struct kvm_vcpu, arch.dec_timer);
237 tasklet_schedule(&vcpu->arch.tasklet);
238
239 return HRTIMER_NORESTART;
240}
241
211int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) 242int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
212{ 243{
213 setup_timer(&vcpu->arch.dec_timer, kvmppc_decrementer_func, 244 hrtimer_init(&vcpu->arch.dec_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
214 (unsigned long)vcpu); 245 tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu);
246 vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup;
215 247
216 return 0; 248 return 0;
217} 249}
@@ -240,34 +272,35 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
240static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu, 272static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu,
241 struct kvm_run *run) 273 struct kvm_run *run)
242{ 274{
243 ulong *gpr = &vcpu->arch.gpr[vcpu->arch.io_gpr]; 275 kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, run->dcr.data);
244 *gpr = run->dcr.data;
245} 276}
246 277
247static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, 278static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu,
248 struct kvm_run *run) 279 struct kvm_run *run)
249{ 280{
250 ulong *gpr = &vcpu->arch.gpr[vcpu->arch.io_gpr]; 281 ulong gpr;
251 282
252 if (run->mmio.len > sizeof(*gpr)) { 283 if (run->mmio.len > sizeof(gpr)) {
253 printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len); 284 printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len);
254 return; 285 return;
255 } 286 }
256 287
257 if (vcpu->arch.mmio_is_bigendian) { 288 if (vcpu->arch.mmio_is_bigendian) {
258 switch (run->mmio.len) { 289 switch (run->mmio.len) {
259 case 4: *gpr = *(u32 *)run->mmio.data; break; 290 case 4: gpr = *(u32 *)run->mmio.data; break;
260 case 2: *gpr = *(u16 *)run->mmio.data; break; 291 case 2: gpr = *(u16 *)run->mmio.data; break;
261 case 1: *gpr = *(u8 *)run->mmio.data; break; 292 case 1: gpr = *(u8 *)run->mmio.data; break;
262 } 293 }
263 } else { 294 } else {
264 /* Convert BE data from userland back to LE. */ 295 /* Convert BE data from userland back to LE. */
265 switch (run->mmio.len) { 296 switch (run->mmio.len) {
266 case 4: *gpr = ld_le32((u32 *)run->mmio.data); break; 297 case 4: gpr = ld_le32((u32 *)run->mmio.data); break;
267 case 2: *gpr = ld_le16((u16 *)run->mmio.data); break; 298 case 2: gpr = ld_le16((u16 *)run->mmio.data); break;
268 case 1: *gpr = *(u8 *)run->mmio.data; break; 299 case 1: gpr = *(u8 *)run->mmio.data; break;
269 } 300 }
270 } 301 }
302
303 kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr);
271} 304}
272 305
273int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, 306int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
@@ -409,11 +442,6 @@ out:
409 return r; 442 return r;
410} 443}
411 444
412int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
413{
414 return -ENOTSUPP;
415}
416
417long kvm_arch_vm_ioctl(struct file *filp, 445long kvm_arch_vm_ioctl(struct file *filp,
418 unsigned int ioctl, unsigned long arg) 446 unsigned int ioctl, unsigned long arg)
419{ 447{
@@ -421,7 +449,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
421 449
422 switch (ioctl) { 450 switch (ioctl) {
423 default: 451 default:
424 r = -EINVAL; 452 r = -ENOTTY;
425 } 453 }
426 454
427 return r; 455 return r;