Skip to content

Commit a6a0b05

Browse files
Ben Gardonbonzini
authored andcommitted
kvm: x86/mmu: Support dirty logging for the TDP MMU
Dirty logging is a key feature of the KVM MMU and must be supported by the TDP MMU. Add support for both the write protection and PML dirty logging modes. Tested by running kvm-unit-tests and KVM selftests on an Intel Haswell machine. This series introduced no new failures. This series can be viewed in Gerrit at: https://linux-review.googlesource.com/c/virt/kvm/kvm/+/2538 Signed-off-by: Ben Gardon <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 1d8dd6b commit a6a0b05

File tree

6 files changed

+328
-9
lines changed

6 files changed

+328
-9
lines changed

arch/x86/kvm/mmu/mmu.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,6 +1223,9 @@ static void kvm_mmu_write_protect_pt_masked(struct kvm *kvm,
12231223
{
12241224
struct kvm_rmap_head *rmap_head;
12251225

1226+
if (kvm->arch.tdp_mmu_enabled)
1227+
kvm_tdp_mmu_clear_dirty_pt_masked(kvm, slot,
1228+
slot->base_gfn + gfn_offset, mask, true);
12261229
while (mask) {
12271230
rmap_head = __gfn_to_rmap(slot->base_gfn + gfn_offset + __ffs(mask),
12281231
PG_LEVEL_4K, slot);
@@ -1249,6 +1252,9 @@ void kvm_mmu_clear_dirty_pt_masked(struct kvm *kvm,
12491252
{
12501253
struct kvm_rmap_head *rmap_head;
12511254

1255+
if (kvm->arch.tdp_mmu_enabled)
1256+
kvm_tdp_mmu_clear_dirty_pt_masked(kvm, slot,
1257+
slot->base_gfn + gfn_offset, mask, false);
12521258
while (mask) {
12531259
rmap_head = __gfn_to_rmap(slot->base_gfn + gfn_offset + __ffs(mask),
12541260
PG_LEVEL_4K, slot);
@@ -5473,6 +5479,8 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm,
54735479
spin_lock(&kvm->mmu_lock);
54745480
flush = slot_handle_level(kvm, memslot, slot_rmap_write_protect,
54755481
start_level, KVM_MAX_HUGEPAGE_LEVEL, false);
5482+
if (kvm->arch.tdp_mmu_enabled)
5483+
flush |= kvm_tdp_mmu_wrprot_slot(kvm, memslot, PG_LEVEL_4K);
54765484
spin_unlock(&kvm->mmu_lock);
54775485

54785486
/*
@@ -5561,6 +5569,8 @@ void kvm_mmu_slot_leaf_clear_dirty(struct kvm *kvm,
55615569

55625570
spin_lock(&kvm->mmu_lock);
55635571
flush = slot_handle_leaf(kvm, memslot, __rmap_clear_dirty, false);
5572+
if (kvm->arch.tdp_mmu_enabled)
5573+
flush |= kvm_tdp_mmu_clear_dirty_slot(kvm, memslot);
55645574
spin_unlock(&kvm->mmu_lock);
55655575

55665576
/*
@@ -5582,6 +5592,8 @@ void kvm_mmu_slot_largepage_remove_write_access(struct kvm *kvm,
55825592
spin_lock(&kvm->mmu_lock);
55835593
flush = slot_handle_large_level(kvm, memslot, slot_rmap_write_protect,
55845594
false);
5595+
if (kvm->arch.tdp_mmu_enabled)
5596+
flush |= kvm_tdp_mmu_wrprot_slot(kvm, memslot, PG_LEVEL_2M);
55855597
spin_unlock(&kvm->mmu_lock);
55865598

55875599
if (flush)
@@ -5596,6 +5608,8 @@ void kvm_mmu_slot_set_dirty(struct kvm *kvm,
55965608

55975609
spin_lock(&kvm->mmu_lock);
55985610
flush = slot_handle_all_level(kvm, memslot, __rmap_set_dirty, false);
5611+
if (kvm->arch.tdp_mmu_enabled)
5612+
flush |= kvm_tdp_mmu_slot_set_dirty(kvm, memslot);
55995613
spin_unlock(&kvm->mmu_lock);
56005614

56015615
if (flush)

arch/x86/kvm/mmu/tdp_iter.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,14 @@ struct tdp_iter {
4141
* Iterates over every SPTE mapping the GFN range [start, end) in a
4242
* preorder traversal.
4343
*/
44-
#define for_each_tdp_pte(iter, root, root_level, start, end) \
45-
for (tdp_iter_start(&iter, root, root_level, PG_LEVEL_4K, start); \
44+
#define for_each_tdp_pte_min_level(iter, root, root_level, min_level, start, end) \
45+
for (tdp_iter_start(&iter, root, root_level, min_level, start); \
4646
iter.valid && iter.gfn < end; \
4747
tdp_iter_next(&iter))
4848

49+
#define for_each_tdp_pte(iter, root, root_level, start, end) \
50+
for_each_tdp_pte_min_level(iter, root, root_level, PG_LEVEL_4K, start, end)
51+
4952
u64 *spte_to_child_pt(u64 pte, int level);
5053

5154
void tdp_iter_start(struct tdp_iter *iter, u64 *root_pt, int root_level,

0 commit comments

Comments
 (0)