diff options
author | Carsten Otte <carsteno@de.ibm.com> | 2009-11-19 08:21:16 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-12-03 02:32:25 -0500 |
commit | d7b0b5eb3000c6fb902f08c619fcd673a23d8fab (patch) | |
tree | 4c7aa92657435c687f98383aaea5ce15ee9fba9c | |
parent | 3cfc3092f40bc37c57ba556cfd8de4218f2135ab (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.h | 3 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 25 | ||||
-rw-r--r-- | include/linux/kvm.h | 8 |
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 */ |
19 | struct kvm_regs { | 20 | struct 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 | ||
118 | int kvm_dev_ioctl_check_extension(long ext) | 118 | int 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 | ||