Skip to content

driver callbacks and user mode #25950

@andrewboie

Description

@andrewboie

Is your enhancement proposal related to a problem? Please describe.
It's common to want to run some application code in response to driver events. Many of our driver subsystems (and our k_timer() API, which is essentially a timer driver callback) allow the user to install a callback handler (and in many cases a context pointer) to run when the event happens. The event is typically in the context of an ISR.

In our current MPU-based protection model, we've specifically forbidden providing access to driver callback installation from user mode, because such callback code runs in supervisor mode in the context of an ISR. We can't allow user mode to install program text which doesn't itself run in user mode for any reason.

The current workaround for this is as follows: in the early stages of the application, like in main() which starts in supervisor mode, is to install these callbacks here, before the application drops its privileges. The callback running under its parent ISR can access any memory it likes, including user memory; it's possible, for example, for the callback to fill user-accessible buffers with data. A user thread which has those buffers in its memory domain may later access them, perhaps using a k_sem shared between the user thread and the callback to synchronize.

Describe the solution you'd like
I would like an efficient way for a user application to set up driver callbacks for kernel events that originate from ISRs. The callback should be able to access memory in the process that installed the callback. The callback should run with the CPU in user mode, with the ability to sleep or make syscalls.

Internally, I imagine infrastructure such that a callback has two parts:

  1. The actual code that runs on behalf of the ISR, which obtains any relevant data and then releases an IPC object (like a k_sem or something) to wake up some user thread for further processing.
  2. The user part, which wakes up and runs the actual callback function logic, and has full access to the data posted by the ISR.

For the particular case of data buffers, we'd like to minimize the amount of copying done. But since the relevant user address space might not even be active, we'd either have to do copies or come up with some mechanism for mapping these buffers on the kernel side. I'm really waving my arms here, more contemplation of the specifics is needed.

I'd like the application-facing parts of this to be very simple to use. Particularly since this has implications for our driver APIs. Since this looks like it will require additional considerations to the current callback APIs we have, like mapping buffer memory, IPC objects, handler threads, etc, I'm wondering if the interface for this could be something like a workqueue API which takes a driver's callback installation API as a parameter.

Describe alternatives you've considered
This currently isn't a full solution spec, more like a problem statement with a few nebulous notions on how to think about addressing it. Open to ideas.

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions