diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2013-10-22 08:44:56 -0700 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2013-10-22 08:44:56 -0700 |
commit | 72ebfda8e29b48e925f48da6f2594e9a7cc4c275 (patch) | |
tree | bae0fc9a5e7016333bb7ff80c24b58fa39be92cb | |
parent | f0923811d809b403b23dee449b849a01df6d2e79 (diff) |
331.17331.17
-rw-r--r-- | command-list.c | 19 | ||||
-rw-r--r-- | files.c | 25 | ||||
-rw-r--r-- | files.h | 2 | ||||
-rw-r--r-- | install-from-cwd.c | 91 | ||||
-rw-r--r-- | kernel.c | 304 | ||||
-rw-r--r-- | manifest.c | 3 | ||||
-rw-r--r-- | misc.c | 23 | ||||
-rw-r--r-- | misc.h | 1 | ||||
-rw-r--r-- | mkprecompiled.c | 44 | ||||
-rw-r--r-- | nvidia-installer.c | 4 | ||||
-rw-r--r-- | nvidia-installer.h | 8 | ||||
-rw-r--r-- | option_table.h | 4 | ||||
-rw-r--r-- | precompiled.c | 36 | ||||
-rw-r--r-- | precompiled.h | 10 | ||||
-rw-r--r-- | version.mk | 2 |
15 files changed, 424 insertions, 152 deletions
diff --git a/command-list.c b/command-list.c index 45b4f19..c2015de 100644 --- a/command-list.c +++ b/command-list.c @@ -862,9 +862,20 @@ static int ignore_conflicting_file(Options *op, ret = info.conflictArch != CONFLICT_ARCH_64; break; default: - ui_warn(op, "Unable to determine the architecture of the file " - "'%s', which has an architecture-specific conflict.", - filename); + /* + * XXX ignore symlinks with indeterminate architectures: their + * targets may have already been deleted, and they'll be reused + * or replaced as part of the installation, anyway. + */ + if (lstat(filename, &stat_buf) == -1) { + ui_warn(op, "Unable to stat '%s'.", filename); + } else if ((stat_buf.st_mode & S_IFLNK) == S_IFLNK) { + ret = TRUE; + } else { + ui_warn(op, "Unable to determine the architecture of the " + "file '%s', which has an architecture-specific " + "conflict.", filename); + } break; } } @@ -873,6 +884,8 @@ static int ignore_conflicting_file(Options *op, if (!info.requiredString) return ret; + ret = FALSE; + if ((fd = open(filename, O_RDONLY)) == -1) { ui_error(op, "Unable to open '%s' for reading (%s)", filename, strerror(errno)); @@ -471,6 +471,9 @@ int set_destinations(Options *op, Package *p) op->kernel_module_src_dir = nvstrcat("nvidia-", p->version, NULL); } + op->uvm_module_src_dir = nvstrcat(op->kernel_module_src_dir, "/" UVM_SUBDIR, + NULL); + for (i = 0; i < p->num_entries; i++) { switch (p->entries[i].type) { @@ -481,13 +484,18 @@ int set_destinations(Options *op, Package *p) continue; case FILE_TYPE_KERNEL_MODULE_SRC: + case FILE_TYPE_UVM_MODULE_SRC: if (op->no_kernel_module_source) { /* Don't install kernel module source files if requested. */ p->entries[i].dst = NULL; continue; } prefix = op->kernel_module_src_prefix; - dir = op->kernel_module_src_dir; + if (p->entries[i].type == FILE_TYPE_UVM_MODULE_SRC) { + dir = op->uvm_module_src_dir; + } else { + dir = op->kernel_module_src_dir; + } path = ""; break; @@ -983,12 +991,11 @@ int get_prefixes (Options *op) */ static void add_kernel_module_helper(Options *op, Package *p, - const char *filename, const char *subdir) + const char *filename, const char *dir) { char *file, *name, *dst; - file = nvstrcat(p->kernel_module_build_directory, "/", subdir, - filename, NULL); + file = nvstrcat(dir, "/", filename, NULL); name = strrchr(file, '/'); @@ -1024,7 +1031,8 @@ int add_kernel_modules_to_package(Options *op, Package *p) int i; if (op->multiple_kernel_modules) { - add_kernel_module_helper(op, p, p->kernel_frontend_module_filename, ""); + add_kernel_module_helper(op, p, p->kernel_frontend_module_filename, + p->kernel_module_build_directory); } for (i = 0; i < op->num_kernel_modules; i++) { @@ -1036,11 +1044,16 @@ int add_kernel_modules_to_package(Options *op, Package *p) tmp = strrchr(name, '0'); if (tmp) *tmp = *tmp + i; - add_kernel_module_helper(op, p, name, ""); + add_kernel_module_helper(op, p, name, p->kernel_module_build_directory); nvfree(name); } + if (op->install_uvm) { + add_kernel_module_helper(op, p, p->uvm_kernel_module_filename, + p->uvm_module_build_directory); + } + return TRUE; } /* add_kernel_module_to_package() */ @@ -23,6 +23,8 @@ #include "nvidia-installer.h" #include "precompiled.h" +#define UVM_SUBDIR "uvm" + int remove_directory(Options *op, const char *victim); int touch_directory(Options *op, const char *victim); int copy_file(Options *op, const char *srcfile, diff --git a/install-from-cwd.c b/install-from-cwd.c index 19e6b84..cbb5499 100644 --- a/install-from-cwd.c +++ b/install-from-cwd.c @@ -150,6 +150,10 @@ int install_from_cwd(Options *op) if (!check_for_nouveau(op)) goto failed; + /* ask if we should install the UVM kernel module */ + + should_install_uvm(op, p); + /* attempt to build a kernel module for the target kernel */ if (!op->no_kernel_module) { @@ -387,6 +391,50 @@ static int install_kernel_module(Options *op, Package *p) { PrecompiledInfo *precompiled_info; + /* Append the UVM dkms.conf fragment to RM's dkms.conf when installing UVM */ + + if (op->install_uvm) { + FILE *dkmsconf, *uvmdkmsconf; + char *tmppath; + + tmppath = nvstrcat(p->kernel_module_build_directory, "/dkms.conf", NULL); + dkmsconf = fopen(tmppath, "a"); + nvfree(tmppath); + + tmppath = nvstrcat(p->uvm_module_build_directory, + "/dkms.conf.fragment", NULL); + uvmdkmsconf = fopen(tmppath, "r"); + nvfree (tmppath); + + if (dkmsconf && uvmdkmsconf) { + char byte; + + while (fread(&byte, 1, 1, uvmdkmsconf)) { + if (!fwrite(&byte, 1, 1, dkmsconf)) { + goto dkmscatfailed; + } + } + + if (ferror(uvmdkmsconf)) { + goto dkmscatfailed; + } + + } else { +dkmscatfailed: + ui_warn(op, "Failed to add build commands for the NVIDIA Unified " + "Memory kernel module to the dkms.conf file: DKMS will " + "not be able to build the NVIDIA Unified Memory kernel " + "module."); + } + + if (dkmsconf) { + fclose(dkmsconf); + } + if (uvmdkmsconf) { + fclose(uvmdkmsconf); + } + } + /* Offer the DKMS option if DKMS exists and the kernel module sources * will be installed somewhere. Don't offer DKMS as an option if module * signing was requested. */ @@ -516,8 +564,13 @@ int add_this_kernel(Options *op) if (!determine_kernel_source_path(op, p)) goto failed; - if (op->multiple_kernel_modules) - num_expected_files = op->num_kernel_modules + 1; + if (op->multiple_kernel_modules) { + num_expected_files += op->num_kernel_modules; + } + + if (op->install_uvm) { + num_expected_files += 1; + } /* build the precompiled files */ @@ -628,16 +681,22 @@ static Package *parse_manifest (Options *op) if (op->multiple_kernel_modules) { module_suffix = "0"; - p->kernel_frontend_module_name = nvstrcat(tmpstr, "-frontend", NULL); - p->kernel_frontend_module_filename = - nvstrcat(p->kernel_frontend_module_name, ".ko", NULL); - p->kernel_frontend_interface_filename = nvstrdup("nv-linuxfrontend.o"); } p->kernel_module_name = nvstrcat(tmpstr, module_suffix, NULL); p->kernel_module_filename = nvstrcat(p->kernel_module_name, ".ko", NULL); p->kernel_interface_filename = nvstrcat("nv-linux", module_suffix, ".o", NULL); + p->kernel_frontend_module_name = nvstrcat(tmpstr, "-frontend", NULL); + p->kernel_frontend_module_filename = nvstrcat(p->kernel_frontend_module_name, + ".ko", NULL); + p->kernel_frontend_interface_filename = "nv-linuxfrontend.o"; + + p->uvm_kernel_module_name = nvstrcat(tmpstr, "-uvm", NULL); + p->uvm_kernel_module_filename = nvstrcat(p->uvm_kernel_module_name, ".ko", + NULL); + p->uvm_interface_filename = "nv-linuxuvm.o"; + nvfree(tmpstr); /* @@ -688,6 +747,9 @@ static Package *parse_manifest (Options *op) if (!p->kernel_module_build_directory) goto invalid_manifest_file; remove_trailing_slashes(p->kernel_module_build_directory); + p->uvm_module_build_directory = nvstrcat(p->kernel_module_build_directory, + "/" UVM_SUBDIR, NULL); + /* * the eigth line is the directory containing precompiled kernel * interfaces @@ -765,6 +827,12 @@ static Package *parse_manifest (Options *op) goto invalid_manifest_file; } + /* if any UVM files have been packaged, set uvm_files_packaged. */ + + if (p->entries[n].type == FILE_TYPE_UVM_MODULE_SRC) { + op->uvm_files_packaged = TRUE; + } + nvfree(flag); /* some libs/symlinks have an arch field */ @@ -966,6 +1034,7 @@ static void free_package(Package *p) } nvfree(p->kernel_module_build_directory); + nvfree(p->uvm_module_build_directory); nvfree(p->precompiled_kernel_interface_directory); @@ -985,7 +1054,8 @@ static void free_package(Package *p) nvfree(p->kernel_frontend_module_filename); nvfree(p->kernel_frontend_module_name); - nvfree(p->kernel_frontend_interface_filename); + nvfree(p->uvm_kernel_module_name); + nvfree(p->uvm_kernel_module_filename); nvfree((char *) p); @@ -1204,6 +1274,13 @@ guess_fail: } } + if (op->install_uvm) { + if (!sign_kernel_module(op, p->uvm_module_build_directory, "uvm", + TRUE)) { + return FALSE; + } + } + if (generate_keys) { /* If keys were generated, we should install the verification cert @@ -435,7 +435,7 @@ static int attach_signature(Options *op, Package *p, ui_log(op, "Attaching module signature to linked kernel module."); module_path = nvstrcat(p->kernel_module_build_directory, "/", - module_name, NULL); + fileInfo->target_directory, "/", module_name, NULL); command_ret = verify_crc(op, module_path, fileInfo->linked_module_crc, &actual_crc); @@ -539,8 +539,9 @@ int link_kernel_module(Options *op, Package *p, const char *build_directory, return FALSE; } - cmd = nvstrcat("cd ", build_directory, "; ", op->utils[LD], " ", - LD_OPTIONS, " -o ", fileInfo->linked_module_name, " ", + cmd = nvstrcat("cd ", build_directory, "/", fileInfo->target_directory, + "; ", op->utils[LD], " ", LD_OPTIONS, " -o ", + fileInfo->linked_module_name, " ", fileInfo->name, " ", fileInfo->core_object_name, NULL); ret = run_command(op, cmd, &result, TRUE, 0, TRUE); @@ -605,13 +606,13 @@ static int build_kernel_module_helper(Options *op, const char *dir, } -static int check_file(Options *op, Package *p, const char *filename, +static int check_file(Options *op, const char *dir, const char *filename, const char *modname) { int ret; char *path; - path = nvstrcat(p->kernel_module_build_directory, "/", filename, NULL); + path = nvstrcat(dir, "/", filename, NULL); ret = access(path, F_OK); nvfree(path); @@ -678,16 +679,40 @@ int build_kernel_module(Options *op, Package *p) /* check that the frontend file actually exists */ if (op->multiple_kernel_modules) { - if (!check_file(op, p, p->kernel_frontend_module_filename, "frontend")) { + if (!check_file(op, p->kernel_module_build_directory, + p->kernel_frontend_module_filename, "frontend")) { return FALSE; } } /* check that the file actually exists */ - if (!check_file(op, p, p->kernel_module_filename, "kernel")) { + if (!check_file(op, p->kernel_module_build_directory, + p->kernel_module_filename, "kernel")) { return FALSE; } + /* + * Build the UVM kernel module. The build directory from the previous kernel + * module build must not be cleaned first, as the UVM kernel module will + * depend on the Module.symvers file produced by that build. + */ + + if (op->install_uvm) { + ret = build_kernel_module_helper(op, p->uvm_module_build_directory, + "Unified Memory", 0); + + ret = ret && check_file(op, p->uvm_module_build_directory, + p->uvm_kernel_module_filename, "Unified Memory"); + + if (!ret) { + ui_error(op, "The Unified Memory kernel module failed to build. " + "To work around this issue, you may attempt to " + "install this driver package again with the " + "'--no-unified-memory' option."); + return FALSE; + } + } + ui_log(op, "Kernel module compilation complete."); return TRUE; @@ -773,7 +798,7 @@ static int create_detached_signature(Options *op, Package *p, { int ret, command_ret; struct stat st; - char *module_path = NULL, *error = NULL; + char *module_path = NULL, *error = NULL, *target_dir = NULL; ui_status_begin(op, "Creating a detached signature for the linked " "kernel module:", "Linking module"); @@ -785,7 +810,8 @@ static int create_detached_signature(Options *op, Package *p, goto done; } - module_path = nvstrcat(build_dir, "/", module_filename, NULL); + target_dir = nvstrcat(build_dir, "/", fileInfo->target_directory, NULL); + module_path = nvstrcat(target_dir, "/", module_filename, NULL); command_ret = stat(module_path, &st); if (command_ret != 0) { @@ -801,7 +827,7 @@ static int create_detached_signature(Options *op, Package *p, ui_status_update(op, .50, "Signing linked module"); - ret = sign_kernel_module(op, build_dir, module_suffix, FALSE); + ret = sign_kernel_module(op, target_dir, module_suffix, FALSE); if (!ret) { error = "Failed to sign the linked kernel module."; @@ -831,6 +857,7 @@ done: } nvfree(module_path); + nvfree(target_dir); return ret; } /* create_detached_signature() */ @@ -846,12 +873,16 @@ done: static int build_kernel_interface_file(Options *op, const char *tmpdir, PrecompiledFileInfo *fileInfo, const char *kernel_interface_filename, - const char *module_suffix, - const char *build_module_instances_parameter) + const char *module_suffix) { char *cmd; - char *kernel_interface; - int command_ret; + char *kernel_interface, *build_module_instances_parameter = NULL; + int ret; + + if (op->multiple_kernel_modules) { + build_module_instances_parameter = + nvasprintf(" NV_BUILD_MODULE_INSTANCES=%d", NV_MAX_MODULE_INSTANCES); + } cmd = nvstrcat("cd ", tmpdir, "; make ", kernel_interface_filename, @@ -860,11 +891,13 @@ static int build_kernel_interface_file(Options *op, const char *tmpdir, " NV_MODULE_SUFFIX=", module_suffix, build_module_instances_parameter, NULL); - command_ret = run_command(op, cmd, NULL, TRUE, 25 /* XXX */, TRUE); + nvfree(build_module_instances_parameter); + + ret = run_command(op, cmd, NULL, TRUE, 25 /* XXX */, TRUE); free(cmd); - if (command_ret != 0) { + if (ret != 0) { ui_status_end(op, "Error."); ui_error(op, "Unable to build the NVIDIA kernel module interface."); /* XXX need more descriptive error message */ @@ -875,15 +908,15 @@ static int build_kernel_interface_file(Options *op, const char *tmpdir, kernel_interface = nvstrcat(tmpdir, "/", kernel_interface_filename, NULL); + ret = access(kernel_interface, F_OK); + nvfree(kernel_interface); - if (access(kernel_interface, F_OK) == -1) { + if (ret == -1) { ui_status_end(op, "Error."); ui_error(op, "The NVIDIA kernel module interface was not created."); - nvfree(kernel_interface); return FALSE; } - nvfree(kernel_interface); return TRUE; } @@ -900,13 +933,14 @@ static int pack_kernel_interface(Options *op, Package *p, const char *module_suffix, const char *kernel_interface, const char *module_filename, - const char *core_file) + const char *core_file, + const char *target_directory) { int command_ret; command_ret = precompiled_read_interface(fileInfo, kernel_interface, module_filename, - core_file); + core_file, target_directory); if (command_ret) { if (op->module_signing_secret_key && op->module_signing_public_key) { @@ -922,6 +956,47 @@ static int pack_kernel_interface(Options *op, Package *p, return FALSE; } + + +static int build_and_pack_interface(Options *op, Package *p, const char *tmpdir, + const char *subdir, + PrecompiledFileInfo *fileInfo, + const char *interface, const char *module, + const char *suffix, const char *core) +{ + int ret; + char *filename = NULL; + char *dir = NULL; + + ui_status_begin(op, "Building kernel module interface: ", "Building %s", + interface); + + dir = nvstrcat(tmpdir, "/", subdir, NULL); + ret = build_kernel_interface_file(op, dir, fileInfo, interface, suffix); + + if (!ret) { + goto done; + } + + ui_status_end(op, "done."); + + ui_log(op, "Kernel module interface compilation complete."); + + filename = nvstrcat(dir, "/", interface, NULL); + + /* add the kernel interface to the list of files to be packaged */ + ret = pack_kernel_interface(op, p, tmpdir, fileInfo, suffix, filename, + module, core, subdir); + +done: + nvfree(dir); + nvfree(filename); + + return ret; +} + + + /* * build_kernel_interface() - build the kernel interface(s), and store any * built interfaces in a newly allocated PrecompiledFileInfo array. Return @@ -941,9 +1016,8 @@ int build_kernel_interface(Options *op, Package *p, char *tmpdir = NULL; char *dstfile = NULL; int files_packaged = 0, i; - int num_files = 1; - int ret_status; - char *build_module_instances_parameter = NULL; + int num_files = 1, ret = FALSE; + char *uvmdir = NULL; *fileInfos = NULL; @@ -966,6 +1040,23 @@ int build_kernel_interface(Options *op, Package *p, "directory '%s'.", tmpdir); goto failed; } + + uvmdir = nvstrcat(tmpdir, "/" UVM_SUBDIR, NULL); + + if (op->install_uvm) { + if (!mkdir_recursive(op, uvmdir, 0655)) { + ui_error(op, "Unable to create a temporary subdirectory for the " + "Unified Memory kernel module build."); + goto failed; + } + + if (!copy_directory_contents(op, + p->uvm_module_build_directory, uvmdir)) { + ui_error(op, "Unable to copy the Unified Memory kernel module " + "sources to temporary directory '%s'.", uvmdir); + goto failed; + } + } /* * touch the contents of the build directory, to avoid make time @@ -976,111 +1067,75 @@ int build_kernel_interface(Options *op, Package *p, if (op->multiple_kernel_modules) { num_files = op->num_kernel_modules; - build_module_instances_parameter = - nvasprintf(" NV_BUILD_MODULE_INSTANCES=%d", - NV_MAX_MODULE_INSTANCES); - } - else { - build_module_instances_parameter = nvstrdup(""); } - *fileInfos = nvalloc(sizeof(PrecompiledFileInfo) * (num_files + 1)); + *fileInfos = nvalloc(sizeof(PrecompiledFileInfo) * (num_files + 2)); for (i = 0; i < num_files; i++) { - char *kernel_interface, *kernel_module_filename; + char *kernel_module_filename; char *kernel_interface_filename; - PrecompiledFileInfo *fileInfo = *fileInfos + i; - char module_instance_str[5]; + char *module_instance_str = NULL; - memset(module_instance_str, 0, sizeof(module_instance_str)); if (op->multiple_kernel_modules) { - snprintf(module_instance_str, sizeof(module_instance_str), "%d", i); + module_instance_str = nvasprintf("%d", i); + } else { + module_instance_str = nvstrdup(""); } kernel_interface_filename = nvstrdup(p->kernel_interface_filename); - replace_zero(kernel_interface_filename, i); - /* build the kernel interface */ - - ui_status_begin(op, "Building kernel interface:", "Building (%d/%d)", - i + 1, num_files); + kernel_module_filename = nvstrdup(p->kernel_module_filename); + replace_zero(kernel_module_filename, i); - ret_status = build_kernel_interface_file(op, tmpdir, fileInfo, - kernel_interface_filename, module_instance_str, - build_module_instances_parameter); + ret = build_and_pack_interface(op, p, tmpdir, "", *fileInfos + i, + kernel_interface_filename, + kernel_module_filename, + module_instance_str, "nv-kernel.o"); - if (!ret_status) { - nvfree(kernel_interface_filename); - goto failed; + if (!ret) { + goto interface_done; } - ui_status_end(op, "done."); - - ui_log(op, "Kernel module interface compilation complete."); - - kernel_interface = nvstrcat(tmpdir, "/", - kernel_interface_filename, NULL); - - kernel_module_filename = nvstrdup(p->kernel_module_filename); - - replace_zero(kernel_module_filename, i); - - /* add the kernel interface to the list of files to be packaged */ - ret_status = pack_kernel_interface(op, p, tmpdir, fileInfo, - module_instance_str, - kernel_interface, - kernel_module_filename, - "nv-kernel.o"); +interface_done: - nvfree(kernel_interface); nvfree(kernel_interface_filename); nvfree(kernel_module_filename); + nvfree(module_instance_str); - if (!ret_status) + if (!ret) goto failed; files_packaged++; } if (op->multiple_kernel_modules) { - char *frontend_interface_filename; - PrecompiledFileInfo *fileInfo = *fileInfos + num_files; - - ui_status_begin(op, "Building frontend interface: ", "Building"); - - ret_status = build_kernel_interface_file(op, tmpdir, fileInfo, - p->kernel_frontend_interface_filename, "frontend", - build_module_instances_parameter); - - if (!ret_status) - goto failed; - - ui_status_end(op, "done."); - - ui_log(op, "Frontend kernel module interface compilation complete."); - - frontend_interface_filename = nvstrcat(tmpdir, "/", + ret = build_and_pack_interface(op, p, tmpdir, "", *fileInfos + num_files, p->kernel_frontend_interface_filename, - NULL); + p->kernel_frontend_module_filename, + "frontend", ""); + if (!ret) { + goto failed; + } - /* add the kernel interface to the list of files to be packaged */ - ret_status = pack_kernel_interface(op, p, tmpdir, fileInfo, - "frontend", - frontend_interface_filename, - p->kernel_frontend_module_filename, - ""); + files_packaged++; + } - nvfree(frontend_interface_filename); + if (op->install_uvm) { + ret = build_and_pack_interface(op, p, tmpdir, UVM_SUBDIR, + *fileInfos + files_packaged, + p->uvm_interface_filename, + p->uvm_kernel_module_filename, "uvm", ""); - if (!ret_status) + if (!ret) { goto failed; + } files_packaged++; } failed: - nvfree(build_module_instances_parameter); + nvfree(uvmdir); if (files_packaged == 0) { nvfree(*fileInfos); @@ -1100,6 +1155,7 @@ failed: + /* * check_for_warning_messages() - check if the kernel module detected * problems with the target system and registered warning messages @@ -1457,37 +1513,55 @@ int test_kernel_module(Options *op, Package *p) nvfree(module_path); if (ret != 0) { - ret = ignore_load_error(op, p, p->kernel_module_filename, - data, ret); - } else { + ret = ignore_load_error(op, p, p->kernel_module_filename, data, ret); + goto test_exit; + } + if (op->install_uvm) { + module_path = nvstrcat(p->uvm_module_build_directory, "/", + p->uvm_kernel_module_filename, NULL); + ret = do_insmod(op, module_path, &data); + nvfree(module_path); - /* - * check if the kernel module detected problems with this - * system's kernel and display any warning messages it may - * have prepared for us. - */ + if (ret != 0) { + ret = ignore_load_error(op, p, p->uvm_kernel_module_filename, data, + ret); + goto test_exit; + } + } - check_for_warning_messages(op); + /* + * check if the kernel module detected problems with this + * system's kernel and display any warning messages it may + * have prepared for us. + */ - /* - * attempt to unload the kernel module, but don't abort if - * this fails: the kernel may not have been configured with - * support for module unloading (Linux 2.6). - */ - cmd = nvstrcat(op->utils[RMMOD], " ", p->kernel_module_name, NULL); + check_for_warning_messages(op); + + /* + * attempt to unload the kernel module, but don't abort if + * this fails: the kernel may not have been configured with + * support for module unloading (Linux 2.6). + */ + + if (op->install_uvm) { + cmd = nvstrcat(op->utils[RMMOD], " ", p->uvm_kernel_module_name, NULL); run_command(op, cmd, NULL, FALSE, 0, TRUE); + nvfree(cmd); + } - if (op->multiple_kernel_modules) { - nvfree(cmd); - cmd = nvstrcat(op->utils[RMMOD], " ", - p->kernel_frontend_module_name, NULL); - run_command(op, cmd, NULL, FALSE, 0, TRUE); - } + cmd = nvstrcat(op->utils[RMMOD], " ", p->kernel_module_name, NULL); + run_command(op, cmd, NULL, FALSE, 0, TRUE); + nvfree(cmd); - ret = TRUE; + if (op->multiple_kernel_modules) { + cmd = nvstrcat(op->utils[RMMOD], " ", + p->kernel_frontend_module_name, NULL); + run_command(op, cmd, NULL, FALSE, 0, TRUE); nvfree(cmd); } + ret = TRUE; + test_exit: nvfree(data); @@ -107,7 +107,8 @@ static const struct { { ENTRY(NVIDIA_MODPROBE_MANPAGE,F, F, T, T, F, F, F ) }, { ENTRY(MODULE_SIGNING_KEY, F, F, T, F, F, F, F ) }, { ENTRY(NVIFR_LIB, T, F, T, F, F, T, F ) }, - { ENTRY(NVIFR_LIB_SYMLINK, T, F, F, F, T, F, F ) }, + { ENTRY(NVIFR_LIB_SYMLINK, T, F, F, F, T, F, F ) }, + { ENTRY(UVM_MODULE_SRC, F, F, T, F, F, F, F ) }, }; /* @@ -1269,6 +1269,29 @@ void should_install_vdpau_wrapper(Options *op, Package *p) /* + * should_install_uvm() - ask the user if he/she wishes to install UVM + */ + +void should_install_uvm(Options *op, Package *p) +{ + /* if the package does not include UVM, it can't be installed. */ + + if (!op->uvm_files_packaged) { + op->install_uvm = FALSE; + return; + } + + /* ask expert users whether they want to install UVM */ + + if (op->expert) { + op->install_uvm = ui_yes_no(op, op->install_uvm, "Would you like to " + "install the NVIDIA Unified Memory kernel " + "module?"); + } +} + + +/* * check_installed_files_from_package() - scan through the entries in * the package, making sure that all symbolic links and files are * properly installed. @@ -58,6 +58,7 @@ int do_install(Options *op, Package *p, CommandList *c); void should_install_opengl_headers(Options *op, Package *p); void should_install_compat32_files(Options *op, Package *p); void should_install_vdpau_wrapper(Options *op, Package *p); +void should_install_uvm(Options *op, Package *p); void check_installed_files_from_package(Options *op, Package *p); int tls_test(Options *op, int compat_32_libs); int check_runtime_configuration(Options *op, Package *p); diff --git a/mkprecompiled.c b/mkprecompiled.c index f6ac578..6840f7f 100644 --- a/mkprecompiled.c +++ b/mkprecompiled.c @@ -150,7 +150,8 @@ static void print_help(void) " --kernel-interface <file> --linked-module-name <module-name>\\\n" " --core-object-name <core-name>\\\n" " [ --linked-module <linked-kmod-file> \\\n" - " --signed-module <signed-kmod-file> ]\n" + " --signed-module <signed-kmod-file> ]\\\n" + " [ --target-directory <target-directory> ]\n" " Pack <file> as a precompiled kernel interface.\n" " <module-name> specifies the name of the kernel module file\n" " that is produced by linking the precompiled kernel interface\n" @@ -168,11 +169,16 @@ static void print_help(void) " correctly applied on the target system, the linking should\n" " be performed with the same linker and flags that will be\n" " used on the target system.\n" + " A target directory for unpacking the interface may be\n" + " specified with the --target-directory option.\n" + " <target-directory> is the name of the directory where the\n" + " unpacked interface will be written.\n" " The --linked-module and --signed-module options must be\n" " given after the --kernel-interface option for the kernel\n" " interface file with which they are associated, and before\n" " any additional --kernel-interface or --kernel-module files.\n" - " --kernel-module <file> [ --signed ]\n" + " --kernel-module <file> [ --signed ]\\\n" + " [ --target-directory <target-directory> ]\n" " Pack <file> as a precompiled kernel module. The --signed\n" " option specifies that <file> includes a module signature.\n" " The --signed option must be given after the --kernel-module\n" @@ -208,6 +214,7 @@ enum { LINKED_AND_SIGNED_MODULE_OPTION, LINKED_MODULE_NAME_OPTION, CORE_OBJECT_NAME_OPTION, + TARGET_DIRECTORY_OPTION }; @@ -302,9 +309,13 @@ static void set_action(Options *op, int action) static void pack_a_file(Options *op, PrecompiledFileInfo *file, char *name, uint32 type, char **linked_name, - char **core_name, char **linked_module_file, - char **signed_module_file) + char **core_name, char **target_directory, + char **linked_module_file, char **signed_module_file) { + if (!*target_directory) { + *target_directory = nvstrdup(""); + } + switch(type) { case PRECOMPILED_FILE_TYPE_INTERFACE: if (*linked_name == NULL || *core_name == NULL) { @@ -314,14 +325,15 @@ static void pack_a_file(Options *op, PrecompiledFileInfo *file, exit(1); } - if (!precompiled_read_interface(file, name, *linked_name, *core_name)) { + if (!precompiled_read_interface(file, name, *linked_name, *core_name, + *target_directory)) { fprintf(stderr, "Failed to read kernel interface '%s'.\n", name); exit(1); } break; case PRECOMPILED_FILE_TYPE_MODULE: - if (!precompiled_read_module(file, name)) { + if (!precompiled_read_module(file, name, *target_directory)) { fprintf(stderr, "Failed to read kernel module '%s'.\n", name); } break; @@ -340,9 +352,11 @@ static void pack_a_file(Options *op, PrecompiledFileInfo *file, nvfree(*linked_name); nvfree(*core_name); + nvfree(*target_directory); nvfree(*linked_module_file); nvfree(*signed_module_file); - *linked_name = *core_name = *linked_module_file = *signed_module_file = NULL; + *linked_name = *core_name = *target_directory = *linked_module_file = + *signed_module_file = NULL; } /* @@ -358,7 +372,7 @@ static Options *parse_commandline(int argc, char *argv[]) uint32 type = 0; PrecompiledFileInfo *file = NULL; char *strval, *signed_mod = NULL, *linked_mod = NULL, *filename = NULL, - *linked_name = NULL, *core_name = NULL; + *linked_name = NULL, *core_name = NULL, *target_directory = NULL; char see_help[1024]; static const NVGetoptOption long_options[] = { @@ -387,6 +401,8 @@ static Options *parse_commandline(int argc, char *argv[]) NVGETOPT_STRING_ARGUMENT, NULL, NULL }, { "core-object-name", CORE_OBJECT_NAME_OPTION, NVGETOPT_STRING_ARGUMENT, NULL, NULL }, + { "target-directory", TARGET_DIRECTORY_OPTION, + NVGETOPT_STRING_ARGUMENT, NULL, NULL }, { NULL, 0, 0, NULL, NULL } }; @@ -430,7 +446,7 @@ static Options *parse_commandline(int argc, char *argv[]) if (file) { pack_a_file(op, file, filename, type, &linked_name, &core_name, - &linked_mod, &signed_mod); + &target_directory, &linked_mod, &signed_mod); } file = op->new_files + op->num_files; @@ -483,6 +499,13 @@ static Options *parse_commandline(int argc, char *argv[]) break; + case TARGET_DIRECTORY_OPTION: + + check_file_option_validity(op, "target-directory"); + target_directory = strval; + + break; + default: fprintf (stderr, "Invalid commandline; %s", see_help); exit(0); @@ -502,7 +525,7 @@ static Options *parse_commandline(int argc, char *argv[]) case PACK: if (file) { pack_a_file(op, file, filename, type, &linked_name, &core_name, - &linked_mod, &signed_mod); + &target_directory, &linked_mod, &signed_mod); } if (op->num_files < 1) { @@ -650,6 +673,7 @@ int main(int argc, char *argv[]) printf(" size: %d bytes\n", file->size); printf(" crc: %" PRIu32 "\n", file->crc); + printf(" target directory: %s\n", file->target_directory); if (file->type == PRECOMPILED_FILE_TYPE_INTERFACE) { printf(" core object name: %s\n", file->core_object_name); diff --git a/nvidia-installer.c b/nvidia-installer.c index 3d8cb59..52caec2 100644 --- a/nvidia-installer.c +++ b/nvidia-installer.c @@ -149,6 +149,7 @@ static Options *load_default_options(void) op->install_vdpau_wrapper = NV_OPTIONAL_BOOL_DEFAULT; op->check_for_alternate_installs = TRUE; op->num_kernel_modules = 1; + op->install_uvm = TRUE; return op; @@ -423,6 +424,9 @@ static void parse_commandline(int argc, char *argv[], Options *op) else op->num_kernel_modules = intval; break; + case NO_UVM_OPTION: + op->install_uvm = FALSE; + break; case NO_CHECK_FOR_ALTERNATE_INSTALLS_OPTION: op->check_for_alternate_installs = FALSE; break; diff --git a/nvidia-installer.h b/nvidia-installer.h index 3389e10..904d43c 100644 --- a/nvidia-installer.h +++ b/nvidia-installer.h @@ -148,6 +148,8 @@ typedef struct __options { int check_for_alternate_installs; int multiple_kernel_modules; int num_kernel_modules; + int install_uvm; + int uvm_files_packaged; NVOptionalBool install_vdpau_wrapper; @@ -187,6 +189,7 @@ typedef struct __options { char *kernel_module_src_prefix; char *kernel_module_src_dir; char *utils[MAX_UTILS]; + char *uvm_module_src_dir; char *proc_mount_point; char *ui_str; @@ -270,6 +273,7 @@ typedef enum { FILE_TYPE_MODULE_SIGNING_KEY, FILE_TYPE_NVIFR_LIB, FILE_TYPE_NVIFR_LIB_SYMLINK, + FILE_TYPE_UVM_MODULE_SRC, FILE_TYPE_MAX } PackageEntryFileType; @@ -363,10 +367,14 @@ typedef struct __package { char **bad_modules; char **bad_module_filenames; char *kernel_module_build_directory; + char *uvm_module_build_directory; char *precompiled_kernel_interface_directory; char *kernel_frontend_module_filename; char *kernel_frontend_module_name; char *kernel_frontend_interface_filename; + char *uvm_kernel_module_name; + char *uvm_kernel_module_filename; + char *uvm_interface_filename; PackageEntry *entries; /* array of filename/checksum/bytesize entries */ int num_entries; diff --git a/option_table.h b/option_table.h index 4afb9bb..49d3556 100644 --- a/option_table.h +++ b/option_table.h @@ -95,6 +95,7 @@ enum { INSTALL_VDPAU_WRAPPER_OPTION, NO_CHECK_FOR_ALTERNATE_INSTALLS_OPTION, MULTIPLE_KERNEL_MODULES_OPTION, + NO_UVM_OPTION, }; static const NVGetoptOption __options[] = { @@ -629,6 +630,9 @@ static const NVGetoptOption __options[] = { "Build and install multiple NVIDIA kernel modules. The maximum number " "of NVIDIA kernel modules that may be built is 8." }, + { "no-unified-memory", NO_UVM_OPTION, 0, NULL, + "Do not install the NVIDIA Unified Memory kernel module."}, + /* Orphaned options: These options were in the long_options table in * nvidia-installer.c but not in the help. */ { "debug", 'd', 0, NULL,NULL }, diff --git a/precompiled.c b/precompiled.c index 8d9e84e..5a4c1c1 100644 --- a/precompiled.c +++ b/precompiled.c @@ -365,7 +365,8 @@ int precompiled_file_unpack(Options *op, const PrecompiledFileInfo *fileInfo, int ret = FALSE, dst_fd = 0; char *dst_path, *dst = NULL; - dst_path = nvstrcat(output_directory, "/", fileInfo->name, NULL); + dst_path = nvstrcat(output_directory, "/", fileInfo->target_directory, "/", + fileInfo->name, NULL); /* extract file */ @@ -479,6 +480,7 @@ int precompiled_pack(const PrecompiledInfo *info, const char *package_filename) strlen(info->files[i].name) + strlen(info->files[i].linked_module_name) + strlen(info->files[i].core_object_name) + + strlen(info->files[i].target_directory) + info->files[i].size + info->files[i].signature_size; } @@ -545,6 +547,7 @@ int precompiled_pack(const PrecompiledInfo *info, const char *package_filename) uint32 name_len = strlen(file->name); uint32 linked_module_name_len = strlen(file->linked_module_name); uint32 core_object_name_len = strlen(file->core_object_name); + uint32 target_directory_len = strlen(file->target_directory); /* file header */ memcpy(&(out[offset]), PRECOMPILED_FILE_HEADER, 4); @@ -572,6 +575,11 @@ int precompiled_pack(const PrecompiledInfo *info, const char *package_filename) memcpy(&(out[offset]), file->core_object_name, core_object_name_len); offset += core_object_name_len; + /* target directory name */ + encode_uint32(target_directory_len, out, &offset); + memcpy(&(out[offset]), file->target_directory, target_directory_len); + offset += target_directory_len; + /* crc */ encode_uint32(file->crc, out, &offset); @@ -645,6 +653,7 @@ void free_precompiled_file_data(PrecompiledFileInfo fileInfo) nvfree(fileInfo.linked_module_name); nvfree(fileInfo.data); nvfree(fileInfo.signature); + nvfree(fileInfo.target_directory); } @@ -659,7 +668,9 @@ void free_precompiled_file_data(PrecompiledFileInfo fileInfo) static int precompiled_read_file(PrecompiledFileInfo *fileInfo, const char *filename, const char *linked_module_name, - const char *core_object_name, uint32 type) + const char *core_object_name, + const char *target_directory, + uint32 type) { int fd; struct stat st; @@ -687,6 +698,7 @@ static int precompiled_read_file(PrecompiledFileInfo *fileInfo, fileInfo->name = nv_basename(filename); fileInfo->linked_module_name = nvstrdup(linked_module_name); fileInfo->core_object_name = nvstrdup(core_object_name); + fileInfo->target_directory = nvstrdup(target_directory); fileInfo->crc = compute_crc(NULL, filename); success = TRUE; @@ -700,16 +712,18 @@ done: int precompiled_read_interface(PrecompiledFileInfo *fileInfo, const char *filename, const char *linked_module_name, - const char *core_object_name) + const char *core_object_name, + const char *target_directory) { return precompiled_read_file(fileInfo, filename, linked_module_name, - core_object_name, + core_object_name, target_directory, PRECOMPILED_FILE_TYPE_INTERFACE); } -int precompiled_read_module(PrecompiledFileInfo *fileInfo, const char *filename) +int precompiled_read_module(PrecompiledFileInfo *fileInfo, const char *filename, + const char *target_directory) { - return precompiled_read_file(fileInfo, filename, "", "", + return precompiled_read_file(fileInfo, filename, "", "", target_directory, PRECOMPILED_FILE_TYPE_MODULE); } @@ -793,6 +807,16 @@ static int precompiled_read_fileinfo(Options *op, PrecompiledFileInfo *fileInfos memcpy(fileInfo->core_object_name, buf + offset, val); offset += val; + val = read_uint32(buf, &offset); + if (offset + val > size) { + ui_log(op, "Bad target directory name length."); + return -1; + } + + fileInfo->target_directory = nvalloc(val + 1); + memcpy(fileInfo->target_directory, buf + offset, val); + offset += val; + fileInfo->crc = read_uint32(buf, &offset); fileInfo->size = read_uint32(buf, &offset); diff --git a/precompiled.h b/precompiled.h index ca33e20..a0ef741 100644 --- a/precompiled.h +++ b/precompiled.h @@ -99,7 +99,7 @@ #define PRECOMPILED_PKG_HEADER "\aNVIDIA\a" -#define PRECOMPILED_PKG_VERSION 1 +#define PRECOMPILED_PKG_VERSION 2 #define PRECOMPILED_FILE_CONSTANT_LENGTH (4 + /* precompiled file header */ \ 4 + /* file serial number */ \ @@ -108,6 +108,7 @@ 4 + /* file name length */ \ 4 + /* linked module name length */ \ 4 + /* core object name length */ \ + 4 + /* target dir name length */ \ 4 + /* file crc */ \ 4 + /* file size */ \ 4 + /* redundant file crc */ \ @@ -138,6 +139,7 @@ typedef struct __precompiled_file_info { char *name; char *linked_module_name; char *core_object_name; + char *target_directory; uint32 crc; uint32 size; uint8 *data; @@ -181,8 +183,10 @@ void free_precompiled_file_data(PrecompiledFileInfo fileInfo); int precompiled_read_interface(PrecompiledFileInfo *fileInfo, const char *filename, const char *linked_module_name, - const char *core_object_name); -int precompiled_read_module(PrecompiledFileInfo *fileInfo, const char *filename); + const char *core_object_name, + const char *target_directory); +int precompiled_read_module(PrecompiledFileInfo *fileInfo, const char *filename, + const char *target_directory); void precompiled_append_files(PrecompiledInfo *info, PrecompiledFileInfo *files, int num_files); @@ -1 +1 @@ -NVIDIA_VERSION = 331.13 +NVIDIA_VERSION = 331.17 |