hyperv.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #ifndef __HYPERV_H
  2. #define __HYPERV_H
  3. #include "libcflat.h"
  4. #include "processor.h"
  5. #define HYPERV_CPUID_FEATURES 0x40000003
  6. #define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1)
  7. #define HV_X64_MSR_SYNIC_AVAILABLE (1 << 2)
  8. #define HV_X64_MSR_SYNTIMER_AVAILABLE (1 << 3)
  9. #define HV_X64_MSR_GUEST_OS_ID 0x40000000
  10. #define HV_X64_MSR_HYPERCALL 0x40000001
  11. #define HV_X64_MSR_TIME_REF_COUNT 0x40000020
  12. #define HV_X64_MSR_REFERENCE_TSC 0x40000021
  13. /* Define synthetic interrupt controller model specific registers. */
  14. #define HV_X64_MSR_SCONTROL 0x40000080
  15. #define HV_X64_MSR_SVERSION 0x40000081
  16. #define HV_X64_MSR_SIEFP 0x40000082
  17. #define HV_X64_MSR_SIMP 0x40000083
  18. #define HV_X64_MSR_EOM 0x40000084
  19. #define HV_X64_MSR_SINT0 0x40000090
  20. #define HV_X64_MSR_SINT1 0x40000091
  21. #define HV_X64_MSR_SINT2 0x40000092
  22. #define HV_X64_MSR_SINT3 0x40000093
  23. #define HV_X64_MSR_SINT4 0x40000094
  24. #define HV_X64_MSR_SINT5 0x40000095
  25. #define HV_X64_MSR_SINT6 0x40000096
  26. #define HV_X64_MSR_SINT7 0x40000097
  27. #define HV_X64_MSR_SINT8 0x40000098
  28. #define HV_X64_MSR_SINT9 0x40000099
  29. #define HV_X64_MSR_SINT10 0x4000009A
  30. #define HV_X64_MSR_SINT11 0x4000009B
  31. #define HV_X64_MSR_SINT12 0x4000009C
  32. #define HV_X64_MSR_SINT13 0x4000009D
  33. #define HV_X64_MSR_SINT14 0x4000009E
  34. #define HV_X64_MSR_SINT15 0x4000009F
  35. /*
  36. * Synthetic Timer MSRs. Four timers per vcpu.
  37. */
  38. #define HV_X64_MSR_STIMER0_CONFIG 0x400000B0
  39. #define HV_X64_MSR_STIMER0_COUNT 0x400000B1
  40. #define HV_X64_MSR_STIMER1_CONFIG 0x400000B2
  41. #define HV_X64_MSR_STIMER1_COUNT 0x400000B3
  42. #define HV_X64_MSR_STIMER2_CONFIG 0x400000B4
  43. #define HV_X64_MSR_STIMER2_COUNT 0x400000B5
  44. #define HV_X64_MSR_STIMER3_CONFIG 0x400000B6
  45. #define HV_X64_MSR_STIMER3_COUNT 0x400000B7
  46. #define HV_SYNIC_CONTROL_ENABLE (1ULL << 0)
  47. #define HV_SYNIC_SIMP_ENABLE (1ULL << 0)
  48. #define HV_SYNIC_SIEFP_ENABLE (1ULL << 0)
  49. #define HV_SYNIC_SINT_MASKED (1ULL << 16)
  50. #define HV_SYNIC_SINT_AUTO_EOI (1ULL << 17)
  51. #define HV_SYNIC_SINT_VECTOR_MASK (0xFF)
  52. #define HV_SYNIC_SINT_COUNT 16
  53. #define HV_STIMER_ENABLE (1ULL << 0)
  54. #define HV_STIMER_PERIODIC (1ULL << 1)
  55. #define HV_STIMER_LAZY (1ULL << 2)
  56. #define HV_STIMER_AUTOENABLE (1ULL << 3)
  57. #define HV_STIMER_SINT(config) (__u8)(((config) >> 16) & 0x0F)
  58. #define HV_SYNIC_STIMER_COUNT (4)
  59. /* Define synthetic interrupt controller message constants. */
  60. #define HV_MESSAGE_SIZE (256)
  61. #define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240)
  62. #define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
  63. /* Define hypervisor message types. */
  64. enum hv_message_type {
  65. HVMSG_NONE = 0x00000000,
  66. /* Memory access messages. */
  67. HVMSG_UNMAPPED_GPA = 0x80000000,
  68. HVMSG_GPA_INTERCEPT = 0x80000001,
  69. /* Timer notification messages. */
  70. HVMSG_TIMER_EXPIRED = 0x80000010,
  71. /* Error messages. */
  72. HVMSG_INVALID_VP_REGISTER_VALUE = 0x80000020,
  73. HVMSG_UNRECOVERABLE_EXCEPTION = 0x80000021,
  74. HVMSG_UNSUPPORTED_FEATURE = 0x80000022,
  75. /* Trace buffer complete messages. */
  76. HVMSG_EVENTLOG_BUFFERCOMPLETE = 0x80000040,
  77. /* Platform-specific processor intercept messages. */
  78. HVMSG_X64_IOPORT_INTERCEPT = 0x80010000,
  79. HVMSG_X64_MSR_INTERCEPT = 0x80010001,
  80. HVMSG_X64_CPUID_INTERCEPT = 0x80010002,
  81. HVMSG_X64_EXCEPTION_INTERCEPT = 0x80010003,
  82. HVMSG_X64_APIC_EOI = 0x80010004,
  83. HVMSG_X64_LEGACY_FP_ERROR = 0x80010005
  84. };
  85. /* Define synthetic interrupt controller message flags. */
  86. union hv_message_flags {
  87. uint8_t asu8;
  88. struct {
  89. uint8_t msg_pending:1;
  90. uint8_t reserved:7;
  91. };
  92. };
  93. union hv_port_id {
  94. uint32_t asu32;
  95. struct {
  96. uint32_t id:24;
  97. uint32_t reserved:8;
  98. } u;
  99. };
  100. /* Define port type. */
  101. enum hv_port_type {
  102. HVPORT_MSG = 1,
  103. HVPORT_EVENT = 2,
  104. HVPORT_MONITOR = 3
  105. };
  106. /* Define synthetic interrupt controller message header. */
  107. struct hv_message_header {
  108. uint32_t message_type;
  109. uint8_t payload_size;
  110. union hv_message_flags message_flags;
  111. uint8_t reserved[2];
  112. union {
  113. uint64_t sender;
  114. union hv_port_id port;
  115. };
  116. };
  117. /* Define timer message payload structure. */
  118. struct hv_timer_message_payload {
  119. uint32_t timer_index;
  120. uint32_t reserved;
  121. uint64_t expiration_time; /* When the timer expired */
  122. uint64_t delivery_time; /* When the message was delivered */
  123. };
  124. /* Define synthetic interrupt controller message format. */
  125. struct hv_message {
  126. struct hv_message_header header;
  127. union {
  128. uint64_t payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
  129. } u;
  130. };
  131. /* Define the synthetic interrupt message page layout. */
  132. struct hv_message_page {
  133. struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
  134. };
  135. #define HV_EVENT_FLAGS_COUNT (256 * 8)
  136. struct hv_event_flags {
  137. ulong flags[HV_EVENT_FLAGS_COUNT / (8 * sizeof(ulong))];
  138. };
  139. struct hv_event_flags_page {
  140. struct hv_event_flags slot[HV_SYNIC_SINT_COUNT];
  141. };
  142. #define HV_X64_MSR_HYPERCALL_ENABLE 0x1
  143. #define HV_HYPERCALL_FAST (1u << 16)
  144. #define HVCALL_POST_MESSAGE 0x5c
  145. #define HVCALL_SIGNAL_EVENT 0x5d
  146. struct hv_input_post_message {
  147. u32 connectionid;
  148. u32 reserved;
  149. u32 message_type;
  150. u32 payload_size;
  151. u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
  152. };
  153. static inline bool synic_supported(void)
  154. {
  155. return cpuid(HYPERV_CPUID_FEATURES).a & HV_X64_MSR_SYNIC_AVAILABLE;
  156. }
  157. static inline bool stimer_supported(void)
  158. {
  159. return cpuid(HYPERV_CPUID_FEATURES).a & HV_X64_MSR_SYNIC_AVAILABLE;
  160. }
  161. static inline bool hv_time_ref_counter_supported(void)
  162. {
  163. return cpuid(HYPERV_CPUID_FEATURES).a & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE;
  164. }
  165. void synic_sint_create(u8 sint, u8 vec, bool auto_eoi);
  166. void synic_sint_set(u8 vcpu, u8 sint);
  167. void synic_sint_destroy(u8 sint);
  168. void msg_conn_create(u8 sint, u8 vec, u8 conn_id);
  169. void msg_conn_destroy(u8 sint, u8 conn_id);
  170. void evt_conn_create(u8 sint, u8 vec, u8 conn_id);
  171. void evt_conn_destroy(u8 sint, u8 conn_id);
  172. struct hv_reference_tsc_page {
  173. uint32_t tsc_sequence;
  174. uint32_t res1;
  175. uint64_t tsc_scale;
  176. int64_t tsc_offset;
  177. };
  178. #endif