VirtualBox

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

Last change on this file since 93554 was 93554, checked in by vboxsync, 3 years ago

VMM: Changed PAGE_SIZE -> GUEST_PAGE_SIZE / HOST_PAGE_SIZE, PAGE_SHIFT -> GUEST_PAGE_SHIFT / HOST_PAGE_SHIFT, and PAGE_OFFSET_MASK -> GUEST_PAGE_OFFSET_MASK / HOST_PAGE_OFFSET_MASK. Also removed most usage of ASMMemIsZeroPage and ASMMemZeroPage since the host and guest page size doesn't need to be the same any more. Some work left to do in the page pool code. bugref:9898

  • 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 93554 2022-02-02 22:57:02Z 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-2022 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, HOST_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, HOST_PAGE_SIZE, _1M - 1);
89 //__debugbreak();
90 rc = RTR0MemObjEnterPhys(&g_hMemLowCore, 0x7000, HOST_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(HOST_PAGE_SIZE);
102 AssertReturn(g_pvSavedLowCore, VERR_NO_MEMORY);
103 memcpy(g_pvSavedLowCore, g_pbLowCore, HOST_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 <= HOST_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, HOST_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