diff options
Diffstat (limited to 'arch/powerpc/kvm/powerpc.c')
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index b7858b1e15e..1266ed02b47 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -301,6 +301,22 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, | |||
301 | } | 301 | } |
302 | } | 302 | } |
303 | 303 | ||
304 | if (vcpu->arch.mmio_sign_extend) { | ||
305 | switch (run->mmio.len) { | ||
306 | #ifdef CONFIG_PPC64 | ||
307 | case 4: | ||
308 | gpr = (s64)(s32)gpr; | ||
309 | break; | ||
310 | #endif | ||
311 | case 2: | ||
312 | gpr = (s64)(s16)gpr; | ||
313 | break; | ||
314 | case 1: | ||
315 | gpr = (s64)(s8)gpr; | ||
316 | break; | ||
317 | } | ||
318 | } | ||
319 | |||
304 | kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr); | 320 | kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr); |
305 | 321 | ||
306 | switch (vcpu->arch.io_gpr & KVM_REG_EXT_MASK) { | 322 | switch (vcpu->arch.io_gpr & KVM_REG_EXT_MASK) { |
@@ -338,10 +354,23 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
338 | vcpu->arch.mmio_is_bigendian = is_bigendian; | 354 | vcpu->arch.mmio_is_bigendian = is_bigendian; |
339 | vcpu->mmio_needed = 1; | 355 | vcpu->mmio_needed = 1; |
340 | vcpu->mmio_is_write = 0; | 356 | vcpu->mmio_is_write = 0; |
357 | vcpu->arch.mmio_sign_extend = 0; | ||
341 | 358 | ||
342 | return EMULATE_DO_MMIO; | 359 | return EMULATE_DO_MMIO; |
343 | } | 360 | } |
344 | 361 | ||
362 | /* Same as above, but sign extends */ | ||
363 | int kvmppc_handle_loads(struct kvm_run *run, struct kvm_vcpu *vcpu, | ||
364 | unsigned int rt, unsigned int bytes, int is_bigendian) | ||
365 | { | ||
366 | int r; | ||
367 | |||
368 | r = kvmppc_handle_load(run, vcpu, rt, bytes, is_bigendian); | ||
369 | vcpu->arch.mmio_sign_extend = 1; | ||
370 | |||
371 | return r; | ||
372 | } | ||
373 | |||
345 | int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, | 374 | int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, |
346 | u64 val, unsigned int bytes, int is_bigendian) | 375 | u64 val, unsigned int bytes, int is_bigendian) |
347 | { | 376 | { |