diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index a045f3086047..f006fe81e085 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -528,6 +528,14 @@ config ARC_DBG_TLB_PARANOIA
 	bool "Paranoia Checks in Low Level TLB Handlers"
 	default n
 
+config ARC_USE_SMART
+	bool "Enable real time trace on-chip debug HW"
+	depends on ISA_ARCV2
+	help
+	  Enable Small real time trace on-chip debug hardware component that
+	  captures instruction-trace history if exists. This trace will be
+	  printed if any unexpected exception is occured.
+
 endif
 
 config ARC_UBOOT_SUPPORT
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index 49bfbd879caa..11f4c5c0df4d 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -118,6 +118,20 @@
 #define ARC_AUX_DPFP_2H         0x304
 #define ARC_AUX_DPFP_STAT       0x305
 
+/* SmaRT registers */
+#define ARC_AUX_SMART_CONTROL	0x700
+#define SMART_CTL_EN		BIT(0)
+#define SMART_CTL_DATA_POS	8
+#define SMART_CTL_DATA_SRC	0
+#define SMART_CTL_DATA_DST	1
+#define SMART_CTL_DATA_FLAG	2
+#define SMART_CTL_IDX_POS	10
+#define ARC_AUX_SMART_DATA	0x701
+#define SMART_FLAG_U		BIT(8)
+#define SMART_FLAG_E		BIT(9)
+#define SMART_FLAG_R		BIT(10)
+#define SMART_FLAG_V		BIT(31)
+
 #ifndef __ASSEMBLY__
 
 #include <soc/arc/aux.h>
diff --git a/arch/arc/include/asm/bug.h b/arch/arc/include/asm/bug.h
index b68f7f82f2d8..bc9c14bcee2a 100644
--- a/arch/arc/include/asm/bug.h
+++ b/arch/arc/include/asm/bug.h
@@ -15,6 +15,13 @@
 
 struct task_struct;
 
+#ifdef CONFIG_ARC_USE_SMART
+void populate_smart(void);
+#define POPULATE_SMART()	populate_smart()
+#else
+#define POPULATE_SMART()
+#endif /* CONFIG_ARC_USE_SMART */
+
 void show_regs(struct pt_regs *regs);
 void show_exception_mesg(struct pt_regs *regs);
 void show_stacktrace(struct task_struct *tsk, struct pt_regs *regs);
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index b2cae79a25d7..e83bbc86397e 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -447,6 +447,12 @@ void setup_processor(void)
 	pr_info("%s", arc_platform_smp_cpuinfo());
 
 	arc_chk_core_config();
+
+#ifdef CONFIG_ARC_USE_SMART
+	if (cpuinfo_arc700[cpu_id].extn.smart)
+		write_aux_reg(ARC_AUX_SMART_CONTROL, SMART_CTL_EN);
+#endif
+
 }
 
 static inline int is_kernel(unsigned long addr)
diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c
index e66fd40296b3..0228f7182e6d 100644
--- a/arch/arc/kernel/traps.c
+++ b/arch/arc/kernel/traps.c
@@ -70,6 +70,7 @@ int name(unsigned long address, struct pt_regs *regs) \
 {						\
 	siginfo_t info;				\
 						\
+	POPULATE_SMART();			\
 	clear_siginfo(&info);			\
 	info.si_signo = signr;			\
 	info.si_errno = 0;			\
@@ -96,6 +97,8 @@ DO_ERROR_INFO(SIGSEGV, "gcc generated __builtin_trap", do_trap5_error, 0)
 int do_misaligned_access(unsigned long address, struct pt_regs *regs,
 			 struct callee_regs *cregs)
 {
+	POPULATE_SMART();
+
 	/* If emulation not enabled, or failed, kill the task */
 	if (misaligned_fixup(address, regs, cregs) != 0)
 		return do_misaligned_error(address, regs);
@@ -128,6 +131,8 @@ void do_non_swi_trap(unsigned long address, struct pt_regs *regs)
 {
 	unsigned int param = regs->ecr_param;
 
+	POPULATE_SMART();
+
 	switch (param) {
 	case 1:
 		trap_is_brkpt(address, regs);
@@ -159,6 +164,8 @@ void do_insterror_or_kprobe(unsigned long address, struct pt_regs *regs)
 {
 	int rc;
 
+	POPULATE_SMART();
+
 	/* Check if this exception is caused by kprobes */
 	rc = notify_die(DIE_IERR, "kprobe_ierr", regs, address, 0, SIGILL);
 	if (rc == NOTIFY_STOP)
diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c
index fdfba1942a06..22017474a29c 100644
--- a/arch/arc/kernel/troubleshoot.c
+++ b/arch/arc/kernel/troubleshoot.c
@@ -14,10 +14,23 @@
 #include <linux/file.h>
 #include <linux/sched/mm.h>
 #include <linux/sched/debug.h>
+#include <linux/percpu-defs.h>
 
 #include <asm/arcregs.h>
 #include <asm/irqflags.h>
 
+#ifdef CONFIG_ARC_USE_SMART
+#define MAX_SMART_BUFF	4096
+
+struct smart_buff {
+	u32 src[MAX_SMART_BUFF];
+	u32 dst[MAX_SMART_BUFF];
+	u32 flags[MAX_SMART_BUFF];
+};
+
+DEFINE_PER_CPU(struct smart_buff, smart_buff_log);
+#endif /* CONFIG_ARC_USE_SMART */
+
 /*
  * Common routine to print scratch regs (r0-r12) or callee regs (r13-r25)
  *   -Prints 3 regs per line and a CR.
@@ -189,9 +202,104 @@ static inline void show_exception_mesg_k(struct pt_regs *regs)
 	show_ecr_verbose(regs);
 }
 
+#ifdef CONFIG_ARC_USE_SMART
+static inline bool smart_exist(void)
+{
+	struct bcr_generic bcr;
+
+	READ_BCR(ARC_REG_SMART_BCR, bcr);
+	return !!bcr.ver ;
+}
+
+static inline u32 smart_stack_size(void)
+{
+	return read_aux_reg(ARC_REG_SMART_BCR) >> SMART_CTL_IDX_POS;
+}
+
+static inline void smart_enable(void)
+{
+	write_aux_reg(ARC_AUX_SMART_CONTROL, SMART_CTL_EN);
+}
+
+static inline void smart_disable(void)
+{
+	write_aux_reg(ARC_AUX_SMART_CONTROL, 0);
+}
+
+static void show_smart(void)
+{
+	struct smart_buff *smart_buff_cpu = this_cpu_ptr(&smart_buff_log);
+	int i, stack_size;
+	char *buf;
+
+	if (!smart_exist())
+		return;
+
+	stack_size = smart_stack_size();
+	pr_info("SmaRT (%d entries):\n", stack_size);
+
+	buf = (char *)__get_free_page(GFP_NOWAIT);
+	if (!buf)
+		return;
+
+	for (i = 0; i < stack_size; i++) {
+		pr_info(" [%4d] %s%s%s%s %#010x -> %#010x ", i,
+			smart_buff_cpu->flags[i] & SMART_FLAG_U ? "U" : " ",
+			smart_buff_cpu->flags[i] & SMART_FLAG_E ? "E" : " ",
+			smart_buff_cpu->flags[i] & SMART_FLAG_R ? "R" : " ",
+			smart_buff_cpu->flags[i] & SMART_FLAG_V ? "V" : " ",
+			smart_buff_cpu->src[i], smart_buff_cpu->dst[i]);
+
+		if (smart_buff_cpu->src[i] < 0x80000000)
+			show_faulting_vma(smart_buff_cpu->src[i], buf);
+		else
+			pr_cont("[src %pS] ", (void *)smart_buff_cpu->src[i]);
+
+		if (smart_buff_cpu->dst[i] < 0x80000000)
+			show_faulting_vma(smart_buff_cpu->dst[i], buf);
+		else
+			pr_cont("[dst %pS]\n", (void *)smart_buff_cpu->dst[i]);
+	}
+
+	free_page((unsigned long)buf);
+}
+#endif /* CONFIG_ARC_USE_SMART */
+
 /************************************************************************
  *  API called by rest of kernel
  ***********************************************************************/
+#ifdef CONFIG_ARC_USE_SMART
+void populate_smart(void)
+{
+	struct smart_buff *smart_buff_cpu;
+	u32 stack_size;
+	int i;
+
+	if (!smart_exist())
+		return;
+
+	smart_disable();
+
+	smart_buff_cpu = this_cpu_ptr(&smart_buff_log);
+	stack_size = smart_stack_size();
+	for (i = 0; i < stack_size; i++) {
+		write_aux_reg(ARC_AUX_SMART_CONTROL,
+			(SMART_CTL_DATA_SRC << SMART_CTL_DATA_POS)
+			| (i << SMART_CTL_IDX_POS));
+		smart_buff_cpu->src[i] = read_aux_reg(ARC_AUX_SMART_DATA);
+		write_aux_reg(ARC_AUX_SMART_CONTROL,
+			(SMART_CTL_DATA_DST << SMART_CTL_DATA_POS)
+			| (i << SMART_CTL_IDX_POS));
+		smart_buff_cpu->dst[i] = read_aux_reg(ARC_AUX_SMART_DATA);
+		write_aux_reg(ARC_AUX_SMART_CONTROL,
+			(SMART_CTL_DATA_FLAG << SMART_CTL_DATA_POS)
+			| (i << SMART_CTL_IDX_POS));
+		smart_buff_cpu->flags[i] = read_aux_reg(ARC_AUX_SMART_DATA);
+	}
+
+	smart_enable();
+}
+#endif /* CONFIG_ARC_USE_SMART */
 
 void show_exception_mesg(struct pt_regs *regs)
 {
@@ -199,6 +307,10 @@ void show_exception_mesg(struct pt_regs *regs)
 		show_exception_mesg_u(regs);
 	else
 		show_exception_mesg_k(regs);
+
+#ifdef CONFIG_ARC_USE_SMART
+	show_smart();
+#endif /* CONFIG_ARC_USE_SMART */
 }
 
 void show_regs(struct pt_regs *regs)
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
index 026d662a7668..7a759fd874de 100644
--- a/arch/arc/mm/fault.c
+++ b/arch/arc/mm/fault.c
@@ -72,6 +72,7 @@ void do_page_fault(unsigned long address, struct pt_regs *regs)
 	int write = regs->ecr_cause & ECR_C_PROTV_STORE;  /* ST/EX */
 	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
+	POPULATE_SMART();
 	clear_siginfo(&info);
 
 	/*
