Skip to content

Commit

Permalink
kernel: remove duplicate esp and ss fields in struct registers
Browse files Browse the repository at this point in the history
  • Loading branch information
mosmeh committed Nov 1, 2024
1 parent 7770803 commit b774f9a
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 32 deletions.
22 changes: 16 additions & 6 deletions kernel/interrupts/asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@
.text
.globl isr_entry
isr_entry:
pusha
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %ebp
pushl %esi
pushl %edi
pushl %ds
pushl %es
pushl %fs
pushl %gs
pushl %ss

movw $KERNEL_DS, %ax
movw %ax, %ds
Expand All @@ -30,12 +35,17 @@ isr_entry:

.globl do_iret
do_iret:
addl $4, %esp # pop ss
popl %gs
popl %fs
popl %es
popl %ds
popa

addl $8, %esp # pop err_code and num
popl %edi
popl %esi
popl %ebp
popl %edx
popl %ecx
popl %ebx
popl %eax

addl $8, %esp # pop error_code and interrupt_num
iret
6 changes: 3 additions & 3 deletions kernel/syscall/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ int sys_sigpending(sigset_t* user_set) {
X86_EFLAGS_CF | X86_EFLAGS_RF)

int sys_sigreturn(struct registers* regs) {
uintptr_t esp = regs->user_esp + sizeof(int); // Pop signum
uintptr_t esp = regs->esp + sizeof(int); // Pop signum
struct sigcontext ctx;
if (copy_from_user(&ctx, (void*)esp, sizeof(struct sigcontext)))
task_crash(SIGSEGV);

regs->user_ss = ctx.regs.user_ss | 3;
regs->ss = ctx.regs.ss | 3;
regs->cs = ctx.regs.cs | 3;
regs->ds = ctx.regs.ds;
regs->es = ctx.regs.es;
Expand All @@ -128,7 +128,7 @@ int sys_sigreturn(struct registers* regs) {
regs->esi = ctx.regs.esi;
regs->edi = ctx.regs.edi;
regs->ebp = ctx.regs.ebp;
regs->user_esp = ctx.regs.user_esp;
regs->esp = ctx.regs.esp;
regs->eip = ctx.regs.eip;

regs->eflags =
Expand Down
2 changes: 1 addition & 1 deletion kernel/syscall/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ static void syscall_handler(struct registers* regs) {
ASSERT((regs->es & 3) == 3);
ASSERT((regs->fs & 3) == 3);
ASSERT((regs->gs & 3) == 3);
ASSERT((regs->user_ss & 3) == 3);
ASSERT((regs->ss & 3) == 3);
ASSERT(interrupts_enabled());

unsigned flags = 0;
Expand Down
2 changes: 1 addition & 1 deletion kernel/syscall/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ int sys_clone(struct registers* regs, unsigned long flags, void* user_stack,
child_regs->eax = 0; // returns 0 in the child

if (user_stack)
child_regs->user_esp = (uintptr_t)user_stack;
child_regs->esp = (uintptr_t)user_stack;

if (flags & CLONE_VM) {
task->vm = current->vm;
Expand Down
17 changes: 4 additions & 13 deletions kernel/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,25 +77,16 @@ noreturn void poweroff(void) {
}

static void dump_registers(const struct registers* regs) {
uint16_t ss;
uint32_t esp;
if (regs->cs & 3) {
ss = regs->user_ss;
esp = regs->user_esp;
} else {
ss = regs->ss;
esp = regs->esp;
}
kprintf(" interrupt_num=%u error_code=0x%08x\n"
kprintf("interrupt_num=%u error_code=0x%08x\n"
" pc=0x%04x:0x%08x eflags=0x%08x\n"
"stack=0x%04x:0x%08x\n"
" ds=0x%04x es=0x%04x fs=0x%04x gs=0x%04x\n"
" eax=0x%08x ebx=0x%08x ecx=0x%08x edx=0x%08x\n"
" ebp=0x%08x esp=0x%08x esi=0x%08x edi=0x%08x\n"
" ebp=0x%08x esi=0x%08x edi=0x%08x\n"
" cr0=0x%08x cr2=0x%08x cr3=0x%08x cr4=0x%08x\n",
regs->interrupt_num, regs->error_code, regs->cs, regs->eip,
regs->eflags, ss, esp, regs->ds, regs->es, regs->fs, regs->gs,
regs->eax, regs->ebx, regs->ecx, regs->edx, regs->ebp, regs->esp,
regs->eflags, regs->ss, regs->esp, regs->ds, regs->es, regs->fs,
regs->gs, regs->eax, regs->ebx, regs->ecx, regs->edx, regs->ebp,
regs->esi, regs->edi, read_cr0(), read_cr2(), read_cr3(),
read_cr4());
}
Expand Down
8 changes: 4 additions & 4 deletions kernel/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ extern unsigned char init_end[];
extern unsigned char kernel_end[];

struct registers {
uint32_t ss, gs, fs, es, ds;
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
uint32_t gs, fs, es, ds;
uint32_t edi, esi, ebp, edx, ecx, ebx, eax;
uint32_t interrupt_num, error_code;
uint32_t eip, cs, eflags, user_esp, user_ss;
} __attribute__((packed));
uint32_t eip, cs, eflags, esp, ss;
};

void dump_context(const struct registers*);

Expand Down
6 changes: 2 additions & 4 deletions kernel/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,6 @@ struct task* task_create(const char* comm, void (*entry_point)(void)) {
.esp = task->esp,
.eip = (uintptr_t)entry_point,
.eflags = X86_EFLAGS_IF | X86_EFLAGS_FIXED,
.user_esp = task->esp,
.user_ss = KERNEL_DS,
};

return task;
Expand Down Expand Up @@ -572,7 +570,7 @@ void task_handle_signal(struct registers* regs, int signum,
ASSERT(0 < signum && signum < NSIG);
ASSERT(action->sa_flags & SA_RESTORER);

uintptr_t esp = ROUND_DOWN(regs->user_esp, 16);
uintptr_t esp = ROUND_DOWN(regs->esp, 16);

// Push the context of the interrupted task
struct sigcontext ctx = {
Expand All @@ -593,7 +591,7 @@ void task_handle_signal(struct registers* regs, int signum,
if (copy_to_user((void*)esp, &action->sa_restorer, sizeof(uintptr_t)))
goto fail;

regs->user_esp = esp;
regs->esp = esp;
regs->eip = (uintptr_t)action->sa_handler;

sigset_t new_blocked = current->blocked_signals | action->sa_mask;
Expand Down

0 comments on commit b774f9a

Please sign in to comment.