VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR0/VMMR0TripleFaultHack.cpp@ 46474

Last change on this file since 46474 was 38954, checked in by vboxsync, 13 years ago

VMMR0: Triple fault debugging hack proof of concept.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.4 KB
Line 
1/* $Id: VMMR0TripleFaultHack.cpp 38954 2011-10-06 11:28:41Z vboxsync $ */
2/** @file
3 * VMM - Host Context Ring 0, Triple Fault Debugging Hack.
4 *
5 * Only use this when desperate. May not work on all systems, esp. newer ones,
6 * since it require BIOS support for the warm reset vector at 0467h.
7 */
8
9/*
10 * Copyright (C) 2011 Oracle Corporation
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.virtualbox.org. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 */
20
21/*******************************************************************************
22* Header Files *
23*******************************************************************************/
24#define LOG_GROUP LOG_GROUP_VMM
25#include <VBox/vmm/vmm.h>
26#include "VMMInternal.h"
27#include <VBox/param.h>
28
29#include <iprt/asm-amd64-x86.h>
30#include <iprt/assert.h>
31#include <iprt/memobj.h>
32#include <iprt/mem.h>
33#include <iprt/string.h>
34
35
36/*******************************************************************************
37* Global Variables *
38*******************************************************************************/
39static RTR0MEMOBJ g_hMemPage0;
40static RTR0MEMOBJ g_hMapPage0;
41static uint8_t *g_pbPage0;
42
43static RTR0MEMOBJ g_hMemLowCore;
44static RTR0MEMOBJ g_hMapLowCore;
45static uint8_t *g_pbLowCore;
46static RTHCPHYS g_HCPhysLowCore;
47
48/** @name For restoring memory we've overwritten.
49 * @{ */
50static uint32_t g_u32SavedVector;
51static uint16_t g_u16SavedCadIndicator;
52static void *g_pvSavedLowCore;
53/** @} */
54
55
56/*******************************************************************************
57* Internal Functions *
58*******************************************************************************/
59/* VMMR0TripleFaultHackA.asm */
60DECLASM(void) vmmR0TripleFaultHackStart(void);
61DECLASM(void) vmmR0TripleFaultHackEnd(void);
62DECLASM(void) vmmR0TripleFaultHackTripleFault(void);
63
64
65/**
66 * Initalizes the triple fault / boot hack.
67 *
68 * Always call vmmR0TripleFaultHackTerm to clean up, even when this call fails.
69 *
70 * @returns VBox status code.
71 */
72int vmmR0TripleFaultHackInit(void)
73{
74 /*
75 * Map the first page.
76 */
77 int rc = RTR0MemObjEnterPhys(&g_hMemPage0, 0, PAGE_SIZE, RTMEM_CACHE_POLICY_DONT_CARE);
78 AssertRCReturn(rc, rc);
79 rc = RTR0MemObjMapKernel(&g_hMapPage0, g_hMemPage0, (void *)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
80 AssertRCReturn(rc, rc);
81 g_pbPage0 = (uint8_t *)RTR0MemObjAddress(g_hMapPage0);
82 LogRel(("0040:0067 = %04x:%04x\n", RT_MAKE_U16(g_pbPage0[0x467+2], g_pbPage0[0x467+3]), RT_MAKE_U16(g_pbPage0[0x467+0], g_pbPage0[0x467+1]) ));
83
84 /*
85 * Allocate some "low core" memory. If that fails, just grab some memory.
86 */
87 //rc = RTR0MemObjAllocPhys(&g_hMemLowCore, PAGE_SIZE, _1M - 1);
88 //__debugbreak();
89 rc = RTR0MemObjEnterPhys(&g_hMemLowCore, 0x7000, PAGE_SIZE, RTMEM_CACHE_POLICY_DONT_CARE);
90 AssertRCReturn(rc, rc);
91 rc = RTR0MemObjMapKernel(&g_hMapLowCore, g_hMemLowCore, (void *)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE);
92 AssertRCReturn(rc, rc);
93 g_pbLowCore = (uint8_t *)RTR0MemObjAddress(g_hMapLowCore);
94 g_HCPhysLowCore = RTR0MemObjGetPagePhysAddr(g_hMapLowCore, 0);
95 LogRel(("Low core at %RHp mapped at %p\n", g_HCPhysLowCore, g_pbLowCore));
96
97 /*
98 * Save memory we'll be overwriting.
99 */
100 g_pvSavedLowCore = RTMemAlloc(PAGE_SIZE);
101 AssertReturn(g_pvSavedLowCore, VERR_NO_MEMORY);
102 memcpy(g_pvSavedLowCore, g_pbLowCore, PAGE_SIZE);
103
104 g_u32SavedVector = RT_MAKE_U32_FROM_U8(g_pbPage0[0x467], g_pbPage0[0x467+1], g_pbPage0[0x467+2], g_pbPage0[0x467+3]);
105 g_u16SavedCadIndicator = RT_MAKE_U16(g_pbPage0[0x472], g_pbPage0[0x472+1]);
106
107 /*
108 * Install the code.
109 */
110 size_t cbCode = (uintptr_t)&vmmR0TripleFaultHackEnd - (uintptr_t)&vmmR0TripleFaultHackStart;
111 AssertLogRelReturn(cbCode <= PAGE_SIZE, VERR_OUT_OF_RANGE);
112 memcpy(g_pbLowCore, &vmmR0TripleFaultHackStart, cbCode);
113
114 g_pbPage0[0x467+0] = 0x00;
115 g_pbPage0[0x467+1] = 0x70;
116 g_pbPage0[0x467+2] = 0x00;
117 g_pbPage0[0x467+3] = 0x00;
118
119 g_pbPage0[0x472+0] = 0x34;
120 g_pbPage0[0x472+1] = 0x12;
121
122 /*
123 * Configure the status port and cmos shutdown command.
124 */
125 uint32_t fSaved = ASMIntDisableFlags();
126
127 ASMOutU8(0x70, 0x0f);
128 ASMOutU8(0x71, 0x0a);
129
130 ASMOutU8(0x70, 0x05);
131 ASMInU8(0x71);
132
133 ASMReloadCR3();
134 ASMWriteBackAndInvalidateCaches();
135
136 ASMSetFlags(fSaved);
137
138#if 1 /* For testing & debugging. */
139 vmmR0TripleFaultHackTripleFault();
140#endif
141
142 return VINF_SUCCESS;
143}
144
145
146/**
147 * Try undo the harm done by the init function.
148 *
149 * This may leave the system in an unstable state since we might have been
150 * hijacking memory below 1MB that is in use by the kernel.
151 */
152void vmmR0TripleFaultHackTerm(void)
153{
154 /*
155 * Restore overwritten memory.
156 */
157 if ( g_pvSavedLowCore
158 && g_pbLowCore)
159 memcpy(g_pbLowCore, g_pvSavedLowCore, PAGE_SIZE);
160
161 if (g_pbPage0)
162 {
163 g_pbPage0[0x467+0] = RT_BYTE1(g_u32SavedVector);
164 g_pbPage0[0x467+1] = RT_BYTE2(g_u32SavedVector);
165 g_pbPage0[0x467+2] = RT_BYTE3(g_u32SavedVector);
166 g_pbPage0[0x467+3] = RT_BYTE4(g_u32SavedVector);
167
168 g_pbPage0[0x472+0] = RT_BYTE1(g_u16SavedCadIndicator);
169 g_pbPage0[0x472+1] = RT_BYTE2(g_u16SavedCadIndicator);
170 }
171
172 /*
173 * Fix the CMOS.
174 */
175 if (g_pvSavedLowCore)
176 {
177 uint32_t fSaved = ASMIntDisableFlags();
178
179 ASMOutU8(0x70, 0x0f);
180 ASMOutU8(0x71, 0x0a);
181
182 ASMOutU8(0x70, 0x00);
183 ASMInU8(0x71);
184
185 ASMReloadCR3();
186 ASMWriteBackAndInvalidateCaches();
187
188 ASMSetFlags(fSaved);
189 }
190
191 /*
192 * Release resources.
193 */
194 RTMemFree(g_pvSavedLowCore);
195 g_pvSavedLowCore = NULL;
196
197 RTR0MemObjFree(g_hMemLowCore, true /*fFreeMappings*/);
198 g_hMemLowCore = NIL_RTR0MEMOBJ;
199 g_hMapLowCore = NIL_RTR0MEMOBJ;
200 g_pbLowCore = NULL;
201 g_HCPhysLowCore = NIL_RTHCPHYS;
202
203 RTR0MemObjFree(g_hMemPage0, true /*fFreeMappings*/);
204 g_hMemPage0 = NIL_RTR0MEMOBJ;
205 g_hMapPage0 = NIL_RTR0MEMOBJ;
206 g_pbPage0 = NULL;
207}
208
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