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} |