Kernel: Pass current cpu index as a GDT limit
I had no idea LSL was an instruction. This cleans up code to get the current cpu by a lot and does not require extra segment usage :D
This commit is contained in:
@@ -12,7 +12,7 @@ namespace Kernel::API
|
|||||||
|
|
||||||
struct SharedPage
|
struct SharedPage
|
||||||
{
|
{
|
||||||
uint8_t __sequence[0x100];
|
uint16_t gdt_cpu_offset;
|
||||||
|
|
||||||
uint32_t features;
|
uint32_t features;
|
||||||
|
|
||||||
|
|||||||
@@ -133,6 +133,12 @@ namespace Kernel
|
|||||||
void set_gsbase(uintptr_t addr);
|
void set_gsbase(uintptr_t addr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static uint16_t cpu_index_offset() { return m_cpu_index_offset; }
|
||||||
|
void set_cpu_index(uint8_t index)
|
||||||
|
{
|
||||||
|
write_entry(m_cpu_index_offset, 0, index, 0xF2, 0x4);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GDT() = default;
|
GDT() = default;
|
||||||
|
|
||||||
@@ -151,11 +157,13 @@ namespace Kernel
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
#if ARCH(x86_64)
|
#if ARCH(x86_64)
|
||||||
BAN::Array<SegmentDescriptor, 8> m_gdt; // null, kernel code, kernel data, user code (32 bit), user data, user code (64 bit), tss low, tss high
|
BAN::Array<SegmentDescriptor, 9> m_gdt; // null, kernel code, kernel data, user code (32 bit), user data, user code (64 bit), cpu-index, tss low, tss high
|
||||||
static constexpr uint16_t m_tss_offset = 0x30;
|
static constexpr uint16_t m_cpu_index_offset = 0x30;
|
||||||
|
static constexpr uint16_t m_tss_offset = 0x38;
|
||||||
#elif ARCH(i686)
|
#elif ARCH(i686)
|
||||||
BAN::Array<SegmentDescriptor, 9> m_gdt; // null, kernel code, kernel data, user code, user data, processor data, fsbase, gsbase, tss
|
BAN::Array<SegmentDescriptor, 10> m_gdt; // null, kernel code, kernel data, user code, user data, processor data, fsbase, gsbase, cpu-index, tss
|
||||||
static constexpr uint16_t m_tss_offset = 0x40;
|
static constexpr uint16_t m_cpu_index_offset = 0x40;
|
||||||
|
static constexpr uint16_t m_tss_offset = 0x48;
|
||||||
#endif
|
#endif
|
||||||
TaskStateSegment m_tss;
|
TaskStateSegment m_tss;
|
||||||
const GDTR m_gdtr {
|
const GDTR m_gdtr {
|
||||||
|
|||||||
@@ -178,9 +178,7 @@ namespace Kernel
|
|||||||
bool m_is_userspace { false };
|
bool m_is_userspace { false };
|
||||||
bool m_delete_process { false };
|
bool m_delete_process { false };
|
||||||
|
|
||||||
bool m_has_custom_fsbase { false };
|
|
||||||
vaddr_t m_fsbase { 0 };
|
vaddr_t m_fsbase { 0 };
|
||||||
bool m_has_custom_gsbase { false };
|
|
||||||
vaddr_t m_gsbase { 0 };
|
vaddr_t m_gsbase { 0 };
|
||||||
|
|
||||||
SchedulerQueue::Node* m_scheduler_node { nullptr };
|
SchedulerQueue::Node* m_scheduler_node { nullptr };
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ namespace Kernel
|
|||||||
gdt->write_entry(0x38, 0x00000000, 0x00000, 0xF2, 0xC); // gsbase
|
gdt->write_entry(0x38, 0x00000000, 0x00000, 0xF2, 0xC); // gsbase
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
gdt->write_entry(m_cpu_index_offset, 0, 0, 0, 0);
|
||||||
|
|
||||||
gdt->write_tss();
|
gdt->write_tss();
|
||||||
|
|
||||||
return gdt;
|
return gdt;
|
||||||
|
|||||||
@@ -3314,7 +3314,6 @@ namespace Kernel
|
|||||||
BAN::ErrorOr<long> Process::sys_set_fsbase(void* addr)
|
BAN::ErrorOr<long> Process::sys_set_fsbase(void* addr)
|
||||||
{
|
{
|
||||||
auto& thread = Thread::current();
|
auto& thread = Thread::current();
|
||||||
thread.m_has_custom_fsbase = true;
|
|
||||||
thread.set_fsbase(reinterpret_cast<vaddr_t>(addr));
|
thread.set_fsbase(reinterpret_cast<vaddr_t>(addr));
|
||||||
Processor::load_fsbase();
|
Processor::load_fsbase();
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3328,7 +3327,6 @@ namespace Kernel
|
|||||||
BAN::ErrorOr<long> Process::sys_set_gsbase(void* addr)
|
BAN::ErrorOr<long> Process::sys_set_gsbase(void* addr)
|
||||||
{
|
{
|
||||||
auto& thread = Thread::current();
|
auto& thread = Thread::current();
|
||||||
thread.m_has_custom_gsbase = true;
|
|
||||||
thread.set_gsbase(reinterpret_cast<vaddr_t>(addr));
|
thread.set_gsbase(reinterpret_cast<vaddr_t>(addr));
|
||||||
Processor::load_gsbase();
|
Processor::load_gsbase();
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -217,8 +217,7 @@ namespace Kernel
|
|||||||
memset(reinterpret_cast<void*>(s_shared_page_vaddr), 0, PAGE_SIZE);
|
memset(reinterpret_cast<void*>(s_shared_page_vaddr), 0, PAGE_SIZE);
|
||||||
|
|
||||||
auto& shared_page = *reinterpret_cast<volatile API::SharedPage*>(s_shared_page_vaddr);
|
auto& shared_page = *reinterpret_cast<volatile API::SharedPage*>(s_shared_page_vaddr);
|
||||||
for (size_t i = 0; i <= 0xFF; i++)
|
shared_page.gdt_cpu_offset = GDT::cpu_index_offset();
|
||||||
shared_page.__sequence[i] = i;
|
|
||||||
shared_page.features = 0;
|
shared_page.features = 0;
|
||||||
|
|
||||||
ASSERT(Processor::count() + sizeof(Kernel::API::SharedPage) <= PAGE_SIZE);
|
ASSERT(Processor::count() + sizeof(Kernel::API::SharedPage) <= PAGE_SIZE);
|
||||||
|
|||||||
@@ -303,22 +303,7 @@ namespace Kernel
|
|||||||
{
|
{
|
||||||
if (!is_userspace() || !has_process())
|
if (!is_userspace() || !has_process())
|
||||||
return;
|
return;
|
||||||
|
Processor::gdt().set_cpu_index(Processor::current_index());
|
||||||
#if ARCH(x86_64)
|
|
||||||
if (m_has_custom_gsbase)
|
|
||||||
return;
|
|
||||||
#elif ARCH(i686)
|
|
||||||
if (m_has_custom_fsbase)
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const vaddr_t vaddr = process().shared_page_vaddr() + Processor::current_index();
|
|
||||||
|
|
||||||
#if ARCH(x86_64)
|
|
||||||
set_gsbase(vaddr);
|
|
||||||
#elif ARCH(i686)
|
|
||||||
set_fsbase(vaddr);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<Thread*> Thread::pthread_create(entry_t entry, void* arg)
|
BAN::ErrorOr<Thread*> Thread::pthread_create(entry_t entry, void* arg)
|
||||||
|
|||||||
@@ -27,12 +27,7 @@ int sched_getcpu(void)
|
|||||||
{
|
{
|
||||||
if (g_shared_page == nullptr)
|
if (g_shared_page == nullptr)
|
||||||
return -1;
|
return -1;
|
||||||
|
uint16_t limit;
|
||||||
uint8_t cpu;
|
asm volatile("lsl %1, %0" : "=r"(limit) : "r"(g_shared_page->gdt_cpu_offset));
|
||||||
#if defined(__x86_64__)
|
return limit;
|
||||||
asm volatile("movb %%gs:0, %0" : "=r"(cpu));
|
|
||||||
#elif defined(__i686__)
|
|
||||||
asm volatile("movb %%fs:0, %0" : "=q"(cpu));
|
|
||||||
#endif
|
|
||||||
return cpu;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,13 +30,9 @@ int clock_gettime(clockid_t clock_id, struct timespec* tp)
|
|||||||
|
|
||||||
const auto get_cpu =
|
const auto get_cpu =
|
||||||
[]() -> uint8_t {
|
[]() -> uint8_t {
|
||||||
uint8_t cpu;
|
uint16_t limit;
|
||||||
#if defined(__x86_64__)
|
asm volatile("lsl %1, %0" : "=r"(limit) : "r"(g_shared_page->gdt_cpu_offset));
|
||||||
asm volatile("movb %%gs:0, %0" : "=r"(cpu));
|
return limit;
|
||||||
#elif defined(__i686__)
|
|
||||||
asm volatile("movb %%fs:0, %0" : "=q"(cpu));
|
|
||||||
#endif
|
|
||||||
return cpu;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
|
|||||||
Reference in New Issue
Block a user