/** * Allocates one page. * * @param virtAddr The virtual address to which this page maybe mapped in * the future. * * @returns Pointer to the allocated page, NULL on failure. */ static page_t *rtR0MemObjSolPageAlloc(caddr_t virtAddr) { u_offset_t offPage; seg_t KernelSeg; /* * 16777215 terabytes of total memory for all VMs or * restart 8000 1GB VMs 2147483 times until wraparound! */ mutex_enter(&g_OffsetMtx); AssertCompileSize(u_offset_t, sizeof(uint64_t)); NOREF(RTASSERTVAR); g_offPage = RT_ALIGN_64(g_offPage, PAGE_SIZE) + PAGE_SIZE; offPage = g_offPage; mutex_exit(&g_OffsetMtx); KernelSeg.s_as = &kas; page_t *pPage = page_create_va(&g_PageVnode, offPage, PAGE_SIZE, PG_WAIT | PG_NORELOC, &KernelSeg, virtAddr); if (RT_LIKELY(pPage)) { /* * Lock this page into memory "long term" to prevent this page from being paged out * when we drop the page lock temporarily (during free). Downgrade to a shared lock * to prevent page relocation. */ page_pp_lock(pPage, 0 /* COW */, 1 /* Kernel */); page_io_unlock(pPage); page_downgrade(pPage); Assert(PAGE_LOCKED_SE(pPage, SE_SHARED)); } return pPage; }
static void tstVDSnapSegmentsDice(PVDSNAPTEST pTest, PVDDISKSEG paDiskSeg, uint32_t cDiskSegments, uint8_t *pbTestPattern, size_t cbTestPattern) { for (uint32_t i = 0; i < cDiskSegments; i++) { /* Do we want to change the current segment? */ if (tstVDSnapIsTrue(pTest->uChangeSegChance)) paDiskSeg[i].pbDataDiff = pbTestPattern + RT_ALIGN_64(RTRandAdvU64Ex(g_hRand, 0, cbTestPattern - paDiskSeg[i].cbSeg - 512), 512); } }
/** * Returns the size of the NOTE section given the name and size of the data. * * @param pszName Name of the note section. * @param cb Size of the data portion of the note section. * * @return The size of the NOTE section as rounded to the file alignment. */ static uint64_t Elf64NoteSectionSize(const char *pszName, uint64_t cbData) { uint64_t cbNote = sizeof(Elf64_Nhdr); size_t cbName = strlen(pszName) + 1; size_t cbNameAlign = RT_ALIGN_Z(cbName, g_NoteAlign); cbNote += cbNameAlign; cbNote += RT_ALIGN_64(cbData, g_NoteAlign); return cbNote; }
/** * Elf function to write 64-bit note header. * * @param hFile The file to write to. * @param Type Type of this section. * @param pszName Name of this section. * @param pcv Opaque pointer to the data, if NULL only computes size. * @param cbData Size of the data. * * @return IPRT status code. */ static int Elf64WriteNoteHdr(RTFILE hFile, uint16_t Type, const char *pszName, const void *pcvData, uint64_t cbData) { AssertReturn(pcvData, VERR_INVALID_POINTER); AssertReturn(cbData > 0, VERR_NO_DATA); char szNoteName[g_cbNoteName]; RT_ZERO(szNoteName); RTStrCopy(szNoteName, sizeof(szNoteName), pszName); size_t cbName = strlen(szNoteName) + 1; size_t cbNameAlign = RT_ALIGN_Z(cbName, g_NoteAlign); uint64_t cbDataAlign = RT_ALIGN_64(cbData, g_NoteAlign); /* * Yell loudly and bail if we are going to be writing a core file that is not compatible with * both Solaris and the 64-bit ELF spec. which dictates 8-byte alignment. See @bugref{5211} comment #3. */ if (cbNameAlign - cbName > 3) { LogRel((DBGFLOG_NAME ": Elf64WriteNoteHdr pszName=%s cbName=%u cbNameAlign=%u, cbName aligns to 4 not 8-bytes!\n", pszName, cbName, cbNameAlign)); return VERR_INVALID_PARAMETER; } if (cbDataAlign - cbData > 3) { LogRel((DBGFLOG_NAME ": Elf64WriteNoteHdr pszName=%s cbData=%u cbDataAlign=%u, cbData aligns to 4 not 8-bytes!\n", pszName, cbData, cbDataAlign)); return VERR_INVALID_PARAMETER; } static const char s_achPad[7] = { 0, 0, 0, 0, 0, 0, 0 }; AssertCompile(sizeof(s_achPad) >= g_NoteAlign - 1); Elf64_Nhdr ElfNoteHdr; RT_ZERO(ElfNoteHdr); ElfNoteHdr.n_namesz = (Elf64_Word)cbName - 1; /* Again, a discrepancy between ELF-64 and Solaris, we will follow ELF-64, see @bugref{5211} comment #3. */ ElfNoteHdr.n_type = Type; ElfNoteHdr.n_descsz = (Elf64_Word)cbDataAlign; /* * Write note header. */ int rc = RTFileWrite(hFile, &ElfNoteHdr, sizeof(ElfNoteHdr), NULL /* all */); if (RT_SUCCESS(rc)) { /* * Write note name. */ rc = RTFileWrite(hFile, szNoteName, cbName, NULL /* all */); if (RT_SUCCESS(rc)) { /* * Write note name padding if required. */ if (cbNameAlign > cbName) rc = RTFileWrite(hFile, s_achPad, cbNameAlign - cbName, NULL); if (RT_SUCCESS(rc)) { /* * Write note data. */ rc = RTFileWrite(hFile, pcvData, cbData, NULL /* all */); if (RT_SUCCESS(rc)) { /* * Write note data padding if required. */ if (cbDataAlign > cbData) rc = RTFileWrite(hFile, s_achPad, cbDataAlign - cbData, NULL /* all*/); } } } } if (RT_FAILURE(rc)) LogRel((DBGFLOG_NAME ": RTFileWrite failed. rc=%Rrc pszName=%s cbName=%u cbNameAlign=%u cbData=%u cbDataAlign=%u\n", rc, pszName, cbName, cbNameAlign, cbData, cbDataAlign)); return rc; }
/** * Translate a TAR header to an IPRT object info structure with additional UNIX * attributes. * * This completes the validation done by rtZipTarHdrValidate. * * @returns VINF_SUCCESS if valid, appropriate VERR_TAR_XXX if not. * @param pThis The TAR reader instance. * @param pObjInfo The object info structure (output). */ static int rtZipTarReaderGetFsObjInfo(PRTZIPTARREADER pThis, PRTFSOBJINFO pObjInfo) { /* * Zap the whole structure, this takes care of unused space in the union. */ RT_ZERO(*pObjInfo); /* * Convert the TAR field in RTFSOBJINFO order. */ int rc; int64_t i64Tmp; #define GET_TAR_NUMERIC_FIELD_RET(a_Var, a_Field) \ do { \ rc = rtZipTarHdrFieldToNum(a_Field, sizeof(a_Field), false /*fOctalOnly*/, &i64Tmp); \ if (RT_FAILURE(rc)) \ return rc; \ (a_Var) = i64Tmp; \ if ((a_Var) != i64Tmp) \ return VERR_TAR_NUM_VALUE_TOO_LARGE; \ } while (0) GET_TAR_NUMERIC_FIELD_RET(pObjInfo->cbObject, pThis->Hdr.Common.size); pObjInfo->cbAllocated = RT_ALIGN_64(pObjInfo->cbObject, 512); int64_t c64SecModTime; GET_TAR_NUMERIC_FIELD_RET(c64SecModTime, pThis->Hdr.Common.mtime); RTTimeSpecSetSeconds(&pObjInfo->ChangeTime, c64SecModTime); RTTimeSpecSetSeconds(&pObjInfo->ModificationTime, c64SecModTime); RTTimeSpecSetSeconds(&pObjInfo->AccessTime, c64SecModTime); RTTimeSpecSetSeconds(&pObjInfo->BirthTime, c64SecModTime); if (c64SecModTime != RTTimeSpecGetSeconds(&pObjInfo->ModificationTime)) return VERR_TAR_NUM_VALUE_TOO_LARGE; GET_TAR_NUMERIC_FIELD_RET(pObjInfo->Attr.fMode, pThis->Hdr.Common.mode); pObjInfo->Attr.enmAdditional = RTFSOBJATTRADD_UNIX; GET_TAR_NUMERIC_FIELD_RET(pObjInfo->Attr.u.Unix.uid, pThis->Hdr.Common.uid); GET_TAR_NUMERIC_FIELD_RET(pObjInfo->Attr.u.Unix.gid, pThis->Hdr.Common.gid); pObjInfo->Attr.u.Unix.cHardlinks = 1; pObjInfo->Attr.u.Unix.INodeIdDevice = 0; pObjInfo->Attr.u.Unix.INodeId = 0; pObjInfo->Attr.u.Unix.fFlags = 0; pObjInfo->Attr.u.Unix.GenerationId = 0; pObjInfo->Attr.u.Unix.Device = 0; switch (pThis->enmType) { case RTZIPTARTYPE_POSIX: case RTZIPTARTYPE_GNU: if ( pThis->Hdr.Common.typeflag == RTZIPTAR_TF_CHR || pThis->Hdr.Common.typeflag == RTZIPTAR_TF_BLK) { uint32_t uMajor, uMinor; GET_TAR_NUMERIC_FIELD_RET(uMajor, pThis->Hdr.Common.devmajor); GET_TAR_NUMERIC_FIELD_RET(uMinor, pThis->Hdr.Common.devminor); pObjInfo->Attr.u.Unix.Device = RTDEV_MAKE(uMajor, uMinor); if ( uMajor != RTDEV_MAJOR(pObjInfo->Attr.u.Unix.Device) || uMinor != RTDEV_MINOR(pObjInfo->Attr.u.Unix.Device)) return VERR_TAR_DEV_VALUE_TOO_LARGE; } break; default: if ( pThis->Hdr.Common.typeflag == RTZIPTAR_TF_CHR || pThis->Hdr.Common.typeflag == RTZIPTAR_TF_BLK) return VERR_TAR_UNKNOWN_TYPE_FLAG; } #undef GET_TAR_NUMERIC_FIELD_RET /* * Massage the result a little bit. * Also validate some more now that we've got the numbers to work with. */ if ( (pObjInfo->Attr.fMode & ~RTFS_UNIX_MASK) && pThis->enmType == RTZIPTARTYPE_POSIX) return VERR_TAR_BAD_MODE_FIELD; pObjInfo->Attr.fMode &= RTFS_UNIX_MASK; RTFMODE fModeType = 0; switch (pThis->Hdr.Common.typeflag) { case RTZIPTAR_TF_OLDNORMAL: case RTZIPTAR_TF_NORMAL: case RTZIPTAR_TF_CONTIG: { const char *pszEnd = strchr(pThis->szName, '\0'); if (pszEnd == &pThis->szName[0] || pszEnd[-1] != '/') fModeType |= RTFS_TYPE_FILE; else fModeType |= RTFS_TYPE_DIRECTORY; break; } case RTZIPTAR_TF_LINK: if (pObjInfo->cbObject != 0) #if 0 /* too strict */ return VERR_TAR_SIZE_NOT_ZERO; #else pObjInfo->cbObject = pObjInfo->cbAllocated = 0; #endif fModeType |= RTFS_TYPE_FILE; /* no better idea for now */ break; case RTZIPTAR_TF_SYMLINK: fModeType |= RTFS_TYPE_SYMLINK; break; case RTZIPTAR_TF_CHR: fModeType |= RTFS_TYPE_DEV_CHAR; break; case RTZIPTAR_TF_BLK: fModeType |= RTFS_TYPE_DEV_BLOCK; break; case RTZIPTAR_TF_DIR: fModeType |= RTFS_TYPE_DIRECTORY; break; case RTZIPTAR_TF_FIFO: fModeType |= RTFS_TYPE_FIFO; break; case RTZIPTAR_TF_GNU_LONGLINK: case RTZIPTAR_TF_GNU_LONGNAME: /* ASSUMES RTFS_TYPE_XXX uses the same values as GNU stored in the mode field. */ fModeType = pObjInfo->Attr.fMode & RTFS_TYPE_MASK; switch (fModeType) { case RTFS_TYPE_FILE: case RTFS_TYPE_DIRECTORY: case RTFS_TYPE_SYMLINK: case RTFS_TYPE_DEV_BLOCK: case RTFS_TYPE_DEV_CHAR: case RTFS_TYPE_FIFO: break; default: case 0: return VERR_TAR_UNKNOWN_TYPE_FLAG; /** @todo new status code */ } default: return VERR_TAR_UNKNOWN_TYPE_FLAG; /* Should've been caught in validate. */ } if ( (pObjInfo->Attr.fMode & RTFS_TYPE_MASK) && (pObjInfo->Attr.fMode & RTFS_TYPE_MASK) != fModeType) return VERR_TAR_MODE_WITH_TYPE; pObjInfo->Attr.fMode &= ~RTFS_TYPE_MASK; pObjInfo->Attr.fMode |= fModeType; switch (pThis->Hdr.Common.typeflag) { case RTZIPTAR_TF_CHR: case RTZIPTAR_TF_BLK: case RTZIPTAR_TF_DIR: case RTZIPTAR_TF_FIFO: pObjInfo->cbObject = 0; pObjInfo->cbAllocated = 0; break; } return VINF_SUCCESS; }
static int tstVDOpenCreateWriteMerge(PVDSNAPTEST pTest) { int rc; PVBOXHDD pVD = NULL; VDGEOMETRY PCHS = { 0, 0, 0 }; VDGEOMETRY LCHS = { 0, 0, 0 }; PVDINTERFACE pVDIfs = NULL; VDINTERFACEERROR VDIfError; /** Buffer storing the random test pattern. */ uint8_t *pbTestPattern = NULL; /** Number of disk segments */ uint32_t cDiskSegments; /** Array of disk segments */ PVDDISKSEG paDiskSeg = NULL; unsigned cDiffs = 0; unsigned idDiff = 0; /* Diff ID counter for the filename */ /* Delete all images from a previous run. */ RTFileDelete(pTest->pcszBaseImage); for (unsigned i = 0; i < pTest->cIterations; i++) { char *pszDiffFilename = NULL; rc = RTStrAPrintf(&pszDiffFilename, "tstVDSnapDiff%u.%s", i, pTest->pcszDiffSuff); if (RT_SUCCESS(rc)) { if (RTFileExists(pszDiffFilename)) RTFileDelete(pszDiffFilename); RTStrFree(pszDiffFilename); } } /* Create the virtual disk test data */ pbTestPattern = (uint8_t *)RTMemAlloc(pTest->cbTestPattern); RTRandAdvBytes(g_hRand, pbTestPattern, pTest->cbTestPattern); cDiskSegments = RTRandAdvU32Ex(g_hRand, pTest->cDiskSegsMin, pTest->cDiskSegsMax); uint64_t cbDisk = 0; paDiskSeg = (PVDDISKSEG)RTMemAllocZ(cDiskSegments * sizeof(VDDISKSEG)); if (!paDiskSeg) { RTPrintf("Failed to allocate memory for random disk segments\n"); g_cErrors++; return VERR_NO_MEMORY; } for (unsigned i = 0; i < cDiskSegments; i++) { paDiskSeg[i].off = cbDisk; paDiskSeg[i].cbSeg = RT_ALIGN_64(RTRandAdvU64Ex(g_hRand, 512, pTest->cbTestPattern), 512); if (tstVDSnapIsTrue(pTest->uAllocatedBlocks)) paDiskSeg[i].pbData = pbTestPattern + RT_ALIGN_64(RTRandAdvU64Ex(g_hRand, 0, pTest->cbTestPattern - paDiskSeg[i].cbSeg - 512), 512); else paDiskSeg[i].pbData = NULL; /* Not allocated initially */ cbDisk += paDiskSeg[i].cbSeg; } RTPrintf("Disk size is %llu bytes\n", cbDisk); #define CHECK(str) \ do \ { \ RTPrintf("%s rc=%Rrc\n", str, rc); \ if (RT_FAILURE(rc)) \ { \ if (pbTestPattern) \ RTMemFree(pbTestPattern); \ if (paDiskSeg) \ RTMemFree(paDiskSeg); \ VDDestroy(pVD); \ g_cErrors++; \ return rc; \ } \ } while (0) #define CHECK_BREAK(str) \ do \ { \ RTPrintf("%s rc=%Rrc\n", str, rc); \ if (RT_FAILURE(rc)) \ { \ g_cErrors++; \ break; \ } \ } while (0) /* Create error interface. */ /* Create error interface. */ VDIfError.pfnError = tstVDError; VDIfError.pfnMessage = tstVDMessage; rc = VDInterfaceAdd(&VDIfError.Core, "tstVD_Error", VDINTERFACETYPE_ERROR, NULL, sizeof(VDINTERFACEERROR), &pVDIfs); AssertRC(rc); rc = VDCreate(pVDIfs, VDTYPE_HDD, &pVD); CHECK("VDCreate()"); rc = VDCreateBase(pVD, pTest->pcszBackend, pTest->pcszBaseImage, cbDisk, VD_IMAGE_FLAGS_NONE, "Test image", &PCHS, &LCHS, NULL, VD_OPEN_FLAGS_NORMAL, NULL, NULL); CHECK("VDCreateBase()"); bool fInit = true; uint32_t cIteration = 0; /* Do the real work now */ while ( RT_SUCCESS(rc) && cIteration < pTest->cIterations) { /* Write */ rc = tstVDSnapWrite(pVD, paDiskSeg, cDiskSegments, cbDisk, fInit); CHECK_BREAK("tstVDSnapWrite()"); fInit = false; /* Write returned, do we want to create a new diff or merge them? */ bool fCreate = cDiffs < pTest->cDiffsMinBeforeMerge ? true : tstVDSnapIsTrue(pTest->uCreateDiffChance); if (fCreate) { char *pszDiffFilename = NULL; RTStrAPrintf(&pszDiffFilename, "tstVDSnapDiff%u.%s", idDiff, pTest->pcszDiffSuff); CHECK("RTStrAPrintf()"); idDiff++; cDiffs++; rc = VDCreateDiff(pVD, pTest->pcszBackend, pszDiffFilename, VD_IMAGE_FLAGS_NONE, "Test diff image", NULL, NULL, VD_OPEN_FLAGS_NORMAL, NULL, NULL); CHECK_BREAK("VDCreateDiff()"); RTStrFree(pszDiffFilename); VDDumpImages(pVD); /* Change data */ tstVDSnapSegmentsDice(pTest, paDiskSeg, cDiskSegments, pbTestPattern, pTest->cbTestPattern); } else { uint32_t uStartMerge = RTRandAdvU32Ex(g_hRand, 1, cDiffs - 1); uint32_t uEndMerge = RTRandAdvU32Ex(g_hRand, uStartMerge + 1, cDiffs); RTPrintf("Merging %u diffs from %u to %u...\n", uEndMerge - uStartMerge, uStartMerge, uEndMerge); if (pTest->fForward) rc = VDMerge(pVD, uStartMerge, uEndMerge, NULL); else rc = VDMerge(pVD, uEndMerge, uStartMerge, NULL); CHECK_BREAK("VDMerge()"); cDiffs -= uEndMerge - uStartMerge; VDDumpImages(pVD); /* Go through the disk segments and reset pointers. */ for (uint32_t i = 0; i < cDiskSegments; i++) { if (paDiskSeg[i].pbDataDiff) { paDiskSeg[i].pbData = paDiskSeg[i].pbDataDiff; paDiskSeg[i].pbDataDiff = NULL; } } /* Now compare the result with our test pattern */ rc = tstVDSnapReadVerify(pVD, paDiskSeg, cDiskSegments, cbDisk); CHECK_BREAK("tstVDSnapReadVerify()"); } cIteration++; } VDDumpImages(pVD); VDDestroy(pVD); if (paDiskSeg) RTMemFree(paDiskSeg); if (pbTestPattern) RTMemFree(pbTestPattern); RTFileDelete(pTest->pcszBaseImage); for (unsigned i = 0; i < idDiff; i++) { char *pszDiffFilename = NULL; RTStrAPrintf(&pszDiffFilename, "tstVDSnapDiff%u.%s", i, pTest->pcszDiffSuff); RTFileDelete(pszDiffFilename); RTStrFree(pszDiffFilename); } #undef CHECK return rc; }
/** * MSR write handler for KVM. * * @returns Strict VBox status code like CPUMSetGuestMsr(). * @retval VINF_CPUM_R3_MSR_WRITE * @retval VERR_CPUM_RAISE_GP_0 * * @param pVCpu Pointer to the VMCPU. * @param idMsr The MSR being written. * @param pRange The range this MSR belongs to. * @param uRawValue The raw value with the ignored bits not masked. */ VMM_INT_DECL(VBOXSTRICTRC) gimKvmWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uRawValue) { NOREF(pRange); PVM pVM = pVCpu->CTX_SUFF(pVM); PGIMKVM pKvm = &pVM->gim.s.u.Kvm; PGIMKVMCPU pKvmCpu = &pVCpu->gim.s.u.KvmCpu; switch (idMsr) { case MSR_GIM_KVM_SYSTEM_TIME: case MSR_GIM_KVM_SYSTEM_TIME_OLD: { bool fEnable = RT_BOOL(uRawValue & MSR_GIM_KVM_SYSTEM_TIME_ENABLE_BIT); #ifdef IN_RING0 gimR0KvmUpdateSystemTime(pVM, pVCpu); return VINF_CPUM_R3_MSR_WRITE; #elif defined(IN_RC) Assert(pVM->cCpus == 1); if (fEnable) { RTCCUINTREG fEFlags = ASMIntDisableFlags(); pKvmCpu->uTsc = TMCpuTickGetNoCheck(pVCpu) | UINT64_C(1); pKvmCpu->uVirtNanoTS = TMVirtualGetNoCheck(pVM) | UINT64_C(1); ASMSetFlags(fEFlags); } return VINF_CPUM_R3_MSR_WRITE; #else /* IN_RING3 */ if (!fEnable) { gimR3KvmDisableSystemTime(pVM); pKvmCpu->u64SystemTimeMsr = uRawValue; return VINF_SUCCESS; } /* Is the system-time struct. already enabled? If so, get flags that need preserving. */ uint8_t fFlags = 0; GIMKVMSYSTEMTIME SystemTime; RT_ZERO(SystemTime); if ( MSR_GIM_KVM_SYSTEM_TIME_IS_ENABLED(pKvmCpu->u64SystemTimeMsr) && MSR_GIM_KVM_SYSTEM_TIME_GUEST_GPA(uRawValue) == pKvmCpu->GCPhysSystemTime) { int rc2 = PGMPhysSimpleReadGCPhys(pVM, &SystemTime, pKvmCpu->GCPhysSystemTime, sizeof(GIMKVMSYSTEMTIME)); if (RT_SUCCESS(rc2)) pKvmCpu->fSystemTimeFlags = (SystemTime.fFlags & GIM_KVM_SYSTEM_TIME_FLAGS_GUEST_PAUSED); } /* Enable and populate the system-time struct. */ pKvmCpu->u64SystemTimeMsr = uRawValue; pKvmCpu->GCPhysSystemTime = MSR_GIM_KVM_SYSTEM_TIME_GUEST_GPA(uRawValue); pKvmCpu->u32SystemTimeVersion += 2; int rc = gimR3KvmEnableSystemTime(pVM, pVCpu); if (RT_FAILURE(rc)) { pKvmCpu->u64SystemTimeMsr = 0; return VERR_CPUM_RAISE_GP_0; } return VINF_SUCCESS; #endif } case MSR_GIM_KVM_WALL_CLOCK: case MSR_GIM_KVM_WALL_CLOCK_OLD: { #ifndef IN_RING3 return VINF_CPUM_R3_MSR_WRITE; #else /* Enable the wall-clock struct. */ RTGCPHYS GCPhysWallClock = MSR_GIM_KVM_WALL_CLOCK_GUEST_GPA(uRawValue); if (RT_LIKELY(RT_ALIGN_64(GCPhysWallClock, 4) == GCPhysWallClock)) { int rc = gimR3KvmEnableWallClock(pVM, GCPhysWallClock); if (RT_SUCCESS(rc)) { pKvm->u64WallClockMsr = uRawValue; return VINF_SUCCESS; } } return VERR_CPUM_RAISE_GP_0; #endif /* IN_RING3 */ } default: { #ifdef IN_RING3 static uint32_t s_cTimes = 0; if (s_cTimes++ < 20) LogRel(("GIM: KVM: Unknown/invalid WrMsr (%#x,%#x`%08x) -> #GP(0)\n", idMsr, uRawValue & UINT64_C(0xffffffff00000000), uRawValue & UINT64_C(0xffffffff))); #endif LogFunc(("Unknown/invalid WrMsr (%#RX32,%#RX64) -> #GP(0)\n", idMsr, uRawValue)); break; } } return VERR_CPUM_RAISE_GP_0; }