VirtualBox

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

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

VMM: better SIPI sending, reschedule to R3 as needed

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 5.0 KB
 
1/* $Id: VMMAll.cpp 19468 2009-05-07 09:03:15Z 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
102/**
103 * Sends SIPI to the virtual CPU by setting CS:EIP into vector-dependent state
104 * and unhalting processor
105 *
106 * @param pVM The VM to operate on.
107 * @param idCpu Virtual CPU to perform SIPI on
108 * @param uVector SIPI vector
109 */
110VMMR3DECL(void) VMMR3SendSipi(PVM pVM, VMCPUID idCpu, uint32_t uVector)
111{
112 AssertReturnVoid(idCpu < pVM->cCPUs);
113
114 PVMREQ pReq;
115 int rc = VMR3ReqCallU(pVM->pUVM, idCpu, &pReq, RT_INDEFINITE_WAIT, 0,
116 (PFNRT)vmmR3SendSipi, 3, pVM, idCpu, uVector);
117 AssertRC(rc);
118 VMR3ReqFree(pReq);
119}
120#endif /* IN_RING3 */
121
122
123/**
124 * Returns the VMCPU of the calling EMT.
125 *
126 * @returns The VMCPU pointer. NULL if not an EMT.
127 *
128 * @param pVM The VM to operate on.
129 */
130VMMDECL(PVMCPU) VMMGetCpu(PVM pVM)
131{
132#ifdef IN_RING3
133 VMCPUID idCpu = VMR3GetVMCPUId(pVM);
134 if (idCpu == NIL_VMCPUID)
135 return NULL;
136 Assert(idCpu < pVM->cCPUs);
137 return &pVM->aCpus[VMR3GetVMCPUId(pVM)];
138
139#elif defined(IN_RING0)
140 if (pVM->cCPUs == 1)
141 return &pVM->aCpus[0];
142 return HWACCMR0GetVMCPU(pVM);
143
144#else /* RC: Always EMT(0) */
145 return &pVM->aCpus[0];
146#endif /* IN_RING0 */
147}
148
149
150/**
151 * Returns the VMCPU of the first EMT thread.
152 *
153 * @returns The VMCPU pointer.
154 * @param pVM The VM to operate on.
155 */
156VMMDECL(PVMCPU) VMMGetCpu0(PVM pVM)
157{
158 Assert(pVM->cCPUs == 1);
159 return &pVM->aCpus[0];
160}
161
162
163/**
164 * Returns the VMCPU of the specified virtual CPU.
165 *
166 * @returns The VMCPU pointer. NULL if idCpu is invalid.
167 *
168 * @param pVM The VM to operate on.
169 * @param idCpu The ID of the virtual CPU.
170 */
171VMMDECL(PVMCPU) VMMGetCpuById(PVM pVM, RTCPUID idCpu)
172{
173 AssertReturn(idCpu < pVM->cCPUs, NULL);
174 return &pVM->aCpus[idCpu];
175}
176
177
178/**
179 * Gets the VBOX_SVN_REV.
180 *
181 * This is just to avoid having to compile a bunch of big files
182 * and requires less Makefile mess.
183 *
184 * @returns VBOX_SVN_REV.
185 */
186VMMDECL(uint32_t) VMMGetSvnRev(void)
187{
188 return VBOX_SVN_REV;
189}
190
191
192/**
193 * Queries the current switcher
194 *
195 * @returns active switcher
196 * @param pVM VM handle.
197 */
198VMMDECL(VMMSWITCHER) VMMGetSwitcher(PVM pVM)
199{
200 return pVM->vmm.s.enmSwitcher;
201}
202
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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