VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/PlatformARMImpl.cpp@ 107437

Last change on this file since 107437 was 106384, checked in by vboxsync, 3 months ago

Main: Code for configuring and enabling nested virtualization support on ARM (M3 based hardware + macOS 15.0 aka Sequioa), bugref:10747

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.7 KB
Line 
1/* $Id: PlatformARMImpl.cpp 106384 2024-10-16 13:58:41Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation - ARM platform settings.
4 */
5
6/*
7 * Copyright (C) 2023-2024 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#define LOG_GROUP LOG_GROUP_MAIN_PLATFORMARM
29#include "MachineImpl.h"
30#include "PlatformARMImpl.h"
31#include "PlatformImpl.h"
32#include "LoggingNew.h"
33
34#include "AutoStateDep.h"
35
36#include <VBox/settings.h>
37
38#include <iprt/cpp/utils.h>
39
40
41/**
42 * ARM-specific platform data.
43 *
44 * This data is unique for a machine and for every machine snapshot.
45 * Stored using the util::Backupable template in the |mPlatformARMData| variable.
46 *
47 * SessionMachine instances can alter this data and discard changes.
48 */
49struct Data
50{
51 Data() { }
52
53 ComObjPtr<PlatformARM> pPeer;
54
55 // use the XML settings structure in the members for simplicity
56 Backupable<settings::PlatformARM> bd;
57};
58
59
60/*
61 * PlatformARM implementation.
62 */
63PlatformARM::PlatformARM()
64{
65}
66
67PlatformARM::~PlatformARM()
68{
69 uninit();
70}
71
72HRESULT PlatformARM::FinalConstruct()
73{
74 return BaseFinalConstruct();
75}
76
77void PlatformARM::FinalRelease()
78{
79 uninit();
80
81 BaseFinalRelease();
82}
83
84HRESULT PlatformARM::init(Platform *aParent, Machine *aMachine)
85{
86 /* Enclose the state transition NotReady->InInit->Ready */
87 AutoInitSpan autoInitSpan(this);
88 AssertReturn(autoInitSpan.isOk(), E_FAIL);
89
90 /* share the parent + machine weakly */
91 unconst(mParent) = aParent;
92 unconst(mMachine) = aMachine;
93
94 m = new Data;
95 m->bd.allocate();
96
97 autoInitSpan.setSucceeded();
98
99 return S_OK;
100}
101
102/**
103 * Initializes the platform object given another platform object
104 * (a kind of copy constructor). This object shares data with
105 * the object passed as an argument.
106 *
107 * @note This object must be destroyed before the original object
108 * it shares data with is destroyed.
109 */
110HRESULT PlatformARM::init(Platform *aParent, Machine *aMachine, PlatformARM *aThat)
111{
112 /* Enclose the state transition NotReady->InInit->Ready */
113 AutoInitSpan autoInitSpan(this);
114 AssertReturn(autoInitSpan.isOk(), E_FAIL);
115
116 ComAssertRet(aParent && aParent, E_INVALIDARG);
117
118 unconst(mParent) = aParent;
119 unconst(mMachine) = aMachine;
120
121 m = new Data();
122 m->pPeer = aThat;
123
124 AutoWriteLock thatlock(aThat COMMA_LOCKVAL_SRC_POS);
125 m->bd.share(aThat->m->bd);
126
127 autoInitSpan.setSucceeded();
128
129 return S_OK;
130}
131
132/**
133 * Initializes the guest object given another guest object
134 * (a kind of copy constructor). This object makes a private copy of data
135 * of the original object passed as an argument.
136 */
137HRESULT PlatformARM::initCopy(Platform *aParent, Machine *aMachine, PlatformARM *aThat)
138{
139 ComAssertRet(aParent && aParent, E_INVALIDARG);
140
141 /* Enclose the state transition NotReady->InInit->Ready */
142 AutoInitSpan autoInitSpan(this);
143 AssertReturn(autoInitSpan.isOk(), E_FAIL);
144
145 unconst(mParent) = aParent;
146 unconst(mMachine) = aMachine;
147
148 m = new Data();
149 // m->pPeer is left null
150
151 AutoWriteLock thatlock(aThat COMMA_LOCKVAL_SRC_POS); /** @todo r=andy Shouldn't a read lock be sufficient here? */
152 m->bd.attachCopy(aThat->m->bd);
153
154 autoInitSpan.setSucceeded();
155
156 return S_OK;
157}
158
159void PlatformARM::uninit()
160{
161 /* Enclose the state transition Ready->InUninit->NotReady */
162 AutoUninitSpan autoUninitSpan(this);
163 if (autoUninitSpan.uninitDone())
164 return;
165
166 unconst(mMachine) = NULL;
167
168 if (m)
169 {
170 m->bd.free();
171 unconst(m->pPeer) = NULL;
172
173 delete m;
174 m = NULL;
175 }
176}
177
178void PlatformARM::i_rollback()
179{
180 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
181 if (m)
182 m->bd.rollback();
183}
184
185void PlatformARM::i_commit()
186{
187 /* sanity */
188 AutoCaller autoCaller(this);
189 AssertComRCReturnVoid(autoCaller.hrc());
190
191 /* sanity too */
192 AutoCaller peerCaller(m->pPeer);
193 AssertComRCReturnVoid(peerCaller.hrc());
194
195 /* lock both for writing since we modify both (mPeer is "master" so locked
196 * first) */
197 AutoMultiWriteLock2 alock(m->pPeer, this COMMA_LOCKVAL_SRC_POS);
198
199 if (m->bd.isBackedUp())
200 {
201 m->bd.commit();
202 if (m->pPeer)
203 {
204 /* attach new data to the peer and reshare it */
205 AutoWriteLock peerlock(m->pPeer COMMA_LOCKVAL_SRC_POS);
206 m->pPeer->m->bd.attach(m->bd);
207 }
208 }
209}
210
211void PlatformARM::i_copyFrom(PlatformARM *aThat)
212{
213 AssertReturnVoid(aThat != NULL);
214
215 /* sanity */
216 AutoCaller autoCaller(this);
217 AssertComRCReturnVoid(autoCaller.hrc());
218
219 /* sanity too */
220 AutoCaller thatCaller(aThat);
221 AssertComRCReturnVoid(thatCaller.hrc());
222
223 /* peer is not modified, lock it for reading (aThat is "master" so locked
224 * first) */
225 AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS);
226 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
227
228 /* this will back up current data */
229 m->bd.assignCopy(aThat->m->bd);
230}
231
232/**
233 * Loads settings from the given platform ARM node.
234 * May be called once right after this object creation.
235 *
236 * @returns HRESULT
237 * @param data Configuration settings.
238 *
239 * @note Locks this object for writing.
240 */
241HRESULT PlatformARM::i_loadSettings(const settings::PlatformARM &data)
242{
243 AutoCaller autoCaller(this);
244 AssertComRCReturnRC(autoCaller.hrc());
245
246 AutoReadLock mlock(mMachine COMMA_LOCKVAL_SRC_POS);
247 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
248
249 // simply copy
250 m->bd.assignCopy(&data);
251 return S_OK;
252}
253
254/**
255 * Saves settings to the given platform ARM node.
256 *
257 * @returns HRESULT
258 * @param data Configuration settings.
259 *
260 * @note Locks this object for reading.
261 */
262HRESULT PlatformARM::i_saveSettings(settings::PlatformARM &data)
263{
264 AutoCaller autoCaller(this);
265 AssertComRCReturnRC(autoCaller.hrc());
266
267 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
268
269 data = *m->bd.data();
270
271 return S_OK;
272}
273
274HRESULT PlatformARM::i_applyDefaults(GuestOSType *aOsType)
275{
276 RT_NOREF(aOsType);
277
278 /* Nothing here yet. */
279 return S_OK;
280}
281
282HRESULT PlatformARM::getCPUProperty(CPUPropertyTypeARM_T aProperty, BOOL *aValue)
283{
284 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
285
286 switch (aProperty)
287 {
288 case CPUPropertyTypeARM_HWVirt:
289 *aValue = m->bd->fNestedHWVirt;
290 break;
291
292 default:
293 return E_INVALIDARG;
294 }
295 return S_OK;
296}
297
298HRESULT PlatformARM::setCPUProperty(CPUPropertyTypeARM_T aProperty, BOOL aValue)
299{
300 /* sanity */
301 AutoCaller autoCaller(this);
302 AssertComRCReturnRC(autoCaller.hrc());
303
304 /* the machine needs to be mutable */
305 AutoMutableStateDependency adep(mMachine);
306 if (FAILED(adep.hrc())) return adep.hrc();
307
308 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
309
310 switch (aProperty)
311 {
312 case CPUPropertyTypeARM_HWVirt:
313 {
314 m->bd.backup();
315 m->bd->fNestedHWVirt = !!aValue;
316 break;
317 }
318
319 default:
320 return E_INVALIDARG;
321 }
322
323 alock.release();
324
325 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
326 mMachine->i_setModified(Machine::IsModified_Platform);
327
328 return S_OK;
329}
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