@ -109,8 +109,69 @@ static int handle_instruction(struct kvm_vcpu *vcpu)
return - EOPNOTSUPP ;
}
static void __extract_prog_irq ( struct kvm_vcpu * vcpu ,
struct kvm_s390_pgm_info * pgm_info )
{
memset ( pgm_info , 0 , sizeof ( struct kvm_s390_pgm_info ) ) ;
pgm_info - > code = vcpu - > arch . sie_block - > iprcc ;
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_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 ;
}
if ( vcpu - > arch . sie_block - > iprcc & PGM_PER ) {
pgm_info - > per_code = vcpu - > arch . sie_block - > perc ;
pgm_info - > per_atmid = vcpu - > arch . sie_block - > peratmid ;
pgm_info - > per_address = vcpu - > arch . sie_block - > peraddr ;
pgm_info - > per_access_id = vcpu - > arch . sie_block - > peraid ;
}
}
static int handle_prog ( struct kvm_vcpu * vcpu )
{
struct kvm_s390_pgm_info pgm_info ;
struct kvm_s390_itdb * itdb ;
int rc ;
@ -128,7 +189,9 @@ static int handle_prog(struct kvm_vcpu *vcpu)
memset ( itdb , 0 , sizeof ( * itdb ) ) ;
skip_itdb :
trace_kvm_s390_intercept_prog ( vcpu , vcpu - > arch . sie_block - > iprcc ) ;
return kvm_s390_inject_program_int ( vcpu , vcpu - > arch . sie_block - > iprcc ) ;
__extract_prog_irq ( vcpu , & pgm_info ) ;
return kvm_s390_inject_prog_irq ( vcpu , & pgm_info ) ;
}
static int handle_instruction_and_prog ( struct kvm_vcpu * vcpu )