1 #include <xen/init.h>
2 #include <xen/kernel.h>
3 #include <xen/lib.h>
4 #include <xen/domain.h>
5 #include <xen/sched.h>
6 #include <xen/trace.h>
7
__trace_pv_trap(int trapnr,unsigned long eip,int use_error_code,unsigned error_code)8 void __trace_pv_trap(int trapnr, unsigned long eip,
9 int use_error_code, unsigned error_code)
10 {
11 if ( is_pv_32bit_vcpu(current) )
12 {
13 struct __packed {
14 unsigned eip:32,
15 trapnr:15,
16 use_error_code:1,
17 error_code:16;
18 } d;
19
20 d.eip = eip;
21 d.trapnr = trapnr;
22 d.error_code = error_code;
23 d.use_error_code=!!use_error_code;
24
25 __trace_var(TRC_PV_TRAP, 1, sizeof(d), &d);
26 }
27 else
28 {
29 struct __packed {
30 unsigned long eip;
31 unsigned trapnr:15,
32 use_error_code:1,
33 error_code:16;
34 } d;
35 unsigned event;
36
37 d.eip = eip;
38 d.trapnr = trapnr;
39 d.error_code = error_code;
40 d.use_error_code=!!use_error_code;
41
42 event = TRC_PV_TRAP;
43 event |= TRC_64_FLAG;
44 __trace_var(event, 1, sizeof(d), &d);
45 }
46 }
47
__trace_pv_page_fault(unsigned long addr,unsigned error_code)48 void __trace_pv_page_fault(unsigned long addr, unsigned error_code)
49 {
50 unsigned long eip = guest_cpu_user_regs()->rip;
51
52 if ( is_pv_32bit_vcpu(current) )
53 {
54 struct __packed {
55 u32 eip, addr, error_code;
56 } d;
57
58 d.eip = eip;
59 d.addr = addr;
60 d.error_code = error_code;
61
62 __trace_var(TRC_PV_PAGE_FAULT, 1, sizeof(d), &d);
63 }
64 else
65 {
66 struct __packed {
67 unsigned long eip, addr;
68 u32 error_code;
69 } d;
70 unsigned event;
71
72 d.eip = eip;
73 d.addr = addr;
74 d.error_code = error_code;
75 event = TRC_PV_PAGE_FAULT;
76 event |= TRC_64_FLAG;
77 __trace_var(event, 1, sizeof(d), &d);
78 }
79 }
80
__trace_trap_one_addr(unsigned event,unsigned long va)81 void __trace_trap_one_addr(unsigned event, unsigned long va)
82 {
83 if ( is_pv_32bit_vcpu(current) )
84 {
85 u32 d = va;
86 __trace_var(event, 1, sizeof(d), &d);
87 }
88 else
89 {
90 event |= TRC_64_FLAG;
91 __trace_var(event, 1, sizeof(va), &va);
92 }
93 }
94
__trace_trap_two_addr(unsigned event,unsigned long va1,unsigned long va2)95 void __trace_trap_two_addr(unsigned event, unsigned long va1,
96 unsigned long va2)
97 {
98 if ( is_pv_32bit_vcpu(current) )
99 {
100 struct __packed {
101 u32 va1, va2;
102 } d;
103 d.va1=va1;
104 d.va2=va2;
105 __trace_var(event, 1, sizeof(d), &d);
106 }
107 else
108 {
109 struct __packed {
110 unsigned long va1, va2;
111 } d;
112 d.va1=va1;
113 d.va2=va2;
114 event |= TRC_64_FLAG;
115 __trace_var(event, 1, sizeof(d), &d);
116 }
117 }
118
__trace_ptwr_emulation(unsigned long addr,l1_pgentry_t npte)119 void __trace_ptwr_emulation(unsigned long addr, l1_pgentry_t npte)
120 {
121 unsigned long eip = guest_cpu_user_regs()->rip;
122
123 /* We have a couple of different modes to worry about:
124 * - 32-on-32: 32-bit pte, 32-bit virtual addresses
125 * - pae-on-pae, pae-on-64: 64-bit pte, 32-bit virtual addresses
126 * - 64-on-64: 64-bit pte, 64-bit virtual addresses
127 * pae-on-64 is the only one that requires extra code; in all other
128 * cases, "unsigned long" is the size of a guest virtual address.
129 */
130
131 if ( is_pv_32bit_vcpu(current) )
132 {
133 struct __packed {
134 l1_pgentry_t pte;
135 u32 addr, eip;
136 } d;
137 d.addr = addr;
138 d.eip = eip;
139 d.pte = npte;
140
141 __trace_var(TRC_PV_PTWR_EMULATION_PAE, 1, sizeof(d), &d);
142 }
143 else
144 {
145 struct {
146 l1_pgentry_t pte;
147 unsigned long addr, eip;
148 } d;
149 unsigned event;
150
151 d.addr = addr;
152 d.eip = eip;
153 d.pte = npte;
154
155 event = TRC_PV_PTWR_EMULATION;
156 event |= TRC_64_FLAG;
157 __trace_var(event, 1/*tsc*/, sizeof(d), &d);
158 }
159 }
160