qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] KQEMU on Win32 (+patch)


From: Filip Navara
Subject: [Qemu-devel] KQEMU on Win32 (+patch)
Date: Thu, 28 Jul 2005 00:04:18 +0200
User-agent: Mozilla Thunderbird 0.9 (Windows/20041103)

Hi,

as there were recently few questions about KQEMU I decided to dedicate few minutes at answering them and to post a few comments.

> I'm trying to find out why qvm86 crashes the host (instant reboot when right clicking on some icons on the guest desktop). > So i thought if it is possible to use some code from kqemu-win32.c to update qvm86-win32.c

No, I wrote both of the files and I can honestly tell you that copying between them will not help. There is one known case where QVM86 on WinNT platforms crashes the host machine and that's when NOEXECUTE support is enabled (see boot.ini). The method QVM86 uses for executing the code involves copying executable code into an allocated page which unfortunately has the NX bit set. I have an experimental fix for this, but I need someone with adequate environment (AMD64 and Win XP SP2+) to test it... Of course host crash can be caused by other bug.

(Also note that this may apply to KQEMU too though I have no proof.)

> The changelog mentions that the KQEMU accelerator is now available as
> a preliminary executable for Windows. I've not been able to find a
> link to that version anywhere. Should I pull down the sources and
> compile on my Linux machine, or is there a pre-compiled version about?

You can compile it yourself on either Windows machine with MinGW or on linux machine with MinGW cross-compiler. I'm temporary hosting a set of QEMU / KQEMU 0.7.1 for Windows binaries here: http://www.volny.cz/xnavara/qemu-0.7.1.zip. If anyone can offer me hosting for these binaries I would be glad.

As a final note (especially for Fabrice), attached are patches for KQEMU for easier driver installation (quite not there yet, but a bit closer) and implementation of kqemu_schedule (as requested). I'm planing to port this to QVM86 shortly.

Best regards,
Filip
Index: exec-all.h
===================================================================
RCS file: /cvsroot/qemu/qemu/exec-all.h,v
retrieving revision 1.34
diff -u -p -r1.34 exec-all.h
--- exec-all.h  24 Jul 2005 14:14:53 -0000      1.34
+++ exec-all.h  27 Jul 2005 20:53:43 -0000
@@ -607,6 +607,7 @@ int kqemu_init(CPUState *env);
 int kqemu_cpu_exec(CPUState *env);
 void kqemu_flush_page(CPUState *env, target_ulong addr);
 void kqemu_flush(CPUState *env, int global);
+void kqemu_cpu_interrupt(CPUState *env);
 
 static inline int kqemu_is_ok(CPUState *env)
 {
Index: kqemu.c
===================================================================
RCS file: /cvsroot/qemu/qemu/kqemu.c,v
retrieving revision 1.4
diff -u -p -r1.4 kqemu.c
--- kqemu.c     24 Apr 2005 18:03:37 -0000      1.4
+++ kqemu.c     27 Jul 2005 20:53:24 -0000
@@ -456,11 +456,14 @@ int kqemu_cpu_exec(CPUState *env)
     }
 
 #ifdef _WIN32
-    DeviceIoControl(kqemu_fd, KQEMU_EXEC,
-                   kenv, sizeof(struct kqemu_cpu_state),
-                   kenv, sizeof(struct kqemu_cpu_state),
-                   &temp, NULL);
-    ret = kenv->retval;
+    if (DeviceIoControl(kqemu_fd, KQEMU_EXEC,
+                        kenv, sizeof(struct kqemu_cpu_state),
+                        kenv, sizeof(struct kqemu_cpu_state),
+                        &temp, NULL)) {
+        ret = kenv->retval;
+    } else {
+        ret = -1;
+    }
 #else
 #if KQEMU_VERSION >= 0x010100
     ioctl(kqemu_fd, KQEMU_EXEC, kenv);
@@ -544,6 +547,15 @@ int kqemu_cpu_exec(CPUState *env)
         exit(1);
     }
     return 0;
+}
+
+void kqemu_cpu_interrupt(CPUState *env)
+{
+#if defined(_WIN32) && KQEMU_VERSION >= 0x010101
+    /* cancelling the I/O request causes KQEMU to finish executing the 
+       current block and successfully returning. */
+    CancelIo(kqemu_fd);
+#endif
 }
 
 #endif
