VirtualBox

source: vbox/trunk/src/VBox/Devices/VirtIO/Virtio_1_0_impl.h@ 80169

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

Changes to enforce VirtIO 1.0 section 4.1.3.1 compliant device configuration access

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.8 KB
Line 
1/* $Id: Virtio_1_0_impl.h 80169 2019-08-07 03:58:55Z vboxsync $ $Revision: 80169 $ $Date: 2019-08-07 03:58:55 +0000 (Wed, 07 Aug 2019) $ $Author: vboxsync $ */
2/** @file
3 * Virtio_1_0_impl.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_impl_h
19#define VBOX_INCLUDED_SRC_VirtIO_Virtio_1_0_impl_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24/**
25* This macro returns true if physical address and access length are within the mapped capability struct.
26*
27* Actual Parameters:
28* @oaram pPhysCapStruct - [input] Pointer to MMIO mapped capability struct
29* @param pCfgCap - [input] Pointer to capability in PCI configuration area
30* @param fMatched - [output] True if GCPhysAddr is within the physically mapped capability.
31*
32* Implied parameters:
33* @param GCPhysAddr - [input, implied] Physical address accessed (via MMIO callback)
34* @param cb - [input, implied] Number of bytes to access
35*
36*/
37#define MATCH_VIRTIO_CAP_STRUCT(pGcPhysCapData, pCfgCap, fMatched) \
38 bool fMatched = false; \
39 if (pGcPhysCapData && pCfgCap && GCPhysAddr >= (RTGCPHYS)pGcPhysCapData \
40 && GCPhysAddr < ((RTGCPHYS)pGcPhysCapData + ((PVIRTIO_PCI_CAP_T)pCfgCap)->uLength) \
41 && cb <= ((PVIRTIO_PCI_CAP_T)pCfgCap)->uLength) \
42 fMatched = true;
43
44/**
45 * This macro resolves to boolean true if uOffset matches a field offset and size exactly,
46 * (or if it is a 64-bit field, if it accesses either 32-bit part as a 32-bit access)
47 * This is mandated by section 4.1.3.1 of the VirtIO 1.0 specification)
48 *
49 * @param member - Member of VIRTIO_PCI_COMMON_CFG_T
50 * @param uOffset - Implied parameter: Offset into VIRTIO_PCI_COMMON_CFG_T
51 * @param cb - Implied parameter: Number of bytes to access
52 * @result - true or false
53 */
54#define COMMON_CFG(member) \
55 (RT_SIZEOFMEMB(VIRTIO_PCI_COMMON_CFG_T, member) == 64 \
56 && ( uOffset == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member) \
57 || uOffset == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member) + sizeof(uint32_t)) \
58 && cb == sizeof(uint32_t)) \
59 || (uOffset == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member) \
60 && cb == RT_SIZEOFMEMB(VIRTIO_PCI_COMMON_CFG_T, member))
61
62#define LOG_ACCESSOR(member) \
63 virtioLogMappedIoValue(__FUNCTION__, #member, pv, cb, uIntraOff, fWrite, false, 0);
64
65#define LOG_INDEXED_ACCESSOR(member, idx) \
66 virtioLogMappedIoValue(__FUNCTION__, #member, pv, cb, uIntraOff, fWrite, true, idx);
67
68#define ACCESSOR(member) \
69 { \
70 uint32_t uIntraOff = uOffset - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
71 if (fWrite) \
72 memcpy(((char *)&pVirtio->member) + uOffset, (const char *)pv, cb); \
73 else \
74 memcpy((char *)pv, (const char *)(((char *)&pVirtio->member) + uOffset), cb); \
75 LOG_ACCESSOR(member); \
76 }
77
78#define ACCESSOR_WITH_IDX(member, idx) \
79 { \
80 uint32_t uIntraOff = uOffset - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
81 if (fWrite) \
82 memcpy(((char *)(pVirtio->member + idx)) + uOffset, (const char *)pv, cb); \
83 else \
84 memcpy((char *)pv, (const char *)(((char *)(pVirtio->member + idx)) + uOffset), cb); \
85 LOG_INDEXED_ACCESSOR(member, idx); \
86 }
87
88#define ACCESSOR_READONLY(member) \
89 { \
90 uint32_t uIntraOff = uOffset - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
91 if (fWrite) \
92 LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s\n", #member)); \
93 else \
94 { \
95 memcpy((char *)pv, (const char *)(((char *)&pVirtio->member) + uOffset), cb); \
96 LOG_ACCESSOR(member); \
97 } \
98 }
99
100#define ACCESSOR_READONLY_WITH_IDX(member, idx) \
101 { \
102 uint32_t uIntraOff = uOffset - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
103 if (fWrite) \
104 LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s[%d]\n", #member, idx)); \
105 else \
106 { \
107 memcpy((char *)pv, ((char *)(pVirtio->member + idx)) + uOffset, cb); \
108 LOG_INDEXED_ACCESSOR(member, idx); \
109 } \
110 }
111
112#ifdef VBOX_DEVICE_STRUCT_TESTCASE
113# define virtioDumpState(x, s) do {} while (0)
114#else
115# ifdef DEBUG
116 static void virtioDumpState(PVIRTIOSTATE pVirtio, const char *pcszCaller)
117 {
118 RT_NOREF2(pVirtio, pcszCaller);
119 /* PK TODO, dump state features, selector, status, ISR, queue info (iterate),
120 descriptors, avail, used, size, indices, address
121 each by variable name on new line, indented slightly */
122 }
123# endif
124#endif
125
126DECLINLINE(void) virtioLogDeviceStatus( uint8_t status)
127{
128 if (status == 0)
129 Log(("RESET"));
130 else
131 {
132 int primed = 0;
133 if (status & VIRTIO_STATUS_ACKNOWLEDGE)
134 Log(("ACKNOWLEDGE", primed++));
135 if (status & VIRTIO_STATUS_DRIVER)
136 Log(("%sDRIVER", primed++ ? " | " : ""));
137 if (status & VIRTIO_STATUS_DRIVER_OK)
138 Log(("%sDRIVER_OK", primed++ ? " | " : ""));
139 if (status & VIRTIO_STATUS_FEATURES_OK)
140 Log(("%sFEATURES_OK", primed++ ? " | " : ""));
141 if (status & VIRTIO_STATUS_FAILED)
142 Log(("%sFAILED", primed++ ? " | " : ""));
143 if (status & VIRTIO_STATUS_DEVICE_NEEDS_RESET)
144 Log(("%sACKNOWLEDGE", primed++ ? " | " : ""));
145 }
146}
147
148#endif /* !VBOX_INCLUDED_SRC_VirtIO_Virtio_1_0_impl_h */
Note: See TracBrowser for help on using the repository browser.

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