aboutsummaryrefslogtreecommitdiffstats
path: root/include/hyperv/hvhdk_mini.h
blob: 41a29bf8ec145ca947577c3dfb6a7ed9ab61453b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
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
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Type definitions for the Microsoft Hypervisor.
 */
#ifndef _HV_HVHDK_MINI_H
#define _HV_HVHDK_MINI_H

#include "hvgdk_mini.h"

/*
 * Doorbell connection_info flags.
 */
#define HV_DOORBELL_FLAG_TRIGGER_SIZE_MASK  0x00000007
#define HV_DOORBELL_FLAG_TRIGGER_SIZE_ANY   0x00000000
#define HV_DOORBELL_FLAG_TRIGGER_SIZE_BYTE  0x00000001
#define HV_DOORBELL_FLAG_TRIGGER_SIZE_WORD  0x00000002
#define HV_DOORBELL_FLAG_TRIGGER_SIZE_DWORD 0x00000003
#define HV_DOORBELL_FLAG_TRIGGER_SIZE_QWORD 0x00000004
#define HV_DOORBELL_FLAG_TRIGGER_ANY_VALUE  0x80000000

/* Each generic set contains 64 elements */
#define HV_GENERIC_SET_SHIFT		(6)
#define HV_GENERIC_SET_MASK		(63)

enum hv_generic_set_format {
	HV_GENERIC_SET_SPARSE_4K,
	HV_GENERIC_SET_ALL,
};
#define HV_GENERIC_SET_FORMAT hv_generic_set_format

enum hv_scheduler_type {
	HV_SCHEDULER_TYPE_LP		= 1, /* Classic scheduler w/o SMT */
	HV_SCHEDULER_TYPE_LP_SMT	= 2, /* Classic scheduler w/ SMT */
	HV_SCHEDULER_TYPE_CORE_SMT	= 3, /* Core scheduler */
	HV_SCHEDULER_TYPE_ROOT		= 4, /* Root / integrated scheduler */
	HV_SCHEDULER_TYPE_MAX
};

/* HV_STATS_AREA_TYPE */
enum hv_stats_area_type {
	HV_STATS_AREA_SELF = 0,
	HV_STATS_AREA_PARENT = 1,
	HV_STATS_AREA_INTERNAL = 2,
	HV_STATS_AREA_COUNT
};

enum hv_stats_object_type {
	HV_STATS_OBJECT_HYPERVISOR		= 0x00000001,
	HV_STATS_OBJECT_LOGICAL_PROCESSOR	= 0x00000002,
	HV_STATS_OBJECT_PARTITION		= 0x00010001,
	HV_STATS_OBJECT_VP			= 0x00010002
};

union hv_stats_object_identity {
	/* hv_stats_hypervisor */
	struct {
		u8 reserved[15];
		u8 stats_area_type;
	} __packed hv;

	/* hv_stats_logical_processor */
	struct {
		u32 lp_index;
		u8 reserved[11];
		u8 stats_area_type;
	} __packed lp;

	/* hv_stats_partition */
	struct {
		u64 partition_id;
		u8  reserved[7];
		u8  stats_area_type;
	} __packed partition;

	/* hv_stats_vp */
	struct {
		u64 partition_id;
		u32 vp_index;
		u16 flags;
		u8  reserved;
		u8  stats_area_type;
	} __packed vp;
};

enum hv_partition_property_code {
	/* Privilege properties */
	HV_PARTITION_PROPERTY_PRIVILEGE_FLAGS			= 0x00010000,
	HV_PARTITION_PROPERTY_SYNTHETIC_PROC_FEATURES		= 0x00010001,

	/* Resource properties */
	HV_PARTITION_PROPERTY_GPA_PAGE_ACCESS_TRACKING		= 0x00050005,
	HV_PARTITION_PROPERTY_UNIMPLEMENTED_MSR_ACTION		= 0x00050017,

	/* Compatibility properties */
	HV_PARTITION_PROPERTY_PROCESSOR_XSAVE_FEATURES		= 0x00060002,
	HV_PARTITION_PROPERTY_XSAVE_STATES                      = 0x00060007,
	HV_PARTITION_PROPERTY_MAX_XSAVE_DATA_SIZE		= 0x00060008,
	HV_PARTITION_PROPERTY_PROCESSOR_CLOCK_FREQUENCY		= 0x00060009,

	/* Extended properties with larger property values */
	HV_PARTITION_PROPERTY_VMM_CAPABILITIES			= 0x00090007,
};

#define HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT		1
#define HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT	59

