context: add copy kernel context

fix also some indentation
This commit is contained in:
Mathieu Maret 2021-10-28 19:18:03 +02:00
parent ca399ee782
commit f1039b7fe4
3 changed files with 72 additions and 29 deletions

View File

@ -2,8 +2,8 @@
#include "alloc.h" #include "alloc.h"
#include "allocArea.h" #include "allocArea.h"
#include "errno.h" #include "errno.h"
#include "klibc.h"
#include "irq.h" #include "irq.h"
#include "klibc.h"
#include "list.h" #include "list.h"
#include "paging.h" #include "paging.h"
#include "stdarg.h" #include "stdarg.h"
@ -70,7 +70,13 @@ struct mmu_context *mmuContextCreate()
ctx->ref = 1; ctx->ref = 1;
//TODO copy kernel space if (pagingCopyKernelSpace(ctx->vaddr_PD, ctx->paddr_PD, currentContext->vaddr_PD)) {
pr_err("Fail to copy Kernel space\n");
free(ctx);
return NULL;
}
disable_IRQs(flags); disable_IRQs(flags);
list_add_tail(listContext, ctx); list_add_tail(listContext, ctx);
restore_IRQs(flags); restore_IRQs(flags);

View File

@ -133,8 +133,7 @@ int pageMap(vaddr_t vaddr, paddr_t paddr, int flags)
uint pdEntry = vaddr >> (PD_SHIFT); uint pdEntry = vaddr >> (PD_SHIFT);
uint ptEntry = (vaddr >> PT_SHIFT) & PTE_MASK; uint ptEntry = (vaddr >> PT_SHIFT) & PTE_MASK;
if ((vaddr >= PAGING_MIRROR_VADDR) && if ((vaddr >= PAGING_MIRROR_VADDR) && (vaddr < PAGING_MIRROR_VADDR + PAGING_MIRROR_SIZE))
(vaddr < PAGING_MIRROR_VADDR + PAGING_MIRROR_SIZE))
return -EINVAL; return -EINVAL;
// Thank to mirroring, we can access the PD // Thank to mirroring, we can access the PD
@ -143,7 +142,6 @@ int pageMap(vaddr_t vaddr, paddr_t paddr, int flags)
struct pte *pt = (struct pte *)((PAGING_MIRROR_VADDR) + (pdEntry * PAGE_SIZE)); struct pte *pt = (struct pte *)((PAGING_MIRROR_VADDR) + (pdEntry * PAGE_SIZE));
if (!pd[pdEntry].present) { if (!pd[pdEntry].present) {
paddr_t ptPhy = allocPhyPage(1); paddr_t ptPhy = allocPhyPage(1);
if (ptPhy == (vaddr_t)NULL) if (ptPhy == (vaddr_t)NULL)
@ -190,8 +188,7 @@ int pageUnmap(vaddr_t vaddr)
uint pdEntry = vaddr >> (PD_SHIFT); uint pdEntry = vaddr >> (PD_SHIFT);
uint ptEntry = (vaddr >> PT_SHIFT) & PTE_MASK; uint ptEntry = (vaddr >> PT_SHIFT) & PTE_MASK;
if ((vaddr >= PAGING_MIRROR_VADDR) && if ((vaddr >= PAGING_MIRROR_VADDR) && (vaddr < PAGING_MIRROR_VADDR + PAGING_MIRROR_SIZE))
(vaddr < PAGING_MIRROR_VADDR + PAGING_MIRROR_SIZE))
return -EINVAL; return -EINVAL;
// Thank to mirroring, we can access the PD // Thank to mirroring, we can access the PD
@ -272,3 +269,42 @@ int pagingSetCurrentPDPaddr(paddr_t paddrPD)
return 0; return 0;
} }
int pagingCopyKernelSpace(vaddr_t destVaddrPD, paddr_t destPaddrPD, vaddr_t srcVaddrPD)
{
struct pde *src_pd = (struct pde *)srcVaddrPD;
struct pde *dest_pd = (struct pde *)destVaddrPD;
struct pde mirror_pde;
uint index_in_pd;
/* Fill destination PD with zeros */
memset((void *)destVaddrPD, 0x0, PAGE_SIZE);
/* Synchronize it with the master Kernel MMU context. Stop just
before the mirroring ! */
for (index_in_pd = 0; index_in_pd < (PAGING_MIRROR_VADDR >> 22); /* 1 PDE = 1 PT
= 1024 Pages
= 4MB */
index_in_pd++) {
/* Copy the master's configuration */
dest_pd[index_in_pd] = src_pd[index_in_pd];
/* We DON'T mark the underlying PT and pages as referenced
because all the PD are equivalent in the kernel space: as
soon as a page is mapped in the kernel, it is mapped by X
address spaces, and as soon as it is unmapped by 1 address
space, it is unmapped in all the others. So that for X
address spaces, the reference counter will be either 0 or X,
and not something else: using the reference counter correctly
won't be of any use and would consume some time in updating it. */
}
/* Setup the mirroring for the new address space */
mirror_pde.present = TRUE;
mirror_pde.write = 1;
mirror_pde.user = 0; /* This is a KERNEL PDE */
mirror_pde.pt_addr = (destPaddrPD >> 12);
dest_pd[PAGING_MIRROR_VADDR >> 22] = mirror_pde;
return 0;
}

View File

@ -27,3 +27,4 @@ unsigned long getNbMappedPage(void);
int pagingSetCurrentPDPaddr(paddr_t paddrPD); int pagingSetCurrentPDPaddr(paddr_t paddrPD);
paddr_t pagingGetPaddr(vaddr_t vaddr); paddr_t pagingGetPaddr(vaddr_t vaddr);
paddr_t pagingGetCurrentPDPaddr(); paddr_t pagingGetCurrentPDPaddr();
int pagingCopyKernelSpace(vaddr_t destVaddrPD, paddr_t destPaddrPD, vaddr_t srcVaddrPD);