mmutrace.h 5.7 KB
Newer Older
1 2 3 4
#if !defined(_TRACE_KVMMMU_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_KVMMMU_H

#include <linux/tracepoint.h>
A
Avi Kivity 已提交
5
#include <linux/ftrace_event.h>
6 7 8 9

#undef TRACE_SYSTEM
#define TRACE_SYSTEM kvmmmu

A
Avi Kivity 已提交
10 11 12 13
#define KVM_MMU_PAGE_FIELDS \
	__field(__u64, gfn) \
	__field(__u32, role) \
	__field(__u32, root_count) \
14
	__field(bool, unsync)
A
Avi Kivity 已提交
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

#define KVM_MMU_PAGE_ASSIGN(sp)			     \
	__entry->gfn = sp->gfn;			     \
	__entry->role = sp->role.word;		     \
	__entry->root_count = sp->root_count;        \
	__entry->unsync = sp->unsync;

#define KVM_MMU_PAGE_PRINTK() ({				        \
	const char *ret = p->buffer + p->len;				\
	static const char *access_str[] = {			        \
		"---", "--x", "w--", "w-x", "-u-", "-ux", "wu-", "wux"  \
	};							        \
	union kvm_mmu_page_role role;				        \
								        \
	role.word = __entry->role;					\
									\
31
	trace_seq_printf(p, "sp gfn %llx %u%s q%u%s %s%s"		\
A
Avi Kivity 已提交
32
			 " %snxe root %u %s%c",				\
33 34
			 __entry->gfn, role.level,			\
			 role.cr4_pae ? " pae" : "",			\
A
Avi Kivity 已提交
35 36 37 38 39 40 41 42 43 44
			 role.quadrant,					\
			 role.direct ? " direct" : "",			\
			 access_str[role.access],			\
			 role.invalid ? " invalid" : "",		\
			 role.nxe ? "" : "!",				\
			 __entry->root_count,				\
			 __entry->unsync ? "unsync" : "sync", 0);	\
	ret;								\
		})

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
#define kvm_mmu_trace_pferr_flags       \
	{ PFERR_PRESENT_MASK, "P" },	\
	{ PFERR_WRITE_MASK, "W" },	\
	{ PFERR_USER_MASK, "U" },	\
	{ PFERR_RSVD_MASK, "RSVD" },	\
	{ PFERR_FETCH_MASK, "F" }

/*
 * A pagetable walk has started
 */
TRACE_EVENT(
	kvm_mmu_pagetable_walk,
	TP_PROTO(u64 addr, int write_fault, int user_fault, int fetch_fault),
	TP_ARGS(addr, write_fault, user_fault, fetch_fault),

	TP_STRUCT__entry(
		__field(__u64, addr)
		__field(__u32, pferr)
	),

	TP_fast_assign(
		__entry->addr = addr;
		__entry->pferr = (!!write_fault << 1) | (!!user_fault << 2)
		                 | (!!fetch_fault << 4);
	),

	TP_printk("addr %llx pferr %x %s", __entry->addr, __entry->pferr,
		  __print_flags(__entry->pferr, "|", kvm_mmu_trace_pferr_flags))
);


/* We just walked a paging element */
TRACE_EVENT(
	kvm_mmu_paging_element,
	TP_PROTO(u64 pte, int level),
	TP_ARGS(pte, level),

	TP_STRUCT__entry(
		__field(__u64, pte)
		__field(__u32, level)
		),

	TP_fast_assign(
		__entry->pte = pte;
		__entry->level = level;
		),

	TP_printk("pte %llx level %u", __entry->pte, __entry->level)
);

95 96
DECLARE_EVENT_CLASS(kvm_mmu_set_bit_class,

97
	TP_PROTO(unsigned long table_gfn, unsigned index, unsigned size),
98

99 100 101 102
	TP_ARGS(table_gfn, index, size),

	TP_STRUCT__entry(
		__field(__u64, gpa)
103
	),
104 105 106 107 108 109 110 111 112

	TP_fast_assign(
		__entry->gpa = ((u64)table_gfn << PAGE_SHIFT)
				+ index * size;
		),

	TP_printk("gpa %llx", __entry->gpa)
);

113 114 115
/* We set a pte accessed bit */
DEFINE_EVENT(kvm_mmu_set_bit_class, kvm_mmu_set_accessed_bit,

116 117
	TP_PROTO(unsigned long table_gfn, unsigned index, unsigned size),

118 119
	TP_ARGS(table_gfn, index, size)
);
120

