aboutsummaryrefslogtreecommitdiff
path: root/device/intr.c
Commit message (Collapse)AuthorAgeFilesLines
* intr: Note which interrupt is being refused to userlandSamuel Thibault2024-12-231-1/+1
|
* intr: Protect internals with a lockSergey Bugaev2024-12-101-16/+22
| | | | | | | | | | | | On SMP builds with 2 CPU cores, we've seen whole-system lock-ups caused by irqdev.tot_num_intr getting set to -1, even though it's supposed to always stay non-negative. Indeed, it was modified without the appropriate synchronization. Fix this by protecting it, as well as various other internals of device/intr with a simple_lock_irq. Reported-by: Damien Zammit <damien@zamaudio.com> Signed-off-by: Sergey Bugaev <bugaevc@gmail.com> Message-ID: <20241210115705.710555-3-bugaevc@gmail.com>
* device/intr: Account for interrupts that could not be deliveredDamien Zammit via Bug reports for the GNU Hurd2024-11-241-0/+4
| | | | | | | | | | | | When an irq handler dies, we are decrementing the n_unacked count and calling __enable_irq() the right number of times, but we need to decrement the total interrupt count by the number that were lost and also clear that number. This fixes a hang when a shared irq handler quits and leaves some unacked interrupts. Message-ID: <20241123222020.245519-1-damien@zamaudio.com>
* Fix interrupt handlingDamien Zammit2023-10-031-2/+14
| | | | | | | | | | | | | | | | | | | | | | | | | 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>
* intr: Fix crash on irq notification port destructionSamuel Thibault2023-06-121-1/+8
| | | | | When the Linux IRQ driver is used we don't really control the list, so we end up with a small leak.
* intr: Simplify clearing after intr port deallocationSamuel Thibault2023-02-161-35/+21
| | | | | This notably avoids calling ipc_port_release from the interrupt handler, which was completely unsafe.
* device intr: Return an error on bogus intr portSamuel Thibault2022-03-131-3/+5
| | | | Rather than risking dereferencing NULL.
* device intr: Fix hypothetical NULL dererefenceSamuel Thibault2022-03-131-1/+1
|
* SMP: Fix warningsSamuel Thibault2021-04-041-2/+2
|
* intr: Always share irqsSamuel Thibault2021-03-311-0/+2
| | | | | | We currently already always assume that irqs user handlers can be shared * device/intr.c (install_user_intr_handler): Add SA_SHIRQ to flags.
* intr: Add user interrupt handling code for non-Linux caseDamien Zammit2021-03-311-0/+80
| | | | | | | | | | * 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>
* Add hardware interrupt notification mechanismSamuel Thibault2020-07-101-0/+283
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.