aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>2014-03-19 09:57:49 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-10-28 08:09:11 -0400
commit3526a66b66e3a997fb7d77af2f65dbdd77d2556e (patch)
treea99c32756015a95c60233988750efac9ac10997e /arch/s390
parenta36c5393266222129ce6f622e3bc3fb5463f290c (diff)
KVM: s390: sigp: dispatch orders with one target in a separate function
All sigp orders except SIGP SET ARCHITECTURE target exactly one vcpu. Let's move the dispatch code for these orders into a separate function to prepare for cleaner target availability checks. Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/kvm/sigp.c74
1 files changed, 43 insertions, 31 deletions
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index cf243ba3d50f..5e259bd62515 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -349,32 +349,15 @@ static int sigp_check_callable(struct kvm_vcpu *vcpu, u16 cpu_addr)
349 return rc; 349 return rc;
350} 350}
351 351
352int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) 352static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code,
353 u16 cpu_addr, u32 parameter, u64 *status_reg)
353{ 354{
354 int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
355 int r3 = vcpu->arch.sie_block->ipa & 0x000f;
356 u32 parameter;
357 u16 cpu_addr = vcpu->run->s.regs.gprs[r3];
358 u8 order_code;
359 int rc; 355 int rc;
360 356
361 /* sigp in userspace can exit */
362 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
363 return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
364
365 order_code = kvm_s390_get_base_disp_rs(vcpu);
366
367 if (r1 % 2)
368 parameter = vcpu->run->s.regs.gprs[r1];
369 else
370 parameter = vcpu->run->s.regs.gprs[r1 + 1];
371
372 trace_kvm_s390_handle_sigp(vcpu, order_code, cpu_addr, parameter);
373 switch (order_code) { 357 switch (order_code) {
374 case SIGP_SENSE: 358 case SIGP_SENSE:
375 vcpu->stat.instruction_sigp_sense++; 359 vcpu->stat.instruction_sigp_sense++;
376 rc = __sigp_sense(vcpu, cpu_addr, 360 rc = __sigp_sense(vcpu, cpu_addr, status_reg);
377 &vcpu->run->s.regs.gprs[r1]);
378 break; 361 break;
379 case SIGP_EXTERNAL_CALL: 362 case SIGP_EXTERNAL_CALL:
380 vcpu->stat.instruction_sigp_external_call++; 363 vcpu->stat.instruction_sigp_external_call++;
@@ -395,25 +378,19 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
395 break; 378 break;
396 case SIGP_STORE_STATUS_AT_ADDRESS: 379 case SIGP_STORE_STATUS_AT_ADDRESS:
397 rc = __sigp_store_status_at_addr(vcpu, cpu_addr, parameter, 380 rc = __sigp_store_status_at_addr(vcpu, cpu_addr, parameter,
398 &vcpu->run->s.regs.gprs[r1]); 381 status_reg);
399 break;
400 case SIGP_SET_ARCHITECTURE:
401 vcpu->stat.instruction_sigp_arch++;
402 rc = __sigp_set_arch(vcpu, parameter);
403 break; 382 break;
404 case SIGP_SET_PREFIX: 383 case SIGP_SET_PREFIX:
405 vcpu->stat.instruction_sigp_prefix++; 384 vcpu->stat.instruction_sigp_prefix++;
406 rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, 385 rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, status_reg);
407 &vcpu->run->s.regs.gprs[r1]);
408 break; 386 break;
409 case SIGP_COND_EMERGENCY_SIGNAL: 387 case SIGP_COND_EMERGENCY_SIGNAL:
410 rc = __sigp_conditional_emergency(vcpu, cpu_addr, parameter, 388 rc = __sigp_conditional_emergency(vcpu, cpu_addr, parameter,
411 &vcpu->run->s.regs.gprs[r1]); 389 status_reg);
412 break; 390 break;
413 case SIGP_SENSE_RUNNING: 391 case SIGP_SENSE_RUNNING:
414 vcpu->stat.instruction_sigp_sense_running++; 392 vcpu->stat.instruction_sigp_sense_running++;
415 rc = __sigp_sense_running(vcpu, cpu_addr, 393 rc = __sigp_sense_running(vcpu, cpu_addr, status_reg);
416 &vcpu->run->s.regs.gprs[r1]);
417 break; 394 break;
418 case SIGP_START: 395 case SIGP_START:
419 rc = sigp_check_callable(vcpu, cpu_addr); 396 rc = sigp_check_callable(vcpu, cpu_addr);
@@ -432,7 +409,42 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
432 } 409 }
433 break; 410 break;
434 default: 411 default:
435 return -EOPNOTSUPP; 412 rc = -EOPNOTSUPP;
413 }
414
415 return rc;
416}
417
418int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
419{
420 int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
421 int r3 = vcpu->arch.sie_block->ipa & 0x000f;
422 u32 parameter;
423 u16 cpu_addr = vcpu->run->s.regs.gprs[r3];
424 u8 order_code;
425 int rc;
426
427 /* sigp in userspace can exit */
428 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
429 return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
430
431 order_code = kvm_s390_get_base_disp_rs(vcpu);
432
433 if (r1 % 2)
434 parameter = vcpu->run->s.regs.gprs[r1];
435 else
436 parameter = vcpu->run->s.regs.gprs[r1 + 1];
437
438 trace_kvm_s390_handle_sigp(vcpu, order_code, cpu_addr, parameter);
439 switch (order_code) {
440 case SIGP_SET_ARCHITECTURE:
441 vcpu->stat.instruction_sigp_arch++;
442 rc = __sigp_set_arch(vcpu, parameter);
443 break;
444 default:
445 rc = handle_sigp_dst(vcpu, order_code, cpu_addr,
446 parameter,
447 &vcpu->run->s.regs.gprs[r1]);
436 } 448 }
437 449
438 if (rc < 0) 450 if (rc < 0)