diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2022-01-11 10:01:21 -0800 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2022-01-11 10:01:21 -0800 |
commit | 04c3e7bf6be5251cd554c6d4d943819fb34a4823 (patch) | |
tree | 80a7b9a61d624982e3af15577f9d35448a033480 | |
parent | f959b8b7b17c9b16bf6ef6d27c9345e3a0bdc5b0 (diff) |
-rw-r--r-- | Makefile | 31 | ||||
-rw-r--r-- | backup.c | 4 | ||||
-rw-r--r-- | common-utils/msg.c | 2 | ||||
-rw-r--r-- | common-utils/nvgetopt.c | 2 | ||||
-rw-r--r-- | common-utils/nvpci-utils.c | 65 | ||||
-rw-r--r-- | common-utils/nvpci-utils.h | 33 | ||||
-rw-r--r-- | common-utils/src.mk | 13 | ||||
-rw-r--r-- | dist-files.mk | 3 | ||||
-rw-r--r-- | files.c | 111 | ||||
-rw-r--r-- | files.h | 9 | ||||
-rw-r--r-- | install-from-cwd.c | 15 | ||||
-rw-r--r-- | kernel.c | 13 | ||||
-rw-r--r-- | misc.c | 365 | ||||
-rw-r--r-- | misc.h | 2 | ||||
-rw-r--r-- | mkprecompiled.c | 2 | ||||
-rw-r--r-- | nvidia-installer.h | 8 | ||||
-rw-r--r-- | precompiled.c | 2 | ||||
-rw-r--r-- | rtld_test.c | 4 | ||||
-rwxr-xr-x | rtld_test_Linux-x86 | bin | 2668 -> 0 bytes | |||
-rw-r--r-- | utils.mk | 3 | ||||
-rw-r--r-- | version.mk | 2 |
21 files changed, 243 insertions, 446 deletions
@@ -25,6 +25,7 @@ # include common variables and functions ############################################################################## +COMMON_UTILS_PCIACCESS = 1 include utils.mk @@ -70,16 +71,6 @@ NCURSESW6_UI_O = $(OUTPUTDIR)/ncursesw6-ui.o NCURSESW6_UI_SO = $(OUTPUTDIR)/nvidia-installer-ncursesw6-ui.so NCURSESW6_UI_SO_C = $(OUTPUTDIR)/g_$(notdir $(NCURSESW6_UI_SO:.so=.c)) -RTLD_TEST_C = $(OUTPUTDIR)/g_rtld_test.c -RTLD_TEST = $(OUTPUTDIR)/rtld_test - -# Use a precompiled rtld_test-Linux-x86 binary to simplify the Linux-x86_64 -# build. If a fresh rtld_test-Linux-x86 binary is needed, it can be copied -# from a Linux-x86 build of nvidia-settings. - -RTLD_TEST_32_C = $(OUTPUTDIR)/g_rtld_test_32.c -RTLD_TEST_32 = rtld_test_$(TARGET_OS)-x86 - GEN_UI_ARRAY = $(OUTPUTDIR)/gen-ui-array CONFIG_H = $(OUTPUTDIR)/config.h @@ -91,14 +82,10 @@ OPTIONS_1_INC = $(OUTPUTDIR)/options.1.inc ifeq ($(TARGET_OS)-$(TARGET_ARCH), Linux-x86_64) TLS_MODEL = initial-exec PIC = -fPIC - # Only Linux-x86_64 needs the rtld_test_32 file - COMPAT_32_SRC = $(RTLD_TEST_32_C) else # So far all other platforms use local-exec TLS_MODEL = local-exec PIC = - # Non-Linux-x86_64 platforms do not include the rtld_test_32 file - COMPAT_32_SRC = endif BULLSEYE_BUILD ?= 0 @@ -128,7 +115,7 @@ NCURSES_UI_SO_SRC += $(if $(BUILD_NCURSESW6),$(NCURSESW6_UI_SO_C),) CFLAGS += $(if $(BUILD_NCURSES6),-DNV_INSTALLER_NCURSES6,) CFLAGS += $(if $(BUILD_NCURSESW6),-DNV_INSTALLER_NCURSESW6,) -INSTALLER_SRC = $(SRC) $(NCURSES_UI_SO_SRC) $(RTLD_TEST_C) $(COMPAT_32_SRC) +INSTALLER_SRC = $(SRC) $(NCURSES_UI_SO_SRC) INSTALLER_OBJS = $(call BUILD_OBJECT_LIST,$(INSTALLER_SRC)) @@ -236,12 +223,6 @@ $(NCURSES6_UI_SO_C): $(GEN_UI_ARRAY) $(NCURSES6_UI_SO) $(NCURSESW6_UI_SO_C): $(GEN_UI_ARRAY) $(NCURSESW6_UI_SO) $(call quiet_cmd,GEN_UI_ARRAY) $(NCURSESW6_UI_SO) ncursesw6_ui_array > $@ -$(RTLD_TEST_C): $(GEN_UI_ARRAY) $(RTLD_TEST) - $(call quiet_cmd,GEN_UI_ARRAY) $(RTLD_TEST) rtld_test_array > $@ - -$(RTLD_TEST_32_C): $(GEN_UI_ARRAY) $(RTLD_TEST_32) - $(call quiet_cmd,GEN_UI_ARRAY) $(RTLD_TEST_32) rtld_test_array_32 > $@ - # misc.c includes pciaccess.h $(call BUILD_OBJECT_LIST,misc.c): CFLAGS += $(PCIACCESS_CFLAGS) @@ -280,14 +261,6 @@ clean clobber: rm -rf $(OUTPUTDIR) -# rule to build a native rtld_test; a precompiled Linux-x86 rtld_test is -# distributed with nvidia-installer to simplify Linux-x86_64 builds. - -$(eval $(call DEBUG_INFO_RULES, $(RTLD_TEST))) -$(RTLD_TEST).unstripped: rtld_test.c $(CONFIG_H) - $(call quiet_cmd,LINK) $(CFLAGS) $(LDFLAGS) $(BIN_LDFLAGS) -o $@ -lGL -lEGL $< - - ############################################################################## # rule to build MAKESELF_HELP_SCRIPT_SH; this shell script is packaged # with the driver so that the script can be run on any platform when @@ -383,7 +383,7 @@ static int parse_first_line(const char *buf, int *num, char **filename) *num = strtol(local_buf, NULL, 10); c++; - while(isspace(*c)) c++; + while (isspace(*c)) c++; *filename = nvstrdup(c); @@ -965,7 +965,7 @@ static BackupInfo *read_backup_log_file(Options *op) b->e = NULL; line_num = 3; - while(1) { + while (1) { percent = (float) (c - buf) / (float) stat_buf.st_size; ui_status_update(op, percent, NULL); diff --git a/common-utils/msg.c b/common-utils/msg.c index 8a78530..70772a2 100644 --- a/common-utils/msg.c +++ b/common-utils/msg.c @@ -113,7 +113,7 @@ do { \ NV_VSNPRINTF(buf, fmt); \ format(stream, prefix, buf, whitespace); \ free (buf); \ -} while(0) +} while (0) /* diff --git a/common-utils/nvgetopt.c b/common-utils/nvgetopt.c index 286aee8..5ae3a14 100644 --- a/common-utils/nvgetopt.c +++ b/common-utils/nvgetopt.c @@ -189,7 +189,7 @@ int nvgetopt(int argc, if (a[0] == '-') a++; if (a[0] == '+') a++; - while(a[0]) { a[0] = a[1]; a++; } + while (a[0]) { a[0] = a[1]; a++; } /* * decrement argv_index so that we process this diff --git a/common-utils/nvpci-utils.c b/common-utils/nvpci-utils.c new file mode 100644 index 0000000..62946d2 --- /dev/null +++ b/common-utils/nvpci-utils.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2021 NVIDIA Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "nvpci-utils.h" + +/* + * libpciaccess stores the device class in bits 16-23, subclass in 8-15, and + * interface in bits 0-7 of dev->device_class. We care only about the class + * and subclass. + */ +const uint32_t PCI_CLASS_DISPLAY_VGA = 0x30000; +const uint32_t PCI_CLASS_SUBCLASS_MASK = 0xffff00; + +/* + * nvpci_find_gpu_by_vendor() - use libpciaccess to find all VGA and 3D PCI + * devices matching the passed-in vendor_id (which may be set to PCI_MATCH_ANY). + * The caller is responsible for calling pci_system_init() before using this + * function, and pci_system_cleanup() when libpciaccess is no longer needed. + */ +struct pci_device_iterator *nvpci_find_gpu_by_vendor(uint32_t vendor_id) +{ + const struct pci_id_match match = { + .vendor_id = vendor_id, + .device_id = PCI_MATCH_ANY, + .subvendor_id = PCI_MATCH_ANY, + .subdevice_id = PCI_MATCH_ANY, + .device_class = PCI_CLASS_DISPLAY_VGA, + /* + * Ignore bit 1 of the subclass, to allow both 0x30000 (VGA controller) + * and 0x30200 (3D controller). + */ + .device_class_mask = PCI_CLASS_SUBCLASS_MASK & ~0x200, + }; + + return pci_id_match_iterator_create(&match); +} + +/* + * nvpci_dev_is_vga() - test whether the passed-in struct pci_device* has the + * VGA device class 0x0300 (and not 3D class 0x0302). + */ +int nvpci_dev_is_vga(struct pci_device *dev) +{ + return (dev->device_class & PCI_CLASS_SUBCLASS_MASK) == + PCI_CLASS_DISPLAY_VGA; +} diff --git a/common-utils/nvpci-utils.h b/common-utils/nvpci-utils.h new file mode 100644 index 0000000..9813e90 --- /dev/null +++ b/common-utils/nvpci-utils.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2021 NVIDIA Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVPCI_UTILS_H__ +#define __NVPCI_UTILS_H__ + +#include <pciaccess.h> + +#define NV_PCI_VENDOR_ID 0x10de + +struct pci_device_iterator *nvpci_find_gpu_by_vendor(uint32_t vendor_id); +int nvpci_dev_is_vga(struct pci_device *dev); + +#endif /* __NVPCI_UTILS_H__ */ diff --git a/common-utils/src.mk b/common-utils/src.mk index 6dbed7a..bb1e1d3 100644 --- a/common-utils/src.mk +++ b/common-utils/src.mk @@ -1,5 +1,8 @@ # makefile fragment included by nvidia-xconfig, nvidia-settings, and nvidia-installer +# the including makefile should set this if the relevant program uses pciaccess +COMMON_UTILS_PCIACCESS ?= + COMMON_UTILS_SRC += nvgetopt.c COMMON_UTILS_SRC += common-utils.c COMMON_UTILS_SRC += msg.c @@ -9,6 +12,16 @@ COMMON_UTILS_EXTRA_DIST += common-utils.h COMMON_UTILS_EXTRA_DIST += msg.h COMMON_UTILS_EXTRA_DIST += src.mk +# only build nvpci-utils.c for programs that actually use libpciaccess, to +# prevent other programs from needing to set the right CFLAGS/LDFLAGS for code +# they won't use. Otherwise, just package it in the source tarball. +ifneq ($(COMMON_UTILS_PCIACCESS),) + COMMON_UTILS_SRC += nvpci-utils.c +else + COMMON_UTILS_EXTRA_DIST += nvpci-utils.c +endif +COMMON_UTILS_EXTRA_DIST += nvpci-utils.h + # gen-manpage-opts-helper.c is listed in EXTRA_DIST, rather than SRC, # because it is not compiled into the utilities themselves, but used # when building the utility's gen-manpage-opts diff --git a/dist-files.mk b/dist-files.mk index 3e67123..cd68742 100644 --- a/dist-files.mk +++ b/dist-files.mk @@ -63,9 +63,6 @@ DIST_FILES += COPYING DIST_FILES += README DIST_FILES += dist-files.mk -DIST_FILES += rtld_test_Linux-x86 -DIST_FILES += rtld_test.c - DIST_FILES += nvidia-installer.1.m4 DIST_FILES += gen-manpage-opts.c DIST_FILES += makeself-help-script.c @@ -1095,7 +1095,7 @@ void add_kernel_modules_to_package(Options *op, Package *p) * FILE_TYPE_KERNEL_MODULE{,_SRC} or FILE_TYPE_DKMS_CONF. */ -void remove_non_kernel_module_files_from_package(Options *op, Package *p) +void remove_non_kernel_module_files_from_package(Package *p) { int i; @@ -1110,9 +1110,60 @@ void remove_non_kernel_module_files_from_package(Options *op, Package *p) /* + * package_entry_is_in_kernel_module_build_directory() - returns TRUE if the + * package entry at index i is in p->kernel_module_build_directory. + */ +static int package_entry_is_in_kernel_module_build_directory(Package *p, int i) +{ + const char *build_dir = p->kernel_module_build_directory; + const char *file = p->entries[i].file; + const char *cwd_prefix = "./"; + + + /* Remove any leading "./" */ + while (strncmp(build_dir, cwd_prefix, strlen(cwd_prefix)) == 0) { + build_dir += strlen(cwd_prefix); + } + while (strncmp(file, cwd_prefix, strlen(cwd_prefix)) == 0) { + file += strlen(cwd_prefix); + } + + /* Check if the build directory is an initial substring of the file path */ + if (strncmp(file, build_dir, strlen(build_dir)) == 0) { + if (build_dir[strlen(build_dir) - 1] == '/') { + /* If the last character of the directory name is a '/', then the + * strncmp(3) test above matched the full directory name, including + * a trailing directory separator character. */ + return TRUE; + } + if (file[strlen(build_dir)] == '/') { + /* If the next character after the matched portion of the file name + * is a '/', then the directory name match is not a partial one. */ + return TRUE; + } + } + + return FALSE; +} + +void remove_non_installed_kernel_module_source_files_from_package(Package *p) +{ + int i; + + for (i = 0; i < p->num_entries; i++) { + if (p->entries[i].type == FILE_TYPE_KERNEL_MODULE_SRC) { + if (!package_entry_is_in_kernel_module_build_directory(p, i)) { + invalidate_package_entry(&(p->entries[i])); + } + } + } +} + + +/* * Invalidate each package entry that is an OpenGL file */ -void remove_opengl_files_from_package(Options *op, Package *p) +void remove_opengl_files_from_package(Package *p) { int i; @@ -1127,7 +1178,7 @@ void remove_opengl_files_from_package(Options *op, Package *p) /* * Invalidate each package entry that is an Wine file */ -void remove_wine_files_from_package(Options *op, Package *p) +void remove_wine_files_from_package(Package *p) { int i; @@ -1142,7 +1193,7 @@ void remove_wine_files_from_package(Options *op, Package *p) /* * Invalidate each package entry that is a systemd file */ -void remove_systemd_files_from_package(Options *op, Package *p) +void remove_systemd_files_from_package(Package *p) { int i; @@ -2094,29 +2145,33 @@ void process_dkms_conf(Options *op, Package *p) invalidate_package_entry(&(p->entries[i])); - tmpfile = process_template_file(op, &p->entries[i], tokens, - replacements); - if (tmpfile != NULL) { - /* add this new file to the package */ - - /* - * XXX 'name' is the basename (non-directory part) of - * the file to be installed; normally, 'name' just - * points into 'file', but in this case 'file' is - * mkstemp(3)-generated, so doesn't have the same - * basename; instead, we just strdup the name from the - * template package entry; yes, 'name' will get leaked - */ - - add_package_entry(p, - tmpfile, - nvstrdup(p->entries[i].path), - nvstrdup(p->entries[i].name), - NULL, /* target */ - NULL, /* dst */ - FILE_TYPE_DKMS_CONF, - p->entries[i].compat_arch, - p->entries[i].mode); + /* only process template files that are in the build directory */ + + if (package_entry_is_in_kernel_module_build_directory(p, i)) { + tmpfile = process_template_file(op, &p->entries[i], tokens, + replacements); + if (tmpfile != NULL) { + /* add this new file to the package */ + + /* + * XXX 'name' is the basename (non-directory part) of + * the file to be installed; normally, 'name' just + * points into 'file', but in this case 'file' is + * mkstemp(3)-generated, so doesn't have the same + * basename; instead, we just strdup the name from the + * template package entry; yes, 'name' will get leaked + */ + + add_package_entry(p, + tmpfile, + nvstrdup(p->entries[i].path), + nvstrdup(p->entries[i].name), + NULL, /* target */ + NULL, /* dst */ + FILE_TYPE_DKMS_CONF, + p->entries[i].compat_arch, + p->entries[i].mode); + } } } } @@ -2438,7 +2493,7 @@ void get_compat32_path(Options *op) if (!op->compat32_prefix) op->compat32_prefix = DEFAULT_OPENGL_PREFIX; - if(!op->compat32_libdir) { + if (!op->compat32_libdir) { char *compat_libdir; @@ -32,10 +32,11 @@ char *write_temp_file(Options *op, const int len, int set_destinations(Options *op, Package *p); /* XXX move? */ int get_prefixes(Options *op); /* XXX move? */ void add_kernel_modules_to_package(Options *op, Package *p); -void remove_non_kernel_module_files_from_package(Options *op, Package *p); -void remove_opengl_files_from_package(Options *op, Package *p); -void remove_wine_files_from_package(Options *op, Package *p); -void remove_systemd_files_from_package(Options *op, Package *p); +void remove_non_kernel_module_files_from_package(Package *p); +void remove_non_installed_kernel_module_source_files_from_package(Package *p); +void remove_opengl_files_from_package(Package *p); +void remove_wine_files_from_package(Package *p); +void remove_systemd_files_from_package(Package *p); int mode_string_to_mode(Options *op, char *s, mode_t *mode); char *mode_to_permission_string(mode_t mode); int confirm_path(Options *op, const char *path); diff --git a/install-from-cwd.c b/install-from-cwd.c index 45e2795..567ccfa 100644 --- a/install-from-cwd.c +++ b/install-from-cwd.c @@ -228,7 +228,7 @@ int install_from_cwd(Options *op) */ if (op->kernel_module_only) { - remove_non_kernel_module_files_from_package(op, p); + remove_non_kernel_module_files_from_package(p); } else { /* ask for the XFree86 and OpenGL installation prefixes. */ @@ -255,21 +255,26 @@ int install_from_cwd(Options *op) } if (op->no_opengl_files) { - remove_opengl_files_from_package(op, p); + remove_opengl_files_from_package(p); } if (op->no_wine_files) { - remove_wine_files_from_package(op, p); + remove_wine_files_from_package(p); } /* * determine whether systemd files should be installed */ if (op->use_systemd != NV_OPTIONAL_BOOL_TRUE) { - remove_systemd_files_from_package(op, p); + remove_systemd_files_from_package(p); } /* + * Remove any kernel module source files that won't be installed. + */ + remove_non_installed_kernel_module_source_files_from_package(p); + + /* * now that we have the installation prefixes, build the * destination for each file to be installed */ @@ -358,8 +363,6 @@ int install_from_cwd(Options *op) check_installed_files_from_package(op, p); - if (!check_runtime_configuration(op, p)) goto failed; - /* done */ if (op->kernel_module_only || op->no_nvidia_xconfig_question) { @@ -467,7 +467,7 @@ static int attach_signature(Options *op, Package *p, } if (ret) { - if(op->kernel_module_signed) { + if (op->kernel_module_signed) { ui_log(op, "Signature attached successfully."); } else { ui_log(op, "Signature not attached."); @@ -1282,14 +1282,9 @@ int test_kernel_modules(Options *op, Package *p) { char *cmd = NULL, *data = NULL; int ret = FALSE, i; - const char *depmods[] = { "i2c-core", "drm", "drm-kms-helper", "vfio_mdev" }; - - /* - * If we're building/installing for a different kernel, then we - * can't test the module now. - */ + const char *depmods[] = { "i2c-core", "drm", "drm-kms-helper", "vfio_mdev", "vfio", "mdev", "vfio_iommu_type1" }; - if (op->kernel_name) return TRUE; + if (op->skip_module_load) return TRUE; /* * Attempt to load modules that nvidia.ko might depend on. Silently ignore @@ -2440,7 +2435,7 @@ static char *get_cpu_type(const Options *op) char *line, *ret = NULL; int eof; - while((line = fget_next_line(fp, &eof))) { + while ((line = fget_next_line(fp, &eof))) { ret = nvrealloc(ret, strlen(line) + 1); if (sscanf(line, "cpu : %s", ret) == 1) { @@ -47,6 +47,7 @@ #include "crc.h" #include "nvLegacy.h" #include "manifest.h" +#include "nvpci-utils.h" static int check_symlink(Options*, const char*, const char*, const char*); @@ -450,13 +451,9 @@ static const Util __utils[] = { /* SystemUtils */ [LDCONFIG] = { "ldconfig", "glibc" }, - [LDD] = { "ldd", "glibc" }, [GREP] = { "grep", "grep" }, [DMESG] = { "dmesg", "util-linux" }, [TAIL] = { "tail", "coreutils" }, - [CUT] = { "cut", "coreutils" }, - [TR] = { "tr", "coreutils" }, - [SED] = { "sed", "sed" }, /* SystemOptionalUtils */ [OBJCOPY] = { "objcopy", "binutils" }, @@ -480,6 +477,8 @@ static const Util __utils[] = { [CC] = { "cc", "gcc" }, [MAKE] = { "make", "make" }, [LD] = { "ld", "binutils" }, + [TR] = { "tr", "coreutils" }, + [SED] = { "sed", "sed" }, }; @@ -805,11 +804,17 @@ char *find_system_util(const char *util) for (x = y = path; ; x++) { if (*x == ':' || *x == '\0') { + struct stat st; + c = *x; *x = '\0'; file = nvstrcat(y, "/", util, NULL); *x = c; - if ((access(file, F_OK | X_OK)) == 0) { + if (stat(file, &st) == 0 && S_ISREG(st.st_mode) && + (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0) { + /* If the path points to a regular file (or a symbolic link to a + * regular file), and it is executable by at least one of user, + * group, or other, use this path for the relevant utility. */ nvfree(path); return file; } @@ -1389,93 +1394,6 @@ int check_installed_file(Options *op, const char *filename, /* - * check_runtime_configuration() - In the past, nvidia-installer has - * frequently failed to backup/move all conflicting files prior to - * installing the NVIDIA OpenGL libraries. Consequently, some of the - * installations considered successful by the installer didn't work - * correctly. - * - * This sanity check attempts to verify that the correct libraries are - * picked up by the runtime linker. It returns TRUE on success and - * FALSE on failure. - */ - -/* pull in the array and size from g_rtld_test.c */ - -extern const unsigned char rtld_test_array[]; -extern const int rtld_test_array_size; - -#if defined(NV_X86_64) - -/* pull in the array and size from g_rtld_test_32.c */ - -extern const unsigned char rtld_test_array_32[]; -extern const int rtld_test_array_32_size; - -#endif /* NV_X86_64 */ - - -/* forward prototype */ - -static int rtld_test_internal(Options *op, Package *p, - const unsigned char *test_array, - const int test_array_size, - int compat_32_libs); - -int check_runtime_configuration(Options *op, Package *p) -{ - int ret = TRUE; - char *tmpdir = NULL; - char old_cwd[PATH_MAX]; - int chdir_success = FALSE; - - ui_status_begin(op, "Running runtime sanity check:", "Checking"); - - /* chdir to an empty directory to avoid picking up DSOs from the CWD */ - - if (getcwd(old_cwd, sizeof(old_cwd)) != NULL && - (tmpdir = make_tmpdir(op)) && - chdir(tmpdir) == 0) { - chdir_success = TRUE; - } else { - ui_warn(op, "Unable to chdir into an empty directory: this may cause " - "the runtime configuration test to fail on some systems."); - } - -#if defined(NV_X86_64) - ret = rtld_test_internal(op, p, - rtld_test_array_32, - rtld_test_array_32_size, - TRUE); -#endif /* NV_X86_64 */ - - if (ret == TRUE) { - ret = rtld_test_internal(op, p, - rtld_test_array, - rtld_test_array_size, - FALSE); - } - - if (chdir_success) { - if (chdir(old_cwd) != 0) { - ui_error(op, "Unable to restore cwd to '%s' (%s)!", old_cwd, - strerror(errno)); - } - } - - if (tmpdir) { - remove_directory(op, tmpdir); - } - - ui_status_end(op, "done."); - ui_log(op, "Runtime sanity check %s.", ret ? "passed" : "failed"); - - return ret; - -} /* check_runtime_configuration() */ - - -/* * collapse_multiple_slashes() - remove any/all occurrences of "//" from the * argument string. */ @@ -1497,235 +1415,6 @@ void collapse_multiple_slashes(char *s) /* - * is_symbolic_link_to() - check if the file with path 'path' is - * a symbolic link pointing to 'dest'. Returns TRUE if this is - * the case; if the file is not a symbolic link if it doesn't point - * to 'dest', is_symbolic_link_to() returns FALSE. - */ - -int is_symbolic_link_to(const char *path, const char *dest) -{ - struct stat stat_buf0, stat_buf1; - - if ((lstat(path, &stat_buf0) != 0) - || !S_ISLNK(stat_buf0.st_mode)) - return FALSE; - - if ((stat(path, &stat_buf0) == 0) && - (stat(dest, &stat_buf1) == 0) && - (stat_buf0.st_dev == stat_buf1.st_dev) && - (stat_buf0.st_ino == stat_buf1.st_ino)) - return TRUE; - - return FALSE; - -} /* is_symbolic_link_to() */ - - - -/* - * rtld_test_internal() - this routine writes the test binaries to a file - * and performs the test; the caller (rtld_test()) selects which array data - * is used (native, compat_32). - */ - -static int rtld_test_internal(Options *op, Package *p, - const unsigned char *test_array, - const int test_array_size, - int compat_32_libs) -{ - int fd, i, found = TRUE, ret = TRUE; - char *name = NULL, *cmd = NULL, *data = NULL; - char *tmpfile, *s; - char *tmpfile1 = NULL; - struct stat stat_buf0, stat_buf1; - - if ((test_array == NULL) || (test_array_size == 0)) { - ui_warn(op, "The runtime configuration test program is not " - "present; assuming successful installation."); - return TRUE; - } - - /* write the rtld_test data to a temporary file */ - - tmpfile = write_temp_file(op, test_array_size, test_array, - S_IRUSR|S_IWUSR|S_IXUSR); - - if (!tmpfile) { - ui_warn(op, "Unable to create a temporary file for the runtime " - "configuration test program (%s); assuming successful " - "installation.", strerror(errno)); - goto done; - } - - /* create another temporary file */ - - tmpfile1 = nvstrcat(op->tmpdir, "/nv-tmp-XXXXXX", NULL); - - fd = mkstemp(tmpfile1); - if (fd == -1) { - ui_warn(op, "Unable to create a temporary file for the runtime " - "configuration test program (%s); assuming successful " - "installation.", strerror(errno)); - goto done; - } - close(fd); - - /* perform the test(s) */ - - for (i = 0; i < p->num_entries; i++) { - if ((p->entries[i].type != FILE_TYPE_OPENGL_LIB) && - (p->entries[i].type != FILE_TYPE_TLS_LIB)) { - continue; -#if defined(NV_X86_64) - } else if ((p->entries[i].compat_arch == FILE_COMPAT_ARCH_NATIVE) - && compat_32_libs) { - continue; - } else if ((p->entries[i].compat_arch == FILE_COMPAT_ARCH_COMPAT32) - && !compat_32_libs) { - continue; -#endif /* NV_X86_64 */ - } - - name = nvstrdup(p->entries[i].name); - if (!name) continue; - - s = strstr(name, ".so.1"); - if (!s || s[strlen(".so.1")] != '\0') goto next; - - cmd = nvstrcat(op->utils[LDD], " ", tmpfile, " > ", tmpfile1, NULL); - - if (run_command(op, cmd, NULL, FALSE, 0, TRUE)) { - /* running ldd on a 32-bit SO will fail without a 32-bit loader */ - if (compat_32_libs) { - ui_warn(op, "Unable to perform the runtime configuration " - "check for 32-bit library '%s' ('%s'); this is " - "typically caused by the lack of a 32-bit " - "compatibility environment. Assuming successful " - "installation.", name, p->entries[i].dst); - } else { - ui_warn(op, "Unable to perform the runtime configuration " - "check for library '%s' ('%s'); assuming successful " - "installation.", name, p->entries[i].dst); - } - goto done; - } - - cmd = nvstrcat(op->utils[GREP], " ", name, " ", tmpfile1, - " | ", op->utils[CUT], " -d \" \" -f 3", NULL); - - if (run_command(op, cmd, &data, FALSE, 0, TRUE) || - (data == NULL)) { - ui_warn(op, "Unable to perform the runtime configuration " - "check for library '%s' ('%s'); assuming successful " - "installation.", name, p->entries[i].dst); - goto done; - } - - if (!strcmp(data, "not") || !strlen(data)) { - /* - * If the library didn't show up in ldd's output or - * wasn't found, set 'found' to false and notify the - * user with a more meaningful message below. - */ - free(data); data = NULL; - found = FALSE; - } else { - /* - * Double slashes in /etc/ld.so.conf make it all the - * way to ldd's output on some systems. Strip them - * here to make sure they don't cause a false failure. - */ - collapse_multiple_slashes(data); - } - - nvfree(name); name = NULL; - name = nvstrdup(p->entries[i].dst); - if (!name) goto next; - - s = strstr(name, ".so.1"); - if (!s) goto next; - *(s + strlen(".so.1")) = '\0'; - - if (!found || (strcmp(data, name) != 0)) { - /* - * XXX Handle the case where the same library is - * referred to, once directly and once via a symbolic - * link. This check is far from perfect, but should - * get the job done. - */ - - if ((stat(data, &stat_buf0) == 0) && - (stat(name, &stat_buf1) == 0) && - (stat_buf0.st_dev == stat_buf1.st_dev) && - (stat_buf0.st_ino == stat_buf1.st_ino)) - goto next; - - if (!found && !compat_32_libs) { - ui_error(op, "The runtime configuration check failed for " - "library '%s' (expected: '%s', found: (not found)). " - "The most likely reason for this is that the library " - "was installed to the wrong location or that your " - "system's dynamic loader configuration needs to be " - "updated. Please check the OpenGL library installation " - "prefix and/or the dynamic loader configuration.", - p->entries[i].name, name); - ret = FALSE; - goto done; -#if defined(NV_X86_64) - } else if (!found) { - ui_warn(op, "The runtime configuration check failed for " - "library '%s' (expected: '%s', found: (not found)). " - "The most likely reason for this is that the library " - "was installed to the wrong location or that your " - "system's dynamic loader configuration needs to be " - "updated. Please check the 32-bit OpenGL compatibility " - "library installation prefix and/or the dynamic loader " - "configuration.", - p->entries[i].name, name); - goto next; -#endif /* NV_X86_64 */ - } else { - ui_error(op, "The runtime configuration check failed for the " - "library '%s' (expected: '%s', found: '%s'). The " - "most likely reason for this is that conflicting " - "OpenGL libraries are installed in a location not " - "inspected by `nvidia-installer`. Please be sure you " - "have uninstalled any third-party OpenGL and/or " - "third-party graphics driver packages.", - p->entries[i].name, name, data); - ret = FALSE; - goto done; - } - } - - next: - nvfree(name); name = NULL; - nvfree(cmd); cmd = NULL; - nvfree(data); data = NULL; - } - - done: - if (tmpfile) { - unlink(tmpfile); - nvfree(tmpfile); - } - if (tmpfile1) { - unlink(tmpfile1); - nvfree(tmpfile1); - } - - nvfree(name); - nvfree(cmd); - nvfree(data); - - return ret; - -} /* rtld_test_internal() */ - - - -/* * get_xserver_information() - parse the versionString (from `X * -version`) and assign relevant information that we infer from the X * server version. @@ -1938,31 +1627,11 @@ int check_for_nvidia_graphics_devices(Options *op, Package *p) int i, found_supported_device = FALSE; int found_vga_device = FALSE; - /* - * libpciaccess stores the device class in bits 16-23, subclass in 8-15, and - * interface in bits 0-7 of dev->device_class. We care only about the class - * and subclass. - */ - const uint32_t PCI_CLASS_DISPLAY_VGA = 0x30000; - const uint32_t PCI_CLASS_SUBCLASS_MASK = 0xffff00; - const struct pci_id_match match = { - .vendor_id = 0x10de, - .device_id = PCI_MATCH_ANY, - .subvendor_id = PCI_MATCH_ANY, - .subdevice_id = PCI_MATCH_ANY, - .device_class = PCI_CLASS_DISPLAY_VGA, - /* - * Ignore bit 1 of the subclass, to allow both 0x30000 (VGA controller) - * and 0x30200 (3D controller). - */ - .device_class_mask = PCI_CLASS_SUBCLASS_MASK & ~0x200, - }; - if (pci_system_init()) { return TRUE; } - iter = pci_id_match_iterator_create(&match); + iter = nvpci_find_gpu_by_vendor(NV_PCI_VENDOR_ID); for (dev = pci_device_next(iter); dev; dev = pci_device_next(iter)) { if (dev->device_id >= 0x0020 /* TNT or later */) { @@ -2025,13 +1694,9 @@ int check_for_nvidia_graphics_devices(Options *op, Package *p) } else { found_supported_device = TRUE; - /* - * libpciaccess packs the device class into bits 16 through 23 - * and the subclass into bits 8 through 15 of dev->device_class. - */ - if ((dev->device_class & PCI_CLASS_SUBCLASS_MASK) == - PCI_CLASS_DISPLAY_VGA) + if (nvpci_dev_is_vga(dev)) { found_vga_device = TRUE; + } } } } @@ -2758,7 +2423,7 @@ int dkms_install_module(Options *op, const char *version, const char *kernel) if (!run_dkms(op, DKMS_BUILD, version, kernel, NULL)) goto failed; ui_status_update(op, .9, "Installing module"); - if(!run_dkms(op, DKMS_INSTALL, version, kernel, NULL)) goto failed; + if( !run_dkms(op, DKMS_INSTALL, version, kernel, NULL)) goto failed; ui_status_end(op, "done."); return TRUE; @@ -2797,7 +2462,7 @@ static int test_last_bit(const char *file) { * trying to read after an fseek(stream, -1, SEEK_END) call on a UEFI * variable file in sysfs hits a premature EOF. */ - while(fread(&buf, 1, 1, fp)) { + while (fread(&buf, 1, 1, fp)) { data_read = TRUE; } @@ -75,9 +75,7 @@ void should_install_optional_modules(Options *op, Package *p, void check_installed_files_from_package(Options *op, Package *p); int check_installed_file(Options*, const char*, const mode_t, const uint32, ui_message_func *logwarn); -int check_runtime_configuration(Options *op, Package *p); void collapse_multiple_slashes(char *s); -int is_symbolic_link_to(const char *path, const char *dest); int check_for_running_x(Options *op); void query_xorg_version(Options *op); int check_for_nvidia_graphics_devices(Options *op, Package *p); diff --git a/mkprecompiled.c b/mkprecompiled.c index 6840f7f..2d86bcd 100644 --- a/mkprecompiled.c +++ b/mkprecompiled.c @@ -662,7 +662,7 @@ int main(int argc, char *argv[]) precompiled_file_type_name(file->type)); printf(" attributes: "); - for(attr = attrs; *attr; attr++) { + for (attr = attrs; *attr; attr++) { if (attr > attrs) { printf(", "); } diff --git a/nvidia-installer.h b/nvidia-installer.h index 8747c66..242c7b8 100644 --- a/nvidia-installer.h +++ b/nvidia-installer.h @@ -37,13 +37,9 @@ typedef enum { MIN_SYSTEM_UTILS = 0, LDCONFIG = MIN_SYSTEM_UTILS, - LDD, GREP, DMESG, TAIL, - CUT, - TR, - SED, MAX_SYSTEM_UTILS } SystemUtils; @@ -88,6 +84,10 @@ typedef enum { CC = MIN_DEVELOP_UTILS, MAKE, LD, + /* TR and SED aren't used directly by the installer, but conftest.sh + * depends on them, so we check for their presence */ + TR, + SED, MAX_DEVELOP_UTILS } DevelopUtils; diff --git a/precompiled.c b/precompiled.c index 08ba107..ddadbd3 100644 --- a/precompiled.c +++ b/precompiled.c @@ -853,7 +853,7 @@ static int precompiled_read_fileinfo(Options *op, PrecompiledFileInfo *fileInfos fileInfo->linked_module_crc = read_uint32(buf, &offset); fileInfo->signature_size = read_uint32(buf, &offset); - if(fileInfo->signature_size) { + if (fileInfo->signature_size) { if (offset + fileInfo->signature_size > size) { ui_log(op, "Bad signature size"); return -1; diff --git a/rtld_test.c b/rtld_test.c deleted file mode 100644 index 4a7c3ee..0000000 --- a/rtld_test.c +++ /dev/null @@ -1,4 +0,0 @@ -int main(int argc, char *argv[]) -{ - return 0; -} diff --git a/rtld_test_Linux-x86 b/rtld_test_Linux-x86 Binary files differdeleted file mode 100755 index 290b8c0..0000000 --- a/rtld_test_Linux-x86 +++ /dev/null @@ -186,6 +186,8 @@ NV_QUIET_COMMAND_REMOVED_TARGET_PREFIX ?= NV_GENERATED_HEADERS ?= +PCIACCESS_CFLAGS ?= +PCIACCESS_LDFLAGS ?= ############################################################################## # This makefile uses the $(eval) builtin function, which was added in @@ -380,6 +382,7 @@ BUILD_OBJECT_LIST_WITH_DIR = \ BUILD_OBJECT_LIST = \ $(call BUILD_OBJECT_LIST_WITH_DIR,$(1),$(OUTPUTDIR)) +$(call BUILD_OBJECT_LIST,nvpci-utils.c): CFLAGS += $(PCIACCESS_CFLAGS) ############################################################################## # function to generate a list of dependency files from their @@ -1,4 +1,4 @@ -NVIDIA_VERSION = 495.46 +NVIDIA_VERSION = 510.39.01 # This file. VERSION_MK_FILE := $(lastword $(MAKEFILE_LIST)) |