Skip to contentSkip to conversation

Suggestion - trap window-close of VM

Qemu-devel In review Ryan Rempel 19 participants 49 messages Mar 27, 2005 – Jul 29, 2005

lore
Share & tools
lore
#0 lore raw

On Mon, Nov 29, 2004 at 21:46:54 +0100, Lennert Buytenhek wrote

Quoted 9 lines · Richard Neill
Quoted 4 lines

A thought that occurred to me. If one is running a virtual machine (eg copy of WinXP), then simply closing the qemu window is a really bad idea, since it will effectively crash the guest.

Related thought -- it would be way cool if we could make killing qemu do exactly happens when you press the power button on an ACPI-capable machine with any recent OS on it (auto shutdown.)

I was wondering if anyone has followed up on this suggestion. I'm putting together a Qemu-based setup for some relatively naive users, and ideally I'd like to be able to deal with this in a reasonable elegant way (the ACPI hook sounds very elegant indeed).

Alternatively, how do people deal with the problem of naive users who might just close the Qemu window without shutting down the guest properly? I'm working in a KDE environment -- perhaps there is a way in KDE to prevent the close button from appearing? But that wouldn't catch every case either (for instance, if the user were to shut down the host).

#1 lore raw
Quoted 19 lines · Ryan Rempel

On Mon, Nov 29, 2004 at 21:46:54 +0100, Lennert Buytenhek wrote

Quoted 11 lines · Richard Neill
Quoted 5 lines

A thought that occurred to me. If one is running a virtual machine (eg copy of WinXP), then simply closing the qemu window is a really bad idea, since it will effectively crash the guest.

Related thought -- it would be way cool if we could make killing qemu do exactly happens when you press the power button on an ACPI-capable machine with any recent OS on it (auto shutdown.)

I was wondering if anyone has followed up on this suggestion. I'm putting together a Qemu-based setup for some relatively naive users, and ideally I'd like to be able to deal with this in a reasonable elegant way (the ACPI hook sounds very elegant indeed).

Quoted 7 lines

Alternatively, how do people deal with the problem of naive users who might just close the Qemu window without shutting down the guest properly? I'm working in a KDE environment -- perhaps there is a way in KDE to prevent the close button from appearing? But that wouldn't catch every case either (for instance, if the user were to shut down the host).

This sounds like a good idea. An alternative solution, that might be more straightforward to implement if Qemu doesn't implement ACPI yet, would be for the kill signal to simply cause Qemu to do the equivalent of entering 'stop' and 'savevm <somefilepath>' into the monitor.

#2 lore raw

Hi,

I've attached a patch against the 2005-03-26 snapshot that implements two '-on-quit' options for the emulator window: ignore-unless-halted and suspend-unless-halted, that aim to make it safe to allow naive users to (try to) close the VM window by trapping requests to shutdown and either ignoring them or forcing a save of the VM state before obeying them.

Caveat: I'll come clean straight away that the patch is implemented using a nasty TARGET_i386-specific hack that detects whether the guest operating system has permanently halted by looking to see if the last instruction executed was 0xF4 and, if so, whether the IF flag is cleared. Saying that, this system appears to work reasonably well on my Pentium host running a Windows 2000 guest, but I have not tested it on any other systems.

Usage:

1. If you provide naive users with a variation on the following command line, then you can let your naive users (try to) close the VM window as much as they like. Unless the guest has permanently halted, attempts to close the VM window should save the VM state to 'suspended.qemu' in the current working directory before qemu exits. The same command line will restart the VM where it left off. Then, once the guest has permanently halted, qemu will delete the suspended.qemu file so that the next launch of qemu will boot afresh:

qemu -hda win2k.raw -m 64 -monitor null -loadvm suspended.qemu -on-quit suspend-unless-halted

2. Alternatively, the following command will make qemu ignore the user's request to close the emulator window unless the guest has already permanently halted:

qemu -hda win2k.raw -m 64 -monitor null -on-quit ignore-unless-halted

3. If you combine this with a test of whether qemu is already running, then it should be safe to let naive users try to both launch and to close qemu as much as they like. e.g.

killall -0 qemu 2>/dev/null; if [ $? == 1 ]; then qemu -hda win2k.raw -m 64 -monitor null -loadvm suspended.qemu -on-quit suspend-unless-halted; fi &

4. Finally, if your leave out the -on-quit option altogether, then qemu's behaviour should remain completely unchanged.

I hope this is useful for some i386/W2K users out there. Any constructive criticism appreciated. If you know how I could improve permanent halt detection (that doesn't require in-depth knowledge of APM or ACPI) then please let me know.

Struan

Quoted 28 lines · Struan Bartlett
Quoted 19 lines · Ryan Rempel

On Mon, Nov 29, 2004 at 21:46:54 +0100, Lennert Buytenhek wrote

Quoted 11 lines · Richard Neill
Quoted 5 lines

A thought that occurred to me. If one is running a virtual machine (eg copy of WinXP), then simply closing the qemu window is a really bad idea, since it will effectively crash the guest.

Related thought -- it would be way cool if we could make killing qemu do exactly happens when you press the power button on an ACPI-capable machine with any recent OS on it (auto shutdown.)

I was wondering if anyone has followed up on this suggestion. I'm putting together a Qemu-based setup for some relatively naive users, and ideally I'd like to be able to deal with this in a reasonable elegant way (the ACPI hook sounds very elegant indeed).

Quoted 7 lines

Alternatively, how do people deal with the problem of naive users who might just close the Qemu window without shutting down the guest properly? I'm working in a KDE environment -- perhaps there is a way in KDE to prevent the close button from appearing? But that wouldn't catch every case either (for instance, if the user were to shut down the host).

Quoted 10 lines

This sounds like a good idea. An alternative solution, that might be more straightforward to implement if Qemu doesn't implement ACPI yet, would be for the kill signal to simply cause Qemu to do the equivalent of entering 'stop' and 'savevm <somefilepath>' into the monitor.

------------------------------------------------------------------------

_______________________________________________
Qemu-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

vl.c +63 -0
@@ -139,6 +139,9 @@
 int graphic_height = 600;
 int graphic_depth = 15;
 int full_screen = 0;
+#ifdef TARGET_I386
+int on_quit = 0;
+#endif
 TextConsole *vga_console;
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
@@ -2675,6 +2678,17 @@
                         qemu_get_clock(rt_clock));
 }
 
