aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/kvm-s390.c
diff options
context:
space:
mode:
authorChristian Borntraeger <borntraeger@de.ibm.com>2011-09-20 11:07:28 -0400
committerHeiko Carstens <heiko.carstens@de.ibm.com>2011-09-20 11:07:34 -0400
commit480e5926ce3bb61ec229be2dab08bdce8abb8d2e (patch)
treeb252230da3bba55a8e4ebd747767257c781670d7 /arch/s390/kvm/kvm-s390.c
parent9d037a777695993ec7437e5f451647dea7919d4c (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.c4
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
268void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) 269void 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();