VirtualBox

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

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

Fixed offset usage that caused reaching into wrong values of newest driver-side config struct, and further refined logging (see #9440, Comment 42)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.7 KB
Line 
1/* $Id: Virtio_1_0_impl.h 80168 2019-08-07 00:48:58Z vboxsync $ $Revision: 80168 $ $Date: 2019-08-07 00:48:58 +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 is within the specified member offset and length.
46 *
47 * @param member - Member of VIRTIO_PCI_COMMON_CFG_T
48 * @param uOffset - Implied parameter: Offset into VIRTIO_PCI_COMMON_CFG_T
49 * @param cb - Implied parameter: Number of bytes to access
50 * @result - true or false
51 */
52#define COMMON_CFG(member) \
53 (uOffset >= RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member) \
54 && uOffset < (uint32_t)(RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member) \
55 + RT_SIZEOFMEMB(VIRTIO_PCI_COMMON_CFG_T, member)) \
56 && cb <= RT_SIZEOFMEMB(VIRTIO_PCI_COMMON_CFG_T, member) \
57 - (uOffset - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member)))
58
59#define LOG_ACCESSOR(member) \
60 virtioLogMappedIoValue(__FUNCTION__, #member, pv, cb, uIntraOff, fWrite, false, 0);
61
62#define LOG_INDEXED_ACCESSOR(member, idx) \
63 virtioLogMappedIoValue(__FUNCTION__, #member, pv, cb, uIntraOff, fWrite, true, idx);
64
65#define ACCESSOR(member) \
66 { \
67 uint32_t uIntraOff = uOffset - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
68 if (fWrite) \
69 memcpy(((char *)&pVirtio->member) + uOffset, (const char *)pv, cb); \
70 else \
71 memcpy((char *)pv, (const char *)(((char *)&pVirtio->member) + uOffset), cb); \
72 LOG_ACCESSOR(member); \
73 }
74
75#define ACCESSOR_WITH_IDX(member, idx) \
76 { \
77 uint32_t uIntraOff = uOffset - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
78 if (fWrite) \
79 memcpy(((char *)(pVirtio->member + idx)) + uOffset, (const char *)pv, cb); \
80 else \
81 memcpy((char *)pv, (const char *)(((char *)(pVirtio->member + idx)) + uOffset), cb); \
82 LOG_INDEXED_ACCESSOR(member, idx); \
83 }
84
85#define ACCESSOR_READONLY(member) \
86 { \
87 uint32_t uIntraOff = uOffset - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
88 if (fWrite) \
89 LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s\n", #member)); \
90 else \
91 { \
92 memcpy((char *)pv, (const char *)(((char *)&pVirtio->member) + uOffset), cb); \
93 LOG_ACCESSOR(member); \
94 } \
95 }
96
97#define ACCESSOR_READONLY_WITH_IDX(member, idx) \
98 { \
99 uint32_t uIntraOff = uOffset - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
100 if (fWrite) \
101 LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s[%d]\n", #member, idx)); \
102 else \
103 { \
104 memcpy((char *)pv, ((char *)(pVirtio->member + idx)) + uOffset, cb); \
105 LOG_INDEXED_ACCESSOR(member, idx); \
106 } \
107 }
108
109#ifdef VBOX_DEVICE_STRUCT_TESTCASE
110# define virtioDumpState(x, s) do {} while (0)
111#else
112# ifdef DEBUG
113 static void virtioDumpState(PVIRTIOSTATE pVirtio, const char *pcszCaller)
114 {
115 RT_NOREF2(pVirtio, pcszCaller);
116 /* PK TODO, dump state features, selector, status, ISR, queue info (iterate),
117 descriptors, avail, used, size, indices, address
118 each by variable name on new line, indented slightly */
119 }
120# endif
121#endif
122
123DECLINLINE(void) virtioLogDeviceStatus( uint8_t status)
124{
125 if (status == 0)
126 Log(("RESET"));
127 else
128 {
129 int primed = 0;
130 if (status & VIRTIO_STATUS_ACKNOWLEDGE)
131 Log(("ACKNOWLEDGE", primed++));
132 if (status & VIRTIO_STATUS_DRIVER)
133 Log(("%sDRIVER", primed++ ? " | " : ""));
134 if (status & VIRTIO_STATUS_DRIVER_OK)
135 Log(("%sDRIVER_OK", primed++ ? " | " : ""));
136 if (status & VIRTIO_STATUS_FEATURES_OK)
137 Log(("%sFEATURES_OK", primed++ ? " | " : ""));
138 if (status & VIRTIO_STATUS_FAILED)
139 Log(("%sFAILED", primed++ ? " | " : ""));
140 if (status & VIRTIO_STATUS_DEVICE_NEEDS_RESET)
141 Log(("%sACKNOWLEDGE", primed++ ? " | " : ""));
142 }
143}
144
145#endif /* !VBOX_INCLUDED_SRC_VirtIO_Virtio_1_0_impl_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