+#ifdef TARGET_I386
+int ishalted() {
+   uint8_t buf[16];
+   uint64_t v;
+	
+   cpu_memory_rw_debug(cpu_single_env, cpu_single_env->eip-1, buf, 16, 0);
+   v = ldub_raw(buf);
+   return (v == 0xf4) && ( !(cpu_single_env->eflags & 0x200) );
+}
+#endif
+
 int main_loop(void)
 {
     int ret, timeout;
@@ -2684,9 +2698,16 @@
         if (vm_running) {
             ret = cpu_exec(env);
             if (shutdown_requested) {
+#ifdef TARGET_I386	       
+	       if( on_quit == 0 || on_quit == 2 || ( on_quit == 1 && ishalted() ) ) {
+#endif		  
                 ret = EXCP_INTERRUPT; 
                 break;
             }
+#ifdef TARGET_I386	       
+ 	       shutdown_requested = 0;
+ 	    }
+#endif
             if (reset_requested) {
                 reset_requested = 0;
                 qemu_system_reset();
@@ -2783,6 +2804,11 @@
            "-std-vga        simulate a standard VGA card with VESA Bochs Extensions\n"
            "                (default is CL-GD5446 PCI VGA)\n"
 #endif
+#ifdef TARGET_I386
+	   "-on-quit [ignore-unless-halted|suspend-unless-halted]\n"
+	   "                select the behaviour when the emulator window is asked to quit\n"
+	   "                (default is none)\n"
+#endif
            "-loadvm file    start right away with a saved state (loadvm in monitor)\n"
            "\n"
            "During emulation, the following keys are useful:\n"
@@ -2864,6 +2890,10 @@
     QEMU_OPTION_full_screen,
     QEMU_OPTION_pidfile,
     QEMU_OPTION_no_kqemu,
+
+#ifdef TARGET_I386	       
+    QEMU_OPTION_on_quit
+#endif     
 };
 
 typedef struct QEMUOption {
@@ -2932,6 +2962,9 @@
     { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
     { "full-screen", 0, QEMU_OPTION_full_screen },
     { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
+#ifdef TARGET_I386
+    { "on-quit", HAS_ARG, QEMU_OPTION_on_quit },
+#endif   
 
     /* temporary options */
     { "pci", 0, QEMU_OPTION_pci },
@@ -3383,6 +3416,19 @@
             case QEMU_OPTION_pidfile:
                 create_pidfile(optarg);
                 break;
+#ifdef TARGET_I386   	       
+            case QEMU_OPTION_on_quit:
+	        if(!strcmp(optarg, "ignore-unless-halted")) {
+		   fprintf(stderr, "%s enabled\n", optarg);
+		   on_quit = 1;
+		}
+		else if(!strcmp(optarg, "suspend-unless-halted")) {
+		   fprintf(stderr, "%s enabled\n", optarg);
+		   on_quit = 2;
+		}
+	        else on_quit = 0;
+	        break;
+#endif	       
 #ifdef USE_KQEMU
             case QEMU_OPTION_no_kqemu:
                 kqemu_allowed = 0;
@@ -3696,6 +3742,23 @@
         }
     }
     main_loop();
+
+#ifdef TARGET_I386   
+    if( on_quit == 2 ) {
+       char *f = "suspended.qemu";
+       if( ishalted() ) {
+ 	
+ 	 fprintf(stderr, "VM is halted: removing suspend file %s\n",f);
+ 	 unlink(f);
+ 	 /* qemu_savevm(f); */
+       }
+       else {
+ 	 fprintf(stderr, "Autosaving VM to file %s\n",f);
+ 	 qemu_savevm(f);
+       }
+    }
+#endif   
+   
     quit_timers();
     return 0;
 }
#3 lore raw

Would it be too hard to implement a proper "state save" such as in Virtual PC and others? In my experience, that single feature is the most important of any emulation system; ability to work for a while, then suspend the whole system for days, weeks, or years, and catching up where you last left it.

Is there some practical reason why QEmu should not offer this?

-ak

28.3.2005 kello 14:34, Struan Bartlett kirjoitti:

Hi,

Quoted 202 lines

I've attached a patch against the 2005-03-26 snapshot that implements
two '-on-quit' options for the emulator window: ignore-unless-halted and suspend-unless-halted, that aim to make it safe to allow naive users to (try to) close the VM window by trapping requests to shutdown and either ignoring them or forcing a save of the VM state before obeying them.

Caveat: I'll come clean straight away that the patch is implemented
using a nasty TARGET_i386-specific hack that detects whether the guest operating system has permanently halted by looking to see if the last instruction executed was 0xF4 and, if so, whether the IF flag is cleared. Saying that, this system appears to work reasonably well on my Pentium host running a Windows 2000 guest, but I have not tested it on any other systems.

Usage:

1. If you provide naive users with a variation on the following
command line, then you can let your naive users (try to) close the VM window as much as they like. Unless the guest has permanently halted, attempts to close the VM window should save the VM state to 'suspended.qemu' in the current working directory before qemu exits. The same command line will restart the VM where it left off. Then, once the guest has permanently halted, qemu will delete the suspended.qemu file so that the next launch of qemu will boot afresh:

qemu -hda win2k.raw -m 64 -monitor null -loadvm suspended.qemu -on-quit suspend-unless-halted

2. Alternatively, the following command will make qemu ignore the
user's request to close the emulator window unless the guest has already permanently halted:

qemu -hda win2k.raw -m 64 -monitor null -on-quit ignore-unless-halted

3. If you combine this with a test of whether qemu is already
running, then it should be safe to let naive users try to both launch and to close qemu as much as they like. e.g.

killall -0 qemu 2>/dev/null; if [ $? == 1 ]; then qemu -hda win2k.raw -m 64 -monitor null -loadvm suspended.qemu -on-quit suspend-unless-halted; fi &

4. Finally, if your leave out the -on-quit option altogether, then
qemu's behaviour should remain completely unchanged.

I hope this is useful for some i386/W2K users out there. Any
constructive criticism appreciated. If you know how I could improve permanent halt detection (that doesn't require in-depth knowledge of APM or ACPI) then please let me know.

Struan

Struan Bartlett wrote:
Ryan Rempel wrote:
On Mon, Nov 29, 2004 at 21:46:54 +0100, Lennert Buytenhek wrote

On Mon, Nov 29, 2004 at 08:43:56PM +0000, Richard Neill wrote:

A thought that occurred to me. If one is running a virtual machine (eg copy of WinXP), then simply closing the qemu window is a really bad idea, since it will effectively crash the guest.

Related thought -- it would be way cool if we could make killing qemu do exactly happens when you press the power button on an ACPI-capable machine with any recent OS on it (auto shutdown.)

I was wondering if anyone has followed up on this suggestion. I'm putting together a Qemu-based setup for some relatively naive users, and ideally I'd like to be able to deal with this in a reasonable elegant way (the ACPI hook sounds very elegant indeed).

Alternatively, how do people deal with the problem of naive users who
might just close the Qemu window without shutting down the guest
properly? I'm working in a KDE environment -- perhaps there is a way
in KDE to prevent the close button from appearing? But that wouldn't
catch every case either (for instance, if the user were to shut down
the host).
This sounds like a good idea. An alternative solution, that might be
more straightforward to implement if Qemu doesn't implement ACPI yet, would be for the kill signal to simply cause Qemu to do the equivalent of entering 'stop' and 'savevm <somefilepath>' into the monitor.

_______________________________________________
Qemu-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

vl.c +14 -0
@@ -139,6 +139,9 @@
 int graphic_height = 600;
 int graphic_depth = 15;
 int full_screen = 0;
+#ifdef TARGET_I386
+int on_quit = 0;
+#endif
 TextConsole *vga_console;
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
@@ -2675,6 +2678,17 @@
                         qemu_get_clock(rt_clock));
 }
 
+#ifdef TARGET_I386
+int ishalted() {
+   uint8_t buf[16];
+   uint64_t v;
+	
+   cpu_memory_rw_debug(cpu_single_env, cpu_single_env->eip-1, buf, 
 16, 0);
+   v = ldub_raw(buf);
+   return (v == 0xf4) && ( !(cpu_single_env->eflags & 0x200) );
+}
+#endif
+
 int main_loop(void)
 {
     int ret, timeout;
vl.c +7 -0
@@ -2684,9 +2698,16 @@
         if (vm_running) {
             ret = cpu_exec(env);
             if (shutdown_requested) {
+#ifdef TARGET_I386	
+	       if( on_quit == 0 || on_quit == 2 || ( on_quit == 1 && 
 ishalted() ) ) {
+#endif		
                 ret = EXCP_INTERRUPT;
                 break;
             }
+#ifdef TARGET_I386	
+ 	       shutdown_requested = 0;
+ 	    }
+#endif
             if (reset_requested) {
                 reset_requested = 0;
                 qemu_system_reset();
vl.c +0 -0
@@ -2783,6 +2804,11 @@
            "-std-vga        simulate a standard VGA card with VESA 

Bochs Extensions\n"
" (default is CL-GD5446 PCI VGA)\n"
#endif

vl.c +3 -0
+#ifdef TARGET_I386
+	   "-on-quit [ignore-unless-halted|suspend-unless-halted]\n"
+	   "                select the behaviour when the emulator window is 

asked to quit\n"

vl.c +2 -0
+	   "                (default is none)\n"
+#endif
            "-loadvm file    start right away with a saved state 

(loadvm in monitor)\n"
"\n"
"During emulation, the following keys are useful:\n"

vl.c +37 -0
@@ -2864,6 +2890,10 @@
     QEMU_OPTION_full_screen,
     QEMU_OPTION_pidfile,
     QEMU_OPTION_no_kqemu,
+
+#ifdef TARGET_I386	
+    QEMU_OPTION_on_quit
+#endif
 };
 
 typedef struct QEMUOption {
@@ -2932,6 +2962,9 @@
     { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
     { "full-screen", 0, QEMU_OPTION_full_screen },
     { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
+#ifdef TARGET_I386
+    { "on-quit", HAS_ARG, QEMU_OPTION_on_quit },
+#endif
 
     /* temporary options */
     { "pci", 0, QEMU_OPTION_pci },
@@ -3383,6 +3416,19 @@
             case QEMU_OPTION_pidfile:
                 create_pidfile(optarg);
                 break;
+#ifdef TARGET_I386   	
+            case QEMU_OPTION_on_quit:
+	        if(!strcmp(optarg, "ignore-unless-halted")) {
+		   fprintf(stderr, "%s enabled\n", optarg);
+		   on_quit = 1;
+		}
+		else if(!strcmp(optarg, "suspend-unless-halted")) {
+		   fprintf(stderr, "%s enabled\n", optarg);
+		   on_quit = 2;
+		}
+	        else on_quit = 0;
+	        break;
+#endif	
 #ifdef USE_KQEMU
             case QEMU_OPTION_no_kqemu:
                 kqemu_allowed = 0;
@@ -3696,6 +3742,23 @@
         }
     }
     main_loop();
+
+#ifdef TARGET_I386
+    if( on_quit == 2 ) {
+       char *f = "suspended.qemu";
+       if( ishalted() ) {
+ 	
+ 	 fprintf(stderr, "VM is halted: removing suspend file %s\n",f);
+ 	 unlink(f);
+ 	 /* qemu_savevm(f); */
+       }
+       else {
+ 	 fprintf(stderr, "Autosaving VM to file %s\n",f);
+ 	 qemu_savevm(f);
+       }
+    }
+#endif
+
     quit_timers();
     return 0;
 }

_______________________________________________
Qemu-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

#4 lore raw
Quoted 7 lines · Asko Kauppi

Would it be too hard to implement a proper "state save" such as in Virtual PC and others? In my experience, that single feature is the most important of any emulation system; ability to work for a while, then suspend the whole system for days, weeks, or years, and catching up where you last left it.

Is there some practical reason why QEmu should not offer this?

It already does. See the savevm and loadvm monitor commands.

Paul

#47 lore raw
In reply to Ryan Rempel
Quoted 6 lines

Alternatively, how do people deal with the problem of naive users who might just close the Qemu window without shutting down the guest properly? I'm working in a KDE environment -- perhaps there is a way in KDE to prevent the close button from appearing? But that wouldn't catch every case either (for instance, if the user were to shut down the host).

Doesn't X allow a handler to be called for events like window closing? You could use this to pop up a "You've asked to close this VM. Kill, save or cancel?" message and allow the user to choose the appropriate option.

$0.02,
Mark

#48 lore raw
Quoted 10 lines · Mark Williamson
Quoted 6 lines

Alternatively, how do people deal with the problem of naive users who might just close the Qemu window without shutting down the guest properly? I'm working in a KDE environment -- perhaps there is a way in KDE to prevent the close button from appearing? But that wouldn't catch every case either (for instance, if the user were to shut down the host).

Doesn't X allow a handler to be called for events like window closing? You could use this to pop up a "You've asked to close this VM. Kill, save or cancel?" message and allow the user to choose the appropriate option.

Yes it does. Try closing your mail window when composing a message, or closing open office with an unsaved document. They'll ask you if you want to save or discard changes. VMWare asks you if you want to close the running system if you try to use the close window command. So yes, you can trap that.

j----- k-----

Signature · 3 lines
Joshua Kugler
CDE System Administrator
http://distance.uaf.edu/
#5 lore raw
In reply to Struan Bartlett
Quoted 6 lines · Struan Bartlett

I've attached a patch against the 2005-03-26 snapshot that implements two '-on-quit' options for the emulator window: ignore-unless-halted and suspend-unless-halted, that aim to make it safe to allow naive users to (try to) close the VM window by trapping requests to shutdown and either ignoring them or forcing a save of the VM state before obeying them.

Quoted 7 lines

Caveat: I'll come clean straight away that the patch is implemented using a nasty TARGET_i386-specific hack that detects whether the guest operating system has permanently halted by looking to see if the last instruction executed was 0xF4 and, if so, whether the IF flag is cleared. Saying that, this system appears to work reasonably well on my Pentium host running a Windows 2000 guest, but I have not tested it on any other systems.

This isn't working quite right for me with a Windows 98 guest -- it traps the attempt to close the window all right, but it doesn't let the window close even when Window 98 has in fact shut down. I wonder whether this is related to the "Windows 98 doesn't use the HLT instruction" problem that is noted elsewhere (since that apparently doesn't affect Windows 2000).

But I should say thanks first -- this is definitely the kind of thing I was looking for!

#6 lore raw
Quoted 3 lines

This isn't working quite right for me with a Windows 98 guest -- it traps the attempt to close the window all right, but it doesn't let the window close even when Window 98 has in fact shut down.

As far as qemu is concerned there's nothing special about windows being "shut down". ie. it's not possible to tell if windows is doing something useful, or just sitting there waiting for you to turn it off.

Quoted 4 lines

I wonder
whether this is related to the "Windows 98 doesn't use the HLT instruction" problem that is noted elsewhere (since that apparently doesn't affect Windows 2000).

No. the HLT thing is just windows 9x being crap. It also happens on real hardware.

In theory windows should be able to "turn off" qemu using APM, like it does on real machines. However there seem to be bugs in the qemu implementation that stop this working.

Paul

#7 lore raw
Quoted 7 lines · Paul Brook
Quoted 3 lines

This isn't working quite right for me with a Windows 98 guest -- it traps the attempt to close the window all right, but it doesn't let the window close even when Window 98 has in fact shut down.

As far as qemu is concerned there's nothing special about windows being "shut down". ie. it's not possible to tell if windows is doing something useful, or just sitting there waiting for you to turn it off.

Just to clarify, I was commenting on Struan's patch, which does try to determine whether windows is "shut down" -- his patch seems to work with a Windows 2000 guest, but not a Windows 98 guest (he reported the former, I was reporting the latter).

Quoted 11 lines
Quoted 4 lines

I wonder
whether this is related to the "Windows 98 doesn't use the HLT instruction" problem that is noted elsewhere (since that apparently doesn't affect Windows 2000).

No. the HLT thing is just windows 9x being crap. It also happens on real hardware.

In theory windows should be able to "turn off" qemu using APM, like it does on real machines. However there seem to be bugs in the qemu implementation that stop this working.

Again to clarify, qemu does ordinarily quit as expected when I shut down a Windows 98 guest -- I was commenting specifically on Struan's patch, rather than qemu's normal behaviour. I was speculating that the HLT instruction might have an impact on Struan's method to detect whether windows had shut down (since it was a known difference between Windows 98 and 2000), but I may well be barking up the wrong tree there.

#8 lore raw

Thanks for testing my patch on Windows 98.

Quoted 14 lines · Ryan Rempel
Quoted 10 lines · Paul Brook
Quoted 5 lines

This isn't working quite right for me with a Windows 98 guest -- it traps the attempt to close the window all right, but it doesn't let the window close even when Window 98 has in fact shut down.

As far as qemu is concerned there's nothing special about windows being "shut down". ie. it's not possible to tell if windows is doing something useful, or just sitting there waiting for you to turn it off.

Quoted 6 lines

Just to clarify, I was commenting on Struan's patch, which does try to determine whether windows is "shut down" -- his patch seems to work with a Windows 2000 guest, but not a Windows 98 guest (he reported the former, I was reporting the latter).

To respond to Paul's original point, in fact it does seem possible in some circumstances to tell if Windows is doing something useful, or just sitting there waiting for you to turn it off - at least it does for Windows 2000. My patch works by examining the emulated i386 EIP and EFLAGS registers. It subtracts one from the EIP (to find the address of the previously-executed instruction) and examines the virtual memory location pointed to. If the memory location contains 0xF4 (HLT) then it examines the EFLAGS register. If the IF (Interrupt-enable) flag is cleared, then one might in fact assume that Windows 2000 is sitting there just waiting for you to turn it off. The assumption here is that if interrupts are disabled then there is no way the processor's halt state can be interrupted.

Quoted 9 lines
Quoted 9 lines
Quoted 9 lines

I wonder
whether this is related to the "Windows 98 doesn't use the HLT instruction" problem that is noted elsewhere (since that apparently doesn't affect Windows 2000).

Quoted 4 lines
Quoted 4 lines

No. the HLT thing is just windows 9x being crap. It also happens on real hardware.

I reckon you might be right and that it's because Win 9x doesn't use the HLT instruction and the code it executes at shutdown is different. If I had an installation of Win98 to hand, I would use the monitor console to take a look at what the EIP was doing and what instructions were being executed in the shutdown state and then adjust the patch to check for this circumstance too, should that be possible.

Quoted 5 lines
Quoted 5 lines

In theory windows should be able to "turn off" qemu using APM, like it does on real machines. However there seem to be bugs in the qemu implementation that stop this working.

Is the bug in the BIOS or in Qemu?

Quoted 10 lines

Again to clarify, qemu does ordinarily quit as expected when I shut down a Windows 98 guest -- I was commenting specifically on Struan's patch, rather than qemu's normal behaviour. I was speculating that the HLT instruction might have an impact on Struan's method to detect whether windows had shut down (since it was a known difference between Windows 98 and 2000), but I may well be barking up the wrong tree there.

If Qemu ordinarily quits as expected when you shut down a Windows 98 guest, then the '-on-quit ignore-unless-halted' option shouldn't be used although the '-on-quit suspend-unless-halted' option could still be useful.

Struan

#9 lore raw
Quoted 8 lines · Struan Bartlett

It subtracts one from the EIP (to find the address of
the previously-executed instruction) and examines the virtual memory location pointed to. If the memory location contains 0xF4 (HLT) then it examines the EFLAGS register. If the IF (Interrupt-enable) flag is cleared, then one might in fact assume that Windows 2000 is sitting there just waiting for you to turn it off. The assumption here is that if interrupts are disabled then there is no way the processor's halt state can be interrupted.

What happens if the previous instruction is a multi-byte instruction that happens to have 0xf4 as its last byte?

--L

#17 lore raw

APM bug Re: [Qemu-devel] Re: Suggestion - trap window-close of VM

In reply to Paul Brook
Quoted 8 lines · Paul Brook
Quoted 5 lines

This isn't working quite right for me with a Windows 98 guest -- it traps the attempt to close the window all right, but it doesn't let the window close even when Window 98 has in fact shut down.

In theory windows should be able to "turn off" qemu using APM, like it does on real machines. However there seem to be bugs in the qemu implementation that stop this working.

I thought I'd have a little look into why Windows 2000 doesn't turn off qemu using APM properly. I enabled DEBUG_BIOS in hw/pc.c then downloaded the latest Debian source for the Bochs bios v1.121 and defined DEBUG_ROMBIOS and DEBUG_APM both to be 1. I recompiled and installed the bios and ran qemu to load up Windows 2000. What we get seems interesting. By the time Qemu boots Windows 2000 to its first progress-bar, it has printed the following debug statements (with my explanation added in square brackets):

APM: EAX=00005300 [53 is the int 15h identifier for APM checked for in rombios.c. 00 is the APM installation check function]
APM: EAX=00005301 [01 is the APM real mode interface connect]
APM: EAX=0000530e [0e appears to request APM driver version]
APM: EAX=00005300 [00, again, is the APM installation check - why is this called twice?]
APM: EAX=00005304 [04 is APM interface disconnect]

Then, while Windows 2000 boots and until shutdown is complete, I get no more debug statements. My question is, why not? I'm no APM expert but, judging from the 'apmbios.S' comments I might expect to see APM: EAX=00005303 [03 is APM 32 bit protected mode interface connect]. I could speculate that the return code from APM function 0e does not satisfy Windows 2000 for some reason, so it does another installation check and then disconnects the APM interface entirely - hence no APM functionality in Windows 2000.

If I get more time I may research the APM functions more fully. In the meantime, if anyone can suggest any alternative theories or how to test them, I'd be curious.

Struan

#10 lore raw
In reply to Lennert Buytenhek
Quoted 11 lines · Lennert Buytenhek
Quoted 3 lines · Struan Bartlett

It subtracts one from the EIP (to find the address of the previously-executed instruction) and examines the virtual memory location pointed to. If the memory location contains 0xF4 (HLT) then it examines the EFLAGS register. If the IF (Interrupt-enable) flag is cleared, then one might in fact assume that Windows 2000 is sitting there just waiting for you to turn it off. The assumption here is that if interrupts are disabled then there is no way the processor's halt state can be interrupted.

What happens if the previous instruction is a multi-byte instruction that happens to have 0xf4 as its last byte?

Before I did the IF check, that was a problem but now it should be ok. In your scenario, the IF flag would probably be found still to be set so it would be (correctly) assumed that Windows 2000 was not waiting to be turned off and qemu would continue normally.

S

#11 lore raw
Quoted 9 lines · Struan Bartlett
Quoted 9 lines
Quoted 8 lines

It subtracts one from the EIP (to find the address of
the previously-executed instruction) and examines the virtual memory location pointed to. If the memory location contains 0xF4 (HLT) then it examines the EFLAGS register. If the IF (Interrupt-enable) flag is cleared, then one might in fact assume that Windows 2000 is sitting there just waiting for you to turn it off. The assumption here is that if interrupts are disabled then there is no way the processor's halt state can be interrupted.

Quoted 7 lines
Quoted 2 lines

What happens if the previous instruction is a multi-byte instruction that happens to have 0xf4 as its last byte?

Before I did the IF check, that was a problem but now it should be ok. In your scenario, the IF flag would probably be found still to be set so it would be (correctly) assumed that Windows 2000 was not waiting to be turned off and qemu would continue normally.

So now you're implying that disabling interrupts is something that only very rarely happens, for example when shutting down the machine? I don't think that is a very realistic assumption.

--L

#12 lore raw

If I understand this correctly, it's specifically doing a halt with interrupts disabled. In theory that should just halt the processor indefinitely, since interrupts cannot be received. I can't imagine this being a common scenario for any software other than when it is completely shut down, unless of course you are explicitly expecting a non-maskable interrupt, which cannot be disabled, during a halt instruction. Again, I don't think it's all that common.

- Leo Reiter

Quoted 7 lines · Lennert Buytenhek

So now you're implying that disabling interrupts is something that only very rarely happens, for example when shutting down the machine? I don't think that is a very realistic assumption.

--L

Signature · 8 lines
Leonardo E. Reiter
Vice President of Engineering

Win4Lin, Inc.
Virtual Computing from Desktop to Data Center
Main: +1 512 339 7979
Fax: +1 512 532 6501
http://www.win4lin.com
#13 lore raw

I think there's two good points here.

Of course it's true that, just because *(EIP-1) == 0xF4 and IF is cleared, it cannot be deduced with certainty that the previous instruction was an HLT and not a multi-byte instruction ending in 0xF4. I was wrong about that. Something like 'cli' then 'mov al,0xf4' might have been the previous instructions. You are right.

However, as a practical matter, I think it's true that this can't be a very common scenario. Before I added the 'IF-cleared' test to my patch I was routinely experiencing false positives (i.e. when closing the window, the patch would judge the guest as having halted when it clearly wasn't). But since I added the IF-cleared test to the patch I haven't personally experienced one single false positive (i.e. it has never so-far judged the guest as having halted when it wasn't) - and I must have tested it over fifty times so far. I understand though that this may not yet be good enough reliability for some people, but if it helps anybody at all I'd be pleased.

Anyhow, I can't say I find this patch's halt-detection method very satisfactory except as a purely interim measure. A solution to the APM bug would be much preferable. I'm looking at the APM Bios Interface Specification v1.2 now (http://www.phamhoaiviet.com/archives%5Cebooks%5Capmv12.rtf)

Struan

Quoted 11 lines · Leonardo E. Reiter

If I understand this correctly, it's specifically doing a halt with interrupts disabled. In theory that should just halt the processor indefinitely, since interrupts cannot be received. I can't imagine this being a common scenario for any software other than when it is completely shut down, unless of course you are explicitly expecting a non-maskable interrupt, which cannot be disabled, during a halt instruction. Again, I don't think it's all that common.

- Leo Reiter

Quoted 4 lines · Lennert Buytenhek

So now you're implying that disabling interrupts is something that only very rarely happens, for example when shutting down the machine? I don't think that is a very realistic assumption.

#16 lore raw
In reply to Leonardo E. Reiter
Quoted 2 lines · Leonardo E. Reiter

If I understand this correctly, it's specifically doing a halt with interrupts disabled.

No.

It checks that the byte before the current instruction pointer is 0xf1. That 0xf1 could be single-byte hlt instruction by itself, or it could be the last byte of a multi-byte instruction.

--L

#14 lore raw
In reply to Struan Bartlett

I suppose there's a reason, but why not trigger or set a flag on actual HLT instruction executed (while interrupts disabled)? That would avoid the kludge of peeking behind the instruction pointer.

I'm no expert, but perhaps such flag is already part of the CPU emulation and can simply be read? If not it doesn't seem like such a bad feature to add...

-- John.

#18 lore raw

Re: APM bug Re: [Qemu-devel] Re: Suggestion - trap window-close of VM

In reply to Struan Bartlett

Having reviewed some of the APM1.2 specification, first impression is that the APM bios is required to provide not only a real-mode and protected 32-bit mode interface to its functions, but also a 16-bit protected mode interface, which the apmbios.S code apparently does not have.

I've tried adding one - although I'm not sure it's correct - and adjusting function 0x00 (APM installation check) to return 0x03 in cx (instead of 0x02 to signify the availability of this 16-bit interface) what's interesting is the debug statements immediately become slightly more promising:

APM: EAX=00005300
APM: EAX=00005301
APM: EAX=0000530e
APM: EAX=00005300
APM: EAX=00005304
APM: EAX=00005302 [16-bit protected mode interface connect]
APM: EAX=0000530e

As we can see, after having disconnected the real-mode interface the Windows APM driver seems to try to connect to the 16-bit protected mode interface (function 0x02). It then calls the APM driver version function (0x0e). But this isn't good enough. Windows 2000 still appears to call no further APM functions as it boots and shuts down. So, what's next?

If it's fair to assume that the Windows 2000 APM driver needs to interface with the APM bios using the 16-bit protected-mode interface (instead of the 32-bit interface) then the first thing that seems worth checking is my implementation of function 0x02, which I think it could well be returning the wrong code and data segment addresses. Here's the code:

;-----------------
; APM 16 bit protected mode interface connect
APMSYM(02):
cmp al, #0x02
jne APMSYM(03)

mov ax, #0xffff // 16 bit code segment base
mov bx, #_apm16_entry
mov cx, #0xf000 // data segment address
// 16 bit code segment size
mov si, #0xfff0
mov di, #0xfff0 // data segment length
jmp APMSYM(ok)

;-----------------
; APM 32 bit protected mode interface connect
APMSYM(03):
cmp al, #0x03
jne APMSYM(04)
mov ax, #0xf000 // 32 bit code segment base
mov ebx, #_apm32_entry
mov cx, #0xf000 // 16 bit code segment base
// 32 bit code segment size (low 16 bits)
// 16 bit code segment size (high 16 bits)
mov esi, #0xfff0fff0
mov dx, #0xf000 // data segment address
mov di, #0xfff0 // data segment length
jmp APMSYM(ok)

Can anyone advise?

Struan

Quoted 24 lines · Struan Bartlett
Quoted 1 line · Paul Brook

In theory windows should be able to "turn off" qemu using APM, like it does on real machines. However there seem to be bugs in the qemu implementation that stop this working.

I thought I'd have a little look into why Windows 2000 doesn't turn off qemu using APM properly. I enabled DEBUG_BIOS in hw/pc.c then downloaded the latest Debian source for the Bochs bios v1.121 and defined DEBUG_ROMBIOS and DEBUG_APM both to be 1. I recompiled and installed the bios and ran qemu to load up Windows 2000. What we get seems interesting. By the time Qemu boots Windows 2000 to its first progress-bar, it has printed the following debug statements (with my explanation added in square brackets):

APM: EAX=00005300 [53 is the int 15h identifier for APM checked for in rombios.c. 00 is the APM installation check function]
APM: EAX=00005301 [01 is the APM real mode interface connect]
APM: EAX=0000530e [0e appears to request APM driver version]
APM: EAX=00005300 [00, again, is the APM installation check - why is this called twice?]
APM: EAX=00005304 [04 is APM interface disconnect]

Then, while Windows 2000 boots and until shutdown is complete, I get no more debug statements. My question is, why not? I'm no APM expert but, judging from the 'apmbios.S' comments I might expect to see APM: EAX=00005303 [03 is APM 32 bit protected mode interface connect]. I could speculate that the return code from APM function 0e does not satisfy Windows 2000 for some reason, so it does another installation check and then disconnects the APM interface entirely - hence no APM functionality in Windows 2000.

If I get more time I may research the APM functions more fully. In the meantime, if anyone can suggest any alternative theories or how to test them, I'd be curious.

Struan

_______________________________________________
Qemu-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

#15 lore raw
In reply to John R. Hogerhuis
Quoted 3 lines · John R. Hogerhuis

I suppose there's a reason, but why not trigger or set a flag on actual HLT instruction executed (while interrupts disabled)? That would avoid the kludge of peeking behind the instruction pointer.

That would seem like a much better idea, indeed.

--L

#39 lore raw

RE: APM bug Re: [Qemu-devel] Re: Suggestion - trap window-close of VM

In reply to Struan Bartlett

My Windows XP guests are also unable to power off QEMU. As I know, there is the posibillity to install W2K or XP without ACPI support. Has anyone tried that ? Could it be, that the default installation of Windows with ACPI disable the APM support ? My brain is remembering something... Win98 guest closes QEMU fine.

Andreas

Quoted 10 lines

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Struan Bartlett
Sent: Wednesday, March 30, 2005 3:22 PM
To: [email protected]
Subject: APM bug Re: [Qemu-devel] Re: Suggestion - trap window-close of VM

Quoted 5 lines

*This message was transferred with a trial version of CommuniGate(tm) Pro*

Quoted 1 line · Paul Brook
Quoted 1 line

This isn't working quite right for me with a Windows 98 guest --

it

Quoted 1 line
Quoted 1 line
Quoted 1 line

traps the attempt to close the window all right, but it doesn't

let

Quoted 33 lines
Quoted 4 lines
Quoted 3 lines

the window close even when Window 98 has in fact shut down.

In theory windows should be able to "turn off" qemu using

APM, like it does on

Quoted 1 line

real machines. However there seem to be bugs in the qemu

implementation that

Quoted 3 lines

stop this working.

I thought I'd have a little look into why Windows 2000 doesn't turn off
qemu using APM properly. I enabled DEBUG_BIOS in hw/pc.c then downloaded
the latest Debian source for the Bochs bios v1.121 and defined DEBUG_ROMBIOS and DEBUG_APM both to be 1. I recompiled and installed the
bios and ran qemu to load up Windows 2000. What we get seems interesting. By the time Qemu boots Windows 2000 to its first progress-bar, it has printed the following debug statements (with my

explanation added in square brackets):

APM: EAX=00005300 [53 is the int 15h identifier for APM checked for in
rombios.c. 00 is the APM installation check function]
APM: EAX=00005301 [01 is the APM real mode interface connect]
APM: EAX=0000530e [0e appears to request APM driver version]
APM: EAX=00005300 [00, again, is the APM installation check - why is

this called twice?]
APM: EAX=00005304 [04 is APM interface disconnect]

Quoted 8 lines

Then, while Windows 2000 boots and until shutdown is complete, I get no
more debug statements. My question is, why not? I'm no APM expert but,
judging from the 'apmbios.S' comments I might expect to see APM:
EAX=00005303 [03 is APM 32 bit protected mode interface connect]. I could speculate that the return code from APM function 0e does not satisfy Windows 2000 for some reason, so it does another

installation

Quoted 19 lines

check and then disconnects the APM interface entirely - hence no APM

functionality in Windows 2000.

If I get more time I may research the APM functions more fully. In the
meantime, if anyone can suggest any alternative theories or how to test
them, I'd be curious.

Struan

_______________________________________________
Qemu-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

#40 lore raw

Re: APM bug Re: [Qemu-devel] Re: Suggestion - trap window-close of VM

Quoted 7 lines · Andreas Bollhalder

My Windows XP guests are also unable to power off QEMU. As I know, there is the posibillity to install W2K or XP without ACPI support. Has anyone tried that ? Could it be, that the default installation of Windows with ACPI disable the APM support ? My brain is remembering something... Win98 guest closes QEMU fine.

Andreas

Win2k/XP can be told to setup w/o ACPI by pressing F5 during the install sequence, right around when it asks for F6 for additional SCSI drivers. If I remember correctly, on normal hardware that prevents the system from turning off automatically even when a similar Win98 might do that. You could give it a try, but I'd be surprised if that worked.

Jason

Quoted 92 lines
Quoted 11 lines

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Struan Bartlett
Sent: Wednesday, March 30, 2005 3:22 PM
To: [email protected]
Subject: APM bug Re: [Qemu-devel] Re: Suggestion - trap window-close of VM

Quoted 5 lines

*This message was transferred with a trial version of CommuniGate(tm) Pro*

Quoted 1 line · Paul Brook
Quoted 1 line

This isn't working quite right for me with a Windows 98 guest --

it

Quoted 1 line
Quoted 1 line
Quoted 1 line

traps the attempt to close the window all right, but it doesn't

let

Quoted 35 lines
Quoted 3 lines
Quoted 1 line

the window close even when Window 98 has in fact shut down.

In theory windows should be able to "turn off" qemu using

APM, like it does on

Quoted 1 line

real machines. However there seem to be bugs in the qemu

implementation that

Quoted 1 line

stop this working.

I thought I'd have a little look into why Windows 2000 doesn't turn off
qemu using APM properly. I enabled DEBUG_BIOS in hw/pc.c then downloaded
the latest Debian source for the Bochs bios v1.121 and defined DEBUG_ROMBIOS and DEBUG_APM both to be 1. I recompiled and installed the
bios and ran qemu to load up Windows 2000. What we get seems interesting. By the time Qemu boots Windows 2000 to its first progress-bar, it has printed the following debug statements (with my

explanation added in square brackets):

APM: EAX=00005300 [53 is the int 15h identifier for APM checked for in
rombios.c. 00 is the APM installation check function]
APM: EAX=00005301 [01 is the APM real mode interface connect]
APM: EAX=0000530e [0e appears to request APM driver version]
APM: EAX=00005300 [00, again, is the APM installation check - why is

this called twice?]
APM: EAX=00005304 [04 is APM interface disconnect]

Quoted 8 lines

Then, while Windows 2000 boots and until shutdown is complete, I get no
more debug statements. My question is, why not? I'm no APM expert but,
judging from the 'apmbios.S' comments I might expect to see APM:
EAX=00005303 [03 is APM 32 bit protected mode interface connect]. I could speculate that the return code from APM function 0e does not satisfy Windows 2000 for some reason, so it does another

installation

Quoted 10 lines

check and then disconnects the APM interface entirely - hence no APM

functionality in Windows 2000.

If I get more time I may research the APM functions more fully. In the
meantime, if anyone can suggest any alternative theories or how to test
them, I'd be curious.

Quoted 8 lines

Struan

_______________________________________________
Qemu-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

_______________________________________________
Qemu-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

#19 lore raw

Re: APM bug Re: [Qemu-devel] Re: Suggestion - trap window-close of VM

In reply to Struan Bartlett

From http://www.microsoft.com/whdc/archive/apm.mspx:

"APM support must be enabled in the BIOS when Windows 2000 is installed. Although APM can be disabled on many mobile systems, a non-ACPI system that has APM disabled in the BIOS will not have power-management capabilities installed under Windows 2000."

The way to test for this apparently is looking in the Registry at HKEY_LOCAL_MACHINE\ HARDWARE\ Description\ System\ MultifunctionAdapter: "If the Windows 2000 Ntdetect module finds an APM BIOS on the system, it creates a MultifunctionAdapter subkey with an entry for APM."

So to get APM working with Windows 2000 I surmise one would need to: a. get the 16-bit protected mode interface function working correctly; b. install Windows 2000 from scratch.

Struan

Quoted 84 lines · Struan Bartlett

Having reviewed some of the APM1.2 specification, first impression is that the APM bios is required to provide not only a real-mode and protected 32-bit mode interface to its functions, but also a 16-bit protected mode interface, which the apmbios.S code apparently does not have.

I've tried adding one - although I'm not sure it's correct - and adjusting function 0x00 (APM installation check) to return 0x03 in cx (instead of 0x02 to signify the availability of this 16-bit interface) what's interesting is the debug statements immediately become slightly more promising:

APM: EAX=00005300
APM: EAX=00005301
APM: EAX=0000530e
APM: EAX=00005300
APM: EAX=00005304
APM: EAX=00005302 [16-bit protected mode interface connect]
APM: EAX=0000530e

As we can see, after having disconnected the real-mode interface the Windows APM driver seems to try to connect to the 16-bit protected mode interface (function 0x02). It then calls the APM driver version function (0x0e). But this isn't good enough. Windows 2000 still appears to call no further APM functions as it boots and shuts down. So, what's next?

If it's fair to assume that the Windows 2000 APM driver needs to interface with the APM bios using the 16-bit protected-mode interface (instead of the 32-bit interface) then the first thing that seems worth checking is my implementation of function 0x02, which I think it could well be returning the wrong code and data segment addresses. Here's the code:

;-----------------
; APM 16 bit protected mode interface connect
APMSYM(02):
cmp al, #0x02
jne APMSYM(03)

mov ax, #0xffff // 16 bit code segment base
mov bx, #_apm16_entry
mov cx, #0xf000 // data segment address
// 16 bit code segment size
mov si, #0xfff0
mov di, #0xfff0 // data segment length
jmp APMSYM(ok)

;-----------------
; APM 32 bit protected mode interface connect
APMSYM(03):
cmp al, #0x03
jne APMSYM(04)
mov ax, #0xf000 // 32 bit code segment base
mov ebx, #_apm32_entry
mov cx, #0xf000 // 16 bit code segment base
// 32 bit code segment size (low 16 bits)
// 16 bit code segment size (high 16 bits)
mov esi, #0xfff0fff0
mov dx, #0xf000 // data segment address
mov di, #0xfff0 // data segment length
jmp APMSYM(ok)

Can anyone advise?

Struan

Quoted 17 lines · Struan Bartlett
Quoted 1 line · Paul Brook

In theory windows should be able to "turn off" qemu using APM, like it does on real machines. However there seem to be bugs in the qemu implementation that stop this working.

I thought I'd have a little look into why Windows 2000 doesn't turn off qemu using APM properly. I enabled DEBUG_BIOS in hw/pc.c then downloaded the latest Debian source for the Bochs bios v1.121 and defined DEBUG_ROMBIOS and DEBUG_APM both to be 1. I recompiled and installed the bios and ran qemu to load up Windows 2000. What we get seems interesting. By the time Qemu boots Windows 2000 to its first progress-bar, it has printed the following debug statements (with my explanation added in square brackets):

APM: EAX=00005300 [53 is the int 15h identifier for APM checked for in rombios.c. 00 is the APM installation check function]
APM: EAX=00005301 [01 is the APM real mode interface connect]
APM: EAX=0000530e [0e appears to request APM driver version]
APM: EAX=00005300 [00, again, is the APM installation check - why is this called twice?]
APM: EAX=00005304 [04 is APM interface disconnect]

Then, while Windows 2000 boots and until shutdown is complete, I get no more debug statements. My question is, why not? I'm no APM expert but, judging from the 'apmbios.S' comments I might expect to see APM: EAX=00005303 [03 is APM 32 bit protected mode interface connect]. I could speculate that the return code from APM function 0e does not satisfy Windows 2000 for some reason, so it does another installation check and then disconnects the APM interface entirely - hence no APM functionality in Windows 2000.

If I get more time I may research the APM functions more fully. In the meantime, if anyone can suggest any alternative theories or how to test them, I'd be curious.

Quoted 8 lines

Struan

_______________________________________________
Qemu-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

_______________________________________________
Qemu-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

#20 lore raw

A Fix Re: APM bug Re: [Qemu-devel] Re: Suggestion - trap window-close of VM

Hi -

For anyone running Windows 2000 on Qemu, I've developed a fix that makes APM - and therefore Windows 2000 shutdown - correctly 'power off' (i.e. close) Qemu.

I needed to patch the BIOS - which didn't implement the APM 1.2 16-bit protected mode interface that Windows 2000 apparently requires. Afterwards, as my Windows 2000 installation didn't have the APM driver installed, I simply needed to install it by going Control Panel => Add/Remove Hardware & Next => Add/Troubleshoot a device => Add a new device & Next => No, I want to select the hardware from a list & Next => NT Apm/Legacy Support & Next => Next (again) a few times. Afterwards, I did Control Panel => Power Options, chose the APM tab and made sure the Advanced Power Management support checkbox was ticked. I also chose the Hibernate tab and enabled Hibernate Support too. After rebooting, Windows 2000 now correctly instructs Qemu to shutdown at the appropriate moment. No patches to Qemu were required.

What doesn't work yet is Standby and Suspend, although I've generalised the APM Bios to support both of them. When attempting Standby (which doesn't always appear as an option - a problem I'm aware of), Windows tries to go into Standby but then reports that /"the device driver for the device is preventing this machine from entering standby. Please close all applications and try again. If the problem persists, you may need to update this driver."/ I don't know why this should be. By contrast, Suspend doesn't ever appear as an option - but it would be nice to make this trigger the Qemu savevm/loadvm facility.

You can find the Bios source patch as well as a precompiled patched-binary bios (for those who don't want to download the Bochs source) at http://www.praguespringpeople.org/Struan/Software/BochsBIOS/. Simply copy bios.bin-patchedAPM1.2 over your /usr/local/share/qemu/bios.bin (or better over pc-bios/bios.bin in your Qemu source directory and then do 'make install').

Struan

#21 lore raw

A Fix Re: APM bug Re: [Qemu-devel] Re: Suggestion - trap window-close of VM

In reply to Struan Bartlett

Hi -

For anyone running Windows 2000 on Qemu, I've developed a fix that makes APM - and therefore Windows 2000 shutdown - correctly 'power off' (i.e. close) Qemu.

I needed to patch the BIOS - which didn't implement the APM 1.2 16-bit protected mode interface that Windows 2000 apparently requires. Afterwards, as my Windows 2000 installation didn't have the APM driver installed, I simply needed to install it by going Control Panel => Add/Remove Hardware & Next => Add/Troubleshoot a device => Add a new device & Next => No, I want to select the hardware from a list & Next => NT Apm/Legacy Support & Next => Next (again) a few times. Afterwards, I did Control Panel => Power Options, chose the APM tab and made sure the Advanced Power Management support checkbox was ticked. I also chose the Hibernate tab and enabled Hibernate Support too. After rebooting, Windows 2000 now correctly instructs Qemu to shutdown at the appropriate moment. No patches to Qemu were required.

What doesn't work yet is Standby and Suspend, although I've generalised the APM Bios to support both of them. When attempting Standby (which doesn't always appear as an option - a problem I'm aware of), Windows tries to go into Standby but then reports that /"the device driver for the device is preventing this machine from entering standby. Please close all applications and try again. If the problem persists, you may need to update this driver."/ I don't know why this should be. By contrast, Suspend doesn't ever appear as an option - but it would be nice to make this trigger the Qemu savevm/loadvm facility.

You can find the Bios source patch as well as a precompiled patched-binary bios (for those who don't want to download the Bochs source) at http://www.praguespringpeople.org/Struan/Software/BochsBIOS/. Simply copy bios.bin-patchedAPM1.2 over your /usr/local/share/qemu/bios.bin (or better over pc-bios/bios.bin in your Qemu source directory and then do 'make install').

Struan

#22 lore raw

A Fix Re: APM bug Re: [Qemu-devel] Re: Suggestion - trap window-close of VM

In reply to Struan Bartlett

Hi -

For anyone running Windows 2000 on Qemu, I've developed a fix that makes APM - and therefore Windows 2000 shutdown - correctly 'power off' (i.e. close) Qemu.

I needed to patch the BIOS - which didn't implement the APM 1.2 16-bit protected mode interface that Windows 2000 apparently requires. Afterwards, as my Windows 2000 installation didn't have the APM driver installed, I simply needed to install it by going Control Panel => Add/Remove Hardware & Next => Add/Troubleshoot a device => Add a new device & Next => No, I want to select the hardware from a list & Next => NT Apm/Legacy Support & Next => Next (again) a few times. Afterwards, I did Control Panel => Power Options, chose the APM tab and made sure the Advanced Power Management support checkbox was ticked. I also chose the Hibernate tab and enabled Hibernate Support too. After rebooting, Windows 2000 now correctly instructs Qemu to shutdown at the appropriate moment. No patches to Qemu were required.

What doesn't work yet is Standby and Suspend, although I've generalised the APM Bios to support both of them. When attempting Standby (which doesn't always appear as an option - a problem I'm aware of), Windows tries to go into Standby but then reports that /"the device driver for the device is preventing this machine from entering standby. Please close all applications and try again. If the problem persists, you may need to update this driver."/ I don't know why this should be. By contrast, Suspend doesn't ever appear as an option - but it would be nice to make this trigger the Qemu savevm/loadvm facility.

You can find the Bios source patch as well as a precompiled patched-binary bios (for those who don't want to download the Bochs source) at http://www.praguespringpeople.org/Struan/Software/BochsBIOS/. Simply copy bios.bin-patchedAPM1.2 over your /usr/local/share/qemu/bios.bin (or better over pc-bios/bios.bin in your Qemu source directory and then do 'make install').

Struan

#23 lore raw

Re: A Fix Re: APM bug Re: [Qemu-devel] Re: Suggestion - trap window-close of VM

Quoted 11 lines · Struan Bartlett

Hi -

For anyone running Windows 2000 on Qemu, I've developed a fix that makes APM - and therefore Windows 2000 shutdown - correctly 'power off' (i.e. close) Qemu.

I needed to patch the BIOS - which didn't implement the APM 1.2 16-bit protected mode interface that Windows 2000 apparently requires.
...

What doesn't work yet is Standby and Suspend, although I've generalised

My network (using -user-net) stops working when I use your patched BIOS.

But it does close the window on shutdown!

Regards,

Iain

#38 lore raw

Re: APM bug Re: [Qemu-devel] Re: Suggestion - trap window-close of VM

In reply to Struan Bartlett

Organization: Free Software Network (http://www.fsn.hu/)
X-Mailer: Sylpheed version 0.9.8claws (GTK+ 1.2.10; powerpc-unknown-linux-gnu)
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit

Hi,

Quoted 7 lines

APM: EAX=00005300
APM: EAX=00005301
APM: EAX=0000530e
APM: EAX=00005300
APM: EAX=00005304
APM: EAX=00005302 [16-bit protected mode interface connect]
APM: EAX=0000530e

The installation check returns that the 16bit pm if is implemented, however, it is not. You forgot to include the new version of apmbios in rombios.c about at line 8791 (however, i have a slightly modified file).

There you need to add:
#define APM_PROT16
#include "apmbios.S"

below the use16 line.

Signature · 2 lines
Alex Beregszaszi 			e-mail: [email protected]
Free Software Network			cell: +36 70 3144424
#24 lore raw

Re: A Fix Re: APM bug Re: [Qemu-devel] Re: Suggestion - trap window-close of VM

In reply to Iain McFarlane

Hi,

Quoted 9 lines
Quoted 5 lines

I needed to patch the BIOS - which didn't implement the APM 1.2 16-bit protected mode interface that Windows 2000 apparently requires.
...

What doesn't work yet is Standby and Suspend, although I've generalised

My network (using -user-net) stops working when I use your patched BIOS.

But it does close the window on shutdown!

I guess the patched rombios is based on a newer version from Bochs CVS. Qemu is still using the rombios of May 31, 2004 with some patches. In the meantime the PCI IRQ routing table has been modified and the PCI IRQ initialization has been added. Qemu needs a small patch to make it work again. I have already sent this patch to Fabrice Bellard and posted it here in the list, but nothing happened. I'd like to apply the APM patch to the official Bochs BIOS if you can confirm that it works. Here is the patch:

hw/pci.c renamed from home/volker/qemu/hw/pci.c +1 -1
diff -urN /home/volker/qemu/hw/pci.c ./hw/pci.c
@@ -494,7 +494,7 @@
 static inline int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
 {
     int slot_addend;
-    slot_addend = (pci_dev->devfn >> 3);
+    slot_addend = (pci_dev->devfn >> 3) - 1;
     return (irq_num + slot_addend) & 3;
 }
 

--
Bye

Volker

#25 lore raw

Re: A Fix Re: APM bug Re: [Qemu-devel] Re: Suggestion - trap window-close of VM

Quoted 35 lines · Volker Ruppert

Hi,

Quoted 9 lines
Quoted 5 lines

I needed to patch the BIOS - which didn't implement the APM 1.2 16-bit protected mode interface that Windows 2000 apparently requires.
...

What doesn't work yet is Standby and Suspend, although I've generalised

My network (using -user-net) stops working when I use your patched BIOS.

But it does close the window on shutdown!

I guess the patched rombios is based on a newer version from Bochs CVS. Qemu is still using the rombios of May 31, 2004 with some patches. In the meantime the PCI IRQ routing table has been modified and the PCI IRQ initialization has been added. Qemu needs a small patch to make it work again. I have already sent this patch to Fabrice Bellard and posted it here in the list, but nothing happened. I'd like to apply the APM patch to the official Bochs BIOS if you can confirm that it works. Here is the patch:

diff -urN /home/volker/qemu/hw/pci.c ./hw/pci.c

hw/pci.c renamed from home/volker/qemu/hw/pci.c +1 -2
@@ -494,7 +494,7 @@
 static inline int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
 {
     int slot_addend;
-    slot_addend = (pci_dev->devfn >> 3);
+    slot_addend = (pci_dev->devfn >> 3) - 1;
     return (irq_num + slot_addend) & 3;
 }
 
--

Bye

Quoted 1 line

Volker

Yes this now works - I can even hibernate win2k and it will restart successfully.

Has anyone had any joy installing service pack 4?

Regards,

Iain

#26 lore raw

[Qemu-devel] Re: Windows 2000 SP4 (was Re: APM bug)

Iain et al,

Here are some things we've discovered about Service Pack 4 and QEMU..

1. You can go from no service pack to SP4 using KQEMU for the x86 on x86 case, and that works fine. It does not work with i386-softmmu on the same processor for example unless you have KQEMU installed.

2. Without using KQEMU, you will have to install all service packs leading up to and include 4 in order (i.e. SP2, then SP3, etc.); but *beware*: SP3 has a dreaded Microsoft bug that will prevent things from booting. This is a known Microsoft bug that happens to manifest all the time (based on our testing) on QEMU. My suggestion for an easy work-around is this:

a. Install SP2 and reboot
b. save the file c:\winnt\system32\dllcache\msgina.dll somewhere
safe (i.e. your My Documents directory, etc.)
c. Install SP3 but *do not* let it restart (check the box) after
it's done
d. Once you exit SP3 installation, copy the saved msgina.dll
from step b into both the c:\winnt\system32 and c:\winnt\system32\dllcache directories. First you will have to rename the existing msgina.dll's in those directories to something else since they are in use. But be quick, because the System File Checker which is not easy to disable will restore them before you know it (after you rename them but before you restore the saved version)
e. Restart the computer

I suggest you backup your hard disk image that contains Windows 2000 either before you start doing all this or after you install SP2 successfully and shut down, just in case something goes wrong. If all goes well, Win2K should boot, but if not, you can probably still use the System Recovery mode or something to fix it. Your safest bet is to make a backup first.

After you get past this SP3 mess, you can then install SP4. I suggest you download the SP2-4 installers from http://www.microsoft.com instead of using Windows update (which will only fetch SP4 anyway). Just do a search in the download area to find each one.

After you get SP4 installed, beware of the following 2 major problems:

1. schannel.dll will fail to start and therefore IE will have a 0-bit cipher strength, no matter what you do (additional updates, etc). Microsoft suggests you restore 2-3 DLLs in this case (including schannel.dll), but it doesn't work in QEMU. What you might want to do is grab the DLL's (schannel.dll and rsabase.dll, and I can't recall the other one) from SP3 or even SP2 and try that. It probably won't work, but if it does, please let us know. In the event viewer the error message appears to be useless - saying that schannel failed to start the RSA engine with an error code 0x57, which we can't find the meaning for in that context yet. If anyone has any clues, I'd love to hear!

(note that 0-bit cipher in IE causes Windows Update to stop working too)

2. Add/Remove Programs will stop working - showing nothing installed as far as applications go. You'll see what looks like a broken graphic link with the text 'Computer graphic' in the place where your list of installed apps should be. You can usually overcome this by installing the Windows Installer 3.0 (get it from microsoft.com) after you install SP4 and restart.

Keep in mind that item 1 did not fail like that with KQEMU enabled. We didn't test item 2 yet with KQEMU.

At this point we are thinking there is an instruction emulation/translation error somewhere that of course doesn't show up with KQEMU because it's likely running native. We're still trying to track it down in the QEMU code, but any ideas or suggestions from anyone would be gladly appreciated. At first we thought it had to do with the 80-bit FP ops not using the "l" versions of various glibc math functions (i.e. sqrt, etc.), but a quick test of replacing those with the "l" versions made no difference here, and slowed down a lot of other stuff tremendously. I'll send a follow-up note to the list with some other findings so anyone who wants to can comment, but there are other issues that we have encountered as well.

Best regards,

Leo Reiter

Signature · 8 lines
Leonardo E. Reiter
Vice President of Engineering

Win4Lin, Inc.
Virtual Computing from Desktop to Data Center
Main: +1 512 339 7979
Fax: +1 512 532 6501
http://www.win4lin.com
#27 lore raw

Re: [Qemu-devel] Re: Windows 2000 SP4 (was Re: APM bug)

Hi Leonardo,

I have tried to install win2k from various CD's I have here around and I stumbled on one really weird thing..

Disk space issues. I have tried with 1GB, 2GB and 4GB virtual disks, and all of them seems to be quickly filled by the win2k installer and then the install fails..

Do you also have the same problem there at win4lin? or is it only happening with QEMU's internal IDE drive emulation? (since I recall that win4lin replaced the IDE driver with their own's one)..

Thanks,
Hetz

#28 lore raw

Re: [Qemu-devel] Re: Windows 2000 SP4 (was Re: APM bug)

Yes, we did replace the IDE driver with our own implementation. But you can apply this patch that was posted long ago on the list that takes care of it on regular QEMU. It will slow things down a bit, so you may want to disable it, so you may want to optimize it or disable it after you get Windows 2000 installed, but it works. The issue seems to be the fact that the install-time Windows 2000 IDE driver doesn't like write operations generating an interrupt too quickly (i.e. before the "out" or DMA transfer returns). It doesn't seem to have this issue after the base OS is installed and booted however, but your experience may vary. Attached is the patch that we found on the list. It applies both to 0.6.1 and 0.6.2, albeit with some possible hunks.

Best regards,

Leo Reiter

Quoted 15 lines · Hetz Ben Hamo

Hi Leonardo,

I have tried to install win2k from various CD's I have here around and I stumbled on one really weird thing..

Disk space issues. I have tried with 1GB, 2GB and 4GB virtual disks, and all of them seems to be quickly filled by the win2k installer and then the install fails..

Do you also have the same problem there at win4lin? or is it only happening with QEMU's internal IDE drive emulation? (since I recall that win4lin replaced the IDE driver with their own's one)..

Thanks,
Hetz

Signature · 8 lines
Leonardo E. Reiter
Vice President of Engineering

Win4Lin, Inc.
Virtual Computing from Desktop to Data Center
Main: +1 512 339 7979
Fax: +1 512 532 6501
http://www.win4lin.com
hw/ide.c +26 -0
diff -rbu qemu.orig/hw/ide.c qemu/hw/ide.c
@@ -332,8 +332,12 @@
     uint8_t *data_ptr;
     uint8_t *data_end;
     uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
+    int ide_set_irq_from_timer;
 } IDEState;
 
+volatile int ide_set_irq_from_timer;
+static IDEState *IDEStates[4];
+
 #define BM_STATUS_DMAING 0x01
 #define BM_STATUS_ERROR  0x02
 #define BM_STATUS_INT    0x04
@@ -512,6 +516,21 @@
     }
 }
 
+void make_ide_set_irq(void)
+{
+	int i;
+	IDEState *s;
+
+	ide_set_irq_from_timer--;
+	for(i = 0; (s=IDEStates[i]) != NULL; i++) {
+		if(s->ide_set_irq_from_timer) {
+			s->ide_set_irq_from_timer--;
+			ide_set_irq(s);
+			break;
+		}
+	}
+}
+
 /* prepare data transfer and tell what to do after */
 static void ide_transfer_start(IDEState *s, uint8_t *buf, int size, 
                                EndTransferFunc *end_transfer_func)
@@ -667,7 +686,11 @@
         ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
     }
     ide_set_sector(s, sector_num + n);
+    if(s->ide_set_irq_from_timer) {
+	ide_set_irq_from_timer++;
+    } else {
     ide_set_irq(s);
+    }
 }
 
 static int ide_write_dma_cb(IDEState *s, 
@@ -1511,6 +1534,7 @@
             s->error = 0;
             s->status = SEEK_STAT | READY_STAT;
             s->req_nb_sectors = 1;
+	    s->ide_set_irq_from_timer = 1;
             ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
             break;
         case WIN_MULTREAD:
@@ -1528,6 +1552,7 @@
             n = s->nsector;
             if (n > s->req_nb_sectors)
                 n = s->req_nb_sectors;
+	    s->ide_set_irq_from_timer = 1;
             ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
             break;
         case WIN_READDMA:
@@ -1883,6 +1908,7 @@
 
     for(i = 0; i < 2; i++) {
         s = ide_state + i;
+	IDEStates[drive_serial-1] = s;
         if (i == 0)
             s->bs = hd0;
         else
vl.c +6 -3
diff -rbu qemu.orig/vl.c qemu/vl.c
@@ -911,7 +911,7 @@
         
         /* timer signal */
         sigfillset(&act.sa_mask);
-        act.sa_flags = 0;
+	act.sa_flags = SA_RESTART;
 #if defined (TARGET_I386) && defined(USE_CODE_COPY)
         act.sa_flags |= SA_ONSTACK;
 #endif
@@ -2403,7 +2403,12 @@
     int n, max_size;
 #endif
     int ret;
+    /* ide.c hack */
+    extern volatile int ide_set_irq_from_timer;
+    extern void make_ide_set_irq(void);
 
+	if(ide_set_irq_from_timer)
+		make_ide_set_irq();
 #ifdef _WIN32
         if (timeout > 0)
             Sleep(timeout);
@@ -2449,8 +2454,6 @@
                             n = read(ioh->fd, buf, ioh->max_size);
                             if (n >= 0) {
                                 ioh->fd_read(ioh->opaque, buf, n);
-                            } else if (errno != EAGAIN) {
-                                ioh->fd_read(ioh->opaque, NULL, -errno);
                             }
                         }
                     }
#36 lore raw

Re: [Qemu-devel] Re: Windows 2000 SP4 (was Re: APM bug)

In reply to Leonardo E. Reiter
Quoted 8 lines · Leonardo E. Reiter

d. Once you exit SP3 installation, copy the saved msgina.dll
from step b into both the c:\winnt\system32 and
c:\winnt\system32\dllcache directories. First you will have
to rename the existing msgina.dll's in those directories to
something else since they are in use. But be quick, because the System File Checker which is not easy to disable will restore them before you know it (after you rename them but
before you restore the saved version)

Not using a copy of win2k I can't say I've tried this, but I recently read that the checker can be disabled. Purportedly one does this by creating a registry key:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon] "SFCDisable"= dword: ffff ff9d

DF

#29 lore raw

Re: [Qemu-devel] Re: Windows 2000 SP4 (was Re: APM bug)

In reply to Leonardo E. Reiter

Thanks for the patch Leonardo...

Indeed, the patch seems to apply with some hunks (I suck at C programming :), and fails to buid with qemu with a compile error on the SPARC part of the emulation (Blue swirl, did you see the error?)

Does anyone else have a better solution other then patching and unpatching QEMU to install and use Windows 2000?

Thanks,
Hetz

Quoted 52 lines · Leonardo E. Reiter

Yes, we did replace the IDE driver with our own implementation. But you can apply this patch that was posted long ago on the list that takes care of it on regular QEMU. It will slow things down a bit, so you may want to disable it, so you may want to optimize it or disable it after you get Windows 2000 installed, but it works. The issue seems to be the fact that the install-time Windows 2000 IDE driver doesn't like write operations generating an interrupt too quickly (i.e. before the "out" or DMA transfer returns). It doesn't seem to have this issue after the base OS is installed and booted however, but your experience may vary. Attached is the patch that we found on the list. It applies both to 0.6.1 and 0.6.2, albeit with some possible hunks.

Best regards,

Leo Reiter

Quoted 9 lines · Hetz Ben Hamo

Hi Leonardo,

I have tried to install win2k from various CD's I have here around and I stumbled on one really weird thing..

Disk space issues. I have tried with 1GB, 2GB and 4GB virtual disks, and all of them seems to be quickly filled by the win2k installer and then the install fails..

Quoted 6 lines

Do you also have the same problem there at win4lin? or is it only happening with QEMU's internal IDE drive emulation? (since I recall that win4lin replaced the IDE driver with their own's one)..

Thanks,
Hetz

--
Leonardo E. Reiter
Vice President of Engineering

Win4Lin, Inc.
Virtual Computing from Desktop to Data Center
Main: +1 512 339 7979
Fax: +1 512 532 6501
http://www.win4lin.com

_______________________________________________
Qemu-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

#30 lore raw

Re: [Qemu-devel] Re: Windows 2000 SP4 (was Re: APM bug)

Hetz,

Sorry, we've only used it with target-i386.

The error you are seeing is probably because hw/ide.c is not used on the sparc target. This is really for x86 PC guests that use the IDE driver.

Sorry I couldn't help more,

Leo Reiter

Quoted 11 lines · Hetz Ben Hamo

Thanks for the patch Leonardo...

Indeed, the patch seems to apply with some hunks (I suck at C programming :), and fails to buid with qemu with a compile error on the SPARC part of the emulation (Blue swirl, did you see the error?)

Does anyone else have a better solution other then patching and unpatching QEMU to install and use Windows 2000?

Thanks,
Hetz

Signature · 8 lines
Leonardo E. Reiter
Vice President of Engineering

Win4Lin, Inc.
Virtual Computing from Desktop to Data Center
Main: +1 512 339 7979
Fax: +1 512 532 6501
http://www.win4lin.com
#31 lore raw

Re: [Qemu-devel] Re: Windows 2000 SP4

In reply to Hetz Ben Hamo

Hetz,

sorry, please disregard my last message as I misunderstood what you were saying. Windows 2000 can't run in target-sparc anyway. So here's how you can fix it - this is based on the very latest CVS tree by the way...

Insert a line right after line 2589 in vl.c that reads as follows:

#ifdef TARGET_I386

then insert a line right after line 2596 that reads as follows:

#endif

That will essentially make the patch active only for target-i386. Compilation with target sparc-softmmu now works fine.

Best regards,

Leo Reiter

Quoted 11 lines · Hetz Ben Hamo

Thanks for the patch Leonardo...

Indeed, the patch seems to apply with some hunks (I suck at C programming :), and fails to buid with qemu with a compile error on the SPARC part of the emulation (Blue swirl, did you see the error?)

Does anyone else have a better solution other then patching and unpatching QEMU to install and use Windows 2000?

Thanks,
Hetz

Signature · 8 lines
Leonardo E. Reiter
Vice President of Engineering

Win4Lin, Inc.
Virtual Computing from Desktop to Data Center
Main: +1 512 339 7979
Fax: +1 512 532 6501
http://www.win4lin.com
#32 lore raw

Re: [Qemu-devel] Re: Windows 2000 SP4 (was Re: APM bug)

In reply to Leonardo E. Reiter

If other people confirm that this patch is solving the issue, I can try to improve it so that it is commitable.

Fabrice.

Quoted 144 lines · Leonardo E. Reiter

Yes, we did replace the IDE driver with our own implementation. But you can apply this patch that was posted long ago on the list that takes care of it on regular QEMU. It will slow things down a bit, so you may want to disable it, so you may want to optimize it or disable it after you get Windows 2000 installed, but it works. The issue seems to be the fact that the install-time Windows 2000 IDE driver doesn't like write operations generating an interrupt too quickly (i.e. before the "out" or DMA transfer returns). It doesn't seem to have this issue after the base OS is installed and booted however, but your experience may vary. Attached is the patch that we found on the list. It applies both to 0.6.1 and 0.6.2, albeit with some possible hunks.

Best regards,

Leo Reiter

Quoted 9 lines · Hetz Ben Hamo

Hi Leonardo,

I have tried to install win2k from various CD's I have here around and I stumbled on one really weird thing..

Disk space issues. I have tried with 1GB, 2GB and 4GB virtual disks, and all of them seems to be quickly filled by the win2k installer and then the install fails..

Quoted 6 lines

Do you also have the same problem there at win4lin? or is it only happening with QEMU's internal IDE drive emulation? (since I recall that win4lin replaced the IDE driver with their own's one)..

Thanks,
Hetz

------------------------------------------------------------------------

diff -rbu qemu.orig/hw/ide.c qemu/hw/ide.c

hw/ide.c +26 -0
@@ -332,8 +332,12 @@
     uint8_t *data_ptr;
     uint8_t *data_end;
     uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
+    int ide_set_irq_from_timer;
 } IDEState;
 
+volatile int ide_set_irq_from_timer;
+static IDEState *IDEStates[4];
+
 #define BM_STATUS_DMAING 0x01
 #define BM_STATUS_ERROR  0x02
 #define BM_STATUS_INT    0x04
@@ -512,6 +516,21 @@
     }
 }
 
+void make_ide_set_irq(void)
+{
+	int i;
+	IDEState *s;
+
+	ide_set_irq_from_timer--;
+	for(i = 0; (s=IDEStates[i]) != NULL; i++) {
+		if(s->ide_set_irq_from_timer) {
+			s->ide_set_irq_from_timer--;
+			ide_set_irq(s);
+			break;
+		}
+	}
+}
+
 /* prepare data transfer and tell what to do after */
 static void ide_transfer_start(IDEState *s, uint8_t *buf, int size, 
                                EndTransferFunc *end_transfer_func)
@@ -667,7 +686,11 @@
         ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
     }
     ide_set_sector(s, sector_num + n);
