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