356 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			356 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ)
 | |
| #define _TRACE_KVM_H
 | |
| 
 | |
| #include <linux/tracepoint.h>
 | |
| 
 | |
| #undef TRACE_SYSTEM
 | |
| #define TRACE_SYSTEM kvm
 | |
| #define TRACE_INCLUDE_PATH arch/x86/kvm
 | |
| #define TRACE_INCLUDE_FILE trace
 | |
| 
 | |
| /*
 | |
|  * Tracepoint for guest mode entry.
 | |
|  */
 | |
| TRACE_EVENT(kvm_entry,
 | |
| 	TP_PROTO(unsigned int vcpu_id),
 | |
| 	TP_ARGS(vcpu_id),
 | |
| 
 | |
| 	TP_STRUCT__entry(
 | |
| 		__field(	unsigned int,	vcpu_id		)
 | |
| 	),
 | |
| 
 | |
| 	TP_fast_assign(
 | |
| 		__entry->vcpu_id	= vcpu_id;
 | |
| 	),
 | |
| 
 | |
| 	TP_printk("vcpu %u", __entry->vcpu_id)
 | |
| );
 | |
| 
 | |
| /*
 | |
|  * Tracepoint for hypercall.
 | |
|  */
 | |
| TRACE_EVENT(kvm_hypercall,
 | |
| 	TP_PROTO(unsigned long nr, unsigned long a0, unsigned long a1,
 | |
| 		 unsigned long a2, unsigned long a3),
 | |
| 	TP_ARGS(nr, a0, a1, a2, a3),
 | |
| 
 | |
| 	TP_STRUCT__entry(
 | |
| 		__field(	unsigned long, 	nr		)
 | |
| 		__field(	unsigned long,	a0		)
 | |
| 		__field(	unsigned long,	a1		)
 | |
| 		__field(	unsigned long,	a2		)
 | |
| 		__field(	unsigned long,	a3		)
 | |
| 	),
 | |
| 
 | |
| 	TP_fast_assign(
 | |
| 		__entry->nr		= nr;
 | |
| 		__entry->a0		= a0;
 | |
| 		__entry->a1		= a1;
 | |
| 		__entry->a2		= a2;
 | |
| 		__entry->a3		= a3;
 | |
| 	),
 | |
| 
 | |
| 	TP_printk("nr 0x%lx a0 0x%lx a1 0x%lx a2 0x%lx a3 0x%lx",
 | |
| 		 __entry->nr, __entry->a0, __entry->a1,  __entry->a2,
 | |
| 		 __entry->a3)
 | |
| );
 | |
| 
 | |
| /*
 | |
|  * Tracepoint for PIO.
 | |
|  */
 | |
| TRACE_EVENT(kvm_pio,
 | |
| 	TP_PROTO(unsigned int rw, unsigned int port, unsigned int size,
 | |
| 		 unsigned int count),
 | |
| 	TP_ARGS(rw, port, size, count),
 | |
| 
 | |
| 	TP_STRUCT__entry(
 | |
| 		__field(	unsigned int, 	rw		)
 | |
| 		__field(	unsigned int, 	port		)
 | |
| 		__field(	unsigned int, 	size		)
 | |
| 		__field(	unsigned int,	count		)
 | |
| 	),
 | |
| 
 | |
| 	TP_fast_assign(
 | |
| 		__entry->rw		= rw;
 | |
| 		__entry->port		= port;
 | |
| 		__entry->size		= size;
 | |
| 		__entry->count		= count;
 | |
| 	),
 | |
| 
 | |
| 	TP_printk("pio_%s at 0x%x size %d count %d",
 | |
| 		  __entry->rw ? "write" : "read",
 | |
| 		  __entry->port, __entry->size, __entry->count)
 | |
| );
 | |
| 
 | |
| /*
 | |
|  * Tracepoint for cpuid.
 | |
|  */
 | |
