|
@@ -364,6 +364,8 @@ static int handle_operexc(struct kvm_vcpu *vcpu)
|
|
|
|
|
|
int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
|
|
|
{
|
|
|
+ int rc, per_rc = 0;
|
|
|
+
|
|
|
if (kvm_is_ucontrol(vcpu->kvm))
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
@@ -372,7 +374,8 @@ int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
|
|
|
case 0x18:
|
|
|
return handle_noop(vcpu);
|
|
|
case 0x04:
|
|
|
- return handle_instruction(vcpu);
|
|
|
+ rc = handle_instruction(vcpu);
|
|
|
+ break;
|
|
|
case 0x08:
|
|
|
return handle_prog(vcpu);
|
|
|
case 0x14:
|
|
@@ -384,10 +387,18 @@ int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
|
|
|
case 0x28:
|
|
|
return handle_stop(vcpu);
|
|
|
case 0x2c:
|
|
|
- return handle_operexc(vcpu);
|
|
|
+ rc = handle_operexc(vcpu);
|
|
|
+ break;
|
|
|
case 0x38:
|
|
|
- return handle_partial_execution(vcpu);
|
|
|
+ rc = handle_partial_execution(vcpu);
|
|
|
+ break;
|
|
|
default:
|
|
|
return -EOPNOTSUPP;
|
|
|
}
|
|
|
+
|
|
|
+ /* process PER, also if the instrution is processed in user space */
|
|
|
+ if (vcpu->arch.sie_block->icptstatus & 0x02 &&
|
|
|
+ (!rc || rc == -EOPNOTSUPP))
|
|
|
+ per_rc = kvm_s390_handle_per_ifetch_icpt(vcpu);
|
|
|
+ return per_rc ? per_rc : rc;
|
|
|
}
|