diff options
author | Thomas Huth <thuth@linux.vnet.ibm.com> | 2014-05-06 11:20:16 -0400 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2014-05-16 08:57:20 -0400 |
commit | fa576c583d877d667d9acaed909a3dfc6b03e138 (patch) | |
tree | 05e28d47d9f33589ed9f96858c007d0235440dd8 /arch/s390 | |
parent | 684135e0962fce7946a89f50cf6c7ffa78a11b09 (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.c | 32 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.h | 1 |
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 | ||
1048 | static 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 | */ | ||
1058 | long 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 | ||
1059 | static void __kvm_inject_pfault_token(struct kvm_vcpu *vcpu, bool start_token, | 1074 | static 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); | |||
156 | int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu); | 156 | int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu); |
157 | 157 | ||
158 | /* implemented in kvm-s390.c */ | 158 | /* implemented in kvm-s390.c */ |
159 | long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable); | ||
159 | int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr); | 160 | int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr); |
160 | int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr); | 161 | int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr); |
161 | void kvm_s390_vcpu_start(struct kvm_vcpu *vcpu); | 162 | void kvm_s390_vcpu_start(struct kvm_vcpu *vcpu); |