diff options
author | Dominik Dingel <dingel@linux.vnet.ibm.com> | 2013-06-17 10:25:18 -0400 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2014-01-30 06:50:39 -0500 |
commit | 24eb3a824c4f3ccfaa2305dc1d9d9e2a708828c5 (patch) | |
tree | a889cb48f43502fb8db57d40ef6f342382d638b6 /arch/s390/kvm | |
parent | a91b8ebe8671980151e0a19ee9fec6b0e1ae1d58 (diff) |
KVM: s390: Add FAULT_FLAG_RETRY_NOWAIT for guest fault
In the case of a fault, we will retry to exit sie64 but with gmap fault
indication for this thread set. This makes it possible to handle async
page faults.
Based on a patch from Martin Schwidefsky.
Signed-off-by: Dominik Dingel <dingel@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 782420f3c4d5..9eec794caa7f 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -255,6 +255,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
255 | if (!kvm->arch.gmap) | 255 | if (!kvm->arch.gmap) |
256 | goto out_nogmap; | 256 | goto out_nogmap; |
257 | kvm->arch.gmap->private = kvm; | 257 | kvm->arch.gmap->private = kvm; |
258 | kvm->arch.gmap->pfault_enabled = 0; | ||
258 | } | 259 | } |
259 | 260 | ||
260 | kvm->arch.css_support = 0; | 261 | kvm->arch.css_support = 0; |
@@ -701,6 +702,17 @@ static int kvm_s390_handle_requests(struct kvm_vcpu *vcpu) | |||
701 | return 0; | 702 | return 0; |
702 | } | 703 | } |
703 | 704 | ||
705 | static long kvm_arch_fault_in_sync(struct kvm_vcpu *vcpu) | ||
706 | { | ||
707 | long rc; | ||
708 | hva_t fault = gmap_fault(current->thread.gmap_addr, vcpu->arch.gmap); | ||
709 | struct mm_struct *mm = current->mm; | ||
710 | down_read(&mm->mmap_sem); | ||
711 | rc = get_user_pages(current, mm, fault, 1, 1, 0, NULL, NULL); | ||
712 | up_read(&mm->mmap_sem); | ||
713 | return rc; | ||
714 | } | ||
715 | |||
704 | static int vcpu_pre_run(struct kvm_vcpu *vcpu) | 716 | static int vcpu_pre_run(struct kvm_vcpu *vcpu) |
705 | { | 717 | { |
706 | int rc, cpuflags; | 718 | int rc, cpuflags; |
@@ -730,7 +742,7 @@ static int vcpu_pre_run(struct kvm_vcpu *vcpu) | |||
730 | 742 | ||
731 | static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) | 743 | static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) |
732 | { | 744 | { |
733 | int rc; | 745 | int rc = -1; |
734 | 746 | ||
735 | VCPU_EVENT(vcpu, 6, "exit sie icptcode %d", | 747 | VCPU_EVENT(vcpu, 6, "exit sie icptcode %d", |
736 | vcpu->arch.sie_block->icptcode); | 748 | vcpu->arch.sie_block->icptcode); |
@@ -744,7 +756,14 @@ static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) | |||
744 | current->thread.gmap_addr; | 756 | current->thread.gmap_addr; |
745 | vcpu->run->s390_ucontrol.pgm_code = 0x10; | 757 | vcpu->run->s390_ucontrol.pgm_code = 0x10; |
746 | rc = -EREMOTE; | 758 | rc = -EREMOTE; |
747 | } else { | 759 | |
760 | } else if (current->thread.gmap_pfault) { | ||
761 | current->thread.gmap_pfault = 0; | ||
762 | if (kvm_arch_fault_in_sync(vcpu) >= 0) | ||
763 | rc = 0; | ||
764 | } | ||
765 | |||
766 | if (rc == -1) { | ||
748 | VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction"); | 767 | VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction"); |
749 | trace_kvm_s390_sie_fault(vcpu); | 768 | trace_kvm_s390_sie_fault(vcpu); |
750 | rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); | 769 | rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); |