switch (vcpu->arch.sie_block->icptcode) { case ICPT_INST: case ICPT_INSTPROGI: case ICPT_OPEREXC: case ICPT_PARTEXEC: case ICPT_IOINST: /* instruction only stored for these icptcodes */
ilen = insn_length(vcpu->arch.sie_block->ipa >> 8); /* Use the length of the EXECUTE instruction if necessary */ if (sie_block->icptstatus & 1) {
ilen = (sie_block->icptstatus >> 4) & 0x6; if (!ilen)
ilen = 4;
} break; case ICPT_PROGI: /* bit 1+2 of pgmilc are the ilc, so we directly get ilen */
ilen = vcpu->arch.sie_block->pgmilc & 0x6; break;
} return ilen;
}
staticint inject_prog_on_prog_intercept(struct kvm_vcpu *vcpu)
{ struct kvm_s390_pgm_info pgm_info = {
.code = vcpu->arch.sie_block->iprcc, /* the PSW has already been rewound */
.flags = KVM_S390_PGM_FLAGS_NO_REWIND,
};
switch (vcpu->arch.sie_block->iprcc & ~PGM_PER) { case PGM_AFX_TRANSLATION: case PGM_ASX_TRANSLATION: case PGM_EX_TRANSLATION: case PGM_LFX_TRANSLATION: case PGM_LSTE_SEQUENCE: case PGM_LSX_TRANSLATION: case PGM_LX_TRANSLATION: case PGM_PRIMARY_AUTHORITY: case PGM_SECONDARY_AUTHORITY: case PGM_SPACE_SWITCH:
pgm_info.trans_exc_code = vcpu->arch.sie_block->tecmc; break; case PGM_ALEN_TRANSLATION: case PGM_ALE_SEQUENCE: case PGM_ASTE_INSTANCE: case PGM_ASTE_SEQUENCE: case PGM_ASTE_VALIDITY: case PGM_EXTENDED_AUTHORITY:
pgm_info.exc_access_id = vcpu->arch.sie_block->eai; break; case PGM_ASCE_TYPE: case PGM_PAGE_TRANSLATION: case PGM_REGION_FIRST_TRANS: case PGM_REGION_SECOND_TRANS: case PGM_REGION_THIRD_TRANS: case PGM_SEGMENT_TRANSLATION:
pgm_info.trans_exc_code = vcpu->arch.sie_block->tecmc;
pgm_info.exc_access_id = vcpu->arch.sie_block->eai;
pgm_info.op_access_id = vcpu->arch.sie_block->oai; break; case PGM_MONITOR:
pgm_info.mon_class_nr = vcpu->arch.sie_block->mcn;
pgm_info.mon_code = vcpu->arch.sie_block->tecmc; break; case PGM_VECTOR_PROCESSING: case PGM_DATA:
pgm_info.data_exc_code = vcpu->arch.sie_block->dxc; break; case PGM_PROTECTION:
pgm_info.trans_exc_code = vcpu->arch.sie_block->tecmc;
pgm_info.exc_access_id = vcpu->arch.sie_block->eai; break; default: break;
}
staticint handle_prog(struct kvm_vcpu *vcpu)
{
psw_t psw; int rc;
vcpu->stat.exit_program_interruption++;
/* *Intercept8indicatesaloopofspecificationexceptions *forprotectedguests.
*/ if (kvm_s390_pv_cpu_is_protected(vcpu)) return -EOPNOTSUPP;
if (should_handle_per_event(vcpu)) {
rc = kvm_s390_handle_per_event(vcpu); if (rc) return rc; /* the interrupt might have been filtered out completely */ if (vcpu->arch.sie_block->iprcc == 0) return0;
}
trace_kvm_s390_intercept_prog(vcpu, vcpu->arch.sie_block->iprcc); if (vcpu->arch.sie_block->iprcc == PGM_SPECIFICATION) {
rc = read_guest_lc(vcpu, __LC_PGM_NEW_PSW, &psw, sizeof(psw_t)); if (rc) return rc; /* Avoid endless loops of specification exceptions */ if (!is_valid_psw(&psw)) return -EOPNOTSUPP;
}
rc = handle_itdb(vcpu); if (rc) return rc;
/* Ensure that the source is paged-in, no actual access -> no key checking */
rc = guest_translate_address_with_key(vcpu, vcpu->run->s.regs.gprs[reg2],
reg2, &srcaddr, GACC_FETCH, 0); if (rc) return kvm_s390_inject_prog_cond(vcpu, rc);
rc = kvm_s390_handle_dat_fault(vcpu, srcaddr, 0); if (rc != 0) return rc;
/* Ensure that the source is paged-in, no actual access -> no key checking */
rc = guest_translate_address_with_key(vcpu, vcpu->run->s.regs.gprs[reg1],
reg1, &dstaddr, GACC_STORE, 0); if (rc) return kvm_s390_inject_prog_cond(vcpu, rc);
rc = kvm_s390_handle_dat_fault(vcpu, dstaddr, FOLL_WRITE); if (rc != 0) return rc;
staticint handle_pv_notification(struct kvm_vcpu *vcpu)
{ int ret;
if (vcpu->arch.sie_block->ipa == 0xb210) return handle_pv_spx(vcpu); if (vcpu->arch.sie_block->ipa == 0xb220) return handle_pv_sclp(vcpu); if (vcpu->arch.sie_block->ipa == 0xb9a4) return handle_pv_uvc(vcpu); if (vcpu->arch.sie_block->ipa >> 8 == 0xae) { /* *Besidesexternalcall,otherSIGPordersalsocausea *108(pvnotify)intercept.Incontrasttoexternalcall, *theseordersneedtobeemulatedandhencetheappropriate *placetohandlethemisinhandle_instruction(). *Sofirsttrykvm_s390_handle_sigp_pei()andifthatisn't *successful,goonwithhandle_instruction().
*/
ret = kvm_s390_handle_sigp_pei(vcpu); if (!ret) return ret;
}
return handle_instruction(vcpu);
}
staticbool should_handle_per_ifetch(conststruct kvm_vcpu *vcpu, int rc)
{ /* Process PER, also if the instruction is processed in user space. */ if (!(vcpu->arch.sie_block->icptstatus & 0x02)) returnfalse; if (rc != 0 && rc != -EOPNOTSUPP) returnfalse; if (guestdbg_sstep_enabled(vcpu) && vcpu->arch.local_int.pending_irqs) /* __vcpu_run() will exit after delivering the interrupt. */ returnfalse; returntrue;
}
int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
{ int rc, per_rc = 0;
if (kvm_is_ucontrol(vcpu->kvm)) return -EOPNOTSUPP;
switch (vcpu->arch.sie_block->icptcode) { case ICPT_EXTREQ:
vcpu->stat.exit_external_request++; return0; case ICPT_IOREQ:
vcpu->stat.exit_io_request++; return0; case ICPT_INST:
rc = handle_instruction(vcpu); break; case ICPT_PROGI: return handle_prog(vcpu); case ICPT_EXTINT: return handle_external_interrupt(vcpu); case ICPT_WAIT: return kvm_s390_handle_wait(vcpu); case ICPT_VALIDITY: return handle_validity(vcpu); case ICPT_STOP: return handle_stop(vcpu); case ICPT_OPEREXC:
rc = handle_operexc(vcpu); break; case ICPT_PARTEXEC:
rc = handle_partial_execution(vcpu); break; case ICPT_KSS: /* Instruction will be redriven, skip the PER check. */ return kvm_s390_skey_check_enable(vcpu); case ICPT_MCHKREQ: case ICPT_INT_ENABLE: /* *PSWbit13oraCR(0,6,14)changedandwemight *nowbeabletodeliverinterrupts.Thepre-runcode *willtakecareofthis.
*/
rc = 0; break; case ICPT_PV_INSTR:
rc = handle_instruction(vcpu); break; case ICPT_PV_NOTIFY:
rc = handle_pv_notification(vcpu); break; case ICPT_PV_PREF:
rc = 0;
kvm_s390_pv_convert_to_secure(vcpu->kvm, kvm_s390_get_prefix(vcpu));
kvm_s390_pv_convert_to_secure(vcpu->kvm, kvm_s390_get_prefix(vcpu) + PAGE_SIZE); break; default: return -EOPNOTSUPP;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.