diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2010-03-24 00:36:05 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2010-03-24 00:36:05 +0000 |
commit | d1a910ddea1d936919bc41da319916bbf007279a (patch) | |
tree | 9c9500e5028328add0a30c668a90a3ded4dc9172 /sys/uvm/uvm_page.c | |
parent | bce2f051822693eb68d990472e07259acdac9503 (diff) |
Bring back PHYSLOAD_DEVICE for uvm_page_physload.
ok kettenis@ beck@ (tentatively) and ariane@. deraadt asked for it to be
commited now.
original commit message:
extend uvm_page_physload to have the ability to add "device" pages to
the system.
This is needed in the case where you need managed pages so you can
handle faulting and pmap_page_protect() on said pages when you manage
memory in such regions (i'm looking at you, graphics cards).
these pages are flagged PG_DEV, and shall never be on the freelists,
assert this. behaviour remains unchanged in the non-device case,
specifically for all archs currently in the tree we panic if called
after bootstrap.
ok art@ kettenis@, beck@
Diffstat (limited to 'sys/uvm/uvm_page.c')
-rw-r--r-- | sys/uvm/uvm_page.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/sys/uvm/uvm_page.c b/sys/uvm/uvm_page.c index 72bbce4a874..7e95c431d18 100644 --- a/sys/uvm/uvm_page.c +++ b/sys/uvm/uvm_page.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_page.c,v 1.97 2009/10/14 17:53:30 beck Exp $ */ +/* $OpenBSD: uvm_page.c,v 1.98 2010/03/24 00:36:04 oga Exp $ */ /* $NetBSD: uvm_page.c,v 1.44 2000/11/27 08:40:04 chs Exp $ */ /* @@ -575,8 +575,8 @@ uvm_page_physget(paddr_t *paddrp) */ void -uvm_page_physload(paddr_t start, paddr_t end, paddr_t avail_start, - paddr_t avail_end, int free_list) +uvm_page_physload_flags(paddr_t start, paddr_t end, paddr_t avail_start, + paddr_t avail_end, int free_list, int flags) { int preload, lcv; psize_t npages; @@ -618,32 +618,46 @@ uvm_page_physload(paddr_t start, paddr_t end, paddr_t avail_start, * if VM is already running, attempt to malloc() vm_page structures */ if (!preload) { -#if defined(VM_PHYSSEG_NOADD) - panic("uvm_page_physload: tried to add RAM after vm_mem_init"); -#else - /* XXXCDC: need some sort of lockout for this case */ - paddr_t paddr; - npages = end - start; /* # of pages */ - pgs = (vm_page *)uvm_km_zalloc(kernel_map, - sizeof(struct vm_page) * npages); + /* + * XXXCDC: need some sort of lockout for this case + * right now it is only used by devices so it should be alright. + */ + paddr_t paddr; + + npages = end - start; /* # of pages */ + + pgs = (struct vm_page *)uvm_km_zalloc(kernel_map, + npages * sizeof(*pgs)); if (pgs == NULL) { printf("uvm_page_physload: can not malloc vm_page " "structs for segment\n"); printf("\tignoring 0x%lx -> 0x%lx\n", start, end); return; } - /* init phys_addr and free_list, and free pages */ - for (lcv = 0, paddr = ptoa(start) ; - lcv < npages ; lcv++, paddr += PAGE_SIZE) { + /* init phys_addr and free pages, XXX uvmexp.npages */ + for (lcv = 0, paddr = ptoa(start); lcv < npages; + lcv++, paddr += PAGE_SIZE) { pgs[lcv].phys_addr = paddr; - pgs[lcv].free_list = free_list; +#ifdef __HAVE_VM_PAGE_MD + VM_MDPAGE_INIT(&pgs[lcv]); +#endif if (atop(paddr) >= avail_start && - atop(paddr) <= avail_end) - uvm_pagefree(&pgs[lcv]); + atop(paddr) <= avail_end) { + if (flags & PHYSLOAD_DEVICE) { + atomic_setbits_int(&pgs[lcv].pg_flags, + PG_DEV); + pgs[lcv].wire_count = 1; + } else { +#if defined(VM_PHYSSEG_NOADD) + panic("uvm_page_physload: tried to add RAM after vm_mem_init"); +#else + uvm_pagefree(&pgs[lcv]); +#endif + } + } } /* XXXCDC: incomplete: need to update uvmexp.free, what else? */ /* XXXCDC: need hook to tell pmap to rebuild pv_list, etc... */ -#endif } else { /* gcc complains if these don't get init'd */ @@ -901,14 +915,12 @@ uvm_pagealloc_strat(struct uvm_object *obj, voff_t off, struct vm_anon *anon, pg->offset = off; pg->uobject = obj; pg->uanon = anon; + KASSERT((pg->pg_flags & PG_DEV) == 0); pg->pg_flags = PG_BUSY|PG_CLEAN|PG_FAKE; pg->pg_version++; if (anon) { anon->an_page = pg; atomic_setbits_int(&pg->pg_flags, PQ_ANON); -#ifdef UBC - uvm_pgcnt_anon++; -#endif } else { if (obj) uvm_pageinsert(pg); @@ -996,6 +1008,7 @@ uvm_pagefree(struct vm_page *pg) UVMHIST_LOG(pghist, "freeing pg %p/%lx", pg, (u_long)VM_PAGE_TO_PHYS(pg), 0, 0); + KASSERT((pg->pg_flags & PG_DEV) == 0); /* * if the page was an object page (and thus "TABLED"), remove it |