VirtualBox

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

Last change on this file since 21217 was 21217, checked in by vboxsync, 15 years ago

include/VBox/*.h: Mark which components the header files relate to.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use