Changeset 92716 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Dec 2, 2021 9:17:42 PM (3 years ago)
- Location:
- trunk/src/VBox/VMM/VMMR3
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/IOMR3IoPort.cpp
r82968 r92716 33 33 #include <VBox/param.h> 34 34 #include <iprt/assert.h> 35 #include <iprt/mem.h> 35 36 #include <iprt/string.h> 36 37 #include <VBox/log.h> … … 198 199 199 200 201 #ifdef VBOX_WITH_STATISTICS 202 /** 203 * Grows the statistics table. 204 * 205 * @returns VBox status code. 206 * @param pVM The cross context VM structure. 207 * @param cNewEntries The minimum number of new entrie. 208 * @see IOMR0IoPortGrowStatisticsTable 209 */ 210 static int iomR3IoPortGrowStatisticsTable(PVM pVM, uint32_t cNewEntries) 211 { 212 AssertReturn(cNewEntries <= _64K, VERR_IOM_TOO_MANY_IOPORT_REGISTRATIONS); 213 214 int rc; 215 if (!SUPR3IsDriverless()) 216 { 217 rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_IOM_GROW_IO_PORT_STATS, cNewEntries, NULL); 218 AssertLogRelRCReturn(rc, rc); 219 AssertReturn(cNewEntries <= pVM->iom.s.cIoPortStatsAllocation, VERR_IOM_IOPORT_IPE_2); 220 } 221 else 222 { 223 /* 224 * Validate input and state. 225 */ 226 uint32_t const cOldEntries = pVM->iom.s.cIoPortStatsAllocation; 227 AssertReturn(cNewEntries > cOldEntries, VERR_IOM_IOPORT_IPE_1); 228 AssertReturn(pVM->iom.s.cIoPortStats <= cOldEntries, VERR_IOM_IOPORT_IPE_2); 229 230 /* 231 * Calc size and allocate a new table. 232 */ 233 uint32_t const cbNew = RT_ALIGN_32(cNewEntries * sizeof(IOMIOPORTSTATSENTRY), PAGE_SIZE); 234 cNewEntries = cbNew / sizeof(IOMIOPORTSTATSENTRY); 235 236 PIOMIOPORTSTATSENTRY const paIoPortStats = (PIOMIOPORTSTATSENTRY)RTMemPageAllocZ(cbNew); 237 if (paIoPortStats) 238 { 239 /* 240 * Anything to copy over, update and free the old one. 241 */ 242 PIOMIOPORTSTATSENTRY const pOldIoPortStats = pVM->iom.s.paIoPortStats; 243 if (pOldIoPortStats) 244 memcpy(paIoPortStats, pOldIoPortStats, cOldEntries * sizeof(IOMIOPORTSTATSENTRY)); 245 246 pVM->iom.s.paIoPortStats = paIoPortStats; 247 pVM->iom.s.cIoPortStatsAllocation = cNewEntries; 248 249 RTMemPageFree(pOldIoPortStats, RT_ALIGN_32(cOldEntries * sizeof(IOMIOPORTSTATSENTRY), PAGE_SIZE)); 250 251 rc = VINF_SUCCESS; 252 } 253 else 254 rc = VERR_NO_PAGE_MEMORY; 255 } 256 257 return rc; 258 } 259 #endif 260 261 262 /** 263 * Grows the I/O port registration statistics table. 264 * 265 * @returns VBox status code. 266 * @param pVM The cross context VM structure. 267 * @param cNewEntries The minimum number of new entrie. 268 * @see IOMR0IoPortGrowRegistrationTables 269 */ 270 static int iomR3IoPortGrowTable(PVM pVM, uint32_t cNewEntries) 271 { 272 AssertReturn(cNewEntries <= _4K, VERR_IOM_TOO_MANY_IOPORT_REGISTRATIONS); 273 274 int rc; 275 if (!SUPR3IsDriverless()) 276 { 277 rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_IOM_GROW_IO_PORTS, cNewEntries, NULL); 278 AssertLogRelRCReturn(rc, rc); 279 AssertReturn(cNewEntries <= pVM->iom.s.cIoPortAlloc, VERR_IOM_IOPORT_IPE_2); 280 } 281 else 282 { 283 /* 284 * Validate input and state. 285 */ 286 uint32_t const cOldEntries = pVM->iom.s.cIoPortAlloc; 287 AssertReturn(cNewEntries >= cOldEntries, VERR_IOM_IOPORT_IPE_1); 288 289 /* 290 * Allocate the new tables. We use a single allocation for the three tables (ring-0, 291 * ring-3, lookup) and does a partial mapping of the result to ring-3. 292 */ 293 uint32_t const cbRing3 = RT_ALIGN_32(cNewEntries * sizeof(IOMIOPORTENTRYR3), PAGE_SIZE); 294 uint32_t const cbShared = RT_ALIGN_32(cNewEntries * sizeof(IOMIOPORTLOOKUPENTRY), PAGE_SIZE); 295 uint32_t const cbNew = cbRing3 + cbShared; 296 297 /* Use the rounded up space as best we can. */ 298 cNewEntries = RT_MIN(cbRing3 / sizeof(IOMIOPORTENTRYR3), cbShared / sizeof(IOMIOPORTLOOKUPENTRY)); 299 300 PIOMIOPORTENTRYR3 const paRing3 = (PIOMIOPORTENTRYR3)RTMemPageAllocZ(cbNew); 301 if (paRing3) 302 { 303 PIOMIOPORTLOOKUPENTRY const paLookup = (PIOMIOPORTLOOKUPENTRY)((uintptr_t)paRing3 + cbRing3); 304 305 /* 306 * Copy over the old info and initialize the idxSelf and idxStats members. 307 */ 308 if (pVM->iom.s.paIoPortRegs != NULL) 309 { 310 memcpy(paRing3, pVM->iom.s.paIoPortRegs, sizeof(paRing3[0]) * cOldEntries); 311 memcpy(paLookup, pVM->iom.s.paIoPortLookup, sizeof(paLookup[0]) * cOldEntries); 312 } 313 314 size_t i = cbRing3 / sizeof(*paRing3); 315 while (i-- > cOldEntries) 316 { 317 paRing3[i].idxSelf = (uint16_t)i; 318 paRing3[i].idxStats = UINT16_MAX; 319 } 320 321 /* 322 * Update the variables and free the old memory. 323 */ 324 void * const pvFree = pVM->iom.s.paIoPortRegs; 325 326 pVM->iom.s.paIoPortRegs = paRing3; 327 pVM->iom.s.paIoPortLookup = paLookup; 328 pVM->iom.s.cIoPortAlloc = cNewEntries; 329 330 RTMemPageFree(pvFree, 331 RT_ALIGN_32(cOldEntries * sizeof(IOMIOPORTENTRYR3), PAGE_SIZE) 332 + RT_ALIGN_32(cOldEntries * sizeof(IOMIOPORTLOOKUPENTRY), PAGE_SIZE)); 333 334 rc = VINF_SUCCESS; 335 } 336 else 337 rc = VERR_NO_PAGE_MEMORY; 338 } 339 return rc; 340 } 341 200 342 201 343 /** … … 254 396 if (cNewIoPortStats > pVM->iom.s.cIoPortStatsAllocation) 255 397 { 256 int rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_IOM_GROW_IO_PORT_STATS, cNewIoPortStats, NULL);257 Assert LogRelRCReturn(rc, rc);398 int rc = iomR3IoPortGrowStatisticsTable(pVM, cNewIoPortStats); 399 AssertRCReturn(rc, rc); 258 400 AssertReturn(idxStats == pVM->iom.s.cIoPortStats, VERR_IOM_IOPORT_IPE_1); 259 AssertReturn(cNewIoPortStats <= pVM->iom.s.cIoPortStatsAllocation, VERR_IOM_IOPORT_IPE_2);260 401 } 261 402 #endif … … 264 405 if (idx >= pVM->iom.s.cIoPortAlloc) 265 406 { 266 int rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_IOM_GROW_IO_PORTS, pVM->iom.s.cIoPortAlloc + 1, NULL);267 Assert LogRelRCReturn(rc, rc);407 int rc = iomR3IoPortGrowTable(pVM, pVM->iom.s.cIoPortAlloc + 1); 408 AssertRCReturn(rc, rc); 268 409 AssertReturn(idx == pVM->iom.s.cIoPortRegs, VERR_IOM_IOPORT_IPE_1); 269 410 AssertReturn(idx < pVM->iom.s.cIoPortAlloc, VERR_IOM_IOPORT_IPE_2); -
trunk/src/VBox/VMM/VMMR3/IOMR3Mmio.cpp
r82968 r92716 33 33 #include <VBox/param.h> 34 34 #include <iprt/assert.h> 35 #include <iprt/mem.h> 35 36 #include <iprt/string.h> 36 37 #include <VBox/log.h> … … 110 111 } 111 112 113 114 /** 115 * Grows the statistics table. 116 * 117 * @returns VBox status code. 118 * @param pVM The cross context VM structure. 119 * @param cNewEntries The minimum number of new entrie. 120 * @see IOMR0IoPortGrowStatisticsTable 121 */ 122 static int iomR3MmioGrowStatisticsTable(PVM pVM, uint32_t cNewEntries) 123 { 124 AssertReturn(cNewEntries <= _64K, VERR_IOM_TOO_MANY_MMIO_REGISTRATIONS); 125 126 int rc; 127 if (!SUPR3IsDriverless()) 128 { 129 rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_IOM_GROW_MMIO_STATS, cNewEntries, NULL); 130 AssertLogRelRCReturn(rc, rc); 131 AssertReturn(cNewEntries <= pVM->iom.s.cMmioStatsAllocation, VERR_IOM_MMIO_IPE_2); 132 } 133 else 134 { 135 /* 136 * Validate input and state. 137 */ 138 uint32_t const cOldEntries = pVM->iom.s.cMmioStatsAllocation; 139 AssertReturn(cNewEntries > cOldEntries, VERR_IOM_MMIO_IPE_1); 140 AssertReturn(pVM->iom.s.cMmioStats <= cOldEntries, VERR_IOM_MMIO_IPE_2); 141 142 /* 143 * Calc size and allocate a new table. 144 */ 145 uint32_t const cbNew = RT_ALIGN_32(cNewEntries * sizeof(IOMMMIOSTATSENTRY), PAGE_SIZE); 146 cNewEntries = cbNew / sizeof(IOMMMIOSTATSENTRY); 147 148 PIOMMMIOSTATSENTRY const paMmioStats = (PIOMMMIOSTATSENTRY)RTMemPageAllocZ(cbNew); 149 if (paMmioStats) 150 { 151 /* 152 * Anything to copy over, update and free the old one. 153 */ 154 PIOMMMIOSTATSENTRY const pOldMmioStats = pVM->iom.s.paMmioStats; 155 if (pOldMmioStats) 156 memcpy(paMmioStats, pOldMmioStats, cOldEntries * sizeof(IOMMMIOSTATSENTRY)); 157 158 pVM->iom.s.paMmioStats = paMmioStats; 159 pVM->iom.s.cMmioStatsAllocation = cNewEntries; 160 161 RTMemPageFree(pOldMmioStats, RT_ALIGN_32(cOldEntries * sizeof(IOMMMIOSTATSENTRY), PAGE_SIZE)); 162 163 rc = VINF_SUCCESS; 164 } 165 else 166 rc = VERR_NO_PAGE_MEMORY; 167 } 168 169 return rc; 170 } 171 112 172 #endif /* VBOX_WITH_STATISTICS */ 173 174 /** 175 * Grows the I/O port registration statistics table. 176 * 177 * @returns VBox status code. 178 * @param pVM The cross context VM structure. 179 * @param cNewEntries The minimum number of new entrie. 180 * @see IOMR0MmioGrowRegistrationTables 181 */ 182 static int iomR3MmioGrowTable(PVM pVM, uint32_t cNewEntries) 183 { 184 AssertReturn(cNewEntries <= _4K, VERR_IOM_TOO_MANY_MMIO_REGISTRATIONS); 185 186 int rc; 187 if (!SUPR3IsDriverless()) 188 { 189 rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_IOM_GROW_MMIO_REGS, cNewEntries, NULL); 190 AssertLogRelRCReturn(rc, rc); 191 AssertReturn(cNewEntries <= pVM->iom.s.cMmioAlloc, VERR_IOM_MMIO_IPE_2); 192 } 193 else 194 { 195 /* 196 * Validate input and state. 197 */ 198 uint32_t const cOldEntries = pVM->iom.s.cMmioAlloc; 199 AssertReturn(cNewEntries >= cOldEntries, VERR_IOM_MMIO_IPE_1); 200 201 /* 202 * Allocate the new tables. We use a single allocation for the three tables (ring-0, 203 * ring-3, lookup) and does a partial mapping of the result to ring-3. 204 */ 205 uint32_t const cbRing3 = RT_ALIGN_32(cNewEntries * sizeof(IOMMMIOENTRYR3), PAGE_SIZE); 206 uint32_t const cbShared = RT_ALIGN_32(cNewEntries * sizeof(IOMMMIOLOOKUPENTRY), PAGE_SIZE); 207 uint32_t const cbNew = cbRing3 + cbShared; 208 209 /* Use the rounded up space as best we can. */ 210 cNewEntries = RT_MIN(cbRing3 / sizeof(IOMMMIOENTRYR3), cbShared / sizeof(IOMMMIOLOOKUPENTRY)); 211 212 PIOMMMIOENTRYR3 const paRing3 = (PIOMMMIOENTRYR3)RTMemPageAllocZ(cbNew); 213 if (paRing3) 214 { 215 PIOMMMIOLOOKUPENTRY const paLookup = (PIOMMMIOLOOKUPENTRY)((uintptr_t)paRing3 + cbRing3); 216 217 /* 218 * Copy over the old info and initialize the idxSelf and idxStats members. 219 */ 220 if (pVM->iom.s.paMmioRegs != NULL) 221 { 222 memcpy(paRing3, pVM->iom.s.paMmioRegs, sizeof(paRing3[0]) * cOldEntries); 223 memcpy(paLookup, pVM->iom.s.paMmioLookup, sizeof(paLookup[0]) * cOldEntries); 224 } 225 226 size_t i = cbRing3 / sizeof(*paRing3); 227 while (i-- > cOldEntries) 228 { 229 paRing3[i].idxSelf = (uint16_t)i; 230 paRing3[i].idxStats = UINT16_MAX; 231 } 232 233 /* 234 * Update the variables and free the old memory. 235 */ 236 void * const pvFree = pVM->iom.s.paMmioRegs; 237 238 pVM->iom.s.paMmioRegs = paRing3; 239 pVM->iom.s.paMmioLookup = paLookup; 240 pVM->iom.s.cMmioAlloc = cNewEntries; 241 242 RTMemPageFree(pvFree, 243 RT_ALIGN_32(cOldEntries * sizeof(IOMMMIOENTRYR3), PAGE_SIZE) 244 + RT_ALIGN_32(cOldEntries * sizeof(IOMMMIOLOOKUPENTRY), PAGE_SIZE)); 245 246 rc = VINF_SUCCESS; 247 } 248 else 249 rc = VERR_NO_PAGE_MEMORY; 250 } 251 return rc; 252 } 113 253 114 254 … … 160 300 if (cNewMmioStats > pVM->iom.s.cMmioStatsAllocation) 161 301 { 162 int rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_IOM_GROW_MMIO_STATS, cNewMmioStats, NULL);163 Assert LogRelRCReturn(rc, rc);302 int rc = iomR3MmioGrowStatisticsTable(pVM, cNewMmioStats); 303 AssertRCReturn(rc, rc); 164 304 AssertReturn(idxStats == pVM->iom.s.cMmioStats, VERR_IOM_MMIO_IPE_1); 165 AssertReturn(cNewMmioStats <= pVM->iom.s.cMmioStatsAllocation, VERR_IOM_MMIO_IPE_2);166 305 } 167 306 #endif … … 170 309 if (idx >= pVM->iom.s.cMmioAlloc) 171 310 { 172 int rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_IOM_GROW_MMIO_REGS, pVM->iom.s.cMmioAlloc + 1, NULL);173 Assert LogRelRCReturn(rc, rc);311 int rc = iomR3MmioGrowTable(pVM, pVM->iom.s.cMmioAlloc + 1); 312 AssertRCReturn(rc, rc); 174 313 AssertReturn(idx == pVM->iom.s.cMmioRegs, VERR_IOM_MMIO_IPE_1); 175 AssertReturn(idx < pVM->iom.s.cMmioAlloc, VERR_IOM_MMIO_IPE_2);176 314 } 177 315
Note:
See TracChangeset
for help on using the changeset viewer.