VirtualBox

儲存庫 vbox 的更動 13635


忽略:
時間撮記:
2008-10-28 下午08:27:33 (16 年 以前)
作者:
vboxsync
訊息:

#1865: TRPM.

位置:
trunk
檔案:
修改 7 筆資料

圖例:

未更動
新增
刪除
  • trunk/include/VBox/trpm.h

    r12989 r13635  
    7474#define TRPM_INVALID_HANDLER        0
    7575
    76 /**
    77  * Query info about the current active trap/interrupt.
    78  * If no trap is active active an error code is returned.
    79  *
    80  * @returns VBox status code.
    81  * @param   pVM                     The virtual machine.
    82  * @param   pu8TrapNo               Where to store the trap number.
    83  * @param   pEnmType                Where to store the trap type.
    84  */
    85 VMMDECL(int)  TRPMQueryTrap(PVM pVM, uint8_t *pu8TrapNo, PTRPMEVENT pEnmType);
    86 
    87 /**
    88  * Gets the trap number for the current trap.
    89  *
    90  * The caller is responsible for making sure there is an active trap which
    91  * takes an error code when making this request.
    92  *
    93  * @returns The current trap number.
    94  * @param   pVM         VM handle.
    95  */
    96 VMMDECL(uint8_t)  TRPMGetTrapNo(PVM pVM);
    97 
    98 /**
    99  * Gets the error code for the current trap.
    100  *
    101  * The caller is responsible for making sure there is an active trap which
    102  * takes an error code when making this request.
    103  *
    104  * @returns Error code.
    105  * @param   pVM         VM handle.
    106  */
    107 VMMDECL(RTGCUINT)  TRPMGetErrorCode(PVM pVM);
    108 
    109 /**
    110  * Gets the fault address for the current trap.
    111  *
    112  * The caller is responsible for making sure there is an active trap 0x0e when
    113  * making this request.
    114  *
    115  * @returns Fault address associated with the trap.
    116  * @param   pVM         VM handle.
    117  */
     76VMMDECL(int)        TRPMQueryTrap(PVM pVM, uint8_t *pu8TrapNo, PTRPMEVENT pEnmType);
     77VMMDECL(uint8_t)    TRPMGetTrapNo(PVM pVM);
     78VMMDECL(RTGCUINT)   TRPMGetErrorCode(PVM pVM);
    11879VMMDECL(RTGCUINTPTR) TRPMGetFaultAddress(PVM pVM);
    119 
    120 /**
    121  * Clears the current active trap/exception/interrupt.
    122  *
    123  * The caller is responsible for making sure there is an active trap
    124  * when making this request.
    125  *
    126  * @returns VBox status code.
    127  * @param   pVM         The virtual machine handle.
    128  */
    129 VMMDECL(int) TRPMResetTrap(PVM pVM);
    130 
    131 /**
    132  * Assert trap/exception/interrupt.
    133  *
    134  * The caller is responsible for making sure there is no active trap
    135  * when making this request.
    136  *
    137  * @returns VBox status code.
    138  * @param   pVM                 The virtual machine.
    139  * @param   u8TrapNo            The trap vector to assert.
    140  * @param   enmType             Trap type.
    141  */
    142 VMMDECL(int)  TRPMAssertTrap(PVM pVM, uint8_t u8TrapNo, TRPMEVENT enmType);
    143 
    144 /**
    145  * Sets the error code of the current trap.
    146  * (This function is for use in trap handlers and such.)
    147  *
    148  * The caller is responsible for making sure there is an active trap
    149  * which takes an errorcode when making this request.
    150  *
    151  * @param   pVM         The virtual machine.
    152  * @param   uErrorCode  The new error code.
    153  */
    154 VMMDECL(void)  TRPMSetErrorCode(PVM pVM, RTGCUINT uErrorCode);
    155 
    156 /**
    157  * Sets the error code of the current trap.
    158  * (This function is for use in trap handlers and such.)
    159  *
    160  * The caller is responsible for making sure there is an active trap 0e
    161  * when making this request.
    162  *
    163  * @param   pVM         The virtual machine.
    164  * @param   uCR2        The new fault address (cr2 register).
    165  */
    166 VMMDECL(void)  TRPMSetFaultAddress(PVM pVM, RTGCUINTPTR uCR2);
    167 
    168 /**
    169  * Checks if the current active trap/interrupt/exception/fault/whatever is a software
    170  * interrupt or not.
    171  *
    172  * The caller is responsible for making sure there is an active trap
    173  * when making this request.
    174  *
    175  * @returns true if software interrupt, false if not.
    176  *
    177  * @param   pVM         VM handle.
    178  */
    179 VMMDECL(bool) TRPMIsSoftwareInterrupt(PVM pVM);
    180 
    181 /**
    182  * Check if there is an active trap.
    183  *
    184  * @returns true if trap active, false if not.
    185  * @param   pVM         The virtual machine.
    186  */
    187 VMMDECL(bool)  TRPMHasTrap(PVM pVM);
    188 
    189 /**
    190  * Query all info about the current active trap/interrupt.
    191  * If no trap is active active an error code is returned.
    192  *
    193  * @returns VBox status code.
    194  * @param   pVM                     The virtual machine.
    195  * @param   pu8TrapNo               Where to store the trap number.
    196  * @param   pEnmType                Where to store the trap type.
    197  * @param   puErrorCode             Where to store the error code associated with some traps.
    198  *                                  ~0U is stored if the trap have no error code.
    199  * @param   puCR2                   Where to store the CR2 associated with a trap 0E.
    200  */
    201 VMMDECL(int)  TRPMQueryTrapAll(PVM pVM, uint8_t *pu8TrapNo, PTRPMEVENT pEnmType, PRTGCUINT puErrorCode, PRTGCUINTPTR puCR2);
    202 
    203 
    204 /**
    205  * Save the active trap.
    206  *
    207  * This routine useful when doing try/catch in the hypervisor.
    208  * Any function which uses temporary trap handlers should
    209  * probably also use this facility to save the original trap.
    210  *
    211  * @param   pVM     VM handle.
    212  */
    213 VMMDECL(void) TRPMSaveTrap(PVM pVM);
    214 
    215 /**
    216  * Restore a saved trap.
    217  *
    218  * Multiple restores of a saved trap is possible.
    219  *
    220  * @param   pVM     VM handle.
    221  */
    222 VMMDECL(void) TRPMRestoreTrap(PVM pVM);
    223 
    224 /**
    225  * Forward trap or interrupt to the guest's handler
    226  *
    227  *
    228  * @returns VBox status code.
    229  *  or does not return at all (when the trap is actually forwarded)
    230  *
    231  * @param   pVM         The VM to operate on.
    232  * @param   pRegFrame   Pointer to the register frame for the trap.
    233  * @param   iGate       Trap or interrupt gate number
    234  * @param   opsize      Instruction size (only relevant for software interrupts)
    235  * @param   enmError    TRPM_TRAP_HAS_ERRORCODE or TRPM_TRAP_NO_ERRORCODE.
    236  * @param   enmType     TRPM event type
    237  * @param   iOrgTrap    Original trap.
    238  * @internal
    239  */
    240 VMMDECL(int) TRPMForwardTrap(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_t iGate, uint32_t opsize, TRPMERRORCODE enmError, TRPMEVENT enmType, int32_t iOrgTrap);
    241 
    242 /**
    243  * Raises a cpu exception which doesn't take an error code.
    244  *
    245  * This function may or may not dispatch the exception before returning.
    246  *
    247  * @returns VBox status code fit for scheduling.
    248  * @retval  VINF_EM_RAW_GUEST_TRAP if the exception was left pending.
    249  * @retval  VINF_TRPM_XCPT_DISPATCHED if the exception was raised and dispatched for raw-mode execution.
    250  * @retval  VINF_EM_RESCHEDULE_REM if the exception was dispatched and cannot be executed in raw-mode.
    251  *
    252  * @param   pVM         The VM handle.
    253  * @param   pCtxCore    The CPU context core.
    254  * @param   enmXcpt     The exception.
    255  */
    256 VMMDECL(int) TRPMRaiseXcpt(PVM pVM, PCPUMCTXCORE pCtxCore, X86XCPT enmXcpt);
    257 
    258 /**
    259  * Raises a cpu exception with an errorcode.
    260  *
    261  * This function may or may not dispatch the exception before returning.
    262  *
    263  * @returns VBox status code fit for scheduling.
    264  * @retval  VINF_EM_RAW_GUEST_TRAP if the exception was left pending.
    265  * @retval  VINF_TRPM_XCPT_DISPATCHED if the exception was raised and dispatched for raw-mode execution.
    266  * @retval  VINF_EM_RESCHEDULE_REM if the exception was dispatched and cannot be executed in raw-mode.
    267  *
    268  * @param   pVM         The VM handle.
    269  * @param   pCtxCore    The CPU context core.
    270  * @param   enmXcpt     The exception.
    271  * @param   uErr        The error code.
    272  */
    273 VMMDECL(int) TRPMRaiseXcptErr(PVM pVM, PCPUMCTXCORE pCtxCore, X86XCPT enmXcpt, uint32_t uErr);
    274 
    275 /**
    276  * Raises a cpu exception with an errorcode and CR2.
    277  *
    278  * This function may or may not dispatch the exception before returning.
    279  *
    280  * @returns VBox status code fit for scheduling.
    281  * @retval  VINF_EM_RAW_GUEST_TRAP if the exception was left pending.
    282  * @retval  VINF_TRPM_XCPT_DISPATCHED if the exception was raised and dispatched for raw-mode execution.
    283  * @retval  VINF_EM_RESCHEDULE_REM if the exception was dispatched and cannot be executed in raw-mode.
    284  *
    285  * @param   pVM         The VM handle.
    286  * @param   pCtxCore    The CPU context core.
    287  * @param   enmXcpt     The exception.
    288  * @param   uErr        The error code.
    289  * @param   uCR2        The CR2 value.
    290  */
    291 VMMDECL(int) TRPMRaiseXcptErrCR2(PVM pVM, PCPUMCTXCORE pCtxCore, X86XCPT enmXcpt, uint32_t uErr, RTGCUINTPTR uCR2);
     80VMMDECL(int)        TRPMResetTrap(PVM pVM);
     81VMMDECL(int)        TRPMAssertTrap(PVM pVM, uint8_t u8TrapNo, TRPMEVENT enmType);
     82VMMDECL(void)       TRPMSetErrorCode(PVM pVM, RTGCUINT uErrorCode);
     83VMMDECL(void)       TRPMSetFaultAddress(PVM pVM, RTGCUINTPTR uCR2);
     84VMMDECL(bool)       TRPMIsSoftwareInterrupt(PVM pVM);
     85VMMDECL(bool)       TRPMHasTrap(PVM pVM);
     86VMMDECL(int)        TRPMQueryTrapAll(PVM pVM, uint8_t *pu8TrapNo, PTRPMEVENT pEnmType, PRTGCUINT puErrorCode, PRTGCUINTPTR puCR2);
     87VMMDECL(void)       TRPMSaveTrap(PVM pVM);
     88VMMDECL(void)       TRPMRestoreTrap(PVM pVM);
     89VMMDECL(int)        TRPMForwardTrap(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_t iGate, uint32_t opsize, TRPMERRORCODE enmError, TRPMEVENT enmType, int32_t iOrgTrap);
     90VMMDECL(int)        TRPMRaiseXcpt(PVM pVM, PCPUMCTXCORE pCtxCore, X86XCPT enmXcpt);
     91VMMDECL(int)        TRPMRaiseXcptErr(PVM pVM, PCPUMCTXCORE pCtxCore, X86XCPT enmXcpt, uint32_t uErr);
     92VMMDECL(int)        TRPMRaiseXcptErrCR2(PVM pVM, PCPUMCTXCORE pCtxCore, X86XCPT enmXcpt, uint32_t uErr, RTGCUINTPTR uCR2);
    29293
    29394
     
    29798 * @{
    29899 */
    299 
    300 /**
    301  * Initializes the SELM.
    302  *
    303  * @returns VBox status code.
    304  * @param   pVM         The VM to operate on.
    305  */
    306 VMMR3DECL(int) TRPMR3Init(PVM pVM);
    307 
    308 /**
    309  * Applies relocations to data and code managed by this component.
    310  *
    311  * This function will be called at init and whenever the VMM need
    312  * to relocate itself inside the GC.
    313  *
    314  * @param   pVM         The VM handle.
    315  * @param   offDelta    Relocation delta relative to old location.
    316  */
    317 VMMR3DECL(void) TRPMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
    318 
    319 /**
    320  * The VM is being reset.
    321  *
    322  * For the TRPM component this means that any IDT write monitors
    323  * needs to be removed, any pending trap cleared, and the IDT reset.
    324  *
    325  * @param   pVM     VM handle.
    326  */
    327 VMMR3DECL(void) TRPMR3Reset(PVM pVM);
    328 
    329 /**
    330  * Set interrupt gate handler
    331  * Used for setting up interrupt gates used for kernel calls.
    332  *
    333  * @returns VBox status code.
    334  * @param   pVM         The VM to operate on.
    335  * @param   iTrap       Interrupt number.
    336  */
    337 VMMR3DECL(int) TRPMR3EnableGuestTrapHandler(PVM pVM, unsigned iTrap);
    338 
    339 /**
    340  * Set guest trap/interrupt gate handler
    341  * Used for setting up trap gates used for kernel calls.
    342  *
    343  * @returns VBox status code.
    344  * @param   pVM         The VM to operate on.
    345  * @param   iTrap       Interrupt/trap number.
    346  * @parapm  pHandler    GC handler pointer
    347  */
    348 VMMR3DECL(int) TRPMR3SetGuestTrapHandler(PVM pVM, unsigned iTrap, RTRCPTR pHandler);
    349 
    350 /**
    351  * Get guest trap/interrupt gate handler
    352  *
    353  * @returns Guest trap handler address or TRPM_INVALID_HANDLER if none installed
    354  * @param   pVM         The VM to operate on.
    355  * @param   iTrap       Interrupt/trap number.
    356  */
    357 VMMR3DECL(RTRCPTR) TRPMR3GetGuestTrapHandler(PVM pVM, unsigned iTrap);
    358 
    359 /**
    360  * Disable IDT monitoring and syncing
    361  *
    362  * @param   pVM         The VM to operate on.
    363  */
    364 VMMR3DECL(void) TRPMR3DisableMonitoring(PVM pVM);
    365 
    366 /**
    367  * Check if gate handlers were updated
    368  *
    369  * @returns VBox status code.
    370  * @param   pVM         The VM to operate on.
    371  */
    372 VMMR3DECL(int) TRPMR3SyncIDT(PVM pVM);
    373 
    374 /**
    375  * Check if address is a gate handler (interrupt/trap/task/anything).
    376  *
    377  * @returns True is gate handler, false if not.
    378  *
    379  * @param   pVM         VM handle.
    380  * @param   GCPtr       GC address to check.
    381  */
    382 VMMR3DECL(bool) TRPMR3IsGateHandler(PVM pVM, RTRCPTR GCPtr);
    383 
    384 /**
    385  * Check if address is a gate handler (interrupt or trap).
    386  *
    387  * @returns gate nr or ~0 is not found
    388  *
    389  * @param   pVM         VM handle.
    390  * @param   GCPtr       GC address to check.
    391  */
     100VMMR3DECL(int)      TRPMR3Init(PVM pVM);
     101VMMR3DECL(void)     TRPMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
     102VMMR3DECL(void)     TRPMR3Reset(PVM pVM);
     103VMMR3DECL(int)      TRPMR3Term(PVM pVM);
     104VMMR3DECL(int)      TRPMR3EnableGuestTrapHandler(PVM pVM, unsigned iTrap);
     105VMMR3DECL(int)      TRPMR3SetGuestTrapHandler(PVM pVM, unsigned iTrap, RTRCPTR pHandler);
     106VMMR3DECL(RTRCPTR)  TRPMR3GetGuestTrapHandler(PVM pVM, unsigned iTrap);
     107VMMR3DECL(void)     TRPMR3DisableMonitoring(PVM pVM);
     108VMMR3DECL(int)      TRPMR3SyncIDT(PVM pVM);
     109VMMR3DECL(bool)     TRPMR3IsGateHandler(PVM pVM, RTRCPTR GCPtr);
    392110VMMR3DECL(uint32_t) TRPMR3QueryGateByHandler(PVM pVM, RTRCPTR GCPtr);
    393 
    394 /**
    395  * Initializes the SELM.
    396  *
    397  * @returns VBox status code.
    398  * @param   pVM         The VM to operate on.
    399  */
    400 VMMR3DECL(int) TRPMR3Term(PVM pVM);
    401 
    402 
    403 /**
    404  * Inject event (such as external irq or trap)
    405  *
    406  * @returns VBox status code.
    407  * @param   pVM         The VM to operate on.
    408  * @param   enmEvent    Trpm event type
    409  */
    410 VMMR3DECL(int) TRPMR3InjectEvent(PVM pVM, TRPMEVENT enmEvent);
    411 
     111VMMR3DECL(int)      TRPMR3InjectEvent(PVM pVM, TRPMEVENT enmEvent);
    412112/** @} */
    413113#endif
     
    432132typedef FNTRPMGCTRAPHANDLER *PFNTRPMGCTRAPHANDLER;
    433133
    434 /**
    435  * Arms a temporary trap handler for traps in Hypervisor code.
    436  *
    437  * The operation is similar to a System V signal handler. I.e. when the handler
    438  * is called it is first set to default action. So, if you need to handler more
    439  * than one trap, you must reinstall the handler.
    440  *
    441  * To uninstall the temporary handler, call this function with pfnHandler set to NULL.
    442  *
    443  * @returns VBox status.
    444  * @param   pVM         VM handle.
    445  * @param   iTrap       Trap number to install handler [0..255].
    446  * @param   pfnHandler  Pointer to the handler. Use NULL for uninstalling the handler.
    447  */
    448 VMMRCDECL(int) TRPMGCSetTempHandler(PVM pVM, unsigned iTrap, PFNTRPMGCTRAPHANDLER pfnHandler);
    449 
    450 /**
    451  * Return to host context from a hypervisor trap handler.
    452  * It will also reset any traps that are pending.
    453  *
    454  * This function will *never* return.
    455  *
    456  * @param   pVM     The VM handle.
    457  * @param   rc      The return code for host context.
    458  */
    459 VMMRCDECL(void) TRPMGCHyperReturnToHost(PVM pVM, int rc);
    460 
     134VMMRCDECL(int)      TRPMGCSetTempHandler(PVM pVM, unsigned iTrap, PFNTRPMGCTRAPHANDLER pfnHandler);
     135VMMRCDECL(void)     TRPMGCHyperReturnToHost(PVM pVM, int rc);
    461136/** @} */
    462137#endif
     
    468143 * @{
    469144 */
    470 
    471 /**
    472  * Dispatches an interrupt that arrived while we were in the guest context.
    473  *
    474  * @param   pVM     The VM handle.
    475  * @remark  Must be called with interrupts disabled.
    476  */
    477 VMMR0DECL(void) TRPMR0DispatchHostInterrupt(PVM pVM);
    478 
    479 /**
    480  * Changes the VMMR0Entry() call frame and stack used by the IDT patch code
    481  * so that we'll dispatch an interrupt rather than returning directly to Ring-3
    482  * when VMMR0Entry() returns.
    483  *
    484  * @param   pVM         Pointer to the VM.
    485  * @param   pvRet       Pointer to the return address of VMMR0Entry() on the stack.
    486  */
    487 VMMR0DECL(void) TRPMR0SetupInterruptDispatcherFrame(PVM pVM, void *pvRet);
    488 
     145VMMR0DECL(void)     TRPMR0DispatchHostInterrupt(PVM pVM);
     146VMMR0DECL(void)     TRPMR0SetupInterruptDispatcherFrame(PVM pVM, void *pvRet);
    489147/** @} */
    490148#endif
  • trunk/src/VBox/VMM/TRPM.cpp

    r13532 r13635  
    11/* $Id$ */
    22/** @file
    3  * TRPM - The Trap Monitor
     3 * TRPM - The Trap Monitor.
    44 */
    55
     
    2020 */
    2121
    22 
    2322/** @page pg_trpm   TRPM - The Trap Monitor
    2423 *
    25  * The Trap Monitor (TRPM) is responsible for all trap and interrupt
    26  * handling in the VMM.
    27  *
    28  * Interrupts occuring in GC will be routed to the HC and reassert there. TRPM
    29  * makes the assumption that the VMM or Guest will not cause hardware
    30  * interrupts to occur.
    31  *
    32  * Traps will be passed to a list of registered trap handlers which will
    33  * check and see if they are the responsible part for the trap. If no handler
    34  * was found the default action is to pass the trap on the Guest OS. Trap
    35  * handlers may raise a Guest OS trap as a result of the trap handling.
    36  * Statistics will be maintained so the trap handler list can be resorted
    37  * every now and then to examin handlers in the optimal order.
    38  *
    39  * If a trap happens inside the VMM (Guest Context) the TRPM will take the
    40  * shortest path back to Ring-3 Host Context and brutally destroy the VM.
    41  *
    42  * The TRPM will have interfaces to enable devices to assert interrupts
    43  * in the guest, these interfaces are multithreaded and availble from
    44  * all contexts. This is to allow devices to have use worker threads.
    45  *
    46  */
    47 
    48 
     24 * The Trap Monitor (TRPM) is responsible for all trap and interrupt handling in
     25 * the VMM.  It plays a major role in raw-mode execution and a lesser one in the
     26 * hardware assisted mode.
     27 *
     28 * Note first, the following will use trap as a collective term for faults,
     29 * aborts and traps.
     30 *
     31 * @see grp_trpm
     32 *
     33 *
     34 * @section sec_trpm_rc     Raw-Mode Context
     35 *
     36 * When executing in the raw-mode context, TRPM will be managing the IDT and
     37 * processing all traps and interrupts.  It will also monitor the guest IDT
     38 * because CSAM wishes to know about changes to it (trap/interrupt/syscall
     39 * handler patching) and TRPM needs to keep the #\BP gate in sync (ring-3
     40 * considerations).  See TRPMR3SyncIDT and CSAMR3CheckGates.
     41 *
     42 * External interrupts will be forwarded to the host context by the quickest
     43 * possible route where they will be reasserted.  The other events will be
     44 * categorized into virtualization traps, genuine guest traps and hypervisor
     45 * traps.  The latter group may be recoverable depending on when they happen and
     46 * whether there is a handler for it, otherwise it will cause a guru meditation.
     47 *
     48 * TRPM disgishishes the between the first two (virt and guest traps) and the
     49 * latter (hyper) by checking the CPL of the trapping code, if CPL == 0 then
     50 * it's a hyper trap otherwise it's a virt/guest trap.  There are three trap
     51 * dispatcher tables, one ad-hoc for one time traps registered via
     52 * TRPMGCSetTempHandler(), one for hyper traps and one for virt/guest traps.
     53 * The latter two live in TRPMGCHandlersA.asm, the former in the VM structure.
     54 *
     55 * The raw-mode context trap handlers found in TRPMGCHandlers.cpp (for the most
     56 * part), will call up the other VMM sub-systems depending on what it things
     57 * happens.  The two most busy traps are page faults (\#PF) and general
     58 * protection fault/trap (\#GP).
     59 *
     60 * Before resuming guest code after having taken a virtualization trap or
     61 * injected a guest trap, TRPM will check for pending forced action and
     62 * every now and again let TM check for timed out timers.  This allows code that
     63 * is being executed as part of virtualization traps to signal ring-3 exits,
     64 * page table resyncs and similar without necessarily using the status code.  It
     65 * also make sure we're more responsive to timers and requests from other
     66 * threads (necessarily running on some different core/cpu in most cases).
     67 *
     68 *
     69 * @section sec_trpm_all    All Contexts
     70 *
     71 * TRPM will also dispatch / inject interrupts and traps to the guest, both when
     72 * in raw-mode and when in hardware assisted mode.  See TRPMInject().
     73 *
     74 */
    4975
    5076/*******************************************************************************
     
    413439static DECLCALLBACK(int) trpmR3Save(PVM pVM, PSSMHANDLE pSSM);
    414440static DECLCALLBACK(int) trpmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t u32Version);
    415 static DECLCALLBACK(int) trpmGuestIDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
     441static DECLCALLBACK(int) trpmR3GuestIDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
    416442
    417443
     
    425451{
    426452    LogFlow(("TRPMR3Init\n"));
     453
    427454    /*
    428455     * Assert sizes and alignments.
     
    439466    pVM->trpm.s.uActiveVector      = ~0;
    440467    pVM->trpm.s.GuestIdtr.pIdt     = RTRCPTR_MAX;
    441     pVM->trpm.s.GCPtrIdt           = RTRCPTR_MAX;
     468    pVM->trpm.s.pvMonShwIdtRC            = RTRCPTR_MAX;
    442469    pVM->trpm.s.fDisableMonitoring = false;
    443470    pVM->trpm.s.fSafeToDropGuestIDTMonitoring = false;
     
    478505     * Statistics.
    479506     */
    480     STAM_REG(pVM, &pVM->trpm.s.StatGCWriteGuestIDTFault,   STAMTYPE_COUNTER, "/TRPM/GC/Write/IDT/Fault",   STAMUNIT_OCCURENCES,     "The number of writes to the Guest IDT.");
    481     STAM_REG(pVM, &pVM->trpm.s.StatGCWriteGuestIDTHandled, STAMTYPE_COUNTER, "/TRPM/GC/Write/IDT/Handled", STAMUNIT_OCCURENCES,     "The number of writes to the Guest IDT.");
    482 
    483     STAM_REG(pVM, &pVM->trpm.s.StatSyncIDT,             STAMTYPE_PROFILE, "/PROF/TRPM/SyncIDT",         STAMUNIT_TICKS_PER_CALL, "Profiling of TRPMR3SyncIDT().");
     507    STAM_REG(pVM, &pVM->trpm.s.StatRCWriteGuestIDTFault,    STAMTYPE_COUNTER, "/TRPM/RC/IDTWritesFault",    STAMUNIT_OCCURENCES,     "Guest IDT writes the we returned to R3 to handle.");
     508    STAM_REG(pVM, &pVM->trpm.s.StatRCWriteGuestIDTHandled,  STAMTYPE_COUNTER, "/TRPM/RC/IDTWritesHandled",  STAMUNIT_OCCURENCES,     "Guest IDT writes that we handled successfully.");
     509    STAM_REG(pVM, &pVM->trpm.s.StatSyncIDT,                 STAMTYPE_PROFILE, "/PROF/TRPM/SyncIDT",         STAMUNIT_TICKS_PER_CALL, "Profiling of TRPMR3SyncIDT().");
    484510
    485511    /* traps */
    486     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x00],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/00",      STAMUNIT_TICKS_PER_CALL, "#DE - Divide error.");
    487     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x01],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/01",      STAMUNIT_TICKS_PER_CALL, "#DB - Debug (single step and more).");
    488     //STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x02],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/02",      STAMUNIT_TICKS_PER_CALL, "NMI");
    489     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x03],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/03",      STAMUNIT_TICKS_PER_CALL, "#BP - Breakpoint.");
    490     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x04],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/04",      STAMUNIT_TICKS_PER_CALL, "#OF - Overflow.");
    491     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x05],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/05",      STAMUNIT_TICKS_PER_CALL, "#BR - Bound range exceeded.");
    492     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x06],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/06",      STAMUNIT_TICKS_PER_CALL, "#UD - Undefined opcode.");
    493     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x07],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/07",      STAMUNIT_TICKS_PER_CALL, "#NM - Device not available (FPU).");
    494     //STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x08],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/08",      STAMUNIT_TICKS_PER_CALL, "#DF - Double fault.");
    495     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x09],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/09",      STAMUNIT_TICKS_PER_CALL, "#?? - Coprocessor segment overrun (obsolete).");
    496     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x0a],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/0a",      STAMUNIT_TICKS_PER_CALL, "#TS - Task switch fault.");
    497     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x0b],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/0b",      STAMUNIT_TICKS_PER_CALL, "#NP - Segemnt not present.");
    498     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x0c],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/0c",      STAMUNIT_TICKS_PER_CALL, "#SS - Stack segment fault.");
    499     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x0d],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/0d",      STAMUNIT_TICKS_PER_CALL, "#GP - General protection fault.");
    500     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x0e],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/0e",      STAMUNIT_TICKS_PER_CALL, "#PF - Page fault.");
    501     //STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x0f],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/0f",      STAMUNIT_TICKS_PER_CALL, "Reserved.");
    502     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x10],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/10",      STAMUNIT_TICKS_PER_CALL, "#MF - Math fault..");
    503     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x11],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/11",      STAMUNIT_TICKS_PER_CALL, "#AC - Alignment check.");
    504     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x12],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/12",      STAMUNIT_TICKS_PER_CALL, "#MC - Machine check.");
    505     STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x13],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/13",      STAMUNIT_TICKS_PER_CALL, "#XF - SIMD Floating-Point Exception.");
     512    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x00],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/00",          STAMUNIT_TICKS_PER_CALL, "#DE - Divide error.");
     513    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x01],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/01",          STAMUNIT_TICKS_PER_CALL, "#DB - Debug (single step and more).");
     514    //STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x02],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/02",          STAMUNIT_TICKS_PER_CALL, "NMI");
     515    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x03],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/03",          STAMUNIT_TICKS_PER_CALL, "#BP - Breakpoint.");
     516    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x04],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/04",          STAMUNIT_TICKS_PER_CALL, "#OF - Overflow.");
     517    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x05],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/05",          STAMUNIT_TICKS_PER_CALL, "#BR - Bound range exceeded.");
     518    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x06],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/06",          STAMUNIT_TICKS_PER_CALL, "#UD - Undefined opcode.");
     519    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x07],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/07",          STAMUNIT_TICKS_PER_CALL, "#NM - Device not available (FPU).");
     520    //STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x08],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/08",          STAMUNIT_TICKS_PER_CALL, "#DF - Double fault.");
     521    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x09],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/09",          STAMUNIT_TICKS_PER_CALL, "#?? - Coprocessor segment overrun (obsolete).");
     522    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x0a],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/0a",          STAMUNIT_TICKS_PER_CALL, "#TS - Task switch fault.");
     523    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x0b],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/0b",          STAMUNIT_TICKS_PER_CALL, "#NP - Segemnt not present.");
     524    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x0c],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/0c",          STAMUNIT_TICKS_PER_CALL, "#SS - Stack segment fault.");
     525    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x0d],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/0d",          STAMUNIT_TICKS_PER_CALL, "#GP - General protection fault.");
     526    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x0e],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/0e",          STAMUNIT_TICKS_PER_CALL, "#PF - Page fault.");
     527    //STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x0f],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/0f",          STAMUNIT_TICKS_PER_CALL, "Reserved.");
     528    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x10],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/10",          STAMUNIT_TICKS_PER_CALL, "#MF - Math fault..");
     529    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x11],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/11",          STAMUNIT_TICKS_PER_CALL, "#AC - Alignment check.");
     530    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x12],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/12",          STAMUNIT_TICKS_PER_CALL, "#MC - Machine check.");
     531    STAM_REG(pVM, &pVM->trpm.s.aStatGCTraps[0x13],      STAMTYPE_PROFILE_ADV, "/TRPM/GC/Traps/13",          STAMUNIT_TICKS_PER_CALL, "#XF - SIMD Floating-Point Exception.");
    506532
    507533#ifdef VBOX_WITH_STATISTICS
    508534    rc = MMHyperAlloc(pVM, sizeof(STAMCOUNTER) * 255, 8, MM_TAG_STAM, (void **)&pVM->trpm.s.paStatForwardedIRQR3);
    509535    AssertRCReturn(rc, rc);
    510     pVM->trpm.s.paStatForwardedIRQGC = MMHyperR3ToRC(pVM, pVM->trpm.s.paStatForwardedIRQR3);
     536    pVM->trpm.s.paStatForwardedIRQRC = MMHyperR3ToRC(pVM, pVM->trpm.s.paStatForwardedIRQR3);
    511537    pVM->trpm.s.paStatForwardedIRQR0 = MMHyperR3ToR0(pVM, pVM->trpm.s.paStatForwardedIRQR3);
    512538    for (unsigned i = 0; i < 255; i++)
     
    514540                        i < 0x20 ? "/TRPM/ForwardRaw/TRAP/%02X" : "/TRPM/ForwardRaw/IRQ/%02X", i);
    515541#endif
    516     STAM_REG(pVM, &pVM->trpm.s.StatForwardFailNoHandler,    STAMTYPE_COUNTER, "/TRPM/ForwardRaw/Fail/NoHandler",      STAMUNIT_OCCURENCES, "Failure to forward interrupt in raw mode.");
    517     STAM_REG(pVM, &pVM->trpm.s.StatForwardFailPatchAddr,    STAMTYPE_COUNTER, "/TRPM/ForwardRaw/Fail/PatchAddr",      STAMUNIT_OCCURENCES, "Failure to forward interrupt in raw mode.");
    518 
    519     STAM_REG(pVM, &pVM->trpm.s.StatForwardFailGC,           STAMTYPE_COUNTER, "/TRPM/ForwardRaw/Fail/GC",             STAMUNIT_OCCURENCES, "Failure to forward interrupt in raw mode.");
    520     STAM_REG(pVM, &pVM->trpm.s.StatForwardFailHC,           STAMTYPE_COUNTER, "/TRPM/ForwardRaw/Fail/HC",             STAMUNIT_OCCURENCES, "Failure to forward interrupt in raw mode.");
    521     STAM_REG(pVM, &pVM->trpm.s.StatForwardProfGC,       STAMTYPE_PROFILE_ADV, "/TRPM/ForwardRaw/Prof/GC",         STAMUNIT_TICKS_PER_CALL, "Profiling TRPMForwardTrap.");
    522     STAM_REG(pVM, &pVM->trpm.s.StatForwardProfHC,       STAMTYPE_PROFILE_ADV, "/TRPM/ForwardRaw/Prof/HC",         STAMUNIT_TICKS_PER_CALL, "Profiling TRPMForwardTrap.");
    523 
    524     STAM_REG(pVM, &pVM->trpm.s.StatTrap0dDisasm,        STAMTYPE_PROFILE, "/TRPM/GC/Traps/0d/Disasm",              STAMUNIT_TICKS_PER_CALL, "Profiling disassembly part of trpmGCTrap0dHandler.");
    525     STAM_REG(pVM, &pVM->trpm.s.StatTrap0dRdTsc,         STAMTYPE_COUNTER, "/TRPM/GC/Traps/0d/RdTsc",                   STAMUNIT_OCCURENCES, "Number of RDTSC #GPs.");
     542
     543    STAM_REG(pVM, &pVM->trpm.s.StatForwardProfR3,       STAMTYPE_PROFILE_ADV, "/TRPM/ForwardRaw/ProfR3",   STAMUNIT_TICKS_PER_CALL, "Profiling TRPMForwardTrap.");
     544    STAM_REG(pVM, &pVM->trpm.s.StatForwardProfRZ,       STAMTYPE_PROFILE_ADV, "/TRPM/ForwardRaw/ProfRZ",   STAMUNIT_TICKS_PER_CALL, "Profiling TRPMForwardTrap.");
     545    STAM_REG(pVM, &pVM->trpm.s.StatForwardFailNoHandler,    STAMTYPE_COUNTER, "/TRPM/ForwardRaw/FailNoHandler", STAMUNIT_OCCURENCES,"Failure to forward interrupt in raw mode.");
     546    STAM_REG(pVM, &pVM->trpm.s.StatForwardFailPatchAddr,    STAMTYPE_COUNTER, "/TRPM/ForwardRaw/FailPatchAddr", STAMUNIT_OCCURENCES,"Failure to forward interrupt in raw mode.");
     547    STAM_REG(pVM, &pVM->trpm.s.StatForwardFailR3,           STAMTYPE_COUNTER, "/TRPM/ForwardRaw/FailR3",       STAMUNIT_OCCURENCES, "Failure to forward interrupt in raw mode.");
     548    STAM_REG(pVM, &pVM->trpm.s.StatForwardFailRZ,           STAMTYPE_COUNTER, "/TRPM/ForwardRaw/FailRZ",       STAMUNIT_OCCURENCES, "Failure to forward interrupt in raw mode.");
     549
     550    STAM_REG(pVM, &pVM->trpm.s.StatTrap0dDisasm,            STAMTYPE_PROFILE, "/TRPM/RC/Traps/0d/Disasm",   STAMUNIT_TICKS_PER_CALL, "Profiling disassembly part of trpmGCTrap0dHandler.");
     551    STAM_REG(pVM, &pVM->trpm.s.StatTrap0dRdTsc,             STAMTYPE_COUNTER, "/TRPM/RC/Traps/0d/RdTsc",        STAMUNIT_OCCURENCES, "Number of RDTSC #GPs.");
    526552
    527553    /*
     
    552578     * exports in TRPMR3Init().
    553579     */
    554     RTGCPTR32 aGCPtrs[TRPM_HANDLER_MAX] = {0};
     580    RTRCPTR aRCPtrs[TRPM_HANDLER_MAX] = {0};
    555581    int rc;
    556     rc = PDMR3LdrGetSymbolRC(pVM, VMMGC_MAIN_MODULE_NAME, "TRPMGCHandlerInterupt", &aGCPtrs[TRPM_HANDLER_INT]);
     582    rc = PDMR3LdrGetSymbolRC(pVM, VMMGC_MAIN_MODULE_NAME, "TRPMGCHandlerInterupt", &aRCPtrs[TRPM_HANDLER_INT]);
    557583    AssertReleaseMsgRC(rc, ("Couldn't find TRPMGCHandlerInterupt in VMMGC.gc!\n"));
    558584
    559     rc = PDMR3LdrGetSymbolRC(pVM, VMMGC_MAIN_MODULE_NAME, "TRPMGCHandlerGeneric",  &aGCPtrs[TRPM_HANDLER_TRAP]);
     585    rc = PDMR3LdrGetSymbolRC(pVM, VMMGC_MAIN_MODULE_NAME, "TRPMGCHandlerGeneric",  &aRCPtrs[TRPM_HANDLER_TRAP]);
    560586    AssertReleaseMsgRC(rc, ("Couldn't find TRPMGCHandlerGeneric in VMMGC.gc!\n"));
    561587
    562     rc = PDMR3LdrGetSymbolRC(pVM, VMMGC_MAIN_MODULE_NAME, "TRPMGCHandlerTrap08",   &aGCPtrs[TRPM_HANDLER_TRAP_08]);
     588    rc = PDMR3LdrGetSymbolRC(pVM, VMMGC_MAIN_MODULE_NAME, "TRPMGCHandlerTrap08",   &aRCPtrs[TRPM_HANDLER_TRAP_08]);
    563589    AssertReleaseMsgRC(rc, ("Couldn't find TRPMGCHandlerTrap08 in VMMGC.gc!\n"));
    564590
    565     rc = PDMR3LdrGetSymbolRC(pVM, VMMGC_MAIN_MODULE_NAME, "TRPMGCHandlerTrap12",   &aGCPtrs[TRPM_HANDLER_TRAP_12]);
     591    rc = PDMR3LdrGetSymbolRC(pVM, VMMGC_MAIN_MODULE_NAME, "TRPMGCHandlerTrap12",   &aRCPtrs[TRPM_HANDLER_TRAP_12]);
    566592    AssertReleaseMsgRC(rc, ("Couldn't find TRPMGCHandlerTrap12 in VMMGC.gc!\n"));
    567593
     
    580606        {
    581607            Assert(pIdteTemplate->u16OffsetLow < TRPM_HANDLER_MAX);
    582             RTGCPTR Offset = aGCPtrs[pIdteTemplate->u16OffsetLow];
     608            RTGCPTR Offset = aRCPtrs[pIdteTemplate->u16OffsetLow];
    583609            switch (pIdteTemplate->u16OffsetLow)
    584610            {
     
    618644    {
    619645#ifdef TRPM_TRACK_SHADOW_IDT_CHANGES
    620         if (pVM->trpm.s.GCPtrIdt != RTRCPTR_MAX)
    621         {
    622             rc = PGMHandlerVirtualDeregister(pVM, pVM->trpm.s.GCPtrIdt);
     646        if (pVM->trpm.s.pvMonShwIdtRC != RTRCPTR_MAX)
     647        {
     648            rc = PGMHandlerVirtualDeregister(pVM, pVM->trpm.s.pvMonShwIdtRC);
    623649            AssertRC(rc);
    624650        }
    625         pVM->trpm.s.GCPtrIdt = VM_GUEST_ADDR(pVM, &pVM->trpm.s.aIdt[0]);
    626         rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_HYPERVISOR, pVM->trpm.s.GCPtrIdt, pVM->trpm.s.GCPtrIdt + sizeof(pVM->trpm.s.aIdt) - 1,
    627                                          0, 0, "trpmgcShadowIDTWriteHandler", 0, "Shadow IDT write access handler");
     651        pVM->trpm.s.pvMonShwIdtRC = VM_GUEST_ADDR(pVM, &pVM->trpm.s.aIdt[0]);
     652        rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_HYPERVISOR, pVM->trpm.s.pvMonShwIdtRC, pVM->trpm.s.pvMonShwIdtRC + sizeof(pVM->trpm.s.aIdt) - 1,
     653                                         0, 0, "trpmRCShadowIDTWriteHandler", 0, "Shadow IDT write access handler");
    628654        AssertRC(rc);
    629655#endif
     
    653679    }
    654680
    655     pVM->trpm.s.paStatForwardedIRQGC += offDelta;
     681    pVM->trpm.s.paStatForwardedIRQRC += offDelta;
    656682    pVM->trpm.s.paStatForwardedIRQR0 = MMHyperR3ToR0(pVM, pVM->trpm.s.paStatForwardedIRQR3);
    657683}
     
    931957            /* limit is including */
    932958            rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, IDTR.pIdt, IDTR.pIdt + IDTR.cbIdt /* already inclusive */,
    933                                              0, trpmGuestIDTWriteHandler, "trpmgcGuestIDTWriteHandler", 0, "Guest IDT write access handler");
     959                                             0, trpmR3GuestIDTWriteHandler, "trpmRCGuestIDTWriteHandler", 0, "Guest IDT write access handler");
    934960
    935961            if (rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT)
     
    941967
    942968                rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, IDTR.pIdt, IDTR.pIdt + IDTR.cbIdt /* already inclusive */,
    943                                                  0, trpmGuestIDTWriteHandler, "trpmgcGuestIDTWriteHandler", 0, "Guest IDT write access handler");
     969                                                 0, trpmR3GuestIDTWriteHandler, "trpmRCGuestIDTWriteHandler", 0, "Guest IDT write access handler");
    944970            }
    945971
     
    10021028
    10031029#ifdef TRPM_TRACK_SHADOW_IDT_CHANGES
    1004     if (pVM->trpm.s.GCPtrIdt != RTRCPTR_MAX)
    1005     {
    1006         int rc = PGMHandlerVirtualDeregister(pVM, pVM->trpm.s.GCPtrIdt);
     1030    if (pVM->trpm.s.pvMonShwIdtRC != RTRCPTR_MAX)
     1031    {
     1032        int rc = PGMHandlerVirtualDeregister(pVM, pVM->trpm.s.pvMonShwIdtRC);
    10071033        AssertRC(rc);
    1008         pVM->trpm.s.GCPtrIdt = RTRCPTR_MAX;
     1034        pVM->trpm.s.pvMonShwIdtRC = RTRCPTR_MAX;
    10091035    }
    10101036#endif
     
    10321058 * @param   pvUser          User argument.
    10331059 */
    1034 static DECLCALLBACK(int) trpmGuestIDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
     1060static DECLCALLBACK(int) trpmR3GuestIDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
    10351061{
    10361062    Assert(enmAccessType == PGMACCESSTYPE_WRITE);
    1037     Log(("trpmGuestIDTWriteHandler: write to %VGv size %d\n", GCPtr, cbBuf));
     1063    Log(("trpmR3GuestIDTWriteHandler: write to %VGv size %d\n", GCPtr, cbBuf));
    10381064    VM_FF_SET(pVM, VM_FF_TRPM_SYNC_IDT);
    10391065    return VINF_PGM_HANDLER_DO_DEFAULT;
  • trunk/src/VBox/VMM/TRPMInternal.h

    r13596 r13635  
    7272 * @param   pTRPM   Pointer to TRPM instance data.
    7373 */
    74 #define TRPM2VM(pTRPM)  ( (PVM)((char*)pTRPM - pTRPM->offVM) )
     74#define TRPM2VM(pTRPM)          ( (PVM)((char*)pTRPM - pTRPM->offVM) )
    7575
    7676
     
    8585    /** Offset to the VM structure.
    8686     * See TRPM2VM(). */
    87     RTINT           offVM;
     87    RTINT                   offVM;
    8888
    8989    /** Active Interrupt or trap vector number.
     
    9292     * at that vector number.
    9393     */
    94     RTUINT          uActiveVector;
     94    RTUINT                  uActiveVector;
    9595
    9696    /** Active trap type. */
    97     TRPMEVENT       enmActiveType;
     97    TRPMEVENT               enmActiveType;
    9898
    9999    /** Errorcode for the active interrupt/trap. */
    100     RTGCUINT        uActiveErrorCode; /**< @todo don't use RTGCUINT */
     100    RTGCUINT                uActiveErrorCode; /**< @todo don't use RTGCUINT */
    101101
    102102    /** CR2 at the time of the active exception. */
    103     RTGCUINTPTR     uActiveCR2;
     103    RTGCUINTPTR             uActiveCR2;
    104104
    105105    /** Saved trap vector number. */
    106     RTGCUINT        uSavedVector; /**< @todo don't use RTGCUINT */
     106    RTGCUINT                uSavedVector; /**< @todo don't use RTGCUINT */
    107107
    108108    /** Saved trap type. */
    109     TRPMEVENT       enmSavedType;
     109    TRPMEVENT               enmSavedType;
    110110
    111111    /** Saved errorcode. */
    112     RTGCUINT        uSavedErrorCode;
     112    RTGCUINT                uSavedErrorCode;
    113113
    114114    /** Saved cr2. */
    115     RTGCUINTPTR     uSavedCR2;
     115    RTGCUINTPTR             uSavedCR2;
    116116
    117117    /** Previous trap vector # - for debugging. */
    118     RTGCUINT        uPrevVector;
     118    RTGCUINT                uPrevVector;
    119119
    120120    /** IDT monitoring and sync flag (HWACC). */
    121     bool            fDisableMonitoring; /** @todo r=bird: bool and 7 byte achPadding1. */
     121    bool                    fDisableMonitoring; /** @todo r=bird: bool and 7 byte achPadding1. */
    122122
    123123    /** Whether monitoring of the guest IDT is enabled or not.
     
    133133     * @cfgm    /TRPM/SafeToDropGuestIDTMonitoring   boolean     defaults to false.
    134134     */
    135     bool            fSafeToDropGuestIDTMonitoring;
     135    bool                    fSafeToDropGuestIDTMonitoring;
    136136
    137137    /** Padding to get the IDTs at a 16 byte alignement. */
    138138#if GC_ARCH_BITS == 32
    139     uint8_t         abPadding1[6];
     139    uint8_t                 abPadding1[6];
    140140#else
    141     uint8_t         abPadding1[14];
     141    uint8_t                 abPadding1[14];
    142142#endif
    143143    /** IDTs. Aligned at 16 byte offset for speed. */
    144     VBOXIDTE        aIdt[256];
     144    VBOXIDTE                aIdt[256];
    145145
    146146    /** Bitmap for IDTEs that contain PATM handlers. (needed for relocation) */
    147     uint32_t        au32IdtPatched[8];
     147    uint32_t                au32IdtPatched[8];
    148148
    149149    /** Temporary Hypervisor trap handlers.
    150150     * NULL means default action. */
    151     RCPTRTYPE(void *) aTmpTrapHandlers[256];
    152 
    153     /** GC Pointer to the IDT shadow area (aIdt) placed in Hypervisor memory arena. */
    154     RCPTRTYPE(void *) GCPtrIdt;
     151    RCPTRTYPE(void *)       aTmpTrapHandlers[256];
     152
     153    /** RC Pointer to the IDT shadow area (aIdt) in HMA. */
     154    RCPTRTYPE(void *)       pvMonShwIdtRC;
    155155    /** Current (last) Guest's IDTR. */
    156     VBOXIDTR        GuestIdtr;
     156    VBOXIDTR                GuestIdtr;
    157157
    158158    /** padding. */
    159     uint8_t         au8Padding[2];
     159    uint8_t                 au8Padding[2];
    160160
    161161    /** Checked trap & interrupt handler array */
    162     RCPTRTYPE(void *) aGuestTrapHandler[256];
    163 
    164     /** GC: The number of times writes to the Guest IDT were detected. */
    165     STAMCOUNTER     StatGCWriteGuestIDTFault;
    166     STAMCOUNTER     StatGCWriteGuestIDTHandled;
     162    RCPTRTYPE(void *)       aGuestTrapHandler[256];
     163
     164#ifdef VBOX_WITH_STATISTICS
     165    /** RC: The number of times writes to the Guest IDT were detected. */
     166    STAMCOUNTER             StatRCWriteGuestIDTFault;
     167    STAMCOUNTER             StatRCWriteGuestIDTHandled;
    167168
    168169    /** HC: Profiling of the TRPMR3SyncIDT() method. */
    169     STAMPROFILE     StatSyncIDT;
     170    STAMPROFILE             StatSyncIDT;
    170171    /** GC: Statistics for the trap handlers. */
    171     STAMPROFILEADV  aStatGCTraps[0x14];
    172 
    173     STAMCOUNTER     StatForwardFailNoHandler;
    174     STAMCOUNTER     StatForwardFailPatchAddr;
    175     STAMCOUNTER     StatForwardFailGC;
    176     STAMCOUNTER     StatForwardFailHC;
    177 
    178     STAMPROFILEADV  StatForwardProfGC;
    179     STAMPROFILEADV  StatForwardProfHC;
    180     STAMPROFILE     StatTrap0dDisasm;
    181     STAMCOUNTER     StatTrap0dRdTsc;        /**< Number of RDTSC #GPs. */
     172    STAMPROFILEADV          aStatGCTraps[0x14];
     173
     174    STAMPROFILEADV          StatForwardProfR3;
     175    STAMPROFILEADV          StatForwardProfRZ;
     176    STAMCOUNTER             StatForwardFailNoHandler;
     177    STAMCOUNTER             StatForwardFailPatchAddr;
     178    STAMCOUNTER             StatForwardFailR3;
     179    STAMCOUNTER             StatForwardFailRZ;
     180
     181    STAMPROFILE             StatTrap0dDisasm;
     182    STAMCOUNTER             StatTrap0dRdTsc;    /**< Number of RDTSC #GPs. */
    182183
    183184    /* R3: Statistics for interrupt handlers (allocated on the hypervisor heap). */
     
    185186    /* R0: Statistics for interrupt handlers (allocated on the hypervisor heap). */
    186187    R0PTRTYPE(PSTAMCOUNTER) paStatForwardedIRQR0;
    187     /* GC: Statistics for interrupt handlers (allocated on the hypervisor heap). */
    188     RCPTRTYPE(PSTAMCOUNTER) paStatForwardedIRQGC;
     188    /* RC: Statistics for interrupt handlers (allocated on the hypervisor heap). */
     189    RCPTRTYPE(PSTAMCOUNTER) paStatForwardedIRQRC;
     190#endif /* VBOX_WITH_STATISTICS */
    189191} TRPM;
    190192#pragma pack()
     
    193195typedef TRPM *PTRPM;
    194196
    195 VMMRCDECL(int) trpmgcGuestIDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
    196 VMMRCDECL(int) trpmgcShadowIDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
     197VMMRCDECL(int) trpmRCGuestIDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
     198VMMRCDECL(int) trpmRCShadowIDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
    197199
    198200/**
     
    240242# ifdef VBOX_WITH_IDT_PATCHING
    241243/**
    242  * Code used for the dispatching of interrupts in HC.
     244 * Code used for the dispatching of interrupts in R0 upon return from RC.
    243245 * @internal
    244246 */
     
    246248# endif /* VBOX_WITH_IDT_PATCHING */
    247249
     250#endif /* IN_RING0 */
     251
     252/** @} */
     253
     254__END_DECLS
     255
    248256#endif
    249 
    250 /** @} */
    251 
    252 __END_DECLS
    253 
    254 #endif
  • trunk/src/VBox/VMM/TRPMInternal.mac

    r9430 r13635  
    5454    .aTmpTrapHandlers   RTRCPTR_RES 256
    5555
    56     .GCPtrIdt           RTRCPTR_RES 1
     56    .pvMonShwIdtRC            RTRCPTR_RES 1
    5757    .GuestIdtr          resb 10
    5858    .au8Padding         resb 2
     
    6060    .aGuestTrapHandler  RTRCPTR_RES 256
    6161
    62     .StatGCWriteGuestIDTFault  resb STAMCOUNTER_size
    63     .StatGCWriteGuestIDTHandled  resb STAMCOUNTER_size
     62    .StatRCWriteGuestIDTFault  resb STAMCOUNTER_size
     63    .StatRCWriteGuestIDTHandled  resb STAMCOUNTER_size
    6464    .StatSyncIDT        resb STAMPROFILE_size
    6565    .aStatGCTraps       resb STAMPROFILEADV_size * 0x14
    6666
     67    .StatForwardProfR3        resb STAMPROFILEADV_size
     68    .StatForwardProfRZ        resb STAMPROFILEADV_size
    6769    .StatForwardFailNoHandler resb STAMCOUNTER_size
    6870    .StatForwardFailPatchAddr resb STAMCOUNTER_size
    69     .StatForwardFailGC        resb STAMCOUNTER_size
    70     .StatForwardFailHC        resb STAMCOUNTER_size
     71    .StatForwardFailR3        resb STAMCOUNTER_size
     72    .StatForwardFailRZ        resb STAMCOUNTER_size
    7173
    72     .StatForwardProfGC        resb STAMPROFILEADV_size
    73     .StatForwardProfHC        resb STAMPROFILEADV_size
    7474    .StatTrap0dDisasm         resb STAMPROFILE_size
    7575    .StatTrap0dRdTsc          resb STAMCOUNTER_size
     
    7777    .paStatForwardedIRQR3  RTR3PTR_RES 1
    7878    .paStatForwardedIRQR0  RTR0PTR_RES 1
    79     .paStatForwardedIRQGC  RTGCPTR32_RES 1
     79    .paStatForwardedIRQRC  RTRCPTR_RES 1
    8080endstruc
    8181
  • trunk/src/VBox/VMM/VMMAll/TRPMAll.cpp

    r13144 r13635  
    343343}
    344344
     345
    345346#ifndef IN_RING0
    346347/**
     
    365366    X86EFLAGS eflags;
    366367
    367     STAM_PROFILE_ADV_START(CTXSUFF(&pVM->trpm.s.StatForwardProf), a);
     368    STAM_PROFILE_ADV_START(&pVM->trpm.s.CTX_SUFF_Z(StatForwardProf), a);
    368369
    369370#ifdef DEBUG
     
    689690                    Assert(eflags.Bits.u1IF);
    690691                    Assert(eflags.Bits.u2IOPL == 0);
    691                     STAM_COUNTER_INC(&pVM->trpm.s.CTXALLSUFF(paStatForwardedIRQ)[iGate]);
    692                     STAM_PROFILE_ADV_STOP(CTXSUFF(&pVM->trpm.s.StatForwardProf), a);
     692                    STAM_COUNTER_INC(&pVM->trpm.s.CTX_SUFF(paStatForwardedIRQ)[iGate]);
     693                    STAM_PROFILE_ADV_STOP(&pVM->trpm.s.CTX_SUFF_Z(StatForwardProf), a);
    693694                    if (iOrgTrap >= 0 && iOrgTrap < (int)RT_ELEMENTS(pVM->trpm.s.aStatGCTraps))
    694695                        STAM_PROFILE_ADV_STOP(&pVM->trpm.s.aStatGCTraps[iOrgTrap], o);
     
    707708                    pRegFrame->esp        = esp_r0;
    708709                    pRegFrame->ss         = ss_r0 & ~X86_SEL_RPL;     /* set rpl to ring 0 */
    709                     STAM_PROFILE_ADV_STOP(CTXSUFF(&pVM->trpm.s.StatForwardProf), a);
     710                    STAM_PROFILE_ADV_STOP(&pVM->trpm.s.CTX_SUFF_Z(StatForwardProf), a);
    710711                    PGMPhysReleasePageMappingLock(pVM, &PageMappingLock);
    711712                    return VINF_SUCCESS;
     
    727728        if (pVM->trpm.s.aGuestTrapHandler[iGate] == TRPM_INVALID_HANDLER)
    728729            STAM_COUNTER_INC(&pVM->trpm.s.StatForwardFailNoHandler);
    729         else
    730         if (PATMIsPatchGCAddr(pVM, (RTRCPTR)pRegFrame->eip))
     730        else if (PATMIsPatchGCAddr(pVM, (RTRCPTR)pRegFrame->eip))
    731731            STAM_COUNTER_INC(&pVM->trpm.s.StatForwardFailPatchAddr);
    732732#endif
    733733    }
    734734failure:
    735     STAM_COUNTER_INC(&CTXSUFF(pVM->trpm.s.StatForwardFail));
    736     STAM_PROFILE_ADV_STOP(CTXSUFF(&pVM->trpm.s.StatForwardProf), a);
     735    STAM_COUNTER_INC(&pVM->trpm.s.CTX_SUFF_Z(StatForwardFail));
     736    STAM_PROFILE_ADV_STOP(&pVM->trpm.s.CTX_SUFF_Z(StatForwardProf), a);
    737737
    738738    Log(("TRAP%02X: forwarding to REM (ss rpl=%d eflags=%08X VMIF=%d handler=%08X\n", iGate, pRegFrame->ss & X86_SEL_RPL, pRegFrame->eflags.u32, PATMAreInterruptsEnabledByCtxCore(pVM, pRegFrame), pVM->trpm.s.aGuestTrapHandler[iGate]));
     
    741741}
    742742#endif /* !IN_RING0 */
     743
    743744
    744745/**
     
    852853}
    853854
    854 
  • trunk/src/VBox/VMM/VMMGC/TRPMGC.cpp

    r13027 r13635  
    105105 *                      (If it's a EIP range this's the EIP, if not it's pvFault.)
    106106 */
    107 VMMRCDECL(int) trpmgcGuestIDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
     107VMMRCDECL(int) trpmRCGuestIDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
    108108{
    109109    uint16_t    cbIDT;
     
    118118
    119119#if 0
    120     /** @note this causes problems in Windows XP as instructions following the update can be dangerous (str eax has been seen) */
    121     /** @note not going back to ring 3 could make the code scanner miss them. */
     120    /* Note! this causes problems in Windows XP as instructions following the update can be dangerous (str eax has been seen) */
     121    /* Note! not going back to ring 3 could make the code scanner miss them. */
    122122    /* Check if we can handle the write here. */
    123123    if (     iGate != 3                                         /* Gate 3 is handled differently; could do it here as well, but let ring 3 handle this case for now. */
     
    130130            uint32_t iGate1 = (offRange + cb - 1)/sizeof(VBOXIDTE);
    131131
    132             Log(("trpmgcGuestIDTWriteHandler: write to gate %x (%x) offset %x cb=%d\n", iGate, iGate1, offRange, cb));
     132            Log(("trpmRCGuestIDTWriteHandler: write to gate %x (%x) offset %x cb=%d\n", iGate, iGate1, offRange, cb));
    133133
    134134            trpmClearGuestTrapHandler(pVM, iGate);
     
    136136                trpmClearGuestTrapHandler(pVM, iGate1);
    137137
    138             STAM_COUNTER_INC(&pVM->trpm.s.StatGCWriteGuestIDTHandled);
     138            STAM_COUNTER_INC(&pVM->trpm.s.StatRCWriteGuestIDTHandled);
    139139            return VINF_SUCCESS;
    140140        }
     
    144144#endif
    145145
    146     Log(("trpmgcGuestIDTWriteHandler: eip=%VGv write to gate %x offset %x\n", pRegFrame->eip, iGate, offRange));
     146    Log(("trpmRCGuestIDTWriteHandler: eip=%VGv write to gate %x offset %x\n", pRegFrame->eip, iGate, offRange));
    147147
    148148    /** @todo Check which IDT entry and keep the update cost low in TRPMR3SyncIDT() and CSAMCheckGates(). */
    149149    VM_FF_SET(pVM, VM_FF_TRPM_SYNC_IDT);
    150150
    151     STAM_COUNTER_INC(&pVM->trpm.s.StatGCWriteGuestIDTFault);
     151    STAM_COUNTER_INC(&pVM->trpm.s.StatRCWriteGuestIDTFault);
    152152    return VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT;
    153153}
     
    166166 *                      (If it's a EIP range this's the EIP, if not it's pvFault.)
    167167 */
    168 VMMRCDECL(int) trpmgcShadowIDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
     168VMMRCDECL(int) trpmRCShadowIDTWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange)
    169169{
    170     LogRel(("FATAL ERROR: trpmgcShadowIDTWriteHandler: eip=%08X pvFault=%VGv pvRange=%08X\r\n", pRegFrame->eip, pvFault, pvRange));
     170    LogRel(("FATAL ERROR: trpmRCShadowIDTWriteHandler: eip=%08X pvFault=%VGv pvRange=%08X\r\n", pRegFrame->eip, pvFault, pvRange));
    171171
    172172    /* If we ever get here, then the guest has executed an sidt instruction that we failed to patch. In theory this could be very bad, but
  • trunk/src/VBox/VMM/VMMGC/TRPMGCHandlers.cpp

    r12339 r13635  
    281281
    282282
    283 
    284283/**
    285284 * NMI handler, for when we are using NMIs to debug things.
     
    915914}
    916915
     916
    917917/**
    918918 * \#PF (Page Fault) handler.
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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