1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

create for each task an interrupt stack table (IST1)

Currently, "user-level" code has to deactivate the red zone support.
To avoid this, we create an interrupt stack table (IST1), which is
the default stack for all interrupts. Consequently, the common stack
isn't touch by handling any interrupt and the red-zone could be used
for compiler optimizations.

By using IST1, nested interrupts (beside NMI) arn't longer supported.
But HermitCores doesn't rely on this support.
This commit is contained in:
Stefan Lankes 2016-06-03 06:24:46 +02:00
parent b17b74fe49
commit a2b36849d9
13 changed files with 161 additions and 114 deletions

View file

@ -54,10 +54,10 @@ ifdef PROFILING
PROFILING_CFLAGS += -DXRAY_ANNOTATE
endif
CFLAGS_FOR_NEWLIB = -m64 -mtls-direct-seg-refs -mno-red-zone -O3 -march=native -mtune=native -ftree-vectorize $(STACKPROT)
FCFLAGS_FOR_NEWLIB = -m64 -mtls-direct-seg-refs -mno-red-zone -O3 -march=native -mtune=native -ftree-vectorize
FFLAGS_FOR_NEWLIB = -m64 -mtls-direct-seg-refs -mno-red-zone -O3 -march=native -mtune=native -ftree-vectorize
CXXFLAGS_FOR_NEWLIB = -m64 -mtls-direct-seg-refs -mno-red-zone -O3 -march=native -mtune=native -ftree-vectorize
CFLAGS_FOR_NEWLIB = -m64 -mtls-direct-seg-refs -O3 -march=native -mtune=native -ftree-vectorize #$(STACKPROT)
FCFLAGS_FOR_NEWLIB = -m64 -mtls-direct-seg-refs -O3 -march=native -mtune=native -ftree-vectorize
FFLAGS_FOR_NEWLIB = -m64 -mtls-direct-seg-refs -O3 -march=native -mtune=native -ftree-vectorize
CXXFLAGS_FOR_NEWLIB = -m64 -mtls-direct-seg-refs -O3 -march=native -mtune=native -ftree-vectorize
LDFLAGS_FOR_NEWLIB =
NASMFLAGS_FOR_NEWLIB = -felf64
CFLAGS_FOR_TOOLS = -O2 -Wall

View file

@ -59,9 +59,9 @@ typedef struct {
uint16_t res6, bitmap;
} __attribute__ ((packed)) tss_t;
/** @brief Set rsp0 in TSS of the current core
/** @brief Set rsp0 & ist1 in TSS of the current core
*/
void tss_set_rsp0(size_t ptr);
void set_tss(size_t rsp0, size_t ist1);
#ifdef __cplusplus
}

View file

@ -646,6 +646,9 @@ align 4096
global boot_stack
boot_stack:
TIMES (MAX_CORES*KERNEL_STACK_SIZE) DB 0xcd
global boot_ist
boot_ist:
TIMES KERNEL_STACK_SIZE DB 0xcd
; add some hints to the ELF file
SECTION .note.GNU-stack noalloc noexec nowrite progbits

View file