Index: vl.c
===================================================================
RCS file: /cvsroot/qemu/qemu/vl.c,v
retrieving revision 1.133
diff -u -p -r1.133 vl.c
--- vl.c        24 Jul 2005 18:44:55 -0000      1.133
+++ vl.c        27 Jul 2005 20:54:26 -0000
@@ -875,6 +875,9 @@ static void host_alarm_handler(int host_
                            qemu_get_clock(rt_clock))) {
         /* stop the cpu because a timer occured */
         cpu_interrupt(global_env, CPU_INTERRUPT_EXIT);
+#ifdef USE_KQEMU
+        kqemu_cpu_interrupt(global_env);
+#endif
     }
 }
 
--- kqemu/kqemu-doc.html        Sun Jul 24 20:02:14 2005
+++ kqemu/kqemu-doc.html        Wed Jul 27 23:20:28 2005
@@ -173,16 +173,7 @@ the option <CODE>major=N</CODE> to set a
 <H2><A NAME="SEC5" HREF="kqemu-doc.html#TOC5">2.3 QEMU Accelerator 
Installation for Windows</A></H2>
 
 <P>
-Copy the kqemu driver <TT>`kqemu.sys'</TT> to
-<TT>`c:\winnt\system32\drivers'</TT>.  Then do:
-
-<PRE>
-regedit kqemu.reg 
-</PRE>
-
-<P>
-Now kqemu is installed and you must restart your system.
-
+Right click on <TT>`kqemu.inf'</TT> in Explorer and choose Install.
 
 <P>
 In order to start kqemu, you must do:
--- kqemu/kqemu-doc.texi        Sun Jul 24 20:02:12 2005
+++ kqemu/kqemu-doc.texi        Wed Jul 27 23:19:38 2005
@@ -112,13 +112,7 @@ the option @code{major=N} to set an alte
 
 @section QEMU Accelerator Installation for Windows
 
-Copy the kqemu driver @file{kqemu.sys} to
address@hidden:\winnt\system32\drivers}.  Then do:
address@hidden
-regedit kqemu.reg 
address@hidden example
-
-Now kqemu is installed and you must restart your system.
+Right click on @file{kqemu.inf} in Explorer and choose Install.
 
 In order to start kqemu, you must do:
 @example
--- kqemu/kqemu-win32.c Sun Jul 24 19:39:55 2005
+++ kqemu/kqemu-win32.c Wed Jul 27 23:16:21 2005
@@ -36,6 +36,14 @@ typedef unsigned long long uint64_t;
 /* XXX: make it dynamic according to available RAM */
 #define MAX_LOCKED_PAGES (16386 / 4)
 
+struct kqemu_instance {
+    struct kqemu_state *state;
+    PIRP current_irp;
+};
+
+FAST_MUTEX instance_lock;
+struct kqemu_instance *active_instance;
+
 /* lock the page at virtual address 'user_addr' and return its
    page index. Return -1 if error */
 struct kqemu_user_page *CDECL kqemu_lock_user_page(unsigned long *ppage_index,
@@ -150,19 +158,19 @@ void CDECL kqemu_io_unmap(void *ptr, uns
    execution) */
 int CDECL kqemu_schedule(void)
 {
-    /* XXX: do it */
-    return TRUE;
+    return active_instance->current_irp->Cancel;
 }
 
 void CDECL kqemu_log(const char *fmt, ...)
 {
-    /* XXX: format parameters */
-    DbgPrint("%s", fmt);
-}
+    char log_buf[1024];
+    va_list ap;
 
-struct kqemu_instance {
-    struct kqemu_state *state;
-};
+    va_start(ap, fmt);
+    _vsnprintf(log_buf, sizeof(log_buf), fmt, ap);
+    DbgPrint("kqemu: %s", log_buf);
+    va_end(ap);
+}
 
 NTSTATUS STDCALL
 KQemuCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
@@ -256,12 +264,19 @@ KQemuDeviceControl(PDEVICE_OBJECT Device
                     break;
                 }
                 
+                ExAcquireFastMutex(&instance_lock);
+                active_instance = State;
+                State->current_irp = Irp;
+
                 ctx = kqemu_get_cpu_state(State->state);
                 
                 RtlCopyMemory(ctx, Irp->AssociatedIrp.SystemBuffer, 
                               sizeof(*ctx));
                 ret = kqemu_exec(State->state);
                 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, ctx, 
sizeof(*ctx));
+
+                ExReleaseFastMutex(&instance_lock);
+                
                 Irp->IoStatus.Information = sizeof(*ctx);
                 Status = STATUS_SUCCESS;
             }
@@ -311,6 +326,8 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
              (KQEMU_VERSION) & 0xff);
 
     MmLockPagableCodeSection(DriverEntry);
+
+    ExInitializeFastMutex(&instance_lock);
 
     DriverObject->MajorFunction[IRP_MJ_CREATE] = KQemuCreate;
     DriverObject->MajorFunction[IRP_MJ_CLOSE] = KQemuClose;
--- kqemu/kqemu.h       Sun Jul 24 19:38:27 2005
+++ kqemu/kqemu.h       Wed Jul 27 23:07:48 2005
@@ -1,7 +1,7 @@
 #ifndef KQEMU_H
 #define KQEMU_H
 
-#define KQEMU_VERSION 0x010100
+#define KQEMU_VERSION 0x010101
 
 struct kqemu_segment_cache {
     uint32_t selector;
--- kqemu/kqemu.inf     Thu Jan  1 01:00:00 1970
+++ kqemu/kqemu.inf     Wed Jul 27 22:34:39 2005
@@ -0,0 +1,64 @@
+; Copyright (C) 2005 Filip Navara, Damien Mascord
+
+[Version]
+Signature   = "$Windows NT$"
+Class       = System
+ClassGuid   = {4D36E97D-E325-11CE-BFC1-08002BE10318}
+Provider    = %Author%
+DriverVer   = 04/28/2005,1.0
+
+[DestinationDirs]
+DefaultDestDir    = 12
+KQemu.DriverFiles = 12
+KQemu.InfFiles    = 10,inf
+
+[SourceDisksNames]
+1 = %InstDisk%
+   
+[SourceDisksFiles]
+kqemu.sys = 1
+
+[Manufacturer]
+%Author% = KQemu.Manufacturer
+
+[KQemu.Manufacturer]
+%Description% = DefaultInstall,kqemu
+
+[DefaultInstall.NT]
+CopyFiles = KQemu.DriverFiles, KQemu.InfFiles
+AddReg = KQemu.UninstallRegistry
+
+[DefaultInstall.NT.Services]
+AddService = kqemu,,KQemuService_Inst
+
+[Uninstall.NT]
+DelFiles = KQemu.DriverFiles, KQemu.InfFiles
+DelReg = KQemu.UninstallRegistry
+
+[Uninstall.NT.Services]
+DelService = kqemu,0x00000200
+
+[KQemu.DriverFiles]
+kqemu.sys
+
+[KQemu.InfFiles]
+kqemu.inf
+
+[KQemu.UninstallRegistry]
+HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\KQEMU,"DisplayName",,%Description%
+HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\KQEMU,"UninstallString",0x20000,"RunDll32
 setupapi.dll,InstallHinfSection Uninstall 132 %SystemRoot%\inf\kqemu.inf"
+
+[KQemuService_Inst]
+DisplayName   = %Description%
+ServiceType   = %SERVICE_KERNEL_DRIVER%
+StartType     = %SERVICE_DEMAND_START%
+ErrorControl  = %SERVICE_ERROR_NORMAL%
+ServiceBinary = %12%\kqemu.sys
+
+[Strings]
+Author = "Fabrice Bellard"
+Description = "KQEMU virtualisation module for QEMU"
+InstDisk = "KQEMU Install Disk"
+SERVICE_KERNEL_DRIVER = 1
+SERVICE_DEMAND_START = 3
+SERVICE_ERROR_NORMAL = 1
--- kqemu/kqemu.reg     Tue Apr 12 23:24:49 2005
+++ /dev/null   Wed Jul 27 23:24:00 2005
@@ -1,7 +0,0 @@
-REGEDIT4
-
-[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\kqemu]
-"Type"=dword:00000001
-"Start"=dword:00000003
-"ErrorControl"=dword:00000001
-"DisplayName"="kqemu"

reply via email to

[Prev in Thread] Current Thread [Next in Thread]