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
|
||||
#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 */
|
||||
|
|
|
@ -117,10 +117,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 */
|
||||
|
@ -420,8 +426,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;
|
||||
}
|
||||
|
@ -509,9 +517,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:
|
||||
|
@ -520,6 +525,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 {
|
||||
|
@ -539,8 +547,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;
|
||||
|
@ -552,6 +558,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);
|
||||
|
||||
|
|
|
@ -181,6 +181,11 @@ struct kvm_run {
|
|||
__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 {
|
||||
|
@ -232,8 +237,6 @@ struct kvm_run {
|
|||
/* KVM_EXIT_S390_SIEIC */
|
||||
struct {
|
||||
__u8 icptcode;
|
||||
__u64 mask; /* psw upper half */
|
||||
__u64 addr; /* psw lower half */
|
||||
__u16 ipa;
|
||||
__u32 ipb;
|
||||
} s390_sieic;
|
||||
|
@ -492,6 +495,7 @@ struct kvm_ioeventfd {
|
|||
#ifdef __KVM_HAVE_VCPU_EVENTS
|
||||
#define KVM_CAP_VCPU_EVENTS 41
|
||||
#endif
|
||||
#define KVM_CAP_S390_PSW 42
|
||||
|
||||
#ifdef KVM_CAP_IRQ_ROUTING
|
||||
|
||||
|
|
Loading…
Reference in New Issue