Commit-ID:  882a0db9d143e5e8dac54b96e83135bccd1f68d1
Gitweb:     https://git.kernel.org/tip/882a0db9d143e5e8dac54b96e83135bccd1f68d1
Author:     Peter Zijlstra <pet...@infradead.org>
AuthorDate: Wed, 24 Jul 2019 17:47:26 -0500
Committer:  Thomas Gleixner <t...@linutronix.de>
CommitDate: Thu, 25 Jul 2019 08:36:39 +0200

objtool: Improve UACCESS coverage

A clang build reported an (obvious) double CLAC while a GCC build did not;
it turns out that objtool only re-visits instructions if the first visit
was with AC=0. If OTOH the first visit was with AC=1, it completely ignores
any subsequent visit, even when it has AC=0.

Fix this by using a visited mask instead of a boolean, and (explicitly)
mark the AC state.

$ ./objtool check -b --no-fp --retpoline --uaccess 
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool: 
.altinstr_replacement+0x22: redundant UACCESS disable
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:   
eb_copy_relocations.isra.34()+0xea: (alt)
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:   
.altinstr_replacement+0xffffffffffffffff: (branch)
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:   
eb_copy_relocations.isra.34()+0xd9: (alt)
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:   
eb_copy_relocations.isra.34()+0xb2: (branch)
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:   
eb_copy_relocations.isra.34()+0x39: (branch)
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:   
eb_copy_relocations.isra.34()+0x0: <=== (func)

Reported-by: Josh Poimboeuf <jpoim...@redhat.com>
Reported-by: Thomas Gleixner <t...@linutronix.de>
Reported-by: Sedat Dilek <sedat.di...@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org>
Signed-off-by: Josh Poimboeuf <jpoim...@redhat.com>
Signed-off-by: Thomas Gleixner <t...@linutronix.de>
Tested-by: Nathan Chancellor <natechancel...@gmail.com>
Tested-by: Nick Desaulniers <ndesaulni...@google.com>
Tested-by: Sedat Dilek <sedat.di...@gmail.com>
Link: https://github.com/ClangBuiltLinux/linux/issues/617
Link: 
https://lkml.kernel.org/r/5359166aad2d53f3145cd442d83d0e5115e0cd17.1564007838.git.jpoim...@redhat.com

---
 tools/objtool/check.c | 7 ++++---
 tools/objtool/check.h | 3 ++-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 5f26620f13f5..176f2f084060 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1946,6 +1946,7 @@ static int validate_branch(struct objtool_file *file, 
struct symbol *func,
        struct alternative *alt;
        struct instruction *insn, *next_insn;
        struct section *sec;
+       u8 visited;
        int ret;
 
        insn = first;
@@ -1972,12 +1973,12 @@ static int validate_branch(struct objtool_file *file, 
struct symbol *func,
                        return 1;
                }
 
+               visited = 1 << state.uaccess;
                if (insn->visited) {
                        if (!insn->hint && !insn_state_match(insn, &state))
                                return 1;
 
-                       /* If we were here with AC=0, but now have AC=1, go 
again */
-                       if (insn->state.uaccess || !state.uaccess)
+                       if (insn->visited & visited)
                                return 0;
                }
 
@@ -2024,7 +2025,7 @@ static int validate_branch(struct objtool_file *file, 
struct symbol *func,
                } else
                        insn->state = state;
 
-               insn->visited = true;
+               insn->visited |= visited;
 
                if (!insn->ignore_alts) {
                        bool skip_orig = false;
diff --git a/tools/objtool/check.h b/tools/objtool/check.h
index b881fafcf55d..6d875ca6fce0 100644
--- a/tools/objtool/check.h
+++ b/tools/objtool/check.h
@@ -33,8 +33,9 @@ struct instruction {
        unsigned int len;
        enum insn_type type;
        unsigned long immediate;
-       bool alt_group, visited, dead_end, ignore, hint, save, restore, 
ignore_alts;
+       bool alt_group, dead_end, ignore, hint, save, restore, ignore_alts;
        bool retpoline_safe;
+       u8 visited;
        struct symbol *call_dest;
        struct instruction *jump_dest;
        struct instruction *first_jump_src;

Reply via email to