forked from Bananymous/banan-os
Kernel: Change signal kernel API
return rsp and rip are now stored per thread
This commit is contained in:
parent
adb14ba373
commit
f7bf6d5e62
|
@ -1,6 +1,7 @@
|
||||||
#include <BAN/Errors.h>
|
#include <BAN/Errors.h>
|
||||||
#include <kernel/IDT.h>
|
#include <kernel/IDT.h>
|
||||||
#include <kernel/InterruptController.h>
|
#include <kernel/InterruptController.h>
|
||||||
|
#include <kernel/InterruptStack.h>
|
||||||
#include <kernel/Memory/kmalloc.h>
|
#include <kernel/Memory/kmalloc.h>
|
||||||
#include <kernel/Panic.h>
|
#include <kernel/Panic.h>
|
||||||
#include <kernel/Process.h>
|
#include <kernel/Process.h>
|
||||||
|
@ -135,7 +136,7 @@ namespace IDT
|
||||||
"Unkown Exception 0x1F",
|
"Unkown Exception 0x1F",
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" void cpp_isr_handler(uint64_t isr, uint64_t error, const Registers* regs)
|
extern "C" void cpp_isr_handler(uint64_t isr, uint64_t error, Kernel::InterruptStack& interrupt_stack, const Registers* regs)
|
||||||
{
|
{
|
||||||
pid_t tid = Kernel::Scheduler::current_tid();
|
pid_t tid = Kernel::Scheduler::current_tid();
|
||||||
pid_t pid = tid ? Kernel::Process::current().pid() : 0;
|
pid_t pid = tid ? Kernel::Process::current().pid() : 0;
|
||||||
|
@ -154,6 +155,12 @@ namespace IDT
|
||||||
regs->cr0, regs->cr2, regs->cr3, regs->cr4
|
regs->cr0, regs->cr2, regs->cr3, regs->cr4
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (tid)
|
||||||
|
{
|
||||||
|
Kernel::Thread::current().set_return_rsp(interrupt_stack.rsp);
|
||||||
|
Kernel::Thread::current().set_return_rip(interrupt_stack.rip);
|
||||||
|
}
|
||||||
|
|
||||||
if (tid && Kernel::Thread::current().is_userspace() && !Kernel::Thread::current().is_in_syscall())
|
if (tid && Kernel::Thread::current().is_userspace() && !Kernel::Thread::current().is_in_syscall())
|
||||||
{
|
{
|
||||||
auto message = BAN::String::formatted("{}, aborting\n", isr_exceptions[isr]);
|
auto message = BAN::String::formatted("{}, aborting\n", isr_exceptions[isr]);
|
||||||
|
@ -167,8 +174,14 @@ namespace IDT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void cpp_irq_handler(uint64_t irq)
|
extern "C" void cpp_irq_handler(uint64_t irq, Kernel::InterruptStack& interrupt_stack)
|
||||||
{
|
{
|
||||||
|
if (Kernel::Scheduler::current_tid())
|
||||||
|
{
|
||||||
|
Kernel::Thread::current().set_return_rsp(interrupt_stack.rsp);
|
||||||
|
Kernel::Thread::current().set_return_rip(interrupt_stack.rip);
|
||||||
|
}
|
||||||
|
|
||||||
if (s_irq_handlers[irq])
|
if (s_irq_handlers[irq])
|
||||||
s_irq_handlers[irq]();
|
s_irq_handlers[irq]();
|
||||||
else
|
else
|
||||||
|
|
|
@ -64,7 +64,11 @@ isr_stub:
|
||||||
|
|
||||||
movq 176(%rsp), %rdi
|
movq 176(%rsp), %rdi
|
||||||
movq 184(%rsp), %rsi
|
movq 184(%rsp), %rsi
|
||||||
|
|
||||||
movq %rsp, %rdx
|
movq %rsp, %rdx
|
||||||
|
addq $192, %rdx
|
||||||
|
|
||||||
|
movq %rsp, %rcx
|
||||||
|
|
||||||
call cpp_isr_handler
|
call cpp_isr_handler
|
||||||
addq $56, %rsp
|
addq $56, %rsp
|
||||||
|
@ -75,6 +79,8 @@ isr_stub:
|
||||||
irq_stub:
|
irq_stub:
|
||||||
pushaq
|
pushaq
|
||||||
movq 0x78(%rsp), %rdi # irq number
|
movq 0x78(%rsp), %rdi # irq number
|
||||||
|
movq %rsp, %rsi
|
||||||
|
addq $136, %rsi
|
||||||
call cpp_irq_handler
|
call cpp_irq_handler
|
||||||
popaq
|
popaq
|
||||||
addq $16, %rsp
|
addq $16, %rsp
|
||||||
|
|
|
@ -101,8 +101,8 @@ namespace Kernel
|
||||||
BAN::ErrorOr<long> sys_free(void*);
|
BAN::ErrorOr<long> sys_free(void*);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_signal(int, void (*)(int));
|
BAN::ErrorOr<long> sys_signal(int, void (*)(int));
|
||||||
BAN::ErrorOr<long> sys_kill(pid_t pid, int signal, uintptr_t& return_rsp, uintptr_t& return_rip);
|
BAN::ErrorOr<long> sys_raise(int signal);
|
||||||
BAN::ErrorOr<long> sys_raise(int signal, uintptr_t& return_rsp, uintptr_t& return_rip);
|
static BAN::ErrorOr<long> sys_kill(pid_t pid, int signal);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_termid(char*) const;
|
BAN::ErrorOr<long> sys_termid(char*) const;
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,11 @@ namespace Kernel
|
||||||
bool has_signal_to_execute() const;
|
bool has_signal_to_execute() const;
|
||||||
void set_signal_done(int signal);
|
void set_signal_done(int signal);
|
||||||
void handle_next_signal();
|
void handle_next_signal();
|
||||||
void handle_signal(int signal, uintptr_t& return_rsp, uintptr_t& return_rip);
|
|
||||||
|
void set_return_rsp(uintptr_t& rsp) { m_return_rsp = &rsp; }
|
||||||
|
void set_return_rip(uintptr_t& rip) { m_return_rip = &rip; }
|
||||||
|
uintptr_t& return_rsp() { ASSERT(m_return_rsp); return *m_return_rsp; }
|
||||||
|
uintptr_t& return_rip() { ASSERT(m_return_rip); return *m_return_rip; }
|
||||||
|
|
||||||
pid_t tid() const { return m_tid; }
|
pid_t tid() const { return m_tid; }
|
||||||
|
|
||||||
|
@ -90,6 +94,9 @@ namespace Kernel
|
||||||
bool m_in_syscall { false };
|
bool m_in_syscall { false };
|
||||||
bool m_is_userspace { false };
|
bool m_is_userspace { false };
|
||||||
|
|
||||||
|
uintptr_t* m_return_rsp { nullptr };
|
||||||
|
uintptr_t* m_return_rip { nullptr };
|
||||||
|
|
||||||
BAN::CircularQueue<int, 10> m_signal_queue;
|
BAN::CircularQueue<int, 10> m_signal_queue;
|
||||||
uint64_t m_signal_mask { 0 };
|
uint64_t m_signal_mask { 0 };
|
||||||
bool m_handling_signal { false };
|
bool m_handling_signal { false };
|
||||||
|
|
|
@ -806,18 +806,19 @@ namespace Kernel
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_kill(pid_t pid, int signal, uintptr_t& return_rsp, uintptr_t& return_rip)
|
BAN::ErrorOr<long> Process::sys_kill(pid_t pid, int signal)
|
||||||
{
|
{
|
||||||
if (pid <= 0)
|
if (pid <= 0)
|
||||||
return BAN::Error::from_errno(ENOTSUP);
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
if (signal != 0 && (signal < _SIGMIN || signal > _SIGMAX))
|
if (signal != 0 && (signal < _SIGMIN || signal > _SIGMAX))
|
||||||
return BAN::Error::from_errno(EINVAL);
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
if (pid == this->pid())
|
if (pid == Process::current().pid())
|
||||||
return sys_raise(signal, return_rsp, return_rip);
|
return Process::current().sys_raise(signal);
|
||||||
|
|
||||||
LockGuard process_guard(s_process_lock);
|
LockGuard process_guard(s_process_lock);
|
||||||
CriticalScope _;
|
CriticalScope _;
|
||||||
|
|
||||||
for (auto* process : s_processes)
|
for (auto* process : s_processes)
|
||||||
{
|
{
|
||||||
if (process->pid() == pid)
|
if (process->pid() == pid)
|
||||||
|
@ -831,17 +832,24 @@ namespace Kernel
|
||||||
return BAN::Error::from_errno(ESRCH);
|
return BAN::Error::from_errno(ESRCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_raise(int signal, uintptr_t& return_rsp, uintptr_t& return_rip)
|
BAN::ErrorOr<long> Process::sys_raise(int signal)
|
||||||
{
|
{
|
||||||
if (signal < _SIGMIN || signal > _SIGMAX)
|
if (signal < _SIGMIN || signal > _SIGMAX)
|
||||||
return BAN::Error::from_errno(EINVAL);
|
return BAN::Error::from_errno(EINVAL);
|
||||||
ASSERT(m_threads.size() == 1);
|
ASSERT(m_threads.size() == 1);
|
||||||
CriticalScope _;
|
CriticalScope _;
|
||||||
Thread::current().m_signal_queue.push(signal);
|
Thread& current = Thread::current();
|
||||||
Thread::current().handle_signal(signal, return_rsp, return_rip);
|
current.m_signal_queue.push(signal);
|
||||||
|
current.handle_next_signal();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pid_t Process::foreground_pid()
|
||||||
|
{
|
||||||
|
ASSERT(s_foreground_pid);
|
||||||
|
return s_foreground_pid;
|
||||||
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_setuid(uid_t uid)
|
BAN::ErrorOr<long> Process::sys_setuid(uid_t uid)
|
||||||
{
|
{
|
||||||
if (uid < 0 || uid >= 1'000'000'000)
|
if (uid < 0 || uid >= 1'000'000'000)
|
||||||
|
|
|
@ -21,6 +21,8 @@ namespace Kernel
|
||||||
extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, InterruptStack& interrupt_stack)
|
extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, InterruptStack& interrupt_stack)
|
||||||
{
|
{
|
||||||
Thread::current().set_in_syscall(true);
|
Thread::current().set_in_syscall(true);
|
||||||
|
Thread::current().set_return_rsp(interrupt_stack.rsp);
|
||||||
|
Thread::current().set_return_rip(interrupt_stack.rip);
|
||||||
|
|
||||||
if (syscall == SYS_SIGNAL_DONE)
|
if (syscall == SYS_SIGNAL_DONE)
|
||||||
{
|
{
|
||||||
|
@ -147,10 +149,10 @@ namespace Kernel
|
||||||
ret = Process::current().sys_dup2((int)arg1, (int)arg2);
|
ret = Process::current().sys_dup2((int)arg1, (int)arg2);
|
||||||
break;
|
break;
|
||||||
case SYS_RAISE:
|
case SYS_RAISE:
|
||||||
ret = Process::current().sys_raise((int)arg1, interrupt_stack.rsp, interrupt_stack.rip);
|
ret = Process::current().sys_raise((int)arg1);
|
||||||
break;
|
break;
|
||||||
case SYS_KILL:
|
case SYS_KILL:
|
||||||
ret = Process::current().sys_kill((pid_t)arg1, (int)arg2, interrupt_stack.rsp, interrupt_stack.rip);
|
ret = Process::current().sys_kill((pid_t)arg1, (int)arg2);
|
||||||
break;
|
break;
|
||||||
case SYS_SIGNAL:
|
case SYS_SIGNAL:
|
||||||
ret = Process::current().sys_signal((int)arg1, (void (*)(int))arg2);
|
ret = Process::current().sys_signal((int)arg1, (void (*)(int))arg2);
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include <kernel/Scheduler.h>
|
#include <kernel/Scheduler.h>
|
||||||
#include <kernel/Thread.h>
|
#include <kernel/Thread.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -167,16 +166,14 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
ASSERT(!interrupts_enabled());
|
ASSERT(!interrupts_enabled());
|
||||||
ASSERT(!m_signal_queue.empty());
|
ASSERT(!m_signal_queue.empty());
|
||||||
handle_signal(m_signal_queue.front(), m_rsp, m_rip);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Thread::handle_signal(int signal, uintptr_t& return_rsp, uintptr_t& return_rip)
|
|
||||||
{
|
|
||||||
ASSERT(!interrupts_enabled());
|
|
||||||
ASSERT(signal >= _SIGMIN && signal <= _SIGMAX);
|
|
||||||
ASSERT(&Thread::current() == this);
|
ASSERT(&Thread::current() == this);
|
||||||
ASSERT(!m_signal_queue.empty());
|
ASSERT(is_userspace());
|
||||||
ASSERT(m_signal_queue.front() == signal);
|
|
||||||
|
int signal = m_signal_queue.front();
|
||||||
|
ASSERT(signal >= _SIGMIN && signal <= _SIGMAX);
|
||||||
|
|
||||||
|
uintptr_t& return_rsp = this->return_rsp();
|
||||||
|
uintptr_t& return_rip = this->return_rip();
|
||||||
|
|
||||||
vaddr_t signal_handler = process().m_signal_handlers[signal];
|
vaddr_t signal_handler = process().m_signal_handlers[signal];
|
||||||
|
|
||||||
|
@ -212,8 +209,11 @@ namespace Kernel
|
||||||
case SIGTRAP:
|
case SIGTRAP:
|
||||||
case SIGXCPU:
|
case SIGXCPU:
|
||||||
case SIGXFSZ:
|
case SIGXFSZ:
|
||||||
// TODO: additional actions
|
{
|
||||||
// fall through
|
auto message = BAN::String::formatted("killed by signal {}\n", signal);
|
||||||
|
(void)process().tty().write(0, message.data(), message.size());
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
|
||||||
// Abnormal termination of the process
|
// Abnormal termination of the process
|
||||||
case SIGALRM:
|
case SIGALRM:
|
||||||
|
@ -228,9 +228,6 @@ namespace Kernel
|
||||||
case SIGPROF:
|
case SIGPROF:
|
||||||
case SIGVTALRM:
|
case SIGVTALRM:
|
||||||
{
|
{
|
||||||
auto message = BAN::String::formatted("killed by signal {}\n", signal);
|
|
||||||
(void)process().tty().write(0, message.data(), message.size());
|
|
||||||
|
|
||||||
ENABLE_INTERRUPTS();
|
ENABLE_INTERRUPTS();
|
||||||
process().exit(128 + signal);
|
process().exit(128 + signal);
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
|
|
Loading…
Reference in New Issue