This patch series makes suspend support in qemu alot more useful. Right now the guest can put itself into s3, but qemu will wakeup the guest instantly. With this patch series applied the guest will stay suspended instead and there are a few events which can kick the guest out of suspend state: A monitor command, ps/2 input, serial input, rtc. Not much yet, but it''s a start with the low hanging fruits ;) Changes in v2: * Add a suspend notifier. * Replace the cmos_s3 qemu_irq with the notifier, zap a bunch of hackish cmos_s3 windup code (this touches xen-all.c, thus cc xen-devel). * Add rtc wakeup support. Gerd Hoffmann (6): suspend: add infrastructure suspend: switch acpi s3 to new infrastructure. suspend: add wakeup monitor command suspend: make ps/2 devices wakeup the guest suspend: make serial ports wakeup the guest. suspend: make rtc alarm wakeup the guest. hmp-commands.hx | 14 ++++++++++++++ hmp.c | 5 +++++ hmp.h | 1 + hw/acpi.c | 11 +---------- hw/acpi.h | 2 -- hw/acpi_piix4.c | 3 +-- hw/mc146818rtc.c | 17 +++++++++++++++++ hw/mips_malta.c | 2 +- hw/pc.c | 11 ----------- hw/pc.h | 3 +-- hw/pc_piix.c | 8 +------- hw/ps2.c | 6 ++++++ hw/serial.c | 6 ++++++ hw/vt82c686.c | 1 - qapi-schema.json | 11 +++++++++++ qmp-commands.hx | 21 +++++++++++++++++++++ qmp.c | 5 +++++ sysemu.h | 3 +++ vl.c | 28 ++++++++++++++++++++++++++++ xen-all.c | 11 ++++++----- 20 files changed, 128 insertions(+), 41 deletions(-)
This patch adds some infrastructure to handle suspend and resume to qemu. First there are two functions to switch state and second there is a suspend notifier: * qemu_system_suspend_request() is supposed to be called when the guest asks for being be suspended, for example via ACPI. * qemu_system_wakeup_request is supposed to be called on events which should wake up the guest. * qemu_register_suspend_notifier can be used to register a notifier which will be called when the guest is suspended. Machine types and device models can hook in there to modify state if needed. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- sysemu.h | 3 +++ vl.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 0 deletions(-) diff --git a/sysemu.h b/sysemu.h index ddef2bb..22470a3 100644 --- a/sysemu.h +++ b/sysemu.h @@ -39,6 +39,9 @@ void vm_stop(RunState state); void vm_stop_force_state(RunState state); void qemu_system_reset_request(void); +void qemu_system_suspend_request(void); +void qemu_register_suspend_notifier(Notifier *notifier); +void qemu_system_wakeup_request(void); void qemu_system_shutdown_request(void); void qemu_system_powerdown_request(void); void qemu_system_debug_request(void); diff --git a/vl.c b/vl.c index ba55b35..755cd67 100644 --- a/vl.c +++ b/vl.c @@ -1282,6 +1282,9 @@ static int shutdown_requested, shutdown_signal = -1; static pid_t shutdown_pid; static int powerdown_requested; static int debug_requested; +static bool is_suspended; +static NotifierList suspend_notifiers + NOTIFIER_LIST_INITIALIZER(suspend_notifiers); static RunState vmstop_requested = RUN_STATE_MAX; int qemu_shutdown_requested_get(void) @@ -1397,6 +1400,31 @@ void qemu_system_reset_request(void) qemu_notify_event(); } +void qemu_system_suspend_request(void) +{ + if (is_suspended) { + return; + } + cpu_stop_current(); + notifier_list_notify(&suspend_notifiers, NULL); + is_suspended = true; +} + +void qemu_register_suspend_notifier(Notifier *notifier) +{ + notifier_list_add(&suspend_notifiers, notifier); +} + +void qemu_system_wakeup_request(void) +{ + if (!is_suspended) { + return; + } + reset_requested = 1; + qemu_notify_event(); + is_suspended = false; +} + void qemu_system_killed(int signal, pid_t pid) { shutdown_signal = signal; -- 1.7.1
Gerd Hoffmann
2012-Jan-16 18:15 UTC
[PATCH v2 2/6] suspend: switch acpi s3 to new infrastructure.
This patch switches pc s3 suspend over to the new infrastructure. The cmos_s3 qemu_irq is killed, the new notifier is used instead. The xen hack goes away with that too, the hypercall can simply be done in a notifier function now. This patch also makes the guest actually stay suspended instead of leaving suspend instantly, so it is useful for more than just testing whenever the suspend/resume cycle actually works. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/acpi.c | 11 +---------- hw/acpi.h | 2 -- hw/acpi_piix4.c | 3 +-- hw/mc146818rtc.c | 12 ++++++++++++ hw/mips_malta.c | 2 +- hw/pc.c | 11 ----------- hw/pc.h | 3 +-- hw/pc_piix.c | 8 +------- hw/vt82c686.c | 1 - xen-all.c | 11 ++++++----- 10 files changed, 23 insertions(+), 41 deletions(-) diff --git a/hw/acpi.c b/hw/acpi.c index 9c35f2d..de93449 100644 --- a/hw/acpi.c +++ b/hw/acpi.c @@ -327,11 +327,6 @@ void acpi_pm_tmr_reset(ACPIPMTimer *tmr) } /* ACPI PM1aCNT */ -void acpi_pm1_cnt_init(ACPIPM1CNT *pm1_cnt, qemu_irq cmos_s3) -{ - pm1_cnt->cmos_s3 = cmos_s3; -} - void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val) { pm1_cnt->cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE); @@ -348,8 +343,7 @@ void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val) Pretend that resume was caused by power button */ pm1a->sts | (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS); - qemu_system_reset_request(); - qemu_irq_raise(pm1_cnt->cmos_s3); + qemu_system_suspend_request(); default: break; } @@ -370,9 +364,6 @@ void acpi_pm1_cnt_update(ACPIPM1CNT *pm1_cnt, void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt) { pm1_cnt->cnt = 0; - if (pm1_cnt->cmos_s3) { - qemu_irq_lower(pm1_cnt->cmos_s3); - } } /* ACPI GPE */ diff --git a/hw/acpi.h b/hw/acpi.h index c141e65..e0c7dbe 100644 --- a/hw/acpi.h +++ b/hw/acpi.h @@ -115,8 +115,6 @@ void acpi_pm1_evt_reset(ACPIPM1EVT *pm1); /* PM1a_CNT: piix and ich9 don''t implement PM1b CNT. */ struct ACPIPM1CNT { uint16_t cnt; - - qemu_irq cmos_s3; }; typedef struct ACPIPM1CNT ACPIPM1CNT; diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index d9075e6..1e575fd 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -373,7 +373,7 @@ static int piix4_pm_initfn(PCIDevice *dev) } i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, - qemu_irq sci_irq, qemu_irq cmos_s3, qemu_irq smi_irq, + qemu_irq sci_irq, qemu_irq smi_irq, int kvm_enabled) { PCIDevice *dev; @@ -384,7 +384,6 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, s = DO_UPCAST(PIIX4PMState, dev, dev); s->irq = sci_irq; - acpi_pm1_cnt_init(&s->pm1_cnt, cmos_s3); s->smi_irq = smi_irq; s->kvm_enabled = kvm_enabled; diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index 9cbd052..ae4e16c 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -101,6 +101,7 @@ typedef struct RTCState { QEMUTimer *second_timer; QEMUTimer *second_timer2; Notifier clock_reset_notifier; + Notifier suspend_notifier; } RTCState; static void rtc_set_time(RTCState *s); @@ -590,6 +591,14 @@ static void rtc_notify_clock_reset(Notifier *notifier, void *data) #endif } +/* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE) + BIOS will read it and start S3 resume at POST Entry */ +static void rtc_notify_suspend(Notifier *notifier, void *data) +{ + RTCState *s = container_of(notifier, RTCState, suspend_notifier); + rtc_set_memory(&s->dev, 0xF, 0xFE); +} + static void rtc_reset(void *opaque) { RTCState *s = opaque; @@ -661,6 +670,9 @@ static int rtc_initfn(ISADevice *dev) s->clock_reset_notifier.notify = rtc_notify_clock_reset; qemu_register_clock_reset_notifier(rtc_clock, &s->clock_reset_notifier); + s->suspend_notifier.notify = rtc_notify_suspend; + qemu_register_suspend_notifier(&s->suspend_notifier); + s->next_second_time qemu_get_clock_ns(rtc_clock) + (get_ticks_per_sec() * 99) / 100; qemu_mod_timer(s->second_timer2, s->next_second_time); diff --git a/hw/mips_malta.c b/hw/mips_malta.c index e625ec3..b246ebf 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -966,7 +966,7 @@ void mips_malta_init (ram_addr_t ram_size, pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1); usb_uhci_piix4_init(pci_bus, piix4_devfn + 2); smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, - isa_get_irq(NULL, 9), NULL, NULL, 0); + isa_get_irq(NULL, 9), NULL, 0); /* TODO: Populate SPD eeprom data. */ smbus_eeprom_init(smbus, 8, NULL, 0); pit = pit_init(isa_bus, 0x40, 0); diff --git a/hw/pc.c b/hw/pc.c index 85304cf..4ce046c 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -901,17 +901,6 @@ static DeviceState *apic_init(void *env, uint8_t apic_id) return dev; } -/* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE) - BIOS will read it and start S3 resume at POST Entry */ -void pc_cmos_set_s3_resume(void *opaque, int irq, int level) -{ - ISADevice *s = opaque; - - if (level) { - rtc_set_memory(s, 0xF, 0xFE); - } -} - void pc_acpi_smi_interrupt(void *opaque, int irq, int level) { CPUState *s = opaque; diff --git a/hw/pc.h b/hw/pc.h index 13e41f1..68714c7 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -128,7 +128,6 @@ void i8042_setup_a20_line(ISADevice *dev, qemu_irq *a20_out); extern int fd_bootchk; void pc_register_ferr_irq(qemu_irq irq); -void pc_cmos_set_s3_resume(void *opaque, int irq, int level); void pc_acpi_smi_interrupt(void *opaque, int irq, int level); void pc_cpus_init(const char *cpu_model); @@ -167,7 +166,7 @@ int acpi_table_add(const char *table_desc); /* acpi_piix.c */ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, - qemu_irq sci_irq, qemu_irq cmos_s3, qemu_irq smi_irq, + qemu_irq sci_irq, qemu_irq smi_irq, int kvm_enabled); void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr); diff --git a/hw/pc_piix.c b/hw/pc_piix.c index b70431f..9684ed0 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -90,7 +90,6 @@ static void pc_init1(MemoryRegion *system_memory, qemu_irq *cpu_irq; qemu_irq *gsi; qemu_irq *i8259; - qemu_irq *cmos_s3; qemu_irq *smi_irq; GSIState *gsi_state; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; @@ -234,15 +233,10 @@ static void pc_init1(MemoryRegion *system_memory, if (pci_enabled && acpi_enabled) { i2c_bus *smbus; - if (!xen_enabled()) { - cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1); - } else { - cmos_s3 = qemu_allocate_irqs(xen_cmos_set_s3_resume, rtc_state, 1); - } smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1); /* TODO: Populate SPD eeprom data. */ smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, - gsi[9], *cmos_s3, *smi_irq, + gsi[9], *smi_irq, kvm_enabled()); smbus_eeprom_init(smbus, 8, NULL, 0); } diff --git a/hw/vt82c686.c b/hw/vt82c686.c index 038128b..9c730d3 100644 --- a/hw/vt82c686.c +++ b/hw/vt82c686.c @@ -425,7 +425,6 @@ static int vt82c686b_pm_initfn(PCIDevice *dev) apm_init(&s->apm, NULL, s); acpi_pm_tmr_init(&s->tmr, pm_tmr_timer); - acpi_pm1_cnt_init(&s->pm1_cnt, NULL); pm_smbus_init(&s->dev.qdev, &s->smb); diff --git a/xen-all.c b/xen-all.c index c86ebf4..4030f3e 100644 --- a/xen-all.c +++ b/xen-all.c @@ -87,6 +87,7 @@ typedef struct XenIOState { const XenPhysmap *log_for_dirtybit; Notifier exit; + Notifier suspend; } XenIOState; /* Xen specific function for piix pci */ @@ -119,12 +120,9 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len) } } -void xen_cmos_set_s3_resume(void *opaque, int irq, int level) +static void xen_suspend_notifier(Notifier *notifier, void *data) { - pc_cmos_set_s3_resume(opaque, irq, level); - if (level) { - xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 3); - } + xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 3); } /* Xen Interrupt Controller */ @@ -933,6 +931,9 @@ int xen_hvm_init(void) state->exit.notify = xen_exit_notifier; qemu_add_exit_notifier(&state->exit); + state->suspend.notify = xen_suspend_notifier; + qemu_register_suspend_notifier(&state->suspend); + xc_get_hvm_param(xen_xc, xen_domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn); DPRINTF("shared page at pfn %lx\n", ioreq_pfn); state->shared_page = xc_map_foreign_range(xen_xc, xen_domid, XC_PAGE_SIZE, -- 1.7.1
This patch adds a wakeup monitor command which will simply wake up suspended guests. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hmp-commands.hx | 14 ++++++++++++++ hmp.c | 5 +++++ hmp.h | 1 + qapi-schema.json | 11 +++++++++++ qmp-commands.hx | 21 +++++++++++++++++++++ qmp.c | 5 +++++ 6 files changed, 57 insertions(+), 0 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index a586498..c62871a 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -313,6 +313,20 @@ Resume emulation. ETEXI { + .name = "wakeup", + .args_type = "", + .params = "", + .help = "wakeup guest from suspend", + .mhandler.cmd = hmp_wakeup, + }, + +STEXI +@item wakeup +@findex wakeup +Wakeup guest from suspend. +ETEXI + + { .name = "gdbserver", .args_type = "device:s?", .params = "[device]", diff --git a/hmp.c b/hmp.c index e7659d5..1a14684 100644 --- a/hmp.c +++ b/hmp.c @@ -594,6 +594,11 @@ void hmp_cont(Monitor *mon, const QDict *qdict) } } +void hmp_wakeup(Monitor *mon, const QDict *qdict) +{ + qmp_wakeup(NULL); +} + void hmp_inject_nmi(Monitor *mon, const QDict *qdict) { Error *errp = NULL; diff --git a/hmp.h b/hmp.h index 093242d..76eb3df 100644 --- a/hmp.h +++ b/hmp.h @@ -40,6 +40,7 @@ void hmp_cpu(Monitor *mon, const QDict *qdict); void hmp_memsave(Monitor *mon, const QDict *qdict); void hmp_pmemsave(Monitor *mon, const QDict *qdict); void hmp_cont(Monitor *mon, const QDict *qdict); +void hmp_wakeup(Monitor *mon, const QDict *qdict); void hmp_inject_nmi(Monitor *mon, const QDict *qdict); void hmp_set_link(Monitor *mon, const QDict *qdict); void hmp_block_passwd(Monitor *mon, const QDict *qdict); diff --git a/qapi-schema.json b/qapi-schema.json index 44cf764..75773d4 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -967,6 +967,17 @@ { ''command'': ''cont'' } ## +# @wakeup: +# +# Wakrup guest from suspend +# +# Since: 1.1 +# +# Returns: nothing. +## +{ ''command'': ''wakeup'' } + +## # @inject-nmi: # # Injects an Non-Maskable Interrupt into all guest''s VCPUs. diff --git a/qmp-commands.hx b/qmp-commands.hx index 7e3f4b9..2c84a7a 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -218,6 +218,27 @@ Example: EQMP { + .name = "wakeup", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_wakeup, + }, + +SQMP +wakeup +------ + +Wakeup guest from suspend. + +Arguments: None. + +Example: + +-> { "execute": "wakeup" } +<- { "return": {} } + +EQMP + + { .name = "system_reset", .args_type = "", .mhandler.cmd_new = qmp_marshal_input_system_reset, diff --git a/qmp.c b/qmp.c index 5e09b41..f8b1dc7 100644 --- a/qmp.c +++ b/qmp.c @@ -158,6 +158,11 @@ void qmp_cont(Error **errp) vm_start(); } +void qmp_wakeup(Error **errp) +{ + qemu_system_wakeup_request(); +} + DevicePropertyInfoList *qmp_qom_list(const char *path, Error **errp) { DeviceState *dev; -- 1.7.1
Gerd Hoffmann
2012-Jan-16 18:15 UTC
[PATCH v2 4/6] suspend: make ps/2 devices wakeup the guest
This patch adds wakeup support to ps/2 emulation. Any key press on the ps/2 keyboard will wakeup the guest. Likewise any mouse button press will wakeup the guest. Mouse moves are ignored, so the guest will not wakeup in case your mouse crosses the vnc window of a suspended guest by accident. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/ps2.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/hw/ps2.c b/hw/ps2.c index 1d9057b..d1b2505 100644 --- a/hw/ps2.c +++ b/hw/ps2.c @@ -24,6 +24,7 @@ #include "hw.h" #include "ps2.h" #include "console.h" +#include "sysemu.h" /* debug PC keyboard */ //#define DEBUG_KBD @@ -154,6 +155,7 @@ static void ps2_put_keycode(void *opaque, int keycode) { PS2KbdState *s = opaque; + qemu_system_wakeup_request(); /* XXX: add support for scancode set 1 */ if (!s->translate && keycode < 0xe0 && s->scancode_set > 1) { if (keycode & 0x80) { @@ -368,6 +370,10 @@ static void ps2_mouse_event(void *opaque, return; s->mouse_buttons = buttons_state; + if (buttons_state) { + qemu_system_wakeup_request(); + } + if (!(s->mouse_status & MOUSE_STATUS_REMOTE) && (s->common.queue.count < (PS2_QUEUE_SIZE - 16))) { for(;;) { -- 1.7.1
Gerd Hoffmann
2012-Jan-16 18:15 UTC
[PATCH v2 5/6] suspend: make serial ports wakeup the guest.
Add a ''wakeup'' property to the serial port. It is off by default. When enabled any incoming character on the serial line will wake up the guest. Useful for guests which have a serial console configured. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/serial.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/hw/serial.c b/hw/serial.c index d35c7a9..96ac7c1 100644 --- a/hw/serial.c +++ b/hw/serial.c @@ -139,6 +139,7 @@ struct SerialState { int it_shift; int baudbase; int tsr_retry; + uint32_t wakeup; uint64_t last_xmit_ts; /* Time when the last byte was successfully sent out of the tsr */ SerialFIFO recv_fifo; @@ -635,6 +636,10 @@ static int serial_can_receive1(void *opaque) static void serial_receive1(void *opaque, const uint8_t *buf, int size) { SerialState *s = opaque; + + if (s->wakeup) { + qemu_system_wakeup_request(); + } if(s->fcr & UART_FCR_FE) { int i; for (i = 0; i < size; i++) { @@ -889,6 +894,7 @@ static ISADeviceInfo serial_isa_info = { DEFINE_PROP_HEX32("iobase", ISASerialState, iobase, -1), DEFINE_PROP_UINT32("irq", ISASerialState, isairq, -1), DEFINE_PROP_CHR("chardev", ISASerialState, state.chr), + DEFINE_PROP_UINT32("wakeup", ISASerialState, state.wakeup, 0), DEFINE_PROP_END_OF_LIST(), }, }; -- 1.7.1
Gerd Hoffmann
2012-Jan-16 18:15 UTC
[PATCH v2 6/6] suspend: make rtc alarm wakeup the guest.
Add a ''wakeup'' property to the mc146818rtc. It is on by default. When enabled the rtc will wake up the guest when the alarm fires. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/mc146818rtc.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index ae4e16c..039c603 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -86,6 +86,7 @@ typedef struct RTCState { uint8_t cmos_index; struct tm current_tm; int32_t base_year; + uint32_t wakeup; qemu_irq irq; qemu_irq sqw_irq; int it_shift; @@ -431,6 +432,9 @@ static void rtc_update_second2(void *opaque) ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 || rtc_from_bcd(s, s->cmos_data[RTC_HOURS_ALARM]) == s->current_tm.tm_hour)) { + if (s->wakeup) { + qemu_system_wakeup_request(); + } s->cmos_data[RTC_REG_C] |= 0xa0; qemu_irq_raise(s->irq); } @@ -714,6 +718,7 @@ static ISADeviceInfo mc146818rtc_info = { .init = rtc_initfn, .qdev.props = (Property[]) { DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980), + DEFINE_PROP_UINT32("wakeup", RTCState, wakeup, 1), DEFINE_PROP_END_OF_LIST(), } }; -- 1.7.1
On 01/16/2012 07:15 PM, Gerd Hoffmann wrote:> This patch series makes suspend support in qemu alot more useful. Right > now the guest can put itself into s3, but qemu will wakeup the guest > instantly. With this patch series applied the guest will stay suspended > instead and there are a few events which can kick the guest out of > suspend state: A monitor command, ps/2 input, serial input, rtc. Not > much yet, but it''s a start with the low hanging fruits ;) > > Changes in v2: > * Add a suspend notifier. > * Replace the cmos_s3 qemu_irq with the notifier, zap a bunch of hackish > cmos_s3 windup code (this touches xen-all.c, thus cc xen-devel). > * Add rtc wakeup support. > > Gerd Hoffmann (6): > suspend: add infrastructure > suspend: switch acpi s3 to new infrastructure. > suspend: add wakeup monitor command > suspend: make ps/2 devices wakeup the guest > suspend: make serial ports wakeup the guest. > suspend: make rtc alarm wakeup the guest. > > hmp-commands.hx | 14 ++++++++++++++ > hmp.c | 5 +++++ > hmp.h | 1 + > hw/acpi.c | 11 +---------- > hw/acpi.h | 2 -- > hw/acpi_piix4.c | 3 +-- > hw/mc146818rtc.c | 17 +++++++++++++++++ > hw/mips_malta.c | 2 +- > hw/pc.c | 11 ----------- > hw/pc.h | 3 +-- > hw/pc_piix.c | 8 +------- > hw/ps2.c | 6 ++++++ > hw/serial.c | 6 ++++++ > hw/vt82c686.c | 1 - > qapi-schema.json | 11 +++++++++++ > qmp-commands.hx | 21 +++++++++++++++++++++ > qmp.c | 5 +++++ > sysemu.h | 3 +++ > vl.c | 28 ++++++++++++++++++++++++++++ > xen-all.c | 11 ++++++----- > 20 files changed, 128 insertions(+), 41 deletions(-)Nice. :) Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Paolo
Luiz Capitulino
2012-Jan-19 13:19 UTC
Re: [PATCH v2 3/6] suspend: add wakeup monitor command
On Mon, 16 Jan 2012 19:15:12 +0100 Gerd Hoffmann <kraxel@redhat.com> wrote:> This patch adds a wakeup monitor command which will simply wake up > suspended guests. > > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> > --- > hmp-commands.hx | 14 ++++++++++++++ > hmp.c | 5 +++++ > hmp.h | 1 + > qapi-schema.json | 11 +++++++++++ > qmp-commands.hx | 21 +++++++++++++++++++++ > qmp.c | 5 +++++ > 6 files changed, 57 insertions(+), 0 deletions(-) > > diff --git a/hmp-commands.hx b/hmp-commands.hx > index a586498..c62871a 100644 > --- a/hmp-commands.hx > +++ b/hmp-commands.hx > @@ -313,6 +313,20 @@ Resume emulation. > ETEXI > > { > + .name = "wakeup", > + .args_type = "", > + .params = "", > + .help = "wakeup guest from suspend", > + .mhandler.cmd = hmp_wakeup, > + }, > + > +STEXI > +@item wakeup > +@findex wakeup > +Wakeup guest from suspend. > +ETEXI > + > + { > .name = "gdbserver", > .args_type = "device:s?", > .params = "[device]", > diff --git a/hmp.c b/hmp.c > index e7659d5..1a14684 100644 > --- a/hmp.c > +++ b/hmp.c > @@ -594,6 +594,11 @@ void hmp_cont(Monitor *mon, const QDict *qdict) > } > } > > +void hmp_wakeup(Monitor *mon, const QDict *qdict) > +{ > + qmp_wakeup(NULL); > +} > + > void hmp_inject_nmi(Monitor *mon, const QDict *qdict) > { > Error *errp = NULL; > diff --git a/hmp.h b/hmp.h > index 093242d..76eb3df 100644 > --- a/hmp.h > +++ b/hmp.h > @@ -40,6 +40,7 @@ void hmp_cpu(Monitor *mon, const QDict *qdict); > void hmp_memsave(Monitor *mon, const QDict *qdict); > void hmp_pmemsave(Monitor *mon, const QDict *qdict); > void hmp_cont(Monitor *mon, const QDict *qdict); > +void hmp_wakeup(Monitor *mon, const QDict *qdict); > void hmp_inject_nmi(Monitor *mon, const QDict *qdict); > void hmp_set_link(Monitor *mon, const QDict *qdict); > void hmp_block_passwd(Monitor *mon, const QDict *qdict); > diff --git a/qapi-schema.json b/qapi-schema.json > index 44cf764..75773d4 100644 > --- a/qapi-schema.json > +++ b/qapi-schema.json > @@ -967,6 +967,17 @@ > { ''command'': ''cont'' } > > ## > +# @wakeup: > +# > +# Wakrup guest from suspends/Wakrup/Wakeup Very nice series: Acked-by: Luiz Capitulino <lcapitulino@redhat.com>> +# > +# Since: 1.1 > +# > +# Returns: nothing. > +## > +{ ''command'': ''wakeup'' } > + > +## > # @inject-nmi: > # > # Injects an Non-Maskable Interrupt into all guest''s VCPUs. > diff --git a/qmp-commands.hx b/qmp-commands.hx > index 7e3f4b9..2c84a7a 100644 > --- a/qmp-commands.hx > +++ b/qmp-commands.hx > @@ -218,6 +218,27 @@ Example: > EQMP > > { > + .name = "wakeup", > + .args_type = "", > + .mhandler.cmd_new = qmp_marshal_input_wakeup, > + }, > + > +SQMP > +wakeup > +------ > + > +Wakeup guest from suspend. > + > +Arguments: None. > + > +Example: > + > +-> { "execute": "wakeup" } > +<- { "return": {} } > + > +EQMP > + > + { > .name = "system_reset", > .args_type = "", > .mhandler.cmd_new = qmp_marshal_input_system_reset, > diff --git a/qmp.c b/qmp.c > index 5e09b41..f8b1dc7 100644 > --- a/qmp.c > +++ b/qmp.c > @@ -158,6 +158,11 @@ void qmp_cont(Error **errp) > vm_start(); > } > > +void qmp_wakeup(Error **errp) > +{ > + qemu_system_wakeup_request(); > +} > + > DevicePropertyInfoList *qmp_qom_list(const char *path, Error **errp) > { > DeviceState *dev;