Module Name:    src
Committed By:   rmind
Date:           Sun Oct  3 19:46:35 UTC 2010

Modified Files:
        src/sys/arch/x86/x86: vga_post.c

Log Message:
vga_post_init: fix a bug and memleak in error path.


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/x86/x86/vga_post.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x86/x86/vga_post.c
diff -u src/sys/arch/x86/x86/vga_post.c:1.15 src/sys/arch/x86/x86/vga_post.c:1.16
--- src/sys/arch/x86/x86/vga_post.c:1.15	Mon Jun 28 00:39:47 2010
+++ src/sys/arch/x86/x86/vga_post.c	Sun Oct  3 19:46:35 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: vga_post.c,v 1.15 2010/06/28 00:39:47 rmind Exp $ */
+/* $NetBSD: vga_post.c,v 1.16 2010/10/03 19:46:35 rmind Exp $ */
 
 /*-
  * Copyright (c) 2007 Joerg Sonnenberger <jo...@netbsd.org>.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vga_post.c,v 1.15 2010/06/28 00:39:47 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vga_post.c,v 1.16 2010/10/03 19:46:35 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -143,30 +143,30 @@
 	vaddr_t sys_image, sys_bios_data;
 	int err;
 
-	sys_bios_data = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, UVM_KMF_VAONLY);
-	if (sys_bios_data == 0)
-		return NULL;
-
 	sys_image = uvm_km_alloc(kernel_map, 1024 * 1024, 0, UVM_KMF_VAONLY);
 	if (sys_image == 0) {
-		uvm_km_free(kernel_map, sys_bios_data, PAGE_SIZE,
-				UVM_KMF_VAONLY);
 		return NULL;
 	}
 	sc = kmem_alloc(sizeof(*sc), KM_SLEEP);
+	sc->sys_image = sys_image;
+	sc->emu.sys_private = sc;
 
 	err = uvm_pglistalloc(BASE_MEMORY, 0, (paddr_t)-1, 0, 0,
 	    &sc->ram_backing, BASE_MEMORY/PAGE_SIZE, 1);
 	if (err) {
-		uvm_km_free(kernel_map, sc->sys_image, 1024 * 1024,
-				UVM_KMF_VAONLY);
+		uvm_km_free(kernel_map, sc->sys_image,
+		    1024 * 1024, UVM_KMF_VAONLY);
 		kmem_free(sc, sizeof(*sc));
 		return NULL;
 	}
 
-	sc->sys_image = sys_image;
-	sc->emu.sys_private = sc;
-
+	/*
+	 * Map and copy BIOS data.
+	 */
+	sys_bios_data = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, UVM_KMF_VAONLY);
+	if (sys_bios_data == 0) {
+		return NULL;
+	}
 	pmap_kenter_pa(sys_bios_data, 0, VM_PROT_READ, 0);
 	pmap_update(pmap_kernel());
 
@@ -176,17 +176,21 @@
 	pmap_update(pmap_kernel());
 	uvm_km_free(kernel_map, sys_bios_data, PAGE_SIZE, UVM_KMF_VAONLY);
 
+	/*
+	 * Map 0 .. 64KB and 640KB .. 1MB ranges.
+	 */
 	iter = 0;
 	TAILQ_FOREACH(pg, &sc->ram_backing, pageq.queue) {
 		pmap_kenter_pa(sc->sys_image + iter, VM_PAGE_TO_PHYS(pg),
-				VM_PROT_READ | VM_PROT_WRITE, 0);
+		    VM_PROT_READ | VM_PROT_WRITE, 0);
 		iter += PAGE_SIZE;
 	}
-	KASSERT(iter == 65536);
+	KASSERT(iter == BASE_MEMORY);
 
-	for (iter = 640 * 1024; iter < 1024 * 1024; iter += PAGE_SIZE)
+	for (iter = 640 * 1024; iter < 1024 * 1024; iter += PAGE_SIZE) {
 		pmap_kenter_pa(sc->sys_image + iter, iter,
-				VM_PROT_READ | VM_PROT_WRITE, 0);
+		    VM_PROT_READ | VM_PROT_WRITE, 0);
+	}
 	pmap_update(pmap_kernel());
 
 	memset(&sc->emu, 0, sizeof(sc->emu));

Reply via email to