diff options
author | David Hildenbrand <dahi@linux.vnet.ibm.com> | 2014-03-19 09:57:49 -0400 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2014-10-28 08:09:11 -0400 |
commit | 3526a66b66e3a997fb7d77af2f65dbdd77d2556e (patch) | |
tree | a99c32756015a95c60233988750efac9ac10997e /arch/s390 | |
parent | a36c5393266222129ce6f622e3bc3fb5463f290c (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.c | 74 |
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 | ||
352 | int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) | 352 | static 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 | |||
418 | int 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) |