+    if(s->ide_set_irq_from_timer) {
+	ide_set_irq_from_timer++;
+    } else {
     ide_set_irq(s);
+    }
 }
 
 static int ide_write_dma_cb(IDEState *s, 
@@ -1511,6 +1534,7 @@
             s->error = 0;
             s->status = SEEK_STAT | READY_STAT;
             s->req_nb_sectors = 1;
+	    s->ide_set_irq_from_timer = 1;
             ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
             break;
         case WIN_MULTREAD:
@@ -1528,6 +1552,7 @@
             n = s->nsector;
             if (n > s->req_nb_sectors)
                 n = s->req_nb_sectors;
+	    s->ide_set_irq_from_timer = 1;
             ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
             break;
         case WIN_READDMA:
@@ -1883,6 +1908,7 @@
 
     for(i = 0; i < 2; i++) {
         s = ide_state + i;
+	IDEStates[drive_serial-1] = s;
         if (i == 0)
             s->bs = hd0;
         else

diff -rbu qemu.orig/vl.c qemu/vl.c

vl.c +6 -4
@@ -911,7 +911,7 @@
 
         /* timer signal */
         sigfillset(&act.sa_mask);
-        act.sa_flags = 0;
+	act.sa_flags = SA_RESTART;
 #if defined (TARGET_I386) && defined(USE_CODE_COPY)
         act.sa_flags |= SA_ONSTACK;
 #endif
@@ -2403,7 +2403,12 @@
     int n, max_size;
 #endif
     int ret;
+    /* ide.c hack */
+    extern volatile int ide_set_irq_from_timer;
+    extern void make_ide_set_irq(void);
 
+	if(ide_set_irq_from_timer)
+		make_ide_set_irq();
 #ifdef _WIN32
         if (timeout > 0)
             Sleep(timeout);
@@ -2449,8 +2454,6 @@
                             n = read(ioh->fd, buf, ioh->max_size);
                             if (n >= 0) {
                                 ioh->fd_read(ioh->opaque, buf, n);
-                            } else if (errno != EAGAIN) {
-                                ioh->fd_read(ioh->opaque, NULL, -errno);
                             }
                         }
                     }
 
 
