[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20201120202426.18009-9-rick.p.edgecombe@intel.com>
Date: Fri, 20 Nov 2020 12:24:24 -0800
From: Rick Edgecombe <rick.p.edgecombe@...el.com>
To: akpm@...ux-foundation.org, jeyu@...nel.org, bpf@...r.kernel.org,
ast@...nel.org, daniel@...earbox.net, luto@...nel.org,
dave.hansen@...ux.intel.com, peterz@...radead.org, x86@...nel.org,
rppt@...nel.org, linux-mm@...ck.org, linux-kernel@...r.kernel.org,
dan.j.williams@...el.com
Cc: elena.reshetova@...el.com, ira.weiny@...el.com,
Rick Edgecombe <rick.p.edgecombe@...el.com>
Subject: [PATCH RFC 08/10] jump_label: Handle module writable address
Since modules can have a separate writable address during loading,
do the nop application at the writable address.
As long as info is on hand about if the operations is happening during
a module load, don't do a full text_poke() when writing data to a
writable address.
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@...el.com>
---
arch/x86/kernel/jump_label.c | 18 ++++++++++++++++--
kernel/jump_label.c | 2 +-
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c
index 5ba8477c2cb7..7a50148a63dd 100644
--- a/arch/x86/kernel/jump_label.c
+++ b/arch/x86/kernel/jump_label.c
@@ -63,6 +63,18 @@ static inline void __jump_label_transform(struct jump_entry *entry,
int init)
{
const void *opcode = __jump_label_set_jump_code(entry, type, init);
+ unsigned long addr = jump_entry_code(entry);
+ struct module *mod = __module_address(addr);
+ bool mod_writable = false;
+
+ if (mod) {
+ struct perm_allocation *alloc = module_get_allocation(mod, addr);
+
+ if (perm_is_writable(alloc)) {
+ addr = perm_writable_addr(alloc, addr);
+ mod_writable = true;
+ }
+ }
/*
* As long as only a single processor is running and the code is still
@@ -74,9 +86,11 @@ static inline void __jump_label_transform(struct jump_entry *entry,
* At the time the change is being done, just ignore whether we
* are doing nop -> jump or jump -> nop transition, and assume
* always nop being the 'currently valid' instruction
+ *
+ * If this is a module being loaded, text_poke_early can also be used.
*/
- if (init || system_state == SYSTEM_BOOTING) {
- text_poke_early((void *)jump_entry_code(entry), opcode,
+ if (init || system_state == SYSTEM_BOOTING || mod_writable) {
+ text_poke_early((void *)addr, opcode,
JUMP_LABEL_NOP_SIZE);
return;
}
diff --git a/kernel/jump_label.c b/kernel/jump_label.c
index 015ef903ce8c..3919e78fce12 100644
--- a/kernel/jump_label.c
+++ b/kernel/jump_label.c
@@ -595,7 +595,7 @@ static void __jump_label_mod_update(struct static_key *key)
*/
void jump_label_apply_nops(struct module *mod)
{
- struct jump_entry *iter_start = mod->jump_entries;
+ struct jump_entry *iter_start = module_adjust_writable_addr(mod->jump_entries);
struct jump_entry *iter_stop = iter_start + mod->num_jump_entries;
struct jump_entry *iter;
--
2.20.1
Powered by blists - more mailing lists