VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR0/GIMR0Kvm.cpp@ 84948

Last change on this file since 84948 was 84044, checked in by vboxsync, 5 years ago

GIM/KVM: Instead of reading the time and TSC separately, only read the time and calculate TSC. Avoids problems caused by values not being completely in sync (see bugref:7270).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.3 KB
Line 
1/* $Id: GIMR0Kvm.cpp 84044 2020-04-28 12:01:07Z vboxsync $ */
2/** @file
3 * Guest Interface Manager (GIM), KVM - Host Context Ring-0.
4 */
5
6/*
7 * Copyright (C) 2015-2020 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 "GIMKvmInternal.h"
27#include <VBox/vmm/vmcc.h>
28
29#include <VBox/err.h>
30
31#include <iprt/spinlock.h>
32#include <iprt/asm-math.h>
33
34
35/**
36 * Updates KVM's system time information globally for all VCPUs.
37 *
38 * @returns VBox status code.
39 * @param pVM The cross context VM structure.
40 * @param pVCpu The cross context virtual CPU structure.
41 * @thread EMT.
42 * @remarks Can be called with preemption disabled!
43 */
44VMM_INT_DECL(int) gimR0KvmUpdateSystemTime(PVMCC pVM, PVMCPUCC pVCpu)
45{
46 /*
47 * Validate.
48 */
49 Assert(GIMIsEnabled(pVM));
50 PGIMKVM pKvm = &pVM->gim.s.u.Kvm;
51 AssertReturn(pKvm->hSpinlockR0 != NIL_RTSPINLOCK, VERR_GIM_IPE_3);
52
53 /*
54 * Record TSC and derive the virtual time from that (to ensure that
55 * the two quantities are in perfect sync).
56 */
57 uint64_t uTsc;
58 uint64_t uVirtNanoTS;
59
60 uTsc = TMCpuTickGetNoCheck(pVCpu);
61 uVirtNanoTS = ASMMultU64ByU32DivByU32(uTsc, RT_NS_1SEC, pKvm->cTscTicksPerSecond);
62
63 /*
64 * Update VCPUs with this information. The first VCPU's values
65 * will be applied to the remaining.
66 */
67 RTSpinlockAcquire(pKvm->hSpinlockR0);
68 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
69 {
70 PGIMKVMCPU pKvmCpu = &VMCC_GET_CPU(pVM, idCpu)->gim.s.u.KvmCpu;
71 pKvmCpu->uTsc = uTsc;
72 pKvmCpu->uVirtNanoTS = uVirtNanoTS;
73 }
74 RTSpinlockRelease(pKvm->hSpinlockR0);
75
76 return VINF_SUCCESS;
77}
78
79
80/**
81 * Does ring-0 per-VM GIM KVM initialization.
82 *
83 * @returns VBox status code.
84 * @param pVM The cross context VM structure.
85 */
86VMMR0_INT_DECL(int) gimR0KvmInitVM(PVMCC pVM)
87{
88 AssertPtr(pVM);
89 Assert(GIMIsEnabled(pVM));
90
91 PGIMKVM pKvm = &pVM->gim.s.u.Kvm;
92 Assert(pKvm->hSpinlockR0 == NIL_RTSPINLOCK);
93
94 int rc = RTSpinlockCreate(&pKvm->hSpinlockR0, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "KVM");
95 return rc;
96}
97
98
99/**
100 * Does ring-0 per-VM GIM KVM termination.
101 *
102 * @returns VBox status code.
103 * @param pVM The cross context VM structure.
104 */
105VMMR0_INT_DECL(int) gimR0KvmTermVM(PVMCC pVM)
106{
107 AssertPtr(pVM);
108 Assert(GIMIsEnabled(pVM));
109
110 PGIMKVM pKvm = &pVM->gim.s.u.Kvm;
111 RTSpinlockDestroy(pKvm->hSpinlockR0);
112 pKvm->hSpinlockR0 = NIL_RTSPINLOCK;
113
114 return VINF_SUCCESS;
115}
116
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