@ -35,11 +35,13 @@
#include <asm/tss.h>
#include <asm/page.h>
#define MAX_IST 3
gdt_ptr_t gp;
// currently, our kernel has full access to the ioports
static gdt_entry_t gdt[GDT_ENTRIES] = {[0 ... GDT_ENTRIES-1] = {0, 0, 0, 0, 0, 0}};
static tss_t task_state_segments[MAX_CORES] __attribute__ ((aligned (PAGE_SIZE)));
static uint8_t stack_table[MAX_CORES*KERNEL_STACK_SIZE*3];
static uint8_t stack_table[MAX_CORES*KERNEL_STACK_SIZE*MAX_IST] __attribute__ ((aligned (PAGE_SIZE)));
extern const void boot_stack;
@ -51,9 +53,10 @@ extern void gdt_flush(void);
extern const void boot_stack;
void tss_set_rsp0(size_t stptr)
void set_tss(size_t rps0, size_t ist1)
{
task_state_segments[CORE_ID].rsp0 = stptr;
task_state_segments[CORE_ID].rsp0 = rps0;
task_state_segments[CORE_ID].ist1 = ist1;
}
/* Setup a descriptor in the Global Descriptor Table */
@ -145,9 +148,10 @@ void gdt_install(void)
*/
for(i=0; i<MAX_CORES; i++) {
task_state_segments[i].rsp0 = (size_t)&boot_stack + (i+1) * KERNEL_STACK_SIZE - 0x10;
task_state_segments[i].ist1 = (size_t)stack_table + 3*i * KERNEL_STACK_SIZE + KERNEL_STACK_SIZE - 0x10;
task_state_segments[i].ist2 = (size_t)stack_table + 3*i * KERNEL_STACK_SIZE + 2 * KERNEL_STACK_SIZE - 0x10;
task_state_segments[i].ist3 = (size_t)stack_table + 3*i * KERNEL_STACK_SIZE + 3 * KERNEL_STACK_SIZE - 0x10;
task_state_segments[i].ist1 = 0; // ist will created per task
task_state_segments[i].ist2 = (size_t)stack_table + MAX_IST*i * KERNEL_STACK_SIZE + (2 /*IST number */ - 1) * KERNEL_STACK_SIZE - 0x10;
task_state_segments[i].ist3 = (size_t)stack_table + MAX_IST*i * KERNEL_STACK_SIZE + (3 /*IST number */ - 1) * KERNEL_STACK_SIZE - 0x10;
task_state_segments[i].ist4 = (size_t)stack_table + MAX_IST*i * KERNEL_STACK_SIZE + (4 /*IST number */ - 1) * KERNEL_STACK_SIZE - 0x10;
gdt_set_gate(num+i*2, (unsigned long) (task_state_segments+i), sizeof(tss_t)-1,
GDT_FLAG_PRESENT | GDT_FLAG_TSS | GDT_FLAG_RING0, 0);

View file

@ -173,76 +173,80 @@ static int irq_install(void)
{
irq_remap();
/*
* "User-level" doesn't protect the red zone. Consequently we
* protect the common stack the usage of IST number 1.
*/
idt_set_gate(32, (size_t)irq0, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(33, (size_t)irq1, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(34, (size_t)irq2, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(35, (size_t)irq3, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(36, (size_t)irq4, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(37, (size_t)irq5, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(38, (size_t)irq6, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(39, (size_t)irq7, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(40, (size_t)irq8, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(41, (size_t)irq9, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(42, (size_t)irq10, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(43, (size_t)irq11, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(44, (size_t)irq12, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(45, (size_t)irq13, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(46, (size_t)irq14, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(47, (size_t)irq15, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(48, (size_t)irq16, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(49, (size_t)irq17, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(50, (size_t)irq18, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(51, (size_t)irq19, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(52, (size_t)irq20, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(53, (size_t)irq21, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(54, (size_t)irq22, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(55, (size_t)irq23, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(112, (size_t)irq80, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(113, (size_t)irq81, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(121, (size_t)wakeup, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(122, (size_t)mmnif_irq, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
// add APIC interrupt handler
idt_set_gate(123, (size_t)apic_timer, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(124, (size_t)apic_lint0, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(125, (size_t)apic_lint1, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(126, (size_t)apic_error, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(127, (size_t)apic_svr, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
return 0;
}

View file

@ -99,73 +99,77 @@ void isrs_install(void)
{
int i;
/*
* "User-level" doesn't protect the red zone. Consequently we
* protect the common stack by the usage of IST number 1.
*/
idt_set_gate(0, (size_t)isr0, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(1, (size_t)isr1, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
// NMI Exception gets its own stack (ist1)
idt_set_gate(2, (size_t)isr2, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(3, (size_t)isr3, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(4, (size_t)isr4, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(5, (size_t)isr5, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(6, (size_t)isr6, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(7, (size_t)isr7, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
// Double Fault Exception gets its own stack (ist2)
idt_set_gate(8, (size_t)isr8, KERNEL_CODE_SELECTOR,
idt_set_gate(1, (size_t)isr1, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
// NMI Exception gets its own stack (ist2)
idt_set_gate(2, (size_t)isr2, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 2);
idt_set_gate(9, (size_t)isr9, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(10, (size_t)isr10, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(11, (size_t)isr11, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(12, (size_t)isr12, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(13, (size_t)isr13, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(14, (size_t)isr14, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(15, (size_t)isr15, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(16, (size_t)isr16, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(17, (size_t)isr17, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
// Machine Check Exception gets its own stack (ist3)
idt_set_gate(18, (size_t)isr18, KERNEL_CODE_SELECTOR,
idt_set_gate(3, (size_t)isr3, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(4, (size_t)isr4, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(5, (size_t)isr5, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(6, (size_t)isr6, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(7, (size_t)isr7, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
// Double Fault Exception gets its own stack (ist3)
idt_set_gate(8, (size_t)isr8, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 3);
idt_set_gate(9, (size_t)isr9, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(10, (size_t)isr10, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(11, (size_t)isr11, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(12, (size_t)isr12, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(13, (size_t)isr13, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(14, (size_t)isr14, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(15, (size_t)isr15, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(16, (size_t)isr16, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(17, (size_t)isr17, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
// Machine Check Exception gets its own stack (ist4)
idt_set_gate(18, (size_t)isr18, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 4);
idt_set_gate(19, (size_t)isr19, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(20, (size_t)isr20, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(21, (size_t)isr21, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(22, (size_t)isr22, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(23, (size_t)isr23, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(24, (size_t)isr24, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(25, (size_t)isr25, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(26, (size_t)isr26, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(27, (size_t)isr27, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(28, (size_t)isr28, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(29, (size_t)isr29, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(30, (size_t)isr30, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(31, (size_t)isr31, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
// install the default handler
for(i=0; i<32; i++)
@ -215,7 +219,6 @@ static void fault_handler(struct state *s)
s->rax, s->rbx, s->rcx, s->rdx, s->rbp, s->rsp, s->rdi, s->rsi, s->r8, s->r9, s->r10, s->r11, s->r12, s->r13, s->r14, s->r15);
apic_eoi(s->int_no);
irq_enable();
//do_abort();
sys_exit(-EFAULT);
}

View file

@ -71,7 +71,7 @@ size_t* get_current_stack(void)
stptr = (stptr + DEFAULT_STACK_SIZE - sizeof(size_t)) & ~0x1F;
set_per_core(kernel_stack, stptr);
tss_set_rsp0(stptr);
set_tss(stptr, (size_t) curr_task->ist_addr + KERNEL_STACK_SIZE - 0x10);
return curr_task->last_stack_pointer;
}

View file

@ -271,7 +271,6 @@ default_handler:
kprintf("Heap 0x%llx - 0x%llx\n", task->heap->start, task->heap->end);
apic_eoi(s->int_no);
irq_enable();
//do_abort();
sys_exit(-EFAULT);
}

View file

@ -73,11 +73,11 @@ void* kmalloc(size_t sz);
/** @brief Create a stack with guard pages
*/
void* create_stack(void);
void* create_stack(size_t sz);
/** @brief Destroy stack with its guard pages
*/
int destroy_stack(void* addr);
int destroy_stack(void* addr, size_t sz);
/** @brief Release memory back to the buddy system
*

View file

@ -80,6 +80,8 @@ typedef struct task {
size_t* last_stack_pointer;
/// start address of the stack
void* stack;
/// interrupt stack for IST1
void* ist_addr;
/// Additional status flags. For instance, to signalize the using of the FPU
uint8_t flags;
/// Task priority

View file

@ -36,6 +36,7 @@
#include <hermit/errno.h>
#include <hermit/syscall.h>
#include <hermit/memory.h>
#include <asm/tss.h>
/*
* Note that linker symbols are not variables, they have no memory allocated for
@ -51,8 +52,8 @@ extern const void tls_end;
* A task's id will be its position in this array.
*/
static task_t task_table[MAX_TASKS] = { \
[0] = {0, TASK_IDLE, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, NULL, 0, NULL, NULL, 0, 0, 0}, \
[1 ... MAX_TASKS-1] = {0, TASK_INVALID, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, NULL, 0, NULL, NULL, 0, 0, 0}};
[0] = {0, TASK_IDLE, 0, NULL, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, NULL, 0, NULL, NULL, 0, 0, 0}, \
[1 ... MAX_TASKS-1] = {0, TASK_INVALID, 0, NULL, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, NULL, 0, NULL, NULL, 0, 0, 0}};
static spinlock_irqsave_t table_lock = SPINLOCK_IRQSAVE_INIT;
@ -69,6 +70,7 @@ DEFINE_PER_CORE(char*, kernel_stack, NULL);
DEFINE_PER_CORE(uint32_t, __core_id, 0);
#endif
extern const void boot_stack;
extern const void boot_ist;
/** @brief helper function for the assembly code to determine the current task
* @return Pointer to the task_t structure of current task
@ -106,8 +108,10 @@ int multitasking_init(void)
task_table[0].prio = IDLE_PRIO;
task_table[0].stack = (char*) ((size_t)&boot_stack + core_id * KERNEL_STACK_SIZE);
task_table[0].ist_addr = (char*)&boot_ist;
set_per_core(kernel_stack, task_table[0].stack + KERNEL_STACK_SIZE - 0x10);
set_per_core(current_task, task_table+0);
set_tss((size_t) task_table[0].stack + KERNEL_STACK_SIZE - 0x10, (size_t) task_table[0].ist_addr + KERNEL_STACK_SIZE - 0x10);
readyqueues[core_id].idle = task_table+0;
@ -158,6 +162,7 @@ int set_idle_task(void)
task_table[i].last_core = core_id;
task_table[i].last_stack_pointer = NULL;
task_table[i].stack = (char*) ((size_t)&boot_stack + core_id * KERNEL_STACK_SIZE);
task_table[i].ist_addr = create_stack(KERNEL_STACK_SIZE);
set_per_core(kernel_stack, task_table[i].stack + KERNEL_STACK_SIZE - 0x10);
task_table[i].prio = IDLE_PRIO;
task_table[i].heap = NULL;
@ -214,7 +219,7 @@ void finish_task_switch(void)
/* cleanup task */
if (old->stack) {
kprintf("Release stack at 0x%zx\n", old->stack);
destroy_stack(old->stack);
destroy_stack(old->stack, DEFAULT_STACK_SIZE);
old->stack = NULL;
}
@ -223,6 +228,11 @@ void finish_task_switch(void)
old->heap = NULL;
}
if (old->ist_addr) {
destroy_stack(old->ist_addr, KERNEL_STACK_SIZE);
old->ist_addr = NULL;
}
old->last_stack_pointer = NULL;
readyqueues[core_id].old_task = NULL;
@ -322,6 +332,7 @@ int clone_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
int ret = -EINVAL;
uint32_t i;
void* stack = NULL;
void* ist = NULL;
task_t* curr_task;
uint32_t core_id;
@ -334,10 +345,16 @@ int clone_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
curr_task = per_core(current_task);
stack = create_stack();
stack = create_stack(DEFAULT_STACK_SIZE);
if (BUILTIN_EXPECT(!stack, 0))
return -ENOMEM;
ist = create_stack(KERNEL_STACK_SIZE);
if (BUILTIN_EXPECT(!ist, 0)) {
destroy_stack(stack, DEFAULT_STACK_SIZE);
return -ENOMEM;
}
spinlock_irqsave_lock(&table_lock);
core_id = get_next_core_id();
@ -357,6 +374,7 @@ int clone_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
task_table[i].parent = curr_task->id;
task_table[i].tls_addr = curr_task->tls_addr;
task_table[i].tls_size = curr_task->tls_size;
task_table[i].ist_addr = ist;
task_table[i].lwip_err = 0;
if (id)
@ -392,7 +410,7 @@ int clone_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
out:
if (ret)
destroy_stack(stack);
destroy_stack(stack, DEFAULT_STACK_SIZE);
#if 0
if (core_id != CORE_ID)
@ -407,6 +425,7 @@ int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio, uint32_t c
int ret = -ENOMEM;
uint32_t i;
void* stack = NULL;
void* ist = NULL;
void* counter = NULL;
if (BUILTIN_EXPECT(!ep, 0))
@ -420,13 +439,20 @@ int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio, uint32_t c
if (BUILTIN_EXPECT(!readyqueues[core_id].idle, 0))
return -EINVAL;
stack = create_stack();
stack = create_stack(DEFAULT_STACK_SIZE);
if (BUILTIN_EXPECT(!stack, 0))
return -ENOMEM;
ist = create_stack(KERNEL_STACK_SIZE);
if (BUILTIN_EXPECT(!ist, 0)) {
destroy_stack(stack, DEFAULT_STACK_SIZE);
return -ENOMEM;
}
counter = kmalloc(sizeof(atomic_int64_t));
if (BUILTIN_EXPECT(!counter, 0)) {
destroy_stack(stack);
destroy_stack(stack, KERNEL_STACK_SIZE);
destroy_stack(stack, DEFAULT_STACK_SIZE);
return -ENOMEM;
}
atomic_int64_set((atomic_int64_t*) counter, 0);
@ -444,6 +470,7 @@ int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio, uint32_t c
task_table[i].heap = NULL;
task_table[i].start_tick = get_clock_tick();
task_table[i].parent = 0;
task_table[i].ist_addr = ist;
task_table[i].tls_addr = 0;
task_table[i].tls_size = 0;
task_table[i].lwip_err = 0;
@ -482,7 +509,7 @@ out:
spinlock_irqsave_unlock(&table_lock);
if (ret) {
destroy_stack(stack);
destroy_stack(stack, DEFAULT_STACK_SIZE);
kfree(counter);
}

View file

@ -167,14 +167,17 @@ void* palloc(size_t sz, uint32_t flags)
return (void*) viraddr;
}
void* create_stack(void)
void* create_stack(size_t sz)
{
size_t phyaddr, viraddr, bits;
uint32_t npages = PAGE_FLOOR(DEFAULT_STACK_SIZE) >> PAGE_BITS;
uint32_t npages = PAGE_FLOOR(sz) >> PAGE_BITS;
int err;
//kprintf("create_stack(0x%zx) (%lu pages)\n", DEFAULT_STACK_SIZE, npages);
if (BUILTIN_EXPECT(!sz, 0))
return NULL;
// get free virtual address space
viraddr = vma_alloc((npages+2)*PAGE_SIZE, VMA_READ|VMA_WRITE|VMA_CACHEABLE);
if (BUILTIN_EXPECT(!viraddr, 0))
@ -203,15 +206,17 @@ void* create_stack(void)
return (void*) (viraddr+PAGE_SIZE);
}
int destroy_stack(void* viraddr)
int destroy_stack(void* viraddr, size_t sz)
{
size_t phyaddr;
uint32_t npages = PAGE_FLOOR(DEFAULT_STACK_SIZE) >> PAGE_BITS;
uint32_t npages = PAGE_FLOOR(sz) >> PAGE_BITS;
//kprintf("destroy_stack(0x%zx) (size 0x%zx)\n", viraddr, DEFAULT_STACK_SIZE);
if (BUILTIN_EXPECT(!viraddr, 0))
return -ENOMEM;
return -EINVAL;
if (BUILTIN_EXPECT(!sz, 0))
return -EINVAL;
phyaddr = virt_to_phys((size_t)viraddr);
if (BUILTIN_EXPECT(!phyaddr, 0))

View file

@ -62,7 +62,7 @@ stream: stream.o
stream_icc.o: stream.c
@echo [ICC] $@
icc -m64 -c -o $@ -mno-red-zone -O3 -xHost -fno-stack-protector -I$(TOPDIR)/hermit/usr/x86/x86_64-hermit/include/ -openmp -ffreestanding $<
icc -m64 -c -o $@ -O3 -xHost -I$(TOPDIR)/hermit/usr/x86/x86_64-hermit/include/ -openmp -ffreestanding $<
$Q$(ELFEDIT_FOR_TARGET) --output-osabi HermitCore $@
stream_icc: stream_icc.o