diff options
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/arch/amd64/cpu/cpu.c | 10 | ||||
| -rw-r--r-- | sys/arch/amd64/cpu/spinlock.c | 16 | ||||
| -rw-r--r-- | sys/kern/vfs_mount.c | 8 |
3 files changed, 24 insertions, 10 deletions
diff --git a/sys/arch/amd64/cpu/cpu.c b/sys/arch/amd64/cpu/cpu.c index 4edc850..d9093fd 100644 --- a/sys/arch/amd64/cpu/cpu.c +++ b/sys/arch/amd64/cpu/cpu.c @@ -29,11 +29,21 @@ #include <sys/types.h> #include <sys/cdefs.h> +#include <sys/param.h> #include <os/trace.h> #include <mu/cpu.h> #include <md/msr.h> #include <md/lapic.h> +bool +mu_irq_state(void) +{ + uint64_t rflags; + + __asmv("pushfq; pop %0" : "=r" (rflags) :: "memory"); + return ISSET(rflags, BIT(9)) != 0; +} + struct cpu_info * cpu_self(void) { diff --git a/sys/arch/amd64/cpu/spinlock.c b/sys/arch/amd64/cpu/spinlock.c index 1cfa088..6857aa6 100644 --- a/sys/arch/amd64/cpu/spinlock.c +++ b/sys/arch/amd64/cpu/spinlock.c @@ -29,12 +29,15 @@ #include <sys/cdefs.h> #include <mu/spinlock.h> +#include <mu/irq.h> void mu_spinlock_acq(volatile size_t *lock, int flags) { - if (ISSET(flags, SPINLOCK_INTTOG)) { - asm volatile("cli"); + bool irq_en = mu_irq_state(); + + if (ISSET(flags, SPINLOCK_INTTOG) && irq_en) { + __asmv("cli"); } __asmv( @@ -48,6 +51,11 @@ mu_spinlock_acq(volatile size_t *lock, int flags) : "r" (lock) : "memory", "rax" ); + + if (ISSET(flags, SPINLOCK_INTTOG)) { + if (irq_en && !mu_irq_state()) + __asmv("sti"); + } } void @@ -60,8 +68,4 @@ mu_spinlock_rel(volatile size_t *lock, int flags) : : "memory", "rax" ); - - if (ISSET(flags, SPINLOCK_INTTOG)) { - asm volatile("sti"); - } } diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 39f98d2..bfbc355 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -116,9 +116,9 @@ mount(struct mount_args *margs) /* * TODO: We'd need to do a namei() here, add by-path */ - spinlock_acquire(&mount_lock, false); + spinlock_acquire(&mount_lock, true); TAILQ_INSERT_TAIL(&mountlist, mp, link); - spinlock_release(&mount_lock, false); + spinlock_release(&mount_lock, true); return 0; } @@ -137,7 +137,7 @@ mount_lookup(const char *name, struct mount **mres) return -EINVAL; } - spinlock_acquire(&mount_lock, false); + spinlock_acquire(&mount_lock, true); TAILQ_FOREACH(iter, &mountlist, link) { fip = iter->fip; if (__likely(*name != *fip->name)) { @@ -150,7 +150,7 @@ mount_lookup(const char *name, struct mount **mres) } } - spinlock_release(&mount_lock, false); + spinlock_release(&mount_lock, true); if (mount == NULL) { return -ENOENT; } |
