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