sigp.c (4e9816d012dbc28dc89559261c6ffbf8ffc440dd) sigp.c (4ae3c0815fb63cbed1afcd5bacc7705c6d1b9fec)
1/*
2 * handling interprocessor communication
3 *
4 * Copyright IBM Corp. 2008, 2013
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.

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

130 struct kvm_s390_interrupt_info *inti;
131 int rc = SIGP_CC_ORDER_CODE_ACCEPTED;
132
133 inti = kzalloc(sizeof(*inti), GFP_ATOMIC);
134 if (!inti)
135 return -ENOMEM;
136 inti->type = KVM_S390_SIGP_STOP;
137
1/*
2 * handling interprocessor communication
3 *
4 * Copyright IBM Corp. 2008, 2013
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.

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

130 struct kvm_s390_interrupt_info *inti;
131 int rc = SIGP_CC_ORDER_CODE_ACCEPTED;
132
133 inti = kzalloc(sizeof(*inti), GFP_ATOMIC);
134 if (!inti)
135 return -ENOMEM;
136 inti->type = KVM_S390_SIGP_STOP;
137
138 spin_lock_bh(&li->lock);
138 spin_lock(&li->lock);
139 if (li->action_bits & ACTION_STOP_ON_STOP) {
140 /* another SIGP STOP is pending */
141 rc = SIGP_CC_BUSY;
142 goto out;
143 }
139 if ((atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) {
140 kfree(inti);
141 if ((action & ACTION_STORE_ON_STOP) != 0)
142 rc = -ESHUTDOWN;
143 goto out;
144 }
145 list_add_tail(&inti->list, &li->list);
146 atomic_set(&li->active, 1);
144 if ((atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) {
145 kfree(inti);
146 if ((action & ACTION_STORE_ON_STOP) != 0)
147 rc = -ESHUTDOWN;
148 goto out;
149 }
150 list_add_tail(&inti->list, &li->list);
151 atomic_set(&li->active, 1);
147 atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags);
148 li->action_bits |= action;
152 li->action_bits |= action;
153 atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags);
149 if (waitqueue_active(li->wq))
150 wake_up_interruptible(li->wq);
151out:
154 if (waitqueue_active(li->wq))
155 wake_up_interruptible(li->wq);
156out:
152 spin_unlock_bh(&li->lock);
157 spin_unlock(&li->lock);
153
154 return rc;
155}
156
157static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action)
158{
159 struct kvm_s390_local_interrupt *li;
160 struct kvm_vcpu *dst_vcpu = NULL;

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

233 *reg |= SIGP_STATUS_INVALID_PARAMETER;
234 return SIGP_CC_STATUS_STORED;
235 }
236
237 inti = kzalloc(sizeof(*inti), GFP_KERNEL);
238 if (!inti)
239 return SIGP_CC_BUSY;
240
158
159 return rc;
160}
161
162static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action)
163{
164 struct kvm_s390_local_interrupt *li;
165 struct kvm_vcpu *dst_vcpu = NULL;

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

238 *reg |= SIGP_STATUS_INVALID_PARAMETER;
239 return SIGP_CC_STATUS_STORED;
240 }
241
242 inti = kzalloc(sizeof(*inti), GFP_KERNEL);
243 if (!inti)
244 return SIGP_CC_BUSY;
245
241 spin_lock_bh(&li->lock);
246 spin_lock(&li->lock);
242 /* cpu must be in stopped state */
243 if (!(atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) {
244 *reg &= 0xffffffff00000000UL;
245 *reg |= SIGP_STATUS_INCORRECT_STATE;
246 rc = SIGP_CC_STATUS_STORED;
247 kfree(inti);
248 goto out_li;
249 }

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

254 list_add_tail(&inti->list, &li->list);
255 atomic_set(&li->active, 1);
256 if (waitqueue_active(li->wq))
257 wake_up_interruptible(li->wq);
258 rc = SIGP_CC_ORDER_CODE_ACCEPTED;
259
260 VCPU_EVENT(vcpu, 4, "set prefix of cpu %02x to %x", cpu_addr, address);
261out_li:
247 /* cpu must be in stopped state */
248 if (!(atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) {
249 *reg &= 0xffffffff00000000UL;
250 *reg |= SIGP_STATUS_INCORRECT_STATE;
251 rc = SIGP_CC_STATUS_STORED;
252 kfree(inti);
253 goto out_li;
254 }

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

259 list_add_tail(&inti->list, &li->list);
260 atomic_set(&li->active, 1);
261 if (waitqueue_active(li->wq))
262 wake_up_interruptible(li->wq);
263 rc = SIGP_CC_ORDER_CODE_ACCEPTED;
264
265 VCPU_EVENT(vcpu, 4, "set prefix of cpu %02x to %x", cpu_addr, address);
266out_li:
262 spin_unlock_bh(&li->lock);
267 spin_unlock(&li->lock);
263 return rc;
264}
265
266static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu, u16 cpu_id,
267 u32 addr, u64 *reg)
268{
269 struct kvm_vcpu *dst_vcpu = NULL;
270 int flags;
271 int rc;
272
273 if (cpu_id < KVM_MAX_VCPUS)
274 dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_id);
275 if (!dst_vcpu)
276 return SIGP_CC_NOT_OPERATIONAL;
277
268 return rc;
269}
270
271static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu, u16 cpu_id,
272 u32 addr, u64 *reg)
273{
274 struct kvm_vcpu *dst_vcpu = NULL;
275 int flags;
276 int rc;
277
278 if (cpu_id < KVM_MAX_VCPUS)
279 dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_id);
280 if (!dst_vcpu)
281 return SIGP_CC_NOT_OPERATIONAL;
282
278 spin_lock_bh(&dst_vcpu->arch.local_int.lock);
283 spin_lock(&dst_vcpu->arch.local_int.lock);
279 flags = atomic_read(dst_vcpu->arch.local_int.cpuflags);
284 flags = atomic_read(dst_vcpu->arch.local_int.cpuflags);
280 spin_unlock_bh(&dst_vcpu->arch.local_int.lock);
285 spin_unlock(&dst_vcpu->arch.local_int.lock);
281 if (!(flags & CPUSTAT_STOPPED)) {
282 *reg &= 0xffffffff00000000UL;
283 *reg |= SIGP_STATUS_INCORRECT_STATE;
284 return SIGP_CC_STATUS_STORED;
285 }
286
287 addr &= 0x7ffffe00;
288 rc = kvm_s390_store_status_unloaded(dst_vcpu, addr);

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

