提交 eb45fda4 编写于 作者: M Marcelo Tosatti

KVM: MMU: fix rmap_remove on non present sptes

drop_spte should not attempt to rmap_remove a non present shadow pte.

This fixes a BUG_ON seen on kvm-autotest.
Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
Reported-by: NLucas Meneghel Rodrigues <lmr@redhat.com>
Signed-off-by: NAvi Kivity <avi@redhat.com>
上级 edde99ce
...@@ -720,7 +720,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte) ...@@ -720,7 +720,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
} }
} }
static void set_spte_track_bits(u64 *sptep, u64 new_spte) static int set_spte_track_bits(u64 *sptep, u64 new_spte)
{ {
pfn_t pfn; pfn_t pfn;
u64 old_spte = *sptep; u64 old_spte = *sptep;
...@@ -731,19 +731,20 @@ static void set_spte_track_bits(u64 *sptep, u64 new_spte) ...@@ -731,19 +731,20 @@ static void set_spte_track_bits(u64 *sptep, u64 new_spte)
old_spte = __xchg_spte(sptep, new_spte); old_spte = __xchg_spte(sptep, new_spte);
if (!is_rmap_spte(old_spte)) if (!is_rmap_spte(old_spte))
return; return 0;
pfn = spte_to_pfn(old_spte); pfn = spte_to_pfn(old_spte);
if (!shadow_accessed_mask || old_spte & shadow_accessed_mask) if (!shadow_accessed_mask || old_spte & shadow_accessed_mask)
kvm_set_pfn_accessed(pfn); kvm_set_pfn_accessed(pfn);
if (!shadow_dirty_mask || (old_spte & shadow_dirty_mask)) if (!shadow_dirty_mask || (old_spte & shadow_dirty_mask))
kvm_set_pfn_dirty(pfn); kvm_set_pfn_dirty(pfn);
return 1;
} }
static void drop_spte(struct kvm *kvm, u64 *sptep, u64 new_spte) static void drop_spte(struct kvm *kvm, u64 *sptep, u64 new_spte)
{ {
set_spte_track_bits(sptep, new_spte); if (set_spte_track_bits(sptep, new_spte))
rmap_remove(kvm, sptep); rmap_remove(kvm, sptep);
} }
static u64 *rmap_next(struct kvm *kvm, unsigned long *rmapp, u64 *spte) static u64 *rmap_next(struct kvm *kvm, unsigned long *rmapp, u64 *spte)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册