VirtualBox

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

Last change on this file since 8006 was 7133, checked in by vboxsync, 16 years ago

Eliminate cpum.h dependency (shuts up a bunch of .c warnings). Fixed the header tests.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use