KVM: s390: Make psw available on all exits, not just a subset
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>
This commit is contained in:
parent
3cfc3092f4
commit
d7b0b5eb30
|
@ -1,6 +1,5 @@
|
||||||
#ifndef __LINUX_KVM_S390_H
|
#ifndef __LINUX_KVM_S390_H
|
||||||
#define __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
|
||||||
*
|
*
|
||||||
|
@ -15,6 +14,8 @@
|
||||||
*/
|
*/
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#define __KVM_S390
|
||||||
|
|
||||||
/* for KVM_GET_REGS and KVM_SET_REGS */
|
/* for KVM_GET_REGS and KVM_SET_REGS */
|
||||||
struct kvm_regs {
|
struct kvm_regs {
|
||||||
/* general purpose regs for s390 */
|
/* general purpose regs for s390 */
|
||||||
|
|
|
@ -117,10 +117,16 @@ long kvm_arch_dev_ioctl(struct file *filp,
|
||||||
|
|
||||||
int kvm_dev_ioctl_check_extension(long ext)
|
int kvm_dev_ioctl_check_extension(long ext)
|
||||||
{
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
switch (ext) {
|
switch (ext) {
|
||||||
|
case KVM_CAP_S390_PSW:
|
||||||
|
r = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
r = 0;
|
||||||
}
|
}
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Section: vm related */
|
/* Section: vm related */
|
||||||
|
@ -420,8 +426,10 @@ static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
|
||||||
vcpu_load(vcpu);
|
vcpu_load(vcpu);
|
||||||
if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
|
if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
|
||||||
rc = -EBUSY;
|
rc = -EBUSY;
|
||||||
else
|
else {
|
||||||
vcpu->arch.sie_block->gpsw = psw;
|
vcpu->run->psw_mask = psw.mask;
|
||||||
|
vcpu->run->psw_addr = psw.addr;
|
||||||
|
}
|
||||||
vcpu_put(vcpu);
|
vcpu_put(vcpu);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -509,9 +517,6 @@ rerun_vcpu:
|
||||||
|
|
||||||
switch (kvm_run->exit_reason) {
|
switch (kvm_run->exit_reason) {
|
||||||
case KVM_EXIT_S390_SIEIC:
|
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_UNKNOWN:
|
||||||
case KVM_EXIT_INTR:
|
case KVM_EXIT_INTR:
|
||||||
case KVM_EXIT_S390_RESET:
|
case KVM_EXIT_S390_RESET:
|
||||||
|
@ -520,6 +525,9 @@ rerun_vcpu:
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
|
||||||
|
vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
|
||||||
|
|
||||||
might_fault();
|
might_fault();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -539,8 +547,6 @@ rerun_vcpu:
|
||||||
/* intercept cannot be handled in-kernel, prepare kvm-run */
|
/* intercept cannot be handled in-kernel, prepare kvm-run */
|
||||||
kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
|
kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
|
||||||
kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
|
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.ipa = vcpu->arch.sie_block->ipa;
|
||||||
kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
|
kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
@ -552,6 +558,9 @@ rerun_vcpu:
|
||||||
rc = 0;
|
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)
|
if (vcpu->sigset_active)
|
||||||
sigprocmask(SIG_SETMASK, &sigsaved, NULL);
|
sigprocmask(SIG_SETMASK, &sigsaved, NULL);
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,11 @@ struct kvm_run {
|
||||||
__u64 cr8;
|
__u64 cr8;
|
||||||
__u64 apic_base;
|
__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 {
|
union {
|
||||||
/* KVM_EXIT_UNKNOWN */
|
/* KVM_EXIT_UNKNOWN */
|
||||||
struct {
|
struct {
|
||||||
|
@ -232,8 +237,6 @@ struct kvm_run {
|
||||||
/* KVM_EXIT_S390_SIEIC */
|
/* KVM_EXIT_S390_SIEIC */
|
||||||
struct {
|
struct {
|
||||||
__u8 icptcode;
|
__u8 icptcode;
|
||||||
__u64 mask; /* psw upper half */
|
|
||||||
__u64 addr; /* psw lower half */
|
|
||||||
__u16 ipa;
|
__u16 ipa;
|
||||||
__u32 ipb;
|
__u32 ipb;
|
||||||
} s390_sieic;
|
} s390_sieic;
|
||||||
|
@ -492,6 +495,7 @@ struct kvm_ioeventfd {
|
||||||
#ifdef __KVM_HAVE_VCPU_EVENTS
|
#ifdef __KVM_HAVE_VCPU_EVENTS
|
||||||
#define KVM_CAP_VCPU_EVENTS 41
|
#define KVM_CAP_VCPU_EVENTS 41
|
||||||
#endif
|
#endif
|
||||||
|
#define KVM_CAP_S390_PSW 42
|
||||||
|
|
||||||
#ifdef KVM_CAP_IRQ_ROUTING
|
#ifdef KVM_CAP_IRQ_ROUTING
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue