diff options
Diffstat (limited to 'debian')
11 files changed, 0 insertions, 2045 deletions
diff --git a/debian/patches/700001-70_dde.patch.patch b/debian/patches/700001-70_dde.patch.patch deleted file mode 100644 index 55beaf1..0000000 --- a/debian/patches/700001-70_dde.patch.patch +++ /dev/null @@ -1,819 +0,0 @@ -From 9ad7eb46b65b7324dd5f2c6f5568b6a0e033a5f4 Mon Sep 17 00:00:00 2001 -From: Justus Winter <justus@gnupg.org> -Date: Thu, 25 Feb 2016 18:46:32 +0100 -Subject: [PATCH gnumach 01/10] 70_dde.patch - ---- - Makefrag.am | 9 ++ - device/ds_routines.c | 55 +++++++++++ - device/ds_routines.h | 3 + - device/intr.c | 198 +++++++++++++++++++++++++++++++++++++++ - include/device/intr.h | 17 ++++ - include/mach/experimental.defs | 100 ++++++++++++++++++++ - kern/experimental.srv | 3 + - kern/ipc_kobject.c | 3 + - kern/startup.c | 4 + - linux/dev/arch/i386/kernel/irq.c | 81 +++++++++++++++- - linux/dev/drivers/block/genhd.c | 4 +- - vm/vm_user.c | 103 ++++++++++++++++++++ - 12 files changed, 578 insertions(+), 2 deletions(-) - create mode 100644 device/intr.c - create mode 100644 include/device/intr.h - create mode 100644 include/mach/experimental.defs - create mode 100644 kern/experimental.srv - -diff --git a/Makefrag.am b/Makefrag.am -index 9a68af8..de11a71 100644 ---- a/Makefrag.am -+++ b/Makefrag.am -@@ -220,6 +220,7 @@ EXTRA_DIST += \ - kern/mach.srv \ - kern/mach4.srv \ - kern/gnumach.srv \ -+ kern/experimental.srv \ - kern/mach_debug.srv \ - kern/mach_host.srv \ - kern/task_notify.cli -@@ -304,6 +305,7 @@ libkernel_a_SOURCES += \ - device/device_types_kernel.h \ - device/ds_routines.c \ - device/ds_routines.h \ -+ device/intr.c \ - device/if_ether.h \ - device/if_hdr.h \ - device/io_req.h \ -@@ -352,6 +354,7 @@ include_device_HEADERS = \ - include/device/device_types.defs \ - include/device/device_types.h \ - include/device/disk_status.h \ -+ include/device/intr.h \ - include/device/net_status.h \ - include/device/tape_status.h \ - include/device/tty_status.h -@@ -374,6 +377,7 @@ include_mach_HEADERS = \ - include/mach/memory_object_default.defs \ - include/mach/notify.defs \ - include/mach/std_types.defs \ -+ include/mach/experimental.defs \ - include/mach/alert.h \ - include/mach/boolean.h \ - include/mach/boot.h \ -@@ -522,6 +526,7 @@ nodist_lib_dep_tr_for_defs_a_SOURCES += \ - kern/mach.server.defs.c \ - kern/mach4.server.defs.c \ - kern/gnumach.server.defs.c \ -+ kern/experimental.server.defs.c \ - kern/mach_debug.server.defs.c \ - kern/mach_host.server.defs.c - nodist_libkernel_a_SOURCES += \ -@@ -534,6 +539,9 @@ nodist_libkernel_a_SOURCES += \ - kern/gnumach.server.h \ - kern/gnumach.server.c \ - kern/gnumach.server.msgids \ -+ kern/experimental.server.h \ -+ kern/experimental.server.c \ -+ kern/experimental.server.msgids \ - kern/mach_debug.server.h \ - kern/mach_debug.server.c \ - kern/mach_debug.server.msgids \ -@@ -543,6 +551,7 @@ nodist_libkernel_a_SOURCES += \ - # kern/mach.server.defs - # kern/mach4.server.defs - # kern/gnumach.server.defs -+# kern/experimental.server.defs - # kern/mach_debug.server.defs - # kern/mach_host.server.defs - -diff --git a/device/ds_routines.c b/device/ds_routines.c -index dbff7f8..4f6b345 100644 ---- a/device/ds_routines.c -+++ b/device/ds_routines.c -@@ -318,6 +318,43 @@ ds_device_map (device_t dev, vm_prot_t prot, vm_offset_t offset, - offset, size, pager, unmap); - } - -+io_return_t -+experimental_device_intr_register (ipc_port_t master_port, int line, -+ int id, int flags, ipc_port_t receive_port) -+{ -+#ifdef MACH_XEN -+ return D_INVALID_OPERATION; -+#else /* MACH_XEN */ -+ extern int install_user_intr_handler (unsigned int line, -+ unsigned long flags, -+ ipc_port_t dest); -+ io_return_t ret; -+ -+ /* Open must be called on the master device port. */ -+ if (master_port != master_device_port) -+ return D_INVALID_OPERATION; -+ -+ /* XXX: move to arch-specific */ -+ if (line < 0 || line >= 16) -+ return D_INVALID_OPERATION; -+ -+ ret = insert_intr_entry (line, receive_port); -+ if (ret) -+ return ret; -+ // TODO The original port should be replaced -+ // when the same device driver calls it again, -+ // in order to handle the case that the device driver crashes and restarts. -+ ret = install_user_intr_handler (line, flags, receive_port); -+ -+ /* If the port is installed successfully, increase its reference by 1. -+ * Thus, the port won't be destroyed after its task is terminated. */ -+ if (ret == 0) -+ ip_reference (receive_port); -+ -+ return ret; -+#endif /* MACH_XEN */ -+} -+ - boolean_t - ds_notify (mach_msg_header_t *msg) - { -@@ -1798,6 +1835,24 @@ device_writev_trap (mach_device_t device, dev_mode_t mode, - return (result); - } - -+kern_return_t -+experimental_device_intr_enable(ipc_port_t master_port, int line, char status) -+{ -+#ifdef MACH_XEN -+ return D_INVALID_OPERATION; -+#else /* MACH_XEN */ -+ if (master_port != master_device_port) -+ return D_INVALID_OPERATION; -+ -+ if (status) -+ /* TODO: better name for generic-to-arch-specific call */ -+ enable_irq (line); -+ else -+ disable_irq (line); -+ return 0; -+#endif /* MACH_XEN */ -+} -+ - struct device_emulation_ops mach_device_emulation_ops = - { - (void*) mach_device_reference, -diff --git a/device/ds_routines.h b/device/ds_routines.h -index c0543cb..e9f115f 100644 ---- a/device/ds_routines.h -+++ b/device/ds_routines.h -@@ -83,4 +83,7 @@ io_return_t ds_device_writev_trap( - io_buf_vec_t *iovec, - vm_size_t count); - -+/* XXX arch-specific */ -+extern ipc_port_t intr_rcv_ports[16]; -+ - #endif /* DS_ROUTINES_H */ -diff --git a/device/intr.c b/device/intr.c -new file mode 100644 -index 0000000..6fca328 ---- /dev/null -+++ b/device/intr.c -@@ -0,0 +1,198 @@ -+#include <device/intr.h> -+#include <device/ds_routines.h> -+#include <kern/queue.h> -+#include <kern/printf.h> -+ -+#ifndef MACH_XEN -+// TODO this is only for x86 system -+#define sti() __asm__ __volatile__ ("sti": : :"memory") -+#define cli() __asm__ __volatile__ ("cli": : :"memory") -+ -+static boolean_t deliver_intr (int line, ipc_port_t dest_port); -+ -+struct intr_entry -+{ -+ queue_chain_t chain; -+ ipc_port_t dest; -+ int line; -+ /* The number of interrupts occur since last run of intr_thread. */ -+ int interrupts; -+}; -+ -+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. */ -+void -+queue_intr (int line, ipc_port_t dest) -+{ -+ extern void intr_thread (); -+ struct intr_entry *e; -+ -+ cli (); -+ e = search_intr (line, dest); -+ assert (e); -+ e->interrupts++; -+ tot_num_intr++; -+ sti (); -+ -+ thread_wakeup ((event_t) &intr_thread); -+} -+ -+/* insert an interrupt entry in the queue. -+ * This entry exists in the queue until -+ * the corresponding interrupt port is removed.*/ -+int -+insert_intr_entry (int line, ipc_port_t dest) -+{ -+ int err = 0; -+ struct intr_entry *e, *new; -+ int free = 0; -+ -+ 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; -+ queue_enter (&intr_queue, new, struct intr_entry *, chain); -+out: -+ sti (); -+ if (free) -+ kfree ((vm_offset_t) new, sizeof (*new)); -+ return err; -+} -+ -+/* this function should be called when line is disabled. */ -+void mark_intr_removed (int line, ipc_port_t dest) -+{ -+ struct intr_entry *e; -+ -+ e = search_intr (line, dest); -+ if (e) -+ e->dest = NULL; -+} -+ -+void -+intr_thread () -+{ -+ struct intr_entry *e; -+ int line; -+ ipc_port_t dest; -+ queue_init (&intr_queue); -+ -+ for (;;) -+ { -+ assert_wait ((event_t) &intr_thread, FALSE); -+ cli (); -+ while (tot_num_intr) -+ { -+ int del = 0; -+ -+ queue_iterate (&intr_queue, e, struct intr_entry *, chain) -+ { -+ /* if an entry doesn't have dest port, -+ * we should remove it. */ -+ if (e->dest == NULL) -+ { -+ del = 1; -+ break; -+ } -+ -+ if (e->interrupts) -+ { -+ line = e->line; -+ dest = e->dest; -+ e->interrupts--; -+ tot_num_intr--; -+ -+ sti (); -+ deliver_intr (line, dest); -+ cli (); -+ } -+ } -+ -+ /* remove the entry without dest port from the queue and free it. */ -+ if (del) -+ { -+ assert (!queue_empty (&intr_queue)); -+ queue_remove (&intr_queue, e, struct intr_entry *, chain); -+ sti (); -+ kfree ((vm_offset_t) e, sizeof (*e)); -+ cli (); -+ } -+ } -+ sti (); -+ thread_block (NULL); -+ } -+} -+ -+static boolean_t -+deliver_intr (int line, ipc_port_t dest_port) -+{ -+ ipc_kmsg_t kmsg; -+ mach_intr_notification_t *n; -+ mach_port_t dest = (mach_port_t) dest_port; -+ -+ if (dest == MACH_PORT_NULL) -+ return FALSE; -+ -+ kmsg = ikm_alloc(sizeof *n); -+ 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->intr_header.msgh_remote_port = dest; -+ n->line = line; -+ -+ ipc_port_copy_send (dest_port); -+ ipc_mqueue_send_always(kmsg); -+ -+ return TRUE; -+} -+#endif /* MACH_XEN */ -diff --git a/include/device/intr.h b/include/device/intr.h -new file mode 100644 -index 0000000..a02b64c ---- /dev/null -+++ b/include/device/intr.h -@@ -0,0 +1,17 @@ -+#ifndef __INTR_H__ -+ -+#define __INTR_H__ -+ -+#include <device/device_types.h> -+ -+typedef struct -+{ -+ mach_msg_header_t intr_header; -+ mach_msg_type_t intr_type; -+ int line; -+} mach_intr_notification_t; -+ -+#define INTR_NOTIFY_MSGH_SEQNO 0 -+#define MACH_INTR_NOTIFY 424242 -+ -+#endif -diff --git a/include/mach/experimental.defs b/include/mach/experimental.defs -new file mode 100644 -index 0000000..ca1eb92 ---- /dev/null -+++ b/include/mach/experimental.defs -@@ -0,0 +1,100 @@ -+/* -+ * Mach Operating System -+ * Copyright (c) 1991,1990,1989 Carnegie Mellon University -+ * All Rights Reserved. -+ * -+ * Permission to use, copy, modify and distribute this software and its -+ * documentation is hereby granted, provided that both the copyright -+ * notice and this permission notice appear in all copies of the -+ * software, derivative works or modified versions, and any portions -+ * thereof, and that both notices appear in supporting documentation. -+ * -+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" -+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR -+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. -+ * -+ * Carnegie Mellon requests users of this software to return to -+ * -+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU -+ * School of Computer Science -+ * Carnegie Mellon University -+ * Pittsburgh PA 15213-3890 -+ * -+ * any improvements or extensions that they make and grant Carnegie Mellon -+ * the rights to redistribute these changes. -+ */ -+ -+subsystem -+#if KERNEL_USER -+ KernelUser -+#endif /* KERNEL_USER */ -+#if KERNEL_SERVER -+ KernelServer -+#endif /* KERNEL_SERVER */ -+ experimental 424242; -+ -+#include <mach/std_types.defs> -+#include <mach/mach_types.defs> -+ -+serverprefix experimental_; -+ -+type notify_port_t = MACH_MSG_TYPE_MOVE_SEND_ONCE -+ ctype: mach_port_t; -+ -+skip; /*simpleroutine mach_intr_notify( -+ notify : notify_port_t; -+ name : int);*/ -+ -+routine device_intr_register( -+ master_port : mach_port_t; -+ in line : int; -+ in id : int; -+ in flags : int; -+ in receive_port : mach_port_send_t -+ ); -+ -+/* -+ * enable/disable the specified line. -+ */ -+/* XXX: Naming a function taht can disable something "xxx_enable" is confusing. */ -+/* Is the disable part actually used at all? AIUI, the kernel IRQ handler -+should always disable the line; and the userspace driver only has to -+reenable it, after acknowledging and handling the interrupt... -+*/ -+routine device_intr_enable( -+ master_port : mach_port_t; -+ line : int; -+ status : char); -+ -+/* -+ * This routine is created for allocating DMA buffers. -+ * We are going to get a contiguous physical memory -+ * and its physical address in addition to the virtual address. -+ */ -+ -+ /* XXX -+ This RPC lacks a few additional constraints like boundaries, alignment -+and maybe phase. We may not use them now, but they're important for -+portability (e.g. if GNU Mach supports PAE, drivers that can't use -+physical memory beyond the 4 GiB limit must be able to express it). -+ -+> What do you mean by "phase"? -+ -+Offset from the alignment. But I don't think it's useful at all in this -+case. Minimum and maximum addresses and alignment should do. Maybe -+boundary crossing but usually, specifying the right alignment and size -+is enough. -+ -+For upstream -+inclusion, we need to do it properly: the RPC should return a special -+memory object (similar to device_map() ), which can then be mapped into -+the process address space with vm_map() like any other memory object. -+ -+phys_address_t? -+ */ -+routine vm_allocate_contiguous( -+ host_priv : host_priv_t; -+ target_task : vm_task_t; -+ out vaddr : vm_address_t; -+ out paddr : vm_address_t; -+ size : vm_size_t); -diff --git a/kern/experimental.srv b/kern/experimental.srv -new file mode 100644 -index 0000000..2ccfd78 ---- /dev/null -+++ b/kern/experimental.srv -@@ -0,0 +1,3 @@ -+#define KERNEL_SERVER 1 -+ -+#include <mach/experimental.defs> -diff --git a/kern/ipc_kobject.c b/kern/ipc_kobject.c -index 709ec9e..c65458b 100644 ---- a/kern/ipc_kobject.c -+++ b/kern/ipc_kobject.c -@@ -56,6 +56,7 @@ - #include <device/device_pager.server.h> - #include <kern/mach4.server.h> - #include <kern/gnumach.server.h> -+#include <kern/experimental.server.h> - - #if MACH_DEBUG - #include <kern/mach_debug.server.h> -@@ -159,6 +160,7 @@ ipc_kobject_server(request) - * to perform the kernel function - */ - { -+ extern mig_routine_t experimental_server_routine(); - check_simple_locks(); - if ((routine = mach_server_routine(&request->ikm_header)) != 0 - || (routine = mach_port_server_routine(&request->ikm_header)) != 0 -@@ -170,6 +172,7 @@ ipc_kobject_server(request) - #endif /* MACH_DEBUG */ - || (routine = mach4_server_routine(&request->ikm_header)) != 0 - || (routine = gnumach_server_routine(&request->ikm_header)) != 0 -+ || (routine = experimental_server_routine(&request->ikm_header)) != 0 - #if MACH_MACHINE_ROUTINES - || (routine = MACHINE_SERVER_ROUTINE(&request->ikm_header)) != 0 - #endif /* MACH_MACHINE_ROUTINES */ -diff --git a/kern/startup.c b/kern/startup.c -index bd29694..05de5e6 100644 ---- a/kern/startup.c -+++ b/kern/startup.c -@@ -79,6 +79,7 @@ boolean_t reboot_on_panic = TRUE; - /* XX */ - extern vm_offset_t phys_first_addr, phys_last_addr; - extern char *kernel_cmdline; -+extern void intr_thread(); - - /* - * Running in virtual memory, on the interrupt stack. -@@ -221,6 +222,9 @@ void start_kernel_threads(void) - (void) kernel_thread(kernel_task, reaper_thread, (char *) 0); - (void) kernel_thread(kernel_task, swapin_thread, (char *) 0); - (void) kernel_thread(kernel_task, sched_thread, (char *) 0); -+#ifndef MACH_XEN -+ (void) kernel_thread(kernel_task, intr_thread, (char *)0); -+#endif /* MACH_XEN */ - - #if NCPUS > 1 - /* -diff --git a/linux/dev/arch/i386/kernel/irq.c b/linux/dev/arch/i386/kernel/irq.c -index 7753814..b7dfa1a 100644 ---- a/linux/dev/arch/i386/kernel/irq.c -+++ b/linux/dev/arch/i386/kernel/irq.c -@@ -83,6 +83,7 @@ struct linux_action - void *dev_id; - struct linux_action *next; - unsigned long flags; -+ volatile ipc_port_t delivery_port; - }; - - static struct linux_action *irq_action[16] = -@@ -102,6 +103,7 @@ linux_intr (int irq) - { - struct pt_regs regs; - struct linux_action *action = *(irq_action + irq); -+ struct linux_action **prev = &irq_action[irq]; - unsigned long flags; - - kstat.interrupts[irq]++; -@@ -113,7 +115,37 @@ linux_intr (int irq) - - while (action) - { -- action->handler (irq, action->dev_id, ®s); -+ // TODO I might need to check whether the interrupt belongs to -+ // the current device. But I don't do it for now. -+ if (action->delivery_port) -+ { -+ /* The reference of the port was increased -+ * when the port was installed. -+ * If the reference is 1, it means the port should -+ * have been destroyed and I destroy it now. */ -+ if (action->delivery_port -+ && action->delivery_port->ip_references == 1) -+ { -+ mark_intr_removed (irq, action->delivery_port); -+ ipc_port_release (action->delivery_port); -+ *prev = action->next; -+ printk ("irq handler %d: release an dead delivery port\n", irq); -+ linux_kfree(action); -+ action = *prev; -+ continue; -+ } -+ else -+ { -+ /* We disable the irq here and it will be enabled -+ * after the interrupt is handled by the user space driver. */ -+ disable_irq (irq); -+ queue_intr (irq, action->delivery_port); -+ } -+ -+ } -+ else if (action->handler) -+ action->handler (irq, action->dev_id, ®s); -+ prev = &action->next; - action = action->next; - } - -@@ -233,6 +265,7 @@ setup_x86_irq (int irq, struct linux_action *new) - } - while (old); - shared = 1; -+ printk("store a new irq %d\n", irq); - } - - save_flags (flags); -@@ -250,6 +283,51 @@ setup_x86_irq (int irq, struct linux_action *new) - return 0; - } - -+int -+install_user_intr_handler (unsigned int irq, unsigned long flags, -+ ipc_port_t dest) -+{ -+ struct linux_action *action; -+ struct linux_action *old; -+ int retval; -+ -+ assert (irq < 16); -+ -+ /* Test whether the irq handler has been set */ -+ // TODO I need to protect the array when iterating it. -+ old = irq_action[irq]; -+ while (old) -+ { -+ if (old->delivery_port == dest) -+ { -+ printk ("The interrupt handler has been installed on line %d", irq); -+ return linux_to_mach_error (-EAGAIN); -+ } -+ old = old->next; -+ } -+ -+ /* -+ * Hmm... Should I use `kalloc()' ? -+ * By OKUJI Yoshinori. -+ */ -+ action = (struct linux_action *) -+ linux_kmalloc (sizeof (struct linux_action), GFP_KERNEL); -+ if (action == NULL) -+ return linux_to_mach_error (-ENOMEM); -+ -+ action->handler = NULL; -+ action->next = NULL; -+ action->dev_id = NULL; -+ action->flags = flags; -+ action->delivery_port = dest; -+ -+ retval = setup_x86_irq (irq, action); -+ if (retval) -+ linux_kfree (action); -+ -+ return linux_to_mach_error (retval); -+} -+ - /* - * Attach a handler to an IRQ. - */ -@@ -278,6 +356,7 @@ request_irq (unsigned int irq, void (*handler) (int, void *, struct pt_regs *), - action->next = NULL; - action->dev_id = dev_id; - action->flags = flags; -+ action->delivery_port = NULL; - - retval = setup_x86_irq (irq, action); - if (retval) -diff --git a/linux/dev/drivers/block/genhd.c b/linux/dev/drivers/block/genhd.c -index 3a86138..4a36f7f 100644 ---- a/linux/dev/drivers/block/genhd.c -+++ b/linux/dev/drivers/block/genhd.c -@@ -812,7 +812,9 @@ void device_setup(void) - #ifdef MACH - linux_intr_pri = SPL6; - #endif -- net_dev_init(); -+ extern char *kernel_cmdline; -+ if (!strstr(kernel_cmdline, " nonetdev")) -+ net_dev_init(); - #endif - #ifndef MACH - console_map_init(); -diff --git a/vm/vm_user.c b/vm/vm_user.c -index e65f6d5..788f43a 100644 ---- a/vm/vm_user.c -+++ b/vm/vm_user.c -@@ -449,3 +449,106 @@ kern_return_t vm_wire(port, map, start, size, access) - round_page(start+size), - access); - } -+ -+kern_return_t experimental_vm_allocate_contiguous(host_priv, map, result_vaddr, result_paddr, size) -+ host_t host_priv; -+ vm_map_t map; -+ vm_address_t *result_vaddr; -+ vm_address_t *result_paddr; -+ vm_size_t size; -+{ -+ unsigned int npages; -+ unsigned int i; -+ unsigned int order; -+ vm_page_t pages; -+ vm_object_t object; -+ vm_map_entry_t entry; -+ kern_return_t kr; -+ vm_address_t vaddr; -+ vm_offset_t offset = 0; -+ -+ if (host_priv == HOST_NULL) -+ return KERN_INVALID_HOST; -+ -+ if (map == VM_MAP_NULL) -+ return KERN_INVALID_TASK; -+ -+ /* -+ * XXX The page allocator returns blocks with a power-of-two size. -+ * The requested size may not be a power-of-two, causing the pages -+ * at the end of a block to be unused. In order to keep track of -+ * those pages, they must all be inserted in the VM object created -+ * by this function. -+ */ -+ order = vm_page_order(size); -+ size = (1 << (order + PAGE_SHIFT)); -+ -+ /* We allocate the contiguous physical pages for the buffer. */ -+ -+ npages = size / PAGE_SIZE; -+ pages = vm_page_grab_contig(size, VM_PAGE_SEL_DIRECTMAP); -+ if (pages == NULL) -+ { -+ return KERN_RESOURCE_SHORTAGE; -+ } -+ -+#if 0 -+ kr = vm_page_grab_contig(npages, pages, NULL, TRUE); -+ if (kr) -+ { -+ kfree (pages, npages * sizeof (vm_page_t)); -+ return kr; -+ } -+#endif -+ -+ /* Allocate the object -+ * and find the virtual address for the DMA buffer */ -+ -+ object = vm_object_allocate(size); -+ vm_map_lock(map); -+ /* TODO user_wired_count might need to be set as 1 */ -+ kr = vm_map_find_entry(map, &vaddr, size, (vm_offset_t) 0, -+ VM_OBJECT_NULL, &entry); -+ if (kr != KERN_SUCCESS) -+ { -+ vm_map_unlock(map); -+ vm_object_deallocate(object); -+ vm_page_free_contig(pages, size); -+ return kr; -+ } -+ -+ entry->object.vm_object = object; -+ entry->offset = 0; -+ -+ /* We can unlock map now. */ -+ vm_map_unlock(map); -+ -+ /* We have physical pages we need and now we need to do the mapping. */ -+ -+ pmap_pageable (map->pmap, vaddr, vaddr + size, FALSE); -+ -+ *result_vaddr = vaddr; -+ *result_paddr = pages->phys_addr; -+ -+ for (i = 0; i < npages; i++) -+ { -+ vm_object_lock(object); -+ vm_page_lock_queues(); -+ vm_page_insert(&pages[i], object, offset); -+ vm_page_wire(&pages[i]); -+ vm_page_unlock_queues(); -+ vm_object_unlock(object); -+ -+ /* Enter it in the kernel pmap */ -+ PMAP_ENTER(map->pmap, vaddr, &pages[i], VM_PROT_DEFAULT, TRUE); -+ -+ vm_object_lock(object); -+ PAGE_WAKEUP_DONE(&pages[i]); -+ vm_object_unlock(object); -+ -+ vaddr += PAGE_SIZE; -+ offset += PAGE_SIZE; -+ } -+ -+ return KERN_SUCCESS; -+} --- -2.1.4 - diff --git a/debian/patches/700002-Disable-disabling-the-irq-via-device_intr_enable.patch b/debian/patches/700002-Disable-disabling-the-irq-via-device_intr_enable.patch deleted file mode 100644 index d4a5ce1..0000000 --- a/debian/patches/700002-Disable-disabling-the-irq-via-device_intr_enable.patch +++ /dev/null @@ -1,92 +0,0 @@ -From f7c2f4ba69c3ae7df8fddcc2969e2c21e109dbd1 Mon Sep 17 00:00:00 2001 -From: Justus Winter <justus@gnupg.org> -Date: Thu, 25 Feb 2016 18:56:43 +0100 -Subject: [PATCH gnumach 02/10] Disable disabling the irq via - device_intr_enable - ---- - device/ds_routines.c | 9 ++++----- - device/intr.c | 3 ++- - include/mach/experimental.defs | 22 +++++++++++++++------- - 3 files changed, 21 insertions(+), 13 deletions(-) - -diff --git a/device/ds_routines.c b/device/ds_routines.c -index 4f6b345..9d399ee 100644 ---- a/device/ds_routines.c -+++ b/device/ds_routines.c -@@ -1844,11 +1844,10 @@ experimental_device_intr_enable(ipc_port_t master_port, int line, char status) - if (master_port != master_device_port) - return D_INVALID_OPERATION; - -- if (status) -- /* TODO: better name for generic-to-arch-specific call */ -- enable_irq (line); -- else -- disable_irq (line); -+ if (! status) -+ return D_INVALID_OPERATION; -+ -+ enable_irq (line); - return 0; - #endif /* MACH_XEN */ - } -diff --git a/device/intr.c b/device/intr.c -index 6fca328..02e0bab 100644 ---- a/device/intr.c -+++ b/device/intr.c -@@ -35,11 +35,12 @@ search_intr (int line, ipc_port_t dest) - return NULL; - } - -+void intr_thread (void); -+ - /* This function can only be used in the interrupt handler. */ - void - queue_intr (int line, ipc_port_t dest) - { -- extern void intr_thread (); - struct intr_entry *e; - - cli (); -diff --git a/include/mach/experimental.defs b/include/mach/experimental.defs -index ca1eb92..11c51d6 100644 ---- a/include/mach/experimental.defs -+++ b/include/mach/experimental.defs -@@ -52,19 +52,27 @@ routine device_intr_register( - in flags : int; - in receive_port : mach_port_send_t - ); -+/* JW: It doesn't look safe to pass flags through. dde sets -+ * SA_SHIRQ. -+ * -+ * ID seems unused. dde hands in 0. -+ */ - - /* -- * enable/disable the specified line. -+ * enable the specified line. -+ */ -+/* Is the disable part actually used at all? -- No. */ -+/* AIUI, the kernel IRQ handler should always disable the line; and -+ * the userspace driver only has to reenable it, after acknowledging -+ * and handling the interrupt... -+ * -+ * -- Indeed, and we should change the interface so that the irq is -+ * also re-enabled if the driver crashes. - */ --/* XXX: Naming a function taht can disable something "xxx_enable" is confusing. */ --/* Is the disable part actually used at all? AIUI, the kernel IRQ handler --should always disable the line; and the userspace driver only has to --reenable it, after acknowledging and handling the interrupt... --*/ - routine device_intr_enable( - master_port : mach_port_t; - line : int; -- status : char); -+ status : char /* MUST be true-ish */); - - /* - * This routine is created for allocating DMA buffers. --- -2.1.4 - diff --git a/debian/patches/700003-Rework-comment-on-the-userspace-interrupt-handling.patch b/debian/patches/700003-Rework-comment-on-the-userspace-interrupt-handling.patch deleted file mode 100644 index 4786b0b..0000000 --- a/debian/patches/700003-Rework-comment-on-the-userspace-interrupt-handling.patch +++ /dev/null @@ -1,284 +0,0 @@ -From 652cbc1f88f02f92096051a7ce13dcbf77e55fc4 Mon Sep 17 00:00:00 2001 -From: Justus Winter <justus@gnupg.org> -Date: Thu, 25 Feb 2016 20:54:22 +0100 -Subject: [PATCH gnumach 03/10] Rework/comment on the userspace interrupt - handling - ---- - device/ds_routines.c | 8 +++---- - device/interrupt.h | 14 ++++++++++++ - device/intr.c | 37 +++++++++++++++--------------- - kern/startup.c | 2 +- - linux/dev/arch/i386/kernel/irq.c | 49 ++++++++++++++++++---------------------- - 5 files changed, 58 insertions(+), 52 deletions(-) - create mode 100644 device/interrupt.h - -diff --git a/device/ds_routines.c b/device/ds_routines.c -index 9d399ee..7a5dda5 100644 ---- a/device/ds_routines.c -+++ b/device/ds_routines.c -@@ -325,9 +325,7 @@ experimental_device_intr_register (ipc_port_t master_port, int line, - #ifdef MACH_XEN - return D_INVALID_OPERATION; - #else /* MACH_XEN */ -- extern int install_user_intr_handler (unsigned int line, -- unsigned long flags, -- ipc_port_t dest); -+ struct intr_entry *entry; - io_return_t ret; - - /* Open must be called on the master device port. */ -@@ -338,13 +336,13 @@ 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); -+ ret = insert_intr_entry (line, receive_port, &entry); - if (ret) - return ret; - // TODO The original port should be replaced - // when the same device driver calls it again, - // in order to handle the case that the device driver crashes and restarts. -- ret = install_user_intr_handler (line, flags, receive_port); -+ ret = install_user_intr_handler (line, flags, entry); - - /* If the port is installed successfully, increase its reference by 1. - * Thus, the port won't be destroyed after its task is terminated. */ -diff --git a/device/interrupt.h b/device/interrupt.h -new file mode 100644 -index 0000000..0de43c2 ---- /dev/null -+++ b/device/interrupt.h -@@ -0,0 +1,14 @@ -+#ifndef DEVICE_INTERRUPT_H -+#define DEVICE_INTERRUPT_H -+ -+struct intr_entry; -+boolean_t queue_intr (struct intr_entry *e); -+int insert_intr_entry (int line, ipc_port_t dest, struct intr_entry **entry); -+ -+int install_user_intr_handler (unsigned int line, -+ unsigned long flags, -+ struct intr_entry *entry); -+ -+void intr_thread (void); -+ -+#endif /* DEVICE_INTERRUPT_H */ -diff --git a/device/intr.c b/device/intr.c -index 02e0bab..986f0ee 100644 ---- a/device/intr.c -+++ b/device/intr.c -@@ -3,6 +3,8 @@ - #include <kern/queue.h> - #include <kern/printf.h> - -+#include "interrupt.h" -+ - #ifndef MACH_XEN - // TODO this is only for x86 system - #define sti() __asm__ __volatile__ ("sti": : :"memory") -@@ -35,29 +37,35 @@ search_intr (int line, ipc_port_t dest) - return NULL; - } - --void intr_thread (void); -- - /* This function can only be used in the interrupt handler. */ --void --queue_intr (int line, ipc_port_t dest) -+boolean_t -+queue_intr (struct intr_entry *e) - { -- struct intr_entry *e; -- -+ /* The reference of the port was increased when the port was -+ * installed. If the reference is 1, it means the port should have -+ * been destroyed and I destroy it now. */ -+ if (e->dest && e->dest->ip_references == 1) -+ { -+ ipc_port_release (e->dest); -+ e->dest = NULL; -+ printk ("irq handler %d: release an dead delivery port\n", e->line); -+ return FALSE; -+ } -+ - cli (); -- e = search_intr (line, dest); -- assert (e); - e->interrupts++; - tot_num_intr++; - sti (); - - thread_wakeup ((event_t) &intr_thread); -+ return TRUE; - } - - /* insert an interrupt entry in the queue. - * This entry exists in the queue until - * the corresponding interrupt port is removed.*/ - int --insert_intr_entry (int line, ipc_port_t dest) -+insert_intr_entry (int line, ipc_port_t dest, struct intr_entry **entry) - { - int err = 0; - struct intr_entry *e, *new; -@@ -86,19 +94,10 @@ out: - sti (); - if (free) - kfree ((vm_offset_t) new, sizeof (*new)); -+ *entry = new; - return err; - } - --/* this function should be called when line is disabled. */ --void mark_intr_removed (int line, ipc_port_t dest) --{ -- struct intr_entry *e; -- -- e = search_intr (line, dest); -- if (e) -- e->dest = NULL; --} -- - void - intr_thread () - { -diff --git a/kern/startup.c b/kern/startup.c -index 05de5e6..0a571ff 100644 ---- a/kern/startup.c -+++ b/kern/startup.c -@@ -62,6 +62,7 @@ - #include <machine/model_dep.h> - #include <mach/version.h> - #include <device/device_init.h> -+#include <device/interrupt.h> - - #if MACH_KDB - #include <device/cons.h> -@@ -79,7 +80,6 @@ boolean_t reboot_on_panic = TRUE; - /* XX */ - extern vm_offset_t phys_first_addr, phys_last_addr; - extern char *kernel_cmdline; --extern void intr_thread(); - - /* - * Running in virtual memory, on the interrupt stack. -diff --git a/linux/dev/arch/i386/kernel/irq.c b/linux/dev/arch/i386/kernel/irq.c -index b7dfa1a..15f95c3 100644 ---- a/linux/dev/arch/i386/kernel/irq.c -+++ b/linux/dev/arch/i386/kernel/irq.c -@@ -49,6 +49,7 @@ - - #include <linux/dev/glue/glue.h> - #include <machine/machspl.h> -+#include <device/interrupt.h> - - #if 0 - /* XXX: This is the way it's done in linux 2.2. GNU Mach currently uses intr_count. It should be made using local_{bh/irq}_count instead (through hardirq_enter/exit) for SMP support. */ -@@ -83,7 +84,7 @@ struct linux_action - void *dev_id; - struct linux_action *next; - unsigned long flags; -- volatile ipc_port_t delivery_port; -+ struct intr_entry *userspace_handler; - }; - - static struct linux_action *irq_action[16] = -@@ -117,31 +118,19 @@ linux_intr (int irq) - { - // TODO I might need to check whether the interrupt belongs to - // the current device. But I don't do it for now. -- if (action->delivery_port) -+ if (action->userspace_handler) - { -- /* The reference of the port was increased -- * when the port was installed. -- * If the reference is 1, it means the port should -- * have been destroyed and I destroy it now. */ -- if (action->delivery_port -- && action->delivery_port->ip_references == 1) -- { -- mark_intr_removed (irq, action->delivery_port); -- ipc_port_release (action->delivery_port); -- *prev = action->next; -- printk ("irq handler %d: release an dead delivery port\n", irq); -- linux_kfree(action); -- action = *prev; -- continue; -- } -- else -- { - /* We disable the irq here and it will be enabled - * after the interrupt is handled by the user space driver. */ - disable_irq (irq); -- queue_intr (irq, action->delivery_port); -- } -- -+ if (! queue_intr (action->userspace_handler)) -+ { -+ *prev = action->next; -+ linux_kfree(action); -+ action = *prev; -+ enable_irq (irq); -+ continue; -+ } - } - else if (action->handler) - action->handler (irq, action->dev_id, ®s); -@@ -285,26 +274,32 @@ setup_x86_irq (int irq, struct linux_action *new) - - int - install_user_intr_handler (unsigned int irq, unsigned long flags, -- ipc_port_t dest) -+ struct intr_entry *entry) - { - struct linux_action *action; -+#if 0 - struct linux_action *old; -+#endif - int retval; - - assert (irq < 16); - -- /* Test whether the irq handler has been set */ -+#if 0 -+ /* Test whether the irq handler has already been set. */ -+ /* JW: Actually, that cannot happen. We test for that in -+ device_intr_register before calling this function. */ - // TODO I need to protect the array when iterating it. - old = irq_action[irq]; - while (old) - { -- if (old->delivery_port == dest) -+ if (old->delivery_port == entry->dest) - { - printk ("The interrupt handler has been installed on line %d", irq); - return linux_to_mach_error (-EAGAIN); - } - old = old->next; - } -+#endif - - /* - * Hmm... Should I use `kalloc()' ? -@@ -319,7 +314,7 @@ install_user_intr_handler (unsigned int irq, unsigned long flags, - action->next = NULL; - action->dev_id = NULL; - action->flags = flags; -- action->delivery_port = dest; -+ action->userspace_handler = entry; - - retval = setup_x86_irq (irq, action); - if (retval) -@@ -356,7 +351,7 @@ request_irq (unsigned int irq, void (*handler) (int, void *, struct pt_regs *), - action->next = NULL; - action->dev_id = dev_id; - action->flags = flags; -- action->delivery_port = NULL; -+ action->userspace_handler = NULL; - - retval = setup_x86_irq (irq, action); - if (retval) --- -2.1.4 - 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 deleted file mode 100644 index 66c7b6f..0000000 --- a/debian/patches/700004-Some-cleanups-of-the-userspace-interrupt-handling.patch +++ /dev/null @@ -1,170 +0,0 @@ -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 04/10] 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 - diff --git a/debian/patches/700005-Fix-synchronization.patch b/debian/patches/700005-Fix-synchronization.patch deleted file mode 100644 index 70347a6..0000000 --- a/debian/patches/700005-Fix-synchronization.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 6632518b1183e15f2016ec53088e3f26f151a96d Mon Sep 17 00:00:00 2001 -From: Justus Winter <justus@gnupg.org> -Date: Fri, 26 Feb 2016 13:21:12 +0100 -Subject: [PATCH gnumach 05/10] Fix synchronization - ---- - device/intr.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/device/intr.c b/device/intr.c -index 177c095..1e5a3ea 100644 ---- a/device/intr.c -+++ b/device/intr.c -@@ -123,6 +123,7 @@ intr_thread () - - for (;;) - { -+ assert_wait ((event_t) &intr_thread, FALSE); - cli (); - while (tot_num_intr) - { -@@ -162,8 +163,6 @@ intr_thread () - } - } - sti (); -- -- assert_wait ((event_t) &intr_thread, FALSE); - thread_block (thread_no_continuation); - } - } --- -2.1.4 - diff --git a/debian/patches/700006-Reorder.patch b/debian/patches/700006-Reorder.patch deleted file mode 100644 index 4e9b42e..0000000 --- a/debian/patches/700006-Reorder.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 552d46db26f7c90b178eaa9be45bba8d72875d76 Mon Sep 17 00:00:00 2001 -From: Justus Winter <justus@gnupg.org> -Date: Fri, 26 Feb 2016 13:27:28 +0100 -Subject: [PATCH gnumach 06/10] Reorder - ---- - device/intr.c | 55 +++++++++++++++++++++++++++---------------------------- - 1 file changed, 27 insertions(+), 28 deletions(-) - -diff --git a/device/intr.c b/device/intr.c -index 1e5a3ea..b0dcd83 100644 ---- a/device/intr.c -+++ b/device/intr.c -@@ -10,8 +10,6 @@ - #define sti() __asm__ __volatile__ ("sti": : :"memory") - #define cli() __asm__ __volatile__ ("cli": : :"memory") - --static boolean_t deliver_intr (int line, ipc_port_t dest_port); -- - struct intr_entry - { - queue_chain_t chain; -@@ -112,6 +110,33 @@ init_mach_intr_notification (mach_intr_notification_t *n) - t->msgt_unused = 0; - } - -+static boolean_t -+deliver_intr (int line, ipc_port_t dest_port) -+{ -+ ipc_kmsg_t kmsg; -+ mach_intr_notification_t *n; -+ mach_port_t dest = (mach_port_t) dest_port; -+ -+ if (dest == MACH_PORT_NULL) -+ return FALSE; -+ -+ kmsg = ikm_alloc(sizeof *n); -+ if (kmsg == IKM_NULL) -+ return FALSE; -+ -+ ikm_init(kmsg, sizeof *n); -+ n = (mach_intr_notification_t *) &kmsg->ikm_header; -+ *n = mach_intr_notification_template; -+ -+ n->intr_header.msgh_remote_port = dest; -+ n->line = line; -+ -+ ipc_port_copy_send (dest_port); -+ ipc_mqueue_send_always(kmsg); -+ -+ return TRUE; -+} -+ - void - intr_thread () - { -@@ -167,30 +192,4 @@ intr_thread () - } - } - --static boolean_t --deliver_intr (int line, ipc_port_t dest_port) --{ -- ipc_kmsg_t kmsg; -- mach_intr_notification_t *n; -- mach_port_t dest = (mach_port_t) dest_port; -- -- if (dest == MACH_PORT_NULL) -- return FALSE; -- -- kmsg = ikm_alloc(sizeof *n); -- if (kmsg == IKM_NULL) -- return FALSE; -- -- ikm_init(kmsg, sizeof *n); -- n = (mach_intr_notification_t *) &kmsg->ikm_header; -- *n = mach_intr_notification_template; -- -- n->intr_header.msgh_remote_port = dest; -- n->line = line; -- -- ipc_port_copy_send (dest_port); -- ipc_mqueue_send_always(kmsg); -- -- return TRUE; --} - #endif /* MACH_XEN */ --- -2.1.4 - diff --git a/debian/patches/700007-Use-the-slab-allocator.patch b/debian/patches/700007-Use-the-slab-allocator.patch deleted file mode 100644 index e89f253..0000000 --- a/debian/patches/700007-Use-the-slab-allocator.patch +++ /dev/null @@ -1,63 +0,0 @@ -From ad33ca5d3fbc25618d26b7af4d9a67be041c779a Mon Sep 17 00:00:00 2001 -From: Justus Winter <justus@gnupg.org> -Date: Fri, 26 Feb 2016 13:43:11 +0100 -Subject: [PATCH gnumach 07/10] Use the slab allocator - ---- - device/intr.c | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) - -diff --git a/device/intr.c b/device/intr.c -index b0dcd83..0fa43c5 100644 ---- a/device/intr.c -+++ b/device/intr.c -@@ -10,6 +10,9 @@ - #define sti() __asm__ __volatile__ ("sti": : :"memory") - #define cli() __asm__ __volatile__ ("cli": : :"memory") - -+/* The cache which holds our proxy memory objects. */ -+static struct kmem_cache intr_entry_cache; -+ - struct intr_entry - { - queue_chain_t chain; -@@ -58,7 +61,7 @@ insert_intr_entry (int line, ipc_port_t dest, struct intr_entry **entry) - struct intr_entry *e, *new; - int free = 0; - -- new = (struct intr_entry *) kalloc (sizeof (*new)); -+ new = (struct intr_entry *) kmem_cache_alloc (&intr_entry_cache); - if (new == NULL) - return D_NO_MEMORY; - new->line = line; -@@ -81,7 +84,7 @@ insert_intr_entry (int line, ipc_port_t dest, struct intr_entry **entry) - out: - sti (); - if (free) -- kfree ((vm_offset_t) new, sizeof (*new)); -+ kmem_cache_free (&intr_entry_cache, (vm_offset_t) new); - *entry = new; - return err; - } -@@ -146,6 +149,9 @@ intr_thread () - queue_init (&intr_queue); - init_mach_intr_notification (&mach_intr_notification_template); - -+ kmem_cache_init (&intr_entry_cache, "intr_entry", -+ sizeof (struct intr_entry), 0, NULL, 0); -+ - for (;;) - { - assert_wait ((event_t) &intr_thread, FALSE); -@@ -183,7 +189,7 @@ intr_thread () - assert (!queue_empty (&intr_queue)); - queue_remove (&intr_queue, e, struct intr_entry *, chain); - sti (); -- kfree ((vm_offset_t) e, sizeof (*e)); -+ kmem_cache_free (&intr_entry_cache, (vm_offset_t) e); - cli (); - } - } --- -2.1.4 - diff --git a/debian/patches/700008-Fix-reference-counting-use-dead-name-notification.patch b/debian/patches/700008-Fix-reference-counting-use-dead-name-notification.patch deleted file mode 100644 index 4b12e3b..0000000 --- a/debian/patches/700008-Fix-reference-counting-use-dead-name-notification.patch +++ /dev/null @@ -1,371 +0,0 @@ -From e5921e151ef397b25db7fe85a325728503a77e9b Mon Sep 17 00:00:00 2001 -From: Justus Winter <justus@gnupg.org> -Date: Fri, 26 Feb 2016 15:24:45 +0100 -Subject: [PATCH gnumach 08/10] Fix reference counting; use dead-name - notification - ---- - device/ds_routines.c | 15 ++--- - device/interrupt.h | 4 +- - device/intr.c | 168 +++++++++++++++++++++++++++++++++++++-------------- - kern/ipc_kobject.c | 8 +++ - kern/ipc_kobject.h | 5 +- - 5 files changed, 141 insertions(+), 59 deletions(-) - -diff --git a/device/ds_routines.c b/device/ds_routines.c -index 7a5dda5..2b9869a 100644 ---- a/device/ds_routines.c -+++ b/device/ds_routines.c -@@ -87,6 +87,7 @@ - #include <device/dev_hdr.h> - #include <device/conf.h> - #include <device/io_req.h> -+#include <device/interrupt.h> - #include <device/ds_routines.h> - #include <device/net_status.h> - #include <device/device_port.h> -@@ -332,6 +333,9 @@ experimental_device_intr_register (ipc_port_t master_port, int line, - if (master_port != master_device_port) - return D_INVALID_OPERATION; - -+ if (receive_port == MACH_PORT_NULL) -+ return D_INVALID_OPERATION; -+ - /* XXX: move to arch-specific */ - if (line < 0 || line >= 16) - return D_INVALID_OPERATION; -@@ -339,17 +343,8 @@ experimental_device_intr_register (ipc_port_t master_port, int line, - ret = insert_intr_entry (line, receive_port, &entry); - if (ret) - return ret; -- // TODO The original port should be replaced -- // when the same device driver calls it again, -- // in order to handle the case that the device driver crashes and restarts. -- ret = install_user_intr_handler (line, flags, entry); -- -- /* If the port is installed successfully, increase its reference by 1. -- * Thus, the port won't be destroyed after its task is terminated. */ -- if (ret == 0) -- ip_reference (receive_port); - -- return ret; -+ return install_user_intr_handler (line, flags, entry); - #endif /* MACH_XEN */ - } - -diff --git a/device/interrupt.h b/device/interrupt.h -index 0de43c2..8adc02d 100644 ---- a/device/interrupt.h -+++ b/device/interrupt.h -@@ -3,12 +3,14 @@ - - struct intr_entry; - boolean_t queue_intr (struct intr_entry *e); --int insert_intr_entry (int line, ipc_port_t dest, struct intr_entry **entry); -+kern_return_t insert_intr_entry (int line, ipc_port_t dest, -+ struct intr_entry **entry); - - int install_user_intr_handler (unsigned int line, - unsigned long flags, - struct intr_entry *entry); - -+boolean_t intr_entry_notify (mach_msg_header_t *msg); - void intr_thread (void); - - #endif /* DEVICE_INTERRUPT_H */ -diff --git a/device/intr.c b/device/intr.c -index 0fa43c5..7a1eccb 100644 ---- a/device/intr.c -+++ b/device/intr.c -@@ -1,7 +1,9 @@ - #include <device/intr.h> - #include <device/ds_routines.h> -+#include <ipc/ipc_space.h> - #include <kern/queue.h> - #include <kern/printf.h> -+#include <mach/notify.h> - - #include "interrupt.h" - -@@ -15,12 +17,14 @@ static struct kmem_cache intr_entry_cache; - - struct intr_entry - { -+ ipc_port_t port; /* We receive notifications on this port. */ - queue_chain_t chain; - ipc_port_t dest; - int line; - /* The number of interrupts occur since last run of intr_thread. */ - int interrupts; - }; -+typedef struct intr_entry *intr_entry_t; - - static queue_head_t intr_queue; - /* The total number of unprocessed interrupts. */ -@@ -30,18 +34,6 @@ static int tot_num_intr; - boolean_t - queue_intr (struct intr_entry *e) - { -- /* The reference of the port was increased when the port was -- * installed. If the reference is 1, it means the port should have -- * 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; -- printf ("irq handler %d: release an dead delivery port\n", e->line); -- return FALSE; -- } -- - cli (); - e->interrupts++; - tot_num_intr++; -@@ -54,20 +46,58 @@ queue_intr (struct intr_entry *e) - /* insert an interrupt entry in the queue. - * This entry exists in the queue until - * the corresponding interrupt port is removed.*/ --int -+kern_return_t - insert_intr_entry (int line, ipc_port_t dest, struct intr_entry **entry) - { -- int err = 0; -+ kern_return_t err = 0; - struct intr_entry *e, *new; - int free = 0; -+ ipc_port_t dnnotify; -+ ipc_port_request_index_t dnindex; - - new = (struct intr_entry *) kmem_cache_alloc (&intr_entry_cache); - if (new == NULL) - return D_NO_MEMORY; -+ -+ /* Allocate port, keeping a reference for it. */ -+ new->port = ipc_port_alloc_kernel (); -+ if (new->port == IP_NULL) -+ { -+ kmem_cache_free (&intr_entry_cache, (vm_offset_t) new); -+ return KERN_RESOURCE_SHORTAGE; -+ } -+ -+ /* Associate the port with the object. */ -+ ipc_kobject_set (new->port, (ipc_kobject_t) new, IKOT_INTR_ENTRY); -+ - new->line = line; - new->dest = dest; - new->interrupts = 0; - -+ /* Register a dead-name notification so that we are notified if the -+ userspace handler dies. */ -+ dnnotify = ipc_port_make_sonce (new->port); -+ ip_lock (dest); -+ /* We use a bogus port name. We don't need it to distinguish the -+ notifications because we register just one per object. */ -+ retry: -+ err = ipc_port_dnrequest (dest, (mach_port_t) 1, dnnotify, &dnindex); -+ if (err) -+ { -+ err = ipc_port_dngrow (dest); -+ /* dest is unlocked */ -+ if (err != KERN_SUCCESS) -+ { -+ ipc_port_release_sonce (dnnotify); -+ kmem_cache_free (&intr_entry_cache, (vm_offset_t) new); -+ return err; -+ } -+ ip_lock (dest); -+ goto retry; -+ } -+ /* dest is locked. dnindex is only valid until we unlock it and we -+ might decide to cancel. */ -+ - /* check whether the intr entry has been in the queue. */ - cli (); - queue_iterate (&intr_queue, e, struct intr_entry *, chain) -@@ -84,11 +114,74 @@ insert_intr_entry (int line, ipc_port_t dest, struct intr_entry **entry) - out: - sti (); - if (free) -- kmem_cache_free (&intr_entry_cache, (vm_offset_t) new); -+ { -+ ipc_port_dncancel (new->dest, (mach_port_t) 1, dnindex); -+ ip_unlock (new->dest); -+ ipc_port_release_sonce (dnnotify); -+ ipc_port_dealloc_kernel (new->port); -+ ipc_port_release_send (new->dest); -+ kmem_cache_free (&intr_entry_cache, (vm_offset_t) new); -+ } -+ else -+ ip_unlock (new->dest); - *entry = new; - return err; - } - -+/* Lookup a intr_entry object by its port. */ -+static intr_entry_t -+intr_entry_port_lookup (ipc_port_t port) -+{ -+ struct intr_entry *entry; -+ -+ if (!IP_VALID(port)) -+ return 0; -+ -+ ip_lock (port); -+ if (ip_active (port) && (ip_kotype (port) == IKOT_INTR_ENTRY)) -+ entry = (struct intr_entry *) port->ip_kobject; -+ else -+ entry = 0; -+ ip_unlock (port); -+ return entry; -+} -+ -+/* Process a dead-name notification for a userspace interrupt handler -+ notification port. */ -+boolean_t -+intr_entry_notify (mach_msg_header_t *msg) -+{ -+ if (msg->msgh_id == MACH_NOTIFY_DEAD_NAME) -+ { -+ struct intr_entry *entry; -+ int line; -+ mach_dead_name_notification_t *dn; -+ -+ dn = (mach_dead_name_notification_t *) msg; -+ entry = intr_entry_port_lookup -+ ((ipc_port_t) dn->not_header.msgh_remote_port); -+ assert (entry); -+ -+ cli (); -+ line = entry->line; -+ assert (!queue_empty (&intr_queue)); -+ queue_remove (&intr_queue, entry, struct intr_entry *, chain); -+ sti (); -+ -+ ipc_port_dealloc_kernel (entry->port); -+ ipc_port_release_send (entry->dest); -+ kmem_cache_free (&intr_entry_cache, (vm_offset_t) entry); -+ -+ printf ("irq handler %d: userspace handler died\n", line); -+ return TRUE; -+ } -+ -+ printf ("intr_entry_notify: strange notification %d\n", -+ msg->msgh_id); -+ return FALSE; -+} -+ -+ - mach_intr_notification_t mach_intr_notification_template; - - static void -@@ -156,43 +249,26 @@ intr_thread () - { - assert_wait ((event_t) &intr_thread, FALSE); - cli (); -- while (tot_num_intr) -- { -- int del = 0; - -- queue_iterate (&intr_queue, e, struct intr_entry *, chain) -+ while (tot_num_intr) -+ queue_iterate (&intr_queue, e, struct intr_entry *, chain) -+ if (e->interrupts) - { -- /* if an entry doesn't have dest port, -- * we should remove it. */ -- if (e->dest == NULL) -- { -- del = 1; -- break; -- } -- -- if (e->interrupts) -- { -- line = e->line; -- dest = e->dest; -- e->interrupts--; -- tot_num_intr--; -- -- sti (); -- deliver_intr (line, dest); -- cli (); -- } -- } -+ line = e->line; -+ dest = e->dest; -+ e->interrupts--; -+ tot_num_intr--; - -- /* remove the entry without dest port from the queue and free it. */ -- if (del) -- { -- assert (!queue_empty (&intr_queue)); -- queue_remove (&intr_queue, e, struct intr_entry *, chain); - sti (); -- kmem_cache_free (&intr_entry_cache, (vm_offset_t) e); -+ deliver_intr (line, dest); - cli (); -+ -+ /* We cannot assume that e still exists at this point -+ because we released the lock. Hence we restart the -+ iteration. */ -+ break; - } -- } -+ - sti (); - thread_block (thread_no_continuation); - } -diff --git a/kern/ipc_kobject.c b/kern/ipc_kobject.c -index c65458b..97c632a 100644 ---- a/kern/ipc_kobject.c -+++ b/kern/ipc_kobject.c -@@ -48,6 +48,7 @@ - #include <vm/vm_object.h> - #include <vm/memory_object_proxy.h> - #include <device/ds_routines.h> -+#include <device/interrupt.h> - - #include <kern/mach.server.h> - #include <ipc/mach_port.server.h> -@@ -326,6 +327,10 @@ ipc_kobject_destroy( - vm_object_pager_wakeup(port); - break; - -+ case IKOT_INTR_ENTRY: -+ /* Do nothing. */ -+ break; -+ - default: - #if MACH_ASSERT - printf("ipc_kobject_destroy: port 0x%p, kobj 0x%lx, type %d\n", -@@ -368,6 +373,9 @@ ipc_kobject_notify(request_header, reply_header) - case IKOT_PAGER_PROXY: - return memory_object_proxy_notify(request_header); - -+ case IKOT_INTR_ENTRY: -+ return intr_entry_notify(request_header); -+ - default: - return FALSE; - } -diff --git a/kern/ipc_kobject.h b/kern/ipc_kobject.h -index 606a66a..6aefea7 100644 ---- a/kern/ipc_kobject.h -+++ b/kern/ipc_kobject.h -@@ -77,9 +77,10 @@ typedef unsigned int ipc_kobject_type_t; - #define IKOT_CLOCK 25 - #define IKOT_CLOCK_CTRL 26 - #define IKOT_PAGER_PROXY 27 -+#define IKOT_INTR_ENTRY 28 - /* << new entries here */ --#define IKOT_UNKNOWN 28 /* magic catchall */ --#define IKOT_MAX_TYPE 29 /* # of IKOT_ types */ -+#define IKOT_UNKNOWN 29 /* magic catchall */ -+#define IKOT_MAX_TYPE 30 /* # of IKOT_ types */ - /* Please keep ipc/ipc_object.c:ikot_print_array up to date */ - - #define is_ipc_kobject(ikot) (ikot != IKOT_NONE) --- -2.1.4 - diff --git a/debian/patches/700009-Fix-xen-build.patch b/debian/patches/700009-Fix-xen-build.patch deleted file mode 100644 index 5170aaa..0000000 --- a/debian/patches/700009-Fix-xen-build.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 7debcbf8fb5b5b99e5a0b48ec6e9672455237938 Mon Sep 17 00:00:00 2001 -From: Justus Winter <justus@gnupg.org> -Date: Fri, 26 Feb 2016 15:32:12 +0100 -Subject: [PATCH gnumach 09/10] Fix xen build - ---- - device/intr.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/device/intr.c b/device/intr.c -index 7a1eccb..a061d5e 100644 ---- a/device/intr.c -+++ b/device/intr.c -@@ -1,6 +1,7 @@ - #include <device/intr.h> - #include <device/ds_routines.h> - #include <ipc/ipc_space.h> -+#include <kern/debug.h> - #include <kern/queue.h> - #include <kern/printf.h> - #include <mach/notify.h> -@@ -274,4 +275,12 @@ intr_thread () - } - } - -+#else /* MACH_XEN */ -+ -+boolean_t -+intr_entry_notify (mach_msg_header_t *msg) -+{ -+ panic ("not reached"); -+} -+ - #endif /* MACH_XEN */ --- -2.1.4 - diff --git a/debian/patches/700010-Fix-infinite-loop-with-cli-if-netdde-is-killed-with-.patch b/debian/patches/700010-Fix-infinite-loop-with-cli-if-netdde-is-killed-with-.patch deleted file mode 100644 index 6394e9d..0000000 --- a/debian/patches/700010-Fix-infinite-loop-with-cli-if-netdde-is-killed-with-.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 23ffabdd5b4e62340454884bf1e85c925bcf509b Mon Sep 17 00:00:00 2001 -From: Justus Winter <justus@gnupg.org> -Date: Fri, 26 Feb 2016 16:01:46 +0100 -Subject: [PATCH gnumach 10/10] Fix infinite loop with cli if netdde is killed - with pending irqs - ---- - device/intr.c | 38 +++++++++++++++++--------------------- - 1 file changed, 17 insertions(+), 21 deletions(-) - -diff --git a/device/intr.c b/device/intr.c -index a061d5e..39408ea 100644 ---- a/device/intr.c -+++ b/device/intr.c -@@ -28,8 +28,6 @@ struct intr_entry - typedef struct intr_entry *intr_entry_t; - - static queue_head_t intr_queue; --/* The total number of unprocessed interrupts. */ --static int tot_num_intr; - - /* This function can only be used in the interrupt handler. */ - boolean_t -@@ -37,7 +35,6 @@ queue_intr (struct intr_entry *e) - { - cli (); - e->interrupts++; -- tot_num_intr++; - sti (); - - thread_wakeup ((event_t) &intr_thread); -@@ -251,24 +248,23 @@ intr_thread () - assert_wait ((event_t) &intr_thread, FALSE); - cli (); - -- while (tot_num_intr) -- queue_iterate (&intr_queue, e, struct intr_entry *, chain) -- if (e->interrupts) -- { -- line = e->line; -- dest = e->dest; -- e->interrupts--; -- tot_num_intr--; -- -- sti (); -- deliver_intr (line, dest); -- cli (); -- -- /* We cannot assume that e still exists at this point -- because we released the lock. Hence we restart the -- iteration. */ -- break; -- } -+ restart: -+ queue_iterate (&intr_queue, e, struct intr_entry *, chain) -+ if (e->interrupts) -+ { -+ line = e->line; -+ dest = e->dest; -+ e->interrupts--; -+ -+ sti (); -+ deliver_intr (line, dest); -+ cli (); -+ -+ /* We cannot assume that e still exists at this point -+ because we released the lock. Hence we restart the -+ iteration. */ -+ goto restart; -+ } - - sti (); - thread_block (thread_no_continuation); --- -2.1.4 - diff --git a/debian/patches/series b/debian/patches/series index 1c11fd9..8f9b1c3 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -14,13 +14,3 @@ sysenter0001-yyy-sysenter-prototype.patch #vm-cache-policy0003-vm-evict-clean-pages-first.patch vm-cache-policy0001-VM-cache-policy-change.patch vm-cache-policy0002-Fix-page-cache-accounting.patch -700001-70_dde.patch.patch -700002-Disable-disabling-the-irq-via-device_intr_enable.patch -700003-Rework-comment-on-the-userspace-interrupt-handling.patch -700004-Some-cleanups-of-the-userspace-interrupt-handling.patch -700005-Fix-synchronization.patch -700006-Reorder.patch -700007-Use-the-slab-allocator.patch -700008-Fix-reference-counting-use-dead-name-notification.patch -700009-Fix-xen-build.patch -700010-Fix-infinite-loop-with-cli-if-netdde-is-killed-with-.patch |