summaryrefslogtreecommitdiff
path: root/debian/patches/700015-New-kind-of-notification-untested.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/700015-New-kind-of-notification-untested.patch')
-rw-r--r--debian/patches/700015-New-kind-of-notification-untested.patch266
1 files changed, 266 insertions, 0 deletions
diff --git a/debian/patches/700015-New-kind-of-notification-untested.patch b/debian/patches/700015-New-kind-of-notification-untested.patch
new file mode 100644
index 0000000..4fabb7d
--- /dev/null
+++ b/debian/patches/700015-New-kind-of-notification-untested.patch
@@ -0,0 +1,266 @@
+From bd4eaa3a4209af577b1cf33c9c3afab42c716b47 Mon Sep 17 00:00:00 2001
+From: Justus Winter <justus@gnupg.org>
+Date: Fri, 26 Feb 2016 20:05:40 +0100
+Subject: [PATCH gnumach 15/15] New kind of notification, untested
+
+---
+ device/ds_routines.c | 31 +++++++++++-
+ device/interrupt.h | 1 +
+ device/intr.c | 104 ++++++++++++++++++++++++++++++++++++++---
+ include/device/intr.h | 12 +++++
+ include/mach/experimental.defs | 14 ++++++
+ 5 files changed, 155 insertions(+), 7 deletions(-)
+
+diff --git a/device/ds_routines.c b/device/ds_routines.c
+index 2b9869a..74569aa 100644
+--- a/device/ds_routines.c
++++ b/device/ds_routines.c
+@@ -340,7 +340,36 @@ experimental_device_intr_register (ipc_port_t master_port, int line,
+ if (line < 0 || line >= 16)
+ return D_INVALID_OPERATION;
+
+- ret = insert_intr_entry (line, receive_port, &entry);
++ ret = insert_intr_entry (line, receive_port, FALSE, &entry);
++ if (ret)
++ return ret;
++
++ return install_user_intr_handler (line, flags, entry);
++#endif /* MACH_XEN */
++}
++
++io_return_t
++experimental_device_intr_register2 (ipc_port_t master_port, int line,
++ int flags, ipc_port_t notification_port)
++{
++#ifdef MACH_XEN
++ return D_INVALID_OPERATION;
++#else /* MACH_XEN */
++ struct intr_entry *entry;
++ io_return_t ret;
++
++ /* Open must be called on the master device port. */
++ if (master_port != master_device_port)
++ return D_INVALID_OPERATION;
++
++ if (notification_port == MACH_PORT_NULL)
++ return D_INVALID_OPERATION;
++
++ /* XXX: move to arch-specific */
++ if (line < 0 || line >= 16)
++ return D_INVALID_OPERATION;
++
++ ret = insert_intr_entry (line, notification_port, TRUE, &entry);
+ if (ret)
+ return ret;
+
+diff --git a/device/interrupt.h b/device/interrupt.h
+index c43c3e0..12e6efc 100644
+--- a/device/interrupt.h
++++ b/device/interrupt.h
+@@ -21,6 +21,7 @@
+ struct intr_entry;
+ boolean_t queue_intr (struct intr_entry *e);
+ kern_return_t insert_intr_entry (int line, ipc_port_t dest,
++ int new_style, /* version2 notifications? */
+ struct intr_entry **entry);
+
+ int install_user_intr_handler (unsigned int line,
+diff --git a/device/intr.c b/device/intr.c
+index c930e84..143bed3 100644
+--- a/device/intr.c
++++ b/device/intr.c
+@@ -36,6 +36,7 @@ struct intr_entry
+ ipc_port_t port; /* We receive notifications on this port. */
+ queue_chain_t chain;
+ ipc_port_t dest;
++ int new_style; /* version2 notifications?. */
+ int line;
+ /* The number of interrupts occur since last run of intr_thread. */
+ int interrupts;
+@@ -62,7 +63,10 @@ queue_intr (struct intr_entry *e)
+ * This entry exists in the queue until
+ * the corresponding interrupt port is removed.*/
+ kern_return_t
+-insert_intr_entry (int line, ipc_port_t dest, struct intr_entry **entry)
++insert_intr_entry (int line,
++ ipc_port_t dest,
++ int new_style, /* version2 notifications? */
++ struct intr_entry **entry)
+ {
+ kern_return_t err = 0;
+ unsigned long flags;
+@@ -88,6 +92,7 @@ insert_intr_entry (int line, ipc_port_t dest, struct intr_entry **entry)
+
+ new->line = line;
+ new->dest = dest;
++ new->new_style = new_style;
+ new->interrupts = 0;
+
+ /* Register a dead-name notification so that we are notified if the
+@@ -250,6 +255,79 @@ deliver_intr (int line, ipc_port_t dest_port)
+ return TRUE;
+ }
+
++mach_intr_notification2_t mach_intr_notification2_template;
++
++static void
++init_mach_intr_notification2 (mach_intr_notification2_t *n)
++{
++ mach_msg_header_t *m = &n->intr_header;
++ mach_msg_type_t *t = &n->line_type;
++
++ m->msgh_bits =
++ MACH_MSGH_BITS_COMPLEX | 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;
++
++ t = &n->count_type;
++ 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;
++
++ t = &n->port_type;
++ t->msgt_name = MACH_MSG_TYPE_MAKE_SEND;
++ t->msgt_size = 32;
++ t->msgt_number = 1;
++ t->msgt_inline = TRUE;
++ t->msgt_longform = FALSE;
++ t->msgt_deallocate = FALSE;
++ t->msgt_unused = 0;
++}
++
++static boolean_t
++deliver_intr_notification2 (ipc_port_t notification_port,
++ int line, int count,
++ ipc_port_t interrupt_port)
++{
++ ipc_kmsg_t kmsg;
++ mach_intr_notification2_t *n;
++
++ assert (notification_port);
++ assert (interrupt_port);
++
++ kmsg = ikm_alloc(sizeof *n);
++ if (kmsg == IKM_NULL)
++ return FALSE;
++
++ ikm_init(kmsg, sizeof *n);
++ n = (mach_intr_notification2_t *) &kmsg->ikm_header;
++ *n = mach_intr_notification2_template;
++
++ n->intr_header.msgh_remote_port = (mach_port_t) notification_port;
++ n->line = line;
++ n->count = count;
++ n->interrupt_port = (mach_port_t) interrupt_port;
++
++ ipc_port_copy_send (notification_port);
++ ipc_mqueue_send_always(kmsg);
++
++ return TRUE;
++}
++
+ void
+ intr_thread ()
+ {
+@@ -258,6 +336,7 @@ intr_thread ()
+ ipc_port_t dest;
+ queue_init (&intr_queue);
+ init_mach_intr_notification (&mach_intr_notification_template);
++ init_mach_intr_notification2 (&mach_intr_notification2_template);
+
+ kmem_cache_init (&intr_entry_cache, "intr_entry",
+ sizeof (struct intr_entry), 0, NULL, 0);
+@@ -274,11 +353,24 @@ intr_thread ()
+ {
+ line = e->line;
+ dest = e->dest;
+- e->interrupts--;
+-
+- cpu_intr_restore (flags);
+- deliver_intr (line, dest);
+- cpu_intr_save (&flags);
++ if (e->new_style)
++ {
++ ipc_port_t interrupt_port = e->port;
++ int count = e->interrupts;
++ e->interrupts = 0;
++
++ cpu_intr_restore (flags);
++ deliver_intr_notification2 (dest, line, count, interrupt_port);
++ cpu_intr_save (&flags);
++ }
++ else
++ {
++ e->interrupts--;
++
++ cpu_intr_restore (flags);
++ deliver_intr (line, dest);
++ cpu_intr_save (&flags);
++ }
+
+ /* We cannot assume that e still exists at this point
+ because we released the lock. Hence we restart the
+diff --git a/include/device/intr.h b/include/device/intr.h
+index a02b64c..e7aa7e2 100644
+--- a/include/device/intr.h
++++ b/include/device/intr.h
+@@ -11,7 +11,19 @@ typedef struct
+ int line;
+ } mach_intr_notification_t;
+
++typedef struct
++{
++ mach_msg_header_t intr_header;
++ mach_msg_type_t line_type;
++ mach_msg_type_number_t line;
++ mach_msg_type_t count_type;
++ mach_msg_type_number_t count;
++ mach_msg_type_t port_type;
++ mach_port_t interrupt_port;
++} mach_intr_notification2_t;
++
+ #define INTR_NOTIFY_MSGH_SEQNO 0
+ #define MACH_INTR_NOTIFY 424242
++#define MACH_INTR_NOTIFY2 424247
+
+ #endif
+diff --git a/include/mach/experimental.defs b/include/mach/experimental.defs
+index 11c51d6..03fdee4 100644
+--- a/include/mach/experimental.defs
++++ b/include/mach/experimental.defs
+@@ -106,3 +106,17 @@ routine vm_allocate_contiguous(
+ out vaddr : vm_address_t;
+ out paddr : vm_address_t;
+ size : vm_size_t);
++
++/* 424246 */
++routine device_intr_register2(
++ master_port : mach_port_t;
++ line : int;
++ flags : int;
++ notification_port: mach_port_send_t);
++
++/* 424247 */
++skip; /* simpleroutine mach_intr_notify2(
++ notify : notify_port_t;
++ line : int,
++ count : int,
++ port : mach_port_send_t); */
+--
+2.1.4
+