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);
 }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to