VirtualBox

Changeset 60695 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Apr 25, 2016 5:45:33 PM (9 years ago)
Author:
vboxsync
Message:

VMM/APIC: Fuzzy saved-state generation and logging for testing compatibility. Helped find an error
with invalid TPR (invalid shift) while restoring old saved-state with the new APIC code.

Location:
trunk/src/VBox
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevAPIC.cpp

    r60307 r60695  
    5555#include <iprt/asm.h>
    5656#include <iprt/assert.h>
     57#ifdef APIC_FUZZY_SSM_COMPAT_TEST
     58# include <iprt/rand.h>
     59#endif
    5760
    5861#include <VBox/msi.h>
     
    17321735}
    17331736
     1737
     1738#ifdef APIC_FUZZY_SSM_COMPAT_TEST
     1739/**
     1740 * Helper for dumping per-VCPU APIC state to the release logger.
     1741 *
     1742 * This is primarily concerned about the APIC state relevant for saved-states.
     1743 *
     1744 * @param   pApic       The APIC state.
     1745 * @param   pszPrefix   A caller supplied prefix before dumping the state.
     1746 */
     1747static void apic_dump_state(APICState *pApic, const char *pszPrefix)
     1748{
     1749    LogRel(("APIC%u: %s\n", pApic->phys_id, pszPrefix));
     1750    LogRel(("APIC%u: uApicBaseMsr             = %#RX32\n", pApic->phys_id, pApic->apicbase));
     1751    LogRel(("APIC%u: uId                      = %#RX32\n", pApic->phys_id, pApic->id));
     1752    LogRel(("APIC%u: uPhysId                  = %#RX32\n", pApic->phys_id, pApic->phys_id));
     1753    LogRel(("APIC%u: uArbId                   = %#RX32\n", pApic->phys_id, pApic->arb_id));
     1754    LogRel(("APIC%u: uTrp                     = %#RX32\n", pApic->phys_id, pApic->tpr));
     1755    LogRel(("APIC%u: uSvr                     = %#RX32\n", pApic->phys_id, pApic->spurious_vec));
     1756    LogRel(("APIC%u: uLdr                     = %#x\n",    pApic->phys_id, pApic->log_dest));
     1757    LogRel(("APIC%u: uDfr                     = %#x\n",    pApic->phys_id, pApic->dest_mode));
     1758
     1759    for (size_t i = 0; i < 8; i++)
     1760    {
     1761        LogRel(("APIC%u: Isr[%u].u32Reg           = %#RX32\n", pApic->phys_id, i, pApic->isr.au32Bitmap[i]));
     1762        LogRel(("APIC%u: Tmr[%u].u32Reg           = %#RX32\n", pApic->phys_id, i, pApic->tmr.au32Bitmap[i]));
     1763        LogRel(("APIC%u: Irr[%u].u32Reg           = %#RX32\n", pApic->phys_id, i, pApic->irr.au32Bitmap[i]));
     1764    }
     1765
     1766    for (size_t i = 0; i < APIC_LVT_NB; i++)
     1767        LogRel(("APIC%u: Lvt[%u].u32Reg           = %#RX32\n", pApic->phys_id, i, pApic->lvt[i]));
     1768
     1769    LogRel(("APIC%u: uEsr                     = %#RX32\n", pApic->phys_id, pApic->esr));
     1770    LogRel(("APIC%u: uIcr_Lo                  = %#RX32\n", pApic->phys_id, pApic->icr[0]));
     1771    LogRel(("APIC%u: uIcr_Hi                  = %#RX32\n", pApic->phys_id, pApic->icr[1]));
     1772    LogRel(("APIC%u: uTimerDcr                = %#RX32\n", pApic->phys_id, pApic->divide_conf));
     1773    LogRel(("APIC%u: uCountShift              = %#RX32\n", pApic->phys_id, pApic->count_shift));
     1774    LogRel(("APIC%u: uInitialCount            = %#RX32\n", pApic->phys_id, pApic->initial_count));
     1775    LogRel(("APIC%u: u64InitialCountLoadTime  = %#RX64\n", pApic->phys_id, pApic->initial_count_load_time));
     1776    LogRel(("APIC%u: u64NextTime / TimerCCR   = %#RX64\n", pApic->phys_id, pApic->next_time));
     1777}
     1778
     1779
     1780/**
     1781 * Fuzzies up the APIC state with completely random bits for testing &
     1782 * validation purposes.
     1783 *
     1784 * @param   pApic       The APIC state.
     1785 * @remarks Warning! This should ONLY be used for diagnostics, otherwise will
     1786 *          corrupt saved-states and may result in loss of data!
     1787 */
     1788static void apic_fuzz_state(APICState *pApic)
     1789{
     1790    pApic->apicbase     = RTRandU32();
     1791    pApic->id           = RTRandU32();
     1792    pApic->phys_id      = RTRandU32();
     1793    pApic->arb_id       = RTRandU32();
     1794    pApic->tpr          = RTRandU32();
     1795    pApic->spurious_vec = RTRandU32();
     1796    pApic->log_dest     = RTRandU32();
     1797    pApic->dest_mode    = RTRandU32();
     1798
     1799    for (size_t i = 0; i < 8; i++)
     1800    {
     1801        pApic->isr.au32Bitmap[i] = RTRandU32();
     1802        pApic->tmr.au32Bitmap[i] = RTRandU32();
     1803        pApic->irr.au32Bitmap[i] = RTRandU32();
     1804    }
     1805
     1806    for (size_t i = 0; i < APIC_LVT_NB; i++)
     1807        pApic->lvt[i] = RTRandU32();
     1808
     1809    pApic->esr         = RTRandU32();
     1810    pApic->icr[0]      = RTRandU32();
     1811    pApic->icr[1]      = RTRandU32();
     1812    pApic->divide_conf = RTRandU32();
     1813
     1814    int v = (pApic->divide_conf & 3) | ((pApic->divide_conf >> 1) & 4);
     1815    pApic->count_shift = (v + 1) & 7;
     1816
     1817    pApic->initial_count           = RTRandU32();
     1818    pApic->initial_count_load_time = RTRandU64();
     1819    pApic->next_time = pApic->initial_count_load_time;
     1820}
     1821#endif  /* APIC_FUZZY_SSM_COMPAT_TEST */
     1822
     1823
    17341824static void apic_save(SSMHANDLE* f, void *opaque)
    17351825{
    17361826    APICState *pApic = (APICState*)opaque;
    17371827    int i;
     1828
     1829#ifdef APIC_FUZZY_SSM_COMPAT_TEST
     1830#error "Fuzzying state is purely for testing. Remove this manually and proceed at your own risk!"
     1831    APICState *pOriginal = pApic;
     1832    APICState FuzzedApic;
     1833    apic_fuzz_state(&FuzzedApic);
     1834    pApic = &FuzzedApic;
     1835    pApic->phys_id = pOriginal->phys_id;
     1836#endif
    17381837
    17391838    SSMR3PutU32(f, pApic->apicbase);
     
    17611860    SSMR3PutU64(f, pApic->initial_count_load_time);
    17621861    SSMR3PutU64(f, pApic->next_time);
     1862
     1863#ifdef APIC_FUZZY_SSM_COMPAT_TEST
     1864    apic_dump_state(pApic, "Saved state:");
     1865    pApic = pOriginal;
     1866#endif
    17631867
    17641868    TMR3TimerSave(pApic->CTX_SUFF(pTimer), f);
  • trunk/src/VBox/VMM/VMMR3/APIC.cpp

    r60689 r60695  
    632632
    633633
    634 #ifdef DEBUG_ramshankar
     634#ifdef APIC_FUZZY_SSM_COMPAT_TEST
     635/**
     636 * Reads a 32-bit register at a specified offset.
     637 *
     638 * @returns The value at the specified offset.
     639 * @param   pXApicPage      The xAPIC page.
     640 * @param   offReg          The offset of the register being read.
     641 *
     642 * @remarks Duplicate of apicReadRaw32()!
     643 */
     644static uint32_t apicR3ReadRawR32(PCXAPICPAGE pXApicPage, uint16_t offReg)
     645{
     646    Assert(offReg < sizeof(*pXApicPage) - sizeof(uint32_t));
     647    uint8_t  const *pbXApic =  (const uint8_t *)pXApicPage;
     648    uint32_t const  uValue  = *(const uint32_t *)(pbXApic + offReg);
     649    return uValue;
     650}
     651
     652
    635653/**
    636654 * Helper for dumping per-VCPU APIC state to the release logger.
     
    640658 * @param   pVCpu       The cross context virtual CPU structure.
    641659 * @param   pszPrefix   A caller supplied prefix before dumping the state.
    642  */
    643 static void apicR3DumpState(PVMCPU pVCpu, const char *pszPrefix)
     660 * @param   uVersion    Data layout version.
     661 */
     662static void apicR3DumpState(PVMCPU pVCpu, const char *pszPrefix, uint32_t uVersion)
    644663{
    645664    PCAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
    646665
    647     /* The auxiliary state. */
    648     LogRel(("APIC%u: %s\n", pVCpu->idCpu, pszPrefix));
    649     LogRel(("APIC%u: uApicBaseMsr             = %#RX64\n", pVCpu->idCpu, pApicCpu->uApicBaseMsr));
    650     LogRel(("APIC%u: uEsrInternal             = %#RX64\n", pVCpu->idCpu, pApicCpu->uEsrInternal));
    651 
    652     /* The timer. */
    653     LogRel(("APIC%u: u64TimerInitial          = %#RU64\n", pVCpu->idCpu, pApicCpu->u64TimerInitial));
    654     LogRel(("APIC%u: uHintedTimerInitialCount = %#RU64\n", pVCpu->idCpu, pApicCpu->uHintedTimerInitialCount));
    655     LogRel(("APIC%u: uHintedTimerShift        = %#RU64\n", pVCpu->idCpu, pApicCpu->uHintedTimerShift));
    656 
    657     PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu);
    658     LogRel(("APIC%u: uTimerICR                = %#RX32\n", pVCpu->idCpu, pXApicPage->timer_icr.u32InitialCount));
    659     LogRel(("APIC%u: uTimerCCR                = %#RX32\n", pVCpu->idCpu, pXApicPage->timer_ccr.u32CurrentCount));
    660 
    661     /* The PIBs. */
    662     LogRel(("APIC%u: Edge PIB : %.*Rhxs\n", pVCpu->idCpu, sizeof(APICPIB), pApicCpu->pvApicPibR3));
    663     LogRel(("APIC%u: Level PIB: %.*Rhxs\n", pVCpu->idCpu, sizeof(APICPIB), &pApicCpu->ApicPibLevel));
    664 
    665     /* The APIC page. */
    666     LogRel(("APIC%u: APIC page: %.*Rhxs\n", pVCpu->idCpu, sizeof(XAPICPAGE), pApicCpu->pvApicPageR3));
    667 }
    668 #endif
     666    LogRel(("APIC%u: %s (version %u):\n", pVCpu->idCpu, pszPrefix, uVersion));
     667
     668    switch (uVersion)
     669    {
     670        case APIC_SAVED_STATE_VERSION:
     671        {
     672            /* The auxiliary state. */
     673            LogRel(("APIC%u: uApicBaseMsr             = %#RX64\n", pVCpu->idCpu, pApicCpu->uApicBaseMsr));
     674            LogRel(("APIC%u: uEsrInternal             = %#RX64\n", pVCpu->idCpu, pApicCpu->uEsrInternal));
     675
     676            /* The timer. */
     677            LogRel(("APIC%u: u64TimerInitial          = %#RU64\n", pVCpu->idCpu, pApicCpu->u64TimerInitial));
     678            LogRel(("APIC%u: uHintedTimerInitialCount = %#RU64\n", pVCpu->idCpu, pApicCpu->uHintedTimerInitialCount));
     679            LogRel(("APIC%u: uHintedTimerShift        = %#RU64\n", pVCpu->idCpu, pApicCpu->uHintedTimerShift));
     680
     681            PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu);
     682            LogRel(("APIC%u: uTimerICR                = %#RX32\n", pVCpu->idCpu, pXApicPage->timer_icr.u32InitialCount));
     683            LogRel(("APIC%u: uTimerCCR                = %#RX32\n", pVCpu->idCpu, pXApicPage->timer_ccr.u32CurrentCount));
     684
     685            /* The PIBs. */
     686            LogRel(("APIC%u: Edge PIB : %.*Rhxs\n", pVCpu->idCpu, sizeof(APICPIB), pApicCpu->pvApicPibR3));
     687            LogRel(("APIC%u: Level PIB: %.*Rhxs\n", pVCpu->idCpu, sizeof(APICPIB), &pApicCpu->ApicPibLevel));
     688
     689            /* The APIC page. */
     690            LogRel(("APIC%u: APIC page: %.*Rhxs\n", pVCpu->idCpu, sizeof(XAPICPAGE), pApicCpu->pvApicPageR3));
     691            break;
     692        }
     693
     694        case APIC_SAVED_STATE_VERSION_VBOX_50:
     695        case APIC_SAVED_STATE_VERSION_VBOX_30:
     696        case APIC_SAVED_STATE_VERSION_ANCIENT:
     697        {
     698            PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu);
     699            LogRel(("APIC%u: uApicBaseMsr             = %#RX32\n", pVCpu->idCpu, RT_LO_U32(pApicCpu->uApicBaseMsr)));
     700            LogRel(("APIC%u: uId                      = %#RX32\n", pVCpu->idCpu, pXApicPage->id.u8ApicId));
     701            LogRel(("APIC%u: uPhysId                  = N/A\n",    pVCpu->idCpu));
     702            LogRel(("APIC%u: uArbId                   = N/A\n",    pVCpu->idCpu));
     703            LogRel(("APIC%u: uTrp                     = %#RX32\n", pVCpu->idCpu, pXApicPage->tpr.u8Tpr));
     704            LogRel(("APIC%u: uSvr                     = %#RX32\n", pVCpu->idCpu, pXApicPage->svr.all.u32Svr));
     705            LogRel(("APIC%u: uLdr                     = %#x\n",    pVCpu->idCpu, pXApicPage->ldr.all.u32Ldr));
     706            LogRel(("APIC%u: uDfr                     = %#x\n",    pVCpu->idCpu, pXApicPage->dfr.all.u32Dfr));
     707
     708            for (size_t i = 0; i < 8; i++)
     709            {
     710                LogRel(("APIC%u: Isr[%u].u32Reg           = %#RX32\n", pVCpu->idCpu, i, pXApicPage->isr.u[i].u32Reg));
     711                LogRel(("APIC%u: Tmr[%u].u32Reg           = %#RX32\n", pVCpu->idCpu, i, pXApicPage->tmr.u[i].u32Reg));
     712                LogRel(("APIC%u: Irr[%u].u32Reg           = %#RX32\n", pVCpu->idCpu, i, pXApicPage->irr.u[i].u32Reg));
     713            }
     714
     715            for (size_t i = 0; i < XAPIC_MAX_LVT_ENTRIES_P4; i++)
     716            {
     717                uint16_t const offReg = XAPIC_OFF_LVT_START + (i << 4);
     718                LogRel(("APIC%u: Lvt[%u].u32Reg           = %#RX32\n", pVCpu->idCpu, i, apicR3ReadRawR32(pXApicPage, offReg)));
     719            }
     720
     721            LogRel(("APIC%u: uEsr                     = %#RX32\n", pVCpu->idCpu, pXApicPage->esr.all.u32Errors));
     722            LogRel(("APIC%u: uIcr_Lo                  = %#RX32\n", pVCpu->idCpu, pXApicPage->icr_lo.all.u32IcrLo));
     723            LogRel(("APIC%u: uIcr_Hi                  = %#RX32\n", pVCpu->idCpu, pXApicPage->icr_hi.all.u32IcrHi));
     724            LogRel(("APIC%u: uTimerDcr                = %#RX32\n", pVCpu->idCpu, pXApicPage->timer_dcr.all.u32DivideValue));
     725            LogRel(("APIC%u: uCountShift              = %#RX32\n", pVCpu->idCpu, apicGetTimerShift(pXApicPage)));
     726            LogRel(("APIC%u: uInitialCount            = %#RX32\n", pVCpu->idCpu, pXApicPage->timer_icr.u32InitialCount));
     727            LogRel(("APIC%u: u64InitialCountLoadTime  = %#RX64\n", pVCpu->idCpu, pApicCpu->u64TimerInitial));
     728            LogRel(("APIC%u: u64NextTime / TimerCCR   = %#RX64\n", pVCpu->idCpu, pXApicPage->timer_ccr.u32CurrentCount));
     729            break;
     730        }
     731
     732        default:
     733        {
     734            LogRel(("APIC: apicR3DumpState: Invalid/unrecognized saved-state version %u (%#x)\n", uVersion, uVersion));
     735            break;
     736        }
     737    }
     738}
     739#endif  /* APIC_FUZZY_SSM_COMPAT_TEST */
    669740
    670741
     
    771842    uint32_t u32Tpr;
    772843    SSMR3GetU32(pSSM, &u32Tpr);
    773     pXApicPage->tpr.u8Tpr = XAPIC_TPR_GET_TPR_FROM_U32(u32Tpr);
     844    pXApicPage->tpr.u8Tpr = u32Tpr & XAPIC_TPR;
    774845
    775846    SSMR3GetU32(pSSM, &pXApicPage->svr.all.u32Svr);
     
    886957        TMR3TimerSave(pApicCpu->pTimerR3, pSSM);
    887958
    888 #ifdef DEBUG_ramshankar
    889         apicR3DumpState(pVCpu, "Saved state:");
     959#if defined(APIC_FUZZY_SSM_COMPAT_TEST) || defined(DEBUG_ramshankar)
     960        apicR3DumpState(pVCpu, "Saved state", APIC_SAVED_STATE_VERSION);
    890961#endif
    891962    }
    892963
     964#ifdef APIC_FUZZY_SSM_COMPAT_TEST
     965    /* The state is fuzzy, don't even bother trying to load the guest. */
     966    return VERR_INVALID_STATE;
     967#else
    893968    return rc;
     969#endif
    894970}
    895971
     
    9691045        }
    9701046
    971 #ifdef DEBUG_ramshankar
    972         char szLoadedState[128];
    973         RTStrPrintf(szLoadedState, sizeof(szLoadedState), "Loaded state (version %u):", uVersion);
    974         apicR3DumpState(pVCpu, &szLoadedState[0]);
     1047#if defined(APIC_FUZZY_SSM_COMPAT_TEST) || defined(DEBUG_ramshankar)
     1048        apicR3DumpState(pVCpu, "Loaded state", uVersion);
    9751049#endif
    9761050    }
  • trunk/src/VBox/VMM/include/APICInternal.h

    r60689 r60695  
    113113/** TPR - Gets the task-priority subclass. */
    114114#define XAPIC_TPR_GET_TP_SUBCLASS(a_Tpr)     ((a_Tpr) & XAPIC_TPR_TP_SUBCLASS)
    115 /** TPR - Gets the TPR from its 32-bit register. */
    116 #define XAPIC_TPR_GET_TPR_FROM_U32(a_32Tpr)  (((a_32Tpr) >> 24) & XAPIC_TPR)
    117115
    118116/** PPR - Valid bits. */
Note: See TracChangeset for help on using the changeset viewer.

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