VirtualBox

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

Last change on this file since 74795 was 69111, checked in by vboxsync, 7 years ago

(C) year

  • 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 69111 2017-10-17 14:26:02Z vboxsync $ */
2/** @file
3 * Guest Interface Manager (GIM), Hyper-V - Host Context Ring-0.
4 */
5
6/*
7 * Copyright (C) 2014-2017 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/vm.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, 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, 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(PVM 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(PVM 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(PVM 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.

© 2023 Oracle
ContactPrivacy policyTerms of Use