@@ -228,6 +228,21 @@ static int handle_itdb(struct kvm_vcpu *vcpu)
228228
229229#define per_event (vcpu ) (vcpu->arch.sie_block->iprcc & PGM_PER)
230230
231+ static bool should_handle_per_event (const struct kvm_vcpu * vcpu )
232+ {
233+ if (!guestdbg_enabled (vcpu ) || !per_event (vcpu ))
234+ return false;
235+ if (guestdbg_sstep_enabled (vcpu ) &&
236+ vcpu -> arch .sie_block -> iprcc != PGM_PER ) {
237+ /*
238+ * __vcpu_run() will exit after delivering the concurrently
239+ * indicated condition.
240+ */
241+ return false;
242+ }
243+ return true;
244+ }
245+
231246static int handle_prog (struct kvm_vcpu * vcpu )
232247{
233248 psw_t psw ;
@@ -242,7 +257,7 @@ static int handle_prog(struct kvm_vcpu *vcpu)
242257 if (kvm_s390_pv_cpu_is_protected (vcpu ))
243258 return - EOPNOTSUPP ;
244259
245- if (guestdbg_enabled ( vcpu ) && per_event (vcpu )) {
260+ if (should_handle_per_event (vcpu )) {
246261 rc = kvm_s390_handle_per_event (vcpu );
247262 if (rc )
248263 return rc ;
@@ -571,6 +586,19 @@ static int handle_pv_notification(struct kvm_vcpu *vcpu)
571586 return handle_instruction (vcpu );
572587}
573588
589+ static bool should_handle_per_ifetch (const struct kvm_vcpu * vcpu , int rc )
590+ {
591+ /* Process PER, also if the instruction is processed in user space. */
592+ if (!(vcpu -> arch .sie_block -> icptstatus & 0x02 ))
593+ return false;
594+ if (rc != 0 && rc != - EOPNOTSUPP )
595+ return false;
596+ if (guestdbg_sstep_enabled (vcpu ) && vcpu -> arch .local_int .pending_irqs )
597+ /* __vcpu_run() will exit after delivering the interrupt. */
598+ return false;
599+ return true;
600+ }
601+
574602int kvm_handle_sie_intercept (struct kvm_vcpu * vcpu )
575603{
576604 int rc , per_rc = 0 ;
@@ -605,8 +633,8 @@ int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
605633 rc = handle_partial_execution (vcpu );
606634 break ;
607635 case ICPT_KSS :
608- rc = kvm_s390_skey_check_enable ( vcpu );
609- break ;
636+ /* Instruction will be redriven, skip the PER check. */
637+ return kvm_s390_skey_check_enable ( vcpu ) ;
610638 case ICPT_MCHKREQ :
611639 case ICPT_INT_ENABLE :
612640 /*
@@ -633,9 +661,7 @@ int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
633661 return - EOPNOTSUPP ;
634662 }
635663
636- /* process PER, also if the instruction is processed in user space */
637- if (vcpu -> arch .sie_block -> icptstatus & 0x02 &&
638- (!rc || rc == - EOPNOTSUPP ))
664+ if (should_handle_per_ifetch (vcpu , rc ))
639665 per_rc = kvm_s390_handle_per_ifetch_icpt (vcpu );
640666 return per_rc ? per_rc : rc ;
641667}
0 commit comments