Pull MIPS fixes from Paul Burton: "A collection of MIPS fixes: - Fill the struct cacheinfo shared_cpu_map field with sensible values, notably avoiding issues with perf which was unhappy in the absence of these values. - A boot fix for Loongson 2E & 2F machines which was fallout from some refactoring performed this cycle. - A Kconfig dependency fix for the Loongson CPU HWMon driver. - A couple of VDSO fixes, ensuring gettimeofday() behaves appropriately for kernel configurations that don't include support for a clocksource the VDSO can use & fixing the calling convention for the n32 & n64 VDSOs which would previously clobber the $gp/$28 register. - A build fix for vmlinuz compressed images which were inappropriately building with -fsanitize-coverage despite not being part of the kernel proper, then failing to link due to the missing __sanitizer_cov_trace_pc() function. - A couple of eBPF JIT fixes, including disabling it for MIPS32 due to a large number of issues with the code generated there & reflecting ISA dependencies in Kconfig to enforce that systems which don't support the JIT must include the interpreter" * tag 'mips_fixes_5.5_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: MIPS: Avoid VDSO ABI breakage due to global register variable MIPS: BPF: eBPF JIT: check for MIPS ISA compliance in Kconfig MIPS: BPF: Disable MIPS32 eBPF JIT MIPS: Prevent link failure with kcov instrumentation MIPS: Kconfig: Use correct form for 'depends on' mips: Fix gettimeofday() in the vdso library MIPS: Fix boot on Fuloong2 systems mips: cacheinfo: report shared CPU map
Unified · Split
| @@ -47,7 +47,7 @@ config MIPS · 46 unmodified lines | |||
| 47 | select HAVE_ARCH_TRACEHOOK | 47 | select HAVE_ARCH_TRACEHOOK |
| 48 | select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES | 48 | select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES |
| 49 | select HAVE_ASM_MODVERSIONS | 49 | select HAVE_ASM_MODVERSIONS |
| 50 | select HAVE_EBPF_JIT if (!CPU_MICROMIPS) | 50 | select HAVE_EBPF_JIT if 64BIT && !CPU_MICROMIPS && TARGET_ISA_REV >= 2 |
| 51 | select HAVE_CONTEXT_TRACKING | 51 | select HAVE_CONTEXT_TRACKING |
| 52 | select HAVE_COPY_THREAD_TLS | 52 | select HAVE_COPY_THREAD_TLS |
| 53 | select HAVE_C_RECORDMCOUNT | 53 | select HAVE_C_RECORDMCOUNT |
| @@ -29,6 +29,9 @@ KBUILD_AFLAGS := $(KBUILD_AFLAGS) -D__ASSEMBLY__ \ · 28 unmodified lines | |||
| 29 | -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \ | 29 | -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \ |
| 30 | -DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS) | 30 | -DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS) |
| 31 | 31 | ||
| 32 | # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. | ||
| 33 | KCOV_INSTRUMENT := n | ||
| 34 | |||
| 32 | # decompressor objects (linked with vmlinuz) | 35 | # decompressor objects (linked with vmlinuz) |
| 33 | vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o | 36 | vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o |
| 34 | 37 | ||
| @@ -15,7 +15,8 @@ · 14 unmodified lines | |||
| 15 | static inline int __pure __get_cpu_type(const int cpu_type) | 15 | static inline int __pure __get_cpu_type(const int cpu_type) |
| 16 | { | 16 | { |
| 17 | switch (cpu_type) { | 17 | switch (cpu_type) { |
| 18 | #if defined(CONFIG_SYS_HAS_CPU_LOONGSON2EF) | 18 | #if defined(CONFIG_SYS_HAS_CPU_LOONGSON2E) || \ |
| 19 | defined(CONFIG_SYS_HAS_CPU_LOONGSON2F) | ||
| 19 | case CPU_LOONGSON2EF: | 20 | case CPU_LOONGSON2EF: |
| 20 | #endif | 21 | #endif |
| 21 | 22 | ||
| @@ -49,8 +49,26 @@ struct thread_info { · 48 unmodified lines | |||
| 49 | .addr_limit = KERNEL_DS, \ | 49 | .addr_limit = KERNEL_DS, \ |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | /* How to get the thread information struct from C. */ | 52 | /* |
| 53 | * A pointer to the struct thread_info for the currently executing thread is | ||
| 54 | * held in register $28/$gp. | ||
| 55 | * | ||
| 56 | * We declare __current_thread_info as a global register variable rather than a | ||
| 57 | * local register variable within current_thread_info() because clang doesn't | ||
| 58 | * support explicit local register variables. | ||
| 59 | * | ||
| 60 | * When building the VDSO we take care not to declare the global register | ||
| 61 | * variable because this causes GCC to not preserve the value of $28/$gp in | ||
| 62 | * functions that change its value (which is common in the PIC VDSO when | ||
| 63 | * accessing the GOT). Since the VDSO shouldn't be accessing | ||
| 64 | * __current_thread_info anyway we declare it extern in order to cause a link | ||
| 65 | * failure if it's referenced. | ||
| 66 | */ | ||
| 67 | #ifdef __VDSO__ | ||
| 68 | extern struct thread_info *__current_thread_info; | ||
| 69 | #else | ||
| 53 | register struct thread_info *__current_thread_info __asm__("$28"); | 70 | register struct thread_info *__current_thread_info __asm__("$28"); |
| 71 | #endif | ||
| 54 | 72 | ||
| 55 | static inline struct thread_info *current_thread_info(void) | 73 | static inline struct thread_info *current_thread_info(void) |
| 56 | { | 74 | { |
| @@ -26,8 +26,6 @@ · 25 unmodified lines | |||
| 26 | 26 | ||
| 27 | #define __VDSO_USE_SYSCALL ULLONG_MAX | 27 | #define __VDSO_USE_SYSCALL ULLONG_MAX |
| 28 | 28 | ||
| 29 | #ifdef CONFIG_MIPS_CLOCK_VSYSCALL | ||
| 30 | |||
| 31 | static __always_inline long gettimeofday_fallback( | 29 | static __always_inline long gettimeofday_fallback( |
| 32 | struct __kernel_old_timeval *_tv, | 30 | struct __kernel_old_timeval *_tv, |
| 33 | struct timezone *_tz) | 31 | struct timezone *_tz) |
| @@ -48,17 +46,6 @@ static __always_inline long gettimeofday_fallback( · 14 unmodified lines | |||
| 48 | return error ? -ret : ret; | 46 | return error ? -ret : ret; |
| 49 | } | 47 | } |
| 50 | 48 | ||
| 51 | #else | ||
| 52 | |||
| 53 | static __always_inline long gettimeofday_fallback( | ||
| 54 | struct __kernel_old_timeval *_tv, | ||
| 55 | struct timezone *_tz) | ||
| 56 | { | ||
| 57 | return -1; | ||
| 58 | } | ||
| 59 | |||
| 60 | #endif | ||
| 61 | |||
| 62 | static __always_inline long clock_gettime_fallback( | 49 | static __always_inline long clock_gettime_fallback( |
| 63 | clockid_t _clkid, | 50 | clockid_t _clkid, |
| 64 | struct __kernel_timespec *_ts) | 51 | struct __kernel_timespec *_ts) |
| @@ -50,6 +50,25 @@ static int __init_cache_level(unsigned int cpu) · 49 unmodified lines | |||
| 50 | return 0; | 50 | return 0; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | static void fill_cpumask_siblings(int cpu, cpumask_t *cpu_map) | ||
| 54 | { | ||
| 55 | int cpu1; | ||
| 56 | |||
| 57 | for_each_possible_cpu(cpu1) | ||
| 58 | if (cpus_are_siblings(cpu, cpu1)) | ||
| 59 | cpumask_set_cpu(cpu1, cpu_map); | ||
| 60 | } | ||
| 61 | |||
| 62 | static void fill_cpumask_cluster(int cpu, cpumask_t *cpu_map) | ||
| 63 | { | ||
| 64 | int cpu1; | ||
| 65 | int cluster = cpu_cluster(&cpu_data[cpu]); | ||
| 66 | |||
| 67 | for_each_possible_cpu(cpu1) | ||
| 68 | if (cpu_cluster(&cpu_data[cpu1]) == cluster) | ||
| 69 | cpumask_set_cpu(cpu1, cpu_map); | ||
| 70 | } | ||
| 71 | |||
| 53 | static int __populate_cache_leaves(unsigned int cpu) | 72 | static int __populate_cache_leaves(unsigned int cpu) |
| 54 | { | 73 | { |
| 55 | struct cpuinfo_mips *c = ¤t_cpu_data; | 74 | struct cpuinfo_mips *c = ¤t_cpu_data; |
| @@ -57,14 +76,20 @@ static int __populate_cache_leaves(unsigned int cpu) · 1 unmodified line | |||
| 57 | struct cacheinfo *this_leaf = this_cpu_ci->info_list; | 76 | struct cacheinfo *this_leaf = this_cpu_ci->info_list; |
| 58 | 77 | ||
| 59 | if (c->icache.waysize) { | 78 | if (c->icache.waysize) { |
| 79 | /* L1 caches are per core */ | ||
| 80 | fill_cpumask_siblings(cpu, &this_leaf->shared_cpu_map); | ||
| 60 | populate_cache(dcache, this_leaf, 1, CACHE_TYPE_DATA); | 81 | populate_cache(dcache, this_leaf, 1, CACHE_TYPE_DATA); |
| 82 | fill_cpumask_siblings(cpu, &this_leaf->shared_cpu_map); | ||
| 61 | populate_cache(icache, this_leaf, 1, CACHE_TYPE_INST); | 83 | populate_cache(icache, this_leaf, 1, CACHE_TYPE_INST); |
| 62 | } else { | 84 | } else { |
| 63 | populate_cache(dcache, this_leaf, 1, CACHE_TYPE_UNIFIED); | 85 | populate_cache(dcache, this_leaf, 1, CACHE_TYPE_UNIFIED); |
| 64 | } | 86 | } |
| 65 | 87 | ||
| 66 | if (c->scache.waysize) | 88 | if (c->scache.waysize) { |
| 89 | /* L2 cache is per cluster */ | ||
| 90 | fill_cpumask_cluster(cpu, &this_leaf->shared_cpu_map); | ||
| 67 | populate_cache(scache, this_leaf, 2, CACHE_TYPE_UNIFIED); | 91 | populate_cache(scache, this_leaf, 2, CACHE_TYPE_UNIFIED); |
| 92 | } | ||
| 68 | 93 | ||
| 69 | if (c->tcache.waysize) | 94 | if (c->tcache.waysize) |
| 70 | populate_cache(tcache, this_leaf, 3, CACHE_TYPE_UNIFIED); | 95 | populate_cache(tcache, this_leaf, 3, CACHE_TYPE_UNIFIED); |
| @@ -1804,7 +1804,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) · 1803 unmodified lines | |||
| 1804 | unsigned int image_size; | 1804 | unsigned int image_size; |
| 1805 | u8 *image_ptr; | 1805 | u8 *image_ptr; |
| 1806 | 1806 | ||
| 1807 | if (!prog->jit_requested || MIPS_ISA_REV < 2) | 1807 | if (!prog->jit_requested) |
| 1808 | return prog; | 1808 | return prog; |
| 1809 | 1809 | ||
| 1810 | tmp = bpf_jit_blind_constants(prog); | 1810 | tmp = bpf_jit_blind_constants(prog); |
| @@ -17,12 +17,22 @@ int __vdso_clock_gettime(clockid_t clock, · 16 unmodified lines | |||
| 17 | return __cvdso_clock_gettime32(clock, ts); | 17 | return __cvdso_clock_gettime32(clock, ts); |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | #ifdef CONFIG_MIPS_CLOCK_VSYSCALL | ||
| 21 | |||
| 22 | /* | ||
| 23 | * This is behind the ifdef so that we don't provide the symbol when there's no | ||
| 24 | * possibility of there being a usable clocksource, because there's nothing we | ||
| 25 | * can do without it. When libc fails the symbol lookup it should fall back on | ||
| 26 | * the standard syscall path. | ||
| 27 | */ | ||
| 20 | int __vdso_gettimeofday(struct __kernel_old_timeval *tv, | 28 | int __vdso_gettimeofday(struct __kernel_old_timeval *tv, |
| 21 | struct timezone *tz) | 29 | struct timezone *tz) |
| 22 | { | 30 | { |
| 23 | return __cvdso_gettimeofday(tv, tz); | 31 | return __cvdso_gettimeofday(tv, tz); |
| 24 | } | 32 | } |
| 25 | 33 | ||
| 34 | #endif /* CONFIG_MIPS_CLOCK_VSYSCALL */ | ||
| 35 | |||
| 26 | int __vdso_clock_getres(clockid_t clock_id, | 36 | int __vdso_clock_getres(clockid_t clock_id, |
| 27 | struct old_timespec32 *res) | 37 | struct old_timespec32 *res) |
| 28 | { | 38 | { |
| @@ -43,12 +53,22 @@ int __vdso_clock_gettime(clockid_t clock, · 14 unmodified lines | |||
| 43 | return __cvdso_clock_gettime(clock, ts); | 53 | return __cvdso_clock_gettime(clock, ts); |
| 44 | } | 54 | } |
| 45 | 55 | ||
| 56 | #ifdef CONFIG_MIPS_CLOCK_VSYSCALL | ||
| 57 | |||
| 58 | /* | ||
| 59 | * This is behind the ifdef so that we don't provide the symbol when there's no | ||
| 60 | * possibility of there being a usable clocksource, because there's nothing we | ||
| 61 | * can do without it. When libc fails the symbol lookup it should fall back on | ||
| 62 | * the standard syscall path. | ||
| 63 | */ | ||
| 46 | int __vdso_gettimeofday(struct __kernel_old_timeval *tv, | 64 | int __vdso_gettimeofday(struct __kernel_old_timeval *tv, |
| 47 | struct timezone *tz) | 65 | struct timezone *tz) |
| 48 | { | 66 | { |
| 49 | return __cvdso_gettimeofday(tv, tz); | 67 | return __cvdso_gettimeofday(tv, tz); |
| 50 | } | 68 | } |
| 51 | 69 | ||
| 70 | #endif /* CONFIG_MIPS_CLOCK_VSYSCALL */ | ||
| 71 | |||
| 52 | int __vdso_clock_getres(clockid_t clock_id, | 72 | int __vdso_clock_getres(clockid_t clock_id, |
| 53 | struct __kernel_timespec *res) | 73 | struct __kernel_timespec *res) |
| 54 | { | 74 | { |
| @@ -18,7 +18,7 @@ if MIPS_PLATFORM_DEVICES · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | config CPU_HWMON | 19 | config CPU_HWMON |
| 20 | tristate "Loongson-3 CPU HWMon Driver" | 20 | tristate "Loongson-3 CPU HWMon Driver" |
| 21 | depends on CONFIG_MACH_LOONGSON64 | 21 | depends on MACH_LOONGSON64 |
| 22 | select HWMON | 22 | select HWMON |
| 23 | default y | 23 | default y |
| 24 | help | 24 | help |