| TRACE_EVENT(kvm_cpuid,
 | |
| 	TP_PROTO(unsigned int function, unsigned long rax, unsigned long rbx,
 | |
| 		 unsigned long rcx, unsigned long rdx),
 | |
| 	TP_ARGS(function, rax, rbx, rcx, rdx),
 | |
| 
 | |
| 	TP_STRUCT__entry(
 | |
| 		__field(	unsigned int,	function	)
 | |
| 		__field(	unsigned long,	rax		)
 | |
| 		__field(	unsigned long,	rbx		)
 | |
| 		__field(	unsigned long,	rcx		)
 | |
| 		__field(	unsigned long,	rdx		)
 | |
| 	),
 | |
| 
 | |
| 	TP_fast_assign(
 | |
| 		__entry->function	= function;
 | |
| 		__entry->rax		= rax;
 | |
| 		__entry->rbx		= rbx;
 | |
| 		__entry->rcx		= rcx;
 | |
| 		__entry->rdx		= rdx;
 | |
| 	),
 | |
| 
 | |
| 	TP_printk("func %x rax %lx rbx %lx rcx %lx rdx %lx",
 | |
| 		  __entry->function, __entry->rax,
 | |
| 		  __entry->rbx, __entry->rcx, __entry->rdx)
 | |
| );
 | |
| 
 | |
| #define AREG(x) { APIC_##x, "APIC_" #x }
 | |
| 
 | |
| #define kvm_trace_symbol_apic						    \
 | |
| 	AREG(ID), AREG(LVR), AREG(TASKPRI), AREG(ARBPRI), AREG(PROCPRI),    \
 | |
| 	AREG(EOI), AREG(RRR), AREG(LDR), AREG(DFR), AREG(SPIV), AREG(ISR),  \
 | |
| 	AREG(TMR), AREG(IRR), AREG(ESR), AREG(ICR), AREG(ICR2), AREG(LVTT), \
 | |
| 	AREG(LVTTHMR), AREG(LVTPC), AREG(LVT0), AREG(LVT1), AREG(LVTERR),   \
 | |
| 	AREG(TMICT), AREG(TMCCT), AREG(TDCR), AREG(SELF_IPI), AREG(EFEAT),  \
 | |
| 	AREG(ECTRL)
 | |
| /*
 | |
|  * Tracepoint for apic access.
 | |
|  */
 | |
| TRACE_EVENT(kvm_apic,
 | |
| 	TP_PROTO(unsigned int rw, unsigned int reg, unsigned int val),
 | |
| 	TP_ARGS(rw, reg, val),
 | |
| 
 | |
| 	TP_STRUCT__entry(
 | |
| 		__field(	unsigned int,	rw		)
 | |
| 		__field(	unsigned int,	reg		)
 | |
| 		__field(	unsigned int,	val		)
 | |
| 	),
 | |
| 
 | |
| 	TP_fast_assign(
 | |
| 		__entry->rw		= rw;
 | |
| 		__entry->reg		= reg;
 | |
| 		__entry->val		= val;
 | |
| 	),
 | |
| 
 | |
| 	TP_printk("apic_%s %s = 0x%x",
 | |
| 		  __entry->rw ? "write" : "read",
 | |
| 		  __print_symbolic(__entry->reg, kvm_trace_symbol_apic),
 | |
| 		  __entry->val)
 | |
| );
 | |
| 
 | |
| #define trace_kvm_apic_read(reg, val)		trace_kvm_apic(0, reg, val)
 | |
| #define trace_kvm_apic_write(reg, val)		trace_kvm_apic(1, reg, val)
 | |
| 
 | |
| /*
 | |
|  * Tracepoint for kvm guest exit:
 | |
|  */
 | |
| TRACE_EVENT(kvm_exit,
 | |
| 	TP_PROTO(unsigned int exit_reason, unsigned long guest_rip),
 | |
| 	TP_ARGS(exit_reason, guest_rip),
 | |
| 
 | |
| 	TP_STRUCT__entry(
 | |
| 		__field(	unsigned int,	exit_reason	)
 | |
| 		__field(	unsigned long,	guest_rip	)
 | |
| 	),
 | |
| 
 | |
| 	TP_fast_assign(
 | |
| 		__entry->exit_reason	= exit_reason;
 | |
| 		__entry->guest_rip	= guest_rip;
 | |
| 	),
 | |
| 
 | |
| 	TP_printk("reason %s rip 0x%lx",
 | |
| 		 ftrace_print_symbols_seq(p, __entry->exit_reason,
 | |
| 					  kvm_x86_ops->exit_reasons_str),
 | |
| 		 __entry->guest_rip)
 | |
| );
 | |
| 
 | |
| /*
 | |
|  * Tracepoint for kvm interrupt injection:
 | |
|  */
 | |