------------------------------------------------------------------------

_______________________________________________
Qemu-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

#33 lore raw

Re: [Qemu-devel] Re: Windows 2000 SP4 (was Re: APM bug)

Fabrice,

Please see this before committing:
http://lists.gnu.org/archive/html/qemu-devel/2004-12/msg00167.html
It specifically mentions that this hack is only good for installing win2k, but it degrades performance, so after installing, the patch need to be removed..

I just tested QEMU with this patch and windows 2000 Pro (no service packs). I simply used the command: qemu -m 256 -user-net -hda win2k.img -cdrom /dev/cdrom -boot d - and the installation went perfectly. There aren't any weird (and gazillion files) in c:\winnt\security ;)

BTW: I found a really weird problem. If I install win2k, and QEMU restart after the installation, and then I change the color depths and resolution, I get black background and only text and icons visible. Quitting QEMU and starting QEMU again fixes the problem. Is there a problem when QEMU restarts when it emulating a reset?

Going to try now moving from non service packs to SP4 ;)

Thanks,
Hetz

Quoted 4 lines · Fabrice Bellard

If other people confirm that this patch is solving the issue, I can try to improve it so that it is commitable.

Fabrice.

#34 lore raw

Re: [Qemu-devel] Re: Windows 2000 SP4 (was Re: APM bug)

