diff options
author | David Hildenbrand <dahi@linux.vnet.ibm.com> | 2014-05-23 12:22:56 +0200 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2014-10-28 13:09:13 +0100 |
commit | b8983830826f3b0747a6d1c1f351121b9cc93276 (patch) | |
tree | 6b579972a603611df256d1279e167ea7fa7d093f /arch/s390/kvm | |
parent | KVM: s390: sigp: move target cpu checks into dispatcher (diff) | |
download | linux-b8983830826f3b0747a6d1c1f351121b9cc93276.tar.xz linux-b8983830826f3b0747a6d1c1f351121b9cc93276.zip |
KVM: s390: sigp: separate preparation handlers
This patch introduces in preparation for further code changes separate handler
functions for:
- SIGP (RE)START - will not be allowed to terminate pending orders
- SIGP (INITIAL) CPU RESET - will be allowed to terminate certain pending orders
- unknown sigp orders
All sigp orders that require user space intervention are logged.
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/kvm')
-rw-r--r-- | arch/s390/kvm/sigp.c | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 660a9459ff2a..a9e17397305e 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -284,11 +284,12 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu, return rc; } -/* Test whether the destination CPU is available and not busy */ -static int sigp_check_callable(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu) +static int __prepare_sigp_re_start(struct kvm_vcpu *vcpu, + struct kvm_vcpu *dst_vcpu, u8 order_code) { struct kvm_s390_local_interrupt *li = &dst_vcpu->arch.local_int; - int rc = SIGP_CC_ORDER_CODE_ACCEPTED; + /* handle (RE)START in user space */ + int rc = -EOPNOTSUPP; spin_lock(&li->lock); if (li->action_bits & ACTION_STOP_ON_STOP) @@ -298,6 +299,20 @@ static int sigp_check_callable(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu) return rc; } +static int __prepare_sigp_cpu_reset(struct kvm_vcpu *vcpu, + struct kvm_vcpu *dst_vcpu, u8 order_code) +{ + /* handle (INITIAL) CPU RESET in user space */ + return -EOPNOTSUPP; +} + +static int __prepare_sigp_unknown(struct kvm_vcpu *vcpu, + struct kvm_vcpu *dst_vcpu) +{ + /* handle unknown orders in user space */ + return -EOPNOTSUPP; +} + static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code, u16 cpu_addr, u32 parameter, u64 *status_reg) { @@ -350,25 +365,27 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code, rc = __sigp_sense_running(vcpu, dst_vcpu, status_reg); break; case SIGP_START: - rc = sigp_check_callable(vcpu, dst_vcpu); - if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) - rc = -EOPNOTSUPP; /* Handle START in user space */ + rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code); break; case SIGP_RESTART: vcpu->stat.instruction_sigp_restart++; - rc = sigp_check_callable(vcpu, dst_vcpu); - if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) { - VCPU_EVENT(vcpu, 4, - "sigp restart %x to handle userspace", - cpu_addr); - /* user space must know about restart */ - rc = -EOPNOTSUPP; - } + rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code); + break; + case SIGP_INITIAL_CPU_RESET: + rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code); + break; + case SIGP_CPU_RESET: + rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code); break; default: - rc = -EOPNOTSUPP; + rc = __prepare_sigp_unknown(vcpu, dst_vcpu); } + if (rc == -EOPNOTSUPP) + VCPU_EVENT(vcpu, 4, + "sigp order %u -> cpu %x: handled in user space", + order_code, dst_vcpu->vcpu_id); + return rc; } |