summaryrefslogtreecommitdiff
path: root/debian/patches/700004-Some-cleanups-of-the-userspace-interrupt-handling.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/700004-Some-cleanups-of-the-userspace-interrupt-handling.patch')
-rw-r--r--debian/patches/700004-Some-cleanups-of-the-userspace-interrupt-handling.patch169
1 files changed, 169 insertions, 0 deletions
diff --git a/debian/patches/700004-Some-cleanups-of-the-userspace-interrupt-handling.patch b/debian/patches/700004-Some-cleanups-of-the-userspace-interrupt-handling.patch
new file mode 100644
index 0000000..3a0f341
--- /dev/null
+++ b/debian/patches/700004-Some-cleanups-of-the-userspace-interrupt-handling.patch
@@ -0,0 +1,169 @@
+From e1e25cd0a5f5778cf4f1e83321c8d081e2067683 Mon Sep 17 00:00:00 2001
+From: Justus Winter <justus@gnupg.org>
+Date: Thu, 25 Feb 2016 22:38:40 +0100
+Subject: [PATCH gnumach 4/9] Some cleanups of the userspace interrupt handling
+
+---
+ device/intr.c | 93 +++++++++++++++++++++++++++++------------------------------
+ 1 file changed, 46 insertions(+), 47 deletions(-)
+
+diff --git a/device/intr.c b/device/intr.c
+index 986f0ee..177c095 100644
+--- a/device/intr.c
++++ b/device/intr.c
+@@ -25,18 +25,6 @@ static queue_head_t intr_queue;
+ /* The total number of unprocessed interrupts. */
+ static int tot_num_intr;
+
+-static struct intr_entry *
+-search_intr (int line, ipc_port_t dest)
+-{
+- struct intr_entry *e;
+- queue_iterate (&intr_queue, e, struct intr_entry *, chain)
+- {
+- if (e->dest == dest && e->line == line)
+- return e;
+- }
+- return NULL;
+-}
+-
+ /* This function can only be used in the interrupt handler. */
+ boolean_t
+ queue_intr (struct intr_entry *e)
+@@ -46,9 +34,10 @@ queue_intr (struct intr_entry *e)
+ * been destroyed and I destroy it now. */
+ if (e->dest && e->dest->ip_references == 1)
+ {
++ /* JW: I don't like running this from an interrupt handler. */
+ ipc_port_release (e->dest);
+ e->dest = NULL;
+- printk ("irq handler %d: release an dead delivery port\n", e->line);
++ printf ("irq handler %d: release an dead delivery port\n", e->line);
+ return FALSE;
+ }
+
+@@ -74,21 +63,22 @@ insert_intr_entry (int line, ipc_port_t dest, struct intr_entry **entry)
+ new = (struct intr_entry *) kalloc (sizeof (*new));
+ if (new == NULL)
+ return D_NO_MEMORY;
+-
+- /* check whether the intr entry has been in the queue. */
+- cli ();
+- e = search_intr (line, dest);
+- if (e)
+- {
+- printf ("the interrupt entry for line %d and port %p has been inserted\n",
+- line, dest);
+- free = 1;
+- err = D_ALREADY_OPEN;
+- goto out;
+- }
+ new->line = line;
+ new->dest = dest;
+ new->interrupts = 0;
++
++ /* check whether the intr entry has been in the queue. */
++ cli ();
++ queue_iterate (&intr_queue, e, struct intr_entry *, chain)
++ if (e->dest == dest && e->line == line)
++ {
++ printf ("the interrupt entry for line %d and port %p "
++ "has already been inserted before.\n",
++ line, dest);
++ free = 1;
++ err = D_ALREADY_OPEN;
++ goto out;
++ }
+ queue_enter (&intr_queue, new, struct intr_entry *, chain);
+ out:
+ sti ();
+@@ -98,6 +88,30 @@ out:
+ return err;
+ }
+
++mach_intr_notification_t mach_intr_notification_template;
++
++static void
++init_mach_intr_notification (mach_intr_notification_t *n)
++{
++ mach_msg_header_t *m = &n->intr_header;
++ mach_msg_type_t *t = &n->intr_type;
++
++ m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0);
++ m->msgh_size = sizeof *n;
++ m->msgh_seqno = INTR_NOTIFY_MSGH_SEQNO;
++ m->msgh_local_port = MACH_PORT_NULL;
++ m->msgh_remote_port = MACH_PORT_NULL;
++ m->msgh_id = MACH_INTR_NOTIFY;
++
++ t->msgt_name = MACH_MSG_TYPE_INTEGER_32;
++ t->msgt_size = 32;
++ t->msgt_number = 1;
++ t->msgt_inline = TRUE;
++ t->msgt_longform = FALSE;
++ t->msgt_deallocate = FALSE;
++ t->msgt_unused = 0;
++}
++
+ void
+ intr_thread ()
+ {
+@@ -105,10 +119,10 @@ intr_thread ()
+ int line;
+ ipc_port_t dest;
+ queue_init (&intr_queue);
+-
++ init_mach_intr_notification (&mach_intr_notification_template);
++
+ for (;;)
+ {
+- assert_wait ((event_t) &intr_thread, FALSE);
+ cli ();
+ while (tot_num_intr)
+ {
+@@ -148,7 +162,9 @@ intr_thread ()
+ }
+ }
+ sti ();
+- thread_block (NULL);
++
++ assert_wait ((event_t) &intr_thread, FALSE);
++ thread_block (thread_no_continuation);
+ }
+ }
+
+@@ -163,29 +179,12 @@ deliver_intr (int line, ipc_port_t dest_port)
+ return FALSE;
+
+ kmsg = ikm_alloc(sizeof *n);
+- if (kmsg == IKM_NULL)
++ if (kmsg == IKM_NULL)
+ return FALSE;
+
+ ikm_init(kmsg, sizeof *n);
+ n = (mach_intr_notification_t *) &kmsg->ikm_header;
+-
+- mach_msg_header_t *m = &n->intr_header;
+- mach_msg_type_t *t = &n->intr_type;
+-
+- m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0);
+- m->msgh_size = sizeof *n;
+- m->msgh_seqno = INTR_NOTIFY_MSGH_SEQNO;
+- m->msgh_local_port = MACH_PORT_NULL;
+- m->msgh_remote_port = MACH_PORT_NULL;
+- m->msgh_id = MACH_INTR_NOTIFY;
+-
+- t->msgt_name = MACH_MSG_TYPE_INTEGER_32;
+- t->msgt_size = 32;
+- t->msgt_number = 1;
+- t->msgt_inline = TRUE;
+- t->msgt_longform = FALSE;
+- t->msgt_deallocate = FALSE;
+- t->msgt_unused = 0;
++ *n = mach_intr_notification_template;
+
+ n->intr_header.msgh_remote_port = dest;
+ n->line = line;
+--
+2.1.4
+