VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR3/GIMMinimal.cpp@ 62591

Last change on this file since 62591 was 62591, checked in by vboxsync, 8 years ago

VMM/GIM, CPUM: Retire "EnableHVP" CFGM option and the unconditional insertion of hypervisor-specific CPUID leaves. Rather, this
is now tied to the HVP (Hypervisor Present) bit through the "Minimal" GIM provider. The other GIM providers (HyperV, KVM) already
do their own insertion and setting of the HVP bit as necessary.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.5 KB
Line 
1/* $Id: GIMMinimal.cpp 62591 2016-07-27 13:19:55Z vboxsync $ */
2/** @file
3 * GIM - Guest Interface Manager, Minimal implementation.
4 */
5
6/*
7 * Copyright (C) 2014-2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.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
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_GIM
23#include <VBox/vmm/gim.h>
24#include <VBox/vmm/cpum.h>
25#include <VBox/vmm/tm.h>
26#include <VBox/vmm/pdmapi.h>
27#include "GIMInternal.h"
28#include <VBox/vmm/vm.h>
29
30#include <iprt/assert.h>
31#include <iprt/err.h>
32#include <iprt/asm-amd64-x86.h>
33#include <iprt/string.h>
34
35
36/*********************************************************************************************************************************
37* Defined Constants And Macros *
38*********************************************************************************************************************************/
39
40/**
41 * Initializes the Minimal provider.
42 *
43 * @returns VBox status code.
44 * @param pVM The cross context VM structure.
45 */
46VMMR3_INT_DECL(int) gimR3MinimalInit(PVM pVM)
47{
48 AssertReturn(pVM, VERR_INVALID_PARAMETER);
49 AssertReturn(pVM->gim.s.enmProviderId == GIMPROVIDERID_MINIMAL, VERR_INTERNAL_ERROR_5);
50
51 /*
52 * Expose HVP (Hypervisor Present) bit to the guest.
53 */
54 CPUMR3SetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_HVP);
55
56 /*
57 * Insert the hypervisor leaf range.
58 */
59 CPUMCPUIDLEAF HyperLeaf;
60 RT_ZERO(HyperLeaf);
61 HyperLeaf.uLeaf = UINT32_C(0x40000000);
62 HyperLeaf.uEax = UINT32_C(0x40000010); /* Maximum leaf we implement. */
63 int rc = CPUMR3CpuIdInsert(pVM, &HyperLeaf);
64 if (RT_SUCCESS(rc))
65 {
66 /*
67 * Insert missing zero leaves (you never know what missing leaves are
68 * going to return when read).
69 */
70 RT_ZERO(HyperLeaf);
71 for (uint32_t uLeaf = UINT32_C(0x40000001); uLeaf <= UINT32_C(0x40000010); uLeaf++)
72 {
73 HyperLeaf.uLeaf = uLeaf;
74 rc = CPUMR3CpuIdInsert(pVM, &HyperLeaf);
75 AssertLogRelRCReturn(rc, rc);
76 }
77 }
78 else
79 LogRel(("GIM: Minimal: Failed to insert hypervisor leaf %#RX32. rc=%Rrc\n", HyperLeaf.uLeaf, rc));
80
81 return rc;
82}
83
84
85/**
86 * Initializes remaining bits of the Minimal provider.
87 * This is called after initializing HM and almost all other VMM components.
88 *
89 * @returns VBox status code.
90 * @param pVM The cross context VM structure.
91 */
92VMMR3_INT_DECL(int) gimR3MinimalInitCompleted(PVM pVM)
93{
94 /*
95 * Expose a generic hypervisor-agnostic leaf (originally defined by VMware).
96 * The leaves range from 0x40000010 to 0x400000FF.
97 *
98 * This is done in the init. completed routine as we need PDM to be
99 * initialized (otherwise PDMApicGetTimerFreq() would fail).
100 */
101 CPUMCPUIDLEAF HyperLeaf;
102 int rc = CPUMR3CpuIdGetLeaf(pVM, &HyperLeaf, 0x40000000, 0 /* uSubLeaf */);
103 if (RT_SUCCESS(rc))
104 {
105 Assert(HyperLeaf.uEax >= 0x40000010);
106
107 /*
108 * Add the timing information hypervisor leaf.
109 * MacOS X uses this to determine the TSC, bus frequency. See @bugref{7270}.
110 *
111 * EAX - TSC frequency in KHz.
112 * EBX - APIC frequency in KHz.
113 * ECX, EDX - Reserved.
114 */
115 uint64_t uApicFreq;
116 rc = PDMApicGetTimerFreq(pVM, &uApicFreq);
117 AssertLogRelRCReturn(rc, rc);
118
119 RT_ZERO(HyperLeaf);
120 HyperLeaf.uLeaf = UINT32_C(0x40000010);
121 HyperLeaf.uEax = TMCpuTicksPerSecond(pVM) / UINT64_C(1000);
122 HyperLeaf.uEbx = (uApicFreq + 500) / UINT64_C(1000);
123 rc = CPUMR3CpuIdInsert(pVM, &HyperLeaf);
124 AssertLogRelRCReturn(rc, rc);
125 }
126 else
127 LogRel(("GIM: Minimal: failed to get hypervisor leaf 0x40000000. rc=%Rrc\n", rc));
128
129 return VINF_SUCCESS;
130}
131
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