Page MenuHomePhabricator

ARM: Allow cp10/cp11 coprocessor register access with a warning
Needs ReviewPublic

Authored by falstaff84 on Mar 23 2019, 2:59 AM.



The Linux kernel uses quite some mcr/mrc instructions throughout the ARM port. Probably most of them could be converted to the appropriate vmsr/vmrs instructions along with appropriate FPU definition, e.g.:

arch/arm/vfp/vfpmodule.c:345:2: error: invalid operand for instruction
arch/arm/vfp/vfpinstr.h:82:6: note: expanded from macro 'fmxr'
        asm("mcr p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr   " #_vfp_ ", %0" \
<inline asm>:1:6: note: instantiated into assembly here
        mcr p10, 7, r0, cr8, cr0, 0 @ fmxr      FPEXC, r0

However, there is at least one case where an unofficial/(SoC specific?) control register is accessed:

static u32 venum_read_pmresr(void)
        u32 val;
        asm volatile("mrc p10, 7, %0, c11, c0, 0" : "=r" (val));
        return val;

There is no register definition for control register 11 in lib/Target/ARM/

This patch converts the restriction of mcr/mrc cp10/cp11 instructions to warnings. The warnings can be suppressed using -no-deprecated-warn which is probably what the Linux kernel will use for the time being.

See also the discussion on the kernel side, tracked in this issue:

Diff Detail


Event Timeline

falstaff84 created this revision.Mar 23 2019, 2:59 AM

I prefer having the warning here as there are use cases for using the coprocessor interface for VFP instructions, notably when access to the instructions is gated at run-time and the same source needs to assemble on multiple targets. From what I can see the mrc in venum_read_pmresr() is not a VFP/Neon instruction. It hails from arch/arm/kernel/perf_event_v7.c and is specific to Qualcomm's Scorpion and Krait CPUs. My understanding is that CP15 is used for the PMU in v7, it is possible that the use of p10 there is a mistake but I'm not knowledgeable enough about Scorpion and Krait to know whether this is the case.

You'll need to update test/MC/ARM/diagnostics.s as this is currently failing with this patch as it tests whether the old error message is being produced. You can run the tests from the build directory with make/ninja check-llvm. To run an individual test with output then from the build dir: bin/llvm-lit -v -a /path/to/llvm/test/MC/ARM/diagnostics.s