sigp.c (879f99ef2c4c05d9a7f0a67a05f1415663119825) | sigp.c (4953919feedaeb6d0161ecea920c35d1d1f639d3) |
---|---|
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. --- 221 unchanged lines hidden (view full) --- 230 231static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, 232 u64 *reg) 233{ 234 struct kvm_s390_local_interrupt *li; 235 struct kvm_vcpu *dst_vcpu = NULL; 236 struct kvm_s390_interrupt_info *inti; 237 int rc; | 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. --- 221 unchanged lines hidden (view full) --- 230 231static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, 232 u64 *reg) 233{ 234 struct kvm_s390_local_interrupt *li; 235 struct kvm_vcpu *dst_vcpu = NULL; 236 struct kvm_s390_interrupt_info *inti; 237 int rc; |
238 u8 tmp; | |
239 240 if (cpu_addr < KVM_MAX_VCPUS) 241 dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); 242 if (!dst_vcpu) 243 return SIGP_CC_NOT_OPERATIONAL; 244 li = &dst_vcpu->arch.local_int; 245 | 238 239 if (cpu_addr < KVM_MAX_VCPUS) 240 dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); 241 if (!dst_vcpu) 242 return SIGP_CC_NOT_OPERATIONAL; 243 li = &dst_vcpu->arch.local_int; 244 |
246 /* make sure that the new value is valid memory */ 247 address = address & 0x7fffe000u; 248 if (copy_from_guest_absolute(vcpu, &tmp, address, 1) || 249 copy_from_guest_absolute(vcpu, &tmp, address + PAGE_SIZE, 1)) { | 245 /* 246 * Make sure the new value is valid memory. We only need to check the 247 * first page, since address is 8k aligned and memory pieces are always 248 * at least 1MB aligned and have at least a size of 1MB. 249 */ 250 address &= 0x7fffe000u; 251 if (kvm_is_error_gpa(vcpu->kvm, address)) { |
250 *reg &= 0xffffffff00000000UL; 251 *reg |= SIGP_STATUS_INVALID_PARAMETER; 252 return SIGP_CC_STATUS_STORED; 253 } 254 255 inti = kzalloc(sizeof(*inti), GFP_KERNEL); 256 if (!inti) 257 return SIGP_CC_BUSY; --- 193 unchanged lines hidden (view full) --- 451 } 452 453 if (rc < 0) 454 return rc; 455 456 kvm_s390_set_psw_cc(vcpu, rc); 457 return 0; 458} | 252 *reg &= 0xffffffff00000000UL; 253 *reg |= SIGP_STATUS_INVALID_PARAMETER; 254 return SIGP_CC_STATUS_STORED; 255 } 256 257 inti = kzalloc(sizeof(*inti), GFP_KERNEL); 258 if (!inti) 259 return SIGP_CC_BUSY; --- 193 unchanged lines hidden (view full) --- 453 } 454 455 if (rc < 0) 456 return rc; 457 458 kvm_s390_set_psw_cc(vcpu, rc); 459 return 0; 460} |
461 462/* 463 * Handle SIGP partial execution interception. 464 * 465 * This interception will occur at the source cpu when a source cpu sends an 466 * external call to a target cpu and the target cpu has the WAIT bit set in 467 * its cpuflags. Interception will occurr after the interrupt indicator bits at 468 * the target cpu have been set. All error cases will lead to instruction 469 * interception, therefore nothing is to be checked or prepared. 470 */ 471int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu) 472{ 473 int r3 = vcpu->arch.sie_block->ipa & 0x000f; 474 u16 cpu_addr = vcpu->run->s.regs.gprs[r3]; 475 struct kvm_vcpu *dest_vcpu; 476 u8 order_code = kvm_s390_get_base_disp_rs(vcpu); 477 478 trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr); 479 480 if (order_code == SIGP_EXTERNAL_CALL) { 481 dest_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); 482 BUG_ON(dest_vcpu == NULL); 483 484 spin_lock_bh(&dest_vcpu->arch.local_int.lock); 485 if (waitqueue_active(&dest_vcpu->wq)) 486 wake_up_interruptible(&dest_vcpu->wq); 487 dest_vcpu->preempted = true; 488 spin_unlock_bh(&dest_vcpu->arch.local_int.lock); 489 490 kvm_s390_set_psw_cc(vcpu, SIGP_CC_ORDER_CODE_ACCEPTED); 491 return 0; 492 } 493 494 return -EOPNOTSUPP; 495} |
|