Skip to content

Commit 1ad1fa8

Browse files
iii-ifrankjaa
authored andcommitted
KVM: s390: interrupt: Fix single-stepping userspace-emulated instructions
Single-stepping a userspace-emulated instruction that generates an interrupt causes GDB to land on the instruction following it instead of the respective interrupt handler. The reason is that after arranging a KVM_EXIT_S390_SIEIC exit, kvm_handle_sie_intercept() calls kvm_s390_handle_per_ifetch_icpt(), which sets KVM_GUESTDBG_EXIT_PENDING. This bit, however, is not processed immediately, but rather persists until the next ioctl(), causing a spurious single-step exit. Fix by clearing this bit in ioctl(). Reviewed-by: David Hildenbrand <[email protected]> Reviewed-by: Claudio Imbrenda <[email protected]> Signed-off-by: Ilya Leoshkevich <[email protected]> Message-ID: <[email protected]> Signed-off-by: Claudio Imbrenda <[email protected]> Signed-off-by: Janosch Frank <[email protected]>
1 parent ba853a4 commit 1ad1fa8

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

arch/s390/kvm/kvm-s390.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5383,14 +5383,16 @@ long kvm_arch_vcpu_async_ioctl(struct file *filp,
53835383
{
53845384
struct kvm_vcpu *vcpu = filp->private_data;
53855385
void __user *argp = (void __user *)arg;
5386+
int rc;
53865387

53875388
switch (ioctl) {
53885389
case KVM_S390_IRQ: {
53895390
struct kvm_s390_irq s390irq;
53905391

53915392
if (copy_from_user(&s390irq, argp, sizeof(s390irq)))
53925393
return -EFAULT;
5393-
return kvm_s390_inject_vcpu(vcpu, &s390irq);
5394+
rc = kvm_s390_inject_vcpu(vcpu, &s390irq);
5395+
break;
53945396
}
53955397
case KVM_S390_INTERRUPT: {
53965398
struct kvm_s390_interrupt s390int;
@@ -5400,10 +5402,25 @@ long kvm_arch_vcpu_async_ioctl(struct file *filp,
54005402
return -EFAULT;
54015403
if (s390int_to_s390irq(&s390int, &s390irq))
54025404
return -EINVAL;
5403-
return kvm_s390_inject_vcpu(vcpu, &s390irq);
5405+
rc = kvm_s390_inject_vcpu(vcpu, &s390irq);
5406+
break;
54045407
}
5408+
default:
5409+
rc = -ENOIOCTLCMD;
5410+
break;
54055411
}
5406-
return -ENOIOCTLCMD;
5412+
5413+
/*
5414+
* To simplify single stepping of userspace-emulated instructions,
5415+
* KVM_EXIT_S390_SIEIC exit sets KVM_GUESTDBG_EXIT_PENDING (see
5416+
* should_handle_per_ifetch()). However, if userspace emulation injects
5417+
* an interrupt, it needs to be cleared, so that KVM_EXIT_DEBUG happens
5418+
* after (and not before) the interrupt delivery.
5419+
*/
5420+
if (!rc)
5421+
vcpu->guest_debug &= ~KVM_GUESTDBG_EXIT_PENDING;
5422+
5423+
return rc;
54075424
}
54085425

54095426
static int kvm_s390_handle_pv_vcpu_dump(struct kvm_vcpu *vcpu,

0 commit comments

Comments
 (0)