VirtualBox

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

Last change on this file since 93705 was 93554, checked in by vboxsync, 3 years ago

VMM: Changed PAGE_SIZE -> GUEST_PAGE_SIZE / HOST_PAGE_SIZE, PAGE_SHIFT -> GUEST_PAGE_SHIFT / HOST_PAGE_SHIFT, and PAGE_OFFSET_MASK -> GUEST_PAGE_OFFSET_MASK / HOST_PAGE_OFFSET_MASK. Also removed most usage of ASMMemIsZeroPage and ASMMemZeroPage since the host and guest page size doesn't need to be the same any more. Some work left to do in the page pool code. bugref:9898

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