Skip to content

Commit

Permalink
Merge branches 'fixes' and 'misc'
Browse files Browse the repository at this point in the history
Fix up the conflict between "VDSO: Drop implicit common-page-size
linker flag" and "vdso: pass --be8 to linker if necessary"

Signed-off-by: Russell King <[email protected]>
  • Loading branch information
Russell King committed Jul 8, 2019
2 parents c5d0e49 + f785b42 commit 5ccd3bd
Show file tree
Hide file tree
Showing 14 changed files with 107 additions and 19 deletions.
30 changes: 30 additions & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1175,6 +1175,14 @@ config ARM_ERRATA_825619
DMB NSHST or DMB ISHST instruction followed by a mix of Cacheable
and Device/Strongly-Ordered loads and stores might cause deadlock

config ARM_ERRATA_857271
bool "ARM errata: A12: CPU might deadlock under some very rare internal conditions"
depends on CPU_V7
help
This option enables the workaround for the 857271 Cortex-A12
(all revs) erratum. Under very rare timing conditions, the CPU might
hang. The workaround is expected to have a < 1% performance impact.

config ARM_ERRATA_852421
bool "ARM errata: A17: DMB ST might fail to create order between stores"
depends on CPU_V7
Expand All @@ -1196,6 +1204,16 @@ config ARM_ERRATA_852423
config option from the A12 erratum due to the way errata are checked
for and handled.

config ARM_ERRATA_857272
bool "ARM errata: A17: CPU might deadlock under some very rare internal conditions"
depends on CPU_V7
help
This option enables the workaround for the 857272 Cortex-A17 erratum.
This erratum is not known to be fixed in any A17 revision.
This is identical to Cortex-A12 erratum 857271. It is a separate
config option from the A12 erratum due to the way errata are checked
for and handled.

endmenu

source "arch/arm/common/Kconfig"
Expand Down Expand Up @@ -1232,6 +1250,18 @@ config PCI_HOST_ITE8152
default y
select DMABOUNCE

config ARM_ERRATA_814220
bool "ARM errata: Cache maintenance by set/way operations can execute out of order"
depends on CPU_V7
help
The v7 ARM states that all cache and branch predictor maintenance
operations that do not specify an address execute, relative to
each other, in program order.
However, because of this erratum, an L2 set/way cache maintenance
operation can overtake an L1 set/way cache maintenance operation.
This ERRATA only affected the Cortex-A7 and present in r0p2, r0p3,
r0p4, r0p5.

endmenu

menu "Kernel Features"
Expand Down
1 change: 1 addition & 0 deletions arch/arm/configs/exynos_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ CONFIG_MODULE_UNLOAD=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_EXYNOS=y
CONFIG_ARCH_EXYNOS3=y
CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND=y
CONFIG_SMP=y
CONFIG_BIG_LITTLE=y
CONFIG_NR_CPUS=8
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/include/asm/bug.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int,
extern asmlinkage void c_backtrace(unsigned long fp, int pmode);

struct mm_struct;
extern void show_pte(struct mm_struct *mm, unsigned long addr);
void show_pte(const char *lvl, struct mm_struct *mm, unsigned long addr);
extern void __show_regs(struct pt_regs *);

#endif
7 changes: 7 additions & 0 deletions arch/arm/include/asm/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -479,4 +479,11 @@ static inline void __sync_cache_range_r(volatile void *p, size_t size)
void flush_uprobe_xol_access(struct page *page, unsigned long uaddr,
void *kaddr, unsigned long len);


#ifdef CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND
void check_cpu_icache_size(int cpuid);
#else
static inline void check_cpu_icache_size(int cpuid) { }
#endif

#endif
1 change: 1 addition & 0 deletions arch/arm/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ static void smp_store_cpu_info(unsigned int cpuid)
cpu_info->cpuid = read_cpuid_id();

store_cpu_topology(cpuid);
check_cpu_icache_size(cpuid);
}

