VirtualBox

source: vbox/trunk/include/VBox/patm.h@ 30676

Last change on this file since 30676 was 28800, checked in by vboxsync, 14 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.9 KB
Line 
1/** @file
2 * PATM - Dynamic Guest OS Patching Manager. (VMM)
3 */
4
5/*
6 * Copyright (C) 2006-2007 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___VBox_patm_h
27#define ___VBox_patm_h
28
29#include <VBox/cdefs.h>
30#include <VBox/types.h>
31#include <VBox/dis.h>
32
33
34RT_C_DECLS_BEGIN
35
36/** @defgroup grp_patm The Patch Manager API
37 * @{
38 */
39#define MAX_PATCHES 512
40
41/**
42 * Flags for specifying the type of patch to install with PATMR3InstallPatch
43 * @{
44 */
45#define PATMFL_CODE32 RT_BIT_64(0)
46#define PATMFL_INTHANDLER RT_BIT_64(1)
47#define PATMFL_SYSENTER RT_BIT_64(2)
48#define PATMFL_GUEST_SPECIFIC RT_BIT_64(3)
49#define PATMFL_USER_MODE RT_BIT_64(4)
50#define PATMFL_IDTHANDLER RT_BIT_64(5)
51#define PATMFL_TRAPHANDLER RT_BIT_64(6)
52#define PATMFL_DUPLICATE_FUNCTION RT_BIT_64(7)
53#define PATMFL_REPLACE_FUNCTION_CALL RT_BIT_64(8)
54#define PATMFL_TRAPHANDLER_WITH_ERRORCODE RT_BIT_64(9)
55#define PATMFL_INTHANDLER_WITH_ERRORCODE (PATMFL_TRAPHANDLER_WITH_ERRORCODE)
56#define PATMFL_MMIO_ACCESS RT_BIT_64(10)
57/* no more room -> change PATMInternal.h if more is needed!! */
58
59/*
60 * Flags above 1024 are reserved for internal use!
61 */
62/** @} */
63
64/** Enable to activate sysenter emulation in GC. */
65/* #define PATM_EMULATE_SYSENTER */
66
67/**
68 * Maximum number of cached VGA writes
69 */
70#define MAX_VGA_WRITE_CACHE 64
71
72typedef struct PATMGCSTATE
73{
74 // Virtual Flags register (IF + more later on)
75 uint32_t uVMFlags;
76
77 /* Pending PATM actions (internal use only) */
78 uint32_t uPendingAction;
79
80 // Records the number of times all patches are called (indicating how many exceptions we managed to avoid)
81 uint32_t uPatchCalls;
82 // Scratchpad dword
83 uint32_t uScratch;
84 // Debugging info
85 uint32_t uIretEFlags, uIretCS, uIretEIP;
86
87 /* PATM stack pointer */
88 uint32_t Psp;
89
90 /* PATM interrupt flag */
91 uint32_t fPIF;
92 /* PATM inhibit irq address (used by sti) */
93 RTRCPTR GCPtrInhibitInterrupts;
94
95 /* Scratch room for call patch */
96 RTRCPTR GCCallPatchTargetAddr;
97 RTRCPTR GCCallReturnAddr;
98
99 /* Temporary storage for guest registers. */
100 struct
101 {
102 uint32_t uEAX;
103 uint32_t uECX;
104 uint32_t uEDI;
105 uint32_t eFlags;
106 uint32_t uFlags;
107 } Restore;
108} PATMGCSTATE, *PPATMGCSTATE;
109
110typedef struct PATMTRAPREC
111{
112 // pointer to original guest code instruction (for emulation)
113 RTRCPTR pNewEIP;
114 // pointer to the next guest code instruction
115 RTRCPTR pNextInstr;
116 //pointer to the corresponding next instruction in the patch block
117 RTRCPTR pNextPatchInstr;
118} PATMTRAPREC, *PPATMTRAPREC;
119
120
121/**
122 * Translation state (currently patch to GC ptr)
123 */
124typedef enum
125{
126 PATMTRANS_FAILED,
127 PATMTRANS_SAFE, /* Safe translation */
128 PATMTRANS_PATCHSTART, /* Instruction starts a patch block */
129 PATMTRANS_OVERWRITTEN, /* Instruction overwritten by patchjump */
130 PATMTRANS_INHIBITIRQ /* Instruction must be executed due to instruction fusing */
131} PATMTRANSSTATE;
132
133/**
134 * Load virtualized flags.
135 *
136 * This function is called from CPUMRawEnter(). It doesn't have to update the
137 * IF and IOPL eflags bits, the caller will enforce those to set and 0 repectively.
138 *
139 * @param pVM VM handle.
140 * @param pCtxCore The cpu context core.
141 * @see pg_raw
142 */
143VMMDECL(void) PATMRawEnter(PVM pVM, PCPUMCTXCORE pCtxCore);
144
145/**
146 * Restores virtualized flags.
147 *
148 * This function is called from CPUMRawLeave(). It will update the eflags register.
149 *
150 * @param pVM VM handle.
151 * @param pCtxCore The cpu context core.
152 * @param rawRC Raw mode return code
153 * @see @ref pg_raw
154 */
155VMMDECL(void) PATMRawLeave(PVM pVM, PCPUMCTXCORE pCtxCore, int rawRC);
156
157/**
158 * Get the EFLAGS.
159 * This is a worker for CPUMRawGetEFlags().
160 *
161 * @returns The eflags.
162 * @param pVM The VM handle.
163 * @param pCtxCore The context core.
164 */
165VMMDECL(uint32_t) PATMRawGetEFlags(PVM pVM, PCCPUMCTXCORE pCtxCore);
166
167/**
168 * Updates the EFLAGS.
169 * This is a worker for CPUMRawSetEFlags().
170 *
171 * @param pVM The VM handle.
172 * @param pCtxCore The context core.
173 * @param efl The new EFLAGS value.
174 */
175VMMDECL(void) PATMRawSetEFlags(PVM pVM, PCPUMCTXCORE pCtxCore, uint32_t efl);
176
177/**
178 * Returns the guest context pointer of the GC context structure
179 *
180 * @returns VBox status code.
181 * @param pVM The VM to operate on.
182 */
183VMMDECL(RCPTRTYPE(PPATMGCSTATE)) PATMQueryGCState(PVM pVM);
184
185/**
186 * Checks whether the GC address is part of our patch region
187 *
188 * @returns true -> yes, false -> no
189 * @param pVM The VM to operate on.
190 * @param pAddr Guest context address
191 */
192VMMDECL(bool) PATMIsPatchGCAddr(PVM pVM, RTRCUINTPTR pAddr);
193
194/**
195 * Check if we must use raw mode (patch code being executed or marked safe for IF=0)
196 *
197 * @param pVM VM handle.
198 * @param pAddrGC Guest context address
199 */
200VMMDECL(bool) PATMShouldUseRawMode(PVM pVM, RTRCPTR pAddrGC);
201
202/**
203 * Query PATM state (enabled/disabled)
204 *
205 * @returns 0 - disabled, 1 - enabled
206 * @param pVM The VM to operate on.
207 */
208#define PATMIsEnabled(pVM) (pVM->fPATMEnabled)
209
210/**
211 * Set parameters for pending MMIO patch operation
212 *
213 * @returns VBox status code.
214 * @param pDevIns Device instance.
215 * @param GCPhys MMIO physical address
216 * @param pCachedData GC pointer to cached data
217 */
218VMMDECL(int) PATMSetMMIOPatchInfo(PVM pVM, RTGCPHYS GCPhys, RTRCPTR pCachedData);
219
220
221/**
222 * Adds branch pair to the lookup cache of the particular branch instruction
223 *
224 * @returns VBox status
225 * @param pVM The VM to operate on.
226 * @param pJumpTableGC Pointer to branch instruction lookup cache
227 * @param pBranchTarget Original branch target
228 * @param pRelBranchPatch Relative duplicated function address
229 */
230VMMDECL(int) PATMAddBranchToLookupCache(PVM pVM, RTRCPTR pJumpTableGC, RTRCPTR pBranchTarget, RTRCUINTPTR pRelBranchPatch);
231
232
233/**
234 * Checks if the int 3 was caused by a patched instruction
235 *
236 * @returns VBox status
237 *
238 * @param pVM The VM handle.
239 * @param pCtxCore The relevant core context.
240 */
241VMMDECL(int) PATMHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame);
242
243/**
244 * Checks if the int 3 was caused by a patched instruction
245 *
246 * @returns VBox status
247 *
248 * @param pVM The VM handle.
249 * @param pInstrGC Instruction pointer
250 * @param pOpcode Original instruction opcode (out, optional)
251 * @param pSize Original instruction size (out, optional)
252 */
253VMMDECL(bool) PATMIsInt3Patch(PVM pVM, RTRCPTR pInstrGC, uint32_t *pOpcode, uint32_t *pSize);
254
255
256/**
257 * Checks if the interrupt flag is enabled or not.
258 *
259 * @returns true if it's enabled.
260 * @returns false if it's diabled.
261 *
262 * @param pVM The VM handle.
263 */
264VMMDECL(bool) PATMAreInterruptsEnabled(PVM pVM);
265
266/**
267 * Checks if the interrupt flag is enabled or not.
268 *
269 * @returns true if it's enabled.
270 * @returns false if it's diabled.
271 *
272 * @param pVM The VM handle.
273 * @param pCtxCore CPU context
274 */
275VMMDECL(bool) PATMAreInterruptsEnabledByCtxCore(PVM pVM, PCPUMCTXCORE pCtxCore);
276
277#ifdef PATM_EMULATE_SYSENTER
278/**
279 * Emulate sysenter, sysexit and syscall instructions
280 *
281 * @returns VBox status
282 *
283 * @param pVM The VM handle.
284 * @param pCtxCore The relevant core context.
285 * @param pCpu Disassembly context
286 */
287VMMDECL(int) PATMSysCall(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
288#endif
289
290#ifdef IN_RC
291/** @defgroup grp_patm_gc The Patch Manager API
292 * @ingroup grp_patm
293 * @{
294 */
295
296/**
297 * Checks if the write is located on a page with was patched before.
298 * (if so, then we are not allowed to turn on r/w)
299 *
300 * @returns VBox status
301 * @param pVM The VM to operate on.
302 * @param pRegFrame CPU context
303 * @param GCPtr GC pointer to write address
304 * @param cbWrite Nr of bytes to write
305 *
306 */
307VMMRCDECL(int) PATMGCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite);
308
309/**
310 * Checks if the illegal instruction was caused by a patched instruction
311 *
312 * @returns VBox status
313 *
314 * @param pVM The VM handle.
315 * @param pCtxCore The relevant core context.
316 */
317VMMDECL(int) PATMGCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame);
318
319/** @} */
320
321#endif
322
323#ifdef IN_RING3
324/** @defgroup grp_patm_r3 The Patch Manager API
325 * @ingroup grp_patm
326 * @{
327 */
328
329/**
330 * Query PATM state (enabled/disabled)
331 *
332 * @returns 0 - disabled, 1 - enabled
333 * @param pVM The VM to operate on.
334 */
335VMMR3DECL(int) PATMR3IsEnabled(PVM pVM);
336
337/**
338 * Initializes the PATM.
339 *
340 * @returns VBox status code.
341 * @param pVM The VM to operate on.
342 */
343VMMR3DECL(int) PATMR3Init(PVM pVM);
344
345/**
346 * Finalizes HMA page attributes.
347 *
348 * @returns VBox status code.
349 * @param pVM The VM handle.
350 */
351VMMR3DECL(int) PATMR3InitFinalize(PVM pVM);
352
353/**
354 * Applies relocations to data and code managed by this
355 * component. This function will be called at init and
356 * whenever the VMM need to relocate it self inside the GC.
357 *
358 * The PATM will update the addresses used by the switcher.
359 *
360 * @param pVM The VM.
361 */
362VMMR3DECL(void) PATMR3Relocate(PVM pVM);
363
364/**
365 * Terminates the PATM.
366 *
367 * Termination means cleaning up and freeing all resources,
368 * the VM it self is at this point powered off or suspended.
369 *
370 * @returns VBox status code.
371 * @param pVM The VM to operate on.
372 */
373VMMR3DECL(int) PATMR3Term(PVM pVM);
374
375/**
376 * PATM reset callback.
377 *
378 * @returns VBox status code.
379 * @param pVM The VM which is reset.
380 */
381VMMR3DECL(int) PATMR3Reset(PVM pVM);
382
383/**
384 * Returns the host context pointer and size of the patch memory block
385 *
386 * @returns VBox status code.
387 * @param pVM The VM to operate on.
388 * @param pcb Size of the patch memory block
389 */
390VMMR3DECL(void *) PATMR3QueryPatchMemHC(PVM pVM, uint32_t *pcb);
391
392/**
393 * Returns the guest context pointer and size of the patch memory block
394 *
395 * @returns VBox status code.
396 * @param pVM The VM to operate on.
397 * @param pcb Size of the patch memory block
398 */
399VMMR3DECL(RTRCPTR) PATMR3QueryPatchMemGC(PVM pVM, uint32_t *pcb);
400
401/**
402 * Checks whether the GC address is inside a generated patch jump
403 *
404 * @returns true -> yes, false -> no
405 * @param pVM The VM to operate on.
406 * @param pAddr Guest context address
407 * @param pPatchAddr Guest context patch address (if true)
408 */
409VMMR3DECL(bool) PATMR3IsInsidePatchJump(PVM pVM, RTRCPTR pAddr, PRTGCPTR32 pPatchAddr);
410
411
412/**
413 * Returns the GC pointer of the patch for the specified GC address
414 *
415 * @returns VBox status code.
416 * @param pVM The VM to operate on.
417 * @param pAddrGC Guest context address
418 */
419VMMR3DECL(RTRCPTR) PATMR3QueryPatchGCPtr(PVM pVM, RTRCPTR pAddrGC);
420
421/**
422 * Checks whether the HC address is part of our patch region
423 *
424 * @returns VBox status code.
425 * @param pVM The VM to operate on.
426 * @param pAddrGC Guest context address
427 */
428VMMR3DECL(bool) PATMR3IsPatchHCAddr(PVM pVM, R3PTRTYPE(uint8_t *) pAddrHC);
429
430/**
431 * Convert a GC patch block pointer to a HC patch pointer
432 *
433 * @returns HC pointer or NULL if it's not a GC patch pointer
434 * @param pVM The VM to operate on.
435 * @param pAddrGC GC pointer
436 */
437VMMR3DECL(R3PTRTYPE(void *)) PATMR3GCPtrToHCPtr(PVM pVM, RTRCPTR pAddrGC);
438
439
440/**
441 * Returns the host context pointer and size of the GC context structure
442 *
443 * @returns VBox status code.
444 * @param pVM The VM to operate on.
445 */
446VMMR3DECL(PPATMGCSTATE) PATMR3QueryGCStateHC(PVM pVM);
447
448/**
449 * Handle trap inside patch code
450 *
451 * @returns VBox status code.
452 * @param pVM The VM to operate on.
453 * @param pCtx CPU context
454 * @param pEip GC pointer of trapping instruction
455 * @param pNewEip GC pointer to new instruction
456 */
457VMMR3DECL(int) PATMR3HandleTrap(PVM pVM, PCPUMCTX pCtx, RTRCPTR pEip, RTGCPTR *ppNewEip);
458
459/**
460 * Handle page-fault in monitored page
461 *
462 * @returns VBox status code.
463 * @param pVM The VM to operate on.
464 */
465VMMR3DECL(int) PATMR3HandleMonitoredPage(PVM pVM);
466
467/**
468 * Notifies PATM about a (potential) write to code that has been patched.
469 *
470 * @returns VBox status code.
471 * @param pVM The VM to operate on.
472 * @param GCPtr GC pointer to write address
473 * @param cbWrite Nr of bytes to write
474 *
475 */
476VMMR3DECL(int) PATMR3PatchWrite(PVM pVM, RTRCPTR GCPtr, uint32_t cbWrite);
477
478/**
479 * Notify PATM of a page flush
480 *
481 * @returns VBox status code
482 * @param pVM The VM to operate on.
483 * @param addr GC address of the page to flush
484 */
485VMMR3DECL(int) PATMR3FlushPage(PVM pVM, RTRCPTR addr);
486
487/**
488 * Allows or disallow patching of privileged instructions executed by the guest OS
489 *
490 * @returns VBox status code.
491 * @param pVM The VM to operate on.
492 * @param fAllowPatching Allow/disallow patching
493 */
494VMMR3DECL(int) PATMR3AllowPatching(PVM pVM, uint32_t fAllowPatching);
495
496/**
497 * Patch privileged instruction at specified location
498 *
499 * @returns VBox status code.
500 * @param pVM The VM to operate on.
501 * @param pInstr Guest context point to privileged instruction (0:32 flat address)
502 * @param flags Patch flags
503 *
504 * @note returns failure if patching is not allowed or possible
505 */
506VMMR3DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags);
507
508/**
509 * Gives hint to PATM about supervisor guest instructions
510 *
511 * @returns VBox status code.
512 * @param pVM The VM to operate on.
513 * @param pInstr Guest context point to privileged instruction
514 * @param flags Patch flags
515 */
516VMMR3DECL(int) PATMR3AddHint(PVM pVM, RTRCPTR pInstrGC, uint32_t flags);
517
518/**
519 * Patch branch target function for call/jump at specified location.
520 * (in responds to a VINF_PATM_DUPLICATE_FUNCTION GC exit reason)
521 *
522 * @returns VBox status code.
523 * @param pVM The VM to operate on.
524 * @param pCtx Guest context
525 *
526 */
527VMMR3DECL(int) PATMR3DuplicateFunctionRequest(PVM pVM, PCPUMCTX pCtx);
528
529/**
530 * Query the corresponding GC instruction pointer from a pointer inside the patch block itself
531 *
532 * @returns original GC instruction pointer or 0 if not found
533 * @param pVM The VM to operate on.
534 * @param pPatchGC GC address in patch block
535 * @param pEnmState State of the translated address (out)
536 *
537 */
538VMMR3DECL(RTRCPTR) PATMR3PatchToGCPtr(PVM pVM, RTRCPTR pPatchGC, PATMTRANSSTATE *pEnmState);
539
540/**
541 * Converts Guest code GC ptr to Patch code GC ptr (if found)
542 *
543 * @returns corresponding GC pointer in patch block
544 * @param pVM The VM to operate on.
545 * @param pInstrGC Guest context pointer to privileged instruction
546 *
547 */
548VMMR3DECL(RTRCPTR) PATMR3GuestGCPtrToPatchGCPtr(PVM pVM, RCPTRTYPE(uint8_t*) pInstrGC);
549
550/**
551 * Query the opcode of the original code that was overwritten by the 5 bytes patch jump
552 *
553 * @returns VBox status code.
554 * @param pVM The VM to operate on.
555 * @param pInstrGC GC address of instr
556 * @param pByte opcode byte pointer (OUT)
557 * @returns VBOX error code
558 *
559 */
560VMMR3DECL(int) PATMR3QueryOpcode(PVM pVM, RTRCPTR pInstrGC, uint8_t *pByte);
561
562/**
563 * Disable patch for privileged instruction at specified location
564 *
565 * @returns VBox status code.
566 * @param pVM The VM to operate on.
567 * @param pInstr Guest context point to privileged instruction
568 *
569 * @note returns failure if patching is not allowed or possible
570 *
571 */
572VMMR3DECL(int) PATMR3DisablePatch(PVM pVM, RTRCPTR pInstrGC);
573
574
575/**
576 * Enable patch for privileged instruction at specified location
577 *
578 * @returns VBox status code.
579 * @param pVM The VM to operate on.
580 * @param pInstr Guest context point to privileged instruction
581 *
582 * @note returns failure if patching is not allowed or possible
583 *
584 */
585VMMR3DECL(int) PATMR3EnablePatch(PVM pVM, RTRCPTR pInstrGC);
586
587
588/**
589 * Remove patch for privileged instruction at specified location
590 *
591 * @returns VBox status code.
592 * @param pVM The VM to operate on.
593 * @param pInstr Guest context point to privileged instruction
594 *
595 * @note returns failure if patching is not allowed or possible
596 *
597 */
598VMMR3DECL(int) PATMR3RemovePatch(PVM pVM, RTRCPTR pInstrGC);
599
600
601/**
602 * Detects it the specified address falls within a 5 byte jump generated for an active patch.
603 * If so, this patch is permanently disabled.
604 *
605 * @param pVM The VM to operate on.
606 * @param pInstrGC Guest context pointer to instruction
607 * @param pConflictGC Guest context pointer to check
608 */
609VMMR3DECL(int) PATMR3DetectConflict(PVM pVM, RTRCPTR pInstrGC, RTRCPTR pConflictGC);
610
611
612/**
613 * Checks if the instructions at the specified address has been patched already.
614 *
615 * @returns boolean, patched or not
616 * @param pVM The VM to operate on.
617 * @param pInstrGC Guest context pointer to instruction
618 */
619VMMR3DECL(bool) PATMR3HasBeenPatched(PVM pVM, RTRCPTR pInstrGC);
620
621
622/**
623 * Install Linux 2.6 spinlock patch
624 *
625 * @returns VBox status code.
626 * @param pVM The VM to operate on
627 * @param pCallAcquireSpinlockGC GC pointer of call instruction
628 * @param cbAcquireSpinlockCall Instruction size
629 *
630 */
631VMMR3DECL(int) PATMInstallSpinlockPatch(PVM pVM, RTRCPTR pCallAcquireSpinlockGC, uint32_t cbAcquireSpinlockCall);
632
633
634/**
635 * Check if supplied call target is the Linux 2.6 spinlock acquire function
636 *
637 * @returns boolean
638 * @param pVM The VM to operate on
639 * @param pCallAcquireSpinlockGC Call target GC address
640 *
641 */
642VMMR3DECL(bool) PATMIsSpinlockAcquire(PVM pVM, RTRCPTR pCallTargetGC);
643
644/**
645 * Check if supplied call target is the Linux 2.6 spinlock release function
646 *
647 * @returns boolean
648 * @param pVM The VM to operate on
649 * @param pCallTargetGC Call target GC address
650 *
651 */
652VMMR3DECL(bool) PATMIsSpinlockRelease(PVM pVM, RTRCPTR pCallTargetGC);
653
654/**
655 * Check if supplied call target is the Linux 2.6 spinlock release function (patched equivalent)
656 *
657 * @returns boolean
658 * @param pVM The VM to operate on
659 * @param pCallTargetGC Call target GC address
660 *
661 */
662VMMR3DECL(bool) PATMIsSpinlockReleasePatch(PVM pVM, RTRCPTR pCallTargetGC);
663
664/** @} */
665#endif
666
667
668/** @} */
669RT_C_DECLS_END
670
671
672#endif
Note: See TracBrowser for help on using the repository browser.

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