Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARCv2: Add explcit unaligned access support (and ability to disable too)

As of today we enable unaligned access unconditionally on ARCv2.
Do this under a Kconfig option to allow disable it for test, benchmarking
etc. Also while at it

- Select HAVE_EFFICIENT_UNALIGNED_ACCESS
- Although gcc defaults to unaligned access (since GNU 2018.03), add the
right toggles for enabling or disabling as appropriate
- update bootlog to prints both HW feature status (exists, enabled/disabled)
and SW status (used / not used).
- wire up the relaxed memcpy for unaligned access

Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
[vgupta: squashed patches, handle gcc -mno-unaligned-access quick]

authored by

Eugeniy Paltsev and committed by
Vineet Gupta
76551468 4d1e7918

+57 -14
+9
arch/arc/Kconfig
··· 386 386 387 387 if ISA_ARCV2 388 388 389 + config ARC_USE_UNALIGNED_MEM_ACCESS 390 + bool "Enable unaligned access in HW" 391 + default y 392 + select HAVE_EFFICIENT_UNALIGNED_ACCESS 393 + help 394 + The ARC HS architecture supports unaligned memory access 395 + which is disabled by default. Enable unaligned access in 396 + hardware and use software to use it 397 + 389 398 config ARC_HAS_LL64 390 399 bool "Insn: 64bit LDD/STD" 391 400 help
+6
arch/arc/Makefile
··· 28 28 29 29 ifdef CONFIG_ISA_ARCV2 30 30 31 + ifdef CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS 32 + cflags-y += -munaligned-access 33 + else 34 + cflags-y += -mno-unaligned-access 35 + endif 36 + 31 37 ifndef CONFIG_ARC_HAS_LL64 32 38 cflags-y += -mno-ll64 33 39 endif
+1
arch/arc/include/asm/arcregs.h
··· 82 82 #define ECR_V_DTLB_MISS 0x05 83 83 #define ECR_V_PROTV 0x06 84 84 #define ECR_V_TRAP 0x09 85 + #define ECR_V_MISALIGN 0x0d 85 86 #endif 86 87 87 88 /* DTLB Miss and Protection Violation Cause Codes */
+7 -1
arch/arc/include/asm/irqflags-arcv2.h
··· 44 44 #define ARCV2_IRQ_DEF_PRIO 1 45 45 46 46 /* seed value for status register */ 47 - #define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | STATUS_AD_MASK | \ 47 + #ifdef CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS 48 + #define __AD_ENB STATUS_AD_MASK 49 + #else 50 + #define __AD_ENB 0 51 + #endif 52 + 53 + #define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | __AD_ENB | \ 48 54 (ARCV2_IRQ_DEF_PRIO << 1)) 49 55 50 56 #ifndef __ASSEMBLY__
+5
arch/arc/kernel/head.S
··· 54 54 ; gcc 7.3.1 (ARC GNU 2018.03) onwards generates unaligned access 55 55 ; by default 56 56 lr r5, [status32] 57 + #ifdef CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS 57 58 bset r5, r5, STATUS_AD_BIT 59 + #else 60 + ; Although disabled at reset, bootloader might have enabled it 61 + bclr r5, r5, STATUS_AD_BIT 62 + #endif 58 63 kflag r5 59 64 #endif 60 65 .endm
+1 -1
arch/arc/kernel/intc-arcv2.c
··· 95 95 96 96 /* setup status32, don't enable intr yet as kernel doesn't want */ 97 97 tmp = read_aux_reg(ARC_REG_STATUS32); 98 - tmp |= STATUS_AD_MASK | (ARCV2_IRQ_DEF_PRIO << 1); 98 + tmp |= ARCV2_IRQ_DEF_PRIO << 1; 99 99 tmp &= ~STATUS_IE_MASK; 100 100 asm volatile("kflag %0 \n"::"r"(tmp)); 101 101 }
+17 -10
arch/arc/kernel/setup.c
··· 263 263 { 264 264 struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id]; 265 265 struct bcr_identity *core = &cpu->core; 266 - int i, n = 0, ua = 0; 266 + int n = 0; 267 267 268 268 FIX_PTR(cpu); 269 269 ··· 283 283 IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_TIMERS_64BIT), 284 284 IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_TIMERS_64BIT)); 285 285 286 - #ifdef __ARC_UNALIGNED__ 287 - ua = 1; 288 - #endif 289 - n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s%s", 290 - IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC), 291 - IS_AVAIL2(cpu->isa.ldd, "ll64 ", CONFIG_ARC_HAS_LL64), 292 - IS_AVAIL1(cpu->isa.unalign, "unalign "), IS_USED_RUN(ua)); 286 + n += scnprintf(buf + n, len - n, "%s%s%s%s%s%s", 287 + IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC), 288 + IS_AVAIL2(cpu->isa.ldd, "ll64 ", CONFIG_ARC_HAS_LL64), 289 + IS_AVAIL2(cpu->isa.unalign, "unalign ", CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS)); 293 290 294 - if (i) 295 - n += scnprintf(buf + n, len - n, "\n\t\t: "); 291 + #if defined(__ARC_UNALIGNED__) && !defined(CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS) 292 + /* 293 + * gcc 7.3.1 (GNU 2018.03) onwards generate unaligned access by default 294 + * but -mno-unaligned-access to disable that didn't work until gcc 8.2.1 295 + * (GNU 2019.03). So landing here implies the interim period, when 296 + * despite Kconfig being off, gcc is generating unaligned accesses which 297 + * could bomb later on. So better to disallow such broken builds 298 + */ 299 + BUILD_BUG_ON_MSG(1, "gcc doesn't support -mno-unaligned-access"); 300 + #endif 301 + 302 + n += scnprintf(buf + n, len - n, "\n\t\t: "); 296 303 297 304 if (cpu->extn_mpy.ver) { 298 305 if (cpu->extn_mpy.ver <= 0x2) { /* ARCompact */
+4 -1
arch/arc/kernel/troubleshoot.c
··· 145 145 } else if (vec == ECR_V_PROTV) { 146 146 if (cause_code == ECR_C_PROTV_INST_FETCH) 147 147 pr_cont("Execute from Non-exec Page\n"); 148 - else if (cause_code == ECR_C_PROTV_MISALIG_DATA) 148 + else if (cause_code == ECR_C_PROTV_MISALIG_DATA && 149 + IS_ENABLED(CONFIG_ISA_ARCOMPACT)) 149 150 pr_cont("Misaligned r/w from 0x%08lx\n", address); 150 151 else 151 152 pr_cont("%s access not allowed on page\n", ··· 162 161 pr_cont("Bus Error from Data Mem\n"); 163 162 else 164 163 pr_cont("Bus Error, check PRM\n"); 164 + } else if (vec == ECR_V_MISALIGN) { 165 + pr_cont("Misaligned r/w from 0x%08lx\n", address); 165 166 #endif 166 167 } else if (vec == ECR_V_TRAP) { 167 168 if (regs->ecr_param == 5)
+7 -1
arch/arc/lib/Makefile
··· 8 8 lib-y := strchr-700.o strcpy-700.o strlen.o memcmp.o 9 9 10 10 lib-$(CONFIG_ISA_ARCOMPACT) += memcpy-700.o memset.o strcmp.o 11 - lib-$(CONFIG_ISA_ARCV2) += memcpy-archs.o memset-archs.o strcmp-archs.o 11 + lib-$(CONFIG_ISA_ARCV2) += memset-archs.o strcmp-archs.o 12 + 13 + ifdef CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS 14 + lib-$(CONFIG_ISA_ARCV2) +=memcpy-archs-unaligned.o 15 + else 16 + lib-$(CONFIG_ISA_ARCV2) +=memcpy-archs.o 17 + endif