* [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state
@ 2015-06-19 14:48 Denis V. Lunev
2015-06-19 14:48 ` [Qemu-devel] [PATCH 1/8] apic_internal.h: move apic_get_bit(), apic_set_bit() to apic_internal.h Denis V. Lunev
` (8 more replies)
0 siblings, 9 replies; 17+ messages in thread
From: Denis V. Lunev @ 2015-06-19 14:48 UTC (permalink / raw)
Cc: Denis V. Lunev, Paolo Bonzini, qemu-devel, Pavel Butsykin
Added the hmp command to query IO- and Local APIC registers state,
it can be very useful to identify problems related to the emulation devices.
(qemu) info apic-local
apic.lvt 00-timer 000300fd int=fd .H.EMP delmod=0:Fixed
apic.lvt 00-thermal 00010000 int=00 .H.EM. delmod=0:Fixed
apic.lvt 00-perfmon 000000fe int=fe .H.E.. delmod=0:Fixed
apic.lvt 00-LINT0 0001001f int=1f .H.EM. delmod=0:Fixed
apic.lvt 00-LINT1 000004ff int=ff .H.E.. delmod=4:NMI
apic.lvt 00-Error 000000e3 int=e3 .H.E.. delmod=0:Fixed
apic.error 00 esr 00000000 S:... R:... .
apic.timer 00 DCR=0000000b(b) initial_count=1000090000
apic.icr 00 02000000000c00d1: int=d1 delmod=0:Fixed P..E shorthand=3:all dest=2
apic.prio 00 apr=00(0:0) tpr=40(4:0)
apic.dest 00 dfr=f0(f) ldr=01(01)
apic.svr 00 0000011f vec=1f on focus=off
apic.interrupt 00 065:R.E
(qemu) info apic-io
ioapic ID=00 IRR=00000000 SEL=18
ioapic 00 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 01 0300000000000993: int=93 delmod=1:LowPri L.H.E. dest=3
ioapic 02 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 03 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 04 0300000000000992: int=92 delmod=1:LowPri L.H.E. dest=3
ioapic 05 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 06 02000000000109b3: int=b3 delmod=1:LowPri L.H.EM dest=2
ioapic 07 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 08 01000000000008d1: int=d1 delmod=0:Fixed L.H.E. dest=1
ioapic 09 03000000000089b1: int=b1 delmod=1:LowPri L.H.L. dest=3
ioapic 10 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 11 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 12 03000000000009a3: int=a3 delmod=1:LowPri L.H.E. dest=3
ioapic 13 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 14 0300000000000962: int=62 delmod=1:LowPri L.H.E. dest=3
ioapic 15 0300000000000982: int=82 delmod=1:LowPri L.H.E. dest=3
ioapic 16 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 17 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 18 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 19 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 20 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 21 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 22 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 23 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
Pavel Butsykin (8):
apic_internal.h: move apic_get_bit(), apic_set_bit() to
apic_internal.h
apic_internal.h: rename ESR_ILLEGAL_ADDRESS to
APIC_ESR_ILLEGAL_ADDRESS
apic_internal.h: added more constants
apic_internal.h: Fix formatting and drop unused consts
hmp: added local apic dump state
ioapic_internal.h: added more constants
hmp: added io apic dump state
hmp: implemented io apic dump state for emulator
hmp-commands.hx | 4 +
hw/i386/kvm/ioapic.c | 10 +++
hw/intc/apic.c | 20 +----
hw/intc/ioapic.c | 12 +++
hw/intc/ioapic_common.c | 31 ++++++++
include/hw/i386/apic_internal.h | 90 +++++++++++++++++++---
include/hw/i386/ioapic_internal.h | 7 ++
include/hw/i386/pc.h | 5 ++
include/qom/cpu.h | 14 ++++
monitor.c | 38 ++++++++++
qom/cpu.c | 11 +++
target-i386/cpu-qom.h | 2 +
target-i386/cpu.c | 1 +
target-i386/helper.c | 155 ++++++++++++++++++++++++++++++++++++++
14 files changed, 371 insertions(+), 29 deletions(-)
^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 1/8] apic_internal.h: move apic_get_bit(), apic_set_bit() to apic_internal.h
2015-06-19 14:48 [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state Denis V. Lunev
@ 2015-06-19 14:48 ` Denis V. Lunev
2015-06-19 14:48 ` [Qemu-devel] [PATCH 2/8] apic_internal.h: rename ESR_ILLEGAL_ADDRESS to APIC_ESR_ILLEGAL_ADDRESS Denis V. Lunev
` (7 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Denis V. Lunev @ 2015-06-19 14:48 UTC (permalink / raw)
Cc: Denis V. Lunev, Paolo Bonzini, qemu-devel, Pavel Butsykin
From: Pavel Butsykin <pbutsykin@virtuozzo.com>
It's necessary to work with bitmap isr, tmr, irr outside hw/intc/apic.c
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
---
hw/intc/apic.c | 16 ----------------
include/hw/i386/apic_internal.h | 16 ++++++++++++++++
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index 77b639c..e4ee032 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -51,14 +51,6 @@ static int apic_ffs_bit(uint32_t value)
return ctz32(value);
}
-static inline void apic_set_bit(uint32_t *tab, int index)
-{
- int i, mask;
- i = index >> 5;
- mask = 1 << (index & 0x1f);
- tab[i] |= mask;
-}
-
static inline void apic_reset_bit(uint32_t *tab, int index)
{
int i, mask;
@@ -67,14 +59,6 @@ static inline void apic_reset_bit(uint32_t *tab, int index)
tab[i] &= ~mask;
}
-static inline int apic_get_bit(uint32_t *tab, int index)
-{
- int i, mask;
- i = index >> 5;
- mask = 1 << (index & 0x1f);
- return !!(tab[i] & mask);
-}
-
/* return -1 if no bit is set */
static int get_highest_priority_int(uint32_t *tab)
{
diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h
index dc7a89d..0999cf4 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -146,4 +146,20 @@ void apic_enable_vapic(DeviceState *d, hwaddr paddr);
void vapic_report_tpr_access(DeviceState *dev, CPUState *cpu, target_ulong ip,
TPRAccess access);
+static inline void apic_set_bit(uint32_t *tab, int index)
+{
+ int i, mask;
+ i = index >> 5;
+ mask = 1 << (index & 0x1f);
+ tab[i] |= mask;
+}
+
+static inline int apic_get_bit(uint32_t *tab, int index)
+{
+ int i, mask;
+ i = index >> 5;
+ mask = 1 << (index & 0x1f);
+ return !!(tab[i] & mask);
+}
+
#endif /* !QEMU_APIC_INTERNAL_H */
--
1.9.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 2/8] apic_internal.h: rename ESR_ILLEGAL_ADDRESS to APIC_ESR_ILLEGAL_ADDRESS
2015-06-19 14:48 [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state Denis V. Lunev
2015-06-19 14:48 ` [Qemu-devel] [PATCH 1/8] apic_internal.h: move apic_get_bit(), apic_set_bit() to apic_internal.h Denis V. Lunev
@ 2015-06-19 14:48 ` Denis V. Lunev
2015-06-19 14:48 ` [Qemu-devel] [PATCH 3/8] apic_internal.h: added more constants Denis V. Lunev
` (6 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Denis V. Lunev @ 2015-06-19 14:48 UTC (permalink / raw)
Cc: Denis V. Lunev, Paolo Bonzini, qemu-devel, Pavel Butsykin
From: Pavel Butsykin <pbutsykin@virtuozzo.com>
Added prefix APIC_ for determining the constant of a particular subsystem,
improve the overall readability and match other constant names.
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
---
hw/intc/apic.c | 4 ++--
include/hw/i386/apic_internal.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index e4ee032..d64a0db 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -723,7 +723,7 @@ static uint32_t apic_mem_readl(void *opaque, hwaddr addr)
val = s->divide_conf;
break;
default:
- s->esr |= ESR_ILLEGAL_ADDRESS;
+ s->esr |= APIC_ESR_ILLEGAL_ADDRESS;
val = 0;
break;
}
@@ -836,7 +836,7 @@ static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val)
}
break;
default:
- s->esr |= ESR_ILLEGAL_ADDRESS;
+ s->esr |= APIC_ESR_ILLEGAL_ADDRESS;
break;
}
}
diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h
index 0999cf4..b0d314f 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -56,7 +56,7 @@
#define APIC_INPUT_POLARITY (1<<13)
#define APIC_SEND_PENDING (1<<12)
-#define ESR_ILLEGAL_ADDRESS (1 << 7)
+#define APIC_ESR_ILLEGAL_ADDRESS (1 << 7)
#define APIC_SV_DIRECTED_IO (1<<12)
#define APIC_SV_ENABLE (1<<8)
--
1.9.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 3/8] apic_internal.h: added more constants
2015-06-19 14:48 [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state Denis V. Lunev
2015-06-19 14:48 ` [Qemu-devel] [PATCH 1/8] apic_internal.h: move apic_get_bit(), apic_set_bit() to apic_internal.h Denis V. Lunev
2015-06-19 14:48 ` [Qemu-devel] [PATCH 2/8] apic_internal.h: rename ESR_ILLEGAL_ADDRESS to APIC_ESR_ILLEGAL_ADDRESS Denis V. Lunev
@ 2015-06-19 14:48 ` Denis V. Lunev
2015-06-19 14:48 ` [Qemu-devel] [PATCH 4/8] apic_internal.h: Fix formatting and drop unused consts Denis V. Lunev
` (5 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Denis V. Lunev @ 2015-06-19 14:48 UTC (permalink / raw)
Cc: Denis V. Lunev, Paolo Bonzini, qemu-devel, Pavel Butsykin
From: Pavel Butsykin <pbutsykin@virtuozzo.com>
These constants are needed for optimal access to
bit fields local apic registers without magic numbers.
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
---
include/hw/i386/apic_internal.h | 54 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h
index b0d314f..3263782 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -49,14 +49,68 @@
#define APIC_TRIGGER_EDGE 0
#define APIC_TRIGGER_LEVEL 1
+#define APIC_VECTOR_MASK 0xff
+#define APIC_DCR_MASK 0xf
+
+#define APIC_LVT_TIMER_SHIFT 17
+#define APIC_LVT_MASKED_SHIFT 16
+#define APIC_LVT_LEVEL_TRIGGER_SHIFT 15
+#define APIC_LVT_REMOTE_IRR_SHIFT 14
+#define APIC_LVT_INT_POLARITY_SHIFT 13
+#define APIC_LVT_DELIV_STS_SHIFT 12
+#define APIC_LVT_DELIV_MOD_SHIFT 8
+
#define APIC_LVT_TIMER_PERIODIC (1<<17)
#define APIC_LVT_MASKED (1<<16)
#define APIC_LVT_LEVEL_TRIGGER (1<<15)
#define APIC_LVT_REMOTE_IRR (1<<14)
#define APIC_INPUT_POLARITY (1<<13)
#define APIC_SEND_PENDING (1<<12)
+#define APIC_LVT_INT_POLARITY (1 << APIC_LVT_INT_POLARITY_SHIFT)
+#define APIC_LVT_DELIV_STS (1 << APIC_LVT_DELIV_STS_SHIFT)
+#define APIC_LVT_DELIV_MOD (7 << APIC_LVT_DELIV_MOD_SHIFT)
+
+#define APIC_ESR_ILL_ADDRESS_SHIFT 7
+#define APIC_ESR_RECV_ILL_VECT_SHIFT 6
+#define APIC_ESR_SEND_ILL_VECT_SHIFT 5
+#define APIC_ESR_RECV_ACCEPT_SHIFT 3
+#define APIC_ESR_SEND_ACCEPT_SHIFT 2
+#define APIC_ESR_RECV_CHECK_SUM_SHIFT 1
#define APIC_ESR_ILLEGAL_ADDRESS (1 << 7)
+#define APIC_ESR_RECV_ILLEGAL_VECT (1 << APIC_ESR_RECV_ILL_VECT_SHIFT)
+#define APIC_ESR_SEND_ILLEGAL_VECT (1 << APIC_ESR_SEND_ILL_VECT_SHIFT)
+#define APIC_ESR_RECV_ACCEPT (1 << APIC_ESR_RECV_ACCEPT_SHIFT)
+#define APIC_ESR_SEND_ACCEPT (1 << APIC_ESR_SEND_ACCEPT_SHIFT)
+#define APIC_ESR_RECV_CHECK_SUM (1 << APIC_ESR_RECV_CHECK_SUM_SHIFT)
+#define APIC_ESR_SEND_CHECK_SUM 1
+
+#define APIC_ICR_DEST_SHIFT 24
+#define APIC_ICR_DEST_SHORT_SHIFT 18
+#define APIC_ICR_TRIGGER_MOD_SHIFT 15
+#define APIC_ICR_LEVEL_SHIFT 14
+#define APIC_ICR_DELIV_STS_SHIFT 12
+#define APIC_ICR_DEST_MOD_SHIFT 11
+#define APIC_ICR_DELIV_MOD_SHIFT 8
+
+#define APIC_ICR_DEST_SHORT (3 << APIC_ICR_DEST_SHORT_SHIFT)
+#define APIC_ICR_TRIGGER_MOD (1 << APIC_ICR_TRIGGER_MOD_SHIFT)
+#define APIC_ICR_LEVEL (1 << APIC_ICR_LEVEL_SHIFT)
+#define APIC_ICR_DELIV_STS (1 << APIC_ICR_DELIV_STS_SHIFT)
+#define APIC_ICR_DEST_MOD (1 << APIC_ICR_DEST_MOD_SHIFT)
+#define APIC_ICR_DELIV_MOD (7 << APIC_ICR_DELIV_MOD_SHIFT)
+
+#define APIC_PR_CLASS_SHIFT 4
+#define APIC_PR_SUB_CLASS 0xf
+
+#define APIC_LOGDEST_ID_SHIFT 4
+#define APIC_LOGDEST_APIC_ID 0xf
+
+#define APIC_SPURIO_FOCUS_SHIFT 9
+#define APIC_SPURIO_ENABLED_SHIFT 8
+
+#define APIC_SPURIO_FOCUS (1 << APIC_SPURIO_FOCUS_SHIFT)
+#define APIC_SPURIO_ENABLED (1 << APIC_SPURIO_ENABLED_SHIFT)
#define APIC_SV_DIRECTED_IO (1<<12)
#define APIC_SV_ENABLE (1<<8)
--
1.9.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 4/8] apic_internal.h: Fix formatting and drop unused consts
2015-06-19 14:48 [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state Denis V. Lunev
` (2 preceding siblings ...)
2015-06-19 14:48 ` [Qemu-devel] [PATCH 3/8] apic_internal.h: added more constants Denis V. Lunev
@ 2015-06-19 14:48 ` Denis V. Lunev
2015-06-19 14:48 ` [Qemu-devel] [PATCH 5/8] hmp: added local apic dump state Denis V. Lunev
` (4 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Denis V. Lunev @ 2015-06-19 14:48 UTC (permalink / raw)
Cc: Denis V. Lunev, Paolo Bonzini, qemu-devel, Pavel Butsykin
From: Pavel Butsykin <pbutsykin@virtuozzo.com>
Fix formatting of local apic definitions and drop unused constant
APIC_INPUT_POLARITY, APIC_SEND_PENDING. Magic numbers in shifts are
replaced with constants defined just above.
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
---
include/hw/i386/apic_internal.h | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h
index 3263782..28386ae 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -60,12 +60,10 @@
#define APIC_LVT_DELIV_STS_SHIFT 12
#define APIC_LVT_DELIV_MOD_SHIFT 8
-#define APIC_LVT_TIMER_PERIODIC (1<<17)
-#define APIC_LVT_MASKED (1<<16)
-#define APIC_LVT_LEVEL_TRIGGER (1<<15)
-#define APIC_LVT_REMOTE_IRR (1<<14)
-#define APIC_INPUT_POLARITY (1<<13)
-#define APIC_SEND_PENDING (1<<12)
+#define APIC_LVT_TIMER_PERIODIC (1 << APIC_LVT_TIMER_SHIFT)
+#define APIC_LVT_MASKED (1 << APIC_LVT_MASKED_SHIFT)
+#define APIC_LVT_LEVEL_TRIGGER (1 << APIC_LVT_LEVEL_TRIGGER_SHIFT)
+#define APIC_LVT_REMOTE_IRR (1 << APIC_LVT_REMOTE_IRR_SHIFT)
#define APIC_LVT_INT_POLARITY (1 << APIC_LVT_INT_POLARITY_SHIFT)
#define APIC_LVT_DELIV_STS (1 << APIC_LVT_DELIV_STS_SHIFT)
#define APIC_LVT_DELIV_MOD (7 << APIC_LVT_DELIV_MOD_SHIFT)
@@ -77,7 +75,7 @@
#define APIC_ESR_SEND_ACCEPT_SHIFT 2
#define APIC_ESR_RECV_CHECK_SUM_SHIFT 1
-#define APIC_ESR_ILLEGAL_ADDRESS (1 << 7)
+#define APIC_ESR_ILLEGAL_ADDRESS (1 << APIC_ESR_ILL_ADDRESS_SHIFT)
#define APIC_ESR_RECV_ILLEGAL_VECT (1 << APIC_ESR_RECV_ILL_VECT_SHIFT)
#define APIC_ESR_SEND_ILLEGAL_VECT (1 << APIC_ESR_SEND_ILL_VECT_SHIFT)
#define APIC_ESR_RECV_ACCEPT (1 << APIC_ESR_RECV_ACCEPT_SHIFT)
@@ -112,8 +110,8 @@
#define APIC_SPURIO_FOCUS (1 << APIC_SPURIO_FOCUS_SHIFT)
#define APIC_SPURIO_ENABLED (1 << APIC_SPURIO_ENABLED_SHIFT)
-#define APIC_SV_DIRECTED_IO (1<<12)
-#define APIC_SV_ENABLE (1<<8)
+#define APIC_SV_DIRECTED_IO (1 << 12)
+#define APIC_SV_ENABLE (1 << 8)
#define VAPIC_ENABLE_BIT 0
#define VAPIC_ENABLE_MASK (1 << VAPIC_ENABLE_BIT)
--
1.9.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 5/8] hmp: added local apic dump state
2015-06-19 14:48 [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state Denis V. Lunev
` (3 preceding siblings ...)
2015-06-19 14:48 ` [Qemu-devel] [PATCH 4/8] apic_internal.h: Fix formatting and drop unused consts Denis V. Lunev
@ 2015-06-19 14:48 ` Denis V. Lunev
2015-06-19 15:45 ` Andreas Färber
2015-06-19 14:48 ` [Qemu-devel] [PATCH 6/8] ioapic_internal.h: added more constants Denis V. Lunev
` (3 subsequent siblings)
8 siblings, 1 reply; 17+ messages in thread
From: Denis V. Lunev @ 2015-06-19 14:48 UTC (permalink / raw)
Cc: Luiz Capitulino, Denis V. Lunev, Paolo Bonzini, qemu-devel,
Pavel Butsykin
From: Pavel Butsykin <pbutsykin@virtuozzo.com>
Added the hmp command to query local apic registers state, may be
usefull after guest crashes to understand IRQ routing in guest.
For command name uses "apic-local" because it has to be grouped with
command "apic-io".
(qemu) info apic-local
apic.lvt 00-timer 000300fd int=fd .H.EMP delmod=0:Fixed
apic.lvt 00-thermal 00010000 int=00 .H.EM. delmod=0:Fixed
apic.lvt 00-perfmon 000000fe int=fe .H.E.. delmod=0:Fixed
apic.lvt 00-LINT0 0001001f int=1f .H.EM. delmod=0:Fixed
apic.lvt 00-LINT1 000004ff int=ff .H.E.. delmod=4:NMI
apic.lvt 00-Error 000000e3 int=e3 .H.E.. delmod=0:Fixed
apic.error 00 esr 00000000 S:... R:... .
apic.timer 00 DCR=0000000b(b) initial_count=1000090000
apic.icr 00 02000000000c00d1: int=d1 delmod=0:Fixed P..E
shorthand=3:all dest=2
apic.prio 00 apr=00(0:0) tpr=40(4:0)
apic.dest 00 dfr=f0(f) ldr=01(01)
apic.svr 00 0000011f vec=1f on focus=off
apic.interrupt 00 065:R.E
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Luiz Capitulino <lcapitulino@redhat.com>
---
hmp-commands.hx | 2 +
include/qom/cpu.h | 14 +++++
monitor.c | 16 ++++++
qom/cpu.c | 11 ++++
target-i386/cpu-qom.h | 2 +
target-i386/cpu.c | 1 +
target-i386/helper.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 201 insertions(+)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index d3b7932..95f554e 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1724,6 +1724,8 @@ show the block devices
show block device statistics
@item info registers
show the cpu registers
+@item info apic-local
+show local APIC state
@item info cpus
show infos for each CPU
@item info history
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 39f0f19..d0b5867 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -138,6 +138,8 @@ typedef struct CPUClass {
bool (*virtio_is_big_endian)(CPUState *cpu);
int (*memory_rw_debug)(CPUState *cpu, vaddr addr,
uint8_t *buf, int len, bool is_write);
+ void (*dump_apic_local_state)(CPUState *cpu, FILE *f,
+ fprintf_function cpu_fprintf, int flags);
void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags);
void (*dump_statistics)(CPUState *cpu, FILE *f,
@@ -398,6 +400,18 @@ enum CPUDumpFlags {
};
/**
+ * cpu_dump_apic_local_state:
+ * @cpu: The CPU whose lcoal APIC state is to be dumped.
+ * @f: File to dump to.
+ * @cpu_fprintf: Function to dump with.
+ * @flags: Flags what to dump.
+ *
+ * Dumps local APIC state.
+ */
+void cpu_dump_apic_local_state(CPUState *cpu, FILE *f,
+ fprintf_function cpu_fprintf, int flags);
+
+/**
* cpu_dump_state:
* @cpu: The CPU whose state is to be dumped.
* @f: File to dump to.
diff --git a/monitor.c b/monitor.c
index 8e1a2e8..aad2792 100644
--- a/monitor.c
+++ b/monitor.c
@@ -957,6 +957,15 @@ int monitor_get_cpu_index(void)
return cpu->cpu_index;
}
+static void hmp_info_apic_local(Monitor *mon, const QDict *qdict)
+{
+ CPUState *cpu;
+ CPUArchState *env;
+ env = mon_get_cpu();
+ cpu = ENV_GET_CPU(env);
+ cpu_dump_apic_local_state(cpu, (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU);
+}
+
static void hmp_info_registers(Monitor *mon, const QDict *qdict)
{
CPUState *cpu;
@@ -2572,6 +2581,13 @@ static mon_cmd_t info_cmds[] = {
.mhandler.cmd = hmp_info_registers,
},
{
+ .name = "apic-local",
+ .args_type = "",
+ .params = "",
+ .help = "show local apic state",
+ .mhandler.cmd = hmp_info_apic_local,
+ },
+ {
.name = "cpus",
.args_type = "",
.params = "",
diff --git a/qom/cpu.c b/qom/cpu.c
index 108bfa2..56e8a6b 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -201,6 +201,17 @@ static bool cpu_common_exec_interrupt(CPUState *cpu, int int_req)
return false;
}
+void cpu_dump_apic_local_state(CPUState *cpu, FILE *f,
+ fprintf_function cpu_fprintf, int flags)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ if (cc->dump_apic_local_state) {
+ cpu_synchronize_state(cpu);
+ cc->dump_apic_local_state(cpu, f, cpu_fprintf, flags);
+ }
+}
+
void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags)
{
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index c35b624..e5daeaf 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -151,6 +151,8 @@ void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
int flags);
+void x86_cpu_dump_apic_local_state(CPUState *cs, FILE *f,
+ fprintf_function cpu_fprintf, int flags);
hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index af0552a..4178444 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -3147,6 +3147,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
cc->has_work = x86_cpu_has_work;
cc->do_interrupt = x86_cpu_do_interrupt;
cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
+ cc->dump_apic_local_state = x86_cpu_dump_apic_local_state;
cc->dump_state = x86_cpu_dump_state;
cc->set_pc = x86_cpu_set_pc;
cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 5480a96..8d883f5 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -23,6 +23,7 @@
#ifndef CONFIG_USER_ONLY
#include "sysemu/sysemu.h"
#include "monitor/monitor.h"
+#include "hw/i386/apic_internal.h"
#endif
static void cpu_x86_version(CPUX86State *env, int *family, int *model)
@@ -177,6 +178,160 @@ done:
cpu_fprintf(f, "\n");
}
+#ifndef CONFIG_USER_ONLY
+
+/* ARRAY_SIZE check is not required because
+ * DeliveryMode(dm) has a size of 3 bit.
+ */
+static inline const char *dm2str(uint32_t dm)
+{
+ static const char *str[] = {
+ "Fixed",
+ "...",
+ "SMI",
+ "...",
+ "NMI",
+ "INIT",
+ "...",
+ "ExtINT"
+ };
+ return str[dm];
+}
+
+static void dump_apic_lvt(FILE *f, fprintf_function cpu_fprintf,
+ uint32_t cpu_idx, const char *name,
+ uint32_t lvt, bool is_timer)
+{
+ uint32_t dm = (lvt & APIC_LVT_DELIV_MOD) >> APIC_LVT_DELIV_MOD_SHIFT;
+ cpu_fprintf(f,
+ "apic.lvt\t%02u-%-7s %08x int=%02x %c%c%c%c%c%c delmod=%x:%s\n",
+ cpu_idx, name, lvt,
+ lvt & APIC_VECTOR_MASK,
+ lvt & APIC_LVT_DELIV_STS ? 'P' : '.',
+ lvt & APIC_LVT_INT_POLARITY ? 'L' : 'H',
+ lvt & APIC_LVT_REMOTE_IRR ? 'R' : '.',
+ lvt & APIC_LVT_LEVEL_TRIGGER ? 'L' : 'E',
+ lvt & APIC_LVT_MASKED ? 'M' : '.',
+ !is_timer ? '.' : (lvt & APIC_LVT_TIMER_PERIODIC ? 'P' : 'S'),
+ dm,
+ dm2str(dm));
+
+}
+
+/* ARRAY_SIZE check is not required because
+ * destination shorthand has a size of 2 bit.
+ */
+static inline const char *shorthand2str(uint32_t shorthand)
+{
+ const char *str[] = {
+ "no", "self", "all-self", "all"
+ };
+ return str[shorthand];
+}
+
+void x86_cpu_dump_apic_local_state(CPUState *cs, FILE *f,
+ fprintf_function cpu_fprintf, int flags)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ APICCommonState *s = APIC_COMMON(cpu->apic_state);
+ uint32_t *irr_tab = s->irr, *isr_tab = s->isr, *tmr_tab = s->tmr;
+ uint32_t *lvt = s->lvt;
+ uint32_t icr0 = s->icr[0], icr1 = s->icr[1];
+ uint32_t esr = s->esr;
+ uint32_t cpu_idx = CPU(cpu)->cpu_index;
+ int i;
+
+ dump_apic_lvt(f, cpu_fprintf, cpu_idx, "timer",
+ lvt[APIC_LVT_TIMER], true);
+ dump_apic_lvt(f, cpu_fprintf, cpu_idx, "thermal",
+ lvt[APIC_LVT_THERMAL], false);
+ dump_apic_lvt(f, cpu_fprintf, cpu_idx, "perfmon",
+ lvt[APIC_LVT_PERFORM], false);
+ dump_apic_lvt(f, cpu_fprintf, cpu_idx, "LINT0",
+ lvt[APIC_LVT_LINT0], false);
+ dump_apic_lvt(f, cpu_fprintf, cpu_idx, "LINT1",
+ lvt[APIC_LVT_LINT1], false);
+ dump_apic_lvt(f, cpu_fprintf, cpu_idx, "Error",
+ lvt[APIC_LVT_ERROR], false);
+
+ cpu_fprintf(f, "apic.error\t%02u esr %08x S:%c%c%c R:%c%c%c %c\n",
+ cpu_idx, esr,
+ esr & APIC_ESR_SEND_CHECK_SUM ? 'C' : '.',
+ esr & APIC_ESR_SEND_ACCEPT ? 'A' : '.',
+ esr & APIC_ESR_SEND_ILLEGAL_VECT ? 'I' : '.',
+ esr & APIC_ESR_RECV_CHECK_SUM ? 'C' : '.',
+ esr & APIC_ESR_RECV_ACCEPT ? 'A' : '.',
+ esr & APIC_ESR_RECV_ILLEGAL_VECT ? 'I' : '.',
+ esr & APIC_ESR_ILLEGAL_ADDRESS ? 'R' : '.');
+
+ cpu_fprintf(f, "apic.timer\t%02u DCR=%08x(%x) initial_count=%d\n",
+ cpu_idx, s->divide_conf, s->divide_conf & APIC_DCR_MASK,
+ s->initial_count);
+
+ cpu_fprintf(f, "apic.icr\t%02u %016jx: int=%02x "
+ "delmod=%x:%s %c%c%c%c shorthand=%x:%s dest=%x\n",
+ cpu_idx, ((uint64_t *)s->icr)[0],
+ icr0 & APIC_VECTOR_MASK,
+ (icr0 & APIC_ICR_DELIV_MOD) >> APIC_ICR_DELIV_MOD_SHIFT,
+ dm2str((icr0 & APIC_ICR_DELIV_MOD) >> APIC_ICR_DELIV_MOD_SHIFT),
+ icr0 & APIC_ICR_DEST_MOD ? 'L' : 'P',
+ icr0 & APIC_ICR_DELIV_STS ? 'P' : '.',
+ icr0 & APIC_ICR_LEVEL ? 'A' : '.',
+ icr0 & APIC_ICR_TRIGGER_MOD ? 'L' : 'E',
+ (icr0 & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT,
+ shorthand2str(
+ (icr0 & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT),
+ (icr1 >> APIC_ICR_DEST_SHIFT) &
+ (icr0 & APIC_ICR_DEST_MOD ? 0xff : 0xf));
+
+ cpu_fprintf(f, "apic.prio\t%02u apr=%02x(%x:%x)\ttpr=%02x(%x:%x)\n",
+ cpu_idx,
+ s->arb_id,
+ s->arb_id >> APIC_PR_CLASS_SHIFT,
+ s->arb_id & APIC_PR_SUB_CLASS,
+ s->tpr,
+ s->tpr >> APIC_PR_CLASS_SHIFT,
+ s->tpr & APIC_PR_SUB_CLASS);
+
+ cpu_fprintf(f, "apic.dest\t%02u dfr=%02x(%x)\tldr=%02x",
+ cpu_idx, s->dest_mode << 4, s->dest_mode, s->log_dest);
+ if (s->dest_mode == 0) {
+ cpu_fprintf(f, "(%x:%x)\n",
+ s->log_dest & APIC_LOGDEST_APIC_ID,
+ s->log_dest >> APIC_LOGDEST_ID_SHIFT);
+ } else if (s->dest_mode == 0xf) {
+ cpu_fprintf(f, "(%02x)\n", s->log_dest);
+ } else {
+ cpu_fprintf(f, "(BAD)\n");
+ }
+
+ cpu_fprintf(f, "apic.svr\t%02u %08x vec=%02x %s focus=%s\n",
+ cpu_idx, s->spurious_vec,
+ s->spurious_vec & APIC_VECTOR_MASK,
+ s->spurious_vec & APIC_SPURIO_ENABLED ? "on" : "off",
+ s->spurious_vec & APIC_SPURIO_FOCUS ? "on" : "off");
+
+ for (i = 0; i < 256; i++) {
+ if (irr_tab[i] || isr_tab[i]) {
+ bool irr_bit = apic_get_bit(irr_tab, i);
+ bool isr_bit = apic_get_bit(isr_tab, i);
+
+ if (irr_bit || isr_bit) {
+ cpu_fprintf(f, "apic.interrupt\t%02u %03u:%c%c%c\n", cpu_idx, i,
+ irr_bit ? 'R' : '.',
+ isr_bit ? 'S' : '.',
+ apic_get_bit(tmr_tab, i) ? 'L' : 'E');
+ }
+ }
+ }
+}
+#else
+void x86_cpu_dump_apic_local_state(CPUState *cs, FILE *f,
+ fprintf_function cpu_fprintf, int flags)
+{
+}
+#endif /* !CONFIG_USER_ONLY */
+
#define DUMP_CODE_BYTES_TOTAL 50
#define DUMP_CODE_BYTES_BACKWARD 20
--
1.9.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 6/8] ioapic_internal.h: added more constants
2015-06-19 14:48 [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state Denis V. Lunev
` (4 preceding siblings ...)
2015-06-19 14:48 ` [Qemu-devel] [PATCH 5/8] hmp: added local apic dump state Denis V. Lunev
@ 2015-06-19 14:48 ` Denis V. Lunev
2015-06-19 14:48 ` [Qemu-devel] [PATCH 7/8] hmp: added io apic dump state Denis V. Lunev
` (2 subsequent siblings)
8 siblings, 0 replies; 17+ messages in thread
From: Denis V. Lunev @ 2015-06-19 14:48 UTC (permalink / raw)
Cc: Denis V. Lunev, Paolo Bonzini, qemu-devel, Pavel Butsykin
From: Pavel Butsykin <pbutsykin@virtuozzo.com>
Added the masks for easy access to fields of the redirection table entry
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
---
include/hw/i386/ioapic_internal.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/include/hw/i386/ioapic_internal.h b/include/hw/i386/ioapic_internal.h
index 3be3352..4f7764e 100644
--- a/include/hw/i386/ioapic_internal.h
+++ b/include/hw/i386/ioapic_internal.h
@@ -40,7 +40,12 @@
#define IOAPIC_LVT_DELIV_MODE_SHIFT 8
#define IOAPIC_LVT_MASKED (1 << IOAPIC_LVT_MASKED_SHIFT)
+#define IOAPIC_LVT_TRIGGER_MODE (1 << IOAPIC_LVT_TRIGGER_MODE_SHIFT)
#define IOAPIC_LVT_REMOTE_IRR (1 << IOAPIC_LVT_REMOTE_IRR_SHIFT)
+#define IOAPIC_LVT_POLARITY (1 << IOAPIC_LVT_POLARITY_SHIFT)
+#define IOAPIC_LVT_DELIV_STATUS (1 << IOAPIC_LVT_DELIV_STATUS_SHIFT)
+#define IOAPIC_LVT_DEST_MODE (1 << IOAPIC_LVT_DEST_MODE_SHIFT)
+#define IOAPIC_LVT_DELIV_MODE (7 << IOAPIC_LVT_DELIV_MODE_SHIFT)
#define IOAPIC_TRIGGER_EDGE 0
#define IOAPIC_TRIGGER_LEVEL 1
--
1.9.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 7/8] hmp: added io apic dump state
2015-06-19 14:48 [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state Denis V. Lunev
` (5 preceding siblings ...)
2015-06-19 14:48 ` [Qemu-devel] [PATCH 6/8] ioapic_internal.h: added more constants Denis V. Lunev
@ 2015-06-19 14:48 ` Denis V. Lunev
2015-06-19 15:53 ` Andreas Färber
2015-06-19 16:08 ` Peter Maydell
2015-06-19 14:48 ` [Qemu-devel] [PATCH 8/8] hmp: implemented io apic dump state for emulator Denis V. Lunev
2015-06-19 14:56 ` [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state Eric Blake
8 siblings, 2 replies; 17+ messages in thread
From: Denis V. Lunev @ 2015-06-19 14:48 UTC (permalink / raw)
Cc: Luiz Capitulino, Denis V. Lunev, Paolo Bonzini, qemu-devel,
Pavel Butsykin
From: Pavel Butsykin <pbutsykin@virtuozzo.com>
Added the hmp command to query io apic state, may be usefull after guest
crashes to understand IRQ routing in guest.
Implementation is only for kvm here. The dump will look like
(qemu) info apic-io
ioapic ID=00 IRR=00000000 SEL=18
ioapic 00 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
ioapic 01 0300000000000993: int=93 delmod=1:LowPri L.H.E. dest=3
...
ioapic 23 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Luiz Capitulino <lcapitulino@redhat.com>
---
hmp-commands.hx | 2 ++
hw/i386/kvm/ioapic.c | 10 ++++++++++
hw/intc/ioapic_common.c | 31 +++++++++++++++++++++++++++++++
include/hw/i386/ioapic_internal.h | 2 ++
include/hw/i386/pc.h | 4 ++++
monitor.c | 20 ++++++++++++++++++++
6 files changed, 69 insertions(+)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 95f554e..894ff65 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1726,6 +1726,8 @@ show block device statistics
show the cpu registers
@item info apic-local
show local APIC state
+@item info apic-io
+show io APIC state
@item info cpus
show infos for each CPU
@item info history
diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c
index d2a6c4c..b7390ca 100644
--- a/hw/i386/kvm/ioapic.c
+++ b/hw/i386/kvm/ioapic.c
@@ -10,6 +10,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "monitor/monitor.h"
#include "hw/i386/pc.h"
#include "hw/i386/ioapic_internal.h"
#include "hw/i386/apic_internal.h"
@@ -110,6 +111,15 @@ static void kvm_ioapic_put(IOAPICCommonState *s)
}
}
+void kvm_ioapic_dump_state(Monitor *mon, const QDict *qdict)
+{
+ IOAPICCommonState s;
+
+ kvm_ioapic_get(&s);
+
+ ioapic_print_redtbl(mon, &s);
+}
+
static void kvm_ioapic_reset(DeviceState *dev)
{
IOAPICCommonState *s = IOAPIC_COMMON(dev);
diff --git a/hw/intc/ioapic_common.c b/hw/intc/ioapic_common.c
index 8b7d118..83edf69 100644
--- a/hw/intc/ioapic_common.c
+++ b/hw/intc/ioapic_common.c
@@ -19,6 +19,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "monitor/monitor.h"
#include "hw/i386/ioapic.h"
#include "hw/i386/ioapic_internal.h"
#include "hw/sysbus.h"
@@ -31,6 +32,36 @@
*/
int ioapic_no;
+void ioapic_print_redtbl(Monitor *mon, IOAPICCommonState *s)
+{
+ static const char *delm_str[] = {
+ "Fixed", "LowPri", "SMI", "...", "NMI", "INIT", "...", "ExtINT"};
+ int i;
+
+ monitor_printf(mon, "ioapic ID=%02x IRR=%08x SEL=%02x\n",
+ s->id, s->irr, s->ioregsel);
+
+ for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+ uint64_t entry = s->ioredtbl[i];
+ uint32_t delm = (uint32_t)((entry & IOAPIC_LVT_DELIV_MODE) >>
+ IOAPIC_LVT_DELIV_MODE_SHIFT);
+ monitor_printf(mon, "ioapic %02u %016jx: int=%02jx "
+ "delmod=%x:%-6s %c%c%c%c%c%c dest=%jx\n",
+ i, entry,
+ entry & IOAPIC_VECTOR_MASK,
+ delm,
+ delm_str[delm],
+ entry & IOAPIC_LVT_DEST_MODE ? 'L' : 'P',
+ entry & IOAPIC_LVT_DELIV_STATUS ? 'P' : '.',
+ entry & IOAPIC_LVT_POLARITY ? 'L' : 'H',
+ entry & IOAPIC_LVT_REMOTE_IRR ? 'R' : '.',
+ entry & IOAPIC_LVT_TRIGGER_MODE ? 'L' : 'E',
+ entry & IOAPIC_LVT_MASKED ? 'M' : '.',
+ (entry >> IOAPIC_LVT_DEST_SHIFT) &
+ (entry & IOAPIC_LVT_DEST_MODE ? 0xff : 0xf));
+ }
+}
+
void ioapic_reset_common(DeviceState *dev)
{
IOAPICCommonState *s = IOAPIC_COMMON(dev);
diff --git a/include/hw/i386/ioapic_internal.h b/include/hw/i386/ioapic_internal.h
index 4f7764e..797ed47 100644
--- a/include/hw/i386/ioapic_internal.h
+++ b/include/hw/i386/ioapic_internal.h
@@ -105,4 +105,6 @@ struct IOAPICCommonState {
void ioapic_reset_common(DeviceState *dev);
+void ioapic_print_redtbl(Monitor *mon, IOAPICCommonState *s);
+
#endif /* !QEMU_IOAPIC_INTERNAL_H */
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 86c5651..437085f 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -123,6 +123,10 @@ int pic_get_output(DeviceState *d);
void hmp_info_pic(Monitor *mon, const QDict *qdict);
void hmp_info_irq(Monitor *mon, const QDict *qdict);
+/* ioapic.c */
+
+void kvm_ioapic_dump_state(Monitor *mon, const QDict *qdict);
+
/* Global System Interrupts */
#define GSI_NUM_PINS IOAPIC_NUM_PINS
diff --git a/monitor.c b/monitor.c
index aad2792..5449663 100644
--- a/monitor.c
+++ b/monitor.c
@@ -957,6 +957,19 @@ int monitor_get_cpu_index(void)
return cpu->cpu_index;
}
+#if defined(TARGET_I386)
+static void hmp_info_apic_io(Monitor *mon, const QDict *qdict)
+{
+ if (kvm_irqchip_in_kernel()) {
+ kvm_ioapic_dump_state(mon, qdict);
+ }
+}
+#else
+static void hmp_info_apic_io(Monitor *mon, const QDict *qdict)
+{
+}
+#endif
+
static void hmp_info_apic_local(Monitor *mon, const QDict *qdict)
{
CPUState *cpu;
@@ -2588,6 +2601,13 @@ static mon_cmd_t info_cmds[] = {
.mhandler.cmd = hmp_info_apic_local,
},
{
+ .name = "apic-io",
+ .args_type = "",
+ .params = "",
+ .help = "show io apic state",
+ .mhandler.cmd = hmp_info_apic_io,
+ },
+ {
.name = "cpus",
.args_type = "",
.params = "",
--
1.9.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 8/8] hmp: implemented io apic dump state for emulator
2015-06-19 14:48 [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state Denis V. Lunev
` (6 preceding siblings ...)
2015-06-19 14:48 ` [Qemu-devel] [PATCH 7/8] hmp: added io apic dump state Denis V. Lunev
@ 2015-06-19 14:48 ` Denis V. Lunev
2015-06-19 14:56 ` [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state Eric Blake
8 siblings, 0 replies; 17+ messages in thread
From: Denis V. Lunev @ 2015-06-19 14:48 UTC (permalink / raw)
Cc: Luiz Capitulino, Denis V. Lunev, Paolo Bonzini, qemu-devel,
Pavel Butsykin
From: Pavel Butsykin <pbutsykin@virtuozzo.com>
Added support emulator for the hmp command "info apic-io"
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Luiz Capitulino <lcapitulino@redhat.com>
---
hw/intc/ioapic.c | 12 ++++++++++++
include/hw/i386/pc.h | 1 +
monitor.c | 2 ++
3 files changed, 15 insertions(+)
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index b527932..8c3aeae 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -20,6 +20,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "monitor/monitor.h"
#include "hw/hw.h"
#include "hw/i386/pc.h"
#include "hw/i386/ioapic.h"
@@ -137,6 +138,17 @@ void ioapic_eoi_broadcast(int vector)
}
}
+void ioapic_dump_state(Monitor *mon, const QDict *qdict)
+{
+ int i;
+
+ for (i = 0; i < MAX_IOAPICS; i++) {
+ if (ioapics[i] != 0) {
+ ioapic_print_redtbl(mon, ioapics[i]);
+ }
+ }
+}
+
static uint64_t
ioapic_mem_read(void *opaque, hwaddr addr, unsigned int size)
{
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 437085f..142cebe 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -126,6 +126,7 @@ void hmp_info_irq(Monitor *mon, const QDict *qdict);
/* ioapic.c */
void kvm_ioapic_dump_state(Monitor *mon, const QDict *qdict);
+void ioapic_dump_state(Monitor *mon, const QDict *qdict);
/* Global System Interrupts */
diff --git a/monitor.c b/monitor.c
index 5449663..192b09d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -962,6 +962,8 @@ static void hmp_info_apic_io(Monitor *mon, const QDict *qdict)
{
if (kvm_irqchip_in_kernel()) {
kvm_ioapic_dump_state(mon, qdict);
+ } else {
+ ioapic_dump_state(mon, qdict);
}
}
#else
--
1.9.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state
2015-06-19 14:48 [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state Denis V. Lunev
` (7 preceding siblings ...)
2015-06-19 14:48 ` [Qemu-devel] [PATCH 8/8] hmp: implemented io apic dump state for emulator Denis V. Lunev
@ 2015-06-19 14:56 ` Eric Blake
2015-06-19 15:01 ` Denis V. Lunev
8 siblings, 1 reply; 17+ messages in thread
From: Eric Blake @ 2015-06-19 14:56 UTC (permalink / raw)
To: Denis V. Lunev; +Cc: Paolo Bonzini, qemu-devel, Pavel Butsykin
[-- Attachment #1: Type: text/plain, Size: 541 bytes --]
On 06/19/2015 08:48 AM, Denis V. Lunev wrote:
> Added the hmp command to query IO- and Local APIC registers state,
> it can be very useful to identify problems related to the emulation devices.
Will there ever be a desire to expose this via QMP, or is it really a
debugging aid unlikely to be used by QMP management applications? (We
do have other such HMP-only commands like 'p' and 'x', but it's always
worth asking).
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state
2015-06-19 14:56 ` [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state Eric Blake
@ 2015-06-19 15:01 ` Denis V. Lunev
0 siblings, 0 replies; 17+ messages in thread
From: Denis V. Lunev @ 2015-06-19 15:01 UTC (permalink / raw)
To: Eric Blake; +Cc: Paolo Bonzini, qemu-devel, Pavel Butsykin
On 19/06/15 17:56, Eric Blake wrote:
> On 06/19/2015 08:48 AM, Denis V. Lunev wrote:
>> Added the hmp command to query IO- and Local APIC registers state,
>> it can be very useful to identify problems related to the emulation devices.
> Will there ever be a desire to expose this via QMP, or is it really a
> debugging aid unlikely to be used by QMP management applications? (We
> do have other such HMP-only commands like 'p' and 'x', but it's always
> worth asking).
>
this is written in mind for debug only. I could not imagine how
this could be useful in the other way.
I am glad to hear other opinions which are always welcome :)
Den
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 5/8] hmp: added local apic dump state
2015-06-19 14:48 ` [Qemu-devel] [PATCH 5/8] hmp: added local apic dump state Denis V. Lunev
@ 2015-06-19 15:45 ` Andreas Färber
2015-06-19 18:02 ` Pavel
0 siblings, 1 reply; 17+ messages in thread
From: Andreas Färber @ 2015-06-19 15:45 UTC (permalink / raw)
To: Denis V. Lunev; +Cc: Paolo Bonzini, Pavel Butsykin, qemu-devel, Luiz Capitulino
Am 19.06.2015 um 16:48 schrieb Denis V. Lunev:
> From: Pavel Butsykin <pbutsykin@virtuozzo.com>
>
> Added the hmp command to query local apic registers state, may be
> usefull after guest crashes to understand IRQ routing in guest.
>
> For command name uses "apic-local" because it has to be grouped with
> command "apic-io".
>
> (qemu) info apic-local
> apic.lvt 00-timer 000300fd int=fd .H.EMP delmod=0:Fixed
> apic.lvt 00-thermal 00010000 int=00 .H.EM. delmod=0:Fixed
> apic.lvt 00-perfmon 000000fe int=fe .H.E.. delmod=0:Fixed
> apic.lvt 00-LINT0 0001001f int=1f .H.EM. delmod=0:Fixed
> apic.lvt 00-LINT1 000004ff int=ff .H.E.. delmod=4:NMI
> apic.lvt 00-Error 000000e3 int=e3 .H.E.. delmod=0:Fixed
> apic.error 00 esr 00000000 S:... R:... .
> apic.timer 00 DCR=0000000b(b) initial_count=1000090000
> apic.icr 00 02000000000c00d1: int=d1 delmod=0:Fixed P..E
> shorthand=3:all dest=2
> apic.prio 00 apr=00(0:0) tpr=40(4:0)
> apic.dest 00 dfr=f0(f) ldr=01(01)
> apic.svr 00 0000011f vec=1f on focus=off
> apic.interrupt 00 065:R.E
>
> Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Luiz Capitulino <lcapitulino@redhat.com>
> ---
> hmp-commands.hx | 2 +
> include/qom/cpu.h | 14 +++++
> monitor.c | 16 ++++++
> qom/cpu.c | 11 ++++
> target-i386/cpu-qom.h | 2 +
> target-i386/cpu.c | 1 +
> target-i386/helper.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 7 files changed, 201 insertions(+)
>
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index d3b7932..95f554e 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1724,6 +1724,8 @@ show the block devices
> show block device statistics
> @item info registers
> show the cpu registers
> +@item info apic-local
> +show local APIC state
> @item info cpus
> show infos for each CPU
> @item info history
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 39f0f19..d0b5867 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -138,6 +138,8 @@ typedef struct CPUClass {
> bool (*virtio_is_big_endian)(CPUState *cpu);
> int (*memory_rw_debug)(CPUState *cpu, vaddr addr,
> uint8_t *buf, int len, bool is_write);
> + void (*dump_apic_local_state)(CPUState *cpu, FILE *f,
> + fprintf_function cpu_fprintf, int flags);
Objection, this is a highly x86-specific interface in generic code.
Either make it generic so that it works for a second CPU implementation
and does not contain "apic", or make the HMP command x86-specific and
avoid touching core CPU code then please.
Isn't there already some irq stats info that you could piggy-back on?
Also, you did not use the get_maintainer.pl script, which would've CC'ed
me as CPU maintainer.
One remark below.
Regards,
Andreas
> void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
> int flags);
> void (*dump_statistics)(CPUState *cpu, FILE *f,
> @@ -398,6 +400,18 @@ enum CPUDumpFlags {
> };
>
> /**
> + * cpu_dump_apic_local_state:
> + * @cpu: The CPU whose lcoal APIC state is to be dumped.
> + * @f: File to dump to.
> + * @cpu_fprintf: Function to dump with.
> + * @flags: Flags what to dump.
> + *
> + * Dumps local APIC state.
> + */
> +void cpu_dump_apic_local_state(CPUState *cpu, FILE *f,
> + fprintf_function cpu_fprintf, int flags);
> +
> +/**
> * cpu_dump_state:
> * @cpu: The CPU whose state is to be dumped.
> * @f: File to dump to.
> diff --git a/monitor.c b/monitor.c
> index 8e1a2e8..aad2792 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -957,6 +957,15 @@ int monitor_get_cpu_index(void)
> return cpu->cpu_index;
> }
>
> +static void hmp_info_apic_local(Monitor *mon, const QDict *qdict)
> +{
> + CPUState *cpu;
> + CPUArchState *env;
> + env = mon_get_cpu();
> + cpu = ENV_GET_CPU(env);
Note: There is another pending series that will conflict with this.
> + cpu_dump_apic_local_state(cpu, (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU);
> +}
> +
> static void hmp_info_registers(Monitor *mon, const QDict *qdict)
> {
> CPUState *cpu;
> @@ -2572,6 +2581,13 @@ static mon_cmd_t info_cmds[] = {
> .mhandler.cmd = hmp_info_registers,
> },
> {
> + .name = "apic-local",
> + .args_type = "",
> + .params = "",
> + .help = "show local apic state",
> + .mhandler.cmd = hmp_info_apic_local,
> + },
> + {
> .name = "cpus",
> .args_type = "",
> .params = "",
> diff --git a/qom/cpu.c b/qom/cpu.c
> index 108bfa2..56e8a6b 100644
> --- a/qom/cpu.c
> +++ b/qom/cpu.c
> @@ -201,6 +201,17 @@ static bool cpu_common_exec_interrupt(CPUState *cpu, int int_req)
> return false;
> }
>
> +void cpu_dump_apic_local_state(CPUState *cpu, FILE *f,
> + fprintf_function cpu_fprintf, int flags)
> +{
> + CPUClass *cc = CPU_GET_CLASS(cpu);
> +
> + if (cc->dump_apic_local_state) {
> + cpu_synchronize_state(cpu);
> + cc->dump_apic_local_state(cpu, f, cpu_fprintf, flags);
> + }
> +}
> +
> void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
> int flags)
> {
> diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
> index c35b624..e5daeaf 100644
> --- a/target-i386/cpu-qom.h
> +++ b/target-i386/cpu-qom.h
> @@ -151,6 +151,8 @@ void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
>
> void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
> int flags);
> +void x86_cpu_dump_apic_local_state(CPUState *cs, FILE *f,
> + fprintf_function cpu_fprintf, int flags);
>
> hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
>
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index af0552a..4178444 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -3147,6 +3147,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
> cc->has_work = x86_cpu_has_work;
> cc->do_interrupt = x86_cpu_do_interrupt;
> cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
> + cc->dump_apic_local_state = x86_cpu_dump_apic_local_state;
> cc->dump_state = x86_cpu_dump_state;
> cc->set_pc = x86_cpu_set_pc;
> cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index 5480a96..8d883f5 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -23,6 +23,7 @@
> #ifndef CONFIG_USER_ONLY
> #include "sysemu/sysemu.h"
> #include "monitor/monitor.h"
> +#include "hw/i386/apic_internal.h"
> #endif
>
> static void cpu_x86_version(CPUX86State *env, int *family, int *model)
> @@ -177,6 +178,160 @@ done:
> cpu_fprintf(f, "\n");
> }
>
> +#ifndef CONFIG_USER_ONLY
> +
> +/* ARRAY_SIZE check is not required because
> + * DeliveryMode(dm) has a size of 3 bit.
> + */
> +static inline const char *dm2str(uint32_t dm)
> +{
> + static const char *str[] = {
> + "Fixed",
> + "...",
> + "SMI",
> + "...",
> + "NMI",
> + "INIT",
> + "...",
> + "ExtINT"
> + };
> + return str[dm];
> +}
> +
> +static void dump_apic_lvt(FILE *f, fprintf_function cpu_fprintf,
> + uint32_t cpu_idx, const char *name,
> + uint32_t lvt, bool is_timer)
> +{
> + uint32_t dm = (lvt & APIC_LVT_DELIV_MOD) >> APIC_LVT_DELIV_MOD_SHIFT;
> + cpu_fprintf(f,
> + "apic.lvt\t%02u-%-7s %08x int=%02x %c%c%c%c%c%c delmod=%x:%s\n",
> + cpu_idx, name, lvt,
> + lvt & APIC_VECTOR_MASK,
> + lvt & APIC_LVT_DELIV_STS ? 'P' : '.',
> + lvt & APIC_LVT_INT_POLARITY ? 'L' : 'H',
> + lvt & APIC_LVT_REMOTE_IRR ? 'R' : '.',
> + lvt & APIC_LVT_LEVEL_TRIGGER ? 'L' : 'E',
> + lvt & APIC_LVT_MASKED ? 'M' : '.',
> + !is_timer ? '.' : (lvt & APIC_LVT_TIMER_PERIODIC ? 'P' : 'S'),
> + dm,
> + dm2str(dm));
> +
> +}
> +
> +/* ARRAY_SIZE check is not required because
> + * destination shorthand has a size of 2 bit.
> + */
> +static inline const char *shorthand2str(uint32_t shorthand)
> +{
> + const char *str[] = {
> + "no", "self", "all-self", "all"
> + };
> + return str[shorthand];
> +}
> +
> +void x86_cpu_dump_apic_local_state(CPUState *cs, FILE *f,
> + fprintf_function cpu_fprintf, int flags)
> +{
> + X86CPU *cpu = X86_CPU(cs);
> + APICCommonState *s = APIC_COMMON(cpu->apic_state);
> + uint32_t *irr_tab = s->irr, *isr_tab = s->isr, *tmr_tab = s->tmr;
> + uint32_t *lvt = s->lvt;
> + uint32_t icr0 = s->icr[0], icr1 = s->icr[1];
> + uint32_t esr = s->esr;
> + uint32_t cpu_idx = CPU(cpu)->cpu_index;
> + int i;
> +
> + dump_apic_lvt(f, cpu_fprintf, cpu_idx, "timer",
> + lvt[APIC_LVT_TIMER], true);
> + dump_apic_lvt(f, cpu_fprintf, cpu_idx, "thermal",
> + lvt[APIC_LVT_THERMAL], false);
> + dump_apic_lvt(f, cpu_fprintf, cpu_idx, "perfmon",
> + lvt[APIC_LVT_PERFORM], false);
> + dump_apic_lvt(f, cpu_fprintf, cpu_idx, "LINT0",
> + lvt[APIC_LVT_LINT0], false);
> + dump_apic_lvt(f, cpu_fprintf, cpu_idx, "LINT1",
> + lvt[APIC_LVT_LINT1], false);
> + dump_apic_lvt(f, cpu_fprintf, cpu_idx, "Error",
> + lvt[APIC_LVT_ERROR], false);
> +
> + cpu_fprintf(f, "apic.error\t%02u esr %08x S:%c%c%c R:%c%c%c %c\n",
> + cpu_idx, esr,
> + esr & APIC_ESR_SEND_CHECK_SUM ? 'C' : '.',
> + esr & APIC_ESR_SEND_ACCEPT ? 'A' : '.',
> + esr & APIC_ESR_SEND_ILLEGAL_VECT ? 'I' : '.',
> + esr & APIC_ESR_RECV_CHECK_SUM ? 'C' : '.',
> + esr & APIC_ESR_RECV_ACCEPT ? 'A' : '.',
> + esr & APIC_ESR_RECV_ILLEGAL_VECT ? 'I' : '.',
> + esr & APIC_ESR_ILLEGAL_ADDRESS ? 'R' : '.');
> +
> + cpu_fprintf(f, "apic.timer\t%02u DCR=%08x(%x) initial_count=%d\n",
> + cpu_idx, s->divide_conf, s->divide_conf & APIC_DCR_MASK,
> + s->initial_count);
> +
> + cpu_fprintf(f, "apic.icr\t%02u %016jx: int=%02x "
> + "delmod=%x:%s %c%c%c%c shorthand=%x:%s dest=%x\n",
> + cpu_idx, ((uint64_t *)s->icr)[0],
> + icr0 & APIC_VECTOR_MASK,
> + (icr0 & APIC_ICR_DELIV_MOD) >> APIC_ICR_DELIV_MOD_SHIFT,
> + dm2str((icr0 & APIC_ICR_DELIV_MOD) >> APIC_ICR_DELIV_MOD_SHIFT),
> + icr0 & APIC_ICR_DEST_MOD ? 'L' : 'P',
> + icr0 & APIC_ICR_DELIV_STS ? 'P' : '.',
> + icr0 & APIC_ICR_LEVEL ? 'A' : '.',
> + icr0 & APIC_ICR_TRIGGER_MOD ? 'L' : 'E',
> + (icr0 & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT,
> + shorthand2str(
> + (icr0 & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT),
> + (icr1 >> APIC_ICR_DEST_SHIFT) &
> + (icr0 & APIC_ICR_DEST_MOD ? 0xff : 0xf));
> +
> + cpu_fprintf(f, "apic.prio\t%02u apr=%02x(%x:%x)\ttpr=%02x(%x:%x)\n",
> + cpu_idx,
> + s->arb_id,
> + s->arb_id >> APIC_PR_CLASS_SHIFT,
> + s->arb_id & APIC_PR_SUB_CLASS,
> + s->tpr,
> + s->tpr >> APIC_PR_CLASS_SHIFT,
> + s->tpr & APIC_PR_SUB_CLASS);
> +
> + cpu_fprintf(f, "apic.dest\t%02u dfr=%02x(%x)\tldr=%02x",
> + cpu_idx, s->dest_mode << 4, s->dest_mode, s->log_dest);
> + if (s->dest_mode == 0) {
> + cpu_fprintf(f, "(%x:%x)\n",
> + s->log_dest & APIC_LOGDEST_APIC_ID,
> + s->log_dest >> APIC_LOGDEST_ID_SHIFT);
> + } else if (s->dest_mode == 0xf) {
> + cpu_fprintf(f, "(%02x)\n", s->log_dest);
> + } else {
> + cpu_fprintf(f, "(BAD)\n");
> + }
> +
> + cpu_fprintf(f, "apic.svr\t%02u %08x vec=%02x %s focus=%s\n",
> + cpu_idx, s->spurious_vec,
> + s->spurious_vec & APIC_VECTOR_MASK,
> + s->spurious_vec & APIC_SPURIO_ENABLED ? "on" : "off",
> + s->spurious_vec & APIC_SPURIO_FOCUS ? "on" : "off");
> +
> + for (i = 0; i < 256; i++) {
> + if (irr_tab[i] || isr_tab[i]) {
> + bool irr_bit = apic_get_bit(irr_tab, i);
> + bool isr_bit = apic_get_bit(isr_tab, i);
> +
> + if (irr_bit || isr_bit) {
> + cpu_fprintf(f, "apic.interrupt\t%02u %03u:%c%c%c\n", cpu_idx, i,
> + irr_bit ? 'R' : '.',
> + isr_bit ? 'S' : '.',
> + apic_get_bit(tmr_tab, i) ? 'L' : 'E');
> + }
> + }
> + }
> +}
> +#else
> +void x86_cpu_dump_apic_local_state(CPUState *cs, FILE *f,
> + fprintf_function cpu_fprintf, int flags)
> +{
> +}
> +#endif /* !CONFIG_USER_ONLY */
> +
> #define DUMP_CODE_BYTES_TOTAL 50
> #define DUMP_CODE_BYTES_BACKWARD 20
>
>
--
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Dilip Upmanyu, Graham Norton; HRB
21284 (AG Nürnberg)
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 7/8] hmp: added io apic dump state
2015-06-19 14:48 ` [Qemu-devel] [PATCH 7/8] hmp: added io apic dump state Denis V. Lunev
@ 2015-06-19 15:53 ` Andreas Färber
2015-06-19 18:02 ` Pavel
2015-06-19 16:08 ` Peter Maydell
1 sibling, 1 reply; 17+ messages in thread
From: Andreas Färber @ 2015-06-19 15:53 UTC (permalink / raw)
To: Denis V. Lunev
Cc: Peter Maydell, Paolo Bonzini, Pavel Butsykin, qemu-devel,
Luiz Capitulino
Am 19.06.2015 um 16:48 schrieb Denis V. Lunev:
> From: Pavel Butsykin <pbutsykin@virtuozzo.com>
>
> Added the hmp command to query io apic state, may be usefull after guest
> crashes to understand IRQ routing in guest.
>
> Implementation is only for kvm here. The dump will look like
> (qemu) info apic-io
> ioapic ID=00 IRR=00000000 SEL=18
> ioapic 00 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
> ioapic 01 0300000000000993: int=93 delmod=1:LowPri L.H.E. dest=3
> ...
> ioapic 23 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
>
> Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Luiz Capitulino <lcapitulino@redhat.com>
> ---
> hmp-commands.hx | 2 ++
> hw/i386/kvm/ioapic.c | 10 ++++++++++
> hw/intc/ioapic_common.c | 31 +++++++++++++++++++++++++++++++
> include/hw/i386/ioapic_internal.h | 2 ++
> include/hw/i386/pc.h | 4 ++++
> monitor.c | 20 ++++++++++++++++++++
> 6 files changed, 69 insertions(+)
>
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 95f554e..894ff65 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1726,6 +1726,8 @@ show block device statistics
> show the cpu registers
> @item info apic-local
> show local APIC state
> +@item info apic-io
> +show io APIC state
> @item info cpus
> show infos for each CPU
> @item info history
> diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c
> index d2a6c4c..b7390ca 100644
> --- a/hw/i386/kvm/ioapic.c
> +++ b/hw/i386/kvm/ioapic.c
> @@ -10,6 +10,7 @@
> * See the COPYING file in the top-level directory.
> */
>
> +#include "monitor/monitor.h"
> #include "hw/i386/pc.h"
> #include "hw/i386/ioapic_internal.h"
> #include "hw/i386/apic_internal.h"
> @@ -110,6 +111,15 @@ static void kvm_ioapic_put(IOAPICCommonState *s)
> }
> }
>
> +void kvm_ioapic_dump_state(Monitor *mon, const QDict *qdict)
> +{
> + IOAPICCommonState s;
> +
> + kvm_ioapic_get(&s);
> +
> + ioapic_print_redtbl(mon, &s);
> +}
> +
> static void kvm_ioapic_reset(DeviceState *dev)
> {
> IOAPICCommonState *s = IOAPIC_COMMON(dev);
> diff --git a/hw/intc/ioapic_common.c b/hw/intc/ioapic_common.c
> index 8b7d118..83edf69 100644
> --- a/hw/intc/ioapic_common.c
> +++ b/hw/intc/ioapic_common.c
> @@ -19,6 +19,7 @@
> * License along with this library; if not, see <http://www.gnu.org/licenses/>.
> */
>
> +#include "monitor/monitor.h"
> #include "hw/i386/ioapic.h"
> #include "hw/i386/ioapic_internal.h"
> #include "hw/sysbus.h"
> @@ -31,6 +32,36 @@
> */
> int ioapic_no;
>
> +void ioapic_print_redtbl(Monitor *mon, IOAPICCommonState *s)
> +{
> + static const char *delm_str[] = {
> + "Fixed", "LowPri", "SMI", "...", "NMI", "INIT", "...", "ExtINT"};
> + int i;
> +
> + monitor_printf(mon, "ioapic ID=%02x IRR=%08x SEL=%02x\n",
> + s->id, s->irr, s->ioregsel);
> +
> + for (i = 0; i < IOAPIC_NUM_PINS; i++) {
> + uint64_t entry = s->ioredtbl[i];
> + uint32_t delm = (uint32_t)((entry & IOAPIC_LVT_DELIV_MODE) >>
> + IOAPIC_LVT_DELIV_MODE_SHIFT);
> + monitor_printf(mon, "ioapic %02u %016jx: int=%02jx "
> + "delmod=%x:%-6s %c%c%c%c%c%c dest=%jx\n",
> + i, entry,
> + entry & IOAPIC_VECTOR_MASK,
> + delm,
> + delm_str[delm],
> + entry & IOAPIC_LVT_DEST_MODE ? 'L' : 'P',
> + entry & IOAPIC_LVT_DELIV_STATUS ? 'P' : '.',
> + entry & IOAPIC_LVT_POLARITY ? 'L' : 'H',
> + entry & IOAPIC_LVT_REMOTE_IRR ? 'R' : '.',
> + entry & IOAPIC_LVT_TRIGGER_MODE ? 'L' : 'E',
> + entry & IOAPIC_LVT_MASKED ? 'M' : '.',
> + (entry >> IOAPIC_LVT_DEST_SHIFT) &
> + (entry & IOAPIC_LVT_DEST_MODE ? 0xff : 0xf));
> + }
> +}
> +
> void ioapic_reset_common(DeviceState *dev)
> {
> IOAPICCommonState *s = IOAPIC_COMMON(dev);
> diff --git a/include/hw/i386/ioapic_internal.h b/include/hw/i386/ioapic_internal.h
> index 4f7764e..797ed47 100644
> --- a/include/hw/i386/ioapic_internal.h
> +++ b/include/hw/i386/ioapic_internal.h
> @@ -105,4 +105,6 @@ struct IOAPICCommonState {
>
> void ioapic_reset_common(DeviceState *dev);
>
> +void ioapic_print_redtbl(Monitor *mon, IOAPICCommonState *s);
> +
> #endif /* !QEMU_IOAPIC_INTERNAL_H */
> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> index 86c5651..437085f 100644
> --- a/include/hw/i386/pc.h
> +++ b/include/hw/i386/pc.h
> @@ -123,6 +123,10 @@ int pic_get_output(DeviceState *d);
> void hmp_info_pic(Monitor *mon, const QDict *qdict);
> void hmp_info_irq(Monitor *mon, const QDict *qdict);
>
> +/* ioapic.c */
> +
> +void kvm_ioapic_dump_state(Monitor *mon, const QDict *qdict);
> +
> /* Global System Interrupts */
>
> #define GSI_NUM_PINS IOAPIC_NUM_PINS
> diff --git a/monitor.c b/monitor.c
> index aad2792..5449663 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -957,6 +957,19 @@ int monitor_get_cpu_index(void)
> return cpu->cpu_index;
> }
>
> +#if defined(TARGET_I386)
> +static void hmp_info_apic_io(Monitor *mon, const QDict *qdict)
> +{
> + if (kvm_irqchip_in_kernel()) {
> + kvm_ioapic_dump_state(mon, qdict);
> + }
Why no else clause for TCG?
> +}
> +#else
> +static void hmp_info_apic_io(Monitor *mon, const QDict *qdict)
> +{
> +}
Rather than having a no-op info apic-io on ARM etc., I would suggest to
#ifdef the below array entry too, so that it is for x86 exclusively.
Regards,
Andreas
> +#endif
> +
> static void hmp_info_apic_local(Monitor *mon, const QDict *qdict)
> {
> CPUState *cpu;
> @@ -2588,6 +2601,13 @@ static mon_cmd_t info_cmds[] = {
> .mhandler.cmd = hmp_info_apic_local,
> },
> {
> + .name = "apic-io",
> + .args_type = "",
> + .params = "",
> + .help = "show io apic state",
> + .mhandler.cmd = hmp_info_apic_io,
> + },
> + {
> .name = "cpus",
> .args_type = "",
> .params = "",
--
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Dilip Upmanyu, Graham Norton; HRB
21284 (AG Nürnberg)
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 7/8] hmp: added io apic dump state
2015-06-19 14:48 ` [Qemu-devel] [PATCH 7/8] hmp: added io apic dump state Denis V. Lunev
2015-06-19 15:53 ` Andreas Färber
@ 2015-06-19 16:08 ` Peter Maydell
2015-06-19 18:03 ` Pavel
1 sibling, 1 reply; 17+ messages in thread
From: Peter Maydell @ 2015-06-19 16:08 UTC (permalink / raw)
To: Denis V. Lunev
Cc: Paolo Bonzini, Pavel Butsykin, QEMU Developers, Luiz Capitulino
On 19 June 2015 at 15:48, Denis V. Lunev <den@openvz.org> wrote:
> From: Pavel Butsykin <pbutsykin@virtuozzo.com>
>
> Added the hmp command to query io apic state, may be usefull after guest
> crashes to understand IRQ routing in guest.
>
> Implementation is only for kvm here. The dump will look like
> (qemu) info apic-io
> ioapic ID=00 IRR=00000000 SEL=18
> ioapic 00 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
> ioapic 01 0300000000000993: int=93 delmod=1:LowPri L.H.E. dest=3
> ...
> ioapic 23 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
> --- a/monitor.c
> +++ b/monitor.c
> @@ -957,6 +957,19 @@ int monitor_get_cpu_index(void)
> return cpu->cpu_index;
> }
>
> +#if defined(TARGET_I386)
> +static void hmp_info_apic_io(Monitor *mon, const QDict *qdict)
> +{
> + if (kvm_irqchip_in_kernel()) {
> + kvm_ioapic_dump_state(mon, qdict);
> + }
> +}
> +#else
> +static void hmp_info_apic_io(Monitor *mon, const QDict *qdict)
> +{
> +}
> +#endif
> +
> static void hmp_info_apic_local(Monitor *mon, const QDict *qdict)
> {
> CPUState *cpu;
> @@ -2588,6 +2601,13 @@ static mon_cmd_t info_cmds[] = {
> .mhandler.cmd = hmp_info_apic_local,
> },
> {
> + .name = "apic-io",
> + .args_type = "",
> + .params = "",
> + .help = "show io apic state",
> + .mhandler.cmd = hmp_info_apic_io,
> + }
Can we please not add more target- and device-specific code
to monitor.c? We need a sensible abstraction layer that allows
devices and CPUs to register monitor commands without
filling monitor.c up with random ifdeffery.
thanks
-- PMM
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 5/8] hmp: added local apic dump state
2015-06-19 15:45 ` Andreas Färber
@ 2015-06-19 18:02 ` Pavel
0 siblings, 0 replies; 17+ messages in thread
From: Pavel @ 2015-06-19 18:02 UTC (permalink / raw)
To: Andreas Färber, Denis V. Lunev
Cc: Paolo Bonzini, Pavel Butsykin, qemu-devel, Luiz Capitulino
On 19.06.2015 18:45, Andreas Färber wrote:
> Am 19.06.2015 um 16:48 schrieb Denis V. Lunev:
>> From: Pavel Butsykin <pbutsykin@virtuozzo.com>
>>
>> Added the hmp command to query local apic registers state, may be
>> usefull after guest crashes to understand IRQ routing in guest.
>>
>> For command name uses "apic-local" because it has to be grouped with
>> command "apic-io".
>>
>> (qemu) info apic-local
>> apic.lvt 00-timer 000300fd int=fd .H.EMP delmod=0:Fixed
>> apic.lvt 00-thermal 00010000 int=00 .H.EM. delmod=0:Fixed
>> apic.lvt 00-perfmon 000000fe int=fe .H.E.. delmod=0:Fixed
>> apic.lvt 00-LINT0 0001001f int=1f .H.EM. delmod=0:Fixed
>> apic.lvt 00-LINT1 000004ff int=ff .H.E.. delmod=4:NMI
>> apic.lvt 00-Error 000000e3 int=e3 .H.E.. delmod=0:Fixed
>> apic.error 00 esr 00000000 S:... R:... .
>> apic.timer 00 DCR=0000000b(b) initial_count=1000090000
>> apic.icr 00 02000000000c00d1: int=d1 delmod=0:Fixed P..E
>> shorthand=3:all dest=2
>> apic.prio 00 apr=00(0:0) tpr=40(4:0)
>> apic.dest 00 dfr=f0(f) ldr=01(01)
>> apic.svr 00 0000011f vec=1f on focus=off
>> apic.interrupt 00 065:R.E
>>
>> Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
>> Signed-off-by: Denis V. Lunev <den@openvz.org>
>> CC: Paolo Bonzini <pbonzini@redhat.com>
>> CC: Luiz Capitulino <lcapitulino@redhat.com>
>> ---
>> hmp-commands.hx | 2 +
>> include/qom/cpu.h | 14 +++++
>> monitor.c | 16 ++++++
>> qom/cpu.c | 11 ++++
>> target-i386/cpu-qom.h | 2 +
>> target-i386/cpu.c | 1 +
>> target-i386/helper.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++
>> 7 files changed, 201 insertions(+)
>>
>> diff --git a/hmp-commands.hx b/hmp-commands.hx
>> index d3b7932..95f554e 100644
>> --- a/hmp-commands.hx
>> +++ b/hmp-commands.hx
>> @@ -1724,6 +1724,8 @@ show the block devices
>> show block device statistics
>> @item info registers
>> show the cpu registers
>> +@item info apic-local
>> +show local APIC state
>> @item info cpus
>> show infos for each CPU
>> @item info history
>> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
>> index 39f0f19..d0b5867 100644
>> --- a/include/qom/cpu.h
>> +++ b/include/qom/cpu.h
>> @@ -138,6 +138,8 @@ typedef struct CPUClass {
>> bool (*virtio_is_big_endian)(CPUState *cpu);
>> int (*memory_rw_debug)(CPUState *cpu, vaddr addr,
>> uint8_t *buf, int len, bool is_write);
>> + void (*dump_apic_local_state)(CPUState *cpu, FILE *f,
>> + fprintf_function cpu_fprintf, int flags);
> Objection, this is a highly x86-specific interface in generic code.
> Either make it generic so that it works for a second CPU implementation
> and does not contain "apic", or make the HMP command x86-specific and
> avoid touching core CPU code then please.
>
> Isn't there already some irq stats info that you could piggy-back on?
>
> Also, you did not use the get_maintainer.pl script, which would've CC'ed
> me as CPU maintainer.
>
> One remark below.
>
> Regards,
> Andreas
Yes, indeed. I missed this moment, it needs to be fixed.
I think APIC dump do better separately, because it is necessary to
outputs apic state and not irq statistic past.
Thanks for the reminder about get_maintainer.pl script.
>> void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
>> int flags);
>> void (*dump_statistics)(CPUState *cpu, FILE *f,
>> @@ -398,6 +400,18 @@ enum CPUDumpFlags {
>> };
>>
>> /**
>> + * cpu_dump_apic_local_state:
>> + * @cpu: The CPU whose lcoal APIC state is to be dumped.
>> + * @f: File to dump to.
>> + * @cpu_fprintf: Function to dump with.
>> + * @flags: Flags what to dump.
>> + *
>> + * Dumps local APIC state.
>> + */
>> +void cpu_dump_apic_local_state(CPUState *cpu, FILE *f,
>> + fprintf_function cpu_fprintf, int flags);
>> +
>> +/**
>> * cpu_dump_state:
>> * @cpu: The CPU whose state is to be dumped.
>> * @f: File to dump to.
>> diff --git a/monitor.c b/monitor.c
>> index 8e1a2e8..aad2792 100644
>> --- a/monitor.c
>> +++ b/monitor.c
>> @@ -957,6 +957,15 @@ int monitor_get_cpu_index(void)
>> return cpu->cpu_index;
>> }
>>
>> +static void hmp_info_apic_local(Monitor *mon, const QDict *qdict)
>> +{
>> + CPUState *cpu;
>> + CPUArchState *env;
>> + env = mon_get_cpu();
>> + cpu = ENV_GET_CPU(env);
> Note: There is another pending series that will conflict with this.
ok, we will merge it. if that..
>> + cpu_dump_apic_local_state(cpu, (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU);
>> +}
>> +
>> static void hmp_info_registers(Monitor *mon, const QDict *qdict)
>> {
>> CPUState *cpu;
>> @@ -2572,6 +2581,13 @@ static mon_cmd_t info_cmds[] = {
>> .mhandler.cmd = hmp_info_registers,
>> },
>> {
>> + .name = "apic-local",
>> + .args_type = "",
>> + .params = "",
>> + .help = "show local apic state",
>> + .mhandler.cmd = hmp_info_apic_local,
>> + },
>> + {
>> .name = "cpus",
>> .args_type = "",
>> .params = "",
>> diff --git a/qom/cpu.c b/qom/cpu.c
>> index 108bfa2..56e8a6b 100644
>> --- a/qom/cpu.c
>> +++ b/qom/cpu.c
>> @@ -201,6 +201,17 @@ static bool cpu_common_exec_interrupt(CPUState *cpu, int int_req)
>> return false;
>> }
>>
>> +void cpu_dump_apic_local_state(CPUState *cpu, FILE *f,
>> + fprintf_function cpu_fprintf, int flags)
>> +{
>> + CPUClass *cc = CPU_GET_CLASS(cpu);
>> +
>> + if (cc->dump_apic_local_state) {
>> + cpu_synchronize_state(cpu);
>> + cc->dump_apic_local_state(cpu, f, cpu_fprintf, flags);
>> + }
>> +}
>> +
>> void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
>> int flags)
>> {
>> diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
>> index c35b624..e5daeaf 100644
>> --- a/target-i386/cpu-qom.h
>> +++ b/target-i386/cpu-qom.h
>> @@ -151,6 +151,8 @@ void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
>>
>> void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
>> int flags);
>> +void x86_cpu_dump_apic_local_state(CPUState *cs, FILE *f,
>> + fprintf_function cpu_fprintf, int flags);
>>
>> hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
>>
>> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
>> index af0552a..4178444 100644
>> --- a/target-i386/cpu.c
>> +++ b/target-i386/cpu.c
>> @@ -3147,6 +3147,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
>> cc->has_work = x86_cpu_has_work;
>> cc->do_interrupt = x86_cpu_do_interrupt;
>> cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
>> + cc->dump_apic_local_state = x86_cpu_dump_apic_local_state;
>> cc->dump_state = x86_cpu_dump_state;
>> cc->set_pc = x86_cpu_set_pc;
>> cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
>> diff --git a/target-i386/helper.c b/target-i386/helper.c
>> index 5480a96..8d883f5 100644
>> --- a/target-i386/helper.c
>> +++ b/target-i386/helper.c
>> @@ -23,6 +23,7 @@
>> #ifndef CONFIG_USER_ONLY
>> #include "sysemu/sysemu.h"
>> #include "monitor/monitor.h"
>> +#include "hw/i386/apic_internal.h"
>> #endif
>>
>> static void cpu_x86_version(CPUX86State *env, int *family, int *model)
>> @@ -177,6 +178,160 @@ done:
>> cpu_fprintf(f, "\n");
>> }
>>
>> +#ifndef CONFIG_USER_ONLY
>> +
>> +/* ARRAY_SIZE check is not required because
>> + * DeliveryMode(dm) has a size of 3 bit.
>> + */
>> +static inline const char *dm2str(uint32_t dm)
>> +{
>> + static const char *str[] = {
>> + "Fixed",
>> + "...",
>> + "SMI",
>> + "...",
>> + "NMI",
>> + "INIT",
>> + "...",
>> + "ExtINT"
>> + };
>> + return str[dm];
>> +}
>> +
>> +static void dump_apic_lvt(FILE *f, fprintf_function cpu_fprintf,
>> + uint32_t cpu_idx, const char *name,
>> + uint32_t lvt, bool is_timer)
>> +{
>> + uint32_t dm = (lvt & APIC_LVT_DELIV_MOD) >> APIC_LVT_DELIV_MOD_SHIFT;
>> + cpu_fprintf(f,
>> + "apic.lvt\t%02u-%-7s %08x int=%02x %c%c%c%c%c%c delmod=%x:%s\n",
>> + cpu_idx, name, lvt,
>> + lvt & APIC_VECTOR_MASK,
>> + lvt & APIC_LVT_DELIV_STS ? 'P' : '.',
>> + lvt & APIC_LVT_INT_POLARITY ? 'L' : 'H',
>> + lvt & APIC_LVT_REMOTE_IRR ? 'R' : '.',
>> + lvt & APIC_LVT_LEVEL_TRIGGER ? 'L' : 'E',
>> + lvt & APIC_LVT_MASKED ? 'M' : '.',
>> + !is_timer ? '.' : (lvt & APIC_LVT_TIMER_PERIODIC ? 'P' : 'S'),
>> + dm,
>> + dm2str(dm));
>> +
>> +}
>> +
>> +/* ARRAY_SIZE check is not required because
>> + * destination shorthand has a size of 2 bit.
>> + */
>> +static inline const char *shorthand2str(uint32_t shorthand)
>> +{
>> + const char *str[] = {
>> + "no", "self", "all-self", "all"
>> + };
>> + return str[shorthand];
>> +}
>> +
>> +void x86_cpu_dump_apic_local_state(CPUState *cs, FILE *f,
>> + fprintf_function cpu_fprintf, int flags)
>> +{
>> + X86CPU *cpu = X86_CPU(cs);
>> + APICCommonState *s = APIC_COMMON(cpu->apic_state);
>> + uint32_t *irr_tab = s->irr, *isr_tab = s->isr, *tmr_tab = s->tmr;
>> + uint32_t *lvt = s->lvt;
>> + uint32_t icr0 = s->icr[0], icr1 = s->icr[1];
>> + uint32_t esr = s->esr;
>> + uint32_t cpu_idx = CPU(cpu)->cpu_index;
>> + int i;
>> +
>> + dump_apic_lvt(f, cpu_fprintf, cpu_idx, "timer",
>> + lvt[APIC_LVT_TIMER], true);
>> + dump_apic_lvt(f, cpu_fprintf, cpu_idx, "thermal",
>> + lvt[APIC_LVT_THERMAL], false);
>> + dump_apic_lvt(f, cpu_fprintf, cpu_idx, "perfmon",
>> + lvt[APIC_LVT_PERFORM], false);
>> + dump_apic_lvt(f, cpu_fprintf, cpu_idx, "LINT0",
>> + lvt[APIC_LVT_LINT0], false);
>> + dump_apic_lvt(f, cpu_fprintf, cpu_idx, "LINT1",
>> + lvt[APIC_LVT_LINT1], false);
>> + dump_apic_lvt(f, cpu_fprintf, cpu_idx, "Error",
>> + lvt[APIC_LVT_ERROR], false);
>> +
>> + cpu_fprintf(f, "apic.error\t%02u esr %08x S:%c%c%c R:%c%c%c %c\n",
>> + cpu_idx, esr,
>> + esr & APIC_ESR_SEND_CHECK_SUM ? 'C' : '.',
>> + esr & APIC_ESR_SEND_ACCEPT ? 'A' : '.',
>> + esr & APIC_ESR_SEND_ILLEGAL_VECT ? 'I' : '.',
>> + esr & APIC_ESR_RECV_CHECK_SUM ? 'C' : '.',
>> + esr & APIC_ESR_RECV_ACCEPT ? 'A' : '.',
>> + esr & APIC_ESR_RECV_ILLEGAL_VECT ? 'I' : '.',
>> + esr & APIC_ESR_ILLEGAL_ADDRESS ? 'R' : '.');
>> +
>> + cpu_fprintf(f, "apic.timer\t%02u DCR=%08x(%x) initial_count=%d\n",
>> + cpu_idx, s->divide_conf, s->divide_conf & APIC_DCR_MASK,
>> + s->initial_count);
>> +
>> + cpu_fprintf(f, "apic.icr\t%02u %016jx: int=%02x "
>> + "delmod=%x:%s %c%c%c%c shorthand=%x:%s dest=%x\n",
>> + cpu_idx, ((uint64_t *)s->icr)[0],
>> + icr0 & APIC_VECTOR_MASK,
>> + (icr0 & APIC_ICR_DELIV_MOD) >> APIC_ICR_DELIV_MOD_SHIFT,
>> + dm2str((icr0 & APIC_ICR_DELIV_MOD) >> APIC_ICR_DELIV_MOD_SHIFT),
>> + icr0 & APIC_ICR_DEST_MOD ? 'L' : 'P',
>> + icr0 & APIC_ICR_DELIV_STS ? 'P' : '.',
>> + icr0 & APIC_ICR_LEVEL ? 'A' : '.',
>> + icr0 & APIC_ICR_TRIGGER_MOD ? 'L' : 'E',
>> + (icr0 & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT,
>> + shorthand2str(
>> + (icr0 & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT),
>> + (icr1 >> APIC_ICR_DEST_SHIFT) &
>> + (icr0 & APIC_ICR_DEST_MOD ? 0xff : 0xf));
>> +
>> + cpu_fprintf(f, "apic.prio\t%02u apr=%02x(%x:%x)\ttpr=%02x(%x:%x)\n",
>> + cpu_idx,
>> + s->arb_id,
>> + s->arb_id >> APIC_PR_CLASS_SHIFT,
>> + s->arb_id & APIC_PR_SUB_CLASS,
>> + s->tpr,
>> + s->tpr >> APIC_PR_CLASS_SHIFT,
>> + s->tpr & APIC_PR_SUB_CLASS);
>> +
>> + cpu_fprintf(f, "apic.dest\t%02u dfr=%02x(%x)\tldr=%02x",
>> + cpu_idx, s->dest_mode << 4, s->dest_mode, s->log_dest);
>> + if (s->dest_mode == 0) {
>> + cpu_fprintf(f, "(%x:%x)\n",
>> + s->log_dest & APIC_LOGDEST_APIC_ID,
>> + s->log_dest >> APIC_LOGDEST_ID_SHIFT);
>> + } else if (s->dest_mode == 0xf) {
>> + cpu_fprintf(f, "(%02x)\n", s->log_dest);
>> + } else {
>> + cpu_fprintf(f, "(BAD)\n");
>> + }
>> +
>> + cpu_fprintf(f, "apic.svr\t%02u %08x vec=%02x %s focus=%s\n",
>> + cpu_idx, s->spurious_vec,
>> + s->spurious_vec & APIC_VECTOR_MASK,
>> + s->spurious_vec & APIC_SPURIO_ENABLED ? "on" : "off",
>> + s->spurious_vec & APIC_SPURIO_FOCUS ? "on" : "off");
>> +
>> + for (i = 0; i < 256; i++) {
>> + if (irr_tab[i] || isr_tab[i]) {
>> + bool irr_bit = apic_get_bit(irr_tab, i);
>> + bool isr_bit = apic_get_bit(isr_tab, i);
>> +
>> + if (irr_bit || isr_bit) {
>> + cpu_fprintf(f, "apic.interrupt\t%02u %03u:%c%c%c\n", cpu_idx, i,
>> + irr_bit ? 'R' : '.',
>> + isr_bit ? 'S' : '.',
>> + apic_get_bit(tmr_tab, i) ? 'L' : 'E');
>> + }
>> + }
>> + }
>> +}
>> +#else
>> +void x86_cpu_dump_apic_local_state(CPUState *cs, FILE *f,
>> + fprintf_function cpu_fprintf, int flags)
>> +{
>> +}
>> +#endif /* !CONFIG_USER_ONLY */
>> +
>> #define DUMP_CODE_BYTES_TOTAL 50
>> #define DUMP_CODE_BYTES_BACKWARD 20
>>
>>
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 7/8] hmp: added io apic dump state
2015-06-19 15:53 ` Andreas Färber
@ 2015-06-19 18:02 ` Pavel
0 siblings, 0 replies; 17+ messages in thread
From: Pavel @ 2015-06-19 18:02 UTC (permalink / raw)
To: Andreas Färber, Denis V. Lunev
Cc: Peter Maydell, Paolo Bonzini, Pavel Butsykin, qemu-devel,
Luiz Capitulino
On 19.06.2015 18:53, Andreas Färber wrote:
> Am 19.06.2015 um 16:48 schrieb Denis V. Lunev:
>> From: Pavel Butsykin <pbutsykin@virtuozzo.com>
>>
>> Added the hmp command to query io apic state, may be usefull after guest
>> crashes to understand IRQ routing in guest.
>>
>> Implementation is only for kvm here. The dump will look like
>> (qemu) info apic-io
>> ioapic ID=00 IRR=00000000 SEL=18
>> ioapic 00 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
>> ioapic 01 0300000000000993: int=93 delmod=1:LowPri L.H.E. dest=3
>> ...
>> ioapic 23 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
>>
>> Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
>> Signed-off-by: Denis V. Lunev <den@openvz.org>
>> CC: Paolo Bonzini <pbonzini@redhat.com>
>> CC: Luiz Capitulino <lcapitulino@redhat.com>
>> ---
>> hmp-commands.hx | 2 ++
>> hw/i386/kvm/ioapic.c | 10 ++++++++++
>> hw/intc/ioapic_common.c | 31 +++++++++++++++++++++++++++++++
>> include/hw/i386/ioapic_internal.h | 2 ++
>> include/hw/i386/pc.h | 4 ++++
>> monitor.c | 20 ++++++++++++++++++++
>> 6 files changed, 69 insertions(+)
>>
>> diff --git a/hmp-commands.hx b/hmp-commands.hx
>> index 95f554e..894ff65 100644
>> --- a/hmp-commands.hx
>> +++ b/hmp-commands.hx
>> @@ -1726,6 +1726,8 @@ show block device statistics
>> show the cpu registers
>> @item info apic-local
>> show local APIC state
>> +@item info apic-io
>> +show io APIC state
>> @item info cpus
>> show infos for each CPU
>> @item info history
>> diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c
>> index d2a6c4c..b7390ca 100644
>> --- a/hw/i386/kvm/ioapic.c
>> +++ b/hw/i386/kvm/ioapic.c
>> @@ -10,6 +10,7 @@
>> * See the COPYING file in the top-level directory.
>> */
>>
>> +#include "monitor/monitor.h"
>> #include "hw/i386/pc.h"
>> #include "hw/i386/ioapic_internal.h"
>> #include "hw/i386/apic_internal.h"
>> @@ -110,6 +111,15 @@ static void kvm_ioapic_put(IOAPICCommonState *s)
>> }
>> }
>>
>> +void kvm_ioapic_dump_state(Monitor *mon, const QDict *qdict)
>> +{
>> + IOAPICCommonState s;
>> +
>> + kvm_ioapic_get(&s);
>> +
>> + ioapic_print_redtbl(mon, &s);
>> +}
>> +
>> static void kvm_ioapic_reset(DeviceState *dev)
>> {
>> IOAPICCommonState *s = IOAPIC_COMMON(dev);
>> diff --git a/hw/intc/ioapic_common.c b/hw/intc/ioapic_common.c
>> index 8b7d118..83edf69 100644
>> --- a/hw/intc/ioapic_common.c
>> +++ b/hw/intc/ioapic_common.c
>> @@ -19,6 +19,7 @@
>> * License along with this library; if not, see <http://www.gnu.org/licenses/>.
>> */
>>
>> +#include "monitor/monitor.h"
>> #include "hw/i386/ioapic.h"
>> #include "hw/i386/ioapic_internal.h"
>> #include "hw/sysbus.h"
>> @@ -31,6 +32,36 @@
>> */
>> int ioapic_no;
>>
>> +void ioapic_print_redtbl(Monitor *mon, IOAPICCommonState *s)
>> +{
>> + static const char *delm_str[] = {
>> + "Fixed", "LowPri", "SMI", "...", "NMI", "INIT", "...", "ExtINT"};
>> + int i;
>> +
>> + monitor_printf(mon, "ioapic ID=%02x IRR=%08x SEL=%02x\n",
>> + s->id, s->irr, s->ioregsel);
>> +
>> + for (i = 0; i < IOAPIC_NUM_PINS; i++) {
>> + uint64_t entry = s->ioredtbl[i];
>> + uint32_t delm = (uint32_t)((entry & IOAPIC_LVT_DELIV_MODE) >>
>> + IOAPIC_LVT_DELIV_MODE_SHIFT);
>> + monitor_printf(mon, "ioapic %02u %016jx: int=%02jx "
>> + "delmod=%x:%-6s %c%c%c%c%c%c dest=%jx\n",
>> + i, entry,
>> + entry & IOAPIC_VECTOR_MASK,
>> + delm,
>> + delm_str[delm],
>> + entry & IOAPIC_LVT_DEST_MODE ? 'L' : 'P',
>> + entry & IOAPIC_LVT_DELIV_STATUS ? 'P' : '.',
>> + entry & IOAPIC_LVT_POLARITY ? 'L' : 'H',
>> + entry & IOAPIC_LVT_REMOTE_IRR ? 'R' : '.',
>> + entry & IOAPIC_LVT_TRIGGER_MODE ? 'L' : 'E',
>> + entry & IOAPIC_LVT_MASKED ? 'M' : '.',
>> + (entry >> IOAPIC_LVT_DEST_SHIFT) &
>> + (entry & IOAPIC_LVT_DEST_MODE ? 0xff : 0xf));
>> + }
>> +}
>> +
>> void ioapic_reset_common(DeviceState *dev)
>> {
>> IOAPICCommonState *s = IOAPIC_COMMON(dev);
>> diff --git a/include/hw/i386/ioapic_internal.h b/include/hw/i386/ioapic_internal.h
>> index 4f7764e..797ed47 100644
>> --- a/include/hw/i386/ioapic_internal.h
>> +++ b/include/hw/i386/ioapic_internal.h
>> @@ -105,4 +105,6 @@ struct IOAPICCommonState {
>>
>> void ioapic_reset_common(DeviceState *dev);
>>
>> +void ioapic_print_redtbl(Monitor *mon, IOAPICCommonState *s);
>> +
>> #endif /* !QEMU_IOAPIC_INTERNAL_H */
>> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
>> index 86c5651..437085f 100644
>> --- a/include/hw/i386/pc.h
>> +++ b/include/hw/i386/pc.h
>> @@ -123,6 +123,10 @@ int pic_get_output(DeviceState *d);
>> void hmp_info_pic(Monitor *mon, const QDict *qdict);
>> void hmp_info_irq(Monitor *mon, const QDict *qdict);
>>
>> +/* ioapic.c */
>> +
>> +void kvm_ioapic_dump_state(Monitor *mon, const QDict *qdict);
>> +
>> /* Global System Interrupts */
>>
>> #define GSI_NUM_PINS IOAPIC_NUM_PINS
>> diff --git a/monitor.c b/monitor.c
>> index aad2792..5449663 100644
>> --- a/monitor.c
>> +++ b/monitor.c
>> @@ -957,6 +957,19 @@ int monitor_get_cpu_index(void)
>> return cpu->cpu_index;
>> }
>>
>> +#if defined(TARGET_I386)
>> +static void hmp_info_apic_io(Monitor *mon, const QDict *qdict)
>> +{
>> + if (kvm_irqchip_in_kernel()) {
>> + kvm_ioapic_dump_state(mon, qdict);
>> + }
> Why no else clause for TCG?
See next commit pls
>
>> +}
>> +#else
>> +static void hmp_info_apic_io(Monitor *mon, const QDict *qdict)
>> +{
>> +}
> Rather than having a no-op info apic-io on ARM etc., I would suggest to
> #ifdef the below array entry too, so that it is for x86 exclusively.
>
> Regards,
> Andreas
Yes, thanks. I think it needs to be fixed..
>> +#endif
>> +
>> static void hmp_info_apic_local(Monitor *mon, const QDict *qdict)
>> {
>> CPUState *cpu;
>> @@ -2588,6 +2601,13 @@ static mon_cmd_t info_cmds[] = {
>> .mhandler.cmd = hmp_info_apic_local,
>> },
>> {
>> + .name = "apic-io",
>> + .args_type = "",
>> + .params = "",
>> + .help = "show io apic state",
>> + .mhandler.cmd = hmp_info_apic_io,
>> + },
>> + {
>> .name = "cpus",
>> .args_type = "",
>> .params = "",
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 7/8] hmp: added io apic dump state
2015-06-19 16:08 ` Peter Maydell
@ 2015-06-19 18:03 ` Pavel
0 siblings, 0 replies; 17+ messages in thread
From: Pavel @ 2015-06-19 18:03 UTC (permalink / raw)
To: Peter Maydell, Denis V. Lunev
Cc: Paolo Bonzini, Pavel Butsykin, QEMU Developers, Luiz Capitulino
On 19.06.2015 19:08, Peter Maydell wrote:
> On 19 June 2015 at 15:48, Denis V. Lunev <den@openvz.org> wrote:
>> From: Pavel Butsykin <pbutsykin@virtuozzo.com>
>>
>> Added the hmp command to query io apic state, may be usefull after guest
>> crashes to understand IRQ routing in guest.
>>
>> Implementation is only for kvm here. The dump will look like
>> (qemu) info apic-io
>> ioapic ID=00 IRR=00000000 SEL=18
>> ioapic 00 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
>> ioapic 01 0300000000000993: int=93 delmod=1:LowPri L.H.E. dest=3
>> ...
>> ioapic 23 00000000000100ff: int=ff delmod=0:Fixed P.H.EM dest=0
>> --- a/monitor.c
>> +++ b/monitor.c
>> @@ -957,6 +957,19 @@ int monitor_get_cpu_index(void)
>> return cpu->cpu_index;
>> }
>>
>> +#if defined(TARGET_I386)
>> +static void hmp_info_apic_io(Monitor *mon, const QDict *qdict)
>> +{
>> + if (kvm_irqchip_in_kernel()) {
>> + kvm_ioapic_dump_state(mon, qdict);
>> + }
>> +}
>> +#else
>> +static void hmp_info_apic_io(Monitor *mon, const QDict *qdict)
>> +{
>> +}
>> +#endif
>> +
>> static void hmp_info_apic_local(Monitor *mon, const QDict *qdict)
>> {
>> CPUState *cpu;
>> @@ -2588,6 +2601,13 @@ static mon_cmd_t info_cmds[] = {
>> .mhandler.cmd = hmp_info_apic_local,
>> },
>> {
>> + .name = "apic-io",
>> + .args_type = "",
>> + .params = "",
>> + .help = "show io apic state",
>> + .mhandler.cmd = hmp_info_apic_io,
>> + }
> Can we please not add more target- and device-specific code
> to monitor.c? We need a sensible abstraction layer that allows
> devices and CPUs to register monitor commands without
> filling monitor.c up with random ifdeffery.
>
> thanks
> -- PMM
No problem. I think anything to do with it, thanks.
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2015-06-19 18:34 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-19 14:48 [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state Denis V. Lunev
2015-06-19 14:48 ` [Qemu-devel] [PATCH 1/8] apic_internal.h: move apic_get_bit(), apic_set_bit() to apic_internal.h Denis V. Lunev
2015-06-19 14:48 ` [Qemu-devel] [PATCH 2/8] apic_internal.h: rename ESR_ILLEGAL_ADDRESS to APIC_ESR_ILLEGAL_ADDRESS Denis V. Lunev
2015-06-19 14:48 ` [Qemu-devel] [PATCH 3/8] apic_internal.h: added more constants Denis V. Lunev
2015-06-19 14:48 ` [Qemu-devel] [PATCH 4/8] apic_internal.h: Fix formatting and drop unused consts Denis V. Lunev
2015-06-19 14:48 ` [Qemu-devel] [PATCH 5/8] hmp: added local apic dump state Denis V. Lunev
2015-06-19 15:45 ` Andreas Färber
2015-06-19 18:02 ` Pavel
2015-06-19 14:48 ` [Qemu-devel] [PATCH 6/8] ioapic_internal.h: added more constants Denis V. Lunev
2015-06-19 14:48 ` [Qemu-devel] [PATCH 7/8] hmp: added io apic dump state Denis V. Lunev
2015-06-19 15:53 ` Andreas Färber
2015-06-19 18:02 ` Pavel
2015-06-19 16:08 ` Peter Maydell
2015-06-19 18:03 ` Pavel
2015-06-19 14:48 ` [Qemu-devel] [PATCH 8/8] hmp: implemented io apic dump state for emulator Denis V. Lunev
2015-06-19 14:56 ` [Qemu-devel] [PATCH 0/8] hmp command IO- and Local APIC dump state Eric Blake
2015-06-19 15:01 ` Denis V. Lunev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).