From 4760818118adcdb0667f289c44626c4dfee6cc7f Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Thu, 12 Mar 2026 22:48:34 +0100 Subject: [PATCH] Spinlock save cpu flags --- kernel/amd64/apic.c | 18 ++-- kernel/amd64/debug.c | 6 +- kernel/amd64/hpet.c | 12 ++- kernel/amd64/intr.c | 10 +- kernel/amd64/intr_defs.h | 6 +- kernel/amd64/mm.c | 5 - kernel/amd64/proc.c | 23 +++-- kernel/amd64/sched1.c | 10 +- kernel/amd64/smp.c | 15 +-- kernel/amd64/spin_lock.c | 8 ++ kernel/amd64/syscall.c | 14 +-- kernel/device/debugconsole.c | 8 +- kernel/device/debugconsole.h | 3 +- kernel/device/device.c | 24 +++-- kernel/device/device.h | 6 +- kernel/device/idedrv.c | 88 +++++++++-------- kernel/device/idedrv.h | 2 +- kernel/device/partdrv.c | 18 ++-- kernel/device/partdrv.h | 3 +- kernel/device/partitions.c | 22 +++-- kernel/device/pci.c | 51 ++++++---- kernel/device/pci.h | 3 +- kernel/device/pci_ide.c | 10 +- kernel/device/ps2_kb.c | 26 ++--- kernel/device/ramdrv.c | 3 +- kernel/device/terminal.c | 3 +- kernel/device/terminal.h | 3 +- kernel/fs/fat1.c | 6 +- kernel/fs/fatfs.c | 32 +++--- kernel/fs/tarfs.c | 11 ++- kernel/fs/vfs.c | 100 ++++++++++++------- kernel/id/id_alloc.c | 14 ++- kernel/irq/irq.c | 18 ++-- kernel/mm/liballoc.c | 29 +++--- kernel/mm/liballoc.h | 4 +- kernel/mm/pmm.c | 14 ++- kernel/proc/mail.c | 58 ++++++----- kernel/proc/mutex.c | 56 ++++++----- kernel/proc/proc.c | 67 +++++++------ kernel/proc/procgroup.c | 57 ++++++----- kernel/proc/resource.c | 34 ++++--- kernel/proc/suspension_q.c | 44 +++++---- kernel/proc/suspension_q.h | 2 +- kernel/sync/spin_lock.c | 8 +- kernel/sync/spin_lock.h | 5 +- kernel/sys/mm.h | 12 ++- kernel/sys/sched.h | 2 +- kernel/sys/spin_lock.h | 4 + kernel/syscall/syscall.c | 186 +++++++++++++++++++++-------------- make/lz4.mk | 2 +- 50 files changed, 704 insertions(+), 461 deletions(-) diff --git a/kernel/amd64/apic.c b/kernel/amd64/apic.c index 3b5894a..5f6ddbc 100644 --- a/kernel/amd64/apic.c +++ b/kernel/amd64/apic.c @@ -57,19 +57,23 @@ static spin_lock_t lapic_calibration_lock = SPIN_LOCK_INIT; /* Read IOAPIC */ static uint32_t ioapic_read (struct ioapic* ioapic, uint32_t reg) { - spin_lock (&ioapic->lock); + uint64_t fia; + + spin_lock (&ioapic->lock, &fia); *(volatile uint32_t*)ioapic->mmio_base = reg; uint32_t ret = *(volatile uint32_t*)(ioapic->mmio_base + 0x10); - spin_unlock (&ioapic->lock); + spin_unlock (&ioapic->lock, fia); return ret; } /* Write IOAPIC */ static void ioapic_write (struct ioapic* ioapic, uint32_t reg, uint32_t value) { - spin_lock (&ioapic->lock); + uint64_t fia; + + spin_lock (&ioapic->lock, &fia); *(volatile uint32_t*)ioapic->mmio_base = reg; *(volatile uint32_t*)(ioapic->mmio_base + 0x10) = value; - spin_unlock (&ioapic->lock); + spin_unlock (&ioapic->lock, fia); } /* Find an IOAPIC corresposting to provided IRQ */ @@ -197,7 +201,9 @@ void lapic_eoi (void) { lapic_write (LAPIC_EOI, 0); } * us - Period length in microseconds */ static uint32_t lapic_calibrate (uint32_t us) { - spin_lock (&lapic_calibration_lock); + uint64_t flc; + + spin_lock (&lapic_calibration_lock, &flc); lapic_write (LAPIC_DCR, DIVIDER_VALUE); @@ -210,7 +216,7 @@ static uint32_t lapic_calibrate (uint32_t us) { uint32_t ticks = 0xFFFFFFFF - lapic_read (LAPIC_TIMCCT); DEBUG ("timer ticks = %u\n", ticks); - spin_unlock (&lapic_calibration_lock); + spin_unlock (&lapic_calibration_lock, flc); return ticks; } diff --git a/kernel/amd64/debug.c b/kernel/amd64/debug.c index 22abbcd..f9c24aa 100644 --- a/kernel/amd64/debug.c +++ b/kernel/amd64/debug.c @@ -33,6 +33,8 @@ static void debug_serial_write (char x) { * Formatted printing to serial. serial_lock ensures that all prints are atomic. */ void debugprintf (const char* fmt, ...) { + uint64_t f1; + if (!debug_is_init) return; @@ -48,14 +50,14 @@ void debugprintf (const char* fmt, ...) { const char* p = buffer; - spin_lock (&serial_lock); + spin_lock (&serial_lock, &f1); while (*p) { debug_serial_write (*p); p++; } - spin_unlock (&serial_lock); + spin_unlock (&serial_lock, f1); } /* Initialize serial */ diff --git a/kernel/amd64/hpet.c b/kernel/amd64/hpet.c index 45ccc2e..9bbb82f 100644 --- a/kernel/amd64/hpet.c +++ b/kernel/amd64/hpet.c @@ -59,8 +59,10 @@ static void hpet_write32 (uint32_t reg, uint32_t value) { /* Read current value of HPET_MCVR register. */ static uint64_t hpet_read_counter (void) { + uint64_t fh; + uint64_t value; - spin_lock (&hpet_lock); + spin_lock (&hpet_lock, &fh); if (!hpet_32bits) value = hpet_read64 (HPET_MCVR); @@ -75,13 +77,15 @@ static uint64_t hpet_read_counter (void) { value = ((uint64_t)hi1 << 32) | lo; } - spin_unlock (&hpet_lock); + spin_unlock (&hpet_lock, fh); return value; } static void hpet_write_counter (uint64_t value) { - spin_lock (&hpet_lock); + uint64_t fh; + + spin_lock (&hpet_lock, &fh); if (!hpet_32bits) hpet_write64 (HPET_MCVR, value); @@ -90,7 +94,7 @@ static void hpet_write_counter (uint64_t value) { hpet_write32 (HPET_MCVR + 4, (uint32_t)(value >> 32)); } - spin_unlock (&hpet_lock); + spin_unlock (&hpet_lock, fh); } /* Sleep for a given amount of microseconds. This time can last longer due to \ref hpet_lock being diff --git a/kernel/amd64/intr.c b/kernel/amd64/intr.c index abcee68..17934b8 100644 --- a/kernel/amd64/intr.c +++ b/kernel/amd64/intr.c @@ -191,20 +191,22 @@ void intr_handler (void* stack_ptr) { if (regs->trap <= 31) { intr_exception (regs); } else { - spin_lock (&thiscpu->lock); + uint64_t ftc, fpc; + + spin_lock (&thiscpu->lock, &ftc); struct proc* proc_current = thiscpu->proc_current; if (proc_current != NULL) { - spin_lock (&proc_current->lock); + spin_lock (&proc_current->lock, &fpc); memcpy (&proc_current->pdata.regs, regs, sizeof (struct saved_regs)); fx_save (proc_current->pdata.fx_env); - spin_unlock (&proc_current->lock); + spin_unlock (&proc_current->lock, fpc); } - spin_unlock (&thiscpu->lock); + spin_unlock (&thiscpu->lock, ftc); lapic_eoi (); diff --git a/kernel/amd64/intr_defs.h b/kernel/amd64/intr_defs.h index 8da1fa4..2390ef8 100644 --- a/kernel/amd64/intr_defs.h +++ b/kernel/amd64/intr_defs.h @@ -1,9 +1,9 @@ #ifndef _KERNEL_AMD64_INTR_DEFS_H #define _KERNEL_AMD64_INTR_DEFS_H -#define PS2KB 32 -#define IDE_DRIVE_PRIM 33 -#define IDE_DRIVE_SCND 34 +#define PS2KB 32 +#define IDE_DRIVE_PRIM 33 +#define IDE_DRIVE_SCND 34 #define SCHED_PREEMPT_TIMER 80 #define CPU_REQUEST_SCHED 82 diff --git a/kernel/amd64/mm.c b/kernel/amd64/mm.c index 485b216..e0e5e7f 100644 --- a/kernel/amd64/mm.c +++ b/kernel/amd64/mm.c @@ -23,11 +23,6 @@ struct pg_index { /* Kernel page directory */ static struct pd kernel_pd; -static spin_lock_t kernel_pd_lock; - -void mm_kernel_lock (void) { spin_lock (&kernel_pd_lock); } - -void mm_kernel_unlock (void) { spin_lock (&kernel_pd_lock); } /* Get current value of CR3 register */ static uintptr_t current_cr3 (void) { diff --git a/kernel/amd64/proc.c b/kernel/amd64/proc.c index 0dab0ff..c2f0f77 100644 --- a/kernel/amd64/proc.c +++ b/kernel/amd64/proc.c @@ -68,6 +68,7 @@ struct proc* proc_from_elf (uint8_t* elf_contents) { struct proc* proc_clone (struct proc* proto, uintptr_t vstack_top, uintptr_t entry, uintptr_t argument_ptr) { + uint64_t fpt; struct limine_hhdm_response* hhdm = limine_hhdm_request.response; struct proc* proc = malloc (sizeof (*proc)); @@ -85,12 +86,12 @@ struct proc* proc_clone (struct proc* proto, uintptr_t vstack_top, uintptr_t ent return NULL; } - spin_lock (&proto->lock); + spin_lock (&proto->lock, &fpt); proc->procgroup = proto->procgroup; procgroup_attach (proc->procgroup, proc); - spin_unlock (&proto->lock); + spin_unlock (&proto->lock, fpt); uintptr_t kstack_paddr = pmm_alloc (KSTACK_SIZE / PAGE_SIZE); proc->pdata.kernel_stack = kstack_paddr + (uintptr_t)hhdm->offset + KSTACK_SIZE; @@ -112,25 +113,27 @@ struct proc* proc_clone (struct proc* proto, uintptr_t vstack_top, uintptr_t ent } void proc_cleanup (struct proc* proc, struct reschedule_ctx* rctx) { - spin_lock (&proc->lock); - spin_lock (&proc->done_sq.lock); + uint64_t fp, fsq; + + spin_lock (&proc->lock, &fp); + spin_lock (&proc->done_sq.lock, &fsq); while (proc->done_sq.proc_list != NULL) { struct list_node_link* node = proc->done_sq.proc_list; struct proc_sq_entry* sq_entry = list_entry (node, struct proc_sq_entry, sq_link); struct proc* suspended_proc = sq_entry->proc; - spin_unlock (&proc->done_sq.lock); - spin_unlock (&proc->lock); + spin_unlock (&proc->done_sq.lock, fsq); + spin_unlock (&proc->lock, fp); proc_sq_resume (suspended_proc, sq_entry, rctx); - spin_lock (&proc->lock); - spin_lock (&proc->done_sq.lock); + spin_lock (&proc->lock, &fp); + spin_lock (&proc->done_sq.lock, &fsq); } - spin_unlock (&proc->done_sq.lock); - spin_unlock (&proc->lock); + spin_unlock (&proc->done_sq.lock, fsq); + spin_unlock (&proc->lock, fp); proc_sqs_cleanup (proc); proc_mutexes_cleanup (proc, rctx); diff --git a/kernel/amd64/sched1.c b/kernel/amd64/sched1.c index d4aab1d..64a5f40 100644 --- a/kernel/amd64/sched1.c +++ b/kernel/amd64/sched1.c @@ -11,8 +11,10 @@ #include #include -void do_sched (struct proc* proc, spin_lock_t* cpu_lock) { - spin_lock (&proc->lock); +void do_sched (struct proc* proc, spin_lock_t* cpu_lock, uint64_t lockflags) { + uint64_t fp; + + spin_lock (&proc->lock, &fp); thiscpu->tss.rsp0 = proc->pdata.kernel_stack; thiscpu->syscall_kernel_stack = proc->pdata.kernel_stack; @@ -25,8 +27,8 @@ void do_sched (struct proc* proc, spin_lock_t* cpu_lock) { fx_restore (proc->pdata.fx_env); - spin_unlock (&proc->lock); - spin_unlock (cpu_lock); + spin_unlock (&proc->lock, fp); + spin_unlock (cpu_lock, lockflags); do_sched1 ((void*)®s, cr3); } diff --git a/kernel/amd64/smp.c b/kernel/amd64/smp.c index bb8d149..c1ef79a 100644 --- a/kernel/amd64/smp.c +++ b/kernel/amd64/smp.c @@ -57,24 +57,25 @@ void cpu_request_sched (struct cpu* cpu) { } struct cpu* cpu_find_lightest (void) { + uint64_t fc; struct limine_mp_response* mp = limine_mp_request.response; int start = atomic_fetch_add (&last_cpu_index, 1) % mp->cpu_count; struct cpu* best_cpu = &cpus[start]; - spin_lock (&best_cpu->lock); + spin_lock (&best_cpu->lock, &fc); int best_load = best_cpu->proc_run_q_count; - spin_unlock (&best_cpu->lock); + spin_unlock (&best_cpu->lock, fc); for (int i = 1; i < (int)mp->cpu_count; i++) { int idx = (start + i) % mp->cpu_count; struct cpu* cpu = &cpus[idx]; - spin_lock (&cpu->lock); + spin_lock (&cpu->lock, &fc); int l = cpu->proc_run_q_count; - spin_unlock (&cpu->lock); + spin_unlock (&cpu->lock, fc); if (l < best_load) { best_load = l; @@ -87,6 +88,8 @@ struct cpu* cpu_find_lightest (void) { /// Bootstrap code for non-BSP CPUs static void smp_bootstrap (struct limine_mp_info* mp_info) { + uint64_t fc; + load_kernel_cr3 (); struct cpu* cpu = cpu_make (mp_info->lapic_id, mp_info->processor_id); @@ -110,8 +113,8 @@ static void smp_bootstrap (struct limine_mp_info* mp_info) { struct proc* spin_proc = proc_from_file (thiscpu->kproc, "RD", "/spin", &rctx); proc_register (spin_proc, thiscpu, &rctx); - spin_lock (&spin_proc->cpu->lock); - do_sched (spin_proc, &spin_proc->cpu->lock); + spin_lock (&spin_proc->cpu->lock, &fc); + do_sched (spin_proc, &spin_proc->cpu->lock, fc); } /// Initialize SMP subsystem for AMD64. Start AP CPUs diff --git a/kernel/amd64/spin_lock.c b/kernel/amd64/spin_lock.c index a2ecc85..8575a32 100644 --- a/kernel/amd64/spin_lock.c +++ b/kernel/amd64/spin_lock.c @@ -2,3 +2,11 @@ /// Relax the spinlock using AMD64 pause instruction void spin_lock_relax (void) { __asm__ volatile ("pause"); } + +void spin_lock_save_flags (uint64_t* flags) { + __asm__ volatile ("pushfq; cli; popq %0" : "=rm"(*flags)::"memory"); +} + +void spin_lock_restore_flags (uint64_t flags) { + __asm__ volatile ("pushq %0; popfq" ::"rm"(flags) : "memory", "cc"); +} diff --git a/kernel/amd64/syscall.c b/kernel/amd64/syscall.c index 9f4df56..008cdbb 100644 --- a/kernel/amd64/syscall.c +++ b/kernel/amd64/syscall.c @@ -19,20 +19,22 @@ extern void syscall_entry (void); uintptr_t syscall_dispatch (void* stack_ptr) { + uint64_t fp, fc; + load_kernel_cr3 (); struct saved_regs* regs = stack_ptr; - spin_lock (&thiscpu->lock); + spin_lock (&thiscpu->lock, &fc); struct proc* caller = thiscpu->proc_current; int caller_pid = caller->pid; - spin_lock (&caller->lock); + spin_lock (&caller->lock, &fp); memcpy (&caller->pdata.regs, regs, sizeof (struct saved_regs)); fx_save (caller->pdata.fx_env); - spin_unlock (&caller->lock); - spin_unlock (&thiscpu->lock); + spin_unlock (&caller->lock, fp); + spin_unlock (&thiscpu->lock, fc); int syscall_num = regs->rax; syscall_handler_func_t func = syscall_find_handler (syscall_num); @@ -50,9 +52,9 @@ uintptr_t syscall_dispatch (void* stack_ptr) { caller = proc_find_pid (caller_pid); if (caller != NULL) { - spin_lock (&caller->lock); + spin_lock (&caller->lock, &fp); caller->pdata.regs.rax = r; - spin_unlock (&caller->lock); + spin_unlock (&caller->lock, fp); } bool do_thiscpu = false; diff --git a/kernel/device/debugconsole.c b/kernel/device/debugconsole.c index 2bc4238..5fc25a4 100644 --- a/kernel/device/debugconsole.c +++ b/kernel/device/debugconsole.c @@ -6,7 +6,8 @@ #include #include -bool debugconsole_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx) { +bool debugconsole_init (struct device* device, void* arg, struct proc* proc, + struct reschedule_ctx* rctx) { (void)device, (void)arg, (void)proc, (void)rctx; return true; } @@ -18,6 +19,7 @@ void debugconsole_fini (struct device* device, struct proc* proc, struct resched int debugconsole_putstr (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4) { (void)a2, (void)a3, (void)a4, (void)device, (void)rctx; + uint64_t fp; char* string = (char*)a1; size_t* len = (size_t*)a2; @@ -25,9 +27,9 @@ int debugconsole_putstr (struct device* device, struct proc* proc, struct resche if (string == NULL || len == NULL) return -ST_BAD_ADDRESS_SPACE; - spin_lock (&proc->lock); + spin_lock (&proc->lock, &fp); int pid = proc->pid; - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); debugprintf ("(CPU %d; PID %d) %.*s\n", thiscpu->id, pid, (int)*len, string); diff --git a/kernel/device/debugconsole.h b/kernel/device/debugconsole.h index 56a3bae..65296ca 100644 --- a/kernel/device/debugconsole.h +++ b/kernel/device/debugconsole.h @@ -7,7 +7,8 @@ struct device; -bool debugconsole_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx); +bool debugconsole_init (struct device* device, void* arg, struct proc* proc, + struct reschedule_ctx* rctx); void debugconsole_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx); diff --git a/kernel/device/device.c b/kernel/device/device.c index 667a2f0..a1a8ce0 100644 --- a/kernel/device/device.c +++ b/kernel/device/device.c @@ -33,14 +33,16 @@ struct device_table { static struct device_table device_table; struct device* device_find (const char* key) { + uint64_t fdt; + struct hash_node_link* found_link = NULL; size_t key_len = strlen_null (key); uint32_t hash = hash_fnv32 (key, key_len); - spin_lock (&device_table.lock); + spin_lock (&device_table.lock, &fdt); hash_find (&device_table, key, key_len, hash, lengthof (device_table.device_buckets), device_buckets, struct device, device_table_link, key, found_link); - spin_unlock (&device_table.lock); + spin_unlock (&device_table.lock, fdt); if (found_link == NULL) return NULL; @@ -51,6 +53,8 @@ struct device* device_find (const char* key) { struct device* device_create (const char* key, device_op_func_t* ops, size_t ops_len, device_init_func_t init, device_fini_func_t fini, void* arg, struct proc* proc, struct reschedule_ctx* rctx) { + uint64_t fdt; + if (ops_len >= fieldlengthof (struct device, ops)) return NULL; @@ -75,12 +79,12 @@ struct device* device_create (const char* key, device_op_func_t* ops, size_t ops uint32_t device_hash = hash_fnv32 (device->key, strlen_null (device->key)); - spin_lock (&device_table.lock); + spin_lock (&device_table.lock, &fdt); hash_insert (&device_table, &device->device_table_link, device_hash, lengthof (device_table.device_buckets), device_buckets); - spin_unlock (&device_table.lock); + spin_unlock (&device_table.lock, fdt); DEBUG ("Created device %s\n", device->key); @@ -94,7 +98,8 @@ static void debugconsole_device_init (void) { device_op_func_t ops[] = { [DEBUGCONSOLE_PUTSTR] = &debugconsole_putstr, }; - device_create ("DEBUGCONSOLE", ops, lengthof (ops), &debugconsole_init, &debugconsole_fini, NULL, thiscpu->kproc, &rctx); + device_create ("DEBUGCONSOLE", ops, lengthof (ops), &debugconsole_init, &debugconsole_fini, NULL, + thiscpu->kproc, &rctx); } static void terminal_device_init (void) { @@ -105,7 +110,8 @@ static void terminal_device_init (void) { [TERMINAL_PUTSTR] = &terminal_putstr, [TERMINAL_DIMENSIONS] = &terminal_dimensions, }; - device_create ("TERMINAL", ops, lengthof (ops), &terminal_init, &terminal_fini, NULL, thiscpu->kproc, &rctx); + device_create ("TERMINAL", ops, lengthof (ops), &terminal_init, &terminal_fini, NULL, + thiscpu->kproc, &rctx); } static void ramdisk_device_init (void) { @@ -149,7 +155,8 @@ static void ramdisk_device_init (void) { .sector_size = 512, .buffer = unpack_buffer, }; - device_create ("RD0", ops, lengthof (ops), &ramdrv_init, &ramdrv_fini, &init, thiscpu->kproc, &rctx); + device_create ("RD0", ops, lengthof (ops), &ramdrv_init, &ramdrv_fini, &init, thiscpu->kproc, + &rctx); LZ4F_freeDecompressionContext (dctx); } @@ -170,7 +177,8 @@ static void temp_device_init (void) { .total_size = 1024 * 1024 * 20, .sector_size = 512, }; - device_create ("TEMP0", ops, lengthof (ops), &ramdrv_init, &ramdrv_fini, &init, thiscpu->kproc, &rctx); + device_create ("TEMP0", ops, lengthof (ops), &ramdrv_init, &ramdrv_fini, &init, thiscpu->kproc, + &rctx); } #if defined(__x86_64__) diff --git a/kernel/device/device.h b/kernel/device/device.h index 8263afb..591bc35 100644 --- a/kernel/device/device.h +++ b/kernel/device/device.h @@ -22,8 +22,10 @@ struct device; typedef int (*device_op_func_t) (struct device* device, struct proc*, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4); -typedef bool (*device_init_func_t) (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx); -typedef void (*device_fini_func_t) (struct device* device, struct proc* proc, struct reschedule_ctx* rctx); +typedef bool (*device_init_func_t) (struct device* device, void* arg, struct proc* proc, + struct reschedule_ctx* rctx); +typedef void (*device_fini_func_t) (struct device* device, struct proc* proc, + struct reschedule_ctx* rctx); struct device { char key[0x100]; diff --git a/kernel/device/idedrv.c b/kernel/device/idedrv.c index 10a876e..e46ab55 100644 --- a/kernel/device/idedrv.c +++ b/kernel/device/idedrv.c @@ -1,18 +1,18 @@ -#include -#include #include +#include +#include #include #include #include #include -#include +#include #include +#include #include #include #include #include #include -#include #define IDE_REG_DATA 0x00 #define IDE_REG_ERROR 0x01 @@ -91,15 +91,17 @@ static void ide_flush (struct idedrv* idedrv) { } static void ide_irq (void* arg, void* regs, struct reschedule_ctx* rctx) { + uint64_t fd, fp; + struct idedrv* idedrv = arg; - spin_lock (&idedrv->device->lock); + spin_lock (&idedrv->device->lock, &fd); struct list_node_link* node = idedrv->requests; if (node == NULL) { (void)inb (idedrv->io + IDE_REG_STATUS); - spin_unlock (&idedrv->device->lock); + spin_unlock (&idedrv->device->lock, fd); return; } @@ -107,18 +109,18 @@ static void ide_irq (void* arg, void* regs, struct reschedule_ctx* rctx) { struct list_node_link* sqlist_node = req->sq.proc_list; struct proc_sq_entry* sq_entry = list_entry (sqlist_node, struct proc_sq_entry, sq_link); struct proc* resumed_proc = sq_entry->proc; - + uint8_t status = inb (idedrv->io + IDE_REG_STATUS); if ((status & (IDE_ERR | IDE_DRQ))) { list_remove (idedrv->requests, &req->requests_link); - spin_unlock (&idedrv->device->lock); + spin_unlock (&idedrv->device->lock, fd); proc_sq_resume (resumed_proc, sq_entry, rctx); free (req); return; } - spin_lock (&resumed_proc->lock); + spin_lock (&resumed_proc->lock, &fp); if (req->rw == 1) { if ((status & IDE_DRQ)) { @@ -140,16 +142,16 @@ static void ide_irq (void* arg, void* regs, struct reschedule_ctx* rctx) { list_remove (idedrv->requests, &req->requests_link); - spin_unlock (&resumed_proc->lock); - spin_unlock (&idedrv->device->lock); + spin_unlock (&resumed_proc->lock, fp); + spin_unlock (&idedrv->device->lock, fd); free (req); proc_sq_resume (resumed_proc, sq_entry, rctx); return; } - spin_unlock (&resumed_proc->lock); - spin_unlock (&idedrv->device->lock); + spin_unlock (&resumed_proc->lock, fp); + spin_unlock (&idedrv->device->lock, fd); } void ide_probe (uint16_t io, uint16_t ctrl, uint8_t devno, struct ide_probe* probe) { @@ -244,7 +246,8 @@ static void ide_prepare (struct idedrv* idedrv, size_t sector, uint16_t sector_c } } -bool idedrv_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx) { +bool idedrv_init (struct device* device, void* arg, struct proc* proc, + struct reschedule_ctx* rctx) { (void)proc, (void)rctx; struct idedrv_init* init = arg; @@ -279,7 +282,7 @@ bool idedrv_init (struct device* device, void* arg, struct proc* proc, struct re void idedrv_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx) { struct idedrv* idedrv = device->udata; - struct list_node_link* req_link, *tmp_req_link; + struct list_node_link *req_link, *tmp_req_link; list_foreach (idedrv->requests, req_link, tmp_req_link) { struct idedrv_request* req = list_entry (req_link, struct idedrv_request, requests_link); list_remove (idedrv->requests, &req->requests_link); @@ -295,6 +298,7 @@ void idedrv_fini (struct device* device, struct proc* proc, struct reschedule_ct int idedrv_read (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4) { (void)proc, (void)rctx, (void)a4; + uint64_t fp; if (a1 == NULL || a2 == NULL || a3 == NULL) return -ST_BAD_ADDRESS_SPACE; @@ -308,25 +312,26 @@ int idedrv_read (struct device* device, struct proc* proc, struct reschedule_ctx if (sector + sector_count > idedrv->sector_count) return -ST_OOB_ERROR; - spin_lock (&proc->lock); + spin_lock (&proc->lock, &fp); bool is_kproc = (proc->flags & PROC_KPROC) != 0; - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); /* /1* polling *1/ */ /* if (is_kproc) { */ - ide_prepare (idedrv, sector, sector_count, false); + ide_prepare (idedrv, sector, sector_count, false); - uint8_t cmd = idedrv->lba48 ? IDE_CMD_READ48 : IDE_CMD_READ28; - outb (idedrv->io + IDE_REG_CMD, cmd); + uint8_t cmd = idedrv->lba48 ? IDE_CMD_READ48 : IDE_CMD_READ28; + outb (idedrv->io + IDE_REG_CMD, cmd); - for (uint16_t s = 0; s < sector_count; s++) { - if (!ide_wait (idedrv->io, 100000, true, true)) - return -ST_XDRV_READ_ERROR; + for (uint16_t s = 0; s < sector_count; s++) { + if (!ide_wait (idedrv->io, 100000, true, true)) + return -ST_XDRV_READ_ERROR; - insw (idedrv->io + IDE_REG_DATA, buffer + (s * (idedrv->sector_size / 2)), (idedrv->sector_size / 2)); - } - - return ST_OK; + insw (idedrv->io + IDE_REG_DATA, buffer + (s * (idedrv->sector_size / 2)), + (idedrv->sector_size / 2)); + } + + return ST_OK; /* } else { /1* IRQ *1/ */ /* struct idedrv_request* req = malloc (sizeof (*req)); */ @@ -354,6 +359,7 @@ int idedrv_read (struct device* device, struct proc* proc, struct reschedule_ctx int idedrv_write (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4) { (void)proc, (void)rctx, (void)a4; + uint64_t fp; if (a1 == NULL || a2 == NULL || a3 == NULL) return -ST_BAD_ADDRESS_SPACE; @@ -366,26 +372,27 @@ int idedrv_write (struct device* device, struct proc* proc, struct reschedule_ct if (sector + sector_count > idedrv->sector_count) return -ST_OOB_ERROR; - - spin_lock (&proc->lock); + + spin_lock (&proc->lock, &fp); bool is_kproc = (proc->flags & PROC_KPROC) != 0; - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); /* /1* polling *1/ */ /* if (is_kproc) { */ - ide_prepare (idedrv, sector, sector_count, false); + ide_prepare (idedrv, sector, sector_count, false); - uint8_t cmd = idedrv->lba48 ? IDE_CMD_WRITE48 : IDE_CMD_WRITE28; - outb (idedrv->io + IDE_REG_CMD, cmd); + uint8_t cmd = idedrv->lba48 ? IDE_CMD_WRITE48 : IDE_CMD_WRITE28; + outb (idedrv->io + IDE_REG_CMD, cmd); - for (uint16_t s = 0; s < sector_count; s++) { - if (!ide_wait (idedrv->io, 100000, true, true)) - return -ST_XDRV_WRITE_ERROR; + for (uint16_t s = 0; s < sector_count; s++) { + if (!ide_wait (idedrv->io, 100000, true, true)) + return -ST_XDRV_WRITE_ERROR; - outsw (idedrv->io + IDE_REG_DATA, buffer + (s * (idedrv->sector_size / 2)), (idedrv->sector_size / 2)); - } + outsw (idedrv->io + IDE_REG_DATA, buffer + (s * (idedrv->sector_size / 2)), + (idedrv->sector_size / 2)); + } - return ST_OK; + return ST_OK; /* } else { /1* IRQ *1/ */ /* struct idedrv_request* req = malloc (sizeof (*req)); */ @@ -408,7 +415,8 @@ int idedrv_write (struct device* device, struct proc* proc, struct reschedule_ct /* if (!ide_wait (idedrv->io, 100000, true, true)) { */ /* list_remove (idedrv->requests, &req->requests_link); */ - /* struct proc_sq_entry* sq_entry = list_entry (req->sq.proc_list, struct proc_sq_entry, sq_link); */ + /* struct proc_sq_entry* sq_entry = list_entry (req->sq.proc_list, struct proc_sq_entry, + * sq_link); */ /* proc_sq_resume (proc, sq_entry, rctx); */ /* free (req); */ /* return -ST_XDRV_WRITE_ERROR; */ diff --git a/kernel/device/idedrv.h b/kernel/device/idedrv.h index 48298dc..de92440 100644 --- a/kernel/device/idedrv.h +++ b/kernel/device/idedrv.h @@ -1,8 +1,8 @@ #ifndef _KERNEL_DEVICE_IDEDRV_H #define _KERNEL_DEVICE_IDEDRV_H -#include #include +#include #include #include #include diff --git a/kernel/device/partdrv.c b/kernel/device/partdrv.c index 8a36f4e..3358eec 100644 --- a/kernel/device/partdrv.c +++ b/kernel/device/partdrv.c @@ -7,7 +7,8 @@ #include #include -bool partdrv_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx) { +bool partdrv_init (struct device* device, void* arg, struct proc* proc, + struct reschedule_ctx* rctx) { (void)proc, (void)rctx; struct partdrv_init* init = arg; @@ -36,6 +37,7 @@ void partdrv_fini (struct device* device, struct proc* proc, struct reschedule_c int partdrv_read (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4) { (void)proc, (void)rctx, (void)a4; + uint64_t fs; if (a1 == NULL || a2 == NULL || a3 == NULL) return -ST_BAD_ADDRESS_SPACE; @@ -47,9 +49,9 @@ int partdrv_read (struct device* device, struct proc* proc, struct reschedule_ct size_t sector_count = *(size_t*)a2; uint8_t* buffer = a3; - spin_lock (&super->lock); + spin_lock (&super->lock, &fs); int ret = device_op (super, XDRV_READ, proc, rctx, §or, §or_count, buffer); - spin_unlock (&super->lock); + spin_unlock (&super->lock, fs); return ret; } @@ -57,6 +59,7 @@ int partdrv_read (struct device* device, struct proc* proc, struct reschedule_ct int partdrv_write (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4) { (void)proc, (void)rctx, (void)a4; + uint64_t fs; if (a1 == NULL || a2 == NULL || a3 == NULL) return -ST_BAD_ADDRESS_SPACE; @@ -68,9 +71,9 @@ int partdrv_write (struct device* device, struct proc* proc, struct reschedule_c size_t sector_count = *(size_t*)a2; uint8_t* buffer = a3; - spin_lock (&super->lock); + spin_lock (&super->lock, &fs); int ret = device_op (super, XDRV_WRITE, proc, rctx, §or, §or_count, buffer); - spin_unlock (&super->lock); + spin_unlock (&super->lock, fs); return ret; } @@ -92,6 +95,7 @@ int partdrv_get_device_type (struct device* device, struct proc* proc, struct re int partdrv_get_sector_size (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4) { (void)proc, (void)rctx, (void)a2, (void)a3, (void)a4; + uint64_t fs; if (a1 == NULL) return -ST_BAD_ADDRESS_SPACE; @@ -100,9 +104,9 @@ int partdrv_get_sector_size (struct device* device, struct proc* proc, struct re struct partdrv* partdrv = device->udata; - spin_lock (&partdrv->super->lock); + spin_lock (&partdrv->super->lock, &fs); device_op (partdrv->super, XDRV_GET_SECTOR_SIZE, proc, rctx, secsize); - spin_unlock (&partdrv->super->lock); + spin_unlock (&partdrv->super->lock, fs); return ST_OK; } diff --git a/kernel/device/partdrv.h b/kernel/device/partdrv.h index e0229c3..e31fc82 100644 --- a/kernel/device/partdrv.h +++ b/kernel/device/partdrv.h @@ -19,7 +19,8 @@ struct partdrv { size_t total_size; }; -bool partdrv_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx); +bool partdrv_init (struct device* device, void* arg, struct proc* proc, + struct reschedule_ctx* rctx); void partdrv_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx); diff --git a/kernel/device/partitions.c b/kernel/device/partitions.c index ea10500..0c47494 100644 --- a/kernel/device/partitions.c +++ b/kernel/device/partitions.c @@ -7,12 +7,15 @@ #include #include #include -#include -#include #include #include +#include +#include + +static int device_probe_partitions_dos (struct proc* proc, struct reschedule_ctx* rctx, + struct device* device) { + uint64_t fd; -static int device_probe_partitions_dos (struct proc* proc, struct reschedule_ctx* rctx, struct device* device) { struct dos_mbr mbr; memset (&mbr, 0, sizeof (mbr)); size_t sector = 0; @@ -27,19 +30,19 @@ static int device_probe_partitions_dos (struct proc* proc, struct reschedule_ctx [XDRV_WRITE] = &partdrv_write, }; - spin_lock (&device->lock); + spin_lock (&device->lock, &fd); device_op (device, XDRV_GET_SECTOR_SIZE, proc, rctx, §or_size); int ret = device_op (device, XDRV_READ, proc, rctx, §or, §or_count, &mbr); if (ret < 0) { - spin_unlock (&device->lock); + spin_unlock (&device->lock, fd); return ret; } if (!(mbr.valid_sign[0] == 0x55 && mbr.valid_sign[1] == 0xAA)) { - spin_unlock (&device->lock); + spin_unlock (&device->lock, fd); return -ST_PARTITION_ERROR; } @@ -59,9 +62,12 @@ static int device_probe_partitions_dos (struct proc* proc, struct reschedule_ctx device_create (key, ops, lengthof (ops), &partdrv_init, &partdrv_fini, &init, proc, rctx); } - spin_unlock (&device->lock); + spin_unlock (&device->lock, fd); return ST_OK; } -int device_probe_partitions (struct proc* proc, struct reschedule_ctx* rctx, struct device* device) { return device_probe_partitions_dos (proc, rctx, device); } +int device_probe_partitions (struct proc* proc, struct reschedule_ctx* rctx, + struct device* device) { + return device_probe_partitions_dos (proc, rctx, device); +} diff --git a/kernel/device/pci.c b/kernel/device/pci.c index a30c153..e246370 100644 --- a/kernel/device/pci.c +++ b/kernel/device/pci.c @@ -16,86 +16,100 @@ static const struct pci_driver_info pci_driver_infos[] = { static spin_lock_t pci_lock = SPIN_LOCK_INIT; uint32_t pci_read32 (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) { + uint64_t fpci; + uint32_t addr = (uint32_t)((uint32_t)bus << 16) | ((uint32_t)slot << 11) | ((uint32_t)func << 8) | (offset & 0xFC) | ((uint32_t)0x80000000); - spin_lock (&pci_lock); + spin_lock (&pci_lock, &fpci); outl (PCI_CONFIG_ADDR, addr); uint32_t r = inl (PCI_CONFIG_DATA); - spin_unlock (&pci_lock); + spin_unlock (&pci_lock, fpci); return r; } void pci_write32 (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset, uint32_t value) { + uint64_t fpci; + uint32_t addr = (uint32_t)((uint32_t)bus << 16) | ((uint32_t)slot << 11) | ((uint32_t)func << 8) | (offset & 0xFC) | ((uint32_t)0x80000000); - spin_lock (&pci_lock); + spin_lock (&pci_lock, &fpci); outl (PCI_CONFIG_ADDR, addr); outl (PCI_CONFIG_DATA, value); - spin_unlock (&pci_lock); + spin_unlock (&pci_lock, fpci); } uint16_t pci_read16 (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) { + uint64_t fpci; + uint32_t addr = (uint32_t)((uint32_t)bus << 16) | ((uint32_t)slot << 11) | ((uint32_t)func << 8) | (offset & 0xFC) | ((uint32_t)0x80000000); - spin_lock (&pci_lock); + spin_lock (&pci_lock, &fpci); outl (PCI_CONFIG_ADDR, addr); uint16_t r = inw (PCI_CONFIG_DATA + (offset & 2)); - spin_unlock (&pci_lock); + spin_unlock (&pci_lock, fpci); return r; } void pci_write16 (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset, uint16_t value) { + uint64_t fpci; + uint32_t addr = (uint32_t)((uint32_t)bus << 16) | ((uint32_t)slot << 11) | ((uint32_t)func << 8) | (offset & 0xFC) | ((uint32_t)0x80000000); - spin_lock (&pci_lock); + spin_lock (&pci_lock, &fpci); outl (PCI_CONFIG_ADDR, addr); outw (PCI_CONFIG_DATA + (offset & 2), value); - spin_unlock (&pci_lock); + spin_unlock (&pci_lock, fpci); } uint8_t pci_read8 (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) { + uint64_t fpci; + uint32_t addr = (uint32_t)((uint32_t)bus << 16) | ((uint32_t)slot << 11) | ((uint32_t)func << 8) | (offset & 0xFC) | ((uint32_t)0x80000000); - spin_lock (&pci_lock); + spin_lock (&pci_lock, &fpci); outl (PCI_CONFIG_ADDR, addr); uint8_t r = inb (PCI_CONFIG_DATA + (offset & 3)); - spin_unlock (&pci_lock); + spin_unlock (&pci_lock, fpci); return r; } void pci_write8 (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset, uint8_t value) { + uint64_t fpci; + uint32_t addr = (uint32_t)((uint32_t)bus << 16) | ((uint32_t)slot << 11) | ((uint32_t)func << 8) | (offset & 0xFC) | ((uint32_t)0x80000000); - spin_lock (&pci_lock); + spin_lock (&pci_lock, &fpci); outl (PCI_CONFIG_ADDR, addr); outb (PCI_CONFIG_DATA + (offset & 3), value); - spin_unlock (&pci_lock); + spin_unlock (&pci_lock, fpci); } -static void pci_check_bus (struct proc* proc, struct reschedule_ctx* rctx, uint8_t bus, pci_cb_func_t cb); +static void pci_check_bus (struct proc* proc, struct reschedule_ctx* rctx, uint8_t bus, + pci_cb_func_t cb); -static void pci_check_func (struct proc* proc, struct reschedule_ctx* rctx, uint8_t bus, uint8_t slot, uint8_t func, pci_cb_func_t cb) { +static void pci_check_func (struct proc* proc, struct reschedule_ctx* rctx, uint8_t bus, + uint8_t slot, uint8_t func, pci_cb_func_t cb) { uint32_t reg0 = pci_read32 (bus, slot, func, PCI_VENDOR_ID); uint16_t vendor = (uint16_t)(reg0 & 0xFFFF); @@ -124,7 +138,8 @@ static void pci_check_func (struct proc* proc, struct reschedule_ctx* rctx, uint } } -static void pci_check_device (struct proc* proc, struct reschedule_ctx* rctx, uint8_t bus, uint8_t slot, pci_cb_func_t cb) { +static void pci_check_device (struct proc* proc, struct reschedule_ctx* rctx, uint8_t bus, + uint8_t slot, pci_cb_func_t cb) { uint32_t reg0 = pci_read32 (bus, slot, 0, PCI_VENDOR_ID); if ((uint16_t)(reg0 & 0xFFFF) == 0xFFFF) @@ -140,7 +155,8 @@ static void pci_check_device (struct proc* proc, struct reschedule_ctx* rctx, ui } } -static void pci_check_bus (struct proc* proc, struct reschedule_ctx* rctx, uint8_t bus, pci_cb_func_t cb) { +static void pci_check_bus (struct proc* proc, struct reschedule_ctx* rctx, uint8_t bus, + pci_cb_func_t cb) { for (uint8_t slot = 0; slot < 32; slot++) pci_check_device (proc, rctx, bus, slot, cb); } @@ -188,7 +204,8 @@ static void pci_string_identifiers (uint16_t vendor_id, uint16_t device_id, uint } } -static void pci_discovery_cb (struct proc* proc, struct reschedule_ctx* rctx, struct pci_info pci_info) { +static void pci_discovery_cb (struct proc* proc, struct reschedule_ctx* rctx, + struct pci_info pci_info) { const char *vname, *dname, *cname; pci_string_identifiers (pci_info.vendor, pci_info.device, pci_info.class, pci_info.subclass, &vname, &dname, &cname); diff --git a/kernel/device/pci.h b/kernel/device/pci.h index b88e21c..b8ae220 100644 --- a/kernel/device/pci.h +++ b/kernel/device/pci.h @@ -58,7 +58,8 @@ struct pci_driver_info { bool (*init) (struct proc* proc, struct reschedule_ctx* rctx, struct pci_info pci_info); }; -typedef void (*pci_cb_func_t) (struct proc* proc, struct reschedule_ctx* rctx, struct pci_info pci_info); +typedef void (*pci_cb_func_t) (struct proc* proc, struct reschedule_ctx* rctx, + struct pci_info pci_info); void pci_init (void); diff --git a/kernel/device/pci_ide.c b/kernel/device/pci_ide.c index 510587f..67033ea 100644 --- a/kernel/device/pci_ide.c +++ b/kernel/device/pci_ide.c @@ -1,17 +1,17 @@ #include #include #include +#include #include #include -#include #include #include #include #include #include -#include #include #include +#include static atomic_int ide_counter = 0; @@ -30,7 +30,8 @@ static const char* progif_msg[] = { "PCI native mode controller, supports both channels switched to ISA compatibility mode, supports bus mastering", }; -static void ide_make_device (struct proc* proc, struct reschedule_ctx* rctx, struct ide_probe probe) { +static void ide_make_device (struct proc* proc, struct reschedule_ctx* rctx, + struct ide_probe probe) { DEBUG ("Found IDE drive: io=%x ctrl=%x no=%u sector=%zu count=%zu\n", probe.io, probe.ctrl, probe.devno, probe.sector_size, probe.sector_count); @@ -54,7 +55,8 @@ static void ide_make_device (struct proc* proc, struct reschedule_ctx* rctx, str .devno = probe.devno, .primscnd = probe.primscnd, }; - struct device* ide = device_create (device_key, ops, lengthof (ops), &idedrv_init, &idedrv_fini, &init, proc, rctx); + struct device* ide = device_create (device_key, ops, lengthof (ops), &idedrv_init, &idedrv_fini, + &init, proc, rctx); device_probe_partitions (proc, rctx, ide); } diff --git a/kernel/device/ps2_kb.c b/kernel/device/ps2_kb.c index 3bfd244..20efe5f 100644 --- a/kernel/device/ps2_kb.c +++ b/kernel/device/ps2_kb.c @@ -148,14 +148,15 @@ static int32_t ps2kb_keycode (void) { static void ps2kb_irq (void* arg, void* regs, struct reschedule_ctx* rctx) { (void)arg, (void)regs; + uint64_t frb, fsq; int32_t keycode = ps2kb_keycode (); if (keycode <= 0 || keycode == 0xFA) return; - spin_lock (&ps2kb_ringbuffer_lock); - spin_lock (&ps2kb_sq.lock); + spin_lock (&ps2kb_ringbuffer_lock, &frb); + spin_lock (&ps2kb_sq.lock, &fsq); ringbuffer_push (uint8_t, &ps2kb_ringbuffer, (uint8_t)keycode); @@ -165,20 +166,21 @@ static void ps2kb_irq (void* arg, void* regs, struct reschedule_ctx* rctx) { struct proc_sq_entry* sq_entry = list_entry (node, struct proc_sq_entry, sq_link); struct proc* resumed_proc = sq_entry->proc; - spin_unlock (&ps2kb_sq.lock); - spin_unlock (&ps2kb_ringbuffer_lock); + spin_unlock (&ps2kb_sq.lock, fsq); + spin_unlock (&ps2kb_ringbuffer_lock, frb); proc_sq_resume (resumed_proc, sq_entry, rctx); return; } - spin_unlock (&ps2kb_sq.lock); - spin_unlock (&ps2kb_ringbuffer_lock); + spin_unlock (&ps2kb_sq.lock, fsq); + spin_unlock (&ps2kb_ringbuffer_lock, frb); } int ps2kb_read_key (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4) { (void)device, (void)a2, (void)a3, (void)a4; + uint64_t frb, fsq; if (!(proc->procgroup->capabilities & PROC_CAP_KB)) return -ST_PERMISSION_ERROR; @@ -188,7 +190,7 @@ int ps2kb_read_key (struct device* device, struct proc* proc, struct reschedule_ if (chbuf == NULL) return -ST_BAD_ADDRESS_SPACE; - spin_lock (&ps2kb_ringbuffer_lock); + spin_lock (&ps2kb_ringbuffer_lock, &frb); size_t prev_count = ps2kb_ringbuffer.count; @@ -198,21 +200,21 @@ int ps2kb_read_key (struct device* device, struct proc* proc, struct reschedule_ /* didn't pop anything */ if (prev_count == new_count) { - spin_lock (&ps2kb_sq.lock); + spin_lock (&ps2kb_sq.lock, &fsq); struct list_node_link* node = ps2kb_sq.proc_list; - spin_unlock (&ps2kb_sq.lock); + spin_unlock (&ps2kb_sq.lock, fsq); if (node != NULL) { - spin_unlock (&ps2kb_ringbuffer_lock); + spin_unlock (&ps2kb_ringbuffer_lock, frb); return -ST_PERMISSION_ERROR; } - proc_sq_suspend (proc, &ps2kb_sq, &ps2kb_ringbuffer_lock, rctx); + proc_sq_suspend (proc, &ps2kb_sq, &ps2kb_ringbuffer_lock, frb, rctx); return ST_OK; } - spin_unlock (&ps2kb_ringbuffer_lock); + spin_unlock (&ps2kb_ringbuffer_lock, frb); return ST_OK; } diff --git a/kernel/device/ramdrv.c b/kernel/device/ramdrv.c index 18b9bb3..ce51ff2 100644 --- a/kernel/device/ramdrv.c +++ b/kernel/device/ramdrv.c @@ -9,7 +9,8 @@ #include #include -bool ramdrv_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx) { +bool ramdrv_init (struct device* device, void* arg, struct proc* proc, + struct reschedule_ctx* rctx) { (void)proc, (void)rctx; struct ramdrv_init* init = arg; diff --git a/kernel/device/terminal.c b/kernel/device/terminal.c index d470587..7b4aa00 100644 --- a/kernel/device/terminal.c +++ b/kernel/device/terminal.c @@ -19,7 +19,8 @@ void ft_free (void* ptr, size_t size) { free (ptr); } -bool terminal_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx) { +bool terminal_init (struct device* device, void* arg, struct proc* proc, + struct reschedule_ctx* rctx) { (void)arg, (void)device, (void)proc, (void)rctx; struct limine_framebuffer_response* fb_r = limine_framebuffer_request.response; diff --git a/kernel/device/terminal.h b/kernel/device/terminal.h index 761bfef..4b90801 100644 --- a/kernel/device/terminal.h +++ b/kernel/device/terminal.h @@ -8,7 +8,8 @@ struct device; -bool terminal_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx); +bool terminal_init (struct device* device, void* arg, struct proc* proc, + struct reschedule_ctx* rctx); void terminal_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx); diff --git a/kernel/fs/fat1.c b/kernel/fs/fat1.c index 55b0b99..312d549 100644 --- a/kernel/fs/fat1.c +++ b/kernel/fs/fat1.c @@ -6,11 +6,13 @@ #include #include -static int media_write (struct fatfs* _fs, struct fatfs_ctx* ctx, size_t sector, uint8_t* buffer, size_t sector_count) { +static int media_write (struct fatfs* _fs, struct fatfs_ctx* ctx, size_t sector, uint8_t* buffer, + size_t sector_count) { return _fs->disk_io.write_media (ctx, sector, buffer, sector_count); } -static int media_read (struct fatfs* _fs, struct fatfs_ctx* ctx, size_t sector, uint8_t* buffer, size_t sector_count) { +static int media_read (struct fatfs* _fs, struct fatfs_ctx* ctx, size_t sector, uint8_t* buffer, + size_t sector_count) { return _fs->disk_io.read_media (ctx, sector, buffer, sector_count); } diff --git a/kernel/fs/fatfs.c b/kernel/fs/fatfs.c index 7e6a5ab..3c122bd 100644 --- a/kernel/fs/fatfs.c +++ b/kernel/fs/fatfs.c @@ -20,6 +20,8 @@ static int fat1_diskio_read (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* buffer, uint32_t sector_count) { + uint64_t fd; + struct vfs_volume* volume = ctx->udata; struct device* back_device = volume->back_device; @@ -30,11 +32,11 @@ static int fat1_diskio_read (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* bu size_t phys_sector, phys_sector_count; int ret; - spin_lock (&back_device->lock); + spin_lock (&back_device->lock, &fd); ret = device_op (back_device, XDRV_GET_SECTOR_SIZE, ctx->proc, ctx->rctx, §or_size); if (ret < 0) { - spin_unlock (&back_device->lock); + spin_unlock (&back_device->lock, fd); return 0; } @@ -44,11 +46,11 @@ static int fat1_diskio_read (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* bu ret = device_op (back_device, XDRV_READ, ctx->proc, ctx->rctx, &phys_sector, &phys_sector_count, buffer); if (ret < 0) { - spin_unlock (&back_device->lock); + spin_unlock (&back_device->lock, fd); return 0; } - spin_unlock (&back_device->lock); + spin_unlock (&back_device->lock, fd); if (ret < 0) return 0; @@ -57,6 +59,8 @@ static int fat1_diskio_read (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* bu static int fat1_diskio_write (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* buffer, uint32_t sector_count) { + uint64_t fd; + struct vfs_volume* volume = ctx->udata; struct device* back_device = volume->back_device; @@ -67,11 +71,11 @@ static int fat1_diskio_write (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* b size_t phys_sector, phys_sector_count; int ret; - spin_lock (&back_device->lock); + spin_lock (&back_device->lock, &fd); ret = device_op (back_device, XDRV_GET_SECTOR_SIZE, ctx->proc, ctx->rctx, §or_size); if (ret < 0) { - spin_unlock (&back_device->lock); + spin_unlock (&back_device->lock, fd); return 0; } @@ -81,11 +85,11 @@ static int fat1_diskio_write (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* b ret = device_op (back_device, XDRV_WRITE, ctx->proc, ctx->rctx, &phys_sector, &phys_sector_count, buffer); if (ret < 0) { - spin_unlock (&back_device->lock); + spin_unlock (&back_device->lock, fd); return 0; } - spin_unlock (&back_device->lock); + spin_unlock (&back_device->lock, fd); if (ret < 0) return 0; @@ -124,15 +128,17 @@ int fatfs_mount (struct vfs_volume* volume, struct proc* proc, struct reschedule } int fatfs16_format (struct vfs_volume* volume, struct proc* proc, struct reschedule_ctx* rctx) { + uint64_t fd; + struct fatfs_ctx* fatfs_ctx = volume->udata; struct device* back_device = volume->back_device; size_t total_size; fatfs_ctx->proc = proc; fatfs_ctx->rctx = rctx; - spin_lock (&back_device->lock); + spin_lock (&back_device->lock, &fd); device_op (back_device, XDRV_GET_SIZE, proc, rctx, &total_size); - spin_unlock (&back_device->lock); + spin_unlock (&back_device->lock, fd); size_t sectors = div_align_up (total_size, FAT_SECTOR_SIZE); int r = fatfs_format_fat16 (fatfs_ctx, &fatfs_ctx->_fs, sectors, "mop3 fat16"); @@ -140,15 +146,17 @@ int fatfs16_format (struct vfs_volume* volume, struct proc* proc, struct resched } int fatfs32_format (struct vfs_volume* volume, struct proc* proc, struct reschedule_ctx* rctx) { + uint64_t fd; + struct fatfs_ctx* fatfs_ctx = volume->udata; struct device* back_device = volume->back_device; size_t total_size; fatfs_ctx->proc = proc; fatfs_ctx->rctx = rctx; - spin_lock (&back_device->lock); + spin_lock (&back_device->lock, &fd); device_op (back_device, XDRV_GET_SIZE, proc, rctx, &total_size); - spin_unlock (&back_device->lock); + spin_unlock (&back_device->lock, fd); size_t sectors = div_align_up (total_size, FAT_SECTOR_SIZE); int r = fatfs_format_fat32 (fatfs_ctx, &fatfs_ctx->_fs, sectors, "mop3 fat32"); diff --git a/kernel/fs/tarfs.c b/kernel/fs/tarfs.c index 8b0407e..ca82fd7 100644 --- a/kernel/fs/tarfs.c +++ b/kernel/fs/tarfs.c @@ -68,6 +68,7 @@ static size_t tar_parse (struct tarfs* tarfs, uint8_t* addr, size_t max_size) { int tarfs_mount (struct vfs_volume* volume, struct proc* proc, struct reschedule_ctx* rctx, bool format) { (void)format; + uint64_t fd; struct tarfs* tarfs = malloc (sizeof (*tarfs)); @@ -82,18 +83,18 @@ int tarfs_mount (struct vfs_volume* volume, struct proc* proc, struct reschedule size_t total_size, sector_size; int ret; - spin_lock (&back_device->lock); + spin_lock (&back_device->lock, &fd); ret = device_op (back_device, XDRV_GET_SIZE, NULL, NULL, &total_size); if (ret < 0) { - spin_unlock (&back_device->lock); + spin_unlock (&back_device->lock, fd); free (volume->udata); return ret; } ret = device_op (back_device, XDRV_GET_SECTOR_SIZE, NULL, NULL, §or_size); if (ret < 0) { - spin_unlock (&back_device->lock); + spin_unlock (&back_device->lock, fd); free (volume->udata); return ret; } @@ -101,7 +102,7 @@ int tarfs_mount (struct vfs_volume* volume, struct proc* proc, struct reschedule uint8_t* buffer = malloc (total_size); if (buffer == NULL) { - spin_unlock (&back_device->lock); + spin_unlock (&back_device->lock, fd); free (volume->udata); volume->udata = NULL; return ret; @@ -113,7 +114,7 @@ int tarfs_mount (struct vfs_volume* volume, struct proc* proc, struct reschedule ret = device_op (back_device, XDRV_READ, proc, rctx, §or, §or_count, dest); } - spin_unlock (&back_device->lock); + spin_unlock (&back_device->lock, fd); if (ret < 0) { free (buffer); diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index 0f1e81b..98f9151 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -22,14 +22,16 @@ static struct vfs_volume_table volume_table; static struct vfs_volume* vfs_find_volume (const char* volume) { + uint64_t fvt; + struct hash_node_link* found_link = NULL; size_t volume_len = strlen_null (volume); uint32_t hash = hash_fnv32 (volume, volume_len); - spin_lock (&volume_table.lock); + spin_lock (&volume_table.lock, &fvt); hash_find (&volume_table, volume, volume_len, hash, lengthof (volume_table.volume_buckets), volume_buckets, struct vfs_volume, volume_table_link, key, found_link); - spin_unlock (&volume_table.lock); + spin_unlock (&volume_table.lock, fvt); if (found_link == NULL) return NULL; @@ -39,6 +41,8 @@ static struct vfs_volume* vfs_find_volume (const char* volume) { int vfs_create_volume (struct proc* proc, struct reschedule_ctx* rctx, const char* key, int fs_type, struct device* back_device, bool format) { + uint64_t fvt; + if (strlen_null (key) > VOLUME_MAX) return -ST_OOB_ERROR; @@ -102,49 +106,53 @@ int vfs_create_volume (struct proc* proc, struct reschedule_ctx* rctx, const cha uint32_t mp_hash = hash_fnv32 (volume->key, strlen_null (volume->key)); - spin_lock (&volume_table.lock); + spin_lock (&volume_table.lock, &fvt); hash_insert (&volume_table, &volume->volume_table_link, mp_hash, lengthof (volume_table.volume_buckets), volume_buckets); - spin_unlock (&volume_table.lock); + spin_unlock (&volume_table.lock, fvt); return ST_OK; } int vfs_volume_open (struct proc* proc, const char* volume_name, struct reschedule_ctx* rctx) { + uint64_t fv; + struct vfs_volume* volume = vfs_find_volume (volume_name); if (volume == NULL) return -ST_NOT_FOUND; - spin_lock (&volume->lock); + spin_lock (&volume->lock, &fv); if (!volume->locked) { volume->locked = true; volume->owner = proc; - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return ST_OK; } else { - proc_sq_suspend (proc, &volume->sq, &volume->lock, rctx); + proc_sq_suspend (proc, &volume->sq, &volume->lock, fv, rctx); return ST_OK; } } int vfs_volume_close (struct proc* proc, const char* volume_name, struct reschedule_ctx* rctx) { + uint64_t fv, fvsq; + struct vfs_volume* volume = vfs_find_volume (volume_name); if (volume == NULL) return -ST_NOT_FOUND; - spin_lock (&volume->lock); + spin_lock (&volume->lock, &fv); if (volume->locked && volume->owner != proc) { - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return -ST_PERMISSION_ERROR; } - spin_lock (&volume->sq.lock); + spin_lock (&volume->sq.lock, &fvsq); struct list_node_link* node = volume->sq.proc_list; @@ -155,8 +163,8 @@ int vfs_volume_close (struct proc* proc, const char* volume_name, struct resched volume->owner = resumed_proc; volume->locked = true; - spin_unlock (&volume->sq.lock); - spin_unlock (&volume->lock); + spin_unlock (&volume->sq.lock, fvsq); + spin_unlock (&volume->lock, fv); proc_sq_resume (resumed_proc, sq_entry, rctx); return ST_OK; @@ -165,159 +173,175 @@ int vfs_volume_close (struct proc* proc, const char* volume_name, struct resched volume->locked = false; volume->owner = NULL; - spin_unlock (&volume->sq.lock); - spin_unlock (&volume->lock); + spin_unlock (&volume->sq.lock, fvsq); + spin_unlock (&volume->lock, fv); return ST_OK; } int vfs_format (struct proc* proc, struct reschedule_ctx* rctx, const char* volume_name) { + uint64_t fv; + struct vfs_volume* volume = vfs_find_volume (volume_name); if (volume == NULL) return -ST_NOT_FOUND; - spin_lock (&volume->lock); + spin_lock (&volume->lock, &fv); if (volume->locked && volume->owner != proc) { - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return -ST_PERMISSION_ERROR; } - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return volume->driver_ops.format (volume, proc, rctx); } int vfs_read_file (struct proc* proc, struct reschedule_ctx* rctx, const char* volume_name, const char* path, uint8_t* buffer, size_t off, size_t size) { + uint64_t fv; + struct vfs_volume* volume = vfs_find_volume (volume_name); if (volume == NULL) return -ST_NOT_FOUND; - spin_lock (&volume->lock); + spin_lock (&volume->lock, &fv); if (volume->locked && volume->owner != proc) { - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return -ST_PERMISSION_ERROR; } - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return volume->driver_ops.read_file (volume, proc, rctx, path, buffer, off, size); } int vfs_write_file (struct proc* proc, struct reschedule_ctx* rctx, const char* volume_name, const char* path, uint8_t* buffer, size_t off, size_t size, uint32_t flags) { + uint64_t fv; + struct vfs_volume* volume = vfs_find_volume (volume_name); if (volume == NULL) return -ST_NOT_FOUND; - spin_lock (&volume->lock); + spin_lock (&volume->lock, &fv); if (volume->locked && volume->owner != proc) { - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return -ST_PERMISSION_ERROR; } - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return volume->driver_ops.write_file (volume, proc, rctx, path, buffer, off, size, flags); } int vfs_create_file (struct proc* proc, struct reschedule_ctx* rctx, const char* volume_name, const char* path) { + uint64_t fv; + struct vfs_volume* volume = vfs_find_volume (volume_name); if (volume == NULL) return -ST_NOT_FOUND; - spin_lock (&volume->lock); + spin_lock (&volume->lock, &fv); if (volume->locked && volume->owner != proc) { - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return -ST_PERMISSION_ERROR; } - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return volume->driver_ops.create_file (volume, proc, rctx, path); } int vfs_describe (struct proc* proc, struct reschedule_ctx* rctx, const char* volume_name, const char* path, struct desc* desc) { + uint64_t fv; + struct vfs_volume* volume = vfs_find_volume (volume_name); if (volume == NULL) return -ST_NOT_FOUND; - spin_lock (&volume->lock); + spin_lock (&volume->lock, &fv); if (volume->locked && volume->owner != proc) { - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return -ST_PERMISSION_ERROR; } - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return volume->driver_ops.describe (volume, proc, rctx, path, desc); } int vfs_read_dir_entry (struct proc* proc, struct reschedule_ctx* rctx, const char* volume_name, const char* path, struct dir_entry* entry, size_t entry_num) { + uint64_t fv; + struct vfs_volume* volume = vfs_find_volume (volume_name); if (volume == NULL) return -ST_NOT_FOUND; - spin_lock (&volume->lock); + spin_lock (&volume->lock, &fv); if (volume->locked && volume->owner != proc) { - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return -ST_PERMISSION_ERROR; } - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return volume->driver_ops.read_dir_entry (volume, proc, rctx, path, entry, entry_num); } int vfs_create_dir (struct proc* proc, struct reschedule_ctx* rctx, const char* volume_name, const char* path) { + uint64_t fv; + struct vfs_volume* volume = vfs_find_volume (volume_name); if (volume == NULL) return -ST_NOT_FOUND; - spin_lock (&volume->lock); + spin_lock (&volume->lock, &fv); if (volume->locked && volume->owner != proc) { - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return -ST_PERMISSION_ERROR; } - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return volume->driver_ops.create_dir (volume, proc, rctx, path); } int vfs_remove (struct proc* proc, struct reschedule_ctx* rctx, const char* volume_name, const char* path) { + uint64_t fv; + struct vfs_volume* volume = vfs_find_volume (volume_name); if (volume == NULL) return -ST_NOT_FOUND; - spin_lock (&volume->lock); + spin_lock (&volume->lock, &fv); if (volume->locked && volume->owner != proc) { - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return -ST_PERMISSION_ERROR; } - spin_unlock (&volume->lock); + spin_unlock (&volume->lock, fv); return volume->driver_ops.remove (volume, proc, rctx, path); } diff --git a/kernel/id/id_alloc.c b/kernel/id/id_alloc.c index ee6a2ad..0c41919 100644 --- a/kernel/id/id_alloc.c +++ b/kernel/id/id_alloc.c @@ -27,26 +27,30 @@ void id_alloc_fini (struct id_alloc* ida) { } int id_alloc (struct id_alloc* ida) { - spin_lock (&ida->lock); + uint64_t fid; + + spin_lock (&ida->lock, &fid); for (size_t bit = 0; bit < ida->bm.nbits; bit++) { if (!bm_test (&ida->bm, bit)) { bm_set (&ida->bm, bit); - spin_unlock (&ida->lock); + spin_unlock (&ida->lock, fid); return (int)bit; } } - spin_unlock (&ida->lock); + spin_unlock (&ida->lock, fid); return -ST_OOM_ERROR; } void id_free (struct id_alloc* ida, int id) { + uint64_t fid; + if (id < 0) return; - spin_lock (&ida->lock); + spin_lock (&ida->lock, &fid); bm_clear (&ida->bm, (size_t)id); - spin_unlock (&ida->lock); + spin_unlock (&ida->lock, fid); } diff --git a/kernel/irq/irq.c b/kernel/irq/irq.c index dfceca4..537cc83 100644 --- a/kernel/irq/irq.c +++ b/kernel/irq/irq.c @@ -14,6 +14,8 @@ static struct rb_node_link* irq_tree = NULL; static spin_lock_t irqs_lock = SPIN_LOCK_INIT; bool irq_attach (irq_func_t func, void* arg, uint32_t irq_num) { + uint64_t fiq; + struct irq* irq = malloc (sizeof (*irq)); if (irq == NULL) { return false; @@ -23,29 +25,33 @@ bool irq_attach (irq_func_t func, void* arg, uint32_t irq_num) { irq->arg = arg; irq->irq_num = irq_num; - spin_lock (&irqs_lock); + spin_lock (&irqs_lock, &fiq); rbtree_insert (struct irq, &irq_tree, &irq->irq_tree_link, irq_tree_link, irq_num); - spin_unlock (&irqs_lock); + spin_unlock (&irqs_lock, fiq); return true; } void irq_detach (uint32_t irq_num) { + uint64_t fiq; + struct irq* irq = irq_find (irq_num); - spin_lock (&irqs_lock); + spin_lock (&irqs_lock, &fiq); rbtree_delete (&irq_tree, &irq->irq_tree_link); - spin_unlock (&irqs_lock); + spin_unlock (&irqs_lock, fiq); free (irq); } struct irq* irq_find (uint32_t irq_num) { + uint64_t fiq; + struct irq* irq = NULL; - spin_lock (&irqs_lock); + spin_lock (&irqs_lock, &fiq); rbtree_find (struct irq, &irq_tree, irq_num, irq, irq_tree_link, irq_num); - spin_unlock (&irqs_lock); + spin_unlock (&irqs_lock, fiq); return irq; } diff --git a/kernel/mm/liballoc.c b/kernel/mm/liballoc.c index 20978f0..6dfc858 100644 --- a/kernel/mm/liballoc.c +++ b/kernel/mm/liballoc.c @@ -12,13 +12,13 @@ spin_lock_t _liballoc_lock = SPIN_LOCK_INIT; -int liballoc_lock (void) { - spin_lock (&_liballoc_lock); +int liballoc_lock (uint64_t* flags) { + spin_lock (&_liballoc_lock, flags); return 0; } -int liballoc_unlock (void) { - spin_unlock (&_liballoc_lock); +int liballoc_unlock (uint64_t flags) { + spin_unlock (&_liballoc_lock, flags); return 0; } @@ -242,12 +242,13 @@ static struct boundary_tag* allocate_new_tag (unsigned int size) { void* malloc (size_t size) { size = align_up (size, 16); + uint64_t fla; int index; void* ptr; struct boundary_tag* tag = NULL; - liballoc_lock (); + liballoc_lock (&fla); if (l_initialized == 0) { for (index = 0; index < MAXEXP; index++) { @@ -275,7 +276,7 @@ void* malloc (size_t size) { // No page found. Make one. if (tag == NULL) { if ((tag = allocate_new_tag (size)) == NULL) { - liballoc_unlock (); + liballoc_unlock (fla); return NULL; } @@ -308,23 +309,24 @@ void* malloc (size_t size) { ptr = (void*)((uintptr_t)tag + sizeof (struct boundary_tag)); - liballoc_unlock (); + liballoc_unlock (fla); return ptr; } void free (void* ptr) { int index; struct boundary_tag* tag; + uint64_t flf; if (ptr == NULL) return; - liballoc_lock (); + liballoc_lock (&flf); tag = (struct boundary_tag*)((uintptr_t)ptr - sizeof (struct boundary_tag)); if (tag->magic != LIBALLOC_MAGIC) { - liballoc_unlock (); // release the lock + liballoc_unlock (flf); // release the lock return; } @@ -357,7 +359,7 @@ void free (void* ptr) { liballoc_free (tag, pages); - liballoc_unlock (); + liballoc_unlock (flf); return; } @@ -368,7 +370,7 @@ void free (void* ptr) { insert_tag (tag, index); - liballoc_unlock (); + liballoc_unlock (flf); } void* calloc (size_t nobj, size_t size) { @@ -388,6 +390,7 @@ void* realloc (void* p, size_t size) { void* ptr; struct boundary_tag* tag; int real_size; + uint64_t flr; if (size == 0) { free (p); @@ -397,11 +400,11 @@ void* realloc (void* p, size_t size) { return malloc (size); if (&liballoc_lock != NULL) - liballoc_lock (); // lockit + liballoc_lock (&flr); // lockit tag = (struct boundary_tag*)((uintptr_t)p - sizeof (struct boundary_tag)); real_size = tag->size; if (&liballoc_unlock != NULL) - liballoc_unlock (); + liballoc_unlock (flr); if ((size_t)real_size > size) real_size = size; diff --git a/kernel/mm/liballoc.h b/kernel/mm/liballoc.h index a4c4a3c..88c3b04 100644 --- a/kernel/mm/liballoc.h +++ b/kernel/mm/liballoc.h @@ -48,7 +48,7 @@ struct boundary_tag { * \return 0 if the lock was acquired successfully. Anything else is * failure. */ -extern int liballoc_lock (void); +extern int liballoc_lock (uint64_t* flags); /** This function unlocks what was previously locked by the liballoc_lock * function. If it disabled interrupts, it enables interrupts. If it @@ -56,7 +56,7 @@ extern int liballoc_lock (void); * * \return 0 if the lock was successfully released. */ -extern int liballoc_unlock (void); +extern int liballoc_unlock (uint64_t flags); /** This is the hook into the local system which allocates pages. It * accepts an integer parameter which is the number of pages diff --git a/kernel/mm/pmm.c b/kernel/mm/pmm.c index d4561ef..407976e 100644 --- a/kernel/mm/pmm.c +++ b/kernel/mm/pmm.c @@ -100,6 +100,8 @@ static size_t pmm_find_free_space (struct pmm_region* pmm_region, size_t nblks) } physaddr_t pmm_alloc (size_t nblks) { + uint64_t fpr; + for (size_t region = 0; region < PMM_REGIONS_MAX; region++) { struct pmm_region* pmm_region = &pmm.regions[region]; @@ -107,7 +109,7 @@ physaddr_t pmm_alloc (size_t nblks) { if (!(pmm_region->flags & PMM_REGION_ACTIVE)) continue; - spin_lock (&pmm_region->lock); + spin_lock (&pmm_region->lock, &fpr); /* Find starting bit of the free bit range */ size_t bit = pmm_find_free_space (pmm_region, nblks); @@ -116,18 +118,20 @@ physaddr_t pmm_alloc (size_t nblks) { if (bit != (size_t)-1) { /* Mark it */ bm_set_region (&pmm_region->bm, bit, nblks); - spin_unlock (&pmm_region->lock); + spin_unlock (&pmm_region->lock, fpr); return pmm_region->membase + bit * PAGE_SIZE; } - spin_unlock (&pmm_region->lock); + spin_unlock (&pmm_region->lock, fpr); } return PMM_ALLOC_ERR; } void pmm_free (physaddr_t p_addr, size_t nblks) { + uint64_t fpr; + /* Round down to nearest page boundary */ physaddr_t aligned_p_addr = align_down (p_addr, PAGE_SIZE); @@ -145,11 +149,11 @@ void pmm_free (physaddr_t p_addr, size_t nblks) { size_t bit = div_align_up (addr, PAGE_SIZE); - spin_lock (&pmm_region->lock); + spin_lock (&pmm_region->lock, &fpr); bm_clear_region (&pmm_region->bm, bit, nblks); - spin_unlock (&pmm_region->lock); + spin_unlock (&pmm_region->lock, fpr); break; } diff --git a/kernel/proc/mail.c b/kernel/proc/mail.c index cedb57d..50f6e5a 100644 --- a/kernel/proc/mail.c +++ b/kernel/proc/mail.c @@ -12,43 +12,47 @@ #include void proc_cleanup_resource_mail (struct proc_resource* resource, struct reschedule_ctx* rctx) { + uint64_t fr, fssq; + struct proc_mail* mail = &resource->u.mail; - spin_lock (&mail->resource->lock); + spin_lock (&mail->resource->lock, &fr); ringbuffer_fini (&mail->ringbuffer); - spin_lock (&mail->send_sq.lock); + spin_lock (&mail->send_sq.lock, &fssq); while (mail->send_sq.proc_list != NULL) { struct list_node_link* node = mail->send_sq.proc_list; struct proc_sq_entry* sq_entry = list_entry (node, struct proc_sq_entry, sq_link); struct proc* suspended_proc = sq_entry->proc; - spin_unlock (&mail->send_sq.lock); - spin_unlock (&mail->resource->lock); + spin_unlock (&mail->send_sq.lock, fssq); + spin_unlock (&mail->resource->lock, fr); proc_sq_resume (suspended_proc, sq_entry, rctx); - spin_lock (&mail->resource->lock); - spin_lock (&mail->send_sq.lock); + spin_lock (&mail->resource->lock, &fr); + spin_lock (&mail->send_sq.lock, &fssq); } - spin_unlock (&mail->send_sq.lock); - spin_unlock (&mail->resource->lock); + spin_unlock (&mail->send_sq.lock, fssq); + spin_unlock (&mail->resource->lock, fr); } void proc_mail_send (struct proc* proc, struct proc_mail* mail, struct reschedule_ctx* rctx, void* data, size_t data_size) { - spin_lock (&mail->resource->lock); + uint64_t fr, frsq, fp; + + spin_lock (&mail->resource->lock, &fr); /* mail full */ if (mail->ringbuffer.count == mail->ringbuffer.capacity) { - proc_sq_suspend (proc, &mail->send_sq, &mail->resource->lock, rctx); + proc_sq_suspend (proc, &mail->send_sq, &mail->resource->lock, fr, rctx); return; } - spin_lock (&mail->recv_sq.lock); + spin_lock (&mail->recv_sq.lock, &frsq); /* if receiver available, hand off directly */ struct list_node_link* node = mail->recv_sq.proc_list; @@ -57,10 +61,10 @@ void proc_mail_send (struct proc* proc, struct proc_mail* mail, struct reschedul struct proc_sq_entry* sq_entry = list_entry (node, struct proc_sq_entry, sq_link); struct proc* resumed_proc = sq_entry->proc; - spin_unlock (&mail->recv_sq.lock); - spin_unlock (&mail->resource->lock); + spin_unlock (&mail->recv_sq.lock, frsq); + spin_unlock (&mail->resource->lock, fr); - spin_lock (&resumed_proc->lock); + spin_lock (&resumed_proc->lock, &fp); if (resumed_proc->mail_recv_buffer != NULL) { size_t copy_size = min (data_size, resumed_proc->mail_recv_size); @@ -70,13 +74,13 @@ void proc_mail_send (struct proc* proc, struct proc_mail* mail, struct reschedul resumed_proc->mail_recv_size = 0; } - spin_unlock (&resumed_proc->lock); + spin_unlock (&resumed_proc->lock, fp); proc_sq_resume (resumed_proc, sq_entry, rctx); return; } - spin_unlock (&mail->recv_sq.lock); + spin_unlock (&mail->recv_sq.lock, frsq); /* mail is empty and nobody is waiting */ void* mesg = malloc (data_size); @@ -86,17 +90,19 @@ void proc_mail_send (struct proc* proc, struct proc_mail* mail, struct reschedul ringbuffer_push (struct mail_packet, &mail->ringbuffer, packet); } - spin_unlock (&mail->resource->lock); + spin_unlock (&mail->resource->lock, fr); } void proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct reschedule_ctx* rctx, void* recv_buffer, size_t recv_size) { - spin_lock (&proc->lock); + uint64_t fp, fr, fssq; + + spin_lock (&proc->lock, &fp); proc->mail_recv_buffer = recv_buffer; proc->mail_recv_size = recv_size; - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); - spin_lock (&mail->resource->lock); + spin_lock (&mail->resource->lock, &fr); /* consume mesg if available */ if (mail->ringbuffer.count > 0) { @@ -106,7 +112,7 @@ void proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct resche free (packet.packet_buffer); /* check for suspended sender */ - spin_lock (&mail->send_sq.lock); + spin_lock (&mail->send_sq.lock, &fssq); struct list_node_link* node = mail->send_sq.proc_list; @@ -114,19 +120,19 @@ void proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct resche struct proc_sq_entry* sq_entry = list_entry (node, struct proc_sq_entry, sq_link); struct proc* resumed_proc = sq_entry->proc; - spin_unlock (&mail->send_sq.lock); - spin_unlock (&mail->resource->lock); + spin_unlock (&mail->send_sq.lock, fssq); + spin_unlock (&mail->resource->lock, fr); proc_sq_resume (resumed_proc, sq_entry, rctx); return; } - spin_unlock (&mail->send_sq.lock); - spin_unlock (&mail->resource->lock); + spin_unlock (&mail->send_sq.lock, fssq); + spin_unlock (&mail->resource->lock, fr); return; } /* nothing to receive */ - proc_sq_suspend (proc, &mail->recv_sq, &mail->resource->lock, rctx); + proc_sq_suspend (proc, &mail->recv_sq, &mail->resource->lock, fr, rctx); } diff --git a/kernel/proc/mutex.c b/kernel/proc/mutex.c index a7fa3d8..900ae53 100644 --- a/kernel/proc/mutex.c +++ b/kernel/proc/mutex.c @@ -12,7 +12,9 @@ #include void proc_mutexes_cleanup (struct proc* proc, struct reschedule_ctx* rctx) { - spin_lock (&proc->procgroup->lock); + uint64_t fpg, fr; + + spin_lock (&proc->procgroup->lock, &fpg); struct rb_node_link* rnode; rbtree_first (&proc->procgroup->resource_tree, rnode); @@ -25,30 +27,32 @@ void proc_mutexes_cleanup (struct proc* proc, struct reschedule_ctx* rctx) { rnode = next; - spin_lock (&resource->lock); + spin_lock (&resource->lock, &fr); if (resource->type != PR_MUTEX) { - spin_unlock (&resource->lock); + spin_unlock (&resource->lock, fr); continue; } if (resource->u.mutex.owner == proc && resource->u.mutex.locked) { - spin_unlock (&resource->lock); + spin_unlock (&resource->lock, fr); proc_mutex_unlock (proc, &resource->u.mutex, rctx); } - spin_unlock (&resource->lock); + spin_unlock (&resource->lock, fr); } - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); } void proc_cleanup_resource_mutex (struct proc_resource* resource, struct reschedule_ctx* rctx) { + uint64_t fr, fsq; + struct proc_mutex* mutex = &resource->u.mutex; - spin_lock (&mutex->resource->lock); - spin_lock (&mutex->suspension_q.lock); + spin_lock (&mutex->resource->lock, &fr); + spin_lock (&mutex->suspension_q.lock, &fsq); while (mutex->suspension_q.proc_list != NULL) { struct list_node_link* node = mutex->suspension_q.proc_list; @@ -56,45 +60,49 @@ void proc_cleanup_resource_mutex (struct proc_resource* resource, struct resched struct proc* suspended_proc = sq_entry->proc; /* we will relock during resume */ - spin_unlock (&mutex->suspension_q.lock); - spin_unlock (&mutex->resource->lock); + spin_unlock (&mutex->suspension_q.lock, fsq); + spin_unlock (&mutex->resource->lock, fr); proc_sq_resume (suspended_proc, sq_entry, rctx); /* reacquire */ - spin_lock (&mutex->resource->lock); - spin_lock (&mutex->suspension_q.lock); + spin_lock (&mutex->resource->lock, &fr); + spin_lock (&mutex->suspension_q.lock, &fsq); } mutex->locked = false; mutex->owner = NULL; - spin_unlock (&mutex->suspension_q.lock); - spin_unlock (&mutex->resource->lock); + spin_unlock (&mutex->suspension_q.lock, fsq); + spin_unlock (&mutex->resource->lock, fr); } void proc_mutex_lock (struct proc* proc, struct proc_mutex* mutex, struct reschedule_ctx* rctx) { - spin_lock (&mutex->resource->lock); + uint64_t fr; + + spin_lock (&mutex->resource->lock, &fr); if (!mutex->locked || mutex->owner == proc) { mutex->locked = true; mutex->owner = proc; - spin_unlock (&mutex->resource->lock); + spin_unlock (&mutex->resource->lock, fr); return; } - proc_sq_suspend (proc, &mutex->suspension_q, &mutex->resource->lock, rctx); + proc_sq_suspend (proc, &mutex->suspension_q, &mutex->resource->lock, fr, rctx); } void proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct reschedule_ctx* rctx) { - spin_lock (&mutex->resource->lock); + uint64_t fr, fsq; + + spin_lock (&mutex->resource->lock, &fr); if (mutex->owner != proc) { - spin_unlock (&mutex->resource->lock); + spin_unlock (&mutex->resource->lock, fr); return; } - spin_lock (&mutex->suspension_q.lock); + spin_lock (&mutex->suspension_q.lock, &fsq); struct list_node_link* node = mutex->suspension_q.proc_list; @@ -105,8 +113,8 @@ void proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct resc mutex->owner = resumed_proc; mutex->locked = true; - spin_unlock (&mutex->suspension_q.lock); - spin_unlock (&mutex->resource->lock); + spin_unlock (&mutex->suspension_q.lock, fsq); + spin_unlock (&mutex->resource->lock, fr); proc_sq_resume (resumed_proc, sq_entry, rctx); return; @@ -115,6 +123,6 @@ void proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct resc mutex->locked = false; mutex->owner = NULL; - spin_unlock (&mutex->suspension_q.lock); - spin_unlock (&mutex->resource->lock); + spin_unlock (&mutex->suspension_q.lock, fsq); + spin_unlock (&mutex->resource->lock, fr); } diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index a00c094..f82aaec 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -177,21 +177,25 @@ struct proc* proc_from_file (struct proc* proc1, const char* volume, const char* } struct proc* proc_find_pid (int pid) { + uint64_t fpt; + struct proc* proc = NULL; - spin_lock (&proc_tree_lock); + spin_lock (&proc_tree_lock, &fpt); rbtree_find (struct proc, &proc_tree, pid, proc, proc_tree_link, pid); - spin_unlock (&proc_tree_lock); + spin_unlock (&proc_tree_lock, fpt); return proc; } void proc_register (struct proc* proc, struct cpu* register_cpu, struct reschedule_ctx* rctx) { + uint64_t fpt, fc, fp; + struct cpu* cpu = register_cpu != NULL ? register_cpu : cpu_find_lightest (); - spin_lock (&proc_tree_lock); - spin_lock (&cpu->lock); - spin_lock (&proc->lock); + spin_lock (&proc_tree_lock, &fpt); + spin_lock (&cpu->lock, &fc); + spin_lock (&proc->lock, &fp); proc->cpu = cpu; @@ -202,15 +206,17 @@ void proc_register (struct proc* proc, struct cpu* register_cpu, struct reschedu if (cpu->proc_current == NULL) cpu->proc_current = proc; - spin_unlock (&proc->lock); - spin_unlock (&cpu->lock); - spin_unlock (&proc_tree_lock); + spin_unlock (&proc->lock, fp); + spin_unlock (&cpu->lock, fc); + spin_unlock (&proc_tree_lock, fpt); rctx_insert_cpu (rctx, cpu); } /* caller holds cpu->lock */ static struct proc* proc_find_sched (struct cpu* cpu) { + uint64_t fp; + if (!cpu->proc_run_q) return NULL; @@ -229,16 +235,16 @@ static struct proc* proc_find_sched (struct cpu* cpu) { do { struct proc* proc = list_entry (current, struct proc, cpu_run_q_link); - spin_lock (&proc->lock); + spin_lock (&proc->lock, &fp); int state = proc->state; if (state == PROC_READY && !(proc->flags & PROC_KPROC)) { - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); return proc; } - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); current = current->next ? current->next : cpu->proc_run_q; } while (current != start); @@ -249,36 +255,39 @@ static struct proc* proc_find_sched (struct cpu* cpu) { void proc_sched (void) { struct proc* next = NULL; struct cpu* cpu = thiscpu; + uint64_t fc; - spin_lock (&cpu->lock); + spin_lock (&cpu->lock, &fc); next = proc_find_sched (cpu); if (next) { cpu->proc_current = next; - do_sched (next, &cpu->lock); + do_sched (next, &cpu->lock, fc); } else { cpu->proc_current = NULL; - spin_unlock (&cpu->lock); + spin_unlock (&cpu->lock, fc); spin (); } } void proc_kill (struct proc* proc, struct reschedule_ctx* rctx) { - spin_lock (&proc->lock); + uint64_t fp, fc, fpt; + + spin_lock (&proc->lock, &fp); if ((proc->flags & PROC_KPROC)) { - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); return; } struct cpu* cpu = proc->cpu; - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); - spin_lock (&cpu->lock); - spin_lock (&proc->lock); + spin_lock (&cpu->lock, &fc); + spin_lock (&proc->lock, &fp); proc->state = PROC_DEAD; proc->cpu = NULL; @@ -288,16 +297,16 @@ void proc_kill (struct proc* proc, struct reschedule_ctx* rctx) { if (cpu->proc_current == proc) cpu->proc_current = NULL; - spin_unlock (&proc->lock); - spin_unlock (&cpu->lock); + spin_unlock (&proc->lock, fp); + spin_unlock (&cpu->lock, fc); - spin_lock (&proc_tree_lock); - spin_lock (&proc->lock); + spin_lock (&proc_tree_lock, &fpt); + spin_lock (&proc->lock, &fp); rbtree_delete (&proc_tree, &proc->proc_tree_link); - spin_unlock (&proc->lock); - spin_unlock (&proc_tree_lock); + spin_unlock (&proc->lock, fp); + spin_unlock (&proc_tree_lock, fpt); proc_cleanup (proc, rctx); @@ -307,7 +316,7 @@ void proc_kill (struct proc* proc, struct reschedule_ctx* rctx) { } void proc_wait_for (struct proc* proc, struct reschedule_ctx* rctx, struct proc* wait_proc) { - proc_sq_suspend (proc, &wait_proc->done_sq, NULL, rctx); + proc_sq_suspend (proc, &wait_proc->done_sq, NULL, 0, rctx); } static void proc_irq_sched (void* arg, void* regs, struct reschedule_ctx* rctx) { @@ -323,6 +332,8 @@ static void proc_irq_sched (void* arg, void* regs, struct reschedule_ctx* rctx) } void proc_init (void) { + uint64_t fc; + #if defined(__x86_64__) irq_attach (&proc_irq_sched, NULL, SCHED_PREEMPT_TIMER); irq_attach (&proc_irq_sched, NULL, CPU_REQUEST_SCHED); @@ -338,6 +349,6 @@ void proc_init (void) { init->procgroup->capabilities |= (PROC_CAP_TERMINAL | PROC_CAP_KB); proc_register (init, thiscpu, &rctx); - spin_lock (&spin_proc->cpu->lock); - do_sched (spin_proc, &spin_proc->cpu->lock); + spin_lock (&spin_proc->cpu->lock, &fc); + do_sched (spin_proc, &spin_proc->cpu->lock, fc); } diff --git a/kernel/proc/procgroup.c b/kernel/proc/procgroup.c index c03f40c..a14c5f2 100644 --- a/kernel/proc/procgroup.c +++ b/kernel/proc/procgroup.c @@ -22,25 +22,29 @@ static struct id_alloc pgid_alloc; void procgroup_pgid_alloc_init (void) { id_alloc_init (&pgid_alloc, PGIDS_MAX); } struct procgroup* procgroup_find (int pgid) { + uint64_t fpgt; + struct procgroup* procgroup = NULL; - spin_lock (&procgroup_tree_lock); + spin_lock (&procgroup_tree_lock, &fpgt); rbtree_find (struct procgroup, &procgroup_tree, pgid, procgroup, procgroup_tree_link, pgid); - spin_unlock (&procgroup_tree_lock); + spin_unlock (&procgroup_tree_lock, fpgt); return procgroup; } uintptr_t procgroup_map (struct procgroup* procgroup, uintptr_t vaddr, size_t pages, uint32_t flags, uintptr_t* out_paddr) { - spin_lock (&procgroup->lock); + uint64_t fpg; + + spin_lock (&procgroup->lock, &fpg); vaddr = (vaddr == 0) ? procgroup->map_base : vaddr; struct proc_mapping* mapping = malloc (sizeof (*mapping)); if (mapping == NULL) { - spin_unlock (&procgroup->lock); + spin_unlock (&procgroup->lock, fpg); return 0; } @@ -48,7 +52,7 @@ uintptr_t procgroup_map (struct procgroup* procgroup, uintptr_t vaddr, size_t pa if (paddr == PMM_ALLOC_ERR) { free (mapping); - spin_unlock (&procgroup->lock); + spin_unlock (&procgroup->lock, fpg); return 0; } @@ -68,12 +72,13 @@ uintptr_t procgroup_map (struct procgroup* procgroup, uintptr_t vaddr, size_t pa mm_map_page (&procgroup->pd, ppage, vpage, flags); } - spin_unlock (&procgroup->lock); + spin_unlock (&procgroup->lock, fpg); return vaddr; } bool procgroup_unmap (struct procgroup* procgroup, uintptr_t start_vaddr, size_t pages) { + uint64_t fpg; size_t unmap_size = pages * PAGE_SIZE; uintptr_t end_vaddr = start_vaddr + unmap_size; @@ -85,7 +90,7 @@ bool procgroup_unmap (struct procgroup* procgroup, uintptr_t start_vaddr, size_t if (tail_mapping == NULL) return false; - spin_lock (&procgroup->lock); + spin_lock (&procgroup->lock, &fpg); list_foreach (procgroup->mappings, mapping_link, mapping_link_tmp) { struct proc_mapping* mapping = @@ -138,12 +143,14 @@ bool procgroup_unmap (struct procgroup* procgroup, uintptr_t start_vaddr, size_t mm_unmap_page (&procgroup->pd, vpage); } - spin_unlock (&procgroup->lock); + spin_unlock (&procgroup->lock, fpg); return true; } struct procgroup* procgroup_create (void) { + uint64_t fpgt; + struct procgroup* procgroup = malloc (sizeof (*procgroup)); if (procgroup == NULL) { return NULL; @@ -175,33 +182,37 @@ struct procgroup* procgroup_create (void) { return NULL; } - spin_lock (&procgroup_tree_lock); + spin_lock (&procgroup_tree_lock, &fpgt); rbtree_insert (struct procgroup, &procgroup_tree, &procgroup->procgroup_tree_link, procgroup_tree_link, pgid); - spin_unlock (&procgroup_tree_lock); + spin_unlock (&procgroup_tree_lock, fpgt); return procgroup; } void procgroup_attach (struct procgroup* procgroup, struct proc* proc) { - spin_lock (&procgroup->lock); - spin_lock (&proc->lock); + uint64_t fpg, fp; + + spin_lock (&procgroup->lock, &fpg); + spin_lock (&proc->lock, &fp); rbtree_insert (struct proc, &procgroup->memb_proc_tree, &proc->procgroup_memb_tree_link, procgroup_memb_tree_link, pid); - spin_unlock (&proc->lock); - spin_unlock (&procgroup->lock); + spin_unlock (&proc->lock, fp); + spin_unlock (&procgroup->lock, fpg); } static void procgroup_delete (struct procgroup* procgroup, struct reschedule_ctx* rctx) { - spin_lock (&procgroup_tree_lock); - spin_lock (&procgroup->lock); + uint64_t fpg, fpgt; + + spin_lock (&procgroup_tree_lock, &fpgt); + spin_lock (&procgroup->lock, &fpg); rbtree_delete (&procgroup_tree, &procgroup->procgroup_tree_link); - spin_unlock (&procgroup->lock); - spin_unlock (&procgroup_tree_lock); + spin_unlock (&procgroup->lock, fpg); + spin_unlock (&procgroup_tree_lock, fpgt); /* delete resources */ struct rb_node_link* rnode; @@ -239,14 +250,16 @@ static void procgroup_delete (struct procgroup* procgroup, struct reschedule_ctx void procgroup_detach (struct procgroup* procgroup, struct proc* proc, struct reschedule_ctx* rctx) { - spin_lock (&procgroup->lock); - spin_lock (&proc->lock); + uint64_t fpg, fp; + + spin_lock (&procgroup->lock, &fpg); + spin_lock (&proc->lock, &fp); rbtree_delete (&procgroup->memb_proc_tree, &proc->procgroup_memb_tree_link); struct rb_node_link* memb_tree = procgroup->memb_proc_tree; - spin_unlock (&proc->lock); - spin_unlock (&procgroup->lock); + spin_unlock (&proc->lock, fp); + spin_unlock (&procgroup->lock, fpg); if (memb_tree == NULL) { procgroup_delete (procgroup, rctx); diff --git a/kernel/proc/resource.c b/kernel/proc/resource.c index 8433d29..e97db0d 100644 --- a/kernel/proc/resource.c +++ b/kernel/proc/resource.c @@ -16,17 +16,21 @@ #include struct proc_resource* proc_find_resource (struct procgroup* procgroup, int rid) { + uint64_t fr; + struct proc_resource* resource = NULL; - spin_lock (&procgroup->lock); + spin_lock (&procgroup->lock, &fr); rbtree_find (struct proc_resource, &procgroup->resource_tree, rid, resource, resource_tree_link, rid); - spin_unlock (&procgroup->lock); + spin_unlock (&procgroup->lock, fr); return resource; } struct proc_resource* proc_create_resource_mutex (struct procgroup* procgroup) { + uint64_t fpg; + struct proc_resource* resource; resource = malloc (sizeof (*resource)); @@ -35,13 +39,13 @@ struct proc_resource* proc_create_resource_mutex (struct procgroup* procgroup) { memset (resource, 0, sizeof (*resource)); - spin_lock (&procgroup->lock); + spin_lock (&procgroup->lock, &fpg); resource->rid = id_alloc (&procgroup->rid_alloc); if (resource->rid < 0) { free (resource); - spin_unlock (&procgroup->lock); + spin_unlock (&procgroup->lock, fpg); return NULL; } @@ -53,12 +57,14 @@ struct proc_resource* proc_create_resource_mutex (struct procgroup* procgroup) { rbtree_insert (struct proc_resource, &procgroup->resource_tree, &resource->resource_tree_link, resource_tree_link, rid); - spin_unlock (&procgroup->lock); + spin_unlock (&procgroup->lock, fpg); return resource; } struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup) { + uint64_t fpg; + struct proc_resource* resource; resource = malloc (sizeof (*resource)); @@ -67,13 +73,13 @@ struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup) { memset (resource, 0, sizeof (*resource)); - spin_lock (&procgroup->lock); + spin_lock (&procgroup->lock, &fpg); resource->rid = id_alloc (&procgroup->rid_alloc); if (resource->rid < 0) { free (resource); - spin_unlock (&procgroup->lock); + spin_unlock (&procgroup->lock, fpg); return NULL; } @@ -85,28 +91,30 @@ struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup) { if (!ringbuffer_init (&resource->u.mail.ringbuffer, PROC_MAIL_MAX, sizeof (struct mail_packet))) { id_free (&procgroup->rid_alloc, resource->rid); free (resource); - spin_unlock (&procgroup->lock); + spin_unlock (&procgroup->lock, fpg); return NULL; } rbtree_insert (struct proc_resource, &procgroup->resource_tree, &resource->resource_tree_link, resource_tree_link, rid); - spin_unlock (&procgroup->lock); + spin_unlock (&procgroup->lock, fpg); return resource; } void proc_delete_resource (struct procgroup* procgroup, struct proc_resource* resource, struct reschedule_ctx* rctx) { - spin_lock (&procgroup->lock); - spin_lock (&resource->lock); + uint64_t fr, fpg; + + spin_lock (&procgroup->lock, &fpg); + spin_lock (&resource->lock, &fr); id_free (&procgroup->rid_alloc, resource->rid); rbtree_delete (&procgroup->resource_tree, &resource->resource_tree_link); - spin_unlock (&resource->lock); - spin_unlock (&procgroup->lock); + spin_unlock (&resource->lock, fr); + spin_unlock (&procgroup->lock, fpg); resource->ops.cleanup (resource, rctx); free (resource); diff --git a/kernel/proc/suspension_q.c b/kernel/proc/suspension_q.c index 86ce64d..36905fb 100644 --- a/kernel/proc/suspension_q.c +++ b/kernel/proc/suspension_q.c @@ -11,25 +11,27 @@ #include int proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock, - struct reschedule_ctx* rctx) { + uint64_t lockflags, struct reschedule_ctx* rctx) { + uint64_t fc, fp, fsq; + struct cpu* cpu = proc->cpu; struct proc_sq_entry* sq_entry = malloc (sizeof (*sq_entry)); if (!sq_entry) { if (resource_lock != NULL) - spin_unlock (resource_lock); + spin_unlock (resource_lock, lockflags); return -ST_OOM_ERROR; } sq_entry->proc = proc; sq_entry->sq = sq; - spin_lock (&cpu->lock); - spin_lock (&proc->lock); - spin_lock (&sq->lock); + spin_lock (&cpu->lock, &fc); + spin_lock (&proc->lock, &fp); + spin_lock (&sq->lock, &fsq); if (resource_lock != NULL) - spin_unlock (resource_lock); + spin_unlock (resource_lock, lockflags); proc->state = PROC_SUSPENDED; @@ -48,9 +50,9 @@ int proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_ proc->cpu = NULL; int state = proc->state; - spin_unlock (&sq->lock); - spin_unlock (&proc->lock); - spin_unlock (&cpu->lock); + spin_unlock (&sq->lock, fsq); + spin_unlock (&proc->lock, fp); + spin_unlock (&cpu->lock, fc); rctx_insert_cpu (rctx, cpu); @@ -59,12 +61,14 @@ int proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_ int proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry, struct reschedule_ctx* rctx) { + uint64_t fc, fp, fsq; + struct cpu* cpu = cpu_find_lightest (); struct proc_suspension_q* sq = sq_entry->sq; - spin_lock (&cpu->lock); - spin_lock (&proc->lock); - spin_lock (&sq->lock); + spin_lock (&cpu->lock, &fc); + spin_lock (&proc->lock, &fp); + spin_lock (&sq->lock, &fsq); /* remove from sq's list */ list_remove (sq->proc_list, &sq_entry->sq_link); @@ -82,9 +86,9 @@ int proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry, int state = proc->state; - spin_unlock (&sq->lock); - spin_unlock (&proc->lock); - spin_unlock (&cpu->lock); + spin_unlock (&sq->lock, fsq); + spin_unlock (&proc->lock, fp); + spin_unlock (&cpu->lock, fc); free (sq_entry); @@ -94,7 +98,9 @@ int proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry, } void proc_sqs_cleanup (struct proc* proc) { - spin_lock (&proc->lock); + uint64_t fsq, fp; + + spin_lock (&proc->lock, &fp); /* clean suspension queue entries */ struct list_node_link *sq_link, *sq_link_tmp; @@ -102,7 +108,7 @@ void proc_sqs_cleanup (struct proc* proc) { struct proc_sq_entry* sq_entry = list_entry (sq_link, struct proc_sq_entry, proc_link); struct proc_suspension_q* sq = sq_entry->sq; - spin_lock (&sq->lock); + spin_lock (&sq->lock, &fsq); /* remove from sq's list */ list_remove (sq->proc_list, &sq_entry->sq_link); @@ -110,10 +116,10 @@ void proc_sqs_cleanup (struct proc* proc) { /* remove from proc's list */ list_remove (proc->sq_entries, &sq_entry->proc_link); - spin_unlock (&sq->lock); + spin_unlock (&sq->lock, fsq); free (sq_entry); } - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); } diff --git a/kernel/proc/suspension_q.h b/kernel/proc/suspension_q.h index 465c0b7..e579b1f 100644 --- a/kernel/proc/suspension_q.h +++ b/kernel/proc/suspension_q.h @@ -23,7 +23,7 @@ struct proc_sq_entry { void proc_sqs_cleanup (struct proc* proc); int proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock, - struct reschedule_ctx* rctx); + uint64_t lockflags, struct reschedule_ctx* rctx); int proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry, struct reschedule_ctx* rctx); diff --git a/kernel/sync/spin_lock.c b/kernel/sync/spin_lock.c index 9889096..ca5a857 100644 --- a/kernel/sync/spin_lock.c +++ b/kernel/sync/spin_lock.c @@ -2,9 +2,13 @@ #include #include -void spin_lock (spin_lock_t* sl) { +void spin_lock (spin_lock_t* sl, uint64_t* flags) { + spin_lock_save_flags (flags); while (atomic_flag_test_and_set_explicit (sl, memory_order_acquire)) spin_lock_relax (); } -void spin_unlock (spin_lock_t* sl) { atomic_flag_clear_explicit (sl, memory_order_release); } +void spin_unlock (spin_lock_t* sl, uint64_t flags) { + atomic_flag_clear_explicit (sl, memory_order_release); + spin_lock_restore_flags (flags); +} diff --git a/kernel/sync/spin_lock.h b/kernel/sync/spin_lock.h index bafadd5..83ec155 100644 --- a/kernel/sync/spin_lock.h +++ b/kernel/sync/spin_lock.h @@ -8,7 +8,8 @@ typedef atomic_flag spin_lock_t; -void spin_lock (spin_lock_t* sl); -void spin_unlock (spin_lock_t* sl); +void spin_lock (spin_lock_t* sl, uint64_t* flags); + +void spin_unlock (spin_lock_t* sl, uint64_t flags); #endif // _KERNEL_SYNC_SPIN_LOCK_H diff --git a/kernel/sys/mm.h b/kernel/sys/mm.h index 70cfdd9..663a4bd 100644 --- a/kernel/sys/mm.h +++ b/kernel/sys/mm.h @@ -13,17 +13,25 @@ #define MM_PG_USER (1 << 2) uintptr_t mm_alloc_user_pd_phys (void); -void mm_kernel_lock (void); -void mm_kernel_unlock (void); + void mm_map_page (struct pd* pd, uintptr_t paddr, uintptr_t vaddr, uint32_t flags); + void mm_map_kernel_page (uintptr_t paddr, uintptr_t vaddr, uint32_t flags); + void mm_unmap_page (struct pd* pd, uintptr_t vaddr); + void mm_unmap_kernel_page (uintptr_t vaddr); + bool mm_validate (struct pd* pd, uintptr_t vaddr); + bool mm_validate_buffer (struct pd* pd, uintptr_t vaddr, size_t size); + uintptr_t mm_p2v (struct pd* pd, uintptr_t paddr); + uintptr_t mm_v2p (struct pd* pd, uintptr_t vaddr); + struct pd* mm_get_kernel_pd (void); + void mm_init (void); #endif // _KERNEL_SYS_MM_H diff --git a/kernel/sys/sched.h b/kernel/sys/sched.h index 09bb475..2de757a 100644 --- a/kernel/sys/sched.h +++ b/kernel/sys/sched.h @@ -4,6 +4,6 @@ #include #include -void do_sched (struct proc* proc, spin_lock_t* cpu_lock); +void do_sched (struct proc* proc, spin_lock_t* cpu_lock, uint64_t lockflags); #endif // _KERNEL_SYS_SCHED_H diff --git a/kernel/sys/spin_lock.h b/kernel/sys/spin_lock.h index 902d57a..a83e84e 100644 --- a/kernel/sys/spin_lock.h +++ b/kernel/sys/spin_lock.h @@ -5,4 +5,8 @@ void spin_lock_relax (void); +void spin_lock_save_flags (uint64_t* flags); + +void spin_lock_restore_flags (uint64_t flags); + #endif // _KERNEL_SYS_SPIN_LOCK_H diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 295ad0d..468f8cf 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -31,18 +31,20 @@ #define SYSRESULT(x) ((uintptr_t)(x)) static void* sys_get_user_buffer (struct proc* proc, uintptr_t uvaddr, size_t size) { + uint64_t fpg; + struct limine_hhdm_response* hhdm = limine_hhdm_request.response; - spin_lock (&proc->procgroup->lock); + spin_lock (&proc->procgroup->lock, &fpg); if (!mm_validate_buffer (&proc->procgroup->pd, (uintptr_t)uvaddr, size)) { - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); return NULL; } uintptr_t out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr); - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); uintptr_t out_kvaddr = (uintptr_t)hhdm->offset + out_paddr; @@ -107,9 +109,11 @@ DEFINE_SYSCALL (sys_clone) { /* void* argument_ptr (void) */ DEFINE_SYSCALL (sys_argument_ptr) { - spin_lock (&proc->lock); + uint64_t fp; + + spin_lock (&proc->lock, &fp); uintptr_t p = proc->uvaddr_argument; - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); return p; } @@ -122,14 +126,16 @@ DEFINE_SYSCALL (sys_sched) { /* int mutex_create (void) */ DEFINE_SYSCALL (sys_mutex_create) { + uint64_t fr; + struct proc_resource* mutex_resource = proc_create_resource_mutex (proc->procgroup); if (mutex_resource == NULL) return SYSRESULT (-ST_OOM_ERROR); - spin_lock (&mutex_resource->lock); + spin_lock (&mutex_resource->lock, &fr); int rid = mutex_resource->rid; - spin_unlock (&mutex_resource->lock); + spin_unlock (&mutex_resource->lock, fr); return SYSRESULT (rid); } @@ -224,6 +230,8 @@ DEFINE_SYSCALL (sys_mail_receive) { /* int device_do (int device_id, int cmd, void* a1, void* a2, void* a3, void* a4) */ DEFINE_SYSCALL (sys_device_do) { + uint64_t fpg, fd; + struct limine_hhdm_response* hhdm = limine_hhdm_request.response; uintptr_t uvaddr_key = a1; @@ -237,12 +245,12 @@ DEFINE_SYSCALL (sys_device_do) { if (!(cmd >= 0 && cmd < (int)fieldlengthof (struct device, ops))) return SYSRESULT (-ST_BAD_DEVICE_OP); - spin_lock (&proc->procgroup->lock); + spin_lock (&proc->procgroup->lock, &fpg); out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_key); if (out_paddr == 0) { - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); return SYSRESULT (-ST_BAD_ADDRESS_SPACE); } @@ -264,29 +272,31 @@ DEFINE_SYSCALL (sys_device_do) { if (out_paddr != 0) ka4 = (uintptr_t)hhdm->offset + out_paddr; - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); struct device* device = device_find (key); if (device == NULL) return SYSRESULT (-ST_NOT_FOUND); - spin_lock (&device->lock); + spin_lock (&device->lock, &fd); if (device->ops[cmd] == NULL) { - spin_unlock (&device->lock); + spin_unlock (&device->lock, fd); return SYSRESULT (-ST_NOT_FOUND); } int ret = device_op (device, cmd, proc, rctx, ka1, ka2, ka3, ka4); - spin_unlock (&device->lock); + spin_unlock (&device->lock, fd); return SYSRESULT (ret); } /* int exec (char* volume, char* path) */ DEFINE_SYSCALL (sys_exec) { + uint64_t fpg; + uintptr_t uvaddr_volume = a1; uintptr_t uvaddr_path = a2; @@ -294,18 +304,18 @@ DEFINE_SYSCALL (sys_exec) { uintptr_t out_paddr; - spin_lock (&proc->procgroup->lock); + spin_lock (&proc->procgroup->lock, &fpg); out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_path); - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); if (out_paddr == 0) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); const char* path = (const char*)((uintptr_t)hhdm->offset + out_paddr); - spin_lock (&proc->procgroup->lock); + spin_lock (&proc->procgroup->lock, &fpg); out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_volume); - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); if (out_paddr == 0) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); @@ -327,15 +337,17 @@ DEFINE_SYSCALL (sys_exec) { /* int volume_open (char* volume) */ DEFINE_SYSCALL (sys_volume_open) { + uint64_t fpg, fp; + uintptr_t uvaddr_volume = a1; struct limine_hhdm_response* hhdm = limine_hhdm_request.response; uintptr_t out_paddr; - spin_lock (&proc->procgroup->lock); + spin_lock (&proc->procgroup->lock, &fpg); out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_volume); - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); if (out_paddr == 0) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); @@ -347,26 +359,28 @@ DEFINE_SYSCALL (sys_volume_open) { if (ret < 0) return SYSRESULT (ret); - spin_lock (&proc->lock); + spin_lock (&proc->lock, &fp); strncpy (proc->cwv, volume, VOLUME_MAX); - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); return SYSRESULT (ST_OK); } /* int volume_close (void) */ DEFINE_SYSCALL (sys_volume_close) { + uint64_t fp; + char cwv[VOLUME_MAX]; - spin_lock (&proc->lock); + spin_lock (&proc->lock, &fp); memcpy (cwv, proc->cwv, sizeof (proc->cwv)); - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); int ret = vfs_volume_close (proc, cwv, rctx); if (ret == ST_OK) { - spin_lock (&proc->lock); + spin_lock (&proc->lock, &fp); memset (proc->cwv, 0, sizeof (proc->cwv)); - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); } return SYSRESULT (ret); @@ -374,6 +388,8 @@ DEFINE_SYSCALL (sys_volume_close) { /* int read_file (char* path, size_t off, uint8_t* buffer, size_t size) */ DEFINE_SYSCALL (sys_read_file) { + uint64_t fpg, fp; + uintptr_t uvaddr_path = a1; size_t off = (size_t)a2; uintptr_t uvaddr_buffer = a3; @@ -383,9 +399,9 @@ DEFINE_SYSCALL (sys_read_file) { uintptr_t out_paddr; - spin_lock (&proc->procgroup->lock); + spin_lock (&proc->procgroup->lock, &fpg); out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_path); - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); if (out_paddr == 0) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); @@ -398,9 +414,9 @@ DEFINE_SYSCALL (sys_read_file) { return SYSRESULT (-ST_BAD_ADDRESS_SPACE); char cwv[VOLUME_MAX]; - spin_lock (&proc->lock); + spin_lock (&proc->lock, &fp); memcpy (cwv, proc->cwv, sizeof (proc->cwv)); - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); int ret = vfs_read_file (proc, rctx, cwv, path, buffer, off, size); @@ -409,6 +425,8 @@ DEFINE_SYSCALL (sys_read_file) { /* int describe (char* path, struct desc* desc) */ DEFINE_SYSCALL (sys_describe) { + uint64_t fpg, fp; + uintptr_t uvaddr_path = a1; uintptr_t uvaddr_desc = a2; @@ -416,9 +434,9 @@ DEFINE_SYSCALL (sys_describe) { uintptr_t out_paddr; - spin_lock (&proc->procgroup->lock); + spin_lock (&proc->procgroup->lock, &fpg); out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_path); - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); if (out_paddr == 0) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); @@ -429,11 +447,11 @@ DEFINE_SYSCALL (sys_describe) { if (desc == NULL) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); - + char cwv[VOLUME_MAX]; - spin_lock (&proc->lock); + spin_lock (&proc->lock, &fp); memcpy (cwv, proc->cwv, sizeof (proc->cwv)); - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); int ret = vfs_describe (proc, rctx, cwv, path, desc); @@ -442,6 +460,8 @@ DEFINE_SYSCALL (sys_describe) { /* int get_procgroup (int pid) */ DEFINE_SYSCALL (sys_get_procgroup) { + uint64_t fp; + int pid = (int)a1; struct proc* target_proc = proc_find_pid (pid); @@ -449,22 +469,24 @@ DEFINE_SYSCALL (sys_get_procgroup) { if (target_proc == NULL) return SYSRESULT (-ST_NOT_FOUND); - spin_lock (&target_proc->lock); + spin_lock (&target_proc->lock, &fp); if (target_proc->state == PROC_DEAD) { - spin_unlock (&target_proc->lock); + spin_unlock (&target_proc->lock, fp); return SYSRESULT (-ST_NOT_FOUND); } int pgid = target_proc->procgroup->pgid; - spin_unlock (&target_proc->lock); + spin_unlock (&target_proc->lock, fp); return SYSRESULT (pgid); } /* int read_dir_entry (char* path, struct dir_entry* entry, size_t entry_num) */ DEFINE_SYSCALL (sys_read_dir_entry) { + uint64_t fpg, fp; + uintptr_t uvaddr_path = a1; uintptr_t uvaddr_entry = a2; size_t entry_num = (size_t)a3; @@ -473,9 +495,9 @@ DEFINE_SYSCALL (sys_read_dir_entry) { uintptr_t out_paddr; - spin_lock (&proc->procgroup->lock); + spin_lock (&proc->procgroup->lock, &fpg); out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_path); - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); if (out_paddr == 0) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); @@ -486,11 +508,11 @@ DEFINE_SYSCALL (sys_read_dir_entry) { if (entry == NULL) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); - + char cwv[VOLUME_MAX]; - spin_lock (&proc->lock); + spin_lock (&proc->lock, &fp); memcpy (cwv, proc->cwv, sizeof (proc->cwv)); - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); int ret = vfs_read_dir_entry (proc, rctx, cwv, path, entry, entry_num); @@ -499,25 +521,27 @@ DEFINE_SYSCALL (sys_read_dir_entry) { /* int create_file (char* path) */ DEFINE_SYSCALL (sys_create_file) { + uint64_t fpg, fp; + uintptr_t uvaddr_path = a1; struct limine_hhdm_response* hhdm = limine_hhdm_request.response; uintptr_t out_paddr; - spin_lock (&proc->procgroup->lock); + spin_lock (&proc->procgroup->lock, &fpg); out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_path); - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); if (out_paddr == 0) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); const char* path = (const char*)((uintptr_t)hhdm->offset + out_paddr); - + char cwv[VOLUME_MAX]; - spin_lock (&proc->lock); + spin_lock (&proc->lock, &fp); memcpy (cwv, proc->cwv, sizeof (proc->cwv)); - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); int ret = vfs_create_file (proc, rctx, cwv, path); @@ -526,6 +550,8 @@ DEFINE_SYSCALL (sys_create_file) { /* int write_file (char* path, size_t off, uint8_t* buffer, size_t size, uint32_t flags) */ DEFINE_SYSCALL (sys_write_file) { + uint64_t fpg, fp; + uintptr_t uvaddr_path = a1; size_t off = (size_t)a2; uintptr_t uvaddr_buffer = a3; @@ -536,9 +562,9 @@ DEFINE_SYSCALL (sys_write_file) { uintptr_t out_paddr; - spin_lock (&proc->procgroup->lock); + spin_lock (&proc->procgroup->lock, &fpg); out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_path); - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); if (out_paddr == 0) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); @@ -549,11 +575,11 @@ DEFINE_SYSCALL (sys_write_file) { if (buffer == NULL) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); - + char cwv[VOLUME_MAX]; - spin_lock (&proc->lock); + spin_lock (&proc->lock, &fp); memcpy (cwv, proc->cwv, sizeof (proc->cwv)); - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); int ret = vfs_write_file (proc, rctx, cwv, path, buffer, off, size, flags); @@ -562,15 +588,19 @@ DEFINE_SYSCALL (sys_write_file) { /* int get_exec_pid (void) */ DEFINE_SYSCALL (sys_get_exec_pid) { - spin_lock (&proc->lock); + uint64_t fp; + + spin_lock (&proc->lock, &fp); int exec_pid = proc->exec_pid; - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); return SYSRESULT (exec_pid); } /* wait_for_pid (int pid) */ DEFINE_SYSCALL (sys_wait_for_pid) { + uint64_t fp; + int pid = (int)a1; struct proc* wait_proc = proc_find_pid (pid); @@ -578,14 +608,14 @@ DEFINE_SYSCALL (sys_wait_for_pid) { if (wait_proc == NULL) return SYSRESULT (-ST_NOT_FOUND); - spin_lock (&wait_proc->lock); + spin_lock (&wait_proc->lock, &fp); if (wait_proc->state == PROC_DEAD) { - spin_unlock (&wait_proc->lock); + spin_unlock (&wait_proc->lock, fp); return SYSRESULT (-ST_NOT_FOUND); } - spin_unlock (&wait_proc->lock); + spin_unlock (&wait_proc->lock, fp); proc_wait_for (proc, rctx, wait_proc); @@ -595,6 +625,8 @@ DEFINE_SYSCALL (sys_wait_for_pid) { /* int kill (int pid) */ DEFINE_SYSCALL (sys_kill) { + uint64_t fp; + int pid = (int)a1; struct proc* target_proc = proc_find_pid (pid); @@ -602,14 +634,14 @@ DEFINE_SYSCALL (sys_kill) { if (target_proc == NULL) return SYSRESULT (-ST_NOT_FOUND); - spin_lock (&target_proc->lock); + spin_lock (&target_proc->lock, &fp); if (target_proc->state == PROC_DEAD) { - spin_unlock (&target_proc->lock); + spin_unlock (&target_proc->lock, fp); return SYSRESULT (-ST_NOT_FOUND); } - spin_unlock (&target_proc->lock); + spin_unlock (&target_proc->lock, fp); proc_kill (target_proc, rctx); @@ -618,25 +650,27 @@ DEFINE_SYSCALL (sys_kill) { /* int create_dir (char* path) */ DEFINE_SYSCALL (sys_create_dir) { + uint64_t fpg, fp; + uintptr_t uvaddr_path = a1; struct limine_hhdm_response* hhdm = limine_hhdm_request.response; uintptr_t out_paddr; - spin_lock (&proc->procgroup->lock); + spin_lock (&proc->procgroup->lock, &fpg); out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_path); - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); if (out_paddr == 0) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); const char* path = (const char*)((uintptr_t)hhdm->offset + out_paddr); - + char cwv[VOLUME_MAX]; - spin_lock (&proc->lock); + spin_lock (&proc->lock, &fp); memcpy (cwv, proc->cwv, sizeof (proc->cwv)); - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); int ret = vfs_create_dir (proc, rctx, cwv, path); @@ -645,25 +679,27 @@ DEFINE_SYSCALL (sys_create_dir) { /* int remove (char* path) */ DEFINE_SYSCALL (sys_remove) { + uint64_t fpg, fp; + uintptr_t uvaddr_path = a1; struct limine_hhdm_response* hhdm = limine_hhdm_request.response; uintptr_t out_paddr; - spin_lock (&proc->procgroup->lock); + spin_lock (&proc->procgroup->lock, &fpg); out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_path); - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); if (out_paddr == 0) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); const char* path = (const char*)((uintptr_t)hhdm->offset + out_paddr); - + char cwv[VOLUME_MAX]; - spin_lock (&proc->lock); + spin_lock (&proc->lock, &fp); memcpy (cwv, proc->cwv, sizeof (proc->cwv)); - spin_unlock (&proc->lock); + spin_unlock (&proc->lock, fp); int ret = vfs_remove (proc, rctx, cwv, path); @@ -672,6 +708,8 @@ DEFINE_SYSCALL (sys_remove) { /* int create_volume (char* key, int fs_type, char* device_key) */ DEFINE_SYSCALL (sys_create_volume) { + uint64_t fpg; + uintptr_t uvaddr_key = a1; int type = (int)a2; uintptr_t uvaddr_device_key = a3; @@ -680,12 +718,12 @@ DEFINE_SYSCALL (sys_create_volume) { uintptr_t out_paddr; - spin_lock (&proc->procgroup->lock); + spin_lock (&proc->procgroup->lock, &fpg); out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_key); if (out_paddr == 0) { - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); return SYSRESULT (-ST_BAD_ADDRESS_SPACE); } @@ -694,13 +732,13 @@ DEFINE_SYSCALL (sys_create_volume) { out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_device_key); if (out_paddr == 0) { - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); return SYSRESULT (-ST_BAD_ADDRESS_SPACE); } const char* device_key = (const char*)((uintptr_t)hhdm->offset + out_paddr); - spin_unlock (&proc->procgroup->lock); + spin_unlock (&proc->procgroup->lock, fpg); struct device* device = device_find (device_key); diff --git a/make/lz4.mk b/make/lz4.mk index 1b08401..828dbc1 100644 --- a/make/lz4.mk +++ b/make/lz4.mk @@ -1,2 +1,2 @@ all_lz4: - make -C lz4 -j1 allmost + if [ ! -e ./lz4/lz4 ]; then make -C lz4 -j1 allmost; fi