Skip to content

Commit

Permalink
Add a workaround to Linux 6.1's sev-guest lockout
Browse files Browse the repository at this point in the history
The IV reuse fix 47894e0fa6a5 works against the host's throttling by
making the sev-guest device useless when throttled. The x86/urgent fix
72f7754dcf31 that merged to tip on March 16 still hasn't made it to
some distros, so this workaround is still needed temporarily.

Issue #40 is to revert this change at the appropriate time. The same
fix for #40 includes the fix for #5.

Signed-off-by: Dionna Glaze <[email protected]>
  • Loading branch information
deeglaze committed Mar 19, 2023
1 parent 5086a95 commit 56d47e8
Showing 1 changed file with 23 additions and 3 deletions.
26 changes: 23 additions & 3 deletions client/client_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,24 @@ package client

import (
"fmt"
"time"

labi "github.com/google/go-sev-guest/client/linuxabi"
"golang.org/x/sys/unix"
)

// defaultSevGuestDevicePath is the platform's usual device path to the SEV guest.
const defaultSevGuestDevicePath = "/dev/sev-guest"
const (
// defaultSevGuestDevicePath is the platform's usual device path to the SEV guest.
defaultSevGuestDevicePath = "/dev/sev-guest"
throttleDuration = 2 * time.Second
burstMax = 2
)

// LinuxDevice implements the Device interface with Linux ioctls.
type LinuxDevice struct {
fd int
fd int
lastCmd time.Time
burst int
}

// Open opens the SEV-SNP guest device from a given path
Expand Down Expand Up @@ -71,11 +78,24 @@ func (d *LinuxDevice) Close() error {

// Ioctl sends a command with its wrapped request and response values to the Linux device.
func (d *LinuxDevice) Ioctl(command uintptr, req any) (uintptr, error) {
// TODO(Issue #40): Remove the workaround to the ENOTTY lockout when throttled
// in Linux 6.1 by throttling ourselves first.
if d.burst == 0 {
sinceLast := time.Since(d.lastCmd)
// Self-throttle for tests without guest OS throttle detection
if sinceLast < throttleDuration {
time.Sleep(throttleDuration - sinceLast)
}
}
switch sreq := req.(type) {
case *labi.SnpUserGuestRequest:
abi := sreq.ABI()
result, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(d.fd), command, uintptr(abi.Pointer()))
abi.Finish(sreq)
d.burst = (d.burst + 1) % burstMax
if d.burst == 0 {
d.lastCmd = time.Now()
}

// TODO(Issue #5): remove the work around for the kernel bug that writes
// uninitialized memory back on non-EIO.
Expand Down

0 comments on commit 56d47e8

Please sign in to comment.