Quoted 4 lines · Hetz Ben Hamo

Please see this before committing:
http://lists.gnu.org/archive/html/qemu-devel/2004-12/msg00167.html
It specifically mentions that this hack is only good for installing win2k,

Is it really a hack, or is it simply impossible in a real PC for that interrupt to be triggered so fast and does that patch fix this?

Quoted 2 lines

but it degrades performance, so after installing, the patch need to be removed..

Well, there are probably a thousand ways to speed up QEMU by cutting some corners here and there, which will only break one or another program. Correctness is more important than speed, I think.

Otoh, I think the latest version of VPC has a special compatibility mode which slows down everything tremendously, but which you can turn on to install certain programs or OS'es that won't install otherwise. I don't know what it does exactly, but this is another approach which can be followed.

Jonas

#35 lore raw

Re: [Qemu-devel] Re: Windows 2000 SP4 (was Re: APM bug)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

| Well, there are probably a thousand ways to speed up QEMU by cutting
| some corners here and there, which will only break one or another
| program. Correctness is more important than speed, I think.

I'd suggest to have a command line switch (ie -compatibility) that triggers this kind of behavior.

Sometimes speed is more important that correctness. :-)

- --
Flavio Visentin

|                     \|||/
|                    @/0.0\@
|                     \ - /
+------------------oOOo---oOOo------------------

