aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/kvm_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r--virt/kvm/kvm_main.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index bf040c4e02b3..a9dd682cf5e3 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1058,12 +1058,18 @@ unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn)
1058EXPORT_SYMBOL_GPL(gfn_to_hva); 1058EXPORT_SYMBOL_GPL(gfn_to_hva);
1059 1059
1060/* 1060/*
1061 * The hva returned by this function is only allowed to be read. 1061 * If writable is set to false, the hva returned by this function is only
1062 * It should pair with kvm_read_hva() or kvm_read_hva_atomic(). 1062 * allowed to be read.
1063 */ 1063 */
1064static unsigned long gfn_to_hva_read(struct kvm *kvm, gfn_t gfn) 1064unsigned long gfn_to_hva_prot(struct kvm *kvm, gfn_t gfn, bool *writable)
1065{ 1065{
1066 return __gfn_to_hva_many(gfn_to_memslot(kvm, gfn), gfn, NULL, false); 1066 struct kvm_memory_slot *slot = gfn_to_memslot(kvm, gfn);
1067 unsigned long hva = __gfn_to_hva_many(slot, gfn, NULL, false);
1068
1069 if (!kvm_is_error_hva(hva) && writable)
1070 *writable = !memslot_is_readonly(slot);
1071
1072 return hva;
1067} 1073}
1068 1074
1069static int kvm_read_hva(void *data, void __user *hva, int len) 1075static int kvm_read_hva(void *data, void __user *hva, int len)
@@ -1430,7 +1436,7 @@ int kvm_read_guest_page(struct kvm *kvm, gfn_t gfn, void *data, int offset,
1430 int r; 1436 int r;
1431 unsigned long addr; 1437 unsigned long addr;
1432 1438
1433 addr = gfn_to_hva_read(kvm, gfn); 1439 addr = gfn_to_hva_prot(kvm, gfn, NULL);
1434 if (kvm_is_error_hva(addr)) 1440 if (kvm_is_error_hva(addr))
1435 return -EFAULT; 1441 return -EFAULT;
1436 r = kvm_read_hva(data, (void __user *)addr + offset, len); 1442 r = kvm_read_hva(data, (void __user *)addr + offset, len);
@@ -1468,7 +1474,7 @@ int kvm_read_guest_atomic(struct kvm *kvm, gpa_t gpa, void *data,
1468 gfn_t gfn = gpa >> PAGE_SHIFT; 1474 gfn_t gfn = gpa >> PAGE_SHIFT;
1469 int offset = offset_in_page(gpa); 1475 int offset = offset_in_page(gpa);
1470 1476
1471 addr = gfn_to_hva_read(kvm, gfn); 1477 addr = gfn_to_hva_prot(kvm, gfn, NULL);
1472 if (kvm_is_error_hva(addr)) 1478 if (kvm_is_error_hva(addr))
1473 return -EFAULT; 1479 return -EFAULT;
1474 pagefault_disable(); 1480 pagefault_disable();