summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <justus@gnupg.org>2016-02-26 17:53:16 +0100
committerJustus Winter <justus@gnupg.org>2016-02-26 17:53:16 +0100
commitc113575502e58f8bfb9870867472d08e653e7c09 (patch)
treeb204d62a4044b01a857898b1fc87c6b18bb04e4e
parentd8210eecee55d4848b391fef280fe1b5afc84201 (diff)
Avoid cli/sti in favor of cpu_intr_{save,restore}
-rw-r--r--device/intr.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/device/intr.c b/device/intr.c
index 1cbe661..c930e84 100644
--- a/device/intr.c
+++ b/device/intr.c
@@ -22,13 +22,11 @@
#include <kern/queue.h>
#include <kern/printf.h>
#include <mach/notify.h>
+#include <machine/cpu.h>
#include "interrupt.h"
#ifndef MACH_XEN
-// TODO this is only for x86 system
-#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;
@@ -50,9 +48,11 @@ static queue_head_t intr_queue;
boolean_t
queue_intr (struct intr_entry *e)
{
- cli ();
+ unsigned long flags;
+
+ cpu_intr_save (&flags);
e->interrupts++;
- sti ();
+ cpu_intr_restore (flags);
thread_wakeup ((event_t) &intr_thread);
return TRUE;
@@ -65,6 +65,7 @@ kern_return_t
insert_intr_entry (int line, ipc_port_t dest, struct intr_entry **entry)
{
kern_return_t err = 0;
+ unsigned long flags;
struct intr_entry *e, *new;
int free = 0;
ipc_port_t dnnotify;
@@ -114,7 +115,7 @@ insert_intr_entry (int line, ipc_port_t dest, struct intr_entry **entry)
might decide to cancel. */
/* check whether the intr entry has been in the queue. */
- cli ();
+ cpu_intr_save (&flags);
queue_iterate (&intr_queue, e, struct intr_entry *, chain)
if (e->dest == dest && e->line == line)
{
@@ -126,8 +127,8 @@ insert_intr_entry (int line, ipc_port_t dest, struct intr_entry **entry)
goto out;
}
queue_enter (&intr_queue, new, struct intr_entry *, chain);
-out:
- sti ();
+ out:
+ cpu_intr_restore (flags);
if (free)
{
ipc_port_dncancel (new->dest, (mach_port_t) 1, dnindex);
@@ -171,17 +172,18 @@ intr_entry_notify (mach_msg_header_t *msg)
struct intr_entry *entry;
int line;
mach_dead_name_notification_t *dn;
+ unsigned long flags;
dn = (mach_dead_name_notification_t *) msg;
entry = intr_entry_port_lookup
((ipc_port_t) dn->not_header.msgh_remote_port);
assert (entry);
- cli ();
+ cpu_intr_save (&flags);
line = entry->line;
assert (!queue_empty (&intr_queue));
queue_remove (&intr_queue, entry, struct intr_entry *, chain);
- sti ();
+ cpu_intr_restore (flags);
ipc_port_dealloc_kernel (entry->port);
ipc_port_release_send (entry->dest);
@@ -262,8 +264,9 @@ intr_thread ()
for (;;)
{
+ unsigned long flags;
assert_wait ((event_t) &intr_thread, FALSE);
- cli ();
+ cpu_intr_save (&flags);
restart:
queue_iterate (&intr_queue, e, struct intr_entry *, chain)
@@ -273,9 +276,9 @@ intr_thread ()
dest = e->dest;
e->interrupts--;
- sti ();
+ cpu_intr_restore (flags);
deliver_intr (line, dest);
- cli ();
+ cpu_intr_save (&flags);
/* We cannot assume that e still exists at this point
because we released the lock. Hence we restart the
@@ -283,7 +286,7 @@ intr_thread ()
goto restart;
}
- sti ();
+ cpu_intr_restore (flags);
thread_block (thread_no_continuation);
}
}