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