diff options
author | Andrey Konovalov <andrey.konovalov@linaro.org> | 2014-05-15 17:09:01 +0400 |
---|---|---|
committer | Andrey Konovalov <andrey.konovalov@linaro.org> | 2014-05-15 17:09:01 +0400 |
commit | 5f647d339e4502aa8dcdbe38503109432027220f (patch) | |
tree | 2d8a557fce5a1b8506a821adaba694187dfdd12c | |
parent | aea97350c0b1f977e149df6a6afdadd8b87830da (diff) | |
parent | c71a08d692959cf5610016f414985061c937e9d9 (diff) |
Merge branch 'tracking-llvm' into merge-linux-linaro
46 files changed, 371 insertions, 189 deletions
@@ -396,10 +396,11 @@ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common \ -Werror-implicit-function-declaration \ -Wno-format-security \ + $(call cc-option,-no-integrated-as,) \ $(call cc-option,-fno-delete-null-pointer-checks,) KBUILD_AFLAGS_KERNEL := KBUILD_CFLAGS_KERNEL := -KBUILD_AFLAGS := -D__ASSEMBLY__ +KBUILD_AFLAGS := -D__ASSEMBLY__ $(call cc-option,-no-integrated-as,) KBUILD_AFLAGS_MODULE := -DMODULE KBUILD_CFLAGS_MODULE := -DMODULE KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds @@ -673,7 +674,7 @@ endif ifdef CONFIG_DEBUG_INFO KBUILD_CFLAGS += -g -KBUILD_AFLAGS += -Wa,--gdwarf-2 +KBUILD_AFLAGS += -Wa,-gdwarf-2 endif ifdef CONFIG_DEBUG_INFO_REDUCED diff --git a/arch/arm/Makefile b/arch/arm/Makefile index f77d085cb576..61a9932e6dec 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -23,6 +23,14 @@ OBJCOPYFLAGS :=-O binary -R .comment -S GZFLAGS :=-9 #KBUILD_CFLAGS +=-pipe +ifeq ($(COMPILER),clang) +# Clang options +ifneq ($(CROSS_COMPILE),) +KBUILD_CPPFLAGS += -target $(CROSS_COMPILE:-=) +endif +KBUILD_CFLAGS += -fno-builtin -Wno-asm-operand-widths -Xassembler -mno-warn-deprecated +endif + # Never generate .eh_frame KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) @@ -41,11 +49,11 @@ KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog endif ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) -KBUILD_CPPFLAGS += -mbig-endian +KBUILD_CPPFLAGS += $(call cc-option,-mbig-endian,) AS += -EB LD += -EB else -KBUILD_CPPFLAGS += -mlittle-endian +KBUILD_CPPFLAGS += $(call cc-option,-mlittle-endian,) AS += -EL LD += -EL endif @@ -96,7 +104,7 @@ tune-$(CONFIG_CPU_V6K) =$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) tune-y := $(tune-y) ifeq ($(CONFIG_AEABI),y) -CFLAGS_ABI :=-mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp +CFLAGS_ABI :=-mabi=aapcs-linux $(call cc-option,-mno-thumb-interwork,) -mfpu=vfp else CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,) endif @@ -120,7 +128,7 @@ AFLAGS_ISA :=$(CFLAGS_ISA) endif # Need -Uarm for gcc < 3.x -KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm +KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float $(call cc-option, -Uarm,) KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float CHECKFLAGS += -D__arm__ diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 68c918362b79..9aee36e74c9f 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -121,7 +121,7 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS) KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) endif -ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj) +ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin -I$(obj) asflags-y := -DZIMAGE # Supply kernel BSS size to the decompressor via a linker symbol. diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h index eb577f4f5f70..bca6f7fecd98 100644 --- a/arch/arm/include/asm/ftrace.h +++ b/arch/arm/include/asm/ftrace.h @@ -45,7 +45,7 @@ void *return_address(unsigned int); #else -extern inline void *return_address(unsigned int level) +static inline void *return_address(unsigned int level) { return NULL; } diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h index c81adc08b3fb..a3c24cd5b7c8 100644 --- a/arch/arm/include/asm/glue-cache.h +++ b/arch/arm/include/asm/glue-cache.h @@ -130,22 +130,22 @@ #endif #ifndef __ASSEMBLER__ -extern inline void nop_flush_icache_all(void) { } -extern inline void nop_flush_kern_cache_all(void) { } -extern inline void nop_flush_kern_cache_louis(void) { } -extern inline void nop_flush_user_cache_all(void) { } -extern inline void nop_flush_user_cache_range(unsigned long a, +static inline void nop_flush_icache_all(void) { } +static inline void nop_flush_kern_cache_all(void) { } +static inline void nop_flush_kern_cache_louis(void) { } +static inline void nop_flush_user_cache_all(void) { } +static inline void nop_flush_user_cache_range(unsigned long a, unsigned long b, unsigned int c) { } -extern inline void nop_coherent_kern_range(unsigned long a, unsigned long b) { } -extern inline int nop_coherent_user_range(unsigned long a, +static inline void nop_coherent_kern_range(unsigned long a, unsigned long b) { } +static inline int nop_coherent_user_range(unsigned long a, unsigned long b) { return 0; } -extern inline void nop_flush_kern_dcache_area(void *a, size_t s) { } +static inline void nop_flush_kern_dcache_area(void *a, size_t s) { } -extern inline void nop_dma_flush_range(const void *a, const void *b) { } +static inline void nop_dma_flush_range(const void *a, const void *b) { } -extern inline void nop_dma_map_area(const void *s, size_t l, int f) { } -extern inline void nop_dma_unmap_area(const void *s, size_t l, int f) { } +static inline void nop_dma_map_area(const void *s, size_t l, int f) { } +static inline void nop_dma_unmap_area(const void *s, size_t l, int f) { } #endif #ifndef MULTI_CACHE diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index c877654fe3bf..46800b1ecc8a 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -148,9 +148,9 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs) return regs->ARM_sp; } -#define current_pt_regs(void) ({ \ - register unsigned long sp asm ("sp"); \ - (struct pt_regs *)((sp | (THREAD_SIZE - 1)) - 7) - 1; \ +#define current_pt_regs(void) ({ \ + (struct pt_regs *)(((unsigned long)(__builtin_stack_pointer()) \ + | (THREAD_SIZE - 1)) - 7) - 1; \ }) #endif /* __ASSEMBLY__ */ diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index f989d7c22dc5..5d7ae3551233 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@ -100,14 +100,34 @@ struct thread_info { #define init_stack (init_thread_union.stack) /* + * how to get the current stack pointer in C + */ +#if defined(CONFIG_BUILTIN_STACK_POINTER) +/* compiler has __builtin_stack_pointer support already */ + +#elif defined(__clang__) +#define __builtin_stack_pointer() ({ \ + unsigned long current_sp; \ + asm ("mov %0, sp" : "=r" (current_sp)); \ + current_sp; \ +}) +#define current_stack_pointer __builtin_stack_pointer() + +#else /* gcc */ +register unsigned long current_stack_pointer asm ("sp"); +#define __builtin_stack_pointer() current_stack_pointer +#endif + +/* * how to get the thread information struct from C */ static inline struct thread_info *current_thread_info(void) __attribute_const__; static inline struct thread_info *current_thread_info(void) { - register unsigned long sp asm ("sp"); - return (struct thread_info *)(sp & ~(THREAD_SIZE - 1)); + return (struct thread_info *) + ((u32)(__builtin_stack_pointer()) + & ~(THREAD_SIZE - 1)); } #define thread_saved_pc(tsk) \ diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c index fafedd86885d..4dc8ecb26709 100644 --- a/arch/arm/kernel/return_address.c +++ b/arch/arm/kernel/return_address.c @@ -39,13 +39,12 @@ void *return_address(unsigned int level) { struct return_address_data data; struct stackframe frame; - register unsigned long current_sp asm ("sp"); data.level = level + 2; data.addr = NULL; frame.fp = (unsigned long)__builtin_frame_address(0); - frame.sp = current_sp; + frame.sp = __builtin_stack_pointer(); frame.lr = (unsigned long)__builtin_return_address(0); frame.pc = (unsigned long)return_address; @@ -63,11 +62,6 @@ void *return_address(unsigned int level) #warning "TODO: return_address should use unwind tables" #endif -void *return_address(unsigned int level) -{ - return NULL; -} - #endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) / else */ EXPORT_SYMBOL_GPL(return_address); diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index af4e8c8a5422..8b83eaf7e437 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c @@ -109,11 +109,9 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) frame.pc = thread_saved_pc(tsk); #endif } else { - register unsigned long current_sp asm ("sp"); - data.no_sched_functions = 0; frame.fp = (unsigned long)__builtin_frame_address(0); - frame.sp = current_sp; + frame.sp = __builtin_stack_pointer(); frame.lr = (unsigned long)__builtin_return_address(0); frame.pc = (unsigned long)save_stack_trace_tsk; } diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c index 3c217694ebec..67ba4bb9db89 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c @@ -31,7 +31,7 @@ #warning Your compiler does not have EABI support. #warning ARM unwind is known to compile only with EABI compilers. #warning Change compiler or disable ARM_UNWIND option. -#elif (__GNUC__ == 4 && __GNUC_MINOR__ <= 2) +#elif (__GNUC__ == 4 && __GNUC_MINOR__ <= 2) && !defined(__clang__) #warning Your compiler is too buggy; it is known to not compile ARM unwind support. #warning Change compiler or disable ARM_UNWIND option. #endif @@ -471,7 +471,6 @@ int unwind_frame(struct stackframe *frame) void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk) { struct stackframe frame; - register unsigned long current_sp asm ("sp"); pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); @@ -487,7 +486,7 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk) ? regs->ARM_pc : regs->ARM_lr; } else if (tsk == current) { frame.fp = (unsigned long)__builtin_frame_address(0); - frame.sp = current_sp; + frame.sp = __builtin_stack_pointer(); frame.lr = (unsigned long)__builtin_return_address(0); frame.pc = (unsigned long)unwind_backtrace; } else { diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 0573faab96ad..b585fcf2234a 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -15,6 +15,10 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ io-readsb.o io-writesb.o io-readsl.o io-writesl.o \ call_with_stack.o bswapsdi2.o +ifeq ($(COMPILER),clang) +lib-y += eabi.o +endif + mmu-y := clear_user.o copy_page.o getuser.o putuser.o # the code in uaccess.S is not preemption safe and diff --git a/arch/arm/lib/eabi.c b/arch/arm/lib/eabi.c new file mode 100644 index 000000000000..41b27b2f49b8 --- /dev/null +++ b/arch/arm/lib/eabi.c @@ -0,0 +1,32 @@ +/* + * linux/lib/eabi.c + * + * Copyright (C) 2012 Mark Charlebois + */ + +/* + * EABI routines + */ + +#include <linux/types.h> +#include <linux/string.h> +#include <linux/ctype.h> +#include <linux/export.h> + +void __aeabi_memcpy(void *dest, const void *src, size_t n) +{ + (void)memcpy(dest, src, n); +} +EXPORT_SYMBOL(__aeabi_memcpy); + +void __aeabi_memmove(void *dest, const void *src, size_t n) +{ + (void)memmove(dest, src, n); +} +EXPORT_SYMBOL(__aeabi_memmove); + +void __aeabi_memset(void *s, size_t n, int c) +{ + (void)memset(s, c, n); +} +EXPORT_SYMBOL(__aeabi_memset); diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 2fceb71ac3b7..c71005e9fb88 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -19,13 +19,20 @@ LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) KBUILD_DEFCONFIG := defconfig -KBUILD_CFLAGS += -mgeneral-regs-only -ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) -KBUILD_CPPFLAGS += -mbig-endian +ifeq ($(COMPILER),clang) +# Clang options +KBUILD_CPPFLAGS += $(call cc-option,-target $(CROSS_COMPILE:-=),) +KBUILD_CFLAGS += $(call cc-option,-fno-builtin,) +KBUILD_CFLAGS += $(call cc-disable-warning,asm-operand-widths) +endif + +KBUILD_CFLAGS += $(call cc-option,-mgeneral-regs-only,) +ifeq ($(CONFIG_CPU_BG_ENDIAN), y) +KBUILD_CPPFLAGS += $(call cc-option,-mbig-endian,) AS += -EB LD += -EB else -KBUILD_CPPFLAGS += -mlittle-endian +KBUILD_CPPFLAGS += $(call cc-option,-mlittle-endian,) AS += -EL LD += -EL endif diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index 9400596a0f39..622cbef5e10a 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -37,19 +37,19 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val) if (access == ARCH_TIMER_PHYS_ACCESS) { switch (reg) { case ARCH_TIMER_REG_CTRL: - asm volatile("msr cntp_ctl_el0, %0" : : "r" (val)); + asm volatile("msr cntp_ctl_el0, %0" : : "r" ((u64)val)); break; case ARCH_TIMER_REG_TVAL: - asm volatile("msr cntp_tval_el0, %0" : : "r" (val)); + asm volatile("msr cntp_tval_el0, %0" : : "r" ((u64)val)); break; } } else if (access == ARCH_TIMER_VIRT_ACCESS) { switch (reg) { case ARCH_TIMER_REG_CTRL: - asm volatile("msr cntv_ctl_el0, %0" : : "r" (val)); + asm volatile("msr cntv_ctl_el0, %0" : : "r" ((u64)val)); break; case ARCH_TIMER_REG_TVAL: - asm volatile("msr cntv_tval_el0, %0" : : "r" (val)); + asm volatile("msr cntv_tval_el0, %0" : : "r" ((u64)val)); break; } } @@ -60,7 +60,7 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val) static __always_inline u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) { - u32 val; + u64 val; if (access == ARCH_TIMER_PHYS_ACCESS) { switch (reg) { @@ -80,28 +80,30 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg) asm volatile("mrs %0, cntv_tval_el0" : "=r" (val)); break; } + } else { + BUG(); } - return val; + return (u32)val; } static inline u32 arch_timer_get_cntfrq(void) { - u32 val; + u64 val; asm volatile("mrs %0, cntfrq_el0" : "=r" (val)); - return val; + return (u32)val; } static inline u32 arch_timer_get_cntkctl(void) { - u32 cntkctl; + u64 cntkctl; asm volatile("mrs %0, cntkctl_el1" : "=r" (cntkctl)); - return cntkctl; + return (u32)cntkctl; } static inline void arch_timer_set_cntkctl(u32 cntkctl) { - asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl)); + asm volatile("msr cntkctl_el1, %0" : : "r" ((u64)cntkctl)); } static inline void arch_counter_set_user_access(void) diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h index 57c0fa7bf711..b331cf8ec812 100644 --- a/arch/arm64/include/asm/cmpxchg.h +++ b/arch/arm64/include/asm/cmpxchg.h @@ -64,6 +64,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size : "memory"); break; default: + ret = 0; BUILD_BUG(); } @@ -141,6 +142,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, break; default: + res = 0; BUILD_BUG(); } diff --git a/arch/arm64/include/asm/compiler.h b/arch/arm64/include/asm/compiler.h index ee35fd0f2236..d96919d1b731 100644 --- a/arch/arm64/include/asm/compiler.h +++ b/arch/arm64/include/asm/compiler.h @@ -27,4 +27,37 @@ */ #define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t" +#if defined(CONFIG_SMP) && !defined(CONFIG_CPU_V6) +/* + * Read TPIDRPRW. + * GCC requires a workaround as it does not treat a "memory" clobber on a + * non-volatile asm block as a side-effect. + * We want to allow caching the value, so for GCC avoid using volatile and + * instead use a fake stack read to hazard against barrier(). + */ +#if defined(__clang__) +static inline unsigned long read_TPIDRPRW(void) +{ + unsigned long off = 1; + + /* + * Read TPIDRPRW. + */ + // FIXME: asm("mrs %0, tpidr_el1" : "=r" (off) : : "memory"); + + return off; +} +#else +static inline unsigned long read_TPIDRPRW(void) +{ + unsigned long off; + register unsigned long *sp asm ("sp"); + + asm("mrs %0, tpidr_el1" : "=r" (off) : "Q" (*sp)); + + return off; +} +#endif +#endif + #endif /* __ASM_COMPILER_H */ diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h index 5f750dc96e0f..b6f979290563 100644 --- a/arch/arm64/include/asm/futex.h +++ b/arch/arm64/include/asm/futex.h @@ -108,7 +108,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, int ret = 0; u32 val, tmp; - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) + if (uaddr == 0 || !access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) return -EFAULT; asm volatile("// futex_atomic_cmpxchg_inatomic\n" diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h index 453a179469a3..5d510784804e 100644 --- a/arch/arm64/include/asm/percpu.h +++ b/arch/arm64/include/asm/percpu.h @@ -18,25 +18,14 @@ #ifdef CONFIG_SMP +#include "asm/compiler.h" + static inline void set_my_cpu_offset(unsigned long off) { asm volatile("msr tpidr_el1, %0" :: "r" (off) : "memory"); } -static inline unsigned long __my_cpu_offset(void) -{ - unsigned long off; - register unsigned long *sp asm ("sp"); - - /* - * We want to allow caching the value, so avoid using volatile and - * instead use a fake stack read to hazard against barrier(). - */ - asm("mrs %0, tpidr_el1" : "=r" (off) : "Q" (*sp)); - - return off; -} -#define __my_cpu_offset __my_cpu_offset() +#define __my_cpu_offset read_TPIDRPRW() #else /* !CONFIG_SMP */ diff --git a/arch/arm64/include/asm/spinlock.h b/arch/arm64/include/asm/spinlock.h index c45b7b1b7197..682508bb1456 100644 --- a/arch/arm64/include/asm/spinlock.h +++ b/arch/arm64/include/asm/spinlock.h @@ -58,7 +58,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) /* We got the lock. Critical section starts here. */ "3:" : "=&r" (lockval), "=&r" (newval), "=&r" (tmp), "+Q" (*lock) - : "Q" (lock->owner), "I" (1 << TICKET_SHIFT) + : "Q" (lock->owner), "r" (1 << TICKET_SHIFT) : "memory"); } @@ -77,7 +77,7 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) " cbnz %w1, 1b\n" "2:" : "=&r" (lockval), "=&r" (tmp), "+Q" (*lock) - : "I" (1 << TICKET_SHIFT) + : "r" (1 << TICKET_SHIFT) : "memory"); return !tmp; diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h index 0a8b2a97a32e..149563b5d908 100644 --- a/arch/arm64/include/asm/thread_info.h +++ b/arch/arm64/include/asm/thread_info.h @@ -69,14 +69,24 @@ struct thread_info { #define init_stack (init_thread_union.stack) /* + * how to get the current stack pointer from C + */ +#define current_stack_pointer ({ \ + unsigned long current_sp; \ + asm ("mov %0, sp" : "=r" (current_sp)); \ + current_sp; \ +}) + +/* * how to get the thread information struct from C */ static inline struct thread_info *current_thread_info(void) __attribute_const__; static inline struct thread_info *current_thread_info(void) { - register unsigned long sp asm ("sp"); - return (struct thread_info *)(sp & ~(THREAD_SIZE - 1)); + return (struct thread_info *) + ((u64)(__builtin_frame_address(0)) + & ~(THREAD_SIZE - 1)); } #define thread_saved_pc(tsk) \ diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h index 3bf8f4e99a51..104719b288fc 100644 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h @@ -93,7 +93,7 @@ static inline void set_fs(mm_segment_t fs) __chk_user_ptr(addr); \ asm("adds %1, %1, %3; ccmp %1, %4, #2, cc; cset %0, ls" \ : "=&r" (flag), "=&r" (roksum) \ - : "1" (addr), "Ir" (size), \ + : "1" (addr), "r" ((u64)size), \ "r" (current_thread_info()->addr_limit) \ : "cc"); \ flag; \ diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index a7fb874b595e..fa1dd29eb1a0 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c @@ -52,15 +52,15 @@ static void mdscr_write(u32 mdscr) { unsigned long flags; local_dbg_save(flags); - asm volatile("msr mdscr_el1, %0" :: "r" (mdscr)); + asm volatile("msr mdscr_el1, %0" :: "r" ((u64)mdscr)); local_dbg_restore(flags); } static u32 mdscr_read(void) { - u32 mdscr; + u64 mdscr; asm volatile("mrs %0, mdscr_el1" : "=r" (mdscr)); - return mdscr; + return (u32)mdscr; } /* @@ -136,7 +136,7 @@ void disable_debug_monitors(enum debug_el el) */ static void clear_os_lock(void *unused) { - asm volatile("msr oslar_el1, %0" : : "r" (0)); + asm volatile("msr oslar_el1, %0" : : "r" ((u64)0)); } static int os_lock_notify(struct notifier_block *self, diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index baf5afb7e6a0..4139373ccc1f 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -844,16 +844,16 @@ static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] static inline u32 armv8pmu_pmcr_read(void) { - u32 val; + u64 val; asm volatile("mrs %0, pmcr_el0" : "=r" (val)); - return val; + return (u32)val; } static inline void armv8pmu_pmcr_write(u32 val) { val &= ARMV8_PMCR_MASK; isb(); - asm volatile("msr pmcr_el0, %0" :: "r" (val)); + asm volatile("msr pmcr_el0, %0" :: "r" ((u64)val)); } static inline int armv8pmu_has_overflowed(u32 pmovsr) @@ -893,7 +893,7 @@ static inline int armv8pmu_select_counter(int idx) } counter = ARMV8_IDX_TO_COUNTER(idx); - asm volatile("msr pmselr_el0, %0" :: "r" (counter)); + asm volatile("msr pmselr_el0, %0" :: "r" ((u64)counter)); isb(); return idx; @@ -901,7 +901,7 @@ static inline int armv8pmu_select_counter(int idx) static inline u32 armv8pmu_read_counter(int idx) { - u32 value = 0; + u64 value = 0; if (!armv8pmu_counter_valid(idx)) pr_err("CPU%u reading wrong counter %d\n", @@ -911,7 +911,7 @@ static inline u32 armv8pmu_read_counter(int idx) else if (armv8pmu_select_counter(idx) == idx) asm volatile("mrs %0, pmxevcntr_el0" : "=r" (value)); - return value; + return (u32)value; } static inline void armv8pmu_write_counter(int idx, u32 value) @@ -920,16 +920,16 @@ static inline void armv8pmu_write_counter(int idx, u32 value) pr_err("CPU%u writing wrong counter %d\n", smp_processor_id(), idx); else if (idx == ARMV8_IDX_CYCLE_COUNTER) - asm volatile("msr pmccntr_el0, %0" :: "r" (value)); + asm volatile("msr pmccntr_el0, %0" :: "r" ((u64)value)); else if (armv8pmu_select_counter(idx) == idx) - asm volatile("msr pmxevcntr_el0, %0" :: "r" (value)); + asm volatile("msr pmxevcntr_el0, %0" :: "r" ((u64)value)); } static inline void armv8pmu_write_evtype(int idx, u32 val) { if (armv8pmu_select_counter(idx) == idx) { val &= ARMV8_EVTYPE_MASK; - asm volatile("msr pmxevtyper_el0, %0" :: "r" (val)); + asm volatile("msr pmxevtyper_el0, %0" :: "r" ((u64)val)); } } @@ -944,7 +944,7 @@ static inline int armv8pmu_enable_counter(int idx) } counter = ARMV8_IDX_TO_COUNTER(idx); - asm volatile("msr pmcntenset_el0, %0" :: "r" (BIT(counter))); + asm volatile("msr pmcntenset_el0, %0" :: "r" ((u64)BIT(counter))); return idx; } @@ -959,7 +959,7 @@ static inline int armv8pmu_disable_counter(int idx) } counter = ARMV8_IDX_TO_COUNTER(idx); - asm volatile("msr pmcntenclr_el0, %0" :: "r" (BIT(counter))); + asm volatile("msr pmcntenclr_el0, %0" :: "r" ((u64)BIT(counter))); return idx; } @@ -974,7 +974,7 @@ static inline int armv8pmu_enable_intens(int idx) } counter = ARMV8_IDX_TO_COUNTER(idx); - asm volatile("msr pmintenset_el1, %0" :: "r" (BIT(counter))); + asm volatile("msr pmintenset_el1, %0" :: "r" ((u64)BIT(counter))); return idx; } @@ -989,17 +989,17 @@ static inline int armv8pmu_disable_intens(int idx) } counter = ARMV8_IDX_TO_COUNTER(idx); - asm volatile("msr pmintenclr_el1, %0" :: "r" (BIT(counter))); + asm volatile("msr pmintenclr_el1, %0" :: "r" ((u64)BIT(counter))); isb(); /* Clear the overflow flag in case an interrupt is pending. */ - asm volatile("msr pmovsclr_el0, %0" :: "r" (BIT(counter))); + asm volatile("msr pmovsclr_el0, %0" :: "r" ((u64)BIT(counter))); isb(); return idx; } static inline u32 armv8pmu_getreset_flags(void) { - u32 value; + u64 value; /* Read */ asm volatile("mrs %0, pmovsclr_el0" : "=r" (value)); @@ -1008,7 +1008,7 @@ static inline u32 armv8pmu_getreset_flags(void) value &= ARMV8_OVSR_MASK; asm volatile("msr pmovsclr_el0, %0" :: "r" (value)); - return value; + return (u32)value; } static void armv8pmu_enable_event(struct hw_perf_event *hwc, int idx) @@ -1217,7 +1217,7 @@ static void armv8pmu_reset(void *info) armv8pmu_pmcr_write(ARMV8_PMCR_P | ARMV8_PMCR_C); /* Disable access from userspace. */ - asm volatile("msr pmuserenr_el0, %0" :: "r" (0)); + asm volatile("msr pmuserenr_el0, %0" :: "r" ((u64)0)); } static int armv8_pmuv3_map_event(struct perf_event *event) diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 55437ba1f5a4..407991bf79f5 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -111,10 +111,9 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) frame.sp = thread_saved_sp(tsk); frame.pc = thread_saved_pc(tsk); } else { - register unsigned long current_sp asm("sp"); data.no_sched_functions = 0; frame.fp = (unsigned long)__builtin_frame_address(0); - frame.sp = current_sp; + frame.sp = current_stack_pointer; frame.pc = (unsigned long)save_stack_trace_tsk; } diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 7ffadddb645d..44676523a879 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -132,7 +132,6 @@ static void dump_instr(const char *lvl, struct pt_regs *regs) static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) { struct stackframe frame; - const register unsigned long current_sp asm ("sp"); pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); @@ -145,7 +144,7 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) frame.pc = regs->pc; } else if (tsk == current) { frame.fp = (unsigned long)__builtin_frame_address(0); - frame.sp = current_sp; + frame.sp = current_stack_pointer; frame.pc = (unsigned long)dump_backtrace; } else { /* @@ -341,6 +340,15 @@ void __pgd_error(const char *file, int line, unsigned long val) printk("%s:%d: bad pgd %016lx.\n", file, line, val); } +void abort(void) +{ + BUG(); + + /* if that doesn't kill us, halt */ + panic("Oops failed to kill thread"); +} +EXPORT_SYMBOL(abort); + void __init trap_init(void) { return; diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile index d98d3e39879e..0d3407c4131a 100644 --- a/arch/arm64/lib/Makefile +++ b/arch/arm64/lib/Makefile @@ -3,3 +3,7 @@ lib-y := bitops.o clear_user.o delay.o copy_from_user.o \ clear_page.o memchr.o memcpy.o memmove.o memset.o \ memcmp.o strcmp.o strncmp.o strlen.o strnlen.o \ strchr.o strrchr.o + +ifeq ($(COMPILER),clang) +lib-y += eabi.o +endif diff --git a/arch/arm64/lib/eabi.c b/arch/arm64/lib/eabi.c new file mode 100644 index 000000000000..41b27b2f49b8 --- /dev/null +++ b/arch/arm64/lib/eabi.c @@ -0,0 +1,32 @@ +/* + * linux/lib/eabi.c + * + * Copyright (C) 2012 Mark Charlebois + */ + +/* + * EABI routines + */ + +#include <linux/types.h> +#include <linux/string.h> +#include <linux/ctype.h> +#include <linux/export.h> + +void __aeabi_memcpy(void *dest, const void *src, size_t n) +{ + (void)memcpy(dest, src, n); +} +EXPORT_SYMBOL(__aeabi_memcpy); + +void __aeabi_memmove(void *dest, const void *src, size_t n) +{ + (void)memmove(dest, src, n); +} +EXPORT_SYMBOL(__aeabi_memmove); + +void __aeabi_memset(void *s, size_t n, int c) +{ + (void)memset(s, c, n); +} +EXPORT_SYMBOL(__aeabi_memset); diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 0a472c41a67f..6fd757d03701 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -98,7 +98,7 @@ static int __init early_cachepolicy(char *p) */ asm volatile( " mrs %0, mair_el1\n" - " bfi %0, %1, #%2, #8\n" + " bfi %0, %1, %2, #8\n" " msr mair_el1, %0\n" " isb\n" : "=&r" (tmp) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 33f71b01fd22..6b564030fe57 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -19,11 +19,12 @@ endif # attempt to ensure that our asm(".code16gcc") is first in the asm # output. CODE16GCC_CFLAGS := -m32 -include $(srctree)/arch/x86/boot/code16gcc.h \ + $(call cc-option, -no-integrated-as,)\ $(call cc-option, -fno-toplevel-reorder,\ $(call cc-option, -fno-unit-at-a-time)) M16_CFLAGS := $(call cc-option, -m16, $(CODE16GCC_CFLAGS)) -REALMODE_CFLAGS := $(M16_CFLAGS) -g -Os -D__KERNEL__ \ +REALMODE_CFLAGS := $(CODE16GCC_CFLAGS) -g -Os -D__KERNEL__ \ -DDISABLE_BRANCH_PROFILING \ -Wall -Wstrict-prototypes -march=i386 -mregparm=3 \ -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index dbe8dd2fe247..8cc1aa8ed2c7 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -55,6 +55,15 @@ KBUILD_CFLAGS := $(USERINCLUDE) $(REALMODE_CFLAGS) -D_SETUP KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ GCOV_PROFILE := n + +# For clang we need to rely on no-integrated-as for .code16 . We use gas. +ifeq ($(COMPILER),clang) +KBUILD_CFLAGS += -Wno-unused-value -Wno-unused-parameter -mno-sse \ + $(call cc-option,-no-integrated-as,) +KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ +endif + + $(obj)/bzImage: asflags-y := $(SVGA_MODE) quiet_cmd_image = BUILD $@ diff --git a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c index db75d07c3645..7af65046dfad 100644 --- a/arch/x86/boot/memory.c +++ b/arch/x86/boot/memory.c @@ -63,8 +63,13 @@ static int detect_memory_e820(void) count = 0; break; } - +#ifdef __clang__ + /* PR18415 */ + memcpy(desc, &buf, sizeof(*desc)); + desc++; +#else *desc++ = buf; +#endif count++; } while (ireg.ebx && count < ARRAY_SIZE(boot_params.e820_map)); diff --git a/arch/x86/boot/string.h b/arch/x86/boot/string.h index 725e820602b1..3e07af1d80e3 100644 --- a/arch/x86/boot/string.h +++ b/arch/x86/boot/string.h @@ -14,8 +14,10 @@ int memcmp(const void *s1, const void *s2, size_t len); * Access builtin version by default. If one needs to use optimized version, * do "undef memcpy" in .c file and link against right string.c */ +#ifndef __clang__ /* PR18415 */ #define memcpy(d,s,l) __builtin_memcpy(d,s,l) #define memset(d,c,l) __builtin_memset(d,c,l) #define memcmp __builtin_memcmp +#endif #endif /* BOOT_STRING_H */ diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile index 3497f14e4dea..7e44536d6ab8 100644 --- a/arch/x86/realmode/rm/Makefile +++ b/arch/x86/realmode/rm/Makefile @@ -19,6 +19,14 @@ wakeup-objs += video-vga.o wakeup-objs += video-vesa.o wakeup-objs += video-bios.o +# For clang, we need to enforce not to use the integrated assembler +AFLAGS_wakeup_asm.o = $(call cc-option,-no-integrated-as,) +AFLAGS_bioscall.o = $(call cc-option,-no-integrated-as,) +AFLAGS_copy.o = $(call cc-option,-no-integrated-as,) +AFLAGS_trampoline_32.o = $(call cc-option,-no-integrated-as,) +AFLAGS_trampoline_64.o = $(call cc-option,-no-integrated-as,) +AFLAGS_reboot_32.o = $(call cc-option,-no-integrated-as,) + realmode-y += header.o realmode-y += trampoline_$(BITS).o realmode-y += stack.o diff --git a/arch/x86/um/ksyms.c b/arch/x86/um/ksyms.c index 2e8f43ec6214..04aedcecd887 100644 --- a/arch/x86/um/ksyms.c +++ b/arch/x86/um/ksyms.c @@ -4,7 +4,7 @@ #ifndef CONFIG_X86_32 /*XXX: we need them because they would be exported by x86_64 */ -#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 +#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 || defined(__clang__) EXPORT_SYMBOL(memcpy); #else EXPORT_SYMBOL(__memcpy); diff --git a/crypto/hmac.c b/crypto/hmac.c index 8d9544cf8169..10612555c44a 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -52,20 +52,19 @@ static int hmac_setkey(struct crypto_shash *parent, struct hmac_ctx *ctx = align_ptr(opad + ss, crypto_tfm_ctx_alignment()); struct crypto_shash *hash = ctx->hash; - struct { - struct shash_desc shash; - char ctx[crypto_shash_descsize(hash)]; - } desc; + char desc[sizeof(struct shash_desc) + crypto_shash_descsize(hash) + + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR; + struct shash_desc *shash = (struct shash_desc *)desc; unsigned int i; - desc.shash.tfm = hash; - desc.shash.flags = crypto_shash_get_flags(parent) & - CRYPTO_TFM_REQ_MAY_SLEEP; + shash->tfm = hash; + shash->flags = crypto_shash_get_flags(parent) + & CRYPTO_TFM_REQ_MAY_SLEEP; if (keylen > bs) { int err; - err = crypto_shash_digest(&desc.shash, inkey, keylen, ipad); + err = crypto_shash_digest(shash, inkey, keylen, ipad); if (err) return err; @@ -81,12 +80,12 @@ static int hmac_setkey(struct crypto_shash *parent, opad[i] ^= 0x5c; } - return crypto_shash_init(&desc.shash) ?: - crypto_shash_update(&desc.shash, ipad, bs) ?: - crypto_shash_export(&desc.shash, ipad) ?: - crypto_shash_init(&desc.shash) ?: - crypto_shash_update(&desc.shash, opad, bs) ?: - crypto_shash_export(&desc.shash, opad); + return crypto_shash_init(shash) ?: + crypto_shash_update(shash, ipad, bs) ?: + crypto_shash_export(shash, ipad) ?: + crypto_shash_init(shash) ?: + crypto_shash_update(shash, opad, bs) ?: + crypto_shash_export(shash, opad); } static int hmac_export(struct shash_desc *pdesc, void *out) diff --git a/crypto/shash.c b/crypto/shash.c index 929058a68561..47c713954bf3 100644 --- a/crypto/shash.c +++ b/crypto/shash.c @@ -67,7 +67,8 @@ EXPORT_SYMBOL_GPL(crypto_shash_setkey); static inline unsigned int shash_align_buffer_size(unsigned len, unsigned long mask) { - return len + (mask & ~(__alignof__(u8 __attribute__ ((aligned))) - 1)); + typedef u8 __attribute__ ((aligned)) u8_aligned; + return len + (mask & ~(__alignof__(u8_aligned) - 1)); } static int shash_update_unaligned(struct shash_desc *desc, const u8 *data, diff --git a/crypto/testmgr.c b/crypto/testmgr.c index dc3cf3535ef0..035af92cbe4a 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -1663,16 +1663,17 @@ static int alg_test_crc32c(const struct alg_test_desc *desc, } do { - struct { - struct shash_desc shash; - char ctx[crypto_shash_descsize(tfm)]; - } sdesc; + char sdesc[sizeof(struct shash_desc) + + crypto_shash_descsize(tfm) + + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR; + struct shash_desc *shash = (struct shash_desc *)sdesc; + u32 *ctx = (u32 *)shash_desc_ctx(shash); - sdesc.shash.tfm = tfm; - sdesc.shash.flags = 0; + shash->tfm = tfm; + shash->flags = 0; - *(u32 *)sdesc.ctx = le32_to_cpu(420553207); - err = crypto_shash_final(&sdesc.shash, (u8 *)&val); + *ctx = le32_to_cpu(420553207); + err = crypto_shash_final(shash, (u8 *)&val); if (err) { printk(KERN_ERR "alg: crc32c: Operation failed for " "%s: %d\n", driver, err); diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 784695d22fde..8b45281f3358 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -543,29 +543,29 @@ static int crypt_iv_lmk_one(struct crypt_config *cc, u8 *iv, u8 *data) { struct iv_lmk_private *lmk = &cc->iv_gen_private.lmk; - struct { - struct shash_desc desc; - char ctx[crypto_shash_descsize(lmk->hash_tfm)]; - } sdesc; + char sdesc[sizeof(struct shash_desc) + + crypto_shash_descsize(lmk->hash_tfm) + + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR; + struct shash_desc *desc = (struct shash_desc *)sdesc; struct md5_state md5state; __le32 buf[4]; int i, r; - sdesc.desc.tfm = lmk->hash_tfm; - sdesc.desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; + desc->tfm = lmk->hash_tfm; + desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; - r = crypto_shash_init(&sdesc.desc); + r = crypto_shash_init(desc); if (r) return r; if (lmk->seed) { - r = crypto_shash_update(&sdesc.desc, lmk->seed, LMK_SEED_SIZE); + r = crypto_shash_update(desc, lmk->seed, LMK_SEED_SIZE); if (r) return r; } /* Sector is always 512B, block size 16, add data of blocks 1-31 */ - r = crypto_shash_update(&sdesc.desc, data + 16, 16 * 31); + r = crypto_shash_update(desc, data + 16, 16 * 31); if (r) return r; @@ -574,12 +574,12 @@ static int crypt_iv_lmk_one(struct crypt_config *cc, u8 *iv, buf[1] = cpu_to_le32((((u64)dmreq->iv_sector >> 32) & 0x00FFFFFF) | 0x80000000); buf[2] = cpu_to_le32(4024); buf[3] = 0; - r = crypto_shash_update(&sdesc.desc, (u8 *)buf, sizeof(buf)); + r = crypto_shash_update(desc, (u8 *)buf, sizeof(buf)); if (r) return r; /* No MD5 padding here */ - r = crypto_shash_export(&sdesc.desc, &md5state); + r = crypto_shash_export(desc, &md5state); if (r) return r; diff --git a/fs/btrfs/hash.c b/fs/btrfs/hash.c index 85889aa82c62..110de4c7c7f8 100644 --- a/fs/btrfs/hash.c +++ b/fs/btrfs/hash.c @@ -33,18 +33,19 @@ void btrfs_hash_exit(void) u32 btrfs_crc32c(u32 crc, const void *address, unsigned int length) { - struct { - struct shash_desc shash; - char ctx[crypto_shash_descsize(tfm)]; - } desc; + char desc[sizeof(struct shash_desc) + + crypto_shash_descsize(tfm) + + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR; + struct shash_desc *shash = (struct shash_desc *)desc; + u32 *ctx = (u32 *)shash_desc_ctx(shash); int err; - desc.shash.tfm = tfm; - desc.shash.flags = 0; - *(u32 *)desc.ctx = crc; + shash->tfm = tfm; + shash->flags = 0; + *ctx = crc; - err = crypto_shash_update(&desc.shash, address, length); + err = crypto_shash_update(shash, address, length); BUG_ON(err); - return *(u32 *)desc.ctx; + return *ctx; } diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index e82289047272..c374c73bb795 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -810,7 +810,7 @@ static int compat_ioctl_preallocate(struct file *file, */ #define XFORM(i) (((i) ^ ((i) << 27) ^ ((i) << 17)) & 0xffffffff) -#define COMPATIBLE_IOCTL(cmd) XFORM(cmd), +#define COMPATIBLE_IOCTL(cmd) XFORM((u32)cmd), /* ioctl should not be warned about even if it's not implemented. Valid reasons to use this: - It is implemented with ->compat_ioctl on some device, but programs diff --git a/fs/mbcache.c b/fs/mbcache.c index bf166e388f0d..2c0752b59060 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c @@ -93,7 +93,7 @@ #define MB_CACHE_WRITER ((unsigned short)~0U >> 1) -#define MB_CACHE_ENTRY_LOCK_BITS __builtin_log2(NR_BG_LOCKS) +#define MB_CACHE_ENTRY_LOCK_BITS ilog2(NR_BG_LOCKS) #define MB_CACHE_ENTRY_LOCK_INDEX(ce) \ (hash_long((unsigned long)ce, MB_CACHE_ENTRY_LOCK_BITS)) diff --git a/lib/Makefile b/lib/Makefile index 0cd7b68e1382..e40bf4b378b8 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -46,7 +46,9 @@ obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o GCOV_PROFILE_hweight.o := n +ifneq ($(COMPILER),clang) CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS)) +endif obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o obj-$(CONFIG_BTREE) += btree.o diff --git a/lib/libcrc32c.c b/lib/libcrc32c.c index 244f5480c898..c155b3fc1be3 100644 --- a/lib/libcrc32c.c +++ b/lib/libcrc32c.c @@ -41,20 +41,20 @@ static struct crypto_shash *tfm; u32 crc32c(u32 crc, const void *address, unsigned int length) { - struct { - struct shash_desc shash; - char ctx[crypto_shash_descsize(tfm)]; - } desc; + char desc[sizeof(struct shash_desc) + crypto_shash_descsize(tfm) + + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR; + struct shash_desc *shash = (struct shash_desc *)desc; + u32 *ctx = (u32 *)shash_desc_ctx(shash); int err; - desc.shash.tfm = tfm; - desc.shash.flags = 0; - *(u32 *)desc.ctx = crc; + shash->tfm = tfm; + shash->flags = 0; + *ctx = crc; - err = crypto_shash_update(&desc.shash, address, length); + err = crypto_shash_update(shash, address, length); BUG_ON(err); - return *(u32 *)desc.ctx; + return *ctx; } EXPORT_SYMBOL(crc32c); diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c index 7c7df475a401..71e2abdab023 100644 --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c @@ -23,12 +23,12 @@ void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, u8 *data, size_t data_len, u8 *mic) { struct scatterlist assoc, pt, ct[2]; - struct { - struct aead_request req; - u8 priv[crypto_aead_reqsize(tfm)]; - } aead_req; - memset(&aead_req, 0, sizeof(aead_req)); + char aead_req_data[sizeof(struct aead_request) + + crypto_aead_reqsize(tfm)] + __aligned(__alignof__(struct aead_request)); + struct aead_request *aead_req = (void *) aead_req_data; + memset(aead_req, 0, sizeof(aead_req_data)); sg_init_one(&pt, data, data_len); sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad)); @@ -36,23 +36,22 @@ void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, sg_set_buf(&ct[0], data, data_len); sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN); - aead_request_set_tfm(&aead_req.req, tfm); - aead_request_set_assoc(&aead_req.req, &assoc, assoc.length); - aead_request_set_crypt(&aead_req.req, &pt, ct, data_len, b_0); + aead_request_set_tfm(aead_req, tfm); + aead_request_set_assoc(aead_req, &assoc, assoc.length); + aead_request_set_crypt(aead_req, &pt, ct, data_len, b_0); - crypto_aead_encrypt(&aead_req.req); + crypto_aead_encrypt(aead_req); } int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, u8 *data, size_t data_len, u8 *mic) { struct scatterlist assoc, pt, ct[2]; - struct { - struct aead_request req; - u8 priv[crypto_aead_reqsize(tfm)]; - } aead_req; - - memset(&aead_req, 0, sizeof(aead_req)); + char aead_req_data[sizeof(struct aead_request) + + crypto_aead_reqsize(tfm)] + __aligned(__alignof__(struct aead_request)); + struct aead_request *aead_req = (void *) aead_req_data; + memset(aead_req, 0, sizeof(aead_req_data)); sg_init_one(&pt, data, data_len); sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad)); @@ -60,12 +59,12 @@ int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, sg_set_buf(&ct[0], data, data_len); sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN); - aead_request_set_tfm(&aead_req.req, tfm); - aead_request_set_assoc(&aead_req.req, &assoc, assoc.length); - aead_request_set_crypt(&aead_req.req, ct, &pt, + aead_request_set_tfm(aead_req, tfm); + aead_request_set_assoc(aead_req, &assoc, assoc.length); + aead_request_set_crypt(aead_req, ct, &pt, data_len + IEEE80211_CCMP_MIC_LEN, b_0); - return crypto_aead_decrypt(&aead_req.req); + return crypto_aead_decrypt(aead_req); } struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[]) diff --git a/net/netfilter/xt_repldata.h b/net/netfilter/xt_repldata.h index 6efe4e5a81c6..8fd324116e6f 100644 --- a/net/netfilter/xt_repldata.h +++ b/net/netfilter/xt_repldata.h @@ -5,23 +5,35 @@ * they serve as the hanging-off data accessed through repl.data[]. */ +/* tbl has the following structure equivalent, but is C99 compliant: + * struct { + * struct type##_replace repl; + * struct type##_standard entries[nhooks]; + * struct type##_error term; + * } *tbl; + */ + #define xt_alloc_initial_table(type, typ2) ({ \ unsigned int hook_mask = info->valid_hooks; \ unsigned int nhooks = hweight32(hook_mask); \ unsigned int bytes = 0, hooknum = 0, i = 0; \ struct { \ struct type##_replace repl; \ - struct type##_standard entries[nhooks]; \ - struct type##_error term; \ - } *tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); \ + struct type##_standard entries[]; \ + } *tbl; \ + struct type##_error *term; \ + size_t term_offset = (offsetof(typeof(*tbl), entries[nhooks]) + \ + __alignof__(*term) - 1) & ~(__alignof__(*term) - 1); \ + tbl = kzalloc(term_offset + sizeof(*term), GFP_KERNEL); \ if (tbl == NULL) \ return NULL; \ + term = (struct type##_error *)&(((char *)tbl)[term_offset]); \ strncpy(tbl->repl.name, info->name, sizeof(tbl->repl.name)); \ - tbl->term = (struct type##_error)typ2##_ERROR_INIT; \ + *term = (struct type##_error)typ2##_ERROR_INIT; \ tbl->repl.valid_hooks = hook_mask; \ tbl->repl.num_entries = nhooks + 1; \ tbl->repl.size = nhooks * sizeof(struct type##_standard) + \ - sizeof(struct type##_error); \ + sizeof(struct type##_error); \ for (; hook_mask != 0; hook_mask >>= 1, ++hooknum) { \ if (!(hook_mask & 1)) \ continue; \ diff --git a/security/apparmor/crypto.c b/security/apparmor/crypto.c index 532471d0b3a0..7ab929f7f0a4 100644 --- a/security/apparmor/crypto.c +++ b/security/apparmor/crypto.c @@ -32,10 +32,10 @@ unsigned int aa_hash_size(void) int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start, size_t len) { - struct { - struct shash_desc shash; - char ctx[crypto_shash_descsize(apparmor_tfm)]; - } desc; + char desc[sizeof(struct shash_desc) + + crypto_shash_descsize(apparmor_tfm) + + CRYPTO_MINALIGN] CRYPTO_MINALIGN_ATTR; + struct shash_desc *shash = (struct shash_desc *)desc; int error = -ENOMEM; u32 le32_version = cpu_to_le32(version); @@ -46,19 +46,19 @@ int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start, if (!profile->hash) goto fail; - desc.shash.tfm = apparmor_tfm; - desc.shash.flags = 0; + shash->tfm = apparmor_tfm; + shash->flags = 0; - error = crypto_shash_init(&desc.shash); + error = crypto_shash_init(shash); if (error) goto fail; - error = crypto_shash_update(&desc.shash, (u8 *) &le32_version, 4); + error = crypto_shash_update(shash, (u8 *) &le32_version, 4); if (error) goto fail; - error = crypto_shash_update(&desc.shash, (u8 *) start, len); + error = crypto_shash_update(shash, (u8 *) start, len); if (error) goto fail; - error = crypto_shash_final(&desc.shash, profile->hash); + error = crypto_shash_final(shash, profile->hash); if (error) goto fail; |