Changeset 1416 in vbox for trunk/src/VBox
- Timestamp:
- Mar 12, 2007 12:00:27 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 19422
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/SELM.cpp
r1411 r1416 164 164 STAM_REG(pVM, &pVM->selm.s.StatUpdateFromCPUM, STAMTYPE_PROFILE, "/PROF/SELM/UpdateFromCPUM", STAMUNIT_TICKS_PER_CALL, "Profiling of the SELMR3UpdateFromCPUM() body."); 165 165 166 STAM_REG(pVM, &pVM->selm.s.StatHyperSelsChanged, STAMTYPE_COUNTER, "/SELM/HyperSels/Changed", STAMUNIT_OCCURENCES, "The number of times we had to relocate our hypervisor selectors."); 167 166 168 /* 167 169 * Default action when entering raw mode for the first time … … 227 229 228 230 /** 229 * Applies relocations to data and code managed by this 230 * component. This function will be called at init and 231 * whenever the VMM need to relocate it self inside the GC. 232 * 233 * @param pVM The VM. 234 */ 235 SELMR3DECL(void) SELMR3Relocate(PVM pVM) 236 { 237 LogFlow(("SELMR3Relocate\n")); 231 * Save hypervisor GDT selectors in our shadow table 232 * 233 * @param pVM The VM handle. 234 */ 235 static void selmR3SaveHyperGDTSelectors(PVM pVM) 236 { 238 237 PVBOXDESC paGdt = pVM->selm.s.paGdtHC; 239 240 /*241 * Update GDTR and selector.242 */243 CPUMSetHyperGDTR(pVM, MMHyperHC2GC(pVM, paGdt), SELM_GDT_ELEMENTS * sizeof(paGdt[0]) - 1);244 245 /** @todo selector relocations should be a seperate operation? */246 CPUMSetHyperCS(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS]);247 CPUMSetHyperDS(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]);248 CPUMSetHyperES(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]);249 CPUMSetHyperSS(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]);250 CPUMSetHyperTR(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS]);251 238 252 239 /* … … 338 325 pDesc->Gen.u1DefBig = 0; 339 326 pDesc->Gen.u1Granularity = 0; /* byte limit */ 327 } 328 329 /** 330 * Applies relocations to data and code managed by this 331 * component. This function will be called at init and 332 * whenever the VMM need to relocate it self inside the GC. 333 * 334 * @param pVM The VM. 335 */ 336 SELMR3DECL(void) SELMR3Relocate(PVM pVM) 337 { 338 PVBOXDESC paGdt = pVM->selm.s.paGdtHC; 339 LogFlow(("SELMR3Relocate\n")); 340 341 /* 342 * Update GDTR and selector. 343 */ 344 CPUMSetHyperGDTR(pVM, MMHyperHC2GC(pVM, paGdt), SELM_GDT_ELEMENTS * sizeof(paGdt[0]) - 1); 345 346 /** @todo selector relocations should be a seperate operation? */ 347 CPUMSetHyperCS(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS]); 348 CPUMSetHyperDS(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]); 349 CPUMSetHyperES(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]); 350 CPUMSetHyperSS(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS]); 351 CPUMSetHyperTR(pVM, pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS]); 352 353 selmR3SaveHyperGDTSelectors(pVM); 340 354 341 355 /** @todo SELM must be called when any of the CR3s changes during a cpu mode change. */ … … 667 681 RTSEL SelTSSTrap08; 668 682 SSMR3GetSel(pSSM, &SelTSSTrap08); 669 if (u32Version == 1) 670 { 671 RTSEL SelTSSTrap0a; 672 int rc = SSMR3GetSel(pSSM, &SelTSSTrap0a); 673 if (VBOX_FAILURE(rc)) 674 return rc; 675 } 676 677 /* Check that no selectors have be relocated. */ 683 684 /* Copy the selectors; they will be checked during relocation. */ 678 685 PSELM pSelm = &pVM->selm.s; 679 if ( SelCS != pSelm->aHyperSel[SELM_HYPER_SEL_CS] 680 || SelDS != pSelm->aHyperSel[SELM_HYPER_SEL_DS] 681 || SelCS64 != pSelm->aHyperSel[SELM_HYPER_SEL_CS64] 682 || SelDS64 != pSelm->aHyperSel[SELM_HYPER_SEL_CS64] 683 || SelTSS != pSelm->aHyperSel[SELM_HYPER_SEL_TSS] 684 || SelTSSTrap08 != pSelm->aHyperSel[SELM_HYPER_SEL_TSS_TRAP08]) 685 { 686 AssertMsgFailed(("Some selector have been relocated - this cannot happen!\n")); 687 return VERR_SSM_DATA_UNIT_FORMAT_CHANGED; 688 } 686 pSelm->aHyperSel[SELM_HYPER_SEL_CS] = SelCS; 687 pSelm->aHyperSel[SELM_HYPER_SEL_DS] = SelDS; 688 pSelm->aHyperSel[SELM_HYPER_SEL_CS64] = SelCS64; 689 pSelm->aHyperSel[SELM_HYPER_SEL_TSS] = SelTSS; 690 pSelm->aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] = SelTSSTrap08; 689 691 690 692 return VINF_SUCCESS; … … 735 737 736 738 739 #if 0 /* obsolete */ 737 740 /** 738 741 * Sets up the virtualization of a guest GDT. … … 745 748 SELMR3DECL(int) SELMR3GdtSetup(PVM pVM, PCVBOXDESC paGDTEs, unsigned cGDTEs) 746 749 { 747 AssertMsg(cGDTEs <= (unsigned)(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] >> 3), ("Oops! the loaded GDT is as large as our.. we assume no clashes!!!\n"));748 749 750 /* 750 751 * Enumerate the array. … … 772 773 return VINF_SUCCESS; 773 774 } 774 775 #endif 775 776 776 777 /** … … 895 896 * Check if the Guest GDT intrudes on our GDT entries. 896 897 */ 897 // RTSEL aHyperGDT[MAX_NEEDED_HYPERVISOR_GDTS];898 if (cbEffLimit >= pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08])899 {900 #if 0 898 /** @todo we should try to minimize relocations by making sure our current selectors can be reused. */ 899 RTSEL aHyperGDT[SELM_HYPER_SEL_MAX]; 900 if (cbEffLimit >= SELM_HYPER_DEFAULT_BASE) 901 { 901 902 PVBOXDESC pGDTEStart = pVM->selm.s.paGdtHC; 902 903 PVBOXDESC pGDTE = (PVBOXDESC)((char *)pGDTEStart + GDTR.cbGdt + 1 - sizeof(VBOXDESC)); 903 904 int iGDT = 0; 904 905 905 /* Disabling this for now; previously saw triple faults with OS/2, before fixing the above if statement */906 906 Log(("Internal SELM GDT conflict: use non-present entries\n")); 907 while (pGDTE > pGDTEStart && iGDT < MAX_NEEDED_HYPERVISOR_GDTS)907 while (pGDTE > pGDTEStart && iGDT < SELM_HYPER_SEL_MAX) 908 908 { 909 909 /* We can reuse non-present entries */ … … 918 918 pGDTE--; 919 919 } 920 if (iGDT != MAX_NEEDED_HYPERVISOR_GDTS) 921 #endif 920 if (iGDT != SELM_HYPER_SEL_MAX) 922 921 { 923 922 AssertReleaseMsgFailed(("Internal SELM GDT conflict.\n")); … … 925 924 return VERR_NOT_IMPLEMENTED; 926 925 } 926 } 927 else 928 { 929 aHyperGDT[SELM_HYPER_SEL_CS] = SELM_HYPER_DEFAULT_SEL_CS; 930 aHyperGDT[SELM_HYPER_SEL_DS] = SELM_HYPER_DEFAULT_SEL_DS; 931 aHyperGDT[SELM_HYPER_SEL_CS64] = SELM_HYPER_DEFAULT_SEL_CS64; 932 aHyperGDT[SELM_HYPER_SEL_TSS] = SELM_HYPER_DEFAULT_SEL_TSS; 933 aHyperGDT[SELM_HYPER_SEL_TSS_TRAP08] = SELM_HYPER_DEFAULT_SEL_TSS_TRAP08; 927 934 } 928 935 … … 973 980 } 974 981 975 #if 0 /** @todo r=bird: The relocation code won't be working right. Start with the IF below. */ 976 /* 977 * Check if the Guest GDT intrudes on our GDT entries. 978 */ 979 if (cbEffLimit >= pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08]) 982 /* 983 * Check if our hypervisor selectors were changed. 984 */ 985 if ( aHyperGDT[SELM_HYPER_SEL_CS] != pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS] 986 || aHyperGDT[SELM_HYPER_SEL_DS] != pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS] 987 || aHyperGDT[SELM_HYPER_SEL_CS64] != pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS64] 988 || aHyperGDT[SELM_HYPER_SEL_TSS] != pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS] 989 || aHyperGDT[SELM_HYPER_SEL_TSS_TRAP08] != pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08]) 980 990 { 981 991 /* Reinitialize our hypervisor GDTs */ 982 pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS] = aHyperGDT[0]; 983 pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS] = aHyperGDT[1]; 984 pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS64] = aHyperGDT[2]; 985 pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS] = aHyperGDT[3]; 986 pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] = aHyperGDT[4]; 987 SELMR3Relocate(pVM); /** @todo r=bird: Must call VMR3Relocate! */ 988 } 989 #endif 992 pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS] = aHyperGDT[SELM_HYPER_SEL_CS]; 993 pVM->selm.s.aHyperSel[SELM_HYPER_SEL_DS] = aHyperGDT[SELM_HYPER_SEL_DS]; 994 pVM->selm.s.aHyperSel[SELM_HYPER_SEL_CS64] = aHyperGDT[SELM_HYPER_SEL_CS64]; 995 pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS] = aHyperGDT[SELM_HYPER_SEL_TSS]; 996 pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] = aHyperGDT[SELM_HYPER_SEL_TSS_TRAP08]; 997 998 STAM_COUNTER_INC(&pVM->selm.s.StatHyperSelsChanged); 999 /** Relocate (switcher and selector data needs to update their selectors) */ 1000 VMR3Relocate(pVM, 0); 1001 } 1002 else 1003 if (cbEffLimit >= SELM_HYPER_DEFAULT_BASE) 1004 /* We overwrote all entries above, so we have to save them again. */ 1005 selmR3SaveHyperGDTSelectors(pVM); 990 1006 991 1007 /* … … 1545 1561 return VINF_SUCCESS; 1546 1562 1547 #if 01548 1563 if (GDTR.cbGdt >= (unsigned)(pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS_TRAP08] >> X86_SEL_SHIFT)) 1549 { 1550 AssertReleaseMsgFailed(("Internal SELM GDT conflict.\n")); 1551 return VERR_NOT_IMPLEMENTED; 1552 } 1553 #endif 1564 Log(("SELMR3DebugCheck: guest GDT size forced us to look for unused selectors.\n")); 1554 1565 1555 1566 if (GDTR.cbGdt != pVM->selm.s.GuestGdtr.cbGdt) -
trunk/src/VBox/VMM/SELMInternal.h
r1411 r1416 39 39 */ 40 40 41 /** Number of GDTs we need for internal use */42 #define MAX_NEEDED_HYPERVISOR_GDTS 543 44 41 /** The number of GDTS allocated for our GDT. (full size) */ 45 42 #define SELM_GDT_ELEMENTS 8192 … … 56 53 /** The TSS selector for taking trap 08 (\#DF). */ 57 54 #define SELM_HYPER_SEL_TSS_TRAP08 4 55 /** Number of GDTs we need for internal use */ 58 56 #define SELM_HYPER_SEL_MAX (SELM_HYPER_SEL_TSS_TRAP08+1) 57 58 59 /** Default GDT selectors we use for the hypervisor. */ 60 #define SELM_HYPER_DEFAULT_SEL_CS ((SELM_GDT_ELEMENTS - 0x1) << 3) 61 #define SELM_HYPER_DEFAULT_SEL_DS ((SELM_GDT_ELEMENTS - 0x2) << 3) 62 #define SELM_HYPER_DEFAULT_SEL_CS64 ((SELM_GDT_ELEMENTS - 0x3) << 3) 63 #define SELM_HYPER_DEFAULT_SEL_TSS ((SELM_GDT_ELEMENTS - 0x4) << 3) 64 #define SELM_HYPER_DEFAULT_SEL_TSS_TRAP08 ((SELM_GDT_ELEMENTS - 0x5) << 3) 65 /** @note SELM_HYPER_DEFAULT_BASE is the lowest value we use. */ 66 #define SELM_HYPER_DEFAULT_BASE SELM_HYPER_DEFAULT_SEL_TSS_TRAP08 59 67 60 68 /** … … 156 164 /** GC: The number of unhandled write to the Guest's TSS. */ 157 165 STAMCOUNTER StatGCWriteGuestTSSUnhandled; 166 /** The number of times we had to relocate our hypervisor selectors. */ 167 STAMCOUNTER StatHyperSelsChanged; 158 168 } SELM, *PSELM; 159 169
Note:
See TracChangeset
for help on using the changeset viewer.