1
2
3
4
5
6
7
8
9#ifndef _ASM_GENERIC_HYPERV_TLFS_H
10#define _ASM_GENERIC_HYPERV_TLFS_H
11
12#include <linux/types.h>
13#include <linux/bits.h>
14#include <linux/time64.h>
15
16
17
18
19
20
21
22#define HV_HYP_PAGE_SHIFT 12
23#define HV_HYP_PAGE_SIZE BIT(HV_HYP_PAGE_SHIFT)
24#define HV_HYP_PAGE_MASK (~(HV_HYP_PAGE_SIZE - 1))
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#define HV_MSR_VP_RUNTIME_AVAILABLE BIT(0)
51
52#define HV_MSR_TIME_REF_COUNT_AVAILABLE BIT(1)
53
54#define HV_MSR_SYNIC_AVAILABLE BIT(2)
55
56#define HV_MSR_SYNTIMER_AVAILABLE BIT(3)
57
58#define HV_MSR_APIC_ACCESS_AVAILABLE BIT(4)
59
60#define HV_MSR_HYPERCALL_AVAILABLE BIT(5)
61
62#define HV_MSR_VP_INDEX_AVAILABLE BIT(6)
63
64#define HV_MSR_RESET_AVAILABLE BIT(7)
65
66#define HV_MSR_STAT_PAGES_AVAILABLE BIT(8)
67
68#define HV_MSR_REFERENCE_TSC_AVAILABLE BIT(9)
69
70#define HV_MSR_GUEST_IDLE_AVAILABLE BIT(10)
71
72#define HV_ACCESS_FREQUENCY_MSRS BIT(11)
73
74#define HV_ACCESS_REENLIGHTENMENT BIT(13)
75
76#define HV_ACCESS_TSC_INVARIANT BIT(15)
77
78
79
80
81#define HV_CREATE_PARTITIONS BIT(0)
82#define HV_ACCESS_PARTITION_ID BIT(1)
83#define HV_ACCESS_MEMORY_POOL BIT(2)
84#define HV_ADJUST_MESSAGE_BUFFERS BIT(3)
85#define HV_POST_MESSAGES BIT(4)
86#define HV_SIGNAL_EVENTS BIT(5)
87#define HV_CREATE_PORT BIT(6)
88#define HV_CONNECT_PORT BIT(7)
89#define HV_ACCESS_STATS BIT(8)
90#define HV_DEBUGGING BIT(11)
91#define HV_CPU_MANAGEMENT BIT(12)
92#define HV_ENABLE_EXTENDED_HYPERCALLS BIT(20)
93#define HV_ISOLATION BIT(22)
94
95
96
97
98struct ms_hyperv_tsc_page {
99 volatile u32 tsc_sequence;
100 u32 reserved1;
101 volatile u64 tsc_scale;
102 volatile s64 tsc_offset;
103} __packed;
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#define HV_LINUX_VENDOR_ID 0x8100
130
131
132
133
134#define HV_CRASH_CTL_CRASH_NOTIFY_MSG BIT_ULL(62)
135#define HV_CRASH_CTL_CRASH_NOTIFY BIT_ULL(63)
136
137
138#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002
139#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003
140#define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
141#define HVCALL_SEND_IPI 0x000b
142#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
143#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
144#define HVCALL_SEND_IPI_EX 0x0015
145#define HVCALL_GET_PARTITION_ID 0x0046
146#define HVCALL_DEPOSIT_MEMORY 0x0048
147#define HVCALL_CREATE_VP 0x004e
148#define HVCALL_GET_VP_REGISTERS 0x0050
149#define HVCALL_SET_VP_REGISTERS 0x0051
150#define HVCALL_POST_MESSAGE 0x005c
151#define HVCALL_SIGNAL_EVENT 0x005d
152#define HVCALL_POST_DEBUG_DATA 0x0069
153#define HVCALL_RETRIEVE_DEBUG_DATA 0x006a
154#define HVCALL_RESET_DEBUG_SESSION 0x006b
155#define HVCALL_ADD_LOGICAL_PROCESSOR 0x0076
156#define HVCALL_MAP_DEVICE_INTERRUPT 0x007c
157#define HVCALL_UNMAP_DEVICE_INTERRUPT 0x007d
158#define HVCALL_RETARGET_INTERRUPT 0x007e
159#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af
160#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0
161
162
163#define HV_EXT_CALL_QUERY_CAPABILITIES 0x8001
164#define HV_EXT_CALL_MEMORY_HEAT_HINT 0x8003
165
166#define HV_FLUSH_ALL_PROCESSORS BIT(0)
167#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES BIT(1)
168#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY BIT(2)
169#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3)
170
171
172#define HV_EXT_CAPABILITY_MEMORY_COLD_DISCARD_HINT BIT(8)
173
174enum HV_GENERIC_SET_FORMAT {
175 HV_GENERIC_SET_SPARSE_4K,
176 HV_GENERIC_SET_ALL,
177};
178
179#define HV_PARTITION_ID_SELF ((u64)-1)
180#define HV_VP_INDEX_SELF ((u32)-2)
181
182#define HV_HYPERCALL_RESULT_MASK GENMASK_ULL(15, 0)
183#define HV_HYPERCALL_FAST_BIT BIT(16)
184#define HV_HYPERCALL_VARHEAD_OFFSET 17
185#define HV_HYPERCALL_REP_COMP_OFFSET 32
186#define HV_HYPERCALL_REP_COMP_1 BIT_ULL(32)
187#define HV_HYPERCALL_REP_COMP_MASK GENMASK_ULL(43, 32)
188#define HV_HYPERCALL_REP_START_OFFSET 48
189#define HV_HYPERCALL_REP_START_MASK GENMASK_ULL(59, 48)
190
191
192#define HV_STATUS_SUCCESS 0
193#define HV_STATUS_INVALID_HYPERCALL_CODE 2
194#define HV_STATUS_INVALID_HYPERCALL_INPUT 3
195#define HV_STATUS_INVALID_ALIGNMENT 4
196#define HV_STATUS_INVALID_PARAMETER 5
197#define HV_STATUS_ACCESS_DENIED 6
198#define HV_STATUS_OPERATION_DENIED 8
199#define HV_STATUS_INSUFFICIENT_MEMORY 11
200#define HV_STATUS_INVALID_PORT_ID 17
201#define HV_STATUS_INVALID_CONNECTION_ID 18
202#define HV_STATUS_INSUFFICIENT_BUFFERS 19
203
204
205
206
207
208#define HV_CLOCK_HZ (NSEC_PER_SEC/100)
209
210
211#define HV_SYNIC_SINT_COUNT (16)
212
213#define HV_SYNIC_VERSION_1 (0x1)
214
215#define HV_SYNIC_FIRST_VALID_VECTOR (16)
216
217#define HV_SYNIC_CONTROL_ENABLE (1ULL << 0)
218#define HV_SYNIC_SIMP_ENABLE (1ULL << 0)
219#define HV_SYNIC_SIEFP_ENABLE (1ULL << 0)
220#define HV_SYNIC_SINT_MASKED (1ULL << 16)
221#define HV_SYNIC_SINT_AUTO_EOI (1ULL << 17)
222#define HV_SYNIC_SINT_VECTOR_MASK (0xFF)
223
224#define HV_SYNIC_STIMER_COUNT (4)
225
226
227#define HV_MESSAGE_SIZE (256)
228#define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240)
229#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
230
231
232
233
234
235
236
237
238
239enum hv_message_type {
240 HVMSG_NONE = 0x00000000,
241
242
243 HVMSG_UNMAPPED_GPA = 0x80000000,
244 HVMSG_GPA_INTERCEPT = 0x80000001,
245
246
247 HVMSG_TIMER_EXPIRED = 0x80000010,
248
249
250 HVMSG_INVALID_VP_REGISTER_VALUE = 0x80000020,
251 HVMSG_UNRECOVERABLE_EXCEPTION = 0x80000021,
252 HVMSG_UNSUPPORTED_FEATURE = 0x80000022,
253
254
255 HVMSG_EVENTLOG_BUFFERCOMPLETE = 0x80000040,
256
257
258 HVMSG_X64_IOPORT_INTERCEPT = 0x80010000,
259 HVMSG_X64_MSR_INTERCEPT = 0x80010001,
260 HVMSG_X64_CPUID_INTERCEPT = 0x80010002,
261 HVMSG_X64_EXCEPTION_INTERCEPT = 0x80010003,
262 HVMSG_X64_APIC_EOI = 0x80010004,
263 HVMSG_X64_LEGACY_FP_ERROR = 0x80010005
264};
265
266
267union hv_message_flags {
268 __u8 asu8;
269 struct {
270 __u8 msg_pending:1;
271 __u8 reserved:7;
272 } __packed;
273};
274
275
276union hv_port_id {
277 __u32 asu32;
278 struct {
279 __u32 id:24;
280 __u32 reserved:8;
281 } __packed u;
282};
283
284
285struct hv_message_header {
286 __u32 message_type;
287 __u8 payload_size;
288 union hv_message_flags message_flags;
289 __u8 reserved[2];
290 union {
291 __u64 sender;
292 union hv_port_id port;
293 };
294} __packed;
295
296
297struct hv_message {
298 struct hv_message_header header;
299 union {
300 __u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
301 } u;
302} __packed;
303
304
305struct hv_message_page {
306 struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
307} __packed;
308
309
310struct hv_timer_message_payload {
311 __u32 timer_index;
312 __u32 reserved;
313 __u64 expiration_time;
314 __u64 delivery_time;
315} __packed;
316
317
318
319#define HV_EVENT_FLAGS_COUNT (256 * 8)
320#define HV_EVENT_FLAGS_LONG_COUNT (256 / sizeof(unsigned long))
321
322
323
324
325union hv_stimer_config {
326 u64 as_uint64;
327 struct {
328 u64 enable:1;
329 u64 periodic:1;
330 u64 lazy:1;
331 u64 auto_enable:1;
332 u64 apic_vector:8;
333 u64 direct_mode:1;
334 u64 reserved_z0:3;
335 u64 sintx:4;
336 u64 reserved_z1:44;
337 } __packed;
338};
339
340
341
342union hv_synic_event_flags {
343 unsigned long flags[HV_EVENT_FLAGS_LONG_COUNT];
344};
345
346
347union hv_synic_scontrol {
348 u64 as_uint64;
349 struct {
350 u64 enable:1;
351 u64 reserved:63;
352 } __packed;
353};
354
355
356union hv_synic_sint {
357 u64 as_uint64;
358 struct {
359 u64 vector:8;
360 u64 reserved1:8;
361 u64 masked:1;
362 u64 auto_eoi:1;
363 u64 polling:1;
364 u64 reserved2:45;
365 } __packed;
366};
367
368
369union hv_synic_simp {
370 u64 as_uint64;
371 struct {
372 u64 simp_enabled:1;
373 u64 preserved:11;
374 u64 base_simp_gpa:52;
375 } __packed;
376};
377
378
379union hv_synic_siefp {
380 u64 as_uint64;
381 struct {
382 u64 siefp_enabled:1;
383 u64 preserved:11;
384 u64 base_siefp_gpa:52;
385 } __packed;
386};
387
388struct hv_vpset {
389 u64 format;
390 u64 valid_bank_mask;
391 u64 bank_contents[];
392} __packed;
393
394
395struct hv_send_ipi {
396 u32 vector;
397 u32 reserved;
398 u64 cpu_mask;
399} __packed;
400
401
402struct hv_send_ipi_ex {
403 u32 vector;
404 u32 reserved;
405 struct hv_vpset vp_set;
406} __packed;
407
408
409struct hv_guest_mapping_flush {
410 u64 address_space;
411 u64 flags;
412} __packed;
413
414
415
416
417
418#define HV_MAX_FLUSH_PAGES (2048)
419#define HV_GPA_PAGE_RANGE_PAGE_SIZE_2MB 0
420#define HV_GPA_PAGE_RANGE_PAGE_SIZE_1GB 1
421
422
423union hv_gpa_page_range {
424 u64 address_space;
425 struct {
426 u64 additional_pages:11;
427 u64 largepage:1;
428 u64 basepfn:52;
429 } page;
430 struct {
431 u64 reserved:12;
432 u64 page_size:1;
433 u64 reserved1:8;
434 u64 base_large_pfn:43;
435 };
436};
437
438
439
440
441
442
443#define HV_MAX_FLUSH_REP_COUNT ((HV_HYP_PAGE_SIZE - 2 * sizeof(u64)) / \
444 sizeof(union hv_gpa_page_range))
445
446struct hv_guest_mapping_flush_list {
447 u64 address_space;
448 u64 flags;
449 union hv_gpa_page_range gpa_list[HV_MAX_FLUSH_REP_COUNT];
450};
451
452
453struct hv_tlb_flush {
454 u64 address_space;
455 u64 flags;
456 u64 processor_mask;
457 u64 gva_list[];
458} __packed;
459
460
461struct hv_tlb_flush_ex {
462 u64 address_space;
463 u64 flags;
464 struct hv_vpset hv_vp_set;
465 u64 gva_list[];
466} __packed;
467
468
469struct hv_get_partition_id {
470 u64 partition_id;
471} __packed;
472
473
474struct hv_deposit_memory {
475 u64 partition_id;
476 u64 gpa_page_list[];
477} __packed;
478
479struct hv_proximity_domain_flags {
480 u32 proximity_preferred : 1;
481 u32 reserved : 30;
482 u32 proximity_info_valid : 1;
483} __packed;
484
485
486union hv_proximity_domain_info {
487 struct {
488 u32 domain_id;
489 struct hv_proximity_domain_flags flags;
490 };
491 u64 as_uint64;
492} __packed;
493
494struct hv_lp_startup_status {
495 u64 hv_status;
496 u64 substatus1;
497 u64 substatus2;
498 u64 substatus3;
499 u64 substatus4;
500 u64 substatus5;
501 u64 substatus6;
502} __packed;
503
504
505struct hv_add_logical_processor_in {
506 u32 lp_index;
507 u32 apic_id;
508 union hv_proximity_domain_info proximity_domain_info;
509 u64 flags;
510} __packed;
511
512struct hv_add_logical_processor_out {
513 struct hv_lp_startup_status startup_status;
514} __packed;
515
516enum HV_SUBNODE_TYPE
517{
518 HvSubnodeAny = 0,
519 HvSubnodeSocket = 1,
520 HvSubnodeAmdNode = 2,
521 HvSubnodeL3 = 3,
522 HvSubnodeCount = 4,
523 HvSubnodeInvalid = -1
524};
525
526
527struct hv_create_vp {
528 u64 partition_id;
529 u32 vp_index;
530 u8 padding[3];
531 u8 subnode_type;
532 u64 subnode_id;
533 union hv_proximity_domain_info proximity_domain_info;
534 u64 flags;
535} __packed;
536
537enum hv_interrupt_source {
538 HV_INTERRUPT_SOURCE_MSI = 1,
539 HV_INTERRUPT_SOURCE_IOAPIC,
540};
541
542union hv_msi_address_register {
543 u32 as_uint32;
544 struct {
545 u32 reserved1:2;
546 u32 destination_mode:1;
547 u32 redirection_hint:1;
548 u32 reserved2:8;
549 u32 destination_id:8;
550 u32 msi_base:12;
551 };
552} __packed;
553
554union hv_msi_data_register {
555 u32 as_uint32;
556 struct {
557 u32 vector:8;
558 u32 delivery_mode:3;
559 u32 reserved1:3;
560 u32 level_assert:1;
561 u32 trigger_mode:1;
562 u32 reserved2:16;
563 };
564} __packed;
565
566
567union hv_msi_entry {
568 u64 as_uint64;
569 struct {
570 union hv_msi_address_register address;
571 union hv_msi_data_register data;
572 } __packed;
573};
574
575union hv_ioapic_rte {
576 u64 as_uint64;
577
578 struct {
579 u32 vector:8;
580 u32 delivery_mode:3;
581 u32 destination_mode:1;
582 u32 delivery_status:1;
583 u32 interrupt_polarity:1;
584 u32 remote_irr:1;
585 u32 trigger_mode:1;
586 u32 interrupt_mask:1;
587 u32 reserved1:15;
588
589 u32 reserved2:24;
590 u32 destination_id:8;
591 };
592
593 struct {
594 u32 low_uint32;
595 u32 high_uint32;
596 };
597} __packed;
598
599struct hv_interrupt_entry {
600 u32 source;
601 u32 reserved1;
602 union {
603 union hv_msi_entry msi_entry;
604 union hv_ioapic_rte ioapic_rte;
605 };
606} __packed;
607
608
609
610
611#define HV_DEVICE_INTERRUPT_TARGET_MULTICAST 1
612#define HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET 2
613
614struct hv_device_interrupt_target {
615 u32 vector;
616 u32 flags;
617 union {
618 u64 vp_mask;
619 struct hv_vpset vp_set;
620 };
621} __packed;
622
623struct hv_retarget_device_interrupt {
624 u64 partition_id;
625 u64 device_id;
626 struct hv_interrupt_entry int_entry;
627 u64 reserved2;
628 struct hv_device_interrupt_target int_target;
629} __packed __aligned(8);
630
631
632
633struct hv_get_vp_registers_input {
634 struct {
635 u64 partitionid;
636 u32 vpindex;
637 u8 inputvtl;
638 u8 padding[3];
639 } header;
640 struct input {
641 u32 name0;
642 u32 name1;
643 } element[];
644} __packed;
645
646
647
648struct hv_get_vp_registers_output {
649 union {
650 struct {
651 u32 a;
652 u32 b;
653 u32 c;
654 u32 d;
655 } as32 __packed;
656 struct {
657 u64 low;
658 u64 high;
659 } as64 __packed;
660 };
661};
662
663
664struct hv_set_vp_registers_input {
665 struct {
666 u64 partitionid;
667 u32 vpindex;
668 u8 inputvtl;
669 u8 padding[3];
670 } header;
671 struct {
672 u32 name;
673 u32 padding1;
674 u64 padding2;
675 u64 valuelow;
676 u64 valuehigh;
677 } element[];
678} __packed;
679
680enum hv_device_type {
681 HV_DEVICE_TYPE_LOGICAL = 0,
682 HV_DEVICE_TYPE_PCI = 1,
683 HV_DEVICE_TYPE_IOAPIC = 2,
684 HV_DEVICE_TYPE_ACPI = 3,
685};
686
687typedef u16 hv_pci_rid;
688typedef u16 hv_pci_segment;
689typedef u64 hv_logical_device_id;
690union hv_pci_bdf {
691 u16 as_uint16;
692
693 struct {
694 u8 function:3;
695 u8 device:5;
696 u8 bus;
697 };
698} __packed;
699
700union hv_pci_bus_range {
701 u16 as_uint16;
702
703 struct {
704 u8 subordinate_bus;
705 u8 secondary_bus;
706 };
707} __packed;
708
709union hv_device_id {
710 u64 as_uint64;
711
712 struct {
713 u64 reserved0:62;
714 u64 device_type:2;
715 };
716
717
718 struct {
719 u64 id:62;
720 u64 device_type:2;
721 } logical;
722
723
724 struct {
725 union {
726 hv_pci_rid rid;
727 union hv_pci_bdf bdf;
728 };
729
730 hv_pci_segment segment;
731 union hv_pci_bus_range shadow_bus_range;
732
733 u16 phantom_function_bits:2;
734 u16 source_shadow:1;
735
736 u16 rsvdz0:11;
737 u16 device_type:2;
738 } pci;
739
740
741 struct {
742 u8 ioapic_id;
743 u8 rsvdz0;
744 u16 rsvdz1;
745 u16 rsvdz2;
746
747 u16 rsvdz3:14;
748 u16 device_type:2;
749 } ioapic;
750
751
752 struct {
753 u32 input_mapping_base;
754 u32 input_mapping_count:30;
755 u32 device_type:2;
756 } acpi;
757} __packed;
758
759enum hv_interrupt_trigger_mode {
760 HV_INTERRUPT_TRIGGER_MODE_EDGE = 0,
761 HV_INTERRUPT_TRIGGER_MODE_LEVEL = 1,
762};
763
764struct hv_device_interrupt_descriptor {
765 u32 interrupt_type;
766 u32 trigger_mode;
767 u32 vector_count;
768 u32 reserved;
769 struct hv_device_interrupt_target target;
770} __packed;
771
772struct hv_input_map_device_interrupt {
773 u64 partition_id;
774 u64 device_id;
775 u64 flags;
776 struct hv_interrupt_entry logical_interrupt_entry;
777 struct hv_device_interrupt_descriptor interrupt_descriptor;
778} __packed;
779
780struct hv_output_map_device_interrupt {
781 struct hv_interrupt_entry interrupt_entry;
782} __packed;
783
784struct hv_input_unmap_device_interrupt {
785 u64 partition_id;
786 u64 device_id;
787 struct hv_interrupt_entry interrupt_entry;
788} __packed;
789
790#define HV_SOURCE_SHADOW_NONE 0x0
791#define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE 0x1
792
793
794
795
796
797#define HV_MEMORY_HINT_MAX_GPA_PAGE_RANGES \
798 ((HV_HYP_PAGE_SIZE - sizeof(struct hv_memory_hint)) / \
799 sizeof(union hv_gpa_page_range))
800
801
802#define HV_EXT_MEMORY_HEAT_HINT_TYPE_COLD_DISCARD 2
803struct hv_memory_hint {
804 u64 type:2;
805 u64 reserved:62;
806 union hv_gpa_page_range ranges[];
807} __packed;
808
809#endif
810