There are only 10 types of people in this world:
those who understand binary, and those who don't.

GPG Key: http://www.zipman.it/gpgkey.asc
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)

iD8DBQFCVR/9usUmHkh1cnoRAmLpAJ4kWpiBexfUxLf3vKsXDEeIlbhyKwCeIK8S +pum35EBMNBZxvyxQqf5u5M=
=RSkb
-----END PGP SIGNATURE-----

#37 lore raw

RE: A Fix Re: APM bug Re: [Qemu-devel] Re: Suggestion - trap window-closeof VM

In reply to Struan Bartlett

I had it successfully tested with WinXP as guest on WinXP and Gentoo 2005.0 (with and without kqemu and with VNC) hosts. Hibernate works fine. Congratulation !!!

Andreas

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Struan Bartlett
Sent: Monday, April 04, 2005 7:13 PM
To: [email protected]
Subject: A Fix Re: APM bug Re: [Qemu-devel] Re: Suggestion - trap window-closeof VM

Hi -

For anyone running Windows 2000 on Qemu, I've developed a fix that makes APM - and therefore Windows 2000 shutdown - correctly 'power off' (i.e. close) Qemu.

I needed to patch the BIOS - which didn't implement the APM 1.2 16-bit protected mode interface that Windows 2000 apparently requires. Afterwards, as my Windows 2000 installation didn't have the APM driver installed, I simply needed to install it by going Control Panel => Add/Remove Hardware & Next => Add/Troubleshoot a device => Add a new device & Next => No, I want to select the hardware from a list & Next => NT Apm/Legacy Support & Next => Next (again) a few times. Afterwards, I did Control Panel => Power Options, chose the APM tab and made sure the Advanced Power Management support checkbox was ticked. I also chose the Hibernate tab and enabled Hibernate Support too. After rebooting, Windows 2000 now correctly instructs Qemu to shutdown at the appropriate moment. No patches to Qemu were required.

