diff options
Diffstat (limited to 'debian/patches/700015-New-kind-of-notification-untested.patch')
-rw-r--r-- | debian/patches/700015-New-kind-of-notification-untested.patch | 266 |
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 + |