VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR3/DBGFCpu.cpp@ 103583

Last change on this file since 103583 was 98972, checked in by vboxsync, 21 months ago

VMM: More ARMv8 x86/amd64 separation work, get past DBGF, bugref:10385

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.2 KB
Line 
1/* $Id: DBGFCpu.cpp 98972 2023-03-15 09:39:29Z vboxsync $ */
2/** @file
3 * DBGF - Debugger Facility, CPU State Accessors.
4 */
5
6/*
7 * Copyright (C) 2009-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_DBGF
33#define VMCPU_INCL_CPUM_GST_CTX /* For CPUM_IMPORT_EXTRN_RET(). */
34#include <VBox/vmm/dbgf.h>
35#include <VBox/vmm/cpum.h>
36#include "DBGFInternal.h"
37#include <VBox/vmm/vm.h>
38#include <VBox/vmm/uvm.h>
39#include <iprt/errcore.h>
40#include <VBox/log.h>
41#include <VBox/param.h>
42#include <iprt/assert.h>
43
44
45/**
46 * Wrapper around CPUMGetGuestMode.
47 *
48 * @returns VINF_SUCCESS.
49 * @param pVM The cross context VM structure.
50 * @param idCpu The current CPU ID.
51 * @param penmMode Where to return the mode.
52 */
53static DECLCALLBACK(int) dbgfR3CpuGetMode(PVM pVM, VMCPUID idCpu, CPUMMODE *penmMode)
54{
55 Assert(idCpu == VMMGetCpuId(pVM));
56 PVMCPU pVCpu = VMMGetCpuById(pVM, idCpu);
57#if defined(VBOX_VMM_TARGET_ARMV8)
58 CPUM_IMPORT_EXTRN_RET(pVCpu, CPUMCTX_EXTRN_PSTATE);
59#else
60 CPUM_IMPORT_EXTRN_RET(pVCpu, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_EFER);
61#endif
62 *penmMode = CPUMGetGuestMode(pVCpu);
63 return VINF_SUCCESS;
64}
65
66
67/**
68 * Get the current CPU mode.
69 *
70 * @returns The CPU mode on success, CPUMMODE_INVALID on failure.
71 * @param pUVM The user mode VM handle.
72 * @param idCpu The target CPU ID.
73 */
74VMMR3DECL(CPUMMODE) DBGFR3CpuGetMode(PUVM pUVM, VMCPUID idCpu)
75{
76 UVM_ASSERT_VALID_EXT_RETURN(pUVM, CPUMMODE_INVALID);
77 VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, CPUMMODE_INVALID);
78 AssertReturn(idCpu < pUVM->pVM->cCpus, CPUMMODE_INVALID);
79
80 CPUMMODE enmMode;
81 int rc = VMR3ReqPriorityCallWaitU(pUVM, idCpu, (PFNRT)dbgfR3CpuGetMode, 3, pUVM->pVM, idCpu, &enmMode);
82 if (RT_FAILURE(rc))
83 return CPUMMODE_INVALID;
84 return enmMode;
85}
86
87
88/**
89 * Wrapper around CPUMIsGuestIn64BitCode.
90 *
91 * @returns VINF_SUCCESS.
92 * @param pVM The cross context VM structure.
93 * @param idCpu The current CPU ID.
94 * @param pfIn64BitCode Where to return the result.
95 */
96static DECLCALLBACK(int) dbgfR3CpuIn64BitCode(PVM pVM, VMCPUID idCpu, bool *pfIn64BitCode)
97{
98 Assert(idCpu == VMMGetCpuId(pVM));
99 PVMCPU pVCpu = VMMGetCpuById(pVM, idCpu);
100#if defined(VBOX_VMM_TARGET_ARMV8)
101 CPUM_IMPORT_EXTRN_RET(pVCpu, CPUMCTX_EXTRN_PSTATE);
102#else
103 CPUM_IMPORT_EXTRN_RET(pVCpu, CPUMCTX_EXTRN_CS | CPUMCTX_EXTRN_EFER);
104#endif
105 *pfIn64BitCode = CPUMIsGuestIn64BitCode(pVCpu);
106 return VINF_SUCCESS;
107}
108
109
110/**
111 * Checks if the given CPU is executing 64-bit code or not.
112 *
113 * @returns true / false accordingly.
114 * @param pUVM The user mode VM handle.
115 * @param idCpu The target CPU ID.
116 */
117VMMR3DECL(bool) DBGFR3CpuIsIn64BitCode(PUVM pUVM, VMCPUID idCpu)
118{
119 UVM_ASSERT_VALID_EXT_RETURN(pUVM, false);
120 VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, false);
121 AssertReturn(idCpu < pUVM->pVM->cCpus, false);
122
123 bool fIn64BitCode;
124 int rc = VMR3ReqPriorityCallWaitU(pUVM, idCpu, (PFNRT)dbgfR3CpuIn64BitCode, 3, pUVM->pVM, idCpu, &fIn64BitCode);
125 if (RT_FAILURE(rc))
126 return false;
127 return fIn64BitCode;
128}
129
130
131#if !defined(VBOX_VMM_TARGET_ARMV8)
132/**
133 * Wrapper around CPUMIsGuestInV86Code.
134 *
135 * @returns VINF_SUCCESS.
136 * @param pVM The cross context VM structure.
137 * @param idCpu The current CPU ID.
138 * @param pfInV86Code Where to return the result.
139 */
140static DECLCALLBACK(int) dbgfR3CpuInV86Code(PVM pVM, VMCPUID idCpu, bool *pfInV86Code)
141{
142 Assert(idCpu == VMMGetCpuId(pVM));
143 PVMCPU pVCpu = VMMGetCpuById(pVM, idCpu);
144 CPUM_IMPORT_EXTRN_RET(pVCpu, CPUMCTX_EXTRN_RFLAGS);
145 *pfInV86Code = CPUMIsGuestInV86ModeEx(CPUMQueryGuestCtxPtr(pVCpu));
146 return VINF_SUCCESS;
147}
148#endif
149
150
151/**
152 * Checks if the given CPU is executing V8086 code or not.
153 *
154 * @returns true / false accordingly.
155 * @param pUVM The user mode VM handle.
156 * @param idCpu The target CPU ID.
157 */
158VMMR3DECL(bool) DBGFR3CpuIsInV86Code(PUVM pUVM, VMCPUID idCpu)
159{
160 UVM_ASSERT_VALID_EXT_RETURN(pUVM, false);
161 VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, false);
162 AssertReturn(idCpu < pUVM->pVM->cCpus, false);
163
164#if defined(VBOX_VMM_TARGET_ARMV8)
165 /* This is a public visible API, so we need to fill in a stub. */
166 return false;
167#else
168 bool fInV86Code;
169 int rc = VMR3ReqPriorityCallWaitU(pUVM, idCpu, (PFNRT)dbgfR3CpuInV86Code, 3, pUVM->pVM, idCpu, &fInV86Code);
170 if (RT_FAILURE(rc))
171 return false;
172 return fInV86Code;
173#endif
174}
175
176
177/**
178 * Get the number of CPUs (or threads if you insist).
179 *
180 * @returns The number of CPUs
181 * @param pUVM The user mode VM handle.
182 */
183VMMR3DECL(VMCPUID) DBGFR3CpuGetCount(PUVM pUVM)
184{
185 UVM_ASSERT_VALID_EXT_RETURN(pUVM, 1);
186 return pUVM->cCpus;
187}
188
189
190/**
191 * Returns the state of the given CPU as a human readable string.
192 *
193 * @returns Pointer to the human readable CPU state string.
194 * @param pUVM The user mode VM handle.
195 * @param idCpu The target CPU ID.
196 */
197VMMR3DECL(const char *) DBGFR3CpuGetState(PUVM pUVM, VMCPUID idCpu)
198{
199 UVM_ASSERT_VALID_EXT_RETURN(pUVM, NULL);
200 VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, NULL);
201 AssertReturn(idCpu < pUVM->pVM->cCpus, NULL);
202
203 PVMCPU pVCpu = VMMGetCpuById(pUVM->pVM, idCpu);
204 VMCPUSTATE enmCpuState = (VMCPUSTATE)ASMAtomicReadU32((volatile uint32_t *)&pVCpu->enmState);
205
206 switch (enmCpuState)
207 {
208 case VMCPUSTATE_INVALID: return "<INVALID>";
209 case VMCPUSTATE_STOPPED: return "Stopped";
210 case VMCPUSTATE_STARTED: return "Started";
211 case VMCPUSTATE_STARTED_HM: return "Started (HM)";
212 case VMCPUSTATE_STARTED_EXEC: return "Started (Exec)";
213 case VMCPUSTATE_STARTED_EXEC_NEM: return "Started (Exec NEM)";
214 case VMCPUSTATE_STARTED_EXEC_NEM_WAIT: return "Started (Exec NEM Wait)";
215 case VMCPUSTATE_STARTED_EXEC_NEM_CANCELED: return "Started (Exec NEM Canceled)";
216 case VMCPUSTATE_STARTED_HALTED: return "Started (Halted)";
217 case VMCPUSTATE_END: return "END";
218 default: break;
219 }
220
221 AssertMsgFailedReturn(("Unknown CPU state %u\n", enmCpuState), "<UNKNOWN>");
222}
223
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