Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 215815
b: refs/heads/master
c: 8b1fe17
h: refs/heads/master
i:
  215813: 48d3182
  215811: b6567d7
  215807: 499f630
v: v3
  • Loading branch information
Xiao Guangrong authored and Avi Kivity committed Oct 24, 2010
1 parent b04fff2 commit 8cde2fd
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 84e0cefa8ddd5d5018d3b582e1e90585ed551757
refs/heads/master: 8b1fe17cc7a8b2c62b400dcbfaebd96da6b4f58e
7 changes: 7 additions & 0 deletions trunk/arch/x86/kvm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ config KVM_AMD
To compile this as a module, choose M here: the module
will be called kvm-amd.

config KVM_MMU_AUDIT
bool "Audit KVM MMU"
depends on KVM && TRACEPOINTS
---help---
This option adds a R/W kVM module parameter 'mmu_audit', which allows
audit KVM MMU at runtime.

# OK, it's a little counter-intuitive to do this, but it puts it neatly under
# the virtualization menu.
source drivers/vhost/Kconfig
Expand Down
91 changes: 73 additions & 18 deletions trunk/arch/x86/kvm/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,21 @@
*/
bool tdp_enabled = false;

#undef MMU_DEBUG
enum {
AUDIT_PRE_PAGE_FAULT,
AUDIT_POST_PAGE_FAULT,
AUDIT_PRE_PTE_WRITE,
AUDIT_POST_PTE_WRITE
};

#undef AUDIT
char *audit_point_name[] = {
"pre page fault",
"post page fault",
"pre pte write",
"post pte write"
};

#ifdef AUDIT
static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg);
#else
static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg) {}
#endif
#undef MMU_DEBUG

#ifdef MMU_DEBUG

Expand All @@ -71,7 +77,7 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg) {}

#endif

#if defined(MMU_DEBUG) || defined(AUDIT)
#ifdef MMU_DEBUG
static int dbg = 0;
module_param(dbg, bool, 0644);
#endif
Expand Down Expand Up @@ -2964,7 +2970,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
kvm_mmu_access_page(vcpu, gfn);
kvm_mmu_free_some_pages(vcpu);
++vcpu->kvm->stat.mmu_pte_write;
kvm_mmu_audit(vcpu, "pre pte write");
trace_kvm_mmu_audit(vcpu, AUDIT_PRE_PTE_WRITE);
if (guest_initiated) {
if (gfn == vcpu->arch.last_pt_write_gfn
&& !last_updated_pte_accessed(vcpu)) {
Expand Down Expand Up @@ -3037,7 +3043,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
}
mmu_pte_write_flush_tlb(vcpu, zap_page, remote_flush, local_flush);
kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list);
kvm_mmu_audit(vcpu, "post pte write");
trace_kvm_mmu_audit(vcpu, AUDIT_POST_PTE_WRITE);
spin_unlock(&vcpu->kvm->mmu_lock);
if (!is_error_pfn(vcpu->arch.update_pte.pfn)) {
kvm_release_pfn_clean(vcpu->arch.update_pte.pfn);
Expand Down Expand Up @@ -3483,8 +3489,7 @@ int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4])
}
EXPORT_SYMBOL_GPL(kvm_mmu_get_spte_hierarchy);

#ifdef AUDIT

#ifdef CONFIG_KVM_MMU_AUDIT
static const char *audit_msg;

typedef void (*inspect_spte_fn) (struct kvm *kvm, u64 *sptep);
Expand Down Expand Up @@ -3699,18 +3704,68 @@ static void audit_write_protection(struct kvm_vcpu *vcpu)
}
}

static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg)
static void kvm_mmu_audit(void *ignore, struct kvm_vcpu *vcpu, int audit_point)
{
int olddbg = dbg;

dbg = 0;
audit_msg = msg;
audit_msg = audit_point_name[audit_point];
audit_rmap(vcpu);
audit_write_protection(vcpu);
if (strcmp("pre pte write", audit_msg) != 0)
audit_mappings(vcpu);
audit_sptes_have_rmaps(vcpu);
dbg = olddbg;
}

static bool mmu_audit;

static void mmu_audit_enable(void)
{
int ret;

if (mmu_audit)
return;

ret = register_trace_kvm_mmu_audit(kvm_mmu_audit, NULL);
WARN_ON(ret);

mmu_audit = true;
}

static void mmu_audit_disable(void)
{
if (!mmu_audit)
return;

unregister_trace_kvm_mmu_audit(kvm_mmu_audit, NULL);
tracepoint_synchronize_unregister();
mmu_audit = false;
}

static int mmu_audit_set(const char *val, const struct kernel_param *kp)
{
int ret;
unsigned long enable;

ret = strict_strtoul(val, 10, &enable);
if (ret < 0)
return -EINVAL;

switch (enable) {
case 0:
mmu_audit_disable();
break;
case 1:
mmu_audit_enable();
break;
default:
return -EINVAL;
}

return 0;
}

static struct kernel_param_ops audit_param_ops = {
.set = mmu_audit_set,
.get = param_get_bool,
};

module_param_cb(mmu_audit, &audit_param_ops, &mmu_audit, 0644);
#endif
19 changes: 19 additions & 0 deletions trunk/arch/x86/kvm/mmutrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,25 @@ DEFINE_EVENT(kvm_mmu_page_class, kvm_mmu_prepare_zap_page,

TP_ARGS(sp)
);

TRACE_EVENT(
kvm_mmu_audit,
TP_PROTO(struct kvm_vcpu *vcpu, int audit_point),
TP_ARGS(vcpu, audit_point),

TP_STRUCT__entry(
__field(struct kvm_vcpu *, vcpu)
__field(int, audit_point)
),

TP_fast_assign(
__entry->vcpu = vcpu;
__entry->audit_point = audit_point;
),

TP_printk("vcpu:%d %s", __entry->vcpu->cpu,
audit_point_name[__entry->audit_point])
);
#endif /* _TRACE_KVMMMU_H */

#undef TRACE_INCLUDE_PATH
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/x86/kvm/paging_tmpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
if (mmu_notifier_retry(vcpu, mmu_seq))
goto out_unlock;

kvm_mmu_audit(vcpu, "pre page fault");
trace_kvm_mmu_audit(vcpu, AUDIT_PRE_PAGE_FAULT);
kvm_mmu_free_some_pages(vcpu);
sptep = FNAME(fetch)(vcpu, addr, &walker, user_fault, write_fault,
level, &write_pt, pfn);
Expand All @@ -554,7 +554,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
vcpu->arch.last_pt_write_count = 0; /* reset fork detector */

++vcpu->stat.pf_fixed;
kvm_mmu_audit(vcpu, "post page fault (fixed)");
trace_kvm_mmu_audit(vcpu, AUDIT_POST_PAGE_FAULT);
spin_unlock(&vcpu->kvm->mmu_lock);

return write_pt;
Expand Down

0 comments on commit 8cde2fd

Please sign in to comment.