aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm
diff options
context:
space:
mode:
authorDominik Dingel <dingel@linux.vnet.ibm.com>2013-06-17 10:25:18 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-01-30 06:50:39 -0500
commit24eb3a824c4f3ccfaa2305dc1d9d9e2a708828c5 (patch)
treea889cb48f43502fb8db57d40ef6f342382d638b6 /arch/s390/kvm
parenta91b8ebe8671980151e0a19ee9fec6b0e1ae1d58 (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.c23
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
705static 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
704static int vcpu_pre_run(struct kvm_vcpu *vcpu) 716static 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
731static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) 743static 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);