diff options
| author | Dominik Dingel <dingel@linux.vnet.ibm.com> | 2013-07-26 09:04:00 -0400 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2013-07-29 03:02:18 -0400 |
| commit | 2b29a9fdcb92bfc6b6f4c412d71505869de61a56 (patch) | |
| tree | 81e5b700617fbc5d9663eb01118b0ef944c237d4 | |
| parent | 90db76e829479ef2ba1fed8f2552846015469831 (diff) | |
KVM: s390: move kvm_guest_enter,exit closer to sie
Any uaccess between guest_enter and guest_exit could trigger a page fault,
the page fault handler would handle it as a guest fault and translate a
user address as guest address.
Signed-off-by: Dominik Dingel <dingel@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
CC: stable@vger.kernel.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
| -rw-r--r-- | arch/s390/kvm/kvm-s390.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index ba694d2ba51e..34c1c9a90be2 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
| @@ -702,14 +702,25 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) | |||
| 702 | return rc; | 702 | return rc; |
| 703 | 703 | ||
| 704 | vcpu->arch.sie_block->icptcode = 0; | 704 | vcpu->arch.sie_block->icptcode = 0; |
| 705 | preempt_disable(); | ||
| 706 | kvm_guest_enter(); | ||
| 707 | preempt_enable(); | ||
| 708 | VCPU_EVENT(vcpu, 6, "entering sie flags %x", | 705 | VCPU_EVENT(vcpu, 6, "entering sie flags %x", |
| 709 | atomic_read(&vcpu->arch.sie_block->cpuflags)); | 706 | atomic_read(&vcpu->arch.sie_block->cpuflags)); |
| 710 | trace_kvm_s390_sie_enter(vcpu, | 707 | trace_kvm_s390_sie_enter(vcpu, |
| 711 | atomic_read(&vcpu->arch.sie_block->cpuflags)); | 708 | atomic_read(&vcpu->arch.sie_block->cpuflags)); |
| 709 | |||
| 710 | /* | ||
| 711 | * As PF_VCPU will be used in fault handler, between guest_enter | ||
| 712 | * and guest_exit should be no uaccess. | ||
| 713 | */ | ||
| 714 | preempt_disable(); | ||
| 715 | kvm_guest_enter(); | ||
| 716 | preempt_enable(); | ||
| 712 | rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs); | 717 | rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs); |
| 718 | kvm_guest_exit(); | ||
| 719 | |||
| 720 | VCPU_EVENT(vcpu, 6, "exit sie icptcode %d", | ||
| 721 | vcpu->arch.sie_block->icptcode); | ||
| 722 | trace_kvm_s390_sie_exit(vcpu, vcpu->arch.sie_block->icptcode); | ||
| 723 | |||
| 713 | if (rc > 0) | 724 | if (rc > 0) |
| 714 | rc = 0; | 725 | rc = 0; |
| 715 | if (rc < 0) { | 726 | if (rc < 0) { |
| @@ -721,10 +732,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) | |||
| 721 | rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); | 732 | rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); |
| 722 | } | 733 | } |
| 723 | } | 734 | } |
| 724 | VCPU_EVENT(vcpu, 6, "exit sie icptcode %d", | ||
| 725 | vcpu->arch.sie_block->icptcode); | ||
| 726 | trace_kvm_s390_sie_exit(vcpu, vcpu->arch.sie_block->icptcode); | ||
| 727 | kvm_guest_exit(); | ||
| 728 | 735 | ||
| 729 | memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16); | 736 | memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16); |
| 730 | return rc; | 737 | return rc; |
