VirtualBox

source: vbox/trunk/src/VBox/VMM/include/GIMKvmInternal.h@ 72816

Last change on this file since 72816 was 72469, checked in by vboxsync, 7 years ago

GIM,IEM: Correctly hook up hypercalls thru IEM. bugref:9044

  • IEM: Pass opcode and instruction length to GIM so it can do patching.
  • GIM: Introduced GIMHypercallEx API for receiving hypercalls with instruction opcode+length. Hooking this into the exiting #UD code paths.
  • GIM: Move the VMMPatchHypercall API into GIM and corrected the name to GIMQueryHypercallOpcodeBytes.
  • GIM/KVM: Use GIMQueryHypercallOpcodeBytes to decide which instruction is native and cache the opcode bytes for patching.
  • GIM/KVM: Check the VMCALL instruction encoding length rather than assuming its always 3 bytes when patching.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.3 KB
Line 
1/* $Id: GIMKvmInternal.h 72469 2018-06-07 11:35:23Z vboxsync $ */
2/** @file
3 * GIM - KVM, Internal header file.
4 */
5
6/*
7 * Copyright (C) 2015-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#ifndef ___GIMKvmInternal_h
19#define ___GIMKvmInternal_h
20
21#include <VBox/vmm/gim.h>
22#include <VBox/vmm/cpum.h>
23
24
25/** @name KVM base features.
26 * @{
27 */
28/** Old, deprecated clock source available. */
29#define GIM_KVM_BASE_FEAT_CLOCK_OLD RT_BIT(0)
30/** No need for artifical delays on IO operations. */
31#define GIM_KVM_BASE_FEAT_NOP_IO_DELAY RT_BIT(1)
32/** MMU op supported (deprecated, unused). */
33#define GIM_KVM_BASE_FEAT_MMU_OP RT_BIT(2)
34/** Clock source available. */
35#define GIM_KVM_BASE_FEAT_CLOCK RT_BIT(3)
36/** Asynchronous page faults supported. */
37#define GIM_KVM_BASE_FEAT_ASYNC_PF RT_BIT(4)
38/** Steal time (VCPU not executing guest code time in ns) available. */
39#define GIM_KVM_BASE_FEAT_STEAL_TIME RT_BIT(5)
40/** Paravirtualized EOI (end-of-interrupt) supported. */
41#define GIM_KVM_BASE_FEAT_PV_EOI RT_BIT(6)
42/** Paravirtualized spinlock (unhalting VCPU) supported. */
43#define GIM_KVM_BASE_FEAT_PV_UNHALT RT_BIT(7)
44/** The TSC is stable (fixed rate, monotonic). */
45#define GIM_KVM_BASE_FEAT_TSC_STABLE RT_BIT(24)
46/** @} */
47
48
49/** @name KVM MSRs.
50 * @{
51 */
52/** Start of range 0. */
53#define MSR_GIM_KVM_RANGE0_START UINT32_C(0x11)
54/** Old, deprecated wall clock. */
55#define MSR_GIM_KVM_WALL_CLOCK_OLD UINT32_C(0x11)
56/** Old, deprecated System time. */
57#define MSR_GIM_KVM_SYSTEM_TIME_OLD UINT32_C(0x12)
58/** End of range 0. */
59#define MSR_GIM_KVM_RANGE0_END MSR_GIM_KVM_SYSTEM_TIME_OLD
60
61/** Start of range 1. */
62#define MSR_GIM_KVM_RANGE1_START UINT32_C(0x4b564d00)
63/** Wall clock. */
64#define MSR_GIM_KVM_WALL_CLOCK UINT32_C(0x4b564d00)
65/** System time. */
66#define MSR_GIM_KVM_SYSTEM_TIME UINT32_C(0x4b564d01)
67/** Asynchronous page fault. */
68#define MSR_GIM_KVM_ASYNC_PF UINT32_C(0x4b564d02)
69/** Steal time. */
70#define MSR_GIM_KVM_STEAL_TIME UINT32_C(0x4b564d03)
71/** Paravirtualized EOI (end-of-interrupt). */
72#define MSR_GIM_KVM_EOI UINT32_C(0x4b564d04)
73/** End of range 1. */
74#define MSR_GIM_KVM_RANGE1_END MSR_GIM_KVM_EOI
75
76AssertCompile(MSR_GIM_KVM_RANGE0_START <= MSR_GIM_KVM_RANGE0_END);
77AssertCompile(MSR_GIM_KVM_RANGE1_START <= MSR_GIM_KVM_RANGE1_END);
78
79/** KVM page size. */
80#define GIM_KVM_PAGE_SIZE 0x1000
81
82/**
83 * MMIO2 region indices.
84 */
85/** The system time page(s) region. */
86#define GIM_KVM_SYSTEM_TIME_PAGE_REGION_IDX UINT8_C(0)
87/** The steal time page(s) region. */
88#define GIM_KVM_STEAL_TIME_PAGE_REGION_IDX UINT8_C(1)
89/** The maximum region index (must be <= UINT8_MAX). */
90#define GIM_KVM_REGION_IDX_MAX GIM_KVM_STEAL_TIME_PAGE_REGION_IDX
91
92/**
93 * KVM system-time structure (GIM_KVM_SYSTEM_TIME_FLAGS_XXX) flags.
94 * See "Documentation/virtual/kvm/api.txt".
95 */
96/** The TSC is stable (monotonic). */
97#define GIM_KVM_SYSTEM_TIME_FLAGS_TSC_STABLE RT_BIT(0)
98/** The guest VCPU has been paused by the hypervisor. */
99#define GIM_KVM_SYSTEM_TIME_FLAGS_GUEST_PAUSED RT_BIT(1)
100/** */
101
102/** @name KVM MSR - System time (MSR_GIM_KVM_SYSTEM_TIME and
103 * MSR_GIM_KVM_SYSTEM_TIME_OLD).
104 * @{
105 */
106/** The system-time enable bit. */
107#define MSR_GIM_KVM_SYSTEM_TIME_ENABLE_BIT RT_BIT_64(0)
108/** Whether the system-time struct. is enabled or not. */
109#define MSR_GIM_KVM_SYSTEM_TIME_IS_ENABLED(a) RT_BOOL((a) & MSR_GIM_KVM_SYSTEM_TIME_ENABLE_BIT)
110/** Guest-physical address of the system-time struct. */
111#define MSR_GIM_KVM_SYSTEM_TIME_GUEST_GPA(a) ((a) & ~MSR_GIM_KVM_SYSTEM_TIME_ENABLE_BIT)
112/** @} */
113
114/** @name KVM MSR - Wall clock (MSR_GIM_KVM_WALL_CLOCK and
115 * MSR_GIM_KVM_WALL_CLOCK_OLD).
116 * @{
117 */
118/** Guest-physical address of the wall-clock struct. */
119#define MSR_GIM_KVM_WALL_CLOCK_GUEST_GPA(a) (a)
120/** @} */
121
122
123/** @name KVM Hypercall operations.
124 * @{ */
125#define KVM_HYPERCALL_OP_VAPIC_POLL_IRQ 1
126#define KVM_HYPERCALL_OP_MMU 2
127#define KVM_HYPERCALL_OP_FEATURES 3
128#define KVM_HYPERCALL_OP_KICK_CPU 5
129/** @} */
130
131/** @name KVM Hypercall return values.
132 * @{ */
133/* Return values for hypercalls */
134#define KVM_HYPERCALL_RET_SUCCESS 0
135#define KVM_HYPERCALL_RET_ENOSYS (uint64_t)(-1000)
136#define KVM_HYPERCALL_RET_EFAULT (uint64_t)(-14)
137#define KVM_HYPERCALL_RET_E2BIG (uint64_t)(-7)
138#define KVM_HYPERCALL_RET_EPERM (uint64_t)(-1)
139/** @} */
140
141/**
142 * KVM per-VCPU system-time structure.
143 */
144typedef struct GIMKVMSYSTEMTIME
145{
146 /** Version (sequence number). */
147 uint32_t u32Version;
148 /** Alignment padding. */
149 uint32_t u32Padding0;
150 /** TSC time stamp. */
151 uint64_t u64Tsc;
152 /** System time in nanoseconds. */
153 uint64_t u64NanoTS;
154 /** TSC to system time scale factor. */
155 uint32_t u32TscScale;
156 /** TSC frequency shift. */
157 int8_t i8TscShift;
158 /** Clock source (GIM_KVM_SYSTEM_TIME_FLAGS_XXX) flags. */
159 uint8_t fFlags;
160 /** Alignment padding. */
161 uint8_t abPadding0[2];
162} GIMKVMSYSTEMTIME;
163/** Pointer to KVM system-time struct. */
164typedef GIMKVMSYSTEMTIME *PGIMKVMSYSTEMTIME;
165/** Pointer to a const KVM system-time struct. */
166typedef GIMKVMSYSTEMTIME const *PCGIMKVMSYSTEMTIME;
167AssertCompileSize(GIMKVMSYSTEMTIME, 32);
168
169
170/**
171 * KVM per-VM wall-clock structure.
172 */
173typedef struct GIMKVMWALLCLOCK
174{
175 /** Version (sequence number). */
176 uint32_t u32Version;
177 /** Number of seconds since boot. */
178 uint32_t u32Sec;
179 /** Number of nanoseconds since boot. */
180 uint32_t u32Nano;
181} GIMKVMWALLCLOCK;
182/** Pointer to KVM wall-clock struct. */
183typedef GIMKVMWALLCLOCK *PGIMKVMWALLCLOCK;
184/** Pointer to a const KVM wall-clock struct. */
185typedef GIMKVMWALLCLOCK const *PCGIMKVMWALLCLOCK;
186AssertCompileSize(GIMKVMWALLCLOCK, 12);
187
188
189/**
190 * GIM KVM VM instance data.
191 * Changes to this must checked against the padding of the gim union in VM!
192 */
193typedef struct GIMKVM
194{
195 /** Wall-clock MSR. */
196 uint64_t u64WallClockMsr;
197 /** CPUID features: Basic. */
198 uint32_t uBaseFeat;
199 /** Whether GIM needs to trap \#UD exceptions. */
200 bool fTrapXcptUD;
201 /** Disassembler opcode of hypercall instruction native for this host CPU. */
202 uint16_t uOpcodeNative;
203 /** Native hypercall opcode bytes. Use for replacing. */
204 uint8_t abOpcodeNative[3];
205 /** Alignment padding. */
206 uint8_t abPadding[5];
207 /** The TSC frequency (in HZ) reported to the guest. */
208 uint64_t cTscTicksPerSecond;
209 /** Spinlock used for protecting GIMKVMCPU::uTsc and
210 * GIMKVMCPU::uVirtNanoTS. */
211 RTSPINLOCK hSpinlockR0;
212} GIMKVM;
213/** Pointer to per-VM GIM KVM instance data. */
214typedef GIMKVM *PGIMKVM;
215/** Pointer to const per-VM GIM KVM instance data. */
216typedef GIMKVM const *PCGIMKVM;
217
218/**
219 * GIM KVMV VCPU instance data.
220 * Changes to this must checked against the padding of the gim union in VMCPU!
221 */
222typedef struct GIMKVMCPU
223{
224 /** System-time MSR. */
225 uint64_t u64SystemTimeMsr;
226 /** The guest-physical address of the system-time struct. */
227 RTGCPHYS GCPhysSystemTime;
228 /** The version (sequence number) of the system-time struct. */
229 uint32_t u32SystemTimeVersion;
230 /** The guest TSC value while enabling the system-time MSR. */
231 uint64_t uTsc;
232 /** The guest virtual time while enabling the system-time MSR. */
233 uint64_t uVirtNanoTS;
234 /** The flags of the system-time struct. */
235 uint8_t fSystemTimeFlags;
236} GIMKVMCPU;
237/** Pointer to per-VCPU GIM KVM instance data. */
238typedef GIMKVMCPU *PGIMKVMCPU;
239/** Pointer to const per-VCPU GIM KVM instance data. */
240typedef GIMKVMCPU const *PCGIMKVMCPU;
241
242
243RT_C_DECLS_BEGIN
244
245#ifdef IN_RING0
246VMMR0_INT_DECL(int) gimR0KvmInitVM(PVM pVM);
247VMMR0_INT_DECL(int) gimR0KvmTermVM(PVM pVM);
248VMMR0_INT_DECL(int) gimR0KvmUpdateSystemTime(PVM pVM, PVMCPU pVCpu);
249#endif /* IN_RING0 */
250
251#ifdef IN_RING3
252VMMR3_INT_DECL(int) gimR3KvmInit(PVM pVM);
253VMMR3_INT_DECL(int) gimR3KvmInitCompleted(PVM pVM);
254VMMR3_INT_DECL(int) gimR3KvmTerm(PVM pVM);
255VMMR3_INT_DECL(void) gimR3KvmRelocate(PVM pVM, RTGCINTPTR offDelta);
256VMMR3_INT_DECL(void) gimR3KvmReset(PVM pVM);
257VMMR3_INT_DECL(int) gimR3KvmSave(PVM pVM, PSSMHANDLE pSSM);
258VMMR3_INT_DECL(int) gimR3KvmLoad(PVM pVM, PSSMHANDLE pSSM);
259
260VMMR3_INT_DECL(int) gimR3KvmDisableSystemTime(PVM pVM);
261VMMR3_INT_DECL(int) gimR3KvmEnableSystemTime(PVM pVM, PVMCPU pVCpu);
262VMMR3_INT_DECL(int) gimR3KvmEnableWallClock(PVM pVM, RTGCPHYS GCPhysSysTime);
263#endif /* IN_RING3 */
264
265VMM_INT_DECL(bool) gimKvmIsParavirtTscEnabled(PVM pVM);
266VMM_INT_DECL(bool) gimKvmAreHypercallsEnabled(PVMCPU pVCpu);
267VMM_INT_DECL(VBOXSTRICTRC) gimKvmHypercall(PVMCPU pVCpu, PCPUMCTX pCtx);
268VMM_INT_DECL(VBOXSTRICTRC) gimKvmReadMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue);
269VMM_INT_DECL(VBOXSTRICTRC) gimKvmWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uRawValue);
270VMM_INT_DECL(bool) gimKvmShouldTrapXcptUD(PVMCPU pVCpu);
271VMM_INT_DECL(VBOXSTRICTRC) gimKvmXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis, uint8_t *pcbInstr);
272VMM_INT_DECL(VBOXSTRICTRC) gimKvmHypercallEx(PVMCPU pVCpu, PCPUMCTX pCtx, unsigned uDisOpcode, uint8_t cbInstr);
273
274
275RT_C_DECLS_END
276
277#endif
278
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