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