Skip to content

Commit

Permalink
Add opt-in feature for GSP firmware injection
Browse files Browse the repository at this point in the history
This change stops the injection of GSP firmware by default.
An opt-in config option or cdi generate argument is available to
revert to the previous behaviour.

Signed-off-by: Evan Lezar <[email protected]>
  • Loading branch information
elezar committed Sep 17, 2024
1 parent e2d0822 commit f74d321
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 65 deletions.
3 changes: 3 additions & 0 deletions cmd/nvidia-container-runtime-hook/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ func doPrestart() {
if !hook.Features.AllowFabricmanager.IsEnabled() {
args = append(args, "--no-fabricmanager")
}
if !hook.Features.AllowGSPFirmware.IsEnabled() {
args = append(args, "--no-gsp-firmware")
}
if !hook.Features.AllowPersistenced.IsEnabled() {
args = append(args, "--no-persistenced")
}
Expand Down
8 changes: 8 additions & 0 deletions cmd/nvidia-ctk/cdi/generate/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type options struct {
}

withFabricmanager bool
withGSPFirmware bool
withPersistenced bool
}

Expand Down Expand Up @@ -177,6 +178,12 @@ func (m command) build() *cli.Command {
Usage: "Include the nvidia-fabricmanager socket in the generated CDI specification.",
Destination: &opts.withFabricmanager,
},
&cli.BoolFlag{
Name: "with-gsp-firmware",
Aliases: []string{"allow-gsp-firmware"},
Usage: "Include the GST firmware in the generated CDI specification.",
Destination: &opts.withGSPFirmware,
},
&cli.BoolFlag{
Name: "with-persistenced",
Usage: "Include the nvidia-persistenced socket in the generated CDI specification.",
Expand Down Expand Up @@ -287,6 +294,7 @@ func (m command) generateSpec(opts *options) (spec.Interface, error) {
nvcdi.WithCSVFiles(opts.csv.files.Value()),
nvcdi.WithCSVIgnorePatterns(opts.csv.ignorePatterns.Value()),
nvcdi.WithOptInFeature("allow-fabricmanager", opts.withFabricmanager),
nvcdi.WithOptInFeature("allow-gsp-firmware", opts.withGSPFirmware),
nvcdi.WithOptInFeature("allow-persistenced", opts.withPersistenced),
)
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions internal/config/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
FeatureAllowFabricmanager = featureName("allow-fabricmanager")
FeatureAllowLdconfigOverride = featureName("allow-ldconfig-override")
FeatureAllowPersistenced = featureName("allow-persistenced")
FeatureAllowGSPFirmware = featureName("allow-gsp-firmware")
)