What doesn't work yet is Standby and Suspend, although I've generalised the APM Bios to support both of them. When attempting Standby (which doesn't always appear as an option - a problem I'm aware of), Windows tries to go into Standby but then reports that "the device driver for the device is preventing this machine from entering standby. Please close all applications and try again. If the problem persists, you may need to update this driver." I don't know why this should be. By contrast, Suspend doesn't ever appear as an option - but it would be nice to make this trigger the Qemu savevm/loadvm facility.

You can find the Bios source patch as well as a precompiled patched-binary bios (for those who don't want to download the Bochs source) at
http://www.praguespringpeople.org/Struan/Software/BochsBIOS/. Simply copy bios.bin-patchedAPM1.2 over your /usr/local/share/qemu/bios.bin (or better over pc-bios/bios.bin in your Qemu source directory and then do 'make install').

Struan

#41 lore raw

PATCH 1/1 on-quit-v0.21 with resume/suspend/power-off dialog Re: [patch] Re: [Qemu-devel] Suggestion - trap window-close of VM

In reply to Struan Bartlett

Hi,

Having had the APM bios fixed in the 0.7 Qemu release, which allows Windows 2000 to correctly signal Qemu when it wants to shutdown the VM, I've updated my '-on-quit' patch - which prevented the VM from being crudely shut down by accidentally pressing Ctrl-C or closing the VM window - to remove the nasty i386-specific "halt-instruction-detection" code and provide what I hope you will agree is a cleaner replacement.

The new patch instead relies on APM/SDL/Cocoa/Cuda each specifying whether the shutdown request originated from the hardware or from the user. In the case of user request, Qemu's behaviour will depend on the command line option specified: 1. '-on-quit ignore' means ignore the Ctrl-C; 2. '-on-quit suspend' means suspend the VM. In the case of a hardware shutdown, the VM will shut down normally (but if '-on-quit suspend' was selected it will delete the named suspend file first).

The patch features extra options '-on-quit ask' and '-on-quit <filepath>' which both cause Qemu to run a script to ask the user whether they want to resume, suspend or power off the VM. For non-WIN32 platforms, this is easily implemented it using a script that the xmessage command i.e.:

#!/bin/sh

exec /usr/bin/X11/xmessage -center -timeout 10 -buttons 'Resume:0,Suspend:1,Power Off:2' 'Do you want to resume, suspend, or power off this virtual machine?'

The '-on-quit ask' option assumes a default script filename "on_quit_ask", assumed to be in the CONFIG_QEMU_SHAREDIR directory (i.e. usually /usr/local/share/qemu).

Example command (Linux) which should correctly buffer naive users from accidental VM shutdown and suspend file overwriting: it resumes from suspended.qemu file if it exists; asks user whether to resume, power off or suspend on CTRL-C or window close; suspend saves to the same file; power off deleted the suspend file.

qemu -hda win2k.raw -m 64 -monitor null -loadvm suspended.qemu -on-quit ask

Feedback welcome!

Struan

Quoted 199 lines · Struan Bartlett

Hi,

I've attached a patch against the 2005-03-26 snapshot that implements two '-on-quit' options for the emulator window: ignore-unless-halted and suspend-unless-halted, that aim to make it safe to allow naive users to (try to) close the VM window by trapping requests to shutdown and either ignoring them or forcing a save of the VM state before obeying them.

Caveat: I'll come clean straight away that the patch is implemented using a nasty TARGET_i386-specific hack that detects whether the guest operating system has permanently halted by looking to see if the last instruction executed was 0xF4 and, if so, whether the IF flag is cleared. Saying that, this system appears to work reasonably well on my Pentium host running a Windows 2000 guest, but I have not tested it on any other systems.

Usage:

1. If you provide naive users with a variation on the following command line, then you can let your naive users (try to) close the VM window as much as they like. Unless the guest has permanently halted, attempts to close the VM window should save the VM state to 'suspended.qemu' in the current working directory before qemu exits. The same command line will restart the VM where it left off. Then, once the guest has permanently halted, qemu will delete the suspended.qemu file so that the next launch of qemu will boot afresh:

qemu -hda win2k.raw -m 64 -monitor null -loadvm suspended.qemu -on-quit suspend-unless-halted

2. Alternatively, the following command will make qemu ignore the user's request to close the emulator window unless the guest has already permanently halted:

qemu -hda win2k.raw -m 64 -monitor null -on-quit ignore-unless-halted

3. If you combine this with a test of whether qemu is already running, then it should be safe to let naive users try to both launch and to close qemu as much as they like. e.g.

killall -0 qemu 2>/dev/null; if [ $? == 1 ]; then qemu -hda win2k.raw -m 64 -monitor null -loadvm suspended.qemu -on-quit suspend-unless-halted; fi &

4. Finally, if your leave out the -on-quit option altogether, then qemu's behaviour should remain completely unchanged.

I hope this is useful for some i386/W2K users out there. Any constructive criticism appreciated. If you know how I could improve permanent halt detection (that doesn't require in-depth knowledge of APM or ACPI) then please let me know.

Struan

Quoted 28 lines · Struan Bartlett
Quoted 19 lines · Ryan Rempel

On Mon, Nov 29, 2004 at 21:46:54 +0100, Lennert Buytenhek wrote

Quoted 11 lines · Richard Neill
Quoted 5 lines

A thought that occurred to me. If one is running a virtual machine (eg copy of WinXP), then simply closing the qemu window is a really bad idea, since it will effectively crash the guest.

Related thought -- it would be way cool if we could make killing qemu do exactly happens when you press the power button on an ACPI-capable machine with any recent OS on it (auto shutdown.)

I was wondering if anyone has followed up on this suggestion. I'm putting together a Qemu-based setup for some relatively naive users, and ideally I'd like to be able to deal with this in a reasonable elegant way (the ACPI hook sounds very elegant indeed).

Quoted 7 lines

Alternatively, how do people deal with the problem of naive users who might just close the Qemu window without shutting down the guest properly? I'm working in a KDE environment -- perhaps there is a way in KDE to prevent the close button from appearing? But that wouldn't catch every case either (for instance, if the user were to shut down the host).

Quoted 10 lines

This sounds like a good idea. An alternative solution, that might be more straightforward to implement if Qemu doesn't implement ACPI yet, would be for the kill signal to simply cause Qemu to do the equivalent of entering 'stop' and 'savevm <somefilepath>' into the monitor.

------------------------------------------------------------------------

_______________________________________________
Qemu-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

------------------------------------------------------------------------

vl.c +63 -1
@@ -139,6 +139,9 @@
 int graphic_height = 600;
 int graphic_depth = 15;
 int full_screen = 0;
+#ifdef TARGET_I386
+int on_quit = 0;
+#endif
 TextConsole *vga_console;
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
@@ -2675,6 +2678,17 @@
                        qemu_get_clock(rt_clock));
 }
 
