aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/mmu.c
diff options
context:
space:
mode:
authorIzik Eidus <izike@qumranet.com>2007-10-16 08:42:30 -0400
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:52:54 -0500
commit98348e9507ace5fda95432ff8ca23f13e7f66176 (patch)
tree14c63420c4af00a7956e7cfc8b1c8c07d5e79566 /drivers/kvm/mmu.c
parentb284be576471b1521dd04c0845beedb790cbb9d7 (diff)
KVM: MMU: Add rmap_next(), a helper for walking kvm rmaps
Signed-off-by: Izik Eidus <izike@qumranet.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/mmu.c')
-rw-r--r--drivers/kvm/mmu.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index f52604a7f9e8..14e54e331f50 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -456,28 +456,53 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
456 } 456 }
457} 457}
458 458
459static void rmap_write_protect(struct kvm *kvm, u64 gfn) 459static u64 *rmap_next(struct kvm *kvm, unsigned long *rmapp, u64 *spte)
460{ 460{
461 struct kvm_rmap_desc *desc; 461 struct kvm_rmap_desc *desc;
462 struct kvm_rmap_desc *prev_desc;
463 u64 *prev_spte;
464 int i;
465
466 if (!*rmapp)
467 return NULL;
468 else if (!(*rmapp & 1)) {
469 if (!spte)
470 return (u64 *)*rmapp;
471 return NULL;
472 }
473 desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
474 prev_desc = NULL;
475 prev_spte = NULL;
476 while (desc) {
477 for (i = 0; i < RMAP_EXT && desc->shadow_ptes[i]; ++i) {
478 if (prev_spte == spte)
479 return desc->shadow_ptes[i];
480 prev_spte = desc->shadow_ptes[i];
481 }
482 desc = desc->more;
483 }
484 return NULL;
485}
486
487static void rmap_write_protect(struct kvm *kvm, u64 gfn)
488{
462 unsigned long *rmapp; 489 unsigned long *rmapp;
463 u64 *spte; 490 u64 *spte;
491 u64 *prev_spte;
464 492
465 gfn = unalias_gfn(kvm, gfn); 493 gfn = unalias_gfn(kvm, gfn);
466 rmapp = gfn_to_rmap(kvm, gfn); 494 rmapp = gfn_to_rmap(kvm, gfn);
467 495
468 while (*rmapp) { 496 spte = rmap_next(kvm, rmapp, NULL);
469 if (!(*rmapp & 1)) 497 while (spte) {
470 spte = (u64 *)*rmapp;
471 else {
472 desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
473 spte = desc->shadow_ptes[0];
474 }
475 BUG_ON(!spte); 498 BUG_ON(!spte);
476 BUG_ON(!(*spte & PT_PRESENT_MASK)); 499 BUG_ON(!(*spte & PT_PRESENT_MASK));
477 BUG_ON(!(*spte & PT_WRITABLE_MASK)); 500 BUG_ON(!(*spte & PT_WRITABLE_MASK));
478 rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte); 501 rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte);
479 rmap_remove(kvm, spte); 502 prev_spte = spte;
480 set_shadow_pte(spte, *spte & ~PT_WRITABLE_MASK); 503 spte = rmap_next(kvm, rmapp, spte);
504 rmap_remove(kvm, prev_spte);
505 set_shadow_pte(prev_spte, *prev_spte & ~PT_WRITABLE_MASK);
481 kvm_flush_remote_tlbs(kvm); 506 kvm_flush_remote_tlbs(kvm);
482 } 507 }
483} 508}