summaryrefslogtreecommitdiff
path: root/arch/s390
diff options
context:
space:
mode:
authorCarsten Otte <carsteno@de.ibm.com>2009-11-19 14:21:16 +0100
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-18 14:03:35 -0800
commitfff7d05d83d41107dd1c8740cfbfd50fe3ce87e8 (patch)
treea3999af454ef94c3f61a524d23a4418510eff438 /arch/s390
parentf7b0fd208527e8f755e06411821efb5cc89c0868 (diff)
KVM: s390: Make psw available on all exits, not just a subset
commit d7b0b5eb3000c6fb902f08c619fcd673a23d8fab upstream. This patch moves s390 processor status word into the base kvm_run struct and keeps it up-to date on all userspace exits. The userspace ABI is broken by this, however there are no applications in the wild using this. A capability check is provided so users can verify the updated API exists. Signed-off-by: Carsten Otte <cotte@de.ibm.com> Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/kvm.h3
-rw-r--r--arch/s390/kvm/kvm-s390.c25
2 files changed, 19 insertions, 9 deletions
diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/asm/kvm.h
index 3dfcaeb5d7f4..82b32a100c7d 100644
--- a/arch/s390/include/asm/kvm.h
+++ b/arch/s390/include/asm/kvm.h
@@ -1,6 +1,5 @@
#ifndef __LINUX_KVM_S390_H
#define __LINUX_KVM_S390_H
-
/*
* asm-s390/kvm.h - KVM s390 specific structures and definitions
*
@@ -15,6 +14,8 @@
*/
#include <linux/types.h>
+#define __KVM_S390
+
/* for KVM_GET_REGS and KVM_SET_REGS */
struct kvm_regs {
/* general purpose regs for s390 */
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 07ced89740d7..ca2d31277b3b 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -116,10 +116,16 @@ long kvm_arch_dev_ioctl(struct file *filp,
int kvm_dev_ioctl_check_extension(long ext)
{
+ int r;
+
switch (ext) {
+ case KVM_CAP_S390_PSW:
+ r = 1;
+ break;
default:
- return 0;
+ r = 0;
}
+ return r;
}
/* Section: vm related */
@@ -419,8 +425,10 @@ static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
vcpu_load(vcpu);
if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
rc = -EBUSY;
- else
- vcpu->arch.sie_block->gpsw = psw;
+ else {
+ vcpu->run->psw_mask = psw.mask;
+ vcpu->run->psw_addr = psw.addr;
+ }
vcpu_put(vcpu);
return rc;
}
@@ -508,9 +516,6 @@ rerun_vcpu:
switch (kvm_run->exit_reason) {
case KVM_EXIT_S390_SIEIC:
- vcpu->arch.sie_block->gpsw.mask = kvm_run->s390_sieic.mask;
- vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr;
- break;
case KVM_EXIT_UNKNOWN:
case KVM_EXIT_INTR:
case KVM_EXIT_S390_RESET:
@@ -519,6 +524,9 @@ rerun_vcpu:
BUG();
}
+ vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
+ vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
+
might_fault();
do {
@@ -538,8 +546,6 @@ rerun_vcpu:
/* intercept cannot be handled in-kernel, prepare kvm-run */
kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
- kvm_run->s390_sieic.mask = vcpu->arch.sie_block->gpsw.mask;
- kvm_run->s390_sieic.addr = vcpu->arch.sie_block->gpsw.addr;
kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
rc = 0;
@@ -551,6 +557,9 @@ rerun_vcpu:
rc = 0;
}
+ kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
+ kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
+
if (vcpu->sigset_active)
sigprocmask(SIG_SETMASK, &sigsaved, NULL);