diff options
author | Christian Borntraeger <borntraeger@de.ibm.com> | 2008-03-25 13:47:31 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-04-27 05:00:46 -0400 |
commit | 5288fbf0ef041ba0e8b4dcb2df4536b5e3a48b32 (patch) | |
tree | 6f81a87294c9026ac91a84e5a94e55e565002d3b /arch/s390/kvm/intercept.c | |
parent | 453423dce2785b8e22077e3b3eeecb4f60fe3470 (diff) |
KVM: s390: interprocessor communication via sigp
This patch introduces in-kernel handling of _some_ sigp interprocessor
signals (similar to ipi).
kvm_s390_handle_sigp() decodes the sigp instruction and calls individual
handlers depending on the operation requested:
- sigp sense tries to retrieve information such as existence or running state
of the remote cpu
- sigp emergency sends an external interrupt to the remove cpu
- sigp stop stops a remove cpu
- sigp stop store status stops a remote cpu, and stores its entire internal
state to the cpus lowcore
- sigp set arch sets the architecture mode of the remote cpu. setting to
ESAME (s390x 64bit) is accepted, setting to ESA/S390 (s390, 31 or 24 bit) is
denied, all others are passed to userland
- sigp set prefix sets the prefix register of a remote cpu
For implementation of this, the stop intercept indication starts to get reused
on purpose: a set of action bits defines what to do once a cpu gets stopped:
ACTION_STOP_ON_STOP really stops the cpu when a stop intercept is recognized
ACTION_STORE_ON_STOP stores the cpu status to lowcore when a stop intercept is
recognized
Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/s390/kvm/intercept.c')
-rw-r--r-- | arch/s390/kvm/intercept.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index 7a20d63a2eba..9f0d8b239436 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c | |||
@@ -95,6 +95,7 @@ static int handle_lctl(struct kvm_vcpu *vcpu) | |||
95 | } | 95 | } |
96 | 96 | ||
97 | static intercept_handler_t instruction_handlers[256] = { | 97 | static intercept_handler_t instruction_handlers[256] = { |
98 | [0xae] = kvm_s390_handle_sigp, | ||
98 | [0xb2] = kvm_s390_handle_priv, | 99 | [0xb2] = kvm_s390_handle_priv, |
99 | [0xb7] = handle_lctl, | 100 | [0xb7] = handle_lctl, |
100 | [0xeb] = handle_lctg, | 101 | [0xeb] = handle_lctg, |
@@ -117,10 +118,27 @@ static int handle_noop(struct kvm_vcpu *vcpu) | |||
117 | 118 | ||
118 | static int handle_stop(struct kvm_vcpu *vcpu) | 119 | static int handle_stop(struct kvm_vcpu *vcpu) |
119 | { | 120 | { |
121 | int rc; | ||
122 | |||
120 | vcpu->stat.exit_stop_request++; | 123 | vcpu->stat.exit_stop_request++; |
121 | VCPU_EVENT(vcpu, 3, "%s", "cpu stopped"); | ||
122 | atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); | 124 | atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); |
123 | return -ENOTSUPP; | 125 | spin_lock_bh(&vcpu->arch.local_int.lock); |
126 | if (vcpu->arch.local_int.action_bits & ACTION_STORE_ON_STOP) { | ||
127 | vcpu->arch.local_int.action_bits &= ~ACTION_STORE_ON_STOP; | ||
128 | rc = __kvm_s390_vcpu_store_status(vcpu, | ||
129 | KVM_S390_STORE_STATUS_NOADDR); | ||
130 | if (rc >= 0) | ||
131 | rc = -ENOTSUPP; | ||
132 | } | ||
133 | |||
134 | if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) { | ||
135 | vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP; | ||
136 | VCPU_EVENT(vcpu, 3, "%s", "cpu stopped"); | ||
137 | rc = -ENOTSUPP; | ||
138 | } else | ||
139 | rc = 0; | ||
140 | spin_unlock_bh(&vcpu->arch.local_int.lock); | ||
141 | return rc; | ||
124 | } | 142 | } |
125 | 143 | ||
126 | static int handle_validity(struct kvm_vcpu *vcpu) | 144 | static int handle_validity(struct kvm_vcpu *vcpu) |