intercept.c (92c9632119b67f3e201240f6813cd0343bfb0141) | intercept.c (f6af84e7e7eb0558d5ad3882007956eb5b748ffd) |
---|---|
1/* 2 * in-kernel handling for sie intercepts 3 * 4 * Copyright IBM Corp. 2008, 2014 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. --- 122 unchanged lines hidden (view full) --- 131 vcpu->arch.sie_block->ipa, 132 vcpu->arch.sie_block->ipb); 133 handler = instruction_handlers[vcpu->arch.sie_block->ipa >> 8]; 134 if (handler) 135 return handler(vcpu); 136 return -EOPNOTSUPP; 137} 138 | 1/* 2 * in-kernel handling for sie intercepts 3 * 4 * Copyright IBM Corp. 2008, 2014 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. --- 122 unchanged lines hidden (view full) --- 131 vcpu->arch.sie_block->ipa, 132 vcpu->arch.sie_block->ipb); 133 handler = instruction_handlers[vcpu->arch.sie_block->ipa >> 8]; 134 if (handler) 135 return handler(vcpu); 136 return -EOPNOTSUPP; 137} 138 |
139static void __extract_prog_irq(struct kvm_vcpu *vcpu, 140 struct kvm_s390_pgm_info *pgm_info) | 139static int inject_prog_on_prog_intercept(struct kvm_vcpu *vcpu) |
141{ | 140{ |
142 memset(pgm_info, 0, sizeof(struct kvm_s390_pgm_info)); 143 pgm_info->code = vcpu->arch.sie_block->iprcc; | 141 struct kvm_s390_pgm_info pgm_info = { 142 .code = vcpu->arch.sie_block->iprcc, 143 }; |
144 145 switch (vcpu->arch.sie_block->iprcc & ~PGM_PER) { 146 case PGM_AFX_TRANSLATION: 147 case PGM_ASX_TRANSLATION: 148 case PGM_EX_TRANSLATION: 149 case PGM_LFX_TRANSLATION: 150 case PGM_LSTE_SEQUENCE: 151 case PGM_LSX_TRANSLATION: 152 case PGM_LX_TRANSLATION: 153 case PGM_PRIMARY_AUTHORITY: 154 case PGM_SECONDARY_AUTHORITY: 155 case PGM_SPACE_SWITCH: | 144 145 switch (vcpu->arch.sie_block->iprcc & ~PGM_PER) { 146 case PGM_AFX_TRANSLATION: 147 case PGM_ASX_TRANSLATION: 148 case PGM_EX_TRANSLATION: 149 case PGM_LFX_TRANSLATION: 150 case PGM_LSTE_SEQUENCE: 151 case PGM_LSX_TRANSLATION: 152 case PGM_LX_TRANSLATION: 153 case PGM_PRIMARY_AUTHORITY: 154 case PGM_SECONDARY_AUTHORITY: 155 case PGM_SPACE_SWITCH: |
156 pgm_info->trans_exc_code = vcpu->arch.sie_block->tecmc; | 156 pgm_info.trans_exc_code = vcpu->arch.sie_block->tecmc; |
157 break; 158 case PGM_ALEN_TRANSLATION: 159 case PGM_ALE_SEQUENCE: 160 case PGM_ASTE_INSTANCE: 161 case PGM_ASTE_SEQUENCE: 162 case PGM_ASTE_VALIDITY: 163 case PGM_EXTENDED_AUTHORITY: | 157 break; 158 case PGM_ALEN_TRANSLATION: 159 case PGM_ALE_SEQUENCE: 160 case PGM_ASTE_INSTANCE: 161 case PGM_ASTE_SEQUENCE: 162 case PGM_ASTE_VALIDITY: 163 case PGM_EXTENDED_AUTHORITY: |
164 pgm_info->exc_access_id = vcpu->arch.sie_block->eai; | 164 pgm_info.exc_access_id = vcpu->arch.sie_block->eai; |
165 break; 166 case PGM_ASCE_TYPE: 167 case PGM_PAGE_TRANSLATION: 168 case PGM_REGION_FIRST_TRANS: 169 case PGM_REGION_SECOND_TRANS: 170 case PGM_REGION_THIRD_TRANS: 171 case PGM_SEGMENT_TRANSLATION: | 165 break; 166 case PGM_ASCE_TYPE: 167 case PGM_PAGE_TRANSLATION: 168 case PGM_REGION_FIRST_TRANS: 169 case PGM_REGION_SECOND_TRANS: 170 case PGM_REGION_THIRD_TRANS: 171 case PGM_SEGMENT_TRANSLATION: |
172 pgm_info->trans_exc_code = vcpu->arch.sie_block->tecmc; 173 pgm_info->exc_access_id = vcpu->arch.sie_block->eai; 174 pgm_info->op_access_id = vcpu->arch.sie_block->oai; | 172 pgm_info.trans_exc_code = vcpu->arch.sie_block->tecmc; 173 pgm_info.exc_access_id = vcpu->arch.sie_block->eai; 174 pgm_info.op_access_id = vcpu->arch.sie_block->oai; |
175 break; 176 case PGM_MONITOR: | 175 break; 176 case PGM_MONITOR: |
177 pgm_info->mon_class_nr = vcpu->arch.sie_block->mcn; 178 pgm_info->mon_code = vcpu->arch.sie_block->tecmc; | 177 pgm_info.mon_class_nr = vcpu->arch.sie_block->mcn; 178 pgm_info.mon_code = vcpu->arch.sie_block->tecmc; |
179 break; 180 case PGM_VECTOR_PROCESSING: 181 case PGM_DATA: | 179 break; 180 case PGM_VECTOR_PROCESSING: 181 case PGM_DATA: |
182 pgm_info->data_exc_code = vcpu->arch.sie_block->dxc; | 182 pgm_info.data_exc_code = vcpu->arch.sie_block->dxc; |
183 break; 184 case PGM_PROTECTION: | 183 break; 184 case PGM_PROTECTION: |
185 pgm_info->trans_exc_code = vcpu->arch.sie_block->tecmc; 186 pgm_info->exc_access_id = vcpu->arch.sie_block->eai; | 185 pgm_info.trans_exc_code = vcpu->arch.sie_block->tecmc; 186 pgm_info.exc_access_id = vcpu->arch.sie_block->eai; |
187 break; 188 default: 189 break; 190 } 191 192 if (vcpu->arch.sie_block->iprcc & PGM_PER) { | 187 break; 188 default: 189 break; 190 } 191 192 if (vcpu->arch.sie_block->iprcc & PGM_PER) { |
193 pgm_info->per_code = vcpu->arch.sie_block->perc; 194 pgm_info->per_atmid = vcpu->arch.sie_block->peratmid; 195 pgm_info->per_address = vcpu->arch.sie_block->peraddr; 196 pgm_info->per_access_id = vcpu->arch.sie_block->peraid; | 193 pgm_info.per_code = vcpu->arch.sie_block->perc; 194 pgm_info.per_atmid = vcpu->arch.sie_block->peratmid; 195 pgm_info.per_address = vcpu->arch.sie_block->peraddr; 196 pgm_info.per_access_id = vcpu->arch.sie_block->peraid; |
197 } | 197 } |
198 return kvm_s390_inject_prog_irq(vcpu, &pgm_info); |
|
198} 199 200/* 201 * restore ITDB to program-interruption TDB in guest lowcore 202 * and set TX abort indication if required 203*/ 204static int handle_itdb(struct kvm_vcpu *vcpu) 205{ --- 12 unchanged lines hidden (view full) --- 218 219 return 0; 220} 221 222#define per_event(vcpu) (vcpu->arch.sie_block->iprcc & PGM_PER) 223 224static int handle_prog(struct kvm_vcpu *vcpu) 225{ | 199} 200 201/* 202 * restore ITDB to program-interruption TDB in guest lowcore 203 * and set TX abort indication if required 204*/ 205static int handle_itdb(struct kvm_vcpu *vcpu) 206{ --- 12 unchanged lines hidden (view full) --- 219 220 return 0; 221} 222 223#define per_event(vcpu) (vcpu->arch.sie_block->iprcc & PGM_PER) 224 225static int handle_prog(struct kvm_vcpu *vcpu) 226{ |
226 struct kvm_s390_pgm_info pgm_info; | |
227 psw_t psw; 228 int rc; 229 230 vcpu->stat.exit_program_interruption++; 231 232 if (guestdbg_enabled(vcpu) && per_event(vcpu)) { 233 kvm_s390_handle_per_event(vcpu); 234 /* the interrupt might have been filtered out completely */ --- 9 unchanged lines hidden (view full) --- 244 /* Avoid endless loops of specification exceptions */ 245 if (!is_valid_psw(&psw)) 246 return -EOPNOTSUPP; 247 } 248 rc = handle_itdb(vcpu); 249 if (rc) 250 return rc; 251 | 227 psw_t psw; 228 int rc; 229 230 vcpu->stat.exit_program_interruption++; 231 232 if (guestdbg_enabled(vcpu) && per_event(vcpu)) { 233 kvm_s390_handle_per_event(vcpu); 234 /* the interrupt might have been filtered out completely */ --- 9 unchanged lines hidden (view full) --- 244 /* Avoid endless loops of specification exceptions */ 245 if (!is_valid_psw(&psw)) 246 return -EOPNOTSUPP; 247 } 248 rc = handle_itdb(vcpu); 249 if (rc) 250 return rc; 251 |
252 __extract_prog_irq(vcpu, &pgm_info); 253 return kvm_s390_inject_prog_irq(vcpu, &pgm_info); | 252 return inject_prog_on_prog_intercept(vcpu); |
254} 255 256/** 257 * handle_external_interrupt - used for external interruption interceptions 258 * 259 * This interception only occurs if the CPUSTAT_EXT_INT bit was set, or if 260 * the new PSW does not have external interrupts disabled. In the first case, 261 * we've got to deliver the interrupt manually, and in the second case, we --- 116 unchanged lines hidden --- | 253} 254 255/** 256 * handle_external_interrupt - used for external interruption interceptions 257 * 258 * This interception only occurs if the CPUSTAT_EXT_INT bit was set, or if 259 * the new PSW does not have external interrupts disabled. In the first case, 260 * we've got to deliver the interrupt manually, and in the second case, we --- 116 unchanged lines hidden --- |