diff options
| -rw-r--r-- | arch/x86/kvm/mmu.c | 37 | ||||
| -rw-r--r-- | include/trace/events/kvm.h | 16 |
2 files changed, 33 insertions, 20 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index bdd1acbab84d..47d534066325 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
| @@ -1262,7 +1262,8 @@ static bool rmap_write_protect(struct kvm *kvm, u64 gfn) | |||
| 1262 | } | 1262 | } |
| 1263 | 1263 | ||
| 1264 | static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, | 1264 | static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, |
| 1265 | struct kvm_memory_slot *slot, unsigned long data) | 1265 | struct kvm_memory_slot *slot, gfn_t gfn, int level, |
| 1266 | unsigned long data) | ||
| 1266 | { | 1267 | { |
| 1267 | u64 *sptep; | 1268 | u64 *sptep; |
| 1268 | struct rmap_iterator iter; | 1269 | struct rmap_iterator iter; |
| @@ -1270,7 +1271,8 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
| 1270 | 1271 | ||
| 1271 | while ((sptep = rmap_get_first(*rmapp, &iter))) { | 1272 | while ((sptep = rmap_get_first(*rmapp, &iter))) { |
| 1272 | BUG_ON(!(*sptep & PT_PRESENT_MASK)); | 1273 | BUG_ON(!(*sptep & PT_PRESENT_MASK)); |
| 1273 | rmap_printk("kvm_rmap_unmap_hva: spte %p %llx\n", sptep, *sptep); | 1274 | rmap_printk("kvm_rmap_unmap_hva: spte %p %llx gfn %llx (%d)\n", |
| 1275 | sptep, *sptep, gfn, level); | ||
| 1274 | 1276 | ||
| 1275 | drop_spte(kvm, sptep); | 1277 | drop_spte(kvm, sptep); |
| 1276 | need_tlb_flush = 1; | 1278 | need_tlb_flush = 1; |
| @@ -1280,7 +1282,8 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
| 1280 | } | 1282 | } |
| 1281 | 1283 | ||
| 1282 | static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp, | 1284 | static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp, |
| 1283 | struct kvm_memory_slot *slot, unsigned long data) | 1285 | struct kvm_memory_slot *slot, gfn_t gfn, int level, |
| 1286 | unsigned long data) | ||
| 1284 | { | 1287 | { |
| 1285 | u64 *sptep; | 1288 | u64 *sptep; |
| 1286 | struct rmap_iterator iter; | 1289 | struct rmap_iterator iter; |
| @@ -1294,7 +1297,8 @@ static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
| 1294 | 1297 | ||
| 1295 | for (sptep = rmap_get_first(*rmapp, &iter); sptep;) { | 1298 | for (sptep = rmap_get_first(*rmapp, &iter); sptep;) { |
| 1296 | BUG_ON(!is_shadow_present_pte(*sptep)); | 1299 | BUG_ON(!is_shadow_present_pte(*sptep)); |
| 1297 | rmap_printk("kvm_set_pte_rmapp: spte %p %llx\n", sptep, *sptep); | 1300 | rmap_printk("kvm_set_pte_rmapp: spte %p %llx gfn %llx (%d)\n", |
| 1301 | sptep, *sptep, gfn, level); | ||
| 1298 | 1302 | ||
| 1299 | need_flush = 1; | 1303 | need_flush = 1; |
| 1300 | 1304 | ||
| @@ -1328,6 +1332,8 @@ static int kvm_handle_hva_range(struct kvm *kvm, | |||
| 1328 | int (*handler)(struct kvm *kvm, | 1332 | int (*handler)(struct kvm *kvm, |
| 1329 | unsigned long *rmapp, | 1333 | unsigned long *rmapp, |
| 1330 | struct kvm_memory_slot *slot, | 1334 | struct kvm_memory_slot *slot, |
| 1335 | gfn_t gfn, | ||
| 1336 | int level, | ||
| 1331 | unsigned long data)) | 1337 | unsigned long data)) |
| 1332 | { | 1338 | { |
| 1333 | int j; | 1339 | int j; |
| @@ -1357,6 +1363,7 @@ static int kvm_handle_hva_range(struct kvm *kvm, | |||
| 1357 | j < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++j) { | 1363 | j < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++j) { |
| 1358 | unsigned long idx, idx_end; | 1364 | unsigned long idx, idx_end; |
| 1359 | unsigned long *rmapp; | 1365 | unsigned long *rmapp; |
| 1366 | gfn_t gfn = gfn_start; | ||
| 1360 | 1367 | ||
| 1361 | /* | 1368 | /* |
| 1362 | * {idx(page_j) | page_j intersects with | 1369 | * {idx(page_j) | page_j intersects with |
| @@ -1367,8 +1374,10 @@ static int kvm_handle_hva_range(struct kvm *kvm, | |||
| 1367 | 1374 | ||
| 1368 | rmapp = __gfn_to_rmap(gfn_start, j, memslot); | 1375 | rmapp = __gfn_to_rmap(gfn_start, j, memslot); |
| 1369 | 1376 | ||
| 1370 | for (; idx <= idx_end; ++idx) | 1377 | for (; idx <= idx_end; |
| 1371 | ret |= handler(kvm, rmapp++, memslot, data); | 1378 | ++idx, gfn += (1UL << KVM_HPAGE_GFN_SHIFT(j))) |
| 1379 | ret |= handler(kvm, rmapp++, memslot, | ||
| 1380 | gfn, j, data); | ||
| 1372 | } | 1381 | } |
| 1373 | } | 1382 | } |
| 1374 | 1383 | ||
| @@ -1379,6 +1388,7 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, | |||
| 1379 | unsigned long data, | 1388 | unsigned long data, |
| 1380 | int (*handler)(struct kvm *kvm, unsigned long *rmapp, | 1389 | int (*handler)(struct kvm *kvm, unsigned long *rmapp, |
| 1381 | struct kvm_memory_slot *slot, | 1390 | struct kvm_memory_slot *slot, |
| 1391 | gfn_t gfn, int level, | ||
| 1382 | unsigned long data)) | 1392 | unsigned long data)) |
| 1383 | { | 1393 | { |
| 1384 | return kvm_handle_hva_range(kvm, hva, hva + 1, data, handler); | 1394 | return kvm_handle_hva_range(kvm, hva, hva + 1, data, handler); |
| @@ -1400,7 +1410,8 @@ void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) | |||
| 1400 | } | 1410 | } |
| 1401 | 1411 | ||
| 1402 | static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | 1412 | static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, |
| 1403 | struct kvm_memory_slot *slot, unsigned long data) | 1413 | struct kvm_memory_slot *slot, gfn_t gfn, int level, |
| 1414 | unsigned long data) | ||
| 1404 | { | 1415 | { |
| 1405 | u64 *sptep; | 1416 | u64 *sptep; |
| 1406 | struct rmap_iterator uninitialized_var(iter); | 1417 | struct rmap_iterator uninitialized_var(iter); |
| @@ -1415,7 +1426,7 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
| 1415 | * out actively used pages or breaking up actively used hugepages. | 1426 | * out actively used pages or breaking up actively used hugepages. |
| 1416 | */ | 1427 | */ |
| 1417 | if (!shadow_accessed_mask) { | 1428 | if (!shadow_accessed_mask) { |
| 1418 | young = kvm_unmap_rmapp(kvm, rmapp, slot, data); | 1429 | young = kvm_unmap_rmapp(kvm, rmapp, slot, gfn, level, data); |
| 1419 | goto out; | 1430 | goto out; |
| 1420 | } | 1431 | } |
| 1421 | 1432 | ||
| @@ -1430,13 +1441,13 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | |||
| 1430 | } | 1441 | } |
| 1431 | } | 1442 | } |
| 1432 | out: | 1443 | out: |
| 1433 | /* @data has hva passed to kvm_age_hva(). */ | 1444 | trace_kvm_age_page(gfn, level, slot, young); |
| 1434 | trace_kvm_age_page(data, slot, young); | ||
| 1435 | return young; | 1445 | return young; |
| 1436 | } | 1446 | } |
| 1437 | 1447 | ||
| 1438 | static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp, | 1448 | static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp, |
| 1439 | struct kvm_memory_slot *slot, unsigned long data) | 1449 | struct kvm_memory_slot *slot, gfn_t gfn, |
| 1450 | int level, unsigned long data) | ||
| 1440 | { | 1451 | { |
| 1441 | u64 *sptep; | 1452 | u64 *sptep; |
| 1442 | struct rmap_iterator iter; | 1453 | struct rmap_iterator iter; |
| @@ -1474,13 +1485,13 @@ static void rmap_recycle(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn) | |||
| 1474 | 1485 | ||
| 1475 | rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level); | 1486 | rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level); |
| 1476 | 1487 | ||
| 1477 | kvm_unmap_rmapp(vcpu->kvm, rmapp, NULL, 0); | 1488 | kvm_unmap_rmapp(vcpu->kvm, rmapp, NULL, gfn, sp->role.level, 0); |
| 1478 | kvm_flush_remote_tlbs(vcpu->kvm); | 1489 | kvm_flush_remote_tlbs(vcpu->kvm); |
| 1479 | } | 1490 | } |
| 1480 | 1491 | ||
| 1481 | int kvm_age_hva(struct kvm *kvm, unsigned long hva) | 1492 | int kvm_age_hva(struct kvm *kvm, unsigned long hva) |
| 1482 | { | 1493 | { |
| 1483 | return kvm_handle_hva(kvm, hva, hva, kvm_age_rmapp); | 1494 | return kvm_handle_hva(kvm, hva, 0, kvm_age_rmapp); |
| 1484 | } | 1495 | } |
| 1485 | 1496 | ||
| 1486 | int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) | 1497 | int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) |
diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h index ab679c395042..6edf1f2028cd 100644 --- a/include/trace/events/kvm.h +++ b/include/trace/events/kvm.h | |||
| @@ -225,24 +225,26 @@ TRACE_EVENT(kvm_fpu, | |||
| 225 | ); | 225 | ); |
| 226 | 226 | ||
| 227 | TRACE_EVENT(kvm_age_page, | 227 | TRACE_EVENT(kvm_age_page, |
| 228 | TP_PROTO(ulong hva, struct kvm_memory_slot *slot, int ref), | 228 | TP_PROTO(ulong gfn, int level, struct kvm_memory_slot *slot, int ref), |
| 229 | TP_ARGS(hva, slot, ref), | 229 | TP_ARGS(gfn, level, slot, ref), |
| 230 | 230 | ||
| 231 | TP_STRUCT__entry( | 231 | TP_STRUCT__entry( |
| 232 | __field( u64, hva ) | 232 | __field( u64, hva ) |
| 233 | __field( u64, gfn ) | 233 | __field( u64, gfn ) |
| 234 | __field( u8, level ) | ||
| 234 | __field( u8, referenced ) | 235 | __field( u8, referenced ) |
| 235 | ), | 236 | ), |
| 236 | 237 | ||
| 237 | TP_fast_assign( | 238 | TP_fast_assign( |
| 238 | __entry->hva = hva; | 239 | __entry->gfn = gfn; |
| 239 | __entry->gfn = | 240 | __entry->level = level; |
| 240 | slot->base_gfn + ((hva - slot->userspace_addr) >> PAGE_SHIFT); | 241 | __entry->hva = ((gfn - slot->base_gfn) << |
| 242 | PAGE_SHIFT) + slot->userspace_addr; | ||
| 241 | __entry->referenced = ref; | 243 | __entry->referenced = ref; |
| 242 | ), | 244 | ), |
| 243 | 245 | ||
| 244 | TP_printk("hva %llx gfn %llx %s", | 246 | TP_printk("hva %llx gfn %llx level %u %s", |
| 245 | __entry-&g | ||
