diff mbox

arm64: emulate aarch32 CP15 barriers if needed

Message ID 1384075404-19605-1-git-send-email-ming.lei@canonical.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ming Lei Nov. 10, 2013, 9:23 a.m. UTC
CP15BEN of SCTLR_EL1 may not be implemented, so we need
to emulate these three CP15 barriers to avoid breaking
aarch32 applications since they can be used in user mode.

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 arch/arm64/kernel/traps.c |   32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

Comments

Catalin Marinas Nov. 10, 2013, 11:25 a.m. UTC | #1
On 10 Nov 2013, at 09:23, Ming Lei <ming.lei@canonical.com> wrote:
> CP15BEN of SCTLR_EL1 may not be implemented, so we need
> to emulate these three CP15 barriers to avoid breaking
> aarch32 applications since they can be used in user mode.
> 
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Ming Lei <ming.lei@canonical.com>

Can you describe which aarch32 applications is this breaking?  These
barriers have been deprecated in ARMv7 and removed in ARMv8 (same as the
SWP instruction).  User space is supposed to use the kuser helpers which
provide the right barriers for the architecture.  Compiler intrinsics
for ARMv7 already generate (inline) the new ARMv7 barriers.

So for compat support, I consider this similar to other instructions we
will not emulate like SWP and certain unaligned accesses.  IOW, arm64
compat only supports non-deprecated ARMv7 features.

Catalin
Ming Lei Nov. 10, 2013, 12:08 p.m. UTC | #2
On Sun, Nov 10, 2013 at 7:25 PM, Catalin Marinas
<catalin.marinas@arm.com> wrote:
> On 10 Nov 2013, at 09:23, Ming Lei <ming.lei@canonical.com> wrote:
>> CP15BEN of SCTLR_EL1 may not be implemented, so we need
>> to emulate these three CP15 barriers to avoid breaking
>> aarch32 applications since they can be used in user mode.
>>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Cc: Will Deacon <will.deacon@arm.com>
>> Signed-off-by: Ming Lei <ming.lei@canonical.com>
>
> Can you describe which aarch32 applications is this breaking?  These
> barriers have been deprecated in ARMv7 and removed in ARMv8 (same as the
> SWP instruction).  User space is supposed to use the kuser helpers which
> provide the right barriers for the architecture.  Compiler intrinsics
> for ARMv7 already generate (inline) the new ARMv7 barriers.

I know one armv7 business software(closed source) uses cp15 dmb,
and actually any armv7 user applications may use these instructions
since they are allowed in user mode.

>
> So for compat support, I consider this similar to other instructions we
> will not emulate like SWP and certain unaligned accesses.  IOW, arm64
> compat only supports non-deprecated ARMv7 features.

That will inevitably break some current armv7 user space, and cause
compatibility problem since aarch64 claims to support armv7 user
application.

Also looks CP15BEN of SCTLR_EL1 is for such purpose.


Thanks,
--
Ming Lei
Catalin Marinas Nov. 10, 2013, 1:05 p.m. UTC | #3
On 10 Nov 2013, at 12:08, Ming Lei <ming.lei@canonical.com> wrote:
> On Sun, Nov 10, 2013 at 7:25 PM, Catalin Marinas
> <catalin.marinas@arm.com> wrote:
>> On 10 Nov 2013, at 09:23, Ming Lei <ming.lei@canonical.com> wrote:
>>> CP15BEN of SCTLR_EL1 may not be implemented, so we need
>>> to emulate these three CP15 barriers to avoid breaking
>>> aarch32 applications since they can be used in user mode.
>>> 
>>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>>> Cc: Will Deacon <will.deacon@arm.com>
>>> Signed-off-by: Ming Lei <ming.lei@canonical.com>
>> 
>> Can you describe which aarch32 applications is this breaking?  These
>> barriers have been deprecated in ARMv7 and removed in ARMv8 (same as the
>> SWP instruction).  User space is supposed to use the kuser helpers which
>> provide the right barriers for the architecture.  Compiler intrinsics
>> for ARMv7 already generate (inline) the new ARMv7 barriers.
> 
> I know one armv7 business software(closed source) uses cp15 dmb,

OK, so that’s even easier ;)

Next they’ll complain about the performance of such operations (imagine
some fast user-space locking in a database software trapping for each
barrier).

> and actually any armv7 user applications may use these instructions
> since they are allowed in user mode.

There are others allowed like SWP but we decided not to emulate them
since they’ve been deprecated for a long time.

>> So for compat support, I consider this similar to other instructions we
>> will not emulate like SWP and certain unaligned accesses.  IOW, arm64
>> compat only supports non-deprecated ARMv7 features.
> 
> That will inevitably break some current armv7 user space, and cause
> compatibility problem since aarch64 claims to support armv7 user
> application.

It supports armv7 user applications using *non-deprecated& features
(and EABI).

> Also looks CP15BEN of SCTLR_EL1 is for such purpose.

If it’s just a matter of enabling it in SCTLR_EL1, that would be easier
but the hardware may simply not implement these instructions in ARMv8
(I guess that’s why you want emulation). My position is that such legacy
software should be upgraded to make use of the kuser helpers (if ARMv6
and earlier support is required) or just DMB/DSB/ISB if optimised for
ARMv7.

Catalin
diff mbox

Patch

diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 7ffaddd..c9f009d 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -257,6 +257,34 @@  void arm64_notify_die(const char *str, struct pt_regs *regs,
 		die(str, regs, err);
 }
 
+/*
+ * CP15BEN of SCTLR_EL1 may not be implemented, so emulate
+ * these three instructions when they trap in
+ */
+static int aarch32_cp15_barriers(struct pt_regs *regs)
+{
+	unsigned int instr;
+	void __user *pc = (void __user *)instruction_pointer(regs);
+
+	if (!compat_user_mode(regs))
+		return -EFAULT;
+
+	get_user(instr, (u32 __user *)pc);
+	instr &= ~0xf000f000;
+
+	if (instr == 0x0e070fba)	/* CP15DMB */
+		smp_mb();
+	else if (instr == 0x0e070f9a)	/* CP15DSB */
+		dsb();
+	else if (instr == 0x0e070f95)	/* CP15ISB */
+		isb();
+	else
+		return -EFAULT;
+
+	regs->pc += 4;
+	return 0;
+}
+
 asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
 {
 	siginfo_t info;
@@ -266,6 +294,10 @@  asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
 	if (!aarch32_break_handler(regs))
 		return;
 
+	/* check for AArch32 CP15DMB/CP15DSB/CP15ISB */
+	if (!aarch32_cp15_barriers(regs))
+		return;
+
 	if (show_unhandled_signals && unhandled_signal(current, SIGILL) &&
 	    printk_ratelimit()) {
 		pr_info("%s[%d]: undefined instruction: pc=%p\n",