aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/mmu.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2012-07-26 04:54:21 -0400
committerAvi Kivity <avi@redhat.com>2012-07-26 04:54:21 -0400
commite9bda6f6f902e6b55d9baceb5523468a048cbe56 (patch)
treebf09cc165da1197cd34967da0593d08b9a37c0f3 /arch/x86/kvm/mmu.c
parentbdc0077af574800d24318b6945cf2344e8dbb050 (diff)
parent06e48c510aa37f6e791602e6420422ea7071fe94 (diff)
Merge branch 'queue' into next
Merge patches queued during the run-up to the merge window. * queue: (25 commits) KVM: Choose better candidate for directed yield KVM: Note down when cpu relax intercepted or pause loop exited KVM: Add config to support ple or cpu relax optimzation KVM: switch to symbolic name for irq_states size KVM: x86: Fix typos in pmu.c KVM: x86: Fix typos in lapic.c KVM: x86: Fix typos in cpuid.c KVM: x86: Fix typos in emulate.c KVM: x86: Fix typos in x86.c KVM: SVM: Fix typos KVM: VMX: Fix typos KVM: remove the unused parameter of gfn_to_pfn_memslot KVM: remove is_error_hpa KVM: make bad_pfn static to kvm_main.c KVM: using get_fault_pfn to get the fault pfn KVM: MMU: track the refcount when unmap the page KVM: x86: remove unnecessary mark_page_dirty KVM: MMU: Avoid handling same rmap_pde in kvm_handle_hva_range() KVM: MMU: Push trace_kvm_age_page() into kvm_age_rmapp() KVM: MMU: Add memslot parameter to hva handlers ... Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/mmu.c')
-rw-r--r--arch/x86/kvm/mmu.c117
1 files changed, 78 insertions, 39 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 01ca00423938..241993443599 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -556,6 +556,14 @@ static int mmu_spte_clear_track_bits(u64 *sptep)
556 return 0; 556 return 0;
557 557
558 pfn = spte_to_pfn(old_spte); 558 pfn = spte_to_pfn(old_spte);
559
560 /*
561 * KVM does not hold the refcount of the page used by
562 * kvm mmu, before reclaiming the page, we should
563 * unmap it from mmu first.
564 */
565 WARN_ON(!kvm_is_mmio_pfn(pfn) && !page_count(pfn_to_page(pfn)));
566
559 if (!shadow_accessed_mask || old_spte & shadow_accessed_mask) 567 if (!shadow_accessed_mask || old_spte & shadow_accessed_mask)
560 kvm_set_pfn_accessed(pfn); 568 kvm_set_pfn_accessed(pfn);
561 if (!shadow_dirty_mask || (old_spte & shadow_dirty_mask)) 569 if (!shadow_dirty_mask || (old_spte & shadow_dirty_mask))
@@ -960,13 +968,13 @@ static void pte_list_walk(unsigned long *pte_list, pte_list_walk_fn fn)
960static unsigned long *__gfn_to_rmap(gfn_t gfn, int level, 968static unsigned long *__gfn_to_rmap(gfn_t gfn, int level,
961 struct kvm_memory_slot *slot) 969 struct kvm_memory_slot *slot)
962{ 970{
963 struct kvm_lpage_info *linfo; 971 unsigned long idx;
964 972
965 if (likely(level == PT_PAGE_TABLE_LEVEL)) 973 if (likely(level == PT_PAGE_TABLE_LEVEL))
966 return &slot->rmap[gfn - slot->base_gfn]; 974 return &slot->rmap[gfn - slot->base_gfn];
967 975
968 linfo = lpage_info_slot(gfn, slot, level); 976 idx = gfn_to_index(gfn, slot->base_gfn, level);
969 return &linfo->rmap_pde; 977 return &slot->arch.rmap_pde[level - PT_DIRECTORY_LEVEL][idx];
970} 978}
971 979
972/* 980/*
@@ -1200,7 +1208,7 @@ static bool rmap_write_protect(struct kvm *kvm, u64 gfn)
1200} 1208}
1201 1209
1202static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, 1210static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
1203 unsigned long data) 1211 struct kvm_memory_slot *slot, unsigned long data)
1204{ 1212{
1205 u64 *sptep; 1213 u64 *sptep;
1206 struct rmap_iterator iter; 1214 struct rmap_iterator iter;
@@ -1218,7 +1226,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
1218} 1226}
1219 1227
1220static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp, 1228static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp,
1221 unsigned long data) 1229 struct kvm_memory_slot *slot, unsigned long data)
1222{ 1230{
1223 u64 *sptep; 1231 u64 *sptep;
1224 struct rmap_iterator iter; 1232 struct rmap_iterator iter;
@@ -1259,43 +1267,67 @@ static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp,
1259 return 0; 1267 return 0;
1260} 1268}
1261 1269
1262static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, 1270static int kvm_handle_hva_range(struct kvm *kvm,
1263 unsigned long data, 1271 unsigned long start,
1264 int (*handler)(struct kvm *kvm, unsigned long *rmapp, 1272 unsigned long end,
1265 unsigned long data)) 1273 unsigned long data,
1274 int (*handler)(struct kvm *kvm,
1275 unsigned long *rmapp,
1276 struct kvm_memory_slot *slot,
1277 unsigned long data))
1266{ 1278{
1267 int j; 1279 int j;
1268 int ret; 1280 int ret = 0;
1269 int retval = 0;
1270 struct kvm_memslots *slots; 1281 struct kvm_memslots *slots;
1271 struct kvm_memory_slot *memslot; 1282 struct kvm_memory_slot *memslot;
1272 1283
1273 slots = kvm_memslots(kvm); 1284 slots = kvm_memslots(kvm);
1274 1285
1275 kvm_for_each_memslot(memslot, slots) { 1286 kvm_for_each_memslot(memslot, slots) {
1276 unsigned long start = memslot->userspace_addr; 1287 unsigned long hva_start, hva_end;
1277 unsigned long end; 1288 gfn_t gfn_start, gfn_end;
1278 1289
1279 end = start + (memslot->npages << PAGE_SHIFT); 1290 hva_start = max(start, memslot->userspace_addr);
1280 if (hva >= start && hva < end) { 1291 hva_end = min(end, memslot->userspace_addr +
1281 gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT; 1292 (memslot->npages << PAGE_SHIFT));
1282 gfn_t gfn = memslot->base_gfn + gfn_offset; 1293 if (hva_start >= hva_end)
1294 continue;
1295 /*
1296 * {gfn(page) | page intersects with [hva_start, hva_end)} =
1297 * {gfn_start, gfn_start+1, ..., gfn_end-1}.
1298 */
1299 gfn_start = hva_to_gfn_memslot(hva_start, memslot);
1300 gfn_end = hva_to_gfn_memslot(hva_end + PAGE_SIZE - 1, memslot);
1283 1301
1284 ret = handler(kvm, &memslot->rmap[gfn_offset], data); 1302 for (j = PT_PAGE_TABLE_LEVEL;
1303 j < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++j) {
1304 unsigned long idx, idx_end;
1305 unsigned long *rmapp;
1285 1306
1286 for (j = 0; j < KVM_NR_PAGE_SIZES - 1; ++j) { 1307 /*
1287 struct kvm_lpage_info *linfo; 1308 * {idx(page_j) | page_j intersects with
1309 * [hva_start, hva_end)} = {idx, idx+1, ..., idx_end}.
1310 */
1311 idx = gfn_to_index(gfn_start, memslot->base_gfn, j);
1312 idx_end = gfn_to_index(gfn_end - 1, memslot->base_gfn, j);
1288 1313
1289 linfo = lpage_info_slot(gfn, memslot, 1314 rmapp = __gfn_to_rmap(gfn_start, j, memslot);
1290 PT_DIRECTORY_LEVEL + j); 1315
1291 ret |= handler(kvm, &linfo->rmap_pde, data); 1316 for (; idx <= idx_end; ++idx)
1292 } 1317 ret |= handler(kvm, rmapp++, memslot, data);
1293 trace_kvm_age_page(hva, memslot, ret);
1294 retval |= ret;
1295 } 1318 }
1296 } 1319 }
1297 1320
1298 return retval; 1321 return ret;
1322}
1323
1324static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
1325 unsigned long data,
1326 int (*handler)(struct kvm *kvm, unsigned long *rmapp,
1327 struct kvm_memory_slot *slot,
1328 unsigned long data))
1329{
1330 return kvm_handle_hva_range(kvm, hva, hva + 1, data, handler);
1299} 1331}
1300 1332
1301int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) 1333int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
@@ -1303,13 +1335,18 @@ int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
1303 return kvm_handle_hva(kvm, hva, 0, kvm_unmap_rmapp); 1335 return kvm_handle_hva(kvm, hva, 0, kvm_unmap_rmapp);
1304} 1336}
1305 1337
1338int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end)
1339{
1340 return kvm_handle_hva_range(kvm, start, end, 0, kvm_unmap_rmapp);
1341}
1342
1306void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) 1343void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte)
1307{ 1344{
1308 kvm_handle_hva(kvm, hva, (unsigned long)&pte, kvm_set_pte_rmapp); 1345 kvm_handle_hva(kvm, hva, (unsigned long)&pte, kvm_set_pte_rmapp);
1309} 1346}
1310 1347
1311static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, 1348static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
1312 unsigned long data) 1349 struct kvm_memory_slot *slot, unsigned long data)
1313{ 1350{
1314 u64 *sptep; 1351 u64 *sptep;
1315 struct rmap_iterator uninitialized_var(iter); 1352 struct rmap_iterator uninitialized_var(iter);
@@ -1323,8 +1360,10 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
1323 * This has some overhead, but not as much as the cost of swapping 1360 * This has some overhead, but not as much as the cost of swapping
1324 * out actively used pages or breaking up actively used hugepages. 1361 * out actively used pages or breaking up actively used hugepages.
1325 */ 1362 */
1326 if (!shadow_accessed_mask) 1363 if (!shadow_accessed_mask) {
1327 return kvm_unmap_rmapp(kvm, rmapp, data); 1364 young = kvm_unmap_rmapp(kvm, rmapp, slot, data);
1365 goto out;
1366 }
1328 1367
1329 for (sptep = rmap_get_first(*rmapp, &iter); sptep; 1368 for (sptep = rmap_get_first(*rmapp, &iter); sptep;
1330 sptep = rmap_get_next(&iter)) { 1369 sptep = rmap_get_next(&iter)) {
@@ -1336,12 +1375,14 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
1336 (unsigned long *)sptep); 1375 (unsigned long *)sptep);
1337 } 1376 }
1338 } 1377 }
1339 1378out:
1379 /* @data has hva passed to kvm_age_hva(). */
1380 trace_kvm_age_page(data, slot, young);
1340 return young; 1381 return young;
1341} 1382}
1342 1383
1343static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp, 1384static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
1344 unsigned long data) 1385 struct kvm_memory_slot *slot, unsigned long data)
1345{ 1386{
1346 u64 *sptep; 1387 u64 *sptep;
1347 struct rmap_iterator iter; 1388 struct rmap_iterator iter;
@@ -1379,13 +1420,13 @@ static void rmap_recycle(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
1379 1420
1380 rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level); 1421 rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level);
1381 1422
1382 kvm_unmap_rmapp(vcpu->kvm, rmapp, 0); 1423 kvm_unmap_rmapp(vcpu->kvm, rmapp, NULL, 0);
1383 kvm_flush_remote_tlbs(vcpu->kvm); 1424 kvm_flush_remote_tlbs(vcpu->kvm);
1384} 1425}
1385 1426
1386int kvm_age_hva(struct kvm *kvm, unsigned long hva) 1427int kvm_age_hva(struct kvm *kvm, unsigned long hva)
1387{ 1428{
1388 return kvm_handle_hva(kvm, hva, 0, kvm_age_rmapp); 1429 return kvm_handle_hva(kvm, hva, hva, kvm_age_rmapp);
1389} 1430}
1390 1431
1391int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) 1432int kvm_test_age_hva(struct kvm *kvm, unsigned long hva)
@@ -2472,14 +2513,12 @@ static pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn,
2472 unsigned long hva; 2513 unsigned long hva;
2473 2514
2474 slot = gfn_to_memslot_dirty_bitmap(vcpu, gfn, no_dirty_log); 2515 slot = gfn_to_memslot_dirty_bitmap(vcpu, gfn, no_dirty_log);
2475 if (!slot) { 2516 if (!slot)
2476 get_page(fault_page); 2517 return get_fault_pfn();
2477 return page_to_pfn(fault_page);
2478 }
2479 2518
2480 hva = gfn_to_hva_memslot(slot, gfn); 2519 hva = gfn_to_hva_memslot(slot, gfn);
2481 2520
2482 return hva_to_pfn_atomic(vcpu->kvm, hva); 2521 return hva_to_pfn_atomic(hva);
2483} 2522}
2484 2523
2485static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu, 2524static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu,