diff options
Diffstat (limited to 'arch/powerpc/kvm/powerpc.c')
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 297fcd2ff7d0..b7858b1e15ec 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -278,7 +278,7 @@ static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu, | |||
278 | static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, | 278 | static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, |
279 | struct kvm_run *run) | 279 | struct kvm_run *run) |
280 | { | 280 | { |
281 | ulong gpr; | 281 | u64 gpr; |
282 | 282 | ||
283 | if (run->mmio.len > sizeof(gpr)) { | 283 | if (run->mmio.len > sizeof(gpr)) { |
284 | printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len); | 284 | printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len); |
@@ -287,6 +287,7 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, | |||
287 | 287 | ||
288 | if (vcpu->arch.mmio_is_bigendian) { | 288 | if (vcpu->arch.mmio_is_bigendian) { |
289 | switch (run->mmio.len) { | 289 | switch (run->mmio.len) { |
290 | case 8: gpr = *(u64 *)run->mmio.data; break; | ||
290 | case 4: gpr = *(u32 *)run->mmio.data; break; | 291 | case 4: gpr = *(u32 *)run->mmio.data; break; |
291 | case 2: gpr = *(u16 *)run->mmio.data; break; | 292 | case 2: gpr = *(u16 *)run->mmio.data; break; |
292 | case 1: gpr = *(u8 *)run->mmio.data; break; | 293 | case 1: gpr = *(u8 *)run->mmio.data; break; |
@@ -301,6 +302,24 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, | |||
301 | } | 302 | } |
302 | 303 | ||
303 | kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr); | 304 | kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr); |
305 | |||
306 | switch (vcpu->arch.io_gpr & KVM_REG_EXT_MASK) { | ||
307 | case KVM_REG_GPR: | ||
308 | kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr); | ||
309 | break; | ||
310 | case KVM_REG_FPR: | ||
311 | vcpu->arch.fpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; | ||
312 | break; | ||
313 | case KVM_REG_QPR: | ||
314 | vcpu->arch.qpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; | ||
315 | break; | ||
316 | case KVM_REG_FQPR: | ||
317 | vcpu->arch.fpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; | ||
318 | vcpu->arch.qpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; | ||
319 | break; | ||
320 | default: | ||
321 | BUG(); | ||
322 | } | ||
304 | } | 323 | } |
305 | 324 | ||
306 | int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | 325 | int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, |
@@ -324,7 +343,7 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
324 | } | 343 | } |
325 | 344 | ||
326 | int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, | 345 | int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, |
327 | u32 val, unsigned int bytes, int is_bigendian) | 346 | u64 val, unsigned int bytes, int is_bigendian) |
328 | { | 347 | { |
329 | void *data = run->mmio.data; | 348 | void *data = run->mmio.data; |
330 | 349 | ||
@@ -342,6 +361,7 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
342 | /* Store the value at the lowest bytes in 'data'. */ | 361 | /* Store the value at the lowest bytes in 'data'. */ |
343 | if (is_bigendian) { | 362 | if (is_bigendian) { |
344 | switch (bytes) { | 363 | switch (bytes) { |
364 | case 8: *(u64 *)data = val; break; | ||
345 | case 4: *(u32 *)data = val; break; | 365 | case 4: *(u32 *)data = val; break; |
346 | case 2: *(u16 *)data = val; break; | 366 | case 2: *(u16 *)data = val; break; |
347 | case 1: *(u8 *)data = val; break; | 367 | case 1: *(u8 *)data = val; break; |