summaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm
diff options
context:
space:
mode:
authorChristian Borntraeger <borntraeger@de.ibm.com>2008-07-25 15:51:54 +0200
committerAvi Kivity <avi@qumranet.com>2008-07-27 10:36:05 +0200
commit3cd612998f17d5b3588be7f4937720411d247ff6 (patch)
tree2d453cdd9c9f6e83caf404c2982701fb1a91c994 /arch/s390/kvm
parentKVM: s390: Change guestaddr type in gaccess (diff)
downloadlinux-3cd612998f17d5b3588be7f4937720411d247ff6.tar.xz
linux-3cd612998f17d5b3588be7f4937720411d247ff6.zip
KVM: s390: Fix program check on interrupt delivery handling
The current interrupt handling on s390 misbehaves on an error case. On s390 each cpu has the prefix area (lowcore) for interrupt delivery. This memory must always be available. If we fail to access the prefix area for a guest on interrupt delivery the configuration is completely unusable. There is no point in sending another program interrupt to an inaccessible lowcore. Furthermore, we should not bug the host kernel, because this can be triggered by userspace. I think the guest kernel itself can not trigger the problem, as SET PREFIX and SIGNAL PROCESSOR SET PREFIX both check that the memory is available and sane. As this is a userspace bug (e.g. setting the wrong guest offset, unmapping guest memory) we should kill the userspace process instead of BUGing the host kernel. In the long term we probably should notify the userspace process about this problem. Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r--arch/s390/kvm/interrupt.c21
1 files changed, 7 insertions, 14 deletions
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 11230b0db957..2960702b4824 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -13,6 +13,7 @@
#include <asm/lowcore.h>
#include <asm/uaccess.h>
#include <linux/kvm_host.h>
+#include <linux/signal.h>
#include "kvm-s390.h"
#include "gaccess.h"
@@ -246,15 +247,10 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
default:
BUG();
}
-
if (exception) {
- VCPU_EVENT(vcpu, 1, "%s", "program exception while delivering"
- " interrupt");
- kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
- if (inti->type == KVM_S390_PROGRAM_INT) {
- printk(KERN_WARNING "kvm: recursive program check\n");
- BUG();
- }
+ printk("kvm: The guest lowcore is not mapped during interrupt "
+ "delivery, killing userspace\n");
+ do_exit(SIGKILL);
}
}
@@ -277,14 +273,11 @@ static int __try_deliver_ckc_interrupt(struct kvm_vcpu *vcpu)
__LC_EXT_NEW_PSW, sizeof(psw_t));
if (rc == -EFAULT)
exception = 1;
-
if (exception) {
- VCPU_EVENT(vcpu, 1, "%s", "program exception while delivering" \
- " ckc interrupt");
- kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
- return 0;
+ printk("kvm: The guest lowcore is not mapped during interrupt "
+ "delivery, killing userspace\n");
+ do_exit(SIGKILL);
}
-
return 1;
}