VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/PlatformX86Impl.cpp@ 101057

最後變更 在這個檔案從101057是 101054,由 vboxsync 提交於 19 月 前

Main: More checks for (un)supported platforms. See comments for details. bugref:10384

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 25.7 KB
 
1/* $Id: PlatformX86Impl.cpp 101054 2023-09-07 13:59:53Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation - x86 platform settings.
4 */
5
6/*
7 * Copyright (C) 2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.alldomusa.eu.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_PLATFORMX86
29#include "MachineImpl.h"
30#include "PlatformX86Impl.h"
31#include "PlatformImpl.h"
32#include "LoggingNew.h"
33
34#include "AutoStateDep.h"
35
36#include <iprt/cpp/utils.h>
37
38#include <VBox/settings.h>
39
40
41/**
42 * x86-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 |mPlatformX86Data| variable.
46 *
47 * SessionMachine instances can alter this data and discard changes.
48 */
49struct Data
50{
51 Data() { }
52
53 ComObjPtr<PlatformX86> pPeer;
54
55 // use the XML settings structure in the members for simplicity
56 Backupable<settings::PlatformX86> bd;
57};
58
59
60/*
61 * PlatformX86 implementation.
62 */
63PlatformX86::PlatformX86()
64{
65}
66
67PlatformX86::~PlatformX86()
68{
69 uninit();
70}
71
72HRESULT PlatformX86::FinalConstruct()
73{
74 return BaseFinalConstruct();
75}
76
77void PlatformX86::FinalRelease()
78{
79 uninit();
80
81 BaseFinalRelease();
82}
83
84HRESULT PlatformX86::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 m = new Data;
91
92 /* share the parent + machine weakly */
93 unconst(mParent) = aParent;
94 unconst(mMachine) = aMachine;
95
96 m->bd.allocate();
97
98 /* Confirm a successful initialization */
99 autoInitSpan.setSucceeded();
100
101 return S_OK;
102}
103
104/**
105 * Initializes the platform object given another platform object
106 * (a kind of copy constructor). This object shares data with
107 * the object passed as an argument.
108 *
109 * @note This object must be destroyed before the original object
110 * it shares data with is destroyed.
111 */
112HRESULT PlatformX86::init(Platform *aParent, Machine *aMachine, PlatformX86 *aThat)
113{
114 /* Enclose the state transition NotReady->InInit->Ready */
115 AutoInitSpan autoInitSpan(this);
116 AssertReturn(autoInitSpan.isOk(), E_FAIL);
117
118 ComAssertRet(aParent && aParent, E_INVALIDARG);
119
120 unconst(mParent) = aParent;
121 unconst(mMachine) = aMachine;
122
123 m = new Data();
124 m->pPeer = aThat;
125
126 AutoWriteLock thatlock(aThat COMMA_LOCKVAL_SRC_POS);
127 m->bd.share(aThat->m->bd);
128
129 autoInitSpan.setSucceeded();
130
131 return S_OK;
132}
133
134/**
135 * Initializes the guest object given another guest object
136 * (a kind of copy constructor). This object makes a private copy of data
137 * of the original object passed as an argument.
138 */
139HRESULT PlatformX86::initCopy(Platform *aParent, Machine *aMachine, PlatformX86 *aThat)
140{
141 ComAssertRet(aParent && aParent, E_INVALIDARG);
142
143 /* Enclose the state transition NotReady->InInit->Ready */
144 AutoInitSpan autoInitSpan(this);
145 AssertReturn(autoInitSpan.isOk(), E_FAIL);
146
147 unconst(mParent) = aParent;
148 unconst(mMachine) = aMachine;
149
150 m = new Data();
151 // m->pPeer is left null
152
153 AutoWriteLock thatlock(aThat COMMA_LOCKVAL_SRC_POS); /** @todo r=andy Shouldn't a read lock be sufficient here? */
154 m->bd.attachCopy(aThat->m->bd);
155
156 autoInitSpan.setSucceeded();
157
158 return S_OK;
159}
160
161void PlatformX86::uninit()
162{
163 /* Enclose the state transition Ready->InUninit->NotReady */
164 AutoUninitSpan autoUninitSpan(this);
165 if (autoUninitSpan.uninitDone())
166 return;
167
168 unconst(mMachine) = NULL;
169
170 if (m)
171 {
172 m->bd.free();
173 unconst(m->pPeer) = NULL;
174
175 delete m;
176 m = NULL;
177 }
178}
179
180void PlatformX86::i_rollback()
181{
182 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
183 if (m)
184 m->bd.rollback();
185}
186
187void PlatformX86::i_commit()
188{
189 /* sanity */
190 AutoCaller autoCaller(this);
191 AssertComRCReturnVoid(autoCaller.hrc());
192
193 /* sanity too */
194 AutoCaller peerCaller(m->pPeer);
195 AssertComRCReturnVoid(peerCaller.hrc());
196
197 /* lock both for writing since we modify both (mPeer is "master" so locked
198 * first) */
199 AutoMultiWriteLock2 alock(m->pPeer, this COMMA_LOCKVAL_SRC_POS);
200
201 if (m->bd.isBackedUp())
202 {
203 m->bd.commit();
204 if (m->pPeer)
205 {
206 /* attach new data to the peer and reshare it */
207 AutoWriteLock peerlock(m->pPeer COMMA_LOCKVAL_SRC_POS);
208 m->pPeer->m->bd.attach(m->bd);
209 }
210 }
211}
212
213void PlatformX86::i_copyFrom(PlatformX86 *aThat)
214{
215 AssertReturnVoid(aThat != NULL);
216
217 /* sanity */
218 AutoCaller autoCaller(this);
219 AssertComRCReturnVoid(autoCaller.hrc());
220
221 /* sanity too */
222 AutoCaller thatCaller(aThat);
223 AssertComRCReturnVoid(thatCaller.hrc());
224
225 /* peer is not modified, lock it for reading (aThat is "master" so locked
226 * first) */
227 AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS);
228 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
229
230 /* this will back up current data */
231 m->bd.assignCopy(aThat->m->bd);
232}
233
234HRESULT PlatformX86::getHPETEnabled(BOOL *aHPETEnabled)
235{
236 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
237
238 *aHPETEnabled = m->bd->fHPETEnabled;
239
240 return S_OK;
241}
242
243HRESULT PlatformX86::setHPETEnabled(BOOL aHPETEnabled)
244{
245 /* the machine needs to be mutable */
246 AutoMutableStateDependency adep(mMachine);
247 if (FAILED(adep.hrc())) return adep.hrc();
248
249 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
250
251 m->bd.backup();
252 m->bd->fHPETEnabled = aHPETEnabled;
253
254 alock.release();
255
256 AutoWriteLock mlock(mMachine COMMA_LOCKVAL_SRC_POS);
257 mMachine->i_setModified(Machine::IsModified_Platform);
258
259 return S_OK;
260}
261
262HRESULT PlatformX86::getCPUProperty(CPUPropertyTypeX86_T aProperty, BOOL *aValue)
263{
264 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
265
266 switch (aProperty)
267 {
268 case CPUPropertyTypeX86_PAE:
269 *aValue = m->bd->fPAE;
270 break;
271
272 case CPUPropertyTypeX86_LongMode:
273 if (m->bd->enmLongMode == settings::PlatformX86::LongMode_Enabled)
274 *aValue = TRUE;
275 else if (m->bd->enmLongMode == settings::PlatformX86::LongMode_Disabled)
276 *aValue = FALSE;
277#if HC_ARCH_BITS == 64
278 else
279 *aValue = TRUE;
280#else
281 else
282 {
283 *aValue = FALSE;
284
285 ComObjPtr<GuestOSType> pGuestOSType;
286 HRESULT hrc2 = mParent->i_findGuestOSType(mUserData->s.strOsType,
287 pGuestOSType);
288 if (SUCCEEDED(hrc2) && !pGuestOSType.isNull())
289 {
290 if (pGuestOSType->i_is64Bit())
291 {
292 ComObjPtr<Host> pHost = mParent->i_host();
293 alock.release();
294
295 hrc2 = pHost->GetProcessorFeature(ProcessorFeature_LongMode, aValue); AssertComRC(hrc2);
296 if (FAILED(hrc2))
297 *aValue = FALSE;
298 }
299 }
300 }
301#endif
302 break;
303
304 case CPUPropertyTypeX86_TripleFaultReset:
305 *aValue = m->bd->fTripleFaultReset;
306 break;
307
308 case CPUPropertyTypeX86_APIC:
309 *aValue = m->bd->fAPIC;
310 break;
311
312 case CPUPropertyTypeX86_X2APIC:
313 *aValue = m->bd->fX2APIC;
314 break;
315
316 case CPUPropertyTypeX86_IBPBOnVMExit:
317 *aValue = m->bd->fIBPBOnVMExit;
318 break;
319
320 case CPUPropertyTypeX86_IBPBOnVMEntry:
321 *aValue = m->bd->fIBPBOnVMEntry;
322 break;
323
324 case CPUPropertyTypeX86_SpecCtrl:
325 *aValue = m->bd->fSpecCtrl;
326 break;
327
328 case CPUPropertyTypeX86_SpecCtrlByHost:
329 *aValue = m->bd->fSpecCtrlByHost;
330 break;
331
332 case CPUPropertyTypeX86_HWVirt:
333 *aValue = m->bd->fNestedHWVirt;
334 break;
335
336 case CPUPropertyTypeX86_L1DFlushOnEMTScheduling:
337 *aValue = m->bd->fL1DFlushOnSched;
338 break;
339
340 case CPUPropertyTypeX86_L1DFlushOnVMEntry:
341 *aValue = m->bd->fL1DFlushOnVMEntry;
342 break;
343
344 case CPUPropertyTypeX86_MDSClearOnEMTScheduling:
345 *aValue = m->bd->fMDSClearOnSched;
346 break;
347
348 case CPUPropertyTypeX86_MDSClearOnVMEntry:
349 *aValue = m->bd->fMDSClearOnVMEntry;
350 break;
351
352 default:
353 return E_INVALIDARG;
354 }
355 return S_OK;
356}
357
358HRESULT PlatformX86::setCPUProperty(CPUPropertyTypeX86_T aProperty, BOOL aValue)
359{
360 /* sanity */
361 AutoCaller autoCaller(this);
362 AssertComRCReturnRC(autoCaller.hrc());
363
364 /* the machine needs to be mutable */
365 AutoMutableStateDependency adep(mMachine);
366 if (FAILED(adep.hrc())) return adep.hrc();
367
368 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
369
370 switch (aProperty)
371 {
372 case CPUPropertyTypeX86_PAE:
373 {
374 m->bd.backup();
375 m->bd->fPAE = !!aValue;
376 break;
377 }
378
379 case CPUPropertyTypeX86_LongMode:
380 {
381 m->bd.backup();
382 m->bd->enmLongMode = !aValue ? settings::PlatformX86::LongMode_Disabled : settings::PlatformX86::LongMode_Enabled;
383 break;
384 }
385
386 case CPUPropertyTypeX86_TripleFaultReset:
387 {
388 m->bd.backup();
389 m->bd->fTripleFaultReset = !!aValue;
390 break;
391 }
392
393 case CPUPropertyTypeX86_APIC:
394 {
395 if (m->bd->fX2APIC)
396 aValue = TRUE;
397 m->bd.backup();
398 m->bd->fAPIC = !!aValue;
399 break;
400 }
401
402 case CPUPropertyTypeX86_X2APIC:
403 {
404 m->bd.backup();
405 m->bd->fX2APIC = !!aValue;
406 if (aValue)
407 m->bd->fAPIC = !!aValue;
408 break;
409 }
410
411 case CPUPropertyTypeX86_IBPBOnVMExit:
412 {
413 m->bd.backup();
414 m->bd->fIBPBOnVMExit = !!aValue;
415 break;
416 }
417
418 case CPUPropertyTypeX86_IBPBOnVMEntry:
419 {
420 m->bd.backup();
421 m->bd->fIBPBOnVMEntry = !!aValue;
422 break;
423 }
424
425 case CPUPropertyTypeX86_SpecCtrl:
426 {
427 m->bd.backup();
428 m->bd->fSpecCtrl = !!aValue;
429 break;
430 }
431
432 case CPUPropertyTypeX86_SpecCtrlByHost:
433 {
434 m->bd.backup();
435 m->bd->fSpecCtrlByHost = !!aValue;
436 break;
437 }
438
439 case CPUPropertyTypeX86_HWVirt:
440 {
441 m->bd.backup();
442 m->bd->fNestedHWVirt = !!aValue;
443 break;
444 }
445
446 case CPUPropertyTypeX86_L1DFlushOnEMTScheduling:
447 {
448 m->bd.backup();
449 m->bd->fL1DFlushOnSched = !!aValue;
450 break;
451 }
452
453 case CPUPropertyTypeX86_L1DFlushOnVMEntry:
454 {
455 m->bd.backup();
456 m->bd->fL1DFlushOnVMEntry = !!aValue;
457 break;
458 }
459
460 case CPUPropertyTypeX86_MDSClearOnEMTScheduling:
461 {
462 m->bd.backup();
463 m->bd->fMDSClearOnSched = !!aValue;
464 break;
465 }
466
467 case CPUPropertyTypeX86_MDSClearOnVMEntry:
468 {
469 m->bd.backup();
470 m->bd->fMDSClearOnVMEntry = !!aValue;
471 break;
472 }
473
474 default:
475 return E_INVALIDARG;
476 }
477
478 alock.release();
479
480 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
481 mMachine->i_setModified(Machine::IsModified_Platform);
482
483 return S_OK;
484}
485
486HRESULT PlatformX86::getCPUIDLeafByOrdinal(ULONG aOrdinal, ULONG *aIdx, ULONG *aSubIdx, ULONG *aValEax, ULONG *aValEbx,
487 ULONG *aValEcx, ULONG *aValEdx)
488{
489 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
490 if (aOrdinal < m->bd->llCpuIdLeafs.size())
491 {
492 for (settings::CpuIdLeafsX86List::const_iterator it = m->bd->llCpuIdLeafs.begin();
493 it != m->bd->llCpuIdLeafs.end();
494 ++it)
495 {
496 if (aOrdinal == 0)
497 {
498 const settings::CpuIdLeafX86 &rLeaf= *it;
499 *aIdx = rLeaf.idx;
500 *aSubIdx = rLeaf.idxSub;
501 *aValEax = rLeaf.uEax;
502 *aValEbx = rLeaf.uEbx;
503 *aValEcx = rLeaf.uEcx;
504 *aValEdx = rLeaf.uEdx;
505 return S_OK;
506 }
507 aOrdinal--;
508 }
509 }
510 return E_INVALIDARG;
511}
512
513HRESULT PlatformX86::getCPUIDLeaf(ULONG aIdx, ULONG aSubIdx, ULONG *aValEax, ULONG *aValEbx, ULONG *aValEcx, ULONG *aValEdx)
514{
515 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
516
517 /*
518 * Search the list.
519 */
520 for (settings::CpuIdLeafsX86List::const_iterator it = m->bd->llCpuIdLeafs.begin();
521 it != m->bd->llCpuIdLeafs.end();
522 ++it)
523 {
524 const settings::CpuIdLeafX86 &rLeaf= *it;
525 if ( rLeaf.idx == aIdx
526 && ( aSubIdx == UINT32_MAX
527 || rLeaf.idxSub == aSubIdx) )
528 {
529 *aValEax = rLeaf.uEax;
530 *aValEbx = rLeaf.uEbx;
531 *aValEcx = rLeaf.uEcx;
532 *aValEdx = rLeaf.uEdx;
533 return S_OK;
534 }
535 }
536
537 return E_INVALIDARG;
538}
539
540HRESULT PlatformX86::setCPUIDLeaf(ULONG aIdx, ULONG aSubIdx, ULONG aValEax, ULONG aValEbx, ULONG aValEcx, ULONG aValEdx)
541{
542 /* sanity */
543 AutoCaller autoCaller(this);
544 AssertComRCReturnRC(autoCaller.hrc());
545
546 /*
547 * Validate input before taking locks and checking state.
548 */
549 if (aSubIdx != 0 && aSubIdx != UINT32_MAX)
550 return setError(E_INVALIDARG, tr("Currently only aSubIdx values 0 and 0xffffffff are supported: %#x"), aSubIdx);
551 if ( aIdx >= UINT32_C(0x20)
552 && aIdx - UINT32_C(0x80000000) >= UINT32_C(0x20)
553 && aIdx - UINT32_C(0xc0000000) >= UINT32_C(0x10) )
554 return setError(E_INVALIDARG, tr("CpuId override leaf %#x is out of range"), aIdx);
555
556 /* the machine needs to be mutable */
557 AutoMutableStateDependency adep(mMachine);
558 if (FAILED(adep.hrc())) return adep.hrc();
559
560 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
561
562 /*
563 * Impose a maximum number of leaves.
564 */
565 if (m->bd->llCpuIdLeafs.size() > 256)
566 return setError(E_FAIL, tr("Max of 256 CPUID override leaves reached"));
567
568 /*
569 * Updating the list is a bit more complicated. So, let's do a remove first followed by an insert.
570 */
571 m->bd.backup();
572
573 for (settings::CpuIdLeafsX86List::iterator it = m->bd->llCpuIdLeafs.begin(); it != m->bd->llCpuIdLeafs.end(); )
574 {
575 settings::CpuIdLeafX86 &rLeaf= *it;
576 if ( rLeaf.idx == aIdx
577 && ( aSubIdx == UINT32_MAX
578 || rLeaf.idxSub == aSubIdx) )
579 it = m->bd->llCpuIdLeafs.erase(it);
580 else
581 ++it;
582 }
583
584 settings::CpuIdLeafX86 NewLeaf;
585 NewLeaf.idx = aIdx;
586 NewLeaf.idxSub = aSubIdx == UINT32_MAX ? 0 : aSubIdx;
587 NewLeaf.uEax = aValEax;
588 NewLeaf.uEbx = aValEbx;
589 NewLeaf.uEcx = aValEcx;
590 NewLeaf.uEdx = aValEdx;
591 m->bd->llCpuIdLeafs.push_back(NewLeaf);
592
593 alock.release();
594
595 AutoWriteLock mlock(mMachine COMMA_LOCKVAL_SRC_POS);
596 mMachine->i_setModified(Machine::IsModified_Platform);
597
598 return S_OK;
599}
600
601HRESULT PlatformX86::removeCPUIDLeaf(ULONG aIdx, ULONG aSubIdx)
602{
603 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
604
605 AutoWriteLock mlock(mMachine COMMA_LOCKVAL_SRC_POS);
606 HRESULT hrc = mMachine->i_checkStateDependency(Machine::MutableStateDep);
607 if (FAILED(hrc)) return hrc;
608
609 /*
610 * Do the removal.
611 */
612 bool fModified = m->bd.isBackedUp();
613 for (settings::CpuIdLeafsX86List::iterator it = m->bd->llCpuIdLeafs.begin(); it != m->bd->llCpuIdLeafs.end(); )
614 {
615 settings::CpuIdLeafX86 &rLeaf= *it;
616 if ( rLeaf.idx == aIdx
617 && ( aSubIdx == UINT32_MAX
618 || rLeaf.idxSub == aSubIdx) )
619 {
620 if (!fModified)
621 {
622 fModified = true;
623 mMachine->i_setModified(Machine::IsModified_Platform);
624 m->bd.backup();
625 // Start from the beginning, since m->bd.backup() creates
626 // a new list, causing iterator mixup. This makes sure that
627 // the settings are not unnecessarily marked as modified,
628 // at the price of extra list walking.
629 it = m->bd->llCpuIdLeafs.begin();
630 }
631 else
632 it = m->bd->llCpuIdLeafs.erase(it);
633 }
634 else
635 ++it;
636 }
637
638 return S_OK;
639}
640
641HRESULT PlatformX86::removeAllCPUIDLeaves()
642{
643 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
644
645 AutoWriteLock mlock(mMachine COMMA_LOCKVAL_SRC_POS);
646 HRESULT hrc = mMachine->i_checkStateDependency(Machine::MutableStateDep);
647 if (FAILED(hrc)) return hrc;
648
649 if (m->bd->llCpuIdLeafs.size() > 0)
650 {
651 mMachine->i_setModified(Machine::IsModified_Platform);
652 m->bd.backup();
653
654 m->bd->llCpuIdLeafs.clear();
655 }
656
657 return S_OK;
658}
659
660HRESULT PlatformX86::getHWVirtExProperty(HWVirtExPropertyType_T aProperty, BOOL *aValue)
661{
662 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
663
664 switch(aProperty)
665 {
666 case HWVirtExPropertyType_Enabled:
667 *aValue = m->bd->fHWVirtEx;
668 break;
669
670 case HWVirtExPropertyType_VPID:
671 *aValue = m->bd->fHWVirtExVPID;
672 break;
673
674 case HWVirtExPropertyType_NestedPaging:
675 *aValue = m->bd->fHWVirtExNestedPaging;
676 break;
677
678 case HWVirtExPropertyType_UnrestrictedExecution:
679 *aValue = m->bd->fHWVirtExUX;
680 break;
681
682 case HWVirtExPropertyType_LargePages:
683 *aValue = m->bd->fHWVirtExLargePages;
684 break;
685
686 case HWVirtExPropertyType_Force:
687 *aValue = m->bd->fHWVirtExForce;
688 break;
689
690 case HWVirtExPropertyType_UseNativeApi:
691 *aValue = m->bd->fHWVirtExUseNativeApi;
692 break;
693
694 case HWVirtExPropertyType_VirtVmsaveVmload:
695 *aValue = m->bd->fHWVirtExVirtVmsaveVmload;
696 break;
697
698 default:
699 return E_INVALIDARG;
700 }
701 return S_OK;
702}
703
704HRESULT PlatformX86::setHWVirtExProperty(HWVirtExPropertyType_T aProperty, BOOL aValue)
705{
706 /* sanity */
707 AutoCaller autoCaller(this);
708 AssertComRCReturnRC(autoCaller.hrc());
709
710 /* the machine needs to be mutable */
711 AutoMutableStateDependency adep(mMachine);
712 if (FAILED(adep.hrc())) return adep.hrc();
713
714 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
715
716 switch (aProperty)
717 {
718 case HWVirtExPropertyType_Enabled:
719 {
720 m->bd.backup();
721 m->bd->fHWVirtEx = !!aValue;
722 break;
723 }
724
725 case HWVirtExPropertyType_VPID:
726 {
727 m->bd.backup();
728 m->bd->fHWVirtExVPID = !!aValue;
729 break;
730 }
731
732 case HWVirtExPropertyType_NestedPaging:
733 {
734 m->bd.backup();
735 m->bd->fHWVirtExNestedPaging = !!aValue;
736 break;
737 }
738
739 case HWVirtExPropertyType_UnrestrictedExecution:
740 {
741 m->bd.backup();
742 m->bd->fHWVirtExUX = !!aValue;
743 break;
744 }
745
746 case HWVirtExPropertyType_LargePages:
747 {
748 m->bd.backup();
749 m->bd->fHWVirtExLargePages = !!aValue;
750 break;
751 }
752
753 case HWVirtExPropertyType_Force:
754 {
755 m->bd.backup();
756 m->bd->fHWVirtExForce = !!aValue;
757 break;
758 }
759
760 case HWVirtExPropertyType_UseNativeApi:
761 {
762 m->bd.backup();
763 m->bd->fHWVirtExUseNativeApi = !!aValue;
764 break;
765 }
766
767 case HWVirtExPropertyType_VirtVmsaveVmload:
768 {
769 m->bd.backup();
770 m->bd->fHWVirtExVirtVmsaveVmload = !!aValue;
771 break;
772 }
773
774 default:
775 return E_INVALIDARG;
776 }
777
778 alock.release();
779
780 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
781 mMachine->i_setModified(Machine::IsModified_Platform);
782
783 return S_OK;
784}
785
786// public methods only for internal purposes
787////////////////////////////////////////////////////////////////////////////////
788
789#if 0
790void PlatformX86::i_copyFrom(PlatformX86 *aThat)
791{
792 AssertReturnVoid(aThat != NULL);
793
794 /* sanity */
795 AutoCaller autoCaller(this);
796 AssertComRCReturnVoid(autoCaller.hrc());
797
798 /* sanity too */
799 AutoCaller thatCaller(aThat);
800 AssertComRCReturnVoid(thatCaller.hrc());
801
802 /* peer is not modified, lock it for reading (aThat is "master" so locked
803 * first) */
804 AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS);
805 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
806
807 /* this will back up current data */
808 m->bd.assignCopy(aThat->m->bd);
809}
810#endif
811
812/**
813 * Loads settings from the given platform x86 node.
814 * May be called once right after this object creation.
815 *
816 * @returns HRESULT
817 * @param data Configuration settings.
818 *
819 * @note Locks this object for writing.
820 */
821HRESULT PlatformX86::i_loadSettings(const settings::PlatformX86 &data)
822{
823 AutoCaller autoCaller(this);
824 AssertComRCReturnRC(autoCaller.hrc());
825
826 AutoReadLock mlock(mMachine COMMA_LOCKVAL_SRC_POS);
827 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
828
829 // cpuid leafs
830 for (settings::CpuIdLeafsX86List::const_iterator
831 it = data.llCpuIdLeafs.begin();
832 it != data.llCpuIdLeafs.end();
833 ++it)
834 {
835 const settings::CpuIdLeafX86 &rLeaf= *it;
836 if ( rLeaf.idx < UINT32_C(0x20)
837 || rLeaf.idx - UINT32_C(0x80000000) < UINT32_C(0x20)
838 || rLeaf.idx - UINT32_C(0xc0000000) < UINT32_C(0x10) )
839 m->bd->llCpuIdLeafs.push_back(rLeaf);
840 /* else: just ignore */
841 }
842
843 // simply copy
844 m->bd.assignCopy(&data);
845 return S_OK;
846}
847
848/**
849 * Saves settings to the given platform x86 node.
850 *
851 * @returns HRESULT
852 * @param data Configuration settings.
853 *
854 * @note Locks this object for reading.
855 */
856HRESULT PlatformX86::i_saveSettings(settings::PlatformX86 &data)
857{
858 AutoCaller autoCaller(this);
859 AssertComRCReturnRC(autoCaller.hrc());
860
861 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
862
863 /* Standard and Extended CPUID leafs. */
864 data.llCpuIdLeafs.clear();
865 data.llCpuIdLeafs = m->bd->llCpuIdLeafs;
866
867 data = *m->bd.data();
868
869 return S_OK;
870}
871
872#if 0
873void PlatformX86::i_rollback()
874{
875 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
876 m->bd.rollback();
877}
878
879void PlatformX86::i_commit()
880{
881 /* sanity */
882 AutoCaller autoCaller(this);
883 AssertComRCReturnVoid(autoCaller.hrc());
884
885 /* sanity too */
886 AutoCaller peerCaller(m->pPeer);
887 AssertComRCReturnVoid(peerCaller.hrc());
888
889 /* lock both for writing since we modify both (mPeer is "master" so locked
890 * first) */
891 AutoMultiWriteLock2 alock(m->pPeer, this COMMA_LOCKVAL_SRC_POS);
892
893 if (m->bd.isBackedUp())
894 {
895 m->bd.commit();
896 if (m->pPeer)
897 {
898 /* attach new data to the peer and reshare it */
899 AutoWriteLock peerlock(m->pPeer COMMA_LOCKVAL_SRC_POS);
900 m->pPeer->m->bd.attach(m->bd);
901 }
902 }
903}
904#endif
905
906HRESULT PlatformX86::i_applyDefaults(GuestOSType *aOsType)
907{
908 /* sanity */
909 AutoCaller autoCaller(this);
910 AssertComRCReturn(autoCaller.hrc(), autoCaller.hrc());
911
912 HRESULT hrc = S_OK;
913
914 BOOL fPAE;
915 BOOL fAPIC = TRUE; /* Always was enabled. */
916 BOOL fX2APIC;
917 settings::PlatformX86::LongModeType enmLongMode;
918 BOOL fHPET;
919 BOOL fTripleFaultReset;
920
921 if (aOsType)
922 {
923 hrc = aOsType->COMGETTER(RecommendedPAE)(&fPAE);
924 AssertComRCReturn(hrc, hrc);
925
926 hrc = aOsType->COMGETTER(RecommendedX2APIC)(&fX2APIC);
927 AssertComRCReturn(hrc, hrc);
928
929 /* Let the OS type select 64-bit ness. */
930 enmLongMode = aOsType->i_is64Bit()
931 ? settings::PlatformX86::LongMode_Enabled : settings::PlatformX86::LongMode_Disabled;
932
933 hrc = aOsType->COMGETTER(RecommendedHPET)(&fHPET);
934 AssertComRCReturn(hrc, hrc);
935
936 hrc = aOsType->COMGETTER(RecommendedTFReset)(&fTripleFaultReset);
937 AssertComRCReturn(hrc, hrc);
938 }
939 else
940 {
941 /* No guest OS type object. Pick some plausible defaults which the
942 * host can handle. There's no way to know or validate anything. */
943 fX2APIC = FALSE;
944 enmLongMode = HC_ARCH_BITS == 64
945 ? settings::PlatformX86::LongMode_Enabled : settings::PlatformX86::LongMode_Disabled;
946
947#if HC_ARCH_BITS == 64 || defined(RT_OS_WINDOWS) || defined(RT_OS_DARWIN)
948 fPAE = TRUE;
949#else
950 fPAE = FALSE;
951#endif
952 fHPET = FALSE;
953 fTripleFaultReset = FALSE;
954 }
955
956 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
957
958 m->bd->fPAE = fPAE;
959 m->bd->fAPIC = fAPIC;
960 m->bd->fX2APIC = fX2APIC;
961 m->bd->enmLongMode = enmLongMode;
962 m->bd->fHPETEnabled = fHPET;
963
964 m->bd->fTripleFaultReset = RT_BOOL(fTripleFaultReset);
965 m->bd->fIBPBOnVMExit = false;
966 m->bd->fIBPBOnVMEntry = false;
967 m->bd->fSpecCtrl = false;
968 m->bd->fSpecCtrlByHost = false;
969 m->bd->fL1DFlushOnSched = true;
970 m->bd->fL1DFlushOnVMEntry = false;
971 m->bd->fMDSClearOnSched = true;
972 m->bd->fMDSClearOnVMEntry = false;
973
974 /* Hardware virtualization must be ON by default. */
975 m->bd->fHWVirtEx = true;
976
977 return hrc;
978}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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