VirtualBox

Changeset 48221 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Sep 1, 2013 11:27:56 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
88611
Message:

VMM: Adding a debugging aid for 64-on-32 that tries to catch exceptions on the otherwordly context. Set VBOX_WITH_64ON32_IDT in LocalConfig.kmk to enable.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/VMMSwitcher.cpp

    r45786 r48221  
    134134
    135135
     136# ifdef VBOX_WITH_64ON32_IDT
     137/**
     138 * Initializes the 64-bit IDT for 64-bit guest on 32-bit host switchers.
     139 *
     140 * This is only used as a debugging aid when we cannot find out why something
     141 * goes haywire in the intermediate context.
     142 *
     143 * @param   pVM         The cross context VM structure.
     144 * @param   pSwitcher   The switcher descriptor.
     145 * @param   pbDst       Where the switcher code was just copied.
     146 * @param   HCPhysDst   The host physical address corresponding to @a pbDst.
     147 */
     148static void vmmR3Switcher32On64IdtInit(PVM pVM, PVMMSWITCHERDEF pSwitcher, uint8_t *pbDst, RTHCPHYS HCPhysDst)
     149{
     150    AssertRelease(pSwitcher->offGCCode > 0 && pSwitcher->offGCCode < pSwitcher->cbCode);
     151    AssertRelease(pSwitcher->cbCode < _64K);
     152    RTSEL uCs64 = SELMGetHyperCS64(pVM);
     153
     154    PX86DESC64GATE paIdt = (PX86DESC64GATE)(pbDst + pSwitcher->offGCCode);
     155    for (uint32_t i = 0 ; i < 256; i++)
     156    {
     157        AssertRelease(((uint64_t *)&paIdt[i])[0] < pSwitcher->cbCode);
     158        AssertRelease(((uint64_t *)&paIdt[i])[1] == 0);
     159        uint64_t uHandler = HCPhysDst + paIdt[i].u16OffsetLow;
     160        paIdt[i].u16OffsetLow   = (uint16_t)uHandler;
     161        paIdt[i].u16Sel         = uCs64;
     162        paIdt[i].u3IST          = 0;
     163        paIdt[i].u5Reserved     = 0;
     164        paIdt[i].u4Type         = AMD64_SEL_TYPE_SYS_INT_GATE;
     165        paIdt[i].u1DescType     = 0 /* system */;
     166        paIdt[i].u2Dpl          = 3;
     167        paIdt[i].u1Present      = 1;
     168        paIdt[i].u16OffsetHigh  = (uint16_t)(uHandler >> 16);
     169        paIdt[i].u32Reserved    = (uint32_t)(uHandler >> 32);
     170    }
     171
     172    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
     173    {
     174        uint64_t uIdtr = HCPhysDst + pSwitcher->offGCCode; AssertRelease(uIdtr < UINT32_MAX);
     175        CPUMSetHyperIDTR(&pVM->aCpus[iCpu], uIdtr, 16*256 + iCpu);
     176    }
     177}
     178
     179
     180/**
     181 * Relocates the 64-bit IDT for 64-bit guest on 32-bit host switchers.
     182 *
     183 * @param   pVM         The cross context VM structure.
     184 * @param   pSwitcher   The switcher descriptor.
     185 * @param   pbDst       Where the switcher code was just copied.
     186 * @param   HCPhysDst   The host physical address corresponding to @a pbDst.
     187 */
     188static void vmmR3Switcher32On64IdtRelocate(PVM pVM, PVMMSWITCHERDEF pSwitcher, uint8_t *pbDst, RTHCPHYS HCPhysDst)
     189{
     190    AssertRelease(pSwitcher->offGCCode > 0 && pSwitcher->offGCCode < pSwitcher->cbCode && pSwitcher->cbCode < _64K);
     191
     192    /* The intermediate context doesn't move, but the CS may. */
     193    RTSEL uCs64 = SELMGetHyperCS64(pVM);
     194    PX86DESC64GATE paIdt = (PX86DESC64GATE)(pbDst + pSwitcher->offGCCode);
     195    for (uint32_t i = 0 ; i < 256; i++)
     196        paIdt[i].u16Sel = uCs64;
     197
     198    /* Just in case... */
     199    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
     200    {
     201        uint64_t uIdtr = HCPhysDst + pSwitcher->offGCCode; AssertRelease(uIdtr < UINT32_MAX);
     202        CPUMSetHyperIDTR(&pVM->aCpus[iCpu], uIdtr, 16*256 + iCpu);
     203    }
     204}
     205# endif /* VBOX_WITH_64ON32_IDT */
     206
     207
    136208/**
    137209 * VMMR3Init worker that initiates the switcher code (aka core code).
     
    225297    {
    226298        /*
    227          * copy the code.
     299         * Copy the code.
    228300         */
    229301        for (unsigned iSwitcher = 0; iSwitcher < VMMSWITCHER_MAX; iSwitcher++)
     
    231303            PVMMSWITCHERDEF pSwitcher = papSwitchers[iSwitcher];
    232304            if (pSwitcher)
    233                 memcpy((uint8_t *)pVM->vmm.s.pvCoreCodeR3 + pVM->vmm.s.aoffSwitchers[iSwitcher],
    234                        pSwitcher->pvCode, pSwitcher->cbCode);
     305            {
     306                uint8_t *pbDst = (uint8_t *)pVM->vmm.s.pvCoreCodeR3 + pVM->vmm.s.aoffSwitchers[iSwitcher];
     307                memcpy(pbDst, pSwitcher->pvCode, pSwitcher->cbCode);
     308# ifdef VBOX_WITH_64ON32_IDT
     309                if (   pSwitcher->enmType == VMMSWITCHER_32_TO_AMD64
     310                    || pSwitcher->enmType == VMMSWITCHER_PAE_TO_AMD64)
     311                    vmmR3Switcher32On64IdtInit(pVM, pSwitcher, pbDst,
     312                                               pVM->vmm.s.HCPhysCoreCode + pVM->vmm.s.aoffSwitchers[iSwitcher]);
     313# endif
     314            }
    235315        }
    236316
     
    299379                                   pVM->vmm.s.pvCoreCodeRC + off,
    300380                                   pVM->vmm.s.HCPhysCoreCode + off);
     381# ifdef VBOX_WITH_64ON32_IDT
     382            if (   pSwitcher->enmType == VMMSWITCHER_32_TO_AMD64
     383                || pSwitcher->enmType == VMMSWITCHER_PAE_TO_AMD64)
     384                vmmR3Switcher32On64IdtRelocate(pVM, pSwitcher,
     385                                               (uint8_t *)pVM->vmm.s.pvCoreCodeR3 + off,
     386                                               pVM->vmm.s.HCPhysCoreCode + off);
     387# endif
    301388        }
    302389    }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette