aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm
diff options
context:
space:
mode:
authorXiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>2012-08-20 23:00:49 -0400
committerAvi Kivity <avi@redhat.com>2012-08-22 08:08:55 -0400
commit12ce13fea925ab629f2281be2b9b01cf647a86cd (patch)
tree5e67a57d09c890017524017acc22c78bf8cf0548 /virt/kvm
parent2fc843117d64b31c20d36c6b625c0626c9a41a41 (diff)
KVM: use 'writable' as a hint to map writable pfn
In current code, we always map writable pfn for the read fault, in order to support readonly memslot, we map writable pfn only if 'writable' is not NULL Signed-off-by: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'virt/kvm')
-rw-r--r--virt/kvm/kvm_main.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index aa4a38ad9d9a..c89d1b5129e4 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1054,6 +1054,14 @@ static bool hva_to_pfn_fast(unsigned long addr, bool atomic, bool *async,
1054 if (!(async || atomic)) 1054 if (!(async || atomic))
1055 return false; 1055 return false;
1056 1056
1057 /*
1058 * Fast pin a writable pfn only if it is a write fault request
1059 * or the caller allows to map a writable pfn for a read fault
1060 * request.
1061 */
1062 if (!(write_fault || writable))
1063 return false;
1064
1057 npages = __get_user_pages_fast(addr, 1, 1, page); 1065 npages = __get_user_pages_fast(addr, 1, 1, page);
1058 if (npages == 1) { 1066 if (npages == 1) {
1059 *pfn = page_to_pfn(page[0]); 1067 *pfn = page_to_pfn(page[0]);
@@ -1093,7 +1101,7 @@ static int hva_to_pfn_slow(unsigned long addr, bool *async, bool write_fault,
1093 return npages; 1101 return npages;
1094 1102
1095 /* map read fault as writable if possible */ 1103 /* map read fault as writable if possible */
1096 if (unlikely(!write_fault)) { 1104 if (unlikely(!write_fault) && writable) {
1097 struct page *wpage[1]; 1105 struct page *wpage[1];
1098 1106
1099 npages = __get_user_pages_fast(addr, 1, 1, wpage); 1107 npages = __get_user_pages_fast(addr, 1, 1, wpage);
@@ -1109,6 +1117,20 @@ static int hva_to_pfn_slow(unsigned long addr, bool *async, bool write_fault,
1109 return npages; 1117 return npages;
1110} 1118}
1111 1119
1120/*
1121 * Pin guest page in memory and return its pfn.
1122 * @addr: host virtual address which maps memory to the guest
1123 * @atomic: whether this function can sleep
1124 * @async: whether this function need to wait IO complete if the
1125 * host page is not in the memory
1126 * @write_fault: whether we should get a writable host page
1127 * @writable: whether it allows to map a writable host page for !@write_fault
1128 *
1129 * The function will map a writable host page for these two cases:
1130 * 1): @write_fault = true
1131 * 2): @write_fault = false && @writable, @writable will tell the caller
1132 * whether the mapping is writable.
1133 */
1112static pfn_t hva_to_pfn(unsigned long addr, bool atomic, bool *async, 1134static pfn_t hva_to_pfn(unsigned long addr, bool atomic, bool *async,
1113 bool write_fault, bool *writable) 1135 bool write_fault, bool *writable)
1114{ 1136{