/*
Expand Down
3 changes: 2 additions & 1 deletion arch/arm/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,10 +725,11 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)

#ifdef CONFIG_DEBUG_USER
if (user_debug & UDBG_BADABORT) {
pr_err("8<--- cut here ---\n");
pr_err("[%d] %s: bad data abort: code %d instr 0x%08lx\n",
task_pid_nr(current), current->comm, code, instr);
dump_instr(KERN_ERR, regs);
show_pte(current->mm, addr);
show_pte(KERN_ERR, current->mm, addr);
}
#endif

Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-stm32/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ if ARCH_MULTI_V7

config MACH_STM32MP157
bool "STMicroelectronics STM32MP157"
select ARM_ERRATA_814220
default y

endif # ARMv7-A
Expand Down
8 changes: 8 additions & 0 deletions arch/arm/mm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,14 @@ config CPU_ICACHE_DISABLE
Say Y here to disable the processor instruction cache. Unless
you have a reason not to or are unsure, say N.

config CPU_ICACHE_MISMATCH_WORKAROUND
bool "Workaround for I-Cache line size mismatch between CPU cores"
depends on SMP && CPU_V7
help
Some big.LITTLE systems have I-Cache line size mismatch between
LITTLE and big cores. Say Y here to enable a workaround for
proper I-Cache support on such systems. If unsure, say N.

config CPU_DCACHE_DISABLE
bool "Disable D-Cache (C-bit)"
depends on (CPU_CP15 && !SMP) || CPU_V7M
Expand Down
16 changes: 16 additions & 0 deletions arch/arm/mm/cache-v7.S
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@

#include "proc-macros.S"

#ifdef CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND
.globl icache_size
.data
.align 2
icache_size:
.long 64
.text
#endif
/*
* The secondary kernel init calls v7_flush_dcache_all before it enables
* the L1; however, the L1 comes out of reset in an undefined state, so
Expand Down Expand Up @@ -163,6 +171,9 @@ loop2:
skip:
add r10, r10, #2 @ increment cache number
cmp r3, r10
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
bgt flush_levels
finished:
mov r10, #0 @ switch back to cache level 0
Expand Down Expand Up @@ -284,7 +295,12 @@ ENTRY(v7_coherent_user_range)
cmp r12, r1
blo 1b
dsb ishst
#ifdef CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND
ldr r3, =icache_size
ldr r2, [r3, #0]
#else
icache_line_size r2, r3
#endif
sub r3, r2, #1
bic r12, r0, r3
2:
Expand Down
20 changes: 11 additions & 9 deletions arch/arm/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,16 @@ static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr)
* This is useful to dump out the page tables associated with
* 'addr' in mm 'mm'.
*/
void show_pte(struct mm_struct *mm, unsigned long addr)
void show_pte(const char *lvl, struct mm_struct *mm, unsigned long addr)
{
pgd_t *pgd;

if (!mm)
mm = &init_mm;

pr_alert("pgd = %p\n", mm->pgd);
printk("%spgd = %p\n", lvl, mm->pgd);
pgd = pgd_offset(mm, addr);
pr_alert("[%08lx] *pgd=%08llx",
addr, (long long)pgd_val(*pgd));
printk("%s[%08lx] *pgd=%08llx", lvl, addr, (long long)pgd_val(*pgd));

do {
pud_t *pud;
Expand Down Expand Up @@ -121,7 +120,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
pr_cont("\n");
}
#else /* CONFIG_MMU */
void show_pte(struct mm_struct *mm, unsigned long addr)
void show_pte(const char *lvl, struct mm_struct *mm, unsigned long addr)
{ }
#endif /* CONFIG_MMU */

Expand All @@ -142,11 +141,12 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
* No handler, we'll have to terminate things with extreme prejudice.
*/
bust_spinlocks(1);
pr_alert("8<--- cut here ---\n");
pr_alert("Unable to handle kernel %s at virtual address %08lx\n",
(addr < PAGE_SIZE) ? "NULL pointer dereference" :
"paging request", addr);

show_pte(mm, addr);
show_pte(KERN_ALERT, mm, addr);
die("Oops", regs, fsr);
bust_spinlocks(0);
do_exit(SIGKILL);
Expand All @@ -167,9 +167,10 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
#ifdef CONFIG_DEBUG_USER
if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) ||
((user_debug & UDBG_BUS) && (sig == SIGBUS))) {
printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n",
pr_err("8<--- cut here ---\n");
pr_err("%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n",
tsk->comm, sig, addr, fsr);
show_pte(tsk->mm, addr);
show_pte(KERN_ERR, tsk->mm, addr);
show_regs(regs);
}
#endif
Expand Down Expand Up @@ -556,9 +557,10 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs))
return;

