VirtualBox

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

Last change on this file since 229 was 187, checked in by vboxsync, 18 years ago

Turn off sysenter/sysexit emulation.

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