objtool sync up for the stable 4.9.y tree
Subsystems (15)
Greg Kroah-Hartman
maintainercover objtool sync up for the stable 4.9.y tree
There are pros and cons of dealing with tools in the kernel directory. The pros are the fact that development happens fast, and new features can be added to the kernel and the tools at the same times. The cons are when dealing with backported kernel patches, it can be necessary to backport parts of the tool changes as well.
For 4.9.y so far, we have backported individual patches. That quickly breaks down when there are minor differences between how backports were handled, so grabbing 40+ patch long series can be difficult, not impossible, but really frustrating to attempt.
To help mitigate this mess, this patch series works to sync up the objtool code with the version that is currently in 4.14.47. This required a number of objtool old patches to be backported, a single big "sync the world" patch, and a lot of include file updates to get everything all working properly as well as some minor fixes for build warnings.
And at the end of this series, is a set of backported objtool patches for gcc-8 that was the main reason this whole patch series was created. They applied just fine, being the identical version that goes into the 4.14.y stable tree, so it feels like the backport was successful.
This has survivied my limited testing, and as the codebase is identical to 4.14.47, I'm pretty comfortable dropping this big change in here in 4.9.y. Hopefully all goes well...
If anyone has any objections to this patch series, or finds anything I messed up on, please let me know.
thanks,
greg k-h
Arnaldo Carvalho de Melo (11):
tools include: Introduce linux/compiler-gcc.h
tools include: Adopt __compiletime_error
tools include: Introduce atomic_cmpxchg_{relaxed,release}() tools include: Add UINT_MAX def to kernel.h
tools include: Adopt kernel's refcount.h
tools include uapi: Grab copies of stat.h and fcntl.h tools include: Introduce linux/bug.h, from the kernel sources tools include: Adopt __same_type() and __must_be_array() from the
kernel
tools include: Move ARRAY_SIZE() to linux/kernel.h tools include: Drop ARRAY_SIZE() definition from linux/hashtable.h tools include: Include missing headers for fls() and types in
linux/log2.h
Greg Kroah-Hartman (4):
objtool: sync up with the 4.14.47 version of objtool perf/tools: header file sync up
objtool: header file sync-up
x86/xen: Add unwind hint annotations to xen_setup_gdt
Jiri Olsa (3):
tools lib: Add for_each_clear_bit macro
perf tools: Force fixdep compilation at the start of the build perf tools: Move headers check into bash script
Josh Poimboeuf (8):
objtool: Improve detection of BUG() and other dead ends
objtool: Move checking code to check.c
objtool: Support GCC 8's cold subfunctions
objtool: Support GCC 8 switch tables
objtool: Detect RIP-relative switch table references
objtool: Detect RIP-relative switch table references, part 2
objtool: Fix "noreturn" detection for recursive sibling calls objtool, x86: Add several functions and files to the objtool whitelist
Matthew Wilcox (2):
tools: add more bitmap functions
radix tree test suite: Remove types.h
Michael S. Tsirkin (1):
tools: enable endian checks for all sparse builds
arch/x86/crypto/Makefile | 2 +
arch/x86/crypto/sha1-mb/Makefile | 2 +
arch/x86/crypto/sha256-mb/Makefile | 2 +
arch/x86/include/asm/orc_types.h | 107 +
arch/x86/include/asm/unwind_hints.h | 103 +
arch/x86/kernel/Makefile | 1 +
arch/x86/kernel/acpi/Makefile | 2 +
arch/x86/kernel/kprobes/opt.c | 9 +-
arch/x86/kernel/reboot.c | 2 +
arch/x86/kernel/vmlinux.lds.S | 1 +
arch/x86/kvm/svm.c | 2 +
arch/x86/kvm/vmx.c | 3 +
arch/x86/lib/msr-reg.S | 8 +-
arch/x86/net/Makefile | 2 +
arch/x86/platform/efi/Makefile | 1 +
arch/x86/power/Makefile | 2 +
arch/x86/xen/Makefile | 3 +
arch/x86/xen/enlighten.c | 5 +-
include/linux/compiler-gcc.h | 13 +-
kernel/kexec_core.c | 4 +-
tools/arch/arm/include/uapi/asm/kvm.h | 13 +
tools/arch/arm64/include/uapi/asm/kvm.h | 6 +
tools/arch/powerpc/include/uapi/asm/kvm.h | 1 +
tools/arch/s390/include/uapi/asm/kvm.h | 5 +-
tools/arch/x86/include/asm/cpufeatures.h | 44 +-
.../arch/x86/include/asm/disabled-features.h | 7 +-
.../arch/x86/include/asm/required-features.h | 3 +-
tools/include/asm-generic/bitops.h | 1 +
tools/include/asm-generic/bitops/__ffz.h | 12 +
tools/include/asm-generic/bitops/find.h | 28 +
tools/include/linux/atomic.h | 6 +
tools/include/linux/bitmap.h | 26 +
tools/include/linux/bitops.h | 5 +
tools/include/linux/bug.h | 10 +
tools/include/linux/compiler-gcc.h | 21 +
tools/include/linux/compiler.h | 23 +-
tools/include/linux/hashtable.h | 4 -
tools/include/linux/kernel.h | 7 +
tools/include/linux/log2.h | 3 +
tools/include/linux/refcount.h | 151 ++
tools/include/linux/spinlock.h | 5 +
tools/include/linux/types.h | 5 +-
tools/include/uapi/asm-generic/mman-common.h | 5 +
tools/include/uapi/linux/bpf.h | 51 +
tools/include/uapi/linux/fcntl.h | 67 +
tools/include/uapi/linux/stat.h | 45 +
tools/lib/find_bit.c | 25 +
tools/objtool/Build | 4 +
.../Documentation/stack-validation.txt | 195 +-
tools/objtool/Makefile | 35 +-
tools/objtool/arch.h | 66 +-
tools/objtool/arch/x86/Build | 10 +-
tools/objtool/arch/x86/decode.c | 407 ++-
.../arch/x86/{insn => include/asm}/inat.h | 2 +-
.../x86/{insn => include/asm}/inat_types.h | 0
.../arch/x86/{insn => include/asm}/insn.h | 2 +-
.../objtool/arch/x86/include/asm/orc_types.h | 107 +
tools/objtool/arch/x86/{insn => lib}/inat.c | 2 +-
tools/objtool/arch/x86/{insn => lib}/insn.c | 4 +-
.../arch/x86/{insn => lib}/x86-opcode-map.txt | 0
.../x86/{insn => tools}/gen-insn-attr-x86.awk | 0
tools/objtool/builtin-check.c | 1297 +---------
tools/objtool/builtin-orc.c | 68 +
tools/objtool/builtin.h | 6 +
tools/objtool/cfi.h | 55 +
tools/objtool/check.c | 2209 +++++++++++++++++
tools/objtool/check.h | 82 +
tools/objtool/elf.c | 326 ++-
tools/objtool/elf.h | 23 +-
tools/objtool/objtool.c | 12 +-
tools/objtool/orc.h | 30 +
tools/objtool/orc_dump.c | 213 ++
tools/objtool/orc_gen.c | 221 ++
tools/objtool/special.c | 6 +-
tools/objtool/sync-check.sh | 29 +
tools/objtool/warn.h | 10 +
tools/perf/MANIFEST | 6 +
tools/perf/Makefile.perf | 144 +-
.../arch/x86/entry/syscalls/syscall_64.tbl | 7 +-
tools/perf/check-headers.sh | 61 +
tools/perf/util/util.h | 2 -
81 files changed, 4802 insertions(+), 1692 deletions(-)
create mode 100644 arch/x86/include/asm/orc_types.h
create mode 100644 arch/x86/include/asm/unwind_hints.h
create mode 100644 tools/include/asm-generic/bitops/__ffz.h
create mode 100644 tools/include/linux/bug.h
create mode 100644 tools/include/linux/compiler-gcc.h
create mode 100644 tools/include/linux/refcount.h
create mode 100644 tools/include/linux/spinlock.h
create mode 100644 tools/include/uapi/linux/fcntl.h
create mode 100644 tools/include/uapi/linux/stat.h
rename tools/objtool/arch/x86/{insn => include/asm}/inat.h (99%)
rename tools/objtool/arch/x86/{insn => include/asm}/inat_types.h (100%)
rename tools/objtool/arch/x86/{insn => include/asm}/insn.h (99%)
create mode 100644 tools/objtool/arch/x86/include/asm/orc_types.h
rename tools/objtool/arch/x86/{insn => lib}/inat.c (99%)
rename tools/objtool/arch/x86/{insn => lib}/insn.c (99%)
rename tools/objtool/arch/x86/{insn => lib}/x86-opcode-map.txt (100%)
rename tools/objtool/arch/x86/{insn => tools}/gen-insn-attr-x86.awk (100%)
create mode 100644 tools/objtool/builtin-orc.c
create mode 100644 tools/objtool/cfi.h
create mode 100644 tools/objtool/check.c
create mode 100644 tools/objtool/check.h
create mode 100644 tools/objtool/orc.h
create mode 100644 tools/objtool/orc_dump.c
create mode 100644 tools/objtool/orc_gen.c
create mode 100644 tools/objtool/sync-check.sh
create mode 100644 tools/perf/check-headers.shSignature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 1/29 objtool: Improve detection of BUG() and other dead ends
From: Josh Poimboeuf <[email protected]>
commit d1091c7fa3d52ebce4dd3f15d04155b3469b2f90 upstream.
The BUG() macro's use of __builtin_unreachable() via the unreachable() macro tells gcc that the instruction is a dead end, and that it's safe to assume the current code path will not execute past the previous instruction.
On x86, the BUG() macro is implemented with the 'ud2' instruction. When objtool's branch analysis sees that instruction, it knows the current code path has come to a dead end.
Peter Zijlstra has been working on a patch to change the WARN macros to use 'ud2'. That patch will break objtool's assumption that 'ud2' is always a dead end.
Generally it's best for objtool to avoid making those kinds of assumptions anyway. The more ignorant it is of kernel code internals, the better.
So create a more generic way for objtool to detect dead ends by adding an annotation to the unreachable() macro. The annotation stores a pointer to the end of the unreachable code path in an '__unreachable' section. Objtool can read that section to find the dead ends.
--- arch/x86/kernel/vmlinux.lds.S | 1 + include/linux/compiler-gcc.h | 13 ++++++- tools/objtool/arch.h | 5 ++- tools/objtool/arch/x86/decode.c | 3 -- tools/objtool/builtin-check.c | 60 ++++++++++++++++++++++++++++++--- 5 files changed, 71 insertions(+), 11 deletions(-)
arch/x86/kernel/vmlinux.lds.S +1 -0
@@ -353,6 +353,7 @@ SECTIONS /DISCARD/ : { *(.eh_frame) *(__func_stack_frame_non_standard) + *(__unreachable) } }
include/linux/compiler-gcc.h +12 -1
@@ -203,6 +203,17 @@#endif #endif +#ifdef CONFIG_STACK_VALIDATION +#define annotate_unreachable () ({ \ + asm("1:\t\n" \ + ".pushsection __unreachable, \"a\"\t\n" \ + ".long 1b\t\n" \ + ".popsection\t\n"); \ +}) +#else +#define annotate_unreachable () +#endif +/* * Mark a position in code as unreachable. This can be used to * suppress control flow warnings after asm blocks that transfer
@@ -212,7 +223,7 @@* this in the preprocessor, but we can live with this because they're * unreleased. Really, we need to have autoconf for the kernel. */ -#define unreachable () __builtin_unreachable() +#define unreachable () annotate_unreachable(); __builtin_unreachable()/* Mark a function definition as prohibited from being cloned. */ #define __noclone __attribute__((__noclone__, __optimize__("no-tracer")))
tools/objtool/arch.h +2 -3
@@ -31,9 +31,8 @@#define INSN_CALL_DYNAMIC 8#define INSN_RETURN 9#define INSN_CONTEXT_SWITCH 10 -#define INSN_BUG 11 -#define INSN_NOP 12 -#define INSN_OTHER 13 +#define INSN_NOP 11 +#define INSN_OTHER 12#define INSN_LAST INSN_OTHER int arch_decode_instruction(struct elf *elf, struct section *sec,
tools/objtool/arch/x86/decode.c +0 -3
@@ -118,9 +118,6 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, op2 == 0x35)/* sysenter, sysret */ *type =INSN_CONTEXT_SWITCH ; - else if (op2 == 0x0b || op2 == 0xb9) -/* ud2 */ - *type =INSN_BUG ; else if (op2 == 0x0d || op2 == 0x1f)/* nopl/nopw */ *type =INSN_NOP ;
tools/objtool/builtin-check.c +56 -4
88 lines not on this page · raw message
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 2/29 objtool: Move checking code to check.c
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit dcc914f44f065ef73685b37e59877a5bb3cb7358 upstream.
In preparation for the new 'objtool undwarf generate' command, which will rely on 'objtool check', move the checking code from builtin-check.c to check.c where it can be used by other commands.
--- tools/objtool/Build | 1 + tools/objtool/builtin-check.c | 1346 +-------------------------------- tools/objtool/check.c | 1327 ++++++++++++++++++++++++++++++++ tools/objtool/check.h | 51 ++ 4 files changed, 1392 insertions(+), 1333 deletions(-) create mode 100644 tools/objtool/check.c create mode 100644 tools/objtool/check.h
tools/objtool/Build +1 -0
@@ -1,5 +1,6 @@ objtool-y += arch/$(SRCARCH)/ objtool-y += builtin-check.o +objtool-y += check.o objtool-y += elf.o objtool-y += special.o objtool-y += objtool.o
tools/objtool/builtin-check.c +13 -1333
1,370 lines not on this page · raw message
tools/objtool/check.c new file +1327 -0
1,327 lines not on this page · raw message
tools/objtool/check.h new file +51 -0
51 lines not on this page · raw message
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 3/29 tools lib: Add for_each_clear_bit macro
In reply to Greg Kroah-HartmanFrom: Jiri Olsa <[email protected]>
commit 02bc11de567273da8ab25c54336ddbb71986f38f upstream.
Adding for_each_clear_bit macro plus all its the necessary backbone functions. Taken from related kernel code. It will be used in following patch.
--- tools/include/asm-generic/bitops.h | 1 + tools/include/asm-generic/bitops/__ffz.h | 12 ++++++++++ tools/include/asm-generic/bitops/find.h | 28 ++++++++++++++++++++++++ tools/include/linux/bitops.h | 5 +++++ tools/lib/find_bit.c | 25 +++++++++++++++++++++ tools/perf/MANIFEST | 1 + 6 files changed, 72 insertions(+) create mode 100644 tools/include/asm-generic/bitops/__ffz.h
tools/include/asm-generic/bitops.h +1 -0
@@ -13,6 +13,7 @@*/ #include <asm-generic/bitops/__ffs.h> +#include <asm-generic/bitops/__ffz.h> #include <asm-generic/bitops/fls.h> #include <asm-generic/bitops/__fls.h> #include <asm-generic/bitops/fls64.h>
tools/include/asm-generic/bitops/__ffz.h new file +12 -0
@@ -0,0 +1,12 @@ +#ifndef _ASM_GENERIC_BITOPS_FFZ_H_ +#define _ASM_GENERIC_BITOPS_FFZ_H_ + +/* +* ffz - find first zero in word. +* @word: The word to search +* +* Undefined if no zero exists, so code should check against ~0UL first. +*/ +#define ffz (x) __ffs(~(x)) + +#endif /* _ASM_GENERIC_BITOPS_FFZ_H_ */
tools/include/asm-generic/bitops/find.h +28 -0
@@ -15,6 +15,21 @@ extern unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset);#endif +#ifndef find_next_zero_bit + +/** +* find_next_zero_bit - find the next cleared bit in a memory region +* @addr: The address to base the search on +* @offset: The bitnumber to start searching at +* @size: The bitmap size in bits +* +* Returns the bit number of the next zero bit +* If no bits are zero, returns @size. +*/ +unsigned long find_next_zero_bit (const unsigned long *addr,unsigned long size, +unsigned long offset); +#endif +#ifndef find_first_bit/**
@@ -30,4 +45,17 @@ extern unsigned long find_first_bit(const unsigned long *addr,#endif /* find_first_bit */ +#ifndef find_first_zero_bit + +/** +* find_first_zero_bit - find the first cleared bit in a memory region +* @addr: The address to start the search at +* @size: The maximum number of bits to search +* +* Returns the bit number of the first cleared bit. +* If no bits are zero, returns @size. +*/ +unsigned long find_first_zero_bit (const unsigned long *addr,unsigned long size); +#endif +#endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */
tools/include/linux/bitops.h +5 -0
@@ -39,6 +39,11 @@ extern unsigned long __sw_hweight64(__u64 w); (bit) < (size); \ (bit) = find_next_bit((addr), (size), (bit) + 1)) +#define for_each_clear_bit (bit, addr, size) \ + for ((bit) = find_first_zero_bit((addr), (size)); \ + (bit) < (size); \ + (bit) = find_next_zero_bit((addr), (size), (bit) + 1)) +/* same as for_each_set_bit() but use bit as value to start with */ #define for_each_set_bit_from (bit, addr, size) \ for ((bit) = find_next_bit((addr), (size), (bit)); \
tools/lib/find_bit.c +25 -0
@@ -82,3 +82,28 @@ unsigned long find_first_bit(const unsigned long *addr, unsigned long size) return size; }#endif + +#ifndef find_first_zero_bit +/* +* Find the first cleared bit in a memory region. +*/ +unsigned long find_first_zero_bit (const unsigned long *addr,unsigned long size) +{ +unsigned long idx; + +for (idx =0 ; idx *BITS_PER_LONG < size; idx++) { +if (addr[idx] != ~0UL ) +return min (idx *BITS_PER_LONG +ffz (addr[idx]), size); + } + +return size; +} +#endif + +#ifndef find_next_zero_bit +unsigned long find_next_zero_bit (const unsigned long *addr,unsigned long size, +unsigned long offset) +{ +return _find_next_bit (addr, size, offset, ~0UL ); +} +#endif
tools/perf/MANIFEST +1 -0
@@ -51,6 +51,7 @@ tools/include/asm-generic/bitops/arch_hweight.h tools/include/asm-generic/bitops/atomic.h tools/include/asm-generic/bitops/const_hweight.h tools/include/asm-generic/bitops/__ffs.h +tools/include/asm-generic/bitops/__ffz.h tools/include/asm-generic/bitops/__fls.h tools/include/asm-generic/bitops/find.h tools/include/asm-generic/bitops/fls64.h
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 4/29 tools: add more bitmap functions
In reply to Greg Kroah-HartmanFrom: Matthew Wilcox <[email protected]>
commit b328daf3b7130098b105c18bdae694ddaad5b6e3 upstream.
I need the following functions for the radix tree:
bitmap_fill
bitmap_empty
bitmap_full
Copy the implementations from include/linux/bitmap.h
--- tools/include/linux/bitmap.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
tools/include/linux/bitmap.h +26 -0
@@ -35,6 +35,32 @@ static inline void bitmap_zero(unsigned long *dst, int nbits) } } +static inline void bitmap_fill (unsigned long *dst,unsigned int nbits) +{ +unsigned int nlongs =BITS_TO_LONGS (nbits); +if (!small_const_nbits (nbits)) { +unsigned int len = (nlongs -1 ) *sizeof (unsigned long ); +memset (dst,0xff , len); + } + dst[nlongs -1 ] =BITMAP_LAST_WORD_MASK (nbits); +} + +static inline int bitmap_empty (const unsigned long *src,unsigned nbits) +{ +if (small_const_nbits (nbits)) +return ! (*src &BITMAP_LAST_WORD_MASK (nbits)); + +return find_first_bit (src, nbits) == nbits; +} + +static inline int bitmap_full (const unsigned long *src,unsigned int nbits) +{ +if (small_const_nbits (nbits)) +return ! (~(*src) &BITMAP_LAST_WORD_MASK (nbits)); + +return find_first_zero_bit (src, nbits) == nbits; +} +static inline int bitmap_weight (const unsigned long *src,int nbits) {if (small_const_nbits (nbits))
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 5/29 tools: enable endian checks for all sparse builds
In reply to Greg Kroah-HartmanFrom: "Michael S. Tsirkin" <[email protected]>
commit 376a5fb34b04524af501a0c5979c5920be940e05 upstream.
We dropped need for __CHECK_ENDIAN__ for linux,
this mirrors this for tools.
--- tools/include/linux/types.h | 4 ---- 1 file changed, 4 deletions(-)
tools/include/linux/types.h +0 -4
@@ -42,11 +42,7 @@ typedef __s8 s8;#else #define __bitwise__#endif -#ifdef __CHECK_ENDIAN__#define __bitwise __bitwise__ -#else -#define __bitwise -#endif #define __force#define __user
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 6/29 tools include: Introduce linux/compiler-gcc.h
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
commit 192614010a5052fe92611c7076ef664fd9bb60e8 upstream.
To match the kernel headers structure, setting up things that are specific to gcc or to some specific version of gcc.
It gets included by linux/compiler.h when gcc is the compiler being used.
--- tools/include/linux/compiler-gcc.h | 14 ++++++++++++++ tools/include/linux/compiler.h | 10 +++++----- tools/perf/MANIFEST | 1 + 3 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 tools/include/linux/compiler-gcc.h
tools/include/linux/compiler-gcc.h new file +14 -0
@@ -0,0 +1,14 @@ +#ifndef _TOOLS_LINUX_COMPILER_H_ +#error "Please don't include <linux/compiler-gcc.h> directly, include <linux/compiler.h> instead." +#endif + +/* +* Common definitions for all gcc versions go here. +*/ +#define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +#if GCC_VERSION >=70000 && !defined(__CHECKER__) +# define __fallthrough __attribute__ ((fallthrough)) +#endif
tools/include/linux/compiler.h +5 -5
@@ -1,6 +1,10 @@#ifndef _TOOLS_LINUX_COMPILER_H_#define _TOOLS_LINUX_COMPILER_H_ +#ifdef __GNUC__ +#include <linux/compiler-gcc.h> +#endif +/* Optimization barrier */ /* The "volatile" is due to gcc bugs */ #define barrier () __asm__ __volatile__("": : :"memory")
@@ -128,11 +132,7 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s#ifndef __fallthrough -# if defined(__GNUC__) && __GNUC__ >=7 -# define __fallthrough __attribute__ ((fallthrough)) -# else -# define __fallthrough -# endif +# define __fallthrough#endif #endif /* _TOOLS_LINUX_COMPILER_H */
tools/perf/MANIFEST +1 -0
@@ -61,6 +61,7 @@ tools/include/asm-generic/bitops.h tools/include/linux/atomic.h tools/include/linux/bitops.h tools/include/linux/compiler.h +tools/include/linux/compiler-gcc.h tools/include/linux/coresight-pmu.h tools/include/linux/filter.h tools/include/linux/hash.h
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 7/29 radix tree test suite: Remove types.h
In reply to Greg Kroah-HartmanFrom: Matthew Wilcox <[email protected]>
commit 12ea65390bd5a46f8a70f068eb0d48922576a781 upstream.
Move the pieces we still need to tools/include and update a few implicit includes.
--- tools/include/linux/compiler.h | 4 ++++ tools/include/linux/spinlock.h | 5 +++++ 2 files changed, 9 insertions(+) create mode 100644 tools/include/linux/spinlock.h
tools/include/linux/compiler.h +4 -0
@@ -25,6 +25,8 @@#endif #define __user +#define __rcu +#define __read_mostly#ifndef __attribute_const__# define __attribute_const__
@@ -54,6 +56,8 @@# define unlikely (x) __builtin_expect(!!(x), 0)#endif +#define uninitialized_var (x) x = *(&(x)) +#define ACCESS_ONCE (x) (*(volatile typeof(x) *)&(x))#include <linux/types.h>
tools/include/linux/spinlock.h new file +5 -0
@@ -0,0 +1,5 @@ +#define spinlock_t pthread_mutex_t +#define DEFINE_SPINLOCK (x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER; + +#define spin_lock_irqsave (x, f) (void)f, pthread_mutex_lock(x) +#define spin_unlock_irqrestore (x, f) (void)f, pthread_mutex_unlock(x)
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 8/29 tools include: Adopt __compiletime_error
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
commit 4900653829175f60356efc279695bb23c59483c3 upstream.
Quoted 1 line
From the kernel, get the gcc one and provide the fallback so that we can
continue build with other compilers, such as with clang.
Will be used by tools/arch/x86/include/asm/cmpxchg.h.
--- tools/include/linux/compiler-gcc.h | 4 ++++ tools/include/linux/compiler.h | 4 ++++ 2 files changed, 8 insertions(+)
tools/include/linux/compiler-gcc.h +4 -0
@@ -12,3 +12,7 @@#if GCC_VERSION >=70000 && !defined(__CHECKER__)# define __fallthrough __attribute__ ((fallthrough))#endif + +#if GCC_VERSION >=40300 +# define __compiletime_error (message) __attribute__((error(message))) +#endif /* GCC_VERSION >= 40300 */
tools/include/linux/compiler.h +4 -0
@@ -5,6 +5,10 @@#include <linux/compiler-gcc.h> #endif +#ifndef __compiletime_error +# define __compiletime_error (message) +#endif +/* Optimization barrier */ /* The "volatile" is due to gcc bugs */ #define barrier () __asm__ __volatile__("": : :"memory")
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 9/29 tools include: Introduce atomic_cmpxchg_{relaxed,release}()
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
commit 2bcdeadbc094b4f6511aedea1e5b8052bf0cc89c upstream.
Will be used by refcnt.h
--- tools/include/linux/atomic.h | 6 ++++++ 1 file changed, 6 insertions(+)
tools/include/linux/atomic.h +6 -0
@@ -3,4 +3,10 @@#include <asm/atomic.h> +/* atomic_cmpxchg_relaxed */ +#ifndef atomic_cmpxchg_relaxed +#define atomic_cmpxchg_relaxed atomic_cmpxchg +#define atomic_cmpxchg_release atomic_cmpxchg +#endif /* atomic_cmpxchg_relaxed */ +#endif /* __TOOLS_LINUX_ATOMIC_H */
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 10/29 tools include: Add UINT_MAX def to kernel.h
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
commit eaa75b5117d52adf1efd3c6c3fb4bd8f97de648b upstream.
The kernel has it and some files we got from there would require us including the userland header for that, so add it conditionally.
--- tools/include/linux/kernel.h | 4 ++++ 1 file changed, 4 insertions(+)
tools/include/linux/kernel.h +4 -0
@@ -5,6 +5,10 @@#include <stddef.h> #include <assert.h> +#ifndef UINT_MAX +#define UINT_MAX (~0U) +#endif +#define DIV_ROUND_UP (n,d) (((n) + (d) - 1) / (d))#define PERF_ALIGN (x, a) __PERF_ALIGN_MASK(x, (typeof(x))(a)-1)
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 11/29 tools include: Adopt kernel's refcount.h
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
commit 73a9bf95ed1c05698ecabe2f28c47aedfa61b52b upstream.
To aid in catching bugs when using atomics as a reference count.
This is a trimmed down version with just what is used by tools/ at this point.
After this, the patches submitted by Elena for tools/ doing the conversion from atomic_ to recount_ methods can be applied and tested.
To activate it, buint perf with:
make DEBUG=1 -C tools/perf
--- tools/include/linux/refcount.h | 151 +++++++++++++++++++++++++++++++++ tools/perf/MANIFEST | 1 + 2 files changed, 152 insertions(+) create mode 100644 tools/include/linux/refcount.h
tools/include/linux/refcount.h new file +151 -0
@@ -0,0 +1,151 @@ +#ifndef _TOOLS_LINUX_REFCOUNT_H +#define _TOOLS_LINUX_REFCOUNT_H + +/* +* Variant of atomic_t specialized for reference counts. +* +* The interface matches the atomic_t interface (to aid in porting) but only +* provides the few functions one should use for reference counting. +* +* It differs in that the counter saturates at UINT_MAX and will not move once +* there. This avoids wrapping the counter and causing 'spurious' +* use-after-free issues. +* +* Memory ordering rules are slightly relaxed wrt regular atomic_t functions +* and provide only what is strictly required for refcounts. +* +* The increments are fully relaxed; these will not provide ordering. The +* rationale is that whatever is used to obtain the object we're increasing the +* reference count on will provide the ordering. For locked data structures, +* its the lock acquire, for RCU/lockless data structures its the dependent +* load. +* +* Do note that inc_not_zero() provides a control dependency which will order +* future stores against the inc, this ensures we'll never modify the object +* if we did not in fact acquire a reference. +* +* The decrements will provide release order, such that all the prior loads and +* stores will be issued before, it also provides a control dependency, which +* will order us against the subsequent free(). +* +* The control dependency is against the load of the cmpxchg (ll/sc) that +* succeeded. This means the stores aren't fully ordered, but this is fine +* because the 1->0 transition indicates no concurrency. +* +* Note that the allocator is responsible for ordering things between free() +* and alloc(). +* +*/ + +#include <linux/atomic.h> +#include <linux/kernel.h> + +#ifdef NDEBUG +#define REFCOUNT_WARN (cond, str) (void)(cond) +#define __refcount_check +#else +#define REFCOUNT_WARN (cond, str) BUG_ON(cond) +#define __refcount_check __must_check +#endif + +typedef struct refcount_struct { +atomic_t refs; +}refcount_t ; + +#define REFCOUNT_INIT (n) { .refs = ATOMIC_INIT(n), } + +static inline void refcount_set (refcount_t *r,unsigned int n) +{ +atomic_set (&r->refs, n); +} + +static inline unsigned int refcount_read (const refcount_t *r) +{ +return atomic_read (&r->refs); +} + +/* +* Similar to atomic_inc_not_zero(), will saturate at UINT_MAX and WARN. +* +* Provides no memory ordering, it is assumed the caller has guaranteed the +* object memory to be stable (RCU, etc.). It does provide a control dependency +* and thereby orders future stores. See the comment on top. +*/ +static inline __refcount_check +bool refcount_inc_not_zero(refcount_t *r) +{ +unsigned int old, new, val =atomic_read (&r->refs); + +for (;;) { + new = val +1 ; + +if (!val) +return false; + +if (unlikely (!new)) +return true; + + old =atomic_cmpxchg_relaxed (&r->refs, val, new); +if (old == val) +break ; + + val = old; + } + +REFCOUNT_WARN (new ==UINT_MAX ,"refcount_t: saturated; leaking memory.\n" ); + +return true; +} + +/* +* Similar to atomic_inc(), will saturate at UINT_MAX and WARN. +* +* Provides no memory ordering, it is assumed the caller already has a +* reference on the object, will WARN when this is not so. +*/ +static inline void refcount_inc (refcount_t *r) +{ +REFCOUNT_WARN (!refcount_inc_not_zero (r),"refcount_t: increment on 0; use-after-free.\n" ); +} + +/* +* Similar to atomic_dec_and_test(), it will WARN on underflow and fail to +* decrement when saturated at UINT_MAX. +* +* Provides release memory ordering, such that prior loads and stores are done +* before, and provides a control dependency such that free() must come after. +* See the comment on top. +*/ +static inline __refcount_check +bool refcount_sub_and_test(unsigned int i, refcount_t *r) +{ +unsigned int old, new, val =atomic_read (&r->refs); + +for (;;) { +if (unlikely (val ==UINT_MAX )) +return false; + + new = val - i; +if (new > val) { +REFCOUNT_WARN (new > val,"refcount_t: underflow; use-after-free.\n" ); +return false; + } + + old =atomic_cmpxchg_release (&r->refs, val, new); +if (old == val) +break ; + + val = old; + } + +return !new; +} + +static inline __refcount_check +bool refcount_dec_and_test(refcount_t *r) +{ +return refcount_sub_and_test (1 , r); +} + + +#endif /* _ATOMIC_LINUX_REFCOUNT_H */
tools/perf/MANIFEST +1 -0
@@ -78,6 +78,7 @@ tools/include/uapi/linux/perf_event.h tools/include/linux/poison.h tools/include/linux/rbtree.h tools/include/linux/rbtree_augmented.h +tools/include/linux/refcount.h tools/include/linux/string.h tools/include/linux/stringify.h tools/include/linux/types.h
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 12/29 perf tools: Force fixdep compilation at the start of the build
In reply to Greg Kroah-HartmanFrom: Jiri Olsa <[email protected]>
commit abb26210a39522a6645bce3f438ed9a26bedb11b upstream.
The fixdep tool needs to be built before everything else, because it fixes every object dependency file.
We handle this currently by making all objects to depend on fixdep, which is error prone and is easily forgotten when new object is added.
Instead of this, this patch force fixdep tool to be built as the first target in the separate make session. This way we don't need to handle extra fixdep dependencies and we are certain there's no fixdep race with any parallel make job.
Committer notes:
Testing it:
Before:
$ rm -rf /tmp/build/perf/ ; mkdir -p /tmp/build/perf ; make -k O=/tmp/build/perf -C tools/perf install-bin
make: Entering directory '/home/acme/git/linux/tools/perf'
BUILD: Doing 'make -j4' parallel buildAuto-detecting system features:
... dwarf: [ on ] ... dwarf_getlocations: [ on ] ... glibc: [ on ] ... gtk2: [ on ] ... libaudit: [ on ] ... libbfd: [ on ] ... libelf: [ on ] ... libnuma: [ on ] ... numa_num_possible_cpus: [ on ] ... libperl: [ on ] ... libpython: [ on ] ... libslang: [ on ] ... libcrypto: [ on ] ... libunwind: [ on ] ... libdw-dwarf-unwind: [ on ] ... zlib: [ on ] ... lzma: [ on ] ... get_cpuid: [ on ] ... bpf: [ on ]
GEN /tmp/build/perf/common-cmds.h
HOSTCC /tmp/build/perf/fixdep.o
HOSTLD /tmp/build/perf/fixdep-in.o
LINK /tmp/build/perf/fixdep
MKDIR /tmp/build/perf/pmu-events/
HOSTCC /tmp/build/perf/pmu-events/json.o
MKDIR /tmp/build/perf/pmu-events/
HOSTCC /tmp/build/perf/pmu-events/jsmn.o
HOSTCC /tmp/build/perf/pmu-events/jevents.o
HOSTLD /tmp/build/perf/pmu-events/jevents-in.o
PERF_VERSION = 4.9.rc8.g868cd5
CC /tmp/build/perf/perf-read-vdso32<SNIP>
After:
$ rm -rf /tmp/build/perf/ ; mkdir -p /tmp/build/perf ; make -k O=/tmp/build/perf -C tools/perf install-bin
make: Entering directory '/home/acme/git/linux/tools/perf'
BUILD: Doing 'make -j4' parallel build
HOSTCC /tmp/build/perf/fixdep.o
HOSTLD /tmp/build/perf/fixdep-in.o
LINK /tmp/build/perf/fixdepAuto-detecting system features:
... dwarf: [ on ] ... dwarf_getlocations: [ on ] ... glibc: [ on ] ... gtk2: [ on ] ... libaudit: [ on ] ... libbfd: [ on ] ... libelf: [ on ] ... libnuma: [ on ] ... numa_num_possible_cpus: [ on ] ... libperl: [ on ] ... libpython: [ on ] ... libslang: [ on ] ... libcrypto: [ on ] ... libunwind: [ on ] ... libdw-dwarf-unwind: [ on ] ... zlib: [ on ] ... lzma: [ on ] ... get_cpuid: [ on ] ... bpf: [ on ]
GEN /tmp/build/perf/common-cmds.h
MKDIR /tmp/build/perf/fd/
CC /tmp/build/perf/fd/array.o
LD /tmp/build/perf/fd/libapi-in.o
MKDIR /tmp/build/perf/fs/
CC /tmp/build/perf/event-parse.o
CC /tmp/build/perf/fs/fs.o
PERF_VERSION = 4.9.rc8.g57a92f
CC /tmp/build/perf/event-plugin.o
MKDIR /tmp/build/perf/fs/
CC /tmp/build/perf/fs/tracing_path.o<SNIP>
--- tools/perf/Makefile.perf | 50 ++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 12 deletions(-)
tools/perf/Makefile.perf +38 -12
@@ -177,6 +177,35 @@ ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),) endif endif +# The fixdep build - we force fixdep tool to be built as +# the first target in the separate make session not to be +# disturbed by any parallel make jobs. Once fixdep is done +# we issue the requested build with FIXDEP=1 variable. +# +# The fixdep build is disabled for $(NON_CONFIG_TARGETS) +# targets, because it's not necessary. + +ifdef FIXDEP + force_fixdep := 0 +else + force_fixdep := $(config) +endif + +export srctree OUTPUT RM CC CXX LD AR CFLAGS CXXFLAGS V BISON FLEX AWK +export HOSTCC HOSTLD HOSTAR + +include $(srctree)/tools/build/Makefile.include + +ifeq ($(force_fixdep),1) +goals := $(filter-out all sub-make, $(MAKECMDGOALS)) + +$(goals) all: sub-make + +sub-make: fixdep + $(Q)$(MAKE) FIXDEP=1 -f Makefile.perf $(goals) + +else # force_fixdep + # Set FEATURE_TESTS to 'all' so all possible feature checkers are executed. # Without this setting the output feature dump file misses some features, for # example, liberty. Select all checkers so we won't get an incomplete feature
@@ -348,10 +377,6 @@ strip: $(PROGRAMS) $(OUTPUT)perf PERF_IN := $(OUTPUT)perf-in.o -export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX AWK -export HOSTCC HOSTLD HOSTAR -include $(srctree)/tools/build/Makefile.include - JEVENTS := $(OUTPUT)pmu-events/jevents JEVENTS_IN := $(OUTPUT)pmu-events/jevents-in.o
@@ -470,7 +495,7 @@ $(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(PMU_EVENTS_IN) $(LIBTRACEEVENT_DYNAMIC_L $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS) \ $(PERF_IN) $(PMU_EVENTS_IN) $(LIBS) -o $@ -$(GTK_IN): fixdep FORCE +$(GTK_IN): FORCE $(Q)$(MAKE) $(build)=gtk $(OUTPUT)libperf-gtk.so: $(GTK_IN) $(PERFLIBS)
@@ -515,7 +540,7 @@ endif __build-dir = $(subst $(OUTPUT),,$(dir $@)) build-dir = $(if $(__build-dir),$(__build-dir),.) -prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h fixdep archheaders +prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(OUTPUT)%.o: %.c prepare FORCE $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
@@ -555,7 +580,7 @@ $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h) LIBPERF_IN := $(OUTPUT)libperf-in.o -$(LIBPERF_IN): prepare fixdep FORCE +$(LIBPERF_IN): prepare FORCE $(Q)$(MAKE) $(build)=libperf $(LIB_FILE): $(LIBPERF_IN)
@@ -563,10 +588,10 @@ $(LIB_FILE): $(LIBPERF_IN) LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ) -$(LIBTRACEEVENT): fixdep FORCE +$(LIBTRACEEVENT): FORCE $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent.a -libtraceevent_plugins: fixdep FORCE +libtraceevent_plugins: FORCE $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) plugins $(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins
@@ -579,21 +604,21 @@ $(LIBTRACEEVENT)-clean: install-traceevent-plugins: libtraceevent_plugins $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) install_plugins -$(LIBAPI): fixdep FORCE +$(LIBAPI): FORCE $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapi.a $(LIBAPI)-clean: $(call QUIET_CLEAN, libapi) $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null -$(LIBBPF): fixdep FORCE +$(LIBBPF): FORCE $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) $(OUTPUT)libbpf.a FEATURES_DUMP=$(FEATURE_DUMP_EXPORT) $(LIBBPF)-clean: $(call QUIET_CLEAN, libbpf) $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) clean >/dev/null -$(LIBSUBCMD): fixdep FORCE +$(LIBSUBCMD): FORCE $(Q)$(MAKE) -C $(SUBCMD_DIR) O=$(OUTPUT) $(OUTPUT)libsubcmd.a $(LIBSUBCMD)-clean:
@@ -790,3 +815,4 @@ FORCE: .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare .PHONY: libtraceevent_plugins archheaders +endif # force_fixdep
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 13/29 perf tools: Move headers check into bash script
In reply to Greg Kroah-HartmanFrom: Jiri Olsa <[email protected]>
commit aeafd623f866c429307e3a4a39998f5f06b4f00e upstream.
To make it nicer and easily maintainable.
Also moving the check into fixdep sub make, so its output is not scattered around the build output.
Removing extra $$ from mman*.h checks.
--- tools/perf/Makefile.perf | 94 +------------------------------------ tools/perf/check-headers.sh | 59 +++++++++++++++++++++++ 2 files changed, 60 insertions(+), 93 deletions(-) create mode 100644 tools/perf/check-headers.sh
tools/perf/Makefile.perf +1 -93
@@ -202,6 +202,7 @@ goals := $(filter-out all sub-make, $(MAKECMDGOALS)) $(goals) all: sub-make sub-make: fixdep + @./check-headers.sh $(Q)$(MAKE) FIXDEP=1 -f Makefile.perf $(goals) else # force_fixdep
@@ -387,99 +388,6 @@ export JEVENTS build := -f $(srctree)/tools/build/Makefile.build dir=. obj $(PERF_IN): prepare FORCE - @(test -f ../../include/uapi/linux/perf_event.h && ( \ - (diff -B ../include/uapi/linux/perf_event.h ../../include/uapi/linux/perf_event.h >/dev/null) \ - || echo "Warning: tools/include/uapi/linux/perf_event.h differs from kernel" >&2 )) || true - @(test -f ../../include/linux/hash.h && ( \ - (diff -B ../include/linux/hash.h ../../include/linux/hash.h >/dev/null) \ - || echo "Warning: tools/include/linux/hash.h differs from kernel" >&2 )) || true - @(test -f ../../include/uapi/linux/hw_breakpoint.h && ( \ - (diff -B ../include/uapi/linux/hw_breakpoint.h ../../include/uapi/linux/hw_breakpoint.h >/dev/null) \ - || echo "Warning: tools/include/uapi/linux/hw_breakpoint.h differs from kernel" >&2 )) || true - @(test -f ../../arch/x86/include/asm/disabled-features.h && ( \ - (diff -B ../arch/x86/include/asm/disabled-features.h ../../arch/x86/include/asm/disabled-features.h >/dev/null) \ - || echo "Warning: tools/arch/x86/include/asm/disabled-features.h differs from kernel" >&2 )) || true - @(test -f ../../arch/x86/include/asm/required-features.h && ( \ - (diff -B ../arch/x86/include/asm/required-features.h ../../arch/x86/include/asm/required-features.h >/dev/null) \ - || echo "Warning: tools/arch/x86/include/asm/required-features.h differs from kernel" >&2 )) || true - @(test -f ../../arch/x86/include/asm/cpufeatures.h && ( \ - (diff -B ../arch/x86/include/asm/cpufeatures.h ../../arch/x86/include/asm/cpufeatures.h >/dev/null) \ - || echo "Warning: tools/arch/x86/include/asm/cpufeatures.h differs from kernel" >&2 )) || true - @(test -f ../../arch/x86/lib/memcpy_64.S && ( \ - (diff -B ../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memcpy_64.S >/dev/null) \ - || echo "Warning: tools/arch/x86/lib/memcpy_64.S differs from kernel" >&2 )) || true - @(test -f ../../arch/x86/lib/memset_64.S && ( \ - (diff -B ../arch/x86/lib/memset_64.S ../../arch/x86/lib/memset_64.S >/dev/null) \ - || echo "Warning: tools/arch/x86/lib/memset_64.S differs from kernel" >&2 )) || true - @(test -f ../../arch/arm/include/uapi/asm/perf_regs.h && ( \ - (diff -B ../arch/arm/include/uapi/asm/perf_regs.h ../../arch/arm/include/uapi/asm/perf_regs.h >/dev/null) \ - || echo "Warning: tools/arch/arm/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true - @(test -f ../../arch/arm64/include/uapi/asm/perf_regs.h && ( \ - (diff -B ../arch/arm64/include/uapi/asm/perf_regs.h ../../arch/arm64/include/uapi/asm/perf_regs.h >/dev/null) \ - || echo "Warning: tools/arch/arm64/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true - @(test -f ../../arch/powerpc/include/uapi/asm/perf_regs.h && ( \ - (diff -B ../arch/powerpc/include/uapi/asm/perf_regs.h ../../arch/powerpc/include/uapi/asm/perf_regs.h >/dev/null) \ - || echo "Warning: tools/arch/powerpc/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true - @(test -f ../../arch/x86/include/uapi/asm/perf_regs.h && ( \ - (diff -B ../arch/x86/include/uapi/asm/perf_regs.h ../../arch/x86/include/uapi/asm/perf_regs.h >/dev/null) \ - || echo "Warning: tools/arch/x86/include/uapi/asm/perf_regs.h differs from kernel" >&2 )) || true - @(test -f ../../arch/x86/include/uapi/asm/kvm.h && ( \ - (diff -B ../arch/x86/include/uapi/asm/kvm.h ../../arch/x86/include/uapi/asm/kvm.h >/dev/null) \ - || echo "Warning: tools/arch/x86/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true - @(test -f ../../arch/x86/include/uapi/asm/kvm_perf.h && ( \ - (diff -B ../arch/x86/include/uapi/asm/kvm_perf.h ../../arch/x86/include/uapi/asm/kvm_perf.h >/dev/null) \ - || echo "Warning: tools/arch/x86/include/uapi/asm/kvm_perf.h differs from kernel" >&2 )) || true - @(test -f ../../arch/x86/include/uapi/asm/svm.h && ( \ - (diff -B ../arch/x86/include/uapi/asm/svm.h ../../arch/x86/include/uapi/asm/svm.h >/dev/null) \ - || echo "Warning: tools/arch/x86/include/uapi/asm/svm.h differs from kernel" >&2 )) || true - @(test -f ../../arch/x86/include/uapi/asm/vmx.h && ( \ - (diff -B ../arch/x86/include/uapi/asm/vmx.h ../../arch/x86/include/uapi/asm/vmx.h >/dev/null) \ - || echo "Warning: tools/arch/x86/include/uapi/asm/vmx.h differs from kernel" >&2 )) || true - @(test -f ../../arch/powerpc/include/uapi/asm/kvm.h && ( \ - (diff -B ../arch/powerpc/include/uapi/asm/kvm.h ../../arch/powerpc/include/uapi/asm/kvm.h >/dev/null) \ - || echo "Warning: tools/arch/powerpc/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true - @(test -f ../../arch/s390/include/uapi/asm/kvm.h && ( \ - (diff -B ../arch/s390/include/uapi/asm/kvm.h ../../arch/s390/include/uapi/asm/kvm.h >/dev/null) \ - || echo "Warning: tools/arch/s390/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true - @(test -f ../../arch/s390/include/uapi/asm/kvm_perf.h && ( \ - (diff -B ../arch/s390/include/uapi/asm/kvm_perf.h ../../arch/s390/include/uapi/asm/kvm_perf.h >/dev/null) \ - || echo "Warning: tools/arch/s390/include/uapi/asm/kvm_perf.h differs from kernel" >&2 )) || true - @(test -f ../../arch/s390/include/uapi/asm/sie.h && ( \ - (diff -B ../arch/s390/include/uapi/asm/sie.h ../../arch/s390/include/uapi/asm/sie.h >/dev/null) \ - || echo "Warning: tools/arch/s390/include/uapi/asm/sie.h differs from kernel" >&2 )) || true - @(test -f ../../arch/arm/include/uapi/asm/kvm.h && ( \ - (diff -B ../arch/arm/include/uapi/asm/kvm.h ../../arch/arm/include/uapi/asm/kvm.h >/dev/null) \ - || echo "Warning: tools/arch/arm/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true - @(test -f ../../arch/arm64/include/uapi/asm/kvm.h && ( \ - (diff -B ../arch/arm64/include/uapi/asm/kvm.h ../../arch/arm64/include/uapi/asm/kvm.h >/dev/null) \ - || echo "Warning: tools/arch/arm64/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true - @(test -f ../../include/asm-generic/bitops/arch_hweight.h && ( \ - (diff -B ../include/asm-generic/bitops/arch_hweight.h ../../include/asm-generic/bitops/arch_hweight.h >/dev/null) \ - || echo "Warning: tools/include/asm-generic/bitops/arch_hweight.h differs from kernel" >&2 )) || true - @(test -f ../../include/asm-generic/bitops/const_hweight.h && ( \ - (diff -B ../include/asm-generic/bitops/const_hweight.h ../../include/asm-generic/bitops/const_hweight.h >/dev/null) \ - || echo "Warning: tools/include/asm-generic/bitops/const_hweight.h differs from kernel" >&2 )) || true - @(test -f ../../include/asm-generic/bitops/__fls.h && ( \ - (diff -B ../include/asm-generic/bitops/__fls.h ../../include/asm-generic/bitops/__fls.h >/dev/null) \ - || echo "Warning: tools/include/asm-generic/bitops/__fls.h differs from kernel" >&2 )) || true - @(test -f ../../include/asm-generic/bitops/fls.h && ( \ - (diff -B ../include/asm-generic/bitops/fls.h ../../include/asm-generic/bitops/fls.h >/dev/null) \ - || echo "Warning: tools/include/asm-generic/bitops/fls.h differs from kernel" >&2 )) || true - @(test -f ../../include/asm-generic/bitops/fls64.h && ( \ - (diff -B ../include/asm-generic/bitops/fls64.h ../../include/asm-generic/bitops/fls64.h >/dev/null) \ - || echo "Warning: tools/include/asm-generic/bitops/fls64.h differs from kernel" >&2 )) || true - @(test -f ../../include/linux/coresight-pmu.h && ( \ - (diff -B ../include/linux/coresight-pmu.h ../../include/linux/coresight-pmu.h >/dev/null) \ - || echo "Warning: tools/include/linux/coresight-pmu.h differs from kernel" >&2 )) || true - @(test -f ../../include/uapi/asm-generic/mman-common.h && ( \ - (diff -B ../include/uapi/asm-generic/mman-common.h ../../include/uapi/asm-generic/mman-common.h >/dev/null) \ - || echo "Warning: tools/include/uapi/asm-generic/mman-common.h differs from kernel" >&2 )) || true - @(test -f ../../include/uapi/asm-generic/mman.h && ( \ - (diff -B -I "^#include <\(uapi/\)*asm-generic/mman-common.h>$$" ../include/uapi/asm-generic/mman.h ../../include/uapi/asm-generic/mman.h >/dev/null) \ - || echo "Warning: tools/include/uapi/asm-generic/mman.h differs from kernel" >&2 )) || true - @(test -f ../../include/uapi/linux/mman.h && ( \ - (diff -B -I "^#include <\(uapi/\)*asm/mman.h>$$" ../include/uapi/linux/mman.h ../../include/uapi/linux/mman.h >/dev/null) \ - || echo "Warning: tools/include/uapi/linux/mman.h differs from kernel" >&2 )) || true $(Q)$(MAKE) $(build)=perf $(JEVENTS_IN): FORCE
tools/perf/check-headers.sh new file +59 -0
59 lines not on this page · raw message
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 14/29 tools include uapi: Grab copies of stat.h and fcntl.h
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
commit 67ef28794d7e30f33936d655f2951e8dcae7cd5a upstream.
We will need it to build tools/perf/trace/beauty/statx.h.
--- tools/include/linux/types.h | 1 + tools/include/uapi/linux/fcntl.h | 72 +++++++++++++ tools/include/uapi/linux/stat.h | 176 +++++++++++++++++++++++++++++++ tools/perf/MANIFEST | 2 + tools/perf/check-headers.sh | 2 + 5 files changed, 253 insertions(+) create mode 100644 tools/include/uapi/linux/fcntl.h create mode 100644 tools/include/uapi/linux/stat.h
tools/include/linux/types.h +1 -0
@@ -7,6 +7,7 @@#define __SANE_USERSPACE_TYPES__/* For PPC64, to get LL64 types */ #include <asm/types.h> +#include <asm/posix_types.h> struct page ;struct kmem_cache ;
tools/include/uapi/linux/fcntl.h new file +72 -0
72 lines not on this page · raw message
tools/include/uapi/linux/stat.h new file +176 -0
176 lines not on this page · raw message
tools/perf/MANIFEST +2 -0
@@ -72,9 +72,11 @@ tools/include/uapi/asm-generic/mman-common.h tools/include/uapi/asm-generic/mman.h tools/include/uapi/linux/bpf.h tools/include/uapi/linux/bpf_common.h +tools/include/uapi/linux/fcntl.h tools/include/uapi/linux/hw_breakpoint.h tools/include/uapi/linux/mman.h tools/include/uapi/linux/perf_event.h +tools/include/uapi/linux/stat.h tools/include/linux/poison.h tools/include/linux/rbtree.h tools/include/linux/rbtree_augmented.h
tools/perf/check-headers.sh +2 -0
@@ -1,7 +1,9 @@ #!/bin/sh HEADERS=' +include/uapi/linux/fcntl.h include/uapi/linux/perf_event.h +include/uapi/linux/stat.h include/linux/hash.h include/uapi/linux/hw_breakpoint.h arch/x86/include/asm/disabled-features.h
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 15/29 tools include: Introduce linux/bug.h, from the kernel sources
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
commit 379d61b1c7d42512cded04d372f15a7e725db9e1 upstream.
With just what we will need in the upcoming changesets, the BUILD_BUG_ON_ZERO() definition.
--- tools/include/linux/bug.h | 10 ++++++++++ tools/perf/MANIFEST | 1 + 2 files changed, 11 insertions(+) create mode 100644 tools/include/linux/bug.h
tools/include/linux/bug.h new file +10 -0
@@ -0,0 +1,10 @@ +#ifndef _TOOLS_PERF_LINUX_BUG_H +#define _TOOLS_PERF_LINUX_BUG_H + +/* Force a compilation error if condition is true, but also produce a +result (of value 0 and type size_t), so the expression can be used +e.g. in a structure initializer (or where-ever else comma expressions +aren't permitted). */ +#define BUILD_BUG_ON_ZERO (e) (sizeof(struct { int:-!!(e); })) + +#endif /* _TOOLS_PERF_LINUX_BUG_H */
tools/perf/MANIFEST +1 -0
@@ -63,6 +63,7 @@ tools/include/linux/bitops.h tools/include/linux/compiler.h tools/include/linux/compiler-gcc.h tools/include/linux/coresight-pmu.h +tools/include/linux/bug.h tools/include/linux/filter.h tools/include/linux/hash.h tools/include/linux/kernel.h
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 16/29 tools include: Adopt __same_type() and __must_be_array() from the kernel
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
commit f6441aff8946f7fd6ab730d7eb9eba18a9ebeba4 upstream.
Will be used to adopt the more stringent version of ARRAY_SIZE(), the one in the kernel sources.
--- tools/include/linux/compiler-gcc.h | 3 +++ tools/include/linux/compiler.h | 5 +++++ 2 files changed, 8 insertions(+)
tools/include/linux/compiler-gcc.h +3 -0
@@ -16,3 +16,6 @@#if GCC_VERSION >=40300 # define __compiletime_error (message) __attribute__((error(message)))#endif /* GCC_VERSION >= 40300 */ + +/* &a[0] degrades to a pointer: a different type from an array */ +#define __must_be_array (a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
tools/include/linux/compiler.h +5 -0
@@ -17,6 +17,11 @@# define __always_inline inline __attribute__((always_inline))#endif +/* Are two types/vars the same type (ignoring qualifiers)? */ +#ifndef __same_type +# define __same_type (a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) +#endif +#ifdef __ANDROID__/* * FIXME: Big hammer to get rid of tons of:
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 17/29 tools include: Move ARRAY_SIZE() to linux/kernel.h
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
commit 8607c1ee734d12f62c6a46abef13a510e25a1839 upstream.
To match the kernel, then look for places redefining it to make it use this version, which checks that its parameter is an array at build time.
--- tools/include/linux/kernel.h | 3 +++ tools/perf/util/util.h | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-)
tools/include/linux/kernel.h +3 -0
@@ -4,6 +4,7 @@#include <stdarg.h> #include <stddef.h> #include <assert.h> +#include <linux/compiler.h> #ifndef UINT_MAX #define UINT_MAX (~0U)
@@ -76,6 +77,8 @@int vscnprintf (char *buf,size_t size,const char *fmt,va_list args);int scnprintf (char * buf,size_t size,const char * fmt, ...); +#define ARRAY_SIZE (arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) +/* * This looks more complex than it should be. But we need to * get the type for the ~ right in round_down (it needs to be
tools/perf/util/util.h +0 -2
@@ -23,8 +23,6 @@#endif #endif -#define ARRAY_SIZE (x) (sizeof(x)/sizeof(x[0])) -#ifdef __GNUC__#define TYPEOF (x) (__typeof__(x))#else
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 18/29 tools include: Drop ARRAY_SIZE() definition from linux/hashtable.h
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
commit 68289cbd83eaa20faef7cc818121bc8e769065de upstream.
As tools/include/linux/kernel.h has it now, with the goodies present in the kernel.h counterpart, i.e. checking that the parameter is an array at build time.
--- tools/include/linux/hashtable.h | 4 ---- 1 file changed, 4 deletions(-)
tools/include/linux/hashtable.h +0 -4
@@ -13,10 +13,6 @@#include <linux/hash.h> #include <linux/log2.h> -#ifndef ARRAY_SIZE -#define ARRAY_SIZE (x) (sizeof(x) / sizeof((x)[0])) -#endif -#define DEFINE_HASHTABLE (name, bits) \ struct hlist_head name[1 << (bits)] = \ { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 19/29 tools include: Include missing headers for fls() and types in linux/log2.h
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
commit a12a4e023a55f058178afea1ada3ce7bf4db94c3 upstream.
--- tools/include/linux/log2.h | 3 +++ 1 file changed, 3 insertions(+)
tools/include/linux/log2.h +3 -0
@@ -12,6 +12,9 @@#ifndef _TOOLS_LINUX_LOG2_H#define _TOOLS_LINUX_LOG2_H +#include <linux/bitops.h> +#include <linux/types.h> +/* * non-constant log of base 2 calculators * - the arch may override these in asm/bitops.h if they can be implemented
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 20/29 objtool: sync up with the 4.14.47 version of objtool
In reply to Greg Kroah-HartmanThere are pros and cons of dealing with tools in the kernel directory. The pros are the fact that development happens fast, and new features can be added to the kernel and the tools at the same times. The cons are when dealing with backported kernel patches, it can be necessary to backport parts of the tool changes as well.
For 4.9.y so far, we have backported individual patches. That quickly breaks down when there are minor differences between how backports were handled, so grabbing 40+ patch long series can be difficult, not impossible, but really frustrating to attempt.
To help mitigate this mess, here's a single big patch to sync up the objtool logic to the 4.14.47 version of the tool. From this point forward (after some other minor header file patches are applied), the tool should be in sync and much easier to maintain over time.
This has survivied my limited testing, and as the codebase is identical to 4.14.47, I'm pretty comfortable dropping this big change in here in 4.9.y. Hopefully all goes well...
---
arch/x86/include/asm/orc_types.h | 107 ++
arch/x86/include/asm/unwind_hints.h | 103 ++
tools/objtool/Build | 3 +
.../Documentation/stack-validation.txt | 195 +--
tools/objtool/Makefile | 35 +-
tools/objtool/arch.h | 65 +-
tools/objtool/arch/x86/Build | 10 +-
tools/objtool/arch/x86/decode.c | 408 ++++-
.../arch/x86/{insn => include/asm}/inat.h | 12 +-
.../x86/{insn => include/asm}/inat_types.h | 0
.../arch/x86/{insn => include/asm}/insn.h | 2 +-
.../objtool/arch/x86/include/asm/orc_types.h | 107 ++
tools/objtool/arch/x86/{insn => lib}/inat.c | 2 +-
tools/objtool/arch/x86/{insn => lib}/insn.c | 4 +-
.../arch/x86/{insn => lib}/x86-opcode-map.txt | 15 +-
.../x86/{insn => tools}/gen-insn-attr-x86.awk | 1 +
tools/objtool/builtin-check.c | 9 +-
tools/objtool/builtin-orc.c | 68 +
tools/objtool/builtin.h | 6 +
tools/objtool/cfi.h | 55 +
tools/objtool/check.c | 1329 ++++++++++++++---
tools/objtool/check.h | 39 +-
tools/objtool/elf.c | 284 +++-
tools/objtool/elf.h | 21 +-
tools/objtool/objtool.c | 12 +-
tools/objtool/orc.h | 30 +
tools/objtool/orc_dump.c | 213 +++
tools/objtool/orc_gen.c | 221 +++
tools/objtool/special.c | 6 +-
tools/objtool/sync-check.sh | 29 +
tools/objtool/warn.h | 10 +
31 files changed, 2887 insertions(+), 514 deletions(-)
create mode 100644 arch/x86/include/asm/orc_types.h
create mode 100644 arch/x86/include/asm/unwind_hints.h
rename tools/objtool/arch/x86/{insn => include/asm}/inat.h (95%)
rename tools/objtool/arch/x86/{insn => include/asm}/inat_types.h (100%)
rename tools/objtool/arch/x86/{insn => include/asm}/insn.h (99%)
create mode 100644 tools/objtool/arch/x86/include/asm/orc_types.h
rename tools/objtool/arch/x86/{insn => lib}/inat.c (99%)
rename tools/objtool/arch/x86/{insn => lib}/insn.c (99%)
rename tools/objtool/arch/x86/{insn => lib}/x86-opcode-map.txt (99%)
rename tools/objtool/arch/x86/{insn => tools}/gen-insn-attr-x86.awk (99%)
create mode 100644 tools/objtool/builtin-orc.c
create mode 100644 tools/objtool/cfi.h
create mode 100644 tools/objtool/orc.h
create mode 100644 tools/objtool/orc_dump.c
create mode 100644 tools/objtool/orc_gen.c
create mode 100644 tools/objtool/sync-check.sharch/x86/include/asm/orc_types.h new file +107 -0
@@ -0,0 +1,107 @@ +/* +* Copyright (C) 2017 Josh Poimboeuf <[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _ORC_TYPES_H +#define _ORC_TYPES_H + +#include <linux/types.h> +#include <linux/compiler.h> + +/* +* The ORC_REG_* registers are base registers which are used to find other +* registers on the stack. +* +* ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the +* address of the previous frame: the caller's SP before it called the current +* function. +* +* ORC_REG_UNDEFINED means the corresponding register's value didn't change in +* the current frame. +* +* The most commonly used base registers are SP and BP -- which the previous SP +* is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is +* usually based on. +* +* The rest of the base registers are needed for special cases like entry code +* and GCC realigned stacks. +*/ +#define ORC_REG_UNDEFINED 0 +#define ORC_REG_PREV_SP 1 +#define ORC_REG_DX 2 +#define ORC_REG_DI 3 +#define ORC_REG_BP 4 +#define ORC_REG_SP 5 +#define ORC_REG_R10 6 +#define ORC_REG_R13 7 +#define ORC_REG_BP_INDIRECT 8 +#define ORC_REG_SP_INDIRECT 9 +#define ORC_REG_MAX 15 + +/* +* ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the +* caller's SP right before it made the call). Used for all callable +* functions, i.e. all C code and all callable asm functions. +* +* ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points +* to a fully populated pt_regs from a syscall, interrupt, or exception. +* +* ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset +* points to the iret return frame. +* +* The UNWIND_HINT macros are used only for the unwind_hint struct. They +* aren't used in struct orc_entry due to size and complexity constraints. +* Objtool converts them to real types when it converts the hints to orc +* entries. +*/ +#define ORC_TYPE_CALL 0 +#define ORC_TYPE_REGS 1 +#define ORC_TYPE_REGS_IRET 2 +#define UNWIND_HINT_TYPE_SAVE 3 +#define UNWIND_HINT_TYPE_RESTORE 4 + +#ifndef __ASSEMBLY__ +/* +* This struct is more or less a vastly simplified version of the DWARF Call +* Frame Information standard. It contains only the necessary parts of DWARF +* CFI, simplified for ease of access by the in-kernel unwinder. It tells the +* unwinder how to find the previous SP and BP (and sometimes entry regs) on +* the stack for a given code address. Each instance of the struct corresponds +* to one or more code locations. +*/ +struct orc_entry { +s16 sp_offset; +s16 bp_offset; +unsigned sp_reg:4 ; +unsigned bp_reg:4 ; +unsigned type:2 ; +}; + +/* +* This struct is used by asm and inline asm code to manually annotate the +* location of registers on the stack for the ORC unwinder. +* +* Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*. +*/ +struct unwind_hint { +u32 ip; +s16 sp_offset; +u8 sp_reg; +u8 type; +}; +#endif /* __ASSEMBLY__ */ + +#endif /* _ORC_TYPES_H */
arch/x86/include/asm/unwind_hints.h new file +103 -0
103 lines not on this page · raw message
tools/objtool/Build +3 -0
@@ -1,6 +1,9 @@ objtool-y += arch/$(SRCARCH)/ objtool-y += builtin-check.o +objtool-y += builtin-orc.o objtool-y += check.o +objtool-y += orc_gen.o +objtool-y += orc_dump.o objtool-y += elf.o objtool-y += special.o objtool-y += objtool.o
tools/objtool/Documentation/stack-validation.txt +75 -120
278 lines not on this page · raw message
tools/objtool/Makefile +15 -20
@@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 include ../scripts/Makefile.include include ../scripts/Makefile.arch
@@ -6,17 +7,19 @@ ARCH := x86 endif # always use the host compiler -CC = gcc -LD = ld -AR = ar +HOSTCC ?= gcc +HOSTLD ?= ld +CC = $(HOSTCC) +LD = $(HOSTLD) +AR = ar ifeq ($(srctree),) -srctree := $(patsubst %/,%,$(dir $(shell pwd))) +srctree := $(patsubst %/,%,$(dir $(CURDIR))) srctree := $(patsubst %/,%,$(dir $(srctree))) endif SUBCMD_SRCDIR = $(srctree)/tools/lib/subcmd/ -LIBSUBCMD_OUTPUT = $(if $(OUTPUT),$(OUTPUT),$(PWD)/) +LIBSUBCMD_OUTPUT = $(if $(OUTPUT),$(OUTPUT),$(CURDIR)/) LIBSUBCMD = $(LIBSUBCMD_OUTPUT)libsubcmd.a OBJTOOL := $(OUTPUT)objtool
@@ -24,8 +27,11 @@ OBJTOOL_IN := $(OBJTOOL)-in.o all: $(OBJTOOL) -INCLUDES := -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi -CFLAGS += -Wall -Werror $(EXTRA_WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES) +INCLUDES := -I$(srctree)/tools/include \ + -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \ + -I$(srctree)/tools/objtool/arch/$(ARCH)/include +WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed +CFLAGS += -Wall -Werror $(WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES) LDFLAGS += -lelf $(LIBSUBCMD) # Allow old libelf to be used:
@@ -39,19 +45,8 @@ include $(srctree)/tools/build/Makefile.include $(OBJTOOL_IN): fixdep FORCE @$(MAKE) $(build)=objtool -# Busybox's diff doesn't have -I, avoid warning in that case -# $(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN) - @(diff -I 2>&1 | grep -q 'option requires an argument' && \ - test -d ../../kernel -a -d ../../tools -a -d ../objtool && (( \ - diff -I'^#include' arch/x86/insn/insn.c ../../arch/x86/lib/insn.c >/dev/null && \ - diff -I'^#include' arch/x86/insn/inat.c ../../arch/x86/lib/inat.c >/dev/null && \ - diff arch/x86/insn/x86-opcode-map.txt ../../arch/x86/lib/x86-opcode-map.txt >/dev/null && \ - diff arch/x86/insn/gen-insn-attr-x86.awk ../../arch/x86/tools/gen-insn-attr-x86.awk >/dev/null && \ - diff -I'^#include' arch/x86/insn/insn.h ../../arch/x86/include/asm/insn.h >/dev/null && \ - diff -I'^#include' arch/x86/insn/inat.h ../../arch/x86/include/asm/inat.h >/dev/null && \ - diff -I'^#include' arch/x86/insn/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) \ - || echo "warning: objtool: x86 instruction decoder differs from kernel" >&2 )) || true + @$(CONFIG_SHELL) ./sync-check.sh $(QUIET_LINK)$(CC) $(OBJTOOL_IN) $(LDFLAGS) -o $@
@@ -61,7 +56,7 @@ $(LIBSUBCMD): fixdep FORCE clean: $(call QUIET_CLEAN, objtool) $(RM) $(OBJTOOL) $(Q)find $(OUTPUT) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete - $(Q)$(RM) $(OUTPUT)arch/x86/insn/inat-tables.c $(OUTPUT)fixdep + $(Q)$(RM) $(OUTPUT)arch/x86/lib/inat-tables.c $(OUTPUT)fixdep FORCE:
tools/objtool/arch.h +52 -13
77 lines not on this page · raw message
tools/objtool/arch/x86/Build +5 -5
@@ -1,12 +1,12 @@ objtool-y += decode.o -inat_tables_script = arch/x86/insn/gen-insn-attr-x86.awk -inat_tables_maps = arch/x86/insn/x86-opcode-map.txt +inat_tables_script = arch/x86/tools/gen-insn-attr-x86.awk +inat_tables_maps = arch/x86/lib/x86-opcode-map.txt -$(OUTPUT)arch/x86/insn/inat-tables.c: $(inat_tables_script) $(inat_tables_maps) +$(OUTPUT)arch/x86/lib/inat-tables.c: $(inat_tables_script) $(inat_tables_maps) $(call rule_mkdir) $(Q)$(call echo-cmd,gen)$(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@ -$(OUTPUT)arch/x86/decode.o: $(OUTPUT)arch/x86/insn/inat-tables.c +$(OUTPUT)arch/x86/decode.o: $(OUTPUT)arch/x86/lib/inat-tables.c -CFLAGS_decode.o += -I$(OUTPUT)arch/x86/insn +CFLAGS_decode.o += -I$(OUTPUT)arch/x86/lib
tools/objtool/arch/x86/decode.c +363 -45
485 lines not on this page · raw message
tools/objtool/arch/x86/include/asm/inat.h renamed from tools/objtool/arch/x86/insn/inat.h +11 -1
@@ -20,7 +20,7 @@* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ -#include "inat_types.h" +#include <asm/inat_types.h> /* * Internal bits. Don't use bitmasks directly, because these bits are
@@ -97,6 +97,16 @@#define INAT_MAKE_GROUP (grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM)#define INAT_MAKE_IMM (imm) (imm << INAT_IMM_OFFS) +/* Identifiers for segment registers */ +#define INAT_SEG_REG_IGNORE 0 +#define INAT_SEG_REG_DEFAULT 1 +#define INAT_SEG_REG_CS 2 +#define INAT_SEG_REG_SS 3 +#define INAT_SEG_REG_DS 4 +#define INAT_SEG_REG_ES 5 +#define INAT_SEG_REG_FS 6 +#define INAT_SEG_REG_GS 7 +/* Attribute search APIs */ extern insn_attr_t inat_get_opcode_attribute (insn_byte_t opcode);extern int inat_get_last_prefix_id (insn_byte_t last_pfx);
tools/objtool/arch/x86/include/asm/inat_types.h renamed from tools/objtool/arch/x86/insn/inat_types.h +0 -0
tools/objtool/arch/x86/include/asm/insn.h renamed from tools/objtool/arch/x86/insn/insn.h +1 -1
@@ -21,7 +21,7 @@*/ /* insn_attr_t is defined in inat.h */ -#include "inat.h" +#include <asm/inat.h> struct insn_field { union {
tools/objtool/arch/x86/include/asm/orc_types.h new file +107 -0
107 lines not on this page · raw message
tools/objtool/arch/x86/lib/inat.c renamed from tools/objtool/arch/x86/insn/inat.c +1 -1
@@ -18,7 +18,7 @@* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ -#include "insn.h" +#include <asm/insn.h> /* Attribute tables are generated from opcode map */ #include "inat-tables.c"
tools/objtool/arch/x86/lib/insn.c renamed from tools/objtool/arch/x86/insn/insn.c +2 -2
@@ -23,8 +23,8 @@#else #include <string.h> #endif -#include "inat.h" -#include "insn.h" +#include <asm/inat.h> +#include <asm/insn.h> /* Verify next sizeof(t) bytes can be on the same instruction */ #define validate_next (t, insn, n) \
tools/objtool/arch/x86/lib/x86-opcode-map.txt renamed from tools/objtool/arch/x86/insn/x86-opcode-map.txt +12 -3
@@ -607,7 +607,7 @@ fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1) fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1) fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1) fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1) -ff: +ff: UD0 EndTable Table: 3-byte opcode 1 (0x0f 0x38)
@@ -717,7 +717,7 @@ AVXcode: 2 7e: vpermt2d/q Vx,Hx,Wx (66),(ev) 7f: vpermt2ps/d Vx,Hx,Wx (66),(ev) 80: INVEPT Gy,Mdq (66) -81: INVPID Gy,Mdq (66) +81: INVVPID Gy,Mdq (66) 82: INVPCID Gy,Mdq (66) 83: vpmultishiftqb Vx,Hx,Wx (66),(ev) 88: vexpandps/d Vpd,Wpd (66),(ev)
@@ -970,6 +970,15 @@ GrpTable: Grp9 EndTable GrpTable: Grp10 +# all are UD1 +0: UD1 +1: UD1 +2: UD1 +3: UD1 +4: UD1 +5: UD1 +6: UD1 +7: UD1 EndTable # Grp11A and Grp11B are expressed as Grp11 in Intel SDM
@@ -1009,7 +1018,7 @@ GrpTable: Grp15 1: fxstor | RDGSBASE Ry (F3),(11B) 2: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B) 3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B) -4: XSAVE +4: XSAVE | ptwrite Ey (F3),(11B) 5: XRSTOR | lfence (11B) 6: XSAVEOPT | clwb (66) | mfence (11B) 7: clflush | clflushopt (66) | sfence (11B)
tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk renamed from tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk +1 -0
@@ -1,4 +1,5 @@ #!/bin/awk -f +# SPDX-License-Identifier: GPL-2.0 # gen-insn-attr-x86.awk: Instruction attribute table generator # Written by Masami Hiramatsu <[email protected]> #
tools/objtool/builtin-check.c +6 -3
@@ -29,7 +29,7 @@#include "builtin.h" #include "check.h" -bool nofp; +bool no_fp, no_unreachable, retpoline, module;static const char *const check_usage[] = {"objtool check [<options>] file.o" ,
@@ -37,7 +37,10 @@ static const char * const check_usage[] = { };const struct option check_options[] = { -OPT_BOOLEAN ('f' ,"no-fp" , &nofp,"Skip frame pointer validation" ), +OPT_BOOLEAN ('f' ,"no-fp" , &no_fp,"Skip frame pointer validation" ), +OPT_BOOLEAN ('u' ,"no-unreachable" , &no_unreachable,"Skip 'unreachable instruction' warnings" ), +OPT_BOOLEAN ('r' ,"retpoline" , &retpoline,"Validate retpoline assumptions" ), +OPT_BOOLEAN ('m' ,"module" , &module,"Indicates the object will be part of a kernel module" ),OPT_END (), };
@@ -52,5 +55,5 @@ int cmd_check(int argc, const char **argv) objname = argv[0 ]; -return check (objname, nofp); +return check (objname, false); }
tools/objtool/builtin-orc.c new file +68 -0
68 lines not on this page · raw message
tools/objtool/builtin.h +6 -0
@@ -17,6 +17,12 @@#ifndef _BUILTIN_H#define _BUILTIN_H +#include <subcmd/parse-options.h> + +extern const struct option check_options[]; +extern bool no_fp, no_unreachable, retpoline, module; +extern int cmd_check (int argc,const char **argv); +extern int cmd_orc (int argc,const char **argv);#endif /* _BUILTIN_H */
tools/objtool/cfi.h new file +55 -0
55 lines not on this page · raw message
tools/objtool/check.c +1094 -235
1,494 lines not on this page · raw message
tools/objtool/elf.c +237 -47
284 lines not on this page · raw message
tools/objtool/orc_dump.c new file +213 -0
213 lines not on this page · raw message
tools/objtool/orc_gen.c new file +221 -0
221 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.17.1
Part of the diff is not shown here. View the raw message.
Greg Kroah-Hartman
maintainerPATCH 21/29 objtool: Support GCC 8's cold subfunctions
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit 13810435b9a7014fb92eb715f77da488f3b65b99 upstream.
GCC 8 moves a lot of unlikely code out of line to "cold" subfunctions in .text.unlikely. Properly detect the new subfunctions and treat them as extensions of the original functions.
This fixes a bunch of warnings like:
kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags()+0x33: sibling call from callable instruction with modified stack frame kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files()+0x290: sibling call from callable instruction with modified stack frame kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable()+0x25b: sibling call from callable instruction with modified stack frame kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems()+0x325: sibling call from callable instruction with modified stack frame
--- tools/objtool/check.c | 93 ++++++++++++++++++++++++------------------- tools/objtool/elf.c | 42 ++++++++++++++++++- tools/objtool/elf.h | 2 + 3 files changed, 93 insertions(+), 44 deletions(-)
tools/objtool/check.c +51 -42
@@ -59,6 +59,31 @@ static struct instruction *next_insn_same_sec(struct objtool_file *file,return next; } +static struct instruction *next_insn_same_func (struct objtool_file *file, +struct instruction *insn) +{ +struct instruction *next =list_next_entry (insn, list); +struct symbol *func = insn->func; + +if (!func) +return NULL ; + +if (&next->list != &file->insn_list && next->func == func) +return next; + +/* Check if we're already in the subfunction: */ +if (func == func->cfunc) +return NULL ; + +/* Move to the subfunction: */ +return find_insn (file, func->cfunc->sec, func->cfunc->offset); +} + +#define func_for_each_insn_all (file, func, insn) \ + for (insn = find_insn(file, func->sec, func->offset); \ + insn; \ + insn = next_insn_same_func(file, insn)) +#define func_for_each_insn (file, func, insn) \ for (insn = find_insn(file, func->sec, func->offset); \ insn && &insn->list != &file->insn_list && \
@@ -148,10 +173,14 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,if (!strcmp (func->name, global_noreturns[i]))return 1 ; -if (!func->sec) +if (!func->len)return 0 ; -func_for_each_insn (file, func, insn) { + insn =find_insn (file, func->sec, func->offset); +if (!insn->func) +return 0 ; + +func_for_each_insn_all (file, func, insn) { empty = false;if (insn->type ==INSN_RETURN )
@@ -166,35 +195,24 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,* case, the function's dead-end status depends on whether the target * of the sibling call returns. */ -func_for_each_insn (file, func, insn) { -if (insn->sec != func->sec || - insn->offset >= func->offset + func->len) -break ; - +func_for_each_insn_all (file, func, insn) {if (insn->type ==INSN_JUMP_UNCONDITIONAL ) {struct instruction *dest = insn->jump_dest; -struct symbol *dest_func;if (!dest)/* sibling call to another file */ return 0 ; -if (dest->sec != func->sec || - dest->offset < func->offset || - dest->offset >= func->offset + func->len) { -/* local sibling call */ - dest_func =find_symbol_by_offset (dest->sec, - dest->offset); -if (!dest_func) -continue ; +if (dest->func && dest->func->pfunc != insn->func->pfunc) { +/* local sibling call */ if (recursion ==5 ) {WARN_FUNC ("infinite recursion (objtool bug!)" , dest->sec, dest->offset);return -1 ; } -return __dead_end_function (file, dest_func, +return __dead_end_function (file, dest->func, recursion +1 ); } }
@@ -421,7 +439,7 @@ static void add_ignores(struct objtool_file *file)if (!ignore_func (file, func))continue ; -func_for_each_insn (file, func, insn) +func_for_each_insn_all (file, func, insn) insn->ignore = true; } }
@@ -781,9 +799,8 @@ static int add_special_section_alts(struct objtool_file *file)return ret; } -static int add_switch_table (struct objtool_file *file,struct symbol *func, -struct instruction *insn,struct rela *table, -struct rela *next_table) +static int add_switch_table (struct objtool_file *file,struct instruction *insn, +struct rela *table,struct rela *next_table) {struct rela *rela = table;struct instruction *alt_insn;
@@ -793,18 +810,13 @@ static int add_switch_table(struct objtool_file *file, struct symbol *func,if (rela == next_table)break ; -if (rela->sym->sec != insn->sec || - rela->addend <= func->offset || - rela->addend >= func->offset + func->len) + alt_insn =find_insn (file, rela->sym->sec, rela->addend); +if (!alt_insn)break ; - alt_insn =find_insn (file, insn->sec, rela->addend); -if (!alt_insn) { -WARN ("%s: can't find instruction at %s+0x%x" , - file->rodata->rela->name, insn->sec->name, - rela->addend); -return -1 ; - } +/* Make sure the jmp dest is in the function or subfunction: */ +if (alt_insn->func->pfunc != insn->func->pfunc) +break ; alt =malloc (sizeof (*alt));if (!alt) {
@@ -942,7 +954,7 @@ static int add_func_switch_tables(struct objtool_file *file,struct rela *rela, *prev_rela =NULL ;int ret; -func_for_each_insn (file, func, insn) { +func_for_each_insn_all (file, func, insn) {if (!last) last = insn;
@@ -973,8 +985,7 @@ static int add_func_switch_tables(struct objtool_file *file,* the beginning of another switch table in the same function. */ if (prev_jump) { - ret =add_switch_table (file, func, prev_jump, prev_rela, - rela); + ret =add_switch_table (file, prev_jump, prev_rela, rela);if (ret)return ret; }
@@ -984,7 +995,7 @@ static int add_func_switch_tables(struct objtool_file *file, }if (prev_jump) { - ret =add_switch_table (file, func, prev_jump, prev_rela,NULL ); + ret =add_switch_table (file, prev_jump, prev_rela,NULL );if (ret)return ret; }
@@ -1748,15 +1759,13 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,while (1 ) { next_insn =next_insn_same_sec (file, insn); - -if (file->c_file && func && insn->func && func != insn->func) { +if (file->c_file && func && insn->func && func != insn->func->pfunc) {WARN ("%s() falls through to next function %s()" , func->name, insn->func->name);return 1 ; } -if (insn->func) - func = insn->func; + func = insn->func ? insn->func->pfunc :NULL ;if (func && insn->ignore) { WARN_FUNC("BUG: why am I validating an ignored function?",
@@ -1777,7 +1786,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, i = insn; save_insn =NULL ; -func_for_each_insn_continue_reverse (file, func, i) { +func_for_each_insn_continue_reverse (file, insn->func, i) {if (i->save) { save_insn = i;break ;
@@ -1864,7 +1873,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,case INSN_JUMP_UNCONDITIONAL :if (insn->jump_dest && (!func || !insn->jump_dest->func || - func == insn->jump_dest->func)) { + insn->jump_dest->func->pfunc == func)) { ret =validate_branch (file, insn->jump_dest, state);if (ret)
@@ -2059,7 +2068,7 @@ static int validate_functions(struct objtool_file *file)for_each_sec (file, sec) {list_for_each_entry (func, &sec->symbol_list, list) { -if (func->type !=STT_FUNC ) +if (func->type !=STT_FUNC || func->pfunc != func)continue ; insn =find_insn (file, sec, func->offset);
tools/objtool/elf.c +40 -2
62 lines not on this page · raw message
tools/objtool/elf.h +2 -0
@@ -61,6 +61,7 @@ struct symbol {unsigned char bind, type;unsigned long offset;unsigned int len; +struct symbol *pfunc, *cfunc; };struct rela {
@@ -86,6 +87,7 @@ struct elf {struct elf *elf_open (const char *name,int flags);struct section *find_section_by_name (struct elf *elf,const char *name);struct symbol *find_symbol_by_offset (struct section *sec,unsigned long offset); +struct symbol *find_symbol_by_name (struct elf *elf,const char *name);struct symbol *find_symbol_containing (struct section *sec,unsigned long offset);struct rela *find_rela_by_dest (struct section *sec,unsigned long offset); struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset,
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 22/29 objtool: Support GCC 8 switch tables
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit fd35c88b74170d9335530d9abf271d5d73eb5401 upstream.
With GCC 8, some issues were found with the objtool switch table detection.
1) In the .rodata section, immediately after the switch table, there can be another object which contains a pointer to the function which had the switch statement. In this case objtool wrongly considers the function pointer to be part of the switch table. Fix it by:
a) making sure there are no pointers to the beginning of the function; and
b) making sure there are no gaps in the switch table.
Only the former was needed, the latter adds additional protection for future optimizations.
2) In find_switch_table(), case 1 and case 2 are missing the check to ensure that the .rodata switch table data is anonymous, i.e. that it isn't already associated with an ELF symbol. Fix it by adding the same find_symbol_containing() check which is used for case 3.
This fixes the following warnings with GCC 8:
drivers/block/virtio_blk.o: warning: objtool: virtio_queue_rq()+0x0: stack state mismatch: cfa1=7+8 cfa2=7+72 net/ipv6/icmp.o: warning: objtool: icmpv6_rcv()+0x0: stack state mismatch: cfa1=7+8 cfa2=7+64 drivers/usb/core/quirks.o: warning: objtool: quirks_param_set()+0x0: stack state mismatch: cfa1=7+8 cfa2=7+48 drivers/mtd/nand/raw/nand_hynix.o: warning: objtool: hynix_nand_decode_id()+0x0: stack state mismatch: cfa1=7+8 cfa2=7+24 drivers/mtd/nand/raw/nand_samsung.o: warning: objtool: samsung_nand_decode_id()+0x0: stack state mismatch: cfa1=7+8 cfa2=7+32 drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.o: warning: objtool: gk104_top_oneinit()+0x0: stack state mismatch: cfa1=7+8 cfa2=7+64
--- tools/objtool/check.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
tools/objtool/check.c +22 -2
@@ -805,17 +805,28 @@ static int add_switch_table(struct objtool_file *file, struct instruction *insn,struct rela *rela = table;struct instruction *alt_insn;struct alternative *alt; +struct symbol *pfunc = insn->func->pfunc; +unsigned int prev_offset =0 ;list_for_each_entry_from (rela, &file->rodata->rela->rela_list, list) {if (rela == next_table)break ; +/* Make sure the switch table entries are consecutive: */ +if (prev_offset && rela->offset != prev_offset +8 ) +break ; + +/* Detect function pointers from contiguous objects: */ +if (rela->sym->sec == pfunc->sec && + rela->addend == pfunc->offset) +break ; + alt_insn =find_insn (file, rela->sym->sec, rela->addend);if (!alt_insn)break ;/* Make sure the jmp dest is in the function or subfunction: */ -if (alt_insn->func->pfunc != insn->func->pfunc) +if (alt_insn->func->pfunc != pfunc)break ; alt =malloc (sizeof (*alt));
@@ -826,6 +837,13 @@ static int add_switch_table(struct objtool_file *file, struct instruction *insn, alt->insn = alt_insn;list_add_tail (&alt->list, &insn->alts); + prev_offset = rela->offset; + } + +if (!prev_offset) { +WARN_FUNC ("can't find switch jump table" , + insn->sec, insn->offset); +return -1 ; }return 0 ;
@@ -882,7 +900,9 @@ static struct rela *find_switch_table(struct objtool_file *file,struct instruction *orig_insn = insn; text_rela =find_rela_by_dest_range (insn->sec, insn->offset, insn->len); -if (text_rela && text_rela->sym == file->rodata->sym) { +if (text_rela && text_rela->sym == file->rodata->sym && + !find_symbol_containing (file->rodata, text_rela->addend)) { +/* case 1 */ rodata_rela =find_rela_by_dest (file->rodata, text_rela->addend);
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 23/29 objtool: Detect RIP-relative switch table references
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit 6f5ec2993b1f39aed12fa6fd56e8dc2272ee8a33 upstream.
Typically a switch table can be found by detecting a .rodata access followed an indirect jump:
1969: 4a 8b 0c e5 00 00 00 mov 0x0(,%r12,8),%rcx
1970: 00
196d: R_X86_64_32S .rodata+0x438
1971: e9 00 00 00 00 jmpq 1976 <dispc_runtime_suspend+0xb6a>
1972: R_X86_64_PC32 __x86_indirect_thunk_rcx-0x4Randy Dunlap reported a case (seen with GCC 4.8) where the .rodata access uses RIP-relative addressing:
19bd: 48 8b 3d 00 00 00 00 mov 0x0(%rip),%rdi # 19c4 <dispc_runtime_suspend+0xbb8>
19c0: R_X86_64_PC32 .rodata+0x45c
19c4: e9 00 00 00 00 jmpq 19c9 <dispc_runtime_suspend+0xbbd>
19c5: R_X86_64_PC32 __x86_indirect_thunk_rdi-0x4In this case the relocation addend needs to be adjusted accordingly in order to find the location of the switch table.
The fix is for case 3 (as described in the comments), but also make the existing case 1 & 2 checks more precise by only adjusting the addend for R_X86_64_PC32 relocations.
This fixes the following warnings:
drivers/video/fbdev/omap2/omapfb/dss/dispc.o: warning: objtool: dispc_runtime_suspend()+0xbb8: sibling call from callable instruction with modified stack frame drivers/video/fbdev/omap2/omapfb/dss/dispc.o: warning: objtool: dispc_runtime_resume()+0xcc5: sibling call from callable instruction with modified stack frame
--- tools/objtool/check.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-)
tools/objtool/check.c +18 -15
@@ -898,24 +898,24 @@ static struct rela *find_switch_table(struct objtool_file *file, {struct rela *text_rela, *rodata_rela;struct instruction *orig_insn = insn; +unsigned long table_offset; +/* case 1 & 2 */ text_rela =find_rela_by_dest_range (insn->sec, insn->offset, insn->len);if (text_rela && text_rela->sym == file->rodata->sym && !find_symbol_containing (file->rodata, text_rela->addend)) { -/* case 1 */ - rodata_rela =find_rela_by_dest (file->rodata, - text_rela->addend); -if (rodata_rela) -return rodata_rela; + table_offset = text_rela->addend; +if (text_rela->type ==R_X86_64_PC32 ) { +/* case 2 */ + table_offset +=4 ; + file->ignore_unreachables = true; + } -/* case 2 */ - rodata_rela =find_rela_by_dest (file->rodata, - text_rela->addend +4 ); + rodata_rela =find_rela_by_dest (file->rodata, table_offset);if (!rodata_rela)return NULL ; - file->ignore_unreachables = true;return rodata_rela; }
@@ -949,18 +949,21 @@ static struct rela *find_switch_table(struct objtool_file *file,if (!text_rela || text_rela->sym != file->rodata->sym)continue ; + table_offset = text_rela->addend; +if (text_rela->type ==R_X86_64_PC32 ) + table_offset +=4 ; +/* * Make sure the .rodata address isn't associated with a * symbol. gcc jump tables are anonymous data. */ -if (find_symbol_containing (file->rodata, text_rela->addend)) -continue ; - - rodata_rela =find_rela_by_dest (file->rodata, text_rela->addend); -if (!rodata_rela) +if (find_symbol_containing (file->rodata, table_offset))continue ; -return rodata_rela; +/* mov [rodata addr], %reg */ + rodata_rela =find_rela_by_dest (file->rodata, table_offset); +if (rodata_rela) +return rodata_rela; }return NULL ;
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 24/29 objtool: Detect RIP-relative switch table references, part 2
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit 7dec80ccbe310fb7e225bf21c48c672bb780ce7b upstream.
With the following commit:
fd35c88b7417 ("objtool: Support GCC 8 switch tables")
I added a "can't find switch jump table" warning, to stop covering up silent failures if add_switch_table() can't find anything.
That warning found yet another bug in the objtool switch table detection logic. For cases 1 and 2 (as described in the comments of find_switch_table()), the find_symbol_containing() check doesn't adjust the offset for RIP-relative switch jumps.
Incidentally, this bug was already fixed for case 3 with:
6f5ec2993b1f ("objtool: Detect RIP-relative switch table references")
However, that commit missed the fix for cases 1 and 2.
The different cases are now starting to look more and more alike. So fix the bug by consolidating them into a single case, by checking the original dynamic jump instruction in the case 3 loop.
This also simplifies the code and makes it more robust against future switch table detection issues -- of which I'm sure there will be many...
Switch table detection has been the most fragile area of objtool, by far. I long for the day when we'll have a GCC plugin for annotating switch tables. Linus asked me to delay such a plugin due to the flakiness of the plugin infrastructure in older versions of GCC, so this rickety code is what we're stuck with for now. At least the code is now a little simpler than it was.
--- tools/objtool/check.c | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-)
tools/objtool/check.c +12 -25
@@ -900,40 +900,19 @@ static struct rela *find_switch_table(struct objtool_file *file,struct instruction *orig_insn = insn;unsigned long table_offset; -/* case 1 & 2 */ - text_rela =find_rela_by_dest_range (insn->sec, insn->offset, insn->len); -if (text_rela && text_rela->sym == file->rodata->sym && - !find_symbol_containing (file->rodata, text_rela->addend)) { - - table_offset = text_rela->addend; -if (text_rela->type ==R_X86_64_PC32 ) { -/* case 2 */ - table_offset +=4 ; - file->ignore_unreachables = true; - } - - rodata_rela =find_rela_by_dest (file->rodata, table_offset); -if (!rodata_rela) -return NULL ; - -return rodata_rela; - } - -/* case 3 */ /* * Backward search using the @first_jump_src links, these help avoid * much of the 'in between' code. Which avoids us getting confused by * it. */ -for (insn =list_prev_entry (insn, list); - +for (; &insn->list != &file->insn_list && insn->sec == func->sec && insn->offset >= func->offset; insn = insn->first_jump_src ?:list_prev_entry (insn, list)) { -if (insn->type ==INSN_JUMP_DYNAMIC ) +if (insn != orig_insn && insn->type ==INSN_JUMP_DYNAMIC )break ;/* allow small jumps within the range */
@@ -960,10 +939,18 @@ static struct rela *find_switch_table(struct objtool_file *file,if (find_symbol_containing (file->rodata, table_offset))continue ; -/* mov [rodata addr], %reg */ rodata_rela =find_rela_by_dest (file->rodata, table_offset); -if (rodata_rela) +if (rodata_rela) { +/* +* Use of RIP-relative switch jumps is quite rare, and +* indicates a rare GCC quirk/bug which can leave dead +* code behind. +*/ +if (text_rela->type ==R_X86_64_PC32 ) + file->ignore_unreachables = true; +return rodata_rela; + } }return NULL ;
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 25/29 objtool: Fix "noreturn" detection for recursive sibling calls
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit 0afd0d9e0e7879d666c1df2fa1bea4d8716909fe upstream.
Objtool has some crude logic for detecting static "noreturn" functions (aka "dead ends"). This is necessary for being able to correctly follow GCC code flow when such functions are called.
It's remotely possible for two functions to call each other via sibling calls. If they don't have RET instructions, objtool's noreturn detection logic goes into a recursive loop:
drivers/char/ipmi/ipmi_ssif.o: warning: objtool: return_hosed_msg()+0x0: infinite recursion (objtool bug!) drivers/char/ipmi/ipmi_ssif.o: warning: objtool: deliver_recv_msg()+0x0: infinite recursion (objtool bug!)
Instead of reporting an error in this case, consider the functions to be non-dead-ends.
--- tools/objtool/check.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
tools/objtool/check.c +7 -3
@@ -207,9 +207,13 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,/* local sibling call */ if (recursion ==5 ) { -WARN_FUNC ("infinite recursion (objtool bug!)" , - dest->sec, dest->offset); -return -1 ; +/* +* Infinite recursion: two functions +* have sibling calls to each other. +* This is a very rare case. It means +* they aren't dead ends. +*/ +return 0 ; } return __dead_end_function(file, dest->func,
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 26/29 objtool, x86: Add several functions and files to the objtool whitelist
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
commit c207aee48037abca71c669cbec407b9891965c34 upstream.
In preparation for an objtool rewrite which will have broader checks, whitelist functions and files which cause problems because they do unusual things with the stack.
These whitelists serve as a TODO list for which functions and files don't yet have undwarf unwinder coverage. Eventually most of the whitelists can be removed in favor of manual CFI hint annotations or objtool improvements.
--- arch/x86/crypto/Makefile | 2 ++ arch/x86/crypto/sha1-mb/Makefile | 2 ++ arch/x86/crypto/sha256-mb/Makefile | 2 ++ arch/x86/kernel/Makefile | 1 + arch/x86/kernel/acpi/Makefile | 2 ++ arch/x86/kernel/kprobes/opt.c | 9 ++++++++- arch/x86/kernel/reboot.c | 2 ++ arch/x86/kvm/svm.c | 2 ++ arch/x86/kvm/vmx.c | 3 +++ arch/x86/lib/msr-reg.S | 8 ++++---- arch/x86/net/Makefile | 2 ++ arch/x86/platform/efi/Makefile | 1 + arch/x86/power/Makefile | 2 ++ arch/x86/xen/Makefile | 3 +++ kernel/kexec_core.c | 4 +++- 15 files changed, 39 insertions(+), 6 deletions(-)
arch/x86/crypto/Makefile +2 -0
@@ -2,6 +2,8 @@ # Arch-specific CryptoAPI modules. # +OBJECT_FILES_NON_STANDARD := y + avx_supported := $(call as-instr,vpxor %xmm0$(comma)%xmm0$(comma)%xmm0,yes,no) avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\ $(comma)4)$(comma)%ymm2,yes,no)
arch/x86/crypto/sha1-mb/Makefile +2 -0
@@ -2,6 +2,8 @@ # Arch-specific CryptoAPI modules. # +OBJECT_FILES_NON_STANDARD := y + avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\ $(comma)4)$(comma)%ymm2,yes,no) ifeq ($(avx2_supported),yes)
arch/x86/crypto/sha256-mb/Makefile +2 -0
@@ -2,6 +2,8 @@ # Arch-specific CryptoAPI modules. # +OBJECT_FILES_NON_STANDARD := y + avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\ $(comma)4)$(comma)%ymm2,yes,no) ifeq ($(avx2_supported),yes)
arch/x86/kernel/Makefile +1 -0
@@ -29,6 +29,7 @@ OBJECT_FILES_NON_STANDARD_head_$(BITS).o := y OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o := y OBJECT_FILES_NON_STANDARD_mcount_$(BITS).o := y OBJECT_FILES_NON_STANDARD_test_nx.o := y +OBJECT_FILES_NON_STANDARD_paravirt_patch_$(BITS).o := y # If instrumentation of this dir is enabled, boot hangs during first second. # Probably could be more selective here, but note that files related to irqs,
arch/x86/kernel/acpi/Makefile +2 -0
@@ -1,3 +1,5 @@ +OBJECT_FILES_NON_STANDARD_wakeup_$(BITS).o := y + obj-$(CONFIG_ACPI) += boot.o obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o obj-$(CONFIG_ACPI_APEI) += apei.o
arch/x86/kernel/kprobes/opt.c +8 -1
@@ -28,6 +28,7 @@#include <linux/kdebug.h> #include <linux/kallsyms.h> #include <linux/ftrace.h> +#include <linux/frame.h> #include <asm/text-patching.h> #include <asm/cacheflush.h>
@@ -91,6 +92,7 @@ static void synthesize_set_arg1(kprobe_opcode_t *addr, unsigned long val) } asm ( + "optprobe_template_func:\n" ".global optprobe_template_entry\n" "optprobe_template_entry:\n"#ifdef CONFIG_X86_64
@@ -128,7 +130,12 @@ asm (" popf\n" #endif".global optprobe_template_end\n" - "optprobe_template_end:\n"); +"optprobe_template_end:\n" +".type optprobe_template_func, @function\n" + ".size optprobe_template_func, .-optprobe_template_func\n"); + +void optprobe_template_func (void ); +STACK_FRAME_NON_STANDARD (optprobe_template_func);#define TMPL_MOVE_IDX \ ((long)&optprobe_template_val - (long)&optprobe_template_entry)
arch/x86/kernel/reboot.c +2 -0
@@ -9,6 +9,7 @@#include <linux/sched.h> #include <linux/tboot.h> #include <linux/delay.h> +#include <linux/frame.h> #include <acpi/reboot.h> #include <asm/io.h> #include <asm/apic.h>
@@ -127,6 +128,7 @@ void __noreturn machine_real_restart(unsigned int type)#ifdef CONFIG_APM_MODULE EXPORT_SYMBOL (machine_real_restart);#endif +STACK_FRAME_NON_STANDARD (machine_real_restart);/* * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot
arch/x86/kvm/svm.c +2 -0
@@ -36,6 +36,7 @@#include <linux/slab.h> #include <linux/amd-iommu.h> #include <linux/hashtable.h> +#include <linux/frame.h> #include <asm/apic.h> #include <asm/perf_event.h>
@@ -5111,6 +5112,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)mark_all_clean (svm->vmcb); } +STACK_FRAME_NON_STANDARD (svm_vcpu_run);static void svm_set_cr3 (struct kvm_vcpu *vcpu,unsigned long root) {
arch/x86/kvm/vmx.c +3 -0
@@ -33,6 +33,7 @@#include <linux/slab.h> #include <linux/tboot.h> #include <linux/hrtimer.h> +#include <linux/frame.h> #include <linux/nospec.h> #include "kvm_cache_regs.h" #include "x86.h"
@@ -8698,6 +8699,7 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu) ); } } +STACK_FRAME_NON_STANDARD (vmx_handle_external_intr);static bool vmx_has_emulated_msr (int index) {
@@ -9138,6 +9140,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)vmx_recover_nmi_blocking (vmx);vmx_complete_interrupts (vmx); } +STACK_FRAME_NON_STANDARD (vmx_vcpu_run);static void vmx_load_vmcs01 (struct kvm_vcpu *vcpu) {
arch/x86/lib/msr-reg.S +4 -4
@@ -13,14 +13,14 @@ .macro op_safe_regs op ENTRY(\op\()_safe_regs) pushq %rbx - pushq %rbp + pushq %r12 movq %rdi, %r10 /* Save pointer */ xorl %r11d, %r11d /* Return value */ movl (%rdi), %eax movl 4(%rdi), %ecx movl 8(%rdi), %edx movl 12(%rdi), %ebx - movl 20(%rdi), %ebp + movl 20(%rdi), %r12d movl 24(%rdi), %esi movl 28(%rdi), %edi 1: \op
@@ -29,10 +29,10 @@ ENTRY(\op\()_safe_regs) movl %ecx, 4(%r10) movl %edx, 8(%r10) movl %ebx, 12(%r10) - movl %ebp, 20(%r10) + movl %r12d, 20(%r10) movl %esi, 24(%r10) movl %edi, 28(%r10) - popq %rbp + popq %r12 popq %rbx ret 3:
arch/x86/net/Makefile +2 -0
@@ -1,4 +1,6 @@ # # Arch-specific network modules # +OBJECT_FILES_NON_STANDARD_bpf_jit.o += y + obj-$(CONFIG_BPF_JIT) += bpf_jit.o bpf_jit_comp.o
arch/x86/platform/efi/Makefile +1 -0
@@ -1,4 +1,5 @@ OBJECT_FILES_NON_STANDARD_efi_thunk_$(BITS).o := y +OBJECT_FILES_NON_STANDARD_efi_stub_$(BITS).o := y obj-$(CONFIG_EFI) += quirks.o efi.o efi_$(BITS).o efi_stub_$(BITS).o obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o
arch/x86/power/Makefile +2 -0
@@ -1,3 +1,5 @@ +OBJECT_FILES_NON_STANDARD_hibernate_asm_$(BITS).o := y + # __restore_processor_state() restores %gs after S3 resume and so should not # itself be stack-protected nostackp := $(call cc-option, -fno-stack-protector)
arch/x86/xen/Makefile +3 -0
@@ -1,3 +1,6 @@ +OBJECT_FILES_NON_STANDARD_xen-asm_$(BITS).o := y +OBJECT_FILES_NON_STANDARD_xen-pvh.o := y + ifdef CONFIG_FUNCTION_TRACER # Do not profile debug and lowlevel utilities CFLAGS_REMOVE_spinlock.o = -pg
kernel/kexec_core.c +3 -1
@@ -38,6 +38,7 @@#include <linux/syscore_ops.h> #include <linux/compiler.h> #include <linux/hugetlb.h> +#include <linux/frame.h> #include <asm/page.h> #include <asm/sections.h>
@@ -878,7 +879,7 @@ int kexec_load_disabled;* only when panic_cpu holds the current CPU number; this is the only CPU * which processes crash_kexec routines. */ -void __crash_kexec (struct pt_regs *regs) +void __noclone __crash_kexec (struct pt_regs *regs) {/* Take the kexec_mutex here to prevent sys_kexec_load * running on one cpu from replacing the crash kernel
@@ -900,6 +901,7 @@ void __crash_kexec(struct pt_regs *regs)mutex_unlock (&kexec_mutex); } } +STACK_FRAME_NON_STANDARD (__crash_kexec);void crash_kexec (struct pt_regs *regs) {
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 27/29 perf/tools: header file sync up
In reply to Greg Kroah-HartmanWhen building tools/perf/ it rightly complains about a number of .h files being out of sync. Fix this up by syncing them properly with the relevant in-kernel versions.
--- tools/arch/arm/include/uapi/asm/kvm.h | 13 ++ tools/arch/arm64/include/uapi/asm/kvm.h | 6 + tools/arch/powerpc/include/uapi/asm/kvm.h | 1 + tools/arch/s390/include/uapi/asm/kvm.h | 5 +- tools/arch/x86/include/asm/cpufeatures.h | 44 +++++- .../arch/x86/include/asm/disabled-features.h | 7 +- .../arch/x86/include/asm/required-features.h | 3 +- tools/include/uapi/asm-generic/mman-common.h | 5 + tools/include/uapi/linux/bpf.h | 51 +++++++ tools/include/uapi/linux/fcntl.h | 5 - tools/include/uapi/linux/stat.h | 131 ------------------ .../arch/x86/entry/syscalls/syscall_64.tbl | 7 +- 12 files changed, 132 insertions(+), 146 deletions(-)
tools/arch/arm/include/uapi/asm/kvm.h +13 -0
@@ -84,6 +84,13 @@ struct kvm_regs {#define KVM_VGIC_V2_DIST_SIZE 0x1000#define KVM_VGIC_V2_CPU_SIZE 0x2000 +/* Supported VGICv3 address types */ +#define KVM_VGIC_V3_ADDR_TYPE_DIST 2 +#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3 + +#define KVM_VGIC_V3_DIST_SIZE SZ_64K +#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K) +#define KVM_ARM_VCPU_POWER_OFF 0/* CPU is started in OFF state */ #define KVM_ARM_VCPU_PSCI_0_2 1/* CPU uses PSCI v0.2 */
@@ -166,6 +173,12 @@ struct kvm_arch_memory_slot {#define KVM_REG_ARM_VFP_FPINST 0x1009#define KVM_REG_ARM_VFP_FPINST2 0x100A +/* KVM-as-firmware specific pseudo-registers */ +#define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT) +#define KVM_REG_ARM_FW_REG (r) (KVM_REG_ARM | KVM_REG_SIZE_U64 | \ + KVM_REG_ARM_FW | ((r) & 0xffff)) +#define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0) +/* Device Control API: ARM VGIC */ #define KVM_DEV_ARM_VGIC_GRP_ADDR 0#define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
tools/arch/arm64/include/uapi/asm/kvm.h +6 -0
@@ -195,6 +195,12 @@ struct kvm_arch_memory_slot {#define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2)#define KVM_REG_ARM_TIMER_CVAL ARM64_SYS_REG(3, 3, 14, 0, 2) +/* KVM-as-firmware specific pseudo-registers */ +#define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT) +#define KVM_REG_ARM_FW_REG (r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ + KVM_REG_ARM_FW | ((r) & 0xffff)) +#define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0) +/* Device Control API: ARM VGIC */ #define KVM_DEV_ARM_VGIC_GRP_ADDR 0#define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
tools/arch/powerpc/include/uapi/asm/kvm.h +1 -0
@@ -596,6 +596,7 @@ struct kvm_get_htab_header {#define KVM_REG_PPC_TM_VSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U32 | 0x67)#define KVM_REG_PPC_TM_DSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x68)#define KVM_REG_PPC_TM_TAR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x69) +#define KVM_REG_PPC_TM_XER (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x6a)/* PPC64 eXternal Interrupt Controller Specification */ #define KVM_DEV_XICS_GRP_SOURCES 1/* 64-bit source attributes */
tools/arch/s390/include/uapi/asm/kvm.h +4 -1
@@ -197,6 +197,7 @@ struct kvm_guest_debug_arch {#define KVM_SYNC_VRS (1UL << 6)#define KVM_SYNC_RICCB (1UL << 7)#define KVM_SYNC_FPRS (1UL << 8) +#define KVM_SYNC_BPBC (1UL << 10)/* definition of registers in kvm_run */ struct kvm_sync_regs {__u64 prefix;/* prefix register */
@@ -217,7 +218,9 @@ struct kvm_sync_regs { };__u8 reserved[512 ];/* for future vector expansion */ __u32 fpc;/* valid on KVM_SYNC_VRS or KVM_SYNC_FPRS */ -__u8 padding[52 ];/* riccb needs to be 64byte aligned */ + __u8 bpbc : 1; /* bp mode */ + __u8 reserved2 : 7; +__u8 padding1[51 ];/* riccb needs to be 64byte aligned */ __u8 riccb[64 ];/* runtime instrumentation controls block */ };
tools/arch/x86/include/asm/cpufeatures.h +40 -4
86 lines not on this page · raw message
tools/arch/x86/include/asm/disabled-features.h +5 -2
@@ -21,11 +21,13 @@# define DISABLE_K6_MTRR (1<<(X86_FEATURE_K6_MTRR & 31))# define DISABLE_CYRIX_ARR (1<<(X86_FEATURE_CYRIX_ARR & 31))# define DISABLE_CENTAUR_MCR (1<<(X86_FEATURE_CENTAUR_MCR & 31)) +# define DISABLE_PCID 0#else # define DISABLE_VME 0# define DISABLE_K6_MTRR 0# define DISABLE_CYRIX_ARR 0# define DISABLE_CENTAUR_MCR 0 +# define DISABLE_PCID (1<<(X86_FEATURE_PCID & 31))#endif /* CONFIG_X86_64 */ #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
@@ -43,7 +45,7 @@#define DISABLED_MASK1 0#define DISABLED_MASK2 0#define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR) -#define DISABLED_MASK4 0 +#define DISABLED_MASK4 (DISABLE_PCID)#define DISABLED_MASK5 0#define DISABLED_MASK6 0#define DISABLED_MASK7 0
@@ -57,6 +59,7 @@#define DISABLED_MASK15 0#define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE)#define DISABLED_MASK17 0 -#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18) +#define DISABLED_MASK18 0 +#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)#endif /* _ASM_X86_DISABLED_FEATURES_H */
tools/arch/x86/include/asm/required-features.h +2 -1
@@ -100,6 +100,7 @@#define REQUIRED_MASK15 0#define REQUIRED_MASK16 0#define REQUIRED_MASK17 0 -#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18) +#define REQUIRED_MASK18 0 +#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)#endif /* _ASM_X86_REQUIRED_FEATURES_H */
tools/include/uapi/asm-generic/mman-common.h +5 -0
@@ -72,4 +72,9 @@#define MAP_HUGE_SHIFT 26#define MAP_HUGE_MASK 0x3f +#define PKEY_DISABLE_ACCESS 0x1 +#define PKEY_DISABLE_WRITE 0x2 +#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ + PKEY_DISABLE_WRITE) +#endif /* __ASM_GENERIC_MMAN_COMMON_H */
tools/include/uapi/linux/bpf.h +51 -0
63 lines not on this page · raw message
tools/include/uapi/linux/fcntl.h +0 -5
@@ -63,10 +63,5 @@#define AT_NO_AUTOMOUNT 0x800/* Suppress terminal automount traversal */ #define AT_EMPTY_PATH 0x1000/* Allow empty relative pathname */ -#define AT_STATX_SYNC_TYPE 0x6000/* Type of synchronisation required from statx() */ -#define AT_STATX_SYNC_AS_STAT 0x0000/* - Do whatever stat() does */ -#define AT_STATX_FORCE_SYNC 0x2000/* - Force the attributes to be sync'd with the server */ -#define AT_STATX_DONT_SYNC 0x4000/* - Don't sync attributes with the server */ -#endif /* _UAPI_LINUX_FCNTL_H */
tools/include/uapi/linux/stat.h +0 -131
142 lines not on this page · raw message
tools/perf/arch/x86/entry/syscalls/syscall_64.tbl +5 -2
@@ -335,6 +335,9 @@ 326 common copy_file_range sys_copy_file_range 327 64 preadv2 sys_preadv2 328 64 pwritev2 sys_pwritev2 +329 common pkey_mprotect sys_pkey_mprotect +330 common pkey_alloc sys_pkey_alloc +331 common pkey_free sys_pkey_free # # x32-specific system call numbers start at 512 to avoid cache impact
@@ -374,5 +377,5 @@ 543 x32 io_setup compat_sys_io_setup 544 x32 io_submit compat_sys_io_submit 545 x32 execveat compat_sys_execveat/ptregs -534 x32 preadv2 compat_sys_preadv2 -535 x32 pwritev2 compat_sys_pwritev2 +546 x32 preadv2 compat_sys_preadv64v2 +547 x32 pwritev2 compat_sys_pwritev64v2
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 28/29 objtool: header file sync-up
In reply to Greg Kroah-HartmanWhen building tools/objtool/ it rightly complains about a number of files being out of sync. Fix this up by syncing them properly with the relevant in-kernel versions.
--- tools/objtool/arch/x86/include/asm/inat.h | 10 ---------- tools/objtool/arch/x86/include/asm/orc_types.h | 2 +- tools/objtool/arch/x86/lib/x86-opcode-map.txt | 15 +++------------ .../objtool/arch/x86/tools/gen-insn-attr-x86.awk | 1 - 4 files changed, 4 insertions(+), 24 deletions(-)
tools/objtool/arch/x86/include/asm/inat.h +0 -10
@@ -97,16 +97,6 @@#define INAT_MAKE_GROUP (grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM)#define INAT_MAKE_IMM (imm) (imm << INAT_IMM_OFFS) -/* Identifiers for segment registers */ -#define INAT_SEG_REG_IGNORE 0 -#define INAT_SEG_REG_DEFAULT 1 -#define INAT_SEG_REG_CS 2 -#define INAT_SEG_REG_SS 3 -#define INAT_SEG_REG_DS 4 -#define INAT_SEG_REG_ES 5 -#define INAT_SEG_REG_FS 6 -#define INAT_SEG_REG_GS 7 -/* Attribute search APIs */ extern insn_attr_t inat_get_opcode_attribute (insn_byte_t opcode);extern int inat_get_last_prefix_id (insn_byte_t last_pfx);
tools/objtool/arch/x86/include/asm/orc_types.h +1 -1
@@ -88,7 +88,7 @@ struct orc_entry { unsigned sp_reg:4; unsigned bp_reg:4; unsigned type:2; -} __packed; +};/* * This struct is used by asm and inline asm code to manually annotate the
tools/objtool/arch/x86/lib/x86-opcode-map.txt +3 -12
@@ -607,7 +607,7 @@ fb: psubq Pq,Qq | vpsubq Vx,Hx,Wx (66),(v1) fc: paddb Pq,Qq | vpaddb Vx,Hx,Wx (66),(v1) fd: paddw Pq,Qq | vpaddw Vx,Hx,Wx (66),(v1) fe: paddd Pq,Qq | vpaddd Vx,Hx,Wx (66),(v1) -ff: UD0 +ff: EndTable Table: 3-byte opcode 1 (0x0f 0x38)
@@ -717,7 +717,7 @@ AVXcode: 2 7e: vpermt2d/q Vx,Hx,Wx (66),(ev) 7f: vpermt2ps/d Vx,Hx,Wx (66),(ev) 80: INVEPT Gy,Mdq (66) -81: INVVPID Gy,Mdq (66) +81: INVPID Gy,Mdq (66) 82: INVPCID Gy,Mdq (66) 83: vpmultishiftqb Vx,Hx,Wx (66),(ev) 88: vexpandps/d Vpd,Wpd (66),(ev)
@@ -970,15 +970,6 @@ GrpTable: Grp9 EndTable GrpTable: Grp10 -# all are UD1 -0: UD1 -1: UD1 -2: UD1 -3: UD1 -4: UD1 -5: UD1 -6: UD1 -7: UD1 EndTable # Grp11A and Grp11B are expressed as Grp11 in Intel SDM
@@ -1018,7 +1009,7 @@ GrpTable: Grp15 1: fxstor | RDGSBASE Ry (F3),(11B) 2: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B) 3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B) -4: XSAVE | ptwrite Ey (F3),(11B) +4: XSAVE 5: XRSTOR | lfence (11B) 6: XSAVEOPT | clwb (66) | mfence (11B) 7: clflush | clflushopt (66) | sfence (11B)
tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk +0 -1
@@ -1,5 +1,4 @@ #!/bin/awk -f -# SPDX-License-Identifier: GPL-2.0 # gen-insn-attr-x86.awk: Instruction attribute table generator # Written by Masami Hiramatsu <[email protected]> #
Signature · 1 line
2.17.1
Greg Kroah-Hartman
maintainerPATCH 29/29 x86/xen: Add unwind hint annotations to xen_setup_gdt
In reply to Greg Kroah-HartmanNot needed in mainline as this function got rewritten in 4.12
This enables objtool to grok the iret in the middle of a C function.
This matches commit 76846bf3cb09 ("x86/asm: Add unwind hint annotations to sync_core()")
--- arch/x86/xen/enlighten.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
arch/x86/xen/enlighten.c +4 -1
@@ -75,6 +75,7 @@#include <asm/mwait.h> #include <asm/pci_x86.h> #include <asm/cpu.h> +#include <asm/unwind_hints.h> #ifdef CONFIG_ACPI #include <linux/acpi.h>
@@ -1452,10 +1453,12 @@ static void __ref xen_setup_gdt(int cpu)* GDT. The new GDT has __KERNEL_CS with CS.L = 1 * and we are jumping to reload it. */ - asmvolatile ("pushq %0\n" + asmvolatile (UNWIND_HINT_SAVE +"pushq %0\n" "leaq 1f(%%rip),%0\n" "pushq %0\n" "lretq\n" +UNWIND_HINT_RESTORE "1:\n" :"=&r" (dummy) :"0" (__KERNEL_CS));
Signature · 1 line
2.17.1
Quoted 23 lines · Greg Kroah-Hartman
There are pros and cons of dealing with tools in the kernel directory. The pros are the fact that development happens fast, and new features can be added to the kernel and the tools at the same times. The cons are when dealing with backported kernel patches, it can be necessary to backport parts of the tool changes as well.
For 4.9.y so far, we have backported individual patches. That quickly breaks down when there are minor differences between how backports were handled, so grabbing 40+ patch long series can be difficult, not impossible, but really frustrating to attempt.
To help mitigate this mess, this patch series works to sync up the objtool code with the version that is currently in 4.14.47. This required a number of objtool old patches to be backported, a single big "sync the world" patch, and a lot of include file updates to get everything all working properly as well as some minor fixes for build warnings.
And at the end of this series, is a set of backported objtool patches for gcc-8 that was the main reason this whole patch series was created. They applied just fine, being the identical version that goes into the 4.14.y stable tree, so it feels like the backport was successful.
Quoted 6 lines
This has survivied my limited testing, and as the codebase is identical to 4.14.47, I'm pretty comfortable dropping this big change in here in 4.9.y. Hopefully all goes well...
If anyone has any objections to this patch series, or finds anything I messed up on, please let me know.
Thanks Greg. Looks good to me.
Signature · 1 line
Josh