VirtualBox

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

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

The Big Sun Rebranding Header Change

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

© 2023 Oracle
ContactPrivacy policyTerms of Use