On 21.07.23 13:57, Ilya Leoshkevich wrote:
After single-stepping an instruction that generates an interrupt, GDB
ends up on the second instruction of the respective interrupt handler.
The reason is that vcpu_pre_run() manually delivers the interrupt, and
then __vcpu_run() runs the first handler instruction using the
CPUSTAT_P flag. This causes a KVM_SINGLESTEP exit on the second handler
instruction.
Fix by delaying the KVM_SINGLESTEP exit until after the manual
interrupt delivery.
Signed-off-by: Ilya Leoshkevich <iii@xxxxxxxxxxxxx>
---
arch/s390/kvm/interrupt.c | 10 ++++++++++
arch/s390/kvm/kvm-s390.c | 4 ++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 9bd0a873f3b1..2cebe4227b8e 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -1392,6 +1392,7 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
{
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
int rc = 0;
+ bool delivered = false;
unsigned long irq_type;
unsigned long irqs;
@@ -1465,6 +1466,15 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
WARN_ONCE(1, "Unknown pending irq type %ld", irq_type);
clear_bit(irq_type, &li->pending_irqs);
}
+ delivered |= !rc;
+ }
+
Can we add a comment like
/*
* We delivered at least one interrupt and modified the PC. Force a
* singlestep event now.
*/
+ if (delivered && guestdbg_sstep_enabled(vcpu)) {
+ struct kvm_debug_exit_arch *debug_exit = &vcpu->run->debug.arch;
+
+ debug_exit->addr = vcpu->arch.sie_block->gpsw.addr;
+ debug_exit->type = KVM_SINGLESTEP;
+ vcpu->guest_debug |= KVM_GUESTDBG_EXIT_PENDING;
}
I do wonder if we, instead, want to do this whenever we modify the PSW.
That way we could catch any PC changes and only have to add checks for
guestdbg_exit_pending().
But this is simpler and should work as well.
Acked-by: David Hildenbrand <david@xxxxxxxxxx>
--
Cheers,
David / dhildenb