qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [RFC PATCH] Distinguish between reset types


From: Laszlo Ersek
Subject: Re: [Qemu-devel] [RFC PATCH] Distinguish between reset types
Date: Tue, 19 Feb 2013 18:51:01 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20130108 Thunderbird/10.0.12

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



reply via email to

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