@@ -38,3 +38,5 @@ obj-$(CONFIG_OMAP) += omap_tap.o
obj-$(CONFIG_PXA2XX) += pxa2xx_pcmcia.o
obj-$(CONFIG_SLAVIO) += slavio_misc.o
obj-$(CONFIG_ZYNQ) += zynq_slcr.o
+
+common-obj-y += pvpanic.o
new file mode 100644
@@ -0,0 +1,123 @@
+/*
+ * QEMU simulated pvpanic device.
+ *
+ * Copyright Fujitsu, Corp. 2013
+ *
+ * Authors:
+ * Wen Congyang <wency@cn.fujitsu.com>
+ * Hu Tao <hutao@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 <qapi/qmp/qobject.h>
+#include <qapi/qmp/qjson.h>
+#include <monitor/monitor.h>
+#include <sysemu/sysemu.h>
+#include <sysemu/kvm.h>
+
+/* The bit of supported pv event */
+#define PVPANIC_F_PANICKED 0
+
+/* The pv event value */
+#define PVPANIC_PANICKED (1 << PVPANIC_F_PANICKED)
+
+#define TYPE_ISA_PVPANIC_DEVICE "pvpanic"
+#define ISA_PVPANIC_DEVICE(obj) \
+ OBJECT_CHECK(PVPanicState, (obj), TYPE_ISA_PVPANIC_DEVICE)
+
+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 handle_event(int event)
+{
+ static bool logged = false;
+
+ if (event & ~PVPANIC_PANICKED && !logged) {
+ fprintf(stderr, "pvpanic: unknown event %#x.\n", event);
+ logged = true;
+ }
+
+ if (event & PVPANIC_PANICKED) {
+ panicked_mon_event("pause");
+ vm_stop(RUN_STATE_GUEST_PANICKED);
+ return;
+ }
+}
+
+#include "hw/isa/isa.h"
+
+typedef struct PVPanicState {
+ ISADevice parent_obj;
+
+ MemoryRegion io;
+ uint16_t ioport;
+} PVPanicState;
+
+/* return supported events on read */
+static uint64_t pvpanic_ioport_read(void *opaque, hwaddr addr, unsigned size)
+{
+ return PVPANIC_PANICKED;
+}
+
+static void pvpanic_ioport_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned size)
+{
+ handle_event(val);
+}
+
+static const MemoryRegionOps pvpanic_ops = {
+ .read = pvpanic_ioport_read,
+ .write = pvpanic_ioport_write,
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 1,
+ },
+};
+
+static int pvpanic_isa_initfn(ISADevice *dev)
+{
+ PVPanicState *s = ISA_PVPANIC_DEVICE(dev);
+
+ memory_region_init_io(&s->io, &pvpanic_ops, s, "pvpanic", 1);
+ isa_register_ioport(dev, &s->io, s->ioport);
+
+ return 0;
+}
+
+static Property pvpanic_isa_properties[] = {
+ DEFINE_PROP_UINT16("ioport", PVPanicState, ioport, 0x505),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pvpanic_isa_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+
+ ic->init = pvpanic_isa_initfn;
+ dc->no_user = 1;
+ dc->props = pvpanic_isa_properties;
+}
+
+static TypeInfo pvpanic_isa_info = {
+ .name = TYPE_ISA_PVPANIC_DEVICE,
+ .parent = TYPE_ISA_DEVICE,
+ .instance_size = sizeof(PVPanicState),
+ .class_init = pvpanic_isa_class_init,
+};
+
+static void pvpanic_register_types(void)
+{
+ type_register_static(&pvpanic_isa_info);
+}
+
+type_init(pvpanic_register_types)
--
1.8.1.4
>
> I don't like that. I'd prefer it to work like real hardware usually
> does: recognize bit 0 even when other bits are set.
>
> ABI description becomes:
>
> pvpanic exposes a single I/O port, by default 0x505. Each bit of
> the port corresponds to an event.
>
> On read, the bits recognized by the device are set. Software should
> ignore bits it doesn't recognize.
>
> On write, the bits not recognized by the device are ignored.
> Software should set only bits both itself and the device recognize.
>
> Currently, only bit 0 is recognized. Setting it indicates a guest
> panic has happened.
I adopt your words here, with a slight change:
From 758f69bb37fa0fb8567a480258cc8cc998c4d693 Mon Sep 17 00:00:00 2001
From: Hu Tao <hutao@cn.fujitsu.com>
Date: Mon, 15 Apr 2013 10:07:07 +0800
Subject: [PATCH] pvpanic: add document of pvpanic
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
docs/specs/pvpanic.txt | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
create mode 100644 docs/specs/pvpanic.txt
new file mode 100644
@@ -0,0 +1,39 @@
+PVPANIC DEVICE
+==============
+
+pvpanic device is a simulated ISA device, through which a guest panic
+event is sent to qemu, and a QMP event is generated. This allows
+management apps (e.g. libvirt) to be notified and respond to the event.
+
+The management app has the option of waiting for GUEST_PANICKED events,
+and/or polling for guest-panicked RunState, to learn when the pvpanic
+device has fired a panic event.
+
+ISA Interface
+-------------
+
+pvpanic exposes a single I/O port, by default 0x505. On read, the bits
+recognized by the device are set. Software should ignore bits it doesn't
+recognize. On write, the bits not recognized by the device are ignored.
+Software should set only bits both itself and the device recognize.
+Currently, only bit 0 is recognized, setting it indicates a guest panic
+has happened.
+
+ACPI Interface
+--------------
+
+pvpanic device is defined with ACPI ID "QEMU0001". Custom methods:
+
+RDPT: To determine whether guest panic notification is supported.
+Arguments: None
+Return: Returns a byte, bit 0 set to indicate guest panic
+ notification is supported. Other bits are reserved and
+ should be ignored.
+
+WRPT: To send a guest panic event
+Arguments: Arg0 is a byte, with bit 0 set to indicate guest panic has
+ happened. Other bits are reserved and should be cleared.
+Return: None
+
+The ACPI device will automatically refer to the right port in case it
+is modified.