Merge branch 'for-6.4/doc' into for-linus
This commit is contained in:
commit
c9c8133080
|
@ -1,8 +1,8 @@
|
|||
===========================
|
||||
Livepatch module Elf format
|
||||
Livepatch module ELF format
|
||||
===========================
|
||||
|
||||
This document outlines the Elf format requirements that livepatch modules must follow.
|
||||
This document outlines the ELF format requirements that livepatch modules must follow.
|
||||
|
||||
|
||||
.. Table of Contents
|
||||
|
@ -20,17 +20,17 @@ code. So, instead of duplicating code and re-implementing what the module
|
|||
loader can already do, livepatch leverages existing code in the module
|
||||
loader to perform the all the arch-specific relocation work. Specifically,
|
||||
livepatch reuses the apply_relocate_add() function in the module loader to
|
||||
write relocations. The patch module Elf format described in this document
|
||||
write relocations. The patch module ELF format described in this document
|
||||
enables livepatch to be able to do this. The hope is that this will make
|
||||
livepatch more easily portable to other architectures and reduce the amount
|
||||
of arch-specific code required to port livepatch to a particular
|
||||
architecture.
|
||||
|
||||
Since apply_relocate_add() requires access to a module's section header
|
||||
table, symbol table, and relocation section indices, Elf information is
|
||||
table, symbol table, and relocation section indices, ELF information is
|
||||
preserved for livepatch modules (see section 5). Livepatch manages its own
|
||||
relocation sections and symbols, which are described in this document. The
|
||||
Elf constants used to mark livepatch symbols and relocation sections were
|
||||
ELF constants used to mark livepatch symbols and relocation sections were
|
||||
selected from OS-specific ranges according to the definitions from glibc.
|
||||
|
||||
Why does livepatch need to write its own relocations?
|
||||
|
@ -43,7 +43,7 @@ reject the livepatch module. Furthermore, we cannot apply relocations that
|
|||
affect modules not yet loaded at patch module load time (e.g. a patch to a
|
||||
driver that is not loaded). Formerly, livepatch solved this problem by
|
||||
embedding special "dynrela" (dynamic rela) sections in the resulting patch
|
||||
module Elf output. Using these dynrela sections, livepatch could resolve
|
||||
module ELF output. Using these dynrela sections, livepatch could resolve
|
||||
symbols while taking into account its scope and what module the symbol
|
||||
belongs to, and then manually apply the dynamic relocations. However this
|
||||
approach required livepatch to supply arch-specific code in order to write
|
||||
|
@ -80,7 +80,7 @@ Example:
|
|||
3. Livepatch relocation sections
|
||||
================================
|
||||
|
||||
A livepatch module manages its own Elf relocation sections to apply
|
||||
A livepatch module manages its own ELF relocation sections to apply
|
||||
relocations to modules as well as to the kernel (vmlinux) at the
|
||||
appropriate time. For example, if a patch module patches a driver that is
|
||||
not currently loaded, livepatch will apply the corresponding livepatch
|
||||
|
@ -95,7 +95,7 @@ also possible for a livepatch module to have no livepatch relocation
|
|||
sections, as in the case of the sample livepatch module (see
|
||||
samples/livepatch).
|
||||
|
||||
Since Elf information is preserved for livepatch modules (see Section 5), a
|
||||
Since ELF information is preserved for livepatch modules (see Section 5), a
|
||||
livepatch relocation section can be applied simply by passing in the
|
||||
appropriate section index to apply_relocate_add(), which then uses it to
|
||||
access the relocation section and apply the relocations.
|
||||
|
@ -291,19 +291,12 @@ Examples:
|
|||
Note that the 'Ndx' (Section index) for these symbols is SHN_LIVEPATCH (0xff20).
|
||||
"OS" means OS-specific.
|
||||
|
||||
5. Symbol table and Elf section access
|
||||
5. Symbol table and ELF section access
|
||||
======================================
|
||||
A livepatch module's symbol table is accessible through module->symtab.
|
||||
|
||||
Since apply_relocate_add() requires access to a module's section headers,
|
||||
symbol table, and relocation section indices, Elf information is preserved for
|
||||
symbol table, and relocation section indices, ELF information is preserved for
|
||||
livepatch modules and is made accessible by the module loader through
|
||||
module->klp_info, which is a klp_modinfo struct. When a livepatch module loads,
|
||||
this struct is filled in by the module loader. Its fields are documented below::
|
||||
|
||||
struct klp_modinfo {
|
||||
Elf_Ehdr hdr; /* Elf header */
|
||||
Elf_Shdr *sechdrs; /* Section header table */
|
||||
char *secstrings; /* String table for the section headers */
|
||||
unsigned int symndx; /* The symbol table section index */
|
||||
};
|
||||
module->klp_info, which is a :c:type:`klp_modinfo` struct. When a livepatch module
|
||||
loads, this struct is filled in by the module loader.
|
||||
|
|
|
@ -352,6 +352,14 @@ struct mod_kallsyms {
|
|||
};
|
||||
|
||||
#ifdef CONFIG_LIVEPATCH
|
||||
/**
|
||||
* struct klp_modinfo - ELF information preserved from the livepatch module
|
||||
*
|
||||
* @hdr: ELF header
|
||||
* @sechdrs: Section header table
|
||||
* @secstrings: String table for the section headers
|
||||
* @symndx: The symbol table section index
|
||||
*/
|
||||
struct klp_modinfo {
|
||||
Elf_Ehdr hdr;
|
||||
Elf_Shdr *sechdrs;
|
||||
|
@ -515,7 +523,7 @@ struct module {
|
|||
bool klp; /* Is this a livepatch module? */
|
||||
bool klp_alive;
|
||||
|
||||
/* Elf information */
|
||||
/* ELF information */
|
||||
struct klp_modinfo *klp_info;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "internal.h"
|
||||
|
||||
/*
|
||||
* Persist Elf information about a module. Copy the Elf header,
|
||||
* Persist ELF information about a module. Copy the ELF header,
|
||||
* section header table, section string table, and symtab section
|
||||
* index from info to mod->klp_info.
|
||||
*/
|
||||
|
@ -25,11 +25,11 @@ int copy_module_elf(struct module *mod, struct load_info *info)
|
|||
if (!mod->klp_info)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Elf header */
|
||||
/* ELF header */
|
||||
size = sizeof(mod->klp_info->hdr);
|
||||
memcpy(&mod->klp_info->hdr, info->hdr, size);
|
||||
|
||||
/* Elf section header table */
|
||||
/* ELF section header table */
|
||||
size = sizeof(*info->sechdrs) * info->hdr->e_shnum;
|
||||
mod->klp_info->sechdrs = kmemdup(info->sechdrs, size, GFP_KERNEL);
|
||||
if (!mod->klp_info->sechdrs) {
|
||||
|
@ -37,7 +37,7 @@ int copy_module_elf(struct module *mod, struct load_info *info)
|
|||
goto free_info;
|
||||
}
|
||||
|
||||
/* Elf section name string table */
|
||||
/* ELF section name string table */
|
||||
size = info->sechdrs[info->hdr->e_shstrndx].sh_size;
|
||||
mod->klp_info->secstrings = kmemdup(info->secstrings, size, GFP_KERNEL);
|
||||
if (!mod->klp_info->secstrings) {
|
||||
|
@ -45,7 +45,7 @@ int copy_module_elf(struct module *mod, struct load_info *info)
|
|||
goto free_sechdrs;
|
||||
}
|
||||
|
||||
/* Elf symbol section index */
|
||||
/* ELF symbol section index */
|
||||
symndx = info->index.sym;
|
||||
mod->klp_info->symndx = symndx;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/fs.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kernel_read_file.h>
|
||||
#include <linux/kstrtox.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/elf.h>
|
||||
|
@ -2675,7 +2676,7 @@ static int unknown_module_param_cb(char *param, char *val, const char *modname,
|
|||
int ret;
|
||||
|
||||
if (strcmp(param, "async_probe") == 0) {
|
||||
if (strtobool(val, &mod->async_probe_requested))
|
||||
if (kstrtobool(val, &mod->async_probe_requested))
|
||||
mod->async_probe_requested = true;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kstrtox.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/module.h>
|
||||
|
@ -310,7 +311,7 @@ int param_set_bool(const char *val, const struct kernel_param *kp)
|
|||
if (!val) val = "1";
|
||||
|
||||
/* One of =[yYnN01] */
|
||||
return strtobool(val, kp->arg);
|
||||
return kstrtobool(val, kp->arg);
|
||||
}
|
||||
EXPORT_SYMBOL(param_set_bool);
|
||||
|
||||
|
|
|
@ -51,12 +51,11 @@ static int num_test_devs;
|
|||
|
||||
/**
|
||||
* enum kmod_test_case - linker table test case
|
||||
*
|
||||
* If you add a test case, please be sure to review if you need to se
|
||||
* @need_mod_put for your tests case.
|
||||
*
|
||||
* @TEST_KMOD_DRIVER: stress tests request_module()
|
||||
* @TEST_KMOD_FS_TYPE: stress tests get_fs_type()
|
||||
*
|
||||
* If you add a test case, please be sure to review if you need to set
|
||||
* @need_mod_put for your tests case.
|
||||
*/
|
||||
enum kmod_test_case {
|
||||
__TEST_KMOD_INVALID = 0,
|
||||
|
@ -78,7 +77,7 @@ struct test_config {
|
|||
struct kmod_test_device;
|
||||
|
||||
/**
|
||||
* kmod_test_device_info - thread info
|
||||
* struct kmod_test_device_info - thread info
|
||||
*
|
||||
* @ret_sync: return value if request_module() is used, sync request for
|
||||
* @TEST_KMOD_DRIVER
|
||||
|
@ -101,7 +100,7 @@ struct kmod_test_device_info {
|
|||
};
|
||||
|
||||
/**
|
||||
* kmod_test_device - test device to help test kmod
|
||||
* struct kmod_test_device - test device to help test kmod
|
||||
*
|
||||
* @dev_idx: unique ID for test device
|
||||
* @config: configuration for the test
|
||||
|
|
|
@ -14,7 +14,7 @@ modules := $(call read-file, $(MODORDER))
|
|||
ifeq ($(KBUILD_EXTMOD),)
|
||||
dst := $(MODLIB)/kernel
|
||||
else
|
||||
INSTALL_MOD_DIR ?= extra
|
||||
INSTALL_MOD_DIR ?= updates
|
||||
dst := $(MODLIB)/$(INSTALL_MOD_DIR)
|
||||
endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue