aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorThomas Huth <thuth@linux.vnet.ibm.com>2014-05-06 11:20:16 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-05-16 08:57:20 -0400
commitfa576c583d877d667d9acaed909a3dfc6b03e138 (patch)
tree05e28d47d9f33589ed9f96858c007d0235440dd8 /arch/s390
parent684135e0962fce7946a89f50cf6c7ffa78a11b09 (diff)
KVM: s390: Introduce helper function for faulting-in a guest page
Rework the function kvm_arch_fault_in_sync() to become a proper helper function for faulting-in a guest page. Now it takes the guest address as a parameter and does not ignore the possible error code from gmap_fault() anymore (which could cause undetected error conditions before). Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com> Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/kvm/kvm-s390.c32
-rw-r--r--arch/s390/kvm/kvm-s390.h1
2 files changed, 26 insertions, 7 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 0a01744cbdd9..d91feb2f03ea 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -1045,15 +1045,30 @@ retry:
1045 return 0; 1045 return 0;
1046} 1046}
1047 1047
1048static long kvm_arch_fault_in_sync(struct kvm_vcpu *vcpu) 1048/**
1049 * kvm_arch_fault_in_page - fault-in guest page if necessary
1050 * @vcpu: The corresponding virtual cpu
1051 * @gpa: Guest physical address
1052 * @writable: Whether the page should be writable or not
1053 *
1054 * Make sure that a guest page has been faulted-in on the host.
1055 *
1056 * Return: Zero on success, negative error code otherwise.
1057 */
1058long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable)
1049{ 1059{
1050 long rc;
1051 hva_t fault = gmap_fault(current->thread.gmap_addr, vcpu->arch.gmap);
1052 struct mm_struct *mm = current->mm; 1060 struct mm_struct *mm = current->mm;
1061 hva_t hva;
1062 long rc;
1063
1064 hva = gmap_fault(gpa, vcpu->arch.gmap);
1065 if (IS_ERR_VALUE(hva))
1066 return (long)hva;
1053 down_read(&mm->mmap_sem); 1067 down_read(&mm->mmap_sem);
1054 rc = get_user_pages(current, mm, fault, 1, 1, 0, NULL, NULL); 1068 rc = get_user_pages(current, mm, hva, 1, writable, 0, NULL, NULL);
1055 up_read(&mm->mmap_sem); 1069 up_read(&mm->mmap_sem);
1056 return rc; 1070
1071 return rc < 0 ? rc : 0;
1057} 1072}
1058 1073
1059static void __kvm_inject_pfault_token(struct kvm_vcpu *vcpu, bool start_token, 1074static void __kvm_inject_pfault_token(struct kvm_vcpu *vcpu, bool start_token,
@@ -1191,9 +1206,12 @@ static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason)
1191 } else if (current->thread.gmap_pfault) { 1206 } else if (current->thread.gmap_pfault) {
1192 trace_kvm_s390_major_guest_pfault(vcpu); 1207 trace_kvm_s390_major_guest_pfault(vcpu);
1193 current->thread.gmap_pfault = 0; 1208 current->thread.gmap_pfault = 0;
1194 if (kvm_arch_setup_async_pf(vcpu) || 1209 if (kvm_arch_setup_async_pf(vcpu)) {
1195 (kvm_arch_fault_in_sync(vcpu) >= 0))
1196 rc = 0; 1210 rc = 0;
1211 } else {
1212 gpa_t gpa = current->thread.gmap_addr;
1213 rc = kvm_arch_fault_in_page(vcpu, gpa, 1);
1214 }
1197 } 1215 }
1198 1216
1199 if (rc == -1) { 1217 if (rc == -1) {
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index 38b589d69951..e489945921ac 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -156,6 +156,7 @@ int kvm_s390_handle_eb(struct kvm_vcpu *vcpu);
156int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu); 156int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);
157 157
158/* implemented in kvm-s390.c */ 158/* implemented in kvm-s390.c */
159long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable);
159int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr); 160int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr);
160int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr); 161int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr);
161void kvm_s390_vcpu_start(struct kvm_vcpu *vcpu); 162void kvm_s390_vcpu_start(struct kvm_vcpu *vcpu);