aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/priv.c
diff options
context:
space:
mode:
authorThomas Huth <thuth@linux.vnet.ibm.com>2013-06-20 11:22:05 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2013-06-20 17:33:01 -0400
commit87d41fb4da6467622b7a87fd6afe8071abab6dae (patch)
treea047d84655e787d36beb5b14704513fd3f9e7bfa /arch/s390/kvm/priv.c
parent953ed88d10444c0e139a2333b6cd96ce01aa94dc (diff)
KVM: s390: Fixed priority of execution in STSI
Added some missing validity checks for the operands and fixed the priority of exceptions for some function codes according to the "Principles of Operation" document. Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com> Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/s390/kvm/priv.c')
-rw-r--r--arch/s390/kvm/priv.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index c7603f5b4c28..0da3e6eb6be6 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -385,16 +385,27 @@ static int handle_stsi(struct kvm_vcpu *vcpu)
385 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) 385 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
386 return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); 386 return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
387 387
388 operand2 = kvm_s390_get_base_disp_s(vcpu); 388 if (fc > 3) {
389 vcpu->arch.sie_block->gpsw.mask |= 3ul << 44; /* cc 3 */
390 return 0;
391 }
389 392
390 if (operand2 & 0xfff && fc > 0) 393 if (vcpu->run->s.regs.gprs[0] & 0x0fffff00
394 || vcpu->run->s.regs.gprs[1] & 0xffff0000)
391 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 395 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
392 396
393 switch (fc) { 397 if (fc == 0) {
394 case 0:
395 vcpu->run->s.regs.gprs[0] = 3 << 28; 398 vcpu->run->s.regs.gprs[0] = 3 << 28;
396 vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44); 399 vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44); /* cc 0 */
397 return 0; 400 return 0;
401 }
402
403 operand2 = kvm_s390_get_base_disp_s(vcpu);
404
405 if (operand2 & 0xfff)
406 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
407
408 switch (fc) {
398 case 1: /* same handling for 1 and 2 */ 409 case 1: /* same handling for 1 and 2 */
399 case 2: 410 case 2:
400 mem = get_zeroed_page(GFP_KERNEL); 411 mem = get_zeroed_page(GFP_KERNEL);
@@ -411,8 +422,6 @@ static int handle_stsi(struct kvm_vcpu *vcpu)
411 goto out_no_data; 422 goto out_no_data;
412 handle_stsi_3_2_2(vcpu, (void *) mem); 423 handle_stsi_3_2_2(vcpu, (void *) mem);
413 break; 424 break;
414 default:
415 goto out_no_data;
416 } 425 }
417 426
418 if (copy_to_guest_absolute(vcpu, operand2, (void *) mem, PAGE_SIZE)) { 427 if (copy_to_guest_absolute(vcpu, operand2, (void *) mem, PAGE_SIZE)) {