pr_alert("8<--- cut here ---\n");
pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n",
inf->name, fsr, addr);
show_pte(current->mm, addr);
show_pte(KERN_ALERT, current->mm, addr);

arm_notify_die("", regs, inf->sig, inf->code, (void __user *)addr,
fsr, 0);
Expand Down
22 changes: 16 additions & 6 deletions arch/arm/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,22 @@ static void __init arm_initrd_init(void)
#endif
}

#ifdef CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND
void check_cpu_icache_size(int cpuid)
{
u32 size, ctr;

asm("mrc p15, 0, %0, c0, c0, 1" : "=r" (ctr));

size = 1 << ((ctr & 0xf) + 2);
if (cpuid != 0 && icache_size != size)
pr_info("CPU%u: detected I-Cache line size mismatch, workaround enabled\n",
cpuid);
if (icache_size > size)
icache_size = size;
}
#endif

void __init arm_memblock_init(const struct machine_desc *mdesc)
{
/* Register the kernel text, kernel data and initrd with memblock. */
Expand Down Expand Up @@ -450,12 +466,6 @@ static void __init free_highpages(void)
*/
void __init mem_init(void)
{
#ifdef CONFIG_HAVE_TCM
/* These pointers are filled in on TCM detection */
extern u32 dtcm_end;
extern u32 itcm_end;
#endif

set_max_mapnr(pfn_to_page(max_pfn) - mem_map);

/* this will put all unused low memory onto the freelists */
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/mm/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
/* the upper-most page table pointer */
extern pmd_t *top_pmd;

extern int icache_size;

/*
* 0xffff8000 to 0xffffffff is reserved for any ARM architecture
* specific hacks for copying pages efficiently, while 0xffff4000
Expand Down
10 changes: 10 additions & 0 deletions arch/arm/mm/proc-v7.S
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,11 @@ __ca12_errata:
mrc p15, 0, r10, c15, c0, 1 @ read diagnostic register
orr r10, r10, #1 << 24 @ set bit #24
mcr p15, 0, r10, c15, c0, 1 @ write diagnostic register
#endif
#ifdef CONFIG_ARM_ERRATA_857271
mrc p15, 0, r10, c15, c0, 1 @ read diagnostic register
orr r10, r10, #3 << 10 @ set bits #10 and #11
mcr p15, 0, r10, c15, c0, 1 @ write diagnostic register
#endif
b __errata_finish

Expand All @@ -406,6 +411,11 @@ __ca17_errata:
mrcle p15, 0, r10, c15, c0, 1 @ read diagnostic register
orrle r10, r10, #1 << 12 @ set bit #12
mcrle p15, 0, r10, c15, c0, 1 @ write diagnostic register
#endif
#ifdef CONFIG_ARM_ERRATA_857272
mrc p15, 0, r10, c15, c0, 1 @ read diagnostic register
orr r10, r10, #3 << 10 @ set bits #10 and #11
mcr p15, 0, r10, c15, c0, 1 @ write diagnostic register
#endif
b __errata_finish

Expand Down
3 changes: 1 addition & 2 deletions arch/arm/vdso/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ ccflags-y += -DDISABLE_BRANCH_PROFILING

ldflags-$(CONFIG_CPU_ENDIAN_BE8) := --be8
ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \
-z max-page-size=4096 -z common-page-size=4096 \
-nostdlib -shared $(ldflags-y) \
-z max-page-size=4096 -nostdlib -shared $(ldflags-y) \
$(call ld-option, --hash-style=sysv) \
$(call ld-option, --build-id) \
-T
Expand Down

0 comments on commit 5ccd3bd

Please sign in to comment.