VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/VMMAll.cpp@ 19475

最後變更 在這個檔案從19475是 19475,由 vboxsync 提交於 16 年 前

VMM: sending init IPI

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 5.6 KB
 
1/* $Id: VMMAll.cpp 19475 2009-05-07 10:55:17Z vboxsync $ */
2/** @file
3 * VMM All Contexts.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#define LOG_GROUP LOG_GROUP_VMM
27#include <VBox/vmm.h>
28#include "VMMInternal.h"
29#include <VBox/vm.h>
30#include <VBox/vmm.h>
31#include <VBox/param.h>
32#include <VBox/hwaccm.h>
33
34
35/**
36 * Gets the bottom of the hypervisor stack - RC Ptr.
37 *
38 * (The returned address is not actually writable, only after it's decremented
39 * by a push/ret/whatever does it become writable.)
40 *
41 * @returns bottom of the stack.
42 * @param pVM The VM handle.
43 */
44VMMDECL(RTRCPTR) VMMGetStackRC(PVM pVM)
45{
46 PVMCPU pVCpu = VMMGetCpu(pVM);
47 Assert(pVCpu);
48
49 return (RTRCPTR)pVCpu->vmm.s.pbEMTStackBottomRC;
50}
51
52
53/**
54 * Gets the ID virtual of the virtual CPU assoicated with the calling thread.
55 *
56 * @returns The CPU ID. NIL_VMCPUID if the thread isn't an EMT.
57 *
58 * @param pVM Pointer to the shared VM handle.
59 */
60VMMDECL(VMCPUID) VMMGetCpuId(PVM pVM)
61{
62#if defined(IN_RING3)
63 return VMR3GetVMCPUId(pVM);
64
65#elif defined(IN_RING0)
66 if (pVM->cCPUs == 1)
67 return 0;
68 return HWACCMR0GetVMCPUId(pVM);
69
70#else /* RC: Always EMT(0) */
71 return 0;
72#endif
73}
74
75
76#ifdef IN_RING3
77/**
78 * On VCPU worker for VMMSendSipi.
79 *
80 * @param pVM The VM to operate on.
81 * @param idCpu Virtual CPU to perform SIPI on
82 * @param uVector SIPI vector
83 */
84DECLCALLBACK(int) vmmR3SendSipi(PVM pVM, VMCPUID idCpu, uint32_t uVector)
85{
86 PVMCPU pVCpu = VMMGetCpuById(pVM, idCpu);
87 VMCPU_ASSERT_EMT(pVCpu);
88
89 /** @todo what are we supposed to do if the processor is already running? */
90 CPUMSetGuestCS(pVCpu, uVector * 0x100);
91 CPUMSetGuestEIP(pVCpu, 0);
92
93# if 1 /* If we keep the EMSTATE_WAIT_SIPI method, then move this to EM.cpp. */
94 return VINF_EM_RESCHEDULE;
95# else /* And if we go the VMCPU::enmState way it can stay here. */
96 VMCPU_ASSERT_STATE(pVCpu, VMCPUSTATE_STOPPED);
97 VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED);
98 return VINF_SUCCESS;
99# endif
100}
101
102DECLCALLBACK(int) vmmR3SendInitIpi(PVM pVM, VMCPUID idCpu)
103{
104 PVMCPU pVCpu = VMMGetCpuById(pVM, idCpu);
105 VMCPU_ASSERT_EMT(pVCpu);
106
107 /** @todo: reset CPU and halt till SIPI */
108
109 return VINF_SUCCESS;
110}
111
112/**
113 * Sends SIPI to the virtual CPU by setting CS:EIP into vector-dependent state
114 * and unhalting processor
115 *
116 * @param pVM The VM to operate on.
117 * @param idCpu Virtual CPU to perform SIPI on
118 * @param uVector SIPI vector
119 */
120VMMR3DECL(void) VMMR3SendSipi(PVM pVM, VMCPUID idCpu, uint32_t uVector)
121{
122 AssertReturnVoid(idCpu < pVM->cCPUs);
123
124 PVMREQ pReq;
125 int rc = VMR3ReqCallU(pVM->pUVM, idCpu, &pReq, RT_INDEFINITE_WAIT, 0,
126 (PFNRT)vmmR3SendSipi, 3, pVM, idCpu, uVector);
127 AssertRC(rc);
128 VMR3ReqFree(pReq);
129}
130
131/**
132 * Sends init IPI to the virtual CPU.
133 *
134 * @param pVM The VM to operate on.
135 * @param idCpu Virtual CPU to perform int IPI on
136 */
137VMMR3DECL(void) VMMR3SendInitIpi(PVM pVM, VMCPUID idCpu)
138{
139 AssertReturnVoid(idCpu < pVM->cCPUs);
140
141 PVMREQ pReq;
142 int rc = VMR3ReqCallU(pVM->pUVM, idCpu, &pReq, RT_INDEFINITE_WAIT, 0,
143 (PFNRT)vmmR3SendInitIpi, 2, pVM, idCpu);
144 AssertRC(rc);
145 VMR3ReqFree(pReq);
146}
147#endif /* IN_RING3 */
148
149
150/**
151 * Returns the VMCPU of the calling EMT.
152 *
153 * @returns The VMCPU pointer. NULL if not an EMT.
154 *
155 * @param pVM The VM to operate on.
156 */
157VMMDECL(PVMCPU) VMMGetCpu(PVM pVM)
158{
159#ifdef IN_RING3
160 VMCPUID idCpu = VMR3GetVMCPUId(pVM);
161 if (idCpu == NIL_VMCPUID)
162 return NULL;
163 Assert(idCpu < pVM->cCPUs);
164 return &pVM->aCpus[VMR3GetVMCPUId(pVM)];
165
166#elif defined(IN_RING0)
167 if (pVM->cCPUs == 1)
168 return &pVM->aCpus[0];
169 return HWACCMR0GetVMCPU(pVM);
170
171#else /* RC: Always EMT(0) */
172 return &pVM->aCpus[0];
173#endif /* IN_RING0 */
174}
175
176
177/**
178 * Returns the VMCPU of the first EMT thread.
179 *
180 * @returns The VMCPU pointer.
181 * @param pVM The VM to operate on.
182 */
183VMMDECL(PVMCPU) VMMGetCpu0(PVM pVM)
184{
185 Assert(pVM->cCPUs == 1);
186 return &pVM->aCpus[0];
187}
188
189
190/**
191 * Returns the VMCPU of the specified virtual CPU.
192 *
193 * @returns The VMCPU pointer. NULL if idCpu is invalid.
194 *
195 * @param pVM The VM to operate on.
196 * @param idCpu The ID of the virtual CPU.
197 */
198VMMDECL(PVMCPU) VMMGetCpuById(PVM pVM, RTCPUID idCpu)
199{
200 AssertReturn(idCpu < pVM->cCPUs, NULL);
201 return &pVM->aCpus[idCpu];
202}
203
204
205/**
206 * Gets the VBOX_SVN_REV.
207 *
208 * This is just to avoid having to compile a bunch of big files
209 * and requires less Makefile mess.
210 *
211 * @returns VBOX_SVN_REV.
212 */
213VMMDECL(uint32_t) VMMGetSvnRev(void)
214{
215 return VBOX_SVN_REV;
216}
217
218
219/**
220 * Queries the current switcher
221 *
222 * @returns active switcher
223 * @param pVM VM handle.
224 */
225VMMDECL(VMMSWITCHER) VMMGetSwitcher(PVM pVM)
226{
227 return pVM->vmm.s.enmSwitcher;
228}
229
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette