From 3a3a458af17660e683e5a104fb5304baf920964e Mon Sep 17 00:00:00 2001 From: Jens Freimann Date: Wed, 8 Feb 2012 08:28:29 +0100 Subject: [PATCH] --- yaml --- r: 297147 b: refs/heads/master c: 151104a7b3a82f9c56d636595ae58084049d2559 h: refs/heads/master i: 297145: 56589a6756867922d982659f3ef61986f0c3cd05 297143: 7c556f99c59b9bba57a450293e770f3cdd74b81f v: v3 --- [refs] | 2 +- trunk/arch/s390/kvm/sigp.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 06fd70a460c3..1a847c724f32 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9e0d5473e2f0ba2d2fe9dab9408edef3060b710e +refs/heads/master: 151104a7b3a82f9c56d636595ae58084049d2559 diff --git a/trunk/arch/s390/kvm/sigp.c b/trunk/arch/s390/kvm/sigp.c index 30eb0f73f9d5..c703b1cbb0aa 100644 --- a/trunk/arch/s390/kvm/sigp.c +++ b/trunk/arch/s390/kvm/sigp.c @@ -309,6 +309,34 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr, return rc; } +static int __sigp_restart(struct kvm_vcpu *vcpu, u16 cpu_addr) +{ + int rc = 0; + struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; + struct kvm_s390_local_interrupt *li; + + if (cpu_addr >= KVM_MAX_VCPUS) + return 3; /* not operational */ + + spin_lock(&fi->lock); + li = fi->local_int[cpu_addr]; + if (li == NULL) { + rc = 3; /* not operational */ + goto out; + } + + spin_lock_bh(&li->lock); + if (li->action_bits & ACTION_STOP_ON_STOP) + rc = 2; /* busy */ + else + VCPU_EVENT(vcpu, 4, "sigp restart %x to handle userspace", + cpu_addr); + spin_unlock_bh(&li->lock); +out: + spin_unlock(&fi->lock); + return rc; +} + int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) { int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; @@ -372,6 +400,9 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) break; case SIGP_RESTART: vcpu->stat.instruction_sigp_restart++; + rc = __sigp_restart(vcpu, cpu_addr); + if (rc == 2) /* busy */ + break; /* user space must know about restart */ default: return -EOPNOTSUPP;