@@ -57,6 +57,18 @@
".long 998b - .\n\t" \
".popsection\n\t"
+#define ASM_UACCESS_BEGIN \
+ "998:\n\t" \
+ ".pushsection .discard.uaccess_begin\n\t" \
+ ".long 998b - .\n\t" \
+ ".popsection\n\t"
+
+#define ASM_UACCESS_END \
+ "998:\n\t" \
+ ".pushsection .discard.uaccess_end\n\t" \
+ ".long 998b - .\n\t" \
+ ".popsection\n\t"
+
#else /* __ASSEMBLY__ */
/*
@@ -156,6 +168,8 @@
#define STACK_FRAME_NON_STANDARD_FP(func)
#define ANNOTATE_NOENDBR
#define ASM_REACHABLE
+#define ASM_UACCESS_BEGIN
+#define ASM_UACCESS_END
#else
#define ANNOTATE_INTRA_FUNCTION_CALL
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0
@@ -1052,6 +1052,38 @@ static void add_ignores(struct objtool_file *file)
}
}
+static void __add_uaccess(struct objtool_file *file, const char *name,
+ int type, const char *action)
+{
+ struct section *rsec;
+ struct reloc *reloc;
+ struct instruction *insn;
+
+ rsec = find_section_by_name(file->elf, name);
+ if (!rsec)
+ return;
+
+ for_each_reloc(rsec, reloc) {
+ if (reloc->sym->type != STT_SECTION) {
+ WARN("unexpected relocation symbol type in %s: ", rsec->name);
+ continue;
+ }
+ insn = find_insn(file, reloc->sym->sec, reloc_addend(reloc));
+ if (!insn) {
+ WARN("can't find UACCESS %s insn at %s+0x%" PRIx64,
+ action, reloc->sym->sec->name, reloc_addend(reloc));
+ continue;
+ }
+ insn->type = type;
+ }
+}
+
+static void add_uaccess(struct objtool_file *file)
+{
+ __add_uaccess(file, ".rela.discard.uaccess_begin", INSN_STAC, "enable");
+ __add_uaccess(file, ".rela.discard.uaccess_end", INSN_CLAC, "disable");
+}
+
/*
* This is a whitelist of functions that is allowed to be called with AC set.
* The list is meant to be minimal and only contains compiler instrumentation
@@ -2558,6 +2590,7 @@ static int decode_sections(struct objtool_file *file)
return ret;
add_ignores(file);
+ add_uaccess(file);
add_uaccess_safe(file);
ret = add_ignore_alternatives(file);
On x86, UACCESS is controlled by two instructions: STAC and CLAC. STAC instruction enables UACCESS while CLAC disables UACCESS. This is simple enough for objtool to locate UACCESS enable and disable. But on powerpc it is a bit more complex, the same instruction is used for enabling and disabling UACCESS, and the same instruction can be used for many other things. It would be too complex to use exclusively instruction decoding. To help objtool, mark such instruction into .discard.uaccess_begin and .discard.uaccess_end sections, on the same principle as for reachable/unreachable instructions. And add ASM_UACCESS_BEGIN and ASM_UACCESS_END macros to be used in inline assembly code to annotate UACCESS enable and UACCESS disable instructions. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> --- include/linux/objtool.h | 14 ++++++++++++++ tools/objtool/check.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+)