1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
From c113575502e58f8bfb9870867472d08e653e7c09 Mon Sep 17 00:00:00 2001
From: Justus Winter <justus@gnupg.org>
Date: Fri, 26 Feb 2016 17:53:16 +0100
Subject: [PATCH gnumach 13/15] Avoid cli/sti in favor of
cpu_intr_{save,restore}
---
device/intr.c | 31 +++++++++++++++++--------------
1 file 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);
}
}
--
2.1.4
|