mbox series

[v4,00/12] ARM: vfp: Switch to C API to en/disable softirqs

Message ID 20230320131845.3138015-1-ardb@kernel.org (mailing list archive)
Headers show
Series ARM: vfp: Switch to C API to en/disable softirqs | expand

Message

Ard Biesheuvel March 20, 2023, 1:18 p.m. UTC
As it turns out, enabling or disabling softirqs from asm code is more
tricky than it looks. Simply bumping the associated bit in preempt_count
does the trick for uninstrumented kernels, but with lockdep or preempt
debug enabled, we really need to call the C versions, as replicating
their behavior in asm fully is intractible.

So let's rework the existing code a little bit so we can interpose a
little C helper 'vfp_entry()' that disables softirqs before calling the
existing vfpstate handling code in asm. Re-enabling softirqs from asm
code is more straight-forward, as we can simply perform a tail call via
a C routine that is guaranteed to be callable as a function.

However, since calling these APIs from asm code is still not ideal,
let's reimplement the whole thing in C (patch #4)


Changes since v3:

I got a bit carried away, as I noticed that the NEON opcode matching
implemented in asm in entry-armv.S basically duplicates how undef hooks
work, and so I have added a patch that drops the associated asm code and
moves it into C code, reusing the existing VFP undef hook we have for
kernel mode exceptions. (patch #9)

With that removed, no Thumb mode undef exceptions remain that are
dispatched by the coprocessor undef handling, so that can be simplified
as well (patch #10)

iWMMXT undef exceptions can be handled using an undef hook as well,
(patch #11), which allows us to compile out the coprocessor dispatch
entirely unless we have FPE enabled, which is only the case on OABI or
OABI compat. This removes the non-standard calling convention which
returns via register R9 on success, which can only be implemented in
asm. (patch #12)

Patch #4 is a fix for an issue that I spotted while working on this,
patch #5 is an enhancement that makes it easier to keep track of how
many VFP traps were taken for emulation purposes.

The first four patches are fixes, the remaining ones might go into v6.4.

This also fixes the !CONFIG_VFP build error spotted by Guenter.


Changes since v2:
- add Rbs and Tbs from Linus and Guenter (thanks!)
- correct reference to local_bh_enable() vs __local_bh_enable_ip() in
  commit log of patch #3
- add patch that reworks the asm VFP exception handling entirely so the
  bulk of it is implemented in C. This could be taken into v6.4, while
  the  preceding patches are fixes for v6.3-rc

Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/all/ZBBYCSZUJOWBg1s8@localhost.localdomain/

Ard Biesheuvel (12):
  ARM: vfp: Pass thread_info pointer to vfp_support_entry
  ARM: vfp: Pass successful return address via register R3
  ARM: vfp: Fix broken softirq handling with instrumentation enabled
  ARM: entry: Fix iWMMXT TIF flag handling
  ARM: vfp: Record VFP bounces as perf emulation faults
  ARM: vfp: Remove workaround for Feroceon CPUs
  ARM: vfp: Reimplement VFP exception entry in C code
  ARM: kernel: Get rid of thread_info::used_cp[] array
  ARM: vfp: Use undef hook for handling VFP exceptions
  ARM: entry: Disregard Thumb undef exception in coproc dispatch
  ARM: iwmmxt: Use undef hook to enable coprocessor for task
  ARM: entry: Make asm coproc dispatch code NWFPE only

 arch/arm/include/asm/assembler.h   |  13 --
 arch/arm/include/asm/thread_info.h |  17 +-
 arch/arm/kernel/asm-offsets.c      |   1 -
 arch/arm/kernel/entry-armv.S       | 138 +++-----------
 arch/arm/kernel/iwmmxt.S           |   9 +
 arch/arm/kernel/pj4-cp0.c          |   1 +
 arch/arm/kernel/process.c          |   1 -
 arch/arm/kernel/ptrace.c           |   2 -
 arch/arm/kernel/xscale-cp0.c       |   1 +
 arch/arm/mm/proc-feroceon.S        |   4 +
 arch/arm/vfp/Makefile              |   2 +-
 arch/arm/vfp/entry.S               |  39 ----
 arch/arm/vfp/vfp.h                 |   1 +
 arch/arm/vfp/vfphw.S               | 200 ++------------------
 arch/arm/vfp/vfpmodule.c           | 195 ++++++++++++++-----
 15 files changed, 219 insertions(+), 405 deletions(-)
 delete mode 100644 arch/arm/vfp/entry.S

Comments

Guenter Roeck March 23, 2023, 2:44 a.m. UTC | #1
On Mon, Mar 20, 2023 at 02:18:33PM +0100, Ard Biesheuvel wrote:
> As it turns out, enabling or disabling softirqs from asm code is more
> tricky than it looks. Simply bumping the associated bit in preempt_count
> does the trick for uninstrumented kernels, but with lockdep or preempt
> debug enabled, we really need to call the C versions, as replicating
> their behavior in asm fully is intractible.
> 
> So let's rework the existing code a little bit so we can interpose a
> little C helper 'vfp_entry()' that disables softirqs before calling the
> existing vfpstate handling code in asm. Re-enabling softirqs from asm
> code is more straight-forward, as we can simply perform a tail call via
> a C routine that is guaranteed to be callable as a function.
> 
> However, since calling these APIs from asm code is still not ideal,
> let's reimplement the whole thing in C (patch #4)
> 

FWIW, all my qemu tests passed for this series.

Guenter
Ard Biesheuvel March 23, 2023, 8:33 a.m. UTC | #2
On Thu, 23 Mar 2023 at 03:44, Guenter Roeck <linux@roeck-us.net> wrote:
>
> On Mon, Mar 20, 2023 at 02:18:33PM +0100, Ard Biesheuvel wrote:
> > As it turns out, enabling or disabling softirqs from asm code is more
> > tricky than it looks. Simply bumping the associated bit in preempt_count
> > does the trick for uninstrumented kernels, but with lockdep or preempt
> > debug enabled, we really need to call the C versions, as replicating
> > their behavior in asm fully is intractible.
> >
> > So let's rework the existing code a little bit so we can interpose a
> > little C helper 'vfp_entry()' that disables softirqs before calling the
> > existing vfpstate handling code in asm. Re-enabling softirqs from asm
> > code is more straight-forward, as we can simply perform a tail call via
> > a C routine that is guaranteed to be callable as a function.
> >
> > However, since calling these APIs from asm code is still not ideal,
> > let's reimplement the whole thing in C (patch #4)
> >
>
> FWIW, all my qemu tests passed for this series.
>

Thanks for testing!