~ubuntu-branches/ubuntu/trusty/virtualbox-ose/trusty

« back to all changes in this revision

Viewing changes to src/VBox/VMM/PATM/CSAM.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2009-12-18 16:44:29 UTC
  • mfrom: (0.3.3 upstream) (0.4.6 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091218164429-jd34ccexpv5na11a
Tags: 3.1.2-dfsg-1ubuntu1
* Merge from Debian unstable (LP: #498219), remaining changes:
  - Disable update action
    - debian/patches/u01-disable-update-action.dpatch
  - VirtualBox should go in Accessories, not in System tools (LP: #288590)
    - debian/virtualbox-ose-qt.files/virtualbox-ose.desktop
  - Add Apport hook
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Add Launchpad integration
    - debian/control
    - debian/lpi-bug.xpm
    - debian/patches/u02-lp-integration.dpatch
* Fixes the following bugs:
  - Kernel module fails to build with Linux >= 2.6.32 (LP: #474625)
  - X.Org drivers need to be rebuilt against X-Server 1.7 (LP: #495935)
  - The *-source packages try to build the kernel modules even though the
    kernel headers aren't available (LP: #473334)
* Replace *-source packages with transitional packages for *-dkms.
* Adapt u01-disable-update-action.dpatch and u02-lp-integration.dpatch for
  new upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
69
69
*   Internal Functions                                                         *
70
70
*******************************************************************************/
71
71
static DECLCALLBACK(int) csamr3Save(PVM pVM, PSSMHANDLE pSSM);
72
 
static DECLCALLBACK(int) csamr3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t u32Version);
 
72
static DECLCALLBACK(int) csamr3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
73
73
static DECLCALLBACK(int) CSAMCodePageWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
74
74
static DECLCALLBACK(int) CSAMCodePageInvalidate(PVM pVM, RTGCPTR GCPtr);
75
75
 
101
101
};
102
102
#endif
103
103
 
 
104
/**
 
105
 * SSM descriptor table for the CSAM structure.
 
106
 */
 
107
static const SSMFIELD g_aCsamFields[] =
 
108
{
 
109
    /** @todo there are more fields that can be ignored here. */
 
110
    SSMFIELD_ENTRY_IGNORE(      CSAM, offVM),
 
111
    SSMFIELD_ENTRY_PAD_HC64(    CSAM, Alignment0, sizeof(uint32_t)),
 
112
    SSMFIELD_ENTRY_IGN_HCPTR(   CSAM, pPageTree),
 
113
    SSMFIELD_ENTRY(             CSAM, aDangerousInstr),
 
114
    SSMFIELD_ENTRY(             CSAM, cDangerousInstr),
 
115
    SSMFIELD_ENTRY(             CSAM, iDangerousInstr),
 
116
    SSMFIELD_ENTRY_RCPTR(       CSAM, pPDBitmapGC),   /// @todo ignore this?
 
117
    SSMFIELD_ENTRY_RCPTR(       CSAM, pPDHCBitmapGC), /// @todo ignore this?
 
118
    SSMFIELD_ENTRY_IGN_HCPTR(   CSAM, pPDBitmapHC),
 
119
    SSMFIELD_ENTRY_IGN_HCPTR(   CSAM, pPDGCBitmapHC),
 
120
    SSMFIELD_ENTRY_IGN_HCPTR(   CSAM, savedstate.pSSM),
 
121
    SSMFIELD_ENTRY(             CSAM, savedstate.cPageRecords),
 
122
    SSMFIELD_ENTRY(             CSAM, savedstate.cPatchPageRecords),
 
123
    SSMFIELD_ENTRY(             CSAM, cDirtyPages),
 
124
    SSMFIELD_ENTRY_RCPTR_ARRAY( CSAM, pvDirtyBasePage),
 
125
    SSMFIELD_ENTRY_RCPTR_ARRAY( CSAM, pvDirtyFaultPage),
 
126
    SSMFIELD_ENTRY(             CSAM, cPossibleCodePages),
 
127
    SSMFIELD_ENTRY_RCPTR_ARRAY( CSAM, pvPossibleCodePage),
 
128
    SSMFIELD_ENTRY_RCPTR_ARRAY( CSAM, pvCallInstruction),
 
129
    SSMFIELD_ENTRY(             CSAM, iCallInstruction),
 
130
    SSMFIELD_ENTRY(             CSAM, fScanningStarted),
 
131
    SSMFIELD_ENTRY(             CSAM, fGatesChecked),
 
132
    SSMFIELD_ENTRY_PAD_HC(      CSAM, Alignment1, 6, 2),
 
133
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrTraps),
 
134
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrPages),
 
135
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrPagesInv),
 
136
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrRemovedPages),
 