| TRACE_EVENT(kvm_inj_virq,
 | |
| 	TP_PROTO(unsigned int irq),
 | |
| 	TP_ARGS(irq),
 | |
| 
 | |
| 	TP_STRUCT__entry(
 | |
| 		__field(	unsigned int,	irq		)
 | |
| 	),
 | |
| 
 | |
| 	TP_fast_assign(
 | |
| 		__entry->irq		= irq;
 | |
| 	),
 | |
| 
 | |
| 	TP_printk("irq %u", __entry->irq)
 | |
| );
 | |
| 
 | |
| /*
 | |
|  * Tracepoint for page fault.
 | |
|  */
 | |
| TRACE_EVENT(kvm_page_fault,
 | |
| 	TP_PROTO(unsigned long fault_address, unsigned int error_code),
 | |
| 	TP_ARGS(fault_address, error_code),
 | |
| 
 | |
| 	TP_STRUCT__entry(
 | |
| 		__field(	unsigned long,	fault_address	)
 | |
| 		__field(	unsigned int,	error_code	)
 | |
| 	),
 | |
| 
 | |
| 	TP_fast_assign(
 | |
| 		__entry->fault_address	= fault_address;
 | |
| 		__entry->error_code	= error_code;
 | |
| 	),
 | |
| 
 | |
| 	TP_printk("address %lx error_code %x",
 | |
| 		  __entry->fault_address, __entry->error_code)
 | |
| );
 | |
| 
 | |
| /*
 | |
|  * Tracepoint for guest MSR access.
 | |
|  */
 | |
| TRACE_EVENT(kvm_msr,
 | |
| 	TP_PROTO(unsigned int rw, unsigned int ecx, unsigned long data),
 | |
| 	TP_ARGS(rw, ecx, data),
 | |
| 
 | |
| 	TP_STRUCT__entry(
 | |
| 		__field(	unsigned int,	rw		)
 | |
| 		__field(	unsigned int,	ecx		)
 | |
| 		__field(	unsigned long,	data		)
 | |
| 	),
 | |
| 
 | |
| 	TP_fast_assign(
 | |
| 		__entry->rw		= rw;
 | |
| 		__entry->ecx		= ecx;
 | |
| 		__entry->data		= data;
 | |
| 	),
 | |
| 
 | |
| 	TP_printk("msr_%s %x = 0x%lx",
 | |
| 		  __entry->rw ? "write" : "read",
 | |
| 		  __entry->ecx, __entry->data)
 | |
| );
 | |
| 
 | |
| #define trace_kvm_msr_read(ecx, data)		trace_kvm_msr(0, ecx, data)
 | |
| #define trace_kvm_msr_write(ecx, data)		trace_kvm_msr(1, ecx, data)
 | |
| 
 | |
| /*
 | |
|  * Tracepoint for guest CR access.
 | |
|  */
 | |
| TRACE_EVENT(kvm_cr,
 | |
| 	TP_PROTO(unsigned int rw, unsigned int cr, unsigned long val),
 | |
| 	TP_ARGS(rw, cr, val),
 | |
| 
 | |
| 	TP_STRUCT__entry(
 | |
| 		__field(	unsigned int,	rw		)
 | |
| 		__field(	unsigned int,	cr		)
 | |
| 		__field(	unsigned long,	val		)
 | |
| 	),
 | |
| 
 | |
| 	TP_fast_assign(
 | |
| 		__entry->rw		= rw;
 | |
| 		__entry->cr		= cr;
 | |
| 		__entry->val		= val;
 | |
| 	),
 | |
| 
 | |
| 	TP_printk("cr_%s %x = 0x%lx",
 | |
| 		  __entry->rw ? "write" : "read",
 | |
| 		  __entry->cr, __entry->val)
 | |
| );
 | |
| 
 | |
| #define trace_kvm_cr_read(cr, val)		trace_kvm_cr(0, cr, val)
 | |
| #define trace_kvm_cr_write(cr, val)		trace_kvm_cr(1, cr, val)
 | |
| 
 | |
