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.
Cc: stable@kernel.org
Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
#ifndef __LINUX_KVM_S390_H
#define __LINUX_KVM_S390_H
#ifndef __LINUX_KVM_S390_H
#define __LINUX_KVM_S390_H
/*
* asm-s390/kvm.h - KVM s390 specific structures and definitions
*
/*
* asm-s390/kvm.h - KVM s390 specific structures and definitions
*
*/
#include <linux/types.h>
*/
#include <linux/types.h>
/* for KVM_GET_REGS and KVM_SET_REGS */
struct kvm_regs {
/* general purpose regs for s390 */
/* for KVM_GET_REGS and KVM_SET_REGS */
struct kvm_regs {
/* general purpose regs for s390 */
int kvm_dev_ioctl_check_extension(long ext)
{
int kvm_dev_ioctl_check_extension(long ext)
{
+ case KVM_CAP_S390_PSW:
+ r = 1;
+ break;
}
/* Section: vm related */
}
/* Section: vm related */
vcpu_load(vcpu);
if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
rc = -EBUSY;
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;
}
vcpu_put(vcpu);
return rc;
}
switch (kvm_run->exit_reason) {
case KVM_EXIT_S390_SIEIC:
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:
case KVM_EXIT_UNKNOWN:
case KVM_EXIT_INTR:
case KVM_EXIT_S390_RESET:
+ vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
+ vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
+
/* 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;
/* 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;
kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
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);
if (vcpu->sigset_active)
sigprocmask(SIG_SETMASK, &sigsaved, NULL);
__u64 cr8;
__u64 apic_base;
__u64 cr8;
__u64 apic_base;
+#ifdef __KVM_S390
+ /* the processor status word for s390 */
+ __u64 psw_mask; /* psw upper half */
+ __u64 psw_addr; /* psw lower half */
+#endif
union {
/* KVM_EXIT_UNKNOWN */
struct {
union {
/* KVM_EXIT_UNKNOWN */
struct {
/* KVM_EXIT_S390_SIEIC */
struct {
__u8 icptcode;
/* KVM_EXIT_S390_SIEIC */
struct {
__u8 icptcode;
- __u64 mask; /* psw upper half */
- __u64 addr; /* psw lower half */
__u16 ipa;
__u32 ipb;
} s390_sieic;
__u16 ipa;
__u32 ipb;
} s390_sieic;
#ifdef __KVM_HAVE_VCPU_EVENTS
#define KVM_CAP_VCPU_EVENTS 41
#endif
#ifdef __KVM_HAVE_VCPU_EVENTS
#define KVM_CAP_VCPU_EVENTS 41
#endif
+#define KVM_CAP_S390_PSW 42
#ifdef KVM_CAP_IRQ_ROUTING
#ifdef KVM_CAP_IRQ_ROUTING