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