| TRACE_EVENT(kvm_pic_set_irq,
 | |
| 	    TP_PROTO(__u8 chip, __u8 pin, __u8 elcr, __u8 imr, bool coalesced),
 | |
| 	    TP_ARGS(chip, pin, elcr, imr, coalesced),
 | |
| 
 | |
| 	TP_STRUCT__entry(
 | |
| 		__field(	__u8,		chip		)
 | |
| 		__field(	__u8,		pin		)
 | |
| 		__field(	__u8,		elcr		)
 | |
| 		__field(	__u8,		imr		)
 | |
| 		__field(	bool,		coalesced	)
 | |
| 	),
 | |
| 
 | |
| 	TP_fast_assign(
 | |
| 		__entry->chip		= chip;
 | |
| 		__entry->pin		= pin;
 | |
| 		__entry->elcr		= elcr;
 | |
| 		__entry->imr		= imr;
 | |
| 		__entry->coalesced	= coalesced;
 | |
| 	),
 | |
| 
 | |
| 	TP_printk("chip %u pin %u (%s%s)%s",
 | |
| 		  __entry->chip, __entry->pin,
 | |
| 		  (__entry->elcr & (1 << __entry->pin)) ? "level":"edge",
 | |
| 		  (__entry->imr & (1 << __entry->pin)) ? "|masked":"",
 | |
| 		  __entry->coalesced ? " (coalesced)" : "")
 | |
| );
 | |
| 
 | |
| #define kvm_apic_dst_shorthand		\
 | |
| 	{0x0, "dst"},			\
 | |
| 	{0x1, "self"},			\
 | |
| 	{0x2, "all"},			\
 | |
| 	{0x3, "all-but-self"}
 | |
| 
 | |
| TRACE_EVENT(kvm_apic_ipi,
 | |
| 	    TP_PROTO(__u32 icr_low, __u32 dest_id),
 | |
| 	    TP_ARGS(icr_low, dest_id),
 | |
| 
 | |
| 	TP_STRUCT__entry(
 | |
| 		__field(	__u32,		icr_low		)
 | |
| 		__field(	__u32,		dest_id		)
 | |
| 	),
 | |
| 
 | |
| 	TP_fast_assign(
 | |
| 		__entry->icr_low	= icr_low;
 | |
| 		__entry->dest_id	= dest_id;
 | |
| 	),
 | |
| 
 | |
| 	TP_printk("dst %x vec %u (%s|%s|%s|%s|%s)",
 | |
| 		  __entry->dest_id, (u8)__entry->icr_low,
 | |
| 		  __print_symbolic((__entry->icr_low >> 8 & 0x7),
 | |
| 				   kvm_deliver_mode),
 | |
| 		  (__entry->icr_low & (1<<11)) ? "logical" : "physical",
 | |
| 		  (__entry->icr_low & (1<<14)) ? "assert" : "de-assert",
 | |
| 		  (__entry->icr_low & (1<<15)) ? "level" : "edge",
 | |
| 		  __print_symbolic((__entry->icr_low >> 18 & 0x3),
 | |
| 				   kvm_apic_dst_shorthand))
 | |
| );
 | |
| 
 | |
| TRACE_EVENT(kvm_apic_accept_irq,
 | |
| 	    TP_PROTO(__u32 apicid, __u16 dm, __u8 tm, __u8 vec, bool coalesced),
 | |
| 	    TP_ARGS(apicid, dm, tm, vec, coalesced),
 | |
| 
 | |
| 	TP_STRUCT__entry(
 | |
| 		__field(	__u32,		apicid		)
 | |
| 		__field(	__u16,		dm		)
 | |
| 		__field(	__u8,		tm		)
 | |
| 		__field(	__u8,		vec		)
 | |
| 		__field(	bool,		coalesced	)
 | |
| 	),
 | |
| 
 | |
| 	TP_fast_assign(
 | |
| 		__entry->apicid		= apicid;
 | |
| 		__entry->dm		= dm;
 | |
| 		__entry->tm		= tm;
 | |
| 		__entry->vec		= vec;
 | |
| 		__entry->coalesced	= coalesced;
 | |
| 	),
 | |
| 
 | |
| 	TP_printk("apicid %x vec %u (%s|%s)%s",
 | |
| 		  __entry->apicid, __entry->vec,
 | |
| 		  __print_symbolic((__entry->dm >> 8 & 0x7), kvm_deliver_mode),
 | |
| 		  __entry->tm ? "level" : "edge",
 | |
| 		  __entry->coalesced ? " (coalesced)" : "")
 | |
| );
 | |
| 
 | |
| #endif /* _TRACE_KVM_H */
 | |
| 
 | |
| /* This part must be outside protection */
 | |
| #include <trace/define_trace.h>
 |