summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/platform/ring0/lib_amd64.go
blob: 989e3e383f0cc7cdbf9501fe067766b0855e7c21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build amd64

package ring0

import (
	"gvisor.googlesource.com/gvisor/pkg/cpuid"
)

// LoadFloatingPoint loads floating point state by the most efficient mechanism
// available (set by Init).
var LoadFloatingPoint func(*byte)

// SaveFloatingPoint saves floating point state by the most efficient mechanism
// available (set by Init).
var SaveFloatingPoint func(*byte)

// fxrstor uses fxrstor64 to load floating point state.
func fxrstor(*byte)

// xrstor uses xrstor to load floating point state.
func xrstor(*byte)

// fxsave uses fxsave64 to save floating point state.
func fxsave(*byte)

// xsave uses xsave to save floating point state.
func xsave(*byte)

// xsaveopt uses xsaveopt to save floating point state.
func xsaveopt(*byte)

// WriteFS sets the GS address (set by init).
var WriteFS func(addr uintptr)

// wrfsbase writes to the GS base address.
func wrfsbase(addr uintptr)

// wrfsmsr writes to the GS_BASE MSR.
func wrfsmsr(addr uintptr)

// WriteGS sets the GS address (set by init).
var WriteGS func(addr uintptr)

// wrgsbase writes to the GS base address.
func wrgsbase(addr uintptr)

// wrgsmsr writes to the GS_BASE MSR.
func wrgsmsr(addr uintptr)

// writeCR3 writes the CR3 value.
func writeCR3(phys uintptr)

// readCR3 reads the current CR3 value.
func readCR3() uintptr

// readCR2 reads the current CR2 value.
func readCR2() uintptr

// jumpToKernel jumps to the kernel version of the current RIP.
func jumpToKernel()

// jumpToUser jumps to the user version of the current RIP.
func jumpToUser()

// fninit initializes the floating point unit.
func fninit()

// xsetbv writes to an extended control register.
func xsetbv(reg, value uintptr)

// xgetbv reads an extended control register.
func xgetbv(reg uintptr) uintptr

// wrmsr reads to the given MSR.
func wrmsr(reg, value uintptr)

// rdmsr reads the given MSR.
func rdmsr(reg uintptr) uintptr

// Mostly-constants set by Init.
var (
	hasSMEP       bool
	hasPCID       bool
	hasXSAVEOPT   bool
	hasXSAVE      bool
	hasFSGSBASE   bool
	validXCR0Mask uintptr
)

// Init sets function pointers based on architectural features.
//
// This must be called prior to using ring0.
func Init(featureSet *cpuid.FeatureSet) {
	hasSMEP = featureSet.HasFeature(cpuid.X86FeatureSMEP)
	hasPCID = featureSet.HasFeature(cpuid.X86FeaturePCID)
	hasXSAVEOPT = featureSet.UseXsaveopt()
	hasXSAVE = featureSet.UseXsave()
	hasFSGSBASE = featureSet.HasFeature(cpuid.X86FeatureFSGSBase)
	validXCR0Mask = uintptr(featureSet.ValidXCR0Mask())
	if hasXSAVEOPT {
		SaveFloatingPoint = xsaveopt
		LoadFloatingPoint = xrstor
	} else if hasXSAVE {
		SaveFloatingPoint = xsave
		LoadFloatingPoint = xrstor
	} else {
		SaveFloatingPoint = fxsave
		LoadFloatingPoint = fxrstor
	}
	if hasFSGSBASE {
		WriteFS = wrfsbase
		WriteGS = wrgsbase
	} else {
		WriteFS = wrfsmsr
		WriteGS = wrgsmsr
	}
}