333
334 if (cpu_addr >= KVM_MAX_VCPUS)
335 return SIGP_CC_NOT_OPERATIONAL;
336
337 dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
338 if (!dst_vcpu)
339 return SIGP_CC_NOT_OPERATIONAL;
340 li = &dst_vcpu->arch.local_int;
286 if (!(flags & CPUSTAT_STOPPED)) {
287 *reg &= 0xffffffff00000000UL;
288 *reg |= SIGP_STATUS_INCORRECT_STATE;
289 return SIGP_CC_STATUS_STORED;
290 }
291
292 addr &= 0x7ffffe00;
293 rc = kvm_s390_store_status_unloaded(dst_vcpu, addr);

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

338
339 if (cpu_addr >= KVM_MAX_VCPUS)
340 return SIGP_CC_NOT_OPERATIONAL;
341
342 dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
343 if (!dst_vcpu)
344 return SIGP_CC_NOT_OPERATIONAL;
345 li = &dst_vcpu->arch.local_int;
341 spin_lock_bh(&li->lock);
346 spin_lock(&li->lock);
342 if (li->action_bits & ACTION_STOP_ON_STOP)
343 rc = SIGP_CC_BUSY;
347 if (li->action_bits & ACTION_STOP_ON_STOP)
348 rc = SIGP_CC_BUSY;
344 spin_unlock_bh(&li->lock);
349 spin_unlock(&li->lock);
345
346 return rc;
347}
348
349int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
350{
351 int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
352 int r3 = vcpu->arch.sie_block->ipa & 0x000f;

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

456 u8 order_code = kvm_s390_get_base_disp_rs(vcpu);
457
458 trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr);
459
460 if (order_code == SIGP_EXTERNAL_CALL) {
461 dest_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
462 BUG_ON(dest_vcpu == NULL);
463
350
351 return rc;
352}
353
354int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
355{
356 int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
357 int r3 = vcpu->arch.sie_block->ipa & 0x000f;

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

461 u8 order_code = kvm_s390_get_base_disp_rs(vcpu);
462
463 trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr);
464
465 if (order_code == SIGP_EXTERNAL_CALL) {
466 dest_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
467 BUG_ON(dest_vcpu == NULL);
468
464 spin_lock_bh(&dest_vcpu->arch.local_int.lock);
469 spin_lock(&dest_vcpu->arch.local_int.lock);
465 if (waitqueue_active(&dest_vcpu->wq))
466 wake_up_interruptible(&dest_vcpu->wq);
467 dest_vcpu->preempted = true;
470 if (waitqueue_active(&dest_vcpu->wq))
471 wake_up_interruptible(&dest_vcpu->wq);
472 dest_vcpu->preempted = true;
468 spin_unlock_bh(&dest_vcpu->arch.local_int.lock);
473 spin_unlock(&dest_vcpu->arch.local_int.lock);
469
470 kvm_s390_set_psw_cc(vcpu, SIGP_CC_ORDER_CODE_ACCEPTED);
471 return 0;
472 }
473
474 return -EOPNOTSUPP;
475}
474
475 kvm_s390_set_psw_cc(vcpu, SIGP_CC_ORDER_CODE_ACCEPTED);
476 return 0;
477 }
478
479 return -EOPNOTSUPP;
480}