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. 9 * 10 * Author(s): Carsten Otte <cotte@de.ibm.com> 11 * Christian Borntraeger <borntraeger@de.ibm.com> 12 */ 13 14 #include <linux/kvm_host.h> 15 #include <linux/errno.h> 16 #include <linux/pagemap.h> 17 18 #include <asm/kvm_host.h> 19 #include <asm/asm-offsets.h> 20 #include <asm/irq.h> 21 22 #include "kvm-s390.h" 23 #include "gaccess.h" 24 #include "trace.h" 25 #include "trace-s390.h" 26 27 28 static const intercept_handler_t instruction_handlers[256] = { 29 [0x01] = kvm_s390_handle_01, 30 [0x82] = kvm_s390_handle_lpsw, 31 [0x83] = kvm_s390_handle_diag, 32 [0xaa] = kvm_s390_handle_aa, 33 [0xae] = kvm_s390_handle_sigp, 34 [0xb2] = kvm_s390_handle_b2, 35 [0xb6] = kvm_s390_handle_stctl, 36 [0xb7] = kvm_s390_handle_lctl, 37 [0xb9] = kvm_s390_handle_b9, 38 [0xe3] = kvm_s390_handle_e3, 39 [0xe5] = kvm_s390_handle_e5, 40 [0xeb] = kvm_s390_handle_eb, 41 }; 42 43 u8 kvm_s390_get_ilen(struct kvm_vcpu *vcpu) 44 { 45 struct kvm_s390_sie_block *sie_block = vcpu->arch.sie_block; 46 u8 ilen = 0; 47 48 switch (vcpu->arch.sie_block->icptcode) { 49 case ICPT_INST: 50 case ICPT_INSTPROGI: 51 case ICPT_OPEREXC: 52 case ICPT_PARTEXEC: 53 case ICPT_IOINST: 54 /* instruction only stored for these icptcodes */ 55 ilen = insn_length(vcpu->arch.sie_block->ipa >> 8); 56 /* Use the length of the EXECUTE instruction if necessary */ 57 if (sie_block->icptstatus & 1) { 58 ilen = (sie_block->icptstatus >> 4) & 0x6; 59 if (!ilen) 60 ilen = 4; 61 } 62 break; 63 case ICPT_PROGI: 64 /* bit 1+2 of pgmilc are the ilc, so we directly get ilen */ 65 ilen = vcpu->arch.sie_block->pgmilc & 0x6; 66 break; 67 } 68 return ilen; 69 } 70 71 static int handle_noop(struct kvm_vcpu *vcpu) 72 { 73 switch (vcpu->arch.sie_block->icptcode) { 74 case 0x10: 75 vcpu->stat.exit_external_request++; 76 break; 77 default: 78 break; /* nothing */ 79 } 80 return 0; 81 } 82 83 static int handle_stop(struct kvm_vcpu *vcpu) 84 { 85 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; 86 int rc = 0; 87 uint8_t flags, stop_pending; 88 89 vcpu->stat.exit_stop_request++; 90 91 /* delay the stop if any non-stop irq is pending */ 92 if (kvm_s390_vcpu_has_irq(vcpu, 1)) 93 return 0; 94 95 /* avoid races with the injection/SIGP STOP code */ 96 spin_lock(&li->lock); 97 flags = li->irq.stop.flags; 98 stop_pending = kvm_s390_is_stop_irq_pending(vcpu); 99 spin_unlock(&li->lock); 100 101 trace_kvm_s390_stop_request(stop_pending, flags); 102 if (!stop_pending) 103 return 0; 104 105 if (flags & KVM_S390_STOP_FLAG_STORE_STATUS) { 106 rc = kvm_s390_vcpu_store_status(vcpu, 107 KVM_S390_STORE_STATUS_NOADDR); 108 if (rc) 109 return rc; 110 } 111 112 if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm)) 113 kvm_s390_vcpu_stop(vcpu); 114 return -EOPNOTSUPP; 115 } 116 117 static int handle_validity(struct kvm_vcpu *vcpu) 118 { 119 int viwhy = vcpu->arch.sie_block->ipb >> 16; 120 121 vcpu->stat.exit_validity++; 122 trace_kvm_s390_intercept_validity(vcpu, viwhy); 123 KVM_EVENT(3, "validity intercept 0x%x for pid %u (kvm 0x%pK)", viwhy, 124 current->pid, vcpu->kvm); 125 126 /* do not warn on invalid runtime instrumentation mode */ 127 WARN_ONCE(viwhy != 0x44, "kvm: unhandled validity intercept 0x%x\n", 128 viwhy); 129 return -EINVAL; 130 } 131 132 static int handle_instruction(struct kvm_vcpu *vcpu) 133 { 134 intercept_handler_t handler; 135 136 vcpu->stat.exit_instruction++; 137 trace_kvm_s390_intercept_instruction(vcpu, 138 vcpu->arch.sie_block->ipa, 139 vcpu->arch.sie_block->ipb); 140 handler = instruction_handlers[vcpu->arch.sie_block->ipa >> 8]; 141 if (handler) 142 return handler(vcpu); 143 return -EOPNOTSUPP; 144 } 145 146 static int inject_prog_on_prog_intercept(struct kvm_vcpu *vcpu) 147 { 148 struct kvm_s390_pgm_info pgm_info = { 149 .code = vcpu->arch.sie_block->iprcc, 150 /* the PSW has already been rewound */ 151 .flags = KVM_S390_PGM_FLAGS_NO_REWIND, 152 }; 153 154 switch (vcpu->arch.sie_block->iprcc & ~PGM_PER) { 155 case PGM_AFX_TRANSLATION: 156 case PGM_ASX_TRANSLATION: 157 case PGM_EX_TRANSLATION: 158 case PGM_LFX_TRANSLATION: 159 case PGM_LSTE_SEQUENCE: 160 case PGM_LSX_TRANSLATION: 161 case PGM_LX_TRANSLATION: 162 case PGM_PRIMARY_AUTHORITY: 163 case PGM_SECONDARY_AUTHORITY: 164 case PGM_SPACE_SWITCH: 165 pgm_info.trans_exc_code = vcpu->arch.sie_block->tecmc; 166 break; 167 case PGM_ALEN_TRANSLATION: 168 case PGM_ALE_SEQUENCE: 169 case PGM_ASTE_INSTANCE: 170 case PGM_ASTE_SEQUENCE: 171 case PGM_ASTE_VALIDITY: 172 case PGM_EXTENDED_AUTHORITY: 173 pgm_info.exc_access_id = vcpu->arch.sie_block->eai; 174 break; 175 case PGM_ASCE_TYPE: 176 case PGM_PAGE_TRANSLATION: 177 case PGM_REGION_FIRST_TRANS: 178 case PGM_REGION_SECOND_TRANS: 179 case PGM_REGION_THIRD_TRANS: 180 case PGM_SEGMENT_TRANSLATION: 181 pgm_info.trans_exc_code = vcpu->arch.sie_block->tecmc; 182 pgm_info.exc_access_id = vcpu->arch.sie_block->eai; 183 pgm_info.op_access_id = vcpu->arch.sie_block->oai; 184 break; 185 case PGM_MONITOR: 186 pgm_info.mon_class_nr = vcpu->arch.sie_block->mcn; 187 pgm_info.mon_code = vcpu->arch.sie_block->tecmc; 188 break; 189 case PGM_VECTOR_PROCESSING: 190 case PGM_DATA: 191 pgm_info.data_exc_code = vcpu->arch.sie_block->dxc; 192 break; 193 case PGM_PROTECTION: 194 pgm_info.trans_exc_code = vcpu->arch.sie_block->tecmc; 195 pgm_info.exc_access_id = vcpu->arch.sie_block->eai; 196 break; 197 default: 198 break; 199 } 200 201 if (vcpu->arch.sie_block->iprcc & PGM_PER) { 202 pgm_info.per_code = vcpu->arch.sie_block->perc; 203 pgm_info.per_atmid = vcpu->arch.sie_block->peratmid; 204 pgm_info.per_address = vcpu->arch.sie_block->peraddr; 205 pgm_info.per_access_id = vcpu->arch.sie_block->peraid; 206 } 207 return kvm_s390_inject_prog_irq(vcpu, &pgm_info); 208 } 209 210 /* 211 * restore ITDB to program-interruption TDB in guest lowcore 212 * and set TX abort indication if required 213 */ 214 static int handle_itdb(struct kvm_vcpu *vcpu) 215 { 216 struct kvm_s390_itdb *itdb; 217 int rc; 218 219 if (!IS_TE_ENABLED(vcpu) || !IS_ITDB_VALID(vcpu)) 220 return 0; 221 if (current->thread.per_flags & PER_FLAG_NO_TE) 222 return 0; 223 itdb = (struct kvm_s390_itdb *)vcpu->arch.sie_block->itdba; 224 rc = write_guest_lc(vcpu, __LC_PGM_TDB, itdb, sizeof(*itdb)); 225 if (rc) 226 return rc; 227 memset(itdb, 0, sizeof(*itdb)); 228 229 return 0; 230 } 231 232 #define per_event(vcpu) (vcpu->arch.sie_block->iprcc & PGM_PER) 233 234 static int handle_prog(struct kvm_vcpu *vcpu) 235 { 236 psw_t psw; 237 int rc; 238 239 vcpu->stat.exit_program_interruption++; 240 241 if (guestdbg_enabled(vcpu) && per_event(vcpu)) { 242 rc = kvm_s390_handle_per_event(vcpu); 243 if (rc) 244 return rc; 245 /* the interrupt might have been filtered out completely */ 246 if (vcpu->arch.sie_block->iprcc == 0) 247 return 0; 248 } 249 250 trace_kvm_s390_intercept_prog(vcpu, vcpu->arch.sie_block->iprcc); 251 if (vcpu->arch.sie_block->iprcc == PGM_SPECIFICATION) { 252 rc = read_guest_lc(vcpu, __LC_PGM_NEW_PSW, &psw, sizeof(psw_t)); 253 if (rc) 254 return rc; 255 /* Avoid endless loops of specification exceptions */ 256 if (!is_valid_psw(&psw)) 257 return -EOPNOTSUPP; 258 } 259 rc = handle_itdb(vcpu); 260 if (rc) 261 return rc; 262 263 return inject_prog_on_prog_intercept(vcpu); 264 } 265 266 /** 267 * handle_external_interrupt - used for external interruption interceptions 268 * 269 * This interception only occurs if the CPUSTAT_EXT_INT bit was set, or if 270 * the new PSW does not have external interrupts disabled. In the first case, 271 * we've got to deliver the interrupt manually, and in the second case, we 272 * drop to userspace to handle the situation there. 273 */ 274 static int handle_external_interrupt(struct kvm_vcpu *vcpu) 275 { 276 u16 eic = vcpu->arch.sie_block->eic; 277 struct kvm_s390_irq irq; 278 psw_t newpsw; 279 int rc; 280 281 vcpu->stat.exit_external_interrupt++; 282 283 rc = read_guest_lc(vcpu, __LC_EXT_NEW_PSW, &newpsw, sizeof(psw_t)); 284 if (rc) 285 return rc; 286 /* We can not handle clock comparator or timer interrupt with bad PSW */ 287 if ((eic == EXT_IRQ_CLK_COMP || eic == EXT_IRQ_CPU_TIMER) && 288 (newpsw.mask & PSW_MASK_EXT)) 289 return -EOPNOTSUPP; 290 291 switch (eic) { 292 case EXT_IRQ_CLK_COMP: 293 irq.type = KVM_S390_INT_CLOCK_COMP; 294 break; 295 case EXT_IRQ_CPU_TIMER: 296 irq.type = KVM_S390_INT_CPU_TIMER; 297 break; 298 case EXT_IRQ_EXTERNAL_CALL: 299 irq.type = KVM_S390_INT_EXTERNAL_CALL; 300 irq.u.extcall.code = vcpu->arch.sie_block->extcpuaddr; 301 rc = kvm_s390_inject_vcpu(vcpu, &irq); 302 /* ignore if another external call is already pending */ 303 if (rc == -EBUSY) 304 return 0; 305 return rc; 306 default: 307 return -EOPNOTSUPP; 308 } 309 310 return kvm_s390_inject_vcpu(vcpu, &irq); 311 } 312 313 /** 314 * Handle MOVE PAGE partial execution interception. 315 * 316 * This interception can only happen for guests with DAT disabled and 317 * addresses that are currently not mapped in the host. Thus we try to 318 * set up the mappings for the corresponding user pages here (or throw 319 * addressing exceptions in case of illegal guest addresses). 320 */ 321 static int handle_mvpg_pei(struct kvm_vcpu *vcpu) 322 { 323 unsigned long srcaddr, dstaddr; 324 int reg1, reg2, rc; 325 326 kvm_s390_get_regs_rre(vcpu, ®1, ®2); 327 328 /* Make sure that the source is paged-in */ 329 rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg2], 330 reg2, &srcaddr, GACC_FETCH); 331 if (rc) 332 return kvm_s390_inject_prog_cond(vcpu, rc); 333 rc = kvm_arch_fault_in_page(vcpu, srcaddr, 0); 334 if (rc != 0) 335 return rc; 336 337 /* Make sure that the destination is paged-in */ 338 rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg1], 339 reg1, &dstaddr, GACC_STORE); 340 if (rc) 341 return kvm_s390_inject_prog_cond(vcpu, rc); 342 rc = kvm_arch_fault_in_page(vcpu, dstaddr, 1); 343 if (rc != 0) 344 return rc; 345 346 kvm_s390_retry_instr(vcpu); 347 348 return 0; 349 } 350 351 static int handle_partial_execution(struct kvm_vcpu *vcpu) 352 { 353 vcpu->stat.exit_pei++; 354 355 if (vcpu->arch.sie_block->ipa == 0xb254) /* MVPG */ 356 return handle_mvpg_pei(vcpu); 357 if (vcpu->arch.sie_block->ipa >> 8 == 0xae) /* SIGP */ 358 return kvm_s390_handle_sigp_pei(vcpu); 359 360 return -EOPNOTSUPP; 361 } 362 363 static int handle_operexc(struct kvm_vcpu *vcpu) 364 { 365 psw_t oldpsw, newpsw; 366 int rc; 367 368 vcpu->stat.exit_operation_exception++; 369 trace_kvm_s390_handle_operexc(vcpu, vcpu->arch.sie_block->ipa, 370 vcpu->arch.sie_block->ipb); 371 372 if (vcpu->arch.sie_block->ipa == 0xb256) 373 return handle_sthyi(vcpu); 374 375 if (vcpu->arch.sie_block->ipa == 0 && vcpu->kvm->arch.user_instr0) 376 return -EOPNOTSUPP; 377 rc = read_guest_lc(vcpu, __LC_PGM_NEW_PSW, &newpsw, sizeof(psw_t)); 378 if (rc) 379 return rc; 380 /* 381 * Avoid endless loops of operation exceptions, if the pgm new 382 * PSW will cause a new operation exception. 383 * The heuristic checks if the pgm new psw is within 6 bytes before 384 * the faulting psw address (with same DAT, AS settings) and the 385 * new psw is not a wait psw and the fault was not triggered by 386 * problem state. 387 */ 388 oldpsw = vcpu->arch.sie_block->gpsw; 389 if (oldpsw.addr - newpsw.addr <= 6 && 390 !(newpsw.mask & PSW_MASK_WAIT) && 391 !(oldpsw.mask & PSW_MASK_PSTATE) && 392 (newpsw.mask & PSW_MASK_ASC) == (oldpsw.mask & PSW_MASK_ASC) && 393 (newpsw.mask & PSW_MASK_DAT) == (oldpsw.mask & PSW_MASK_DAT)) 394 return -EOPNOTSUPP; 395 396 return kvm_s390_inject_program_int(vcpu, PGM_OPERATION); 397 } 398 399 int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu) 400 { 401 int rc, per_rc = 0; 402 403 if (kvm_is_ucontrol(vcpu->kvm)) 404 return -EOPNOTSUPP; 405 406 switch (vcpu->arch.sie_block->icptcode) { 407 case ICPT_EXTREQ: 408 case ICPT_IOREQ: 409 return handle_noop(vcpu); 410 case ICPT_INST: 411 rc = handle_instruction(vcpu); 412 break; 413 case ICPT_PROGI: 414 return handle_prog(vcpu); 415 case ICPT_EXTINT: 416 return handle_external_interrupt(vcpu); 417 case ICPT_WAIT: 418 return kvm_s390_handle_wait(vcpu); 419 case ICPT_VALIDITY: 420 return handle_validity(vcpu); 421 case ICPT_STOP: 422 return handle_stop(vcpu); 423 case ICPT_OPEREXC: 424 rc = handle_operexc(vcpu); 425 break; 426 case ICPT_PARTEXEC: 427 rc = handle_partial_execution(vcpu); 428 break; 429 case ICPT_KSS: 430 rc = kvm_s390_skey_check_enable(vcpu); 431 break; 432 default: 433 return -EOPNOTSUPP; 434 } 435 436 /* process PER, also if the instrution is processed in user space */ 437 if (vcpu->arch.sie_block->icptstatus & 0x02 && 438 (!rc || rc == -EOPNOTSUPP)) 439 per_rc = kvm_s390_handle_per_ifetch_icpt(vcpu); 440 return per_rc ? per_rc : rc; 441 } 442