struct hv_partition_property_vmm_capabilities {
	u16 bank_count;
	u16 reserved[3];
	union {
		u64 as_uint64[HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT];
		struct {
			u64 map_gpa_preserve_adjustable: 1;
			u64 vmm_can_provide_overlay_gpfn: 1;
			u64 vp_affinity_property: 1;
#if IS_ENABLED(CONFIG_ARM64)
			u64 vmm_can_provide_gic_overlay_locations: 1;
#else
			u64 reservedbit3: 1;
#endif
			u64 assignable_synthetic_proc_features: 1;
			u64 reserved0: HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT;
		} __packed;
	};
} __packed;

enum hv_snp_status {
	HV_SNP_STATUS_NONE = 0,
	HV_SNP_STATUS_AVAILABLE = 1,
	HV_SNP_STATUS_INCOMPATIBLE = 2,
	HV_SNP_STATUS_PSP_UNAVAILABLE = 3,
	HV_SNP_STATUS_PSP_INIT_FAILED = 4,
	HV_SNP_STATUS_PSP_BAD_FW_VERSION = 5,
	HV_SNP_STATUS_BAD_CONFIGURATION = 6,
	HV_SNP_STATUS_PSP_FW_UPDATE_IN_PROGRESS = 7,
	HV_SNP_STATUS_PSP_RB_INIT_FAILED = 8,
	HV_SNP_STATUS_PSP_PLATFORM_STATUS_FAILED = 9,
	HV_SNP_STATUS_PSP_INIT_LATE_FAILED = 10,
};

enum hv_system_property {
	/* Add more values when needed */
	HV_SYSTEM_PROPERTY_SLEEP_STATE = 3,
	HV_SYSTEM_PROPERTY_SCHEDULER_TYPE = 15,
	HV_DYNAMIC_PROCESSOR_FEATURE_PROPERTY = 21,
	HV_SYSTEM_PROPERTY_CRASHDUMPAREA = 47,
};

#define HV_PFN_RANGE_PGBITS 24  /* HV_SPA_PAGE_RANGE_ADDITIONAL_PAGES_BITS */
union hv_pfn_range {            /* HV_SPA_PAGE_RANGE */
	u64 as_uint64;
	struct {
		/* 39:0: base pfn.  63:40: additional pages */
		u64 base_pfn : 64 - HV_PFN_RANGE_PGBITS;
		u64 add_pfns : HV_PFN_RANGE_PGBITS;
	} __packed;
};

enum hv_sleep_state {
	HV_SLEEP_STATE_S1 = 1,
	HV_SLEEP_STATE_S2 = 2,
	HV_SLEEP_STATE_S3 = 3,
	HV_SLEEP_STATE_S4 = 4,
	HV_SLEEP_STATE_S5 = 5,
	/*
	 * After hypervisor has received this, any follow up sleep
	 * state registration requests will be rejected.
	 */
	HV_SLEEP_STATE_LOCK = 6
};

enum hv_dynamic_processor_feature_property {
	/* Add more values when needed */
	HV_X64_DYNAMIC_PROCESSOR_FEATURE_MAX_ENCRYPTED_PARTITIONS = 13,
	HV_X64_DYNAMIC_PROCESSOR_FEATURE_SNP_STATUS = 16,
};

struct hv_input_get_system_property {
	u32 property_id; /* enum hv_system_property */
	union {
		u32 as_uint32;
#if IS_ENABLED(CONFIG_X86)
		/* enum hv_dynamic_processor_feature_property */
		u32 hv_processor_feature;
#endif
		/* More fields to be filled in when needed */
	};
} __packed;

struct hv_output_get_system_property {
	union {
		u32 scheduler_type; /* enum hv_scheduler_type */
#if IS_ENABLED(CONFIG_X86)
		u64 hv_processor_feature_value;
#endif
		union hv_pfn_range hv_cda_info; /* CrashdumpAreaAddress */
		u64 hv_tramp_pa;                /* CrashdumpTrampolineAddress */
	};
} __packed;

struct hv_sleep_state_info {
	u32 sleep_state; /* enum hv_sleep_state */
	u8 pm1a_slp_typ;
	u8 pm1b_slp_typ;
} __packed;

struct hv_input_set_system_property {
	u32 property_id; /* enum hv_system_property */
	u32 reserved;
	union {
		/* More fields to be filled in when needed */
		struct hv_sleep_state_info set_sleep_state_info;

		/*
		 * Add a reserved field to ensure the union is 8-byte aligned as
		 * existing members may not be. This is a temporary measure
		 * until all remaining members are added.
		 */
		 u64 reserved0[8];
	};
} __packed;

struct hv_input_enter_sleep_state {     /* HV_INPUT_ENTER_SLEEP_STATE */
	u32 sleep_state;        /* enum hv_sleep_state */
} __packed;

