Date: Mon, 9 Aug 2010 17:54:26 +0000 (UTC) From: Jung-uk Kim <jkim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r211112 - head/sys/compat/x86bios Message-ID: <201008091754.o79HsQOP062721@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jkim Date: Mon Aug 9 17:54:26 2010 New Revision: 211112 URL: http://svn.freebsd.org/changeset/base/211112 Log: Reduce diffs between VM86 and X86EMU wrappers for x86bios_alloc() and x86bios_free(). Add strict sanity checks for VM86 wrapper and add strict page table locking for X86EMU wrapper. Modified: head/sys/compat/x86bios/x86bios.c Modified: head/sys/compat/x86bios/x86bios.c ============================================================================== --- head/sys/compat/x86bios/x86bios.c Mon Aug 9 17:42:05 2010 (r211111) +++ head/sys/compat/x86bios/x86bios.c Mon Aug 9 17:54:26 2010 (r211112) @@ -112,44 +112,49 @@ x86bios_vmf2emu(struct vm86frame *vmf, s void * x86bios_alloc(uint32_t *offset, size_t size, int flags) { - vm_offset_t addr; + void *vaddr; int i; - addr = (vm_offset_t)contigmalloc(size, M_DEVBUF, flags, 0, - X86BIOS_MEM_SIZE, PAGE_SIZE, 0); - if (addr != 0) { - *offset = vtophys(addr); + if (offset == NULL || size == 0) + return (NULL); + vaddr = contigmalloc(size, M_DEVBUF, flags, 0, X86BIOS_MEM_SIZE, + PAGE_SIZE, 0); + if (vaddr != NULL) { + *offset = vtophys(vaddr); mtx_lock(&x86bios_lock); for (i = 0; i < atop(round_page(size)); i++) vm86_addpage(&x86bios_vmc, atop(*offset) + i, - addr + ptoa(i)); + (vm_offset_t)vaddr + ptoa(i)); mtx_unlock(&x86bios_lock); } - return ((void *)addr); + return (vaddr); } void x86bios_free(void *addr, size_t size) { - int i, last; + vm_paddr_t paddr; + int i, nfree; + if (addr == NULL || size == 0) + return; + paddr = vtophys(addr); + if (paddr >= X86BIOS_MEM_SIZE || (paddr & PAGE_MASK) != 0) + return; + nfree = atop(round_page(size)); mtx_lock(&x86bios_lock); - for (i = 0, last = -1; i < x86bios_vmc.npages; i++) - if (x86bios_vmc.pmap[i].kva >= (vm_offset_t)addr && - x86bios_vmc.pmap[i].kva < (vm_offset_t)addr + size) { - bzero(&x86bios_vmc.pmap[i], - sizeof(x86bios_vmc.pmap[i])); - last = i; - } - if (last < 0) { + for (i = 0; i < x86bios_vmc.npages; i++) + if (x86bios_vmc.pmap[i].kva == (vm_offset_t)addr) + break; + if (i >= x86bios_vmc.npages) { mtx_unlock(&x86bios_lock); return; } - if (last == x86bios_vmc.npages - 1) { - x86bios_vmc.npages -= atop(round_page(size)); - for (i = x86bios_vmc.npages - 1; - i >= 0 && x86bios_vmc.pmap[i].kva == 0; i--) + bzero(x86bios_vmc.pmap + i, sizeof(*x86bios_vmc.pmap) * nfree); + if (i + nfree == x86bios_vmc.npages) { + x86bios_vmc.npages -= nfree; + while (--i >= 0 && x86bios_vmc.pmap[i].kva == 0) x86bios_vmc.npages--; } mtx_unlock(&x86bios_lock); @@ -552,12 +557,13 @@ x86bios_alloc(uint32_t *offset, size_t s if (offset == NULL || size == 0) return (NULL); - vaddr = contigmalloc(size, M_DEVBUF, flags, X86BIOS_RAM_BASE, x86bios_rom_phys, X86BIOS_PAGE_SIZE, 0); if (vaddr != NULL) { *offset = vtophys(vaddr); + mtx_lock_spin(&x86bios_lock); x86bios_set_pages((vm_offset_t)vaddr, *offset, size); + mtx_unlock_spin(&x86bios_lock); } return (vaddr); @@ -570,14 +576,14 @@ x86bios_free(void *addr, size_t size) if (addr == NULL || size == 0) return; - paddr = vtophys(addr); if (paddr < X86BIOS_RAM_BASE || paddr >= x86bios_rom_phys || paddr % X86BIOS_PAGE_SIZE != 0) return; - + mtx_lock_spin(&x86bios_lock); bzero(x86bios_map + paddr / X86BIOS_PAGE_SIZE, sizeof(*x86bios_map) * howmany(size, X86BIOS_PAGE_SIZE)); + mtx_unlock_spin(&x86bios_lock); contigfree(addr, size, M_DEVBUF); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008091754.o79HsQOP062721>