From: Jan Kiszka <jan.kiszka@web.de>
To: Wen Congyang <wency@cn.fujitsu.com>
Cc: kvm list <kvm@vger.kernel.org>,
qemu-devel <qemu-devel@nongnu.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
Avi Kivity <avi@redhat.com>,
"Daniel P. Berrange" <berrange@redhat.com>,
KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>,
Gleb Natapov <gleb@redhat.com>, Blue Swirl <blauwirbel@gmail.com>,
Eric Blake <eblake@redhat.com>, Andrew Jones <drjones@redhat.com>,
Marcelo Tosatti <mtosatti@redhat.com>
Subject: Re: [PATCH v9 5/6] introduce a new qom device to deal with panicked event
Date: Fri, 24 Aug 2012 08:21:57 +0200 [thread overview]
Message-ID: <50371D85.1080601@web.de> (raw)
In-Reply-To: <503719C1.4080304@cn.fujitsu.com>
[-- Attachment #1: Type: text/plain, Size: 9057 bytes --]
On 2012-08-24 08:05, Wen Congyang wrote:
> At 08/23/2012 06:51 PM, Jan Kiszka Wrote:
>> On 2012-08-23 04:32, Wen Congyang wrote:
>>> If the target is x86/x86_64, the guest's kernel will write 0x01 to the
>>> port KVM_PV_EVENT_PORT when it is panciked. This patch introduces a new
>>> qom device kvm_pv_ioport to listen this I/O port, and deal with panicked
>>> event according to panicked_action's value. The possible actions are:
>>> 1. emit QEVENT_GUEST_PANICKED only
>>> 2. emit QEVENT_GUEST_PANICKED and pause the guest
>>> 3. emit QEVENT_GUEST_PANICKED and poweroff the guest
>>> 4. emit QEVENT_GUEST_PANICKED and reset the guest
>>>
>>> I/O ports does not work for some targets(for example: s390). And you
>>> can implement another qom device, and include it's code into pv_event.c
>>> for such target.
>>>
>>> Note: if we emit QEVENT_GUEST_PANICKED only, and the management
>>> application does not receive this event(the management may not
>>> run when the event is emitted), the management won't know the
>>> guest is panicked.
>>>
>>> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
>>> ---
>>> hw/kvm/Makefile.objs | 2 +-
>>> hw/kvm/pv_event.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>> hw/pc_piix.c | 9 +++
>>> kvm.h | 2 +
>>> 4 files changed, 202 insertions(+), 1 deletions(-)
>>> create mode 100644 hw/kvm/pv_event.c
>>>
>>> diff --git a/hw/kvm/Makefile.objs b/hw/kvm/Makefile.objs
>>> index 226497a..23e3b30 100644
>>> --- a/hw/kvm/Makefile.objs
>>> +++ b/hw/kvm/Makefile.objs
>>> @@ -1 +1 @@
>>> -obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o
>>> +obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pv_event.o
>>> diff --git a/hw/kvm/pv_event.c b/hw/kvm/pv_event.c
>>> new file mode 100644
>>> index 0000000..c03dd22
>>> --- /dev/null
>>> +++ b/hw/kvm/pv_event.c
>>> @@ -0,0 +1,190 @@
>>> +/*
>>> + * QEMU KVM support, paravirtual event device
>>> + *
>>> + * Copyright Fujitsu, Corp. 2012
>>> + *
>>> + * Authors:
>>> + * Wen Congyang <wency@cn.fujitsu.com>
>>> + *
>>> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
>>> + * See the COPYING file in the top-level directory.
>>> + *
>>> + */
>>> +
>>> +#include <linux/kvm_para.h>
>>> +#include <asm/kvm_para.h>
>>> +#include <qobject.h>
>>> +#include <qjson.h>
>>> +#include <monitor.h>
>>> +#include <sysemu.h>
>>> +#include <kvm.h>
>>> +
>>> +/* Possible values for action parameter. */
>>> +#define PANICKED_REPORT 1 /* emit QEVENT_GUEST_PANICKED only */
>>> +#define PANICKED_PAUSE 2 /* emit QEVENT_GUEST_PANICKED and pause VM */
>>> +#define PANICKED_POWEROFF 3 /* emit QEVENT_GUEST_PANICKED and quit VM */
>>> +#define PANICKED_RESET 4 /* emit QEVENT_GUEST_PANICKED and reset VM */
>>> +
>>> +#define PV_EVENT_DRIVER "kvm_pv_event"
>>> +
>>> +struct PVEventAction {
>>> + char *panicked_action;
>>> + int panicked_action_value;
>>> +};
>>> +
>>> +#define DEFINE_PV_EVENT_PROPERTIES(_state, _conf) \
>>> + DEFINE_PROP_STRING("panicked_action", _state, _conf.panicked_action)
>>> +
>>> +static void panicked_mon_event(const char *action)
>>> +{
>>> + QObject *data;
>>> +
>>> + data = qobject_from_jsonf("{ 'action': %s }", action);
>>> + monitor_protocol_event(QEVENT_GUEST_PANICKED, data);
>>> + qobject_decref(data);
>>> +}
>>> +
>>> +static void panicked_perform_action(uint32_t panicked_action)
>>> +{
>>> + switch (panicked_action) {
>>> + case PANICKED_REPORT:
>>> + panicked_mon_event("report");
>>> + break;
>>> +
>>> + case PANICKED_PAUSE:
>>> + panicked_mon_event("pause");
>>> + vm_stop(RUN_STATE_GUEST_PANICKED);
>>> + break;
>>> +
>>> + case PANICKED_POWEROFF:
>>> + panicked_mon_event("poweroff");
>>> + qemu_system_shutdown_request();
>>> + break;
>>> +
>>> + case PANICKED_RESET:
>>> + panicked_mon_event("reset");
>>> + qemu_system_reset_request();
>>> + break;
>>> + }
>>> +}
>>> +
>>> +static uint64_t supported_event(void)
>>> +{
>>> + return 1 << KVM_PV_FEATURE_PANICKED;
>>> +}
>>> +
>>> +static void handle_event(int event, struct PVEventAction *conf)
>>> +{
>>> + if (event == KVM_PV_EVENT_PANICKED) {
>>> + panicked_perform_action(conf->panicked_action_value);
>>> + }
>>> +}
>>> +
>>> +static int pv_event_init(struct PVEventAction *conf)
>>> +{
>>> + if (!conf->panicked_action) {
>>> + conf->panicked_action_value = PANICKED_REPORT;
>>> + } else if (strcasecmp(conf->panicked_action, "none") == 0) {
>>> + conf->panicked_action_value = PANICKED_REPORT;
>>> + } else if (strcasecmp(conf->panicked_action, "pause") == 0) {
>>> + conf->panicked_action_value = PANICKED_PAUSE;
>>> + } else if (strcasecmp(conf->panicked_action, "poweroff") == 0) {
>>> + conf->panicked_action_value = PANICKED_POWEROFF;
>>> + } else if (strcasecmp(conf->panicked_action, "reset") == 0) {
>>> + conf->panicked_action_value = PANICKED_RESET;
>>> + } else {
>>> + return -1;
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +#if defined(KVM_PV_EVENT_PORT)
>>> +
>>> +#include "hw/isa.h"
>>> +
>>> +typedef struct {
>>> + ISADevice dev;
>>> + struct PVEventAction conf;
>>> + MemoryRegion ioport;
>>> +} PVIOPortState;
>>> +
>>> +static uint64_t pv_io_read(void *opaque, target_phys_addr_t addr, unsigned size)
>>> +{
>>> + return supported_event();
>>> +}
>>> +
>>> +static void pv_io_write(void *opaque, target_phys_addr_t addr, uint64_t val,
>>> + unsigned size)
>>> +{
>>> + PVIOPortState *s = opaque;
>>> +
>>> + handle_event(val, &s->conf);
>>> +}
>>> +
>>> +static const MemoryRegionOps pv_io_ops = {
>>> + .read = pv_io_read,
>>> + .write = pv_io_write,
>>> + .impl = {
>>> + .min_access_size = 4,
>>> + .max_access_size = 4,
>>> + },
>>> +};
>>> +
>>> +static int pv_ioport_initfn(ISADevice *dev)
>>> +{
>>> + PVIOPortState *s = DO_UPCAST(PVIOPortState, dev, dev);
>>> +
>>> + if (pv_event_init(&s->conf) < 0) {
>>> + return -1;
>>> + }
>>> +
>>> + memory_region_init_io(&s->ioport, &pv_io_ops, s, "pv_event", 1);
>>> + isa_register_ioport(dev, &s->ioport, KVM_PV_EVENT_PORT);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static Property pv_ioport_properties[] = {
>>> + DEFINE_PV_EVENT_PROPERTIES(PVIOPortState, conf),
>>> + DEFINE_PROP_END_OF_LIST(),
>>> +};
>>> +
>>> +static void pv_ioport_class_init(ObjectClass *klass, void *data)
>>> +{
>>> + DeviceClass *dc = DEVICE_CLASS(klass);
>>> + ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
>>> +
>>> + ic->init = pv_ioport_initfn;
>>> + dc->no_user = 1;
>>> + dc->props = pv_ioport_properties;
>>> +}
>>> +
>>> +static TypeInfo pv_ioport_info = {
>>> + .name = PV_EVENT_DRIVER,
>>> + .parent = TYPE_ISA_DEVICE,
>>> + .instance_size = sizeof(PVIOPortState),
>>> + .class_init = pv_ioport_class_init,
>>> +};
>>> +
>>> +static void pv_ioport_register_types(void)
>>> +{
>>> + type_register_static(&pv_ioport_info);
>>> +}
>>> +
>>> +type_init(pv_ioport_register_types)
>>> +
>>> +void kvm_pv_event_init(void *opaque)
>>> +{
>>> + ISABus *bus = opaque;
>>> + ISADevice *dev;
>>> +
>>> + dev = isa_create(bus, PV_EVENT_DRIVER);
>>> + qdev_init_nofail(&dev->qdev);
>>> +}
>>> +
>>> +#else
>>> +void kvm_pv_event_init(void *opaque)
>>> +{
>>
>> Some comment that this stub requires an implementation whenever it is
>> actually built would be helpful. Something that explains a different
>> transport than PIO will be needed.
>
> OK
>
>>
>>> +}
>>> +#endif
>>> diff --git a/hw/pc_piix.c b/hw/pc_piix.c
>>> index 88ff041..f73fb85 100644
>>> --- a/hw/pc_piix.c
>>> +++ b/hw/pc_piix.c
>>> @@ -46,6 +46,9 @@
>>> #ifdef CONFIG_XEN
>>> # include <xen/hvm/hvm_info_table.h>
>>> #endif
>>> +#ifdef CONFIG_KVM
>>> +# include <asm/kvm_para.h>
>>> +#endif
>>>
>>> #define MAX_IDE_BUS 2
>>>
>>> @@ -285,6 +288,12 @@ static void pc_init1(MemoryRegion *system_memory,
>>> if (pci_enabled) {
>>> pc_pci_device_init(pci_bus);
>>> }
>>> +
>>> +#ifdef KVM_PV_EVENT_PORT
>>
>> This file is x86-only, and there we have KVM_PV_EVENT_PORT
>> unconditionally. So drop the #ifdef.
>>
>>> + if (kvm_enabled()) {
>>> + kvm_pv_event_init(isa_bus);
>>
>> But you are missing a kvm-stub entry for kvm_pv_event_init. A
>> --disable-kvm build should be broken for that reason.
>
> Hmm, KVM_PV_EVENT_PORT is defined in asm/kvm_para.h, and I include
> this file only when CONFIG_KVM is defined. So --disable-kvm build
> does not be broken in my test.
Yeah, but that is a bit ugly and another reason to go for a proper kvm-stub.
Jan
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]
next prev parent reply other threads:[~2012-08-24 6:22 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-23 2:28 [PATCH v9] kvm: notify host when the guest is panicked Wen Congyang
2012-08-23 2:30 ` [PATCH v9 1/6] start vm after reseting it Wen Congyang
2012-08-23 2:30 ` [PATCH v9 2/6] kvm: Update kernel headers Wen Congyang
2012-08-23 2:31 ` [PATCH v9 3/6] add a new runstate: RUN_STATE_GUEST_PANICKED Wen Congyang
2012-08-23 2:31 ` [PATCH v9 4/6] add a new qevent: QEVENT_GUEST_PANICKED Wen Congyang
2012-08-23 2:32 ` [PATCH v9 5/6] introduce a new qom device to deal with panicked event Wen Congyang
2012-08-23 10:51 ` Jan Kiszka
2012-08-23 10:51 ` Jan Kiszka
2012-08-24 6:05 ` Wen Congyang
2012-08-24 6:21 ` Jan Kiszka [this message]
2012-08-24 6:33 ` Wen Congyang
2012-08-24 6:30 ` Jan Kiszka
2012-08-24 7:40 ` Wen Congyang
2012-08-23 2:32 ` [PATCH v9 6/6] allower the user to disable pv event support Wen Congyang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=50371D85.1080601@web.de \
--to=jan.kiszka@web.de \
--cc=avi@redhat.com \
--cc=berrange@redhat.com \
--cc=blauwirbel@gmail.com \
--cc=drjones@redhat.com \
--cc=eblake@redhat.com \
--cc=gleb@redhat.com \
--cc=kamezawa.hiroyu@jp.fujitsu.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mtosatti@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=wency@cn.fujitsu.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.