137
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrPatchPages),
 
138
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrPageNPHC),
 
139
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrPageNPGC),
 
140
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrFlushes),
 
141
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrFlushesSkipped),
 
142
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrKnownPagesHC),
 
143
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrKnownPagesGC),
 
144
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrInstr),
 
145
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrBytesRead),
 
146
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrOpcodeRead),
 
147
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatTime),
 
148
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatTimeCheckAddr),
 
149
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatTimeAddrConv),
 
150
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatTimeFlushPage),
 
151
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatTimeDisasm),
 
152
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatFlushDirtyPages),
 
153
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatCheckGates),
 
154
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatCodePageModified),
 
155
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatDangerousWrite),
 
156
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatInstrCacheHit),
 
157
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatInstrCacheMiss),
 
158
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatPagePATM),
 
159
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatPageCSAM),
 
160
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatPageREM),
 
161
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatNrUserPages),
 
162
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatPageMonitor),
 
163
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatPageRemoveREMFlush),
 
164
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatBitmapAlloc),
 
165
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatScanNextFunction),
 
166
    SSMFIELD_ENTRY_IGNORE(      CSAM, StatScanNextFunctionFailed),
 
167
    SSMFIELD_ENTRY_TERM()
 
168
};
 
169
 
 
170
/** Fake type to simplify g_aCsamPDBitmapArray construction. */
 
171
typedef struct
 
172
{
 
173
    uint8_t *a[CSAM_PGDIRBMP_CHUNKS];
 
174
} CSAMPDBITMAPARRAY;
 
175
 
 
176
/**
 
177
 * SSM descriptor table for the CSAM::pPDBitmapHC array.
 
178
 */
 
179
static SSMFIELD const g_aCsamPDBitmapArray[] =
 
180
{
 
181
    SSMFIELD_ENTRY_HCPTR_NI_ARRAY(CSAMPDBITMAPARRAY, a),
 
182
    SSMFIELD_ENTRY_TERM()
 
183
};
 
184
 
 
185
/**
 
186
 * SSM descriptor table for the CSAMPAGEREC structure.
 
187
 */
 
188
static const SSMFIELD g_aCsamPageRecFields[] =
 
