aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarsten Otte <carsteno@de.ibm.com>2009-11-19 08:21:16 -0500
committerAvi Kivity <avi@redhat.com>2009-12-03 02:32:25 -0500
commitd7b0b5eb3000c6fb902f08c619fcd673a23d8fab (patch)
tree4c7aa92657435c687f98383aaea5ce15ee9fba9c
parent3cfc3092f40bc37c57ba556cfd8de4218f2135ab (diff)
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>
-rw-r--r--arch/s390/include/asm/kvm.h3
-rw-r--r--arch/s390/kvm/kvm-s390.c25
-rw-r--r--include/linux/kvm.h8
3 files changed, 25 insertions, 11 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 @@
1#ifndef __LINUX_KVM_S390_H 1#ifndef __LINUX_KVM_S390_H
2#define __LINUX_KVM_S390_H 2#define __LINUX_KVM_S390_H
3
4/* 3/*
5 * asm-s390/kvm.h - KVM s390 specific structures and definitions 4 * asm-s390/kvm.h - KVM s390 specific structures and definitions
6 * 5 *
@@ -15,6 +14,8 @@
15 */ 14 */
16#include <linux/types.h> 15#include <linux/types.h>
17 16
17#define __KVM_S390
18
18/* for KVM_GET_REGS and KVM_SET_REGS */ 19/* for KVM_GET_REGS and KVM_SET_REGS */
19struct kvm_regs { 20struct kvm_regs {
20 /* general purpose regs for s390 */ 21 /* general purpose regs for s390 */
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 544505893c9f..f8bcaefd7d34 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -117,10 +117,16 @@ long kvm_arch_dev_ioctl(struct file *filp,
117 117
118int kvm_dev_ioctl_check_extension(long ext) 118int kvm_dev_ioctl_check_extension(long ext)
119{ 119{
120 int r;
121
120 switch (ext) { 122 switch (ext) {
123 case KVM_CAP_S390_PSW:
124 r = 1;
125 break;
121 default: 126 default:
122 return 0; 127 r = 0;
123 } 128 }
129 return r;
124} 130}
125 131
126/* Section: vm related */ 132/* Section: vm related */
@@ -420,8 +426,10 @@ static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
420 vcpu_load(vcpu); 426 vcpu_load(vcpu);
421 if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING) 427 if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
422 rc = -EBUSY; 428 rc = -EBUSY;
423 else 429 else {
424 vcpu->arch.sie_block->gpsw = psw; 430 vcpu->run->psw_mask = psw.mask;
431 vcpu->run->psw_addr = psw.addr;
432 }
425 vcpu_put(vcpu); 433 vcpu_put(vcpu);
426 return rc; 434 return rc;
427} 435}
@@ -509,9 +517,6 @@ rerun_vcpu:
509 517
510 switch (kvm_run->exit_reason) { 518 switch (kvm_run->exit_reason) {
511 case KVM_EXIT_S390_SIEIC: 519 case KVM_EXIT_S390_SIEIC:
512 vcpu->arch.sie_block->gpsw.mask = kvm_run->s390_sieic.mask;
513 vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr;
514 break;
515 case KVM_EXIT_UNKNOWN: 520 case KVM_EXIT_UNKNOWN:
516 case KVM_EXIT_INTR: 521 case KVM_EXIT_INTR:
517 case KVM_EXIT_S390_RESET: 522 case KVM_EXIT_S390_RESET:
@@ -520,6 +525,9 @@ rerun_vcpu:
520 BUG(); 525 BUG();
521 } 526 }
522 527
528 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
529 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
530
523 might_fault(); 531 might_fault();
524 532
525 do { 533 do {
@@ -539,8 +547,6 @@ rerun_vcpu:
539 /* intercept cannot be handled in-kernel, prepare kvm-run */ 547 /* intercept cannot be handled in-kernel, prepare kvm-run */
540 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC; 548 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
541 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode; 549 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
542 kvm_run->s390_sieic.mask = vcpu->arch.sie_block->gpsw.mask;
543 kvm_run->s390_sieic.addr = vcpu->arch.sie_block->gpsw.addr;
544 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa; 550 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
545 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb; 551 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
546 rc = 0; 552 rc = 0;
@@ -552,6 +558,9 @@ rerun_vcpu:
552 rc = 0; 558 rc = 0;
553 } 559 }
554 560
561 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
562 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
563
555 if (vcpu->sigset_active) 564 if (vcpu->sigset_active)
556 sigprocmask(SIG_SETMASK, &sigsaved, NULL); 565 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
557 566
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 92045a92d714..2d241da07236 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -181,6 +181,11 @@ struct kvm_run {
181 __u64 cr8; 181 __u64 cr8;
182 __u64 apic_base; 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 union { 189 union {
185 /* KVM_EXIT_UNKNOWN */ 190 /* KVM_EXIT_UNKNOWN */
186 struct { 191 struct {
@@ -232,8 +237,6 @@ struct kvm_run {
232 /* KVM_EXIT_S390_SIEIC */ 237 /* KVM_EXIT_S390_SIEIC */
233 struct { 238 struct {
234 __u8 icptcode; 239 __u8 icptcode;
235 __u64 mask; /* psw upper half */
236 __u64 addr; /* psw lower half */
237 __u16 ipa; 240 __u16 ipa;
238 __u32 ipb; 241 __u32 ipb;
239 } s390_sieic; 242 } s390_sieic;
@@ -492,6 +495,7 @@ struct kvm_ioeventfd {
492#ifdef __KVM_HAVE_VCPU_EVENTS 495#ifdef __KVM_HAVE_VCPU_EVENTS
493#define KVM_CAP_VCPU_EVENTS 41 496#define KVM_CAP_VCPU_EVENTS 41
494#endif 497#endif
498#define KVM_CAP_S390_PSW 42
495 499
496#ifdef KVM_CAP_IRQ_ROUTING 500#ifdef KVM_CAP_IRQ_ROUTING
497 501