Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Carsten Otte and committed by
Avi Kivity
d7b0b5eb 3cfc3092

+25 -11
+2 -1
arch/s390/include/asm/kvm.h
··· 1 1 #ifndef __LINUX_KVM_S390_H 2 2 #define __LINUX_KVM_S390_H 3 - 4 3 /* 5 4 * asm-s390/kvm.h - KVM s390 specific structures and definitions 6 5 * ··· 13 14 * Christian Borntraeger <borntraeger@de.ibm.com> 14 15 */ 15 16 #include <linux/types.h> 17 + 18 + #define __KVM_S390 16 19 17 20 /* for KVM_GET_REGS and KVM_SET_REGS */ 18 21 struct kvm_regs {
+17 -8
arch/s390/kvm/kvm-s390.c
··· 117 117 118 118 int kvm_dev_ioctl_check_extension(long ext) 119 119 { 120 + int r; 121 + 120 122 switch (ext) { 123 + case KVM_CAP_S390_PSW: 124 + r = 1; 125 + break; 121 126 default: 122 - return 0; 127 + r = 0; 123 128 } 129 + return r; 124 130 } 125 131 126 132 /* Section: vm related */ ··· 426 420 vcpu_load(vcpu); 427 421 if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING) 428 422 rc = -EBUSY; 429 - else 430 - vcpu->arch.sie_block->gpsw = psw; 423 + else { 424 + vcpu->run->psw_mask = psw.mask; 425 + vcpu->run->psw_addr = psw.addr; 426 + } 431 427 vcpu_put(vcpu); 432 428 return rc; 433 429 } ··· 517 509 518 510 switch (kvm_run->exit_reason) { 519 511 case KVM_EXIT_S390_SIEIC: 520 - vcpu->arch.sie_block->gpsw.mask = kvm_run->s390_sieic.mask; 521 - vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr; 522 - break; 523 512 case KVM_EXIT_UNKNOWN: 524 513 case KVM_EXIT_INTR: 525 514 case KVM_EXIT_S390_RESET: ··· 524 519 default: 525 520 BUG(); 526 521 } 522 + 523 + vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask; 524 + vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr; 527 525 528 526 might_fault(); 529 527 ··· 547 539 /* intercept cannot be handled in-kernel, prepare kvm-run */ 548 540 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC; 549 541 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode; 550 - kvm_run->s390_sieic.mask = vcpu->arch.sie_block->gpsw.mask; 551 - kvm_run->s390_sieic.addr = vcpu->arch.sie_block->gpsw.addr; 552 542 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa; 553 543 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb; 554 544 rc = 0; ··· 557 551 * kvm_run has been prepared by the handler */ 558 552 rc = 0; 559 553 } 554 + 555 + kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask; 556 + kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr; 560 557 561 558 if (vcpu->sigset_active) 562 559 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+6 -2
include/linux/kvm.h
··· 181 181 __u64 cr8; 182 182 __u64 apic_base; 183 183 184 + #ifdef __KVM_S390 185 + /* the processor status word for s390 */ 186 + __u64 psw_mask; /* psw upper half */ 187 + __u64 psw_addr; /* psw lower half */ 188 + #endif 184 189 union { 185 190 /* KVM_EXIT_UNKNOWN */ 186 191 struct { ··· 237 232 /* KVM_EXIT_S390_SIEIC */ 238 233 struct { 239 234 __u8 icptcode; 240 - __u64 mask; /* psw upper half */ 241 - __u64 addr; /* psw lower half */ 242 235 __u16 ipa; 243 236 __u32 ipb; 244 237 } s390_sieic; ··· 495 492 #ifdef __KVM_HAVE_VCPU_EVENTS 496 493 #define KVM_CAP_VCPU_EVENTS 41 497 494 #endif 495 + #define KVM_CAP_S390_PSW 42 498 496 499 497 #ifdef KVM_CAP_IRQ_ROUTING 500 498