diff mbox

[PATCHv3] add "info ioapic" monitor command

Message ID 20100106163502.GQ4905@redhat.com
State New
Headers show

Commit Message

Gleb Natapov Jan. 6, 2010, 4:35 p.m. UTC
Knowing ioapic configuration is very useful for the poor soles
how need to debug guest occasionally.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
--
			Gleb.

Comments

Anthony Liguori Jan. 6, 2010, 7:50 p.m. UTC | #1
On 01/06/2010 10:35 AM, Gleb Natapov wrote:
> Knowing ioapic configuration is very useful for the poor soles
> how need to debug guest occasionally.
>    

This needs to be implemented in terms of VMState.  There is no reason 
for it not to be.

I've just gone through the code in great detail.  You just need to 
implement a vmstate_get_field that looks up a field given an instance 
name and instance id.  You then need to add a to_str callback in 
VMStateInfo.  The vmstate_get_field code will look very much like the 
vmstate_save code except it calls to_str().

The new monitor command should be 'device_info name [instance_id] [field]'.

For the ioapic, you can introduce a new VMStateInfo type that duplicates 
the vmstate_info_uint64 type except it has a different to_str callback 
that decodes the apic fields.  It's just then a matter of a few macros 
and updating the VMState description for the ioapic.

It's the same or less code than your current patch and it lays the 
ground work for a consistent command to look up arbitrary device info.

Regards,

Anthony Liguori
Gleb Natapov Jan. 6, 2010, 9:12 p.m. UTC | #2
On Wed, Jan 06, 2010 at 01:50:21PM -0600, Anthony Liguori wrote:
> On 01/06/2010 10:35 AM, Gleb Natapov wrote:
> >Knowing ioapic configuration is very useful for the poor soles
> >how need to debug guest occasionally.
> 
> This needs to be implemented in terms of VMState.  There is no
> reason for it not to be.
Except that this has nothing to do with VMState.

> 
> I've just gone through the code in great detail.  You just need to
> implement a vmstate_get_field that looks up a field given an
> instance name and instance id.  You then need to add a to_str
> callback in VMStateInfo.  The vmstate_get_field code will look very
> much like the vmstate_save code except it calls to_str().
> 
> The new monitor command should be 'device_info name [instance_id] [field]'.
> 
What is instance_id? And 'field' is implementation detail that should
not be exposed to user at all. And what happens when VMState will start
to support subsections?

> For the ioapic, you can introduce a new VMStateInfo type that
> duplicates the vmstate_info_uint64 type except it has a different
> to_str callback that decodes the apic fields.  It's just then a
> matter of a few macros and updating the VMState description for the
> ioapic.
> 
You just overdesigning!  What is the point in all those to_str() callbacks
instead of only one that knows device internals? What if a meaning of
one field depends on values of other fields? If you want to have a way
to dump VMState then just dump it in a "field_name = value" form. This
is great for migration debugging.  But to present device state in human
readable from is much simpler done by having only one function that
gets device and prints nice info about its current state. If anything,
the devise state print callback should be part of a device structure.

