summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>2014-03-18 10:06:14 +0100
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-04-22 13:24:52 +0200
commitf71d0dc5084b4de761b5be1aef1a855136cecd15 (patch)
treebee07d8a60a7a01c8556fd102ca8572fd8ab8dba
parentKVM: s390: move timer interrupt checks into own functions (diff)
downloadlinux-f71d0dc5084b4de761b5be1aef1a855136cecd15.tar.xz
linux-f71d0dc5084b4de761b5be1aef1a855136cecd15.zip
KVM: s390: no timer interrupts when single-stepping a guest
When a guest is single-stepped, we want to disable timer interrupts. Otherwise, the guest will continuously execute the external interrupt handler and make debugging of code where timer interrupts are enabled almost impossible. The delivery of timer interrupts can be enforced in such sections by setting a breakpoint and continuing execution. In order to disable timer interrupts, they are disabled in the control register of the guest just before SIE entry and are suppressed in the interrupt check/delivery methods. Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
-rw-r--r--arch/s390/kvm/guestdbg.c2
-rw-r--r--arch/s390/kvm/interrupt.c3
2 files changed, 5 insertions, 0 deletions
diff --git a/arch/s390/kvm/guestdbg.c b/arch/s390/kvm/guestdbg.c
index 100e99d1030d..757ccef62fd5 100644
--- a/arch/s390/kvm/guestdbg.c
+++ b/arch/s390/kvm/guestdbg.c
@@ -155,6 +155,8 @@ void kvm_s390_patch_guest_per_regs(struct kvm_vcpu *vcpu)
*/
if (guestdbg_sstep_enabled(vcpu)) {
+ /* disable timer (clock-comparator) interrupts */
+ vcpu->arch.sie_block->gcr[0] &= ~0x800ul;
vcpu->arch.sie_block->gcr[9] |= PER_EVENT_IFETCH;
vcpu->arch.sie_block->gcr[10] = 0;
vcpu->arch.sie_block->gcr[11] = PSW_ADDR_INSN;
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 0165f1b089ac..d020c5f8eabb 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -61,6 +61,9 @@ static int ckc_interrupts_enabled(struct kvm_vcpu *vcpu)
if (psw_extint_disabled(vcpu) ||
!(vcpu->arch.sie_block->gcr[0] & 0x800ul))
return 0;
+ if (guestdbg_enabled(vcpu) && guestdbg_sstep_enabled(vcpu))
+ /* No timer interrupts when single stepping */
+ return 0;
return 1;
}