189
{
 
190
    SSMFIELD_ENTRY_IGN_HCPTR(   CSAMPAGEREC, Core.Key),
 
191
    SSMFIELD_ENTRY_IGN_HCPTR(   CSAMPAGEREC, Core.pLeft),
 
192
    SSMFIELD_ENTRY_IGN_HCPTR(   CSAMPAGEREC, Core.pRight),
 
193
    SSMFIELD_ENTRY_IGNORE(      CSAMPAGEREC, Core.uchHeight),
 
194
    SSMFIELD_ENTRY_PAD_HC_AUTO( 3, 7),
 
195
    SSMFIELD_ENTRY_RCPTR(       CSAMPAGEREC, page.pPageGC),
 
196
    SSMFIELD_ENTRY_PAD_HC_AUTO( 0, 4),
 
197
    SSMFIELD_ENTRY_PAD_MSC32_AUTO( 4),
 
198
    SSMFIELD_ENTRY_GCPHYS(      CSAMPAGEREC, page.GCPhys),
 
199
    SSMFIELD_ENTRY(             CSAMPAGEREC, page.fFlags),
 
200
    SSMFIELD_ENTRY(             CSAMPAGEREC, page.uSize),
 
201
    SSMFIELD_ENTRY_PAD_HC_AUTO( 0, 4),
 
202
    SSMFIELD_ENTRY_HCPTR_NI(    CSAMPAGEREC, page.pBitmap),
 
203
    SSMFIELD_ENTRY(             CSAMPAGEREC, page.fCode32),
 
204
    SSMFIELD_ENTRY(             CSAMPAGEREC, page.fMonitorActive),
 
205
    SSMFIELD_ENTRY(             CSAMPAGEREC, page.fMonitorInvalidation),
 
206
    SSMFIELD_ENTRY_PAD_HC_AUTO( 1, 1),
 
207
    SSMFIELD_ENTRY(             CSAMPAGEREC, page.enmTag),
 
208
    SSMFIELD_ENTRY(             CSAMPAGEREC, page.u64Hash),
 
209
    SSMFIELD_ENTRY_TERM()
 
210
};
 
211
 
104
212
 
105
213
/**
106
214
 * Initializes the CSAM.
129
237
     * Register save and load state notificators.
130
238
     */
131
239
    rc = SSMR3RegisterInternal(pVM, "CSAM", 0, CSAM_SSM_VERSION, sizeof(pVM->csam.s) + PAGE_SIZE*16,
 
240
                               NULL, NULL, NULL,
132
241
                               NULL, csamr3Save, NULL,
133
242
                               NULL, csamr3Load, NULL);
134
243
    AssertRCReturn(rc, rc);
338
447
    return VINF_SUCCESS;
339
448
}
340
449
 
341
 
#define CSAM_SUBTRACT_PTR(a, b) *(uintptr_t *)&(a) = (uintptr_t)(a) - (uintptr_t)(b)
342
 
#define CSAM_ADD_PTR(a, b)      *(uintptr_t *)&(a) = (uintptr_t)(a) + (uintptr_t)(b)
343
 
 
344
450
 
345
451
/**
346
452
 * Callback function for RTAvlPVDoWithAll
442
548
 * @returns VBox status code.
443
549
 * @param   pVM             VM Handle.
444
550
 * @param   pSSM            SSM operation handle.
445
 
 * @param   u32Version      Data layout version.
 
551
 * @param   uVersion        Data layout version.
 
552
 * @param   uPass           The data pass.
446
553
 */
447
 
static DECLCALLBACK(int) csamr3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t u32Version)
 
