VirtualBox

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

Last change on this file since 11083 was 9387, checked in by vboxsync, 17 years ago

64-bit GC alignment fixes

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