struct hv_input_map_stats_page {
	u32 type; /* enum hv_stats_object_type */
	u32 padding;
	union hv_stats_object_identity identity;
} __packed;

struct hv_input_map_stats_page2 {
	u32 type; /* enum hv_stats_object_type */
	u32 padding;
	union hv_stats_object_identity identity;
	u64 map_location;
} __packed;

struct hv_output_map_stats_page {
	u64 map_location;
} __packed;

struct hv_input_unmap_stats_page {
	u32 type; /* enum hv_stats_object_type */
	u32 padding;
	union hv_stats_object_identity identity;
} __packed;

struct hv_proximity_domain_flags {
	u32 proximity_preferred : 1;
	u32 reserved : 30;
	u32 proximity_info_valid : 1;
} __packed;

struct hv_proximity_domain_info {
	u32 domain_id;
	struct hv_proximity_domain_flags flags;
} __packed;

/* HvDepositMemory hypercall */
struct hv_deposit_memory {	/* HV_INPUT_DEPOSIT_MEMORY */
	u64 partition_id;
	u64 gpa_page_list[];
} __packed;

struct hv_input_withdraw_memory {
	u64 partition_id;
	struct hv_proximity_domain_info proximity_domain_info;
} __packed;

struct hv_output_withdraw_memory {
	DECLARE_FLEX_ARRAY(u64, gpa_page_list);
} __packed;

/* HV Map GPA (Guest Physical Address) Flags */
#define HV_MAP_GPA_PERMISSIONS_NONE	       0x0
#define HV_MAP_GPA_READABLE		       0x1
#define HV_MAP_GPA_WRITABLE		       0x2
#define HV_MAP_GPA_KERNEL_EXECUTABLE	       0x4
#define HV_MAP_GPA_USER_EXECUTABLE	       0x8
#define HV_MAP_GPA_EXECUTABLE		       0xC
#define HV_MAP_GPA_PERMISSIONS_MASK	       0xF
#define HV_MAP_GPA_ADJUSTABLE		    0x8000
#define HV_MAP_GPA_NO_ACCESS		   0x10000
#define HV_MAP_GPA_NOT_CACHED		  0x200000
#define HV_MAP_GPA_LARGE_PAGE		0x80000000

struct hv_input_map_gpa_pages {
	u64 target_partition_id;
	u64 target_gpa_base;
	u32 map_flags;
	u32 padding;
	u64 source_gpa_page_list[];
} __packed;

union hv_gpa_page_access_state_flags {
	struct {
		u64 clear_accessed : 1;
		u64 set_accessed : 1;
		u64 clear_dirty : 1;
		u64 set_dirty : 1;
		u64 reserved : 60;
	} __packed;
	u64 as_uint64;
};

struct hv_input_get_gpa_pages_access_state {
	u64  partition_id;
	union hv_gpa_page_access_state_flags flags;
	u64 hv_gpa_page_number;
} __packed;

union hv_gpa_page_access_state {
	struct {
		u8 accessed : 1;
		u8 dirty : 1;
		u8 reserved: 6;
	};
	u8 as_uint8;
} __packed;

enum hv_crashdump_action {
	HV_CRASHDUMP_NONE = 0,
	HV_CRASHDUMP_SUSPEND_ALL_VPS,
	HV_CRASHDUMP_PREPARE_FOR_STATE_SAVE,
	HV_CRASHDUMP_STATE_SAVED,
	HV_CRASHDUMP_ENTRY,
};

struct hv_partition_event_root_crashdump_input {
	u32 crashdump_action; /* enum hv_crashdump_action */
} __packed;

struct hv_input_disable_hyp_ex {   /* HV_X64_INPUT_DISABLE_HYPERVISOR_EX */
	u64 rip;
	u64 arg;
} __packed;

struct hv_crashdump_area {	   /* HV_CRASHDUMP_AREA */
	u32 version;
	union {
		u32 flags_as_uint32;
		struct {
			u32 cda_valid : 1;
			u32 cda_unused : 31;
		} __packed;
	};
	/* more unused fields */
} __packed;

union hv_partition_event_input {
	struct hv_partition_event_root_crashdump_input crashdump_input;
};

enum hv_partition_event {
	HV_PARTITION_EVENT_ROOT_CRASHDUMP = 2,
};

struct hv_input_notify_partition_event {
	u32 event;      /* enum hv_partition_event */
	union hv_partition_event_input input;
} __packed;

struct hv_lp_startup_status {
	u64 hv_status;
	u64 substatus1;
	u64 substatus2;
	u64 substatus3;
	u64 substatus4;
	u64 substatus5;
	u64 substatus6;
} __packed;

struct hv_input_add_logical_processor {
	u32 lp_index;
	u32 apic_id;
	struct hv_proximity_domain_info proximity_domain_info;
} __packed;

