...
 
Commits (27)
nvidia-modprobe (390.87-1~bpo9+1) stretch-backports; urgency=medium
* Rebuild for stretch-backports.
-- Andreas Beckmann <anbe@debian.org> Fri, 25 Jan 2019 20:28:46 +0100
nvidia-modprobe (390.87-1) unstable; urgency=medium
* New upstream release.
* Bump Standards-Version to 4.3.0. No changes needed.
-- Andreas Beckmann <anbe@debian.org> Thu, 17 Jan 2019 02:31:04 +0100
nvidia-modprobe (390.25-1) unstable; urgency=medium
* New upstream release.
-- Andreas Beckmann <anbe@debian.org> Tue, 06 Mar 2018 04:37:14 +0100
nvidia-modprobe (384.111-2~deb9u1) stretch; urgency=medium
* Rebuild for stretch.
-- Andreas Beckmann <anbe@debian.org> Wed, 28 Feb 2018 13:40:28 +0100
nvidia-modprobe (384.111-2) unstable; urgency=medium
* Add setuid.patch to run setuid(0) before forking modprobe to preserve
privileges through shell invocations and recursive modprobe calls.
Thanks to Hiromasa YOSHIMOTO for intensive debugging and the final patch!
(Closes: #888952)
* Add debian/upstream/metadata.
* Fix new Lintian issues.
* Switch Vcs-* URLs to salsa.debian.org.
-- Andreas Beckmann <anbe@debian.org> Tue, 27 Feb 2018 01:50:01 +0100
nvidia-modprobe (384.111-1~bpo9+1) stretch-backports; urgency=medium
* Rebuild for stretch-backports.
......
......@@ -10,10 +10,10 @@ Build-Depends:
dpkg-dev (>= 1.18.8),
m4,
Rules-Requires-Root: binary-targets
Standards-Version: 4.1.3
Standards-Version: 4.3.0
Homepage: https://github.com/NVIDIA/nvidia-modprobe
Vcs-Git: https://anonscm.debian.org/git/pkg-nvidia/nvidia-modprobe.git
Vcs-Browser: https://anonscm.debian.org/cgit/pkg-nvidia/nvidia-modprobe.git
Vcs-Browser: https://salsa.debian.org/nvidia-team/nvidia-modprobe
Vcs-Git: https://salsa.debian.org/nvidia-team/nvidia-modprobe.git
Package: nvidia-modprobe
Architecture: i386 amd64 armhf ppc64el
......
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: nvidia-modprobe
Source: https://download.nvidia.com/XFree86/nvidia-modprobe/
Disclaimer:
This package is not part of the GNU/Linux Debian distribution. It is
provided in the contrib archive area as a convenience to Debian users.
The contents of this source package are freely licensed under the Expat
license, but it is only useful in combination with the proprietary
NVIDIA drivers in non-free.
Files: *
Copyright: Copyright (C) 2004-2017 NVIDIA Corporation
......@@ -19,7 +25,7 @@ Copyright: (C) Copyright IBM Corporation 2006
License: Expat
Files: debian/*
Copyright: © 2014-2018 Andreas Beckmann <anbe@debian.org>
Copyright: © 2014-2019 Andreas Beckmann <anbe@debian.org>
License: Expat
License: Expat
......
Author: Hiromasa YOSHIMOTO <hiromasa.yoshimoto@gmail.com>
Description: use setuid(0) to preserve privileges over shell invocations
Fixing bug https://bugs.debian.org/734869 dash recently started to drop
privileges if euid != uid. (Bash has been doing that for a long time
already, but is usually not used for /bin/sh.)
The Debian modprobe configuration /etc/modprobe.d/nvidia.conf uses install
commands that require forking a shell from within modprobe to (recursively)
run further modprobe commands. If the shell drops privileges in setuid
contexts, the inner modprobe commands are run unprivileged, failing to load
the modules.
Run setuid(0) before forking modprobe to preserve privileges through to the
inner modprobe commands.
Bug-Debian: https://bugs.debian.org/888952
--- nvidia-modprobe-384.111.orig/modprobe-utils/nvidia-modprobe-utils.c
+++ nvidia-modprobe-384.111/modprobe-utils/nvidia-modprobe-utils.c
@@ -374,6 +374,10 @@ static int modprobe_helper(const int pri
*/
silence_current_process();
+ /* Workaround for debian's /etc/modprobe.d/nvidia.conf configuration.
+ * See Bug#888952 for details */
+ setuid(0);
+
execle(modprobe_path, "modprobe",
module_name, NULL, envp);
# upstream provides no signatures
debian-watch-may-check-gpg-signature
debian-watch-does-not-check-gpg-signature
Name: nvidia-modprobe
Repository: https://github.com/NVIDIA/nvidia-modprobe.git
Repository-Browse: https://github.com/NVIDIA/nvidia-modprobe
......@@ -62,6 +62,11 @@
#define NV_MODESET_MODULE_NAME "nvidia-modeset"
#define NV_VGPU_VFIO_MODULE_NAME "nvidia-vgpu-vfio"
#define NV_NVLINK_MODULE_NAME "nvidia-nvlink"
#define NV_NVLINK_PROC_PERM_PATH "/proc/driver/nvidia-nvlink/permissions"
#define NV_DEVICE_FILE_MODE_MASK (S_IRWXU|S_IRWXG|S_IRWXO)
#define NV_DEVICE_FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
#define NV_DEVICE_FILE_UID 0
......@@ -477,6 +482,65 @@ static void init_device_file_parameters(uid_t *uid, gid_t *gid, mode_t *mode,
fclose(fp);
}
/*
* A helper to query device file states.
*/
static int get_file_state_helper(
const char *path,
int major,
int minor,
const char *proc_path,
uid_t uid,
gid_t gid,
mode_t mode)
{
dev_t dev = NV_MAKE_DEVICE(major, minor);
struct stat stat_buf;
int ret;
int state = 0;
ret = stat(path, &stat_buf);
if (ret == 0)
{
nvidia_update_file_state(&state, NvDeviceFileStateFileExists);
if (S_ISCHR(stat_buf.st_mode) && (stat_buf.st_rdev == dev))
{
nvidia_update_file_state(&state, NvDeviceFileStateChrDevOk);
}
if (((stat_buf.st_mode & NV_DEVICE_FILE_MODE_MASK) == mode) &&
(stat_buf.st_uid == uid) &&
(stat_buf.st_gid == gid))
{
nvidia_update_file_state(&state, NvDeviceFileStatePermissionsOk);
}
}
return state;
}
int nvidia_get_file_state(int minor, int module_instance)
{
char path[NV_MAX_CHARACTER_DEVICE_FILE_STRLEN];
char proc_path[NV_MAX_PROC_REGISTRY_PATH_SIZE];
mode_t mode;
uid_t uid;
gid_t gid;
int modification_allowed;
int state = 0;
assign_device_file_name(path, minor, module_instance);
assign_proc_registry_path(proc_path, module_instance);
init_device_file_parameters(&uid, &gid, &mode, &modification_allowed,
proc_path);
state = get_file_state_helper(path, NV_MAJOR_DEVICE_NUMBER, minor,
proc_path, uid, gid, mode);
return state;
}
/*
* Attempt to create the specified device file with the specified major
......@@ -484,8 +548,8 @@ static void init_device_file_parameters(uid_t *uid, gid_t *gid, mode_t *mode,
* permissions. Returns 1 if the file is successfully created; returns 0
* if the file could not be created.
*/
static int mknod_helper(int major, int minor, const char *path,
const char *proc_path)
int mknod_helper(int major, int minor, const char *path,
const char *proc_path)
{
dev_t dev = NV_MAKE_DEVICE(major, minor);
mode_t mode;
......@@ -493,7 +557,7 @@ static int mknod_helper(int major, int minor, const char *path,
gid_t gid;
int modification_allowed;
int ret;
struct stat stat_buf;
int state;
int do_mknod;
if (path == NULL || path[0] == '\0')
......@@ -511,18 +575,12 @@ static int mknod_helper(int major, int minor, const char *path,
return 1;
}
/*
* If the device file already exists with correct properties,
* nothing to do: success.
*/
ret = stat(path, &stat_buf);
state = get_file_state_helper(path, major, minor,
proc_path, uid, gid, mode);
if ((ret == 0) &&
(S_ISCHR(stat_buf.st_mode)) &&
(stat_buf.st_rdev == dev) &&
((stat_buf.st_mode & NV_DEVICE_FILE_MODE_MASK) == mode) &&
(stat_buf.st_uid == uid) &&
(stat_buf.st_gid == gid))
if (nvidia_test_file_state(state, NvDeviceFileStateFileExists) &&
nvidia_test_file_state(state, NvDeviceFileStateChrDevOk) &&
nvidia_test_file_state(state, NvDeviceFileStatePermissionsOk))
{
return 1;
}
......@@ -531,19 +589,18 @@ static int mknod_helper(int major, int minor, const char *path,
do_mknod = 0;
if (ret != 0)
if (!nvidia_test_file_state(state, NvDeviceFileStateFileExists))
{
do_mknod = 1;
}
/*
* If the stat(2) above succeeded but the file is either not a
* character device or has the wrong major/minor character device
* number, then we need to delete it and recreate it.
* If the file exists but the file is either not a character device or has
* the wrong major/minor character device number, then we need to delete it
* and recreate it.
*/
if ((ret == 0) &&
(!S_ISCHR(stat_buf.st_mode) ||
(stat_buf.st_rdev != dev)))
if (!do_mknod &&
!nvidia_test_file_state(state, NvDeviceFileStateChrDevOk))
{
ret = remove(path);
if (ret != 0)
......@@ -602,7 +659,7 @@ int nvidia_mknod(int minor, int module_instance)
* device with the specified name. Returns the major number on success,
* or -1 on failure.
*/
static int get_chardev_major(const char *name)
int get_chardev_major(const char *name)
{
int ret = -1;
char line[NV_MAX_LINE_LENGTH];
......@@ -714,11 +771,50 @@ int nvidia_modeset_mknod(void)
{
char proc_path[NV_MAX_PROC_REGISTRY_PATH_SIZE];
assign_proc_registry_path(proc_path, 0);
assign_proc_registry_path(proc_path, NV_MODULE_INSTANCE_NONE);
return mknod_helper(NV_MAJOR_DEVICE_NUMBER,
NV_MODESET_MINOR_DEVICE_NUM,
NV_MODESET_DEVICE_NAME, proc_path);
}
/*
* Attempt to create the NVIDIA NVLink driver device file.
*/
int nvidia_nvlink_mknod(void)
{
int major = get_chardev_major(NV_NVLINK_MODULE_NAME);
if (major < 0)
{
return 0;
}
return mknod_helper(major,
0,
NV_NVLINK_DEVICE_NAME,
NV_NVLINK_PROC_PERM_PATH);
}
int nvidia_vgpu_vfio_mknod(int minor_num)
{
int major = get_chardev_major(NV_VGPU_VFIO_MODULE_NAME);
char vgpu_dev_name[NV_MAX_CHARACTER_DEVICE_FILE_STRLEN];
char proc_path[NV_MAX_PROC_REGISTRY_PATH_SIZE];
if (major < 0)
{
return 0;
}
assign_proc_registry_path(proc_path, NV_MODULE_INSTANCE_NONE);
snprintf(vgpu_dev_name, NV_MAX_CHARACTER_DEVICE_FILE_STRLEN,
NV_VGPU_VFIO_DEVICE_NAME, minor_num);
vgpu_dev_name[NV_MAX_CHARACTER_DEVICE_FILE_STRLEN - 1] = '\0';
return mknod_helper(major, minor_num, vgpu_dev_name, proc_path);
}
#endif /* NV_LINUX */
......@@ -42,6 +42,8 @@
#define NV_DEVICE_FILE_PATH "/dev/nvidia%d"
#define NV_CTRL_DEVICE_FILE_PATH "/dev/nvidiactl"
#define NV_MODESET_DEVICE_NAME "/dev/nvidia-modeset"
#define NV_VGPU_VFIO_DEVICE_NAME "/dev/nvidia-vgpu%d"
#define NV_NVLINK_DEVICE_NAME "/dev/nvidia-nvlink"
#define NV_NMODULE_CTRL_DEVICE_FILE_PATH "/dev/nvidiactl%d"
......@@ -55,16 +57,39 @@
#if defined(NV_LINUX)
typedef enum
{
NvDeviceFileStateFileExists = 0,
NvDeviceFileStateChrDevOk,
NvDeviceFileStatePermissionsOk
} NvDeviceFileState;
static __inline__ void nvidia_update_file_state(int *state,
NvDeviceFileState value)
{
*state |= (1 << value);
}
static __inline__ int nvidia_test_file_state(int state,
NvDeviceFileState value)
{
return !!(state & (1 << value));
}
int nvidia_get_file_state(int minor, int module_instance);
int nvidia_modprobe(const int print_errors, int module_instance);
int nvidia_mknod(int minor, int module_instance);
int nvidia_uvm_modprobe(void);
#define nvidia_uvm_modprobe(print_errors) nvidia_uvm_modprobe()
int nvidia_uvm_mknod(int base_minor);
int nvidia_modeset_modprobe(void);
int nvidia_modeset_mknod(void);
int nvidia_vgpu_vfio_mknod(int minor_num);
int nvidia_nvlink_mknod(void);
#endif /* NV_LINUX */
int mknod_helper(int major, int minor, const char *path, const char *proc_path);
int get_chardev_major(const char *name);
#endif /* NV_LINUX */
/*
* Detect use of multiple kernel module instances. Use a single
......
/*
* (C) Copyright IBM Corporation 2006
*
* Copyright (c) 2014-2017 NVIDIA Corporation
* Copyright (c) 2014 NVIDIA Corporation
*
* All Rights Reserved.
*
......@@ -51,8 +51,6 @@
#include <sys/mman.h>
#include <dirent.h>
#include <errno.h>
#include <sys/time.h>
#include <time.h>
#include "pci-enum.h"
#include "pci-sysfs.h"
......@@ -60,23 +58,11 @@
#define SYS_BUS_PCI "/sys/bus/pci/"
#define SYS_BUS_PCI_DEVICES SYS_BUS_PCI "devices"
#define SYS_BUS_PCI_RESCAN SYS_BUS_PCI "rescan"
#define PCI_DBDF_FORMAT "%04x:%02x:%02x.%1u"
#define SYSFS_PCI_BRIDGE_RESCAN_FMT SYS_BUS_PCI_DEVICES "/" PCI_DBDF_FORMAT "/rescan"
#define SYSFS_PCI_BRIDGE_RESCAN_FMT SYS_BUS_PCI_DEVICES "/%04x:%02x:%02x.%1x/rescan"
#define SYSFS_RESCAN_STRING "1\n"
#define SYSFS_RESCAN_STRING_SIZE 2
#define PCI_CAP_TTL_MAX 20
#define SYSFS_PATH_SIZE 256
#define BAIL_ON_IO_ERR(buf, err, cnt, action) \
do { \
if (((err) != 0) || ((cnt) < sizeof(buf))) \
{ \
(err) = ((err) == 0) ? EIO : (err); \
action; \
} \
} while (0)
static int pci_sysfs_read_cfg(uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, void *,
static int pci_sysfs_read_cfg(uint16_t, uint16_t, uint16_t, uint16_t, void *,
uint16_t size, uint16_t *);
static int find_matches(struct pci_id_match *match);
......@@ -142,10 +128,10 @@ find_matches(struct pci_id_match *match)
continue;
}
sscanf(d->d_name, PCI_DBDF_FORMAT,
sscanf(d->d_name, "%04x:%02x:%02x.%1u",
& dom, & bus, & dev, & func);
err = pci_sysfs_read_cfg(dom, bus, dev, func, 0, config, 48, & bytes);
err = pci_sysfs_read_cfg(dom, bus, dev, func, config, 48, & bytes);
if ((bytes == 48) && !err)
{
vendor_id = (uint16_t)config[0] + ((uint16_t)config[1] << 8);
......@@ -184,10 +170,10 @@ find_matches(struct pci_id_match *match)
static int
pci_sysfs_read_cfg(uint16_t domain, uint16_t bus, uint16_t device,
uint16_t function, uint16_t off, void *data,
uint16_t size, uint16_t *bytes_read)
uint16_t function, void * data, uint16_t size,
uint16_t *bytes_read)
{
char name[SYSFS_PATH_SIZE];
char name[256];
uint16_t temp_size = size;
int err = 0;
int fd;
......@@ -204,7 +190,7 @@ pci_sysfs_read_cfg(uint16_t domain, uint16_t bus, uint16_t device,
* space. It is used here to obtain most of the information about the
* device.
*/
snprintf(name, SYSFS_PATH_SIZE - 1, "%s/" PCI_DBDF_FORMAT "/config",
snprintf(name, 255, "%s/%04x:%02x:%02x.%1u/config",
SYS_BUS_PCI_DEVICES, domain, bus, device, function);
fd = open(name, O_RDONLY);
......@@ -213,15 +199,6 @@ pci_sysfs_read_cfg(uint16_t domain, uint16_t bus, uint16_t device,
return errno;
}
if (off != 0)
{
if (lseek(fd, (off_t) off, SEEK_SET) < 0)
{
close(fd);
return errno;
}
}
while (temp_size > 0)
{
const ssize_t bytes = read(fd, data_bytes, temp_size);
......@@ -249,81 +226,11 @@ pci_sysfs_read_cfg(uint16_t domain, uint16_t bus, uint16_t device,
return err;
}
static int
pci_sysfs_write_cfg(uint16_t domain, uint16_t bus, uint16_t device,
uint16_t function, uint16_t off, void *data,
uint16_t size, uint16_t *bytes_written)
{
char name[SYSFS_PATH_SIZE];
uint16_t temp_size = size;
int err = 0;
int fd;
char *data_bytes = data;
if (bytes_written != NULL)
{
*bytes_written = 0;
}
/*
* Each device has a directory under sysfs. Within that directory there
* is a file named "config". This file used to access the PCI config
* space.
*/
snprintf(name, SYSFS_PATH_SIZE - 1, "%s/" PCI_DBDF_FORMAT "/config",
SYS_BUS_PCI_DEVICES, domain, bus, device, function);
fd = open(name, O_WRONLY);
if (fd < 0)
{
return errno;
}
if (off != 0)
{
if (lseek(fd, (off_t) off, SEEK_SET) < 0)
{
close(fd);
return errno;
}
}
while (temp_size > 0)
{
const ssize_t bytes = write(fd, data_bytes, temp_size);
if (bytes < 0)
{
err = errno;
break;
}
/*
* If zero bytes were written, then we assume it's the end of the
* config file.
*/
if (bytes == 0)
{
break;
}
temp_size -= bytes;
data_bytes += bytes;
}
if (bytes_written != NULL)
{
*bytes_written = size - temp_size;
}
close(fd);
return err;
}
int
pci_rescan(uint16_t domain, uint8_t bus, uint8_t slot, uint8_t function)
{
char const *node;
char node_buf[SYSFS_PATH_SIZE];
char node_buf[256];
int node_fd;
ssize_t cnt;
......@@ -353,153 +260,4 @@ pci_rescan(uint16_t domain, uint8_t bus, uint8_t slot, uint8_t function)
return cnt == SYSFS_RESCAN_STRING_SIZE ? 0 : EIO;
}
int
pci_find_parent_bridge(pci_info_t *p_gpu_info, pci_info_t *p_bridge_info)
{
char gpu_path[SYSFS_PATH_SIZE];
char bridge_path[SYSFS_PATH_SIZE];
char *p_node;
snprintf(gpu_path, SYSFS_PATH_SIZE - 1, "%s/" PCI_DBDF_FORMAT "/..", SYS_BUS_PCI_DEVICES,
p_gpu_info->domain, p_gpu_info->bus,
p_gpu_info->dev, p_gpu_info->ftn);
if (realpath(gpu_path, bridge_path) == NULL)
{
return errno;
}
p_node = strrchr(bridge_path, '/');
if (p_node == NULL)
{
return ENOENT;
}
++p_node;
if (sscanf(p_node, PCI_DBDF_FORMAT,
&p_bridge_info->domain, &p_bridge_info->bus,
&p_bridge_info->dev, &p_bridge_info->ftn) != 4)
{
return ENOENT;
}
return 0;
}
static int
pci_find_pcie_caps(uint16_t domain, uint8_t bus, uint8_t device, uint8_t ftn, uint8_t *p_caps)
{
unsigned ttl;
uint8_t off;
uint8_t cap_id;
int err = ENXIO;
uint16_t cnt;
for (off = PCI_CAPABILITY_LIST, ttl = PCI_CAP_TTL_MAX; ttl; --ttl)
{
err = pci_sysfs_read_cfg(domain, bus, device, ftn, off,
&off, sizeof(off), &cnt);
BAIL_ON_IO_ERR(off, err, cnt, break);
/* Capabilities must reside above the std config header */
if ((off < PCI_STD_HEADER_SIZEOF) || (off == 0xff))
{
break;
}
/* Clear the reserved bits */
off &= ~3;
err = pci_sysfs_read_cfg(domain, bus, device, ftn, off + PCI_CAP_LIST_ID,
&cap_id, sizeof(cap_id), &cnt);
BAIL_ON_IO_ERR(cap_id, err, cnt, break);
if (cap_id == PCI_CAP_ID_EXP)
{
goto found;
}
if (cap_id == 0xff)
{
break;
}
off += PCI_CAP_LIST_NEXT;
}
return err;
found:
*p_caps = off;
return 0;
}
int
pci_bridge_link_set_enable(uint16_t domain, uint8_t bus, uint8_t device, uint8_t ftn, int enable)
{
uint8_t pcie_caps = 0;
uint16_t reg;
uint16_t cnt;
int err;
struct timeval start;
struct timeval curr;
struct timeval diff;
struct timespec delay = {0, PCI_LINK_DELAY_NS};
err = pci_find_pcie_caps(domain, bus, device, ftn, &pcie_caps);
if (err != 0)
{
return err;
}
err = pci_sysfs_read_cfg(domain, bus, device, ftn, pcie_caps + PCI_EXP_LNKCTL,
&reg, sizeof(reg), &cnt);
BAIL_ON_IO_ERR(reg, err, cnt, return err);
if (enable)
{
reg &= ~PCI_EXP_LNKCTL_LD;
}
else
{
reg |= PCI_EXP_LNKCTL_LD;
}
err = pci_sysfs_write_cfg(domain, bus, device, ftn, pcie_caps + PCI_EXP_LNKCTL,
&reg, sizeof(reg), &cnt);
BAIL_ON_IO_ERR(reg, err, cnt, return err);
if (enable)
{
/* wait for the link to go up and then sleep for 100 ms */
gettimeofday(&start, NULL);
for (;;)
{
err = pci_sysfs_read_cfg(domain, bus, device, ftn, pcie_caps + PCI_EXP_LNKSTA,
&reg, sizeof(reg), &cnt);
BAIL_ON_IO_ERR(reg, err, cnt, return err);
if ((reg & PCI_EXP_LNKSTA_DLLLA) != 0)
{
break;
}
gettimeofday(&curr, NULL);
timersub(&curr, &start, &diff);
if ((diff.tv_sec > 0) || (diff.tv_usec >= PCI_LINK_WAIT_US))
{
return ETIME;
}
}
PCI_NANOSLEEP(&delay, NULL);
}
return err;
}
#endif /* defined(NV_LINUX) */
/*
* Copyright (c) 2016-2017, NVIDIA CORPORATION.
* Copyright (c) 2016, NVIDIA CORPORATION.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
......@@ -28,51 +28,6 @@
#ifndef __PCI_SYSFS_H__
#define __PCI_SYSFS_H__
#if defined(NV_LINUX)
#include <linux/pci.h>
#if !defined(PCI_STD_HEADER_SIZEOF)
#define PCI_STD_HEADER_SIZEOF 64
#endif
#if !defined(PCI_CAP_ID_EXP)
#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
#endif
#if !defined(PCI_EXP_LNKCTL)
#define PCI_EXP_LNKCTL 16 /* Link Control */
#endif
#if !defined(PCI_EXP_LNKCTL_LD)
#define PCI_EXP_LNKCTL_LD 0x0010 /* Link Disable */
#endif
#if !defined(PCI_EXP_LNKSTA)
#define PCI_EXP_LNKSTA 18 /* Link Status */
#endif
#if !defined(PCI_EXP_LNKSTA_DLLLA)
#define PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */
#endif
#define PCI_LINK_WAIT_US 200000 /* 200 ms, must be less than 1000000 (1s) */
#define PCI_LINK_DELAY_NS 100000000 /* 100 ms */
#if (_POSIX_C_SOURCE >= 199309L)
#define PCI_NANOSLEEP(ts, rem) nanosleep(ts, rem)
#elif !(_POSIX_C_SOURCE >= 200809L)
#define PCI_NANOSLEEP(ts, rem) usleep((ts)->tv_sec * 1000000 + ((ts)->tv_nsec + 999) / 1000)
#else
#define PCI_NANOSLEEP(ts, rem) sleep((ts)->tv_sec + ((ts)->tv_nsec + 999999999) / 1000000000)
#endif
typedef struct {
unsigned domain;
unsigned bus;
unsigned dev;
unsigned ftn;
} pci_info_t;
int pci_rescan(uint16_t domain, uint8_t bus, uint8_t slot, uint8_t function);
int pci_find_parent_bridge(pci_info_t *p_gpu_info, pci_info_t *p_bridge_info);
int pci_bridge_link_set_enable(uint16_t domain, uint8_t bus, uint8_t device, uint8_t ftn, int enable);
#endif /* NV_LINUX */
#endif /* __PCI_SYSFS_H__ */
......@@ -80,6 +80,7 @@ HOSTNAME_CMD ?= hostname
DATE ?= date
GZIP_CMD ?= gzip
CHMOD ?= chmod
OBJCOPY ?= objcopy
NV_AUTO_DEPEND ?= 1
NV_VERBOSE ?= 0
......@@ -271,10 +272,14 @@ endif
NV_MODULE_LOGGING_NAME ?=
ifeq ($(NV_VERBOSE),0)
quiet_cmd = @$(PRINTF) \
at_if_quiet := @
quiet_cmd_no_at = $(PRINTF) \
" $(if $(NV_MODULE_LOGGING_NAME),[ %-17.17s ],%s) $(quiet_$(1))\n" \
"$(NV_MODULE_LOGGING_NAME)" && $($(1))
quiet_cmd = @$(quiet_cmd_no_at)
else
at_if_quiet :=
quiet_cmd_no_at = $($(1))
quiet_cmd = $($(1))
endif
......@@ -295,6 +300,8 @@ quiet_HOST_LINK = $(call define_quiet_cmd,HOST_LINK ,$@)
quiet_M4 = $(call define_quiet_cmd,M4 ,$<)
quiet_STRIP_CMD = $(call define_quiet_cmd,STRIP ,$@)
quiet_HARDLINK = $(call define_quiet_cmd,HARDLINK ,$@)
quiet_LD = $(call define_quiet_cmd,LD ,$@)
quiet_OBJCOPY = $(call define_quiet_cmd,OBJCOPY ,$@)
##############################################################################
# Tell gmake to delete the target of a rule if it has changed and its
......@@ -447,3 +454,30 @@ define DEFINE_STAMP_C_RULE
@ $$(PRINTF) "%s\n" "const char *pNV_ID = NV_ID + 11;" >> $$@
endef
##############################################################################
# Define rules that can be used for embedding a file into an ELF object that
# contains the raw contents of that file and symbols pointing to the embedded
# data.
#
# Note that objcopy will name the symbols in the resulting object file based on
# the filename specified in $(1). For example,
#
# $(eval $(call $(READ_ONLY_OBJECT_FROM_FILE_RULE),a/b/c))
#
# will create an object named $(OUTPUTDIR)/c.o with the symbols _binary_c_start,
# _binary_c_end, and _binary_c_size.
#
# Arguments:
# $(1): Path to the file to convert
##############################################################################
define READ_ONLY_OBJECT_FROM_FILE_RULE
$$(OUTPUTDIR)/$$(notdir $(1)).o: $(1)
$(at_if_quiet)cd $$(dir $(1)); \
$$(call quiet_cmd_no_at,LD) -r -z noexecstack --format=binary \
$$(notdir $(1)) -o $$(OUTPUTDIR_ABSOLUTE)/$$(notdir $$@)
$$(call quiet_cmd,OBJCOPY) \
--rename-section .data=.rodata,contents,alloc,load,data,readonly \
$$@
endef
NVIDIA_VERSION = 384.111
NVIDIA_VERSION = 390.87