summaryrefslogtreecommitdiff
path: root/kernel.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel.c')
-rw-r--r--kernel.c304
1 files changed, 189 insertions, 115 deletions
diff --git a/kernel.c b/kernel.c
index 0237cdd..2a90b42 100644
--- a/kernel.c
+++ b/kernel.c
@@ -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);