diff --git a/arch/x86/apic.c b/arch/x86/apic.c index e50f3beb..9ff8c97b 100644 --- a/arch/x86/apic.c +++ b/arch/x86/apic.c @@ -115,7 +115,9 @@ void init_apic(unsigned int cpu_id, apic_mode_t mode) { apic_spiv_t spiv; cpu_t *cpu; - BUG_ON(mode < APIC_MODE_DISABLED); + BUG_ON(mode == APIC_MODE_UNKNOWN); + if (mode <= APIC_MODE_DISABLED) + return; apic_base.reg = rdmsr(MSR_APIC_BASE); @@ -162,7 +164,7 @@ void init_apic(unsigned int cpu_id, apic_mode_t mode) { vmap_4k(apic_get_base(apic_base), apic_base.base, L1_PROT_NOCACHE); spiv.reg = apic_read(APIC_SPIV); - spiv.vector = 0xFF; + spiv.vector = APIC_SPI_VECTOR; spiv.apic_enable = 1; apic_write(APIC_SPIV, spiv.reg); } diff --git a/arch/x86/boot/multiboot.c b/arch/x86/boot/multiboot.c index f1c245ea..2a727d78 100644 --- a/arch/x86/boot/multiboot.c +++ b/arch/x86/boot/multiboot.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -227,23 +228,12 @@ int mbi_get_avail_memory_range(unsigned index, addr_range_t *r) { } if (multiboot_mmap_num == 0) { - if (index == 0) { - BUG_ON(multiboot_mem_lower == 0); - - r->start = 0x0; - r->end = _ptr(multiboot_mem_lower); - return 0; - } - else if (index == 1) { - BUG_ON(multiboot_mem_upper == 0); - - r->start = _ptr(MB(1)); - r->end = r->start + (multiboot_mem_upper); - return 0; - } + r->start = _ptr(index == 0 ? 0x0 : MB(1)); + r->end = r->start + (index == 0 ? multiboot_mem_lower : multiboot_mem_upper); + return r->end > r->start ? 0 : -ENOENT; } - return -1; + return -ENOMEM; } int mbi_get_memory_range(paddr_t pa, addr_range_t *r) { @@ -260,16 +250,12 @@ int mbi_get_memory_range(paddr_t pa, addr_range_t *r) { } if (multiboot_mmap_num == 0) { - BUG_ON(multiboot_mem_lower == 0); - _start = 0x0; _end = multiboot_mem_lower; if (pa < _end) goto found; - BUG_ON(multiboot_mem_upper == 0); - _start = MB(1); _end = _start + multiboot_mem_upper; @@ -277,7 +263,7 @@ int mbi_get_memory_range(paddr_t pa, addr_range_t *r) { goto found; } - return -1; + return -ENOMEM; found: if (r) { diff --git a/arch/x86/entry.S b/arch/x86/entry.S index 5432716b..f3a6d368 100644 --- a/arch/x86/entry.S +++ b/arch/x86/entry.S @@ -115,6 +115,10 @@ ENTRY(asm_interrupt_handler_\sym) END_FUNC(asm_interrupt_handler_\sym) .endm +ENTRY(asm_interrupt_handler_dummy) + IRET +END_FUNC(asm_interrupt_handler_dummy) + ENTRY(handle_exception) SAVE_ALL_REGS diff --git a/arch/x86/traps.c b/arch/x86/traps.c index a44d2609..bd76b384 100644 --- a/arch/x86/traps.c +++ b/arch/x86/traps.c @@ -43,6 +43,7 @@ extern void asm_interrupt_handler_uart1(void); extern void asm_interrupt_handler_uart2(void); extern void asm_interrupt_handler_keyboard(void); extern void asm_interrupt_handler_timer(void); +extern void asm_interrupt_handler_dummy(void); extern void terminate_user_task(void); @@ -112,6 +113,7 @@ static void init_gdt(percpu_t *percpu) { barrier(); lgdt(&percpu->gdt_ptr); + write_ss(__KERN_DS); write_gs(GDT_PERCPU << 3); wrmsr(MSR_KERNEL_GS_BASE, 0x0); @@ -164,6 +166,8 @@ void init_traps(const cpu_t *cpu) { _ul(asm_interrupt_handler_keyboard), GATE_DPL0, GATE_PRESENT, 0); set_intr_gate(&percpu->idt[APIC_TIMER_IRQ], __KERN_CS, _ul(asm_interrupt_handler_timer), GATE_DPL0, GATE_PRESENT, 0); + set_intr_gate(&percpu->idt[APIC_SPI_VECTOR], __KERN_CS, + _ul(asm_interrupt_handler_dummy), GATE_DPL0, GATE_PRESENT, 0); barrier(); lidt(&percpu->idt_ptr); diff --git a/common/usermode.c b/common/usermode.c index 8a0d311e..af16f035 100644 --- a/common/usermode.c +++ b/common/usermode.c @@ -22,6 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include @@ -51,9 +52,11 @@ long syscall_handler(long syscall_nr, long arg1, long arg2, long arg3, long arg4 frame_t *frame; frame = get_free_frames(order); + if (!frame) + return -ENOMEM; + if (!va) va = mfn_to_virt_user(frame->mfn); - va = vmap_user(va, frame->mfn, order, L4_PROT_USER, L3_PROT_USER, L2_PROT_USER, L1_PROT_USER); return _ul(va); diff --git a/drivers/pic.c b/drivers/pic.c index 2419c0f6..781f4f6d 100644 --- a/drivers/pic.c +++ b/drivers/pic.c @@ -53,18 +53,20 @@ void init_pic(void) { outb(PIC2_PORT_DATA, 0xFF); } -void pic_enable_irq(pic_device_sel_t pic, uint8_t irq) { +static void pic_toggle_irq(pic_device_sel_t pic, uint8_t irq, bool enable) { BUG_ON((pic != PIC1_DEVICE_SEL && pic != PIC2_DEVICE_SEL) || irq >= PIC_IRQ_MAX); + uint8_t port = (pic == PIC1_DEVICE_SEL ? PIC1_PORT_DATA : PIC2_PORT_DATA); + uint8_t mask = 1 << irq; uint8_t unmasked_irqs = inb(port); - outb(port, (~(1 << irq)) & unmasked_irqs); + outb(port, enable ? (~mask & unmasked_irqs) : (mask | unmasked_irqs)); } -void pic_disable_irq(pic_device_sel_t pic, uint8_t irq) { - BUG_ON((pic != PIC1_DEVICE_SEL && pic != PIC2_DEVICE_SEL) || irq >= PIC_IRQ_MAX); - uint8_t port = (pic == PIC1_DEVICE_SEL ? PIC1_PORT_DATA : PIC2_PORT_DATA); - uint8_t unmasked_irqs = inb(port); +void pic_enable_irq(pic_device_sel_t pic, uint8_t irq) { + pic_toggle_irq(pic, irq, true); +} - outb(port, (1 << irq) | unmasked_irqs); +void pic_disable_irq(pic_device_sel_t pic, uint8_t irq) { + pic_toggle_irq(pic, irq, false); } diff --git a/include/arch/x86/pagetable.h b/include/arch/x86/pagetable.h index b67ab009..f30de58a 100644 --- a/include/arch/x86/pagetable.h +++ b/include/arch/x86/pagetable.h @@ -269,6 +269,16 @@ static inline pdpe_t *get_pdpe(const void *va) { return (pdpe_t *) &(l3e->entry); } +/* Return the virtual address of the PML4 entry mapping this virtual address + * in the page tables specified by a CR3 pointer. + * The entry is assumed to be mapped + */ +static inline pml4_t *get_pml4(cr3_t *cr3_ptr, const void *va) { + pml4_t *l4t = mfn_to_virt_kern(cr3_ptr->mfn); + pml4_t *l4e = l4_table_entry(l4t, va); + return (pml4_t *) &(l4e->entry); +} + static inline void set_pgentry(pgentry_t *e, mfn_t mfn, unsigned long flags) { *e = pgentry_from_mfn(mfn, flags); barrier(); diff --git a/include/arch/x86/traps.h b/include/arch/x86/traps.h index 431b0604..604212ca 100644 --- a/include/arch/x86/traps.h +++ b/include/arch/x86/traps.h @@ -48,6 +48,8 @@ #define KB_PORT2_IRQ KEYBOARD_PORT2_IRQ_VECTOR #define APIC_TIMER_IRQ APIC_TIMER_IRQ_VECTOR +#define APIC_SPI_VECTOR 0xFF + extern void init_traps(const cpu_t *cpu); extern void init_boot_traps(void); extern void init_rmode_traps(void); diff --git a/include/lib.h b/include/lib.h index bce6f233..d4bef3d8 100644 --- a/include/lib.h +++ b/include/lib.h @@ -239,6 +239,10 @@ static inline unsigned long read_gs(void) { return gs; } +static inline void write_ss(unsigned long ss) { + asm volatile("mov %0, %%ss" ::"r"(ss)); +} + static inline void write_gs(unsigned long gs) { asm volatile("mov %0, %%gs" ::"r"(gs)); } diff --git a/include/mm/regions.h b/include/mm/regions.h index 65930a69..114758e3 100644 --- a/include/mm/regions.h +++ b/include/mm/regions.h @@ -85,9 +85,7 @@ extern unsigned regions_num; extern void display_memory_map(void); -extern addr_range_t get_memory_range(paddr_t pa); -extern paddr_t get_memory_range_start(paddr_t pa); -extern paddr_t get_memory_range_end(paddr_t pa); +extern int get_memory_range(paddr_t pa, addr_range_t *r); extern int get_avail_memory_range(unsigned index, addr_range_t *r); extern bool has_memory_range(paddr_t pa); @@ -130,6 +128,7 @@ static inline bool in_kernel_section(const void *addr) { (addr >= _ptr(__start_data) && addr < _ptr(__end_data)) || (addr >= _ptr(__start_bss) && addr < _ptr(__end_bss)) || (addr >= _ptr(__start_rodata) && addr < _ptr(__end_rodata)) || + (addr >= _ptr(__start_extables) && addr < _ptr(__end_extables)) || (addr >= _ptr(__start_symbols) && addr < _ptr(__end_symbols)); } diff --git a/include/mm/slab.h b/include/mm/slab.h index 2dc25f3e..bbe51059 100644 --- a/include/mm/slab.h +++ b/include/mm/slab.h @@ -92,26 +92,9 @@ struct meta_slab { typedef struct meta_slab meta_slab_t; -static inline void increment_slab_allocs(meta_slab_t *slab) { - BUG_ON(slab == NULL); - BUG_ON((slab->slab_allocs >= (slab->slab_len / slab->slab_size))); +/* External declarations */ - slab->slab_allocs++; -} - -static inline void decrement_slab_allocs(meta_slab_t *slab) { - BUG_ON(slab == NULL); - BUG_ON((slab->slab_allocs == 0)); - - slab->slab_allocs--; -} - -static inline bool slab_is_empty(meta_slab_t *slab) { - BUG_ON(slab == NULL); - return (slab->slab_allocs == 0); -} - -int init_slab(void); +extern int init_slab(void); extern void *kmalloc(size_t size); extern void *kzalloc(size_t size); extern void kfree(void *ptr); diff --git a/mm/regions.c b/mm/regions.c index 4dbbf356..3cbac2a5 100644 --- a/mm/regions.c +++ b/mm/regions.c @@ -23,6 +23,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include +#include #include #include @@ -79,27 +80,12 @@ void display_memory_map(void) { } } -addr_range_t get_memory_range(paddr_t pa) { - addr_range_t r; +int get_memory_range(paddr_t pa, addr_range_t *r) { + memset(r, 0, sizeof(*r)); - memset(&r, 0, sizeof(r)); - if (mbi_get_memory_range(pa, &r) < 0) - /* FIXME: e820_lower_memory_bound() */ - panic("Unable to get memory range for: 0x%016lx", pa); - - return r; -} - -paddr_t get_memory_range_start(paddr_t pa) { - addr_range_t r = get_memory_range(pa); - - return _paddr(r.start); -} - -paddr_t get_memory_range_end(paddr_t pa) { - addr_range_t r = get_memory_range(pa); - - return _paddr(r.end); + if (mbi_get_memory_range(pa, r) < 0) + return -ENOENT; + return 0; } int get_avail_memory_range(unsigned index, addr_range_t *r) { diff --git a/mm/slab.c b/mm/slab.c index e85925ea..ba391c14 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -88,7 +88,7 @@ static int initialize_slab(meta_slab_t *slab) { static void *slab_alloc(meta_slab_t *slab) { slab_t *next_free = NULL; - if (NULL == slab) { + if (!slab) { dprintk("failed, NULL slab param\n"); return NULL; } @@ -99,7 +99,9 @@ static void *slab_alloc(meta_slab_t *slab) { /* TODO: Below should be done in thread-safe manner */ next_free = list_first_entry(&slab->slab_head, slab_t, list); list_unlink(&next_free->list); - increment_slab_allocs(slab); + + BUG_ON(slab->slab_allocs >= (slab->slab_len / slab->slab_size)); + slab->slab_allocs++; return next_free; } @@ -113,7 +115,9 @@ static void slab_free(meta_slab_t *slab, void *ptr) { new_slab = (slab_t *) ptr; /* TODO: eventually below should be done in thread-safe manner */ list_add_tail(&new_slab->list, &slab->slab_head); - decrement_slab_allocs(slab); + + BUG_ON(slab->slab_allocs == 0); + slab->slab_allocs--; } meta_slab_t *slab_meta_alloc() { @@ -271,6 +275,10 @@ void *kzalloc(size_t size) { return ptr; } +static inline bool slab_is_empty(meta_slab_t *slab) { + return slab->slab_allocs == 0; +} + /* * Loop through all the orders and check where does this memory belong * Then link it back into free list. Not a O(1) of implementation but we're looking for @@ -285,6 +293,7 @@ static void ktf_free(void *ptr) { for (alloc_order = SLAB_ORDER_16; alloc_order < SLAB_ORDER_MAX; alloc_order++) { /* Go through list of meta_slab_t and try to allocate a free slab */ list_for_each_entry (slab, &meta_slab_list[alloc_order], list) { + BUG_ON(!slab); if ((_ul(ptr) >= (_ul(slab->slab_base))) && (_ul(ptr) < (_ul(slab->slab_base) + _ul(slab->slab_len)))) { slab_free(slab, ptr); diff --git a/smp/mptables.c b/smp/mptables.c index 1d44ad8e..65ac1bcd 100644 --- a/smp/mptables.c +++ b/smp/mptables.c @@ -84,7 +84,11 @@ static mpf_t *get_mpf_addr(void) { if (ptr) return ptr; - sysm_addr = kmap_4k(paddr_to_mfn(get_memory_range_end(KB(512)) - KB(1)), L1_PROT_RO); + addr_range_t range; + if (get_memory_range(KB(512), &range) < 0) + return NULL; + + sysm_addr = kmap_4k(paddr_to_mfn(_paddr(range.end) - KB(1)), L1_PROT_RO); ptr = find_mpf(sysm_addr, sysm_addr + KB(1)); if (ptr) return ptr; diff --git a/smp/smp.c b/smp/smp.c index 7cd96643..fc0ef959 100644 --- a/smp/smp.c +++ b/smp/smp.c @@ -60,6 +60,7 @@ void __noreturn ap_startup(void) { smp_wmb(); init_timers(cpu); + sti(); if (opt_fpu) enable_fpu();