Changeset 9678 in vbox
- Timestamp:
- Jun 13, 2008 11:42:02 AM (16 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
-
include/VBox/selm.h (modified) (2 diffs)
-
src/VBox/VMM/VMMAll/IOMAllMMIO.cpp (modified) (4 diffs)
-
src/VBox/VMM/VMMAll/SELMAll.cpp (modified) (3 diffs)
-
src/VBox/VMM/VMMAll/TRPMAll.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/selm.h
r9675 r9678 200 200 * @returns VBox status 201 201 * @param pVM VM Handle. 202 * @param SelReg Selector register 203 * @param pCtxCore CPU context 204 * @param Addr Address part. 205 * @param fFlags SELMTOFLAT_FLAGS_* 206 * GDT entires are valid. 207 * @param ppvGC Where to store the GC flat address. 208 */ 209 SELMDECL(int) SELMToFlatEx(PVM pVM, DIS_SELREG SelReg, PCPUMCTXCORE pCtxCore, RTGCPTR Addr, unsigned fFlags, PRTGCPTR ppvGC); 210 211 /** 212 * Converts a GC selector based address to a flat address. 213 * 214 * Some basic checking is done, but not all kinds yet. 215 * 216 * Note: Obsolete: DO NOT USE 217 * 218 * @returns VBox status 219 * @param pVM VM Handle. 202 220 * @param eflags Current eflags 203 221 * @param Sel Selector part. … … 210 228 * the selector. NULL is allowed. 211 229 */ 212 SELMDECL(int) SELMToFlat Ex(PVM pVM, X86EFLAGS eflags, RTSEL Sel, RTGCPTR Addr, PCPUMSELREGHIDpHiddenSel, unsigned fFlags, PRTGCPTR ppvGC, uint32_t *pcb);230 SELMDECL(int) SELMToFlatBySelEx(PVM pVM, X86EFLAGS eflags, RTSEL Sel, RTGCPTR Addr, CPUMSELREGHID *pHiddenSel, unsigned fFlags, PRTGCPTR ppvGC, uint32_t *pcb); 213 231 214 232 /** -
trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
r9659 r9678 345 345 /* Convert source address ds:esi. */ 346 346 RTGCUINTPTR pu8Virt; 347 rc = SELMToFlatEx(pVM, pRegFrame->eflags, pRegFrame->ds, (RTGCPTR)pRegFrame->esi, &pRegFrame->dsHid,347 rc = SELMToFlatEx(pVM, DIS_SELREG_DS, pRegFrame, (RTGCPTR)pRegFrame->esi, 348 348 SELMTOFLAT_FLAGS_HYPER | SELMTOFLAT_FLAGS_NO_PL, 349 (PRTGCPTR)&pu8Virt , NULL);349 (PRTGCPTR)&pu8Virt); 350 350 if (VBOX_SUCCESS(rc)) 351 351 { … … 404 404 /* Convert destination address. */ 405 405 RTGCUINTPTR pu8Virt; 406 rc = SELMToFlatEx(pVM, pRegFrame->eflags, pRegFrame->es, (RTGCPTR)pRegFrame->edi, &pRegFrame->esHid,407 SELMTOFLAT_FLAGS_HYPER | SELMTOFLAT_FLAGS_NO_PL,408 (RTGCPTR *)&pu8Virt, NULL);406 rc = SELMToFlatEx(pVM, DIS_SELREG_ES, pRegFrame, (RTGCPTR)pRegFrame->edi, 407 SELMTOFLAT_FLAGS_HYPER | SELMTOFLAT_FLAGS_NO_PL, 408 (RTGCPTR *)&pu8Virt); 409 409 if (VBOX_FAILURE(rc)) 410 410 return VINF_EM_RAW_GUEST_TRAP; … … 1319 1319 /* Convert destination address es:edi. */ 1320 1320 RTGCPTR GCPtrDst; 1321 int rc = SELMToFlatEx(pVM, pRegFrame->eflags, pRegFrame->es, (RTGCPTR)pRegFrame->edi, &pRegFrame->esHid,1321 int rc = SELMToFlatEx(pVM, DIS_SELREG_ES, pRegFrame, (RTGCPTR)pRegFrame->edi, 1322 1322 SELMTOFLAT_FLAGS_HYPER | SELMTOFLAT_FLAGS_NO_PL, 1323 &GCPtrDst , NULL);1323 &GCPtrDst); 1324 1324 if (VBOX_FAILURE(rc)) 1325 1325 { … … 1474 1474 /* Convert source address ds:esi. */ 1475 1475 RTGCPTR GCPtrSrc; 1476 int rc = SELMToFlatEx(pVM, pRegFrame->eflags, pRegFrame->ds, (RTGCPTR)pRegFrame->esi, &pRegFrame->dsHid,1476 int rc = SELMToFlatEx(pVM, DIS_SELREG_DS, pRegFrame, (RTGCPTR)pRegFrame->esi, 1477 1477 SELMTOFLAT_FLAGS_HYPER | SELMTOFLAT_FLAGS_NO_PL, 1478 &GCPtrSrc , NULL);1478 &GCPtrSrc); 1479 1479 if (VBOX_FAILURE(rc)) 1480 1480 { -
trunk/src/VBox/VMM/VMMAll/SELMAll.cpp
r9675 r9678 52 52 SELMDECL(RTGCPTR) SELMToFlatBySel(PVM pVM, RTSEL Sel, RTGCPTR Addr) 53 53 { 54 Assert(!CPUM AreHiddenSelRegsValid(pVM));54 Assert(!CPUMIsGuestInLongMode(pVM)); /** DON'T USE! */ 55 55 56 56 /** @todo check the limit. */ … … 131 131 } 132 132 133 134 /** 135 * Converts a GC selector based address to a flat address. 136 * 137 * Some basic checking is done, but not all kinds yet. 138 * 139 * @returns VBox status 140 * @param pVM VM Handle. 141 * @param SelReg Selector register 142 * @param pCtxCore CPU context 143 * @param Addr Address part. 144 * @param fFlags SELMTOFLAT_FLAGS_* 145 * GDT entires are valid. 146 * @param ppvGC Where to store the GC flat address. 147 */ 148 SELMDECL(int) SELMToFlatEx(PVM pVM, DIS_SELREG SelReg, PCPUMCTXCORE pCtxCore, RTGCPTR Addr, unsigned fFlags, PRTGCPTR ppvGC) 149 { 150 PCPUMSELREGHID pHiddenSel; 151 RTSEL Sel; 152 int rc; 153 154 rc = DISFetchRegSegEx(pCtxCore, SelReg, &Sel, &pHiddenSel); AssertRC(rc); 155 156 /* 157 * Deal with real & v86 mode first. 158 */ 159 if ( CPUMIsGuestInRealMode(pVM) 160 || pCtxCore->eflags.Bits.u1VM) 161 { 162 RTGCUINTPTR uFlat = (RTGCUINTPTR)Addr & 0xffff; 163 if (ppvGC) 164 { 165 if ( pHiddenSel 166 && CPUMAreHiddenSelRegsValid(pVM)) 167 *ppvGC = (RTGCPTR)(pHiddenSel->u64Base + uFlat); 168 else 169 *ppvGC = (RTGCPTR)(((RTGCUINTPTR)Sel << 4) + uFlat); 170 } 171 return VINF_SUCCESS; 172 } 173 174 175 uint32_t u32Limit; 176 RTGCPTR pvFlat; 177 uint32_t u1Present, u1DescType, u1Granularity, u4Type; 178 179 /** @todo when we're in 16 bits mode, we should cut off the address as well.. */ 180 #ifndef IN_GC 181 if ( pHiddenSel 182 && CPUMAreHiddenSelRegsValid(pVM)) 183 { 184 bool fCheckLimit = true; 185 186 u1Present = pHiddenSel->Attr.n.u1Present; 187 u1Granularity = pHiddenSel->Attr.n.u1Granularity; 188 u1DescType = pHiddenSel->Attr.n.u1DescType; 189 u4Type = pHiddenSel->Attr.n.u4Type; 190 191 u32Limit = pHiddenSel->u32Limit; 192 193 /* 64 bits mode: CS, DS, ES and SS are treated as if each segment base is 0 (Intel® 64 and IA-32 Architectures Software Developer's Manual: 3.4.2.1). */ 194 if ( CPUMIsGuestInLongMode(pVM) 195 && pCtxCore->csHid.Attr.n.u1Long) 196 { 197 fCheckLimit = false; 198 switch (SelReg) 199 { 200 case DIS_SELREG_FS: 201 pvFlat = (CPUMGetGuestFSBASE(pVM) + Addr); 202 break; 203 204 case DIS_SELREG_GS: 205 pvFlat = (CPUMGetGuestGSBASE(pVM) + Addr); 206 break; 207 208 default: 209 pvFlat = Addr; 210 break; 211 } 212 } 213 else 214 pvFlat = (RTGCPTR)(pHiddenSel->u64Base + (RTGCUINTPTR)Addr); 215 216 /* 217 * Check if present. 218 */ 219 if (u1Present) 220 { 221 /* 222 * Type check. 223 */ 224 switch (u4Type) 225 { 226 227 /** Read only selector type. */ 228 case X86_SEL_TYPE_RO: 229 case X86_SEL_TYPE_RO_ACC: 230 case X86_SEL_TYPE_RW: 231 case X86_SEL_TYPE_RW_ACC: 232 case X86_SEL_TYPE_EO: 233 case X86_SEL_TYPE_EO_ACC: 234 case X86_SEL_TYPE_ER: 235 case X86_SEL_TYPE_ER_ACC: 236 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 237 { 238 /** @todo fix this mess */ 239 } 240 /* check limit. */ 241 if (fCheckLimit && (RTGCUINTPTR)Addr > u32Limit) 242 return VERR_OUT_OF_SELECTOR_BOUNDS; 243 /* ok */ 244 if (ppvGC) 245 *ppvGC = pvFlat; 246 return VINF_SUCCESS; 247 248 case X86_SEL_TYPE_EO_CONF: 249 case X86_SEL_TYPE_EO_CONF_ACC: 250 case X86_SEL_TYPE_ER_CONF: 251 case X86_SEL_TYPE_ER_CONF_ACC: 252 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 253 { 254 /** @todo fix this mess */ 255 } 256 /* check limit. */ 257 if (fCheckLimit && (RTGCUINTPTR)Addr > u32Limit) 258 return VERR_OUT_OF_SELECTOR_BOUNDS; 259 /* ok */ 260 if (ppvGC) 261 *ppvGC = pvFlat; 262 return VINF_SUCCESS; 263 264 case X86_SEL_TYPE_RO_DOWN: 265 case X86_SEL_TYPE_RO_DOWN_ACC: 266 case X86_SEL_TYPE_RW_DOWN: 267 case X86_SEL_TYPE_RW_DOWN_ACC: 268 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 269 { 270 /** @todo fix this mess */ 271 } 272 /* check limit. */ 273 if (fCheckLimit) 274 { 275 if (!u1Granularity && (RTGCUINTPTR)Addr > (RTGCUINTPTR)0xffff) 276 return VERR_OUT_OF_SELECTOR_BOUNDS; 277 if ((RTGCUINTPTR)Addr <= u32Limit) 278 return VERR_OUT_OF_SELECTOR_BOUNDS; 279 } 280 /* ok */ 281 if (ppvGC) 282 *ppvGC = pvFlat; 283 return VINF_SUCCESS; 284 285 default: 286 return VERR_INVALID_SELECTOR; 287 288 } 289 } 290 } 291 else 292 #endif /* !IN_GC */ 293 #ifndef IN_RING0 294 { 295 VBOXDESC Desc; 296 297 if (!(Sel & X86_SEL_LDT)) 298 { 299 if ( !(fFlags & SELMTOFLAT_FLAGS_HYPER) 300 && (unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.GuestGdtr.cbGdt) 301 return VERR_INVALID_SELECTOR; 302 Desc = pVM->selm.s.CTXSUFF(paGdt)[Sel >> X86_SEL_SHIFT]; 303 } 304 else 305 { 306 if ((unsigned)(Sel & X86_SEL_MASK) >= pVM->selm.s.cbLdtLimit) 307 return VERR_INVALID_SELECTOR; 308 309 /** @todo handle LDT page(s) not present! */ 310 #ifdef IN_GC 311 PVBOXDESC paLDT = (PVBOXDESC)((char *)pVM->selm.s.GCPtrLdt + pVM->selm.s.offLdtHyper); 312 #else 313 PVBOXDESC paLDT = (PVBOXDESC)((char *)pVM->selm.s.HCPtrLdt + pVM->selm.s.offLdtHyper); 314 #endif 315 Desc = paLDT[Sel >> X86_SEL_SHIFT]; 316 } 317 318 /* calc limit. */ 319 u32Limit = X86DESC_LIMIT(Desc); 320 if (Desc.Gen.u1Granularity) 321 u32Limit = (u32Limit << PAGE_SHIFT) | PAGE_OFFSET_MASK; 322 323 /* calc address assuming straight stuff. */ 324 pvFlat = (RTGCPTR)((RTGCUINTPTR)Addr + X86DESC_BASE(Desc)); 325 326 u1Present = Desc.Gen.u1Present; 327 u1Granularity = Desc.Gen.u1Granularity; 328 u1DescType = Desc.Gen.u1DescType; 329 u4Type = Desc.Gen.u4Type; 330 331 /* 332 * Check if present. 333 */ 334 if (u1Present) 335 { 336 /* 337 * Type check. 338 */ 339 #define BOTH(a, b) ((a << 16) | b) 340 switch (BOTH(u1DescType, u4Type)) 341 { 342 343 /** Read only selector type. */ 344 case BOTH(1,X86_SEL_TYPE_RO): 345 case BOTH(1,X86_SEL_TYPE_RO_ACC): 346 case BOTH(1,X86_SEL_TYPE_RW): 347 case BOTH(1,X86_SEL_TYPE_RW_ACC): 348 case BOTH(1,X86_SEL_TYPE_EO): 349 case BOTH(1,X86_SEL_TYPE_EO_ACC): 350 case BOTH(1,X86_SEL_TYPE_ER): 351 case BOTH(1,X86_SEL_TYPE_ER_ACC): 352 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 353 { 354 /** @todo fix this mess */ 355 } 356 /* check limit. */ 357 if ((RTGCUINTPTR)Addr > u32Limit) 358 return VERR_OUT_OF_SELECTOR_BOUNDS; 359 /* ok */ 360 if (ppvGC) 361 *ppvGC = pvFlat; 362 return VINF_SUCCESS; 363 364 case BOTH(1,X86_SEL_TYPE_EO_CONF): 365 case BOTH(1,X86_SEL_TYPE_EO_CONF_ACC): 366 case BOTH(1,X86_SEL_TYPE_ER_CONF): 367 case BOTH(1,X86_SEL_TYPE_ER_CONF_ACC): 368 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 369 { 370 /** @todo fix this mess */ 371 } 372 /* check limit. */ 373 if ((RTGCUINTPTR)Addr > u32Limit) 374 return VERR_OUT_OF_SELECTOR_BOUNDS; 375 /* ok */ 376 if (ppvGC) 377 *ppvGC = pvFlat; 378 return VINF_SUCCESS; 379 380 case BOTH(1,X86_SEL_TYPE_RO_DOWN): 381 case BOTH(1,X86_SEL_TYPE_RO_DOWN_ACC): 382 case BOTH(1,X86_SEL_TYPE_RW_DOWN): 383 case BOTH(1,X86_SEL_TYPE_RW_DOWN_ACC): 384 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 385 { 386 /** @todo fix this mess */ 387 } 388 /* check limit. */ 389 if (!u1Granularity && (RTGCUINTPTR)Addr > (RTGCUINTPTR)0xffff) 390 return VERR_OUT_OF_SELECTOR_BOUNDS; 391 if ((RTGCUINTPTR)Addr <= u32Limit) 392 return VERR_OUT_OF_SELECTOR_BOUNDS; 393 394 /* ok */ 395 if (ppvGC) 396 *ppvGC = pvFlat; 397 return VINF_SUCCESS; 398 399 case BOTH(0,X86_SEL_TYPE_SYS_286_TSS_AVAIL): 400 case BOTH(0,X86_SEL_TYPE_SYS_LDT): 401 case BOTH(0,X86_SEL_TYPE_SYS_286_TSS_BUSY): 402 case BOTH(0,X86_SEL_TYPE_SYS_286_CALL_GATE): 403 case BOTH(0,X86_SEL_TYPE_SYS_TASK_GATE): 404 case BOTH(0,X86_SEL_TYPE_SYS_286_INT_GATE): 405 case BOTH(0,X86_SEL_TYPE_SYS_286_TRAP_GATE): 406 case BOTH(0,X86_SEL_TYPE_SYS_386_TSS_AVAIL): 407 case BOTH(0,X86_SEL_TYPE_SYS_386_TSS_BUSY): 408 case BOTH(0,X86_SEL_TYPE_SYS_386_CALL_GATE): 409 case BOTH(0,X86_SEL_TYPE_SYS_386_INT_GATE): 410 case BOTH(0,X86_SEL_TYPE_SYS_386_TRAP_GATE): 411 if (!(fFlags & SELMTOFLAT_FLAGS_NO_PL)) 412 { 413 /** @todo fix this mess */ 414 } 415 /* check limit. */ 416 if ((RTGCUINTPTR)Addr > u32Limit) 417 return VERR_OUT_OF_SELECTOR_BOUNDS; 418 /* ok */ 419 if (ppvGC) 420 *ppvGC = pvFlat; 421 return VINF_SUCCESS; 422 423 default: 424 return VERR_INVALID_SELECTOR; 425 426 } 427 #undef BOTH 428 } 429 } 430 #endif /* !IN_RING0 */ 431 return VERR_SELECTOR_NOT_PRESENT; 432 } 133 433 134 434 /** … … 149 449 * the selector. NULL is allowed. 150 450 */ 151 SELMDECL(int) SELMToFlatEx(PVM pVM, X86EFLAGS eflags, RTSEL Sel, RTGCPTR Addr, CPUMSELREGHID *pHiddenSel, unsigned fFlags, PRTGCPTR ppvGC, uint32_t *pcb) 152 { 153 Assert(!CPUMIsGuestInLongMode(pVM)); /** @todo */ 451 SELMDECL(int) SELMToFlatBySelEx(PVM pVM, X86EFLAGS eflags, RTSEL Sel, RTGCPTR Addr, CPUMSELREGHID *pHiddenSel, unsigned fFlags, PRTGCPTR ppvGC, uint32_t *pcb) 452 { 453 Assert(!CPUMIsGuestInLongMode(pVM)); /** DON'T USE! */ 454 154 455 /* 155 456 * Deal with real & v86 mode first. -
trunk/src/VBox/VMM/VMMAll/TRPMAll.cpp
r9412 r9678 555 555 || !ss_r0 556 556 || (ss_r0 & X86_SEL_RPL) != ((dpl == 0) ? 1 : dpl) 557 || SELMToFlat Ex(pVM, fakeflags, ss_r0, (RTGCPTR)esp_r0, NULL, SELMTOFLAT_FLAGS_CPL1, (PRTGCPTR)&pTrapStackGC, NULL) != VINF_SUCCESS557 || SELMToFlatBySelEx(pVM, fakeflags, ss_r0, (RTGCPTR)esp_r0, NULL, SELMTOFLAT_FLAGS_CPL1, (PRTGCPTR)&pTrapStackGC, NULL) != VINF_SUCCESS 558 558 ) 559 559 { … … 569 569 570 570 if ( eflags.Bits.u1VM /* illegal */ 571 || SELMToFlat Ex(pVM, fakeflags, ss_r0, (RTGCPTR)esp_r0, NULL, SELMTOFLAT_FLAGS_CPL1, (PRTGCPTR)&pTrapStackGC, NULL) != VINF_SUCCESS)571 || SELMToFlatBySelEx(pVM, fakeflags, ss_r0, (RTGCPTR)esp_r0, NULL, SELMTOFLAT_FLAGS_CPL1, (PRTGCPTR)&pTrapStackGC, NULL) != VINF_SUCCESS) 572 572 { 573 573 AssertMsgFailed(("Invalid stack %04X:%VRv??? (VM=%d)\n", ss_r0, esp_r0, eflags.Bits.u1VM));
Note:
See TracChangeset
for help on using the changeset viewer.

