]> git.proxmox.com Git - mirror_qemu.git/blame - include/hw/hyperv/dynmem-proto.h
Merge tag 'pull-trivial-patches' of https://gitlab.com/mjt0k/qemu into staging
[mirror_qemu.git] / include / hw / hyperv / dynmem-proto.h
CommitLineData
4f80cd2f
MS
1#ifndef HW_HYPERV_DYNMEM_PROTO_H
2#define HW_HYPERV_DYNMEM_PROTO_H
3
4/*
5 * Hyper-V Dynamic Memory Protocol definitions
6 *
7 * Copyright (C) 2020-2023 Oracle and/or its affiliates.
8 *
9 * Based on drivers/hv/hv_balloon.c from Linux kernel:
10 * Copyright (c) 2012, Microsoft Corporation.
11 *
12 * Author: K. Y. Srinivasan <kys@microsoft.com>
13 *
14 * This work is licensed under the terms of the GNU GPL, version 2.
15 * See the COPYING file in the top-level directory.
16 */
17
18/*
19 * Protocol versions. The low word is the minor version, the high word the major
20 * version.
21 *
22 * History:
23 * Initial version 1.0
24 * Changed to 0.1 on 2009/03/25
25 * Changes to 0.2 on 2009/05/14
26 * Changes to 0.3 on 2009/12/03
27 * Changed to 1.0 on 2011/04/05
28 * Changed to 2.0 on 2019/12/10
29 */
30
31#define DYNMEM_MAKE_VERSION(Major, Minor) ((uint32_t)(((Major) << 16) | (Minor)))
32#define DYNMEM_MAJOR_VERSION(Version) ((uint32_t)(Version) >> 16)
33#define DYNMEM_MINOR_VERSION(Version) ((uint32_t)(Version) & 0xff)
34
35enum {
36 DYNMEM_PROTOCOL_VERSION_1 = DYNMEM_MAKE_VERSION(0, 3),
37 DYNMEM_PROTOCOL_VERSION_2 = DYNMEM_MAKE_VERSION(1, 0),
38 DYNMEM_PROTOCOL_VERSION_3 = DYNMEM_MAKE_VERSION(2, 0),
39
40 DYNMEM_PROTOCOL_VERSION_WIN7 = DYNMEM_PROTOCOL_VERSION_1,
41 DYNMEM_PROTOCOL_VERSION_WIN8 = DYNMEM_PROTOCOL_VERSION_2,
42 DYNMEM_PROTOCOL_VERSION_WIN10 = DYNMEM_PROTOCOL_VERSION_3,
43
44 DYNMEM_PROTOCOL_VERSION_CURRENT = DYNMEM_PROTOCOL_VERSION_WIN10
45};
46
47
48
49/*
50 * Message Types
51 */
52
53enum dm_message_type {
54 /*
55 * Version 0.3
56 */
57 DM_ERROR = 0,
58 DM_VERSION_REQUEST = 1,
59 DM_VERSION_RESPONSE = 2,
60 DM_CAPABILITIES_REPORT = 3,
61 DM_CAPABILITIES_RESPONSE = 4,
62 DM_STATUS_REPORT = 5,
63 DM_BALLOON_REQUEST = 6,
64 DM_BALLOON_RESPONSE = 7,
65 DM_UNBALLOON_REQUEST = 8,
66 DM_UNBALLOON_RESPONSE = 9,
67 DM_MEM_HOT_ADD_REQUEST = 10,
68 DM_MEM_HOT_ADD_RESPONSE = 11,
69 DM_VERSION_03_MAX = 11,
70 /*
71 * Version 1.0.
72 */
73 DM_INFO_MESSAGE = 12,
74 DM_VERSION_1_MAX = 12,
75
76 /*
77 * Version 2.0
78 */
79 DM_MEM_HOT_REMOVE_REQUEST = 13,
80 DM_MEM_HOT_REMOVE_RESPONSE = 14
81};
82
83
84/*
85 * Structures defining the dynamic memory management
86 * protocol.
87 */
88
89union dm_version {
90 struct {
91 uint16_t minor_version;
92 uint16_t major_version;
93 };
94 uint32_t version;
95} QEMU_PACKED;
96
97
98union dm_caps {
99 struct {
100 uint64_t balloon:1;
101 uint64_t hot_add:1;
102 /*
103 * To support guests that may have alignment
104 * limitations on hot-add, the guest can specify
105 * its alignment requirements; a value of n
106 * represents an alignment of 2^n in mega bytes.
107 */
108 uint64_t hot_add_alignment:4;
109 uint64_t hot_remove:1;
110 uint64_t reservedz:57;
111 } cap_bits;
112 uint64_t caps;
113} QEMU_PACKED;
114
115union dm_mem_page_range {
116 struct {
117 /*
118 * The PFN number of the first page in the range.
119 * 40 bits is the architectural limit of a PFN
120 * number for AMD64.
121 */
122 uint64_t start_page:40;
123 /*
124 * The number of pages in the range.
125 */
126 uint64_t page_cnt:24;
127 } finfo;
128 uint64_t page_range;
129} QEMU_PACKED;
130
131
132
133/*
134 * The header for all dynamic memory messages:
135 *
136 * type: Type of the message.
137 * size: Size of the message in bytes; including the header.
138 * trans_id: The guest is responsible for manufacturing this ID.
139 */
140
141struct dm_header {
142 uint16_t type;
143 uint16_t size;
144 uint32_t trans_id;
145} QEMU_PACKED;
146
147/*
148 * A generic message format for dynamic memory.
149 * Specific message formats are defined later in the file.
150 */
151
152struct dm_message {
153 struct dm_header hdr;
154 uint8_t data[]; /* enclosed message */
155} QEMU_PACKED;
156
157
158/*
159 * Specific message types supporting the dynamic memory protocol.
160 */
161
162/*
163 * Version negotiation message. Sent from the guest to the host.
164 * The guest is free to try different versions until the host
165 * accepts the version.
166 *
167 * dm_version: The protocol version requested.
168 * is_last_attempt: If TRUE, this is the last version guest will request.
169 * reservedz: Reserved field, set to zero.
170 */
171
172struct dm_version_request {
173 struct dm_header hdr;
174 union dm_version version;
175 uint32_t is_last_attempt:1;
176 uint32_t reservedz:31;
177} QEMU_PACKED;
178
179/*
180 * Version response message; Host to Guest and indicates
181 * if the host has accepted the version sent by the guest.
182 *
183 * is_accepted: If TRUE, host has accepted the version and the guest
184 * should proceed to the next stage of the protocol. FALSE indicates that
185 * guest should re-try with a different version.
186 *
187 * reservedz: Reserved field, set to zero.
188 */
189
190struct dm_version_response {
191 struct dm_header hdr;
192 uint64_t is_accepted:1;
193 uint64_t reservedz:63;
194} QEMU_PACKED;
195
196/*
197 * Message reporting capabilities. This is sent from the guest to the
198 * host.
199 */
200
201struct dm_capabilities {
202 struct dm_header hdr;
203 union dm_caps caps;
204 uint64_t min_page_cnt;
205 uint64_t max_page_number;
206} QEMU_PACKED;
207
208/*
209 * Response to the capabilities message. This is sent from the host to the
210 * guest. This message notifies if the host has accepted the guest's
211 * capabilities. If the host has not accepted, the guest must shutdown
212 * the service.
213 *
214 * is_accepted: Indicates if the host has accepted guest's capabilities.
215 * reservedz: Must be 0.
216 */
217
218struct dm_capabilities_resp_msg {
219 struct dm_header hdr;
220 uint64_t is_accepted:1;
221 uint64_t hot_remove:1;
222 uint64_t suppress_pressure_reports:1;
223 uint64_t reservedz:61;
224} QEMU_PACKED;
225
226/*
227 * This message is used to report memory pressure from the guest.
228 * This message is not part of any transaction and there is no
229 * response to this message.
230 *
231 * num_avail: Available memory in pages.
232 * num_committed: Committed memory in pages.
233 * page_file_size: The accumulated size of all page files
234 * in the system in pages.
c437eb1d 235 * zero_free: The number of zero and free pages.
4f80cd2f
MS
236 * page_file_writes: The writes to the page file in pages.
237 * io_diff: An indicator of file cache efficiency or page file activity,
238 * calculated as File Cache Page Fault Count - Page Read Count.
239 * This value is in pages.
240 *
241 * Some of these metrics are Windows specific and fortunately
242 * the algorithm on the host side that computes the guest memory
243 * pressure only uses num_committed value.
244 */
245
246struct dm_status {
247 struct dm_header hdr;
248 uint64_t num_avail;
249 uint64_t num_committed;
250 uint64_t page_file_size;
251 uint64_t zero_free;
252 uint32_t page_file_writes;
253 uint32_t io_diff;
254} QEMU_PACKED;
255
256
257/*
258 * Message to ask the guest to allocate memory - balloon up message.
259 * This message is sent from the host to the guest. The guest may not be
260 * able to allocate as much memory as requested.
261 *
262 * num_pages: number of pages to allocate.
263 */
264
265struct dm_balloon {
266 struct dm_header hdr;
267 uint32_t num_pages;
268 uint32_t reservedz;
269} QEMU_PACKED;
270
271
272/*
273 * Balloon response message; this message is sent from the guest
274 * to the host in response to the balloon message.
275 *
276 * reservedz: Reserved; must be set to zero.
277 * more_pages: If FALSE, this is the last message of the transaction.
c437eb1d 278 * if TRUE there will be at least one more message from the guest.
4f80cd2f
MS
279 *
280 * range_count: The number of ranges in the range array.
281 *
282 * range_array: An array of page ranges returned to the host.
283 *
284 */
285
286struct dm_balloon_response {
287 struct dm_header hdr;
288 uint32_t reservedz;
289 uint32_t more_pages:1;
290 uint32_t range_count:31;
291 union dm_mem_page_range range_array[];
292} QEMU_PACKED;
293
294/*
295 * Un-balloon message; this message is sent from the host
296 * to the guest to give guest more memory.
297 *
298 * more_pages: If FALSE, this is the last message of the transaction.
c437eb1d 299 * if TRUE there will be at least one more message from the guest.
4f80cd2f
MS
300 *
301 * reservedz: Reserved; must be set to zero.
302 *
303 * range_count: The number of ranges in the range array.
304 *
305 * range_array: An array of page ranges returned to the host.
306 *
307 */
308
309struct dm_unballoon_request {
310 struct dm_header hdr;
311 uint32_t more_pages:1;
312 uint32_t reservedz:31;
313 uint32_t range_count;
314 union dm_mem_page_range range_array[];
315} QEMU_PACKED;
316
317/*
318 * Un-balloon response message; this message is sent from the guest
319 * to the host in response to an unballoon request.
320 *
321 */
322
323struct dm_unballoon_response {
324 struct dm_header hdr;
325} QEMU_PACKED;
326
327
328/*
329 * Hot add request message. Message sent from the host to the guest.
330 *
331 * mem_range: Memory range to hot add.
332 *
333 */
334
335struct dm_hot_add {
336 struct dm_header hdr;
337 union dm_mem_page_range range;
338} QEMU_PACKED;
339
340/*
341 * Hot add response message.
342 * This message is sent by the guest to report the status of a hot add request.
343 * If page_count is less than the requested page count, then the host should
344 * assume all further hot add requests will fail, since this indicates that
345 * the guest has hit an upper physical memory barrier.
346 *
347 * Hot adds may also fail due to low resources; in this case, the guest must
348 * not complete this message until the hot add can succeed, and the host must
349 * not send a new hot add request until the response is sent.
350 * If VSC fails to hot add memory DYNMEM_NUMBER_OF_UNSUCCESSFUL_HOTADD_ATTEMPTS
351 * times it fails the request.
352 *
353 *
354 * page_count: number of pages that were successfully hot added.
355 *
356 * result: result of the operation 1: success, 0: failure.
357 *
358 */
359
360struct dm_hot_add_response {
361 struct dm_header hdr;
362 uint32_t page_count;
363 uint32_t result;
364} QEMU_PACKED;
365
366struct dm_hot_remove {
367 struct dm_header hdr;
368 uint32_t virtual_node;
369 uint32_t page_count;
370 uint32_t qos_flags;
371 uint32_t reservedZ;
372} QEMU_PACKED;
373
374struct dm_hot_remove_response {
375 struct dm_header hdr;
376 uint32_t result;
377 uint32_t range_count;
378 uint64_t more_pages:1;
379 uint64_t reservedz:63;
380 union dm_mem_page_range range_array[];
381} QEMU_PACKED;
382
383#define DM_REMOVE_QOS_LARGE (1 << 0)
384#define DM_REMOVE_QOS_LOCAL (1 << 1)
385#define DM_REMOVE_QOS_MASK (0x3)
386
387/*
388 * Types of information sent from host to the guest.
389 */
390
391enum dm_info_type {
392 INFO_TYPE_MAX_PAGE_CNT = 0,
393 MAX_INFO_TYPE
394};
395
396
397/*
398 * Header for the information message.
399 */
400
401struct dm_info_header {
402 enum dm_info_type type;
403 uint32_t data_size;
404 uint8_t data[];
405} QEMU_PACKED;
406
407/*
408 * This message is sent from the host to the guest to pass
409 * some relevant information (win8 addition).
410 *
411 * reserved: no used.
412 * info_size: size of the information blob.
413 * info: information blob.
414 */
415
416struct dm_info_msg {
417 struct dm_header hdr;
418 uint32_t reserved;
419 uint32_t info_size;
420 uint8_t info[];
421};
422
423#endif