VirtualBox

source: vbox/trunk/src/VBox/Devices/VirtIO/Virtio_1_0.h@ 80928

Last change on this file since 80928 was 80928, checked in by vboxsync, 5 years ago

Storage/DevVirtioSCSI.cpp: Fixed/improved attach target count/allocation and processing, converted size_t to uint32_t where possible and added mapping on uint32_t <-> size_t conversions between VirtIO and the VSCSI layer. Other clean-up

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.6 KB
Line 
1/* $Id: Virtio_1_0.h 80928 2019-09-21 05:29:54Z vboxsync $ */
2/** @file
3 * Virtio_1_0.h - Virtio Declarations
4 */
5
6/*
7 * Copyright (C) 2009-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef VBOX_INCLUDED_SRC_VirtIO_Virtio_1_0_h
19#define VBOX_INCLUDED_SRC_VirtIO_Virtio_1_0_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include <iprt/ctype.h>
25#include <iprt/sg.h>
26
27typedef void * VIRTIOHANDLE; /**< Opaque handle to the VirtIO framework */
28
29
30/**
31 * Important sizing and bounds params for this impl. of VirtIO 1.0 PCI device
32 */
33 /**
34 * TEMPORARY NOTE: Some of these values are experimental during development and will likely change.
35 */
36#define VIRTIO_MAX_QUEUE_NAME_SIZE 32 /**< Maximum length of a queue name */
37#define VIRTQ_MAX_SIZE 1024 /**< Max size (# desc elements) of a virtq */
38#define VIRTQ_MAX_CNT 24 /**< Max queues we allow guest to create */
39#define VIRTIO_NOTIFY_OFFSET_MULTIPLIER 2 /**< VirtIO Notify Cap. MMIO config param */
40#define VIRTIO_REGION_PCI_CAP 2 /**< BAR for VirtIO Cap. MMIO (impl specific) */
41
42#define VIRTIO_HEX_DUMP(logLevel, pv, cb, base, title) \
43 do { \
44 if (LogIsItEnabled(logLevel, LOG_GROUP)) \
45 virtioHexDump((pv), (cb), (base), (title)); \
46 } while (0)
47
48
49/**
50 * The following structure holds the pre-processed context of descriptor chain pulled from a virtio queue
51 * to conduct a transaction between the client of this virtio implementation and the guest VM's virtio driver.
52 * It contains the head index of the descriptor chain, the output data from the client that has been
53 * converted to a contiguous virtual memory and a physical memory scatter-gather buffer for use by by
54 * the virtio framework to complete the transaction in the final phase of round-trip processing.
55 *
56 * The client should not modify the contents of this buffer. The primary field of interest to the
57 * client is pVirtSrc, which contains the VirtIO "OUT" (to device) buffer from the guest.
58 *
59 * Typical use is, When the client (worker thread) detects available data on the queue, it pulls the
60 * next one of these descriptor chain structs off the queue using virtioQueueGet(), processes the
61 * virtual memory buffer pVirtSrc, produces result data to pass back to the guest driver and calls
62 * virtioQueuePut() to return the result data to the client.
63 */
64typedef struct VIRTIO_DESC_CHAIN
65{
66 uint32_t uHeadIdx; /**< Head idx of associated desc chain */
67 uint32_t cbVirtSrc; /**< Size of virt source buffer */
68 void *pVirtSrc; /**< Virt mem buf holding out data from guest */
69 uint32_t cbPhysDst; /**< Total size of dst buffer */
70 PRTSGBUF pSgPhysDst; /**< Phys S/G buf to store result for guest */
71} VIRTIO_DESC_CHAIN_T, *PVIRTIO_DESC_CHAIN_T, **PPVIRTIO_DESC_CHAIN_T;
72
73/**
74 * The following structure is used to pass the PCI parameters from the consumer
75 * to this generic VirtIO framework. This framework provides the Vendor ID as Virtio.
76 */
77typedef struct VIRTIOPCIPARAMS
78{
79 uint16_t uDeviceId; /**< PCI Cfg Device ID */
80 uint16_t uClassBase; /**< PCI Cfg Base Class */
81 uint16_t uClassSub; /**< PCI Cfg Subclass */
82 uint16_t uClassProg; /**< PCI Cfg Programming Interface Class */
83 uint16_t uSubsystemId; /**< PCI Cfg Card Manufacturer Vendor ID */
84 uint16_t uSubsystemVendorId; /**< PCI Cfg Chipset Manufacturer Vendor ID */
85 uint16_t uRevisionId; /**< PCI Cfg Revision ID */
86 uint16_t uInterruptLine; /**< PCI Cfg Interrupt line */
87 uint16_t uInterruptPin; /**< PCI Cfg Interrupt pin */
88} VIRTIOPCIPARAMS, *PVIRTIOPCIPARAMS;
89
90/**
91 * Implementation-specific client callback to notify client of significant device status
92 * changes.
93 *
94 * @param hVirtio Handle to VirtIO framework
95 * @param fDriverOk True if guest driver is okay (thus queues, etc... are valid)
96 * @param pClient Pointer to opaque client data (state)
97 */
98typedef DECLCALLBACK(void) FNVIRTIOSTATUSCHANGED(VIRTIOHANDLE hVirtio, void *pClient, bool fDriverOk);
99typedef FNVIRTIOSTATUSCHANGED *PFNVIRTIOSTATUSCHANGED;
100
101/**
102 * When guest-to-host queue notifications are enabled, the guest driver notifies the host
103 * that the avail queue has buffers, and this callback informs the client.
104 *
105 * @param hVirtio Handle to the VirtIO framework
106 * @param qIdx Index of the notified queue
107 * @param pClient Pointer to opaque client data (state)
108 */
109typedef DECLCALLBACK(void) FNVIRTIOQUEUENOTIFIED(VIRTIOHANDLE hVirtio, void *pClient, uint16_t qIdx);
110typedef FNVIRTIOQUEUENOTIFIED *PFNVIRTIOQUEUENOTIFIED;
111
112 /**
113 * Implementation-specific client callback to access VirtIO Device-specific capabilities
114 * (other VirtIO capabilities and features are handled in VirtIO implementation)
115 *
116 * @param pDevIns The device instance.
117 * @param offset Offset within device specific capabilities struct
118 * @param pvBuf Buffer in which to save read data
119 * @param cbWrite Number of bytes to write
120 */
121typedef DECLCALLBACK(int) FNVIRTIODEVCAPWRITE(PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, uint32_t cbWrite);
122typedef FNVIRTIODEVCAPWRITE *PFNVIRTIODEVCAPWRITE;
123
124/**
125 * Implementation-specific client ballback to access VirtIO Device-specific capabilities
126 * (other VirtIO capabilities and features are handled in VirtIO implementation)
127 *
128 * @param pDevIns The device instance.
129 * @param offset Offset within device specific capabilities struct
130 * @param pvBuf Buffer in which to save read data
131 * @param cbRead Number of bytes to read
132 */
133typedef DECLCALLBACK(int) FNVIRTIODEVCAPREAD(PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, uint32_t cbRead);
134typedef FNVIRTIODEVCAPREAD *PFNVIRTIODEVCAPREAD;
135
136
137/** @name VirtIO port I/O callbacks.
138 * @{ */
139typedef struct VIRTIOCALLBACKS
140{
141 DECLCALLBACKMEMBER(void, pfnVirtioStatusChanged)
142 (VIRTIOHANDLE hVirtio, void *pClient, bool fDriverOk);
143 DECLCALLBACKMEMBER(void, pfnVirtioQueueNotified)
144 (VIRTIOHANDLE hVirtio, void *pClient, uint16_t qIdx);
145 DECLCALLBACKMEMBER(int, pfnVirtioDevCapRead)
146 (PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, uint32_t cbRead);
147 DECLCALLBACKMEMBER(int, pfnVirtioDevCapWrite)
148 (PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, uint32_t cbWrite);
149 DECLCALLBACKMEMBER(int, pfnSSMDevLiveExec)
150 (PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass);
151 DECLCALLBACKMEMBER(int, pfnSSMDevSaveExec)
152 (PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
153 DECLCALLBACKMEMBER(int, pfnSSMDevLoadExec)
154 (PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
155 DECLCALLBACKMEMBER(int, pfnSSMDevLoadDone)
156 (PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
157
158} VIRTIOCALLBACKS, *PVIRTIOCALLBACKS;
159/** @} */
160
161/** API for VirtIO client */
162
163/**
164 * Allocate client context for client to work with VirtIO-provided with queue
165 * As a side effect creates a buffer vector a client can get a pointer to
166 * with a call to virtioQueueDescChain()
167 *
168 * @param hVirtio - Handle to VirtIO framework
169 * @param qIdx - Queue number
170 * @param pcszName - Name to give queue
171 *
172 * @returns status VINF_SUCCESS - Success
173 * VERR_INVALID_STATE - VirtIO not in ready state
174 * VERR_NO_MEMORY - Out of memory
175 *
176 * @returns status. If false, the call failed and the client should call virtioResetAll()
177 */
178int virtioQueueAttach(VIRTIOHANDLE hVirtio, uint16_t qIdx, const char *pcszName);
179
180/**
181 * Detaches from queue and release resources
182 *
183 * @param hVirtio - Handle for VirtIO framework
184 * @param qIdx - Queue number
185 *
186 */
187int virtioQueueDetach(VIRTIOHANDLE hVirtio, uint16_t qIdx);
188
189/**
190 * Removes descriptor chain from avail ring of indicated queue and converts the descriptor
191 * chain into its OUT (to device) and IN to guest components. Additionally it converts
192 * the OUT desc chain data to a contiguous virtual memory buffer for easy consumption
193 * by the caller. The caller must return the descriptor chain pointer via virtioQueuePut()
194 * and then call virtioQueueSync() at some point to return the data to the guest and
195 * complete the transaction.
196 *
197 * @param hVirtio - Handle for VirtIO framework
198 * @param qIdx - Queue number
199 * @param fRemove - flags whether to remove desc chain from queue (false = peek)
200 * @param ppDescChain - Address to store pointer to descriptor chain that contains the
201 * pre-processed transaction information pulled from the virtq.
202 *
203 * @returns status VINF_SUCCESS - Success
204 * VERR_INVALID_STATE - VirtIO not in ready state
205 */
206int virtioQueueGet(VIRTIOHANDLE hVirtio, uint16_t qIdx, PPVIRTIO_DESC_CHAIN_T ppDescChain, bool fRemove);
207
208
209/**
210 * Returns data to the guest to complete a transaction initiated by virtQueueGet().
211 * The caller passes in a pointer to a scatter-gather buffer of virtual memory segments
212 * and a pointer to the descriptor chain context originally derived from the pulled
213 * queue entry, and this function will put write the virtual memory s/g buffer into the
214 * guest's physical memory free the descriptor chain. The caller handles the freeing
215 * (as needed) of the virtual memory buffer.
216 *
217 * NOTE: This does a write-ahead to the used ring of the guest's queue.
218 * The data written won't be seen by the guest until the next call to virtioQueueSync()
219 *
220 *
221 * @param hVirtio - Handle for VirtIO framework
222 * @param qIdx - Queue number
223 *
224 * @param pSgVirtReturn - Points toscatter-gather buffer of virtual memory segments
225 the caller is returning to the guest.
226 *
227 * @param pDescChain - This contains the context of the scatter-gather buffer
228 * originally pulled from the queue.
229 *
230 * @parame fFence - If true, put up copy fence (memory barrier) after
231 * copying to guest phys. mem.
232 *
233 * @returns VINF_SUCCESS - Success
234 * VERR_INVALID_STATE - VirtIO not in ready state
235 * VERR_NOT_AVAILABLE - Queue is empty
236 */
237
238 int virtioQueuePut(VIRTIOHANDLE hVirtio, uint16_t qIdx, PRTSGBUF pSgVirtReturn,
239 PVIRTIO_DESC_CHAIN_T pDescChain, bool fFence);
240
241
242/**
243 * Updates the indicated virtq's "used ring" descriptor index to match the
244 * current write-head index, thus exposing the data added to the used ring by all
245 * virtioQueuePut() calls since the last sync. This should be called after one or
246 * more virtQueuePut() calls to inform the guest driver there is data in the queue.
247 * Explicit notifications (e.g. interrupt or MSI-X) will be sent to the guest,
248 * depending on VirtIO features negotiated and conditions, otherwise the guest
249 * will detect the update by polling. (see VirtIO 1.0
250 * specification, Section 2.4 "Virtqueues").
251 *
252 * @param hVirtio - Handle for VirtIO framework
253 * @param qIdx - Queue number
254 *
255 * @returns VINF_SUCCESS - Success
256 * VERR_INVALID_STATE - VirtIO not in ready state
257 */
258int virtioQueueSync(VIRTIOHANDLE hVirtio, uint16_t qIdx);
259
260/**
261 * Check if the associated queue is empty
262 *
263 * @param hVirtio - Handle for VirtIO framework
264 * @param qIdx - Queue number
265 *
266 * @returns true - Queue is empty or unavailable.
267 * false - Queue is available and has entries
268 */
269bool virtioQueueIsEmpty (VIRTIOHANDLE hVirtio, uint16_t qIdx);
270
271/**
272 * Return queue enable state
273 *
274 * @param hVirtio - Handle for VirtIO framework
275 * @param qIdx - Queue number
276 * @param fEnabled - Flag indicating whether to enable queue or not
277 */
278bool virtioIsQueueEnabled(VIRTIOHANDLE hVirtio, uint16_t qIdx);
279
280/**
281 * Enable or disable queue
282 *
283 * @param hVirtio - Handle for VirtIO framework
284 * @param qIdx - Queue number
285 * @param fEnabled - Flag indicating whether to enable queue or not
286 */
287void virtioQueueEnable(VIRTIOHANDLE hVirtio, uint16_t qIdx, bool fEnabled);
288
289/**
290 * Request orderly teardown of VirtIO on host and guest
291 * @param hVirtio - Handle for VirtIO framework
292 *
293 */
294void virtioResetAll(VIRTIOHANDLE hVirtio);
295
296/**
297 * This sends notification ('kicks') guest driver to check queues for any new
298 * elements in the used queue to process. It should be called after resuming
299 * in case anything was added to the queues during suspend/quiescing and a
300 * notification was missed, to prevent the guest from stalling after suspend.
301 */
302void virtioPropagateResumeNotification(VIRTIOHANDLE hVirtio);
303
304/**
305 * Get name of queue, by qIdx, assigned at virtioQueueAttach()
306 *
307 * @param hVirtio - Handle for VirtIO framework
308 * @param qIdx - Queue number
309 *
310 * @returns Success: Returns pointer to queue name
311 * Failure: Returns "<null>" (never returns NULL pointer).
312 */
313const char *virtioQueueGetName(VIRTIOHANDLE hVirtio, uint16_t qIdx);
314
315/**
316 * Get the features VirtIO is running withnow.
317 *
318 * @returns Features the guest driver has accepted, finalizing the operational features
319 *
320 */
321uint64_t virtioGetNegotiatedFeatures(VIRTIOHANDLE hVirtio);
322
323
324/** CLIENT MUST CALL ON RELOCATE CALLBACK! */
325void virtioRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta);
326
327/**
328 * Constructor sets up the PCI device controller and VirtIO state
329 *
330 * @param pDevIns Device instance data
331 * @param pClientContext Opaque client context (such as state struct)
332 * @param pVirtio Device State
333 * @param pPciParams Values to populate industry standard PCI Configuration Space data structure
334 * @param pcszInstance Device instance name
335 * @param uDevSpecificFeatures VirtIO device-specific features offered by client
336 * @param devCapReadCallback Client handler to call upon guest read to device specific capabilities.
337 * @param devCapWriteCallback Client handler to call upon guest write to device specific capabilities.
338 * @param devStatusChangedCallback Client handler to call for major device status changes
339 * @param queueNotifiedCallback Client handler for guest-to-host notifications that avail queue has ring data
340 * @param ssmLiveExecCallback Client handler for SSM live exec
341 * @param ssmSaveExecCallback Client handler for SSM save exec
342 * @param ssmLoadExecCallback Client handler for SSM load exec
343 * @param ssmLoadDoneCallback Client handler for SSM load done
344 * @param cbDevSpecificCfg Size of virtio_pci_device_cap device-specific configuration struct
345 * @param pDevSpecificCfg Address of client's VirtIO dev-specific configuration struct
346 */
347int virtioConstruct(PPDMDEVINS pDevIns,
348 void *pClientContext,
349 VIRTIOHANDLE *phVirtio,
350 PVIRTIOPCIPARAMS pPciParams,
351 const char *pcszInstance,
352 uint64_t uDevSpecificFeatures,
353 PFNVIRTIODEVCAPREAD devCapReadCallback,
354 PFNVIRTIODEVCAPWRITE devCapWriteCallback,
355 PFNVIRTIOSTATUSCHANGED devStatusChangedCallback,
356 PFNVIRTIOQUEUENOTIFIED queueNotifiedCallback,
357 PFNSSMDEVLIVEEXEC ssmLiveExecCallback,
358 PFNSSMDEVSAVEEXEC ssmSaveExecCallback,
359 PFNSSMDEVLOADEXEC ssmLoadExecCallback,
360 PFNSSMDEVLOADDONE ssmLoadDoneCallback,
361 uint16_t cbDevSpecificCfg,
362 void *pDevSpecificCfg);
363
364/**
365 * Log memory-mapped I/O input or output value.
366 *
367 * This is designed to be invoked by macros that can make contextual assumptions
368 * (e.g. implicitly derive MACRO parameters from the invoking function). It is exposed
369 * for the VirtIO client doing the device-specific implementation in order to log in a
370 * similar fashion accesses to the device-specific MMIO configuration structure. Macros
371 * that leverage this function are in Virtio_1_0_impl.h and can be used as an example
372 * of how to use this effectively for the device-specific code.
373 *
374 * @param pszFunc - To avoid displaying this function's name via __FUNCTION__ or LogFunc()
375 * @param pszMember - Name of struct member
376 * @param pv - pointer to value
377 * @param cb - size of value
378 * @param uOffset - offset into member where value starts
379 * @param fWrite - True if write I/O
380 * @param fHasIndex - True if the member is indexed
381 * @param idx - The index if fHasIndex
382 */
383void virtioLogMappedIoValue(const char *pszFunc, const char *pszMember, uint32_t uMemberSize,
384 const void *pv, uint32_t cb, uint32_t uOffset,
385 bool fWrite, bool fHasIndex, uint32_t idx);
386
387/**
388 * Does a formatted hex dump using Log(()), recommend using VIRTIO_HEX_DUMP() macro to
389 * control enabling of logging efficiently.
390 *
391 * @param pv - pointer to buffer to dump contents of
392 * @param cb - count of characters to dump from buffer
393 * @param uBase - base address of per-row address prefixing of hex output
394 * @param pszTitle - Optional title. If present displays title that lists
395 * provided text with value of cb to indicate size next to it.
396 */
397void virtioHexDump(uint8_t *pv, uint32_t cb, uint32_t uBase, const char *pszTitle);
398
399#endif /* !VBOX_INCLUDED_SRC_VirtIO_Virtio_1_0_h */
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette