From 3acc66c2e7e6bfbe5a64a076158eed1d90ae700c Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Sat, 2 May 2009 11:21:19 +0300 Subject: [PATCH] Adding support for refcounted page tables. Fixed freeing of kernel pmds on copy_page_tables --- include/l4/generic/tcb.h | 8 +++++++- src/api/thread.c | 6 ++++++ src/arch/arm/v5/mm.c | 6 ++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/include/l4/generic/tcb.h b/include/l4/generic/tcb.h index b1e9e7a..51992a9 100644 --- a/include/l4/generic/tcb.h +++ b/include/l4/generic/tcb.h @@ -39,6 +39,12 @@ struct task_ids { l4id_t tgid; }; +/* A simple page table with a reference count */ +struct address_space { + struct pgd_table_t *pgd; + int ktcb_refs; +}; + struct ktcb { /* User context */ task_context_t context; @@ -86,7 +92,7 @@ struct ktcb { int nlocks; /* Page table information */ - pgd_table_t *pgd; + struct address_space *space; /* Fields for ipc rendezvous */ struct waitqueue_head wqh_recv; diff --git a/src/api/thread.c b/src/api/thread.c index e6c34f8..283f62e 100644 --- a/src/api/thread.c +++ b/src/api/thread.c @@ -256,6 +256,12 @@ int thread_setup_new_ids(struct task_ids *ids, unsigned int flags, return 0; } +#define KTCB_CREATE_PAGE_TABLES (1 << 0) +/* Allocates a ktcb and page tables depending on flags */ +struct ktcb *ktcb_create(unsigned int flags) +{ + +} /* * Creates a thread, with a new thread id, and depending on the flags, * either creates a new space, uses the same space as another thread, diff --git a/src/arch/arm/v5/mm.c b/src/arch/arm/v5/mm.c index d0204c1..ac9122f 100644 --- a/src/arch/arm/v5/mm.c +++ b/src/arch/arm/v5/mm.c @@ -460,9 +460,11 @@ pgd_table_t *copy_page_tables(pgd_table_t *from) return pgd; out_error: - /* Find all allocated pmds and free them */ + /* Find all allocated non-kernel pmds and free them */ for (int i = 0; i < PGD_ENTRY_TOTAL; i++) { - if ((pgd->entry[i] & PGD_TYPE_MASK) == PGD_TYPE_COARSE) { + /* Non-kernel pmd that has just been allocated. */ + if (!is_kern_pgdi(i) && + (pgd->entry[i] & PGD_TYPE_MASK) == PGD_TYPE_COARSE) { /* Obtain the pmd handle */ pmd = (pmd_table_t *) phys_to_virt((pgd->entry[i] &