VirtualBox

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

Last change on this file since 65697 was 62478, checked in by vboxsync, 8 years ago

(C) 2016

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