Changeset 106049 in vbox for trunk/src/VBox
- Timestamp:
- Sep 13, 2024 3:18:53 PM (3 months ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/GCM.cpp
r105701 r106049 1 /* $Id$ */ 1 2 /** @file 2 3 * GCM - Guest Compatibility Manager. … … 76 77 77 78 /********************************************************************************************************************************* 79 * Global Variables * 80 *********************************************************************************************************************************/ 81 /** Fixer flag configuration names. */ 82 static struct 83 { 84 const char *pszName; 85 uint8_t cchName; 86 bool fSafeToClearOnLoad; 87 uint32_t fFlag; 88 } const g_aGcmFixerIds[] = 89 { 90 { RT_STR_TUPLE("DivByZeroDOS"), false, GCMFIXER_DBZ_DOS }, /* These aren't safe to clear on load, */ 91 { RT_STR_TUPLE("DivByZeroOS2"), false, GCMFIXER_DBZ_OS2 }, /* because HM and NEM only queries them */ 92 { RT_STR_TUPLE("DivByZeroWin9x"), false, GCMFIXER_DBZ_WIN9X }, /* on VM init. */ 93 { RT_STR_TUPLE("MesaVmsvgaDrv"), true, GCMFIXER_MESA_VMSVGA_DRV }, /* This is checked for every access, so okay. */ 94 }; 95 96 97 /********************************************************************************************************************************* 78 98 * Internal Functions * 79 99 *********************************************************************************************************************************/ 80 100 static FNSSMINTSAVEEXEC gcmR3Save; 81 101 static FNSSMINTLOADEXEC gcmR3Load; 102 static char *gcmFixerIdsToString(char *pszDst, size_t cbDst, uint32_t fFixerIds, bool fInSpacePrefixedParenthesis) RT_NOEXCEPT; 82 103 83 104 … … 110 131 * Read & validate configuration. 111 132 */ 112 static struct { const char *pszName; uint32_t cchName; uint32_t fFlag; } const s_aFixerIds[] =113 {114 { RT_STR_TUPLE("DivByZeroDOS"), GCMFIXER_DBZ_DOS },115 { RT_STR_TUPLE("DivByZeroOS2"), GCMFIXER_DBZ_OS2 },116 { RT_STR_TUPLE("DivByZeroWin9x"), GCMFIXER_DBZ_WIN9X },117 { RT_STR_TUPLE("MesaVmsvgaDrv"), GCMFIXER_MESA_VMSVGA_DRV },118 };119 120 133 /* Assemble valid value names for CFMGR3ValidateConfig. */ 121 134 char szValidValues[1024]; 122 135 size_t offValidValues = 0; 123 for (unsigned i = 0; i < RT_ELEMENTS( s_aFixerIds); i++)124 { 125 AssertReturn(offValidValues + s_aFixerIds[i].cchName + 2 <= sizeof(szValidValues), VERR_INTERNAL_ERROR_2);136 for (unsigned i = 0; i < RT_ELEMENTS(g_aGcmFixerIds); i++) 137 { 138 AssertReturn(offValidValues + g_aGcmFixerIds[i].cchName + 2 <= sizeof(szValidValues), VERR_INTERNAL_ERROR_2); 126 139 if (offValidValues) 127 140 szValidValues[offValidValues++] = '|'; 128 memcpy(&szValidValues[offValidValues], s_aFixerIds[i].pszName, s_aFixerIds[i].cchName);129 offValidValues += s_aFixerIds[i].cchName;141 memcpy(&szValidValues[offValidValues], g_aGcmFixerIds[i].pszName, g_aGcmFixerIds[i].cchName); 142 offValidValues += g_aGcmFixerIds[i].cchName; 130 143 } 131 144 szValidValues[offValidValues] = '\0'; … … 144 157 /* Read the configuration. */ 145 158 pVM->gcm.s.fFixerSet = 0; 146 for (unsigned i = 0; i < RT_ELEMENTS( s_aFixerIds); i++)159 for (unsigned i = 0; i < RT_ELEMENTS(g_aGcmFixerIds); i++) 147 160 { 148 161 bool fEnabled = false; 149 rc = CFGMR3QueryBoolDef(pCfgNode, s_aFixerIds[i].pszName, &fEnabled, false);162 rc = CFGMR3QueryBoolDef(pCfgNode, g_aGcmFixerIds[i].pszName, &fEnabled, false); 150 163 if (RT_FAILURE(rc)) 151 return VMR3SetError(pVM->pUVM, rc, RT_SRC_POS, "Error reading /GCM/%s as boolean: %Rrc", s_aFixerIds[i].pszName, rc); 164 return VMR3SetError(pVM->pUVM, rc, RT_SRC_POS, "Error reading /GCM/%s as boolean: %Rrc", 165 g_aGcmFixerIds[i].pszName, rc); 152 166 if (fEnabled) 153 pVM->gcm.s.fFixerSet = s_aFixerIds[i].fFlag;167 pVM->gcm.s.fFixerSet = g_aGcmFixerIds[i].fFlag; 154 168 } 155 169 … … 161 175 * Log what's enabled. 162 176 */ 163 offValidValues = 0; 164 for (unsigned i = 0; i < RT_ELEMENTS(s_aFixerIds); i++) 165 if (pVM->gcm.s.fFixerSet & s_aFixerIds[i].fFlag) 166 { 167 AssertReturn(offValidValues + s_aFixerIds[i].cchName + 4 <= sizeof(szValidValues), VERR_INTERNAL_ERROR_2); 168 if (!offValidValues) 177 LogRel(("GCM: Initialized - Fixer bits: %#x%s\n", pVM->gcm.s.fFixerSet, 178 gcmFixerIdsToString(szValidValues, sizeof(szValidValues), pVM->gcm.s.fFixerSet, true))); 179 180 return VINF_SUCCESS; 181 } 182 183 184 /** 185 * Converts the fixer ID set to a string for logging and error reporting. 186 */ 187 static char *gcmFixerIdsToString(char *pszDst, size_t cbDst, uint32_t fFixerIds, bool fInSpacePrefixedParenthesis) RT_NOEXCEPT 188 { 189 AssertReturn(cbDst > 0, NULL); 190 *pszDst = '\0'; 191 192 size_t offDst = 0; 193 for (unsigned i = 0; i < RT_ELEMENTS(g_aGcmFixerIds); i++) 194 if (fFixerIds & g_aGcmFixerIds[i].fFlag) 195 { 196 AssertReturn(offDst + g_aGcmFixerIds[i].cchName + 4 <= cbDst, pszDst); 197 if (offDst) 169 198 { 170 szValidValues[offValidValues++] = '';171 szValidValues[offValidValues++] = '(';199 pszDst[offDst++] = ','; 200 pszDst[offDst++] = ' '; 172 201 } 173 else 202 else if (fInSpacePrefixedParenthesis) 174 203 { 175 szValidValues[offValidValues++] = ',';176 szValidValues[offValidValues++] = '';204 pszDst[offDst++] = ' '; 205 pszDst[offDst++] = '('; 177 206 } 178 memcpy(&szValidValues[offValidValues], s_aFixerIds[i].pszName, s_aFixerIds[i].cchName); 179 offValidValues += s_aFixerIds[i].cchName; 180 } 181 if (offValidValues) 182 szValidValues[offValidValues++] = ')'; 183 szValidValues[offValidValues] = '\0'; 184 LogRel(("GCM: Initialized - Fixer bits: %#x%s\n", pVM->gcm.s.fFixerSet, szValidValues)); 185 186 return VINF_SUCCESS; 207 memcpy(&pszDst[offDst], g_aGcmFixerIds[i].pszName, g_aGcmFixerIds[i].cchName); 208 offDst += g_aGcmFixerIds[i].cchName; 209 pszDst[offDst] = '\0'; 210 211 fFixerIds &= ~g_aGcmFixerIds[i].fFlag; 212 if (!fFixerIds) 213 break; 214 } 215 216 if (fFixerIds) 217 { 218 char szTmp[64]; 219 size_t const cchTmp = RTStrPrintf(szTmp, sizeof(szTmp), "%#x", fFixerIds); 220 AssertReturn(offDst + cchTmp + 4 <= cbDst, pszDst); 221 if (offDst) 222 { 223 pszDst[offDst++] = ','; 224 pszDst[offDst++] = ' '; 225 } 226 else if (fInSpacePrefixedParenthesis) 227 { 228 pszDst[offDst++] = ' '; 229 pszDst[offDst++] = '('; 230 } 231 memcpy(&pszDst[offDst], szTmp, cchTmp); 232 offDst += cchTmp; 233 pszDst[offDst] = '\0'; 234 } 235 236 if (offDst && fInSpacePrefixedParenthesis) 237 { 238 pszDst[offDst++] = ')'; 239 pszDst[offDst] = '\0'; 240 } 241 return pszDst; 187 242 } 188 243 … … 221 276 AssertRCReturn(rc, rc); 222 277 223 if (fFixerSet != pVM->gcm.s.fFixerSet) 224 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Saved GCM fixer set %#X differs from the configured one (%#X)."), 225 fFixerSet, pVM->gcm.s.fFixerSet); 226 227 return VINF_SUCCESS; 278 if (fFixerSet == pVM->gcm.s.fFixerSet) 279 return VINF_SUCCESS; 280 281 /* 282 * Check if we can reconfigure to the loaded fixer set. 283 */ 284 if ((fFixerSet & pVM->gcm.s.fFixerSet) == fFixerSet) 285 { 286 uint32_t fNotSetInSavedState = fFixerSet ^ pVM->gcm.s.fFixerSet; 287 while (fNotSetInSavedState) 288 { 289 unsigned iBit = ASMBitFirstSetU32(fNotSetInSavedState) - 1U; 290 uint32_t fFlag = RT_BIT_32(iBit); 291 292 unsigned idxEntry; 293 for (idxEntry = 0; idxEntry < RT_ELEMENTS(g_aGcmFixerIds); idxEntry++) 294 if (g_aGcmFixerIds[idxEntry].fFlag == fFlag) 295 break; 296 if (idxEntry >= RT_ELEMENTS(g_aGcmFixerIds)) 297 { 298 LogRel(("GCM: Error! Unknown fixer flag set in saved state: %#x\n", fFlag)); 299 break; 300 } 301 if (g_aGcmFixerIds[idxEntry].fSafeToClearOnLoad) 302 { 303 LogRel(("GCM: Error! Fixer flag %s is set in saved state but no in the VM configuration!\n", 304 g_aGcmFixerIds[idxEntry].pszName)); 305 break; 306 } 307 fNotSetInSavedState &= ~fFlag; 308 } 309 if (!fNotSetInSavedState) 310 { 311 pVM->gcm.s.fFixerSet &= fFixerSet; 312 return VINF_SUCCESS; 313 } 314 } 315 char szTmp1[1024], szTmp2[1024]; 316 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Saved GCM fixer set %#x%s differs from the configured one (%#x%s)."), 317 fFixerSet, gcmFixerIdsToString(szTmp1, sizeof(szTmp1), fFixerSet, true), 318 pVM->gcm.s.fFixerSet, gcmFixerIdsToString(szTmp2, sizeof(szTmp2), pVM->gcm.s.fFixerSet, true)); 228 319 } 229 320 -
trunk/src/VBox/VMM/include/GCMInternal.h
r104516 r106049 56 56 /** Windows 9x division by zero. */ 57 57 #define GCMFIXER_DBZ_WIN9X RT_BIT_32(2) 58 /** Workaround for the Mesa vmsvga driver using a IN/OUT backdoor. */ 58 /** Workaround for the Mesa vmsvga driver using a IN/OUT backdoor. 59 * @since 7.0 */ 59 60 #define GCMFIXER_MESA_VMSVGA_DRV RT_BIT_32(3) 60 61 /** @} */
Note:
See TracChangeset
for help on using the changeset viewer.