diff --git a/pkg/sentry/devices/nvproxy/nvconf/version.go b/pkg/sentry/devices/nvproxy/nvconf/version.go index 874f5eddf6..a8a23ca25f 100644 --- a/pkg/sentry/devices/nvproxy/nvconf/version.go +++ b/pkg/sentry/devices/nvproxy/nvconf/version.go @@ -37,7 +37,7 @@ func NewDriverVersion(major, minor, patch int) DriverVersion { // DriverVersionFrom returns a DriverVersion from a string. func DriverVersionFrom(version string) (DriverVersion, error) { parts := strings.Split(version, ".") - if len(parts) != 3 { + if len(parts) < 2 || len(parts) > 3 { return DriverVersion{}, fmt.Errorf("invalid format of version string %q", version) } var ( @@ -52,9 +52,13 @@ func DriverVersionFrom(version string) (DriverVersion, error) { if err != nil { return DriverVersion{}, fmt.Errorf("invalid format for minor version %q: %v", version, err) } - res.patch, err = strconv.Atoi(parts[2]) - if err != nil { - return DriverVersion{}, fmt.Errorf("invalid format for patch version %q: %v", version, err) + if len(parts) == 3 { + res.patch, err = strconv.Atoi(parts[2]) + if err != nil { + return DriverVersion{}, fmt.Errorf("invalid format for patch version %q: %v", version, err) + } + } else { + res.patch = 0 } return res, nil } diff --git a/pkg/sentry/devices/nvproxy/nvproxy_driver_parity_test.go b/pkg/sentry/devices/nvproxy/nvproxy_driver_parity_test.go index cdd78f4abd..0d8ef9f8bb 100644 --- a/pkg/sentry/devices/nvproxy/nvproxy_driver_parity_test.go +++ b/pkg/sentry/devices/nvproxy/nvproxy_driver_parity_test.go @@ -21,6 +21,7 @@ package nvproxy_driver_parity_test import ( "context" + "errors" "fmt" "reflect" "regexp" @@ -70,6 +71,9 @@ func getDriverDefs(t *testing.T, runner *parser.Runner, version nvconf.DriverVer // Run parser defs, err := runner.ParseDriver(version) if err != nil { + if errors.Is(err, parser.ErrDriverSourceNotFound) { + t.Skipf("Skipping parity test for %s because driver source is not available: %v", version, err) + } t.Fatalf("failed to run driver_ast_parser: %v", err) } diff --git a/pkg/sentry/devices/nvproxy/version.go b/pkg/sentry/devices/nvproxy/version.go index 6c4047ab43..0a0d382128 100644 --- a/pkg/sentry/devices/nvproxy/version.go +++ b/pkg/sentry/devices/nvproxy/version.go @@ -1110,7 +1110,7 @@ func Init() { v595_71_05 := addUnsupportedDriverABI(595, 71, 05, v590_48_01) - _ = addUnsupportedDriverABI(610, 43, 02, func() *driverABI { + v610_43_02 := addUnsupportedDriverABI(610, 43, 02, func() *driverABI { abi := v595_71_05() // UVM range groups were removed in 610.43.02. delete(abi.uvmIoctl, nvgpu.UVM_CREATE_RANGE_GROUP) @@ -1161,6 +1161,8 @@ func Init() { } return abi }) + + _ = addDriverABI(615, 15, 00, ChecksumNoDriver, "d5a40daa72e011395721f2a3de8598b77c3271eec057948de9b3d1755d8d02bc", v610_43_02) }) } diff --git a/tools/gpu/drivers/install_driver.go b/tools/gpu/drivers/install_driver.go index 289ad4eb72..16a95cd759 100644 --- a/tools/gpu/drivers/install_driver.go +++ b/tools/gpu/drivers/install_driver.go @@ -66,6 +66,27 @@ type Installer struct { installFunc func(string) error } +func latestInstallableDriver() (nvconf.DriverVersion, error) { + var latest nvconf.DriverVersion + var found bool + nvproxy.ForEachSupportDriver(func(version nvconf.DriverVersion, checksums nvproxy.Checksums) { + checksum, err := checksums.Checksum() + if err != nil { + return + } + if checksum != nvproxy.ChecksumNoDriver && checksum != "" { + if version.IsGreaterThan(latest) { + latest = version + found = true + } + } + }) + if !found { + return nvconf.DriverVersion{}, fmt.Errorf("no installable driver found for arch %q", runtime.GOARCH) + } + return latest, nil +} + // NewInstaller returns a driver installer instance. func NewInstaller(requestedVersion string, latest bool) (*Installer, error) { @@ -77,7 +98,11 @@ func NewInstaller(requestedVersion string, latest bool) (*Installer, error) { } switch { case latest: - ret.requestedVersion = nvproxy.LatestDriver() + version, err := latestInstallableDriver() + if err != nil { + return nil, err + } + ret.requestedVersion = version default: d, err := nvconf.DriverVersionFrom(requestedVersion) if err != nil { diff --git a/tools/nvidia_driver_differ/parser/auxiliary_files.go b/tools/nvidia_driver_differ/parser/auxiliary_files.go index 1879c4a9e7..d3efe597c1 100644 --- a/tools/nvidia_driver_differ/parser/auxiliary_files.go +++ b/tools/nvidia_driver_differ/parser/auxiliary_files.go @@ -15,15 +15,20 @@ package parser import ( + "errors" "fmt" "os" "os/exec" "path" + "strings" "gvisor.dev/gvisor/pkg/sentry/devices/nvproxy" "gvisor.dev/gvisor/pkg/sentry/devices/nvproxy/nvconf" ) +// ErrDriverSourceNotFound is returned when the driver source code cannot be found. +var ErrDriverSourceNotFound = errors.New("driver source not found") + // GitRepoURL is the URL for the NVIDIA open-gpu-kernel-modules repo. const GitRepoURL = "https://github.com/NVIDIA/open-gpu-kernel-modules.git" @@ -41,6 +46,9 @@ func CloneDriverSource(dir string, version nvconf.DriverVersion) (*DriverSourceD } cmd := exec.Command("git", args...) if out, err := cmd.CombinedOutput(); err != nil { + if strings.Contains(string(out), "not found in upstream origin") { + return nil, fmt.Errorf("%w: %s", ErrDriverSourceNotFound, string(out)) + } return nil, fmt.Errorf("failed to clone %s: %w\n%s", version, err, string(out)) } return &DriverSourceDir{