diff options
author | Christian Borntraeger <borntraeger@de.ibm.com> | 2011-09-20 11:07:28 -0400 |
---|---|---|
committer | Heiko Carstens <heiko.carstens@de.ibm.com> | 2011-09-20 11:07:34 -0400 |
commit | 480e5926ce3bb61ec229be2dab08bdce8abb8d2e (patch) | |
tree | b252230da3bba55a8e4ebd747767257c781670d7 /arch/s390/kvm/kvm-s390.c | |
parent | 9d037a777695993ec7437e5f451647dea7919d4c (diff) |
[S390] kvm: fix address mode switching
598841ca9919d008b520114d8a4378c4ce4e40a1 ([S390] use gmap address
spaces for kvm guest images) changed kvm to use a separate address
space for kvm guests. This address space was switched in __vcpu_run
In some cases (preemption, page fault) there is the possibility that
this address space switch is lost.
The typical symptom was a huge amount of validity intercepts or
random guest addressing exceptions.
Fix this by doing the switch in sie_loop and sie_exit and saving the
address space in the gmap structure itself. Also use the preempt
notifier.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Acked-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'arch/s390/kvm/kvm-s390.c')
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index f17296e4fc8..b4eced131e5 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -263,10 +263,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
263 | vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK; | 263 | vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK; |
264 | restore_fp_regs(&vcpu->arch.guest_fpregs); | 264 | restore_fp_regs(&vcpu->arch.guest_fpregs); |
265 | restore_access_regs(vcpu->arch.guest_acrs); | 265 | restore_access_regs(vcpu->arch.guest_acrs); |
266 | gmap_enable(vcpu->arch.gmap); | ||
266 | } | 267 | } |
267 | 268 | ||
268 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | 269 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) |
269 | { | 270 | { |
271 | gmap_disable(vcpu->arch.gmap); | ||
270 | save_fp_regs(&vcpu->arch.guest_fpregs); | 272 | save_fp_regs(&vcpu->arch.guest_fpregs); |
271 | save_access_regs(vcpu->arch.guest_acrs); | 273 | save_access_regs(vcpu->arch.guest_acrs); |
272 | restore_fp_regs(&vcpu->arch.host_fpregs); | 274 | restore_fp_regs(&vcpu->arch.host_fpregs); |
@@ -461,7 +463,6 @@ static void __vcpu_run(struct kvm_vcpu *vcpu) | |||
461 | local_irq_disable(); | 463 | local_irq_disable(); |
462 | kvm_guest_enter(); | 464 | kvm_guest_enter(); |
463 | local_irq_enable(); | 465 | local_irq_enable(); |
464 | gmap_enable(vcpu->arch.gmap); | ||
465 | VCPU_EVENT(vcpu, 6, "entering sie flags %x", | 466 | VCPU_EVENT(vcpu, 6, "entering sie flags %x", |
466 | atomic_read(&vcpu->arch.sie_block->cpuflags)); | 467 | atomic_read(&vcpu->arch.sie_block->cpuflags)); |
467 | if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) { | 468 | if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) { |
@@ -470,7 +471,6 @@ static void __vcpu_run(struct kvm_vcpu *vcpu) | |||
470 | } | 471 | } |
471 | VCPU_EVENT(vcpu, 6, "exit sie icptcode %d", | 472 | VCPU_EVENT(vcpu, 6, "exit sie icptcode %d", |
472 | vcpu->arch.sie_block->icptcode); | 473 | vcpu->arch.sie_block->icptcode); |
473 | gmap_disable(vcpu->arch.gmap); | ||
474 | local_irq_disable(); | 474 | local_irq_disable(); |
475 | kvm_guest_exit(); | 475 | kvm_guest_exit(); |
476 | local_irq_enable(); | 476 | local_irq_enable(); |