From dea0eba83d22323f55e584fdba46b05d9fd5eff0 Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Wed, 6 Mar 2024 22:00:09 +0100 Subject: [PATCH] zero: keep track of allocated pages --- drivers/zero.c | 53 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/drivers/zero.c b/drivers/zero.c index b55bec3..b93e446 100644 --- a/drivers/zero.c +++ b/drivers/zero.c @@ -1,14 +1,41 @@ #include "zero.h" #include "alloc.h" +#include "errno.h" #include "kernel.h" #include "klibc.h" #include "mem.h" +#include "list.h" +#include "paging.h" +#include "types.h" + +struct zeroMappedPage { + uaddr_t mappedAddr; + paddr_t phyAddr; + + struct zeroMappedPage *prev, *next; +}; struct zeroMappedEntry { int refCnt; + + struct zeroMappedPage *listMapped; }; +static int insertMappedPage(struct zeroMappedEntry *entry, uaddr_t vAddr, paddr_t pAddr){ + struct zeroMappedPage *info = (struct zeroMappedPage *)zalloc(sizeof(struct zeroMappedPage)); + + if(!info) + return -ENOMEM; + + info->mappedAddr = vAddr; + info->phyAddr = pAddr; + + list_add_tail(entry->listMapped, info); + return 0; +} + + static int zeroOpen(struct uAddrVirtualReg *vreg) { struct zeroMappedEntry *ent = (struct zeroMappedEntry *)vreg->res->customData; @@ -21,6 +48,11 @@ static int zeroClose(struct uAddrVirtualReg *vreg) struct zeroMappedEntry *ent = (struct zeroMappedEntry *)vreg->res->customData; ent->refCnt--; if (ent->refCnt == 0) { + struct zeroMappedPage *pageInfo; + list_collapse(ent->listMapped, pageInfo){ + pageUnmap(pageInfo->mappedAddr); + free(pageInfo); + } free(vreg->res->customData); free(vreg->res); } @@ -29,17 +61,26 @@ static int zeroClose(struct uAddrVirtualReg *vreg) static int zeroNoPage(struct uAddrVirtualReg *vreg, uaddr_t addr, int right) { - (void)vreg; + int ret = 0; + paddr_t ppage = allocPhyPage(1); + uaddr_t mappedAddr = ALIGN_DOWN(addr, PAGE_SIZE); + ret = pageMap(mappedAddr, ppage, right | PAGING_MEM_USER); - int ret = 0; - paddr_t ppage = allocPhyPage(1); - ret = pageMap(ALIGN_DOWN(addr, PAGE_SIZE), ppage, right | PAGING_MEM_USER) ; + struct zeroMappedEntry *ent = (struct zeroMappedEntry *)vreg->res->customData; unrefPhyPage(ppage); if (ret) { return ret; } - memset((void *)ALIGN_DOWN(addr, PAGE_SIZE), 0, PAGE_SIZE); + + ret = insertMappedPage(ent, mappedAddr, ppage); + if (ret) { + pageUnmap(mappedAddr); + return ret; + } + + memset((void *)mappedAddr, 0, PAGE_SIZE); + return ret; } @@ -65,6 +106,8 @@ int zeroMmap(struct uAddrSpace *as, uaddr_t *uaddr, size_t size, uint32_t rights struct zeroMappedEntry *cust = (struct zeroMappedEntry *)zalloc(sizeof(struct zeroMappedEntry)); + list_init(cust->listMapped); + res->allowedRight = PAGING_MEM_READ | PAGING_MEM_WRITE | PAGING_MEM_EXEC | PAGING_MEM_USER; res->ops = &zeroOps; res->customData = cust;