+#ifdef TARGET_I386
+int ishalted() {
+   uint8_t buf[16];
+   uint64_t v;
+	
+   cpu_memory_rw_debug(cpu_single_env, cpu_single_env->eip-1, buf, 16, 0);
+   v = ldub_raw(buf);
+   return (v == 0xf4) && ( !(cpu_single_env->eflags & 0x200) );
+}
+#endif
+
 int main_loop(void)
 {
    int ret, timeout;
@@ -2684,9 +2698,16 @@
        if (vm_running) {
            ret = cpu_exec(env);
            if (shutdown_requested) {
+#ifdef TARGET_I386	       
+	       if( on_quit == 0 || on_quit == 2 || ( on_quit == 1 && ishalted() ) ) {
+#endif		  
                ret = EXCP_INTERRUPT; 
                break;
            }
+#ifdef TARGET_I386	       
+ 	       shutdown_requested = 0;
+ 	    }
+#endif
            if (reset_requested) {
                reset_requested = 0;
                qemu_system_reset();
@@ -2783,6 +2804,11 @@
           "-std-vga        simulate a standard VGA card with VESA Bochs Extensions\n"
           "                (default is CL-GD5446 PCI VGA)\n"
 #endif
+#ifdef TARGET_I386
+	   "-on-quit [ignore-unless-halted|suspend-unless-halted]\n"
+	   "                select the behaviour when the emulator window is asked to quit\n"
+	   "                (default is none)\n"
+#endif
           "-loadvm file    start right away with a saved state (loadvm in monitor)\n"
           "\n"
           "During emulation, the following keys are useful:\n"
@@ -2864,6 +2890,10 @@
    QEMU_OPTION_full_screen,
    QEMU_OPTION_pidfile,
    QEMU_OPTION_no_kqemu,
+
+#ifdef TARGET_I386	       
+    QEMU_OPTION_on_quit
+#endif     
 };
 
 typedef struct QEMUOption {
@@ -2932,6 +2962,9 @@
    { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
    { "full-screen", 0, QEMU_OPTION_full_screen },
    { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
+#ifdef TARGET_I386
+    { "on-quit", HAS_ARG, QEMU_OPTION_on_quit },
+#endif   
 
    /* temporary options */
    { "pci", 0, QEMU_OPTION_pci },
@@ -3383,6 +3416,19 @@
            case QEMU_OPTION_pidfile:
                create_pidfile(optarg);
                break;
+#ifdef TARGET_I386   	       
+            case QEMU_OPTION_on_quit:
+	        if(!strcmp(optarg, "ignore-unless-halted")) {
+		   fprintf(stderr, "%s enabled\n", optarg);
+		   on_quit = 1;
+		}
+		else if(!strcmp(optarg, "suspend-unless-halted")) {
+		   fprintf(stderr, "%s enabled\n", optarg);
+		   on_quit = 2;
+		}
+	        else on_quit = 0;
+	        break;
+#endif	       
 #ifdef USE_KQEMU
            case QEMU_OPTION_no_kqemu:
                kqemu_allowed = 0;
@@ -3696,6 +3742,23 @@
        }
    }
    main_loop();
+
+#ifdef TARGET_I386   
+    if( on_quit == 2 ) {
+       char *f = "suspended.qemu";
+       if( ishalted() ) {
+ 	
+ 	 fprintf(stderr, "VM is halted: removing suspend file %s\n",f);
+ 	 unlink(f);
+ 	 /* qemu_savevm(f); */
+       }
+       else {
+ 	 fprintf(stderr, "Autosaving VM to file %s\n",f);
+ 	 qemu_savevm(f);
+       }
+    }
+#endif   
+   
    quit_timers();
    return 0;
 }
 
 
------------------------------------------------------------------------
Quoted 6 lines

_______________________________________________
Qemu-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

cocoa.m +1 -1
diff -r -U3 qemu-snapshot-2005-05-06_23/cocoa.m qemu-snapshot-2005-05-06_23-on-quit-v0.2/cocoa.m
@@ -444,7 +444,7 @@
 - (void)applicationWillTerminate:(NSNotification *)aNotification
 {
     printf("Application will terminate\n");
-    qemu_system_shutdown_request();
+    qemu_system_shutdown_request(1);
     /* In order to avoid a crash */
     exit(0);
 }
hw/cuda.c +1 -1
diff -r -U3 qemu-snapshot-2005-05-06_23/hw/cuda.c qemu-snapshot-2005-05-06_23-on-quit-v0.2/hw/cuda.c
@@ -532,7 +532,7 @@
         obuf[0] = CUDA_PACKET;
         obuf[1] = 0;
         cuda_send_packet_to_host(s, obuf, 2);
-	qemu_system_shutdown_request();
+	qemu_system_shutdown_request(1);
 	break;
     default:
         break;
hw/pc.c +1 -1
diff -r -U3 qemu-snapshot-2005-05-06_23/hw/pc.c qemu-snapshot-2005-05-06_23-on-quit-v0.2/hw/pc.c
@@ -297,7 +297,7 @@
             shutdown_index++;
             if (shutdown_index == 8) {
                 shutdown_index = 0;
-                qemu_system_shutdown_request();
+                qemu_system_shutdown_request(-1);
             }
         } else {
             shutdown_index = 0;
sdl.c +1 -1
diff -r -U3 qemu-snapshot-2005-05-06_23/sdl.c qemu-snapshot-2005-05-06_23-on-quit-v0.2/sdl.c
@@ -414,7 +414,7 @@
                 sdl_process_key(&ev->key);
             break;
         case SDL_QUIT:
-            qemu_system_shutdown_request();
+	       qemu_system_shutdown_request(1);
             break;
         case SDL_MOUSEMOTION:
             if (gui_grab) {
vl.c +62 -4

115 lines not on this page · raw message

vl.h +1 -1
diff -r -U3 qemu-snapshot-2005-05-06_23/vl.h qemu-snapshot-2005-05-06_23-on-quit-v0.2/vl.h
@@ -109,7 +109,7 @@
 
 void qemu_register_reset(QEMUResetHandler *func, void *opaque);
 void qemu_system_reset_request(void);
-void qemu_system_shutdown_request(void);
+void qemu_system_shutdown_request(int);
 
 void main_loop_wait(int timeout);
 
#42 lore raw

Re: [patch] on-quit-v0.21 with resume/suspend/power-off dialog Re: [patch] Re: [Qemu-devel] Suggestion - trap window-close of VM

This looks great -- thanks!

I suppose one other option that would be kind of neat is if closing Qemu could somehow signal the Windows 2000 guest to shut down. Someone had suggested that earlier in the thread, but it sounded like that would require ACPI support in Qemu? Or is it something that could be generated through APM? Since Qemu is (in effect) the hardware, I guess the question is whether it's possible for the hardware to tell Windows 2000 to shut down?

#43 lore raw

Re: [patch] on-quit-v0.21 with resume/suspend/power-off dialog Re: [patch] Re: [Qemu-devel] Suggestion - trap window-close of VM

You're welcome Ryan. Glad you like it.

As to your other option, it is already the case that the APM bios sends the shutdown command to Qemu by out'ing bytes to a special port, so I imagine it would be possible for Qemu to send commands to the APM bios in a similar fashion. But, can the APM bios instruct Windows 2000 to shut down? I do not know.

Quoted 17 lines · Ryan Rempel

This looks great -- thanks!

I suppose one other option that would be kind of neat is if closing Qemu could somehow signal the Windows 2000 guest to shut down. Someone had suggested that earlier in the thread, but it sounded like that would require ACPI support in Qemu? Or is it something that could be generated through APM? Since Qemu is (in effect) the hardware, I guess the question is whether it's possible for the hardware to tell Windows 2000 to shut down?

_______________________________________________
Qemu-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

#44 lore raw

Re: [patch] on-quit-v0.21 with resume/suspend/power-off dialog Re: [patch] Re: [Qemu-devel] Suggestion - trap window-close of VM

In reply to Ryan Rempel

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 3 lines

I guess
the question is whether it's possible for the hardware to tell Windows 2000 to shut down?

The answer is YES FOR SURE.
If you press the power button the system cleanly shut down.

The question is: which is the event generated by the power button that triggers the shut down?

- --
Flavio Visentin

|                     \|||/
|                    @/0.0\@
|                     \ - /
+------------------oOOo---oOOo------------------

There are only 10 types of people in this world:
those who understand binary, and those who don't.

GPG Key: http://www.zipman.it/gpgkey.asc
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)

iD8DBQFCf+/4usUmHkh1cnoRAoXBAJ4/9YhZXS1nwUUCek4LWi4DLnpGQACeJU1P rVz+muvcSXoVfHpUCm/e1L4=
=aYOu
-----END PGP SIGNATURE-----

#45 lore raw

Re: [patch] on-quit-v0.21 with resume/suspend/power-off dialog Re: [patch] Re: [Qemu-devel] Suggestion - trap window-close of VM

Great. What I recall happens is that the Windows 2000 APM driver calls the APM bios function 0x0B (Get PM Event) every second and, should the APM bios be aware of an event (such as that the power button has been pressed) it signals this in the return value of the function. Thereafter, the Windows 2000 APM driver is expected to call the APM bios again to determine the details of the event and thereafter, if it can, respond to it by e.g. shutting the OS down, entering standby or suspend state, as appropriate.

At a rough guess, we're talking about having the APM bios signal PM event 0x06 (Power Status Change Notification).

When I get some time, I try looking more through http://www.phamhoaiviet.com/archives%5Cebooks%5Capmv12.rtf.

Quoted 44 lines · Flavio Visentin

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 5 lines

I guess
the question is whether it's possible for the hardware to tell Windows 2000 to shut down?

The answer is YES FOR SURE.
If you press the power button the system cleanly shut down.

The question is: which is the event generated by the power button that triggers the shut down?

- --
Flavio Visentin

|                     \|||/
|                    @/0.0\@
|                     \ - /
+------------------oOOo---oOOo------------------

There are only 10 types of people in this world:
those who understand binary, and those who don't.

GPG Key: http://www.zipman.it/gpgkey.asc
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)

iD8DBQFCf+/4usUmHkh1cnoRAoXBAJ4/9YhZXS1nwUUCek4LWi4DLnpGQACeJU1P rVz+muvcSXoVfHpUCm/e1L4=
=aYOu
-----END PGP SIGNATURE-----

_______________________________________________
Qemu-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/qemu-devel

#46 lore raw

[patch] Re: [patch] on-quit-v0.21 with resume/suspend/power-off dialog Re: [patch] Re: [Qemu-devel] Suggestion - trap window-close of VM

In reply to Struan Bartlett

If anyone cares, I've updated my on-quit-0.21 patch to cleanly apply to qemu 0.7.1 (to be precise the 2005-07-23 nightly snapshot of 0.7.1).

Instructions and history below. Feedback still welcome.

Struan

Quoted 37 lines · Struan Bartlett

Having had the APM bios fixed in the 0.7 Qemu release, which allows Windows 2000 to correctly signal Qemu when it wants to shutdown the VM, I've updated my '-on-quit' patch - which prevented the VM from being crudely shut down by accidentally pressing Ctrl-C or closing the VM window - to remove the nasty i386-specific "halt-instruction-detection" code and provide what I hope you will agree is a cleaner replacement.

The new patch instead relies on APM/SDL/Cocoa/Cuda each specifying whether the shutdown request originated from the hardware or from the user. In the case of user request, Qemu's behaviour will depend on the command line option specified: 1. '-on-quit ignore' means ignore the Ctrl-C; 2. '-on-quit suspend' means suspend the VM. In the case of a hardware shutdown, the VM will shut down normally (but if '-on-quit suspend' was selected it will delete the named suspend file first).

The patch features extra options '-on-quit ask' and '-on-quit <filepath>' which both cause Qemu to run a script to ask the user whether they want to resume, suspend or power off the VM. For non-WIN32 platforms, this is easily implemented it using a script that the xmessage command i.e.:

#!/bin/sh

exec /usr/bin/X11/xmessage -center -timeout 10 -buttons 'Resume:0,Suspend:1,Power Off:2' 'Do you want to resume, suspend, or power off this virtual machine?'

The '-on-quit ask' option assumes a default script filename "on_quit_ask", assumed to be in the CONFIG_QEMU_SHAREDIR directory (i.e. usually /usr/local/share/qemu).

Example command (Linux) which should correctly buffer naive users from accidental VM shutdown and suspend file overwriting: it resumes from suspended.qemu file if it exists; asks user whether to resume, power off or suspend on CTRL-C or window close; suspend saves to the same file; power off deleted the suspend file.

Quoted 101 lines

qemu -hda win2k.raw -m 64 -monitor null -loadvm suspended.qemu -on-quit ask

Feedback welcome!

Struan

Quoted 93 lines · Struan Bartlett

Hi,

I've attached a patch against the 2005-03-26 snapshot that implements two '-on-quit' options for the emulator window: ignore-unless-halted and suspend-unless-halted, that aim to make it safe to allow naive users to (try to) close the VM window by trapping requests to shutdown and either ignoring them or forcing a save of the VM state before obeying them.

Caveat: I'll come clean straight away that the patch is implemented using a nasty TARGET_i386-specific hack that detects whether the guest operating system has permanently halted by looking to see if the last instruction executed was 0xF4 and, if so, whether the IF flag is cleared. Saying that, this system appears to work reasonably well on my Pentium host running a Windows 2000 guest, but I have not tested it on any other systems.

Usage:

1. If you provide naive users with a variation on the following command line, then you can let your naive users (try to) close the VM window as much as they like. Unless the guest has permanently halted, attempts to close the VM window should save the VM state to 'suspended.qemu' in the current working directory before qemu exits. The same command line will restart the VM where it left off. Then, once the guest has permanently halted, qemu will delete the suspended.qemu file so that the next launch of qemu will boot afresh:

qemu -hda win2k.raw -m 64 -monitor null -loadvm suspended.qemu -on-quit suspend-unless-halted

2. Alternatively, the following command will make qemu ignore the user's request to close the emulator window unless the guest has already permanently halted:

qemu -hda win2k.raw -m 64 -monitor null -on-quit ignore-unless-halted

3. If you combine this with a test of whether qemu is already running, then it should be safe to let naive users try to both launch and to close qemu as much as they like. e.g.

killall -0 qemu 2>/dev/null; if [ $? == 1 ]; then qemu -hda win2k.raw -m 64 -monitor null -loadvm suspended.qemu -on-quit suspend-unless-halted; fi &

4. Finally, if your leave out the -on-quit option altogether, then qemu's behaviour should remain completely unchanged.

I hope this is useful for some i386/W2K users out there. Any constructive criticism appreciated. If you know how I could improve permanent halt detection (that doesn't require in-depth knowledge of APM or ACPI) then please let me know.

Struan

Quoted 36 lines · Struan Bartlett
Quoted 21 lines · Ryan Rempel

On Mon, Nov 29, 2004 at 21:46:54 +0100, Lennert Buytenhek wrote

Quoted 13 lines · Richard Neill
Quoted 7 lines

A thought that occurred to me. If one is running a virtual machine (eg copy of WinXP), then simply closing the qemu window is a really bad idea, since it will effectively crash the guest.

Related thought -- it would be way cool if we could make killing qemu do exactly happens when you press the power button on an ACPI-capable machine with any recent OS on it (auto shutdown.)

I was wondering if anyone has followed up on this suggestion. I'm putting together a Qemu-based setup for some relatively naive users, and ideally I'd like to be able to deal with this in a reasonable elegant way (the ACPI hook sounds very elegant indeed).

Quoted 7 lines

Alternatively, how do people deal with the problem of naive users who might just close the Qemu window without shutting down the guest properly? I'm working in a KDE environment -- perhaps there is a way in KDE to prevent the close button from appearing? But that wouldn't catch every case either (for instance, if the user were to shut down the host).

This sounds like a good idea. An alternative solution, that might be more straightforward to implement if Qemu doesn't implement ACPI yet, would be for the kill signal to simply cause Qemu to do the equivalent of entering 'stop' and 'savevm <somefilepath>' into the monitor.

cocoa.m +1 -1
diff -rbw -u qemu-snapshot-2005-07-25_23/cocoa.m qemu-snapshot-2005-07-25_23-on-quit/cocoa.m
@@ -444,7 +444,7 @@
 - (void)applicationWillTerminate:(NSNotification *)aNotification
 {
     printf("Application will terminate\n");
-    qemu_system_shutdown_request();
+    qemu_system_shutdown_request(1);
     /* In order to avoid a crash */
     exit(0);
 }
hw/cuda.c +1 -1
diff -rbw -u qemu-snapshot-2005-07-25_23/hw/cuda.c qemu-snapshot-2005-07-25_23-on-quit/hw/cuda.c
@@ -557,7 +557,7 @@
         obuf[0] = CUDA_PACKET;
         obuf[1] = 0;
         cuda_send_packet_to_host(s, obuf, 2);
-	qemu_system_shutdown_request();
+	qemu_system_shutdown_request(1);
 	break;
     default:
         break;
hw/pc.c +1 -1
diff -rbw -u qemu-snapshot-2005-07-25_23/hw/pc.c qemu-snapshot-2005-07-25_23-on-quit/hw/pc.c
@@ -323,7 +323,7 @@
             shutdown_index++;
             if (shutdown_index == 8) {
                 shutdown_index = 0;
-                qemu_system_shutdown_request();
+                qemu_system_shutdown_request(-1);
             }
         } else {
             shutdown_index = 0;
sdl.c +1 -1
diff -rbw -u qemu-snapshot-2005-07-25_23/sdl.c qemu-snapshot-2005-07-25_23-on-quit/sdl.c
@@ -413,7 +413,7 @@
                 sdl_process_key(&ev->key);
             break;
         case SDL_QUIT:
-            qemu_system_shutdown_request();
+	       qemu_system_shutdown_request(1);
             break;
         case SDL_MOUSEMOTION:
             if (gui_grab) {
vl.c +60 -2

114 lines not on this page · raw message

vl.h +1 -1
diff -rbw -u qemu-snapshot-2005-07-25_23/vl.h qemu-snapshot-2005-07-25_23-on-quit/vl.h
@@ -109,7 +109,7 @@
 
 void qemu_register_reset(QEMUResetHandler *func, void *opaque);
 void qemu_system_reset_request(void);
-void qemu_system_shutdown_request(void);
+void qemu_system_shutdown_request(int);
 void qemu_system_powerdown_request(void);
 #if !defined(TARGET_SPARC)
 // Please implement a power failure function to signal the OS