Skip to content

Commit

Permalink
Add check for 'xsave' and print a friendly error message in runsc.
Browse files Browse the repository at this point in the history
Fixes #6300, #5738

PiperOrigin-RevId: 384385422
  • Loading branch information
Ian Lewis authored and gvisor-bot committed Jul 14, 2021
1 parent 85a0a35 commit 9615b3d
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 4 deletions.
7 changes: 7 additions & 0 deletions g3doc/user_guide/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@ This error may happen when using `gvisor-containerd-shim` with a `containerd`
that does not contain the fix for [CVE-2020-15257]. The resolve the issue,
update containerd to 1.3.9 or 1.4.3 (or newer versions respectively).

### I'm getting an error like `SIGILL: illegal instruction` or `CPU does not support 'xsave' extensions` {#xsave}

gVisor requires support for the 'xsave' set of
[CPU extensions](https://en.wikipedia.org/wiki/CPUID#EAX=1:_Processor_Info_and_Feature_Bits)
(XSAVE, XRESTOR, XSETBV, XGETBV). Please check the CPU you are using to ensure
it supports this instruction set.

[security-model]: /docs/architecture_guide/security/
[host-net]: /docs/user_guide/networking/#network-passthrough
[debugging]: /docs/user_guide/debugging/
Expand Down
3 changes: 3 additions & 0 deletions pkg/ring0/defs_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ type kernelEntry struct {

// tss is the CPU's task state.
tss TaskState64

// xcr0 is the host CPU's xcr0 value.
xcr0 uintptr
}

// CPUArchState contains CPU-specific arch state.
Expand Down
7 changes: 4 additions & 3 deletions pkg/ring0/kernel_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ func (c *CPU) init(cpuID int) {

// Set mandatory flags.
c.registers.Eflags = KernelFlagsSet

// Store xcr0 so it can be synced from the host.
c.xcr0 = xgetbv(0)
}

// StackTop returns the kernel's stack address.
Expand Down Expand Up @@ -257,8 +260,6 @@ func (c *CPU) SwitchToUser(switchOpts SwitchOpts) (vector Vector) {
return
}

var sentryXCR0 = xgetbv(0)

// startGo is the CPU entrypoint.
//
// This is called from the start asm stub (see entry_amd64.go); on return the
Expand All @@ -285,7 +286,7 @@ func startGo(c *CPU) {
fninit()
// Need to sync XCR0 with the host, because xsave and xrstor can be
// called from different contexts.
xsetbv(0, sentryXCR0)
xsetbv(0, c.xcr0)

// Set the syscall target.
wrmsr(_MSR_LSTAR, kernelFunc(addrOfSysenter()))
Expand Down
3 changes: 3 additions & 0 deletions runsc/container/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ go_library(
name = "container",
srcs = [
"container.go",
"cpu_amd64.go",
"cpu_arm64.go",
"hook.go",
"state_file.go",
"status.go",
Expand All @@ -17,6 +19,7 @@ go_library(
deps = [
"//pkg/abi/linux",
"//pkg/cleanup",
"//pkg/cpuid",
"//pkg/log",
"//pkg/sentry/control",
"//pkg/sentry/sighandling",
Expand Down
8 changes: 7 additions & 1 deletion runsc/container/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ type Args struct {
// Destroy() on the container.
func New(conf *config.Config, args Args) (*Container, error) {
log.Debugf("Create container, cid: %s, rootDir: %q", args.ID, conf.RootDir)

// Check for xsave and provide a friendly error message if not supported.
if needXSave() {
return nil, errors.New(specutils.FaqErrorMsg("xsave", "CPU does not support 'xsave' extensions"))
}

if err := validateID(args.ID); err != nil {
return nil, err
}
Expand Down Expand Up @@ -217,7 +223,7 @@ func New(conf *config.Config, args Args) (*Container, error) {
// container is obviously the root. Both container and sandbox share the
// ID.
// 2. Container type == sandbox: it means this is the root container
// starting the sandbox. Both container and sandbox share the same ID.
// starting the sandbox. Both container and sandbox share the same ID.
// 3. Container type == container: it means this is a subcontainer of an
// already started sandbox. In this case, container ID is different than
// the sandbox ID.
Expand Down
24 changes: 24 additions & 0 deletions runsc/container/cpu_amd64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2021 The gVisor Authors.
//
// 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.

package container

import (
"gvisor.dev/gvisor/pkg/cpuid"
)

// needXSave returns true if XSAVE CPU extensions are needed but not present.
func needXSave() bool {
return !cpuid.HostFeatureSet().HasFeature(cpuid.X86FeatureXSAVE)
}
20 changes: 20 additions & 0 deletions runsc/container/cpu_arm64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2021 The gVisor Authors.
//
// 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.

package container

// needXSave returns true if XSAVE CPU extensions are needed but not present.
func needXSave() bool {
return false
}

0 comments on commit 9615b3d

Please # to comment.