diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index d84134e..fa86ec7 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -1718,7 +1718,7 @@ pmap_growkernel(vm_offset_t addr) pmap_zero_page(nkpg); paddr = VM_PAGE_TO_PHYS(nkpg); *pdpe = (pdp_entry_t) - (paddr | PG_V | PG_RW | PG_A | PG_M); + (paddr | PG_V | PG_RW | PG_A | PG_M | PG_U); continue; /* try again */ } pde = pmap_pdpe_to_pde(pdpe, kernel_vm_end); @@ -1739,7 +1739,8 @@ pmap_growkernel(vm_offset_t addr) if ((nkpg->flags & PG_ZERO) == 0) pmap_zero_page(nkpg); paddr = VM_PAGE_TO_PHYS(nkpg); - newpdir = (pd_entry_t) (paddr | PG_V | PG_RW | PG_A | PG_M); + newpdir = (pd_entry_t) (paddr | PG_V | PG_RW | PG_A | PG_M | + PG_U); pde_store(pde, newpdir); kernel_vm_end = (kernel_vm_end + NBPDR) & ~PDRMASK; @@ -3028,6 +3029,8 @@ validate: newpte |= PG_W; if (va < VM_MAXUSER_ADDRESS) newpte |= PG_U; + if (va == syspage_addr) + newpte |= PG_U; if (pmap == kernel_pmap) newpte |= PG_G; diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 09a4f16..ebbebb1 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD: src/sys/kern/kern_clock.c,v 1.210 2009/01/17 07:17:57 jeff E #include #include #include +#include #include #include #include @@ -303,6 +304,7 @@ hardclock(int usermode, uintfptr_t pc) { atomic_add_int((volatile int *)&ticks, 1); + syspage->ticks = ticks; hardclock_cpu(usermode); tc_ticktock(); /* diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index 89a4a19..b3dfec5 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -91,6 +91,10 @@ vm_map_t exec_map=0; vm_map_t pipe_map; vm_map_t buffer_map=0; +vm_offset_t syspage_addr; + +struct syspage *syspage; + /* * kmem_alloc_nofault: * @@ -478,6 +482,8 @@ void kmem_init(start, end) vm_offset_t start, end; { + vm_offset_t addr, offset; + vm_page_t p; vm_map_t m; m = vm_map_create(kernel_pmap, VM_MIN_KERNEL_ADDRESS, end); @@ -493,6 +499,28 @@ kmem_init(start, end) #endif start, VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT); /* ... and ending with the completion of the above `insert' */ + + if (vm_map_findspace(m, vm_map_min(m), PAGE_SIZE, &addr)) + panic("Couldn't find space for syspage\n"); + + offset = addr - VM_MIN_KERNEL_ADDRESS; + + vm_object_reference(kmem_object); + vm_map_insert(m, kmem_object, offset, addr, addr + PAGE_SIZE, + VM_PROT_READ, VM_PROT_READ, 0); + + VM_OBJECT_LOCK(kmem_object); + p = vm_page_alloc(kmem_object, OFF_TO_IDX(offset), + VM_ALLOC_SYSTEM | VM_ALLOC_WIRED); + KASSERT(p, ("Couldn't allocate syspage")); + VM_OBJECT_UNLOCK(kmem_object); + + printf("Inserting syspage at 0x%lx off %lx\n", addr, offset); + + syspage_addr = addr; + syspage = (struct syspage *)PHYS_TO_DMAP(p->phys_addr); + pmap_enter(kernel_pmap, addr, VM_PROT_READ, p, VM_PROT_READ, TRUE); + vm_map_unlock(m); } diff --git a/sys/vm/vm_kern.h b/sys/vm/vm_kern.h index 352b51e..6f082ba 100644 --- a/sys/vm/vm_kern.h +++ b/sys/vm/vm_kern.h @@ -71,4 +71,10 @@ extern vm_map_t exec_map; extern vm_map_t pipe_map; extern u_long vm_kmem_size; +extern vm_offset_t syspage_addr; +struct syspage { + int ticks; +}; +extern struct syspage *syspage; + #endif /* _VM_VM_KERN_H_ */