sigp.c (9134d02bc0af4a8747d448d1f811ec5f8eb96df6) sigp.c (9ace903d171db7dc2fed96e44ac62b6f4c3ccb3d)
1/*
2 * sigp.c - handlinge interprocessor communication
3 *
1/*
2 * sigp.c - handlinge interprocessor communication
3 *
4 * Copyright IBM Corp. 2008
4 * Copyright IBM Corp. 2008,2009
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only)
8 * as published by the Free Software Foundation.
9 *
10 * Author(s): Carsten Otte <cotte@de.ibm.com>
11 * Christian Borntraeger <borntraeger@de.ibm.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only)
8 * as published by the Free Software Foundation.
9 *
10 * Author(s): Carsten Otte <cotte@de.ibm.com>
11 * Christian Borntraeger <borntraeger@de.ibm.com>
12 * Christian Ehrhardt <ehrhardt@de.ibm.com>
12 */
13
14#include <linux/kvm.h>
15#include <linux/kvm_host.h>
16#include "gaccess.h"
17#include "kvm-s390.h"
18
19/* sigp order codes */

--- 82 unchanged lines hidden (view full) ---

102 spin_unlock_bh(&li->lock);
103 rc = 0; /* order accepted */
104unlock:
105 spin_unlock(&fi->lock);
106 VCPU_EVENT(vcpu, 4, "sent sigp emerg to cpu %x", cpu_addr);
107 return rc;
108}
109
13 */
14
15#include <linux/kvm.h>
16#include <linux/kvm_host.h>
17#include "gaccess.h"
18#include "kvm-s390.h"
19
20/* sigp order codes */

--- 82 unchanged lines hidden (view full) ---

103 spin_unlock_bh(&li->lock);
104 rc = 0; /* order accepted */
105unlock:
106 spin_unlock(&fi->lock);
107 VCPU_EVENT(vcpu, 4, "sent sigp emerg to cpu %x", cpu_addr);
108 return rc;
109}
110
110static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int store)
111static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action)
111{
112{
112 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
113 struct kvm_s390_local_interrupt *li;
114 struct kvm_s390_interrupt_info *inti;
113 struct kvm_s390_interrupt_info *inti;
115 int rc;
116
114
117 if (cpu_addr >= KVM_MAX_VCPUS)
118 return 3; /* not operational */
119
120 inti = kzalloc(sizeof(*inti), GFP_KERNEL);
121 if (!inti)
122 return -ENOMEM;
115 inti = kzalloc(sizeof(*inti), GFP_KERNEL);
116 if (!inti)
117 return -ENOMEM;
123
124 inti->type = KVM_S390_SIGP_STOP;
125
118 inti->type = KVM_S390_SIGP_STOP;
119
126 spin_lock(&fi->lock);
127 li = fi->local_int[cpu_addr];
128 if (li == NULL) {
129 rc = 3; /* not operational */
130 kfree(inti);
131 goto unlock;
132 }
133 spin_lock_bh(&li->lock);
134 list_add_tail(&inti->list, &li->list);
135 atomic_set(&li->active, 1);
136 atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags);
120 spin_lock_bh(&li->lock);
121 list_add_tail(&inti->list, &li->list);
122 atomic_set(&li->active, 1);
123 atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags);
137 if (store)
138 li->action_bits |= ACTION_STORE_ON_STOP;
139 li->action_bits |= ACTION_STOP_ON_STOP;
124 li->action_bits |= action;
140 if (waitqueue_active(&li->wq))
141 wake_up_interruptible(&li->wq);
142 spin_unlock_bh(&li->lock);
125 if (waitqueue_active(&li->wq))
126 wake_up_interruptible(&li->wq);
127 spin_unlock_bh(&li->lock);
143 rc = 0; /* order accepted */
128
129 return 0; /* order accepted */
130}
131
132static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action)
133{
134 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
135 struct kvm_s390_local_interrupt *li;
136 int rc;
137
138 if (cpu_addr >= KVM_MAX_VCPUS)
139 return 3; /* not operational */
140
141 spin_lock(&fi->lock);
142 li = fi->local_int[cpu_addr];
143 if (li == NULL) {
144 rc = 3; /* not operational */
145 goto unlock;
146 }
147
148 rc = __inject_sigp_stop(li, action);
149
144unlock:
145 spin_unlock(&fi->lock);
146 VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr);
147 return rc;
148}
149
150unlock:
151 spin_unlock(&fi->lock);
152 VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr);
153 return rc;
154}
155
156int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action)
157{
158 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
159 return __inject_sigp_stop(li, action);
160}
161
150static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter)
151{
152 int rc;
153
154 switch (parameter & 0xff) {
155 case 0:
156 rc = 3; /* not operational */
157 break;

--- 99 unchanged lines hidden (view full) ---

257 &vcpu->arch.guest_gprs[r1]);
258 break;
259 case SIGP_EMERGENCY:
260 vcpu->stat.instruction_sigp_emergency++;
261 rc = __sigp_emergency(vcpu, cpu_addr);
262 break;
263 case SIGP_STOP:
264 vcpu->stat.instruction_sigp_stop++;
162static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter)
163{
164 int rc;
165
166 switch (parameter & 0xff) {
167 case 0:
168 rc = 3; /* not operational */
169 break;

--- 99 unchanged lines hidden (view full) ---

269 &vcpu->arch.guest_gprs[r1]);
270 break;
271 case SIGP_EMERGENCY:
272 vcpu->stat.instruction_sigp_emergency++;
273 rc = __sigp_emergency(vcpu, cpu_addr);
274 break;
275 case SIGP_STOP:
276 vcpu->stat.instruction_sigp_stop++;
265 rc = __sigp_stop(vcpu, cpu_addr, 0);
277 rc = __sigp_stop(vcpu, cpu_addr, ACTION_STOP_ON_STOP);
266 break;
267 case SIGP_STOP_STORE_STATUS:
268 vcpu->stat.instruction_sigp_stop++;
278 break;
279 case SIGP_STOP_STORE_STATUS:
280 vcpu->stat.instruction_sigp_stop++;
269 rc = __sigp_stop(vcpu, cpu_addr, 1);
281 rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP);
270 break;
271 case SIGP_SET_ARCH:
272 vcpu->stat.instruction_sigp_arch++;
273 rc = __sigp_set_arch(vcpu, parameter);
274 break;
275 case SIGP_SET_PREFIX:
276 vcpu->stat.instruction_sigp_prefix++;
277 rc = __sigp_set_prefix(vcpu, cpu_addr, parameter,

--- 16 unchanged lines hidden ---
282 break;
283 case SIGP_SET_ARCH:
284 vcpu->stat.instruction_sigp_arch++;
285 rc = __sigp_set_arch(vcpu, parameter);
286 break;
287 case SIGP_SET_PREFIX:
288 vcpu->stat.instruction_sigp_prefix++;
289 rc = __sigp_set_prefix(vcpu, cpu_addr, parameter,

--- 16 unchanged lines hidden ---