struct hv_output_add_logical_processor {
	struct hv_lp_startup_status startup_status;
} __packed;

enum {	/* HV_SUBNODE_TYPE */
	HV_SUBNODE_ANY		= 0,
	HV_SUBNODE_SOCKET,
	HV_SUBNODE_CLUSTER,
	HV_SUBNODE_L3,
	HV_SUBNODE_COUNT,
	HV_SUBNODE_INVALID	= -1
};

struct hv_create_vp {	/* HV_INPUT_CREATE_VP */
	u64 partition_id;
	u32 vp_index;
	u8 padding[3];
	u8 subnode_type;
	u64 subnode_id;
	struct hv_proximity_domain_info proximity_domain_info;
	u64 flags;
} __packed;

/* HV_INTERRUPT_TRIGGER_MODE */
enum hv_interrupt_trigger_mode {
	HV_INTERRUPT_TRIGGER_MODE_EDGE	= 0,
	HV_INTERRUPT_TRIGGER_MODE_LEVEL	= 1,
};

/* HV_DEVICE_INTERRUPT_DESCRIPTOR */
struct hv_device_interrupt_descriptor {
	u32 interrupt_type;
	u32 trigger_mode;
	u32 vector_count;
	u32 reserved;
	struct hv_device_interrupt_target target;
} __packed;

/* HV_INPUT_MAP_DEVICE_INTERRUPT */
struct hv_input_map_device_interrupt {
	u64 partition_id;
	u64 device_id;
	u32 flags;
	u32 base_irt_idx;
	struct hv_interrupt_entry logical_interrupt_entry;
	struct hv_device_interrupt_descriptor interrupt_descriptor;
} __packed;

/* HV_OUTPUT_MAP_DEVICE_INTERRUPT */
struct hv_output_map_device_interrupt {
	struct hv_interrupt_entry interrupt_entry;
	u64 ext_status_deprecated[5];
} __packed;

/* HV_INPUT_UNMAP_DEVICE_INTERRUPT */
struct hv_input_unmap_device_interrupt {
	u64 partition_id;
	u64 device_id;
	struct hv_interrupt_entry interrupt_entry;
	u32 flags;
} __packed;

#define HV_SOURCE_SHADOW_NONE		    0x0
#define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE   0x1

struct hv_send_ipi_ex { /* HV_INPUT_SEND_SYNTHETIC_CLUSTER_IPI_EX */
	u32 vector;
	u32 reserved;
	struct hv_vpset vp_set;
} __packed;

typedef u16 hv_pci_rid;		/* HV_PCI_RID */
typedef u16 hv_pci_segment;	/* HV_PCI_SEGMENT */
typedef u64 hv_logical_device_id;
union hv_pci_bdf {	/* HV_PCI_BDF */
	u16 as_uint16;

	struct {
		u8 function : 3;
		u8 device : 5;
		u8 bus;
	};
} __packed;

union hv_pci_bus_range {
	u16 as_uint16;

	struct {
		u8 subordinate_bus;
		u8 secondary_bus;
	};
} __packed;

enum hv_device_type {		/* HV_DEVICE_TYPE */
	HV_DEVICE_TYPE_LOGICAL	= 0,
	HV_DEVICE_TYPE_PCI	= 1,
	HV_DEVICE_TYPE_IOAPIC	= 2,
	HV_DEVICE_TYPE_ACPI	= 3,
};

union hv_device_id {		/* HV_DEVICE_ID */
	u64 as_uint64;

	struct {
		u64 reserved0 : 62;
		u64 device_type : 2;
	};

	/* HV_DEVICE_TYPE_LOGICAL */
	struct {
		u64 id : 62;
		u64 device_type : 2;
	} logical;

	/* HV_DEVICE_TYPE_PCI */
	struct {
		union {
			hv_pci_rid rid;
			union hv_pci_bdf bdf;
		};

		hv_pci_segment segment;
		union hv_pci_bus_range shadow_bus_range;

		u16 phantom_function_bits : 2;
		u16 source_shadow : 1;

		u16 rsvdz0 : 11;
		u16 device_type : 2;
	} pci;

	/* HV_DEVICE_TYPE_IOAPIC */
	struct {
		u8 ioapic_id;
		u8 rsvdz0;
		u16 rsvdz1;
		u16 rsvdz2;

		u16 rsvdz3 : 14;
		u16 device_type : 2;
	} ioapic;

	/* HV_DEVICE_TYPE_ACPI */
	struct {
		u32 input_mapping_base;
		u32 input_mapping_count : 30;
		u32 device_type : 2;
	} acpi;
} __packed;

#endif /* _HV_HVHDK_MINI_H */