[PATCH v2] ARC: ARCv2: jump label: implement jump label patching

2019-07-18 Thread Eugeniy Paltsev
Implement jump label patching for ARC. Jump labels provide
an interface to generate dynamic branches using
self-modifying code.

This allows us to implement conditional branches where
changing branch direction is expensive but branch selection
is basically 'free'

This implementation uses 32-bit NOP and BRANCH instructions
which forced to be aligned by 4 to guarantee that they don't
cross L1 I$ cache fetch block and can be update atomically.

Signed-off-by: Eugeniy Paltsev 
---
Changes v1->v2:
 * Patched instruction should not cross L1 I$ fetch block boundary and
   not only L1 I$ line. Fix comments and asserts in code.
 * Other small comments fix and code cleanup.

 arch/arc/Kconfig  |   8 ++
 arch/arc/include/asm/cache.h  |  11 ++
 arch/arc/include/asm/jump_label.h |  71 +
 arch/arc/kernel/Makefile  |   1 +
 arch/arc/kernel/jump_label.c  | 167 ++
 5 files changed, 258 insertions(+)
 create mode 100644 arch/arc/include/asm/jump_label.h
 create mode 100644 arch/arc/kernel/jump_label.c

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 1c8137e7247b..f9657c86c3e1 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -44,6 +44,7 @@ config ARC
select OF_EARLY_FLATTREE
select PCI_SYSCALL if PCI
select PERF_USE_VMALLOC if ARC_CACHE_VIPT_ALIASING
+   select HAVE_ARCH_JUMP_LABEL if ISA_ARCV2 && !CPU_ENDIAN_BE32
 
 config ARCH_HAS_CACHE_LINE_SIZE
def_bool y
@@ -523,6 +524,13 @@ config ARC_DW2_UNWIND
 config ARC_DBG_TLB_PARANOIA
bool "Paranoia Checks in Low Level TLB Handlers"
 
+config ARC_DBG_JUMP_LABEL
+   bool "Paranoid checks in Static Keys (jump labels) code"
+   depends on JUMP_LABEL
+   select STATIC_KEYS_SELFTEST
+   help
+ Enable paranoid checks and self-test of both ARC-specific and generic
+ part of static keys (jump labels) related code.
 endif
 
 config ARC_BUILTIN_DTB_NAME
diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h
index 918804c7c1a4..46d4f673609a 100644
--- a/arch/arc/include/asm/cache.h
+++ b/arch/arc/include/asm/cache.h
@@ -16,6 +16,11 @@
 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
 #define CACHE_LINE_MASK(~(L1_CACHE_BYTES - 1))
 