554
static DECLCALLBACK(int) csamr3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
448
555
{
449
556
    int  rc;
450
557
    CSAM csamInfo;
451
558
 
452
 
    if (u32Version != CSAM_SSM_VERSION)
 
559
    Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
 
560
    if (uVersion != CSAM_SSM_VERSION)
453
561
    {
454
 
        AssertMsgFailed(("csamR3Load: Invalid version u32Version=%d!\n", u32Version));
 
562
        AssertMsgFailed(("csamR3Load: Invalid version uVersion=%d!\n", uVersion));
455
563
        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
456
564
    }
457
565
 
460
568
    /*
461
569
     * Restore CSAM structure
462
570
     */
 
571
#if 0
463
572
    rc = SSMR3GetMem(pSSM, &csamInfo, sizeof(csamInfo));
 
573
#else
 
574
    RT_ZERO(csamInfo);
 
575
    rc = SSMR3GetStructEx(pSSM, &csamInfo, sizeof(csamInfo), SSMSTRUCT_FLAGS_MEM_BAND_AID, &g_aCsamFields[0], NULL);
 
576
#endif
464
577
    AssertRCReturn(rc, rc);
465
578
 
466
579
    pVM->csam.s.fGatesChecked    = csamInfo.fGatesChecked;
476
589
    memcpy(pVM->csam.s.pvPossibleCodePage,  csamInfo.pvPossibleCodePage, sizeof(pVM->csam.s.pvPossibleCodePage));
477
590
 
478
591
    /* Restore pgdir bitmap (we'll change the pointers next). */
 
592
#if 0
479
593
    rc = SSMR3GetMem(pSSM, pVM->csam.s.pPDBitmapHC, CSAM_PGDIRBMP_CHUNKS*sizeof(RTHCPTR));
 
594
#else
 
595
    rc = SSMR3GetStructEx(pSSM, pVM->csam.s.pPDBitmapHC, sizeof(uint8_t *) * CSAM_PGDIRBMP_CHUNKS,
 
596
                          SSMSTRUCT_FLAGS_MEM_BAND_AID, &g_aCsamPDBitmapArray[0], NULL);
 
597
#endif
480
598
    AssertRCReturn(rc, rc);
481
599
 
482
600
    /*
515
633
        CSAMPAGEREC  page;
516
634
        PCSAMPAGE    pPage;
517
635
 
 
636
#if 0
518
637
        rc = SSMR3GetMem(pSSM, &page, sizeof(page));
 
638
#else
 
639
        RT_ZERO(page);
 
640
        rc = SSMR3GetStructEx(pSSM, &page, sizeof(page), SSMSTRUCT_FLAGS_MEM_BAND_AID, &g_aCsamPageRecFields[0], NULL);
 
641
#endif
519
642
        AssertRCReturn(rc, rc);
520
643
 
521
644
        /*
540
663
        }
541
664
    }
542
665
 
543
 
    /** @note we don't restore aDangerousInstr; it will be recreated automatically. */
 
666
    /* Note: we don't restore aDangerousInstr; it will be recreated automatically. */
544
667
    memset(&pVM->csam.s.aDangerousInstr, 0, sizeof(pVM->csam.s.aDangerousInstr));
545
668
    pVM->csam.s.cDangerousInstr = 0;
546
669
    pVM->csam.s.iDangerousInstr  = 0;
562
685
{
563
686
    int rc;
564
687
    R3PTRTYPE(void *) pHCPtr;
565
 
    Assert(pVM->cCPUs == 1);
 
688
    Assert(pVM->cCpus == 1);
566
689
    PVMCPU pVCpu = VMMGetCpu0(pVM);
567
690
 
568
691
    STAM_PROFILE_START(&pVM->csam.s.StatTimeAddrConv, a);
611
734
    RTHCUINTPTR   pInstrHC = (RTHCUINTPTR)pCpu->apvUserData[1];
612
735
    RTGCUINTPTR32 pInstrGC = (uintptr_t)pCpu->apvUserData[2];
613
736
    int           orgsize  = size;
614
 
    Assert(pVM->cCPUs == 1);
 
737
    Assert(pVM->cCpus == 1);
615
738
    PVMCPU        pVCpu = VMMGetCpu0(pVM);
616
739
 
617
740
    /* We are not interested in patched instructions, so read the original opcode bytes. */
1086
1209
    uint32_t opsize;
1087
1210
    R3PTRTYPE(uint8_t *) pCurInstrHC = 0;
1088
1211
    int rc2;
1089
 
    Assert(pVM->cCPUs == 1);
 
1212
    Assert(pVM->cCpus == 1);
1090
1213
    PVMCPU pVCpu = VMMGetCpu0(pVM);
1091
1214
 
1092
1215
#ifdef DEBUG
1362
1485
    uint64_t hash   = 0;
1363
1486
    uint32_t val[5];
1364
1487
    int      rc;
1365
 
    Assert(pVM->cCPUs == 1);
 
1488
    Assert(pVM->cCpus == 1);
1366
1489
    PVMCPU pVCpu = VMMGetCpu0(pVM);
1367
1490
 
1368
1491
    Assert((pInstr & PAGE_OFFSET_MASK) == 0);
1430
1553
    int rc;
1431
1554
    RTGCPHYS GCPhys = 0;
1432
1555
    uint64_t fFlags = 0;
1433
 
    Assert(pVM->cCPUs == 1 || !CSAMIsEnabled(pVM));
 
1556
    Assert(pVM->cCpus == 1 || !CSAMIsEnabled(pVM));
1434
1557
 
1435
1558
    if (!CSAMIsEnabled(pVM))
1436
1559
        return VINF_SUCCESS;
1623
1746
    PCSAMPAGEREC pPage;
1624
1747
    int          rc;
1625
1748
    bool         ret;
1626
 
    Assert(pVM->cCPUs == 1);
 
1749
    Assert(pVM->cCpus == 1);
1627
1750
    PVMCPU pVCpu = VMMGetCpu0(pVM);
1628
1751
 
1629
1752
    Log(("New page record for %RRv\n", GCPtr & PAGE_BASE_GC_MASK));
1726
1849
    PCSAMPAGEREC pPageRec = NULL;
1727
1850
    int          rc;
1728
1851
    bool         fMonitorInvalidation;
1729
 
    Assert(pVM->cCPUs == 1);
 
1852
    Assert(pVM->cCpus == 1);
1730
1853
    PVMCPU pVCpu = VMMGetCpu0(pVM);
1731
1854
 
1732
1855
    /* Dirty pages must be handled before calling this function!. */
1872
1995
static int csamRemovePageRecord(PVM pVM, RTRCPTR GCPtr)
1873
1996
{
1874
1997
    PCSAMPAGEREC pPageRec;
1875
 
    Assert(pVM->cCPUs == 1);
 
1998
    Assert(pVM->cCpus == 1);
1876
1999
    PVMCPU pVCpu = VMMGetCpu0(pVM);
1877
2000
 
1878
2001
    Log(("csamRemovePageRecord %RRv\n", GCPtr));
1981
2104
         */
1982
2105
        Log(("CSAMCodePageWriteHandler: delayed write!\n"));
1983
2106
        AssertCompileSize(RTRCPTR, 4);
1984
 
        rc = VMR3ReqCallEx(pVM, VMCPUID_ANY, NULL, 0, VMREQFLAGS_NO_WAIT | VMREQFLAGS_VOID,
1985
 
                           (PFNRT)CSAMDelayedWriteHandler, 3, pVM, (RTRCPTR)GCPtr, cbBuf);
 
2107
        rc = VMR3ReqCallVoidNoWait(pVM, VMCPUID_ANY, (PFNRT)CSAMDelayedWriteHandler, 3, pVM, (RTRCPTR)GCPtr, cbBuf);
1986
2108
    }
1987
2109
    AssertRC(rc);
1988
2110
 
2193
2315
 */
2194
2316
static int csamR3FlushDirtyPages(PVM pVM)
2195
2317
{
2196
 
    Assert(pVM->cCPUs == 1);
 
2318
    Assert(pVM->cCpus == 1);
2197
2319
    PVMCPU pVCpu = VMMGetCpu0(pVM);
2198
2320
 
2199
2321
    STAM_PROFILE_START(&pVM->csam.s.StatFlushDirtyPages, a);
2244
2366
 */
2245
2367
static int csamR3FlushCodePages(PVM pVM)
2246
2368
{
2247
 
    Assert(pVM->cCPUs == 1);
 
2369
    Assert(pVM->cCpus == 1);
2248
2370
    PVMCPU pVCpu = VMMGetCpu0(pVM);
2249
2371
 
2250
2372
    for (uint32_t i=0;i<pVM->csam.s.cPossibleCodePages;i++)
2288
2410
 */
2289
2411
VMMR3DECL(int) CSAMR3CheckGates(PVM pVM, uint32_t iGate, uint32_t cGates)
2290
2412
{
2291
 
    Assert(pVM->cCPUs == 1);
 
2413
    Assert(pVM->cCpus == 1);
2292
2414
    PVMCPU      pVCpu = VMMGetCpu0(pVM);
2293
2415
    uint16_t    cbIDT;
2294
2416
    RTRCPTR     GCPtrIDT = CPUMGetGuestIDTR(pVCpu, &cbIDT);