Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Type definitions for the Microsoft Hypervisor.
4 */
5#ifndef _HV_HVHDK_MINI_H
6#define _HV_HVHDK_MINI_H
7
8#include "hvgdk_mini.h"
9
10/*
11 * Doorbell connection_info flags.
12 */
13#define HV_DOORBELL_FLAG_TRIGGER_SIZE_MASK 0x00000007
14#define HV_DOORBELL_FLAG_TRIGGER_SIZE_ANY 0x00000000
15#define HV_DOORBELL_FLAG_TRIGGER_SIZE_BYTE 0x00000001
16#define HV_DOORBELL_FLAG_TRIGGER_SIZE_WORD 0x00000002
17#define HV_DOORBELL_FLAG_TRIGGER_SIZE_DWORD 0x00000003
18#define HV_DOORBELL_FLAG_TRIGGER_SIZE_QWORD 0x00000004
19#define HV_DOORBELL_FLAG_TRIGGER_ANY_VALUE 0x80000000
20
21/* Each generic set contains 64 elements */
22#define HV_GENERIC_SET_SHIFT (6)
23#define HV_GENERIC_SET_MASK (63)
24
25enum hv_generic_set_format {
26 HV_GENERIC_SET_SPARSE_4K,
27 HV_GENERIC_SET_ALL,
28};
29#define HV_GENERIC_SET_FORMAT hv_generic_set_format
30
31enum hv_scheduler_type {
32 HV_SCHEDULER_TYPE_LP = 1, /* Classic scheduler w/o SMT */
33 HV_SCHEDULER_TYPE_LP_SMT = 2, /* Classic scheduler w/ SMT */
34 HV_SCHEDULER_TYPE_CORE_SMT = 3, /* Core scheduler */
35 HV_SCHEDULER_TYPE_ROOT = 4, /* Root / integrated scheduler */
36 HV_SCHEDULER_TYPE_MAX
37};
38
39/* HV_STATS_AREA_TYPE */
40enum hv_stats_area_type {
41 HV_STATS_AREA_SELF = 0,
42 HV_STATS_AREA_PARENT = 1,
43 HV_STATS_AREA_INTERNAL = 2,
44 HV_STATS_AREA_COUNT
45};
46
47enum hv_stats_object_type {
48 HV_STATS_OBJECT_HYPERVISOR = 0x00000001,
49 HV_STATS_OBJECT_LOGICAL_PROCESSOR = 0x00000002,
50 HV_STATS_OBJECT_PARTITION = 0x00010001,
51 HV_STATS_OBJECT_VP = 0x00010002
52};
53
54union hv_stats_object_identity {
55 /* hv_stats_hypervisor */
56 struct {
57 u8 reserved[15];
58 u8 stats_area_type;
59 } __packed hv;
60
61 /* hv_stats_logical_processor */
62 struct {
63 u32 lp_index;
64 u8 reserved[11];
65 u8 stats_area_type;
66 } __packed lp;
67
68 /* hv_stats_partition */
69 struct {
70 u64 partition_id;
71 u8 reserved[7];
72 u8 stats_area_type;
73 } __packed partition;
74
75 /* hv_stats_vp */
76 struct {
77 u64 partition_id;
78 u32 vp_index;
79 u16 flags;
80 u8 reserved;
81 u8 stats_area_type;
82 } __packed vp;
83};
84
85enum hv_partition_property_code {
86 /* Privilege properties */
87 HV_PARTITION_PROPERTY_PRIVILEGE_FLAGS = 0x00010000,
88 HV_PARTITION_PROPERTY_SYNTHETIC_PROC_FEATURES = 0x00010001,
89
90 /* Resource properties */
91 HV_PARTITION_PROPERTY_GPA_PAGE_ACCESS_TRACKING = 0x00050005,
92 HV_PARTITION_PROPERTY_UNIMPLEMENTED_MSR_ACTION = 0x00050017,
93
94 /* Compatibility properties */
95 HV_PARTITION_PROPERTY_PROCESSOR_XSAVE_FEATURES = 0x00060002,
96 HV_PARTITION_PROPERTY_XSAVE_STATES = 0x00060007,
97 HV_PARTITION_PROPERTY_MAX_XSAVE_DATA_SIZE = 0x00060008,
98 HV_PARTITION_PROPERTY_PROCESSOR_CLOCK_FREQUENCY = 0x00060009,
99
100 /* Extended properties with larger property values */
101 HV_PARTITION_PROPERTY_VMM_CAPABILITIES = 0x00090007,
102};
103
104#define HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT 1
105#define HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT 59
106
107struct hv_partition_property_vmm_capabilities {
108 u16 bank_count;
109 u16 reserved[3];
110 union {
111 u64 as_uint64[HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT];
112 struct {
113 u64 map_gpa_preserve_adjustable: 1;
114 u64 vmm_can_provide_overlay_gpfn: 1;
115 u64 vp_affinity_property: 1;
116#if IS_ENABLED(CONFIG_ARM64)
117 u64 vmm_can_provide_gic_overlay_locations: 1;
118#else
119 u64 reservedbit3: 1;
120#endif
121 u64 assignable_synthetic_proc_features: 1;
122 u64 reserved0: HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT;
123 } __packed;
124 };
125} __packed;
126
127enum hv_snp_status {
128 HV_SNP_STATUS_NONE = 0,
129 HV_SNP_STATUS_AVAILABLE = 1,
130 HV_SNP_STATUS_INCOMPATIBLE = 2,
131 HV_SNP_STATUS_PSP_UNAVAILABLE = 3,
132 HV_SNP_STATUS_PSP_INIT_FAILED = 4,
133 HV_SNP_STATUS_PSP_BAD_FW_VERSION = 5,
134 HV_SNP_STATUS_BAD_CONFIGURATION = 6,
135 HV_SNP_STATUS_PSP_FW_UPDATE_IN_PROGRESS = 7,
136 HV_SNP_STATUS_PSP_RB_INIT_FAILED = 8,
137 HV_SNP_STATUS_PSP_PLATFORM_STATUS_FAILED = 9,
138 HV_SNP_STATUS_PSP_INIT_LATE_FAILED = 10,
139};
140
141enum hv_system_property {
142 /* Add more values when needed */
143 HV_SYSTEM_PROPERTY_SLEEP_STATE = 3,
144 HV_SYSTEM_PROPERTY_SCHEDULER_TYPE = 15,
145 HV_DYNAMIC_PROCESSOR_FEATURE_PROPERTY = 21,
146 HV_SYSTEM_PROPERTY_CRASHDUMPAREA = 47,
147};
148
149#define HV_PFN_RANGE_PGBITS 24 /* HV_SPA_PAGE_RANGE_ADDITIONAL_PAGES_BITS */
150union hv_pfn_range { /* HV_SPA_PAGE_RANGE */
151 u64 as_uint64;
152 struct {
153 /* 39:0: base pfn. 63:40: additional pages */
154 u64 base_pfn : 64 - HV_PFN_RANGE_PGBITS;
155 u64 add_pfns : HV_PFN_RANGE_PGBITS;
156 } __packed;
157};
158
159enum hv_sleep_state {
160 HV_SLEEP_STATE_S1 = 1,
161 HV_SLEEP_STATE_S2 = 2,
162 HV_SLEEP_STATE_S3 = 3,
163 HV_SLEEP_STATE_S4 = 4,
164 HV_SLEEP_STATE_S5 = 5,
165 /*
166 * After hypervisor has received this, any follow up sleep
167 * state registration requests will be rejected.
168 */
169 HV_SLEEP_STATE_LOCK = 6
170};
171
172enum hv_dynamic_processor_feature_property {
173 /* Add more values when needed */
174 HV_X64_DYNAMIC_PROCESSOR_FEATURE_MAX_ENCRYPTED_PARTITIONS = 13,
175 HV_X64_DYNAMIC_PROCESSOR_FEATURE_SNP_STATUS = 16,
176};
177
178struct hv_input_get_system_property {
179 u32 property_id; /* enum hv_system_property */
180 union {
181 u32 as_uint32;
182#if IS_ENABLED(CONFIG_X86)
183 /* enum hv_dynamic_processor_feature_property */
184 u32 hv_processor_feature;
185#endif
186 /* More fields to be filled in when needed */
187 };
188} __packed;
189
190struct hv_output_get_system_property {
191 union {
192 u32 scheduler_type; /* enum hv_scheduler_type */
193#if IS_ENABLED(CONFIG_X86)
194 u64 hv_processor_feature_value;
195#endif
196 union hv_pfn_range hv_cda_info; /* CrashdumpAreaAddress */
197 u64 hv_tramp_pa; /* CrashdumpTrampolineAddress */
198 };
199} __packed;
200
201struct hv_sleep_state_info {
202 u32 sleep_state; /* enum hv_sleep_state */
203 u8 pm1a_slp_typ;
204 u8 pm1b_slp_typ;
205} __packed;
206
207struct hv_input_set_system_property {
208 u32 property_id; /* enum hv_system_property */
209 u32 reserved;
210 union {
211 /* More fields to be filled in when needed */
212 struct hv_sleep_state_info set_sleep_state_info;
213
214 /*
215 * Add a reserved field to ensure the union is 8-byte aligned as
216 * existing members may not be. This is a temporary measure
217 * until all remaining members are added.
218 */
219 u64 reserved0[8];
220 };
221} __packed;
222
223struct hv_input_enter_sleep_state { /* HV_INPUT_ENTER_SLEEP_STATE */
224 u32 sleep_state; /* enum hv_sleep_state */
225} __packed;
226
227struct hv_input_map_stats_page {
228 u32 type; /* enum hv_stats_object_type */
229 u32 padding;
230 union hv_stats_object_identity identity;
231} __packed;
232
233struct hv_input_map_stats_page2 {
234 u32 type; /* enum hv_stats_object_type */
235 u32 padding;
236 union hv_stats_object_identity identity;
237 u64 map_location;
238} __packed;
239
240struct hv_output_map_stats_page {
241 u64 map_location;
242} __packed;
243
244struct hv_input_unmap_stats_page {
245 u32 type; /* enum hv_stats_object_type */
246 u32 padding;
247 union hv_stats_object_identity identity;
248} __packed;
249
250struct hv_proximity_domain_flags {
251 u32 proximity_preferred : 1;
252 u32 reserved : 30;
253 u32 proximity_info_valid : 1;
254} __packed;
255
256struct hv_proximity_domain_info {
257 u32 domain_id;
258 struct hv_proximity_domain_flags flags;
259} __packed;
260
261/* HvDepositMemory hypercall */
262struct hv_deposit_memory { /* HV_INPUT_DEPOSIT_MEMORY */
263 u64 partition_id;
264 u64 gpa_page_list[];
265} __packed;
266
267struct hv_input_withdraw_memory {
268 u64 partition_id;
269 struct hv_proximity_domain_info proximity_domain_info;
270} __packed;
271
272struct hv_output_withdraw_memory {
273 DECLARE_FLEX_ARRAY(u64, gpa_page_list);
274} __packed;
275
276/* HV Map GPA (Guest Physical Address) Flags */
277#define HV_MAP_GPA_PERMISSIONS_NONE 0x0
278#define HV_MAP_GPA_READABLE 0x1
279#define HV_MAP_GPA_WRITABLE 0x2
280#define HV_MAP_GPA_KERNEL_EXECUTABLE 0x4
281#define HV_MAP_GPA_USER_EXECUTABLE 0x8
282#define HV_MAP_GPA_EXECUTABLE 0xC
283#define HV_MAP_GPA_PERMISSIONS_MASK 0xF
284#define HV_MAP_GPA_ADJUSTABLE 0x8000
285#define HV_MAP_GPA_NO_ACCESS 0x10000
286#define HV_MAP_GPA_NOT_CACHED 0x200000
287#define HV_MAP_GPA_LARGE_PAGE 0x80000000
288
289struct hv_input_map_gpa_pages {
290 u64 target_partition_id;
291 u64 target_gpa_base;
292 u32 map_flags;
293 u32 padding;
294 u64 source_gpa_page_list[];
295} __packed;
296
297union hv_gpa_page_access_state_flags {
298 struct {
299 u64 clear_accessed : 1;
300 u64 set_accessed : 1;
301 u64 clear_dirty : 1;
302 u64 set_dirty : 1;
303 u64 reserved : 60;
304 } __packed;
305 u64 as_uint64;
306};
307
308struct hv_input_get_gpa_pages_access_state {
309 u64 partition_id;
310 union hv_gpa_page_access_state_flags flags;
311 u64 hv_gpa_page_number;
312} __packed;
313
314union hv_gpa_page_access_state {
315 struct {
316 u8 accessed : 1;
317 u8 dirty : 1;
318 u8 reserved: 6;
319 };
320 u8 as_uint8;
321} __packed;
322
323enum hv_crashdump_action {
324 HV_CRASHDUMP_NONE = 0,
325 HV_CRASHDUMP_SUSPEND_ALL_VPS,
326 HV_CRASHDUMP_PREPARE_FOR_STATE_SAVE,
327 HV_CRASHDUMP_STATE_SAVED,
328 HV_CRASHDUMP_ENTRY,
329};
330
331struct hv_partition_event_root_crashdump_input {
332 u32 crashdump_action; /* enum hv_crashdump_action */
333} __packed;
334
335struct hv_input_disable_hyp_ex { /* HV_X64_INPUT_DISABLE_HYPERVISOR_EX */
336 u64 rip;
337 u64 arg;
338} __packed;
339
340struct hv_crashdump_area { /* HV_CRASHDUMP_AREA */
341 u32 version;
342 union {
343 u32 flags_as_uint32;
344 struct {
345 u32 cda_valid : 1;
346 u32 cda_unused : 31;
347 } __packed;
348 };
349 /* more unused fields */
350} __packed;
351
352union hv_partition_event_input {
353 struct hv_partition_event_root_crashdump_input crashdump_input;
354};
355
356enum hv_partition_event {
357 HV_PARTITION_EVENT_ROOT_CRASHDUMP = 2,
358};
359
360struct hv_input_notify_partition_event {
361 u32 event; /* enum hv_partition_event */
362 union hv_partition_event_input input;
363} __packed;
364
365struct hv_lp_startup_status {
366 u64 hv_status;
367 u64 substatus1;
368 u64 substatus2;
369 u64 substatus3;
370 u64 substatus4;
371 u64 substatus5;
372 u64 substatus6;
373} __packed;
374
375struct hv_input_add_logical_processor {
376 u32 lp_index;
377 u32 apic_id;
378 struct hv_proximity_domain_info proximity_domain_info;
379} __packed;
380
381struct hv_output_add_logical_processor {
382 struct hv_lp_startup_status startup_status;
383} __packed;
384
385enum { /* HV_SUBNODE_TYPE */
386 HV_SUBNODE_ANY = 0,
387 HV_SUBNODE_SOCKET,
388 HV_SUBNODE_CLUSTER,
389 HV_SUBNODE_L3,
390 HV_SUBNODE_COUNT,
391 HV_SUBNODE_INVALID = -1
392};
393
394struct hv_create_vp { /* HV_INPUT_CREATE_VP */
395 u64 partition_id;
396 u32 vp_index;
397 u8 padding[3];
398 u8 subnode_type;
399 u64 subnode_id;
400 struct hv_proximity_domain_info proximity_domain_info;
401 u64 flags;
402} __packed;
403
404/* HV_INTERRUPT_TRIGGER_MODE */
405enum hv_interrupt_trigger_mode {
406 HV_INTERRUPT_TRIGGER_MODE_EDGE = 0,
407 HV_INTERRUPT_TRIGGER_MODE_LEVEL = 1,
408};
409
410/* HV_DEVICE_INTERRUPT_DESCRIPTOR */
411struct hv_device_interrupt_descriptor {
412 u32 interrupt_type;
413 u32 trigger_mode;
414 u32 vector_count;
415 u32 reserved;
416 struct hv_device_interrupt_target target;
417} __packed;
418
419/* HV_INPUT_MAP_DEVICE_INTERRUPT */
420struct hv_input_map_device_interrupt {
421 u64 partition_id;
422 u64 device_id;
423 u32 flags;
424 u32 base_irt_idx;
425 struct hv_interrupt_entry logical_interrupt_entry;
426 struct hv_device_interrupt_descriptor interrupt_descriptor;
427} __packed;
428
429/* HV_OUTPUT_MAP_DEVICE_INTERRUPT */
430struct hv_output_map_device_interrupt {
431 struct hv_interrupt_entry interrupt_entry;
432 u64 ext_status_deprecated[5];
433} __packed;
434
435/* HV_INPUT_UNMAP_DEVICE_INTERRUPT */
436struct hv_input_unmap_device_interrupt {
437 u64 partition_id;
438 u64 device_id;
439 struct hv_interrupt_entry interrupt_entry;
440 u32 flags;
441} __packed;
442
443#define HV_SOURCE_SHADOW_NONE 0x0
444#define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE 0x1
445
446struct hv_send_ipi_ex { /* HV_INPUT_SEND_SYNTHETIC_CLUSTER_IPI_EX */
447 u32 vector;
448 u32 reserved;
449 struct hv_vpset vp_set;
450} __packed;
451
452typedef u16 hv_pci_rid; /* HV_PCI_RID */
453typedef u16 hv_pci_segment; /* HV_PCI_SEGMENT */
454typedef u64 hv_logical_device_id;
455union hv_pci_bdf { /* HV_PCI_BDF */
456 u16 as_uint16;
457
458 struct {
459 u8 function : 3;
460 u8 device : 5;
461 u8 bus;
462 };
463} __packed;
464
465union hv_pci_bus_range {
466 u16 as_uint16;
467
468 struct {
469 u8 subordinate_bus;
470 u8 secondary_bus;
471 };
472} __packed;
473
474enum hv_device_type { /* HV_DEVICE_TYPE */
475 HV_DEVICE_TYPE_LOGICAL = 0,
476 HV_DEVICE_TYPE_PCI = 1,
477 HV_DEVICE_TYPE_IOAPIC = 2,
478 HV_DEVICE_TYPE_ACPI = 3,
479};
480
481union hv_device_id { /* HV_DEVICE_ID */
482 u64 as_uint64;
483
484 struct {
485 u64 reserved0 : 62;
486 u64 device_type : 2;
487 };
488
489 /* HV_DEVICE_TYPE_LOGICAL */
490 struct {
491 u64 id : 62;
492 u64 device_type : 2;
493 } logical;
494
495 /* HV_DEVICE_TYPE_PCI */
496 struct {
497 union {
498 hv_pci_rid rid;
499 union hv_pci_bdf bdf;
500 };
501
502 hv_pci_segment segment;
503 union hv_pci_bus_range shadow_bus_range;
504
505 u16 phantom_function_bits : 2;
506 u16 source_shadow : 1;
507
508 u16 rsvdz0 : 11;
509 u16 device_type : 2;
510 } pci;
511
512 /* HV_DEVICE_TYPE_IOAPIC */
513 struct {
514 u8 ioapic_id;
515 u8 rsvdz0;
516 u16 rsvdz1;
517 u16 rsvdz2;
518
519 u16 rsvdz3 : 14;
520 u16 device_type : 2;
521 } ioapic;
522
523 /* HV_DEVICE_TYPE_ACPI */
524 struct {
525 u32 input_mapping_base;
526 u32 input_mapping_count : 30;
527 u32 device_type : 2;
528 } acpi;
529} __packed;
530
531#endif /* _HV_HVHDK_MINI_H */