+#ifdef CONFIG_ISA_ARCV2
+/* instruction_fetch_block_width is same for all ARCv2 */
+#define I_CACHE_FETCH_BLOCK_WIDTH  16
+#endif
+
 /*
  * ARC700 doesn't cache any access in top 1G (0xc000_ to 0x_)
  * Ideal for wiring memory mapped peripherals as we don't need to do
@@ -25,6 +30,12 @@
 
 #ifndef __ASSEMBLY__
 
+#include 
+
+#ifdef CONFIG_ISA_ARCV2
+static_assert(I_CACHE_FETCH_BLOCK_WIDTH <= L1_CACHE_BYTES);
+#endif
+
 /* Uncached access macros */
 #define arc_read_uncached_32(ptr)  \
 ({ \
diff --git a/arch/arc/include/asm/jump_label.h 
b/arch/arc/include/asm/jump_label.h
new file mode 100644
index ..0de7833b2071
--- /dev/null
+++ b/arch/arc/include/asm/jump_label.h
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_ARC_JUMP_LABEL_H
+#define _ASM_ARC_JUMP_LABEL_H
+
+#ifndef __ASSEMBLY__
+
+#include 
+
+#define JUMP_LABEL_NOP_SIZE 4
+
+/*
+ * NOTE about '.balign 4':
+ *
+ * To make atomic update of patched instruction available we need to guarantee
+ * that this instruction doesn't cross L1 I$ fetch block boundary (it's
+ * smaller than L1 I$ line size).
+ *
+ * As of today we simply align instruction which can be patched by 4 byte using
+ * ".balign 4" directive. In that case patched instruction is aligned with one
+ * 16-bit NOP_S if this is required.
+ * However 'align by 4' directive is much stricter than it actually required.
+ * It's enough that our 32-bit instruction don't cross L1 I$ fetch block
+ * boundary which can be achieved by using ".bundle_align_mode" directive.
+ * That will save us from adding useless NOP_S padding in most of the cases.
+ *
+ * TODO: switch to ".bundle_align_mode" directive using whin it will be
+ * supported by ARC toolchain.
+ */
+
+static __always_inline bool arch_static_branch(struct static_key *key,
+  bool branch)
+{
+   asm_volatile_goto(".balign 4\n"
+"1:\n"
+"nop   \n"
+".pushsection __jump_table, \"aw\" \n"
+".word 1b, %l[l_yes], %c0  \n"
+".popsection   \n"
+: : "i" (&((char *)key)[branch]) : : l_yes);
+
+   return false;
+l_yes:
+   return true;
+}
+
+static __always_inline bool arch_static_branch_jump(struct static_key *key,
+   bool branch)
+{
+   asm_volatile_goto(".balign 4\n"
+"1:\n"
+"b %l[l_yes] 

[PATCH v2] mtd: spi-nor: add support for sst26wf016b memory IC

2019-07-18 Thread Eugeniy Paltsev
This commit adds support for the SST sst26wf016b flash memory IC.
This IC was tested with  "snps,dw-apb-ssi" SPI controller.
We don't test dual/quad reads however sst26wf016b flash's datasheet
advertises both dual and quad reads (and support of corresponding
commands)

Signed-off-by: Eugeniy Paltsev 
---
Changes v1->v2:
 * drop sst26wf032 support as untested
 * add note about SPI controller used and dual/quad reads to commit
   message.

 drivers/mtd/spi-nor/spi-nor.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 73172d7f512b..0beed856bad8 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1945,6 +1945,7 @@ static const struct flash_info spi_nor_ids[] = {
{ "sst25wf040b", INFO(0x621613, 0, 64 * 1024,  8, SECT_4K) },
{ "sst25wf040",  INFO(0xbf2504, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) 
},
{ "sst25wf080",  INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) 
},
+   { "sst26wf016b", INFO(0xbf2651, 0, 64 * 1024, 32, SECT_4K | 
SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "sst26vf064b", INFO(0xbf2643, 0, 64 * 1024, 128, SECT_4K | 
SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 
/* ST Microelectronics -- newer production may have feature updates */
-- 
2.21.0


___
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc


RE: [PATCH v2 2/2] ARC: enable uboot support unconditionally

2019-07-18 Thread Alexey Brodkin
Hi Greg,

> -Original Message-
> From: Eugeniy Paltsev 
> Sent: Thursday, February 14, 2019 6:08 PM
> To: linux-snps-arc@lists.infradead.org; Vineet Gupta 
> Cc: linux-ker...@vger.kernel.org; Alexey Brodkin ; 
> Corentin Labbe
> ; khil...@baylibre.com; Eugeniy Paltsev 
> 
> Subject: [PATCH v2 2/2] ARC: enable uboot support unconditionally
> 
> After reworking U-boot args handling code and adding paranoid
> arguments check we can eliminate CONFIG_ARC_UBOOT_SUPPORT and
> enable uboot support unconditionally.
> 
> For JTAG case we can assume that core registers will come up
> reset value of 0 or in worst case we rely on user passing
> '-on=clear_regs' to Metaware debugger.
> 
> Signed-off-by: Eugeniy Paltsev 

May we have this one back-ported to linux-4.19.y?

It was initially applied to Linus' tree during 5.0 development
cycle [1] but was never back-ported.

Now w/o that patch in KernelCI we see boot failure on ARC HSDK
board [2] as opposed to normally working later kernel versions.

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=493a2f812446e92bcb1e69a77381b4d39808d730
[2] 
https://storage.kernelci.org/stable/linux-4.19.y/v4.19.59/arc/hsdk_defconfig/gcc-8/lab-baylibre/boot-hsdk.txt

Below is that same patch but rebased on linux-4.19 as in its pristine
form it won't apply due to offset of one of hunks.

-Alexey

>8
>From 3e565355f6a2d1a82bc9ecd47a46d1fa3c0cd2c1 Mon Sep 17 00:00:00 2001
From: Eugeniy Paltsev 
Date: Thu, 14 Feb 2019 18:07:45 +0300
Subject: [PATCH] ARC: enable uboot support unconditionally

After reworking U-boot args handling code and adding paranoid
arguments check we can eliminate CONFIG_ARC_UBOOT_SUPPORT and
enable uboot support unconditionally.

For JTAG case we can assume that core registers will come up
reset value of 0 or in worst case we rely on user passing
'-on=clear_regs' to Metaware debugger.

Cc: sta...@vger.kernel.org
Tested-by: Corentin LABBE 
Signed-off-by: Eugeniy Paltsev 
Signed-off-by: Vineet Gupta 
---
 arch/arc/Kconfig| 13 -
 arch/arc/configs/nps_defconfig  |  1 -
 arch/arc/configs/vdk_hs38_defconfig |  1 -
 arch/arc/configs/vdk_hs38_smp_defconfig |  2 --
 arch/arc/kernel/head.S  |  2 --
 arch/arc/kernel/setup.c |  2 --
 6 files changed, 21 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 85eb7fc2e241..97b45fe8f0c2 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -199,7 +199,6 @@ config NR_CPUS
 
 config ARC_SMP_HALT_ON_RESET
bool "Enable Halt-on-reset boot mode"
-   default y if ARC_UBOOT_SUPPORT
help
  In SMP configuration cores can be configured as Halt-on-reset
  or they could all start at same time. For Halt-on-reset, non
@@ -538,18 +537,6 @@ config ARC_DBG_TLB_PARANOIA
 
 endif
 
-config ARC_UBOOT_SUPPORT
-   bool "Support uboot arg Handling"
-   default n
-   help
- ARC Linux by default checks for uboot provided args as pointers to
- external cmdline or DTB. This however breaks in absence of uboot,
- when booting from Metaware debugger directly, as the registers are
- not zeroed out on reset by mdb and/or ARCv2 based cores. The bogus
- registers look like uboot args to kernel which then chokes.
- So only enable the uboot arg checking/processing if users are sure
- of uboot being in play.
-
 config ARC_BUILTIN_DTB_NAME
string "Built in DTB"
help
diff --git a/arch/arc/configs/nps_defconfig b/arch/arc/configs/nps_defconfig
index 6e84060e7c90..621f59407d76 100644
--- a/arch/arc/configs/nps_defconfig
+++ b/arch/arc/configs/nps_defconfig
@@ -31,7 +31,6 @@ CONFIG_ARC_CACHE_LINE_SHIFT=5
 # CONFIG_ARC_HAS_LLSC is not set
 CONFIG_ARC_KVADDR_SIZE=402
 CONFIG_ARC_EMUL_UNALIGNED=y
-CONFIG_ARC_UBOOT_SUPPORT=y
 CONFIG_PREEMPT=y
 CONFIG_NET=y
 CONFIG_UNIX=y
diff --git a/arch/arc/configs/vdk_hs38_defconfig 
b/arch/arc/configs/vdk_hs38_defconfig
index 1e59a2e9c602..e447ace6fa1c 100644
--- a/arch/arc/configs/vdk_hs38_defconfig
+++ b/arch/arc/configs/vdk_hs38_defconfig
@@ -13,7 +13,6 @@ CONFIG_PARTITION_ADVANCED=y
 CONFIG_ARC_PLAT_AXS10X=y
 CONFIG_AXS103=y
 CONFIG_ISA_ARCV2=y
-CONFIG_ARC_UBOOT_SUPPORT=y
 CONFIG_ARC_BUILTIN_DTB_NAME="vdk_hs38"
 CONFIG_PREEMPT=y
 CONFIG_NET=y
diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig 
b/arch/arc/configs/vdk_hs38_smp_defconfig
index b5c3f6c54b03..c82cdb10aaf4 100644
--- a/arch/arc/configs/vdk_hs38_smp_defconfig
+++ b/arch/arc/configs/vdk_hs38_smp_defconfig
@@ -15,8 +15,6 @@ CONFIG_AXS103=y
 CONFIG_ISA_ARCV2=y
 CONFIG_SMP=y
 # CONFIG_ARC_TIMERS_64BIT is not set
-# CONFIG_ARC_SMP_HALT_ON_RESET is not set
-CONFIG_ARC_UBOOT_SUPPORT=y
 CONFIG_ARC_BUILTIN_DTB_NAME="vdk_hs38_smp"
 CONFIG_PREEMPT=y
 CONFIG_NET=y
diff --git a/arch/arc/kernel/head.S b/arch/arc/kernel/head.S
index 208bf2c9e7b0..a72bbda2f7aa 100644
--- a/ar