aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorXiao Guangrong <xiaoguangrong@cn.fujitsu.com>2010-08-30 06:25:03 -0400
committerAvi Kivity <avi@redhat.com>2010-10-24 04:51:57 -0400
commit49edf87806f52a005152beaed9f4731862efc8fe (patch)
tree5644102bac68fdb28266d2961a2763f872443ee7 /arch
parent2f4f337248cd5660040b7e09b7287a7a0a861f3f (diff)
KVM: MMU: improve active sp audit
Both audit_rmap() and audit_write_protection() need to walk all active sp, so we can do these checking in a sp walking Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/mmu_audit.c74
1 files changed, 38 insertions, 36 deletions
diff --git a/arch/x86/kvm/mmu_audit.c b/arch/x86/kvm/mmu_audit.c
index fb8a461333c5..8becb86cd348 100644
--- a/arch/x86/kvm/mmu_audit.c
+++ b/arch/x86/kvm/mmu_audit.c
@@ -65,6 +65,16 @@ static void mmu_spte_walk(struct kvm_vcpu *vcpu, inspect_spte_fn fn)
65 return; 65 return;
66} 66}
67 67
68typedef void (*sp_handler) (struct kvm *kvm, struct kvm_mmu_page *sp);
69
70static void walk_all_active_sps(struct kvm *kvm, sp_handler fn)
71{
72 struct kvm_mmu_page *sp;
73
74 list_for_each_entry(sp, &kvm->arch.active_mmu_pages, link)
75 fn(kvm, sp);
76}
77
68static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte, 78static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte,
69 gva_t va, int level) 79 gva_t va, int level)
70{ 80{
@@ -175,67 +185,59 @@ void audit_sptes_have_rmaps(struct kvm_vcpu *vcpu)
175 mmu_spte_walk(vcpu, inspect_spte_has_rmap); 185 mmu_spte_walk(vcpu, inspect_spte_has_rmap);
176} 186}
177 187
178static void check_mappings_rmap(struct kvm_vcpu *vcpu) 188static void check_mappings_rmap(struct kvm *kvm, struct kvm_mmu_page *sp)
179{ 189{
180 struct kvm_mmu_page *sp;
181 int i; 190 int i;
182 191
183 list_for_each_entry(sp, &vcpu->kvm->arch.active_mmu_pages, link) { 192 if (sp->role.level != PT_PAGE_TABLE_LEVEL)
184 u64 *pt = sp->spt; 193 return;
185 194
186 if (sp->role.level != PT_PAGE_TABLE_LEVEL) 195 for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
196 if (!is_rmap_spte(sp->spt[i]))
187 continue; 197 continue;
188 198
189 for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { 199 inspect_spte_has_rmap(kvm, sp->spt + i);
190 if (!is_rmap_spte(pt[i]))
191 continue;
192
193 inspect_spte_has_rmap(vcpu->kvm, &pt[i]);
194 }
195 } 200 }
196 return;
197} 201}
198 202
199static void audit_rmap(struct kvm_vcpu *vcpu) 203void audit_write_protection(struct kvm *kvm, struct kvm_mmu_page *sp)
200{ 204{
201 check_mappings_rmap(vcpu);
202}
203
204static void audit_write_protection(struct kvm_vcpu *vcpu)
205{
206 struct kvm_mmu_page *sp;
207 struct kvm_memory_slot *slot; 205 struct kvm_memory_slot *slot;
208 unsigned long *rmapp; 206 unsigned long *rmapp;
209 u64 *spte; 207 u64 *spte;
210 208
211 list_for_each_entry(sp, &vcpu->kvm->arch.active_mmu_pages, link) { 209 if (sp->role.direct || sp->unsync || sp->role.invalid)
212 if (sp->role.direct) 210 return;
213 continue;
214 if (sp->unsync)
215 continue;
216 if (sp->role.invalid)
217 continue;
218 211
219 slot = gfn_to_memslot(vcpu->kvm, sp->gfn); 212 slot = gfn_to_memslot(kvm, sp->gfn);
220 rmapp = &slot->rmap[sp->gfn - slot->base_gfn]; 213 rmapp = &slot->rmap[sp->gfn - slot->base_gfn];
221 214
222 spte = rmap_next(vcpu->kvm, rmapp, NULL); 215 spte = rmap_next(kvm, rmapp, NULL);
223 while (spte) { 216 while (spte) {
224 if (is_writable_pte(*spte)) 217 if (is_writable_pte(*spte))
225 printk(KERN_ERR "%s: (%s) shadow page has " 218 printk(KERN_ERR "%s: (%s) shadow page has "
226 "writable mappings: gfn %llx role %x\n", 219 "writable mappings: gfn %llx role %x\n",
227 __func__, audit_msg, sp->gfn, 220 __func__, audit_msg, sp->gfn,
228 sp->role.word); 221 sp->role.word);
229 spte = rmap_next(vcpu->kvm, rmapp, spte); 222 spte = rmap_next(kvm, rmapp, spte);
230 }
231 } 223 }
232} 224}
233 225
226static void audit_sp(struct kvm *kvm, struct kvm_mmu_page *sp)
227{
228 check_mappings_rmap(kvm, sp);
229 audit_write_protection(kvm, sp);
230}
231
232static void audit_all_active_sps(struct kvm *kvm)
233{
234 walk_all_active_sps(kvm, audit_sp);
235}
236
234static void kvm_mmu_audit(void *ignore, struct kvm_vcpu *vcpu, int audit_point) 237static void kvm_mmu_audit(void *ignore, struct kvm_vcpu *vcpu, int audit_point)
235{ 238{
236 audit_msg = audit_point_name[audit_point]; 239 audit_msg = audit_point_name[audit_point];
237 audit_rmap(vcpu); 240 audit_all_active_sps(vcpu->kvm);
238 audit_write_protection(vcpu);
239 if (strcmp("pre pte write", audit_msg) != 0) 241 if (strcmp("pre pte write", audit_msg) != 0)
240 audit_mappings(vcpu); 242 audit_mappings(vcpu);
241 audit_sptes_have_rmaps(vcpu); 243 audit_sptes_have_rmaps(vcpu);