diff --git a/kernel/interrupt/handlers.cc b/kernel/interrupt/handlers.cc index c919dfc..145ab9c 100644 --- a/kernel/interrupt/handlers.cc +++ b/kernel/interrupt/handlers.cc @@ -9,6 +9,8 @@ #include "../device/ps2controller.h" #include "./epilogues.h" #include "./guard.h" +#include "../memory/pagetable.h" +#include "../memory/pageframealloc.h" static void printContext(const InterruptContext *context) { DBG << "ip: " << hex << context->cs << ':' << context->ip @@ -49,14 +51,39 @@ static void printContext(const InterruptContext *context) { #include "syscall/skeleton.h" [[gnu::interrupt]] static void handle_page_fault(InterruptContext *context, - uint64_t error) { - DBG << "Page fault encountered at linear address " << hex - << Core::CR<2>::read() << endl - << PageFaultError(error) << endl; - printContext(context); + uint64_t error) { + DBG << "Page fault encountered at linear address " << hex + << Core::CR<2>::read() << endl + << PageFaultError(error) << endl; + four_lvl_paging_t* paging_tree = Guard::enter().vault().scheduler.active()->paging_tree ; + asm volatile("mov %%cr3, %0" : "=r"(paging_tree)); - Syscall::Skeleton::exit(Guard::enter().vault()); - //kernelpanic("Page fault!"); + uintptr_t virt = 0; + asm volatile("mov %%cr2, %0" : "=r"(virt)); + if (PageFaultError(error).present && PageFaultError(error).write) { + uintptr_t pf =isMapped(virt, paging_tree); + uint64_t pf_number = uint64_t (pf >> 12 ); + + if(PageFrameAllocator::PageFrames[pf_number].ref_count==1){ + setMapping(virt, (void*) pf , paging_tree, 1); + + }else{ + + uintptr_t page = (uintptr_t) PageFrameAllocator::alloc(false); + //Syscall::Skeleton::map(page, 4096); + setMapping(virt, (void*) page , paging_tree, 1); + + memcpy( (void*)page, (void*)virt, 4096); + Syscall::Skeleton::invlpg(virt); + } + + + + + } + +Syscall::Skeleton::exit(Guard::enter().vault()); +//kernelpanic("Page fault!"); } /*! \brief Assembly interrupt handler for the keyboard. diff --git a/kernel/memory/pagetable.cc b/kernel/memory/pagetable.cc index 5cf565c..a4f98e3 100644 --- a/kernel/memory/pagetable.cc +++ b/kernel/memory/pagetable.cc @@ -160,7 +160,7 @@ void* getFreeVirtSpace(four_lvl_paging_t* search_table, uint8_t num_pages){ } -void setMapping(uintptr_t vaddr, void* frame, four_lvl_paging_t* flpt){ +void setMapping(uintptr_t vaddr, void* frame, four_lvl_paging_t* flpt, uint8_t writeable){ uint16_t l4Index = (vaddr>>39) & 0x1FF; uint16_t l3Index = (vaddr>>30) & 0x1FF; uint16_t l2Index = (vaddr>>21) & 0x1FF; @@ -207,7 +207,7 @@ void setMapping(uintptr_t vaddr, void* frame, four_lvl_paging_t* flpt){ assert(!(lvl1->entries[l1Index].present)); // should not be present, bc its a new mapping lvl1->entries[l1Index] = { .present = 1, - .write = 1, + .write = writeable, .user = 1, .address = (uintptr_t)frame >> 12 }; diff --git a/kernel/memory/pagetable.h b/kernel/memory/pagetable.h index 441b77a..4c0cea2 100644 --- a/kernel/memory/pagetable.h +++ b/kernel/memory/pagetable.h @@ -50,7 +50,7 @@ typedef struct { void write_identity_map(pagetable_t* identity_table, uint64_t size); void create_basic_page_table(four_lvl_paging_t* table, pagetable_t* kernel_identity); void load_cr3(void* cr3_value); -void setMapping(uintptr_t vaddr, void* frame, four_lvl_paging_t* flpt); +void setMapping(uintptr_t vaddr, void* frame, four_lvl_paging_t* flpt, uint8_t writeable =1); uintptr_t isMapped(uintptr_t vaddr, four_lvl_paging_t* flpt); void* getFreeVirtSpace(four_lvl_paging_t* search_table, uint8_t num_pages); void copy_pagetable(four_lvl_paging_t* parent_table, four_lvl_paging_t* child_table);