aboutsummaryrefslogtreecommitdiff
path: root/pk
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@eecs.berkeley.edu>2014-06-03 11:06:38 -0700
committerAndrew Waterman <waterman@eecs.berkeley.edu>2014-06-03 11:06:38 -0700
commit053aa8ff8006427abe89afc0df944a201d424af2 (patch)
tree3ab7d010e71a9b2eedc9fbdd2db57db5a99afc31 /pk
parent8fc3a35ba546209532c5ee79db52f4f706bf6beb (diff)
downloadpk-053aa8ff8006427abe89afc0df944a201d424af2.zip
pk-053aa8ff8006427abe89afc0df944a201d424af2.tar.gz
pk-053aa8ff8006427abe89afc0df944a201d424af2.tar.bz2
Turn off interrupts when talking to host
Diffstat (limited to 'pk')
-rw-r--r--pk/atomic.h14
-rw-r--r--pk/frontend.c4
2 files changed, 16 insertions, 2 deletions
diff --git a/pk/atomic.h b/pk/atomic.h
index 8e80c78..fea1330 100644
--- a/pk/atomic.h
+++ b/pk/atomic.h
@@ -4,6 +4,7 @@
#define _RISCV_ATOMIC_H
#include "config.h"
+#include "encoding.h"
typedef struct { volatile long val; } atomic_t;
typedef struct { atomic_t lock; } spinlock_t;
@@ -71,4 +72,17 @@ static inline void spinlock_unlock(spinlock_t* lock)
atomic_set(&lock->lock,0);
}
+static inline long spinlock_lock_irqsave(spinlock_t* lock)
+{
+ long flags = clear_csr(status, SR_EI);
+ spinlock_lock(lock);
+ return flags;
+}
+
+static inline void spinlock_unlock_irqrestore(spinlock_t* lock, long flags)
+{
+ spinlock_unlock(lock);
+ set_csr(status, flags & SR_EI);
+}
+
#endif
diff --git a/pk/frontend.c b/pk/frontend.c
index 4c6051e..7bf4710 100644
--- a/pk/frontend.c
+++ b/pk/frontend.c
@@ -10,7 +10,7 @@ long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4)
static volatile uint64_t magic_mem[8];
static spinlock_t lock = SPINLOCK_INIT;
- spinlock_lock(&lock);
+ long irq = spinlock_lock_irqsave(&lock);
magic_mem[0] = n;
magic_mem[1] = a0;
@@ -28,6 +28,6 @@ long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4)
long ret = magic_mem[0];
- spinlock_unlock(&lock);
+ spinlock_unlock_irqrestore(&lock, irq);
return ret;
}