Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/include/hyperv/hvhdk.h
48999 views
1
/* SPDX-License-Identifier: GPL-2.0 */
2
/*
3
* Type definitions for the Microsoft hypervisor.
4
*/
5
#ifndef _HV_HVHDK_H
6
#define _HV_HVHDK_H
7
8
#include <linux/build_bug.h>
9
10
#include "hvhdk_mini.h"
11
#include "hvgdk.h"
12
13
/* Bits for dirty mask of hv_vp_register_page */
14
#define HV_X64_REGISTER_CLASS_GENERAL 0
15
#define HV_X64_REGISTER_CLASS_IP 1
16
#define HV_X64_REGISTER_CLASS_XMM 2
17
#define HV_X64_REGISTER_CLASS_SEGMENT 3
18
#define HV_X64_REGISTER_CLASS_FLAGS 4
19
20
#define HV_VP_REGISTER_PAGE_VERSION_1 1u
21
22
#define HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT 7
23
24
union hv_vp_register_page_interrupt_vectors {
25
u64 as_uint64;
26
struct {
27
u8 vector_count;
28
u8 vector[HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT];
29
} __packed;
30
};
31
32
struct hv_vp_register_page {
33
u16 version;
34
u8 isvalid;
35
u8 rsvdz;
36
u32 dirty;
37
38
#if IS_ENABLED(CONFIG_X86)
39
40
union {
41
struct {
42
/* General purpose registers
43
* (HV_X64_REGISTER_CLASS_GENERAL)
44
*/
45
union {
46
struct {
47
u64 rax;
48
u64 rcx;
49
u64 rdx;
50
u64 rbx;
51
u64 rsp;
52
u64 rbp;
53
u64 rsi;
54
u64 rdi;
55
u64 r8;
56
u64 r9;
57
u64 r10;
58
u64 r11;
59
u64 r12;
60
u64 r13;
61
u64 r14;
62
u64 r15;
63
} __packed;
64
65
u64 gp_registers[16];
66
};
67
/* Instruction pointer (HV_X64_REGISTER_CLASS_IP) */
68
u64 rip;
69
/* Flags (HV_X64_REGISTER_CLASS_FLAGS) */
70
u64 rflags;
71
} __packed;
72
73
u64 registers[18];
74
};
75
/* Volatile XMM registers (HV_X64_REGISTER_CLASS_XMM) */
76
union {
77
struct {
78
struct hv_u128 xmm0;
79
struct hv_u128 xmm1;
80
struct hv_u128 xmm2;
81
struct hv_u128 xmm3;
82
struct hv_u128 xmm4;
83
struct hv_u128 xmm5;
84
} __packed;
85
86
struct hv_u128 xmm_registers[6];
87
};
88
/* Segment registers (HV_X64_REGISTER_CLASS_SEGMENT) */
89
union {
90
struct {
91
struct hv_x64_segment_register es;
92
struct hv_x64_segment_register cs;
93
struct hv_x64_segment_register ss;
94
struct hv_x64_segment_register ds;
95
struct hv_x64_segment_register fs;
96
struct hv_x64_segment_register gs;
97
} __packed;
98
99
struct hv_x64_segment_register segment_registers[6];
100
};
101
/* Misc. control registers (cannot be set via this interface) */
102
u64 cr0;
103
u64 cr3;
104
u64 cr4;
105
u64 cr8;
106
u64 efer;
107
u64 dr7;
108
union hv_x64_pending_interruption_register pending_interruption;
109
union hv_x64_interrupt_state_register interrupt_state;
110
u64 instruction_emulation_hints;
111
u64 xfem;
112
113
/*
114
* Fields from this point are not included in the register page save chunk.
115
* The reserved field is intended to maintain alignment for unsaved fields.
116
*/
117
u8 reserved1[0x100];
118
119
/*
120
* Interrupts injected as part of HvCallDispatchVp.
121
*/
122
union hv_vp_register_page_interrupt_vectors interrupt_vectors;
123
124
#elif IS_ENABLED(CONFIG_ARM64)
125
/* Not yet supported in ARM */
126
#endif
127
} __packed;
128
129
#define HV_PARTITION_PROCESSOR_FEATURES_BANKS 2
130
131
union hv_partition_processor_features {
132
u64 as_uint64[HV_PARTITION_PROCESSOR_FEATURES_BANKS];
133
struct {
134
u64 sse3_support : 1;
135
u64 lahf_sahf_support : 1;
136
u64 ssse3_support : 1;
137
u64 sse4_1_support : 1;
138
u64 sse4_2_support : 1;
139
u64 sse4a_support : 1;
140
u64 xop_support : 1;
141
u64 pop_cnt_support : 1;
142
u64 cmpxchg16b_support : 1;
143
u64 altmovcr8_support : 1;
144
u64 lzcnt_support : 1;
145
u64 mis_align_sse_support : 1;
146
u64 mmx_ext_support : 1;
147
u64 amd3dnow_support : 1;
148
u64 extended_amd3dnow_support : 1;
149
u64 page_1gb_support : 1;
150
u64 aes_support : 1;
151
u64 pclmulqdq_support : 1;
152
u64 pcid_support : 1;
153
u64 fma4_support : 1;
154
u64 f16c_support : 1;
155
u64 rd_rand_support : 1;
156
u64 rd_wr_fs_gs_support : 1;
157
u64 smep_support : 1;
158
u64 enhanced_fast_string_support : 1;
159
u64 bmi1_support : 1;
160
u64 bmi2_support : 1;
161
u64 hle_support_deprecated : 1;
162
u64 rtm_support_deprecated : 1;
163
u64 movbe_support : 1;
164
u64 npiep1_support : 1;
165
u64 dep_x87_fpu_save_support : 1;
166
u64 rd_seed_support : 1;
167
u64 adx_support : 1;
168
u64 intel_prefetch_support : 1;
169
u64 smap_support : 1;
170
u64 hle_support : 1;
171
u64 rtm_support : 1;
172
u64 rdtscp_support : 1;
173
u64 clflushopt_support : 1;
174
u64 clwb_support : 1;
175
u64 sha_support : 1;
176
u64 x87_pointers_saved_support : 1;
177
u64 invpcid_support : 1;
178
u64 ibrs_support : 1;
179
u64 stibp_support : 1;
180
u64 ibpb_support: 1;
181
u64 unrestricted_guest_support : 1;
182
u64 mdd_support : 1;
183
u64 fast_short_rep_mov_support : 1;
184
u64 l1dcache_flush_support : 1;
185
u64 rdcl_no_support : 1;
186
u64 ibrs_all_support : 1;
187
u64 skip_l1df_support : 1;
188
u64 ssb_no_support : 1;
189
u64 rsb_a_no_support : 1;
190
u64 virt_spec_ctrl_support : 1;
191
u64 rd_pid_support : 1;
192
u64 umip_support : 1;
193
u64 mbs_no_support : 1;
194
u64 mb_clear_support : 1;
195
u64 taa_no_support : 1;
196
u64 tsx_ctrl_support : 1;
197
/*
198
* N.B. The final processor feature bit in bank 0 is reserved to
199
* simplify potential downlevel backports.
200
*/
201
u64 reserved_bank0 : 1;
202
203
/* N.B. Begin bank 1 processor features. */
204
u64 acount_mcount_support : 1;
205
u64 tsc_invariant_support : 1;
206
u64 cl_zero_support : 1;
207
u64 rdpru_support : 1;
208
u64 la57_support : 1;
209
u64 mbec_support : 1;
210
u64 nested_virt_support : 1;
211
u64 psfd_support : 1;
212
u64 cet_ss_support : 1;
213
u64 cet_ibt_support : 1;
214
u64 vmx_exception_inject_support : 1;
215
u64 enqcmd_support : 1;
216
u64 umwait_tpause_support : 1;
217
u64 movdiri_support : 1;
218
u64 movdir64b_support : 1;
219
u64 cldemote_support : 1;
220
u64 serialize_support : 1;
221
u64 tsc_deadline_tmr_support : 1;
222
u64 tsc_adjust_support : 1;
223
u64 fzlrep_movsb : 1;
224
u64 fsrep_stosb : 1;
225
u64 fsrep_cmpsb : 1;
226
u64 reserved_bank1 : 42;
227
} __packed;
228
};
229
230
union hv_partition_processor_xsave_features {
231
struct {
232
u64 xsave_support : 1;
233
u64 xsaveopt_support : 1;
234
u64 avx_support : 1;
235
u64 reserved1 : 61;
236
} __packed;
237
u64 as_uint64;
238
};
239
240
struct hv_partition_creation_properties {
241
union hv_partition_processor_features disabled_processor_features;
242
union hv_partition_processor_xsave_features
243
disabled_processor_xsave_features;
244
} __packed;
245
246
#define HV_PARTITION_SYNTHETIC_PROCESSOR_FEATURES_BANKS 1
247
248
union hv_partition_synthetic_processor_features {
249
u64 as_uint64[HV_PARTITION_SYNTHETIC_PROCESSOR_FEATURES_BANKS];
250
251
struct {
252
u64 hypervisor_present : 1;
253
/* Support for HV#1: (CPUID leaves 0x40000000 - 0x40000006)*/
254
u64 hv1 : 1;
255
u64 access_vp_run_time_reg : 1; /* HV_X64_MSR_VP_RUNTIME */
256
u64 access_partition_reference_counter : 1; /* HV_X64_MSR_TIME_REF_COUNT */
257
u64 access_synic_regs : 1; /* SINT-related registers */
258
/*
259
* Access to HV_X64_MSR_STIMER0_CONFIG through
260
* HV_X64_MSR_STIMER3_COUNT.
261
*/
262
u64 access_synthetic_timer_regs : 1;
263
u64 access_intr_ctrl_regs : 1; /* APIC MSRs and VP assist page*/
264
/* HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL */
265
u64 access_hypercall_regs : 1;
266
u64 access_vp_index : 1;
267
u64 access_partition_reference_tsc : 1;
268
u64 access_guest_idle_reg : 1;
269
u64 access_frequency_regs : 1;
270
u64 reserved_z12 : 1;
271
u64 reserved_z13 : 1;
272
u64 reserved_z14 : 1;
273
u64 enable_extended_gva_ranges_for_flush_virtual_address_list : 1;
274
u64 reserved_z16 : 1;
275
u64 reserved_z17 : 1;
276
/* Use fast hypercall output. Corresponds to privilege. */
277
u64 fast_hypercall_output : 1;
278
u64 reserved_z19 : 1;
279
u64 start_virtual_processor : 1; /* Can start VPs */
280
u64 reserved_z21 : 1;
281
/* Synthetic timers in direct mode. */
282
u64 direct_synthetic_timers : 1;
283
u64 reserved_z23 : 1;
284
u64 extended_processor_masks : 1;
285
286
/* Enable various hypercalls */
287
u64 tb_flush_hypercalls : 1;
288
u64 synthetic_cluster_ipi : 1;
289
u64 notify_long_spin_wait : 1;
290
u64 query_numa_distance : 1;
291
u64 signal_events : 1;
292
u64 retarget_device_interrupt : 1;
293
u64 restore_time : 1;
294
295
/* EnlightenedVmcs nested enlightenment is supported. */
296
u64 enlightened_vmcs : 1;
297
u64 reserved : 31;
298
} __packed;
299
};
300
301
#define HV_MAKE_COMPATIBILITY_VERSION(major_, minor_) \
302
((u32)((major_) << 8 | (minor_)))
303
304
#define HV_COMPATIBILITY_21_H2 HV_MAKE_COMPATIBILITY_VERSION(0X6, 0X9)
305
306
union hv_partition_isolation_properties {
307
u64 as_uint64;
308
struct {
309
u64 isolation_type: 5;
310
u64 isolation_host_type : 2;
311
u64 rsvd_z: 5;
312
u64 shared_gpa_boundary_page_number: 52;
313
} __packed;
314
};
315
316
/*
317
* Various isolation types supported by MSHV.
318
*/
319
#define HV_PARTITION_ISOLATION_TYPE_NONE 0
320
#define HV_PARTITION_ISOLATION_TYPE_SNP 2
321
#define HV_PARTITION_ISOLATION_TYPE_TDX 3
322
323
/*
324
* Various host isolation types supported by MSHV.
325
*/
326
#define HV_PARTITION_ISOLATION_HOST_TYPE_NONE 0x0
327
#define HV_PARTITION_ISOLATION_HOST_TYPE_HARDWARE 0x1
328
#define HV_PARTITION_ISOLATION_HOST_TYPE_RESERVED 0x2
329
330
/* Note: Exo partition is enabled by default */
331
#define HV_PARTITION_CREATION_FLAG_GPA_SUPER_PAGES_ENABLED BIT(4)
332
#define HV_PARTITION_CREATION_FLAG_EXO_PARTITION BIT(8)
333
#define HV_PARTITION_CREATION_FLAG_LAPIC_ENABLED BIT(13)
334
#define HV_PARTITION_CREATION_FLAG_INTERCEPT_MESSAGE_PAGE_ENABLED BIT(19)
335
#define HV_PARTITION_CREATION_FLAG_X2APIC_CAPABLE BIT(22)
336
337
struct hv_input_create_partition {
338
u64 flags;
339
struct hv_proximity_domain_info proximity_domain_info;
340
u32 compatibility_version;
341
u32 padding;
342
struct hv_partition_creation_properties partition_creation_properties;
343
union hv_partition_isolation_properties isolation_properties;
344
} __packed;
345
346
struct hv_output_create_partition {
347
u64 partition_id;
348
} __packed;
349
350
struct hv_input_initialize_partition {
351
u64 partition_id;
352
} __packed;
353
354
struct hv_input_finalize_partition {
355
u64 partition_id;
356
} __packed;
357
358
struct hv_input_delete_partition {
359
u64 partition_id;
360
} __packed;
361
362
struct hv_input_get_partition_property {
363
u64 partition_id;
364
u32 property_code; /* enum hv_partition_property_code */
365
u32 padding;
366
} __packed;
367
368
struct hv_output_get_partition_property {
369
u64 property_value;
370
} __packed;
371
372
struct hv_input_set_partition_property {
373
u64 partition_id;
374
u32 property_code; /* enum hv_partition_property_code */
375
u32 padding;
376
u64 property_value;
377
} __packed;
378
379
union hv_partition_property_arg {
380
u64 as_uint64;
381
struct {
382
union {
383
u32 arg;
384
u32 vp_index;
385
};
386
u16 reserved0;
387
u8 reserved1;
388
u8 object_type;
389
} __packed;
390
};
391
392
struct hv_input_get_partition_property_ex {
393
u64 partition_id;
394
u32 property_code; /* enum hv_partition_property_code */
395
u32 padding;
396
union {
397
union hv_partition_property_arg arg_data;
398
u64 arg;
399
};
400
} __packed;
401
402
/*
403
* NOTE: Should use hv_input_set_partition_property_ex_header to compute this
404
* size, but hv_input_get_partition_property_ex is identical so it suffices
405
*/
406
#define HV_PARTITION_PROPERTY_EX_MAX_VAR_SIZE \
407
(HV_HYP_PAGE_SIZE - sizeof(struct hv_input_get_partition_property_ex))
408
409
union hv_partition_property_ex {
410
u8 buffer[HV_PARTITION_PROPERTY_EX_MAX_VAR_SIZE];
411
struct hv_partition_property_vmm_capabilities vmm_capabilities;
412
/* More fields to be filled in when needed */
413
};
414
415
struct hv_output_get_partition_property_ex {
416
union hv_partition_property_ex property_value;
417
} __packed;
418
419
enum hv_vp_state_page_type {
420
HV_VP_STATE_PAGE_REGISTERS = 0,
421
HV_VP_STATE_PAGE_INTERCEPT_MESSAGE = 1,
422
HV_VP_STATE_PAGE_GHCB = 2,
423
HV_VP_STATE_PAGE_COUNT
424
};
425
426
struct hv_input_map_vp_state_page {
427
u64 partition_id;
428
u32 vp_index;
429
u16 type; /* enum hv_vp_state_page_type */
430
union hv_input_vtl input_vtl;
431
union {
432
u8 as_uint8;
433
struct {
434
u8 map_location_provided : 1;
435
u8 reserved : 7;
436
};
437
} flags;
438
u64 requested_map_location;
439
} __packed;
440
441
struct hv_output_map_vp_state_page {
442
u64 map_location; /* GPA page number */
443
} __packed;
444
445
struct hv_input_unmap_vp_state_page {
446
u64 partition_id;
447
u32 vp_index;
448
u16 type; /* enum hv_vp_state_page_type */
449
union hv_input_vtl input_vtl;
450
u8 reserved0;
451
} __packed;
452
453
struct hv_x64_apic_eoi_message {
454
u32 vp_index;
455
u32 interrupt_vector;
456
} __packed;
457
458
struct hv_opaque_intercept_message {
459
u32 vp_index;
460
} __packed;
461
462
enum hv_port_type {
463
HV_PORT_TYPE_MESSAGE = 1,
464
HV_PORT_TYPE_EVENT = 2,
465
HV_PORT_TYPE_MONITOR = 3,
466
HV_PORT_TYPE_DOORBELL = 4 /* Root Partition only */
467
};
468
469
struct hv_port_info {
470
u32 port_type; /* enum hv_port_type */
471
u32 padding;
472
union {
473
struct {
474
u32 target_sint;
475
u32 target_vp;
476
u64 rsvdz;
477
} message_port_info;
478
struct {
479
u32 target_sint;
480
u32 target_vp;
481
u16 base_flag_number;
482
u16 flag_count;
483
u32 rsvdz;
484
} event_port_info;
485
struct {
486
u64 monitor_address;
487
u64 rsvdz;
488
} monitor_port_info;
489
struct {
490
u32 target_sint;
491
u32 target_vp;
492
u64 rsvdz;
493
} doorbell_port_info;
494
};
495
} __packed;
496
497
struct hv_connection_info {
498
u32 port_type;
499
u32 padding;
500
union {
501
struct {
502
u64 rsvdz;
503
} message_connection_info;
504
struct {
505
u64 rsvdz;
506
} event_connection_info;
507
struct {
508
u64 monitor_address;
509
} monitor_connection_info;
510
struct {
511
u64 gpa;
512
u64 trigger_value;
513
u64 flags;
514
} doorbell_connection_info;
515
};
516
} __packed;
517
518
/* Define synthetic interrupt controller flag constants. */
519
#define HV_EVENT_FLAGS_COUNT (256 * 8)
520
#define HV_EVENT_FLAGS_BYTE_COUNT (256)
521
#define HV_EVENT_FLAGS32_COUNT (256 / sizeof(u32))
522
523
/* linux side we create long version of flags to use long bit ops on flags */
524
#define HV_EVENT_FLAGS_UL_COUNT (256 / sizeof(ulong))
525
526
/* Define the synthetic interrupt controller event flags format. */
527
union hv_synic_event_flags {
528
unsigned char flags8[HV_EVENT_FLAGS_BYTE_COUNT];
529
u32 flags32[HV_EVENT_FLAGS32_COUNT];
530
ulong flags[HV_EVENT_FLAGS_UL_COUNT]; /* linux only */
531
};
532
533
struct hv_synic_event_flags_page {
534
volatile union hv_synic_event_flags event_flags[HV_SYNIC_SINT_COUNT];
535
};
536
537
#define HV_SYNIC_EVENT_RING_MESSAGE_COUNT 63
538
539
struct hv_synic_event_ring {
540
u8 signal_masked;
541
u8 ring_full;
542
u16 reserved_z;
543
u32 data[HV_SYNIC_EVENT_RING_MESSAGE_COUNT];
544
} __packed;
545
546
struct hv_synic_event_ring_page {
547
struct hv_synic_event_ring sint_event_ring[HV_SYNIC_SINT_COUNT];
548
};
549
550
/* Define SynIC control register. */
551
union hv_synic_scontrol {
552
u64 as_uint64;
553
struct {
554
u64 enable : 1;
555
u64 reserved : 63;
556
} __packed;
557
};
558
559
/* Define the format of the SIEFP register */
560
union hv_synic_siefp {
561
u64 as_uint64;
562
struct {
563
u64 siefp_enabled : 1;
564
u64 preserved : 11;
565
u64 base_siefp_gpa : 52;
566
} __packed;
567
};
568
569
union hv_synic_sirbp {
570
u64 as_uint64;
571
struct {
572
u64 sirbp_enabled : 1;
573
u64 preserved : 11;
574
u64 base_sirbp_gpa : 52;
575
} __packed;
576
};
577
578
union hv_interrupt_control {
579
u64 as_uint64;
580
struct {
581
u32 interrupt_type; /* enum hv_interrupt_type */
582
#if IS_ENABLED(CONFIG_X86)
583
u32 level_triggered : 1;
584
u32 logical_dest_mode : 1;
585
u32 rsvd : 30;
586
#elif IS_ENABLED(CONFIG_ARM64)
587
u32 rsvd1 : 2;
588
u32 asserted : 1;
589
u32 rsvd2 : 29;
590
#endif
591
} __packed;
592
};
593
594
struct hv_stimer_state {
595
struct {
596
u32 undelivered_msg_pending : 1;
597
u32 reserved : 31;
598
} __packed flags;
599
u32 resvd;
600
u64 config;
601
u64 count;
602
u64 adjustment;
603
u64 undelivered_exp_time;
604
} __packed;
605
606
struct hv_synthetic_timers_state {
607
struct hv_stimer_state timers[HV_SYNIC_STIMER_COUNT];
608
u64 reserved[5];
609
} __packed;
610
611
struct hv_async_completion_message_payload {
612
u64 partition_id;
613
u32 status;
614
u32 completion_count;
615
u64 sub_status;
616
} __packed;
617
618
union hv_input_delete_vp {
619
u64 as_uint64[2];
620
struct {
621
u64 partition_id;
622
u32 vp_index;
623
u8 reserved[4];
624
} __packed;
625
} __packed;
626
627
struct hv_input_assert_virtual_interrupt {
628
u64 partition_id;
629
union hv_interrupt_control control;
630
u64 dest_addr; /* cpu's apic id */
631
u32 vector;
632
u8 target_vtl;
633
u8 rsvd_z0;
634
u16 rsvd_z1;
635
} __packed;
636
637
struct hv_input_create_port {
638
u64 port_partition_id;
639
union hv_port_id port_id;
640
u8 port_vtl;
641
u8 min_connection_vtl;
642
u16 padding;
643
u64 connection_partition_id;
644
struct hv_port_info port_info;
645
struct hv_proximity_domain_info proximity_domain_info;
646
} __packed;
647
648
union hv_input_delete_port {
649
u64 as_uint64[2];
650
struct {
651
u64 port_partition_id;
652
union hv_port_id port_id;
653
u32 reserved;
654
};
655
} __packed;
656
657
struct hv_input_connect_port {
658
u64 connection_partition_id;
659
union hv_connection_id connection_id;
660
u8 connection_vtl;
661
u8 rsvdz0;
662
u16 rsvdz1;
663
u64 port_partition_id;
664
union hv_port_id port_id;
665
u32 reserved2;
666
struct hv_connection_info connection_info;
667
struct hv_proximity_domain_info proximity_domain_info;
668
} __packed;
669
670
union hv_input_disconnect_port {
671
u64 as_uint64[2];
672
struct {
673
u64 connection_partition_id;
674
union hv_connection_id connection_id;
675
u32 is_doorbell: 1;
676
u32 reserved: 31;
677
} __packed;
678
} __packed;
679
680
union hv_input_notify_port_ring_empty {
681
u64 as_uint64;
682
struct {
683
u32 sint_index;
684
u32 reserved;
685
};
686
} __packed;
687
688
struct hv_vp_state_data_xsave {
689
u64 flags;
690
union hv_x64_xsave_xfem_register states;
691
} __packed;
692
693
/*
694
* For getting and setting VP state, there are two options based on the state type:
695
*
696
* 1.) Data that is accessed by PFNs in the input hypercall page. This is used
697
* for state which may not fit into the hypercall pages.
698
* 2.) Data that is accessed directly in the input\output hypercall pages.
699
* This is used for state that will always fit into the hypercall pages.
700
*
701
* In the future this could be dynamic based on the size if needed.
702
*
703
* Note these hypercalls have an 8-byte aligned variable header size as per the tlfs
704
*/
705
706
#define HV_GET_SET_VP_STATE_TYPE_PFN BIT(31)
707
708
enum hv_get_set_vp_state_type {
709
/* HvGetSetVpStateLocalInterruptControllerState - APIC/GIC state */
710
HV_GET_SET_VP_STATE_LAPIC_STATE = 0 | HV_GET_SET_VP_STATE_TYPE_PFN,
711
HV_GET_SET_VP_STATE_XSAVE = 1 | HV_GET_SET_VP_STATE_TYPE_PFN,
712
HV_GET_SET_VP_STATE_SIM_PAGE = 2 | HV_GET_SET_VP_STATE_TYPE_PFN,
713
HV_GET_SET_VP_STATE_SIEF_PAGE = 3 | HV_GET_SET_VP_STATE_TYPE_PFN,
714
HV_GET_SET_VP_STATE_SYNTHETIC_TIMERS = 4,
715
};
716
717
struct hv_vp_state_data {
718
u32 type;
719
u32 rsvd;
720
struct hv_vp_state_data_xsave xsave;
721
} __packed;
722
723
struct hv_input_get_vp_state {
724
u64 partition_id;
725
u32 vp_index;
726
u8 input_vtl;
727
u8 rsvd0;
728
u16 rsvd1;
729
struct hv_vp_state_data state_data;
730
u64 output_data_pfns[];
731
} __packed;
732
733
union hv_output_get_vp_state {
734
struct hv_synthetic_timers_state synthetic_timers_state;
735
} __packed;
736
737
union hv_input_set_vp_state_data {
738
u64 pfns;
739
u8 bytes;
740
} __packed;
741
742
struct hv_input_set_vp_state {
743
u64 partition_id;
744
u32 vp_index;
745
u8 input_vtl;
746
u8 rsvd0;
747
u16 rsvd1;
748
struct hv_vp_state_data state_data;
749
union hv_input_set_vp_state_data data[];
750
} __packed;
751
752
union hv_x64_vp_execution_state {
753
u16 as_uint16;
754
struct {
755
u16 cpl:2;
756
u16 cr0_pe:1;
757
u16 cr0_am:1;
758
u16 efer_lma:1;
759
u16 debug_active:1;
760
u16 interruption_pending:1;
761
u16 vtl:4;
762
u16 enclave_mode:1;
763
u16 interrupt_shadow:1;
764
u16 virtualization_fault_active:1;
765
u16 reserved:2;
766
} __packed;
767
};
768
769
struct hv_x64_intercept_message_header {
770
u32 vp_index;
771
u8 instruction_length:4;
772
u8 cr8:4; /* Only set for exo partitions */
773
u8 intercept_access_type;
774
union hv_x64_vp_execution_state execution_state;
775
struct hv_x64_segment_register cs_segment;
776
u64 rip;
777
u64 rflags;
778
} __packed;
779
780
union hv_x64_memory_access_info {
781
u8 as_uint8;
782
struct {
783
u8 gva_valid:1;
784
u8 gva_gpa_valid:1;
785
u8 hypercall_output_pending:1;
786
u8 tlb_locked_no_overlay:1;
787
u8 reserved:4;
788
} __packed;
789
};
790
791
struct hv_x64_memory_intercept_message {
792
struct hv_x64_intercept_message_header header;
793
u32 cache_type; /* enum hv_cache_type */
794
u8 instruction_byte_count;
795
union hv_x64_memory_access_info memory_access_info;
796
u8 tpr_priority;
797
u8 reserved1;
798
u64 guest_virtual_address;
799
u64 guest_physical_address;
800
u8 instruction_bytes[16];
801
} __packed;
802
803
#if IS_ENABLED(CONFIG_ARM64)
804
union hv_arm64_vp_execution_state {
805
u16 as_uint16;
806
struct {
807
u16 cpl:2; /* Exception Level (EL) */
808
u16 debug_active:1;
809
u16 interruption_pending:1;
810
u16 vtl:4;
811
u16 virtualization_fault_active:1;
812
u16 reserved:7;
813
} __packed;
814
};
815
816
struct hv_arm64_intercept_message_header {
817
u32 vp_index;
818
u8 instruction_length;
819
u8 intercept_access_type;
820
union hv_arm64_vp_execution_state execution_state;
821
u64 pc;
822
u64 cpsr;
823
} __packed;
824
825
union hv_arm64_memory_access_info {
826
u8 as_uint8;
827
struct {
828
u8 gva_valid:1;
829
u8 gva_gpa_valid:1;
830
u8 hypercall_output_pending:1;
831
u8 reserved:5;
832
} __packed;
833
};
834
835
struct hv_arm64_memory_intercept_message {
836
struct hv_arm64_intercept_message_header header;
837
u32 cache_type; /* enum hv_cache_type */
838
u8 instruction_byte_count;
839
union hv_arm64_memory_access_info memory_access_info;
840
u16 reserved1;
841
u8 instruction_bytes[4];
842
u32 reserved2;
843
u64 guest_virtual_address;
844
u64 guest_physical_address;
845
u64 syndrome;
846
} __packed;
847
848
#endif /* CONFIG_ARM64 */
849
850
/*
851
* Dispatch state for the VP communicated by the hypervisor to the
852
* VP-dispatching thread in the root on return from HVCALL_DISPATCH_VP.
853
*/
854
enum hv_vp_dispatch_state {
855
HV_VP_DISPATCH_STATE_INVALID = 0,
856
HV_VP_DISPATCH_STATE_BLOCKED = 1,
857
HV_VP_DISPATCH_STATE_READY = 2,
858
};
859
860
/*
861
* Dispatch event that caused the current dispatch state on return from
862
* HVCALL_DISPATCH_VP.
863
*/
864
enum hv_vp_dispatch_event {
865
HV_VP_DISPATCH_EVENT_INVALID = 0x00000000,
866
HV_VP_DISPATCH_EVENT_SUSPEND = 0x00000001,
867
HV_VP_DISPATCH_EVENT_INTERCEPT = 0x00000002,
868
};
869
870
#define HV_ROOT_SCHEDULER_MAX_VPS_PER_CHILD_PARTITION 1024
871
/* The maximum array size of HV_GENERIC_SET (vp_set) buffer */
872
#define HV_GENERIC_SET_QWORD_COUNT(max) (((((max) - 1) >> 6) + 1) + 2)
873
874
struct hv_vp_signal_bitset_scheduler_message {
875
u64 partition_id;
876
u32 overflow_count;
877
u16 vp_count;
878
u16 reserved;
879
880
#define BITSET_BUFFER_SIZE \
881
HV_GENERIC_SET_QWORD_COUNT(HV_ROOT_SCHEDULER_MAX_VPS_PER_CHILD_PARTITION)
882
union {
883
struct hv_vpset bitset;
884
u64 bitset_buffer[BITSET_BUFFER_SIZE];
885
} vp_bitset;
886
#undef BITSET_BUFFER_SIZE
887
} __packed;
888
889
static_assert(sizeof(struct hv_vp_signal_bitset_scheduler_message) <=
890
(sizeof(struct hv_message) - sizeof(struct hv_message_header)));
891
892
#define HV_MESSAGE_MAX_PARTITION_VP_PAIR_COUNT \
893
(((sizeof(struct hv_message) - sizeof(struct hv_message_header)) / \
894
(sizeof(u64 /* partition id */) + sizeof(u32 /* vp index */))) - 1)
895
896
struct hv_vp_signal_pair_scheduler_message {
897
u32 overflow_count;
898
u8 vp_count;
899
u8 reserved1[3];
900
901
u64 partition_ids[HV_MESSAGE_MAX_PARTITION_VP_PAIR_COUNT];
902
u32 vp_indexes[HV_MESSAGE_MAX_PARTITION_VP_PAIR_COUNT];
903
904
u8 reserved2[4];
905
} __packed;
906
907
static_assert(sizeof(struct hv_vp_signal_pair_scheduler_message) ==
908
(sizeof(struct hv_message) - sizeof(struct hv_message_header)));
909
910
/* Input and output structures for HVCALL_DISPATCH_VP */
911
#define HV_DISPATCH_VP_FLAG_CLEAR_INTERCEPT_SUSPEND 0x1
912
#define HV_DISPATCH_VP_FLAG_ENABLE_CALLER_INTERRUPTS 0x2
913
#define HV_DISPATCH_VP_FLAG_SET_CALLER_SPEC_CTRL 0x4
914
#define HV_DISPATCH_VP_FLAG_SKIP_VP_SPEC_FLUSH 0x8
915
#define HV_DISPATCH_VP_FLAG_SKIP_CALLER_SPEC_FLUSH 0x10
916
#define HV_DISPATCH_VP_FLAG_SKIP_CALLER_USER_SPEC_FLUSH 0x20
917
#define HV_DISPATCH_VP_FLAG_SCAN_INTERRUPT_INJECTION 0x40
918
919
struct hv_input_dispatch_vp {
920
u64 partition_id;
921
u32 vp_index;
922
u32 flags;
923
u64 time_slice; /* in 100ns */
924
u64 spec_ctrl;
925
} __packed;
926
927
struct hv_output_dispatch_vp {
928
u32 dispatch_state; /* enum hv_vp_dispatch_state */
929
u32 dispatch_event; /* enum hv_vp_dispatch_event */
930
} __packed;
931
932
struct hv_input_modify_sparse_spa_page_host_access {
933
u32 host_access : 2;
934
u32 reserved : 30;
935
u32 flags;
936
u64 partition_id;
937
u64 spa_page_list[];
938
} __packed;
939
940
/* hv_input_modify_sparse_spa_page_host_access flags */
941
#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_EXCLUSIVE 0x1
942
#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_MAKE_SHARED 0x2
943
#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_LARGE_PAGE 0x4
944
#define HV_MODIFY_SPA_PAGE_HOST_ACCESS_HUGE_PAGE 0x8
945
946
#endif /* _HV_HVHDK_H */
947
948