// features specifies a set of named features.
Expand All @@ -37,6 +38,8 @@ type features struct {
// AllowFabricmanager enables the injection of the nvidia-fabricmanager
// socket into containers.
AllowFabricmanager *feature `toml:"allow-fabricmanager,omitempty"`
// AllowGSPFirmware enables the injection of GSP firmware into containers.
AllowGSPFirmware *feature `toml:"allow-gsp-firmware,omitempty"`
// AllowLDConfigOverride forces the nvidia-container-cli.ldconfig config
// option to be used instead of the default of @/sbin/ldconfig.
AllowLDConfigOverride *feature `toml:"allow-ldconfig-override,omitempty"`
Expand Down Expand Up @@ -64,6 +67,8 @@ func (fs features) IsEnabledInEnvironment(n featureName, in ...getenver) bool {
// Features without envvar overrides
case FeatureAllowFabricmanager:
return fs.AllowFabricmanager.IsEnabled()
case FeatureAllowGSPFirmware:
return fs.AllowGSPFirmware.IsEnabled()
case FeatureAllowLdconfigOverride:
return fs.AllowLDConfigOverride.IsEnabled()
case FeatureAllowPersistenced:
Expand Down
1 change: 1 addition & 0 deletions internal/modifier/cdi.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ func generateAutomaticCDISpec(logger logger.Interface, cfg *config.Config, devic
nvcdi.WithVendor("runtime.nvidia.com"),
nvcdi.WithClass("gpu"),
nvcdi.WithOptInFeature("allow-fabricmanager", cfg.Features.AllowFabricmanager.IsEnabled()),
nvcdi.WithOptInFeature("allow-gsp-firmware", cfg.Features.AllowGSPFirmware.IsEnabled()),
nvcdi.WithOptInFeature("allow-persistenced", cfg.Features.AllowPersistenced.IsEnabled()),
)
if err != nil {
Expand Down
65 changes: 1 addition & 64 deletions pkg/nvcdi/driver-nvml.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@ package nvcdi

import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/NVIDIA/go-nvml/pkg/nvml"
"golang.org/x/sys/unix"

"github.com/NVIDIA/nvidia-container-toolkit/internal/discover"
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
Expand Down Expand Up @@ -63,7 +61,7 @@ func (l *nvcdilib) newDriverVersionDiscoverer(version string) (discover.Discover
return nil, fmt.Errorf("failed to create discoverer for IPC sockets: %v", err)
}

firmwares, err := NewDriverFirmwareDiscoverer(l.logger, l.driver.Root, version)
firmwares, err := l.newDriverFirmwareDiscoverer(l.logger, l.driver.Root, version)
if err != nil {
return nil, fmt.Errorf("failed to create discoverer for GSP firmware: %v", err)
}
Expand Down Expand Up @@ -107,67 +105,6 @@ func NewDriverLibraryDiscoverer(logger logger.Interface, driver *root.Driver, nv
return d, nil
}

func getUTSRelease() (string, error) {
utsname := &unix.Utsname{}
if err := unix.Uname(utsname); err != nil {
return "", err
}
return unix.ByteSliceToString(utsname.Release[:]), nil
}

func getFirmwareSearchPaths(logger logger.Interface) ([]string, error) {

var firmwarePaths []string
if p := getCustomFirmwareClassPath(logger); p != "" {
logger.Debugf("using custom firmware class path: %s", p)
firmwarePaths = append(firmwarePaths, p)
}

utsRelease, err := getUTSRelease()
if err != nil {
return nil, fmt.Errorf("failed to get UTS_RELEASE: %v", err)
}

standardPaths := []string{
filepath.Join("/lib/firmware/updates/", utsRelease),
"/lib/firmware/updates/",
filepath.Join("/lib/firmware/", utsRelease),
"/lib/firmware/",
}

return append(firmwarePaths, standardPaths...), nil
}

// getCustomFirmwareClassPath returns the custom firmware class path if it exists.
func getCustomFirmwareClassPath(logger logger.Interface) string {
customFirmwareClassPath, err := os.ReadFile("/sys/module/firmware_class/parameters/path")
if err != nil {
logger.Warningf("failed to get custom firmware class path: %v", err)
return ""
}

return strings.TrimSpace(string(customFirmwareClassPath))
}

// NewDriverFirmwareDiscoverer creates a discoverer for GSP firmware associated with the specified driver version.
func NewDriverFirmwareDiscoverer(logger logger.Interface, driverRoot string, version string) (discover.Discover, error) {
gspFirmwareSearchPaths, err := getFirmwareSearchPaths(logger)
if err != nil {
return nil, fmt.Errorf("failed to get firmware search paths: %v", err)
}
gspFirmwarePaths := filepath.Join("nvidia", version, "gsp*.bin")
return discover.NewMounts(
logger,
lookup.NewFileLocator(
lookup.WithLogger(logger),
lookup.WithRoot(driverRoot),
lookup.WithSearchPaths(gspFirmwareSearchPaths...),
),
driverRoot,
[]string{gspFirmwarePaths},
), nil
}

// NewDriverBinariesDiscoverer creates a discoverer for GSP firmware associated with the GPU driver.
func NewDriverBinariesDiscoverer(logger logger.Interface, driverRoot string) discover.Discover {
return discover.NewMounts(
Expand Down
4 changes: 3 additions & 1 deletion pkg/nvcdi/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ type nvcdilib struct {

// New creates a new nvcdi library
func New(opts ...Option) (Interface, error) {
l := &nvcdilib{}
l := &nvcdilib{
optInFeatures: make(map[string]bool),
}
for _, opt := range opts {
opt(l)
}
Expand Down

0 comments on commit f74d321

Please sign in to comment.