| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Logic for interrupts:
- interrupt.S raises spl (thus IF cleared)
- interrupt.S EOI
- interrupt.S calls the handler
- for pure in-kernel handlers, they do whatever they want with IF
cleared.
- when a userland handler is registers, queue_intr masks the irq.
- interrupt.S lowers spl with splx_cli, thus IF still cleared
- iret, that sets IF
- later on, userland acks the IRQ, that unmasks the irq
The key to this change is that all interrupts, including IPIs, are
treated the same way. Eg. the spl level is now raised before an IPI and
restored after. Also, EOI is not needed inside irq_acknowledge.
With this change and the experimental change not to dispatch threads
direct to idle processors in the scheduler, I no longer observe kernel
faults, but an occasional hang does occur.
Message-Id: <20231002033906.124427-1-damien@zamaudio.com>
|
|
|
|
|
| |
When the Linux IRQ driver is used we don't really control the list, so
we end up with a small leak.
|
|
|
|
|
| |
This notably avoids calling ipc_port_release from the interrupt handler,
which was completely unsafe.
|
|
|
|
| |
Rather than risking dereferencing NULL.
|
| |
|
| |
|
|
|
|
|
|
| |
We currently already always assume that irqs user handlers can be shared
* device/intr.c (install_user_intr_handler): Add SA_SHIRQ to flags.
|
|
|
|
|
|
|
|
|
|
| |
* device/intr.c: Include <kern/assert.h>
(struct intr_list): New structure.
(user_intr_handlers): New array.
(user_irq_handler): New function.
(install_user_intr_handler): New function.
Message-Id: <20210330025830.63528-2-damien@zamaudio.com>
|
|
This allows privileged userland drivers to get notifications of hardware
interrupts.
Initial work by Zheng Da, reworked by Damien Zammit and myself.
* Makefrag.am (libkernel_a_SOURCES): Add device/intr.c and
device/intr.h.
(include_device_HEADERS): Add include/device/notify.defs and
include/device/notify.h.
* device/dev_hdr.h (name_equal): Add declaration.
* device/ds_routines.c: Include <device/intr.h>
(ds_device_intr_register, ds_device_intr_ack): New functions.
* device/intr.c, device/intr.h: New files.
* doc/mach.texi (Device Interrupt): New section.
* i386/Makefrag.am (libkernel_a_SOURCES): Add i386/i386/irq.c and
i386/i386/irq.h.
* i386/i386/irq.c, i386/i386/irq.h: New files.
* i386/i386at/conf.c: Include <device/intr.h>.
(irqname): New macro.
(dev_name_list): Add irq device.
* include/device/device.defs (device_intr_register, device_intr_ack):
New RPCs.
* include/device/notify.defs, include/device/notify.h: New files.
* kern/startup.c: Include <device/intr.h>
(start_kernel_threads): Start intr_thread thread.
* linux/dev/arch/i386/kernel/irq.c: Include <device/intr.h>
(linux_action): Add user_intr field.
(linux_intr): Call user_intr action if any.
(mask_irq, unmask_irq): Move functions to i386/i386/pic.c
(__disable_irq, __enable_irq): Move functions to i386/i386/irq.c.
(install_user_intr_handler): New function.
(request_irq): Initialize user_intr field.
* linux/src/include/asm-i386/irq.h (__disable_irq, __enable_irq): Remove
prototypes.
* i386/i386/pic.c (mask_irq, unmask_irq): New functions.
* i386/i386/pic.h (mask_irq, unmask_irq): New prototypes.
|