VirtualBox

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

Last change on this file since 80351 was 80340, checked in by vboxsync, 6 years ago

Fixed error in MMIO handling of cfg gen check/increment. Seem to have resolved stack corruption issue caused by putting structs that allocated 1.5MB on the stack in temporary functions to test notification callback and test de-queing data. See bugref:9440 Comment #53 for more info

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.5 KB
Line 
1/* $Id: Virtio_1_0.h 80340 2019-08-19 07:43:37Z 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
26typedef void * VIRTIOHANDLE; /**< Opaque handle to the VirtIO framework */
27
28#define DISABLE_GUEST_DRIVER 0
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 VIRTQ_DESC_MAX_SIZE (2 * 1024 * 1024)
40#define VIRTIO_NOTIFY_OFFSET_MULTIPLIER 2 /**< VirtIO Notify Cap. MMIO config param */
41#define VIRTIOSCSI_REGION_MEM_IO 0 /**< BAR for MMIO (implementation specific) */
42#define VIRTIOSCSI_REGION_PORT_IO 1 /**< BAR for PORT I/O (impl specific) */
43#define VIRTIOSCSI_REGION_PCI_CAP 2 /**< BAR for VirtIO Cap. MMIO (impl specific) */
44typedef struct VIRTQ_SEG /**< Describes one segment of a buffer vector */
45{
46 RTGCPHYS addr; /**< Physical addr. of this segment's buffer */
47 void *pv; /**< Buf to hold value to write or read */
48 uint32_t cb; /**< Number of bytes to write or read */
49} VIRTQ_SEG_T;
50
51 typedef struct VIRTQ_BUF_VECTOR /**< Scatter/gather buffer vector */
52{
53 uint32_t uDescIdx; /**< Desc at head of this vector list */
54 uint32_t cSegsIn; /**< Count of segments in aSegsIn[] */
55 uint32_t cSegsOut; /**< Count of segments in aSegsOut[] */
56 VIRTQ_SEG_T aSegsIn[VIRTQ_MAX_SIZE]; /**< List of segments to write to guest */
57 VIRTQ_SEG_T aSegsOut[VIRTQ_MAX_SIZE]; /**< List of segments read from guest */
58} VIRTQ_BUF_VECTOR_T, *PVIRTQ_BUF_VECTOR_T;
59
60/**
61 * The following structure is used to pass the PCI parameters from the consumer
62 * to this generic VirtIO framework. This framework provides the Vendor ID as Virtio.
63 */
64typedef struct VIRTIOPCIPARAMS
65{
66 uint16_t uDeviceId; /**< PCI Cfg Device ID */
67 uint16_t uClassBase; /**< PCI Cfg Base Class */
68 uint16_t uClassSub; /**< PCI Cfg Subclass */
69 uint16_t uClassProg; /**< PCI Cfg Programming Interface Class */
70 uint16_t uSubsystemId; /**< PCI Cfg Card Manufacturer Vendor ID */
71 uint16_t uSubsystemVendorId; /**< PCI Cfg Chipset Manufacturer Vendor ID */
72 uint16_t uRevisionId; /**< PCI Cfg Revision ID */
73 uint16_t uInterruptLine; /**< PCI Cfg Interrupt line */
74 uint16_t uInterruptPin; /**< PCI Cfg InterruptPin */
75} VIRTIOPCIPARAMS, *PVIRTIOPCIPARAMS;
76
77/**
78 * Implementation-specific client callback to notify client of significant device status
79 * changes.
80 *
81 * @param hVirtio Handle to VirtIO framework
82 * @param fDriverOk True if guest driver is okay (thus queues, etc... are valid)
83 * @param pClient Pointer to opaque client data (state)
84 */
85typedef DECLCALLBACK(void) FNVIRTIOSTATUSCHANGED(VIRTIOHANDLE hVirtio, void *pClient, bool fDriverOk);
86typedef FNVIRTIOSTATUSCHANGED *PFNVIRTIOSTATUSCHANGED;
87
88/**
89 * When guest-to-host queue notifications are enabled, the guest driver notifies the host
90 * that the avail queue has buffers, and this callback informs the client.
91 *
92 * @param hVirtio Handle to the VirtIO framework
93 * @param qIdx Index of the notified queue
94 * @param pClient Pointer to opaque client data (state)
95 */
96typedef DECLCALLBACK(void) FNVIRTIOQUEUENOTIFIED(VIRTIOHANDLE hVirtio, void *pClient, uint16_t qIdx);
97typedef FNVIRTIOQUEUENOTIFIED *PFNVIRTIOQUEUENOTIFIED;
98
99 /**
100 * Implementation-specific client callback to access VirtIO Device-specific capabilities
101 * (other VirtIO capabilities and features are handled in VirtIO implementation)
102 *
103 * @param pDevIns The device instance.
104 * @param offset Offset within device specific capabilities struct
105 * @param pvBuf Buffer in which to save read data
106 * @param cbWrite Number of bytes to write
107 */
108typedef DECLCALLBACK(int) FNVIRTIODEVCAPWRITE(PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, size_t cbWrite);
109typedef FNVIRTIODEVCAPWRITE *PFNVIRTIODEVCAPWRITE;
110
111/**
112 * Implementation-specific client ballback to access VirtIO Device-specific capabilities
113 * (other VirtIO capabilities and features are handled in VirtIO implementation)
114 *
115 * @param pDevIns The device instance.
116 * @param offset Offset within device specific capabilities struct
117 * @param pvBuf Buffer in which to save read data
118 * @param cbRead Number of bytes to read
119 */
120typedef DECLCALLBACK(int) FNVIRTIODEVCAPREAD(PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, size_t cbRead);
121typedef FNVIRTIODEVCAPREAD *PFNVIRTIODEVCAPREAD;
122
123
124/** @name VirtIO port I/O callbacks.
125 * @{ */
126typedef struct VIRTIOCALLBACKS
127{
128 DECLCALLBACKMEMBER(void, pfnVirtioStatusChanged)
129 (VIRTIOHANDLE hVirtio, void *pClient, bool fDriverOk);
130 DECLCALLBACKMEMBER(void, pfnVirtioQueueNotified)
131 (VIRTIOHANDLE hVirtio, void *pClient, uint16_t qIdx);
132 DECLCALLBACKMEMBER(int, pfnVirtioDevCapRead)
133 (PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, size_t cbRead);
134 DECLCALLBACKMEMBER(int, pfnVirtioDevCapWrite)
135 (PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, size_t cbWrite);
136 DECLCALLBACKMEMBER(int, pfnSSMDevLiveExec)
137 (PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass);
138 DECLCALLBACKMEMBER(int, pfnSSMDevSaveExec)
139 (PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
140 DECLCALLBACKMEMBER(int, pfnSSMDevLoadExec)
141 (PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
142 DECLCALLBACKMEMBER(int, pfnSSMDevLoadDone)
143 (PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
144
145} VIRTIOCALLBACKS, *PVIRTIOCALLBACKS;
146/** @} */
147
148/** API for VirtIO client */
149
150/**
151 * Allocate client context for client to work with VirtIO-provided with queue
152 * As a side effect creates a buffer vector a client can get a pointer to
153 * with a call to virtioQueueBufVec()
154 *
155 * @param hVirtio - Handle to VirtIO framework
156 * @param qIdx - Queue number
157 * @param pcszName - Name to give queue
158 *
159 * @returns status VINF_SUCCESS - Success
160 * VERR_INVALID_STATE - VirtIO not in ready state
161 * VERR_NO_MEMORY - Out of memory
162 *
163 * @returns status. If false, the call failed and the client should call virtioResetAll()
164 */
165int virtioQueueAttach(VIRTIOHANDLE hVirtio, uint16_t qIdx, const char *pcszName);
166/**
167 * Detaches from queue and release resources
168 *
169 * @param hVirtio - Handle for VirtIO framework
170 * @param qIdx - Queue number
171 *
172 */
173int virtioQueueDetach(VIRTIOHANDLE hVirtio, uint16_t qIdx);
174
175/**
176 * Return pointer to buffer vector object associated with queue
177 *
178 * @param hVirtio - Handle for VirtIO framework
179 * @param qIdx - Queue number
180 *
181 * @returns Pointer pBufVec if success, else NULL
182 */
183PVIRTQ_BUF_VECTOR_T virtioQueueGetBuffer(VIRTIOHANDLE hVirtio, uint16_t qIdx);
184
185/**
186 * Get name of queue, by qIdx, assigned at virtioQueueAttach()
187 *
188 * @param hVirtio - Handle for VirtIO framework
189 * @param qIdx - Queue number
190 *
191 * @returns Success: Returns pointer to queue name
192 * Failure: Returns "<null>" (never returns NULL pointer).
193 */
194const char *virtioQueueGetName(VIRTIOHANDLE hVirtio, uint16_t qIdx);
195
196/**
197 * Removes descriptor [chain] from queue and converts it to scatter/gather data
198 * in the vector whose pointer was returned from VirtioQueueAttach.
199 *
200 * @param hVirtio - Handle for VirtIO framework
201 * @param qIdx - Queue number
202 *
203 * @returns status VINF_SUCCESS - Success
204 * VERR_INVALID_STATE - VirtIO not in ready state
205 */
206int virtioQueueGet(VIRTIOHANDLE hVirtio, uint16_t qIdx, bool fRemove);
207
208/**
209 * Same as virtioQueueGet() but leaves the item on the avail ring of the queue.
210 *
211 * @param hVirtio - Handle for VirtIO framework
212 * @param qIdx - Queue number
213 *
214 * @returns VINF_SUCCESS - Success
215 * VERR_INVALID_STATE - VirtIO not in ready state
216 * VERR_NOT_AVAILABLE - Queue is empty
217 */
218int virtioQueuePeek(VIRTIOHANDLE hVirtio, uint16_t qIdx);
219
220/**
221 * Writes scatter/gather segment contained in queue's bufVec.aSegsIn[] array to
222 * physical memory assigned by the guest driver. The data won't be seen by the
223 * driver until the next virtioQueueSync() call.
224 *
225 * @param hVirtio - Handle for VirtIO framework
226 * @param qIdx - Queue number
227 *
228 * @returns VINF_SUCCESS - Success
229 * VERR_INVALID_STATE - VirtIO not in ready state
230 * VERR_NOT_AVAILABLE - Queue is empty
231 */
232int virtioQueuePut(VIRTIOHANDLE hVirtio, uint16_t qIdx, uint32_t cb);
233
234/**
235 * Updates virtq's "used ring" descriptor index to match the current bufVec's
236 * index, thus exposing the data added to the used ring by all virtioQueuePut()
237 * calls since the last sync. This should be called after one or more virtQueuePut()
238 * calls to inform the guest driver there is data in the queue. Explicit
239 * notifications will be sent to the guest depending on VirtIO features negotiated
240 * and conditions.
241 *
242 * @param hVirtio - Handle for VirtIO framework
243 * @param qIdx - Queue number
244 *
245 * @returns VINF_SUCCESS - Success
246 * VERR_INVALID_STATE - VirtIO not in ready state
247 */
248int virtioQueueSync(VIRTIOHANDLE hVirtio, uint16_t qIdx);
249
250/**
251 * Check if the associated queue is empty
252 *
253 * @param hVirtio - Handle for VirtIO framework
254 * @param qIdx - Queue number
255 *
256 * @returns true - Queue is empty or unavailable.
257 * false - Queue is available and has entries
258 */
259bool virtioQueueIsEmpty (VIRTIOHANDLE hVirtio, uint16_t qIdx);
260
261/**
262 * Request orderly teardown of VirtIO on host and guest
263 */
264void virtioResetAll(VIRTIOHANDLE hVirtio);
265
266/** CLIENT MUST CALL ON RELOCATE CALLBACK! */
267void virtioRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta);
268
269/**
270 * Constructor sets up the PCI device controller and VirtIO state
271 *
272 * @param pDevIns Device instance data
273 * @param pClientContext Opaque client context (such as state struct)
274 * @param pVirtio Device State
275 * @param pPciParams Values to populate industry standard PCI Configuration Space data structure
276 * @param pcszInstance Device instance name
277 * @param uDevSpecificFeatures VirtIO device-specific features offered by client
278 * @param devCapReadCallback Client handler to call upon guest read to device specific capabilities.
279 * @param devCapWriteCallback Client handler to call upon guest write to device specific capabilities.
280 * @param devStatusChangedCallback Client handler to call for major device status changes
281 * @param queueNotifiedCallback Client handler for guest-to-host notifications that avail queue has ring data
282 * @param ssmLiveExecCallback Client handler for SSM live exec
283 * @param ssmSaveExecCallback Client handler for SSM save exec
284 * @param ssmLoadExecCallback Client handler for SSM load exec
285 * @param ssmLoadDoneCallback Client handler for SSM load done
286 * @param cbDevSpecificCfg Size of virtio_pci_device_cap device-specific configuration struct
287 * @param pDevSpecificCfg Address of client's VirtIO dev-specific configuration struct
288 */
289int virtioConstruct(PPDMDEVINS pDevIns,
290 void *pClientContext,
291 VIRTIOHANDLE *phVirtio,
292 PVIRTIOPCIPARAMS pPciParams,
293 const char *pcszInstance,
294 uint64_t uDevSpecificFeatures,
295 PFNVIRTIODEVCAPREAD devCapReadCallback,
296 PFNVIRTIODEVCAPWRITE devCapWriteCallback,
297 PFNVIRTIOSTATUSCHANGED devStatusChangedCallback,
298 PFNVIRTIOQUEUENOTIFIED queueNotifiedCallback,
299 PFNSSMDEVLIVEEXEC ssmLiveExecCallback,
300 PFNSSMDEVSAVEEXEC ssmSaveExecCallback,
301 PFNSSMDEVLOADEXEC ssmLoadExecCallback,
302 PFNSSMDEVLOADDONE ssmLoadDoneCallback,
303 uint16_t cbDevSpecificCfg,
304 void *pDevSpecificCfg);
305
306/**
307 * Log memory-mapped I/O input or output value.
308 * This is designed to be invoked by macros that can make contextual assumptions
309 * (e.g. implicitly derive some of the parameters). It is exposed for the VirtIO
310 * client doing the device-specific implementation in order to log in a similar fashion
311 * accesses to the device-specific MMIO configuration structure. Macros that leverage
312 * this function are in Virtio_1_0_impl.h and can be used as an example of how to use
313 * this effectively for the device-specific code.
314 *
315 * @param pszFunc - To avoid displaying this function's name via __FUNCTION__ or LogFunc()
316 * @param pszMember - Name of struct member
317 * @param pv - pointer to value
318 * @param cb - size of value
319 * @param uOffset - offset into member where value starts
320 * @param fWrite - True if write I/O
321 * @param fHasIndex - True if the member is indexed
322 * @param idx - The index if fHasIndex
323 */
324void virtioLogMappedIoValue(const char *pszFunc, const char *pszMember, size_t uMemberSize,
325 const void *pv, uint32_t cb, uint32_t uOffset,
326 bool fWrite, bool fHasIndex, uint32_t idx);
327
328#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