1 /*
2  * Copyright (C) 2018-2022 Intel Corporation.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef PROFILING_INTERNAL_H
8 #define PROFILING_INTERNAL_H
9 
10 #ifdef PROFILING_ON
11 
12 #include <asm/guest/vcpu.h>
13 #include <asm/vm_config.h>
14 
15 #define MAX_MSR_LIST_NUM		15U
16 #define MAX_PROFILING_MSR_STORE_NUM	1
17 #define MAX_HV_MSR_LIST_NUM		(MSR_AREA_COUNT)
18 #define MAX_GROUP_NUM		1U
19 
20 #define COLLECT_PROFILE_DATA	0
21 #define COLLECT_POWER_DATA	1
22 
23 #define SEP_BUF_ENTRY_SIZE 	32U
24 #define SOCWATCH_MSR_OP		100U
25 
26 #define MAGIC_NUMBER		0x99999988U
27 
28 enum MSR_CMD_STATUS {
29 	MSR_OP_READY = 0,
30 	MSR_OP_REQUESTED,
31 	MSR_OP_HANDLED
32 };
33 enum MSR_CMD_TYPE {
34 	MSR_OP_NONE = 0,
35 	MSR_OP_READ,
36 	MSR_OP_WRITE,
37 	MSR_OP_READ_CLEAR
38 };
39 
40 enum PMU_MSR_TYPE {
41 	PMU_MSR_CCCR = 0,
42 	PMU_MSR_ESCR,
43 	PMU_MSR_DATA
44 };
45 typedef enum IPI_COMMANDS {
46 	IPI_MSR_OP = 0,
47 	IPI_PMU_CONFIG,
48 	IPI_PMU_START,
49 	IPI_PMU_STOP,
50 	IPI_VMSW_CONFIG,
51 	IPI_UNKNOWN,
52 } ipi_commands;
53 
54 typedef enum SEP_PMU_STATE {
55 	PMU_INITIALIZED = 0,
56 	PMU_SETUP,
57 	PMU_RUNNING,
58 	PMU_UNINITIALIZED,
59 	PMU_UNKNOWN
60 } sep_pmu_state;
61 
62 typedef enum PROFILING_SEP_FEATURE {
63 	CORE_PMU_SAMPLING = 0,
64 	CORE_PMU_COUNTING,
65 	PEBS_PMU_SAMPLING,
66 	LBR_PMU_SAMPLING,
67 	UNCORE_PMU_SAMPLING,
68 	VM_SWITCH_TRACING,
69 	MAX_SEP_FEATURE_ID
70 } profiling_sep_feature;
71 
72 typedef enum SOCWATCH_STATE {
73 	SW_SETUP = 0,
74 	SW_RUNNING,
75 	SW_STOPPED
76 } socwatch_state;
77 
78 typedef enum PROFILING_SOCWATCH_FEATURE {
79 	SOCWATCH_COMMAND = 0,
80 	SOCWATCH_VM_SWITCH_TRACING,
81 	MAX_SOCWATCH_FEATURE_ID
82 } profiling_socwatch_feature;
83 
84 struct profiling_version_info {
85 	int32_t major;
86 	int32_t minor;
87 	int64_t supported_features;
88 	int64_t reserved;
89 };
90 
91 struct profiling_pcpuid {
92 	uint32_t leaf;
93 	uint32_t subleaf;
94 	uint32_t eax;
95 	uint32_t ebx;
96 	uint32_t ecx;
97 	uint32_t edx;
98 };
99 
100 struct profiling_control {
101 	int32_t	collector_id;
102 	int32_t	reserved;
103 	uint64_t switches;
104 };
105 
106 struct profiling_vcpu_pcpu_map {
107 	int16_t vcpu_id;
108 	int16_t pcpu_id;
109 	uint32_t apic_id;
110 };
111 
112 struct profiling_vm_info {
113 	uint16_t vm_id_num;
114 	char vm_name[16];
115 	uint16_t num_vcpus;
116 	struct profiling_vcpu_pcpu_map cpu_map[MAX_VCPUS_PER_VM];
117 };
118 
119 struct profiling_vm_info_list {
120 	uint16_t num_vms;
121 	struct profiling_vm_info vm_list[CONFIG_MAX_VM_NUM+1];
122 };
123 
124 struct sw_msr_op_info {
125 	uint64_t core_msr[MAX_MSR_LIST_NUM];
126 	uint32_t cpu_id;
127 	uint32_t valid_entries;
128 	uint16_t sample_id;
129 };
130 
131 struct profiling_msr_op {
132 	/* value to write or location to write into */
133 	uint64_t value;
134 	/* MSR address to read/write; last entry will have value of -1 */
135 	uint32_t msr_id;
136 	/* parameter; usage depends on operation */
137 	uint16_t param;
138 	uint8_t	msr_op_type;
139 	uint8_t	reg_type;
140 };
141 
142 struct profiling_msr_ops_list {
143 	int32_t	collector_id;
144 	uint32_t num_entries;
145 	int32_t	msr_op_state;
146 	struct profiling_msr_op entries[MAX_MSR_LIST_NUM];
147 };
148 struct profiling_pmi_config {
149 	uint32_t num_groups;
150 	uint32_t trigger_count;
151 	struct profiling_msr_op initial_list[MAX_GROUP_NUM][MAX_MSR_LIST_NUM];
152 	struct profiling_msr_op start_list[MAX_GROUP_NUM][MAX_MSR_LIST_NUM];
153 	struct profiling_msr_op stop_list[MAX_GROUP_NUM][MAX_MSR_LIST_NUM];
154 	struct profiling_msr_op entry_list[MAX_GROUP_NUM][MAX_MSR_LIST_NUM];
155 	struct profiling_msr_op exit_list[MAX_GROUP_NUM][MAX_MSR_LIST_NUM];
156 };
157 
158 struct profiling_vmsw_config {
159 	int32_t collector_id;
160 	struct profiling_msr_op initial_list[MAX_MSR_LIST_NUM];
161 	struct profiling_msr_op entry_list[MAX_MSR_LIST_NUM];
162 	struct profiling_msr_op exit_list[MAX_MSR_LIST_NUM];
163 };
164 
165 struct guest_vm_info {
166 	uint64_t vmenter_tsc;
167 	uint64_t vmexit_tsc;
168 	uint64_t vmexit_reason;
169 	uint64_t guest_rip;
170 	uint64_t guest_rflags;
171 	uint64_t guest_cs;
172 	uint16_t guest_vm_id;
173 	int32_t external_vector;
174 };
175 
176 struct profiling_status {
177 	uint32_t samples_logged;
178 	uint32_t samples_dropped;
179 };
180 
181 struct sep_state {
182 	sep_pmu_state pmu_state;
183 
184 	uint32_t current_pmi_group_id;
185 	uint32_t num_pmi_groups;
186 
187 	struct profiling_msr_op
188 		pmi_initial_msr_list[MAX_GROUP_NUM][MAX_MSR_LIST_NUM];
189 	struct profiling_msr_op
190 		pmi_start_msr_list[MAX_GROUP_NUM][MAX_MSR_LIST_NUM];
191 	struct profiling_msr_op
192 		pmi_stop_msr_list[MAX_GROUP_NUM][MAX_MSR_LIST_NUM];
193 	struct profiling_msr_op
194 		pmi_entry_msr_list[MAX_GROUP_NUM][MAX_MSR_LIST_NUM];
195 	struct profiling_msr_op
196 		pmi_exit_msr_list[MAX_GROUP_NUM][MAX_MSR_LIST_NUM];
197 
198 	uint32_t current_vmsw_group_id;
199 	uint32_t num_msw_groups;
200 	struct profiling_msr_op
201 		vmsw_initial_msr_list[MAX_GROUP_NUM][MAX_MSR_LIST_NUM];
202 	struct profiling_msr_op
203 		vmsw_entry_msr_list[MAX_GROUP_NUM][MAX_MSR_LIST_NUM];
204 	struct profiling_msr_op
205 		vmsw_exit_msr_list[MAX_GROUP_NUM][MAX_MSR_LIST_NUM];
206 
207 	/* sep handling statistics */
208 	uint32_t samples_logged;
209 	uint32_t samples_dropped;
210 	uint32_t valid_pmi_count;
211 	uint32_t total_pmi_count;
212 	uint32_t total_vmexit_count;
213 	uint32_t frozen_well;
214 	uint32_t frozen_delayed;
215 	uint32_t nofrozen_pmi;
216 
217 	struct msr_store_entry vmexit_msr_list[MAX_PROFILING_MSR_STORE_NUM + MAX_HV_MSR_LIST_NUM];
218 	uint32_t vmexit_msr_cnt;
219 	uint64_t guest_debugctl_value;
220 	uint64_t saved_debugctl_value;
221 } __aligned(8);
222 
223 struct data_header {
224 	int32_t collector_id;
225 	uint16_t cpu_id;
226 	uint16_t data_type;
227 	uint64_t tsc;
228 	uint64_t payload_size;
229 	uint64_t reserved;
230 } __aligned(SEP_BUF_ENTRY_SIZE);
231 
232 #define DATA_HEADER_SIZE ((uint64_t)sizeof(struct data_header))
233 struct core_pmu_sample {
234 	/* context where PMI is triggered */
235 	uint16_t os_id;
236 	/* reserved */
237 	uint16_t reserved;
238 	/* the task id */
239 	uint32_t task_id;
240 	/* instruction pointer */
241 	uint64_t rip;
242 	/* the task name */
243 	char task[16];
244 	/* physical cpu ID */
245 	uint32_t cpu_id;
246 	/* the process id */
247 	uint32_t process_id;
248 	/* perf global status msr value (for overflow status) */
249 	uint64_t overflow_status;
250 	/* rflags */
251 	uint32_t rflags;
252 	/* code segment */
253 	uint32_t cs;
254 } __aligned(SEP_BUF_ENTRY_SIZE);
255 
256 #define CORE_PMU_SAMPLE_SIZE ((uint64_t)sizeof(struct core_pmu_sample))
257 #define NUM_LBR_ENTRY		32
258 
259 struct lbr_pmu_sample {
260 	/* LBR TOS */
261 	uint64_t lbr_tos;
262 	/* LBR FROM IP */
263 	uint64_t lbr_from_ip[NUM_LBR_ENTRY];
264 	/* LBR TO IP */
265 	uint64_t lbr_to_ip[NUM_LBR_ENTRY];
266 	/* LBR info */
267 	uint64_t lbr_info[NUM_LBR_ENTRY];
268 } __aligned(SEP_BUF_ENTRY_SIZE);
269 
270 #define LBR_PMU_SAMPLE_SIZE ((uint64_t)sizeof(struct lbr_pmu_sample))
271 struct pmu_sample {
272 	/* core pmu sample */
273 	struct core_pmu_sample csample;
274 	/* lbr pmu sample */
275 	struct lbr_pmu_sample lsample;
276 } __aligned(SEP_BUF_ENTRY_SIZE);
277 
278 struct vm_switch_trace {
279 	uint64_t vm_enter_tsc;
280 	uint64_t vm_exit_tsc;
281 	uint64_t vm_exit_reason;
282 	uint16_t os_id;
283 	uint16_t reserved;
284 }__aligned(SEP_BUF_ENTRY_SIZE);
285 
286 #define VM_SWITCH_TRACE_SIZE ((uint64_t)sizeof(struct vm_switch_trace))
287 /*
288  * Wrapper containing  SEP sampling/profiling related data structures
289  */
290 struct profiling_info_wrapper {
291 	struct profiling_msr_ops_list *msr_node;
292 	struct sep_state s_state;
293 	struct guest_vm_info vm_info;
294 	ipi_commands ipi_cmd;
295 	struct pmu_sample p_sample;
296 	struct vm_switch_trace vm_trace;
297 	socwatch_state soc_state;
298 	struct sw_msr_op_info sw_msr_info;
299 	spinlock_t sw_lock;
300 } __aligned(8);
301 
302 int32_t profiling_get_version_info(struct acrn_vm *vm, uint64_t addr);
303 int32_t profiling_get_pcpu_id(struct acrn_vm *vm, uint64_t addr);
304 int32_t profiling_msr_ops_all_cpus(struct acrn_vm *vm, uint64_t addr);
305 int32_t profiling_vm_list_info(struct acrn_vm *vm, uint64_t addr);
306 int32_t profiling_get_control(struct acrn_vm *vm, uint64_t addr);
307 int32_t profiling_set_control(struct acrn_vm *vm, uint64_t addr);
308 int32_t profiling_configure_pmi(struct acrn_vm *vm, uint64_t addr);
309 int32_t profiling_configure_vmsw(struct acrn_vm *vm, uint64_t addr);
310 void profiling_ipi_handler(void *data);
311 int32_t profiling_get_status_info(struct acrn_vm *vm, uint64_t addr);
312 
313 #endif
314 
315 #endif /* PROFILING_INTERNAL_H */
316