On 02/19/13 15:40, David Woodhouse wrote: > On Tue, 2013-02-19 at 13:31 +0100, Paolo Bonzini wrote: >> So you can make the hard reset line a qemu_irq (output in PIIX, input in >> i440FX) using qdev_init_gpio_in/out. The input side in the i440FX then >> can reset the PAM registers while the output side can pulse it before >> calling qemu_system_reset_request() if RCR bit 1 is set. Then you can >> connect it using qdev_connect_gpio_out/qdev_get_gpio_in in >> i440fx_common_init. > > Like this? I've still left i440fx_reset() hooked up as dc->reset, and > conditionally do the full reset based on a flag in the state. If I > actually *do* the reset directly from i440fx_handle_reset() rather than > just setting the flag there, it might happen too early? >
> @@ -521,6 +563,8 @@ static void rcr_write(void *opaque, hwaddr addr, uint64_t > val, unsigned len) > PIIX3State *d = opaque; > > if (val & 4) { > + if (val & 2) > + qemu_irq_pulse(d->reset_out); > qemu_system_reset_request(); > return; > } We can't start to savevm between qemu_irq_pulse() and qemu_system_reset_request(); OK. I wonder though if we can enter do_savevm() after rcr_write() returns, but before i440fx_reset() -- the registered reset handler -- is called. Consider a monitor sitting on stdio. First we create the chardev: main() [vl.c] chardev_init_func() qemu_chr_new_from_opts() [qemu-char.c] qemu_chr_open_stdio() via funcptr qemu_chr_open_fd() registers "fd_chr_update_read_handler" Then we hook it to the monitor: main() [vl.c] mon_init_func() qemu_chr_find() [qemu-char.c] monitor_init() [monitor.c] qemu_chr_add_handlers() [qemu-char.c] fd_chr_update_read_handler() via earlier registration qemu_set_fd_handler2() [iohandler.c] append to global list "io_handlers" Then, CPU thread: qemu_kvm_cpu_thread_fn() [cpus.c] kvm_cpu_exec() [kvm-all.c] qemu_mutex_lock_iothread() kvm_handle_io() ... rcr_write() ... loops back qemu_mutex_unlock_iothread() UNLOCK IO thread (with kvm_enabled()==true): main_loop() [vl.c] main_loop_wait(nonblocking = false) [main-loop.c] os_host_main_loop_wait(timeout > 0) qemu_mutex_unlock_iothread() select() qemu_mutex_lock_iothread() LOCK glib_select_poll() qemu_iohandler_poll() [iohandler.c] scans global "io_handlers" list, monitor fd ready monitor_read() / monitor_control_read() handle_user_command() / handle_qmp_command() do_savevm() [savevm.c] via funcptr Apparently, in theory at least, the guest can trap to rcr_write() and set "PCII440FXState.hard_reset", then immediately qemu can save a VM snapshot. If we restore this snapshot, instead of the hard reset we'll do a soft reset. Consider adding "vmstate_i440fx" to "vmstate_i440fx", perhaps? :) Laszlo