aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2013-03-25 12:22:54 -0400
committerGleb Natapov <gleb@redhat.com>2013-04-02 09:14:41 -0400
commitc51f068c23c76a86d427260b8219430ee6f99516 (patch)
tree6c62f20259c8e9ae1d9e857873558533a98997fe /arch/s390
parentdb4a29cb6ac7b2fda505923bdbc58fc35a719f62 (diff)
KVM: s390: fix stsi exception handling
In case of an exception the guest psw condition code should be left alone. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Acked-By: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/kvm/priv.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 23a8370b1045..de1b1b6128e1 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -343,8 +343,8 @@ static int handle_stsi(struct kvm_vcpu *vcpu)
343 int fc = (vcpu->run->s.regs.gprs[0] & 0xf0000000) >> 28; 343 int fc = (vcpu->run->s.regs.gprs[0] & 0xf0000000) >> 28;
344 int sel1 = vcpu->run->s.regs.gprs[0] & 0xff; 344 int sel1 = vcpu->run->s.regs.gprs[0] & 0xff;
345 int sel2 = vcpu->run->s.regs.gprs[1] & 0xffff; 345 int sel2 = vcpu->run->s.regs.gprs[1] & 0xffff;
346 unsigned long mem = 0;
346 u64 operand2; 347 u64 operand2;
347 unsigned long mem;
348 int rc = 0; 348 int rc = 0;
349 349
350 vcpu->stat.instruction_stsi++; 350 vcpu->stat.instruction_stsi++;
@@ -364,36 +364,36 @@ static int handle_stsi(struct kvm_vcpu *vcpu)
364 case 2: 364 case 2:
365 mem = get_zeroed_page(GFP_KERNEL); 365 mem = get_zeroed_page(GFP_KERNEL);
366 if (!mem) 366 if (!mem)
367 goto out_fail; 367 goto out_no_data;
368 if (stsi((void *) mem, fc, sel1, sel2)) 368 if (stsi((void *) mem, fc, sel1, sel2))
369 goto out_mem; 369 goto out_no_data;
370 break; 370 break;
371 case 3: 371 case 3:
372 if (sel1 != 2 || sel2 != 2) 372 if (sel1 != 2 || sel2 != 2)
373 goto out_fail; 373 goto out_no_data;
374 mem = get_zeroed_page(GFP_KERNEL); 374 mem = get_zeroed_page(GFP_KERNEL);
375 if (!mem) 375 if (!mem)
376 goto out_fail; 376 goto out_no_data;
377 handle_stsi_3_2_2(vcpu, (void *) mem); 377 handle_stsi_3_2_2(vcpu, (void *) mem);
378 break; 378 break;
379 default: 379 default:
380 goto out_fail; 380 goto out_no_data;
381 } 381 }
382 382
383 if (copy_to_guest_absolute(vcpu, operand2, (void *) mem, PAGE_SIZE)) { 383 if (copy_to_guest_absolute(vcpu, operand2, (void *) mem, PAGE_SIZE)) {
384 rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); 384 rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
385 goto out_mem; 385 goto out_exception;
386 } 386 }
387 trace_kvm_s390_handle_stsi(vcpu, fc, sel1, sel2, operand2); 387 trace_kvm_s390_handle_stsi(vcpu, fc, sel1, sel2, operand2);
388 free_page(mem); 388 free_page(mem);
389 vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44); 389 vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
390 vcpu->run->s.regs.gprs[0] = 0; 390 vcpu->run->s.regs.gprs[0] = 0;
391 return 0; 391 return 0;
392out_mem: 392out_no_data:
393 free_page(mem);
394out_fail:
395 /* condition code 3 */ 393 /* condition code 3 */
396 vcpu->arch.sie_block->gpsw.mask |= 3ul << 44; 394 vcpu->arch.sie_block->gpsw.mask |= 3ul << 44;
395out_exception:
396 free_page(mem);
397 return rc; 397 return rc;
398} 398}
399 399