121 122
/* We set a pte dirty bit */
DEFINE_EVENT(kvm_mmu_set_bit_class, kvm_mmu_set_dirty_bit,
123

124 125 126
	TP_PROTO(unsigned long table_gfn, unsigned index, unsigned size),

	TP_ARGS(table_gfn, index, size)
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
);

TRACE_EVENT(
	kvm_mmu_walker_error,
	TP_PROTO(u32 pferr),
	TP_ARGS(pferr),

	TP_STRUCT__entry(
		__field(__u32, pferr)
		),

	TP_fast_assign(
		__entry->pferr = pferr;
		),

	TP_printk("pferr %x %s", __entry->pferr,
		  __print_flags(__entry->pferr, "|", kvm_mmu_trace_pferr_flags))
);

A
Avi Kivity 已提交
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
TRACE_EVENT(
	kvm_mmu_get_page,
	TP_PROTO(struct kvm_mmu_page *sp, bool created),
	TP_ARGS(sp, created),

	TP_STRUCT__entry(
		KVM_MMU_PAGE_FIELDS
		__field(bool, created)
		),

	TP_fast_assign(
		KVM_MMU_PAGE_ASSIGN(sp)
		__entry->created = created;
		),

	TP_printk("%s %s", KVM_MMU_PAGE_PRINTK(),
		  __entry->created ? "new" : "existing")
);

165 166
DECLARE_EVENT_CLASS(kvm_mmu_page_class,

A
Avi Kivity 已提交
167 168 169 170 171
	TP_PROTO(struct kvm_mmu_page *sp),
	TP_ARGS(sp),

	TP_STRUCT__entry(
		KVM_MMU_PAGE_FIELDS
172
	),
A
Avi Kivity 已提交
173 174 175

	TP_fast_assign(
		KVM_MMU_PAGE_ASSIGN(sp)
176
	),
A
Avi Kivity 已提交
177 178 179 180

	TP_printk("%s", KVM_MMU_PAGE_PRINTK())
);

181
DEFINE_EVENT(kvm_mmu_page_class, kvm_mmu_sync_page,
A
Avi Kivity 已提交
182 183
	TP_PROTO(struct kvm_mmu_page *sp),

184
	TP_ARGS(sp)
A
Avi Kivity 已提交
185 186
);

187
DEFINE_EVENT(kvm_mmu_page_class, kvm_mmu_unsync_page,
A
Avi Kivity 已提交
188 189
	TP_PROTO(struct kvm_mmu_page *sp),

190 191
	TP_ARGS(sp)
);
A
Avi Kivity 已提交
192

193
DEFINE_EVENT(kvm_mmu_page_class, kvm_mmu_prepare_zap_page,
194
	TP_PROTO(struct kvm_mmu_page *sp),
A
Avi Kivity 已提交
195

196
	TP_ARGS(sp)
A
Avi Kivity 已提交
197
);
198

X
Xiao Guangrong 已提交
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
DEFINE_EVENT(kvm_mmu_page_class, kvm_mmu_delay_free_pages,
	TP_PROTO(struct kvm_mmu_page *sp),

	TP_ARGS(sp)
);

TRACE_EVENT(
	mark_mmio_spte,
	TP_PROTO(u64 *sptep, gfn_t gfn, unsigned access),
	TP_ARGS(sptep, gfn, access),

	TP_STRUCT__entry(
		__field(void *, sptep)
		__field(gfn_t, gfn)
		__field(unsigned, access)
	),

	TP_fast_assign(
		__entry->sptep = sptep;
		__entry->gfn = gfn;
		__entry->access = access;
	),

	TP_printk("sptep:%p gfn %llx access %x", __entry->sptep, __entry->gfn,
		  __entry->access)
);

TRACE_EVENT(
	handle_mmio_page_fault,
	TP_PROTO(u64 addr, gfn_t gfn, unsigned access),
	TP_ARGS(addr, gfn, access),

	TP_STRUCT__entry(
		__field(u64, addr)
		__field(gfn_t, gfn)
		__field(unsigned, access)
	),

	TP_fast_assign(
		__entry->addr = addr;
		__entry->gfn = gfn;
		__entry->access = access;
	),

	TP_printk("addr:%llx gfn %llx access %x", __entry->addr, __entry->gfn,
		  __entry->access)
);

247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
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])
);
265 266
#endif /* _TRACE_KVMMMU_H */

X
Xiao Guangrong 已提交
267 268 269 270 271
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE mmutrace

272 273
/* This part must be outside protection */
#include <trace/define_trace.h>