提交 08a3732b 编写于 作者: M Marcelo Tosatti 提交者: Avi Kivity

KVM: MMU audit: update count_writable_mappings / count_rmaps

Under testing, count_writable_mappings returns a value that is 2 integers
larger than what count_rmaps returns.

Suspicion is that either of the two functions is counting a duplicate (either
positively or negatively).

Modifying check_writable_mappings_rmap to check for rmap existance on
all present MMU pages fails to trigger an error, which should keep Avi
happy.

Also introduce mmu_spte_walk to invoke a callback on all present sptes visible
to the current vcpu, might be useful in the future.
Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: NAvi Kivity <avi@redhat.com>
上级 776e6633
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
......@@ -3045,6 +3045,55 @@ static gva_t canonicalize(gva_t gva)
return gva;
}
typedef void (*inspect_spte_fn) (struct kvm *kvm, struct kvm_mmu_page *sp,
u64 *sptep);
static void __mmu_spte_walk(struct kvm *kvm, struct kvm_mmu_page *sp,
inspect_spte_fn fn)
{
int i;
for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
u64 ent = sp->spt[i];
if (is_shadow_present_pte(ent)) {
if (sp->role.level > 1 && !is_large_pte(ent)) {
struct kvm_mmu_page *child;
child = page_header(ent & PT64_BASE_ADDR_MASK);
__mmu_spte_walk(kvm, child, fn);
}
if (sp->role.level == 1)
fn(kvm, sp, &sp->spt[i]);
}
}
}
static void mmu_spte_walk(struct kvm_vcpu *vcpu, inspect_spte_fn fn)
{
int i;
struct kvm_mmu_page *sp;
if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
return;
if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
hpa_t root = vcpu->arch.mmu.root_hpa;
sp = page_header(root);
__mmu_spte_walk(vcpu->kvm, sp, fn);
return;
}
for (i = 0; i < 4; ++i) {
hpa_t root = vcpu->arch.mmu.pae_root[i];
if (root && VALID_PAGE(root)) {
root &= PT64_BASE_ADDR_MASK;
sp = page_header(root);
__mmu_spte_walk(vcpu->kvm, sp, fn);
}
}
return;
}
static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte,
gva_t va, int level)
{
......@@ -3137,9 +3186,47 @@ static int count_rmaps(struct kvm_vcpu *vcpu)
return nmaps;
}
static int count_writable_mappings(struct kvm_vcpu *vcpu)
void inspect_spte_has_rmap(struct kvm *kvm, struct kvm_mmu_page *sp, u64 *sptep)
{
unsigned long *rmapp;
struct kvm_mmu_page *rev_sp;
gfn_t gfn;
if (*sptep & PT_WRITABLE_MASK) {
rev_sp = page_header(__pa(sptep));
gfn = rev_sp->gfns[sptep - rev_sp->spt];
if (!gfn_to_memslot(kvm, gfn)) {
if (!printk_ratelimit())
return;
printk(KERN_ERR "%s: no memslot for gfn %ld\n",
audit_msg, gfn);
printk(KERN_ERR "%s: index %ld of sp (gfn=%lx)\n",
audit_msg, sptep - rev_sp->spt,
rev_sp->gfn);
dump_stack();
return;
}
rmapp = gfn_to_rmap(kvm, rev_sp->gfns[sptep - rev_sp->spt], 0);
if (!*rmapp) {
if (!printk_ratelimit())
return;
printk(KERN_ERR "%s: no rmap for writable spte %llx\n",
audit_msg, *sptep);
dump_stack();
}
}
}
void audit_writable_sptes_have_rmaps(struct kvm_vcpu *vcpu)
{
mmu_spte_walk(vcpu, inspect_spte_has_rmap);
}
static void check_writable_mappings_rmap(struct kvm_vcpu *vcpu)
{
int nmaps = 0;
struct kvm_mmu_page *sp;
int i;
......@@ -3156,20 +3243,16 @@ static int count_writable_mappings(struct kvm_vcpu *vcpu)
continue;
if (!(ent & PT_WRITABLE_MASK))
continue;
++nmaps;
inspect_spte_has_rmap(vcpu->kvm, sp, &pt[i]);
}
}
return nmaps;
return;
}
static void audit_rmap(struct kvm_vcpu *vcpu)
{
int n_rmap = count_rmaps(vcpu);
int n_actual = count_writable_mappings(vcpu);
if (n_rmap != n_actual)
printk(KERN_ERR "%s: (%s) rmap %d actual %d\n",
__func__, audit_msg, n_rmap, n_actual);
check_writable_mappings_rmap(vcpu);
count_rmaps(vcpu);
}
static void audit_write_protection(struct kvm_vcpu *vcpu)
......@@ -3203,6 +3286,7 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg)
audit_rmap(vcpu);
audit_write_protection(vcpu);
audit_mappings(vcpu);
audit_writable_sptes_have_rmaps(vcpu);
dbg = olddbg;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部