Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1DKXzz-0000Se-BI for qemu-devel@nongnu.org; Sun, 10 Apr 2005 04:40:56 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1DKXzo-0000OG-2H for qemu-devel@nongnu.org; Sun, 10 Apr 2005 04:40:45 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1DKXzn-0000I7-FN for qemu-devel@nongnu.org; Sun, 10 Apr 2005 04:40:43 -0400 Received: from [195.250.128.75] (helo=smtp2.vol.cz) by monty-python.gnu.org with esmtp (TLS-1.0:DHE_RSA_3DES_EDE_CBC_SHA:24) (Exim 4.34) id 1DKYIv-00062H-FY for qemu-devel@nongnu.org; Sun, 10 Apr 2005 05:00:29 -0400 Received: from [10.0.0.2] (prg-v-6-220.static.adsl.vol.cz [62.177.70.220]) by smtp2.vol.cz (8.12.9p2/8.12.9) with ESMTP id j3A8x78T087436 for ; Sun, 10 Apr 2005 10:59:07 +0200 (CEST) (envelope-from xnavara@volny.cz) Message-ID: <4258EAE2.1050505@volny.cz> Date: Sun, 10 Apr 2005 10:59:14 +0200 From: Filip Navara MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------050308070407060201010103" Subject: [Qemu-devel] [patch] Windows host support bugfixes Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. --------------050308070407060201010103 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi, the attached patch solves the memory corruption problems which caused QVM86 to crash on Windows NT host. The underlying problem was that the guest physical memory was allocated using malloc and wasn't aligned to page boundary which later caused problems when mapping the pages in the kernel module... Regards, Filip Navara --------------050308070407060201010103 Content-Type: text/plain; name="qvm86-winnt-2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="qvm86-winnt-2.patch" 2004-04-10 Filip Navara * README: Fix typos. * patch.qvm86: Add patch to force page aligned allocations on WinNT hosts. * qvm86-win32.h: Ditto. * qvm86-win32.c (host_alloc_pages, host_free_pages): Allocate pages from non-cached memory instead of standard memory pool. (host_map_user): Guard for unaligned mappings, better error handling. (host_unmap_user): Fix a memory leak. Index: README =================================================================== RCS file: /cvsroot/qvm86/qvm86/README,v retrieving revision 1.4 diff -u -r1.4 README --- README 9 Apr 2005 23:32:54 -0000 1.4 +++ README 10 Apr 2005 07:40:29 -0000 @@ -27,8 +27,8 @@ /dev/qvm86 should be created automatically when you load the module. On Windows hosts you need to copy qvm86.sys to windows/system32/drivers, apply -avm86.reg, and do "net start qvm86". Windows host support is extremely -experimental. The windows code has ben built with the mingw32 toolchains. +qvm86.reg and do "net start qvm86". Windows host support is extremely +experimental. The windows code has been built with the mingw32 toolchains. It is possible to compile on cygwin, but some hacking of makefiles is required to ensure -mno-cygwin is used. Index: patch.qvm86 =================================================================== RCS file: /cvsroot/qvm86/qvm86/patch.qvm86,v retrieving revision 1.3 diff -u -r1.3 patch.qvm86 --- patch.qvm86 9 Apr 2005 23:32:54 -0000 1.3 +++ patch.qvm86 10 Apr 2005 08:47:20 -0000 @@ -365,8 +365,27 @@ retrieving revision 1.8 diff -u -p -r1.8 osdep.c --- osdep.c 21 Feb 2005 20:10:36 -0000 1.8 -+++ osdep.c 9 Apr 2005 19:14:38 -0000 -@@ -308,7 +308,7 @@ void *qemu_malloc(size_t size) ++++ osdep.c 10 Apr 2005 08:44:29 -0000 +@@ -273,15 +273,13 @@ + + #else + +-#ifdef _BSD ++#ifdef _WIN32 ++#include ++#elif defined(_BSD) + #include + #else + #include + #endif +-#ifdef _WIN32 +-/* XXX: find a solution to have page aligned data */ +-#define memalign(align, size) malloc(size) +-#endif + + int qemu_write(int fd, const void *buf, size_t n) + { +@@ -308,7 +306,7 @@ return malloc(size); } @@ -375,6 +394,32 @@ #include #include +@@ -373,7 +371,12 @@ + /* alloc shared memory pages */ + void *qemu_vmalloc(size_t size) + { +-#ifdef _BSD ++#ifdef _WIN32 ++ /* FIXME: this is not exactly optimal solution since VirtualAlloc ++ has 64Kb granularity, but at least it guarantees us that the ++ memory is page aligned. */ ++ return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); ++#elif defined (_BSD) + return valloc(size); + #else + return memalign(4096, size); +@@ -382,7 +385,11 @@ + + void qemu_vfree(void *ptr) + { ++#ifdef _WIN32 ++ VirtualFree(ptr, 0, MEM_RELEASE); ++#else + free(ptr); ++#endif + } + + #endif Index: target-i386/helper2.c =================================================================== RCS file: /cvsroot/qemu/qemu/target-i386/helper2.c,v Index: qvm86-win32.c =================================================================== RCS file: /cvsroot/qvm86/qvm86/qvm86-win32.c,v retrieving revision 1.1 diff -u -r1.1 qvm86-win32.c --- qvm86-win32.c 9 Apr 2005 23:32:54 -0000 1.1 +++ qvm86-win32.c 10 Apr 2005 08:41:32 -0000 @@ -27,7 +27,7 @@ { void * ptr; - ptr = (void *)ExAllocatePoolWithTag(NonPagedPool, size, TAG('Q','V','M','Z')); + ptr = ExAllocatePoolWithTag(NonPagedPool, size, TAG('Q','V','M','Z')); if (!ptr) return NULL; RtlZeroMemory(ptr, size); @@ -39,7 +39,7 @@ { char * ptr; - ptr = (void *)ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE * count, TAG('Q','V','M','P')); + ptr = MmAllocateNonCachedMemory(PAGE_SIZE * count); if (!ptr) return NULL; RtlZeroMemory(ptr, PAGE_SIZE * count); @@ -59,7 +59,7 @@ { if (!ptr) return; - ExFreePool(ptr); + MmFreeNonCachedMemory(ptr, PAGE_SIZE * count); } unsigned long @@ -76,9 +76,21 @@ PMDL mdl; PPFN_NUMBER mdl_pages; + /* fail if the user address isn't aligned */ + if (useraddr & 0xfff) + { + DbgPrint("qvm86: Tried to map unaligned user memory (%p)\n", useraddr); + map->host = NULL; + return; + } + mdl = ExAllocatePool(NonPagedPool, sizeof(MDL) + sizeof(PFN_NUMBER)); if (mdl == NULL) + { + DbgPrint("qvm86: Not enough memory for MDL structure\n"); + map->host = NULL; return; + } mdl_pages = (PPFN_NUMBER)(mdl + 1); MmInitializeMdl(mdl, useraddr, PAGE_SIZE); @@ -87,6 +99,7 @@ map->host = MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority); if (map->host == NULL) { + DbgPrint("qvm86: Can't map MDL to kernel address space\n"); ExFreePool(mdl); return; } @@ -104,6 +117,7 @@ MmUnmapLockedPages(map->host, mdl); MmUnlockPages(mdl); + ExFreePool(mdl); /* TODO: This should probably be done elsewhere. */ map->host = NULL; --------------050308070407060201010103--