VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR0/GIMR0Hv.cpp

Last change on this file was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.0 KB
Line 
1/* $Id: GIMR0Hv.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * Guest Interface Manager (GIM), Hyper-V - Host Context Ring-0.
4 */
5
6/*
7 * Copyright (C) 2014-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
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_GIM
33#include <VBox/vmm/gim.h>
34#include <VBox/vmm/tm.h>
35#include "GIMInternal.h"
36#include "GIMHvInternal.h"
37#include <VBox/vmm/vmcc.h>
38
39#include <VBox/err.h>
40
41#include <iprt/spinlock.h>
42
43
44#if 0
45/**
46 * Allocates and maps one physically contiguous page. The allocated page is
47 * zero'd out.
48 *
49 * @returns IPRT status code.
50 * @param pMemObj Pointer to the ring-0 memory object.
51 * @param ppVirt Where to store the virtual address of the
52 * allocation.
53 * @param pPhys Where to store the physical address of the
54 * allocation.
55 */
56static int gimR0HvPageAllocZ(PRTR0MEMOBJ pMemObj, PRTR0PTR ppVirt, PRTHCPHYS pHCPhys)
57{
58 AssertPtr(pMemObj);
59 AssertPtr(ppVirt);
60 AssertPtr(pHCPhys);
61
62 int rc = RTR0MemObjAllocCont(pMemObj, HOST_PAGE_SIZE, NIL_RTHCPHYS /*PhysHighest*/, false /* fExecutable */);
63 if (RT_FAILURE(rc))
64 return rc;
65 *ppVirt = RTR0MemObjAddress(*pMemObj);
66 *pHCPhys = RTR0MemObjGetPagePhysAddr(*pMemObj, 0 /* iPage */);
67 ASMMemZero32(*ppVirt, HOST_PAGE_SIZE);
68 return VINF_SUCCESS;
69}
70
71
72/**
73 * Frees and unmaps an allocated physical page.
74 *
75 * @param pMemObj Pointer to the ring-0 memory object.
76 * @param ppVirt Where to re-initialize the virtual address of
77 * allocation as 0.
78 * @param pHCPhys Where to re-initialize the physical address of the
79 * allocation as 0.
80 */
81static void gimR0HvPageFree(PRTR0MEMOBJ pMemObj, PRTR0PTR ppVirt, PRTHCPHYS pHCPhys)
82{
83 AssertPtr(pMemObj);
84 AssertPtr(ppVirt);
85 AssertPtr(pHCPhys);
86 if (*pMemObj != NIL_RTR0MEMOBJ)
87 {
88 int rc = RTR0MemObjFree(*pMemObj, true /* fFreeMappings */);
89 AssertRC(rc);
90 *pMemObj = NIL_RTR0MEMOBJ;
91 *ppVirt = 0;
92 *pHCPhys = 0;
93 }
94}
95#endif
96
97/**
98 * Updates Hyper-V's reference TSC page.
99 *
100 * @returns VBox status code.
101 * @param pVM The cross context VM structure.
102 * @param u64Offset The computed TSC offset.
103 * @thread EMT.
104 */
105VMM_INT_DECL(int) gimR0HvUpdateParavirtTsc(PVMCC pVM, uint64_t u64Offset)
106{
107 Assert(GIMIsEnabled(pVM));
108 bool fHvTscEnabled = MSR_GIM_HV_REF_TSC_IS_ENABLED(pVM->gim.s.u.Hv.u64TscPageMsr);
109 if (RT_UNLIKELY(!fHvTscEnabled))
110 return VERR_GIM_PVTSC_NOT_ENABLED;
111
112 /** @todo this is buggy when large pages are used due to a PGM limitation, see
113 * @bugref{7532}.
114 *
115 * In any case, we do not ever update this page while the guest is
116 * running after setting it up (in ring-3, see gimR3HvEnableTscPage()) as
117 * the TSC offset is handled in the VMCS/VMCB (HM) or by trapping RDTSC
118 * (raw-mode). */
119#if 0
120 PCGIMHV pcHv = &pVM->gim.s.u.Hv;
121 PCGIMMMIO2REGION pcRegion = &pcHv->aMmio2Regions[GIM_HV_REF_TSC_PAGE_REGION_IDX];
122 PGIMHVREFTSC pRefTsc = (PGIMHVREFTSC)pcRegion->CTX_SUFF(pvPage);
123 Assert(pRefTsc);
124
125 /*
126 * Hyper-V reports the reference time in 100 nanosecond units.
127 */
128 uint64_t u64Tsc100Ns = pcHv->cTscTicksPerSecond / RT_NS_10MS;
129 int64_t i64TscOffset = (int64_t)u64Offset / u64Tsc100Ns;
130
131 /*
132 * The TSC page can be simulatenously read by other VCPUs in the guest. The
133 * spinlock is only for protecting simultaneous hypervisor writes from other
134 * EMTs.
135 */
136 RTSpinlockAcquire(pcHv->hSpinlockR0);
137 if (pRefTsc->i64TscOffset != i64TscOffset)
138 {
139 if (pRefTsc->u32TscSequence < UINT32_C(0xfffffffe))
140 ASMAtomicIncU32(&pRefTsc->u32TscSequence);
141 else
142 ASMAtomicWriteU32(&pRefTsc->u32TscSequence, 1);
143 ASMAtomicWriteS64(&pRefTsc->i64TscOffset, i64TscOffset);
144 }
145 RTSpinlockRelease(pcHv->hSpinlockR0);
146
147 Assert(pRefTsc->u32TscSequence != 0);
148 Assert(pRefTsc->u32TscSequence != UINT32_C(0xffffffff));
149#else
150 NOREF(u64Offset);
151#endif
152 return VINF_SUCCESS;
153}
154
155
156/**
157 * Does ring-0 per-VM GIM Hyper-V initialization.
158 *
159 * @returns VBox status code.
160 * @param pVM The cross context VM structure.
161 */
162VMMR0_INT_DECL(int) gimR0HvInitVM(PVMCC pVM)
163{
164 AssertPtr(pVM);
165 Assert(GIMIsEnabled(pVM));
166
167 PGIMHV pHv = &pVM->gim.s.u.Hv;
168 Assert(pHv->hSpinlockR0 == NIL_RTSPINLOCK);
169
170 int rc = RTSpinlockCreate(&pHv->hSpinlockR0, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "Hyper-V");
171 return rc;
172}
173
174
175/**
176 * Does ring-0 per-VM GIM Hyper-V termination.
177 *
178 * @returns VBox status code.
179 * @param pVM The cross context VM structure.
180 */
181VMMR0_INT_DECL(int) gimR0HvTermVM(PVMCC pVM)
182{
183 AssertPtr(pVM);
184 Assert(GIMIsEnabled(pVM));
185
186 PGIMHV pHv = &pVM->gim.s.u.Hv;
187 RTSpinlockDestroy(pHv->hSpinlockR0);
188 pHv->hSpinlockR0 = NIL_RTSPINLOCK;
189
190 return VINF_SUCCESS;
191}
192
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