diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 7bbf325a4f31..73d5ad456e32 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -449,6 +449,13 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
#endif
.endm
+ .macro dacr_sync, rd
+ mrc p15, 0, \rd, c2, c0, 0
+ mov \rd, \rd
+ sub pc, pc, #4
+ mcr p15, 0, \rd, c7, c5, 4
+ .endm
+
.macro uaccess_disable, tmp, isb=1
#ifdef CONFIG_CPU_SW_DOMAIN_PAN
/*
@@ -457,6 +464,7 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
*/
mov \tmp, #DACR_UACCESS_DISABLE
mcr p15, 0, \tmp, c3, c0, 0 @ Set domain register
+ dacr_sync \tmp
.if \isb
instr_sync
.endif
@@ -471,6 +479,7 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
*/
mov \tmp, #DACR_UACCESS_ENABLE
mcr p15, 0, \tmp, c3, c0, 0
+ dacr_sync \tmp
.if \isb
instr_sync
.endif
@@ -488,6 +497,7 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
#ifdef CONFIG_CPU_SW_DOMAIN_PAN
ldr r0, [sp, #S_FRAME_SIZE]
mcr p15, 0, r0, c3, c0, 0
+ dacr_sync r0
#endif
.endm
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index e878129f2fee..10c9a38636ac 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -97,7 +97,11 @@ static inline unsigned int get_domain(void)
static inline void set_domain(unsigned val)
{
asm volatile(
- "mcr p15, 0, %0, c3, c0 @ set domain"
+ "mcr p15, 0, %0, c3, c0; @ set domain \
+ mrc p15, 0, %0, c2, c0, 0; \
+ mov %0, %0; \
+ sub pc, pc, #4; \
+ mcr p15, 0, %0, c7, c5, 4"
: : "r" (val));
isb();
}diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 9769f1eefe3b..c9c454129344 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -747,6 +747,27 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs,
return NULL;
}
+static u32 far_read(void)
+{
+ u32 far;
+ asm("mrc p15, 0, %0, c6, c0, 0" : "=r" (far));
+ return far;
+}
+
+static u32 fsr_read(void)
+{
+ u32 fsr;
+ asm("mrc p15, 0, %0, c5, c0, 0" : "=r" (fsr));
+ return fsr;
+}
+
+static u32 dacr_read(void)
+{
+ u32 dacr;
+ asm("mrc p15, 0, %0, c3, c0, 0" : "=r" (dacr));
+ return dacr;
+}
+
static int
do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{@@ -763,6 +784,8 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
local_irq_enable();
instrptr = instruction_pointer(regs);
+ pr_info("RJK1: fsr=%x far=%x dacr=%x\n", fsr_read(), far_read(), dacr_read());
+ pr_info("RJK2: fsr=%x far=%x dacr=%x\n", fsr_read(), far_read(), dacr_read());
if (thumb_mode(regs)) {
u16 *ptr = (u16 *)(instrptr & ~1);@@ -787,6 +810,8 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
instr = __mem_to_opcode_arm(instr);
}
+ pr_info("RJK3: fsr=%x far=%x dacr=%x\n", fsr_read(), far_read(), dacr_read());
+ pr_info("RJK: fault=%d instr=0x%08x instrptr=%p\n", fault, instr, instrptr);
if (fault) {
type = TYPE_FAULT;
goto bad_or_fault;