Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 
0003 /*
0004  * This file contains definitions from Hyper-V Hypervisor Top-Level Functional
0005  * Specification (TLFS):
0006  * https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs
0007  */
0008 
0009 #ifndef _ASM_GENERIC_HYPERV_TLFS_H
0010 #define _ASM_GENERIC_HYPERV_TLFS_H
0011 
0012 #include <linux/types.h>
0013 #include <linux/bits.h>
0014 #include <linux/time64.h>
0015 
0016 /*
0017  * While not explicitly listed in the TLFS, Hyper-V always runs with a page size
0018  * of 4096. These definitions are used when communicating with Hyper-V using
0019  * guest physical pages and guest physical page addresses, since the guest page
0020  * size may not be 4096 on all architectures.
0021  */
0022 #define HV_HYP_PAGE_SHIFT      12
0023 #define HV_HYP_PAGE_SIZE       BIT(HV_HYP_PAGE_SHIFT)
0024 #define HV_HYP_PAGE_MASK       (~(HV_HYP_PAGE_SIZE - 1))
0025 
0026 /*
0027  * Hyper-V provides two categories of flags relevant to guest VMs.  The
0028  * "Features" category indicates specific functionality that is available
0029  * to guests on this particular instance of Hyper-V. The "Features"
0030  * are presented in four groups, each of which is 32 bits. The group A
0031  * and B definitions are common across architectures and are listed here.
0032  * However, not all flags are relevant on all architectures.
0033  *
0034  * Groups C and D vary across architectures and are listed in the
0035  * architecture specific portion of hyperv-tlfs.h. Some of these flags exist
0036  * on multiple architectures, but the bit positions are different so they
0037  * cannot appear in the generic portion of hyperv-tlfs.h.
0038  *
0039  * The "Enlightenments" category provides recommendations on whether to use
0040  * specific enlightenments that are available. The Enlighenments are a single
0041  * group of 32 bits, but they vary across architectures and are listed in
0042  * the architecture specific portion of hyperv-tlfs.h.
0043  */
0044 
0045 /*
0046  * Group A Features.
0047  */
0048 
0049 /* VP Runtime register available */
0050 #define HV_MSR_VP_RUNTIME_AVAILABLE     BIT(0)
0051 /* Partition Reference Counter available*/
0052 #define HV_MSR_TIME_REF_COUNT_AVAILABLE     BIT(1)
0053 /* Basic SynIC register available */
0054 #define HV_MSR_SYNIC_AVAILABLE          BIT(2)
0055 /* Synthetic Timer registers available */
0056 #define HV_MSR_SYNTIMER_AVAILABLE       BIT(3)
0057 /* Virtual APIC assist and VP assist page registers available */
0058 #define HV_MSR_APIC_ACCESS_AVAILABLE        BIT(4)
0059 /* Hypercall and Guest OS ID registers available*/
0060 #define HV_MSR_HYPERCALL_AVAILABLE      BIT(5)
0061 /* Access virtual processor index register available*/
0062 #define HV_MSR_VP_INDEX_AVAILABLE       BIT(6)
0063 /* Virtual system reset register available*/
0064 #define HV_MSR_RESET_AVAILABLE          BIT(7)
0065 /* Access statistics page registers available */
0066 #define HV_MSR_STAT_PAGES_AVAILABLE     BIT(8)
0067 /* Partition reference TSC register is available */
0068 #define HV_MSR_REFERENCE_TSC_AVAILABLE      BIT(9)
0069 /* Partition Guest IDLE register is available */
0070 #define HV_MSR_GUEST_IDLE_AVAILABLE     BIT(10)
0071 /* Partition local APIC and TSC frequency registers available */
0072 #define HV_ACCESS_FREQUENCY_MSRS        BIT(11)
0073 /* AccessReenlightenmentControls privilege */
0074 #define HV_ACCESS_REENLIGHTENMENT       BIT(13)
0075 /* AccessTscInvariantControls privilege */
0076 #define HV_ACCESS_TSC_INVARIANT         BIT(15)
0077 
0078 /*
0079  * Group B features.
0080  */
0081 #define HV_CREATE_PARTITIONS            BIT(0)
0082 #define HV_ACCESS_PARTITION_ID          BIT(1)
0083 #define HV_ACCESS_MEMORY_POOL           BIT(2)
0084 #define HV_ADJUST_MESSAGE_BUFFERS       BIT(3)
0085 #define HV_POST_MESSAGES            BIT(4)
0086 #define HV_SIGNAL_EVENTS            BIT(5)
0087 #define HV_CREATE_PORT              BIT(6)
0088 #define HV_CONNECT_PORT             BIT(7)
0089 #define HV_ACCESS_STATS             BIT(8)
0090 #define HV_DEBUGGING                BIT(11)
0091 #define HV_CPU_MANAGEMENT           BIT(12)
0092 #define HV_ENABLE_EXTENDED_HYPERCALLS       BIT(20)
0093 #define HV_ISOLATION                BIT(22)
0094 
0095 /*
0096  * TSC page layout.
0097  */
0098 struct ms_hyperv_tsc_page {
0099     volatile u32 tsc_sequence;
0100     u32 reserved1;
0101     volatile u64 tsc_scale;
0102     volatile s64 tsc_offset;
0103 } __packed;
0104 
0105 /*
0106  * The guest OS needs to register the guest ID with the hypervisor.
0107  * The guest ID is a 64 bit entity and the structure of this ID is
0108  * specified in the Hyper-V specification:
0109  *
0110  * msdn.microsoft.com/en-us/library/windows/hardware/ff542653%28v=vs.85%29.aspx
0111  *
0112  * While the current guideline does not specify how Linux guest ID(s)
0113  * need to be generated, our plan is to publish the guidelines for
0114  * Linux and other guest operating systems that currently are hosted
0115  * on Hyper-V. The implementation here conforms to this yet
0116  * unpublished guidelines.
0117  *
0118  *
0119  * Bit(s)
0120  * 63 - Indicates if the OS is Open Source or not; 1 is Open Source
0121  * 62:56 - Os Type; Linux is 0x100
0122  * 55:48 - Distro specific identification
0123  * 47:16 - Linux kernel version number
0124  * 15:0  - Distro specific identification
0125  *
0126  *
0127  */
0128 
0129 #define HV_LINUX_VENDOR_ID              0x8100
0130 
0131 /*
0132  * Crash notification flags.
0133  */
0134 #define HV_CRASH_CTL_CRASH_NOTIFY_MSG       BIT_ULL(62)
0135 #define HV_CRASH_CTL_CRASH_NOTIFY       BIT_ULL(63)
0136 
0137 /* Declare the various hypercall operations. */
0138 #define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE  0x0002
0139 #define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST   0x0003
0140 #define HVCALL_NOTIFY_LONG_SPIN_WAIT        0x0008
0141 #define HVCALL_SEND_IPI             0x000b
0142 #define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX   0x0013
0143 #define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX    0x0014
0144 #define HVCALL_SEND_IPI_EX          0x0015
0145 #define HVCALL_GET_PARTITION_ID         0x0046
0146 #define HVCALL_DEPOSIT_MEMORY           0x0048
0147 #define HVCALL_CREATE_VP            0x004e
0148 #define HVCALL_GET_VP_REGISTERS         0x0050
0149 #define HVCALL_SET_VP_REGISTERS         0x0051
0150 #define HVCALL_POST_MESSAGE         0x005c
0151 #define HVCALL_SIGNAL_EVENT         0x005d
0152 #define HVCALL_POST_DEBUG_DATA          0x0069
0153 #define HVCALL_RETRIEVE_DEBUG_DATA      0x006a
0154 #define HVCALL_RESET_DEBUG_SESSION      0x006b
0155 #define HVCALL_ADD_LOGICAL_PROCESSOR        0x0076
0156 #define HVCALL_MAP_DEVICE_INTERRUPT     0x007c
0157 #define HVCALL_UNMAP_DEVICE_INTERRUPT       0x007d
0158 #define HVCALL_RETARGET_INTERRUPT       0x007e
0159 #define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af
0160 #define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0
0161 #define HVCALL_MODIFY_SPARSE_GPA_PAGE_HOST_VISIBILITY 0x00db
0162 
0163 /* Extended hypercalls */
0164 #define HV_EXT_CALL_QUERY_CAPABILITIES      0x8001
0165 #define HV_EXT_CALL_MEMORY_HEAT_HINT        0x8003
0166 
0167 #define HV_FLUSH_ALL_PROCESSORS         BIT(0)
0168 #define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES BIT(1)
0169 #define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY   BIT(2)
0170 #define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT  BIT(3)
0171 
0172 /* Extended capability bits */
0173 #define HV_EXT_CAPABILITY_MEMORY_COLD_DISCARD_HINT BIT(8)
0174 
0175 enum HV_GENERIC_SET_FORMAT {
0176     HV_GENERIC_SET_SPARSE_4K,
0177     HV_GENERIC_SET_ALL,
0178 };
0179 
0180 #define HV_PARTITION_ID_SELF        ((u64)-1)
0181 #define HV_VP_INDEX_SELF        ((u32)-2)
0182 
0183 #define HV_HYPERCALL_RESULT_MASK    GENMASK_ULL(15, 0)
0184 #define HV_HYPERCALL_FAST_BIT       BIT(16)
0185 #define HV_HYPERCALL_VARHEAD_OFFSET 17
0186 #define HV_HYPERCALL_VARHEAD_MASK   GENMASK_ULL(26, 17)
0187 #define HV_HYPERCALL_RSVD0_MASK     GENMASK_ULL(31, 27)
0188 #define HV_HYPERCALL_REP_COMP_OFFSET    32
0189 #define HV_HYPERCALL_REP_COMP_1     BIT_ULL(32)
0190 #define HV_HYPERCALL_REP_COMP_MASK  GENMASK_ULL(43, 32)
0191 #define HV_HYPERCALL_RSVD1_MASK     GENMASK_ULL(47, 44)
0192 #define HV_HYPERCALL_REP_START_OFFSET   48
0193 #define HV_HYPERCALL_REP_START_MASK GENMASK_ULL(59, 48)
0194 #define HV_HYPERCALL_RSVD2_MASK     GENMASK_ULL(63, 60)
0195 #define HV_HYPERCALL_RSVD_MASK      (HV_HYPERCALL_RSVD0_MASK | \
0196                      HV_HYPERCALL_RSVD1_MASK | \
0197                      HV_HYPERCALL_RSVD2_MASK)
0198 
0199 /* hypercall status code */
0200 #define HV_STATUS_SUCCESS           0
0201 #define HV_STATUS_INVALID_HYPERCALL_CODE    2
0202 #define HV_STATUS_INVALID_HYPERCALL_INPUT   3
0203 #define HV_STATUS_INVALID_ALIGNMENT     4
0204 #define HV_STATUS_INVALID_PARAMETER     5
0205 #define HV_STATUS_ACCESS_DENIED         6
0206 #define HV_STATUS_OPERATION_DENIED      8
0207 #define HV_STATUS_INSUFFICIENT_MEMORY       11
0208 #define HV_STATUS_INVALID_PORT_ID       17
0209 #define HV_STATUS_INVALID_CONNECTION_ID     18
0210 #define HV_STATUS_INSUFFICIENT_BUFFERS      19
0211 
0212 /*
0213  * The Hyper-V TimeRefCount register and the TSC
0214  * page provide a guest VM clock with 100ns tick rate
0215  */
0216 #define HV_CLOCK_HZ (NSEC_PER_SEC/100)
0217 
0218 /* Define the number of synthetic interrupt sources. */
0219 #define HV_SYNIC_SINT_COUNT     (16)
0220 /* Define the expected SynIC version. */
0221 #define HV_SYNIC_VERSION_1      (0x1)
0222 /* Valid SynIC vectors are 16-255. */
0223 #define HV_SYNIC_FIRST_VALID_VECTOR (16)
0224 
0225 #define HV_SYNIC_CONTROL_ENABLE     (1ULL << 0)
0226 #define HV_SYNIC_SIMP_ENABLE        (1ULL << 0)
0227 #define HV_SYNIC_SIEFP_ENABLE       (1ULL << 0)
0228 #define HV_SYNIC_SINT_MASKED        (1ULL << 16)
0229 #define HV_SYNIC_SINT_AUTO_EOI      (1ULL << 17)
0230 #define HV_SYNIC_SINT_VECTOR_MASK   (0xFF)
0231 
0232 #define HV_SYNIC_STIMER_COUNT       (4)
0233 
0234 /* Define synthetic interrupt controller message constants. */
0235 #define HV_MESSAGE_SIZE         (256)
0236 #define HV_MESSAGE_PAYLOAD_BYTE_COUNT   (240)
0237 #define HV_MESSAGE_PAYLOAD_QWORD_COUNT  (30)
0238 
0239 /*
0240  * Define hypervisor message types. Some of the message types
0241  * are x86/x64 specific, but there's no good way to separate
0242  * them out into the arch-specific version of hyperv-tlfs.h
0243  * because C doesn't provide a way to extend enum types.
0244  * Keeping them all in the arch neutral hyperv-tlfs.h seems
0245  * the least messy compromise.
0246  */
0247 enum hv_message_type {
0248     HVMSG_NONE          = 0x00000000,
0249 
0250     /* Memory access messages. */
0251     HVMSG_UNMAPPED_GPA      = 0x80000000,
0252     HVMSG_GPA_INTERCEPT     = 0x80000001,
0253 
0254     /* Timer notification messages. */
0255     HVMSG_TIMER_EXPIRED     = 0x80000010,
0256 
0257     /* Error messages. */
0258     HVMSG_INVALID_VP_REGISTER_VALUE = 0x80000020,
0259     HVMSG_UNRECOVERABLE_EXCEPTION   = 0x80000021,
0260     HVMSG_UNSUPPORTED_FEATURE   = 0x80000022,
0261 
0262     /* Trace buffer complete messages. */
0263     HVMSG_EVENTLOG_BUFFERCOMPLETE   = 0x80000040,
0264 
0265     /* Platform-specific processor intercept messages. */
0266     HVMSG_X64_IOPORT_INTERCEPT  = 0x80010000,
0267     HVMSG_X64_MSR_INTERCEPT     = 0x80010001,
0268     HVMSG_X64_CPUID_INTERCEPT   = 0x80010002,
0269     HVMSG_X64_EXCEPTION_INTERCEPT   = 0x80010003,
0270     HVMSG_X64_APIC_EOI      = 0x80010004,
0271     HVMSG_X64_LEGACY_FP_ERROR   = 0x80010005
0272 };
0273 
0274 /* Define synthetic interrupt controller message flags. */
0275 union hv_message_flags {
0276     __u8 asu8;
0277     struct {
0278         __u8 msg_pending:1;
0279         __u8 reserved:7;
0280     } __packed;
0281 };
0282 
0283 /* Define port identifier type. */
0284 union hv_port_id {
0285     __u32 asu32;
0286     struct {
0287         __u32 id:24;
0288         __u32 reserved:8;
0289     } __packed u;
0290 };
0291 
0292 /* Define synthetic interrupt controller message header. */
0293 struct hv_message_header {
0294     __u32 message_type;
0295     __u8 payload_size;
0296     union hv_message_flags message_flags;
0297     __u8 reserved[2];
0298     union {
0299         __u64 sender;
0300         union hv_port_id port;
0301     };
0302 } __packed;
0303 
0304 /* Define synthetic interrupt controller message format. */
0305 struct hv_message {
0306     struct hv_message_header header;
0307     union {
0308         __u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
0309     } u;
0310 } __packed;
0311 
0312 /* Define the synthetic interrupt message page layout. */
0313 struct hv_message_page {
0314     struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
0315 } __packed;
0316 
0317 /* Define timer message payload structure. */
0318 struct hv_timer_message_payload {
0319     __u32 timer_index;
0320     __u32 reserved;
0321     __u64 expiration_time;  /* When the timer expired */
0322     __u64 delivery_time;    /* When the message was delivered */
0323 } __packed;
0324 
0325 
0326 /* Define synthetic interrupt controller flag constants. */
0327 #define HV_EVENT_FLAGS_COUNT        (256 * 8)
0328 #define HV_EVENT_FLAGS_LONG_COUNT   (256 / sizeof(unsigned long))
0329 
0330 /*
0331  * Synthetic timer configuration.
0332  */
0333 union hv_stimer_config {
0334     u64 as_uint64;
0335     struct {
0336         u64 enable:1;
0337         u64 periodic:1;
0338         u64 lazy:1;
0339         u64 auto_enable:1;
0340         u64 apic_vector:8;
0341         u64 direct_mode:1;
0342         u64 reserved_z0:3;
0343         u64 sintx:4;
0344         u64 reserved_z1:44;
0345     } __packed;
0346 };
0347 
0348 
0349 /* Define the synthetic interrupt controller event flags format. */
0350 union hv_synic_event_flags {
0351     unsigned long flags[HV_EVENT_FLAGS_LONG_COUNT];
0352 };
0353 
0354 /* Define SynIC control register. */
0355 union hv_synic_scontrol {
0356     u64 as_uint64;
0357     struct {
0358         u64 enable:1;
0359         u64 reserved:63;
0360     } __packed;
0361 };
0362 
0363 /* Define synthetic interrupt source. */
0364 union hv_synic_sint {
0365     u64 as_uint64;
0366     struct {
0367         u64 vector:8;
0368         u64 reserved1:8;
0369         u64 masked:1;
0370         u64 auto_eoi:1;
0371         u64 polling:1;
0372         u64 reserved2:45;
0373     } __packed;
0374 };
0375 
0376 /* Define the format of the SIMP register */
0377 union hv_synic_simp {
0378     u64 as_uint64;
0379     struct {
0380         u64 simp_enabled:1;
0381         u64 preserved:11;
0382         u64 base_simp_gpa:52;
0383     } __packed;
0384 };
0385 
0386 /* Define the format of the SIEFP register */
0387 union hv_synic_siefp {
0388     u64 as_uint64;
0389     struct {
0390         u64 siefp_enabled:1;
0391         u64 preserved:11;
0392         u64 base_siefp_gpa:52;
0393     } __packed;
0394 };
0395 
0396 struct hv_vpset {
0397     u64 format;
0398     u64 valid_bank_mask;
0399     u64 bank_contents[];
0400 } __packed;
0401 
0402 /* HvCallSendSyntheticClusterIpi hypercall */
0403 struct hv_send_ipi {
0404     u32 vector;
0405     u32 reserved;
0406     u64 cpu_mask;
0407 } __packed;
0408 
0409 /* HvCallSendSyntheticClusterIpiEx hypercall */
0410 struct hv_send_ipi_ex {
0411     u32 vector;
0412     u32 reserved;
0413     struct hv_vpset vp_set;
0414 } __packed;
0415 
0416 /* HvFlushGuestPhysicalAddressSpace hypercalls */
0417 struct hv_guest_mapping_flush {
0418     u64 address_space;
0419     u64 flags;
0420 } __packed;
0421 
0422 /*
0423  *  HV_MAX_FLUSH_PAGES = "additional_pages" + 1. It's limited
0424  *  by the bitwidth of "additional_pages" in union hv_gpa_page_range.
0425  */
0426 #define HV_MAX_FLUSH_PAGES (2048)
0427 #define HV_GPA_PAGE_RANGE_PAGE_SIZE_2MB     0
0428 #define HV_GPA_PAGE_RANGE_PAGE_SIZE_1GB     1
0429 
0430 /* HvFlushGuestPhysicalAddressList, HvExtCallMemoryHeatHint hypercall */
0431 union hv_gpa_page_range {
0432     u64 address_space;
0433     struct {
0434         u64 additional_pages:11;
0435         u64 largepage:1;
0436         u64 basepfn:52;
0437     } page;
0438     struct {
0439         u64 reserved:12;
0440         u64 page_size:1;
0441         u64 reserved1:8;
0442         u64 base_large_pfn:43;
0443     };
0444 };
0445 
0446 /*
0447  * All input flush parameters should be in single page. The max flush
0448  * count is equal with how many entries of union hv_gpa_page_range can
0449  * be populated into the input parameter page.
0450  */
0451 #define HV_MAX_FLUSH_REP_COUNT ((HV_HYP_PAGE_SIZE - 2 * sizeof(u64)) /  \
0452                 sizeof(union hv_gpa_page_range))
0453 
0454 struct hv_guest_mapping_flush_list {
0455     u64 address_space;
0456     u64 flags;
0457     union hv_gpa_page_range gpa_list[HV_MAX_FLUSH_REP_COUNT];
0458 };
0459 
0460 /* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
0461 struct hv_tlb_flush {
0462     u64 address_space;
0463     u64 flags;
0464     u64 processor_mask;
0465     u64 gva_list[];
0466 } __packed;
0467 
0468 /* HvFlushVirtualAddressSpaceEx, HvFlushVirtualAddressListEx hypercalls */
0469 struct hv_tlb_flush_ex {
0470     u64 address_space;
0471     u64 flags;
0472     struct hv_vpset hv_vp_set;
0473     u64 gva_list[];
0474 } __packed;
0475 
0476 /* HvGetPartitionId hypercall (output only) */
0477 struct hv_get_partition_id {
0478     u64 partition_id;
0479 } __packed;
0480 
0481 /* HvDepositMemory hypercall */
0482 struct hv_deposit_memory {
0483     u64 partition_id;
0484     u64 gpa_page_list[];
0485 } __packed;
0486 
0487 struct hv_proximity_domain_flags {
0488     u32 proximity_preferred : 1;
0489     u32 reserved : 30;
0490     u32 proximity_info_valid : 1;
0491 } __packed;
0492 
0493 /* Not a union in windows but useful for zeroing */
0494 union hv_proximity_domain_info {
0495     struct {
0496         u32 domain_id;
0497         struct hv_proximity_domain_flags flags;
0498     };
0499     u64 as_uint64;
0500 } __packed;
0501 
0502 struct hv_lp_startup_status {
0503     u64 hv_status;
0504     u64 substatus1;
0505     u64 substatus2;
0506     u64 substatus3;
0507     u64 substatus4;
0508     u64 substatus5;
0509     u64 substatus6;
0510 } __packed;
0511 
0512 /* HvAddLogicalProcessor hypercall */
0513 struct hv_add_logical_processor_in {
0514     u32 lp_index;
0515     u32 apic_id;
0516     union hv_proximity_domain_info proximity_domain_info;
0517     u64 flags;
0518 } __packed;
0519 
0520 struct hv_add_logical_processor_out {
0521     struct hv_lp_startup_status startup_status;
0522 } __packed;
0523 
0524 enum HV_SUBNODE_TYPE
0525 {
0526     HvSubnodeAny = 0,
0527     HvSubnodeSocket = 1,
0528     HvSubnodeAmdNode = 2,
0529     HvSubnodeL3 = 3,
0530     HvSubnodeCount = 4,
0531     HvSubnodeInvalid = -1
0532 };
0533 
0534 /* HvCreateVp hypercall */
0535 struct hv_create_vp {
0536     u64 partition_id;
0537     u32 vp_index;
0538     u8 padding[3];
0539     u8 subnode_type;
0540     u64 subnode_id;
0541     union hv_proximity_domain_info proximity_domain_info;
0542     u64 flags;
0543 } __packed;
0544 
0545 enum hv_interrupt_source {
0546     HV_INTERRUPT_SOURCE_MSI = 1, /* MSI and MSI-X */
0547     HV_INTERRUPT_SOURCE_IOAPIC,
0548 };
0549 
0550 union hv_ioapic_rte {
0551     u64 as_uint64;
0552 
0553     struct {
0554         u32 vector:8;
0555         u32 delivery_mode:3;
0556         u32 destination_mode:1;
0557         u32 delivery_status:1;
0558         u32 interrupt_polarity:1;
0559         u32 remote_irr:1;
0560         u32 trigger_mode:1;
0561         u32 interrupt_mask:1;
0562         u32 reserved1:15;
0563 
0564         u32 reserved2:24;
0565         u32 destination_id:8;
0566     };
0567 
0568     struct {
0569         u32 low_uint32;
0570         u32 high_uint32;
0571     };
0572 } __packed;
0573 
0574 struct hv_interrupt_entry {
0575     u32 source;
0576     u32 reserved1;
0577     union {
0578         union hv_msi_entry msi_entry;
0579         union hv_ioapic_rte ioapic_rte;
0580     };
0581 } __packed;
0582 
0583 /*
0584  * flags for hv_device_interrupt_target.flags
0585  */
0586 #define HV_DEVICE_INTERRUPT_TARGET_MULTICAST        1
0587 #define HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET    2
0588 
0589 struct hv_device_interrupt_target {
0590     u32 vector;
0591     u32 flags;
0592     union {
0593         u64 vp_mask;
0594         struct hv_vpset vp_set;
0595     };
0596 } __packed;
0597 
0598 struct hv_retarget_device_interrupt {
0599     u64 partition_id;       /* use "self" */
0600     u64 device_id;
0601     struct hv_interrupt_entry int_entry;
0602     u64 reserved2;
0603     struct hv_device_interrupt_target int_target;
0604 } __packed __aligned(8);
0605 
0606 
0607 /* HvGetVpRegisters hypercall input with variable size reg name list*/
0608 struct hv_get_vp_registers_input {
0609     struct {
0610         u64 partitionid;
0611         u32 vpindex;
0612         u8  inputvtl;
0613         u8  padding[3];
0614     } header;
0615     struct input {
0616         u32 name0;
0617         u32 name1;
0618     } element[];
0619 } __packed;
0620 
0621 
0622 /* HvGetVpRegisters returns an array of these output elements */
0623 struct hv_get_vp_registers_output {
0624     union {
0625         struct {
0626             u32 a;
0627             u32 b;
0628             u32 c;
0629             u32 d;
0630         } as32 __packed;
0631         struct {
0632             u64 low;
0633             u64 high;
0634         } as64 __packed;
0635     };
0636 };
0637 
0638 /* HvSetVpRegisters hypercall with variable size reg name/value list*/
0639 struct hv_set_vp_registers_input {
0640     struct {
0641         u64 partitionid;
0642         u32 vpindex;
0643         u8  inputvtl;
0644         u8  padding[3];
0645     } header;
0646     struct {
0647         u32 name;
0648         u32 padding1;
0649         u64 padding2;
0650         u64 valuelow;
0651         u64 valuehigh;
0652     } element[];
0653 } __packed;
0654 
0655 enum hv_device_type {
0656     HV_DEVICE_TYPE_LOGICAL = 0,
0657     HV_DEVICE_TYPE_PCI = 1,
0658     HV_DEVICE_TYPE_IOAPIC = 2,
0659     HV_DEVICE_TYPE_ACPI = 3,
0660 };
0661 
0662 typedef u16 hv_pci_rid;
0663 typedef u16 hv_pci_segment;
0664 typedef u64 hv_logical_device_id;
0665 union hv_pci_bdf {
0666     u16 as_uint16;
0667 
0668     struct {
0669         u8 function:3;
0670         u8 device:5;
0671         u8 bus;
0672     };
0673 } __packed;
0674 
0675 union hv_pci_bus_range {
0676     u16 as_uint16;
0677 
0678     struct {
0679         u8 subordinate_bus;
0680         u8 secondary_bus;
0681     };
0682 } __packed;
0683 
0684 union hv_device_id {
0685     u64 as_uint64;
0686 
0687     struct {
0688         u64 reserved0:62;
0689         u64 device_type:2;
0690     };
0691 
0692     /* HV_DEVICE_TYPE_LOGICAL */
0693     struct {
0694         u64 id:62;
0695         u64 device_type:2;
0696     } logical;
0697 
0698     /* HV_DEVICE_TYPE_PCI */
0699     struct {
0700         union {
0701             hv_pci_rid rid;
0702             union hv_pci_bdf bdf;
0703         };
0704 
0705         hv_pci_segment segment;
0706         union hv_pci_bus_range shadow_bus_range;
0707 
0708         u16 phantom_function_bits:2;
0709         u16 source_shadow:1;
0710 
0711         u16 rsvdz0:11;
0712         u16 device_type:2;
0713     } pci;
0714 
0715     /* HV_DEVICE_TYPE_IOAPIC */
0716     struct {
0717         u8 ioapic_id;
0718         u8 rsvdz0;
0719         u16 rsvdz1;
0720         u16 rsvdz2;
0721 
0722         u16 rsvdz3:14;
0723         u16 device_type:2;
0724     } ioapic;
0725 
0726     /* HV_DEVICE_TYPE_ACPI */
0727     struct {
0728         u32 input_mapping_base;
0729         u32 input_mapping_count:30;
0730         u32 device_type:2;
0731     } acpi;
0732 } __packed;
0733 
0734 enum hv_interrupt_trigger_mode {
0735     HV_INTERRUPT_TRIGGER_MODE_EDGE = 0,
0736     HV_INTERRUPT_TRIGGER_MODE_LEVEL = 1,
0737 };
0738 
0739 struct hv_device_interrupt_descriptor {
0740     u32 interrupt_type;
0741     u32 trigger_mode;
0742     u32 vector_count;
0743     u32 reserved;
0744     struct hv_device_interrupt_target target;
0745 } __packed;
0746 
0747 struct hv_input_map_device_interrupt {
0748     u64 partition_id;
0749     u64 device_id;
0750     u64 flags;
0751     struct hv_interrupt_entry logical_interrupt_entry;
0752     struct hv_device_interrupt_descriptor interrupt_descriptor;
0753 } __packed;
0754 
0755 struct hv_output_map_device_interrupt {
0756     struct hv_interrupt_entry interrupt_entry;
0757 } __packed;
0758 
0759 struct hv_input_unmap_device_interrupt {
0760     u64 partition_id;
0761     u64 device_id;
0762     struct hv_interrupt_entry interrupt_entry;
0763 } __packed;
0764 
0765 #define HV_SOURCE_SHADOW_NONE               0x0
0766 #define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE   0x1
0767 
0768 /*
0769  * The whole argument should fit in a page to be able to pass to the hypervisor
0770  * in one hypercall.
0771  */
0772 #define HV_MEMORY_HINT_MAX_GPA_PAGE_RANGES  \
0773     ((HV_HYP_PAGE_SIZE - sizeof(struct hv_memory_hint)) / \
0774         sizeof(union hv_gpa_page_range))
0775 
0776 /* HvExtCallMemoryHeatHint hypercall */
0777 #define HV_EXT_MEMORY_HEAT_HINT_TYPE_COLD_DISCARD   2
0778 struct hv_memory_hint {
0779     u64 type:2;
0780     u64 reserved:62;
0781     union hv_gpa_page_range ranges[];
0782 } __packed;
0783 
0784 #endif