> It's the same or less code than your current patch and it lays the
> ground work for a consistent command to look up arbitrary device
> info.
> 
Your description is almost the size of my patch, and you can't seriously
say that what you propose is "the same or less code than my current patch"
since all of my patch will be a subset of what you propose, because all
it does is parse ioapic state into readable form. And this is really
what my patch is about: parsing ioapic state into readable form. Now you
are saying that we can call this code from a different place (that
doesn't exist currently), or we can spread it over multiple to_str functions,
but it can't just disappear.
 
--
			Gleb.
diff mbox

Patch

diff --git a/hw/ioapic.c b/hw/ioapic.c
index b0ad78f..3afb2c4 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -24,6 +24,8 @@ 
 #include "pc.h"
 #include "qemu-timer.h"
 #include "host-utils.h"
+#include "monitor.h"
+#include "qemu-objects.h"
 
 //#define DEBUG_IOAPIC
 
@@ -50,6 +52,8 @@  struct IOAPICState {
     uint64_t ioredtbl[IOAPIC_NUM_PINS];
 };
 
+static struct IOAPICState *ioapic;
+
 static void ioapic_service(IOAPICState *s)
 {
     uint8_t i;
@@ -232,7 +236,7 @@  qemu_irq *ioapic_init(void)
     qemu_irq *irq;
     int io_memory;
 
-    s = qemu_mallocz(sizeof(IOAPICState));
+    ioapic = s = qemu_mallocz(sizeof(IOAPICState));
     ioapic_reset(s);
 
     io_memory = cpu_register_io_memory(ioapic_mem_read,
@@ -245,3 +249,70 @@  qemu_irq *ioapic_init(void)
 
     return irq;
 }
+
+static void qemu_ioapic_qlist_iter(QObject *data, void *opaque)
+{
+    QDict *qdict = qobject_to_qdict(data);
+    Monitor *mon = opaque;
+
+    monitor_printf(mon, "%2"PRId64": ", qdict_get_int(qdict, "index"));
+    if (qdict_get_bool(qdict, "masked")) {
+        monitor_printf(mon, "masked\n");
+    } else {
+        monitor_printf(mon, "vec=%3"PRId64" %s %s acive-%s %s dest=%"PRId64"\n",
+                       qdict_get_int(qdict, "vector"),
+                       qdict_get_str(qdict, "delivery_mode"),
+                       qdict_get_str(qdict, "dest_mode"),
+                       qdict_get_str(qdict, "polarity"),
+                       qdict_get_str(qdict, "trig_mode"),
+                       qdict_get_int(qdict, "destination"));
+    }
+}
+
+void monitor_print_ioapic(Monitor *mon, const QObject *ret_data)
+{
+    qlist_iter(qobject_to_qlist(ret_data), qemu_ioapic_qlist_iter, mon);
+}
+
+static const char *delivery_mode_string[] = {"fixed", "lowprio", "smi", "res",
+                                             "nmi", "init", "res", "extint"};
+
+void do_info_ioapic(Monitor *mon, QObject **ret_data)
+{
+    int i;
+    QList *list;
+
+    *ret_data = NULL;
+
+    if (!ioapic)
+        return;
+
+    list = qlist_new();
+
+    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+        QObject *obj;
+        uint64 e = ioapic->ioredtbl[i];
+        if (e & IOAPIC_LVT_MASKED) {
+            obj = qobject_from_jsonf("{'index': %d, 'masked': true}", i);
+        } else {
+            uint8_t vec = e & 0xff;
+            uint8_t trig_mode = ((e >> 15) & 1);
+            uint8_t dest = e >> 56;
+            uint8_t dest_mode = (e >> 11) & 1;
+            uint8_t delivery_mode = (e >> 8) & 7;
+            uint8_t polarity = (e >> 13) & 1;
+            obj = qobject_from_jsonf("{'index': %d, 'masked': false,"
+                                     "'vector': %d, 'delivery_mode': %s,"
+                                     "'dest_mode': %s, 'polarity': %s,"
+                                     "'trig_mode': %s, 'destination': %d}",
+                                     i, vec,
+                                     delivery_mode_string[delivery_mode],
+                                     dest_mode ? "logical":"physical",
+                                     polarity ? "low" : "high",
+                                     trig_mode ? "level": "edge",
+                                     dest);
+        }
+        qlist_append_obj(list, obj);
+    }
+    *ret_data = QOBJECT(list);
+}
diff --git a/hw/pc.h b/hw/pc.h
index 03ffc91..3e39444 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -2,6 +2,7 @@ 
 #define HW_PC_H
 
 #include "qemu-common.h"
+#include "qobject.h"
 
 /* PC-style peripherals (also used by other machines).  */
 
@@ -45,6 +46,8 @@  int apic_accept_pic_intr(CPUState *env);
 void apic_deliver_pic_intr(CPUState *env, int level);
 int apic_get_interrupt(CPUState *env);
 qemu_irq *ioapic_init(void);
+void do_info_ioapic(Monitor *mon, QObject **ret_data);
+void monitor_print_ioapic(Monitor *mon, const QObject *data);
 void ioapic_set_irq(void *opaque, int vector, int level);
 void apic_reset_irq_delivered(void);
 int apic_get_irq_delivered(void);
diff --git a/monitor.c b/monitor.c
index c0dc48e..367e330 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2625,6 +2625,14 @@  static const mon_cmd_t info_cmds[] = {
         .mhandler.info = do_info_roms,
     },
     {
+        .name       = "ioapic",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show ioapic config",
+        .user_print = monitor_print_ioapic,
+        .mhandler.info_new = do_info_ioapic,
+    },
+    {
         .name       = NULL,
     },
 };