* [Qemu-devel] [PATCH 1/9] apic_internal.h: move apic_get_bit(), apic_set_bit() to apic_internal.h
2015-09-15 9:22 [Qemu-devel] [PATCH v2 0/9] hmp command IO- and Local APIC dump state Denis V. Lunev
@ 2015-09-15 9:23 ` Denis V. Lunev
2015-09-15 9:23 ` [Qemu-devel] [PATCH 2/9] apic_internal.h: rename ESR_ILLEGAL_ADDRESS to APIC_ESR_ILLEGAL_ADDRESS Denis V. Lunev
` (7 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Denis V. Lunev @ 2015-09-15 9:23 UTC (permalink / raw)
Cc: Denis V. Lunev, Andreas Färber, 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: Andreas Färber <andreas.faerber@web.de>
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 26632ac..6a40156 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -147,4 +147,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 */
--
2.1.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 2/9] apic_internal.h: rename ESR_ILLEGAL_ADDRESS to APIC_ESR_ILLEGAL_ADDRESS
2015-09-15 9:22 [Qemu-devel] [PATCH v2 0/9] hmp command IO- and Local APIC dump state Denis V. Lunev
2015-09-15 9:23 ` [Qemu-devel] [PATCH 1/9] apic_internal.h: move apic_get_bit(), apic_set_bit() to apic_internal.h Denis V. Lunev
@ 2015-09-15 9:23 ` Denis V. Lunev
2015-09-15 9:23 ` [Qemu-devel] [PATCH 3/9] apic_internal.h: added more constants Denis V. Lunev
` (6 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Denis V. Lunev @ 2015-09-15 9:23 UTC (permalink / raw)
Cc: Denis V. Lunev, Andreas Färber, 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: Andreas Färber <andreas.faerber@web.de>
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 6a40156..bc8d4e7 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -57,7 +57,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)
--
2.1.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 3/9] apic_internal.h: added more constants
2015-09-15 9:22 [Qemu-devel] [PATCH v2 0/9] hmp command IO- and Local APIC dump state Denis V. Lunev
2015-09-15 9:23 ` [Qemu-devel] [PATCH 1/9] apic_internal.h: move apic_get_bit(), apic_set_bit() to apic_internal.h Denis V. Lunev
2015-09-15 9:23 ` [Qemu-devel] [PATCH 2/9] apic_internal.h: rename ESR_ILLEGAL_ADDRESS to APIC_ESR_ILLEGAL_ADDRESS Denis V. Lunev
@ 2015-09-15 9:23 ` Denis V. Lunev
2015-09-15 9:23 ` [Qemu-devel] [PATCH 4/9] apic_internal.h: fix formatting and drop unused consts Denis V. Lunev
` (5 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Denis V. Lunev @ 2015-09-15 9:23 UTC (permalink / raw)
Cc: Denis V. Lunev, Andreas Färber, 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: Andreas Färber <andreas.faerber@web.de>
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 bc8d4e7..3a3f8fc 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -50,14 +50,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)
--
2.1.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 4/9] apic_internal.h: fix formatting and drop unused consts
2015-09-15 9:22 [Qemu-devel] [PATCH v2 0/9] hmp command IO- and Local APIC dump state Denis V. Lunev
` (2 preceding siblings ...)
2015-09-15 9:23 ` [Qemu-devel] [PATCH 3/9] apic_internal.h: added more constants Denis V. Lunev
@ 2015-09-15 9:23 ` Denis V. Lunev
2015-09-15 9:23 ` [Qemu-devel] [PATCH 5/9] monitor: make monitor_fprintf and mon_get_cpu externally visible Denis V. Lunev
` (4 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Denis V. Lunev @ 2015-09-15 9:23 UTC (permalink / raw)
Cc: Denis V. Lunev, Andreas Färber, 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: Andreas Färber <andreas.faerber@web.de>
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 3a3f8fc..36f6c08 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -61,12 +61,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)
@@ -78,7 +76,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)
@@ -113,8 +111,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)
--
2.1.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 5/9] monitor: make monitor_fprintf and mon_get_cpu externally visible
2015-09-15 9:22 [Qemu-devel] [PATCH v2 0/9] hmp command IO- and Local APIC dump state Denis V. Lunev
` (3 preceding siblings ...)
2015-09-15 9:23 ` [Qemu-devel] [PATCH 4/9] apic_internal.h: fix formatting and drop unused consts Denis V. Lunev
@ 2015-09-15 9:23 ` Denis V. Lunev
2015-09-15 9:23 ` [Qemu-devel] [PATCH 6/9] hmp: added local apic dump state Denis V. Lunev
` (3 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Denis V. Lunev @ 2015-09-15 9:23 UTC (permalink / raw)
Cc: Denis V. Lunev, Andreas Färber, Paolo Bonzini, qemu-devel,
Pavel Butsykin
From: Pavel Butsykin <pbutsykin@virtuozzo.com>
monitor_fprintf and mon_get_cpu will be used in the target-specific monitor,
so it is advisable to make it external.
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Andreas Färber <andreas.faerber@web.de>
CC: Paolo Bonzini <pbonzini@redhat.com>
---
disas.c | 10 ----------
include/monitor/monitor-common.h | 1 +
include/monitor/monitor.h | 1 +
monitor.c | 5 ++---
4 files changed, 4 insertions(+), 13 deletions(-)
diff --git a/disas.c b/disas.c
index 0ae70c2..45878fa 100644
--- a/disas.c
+++ b/disas.c
@@ -392,16 +392,6 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
return 0;
}
-static int GCC_FMT_ATTR(2, 3)
-monitor_fprintf(FILE *stream, const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- monitor_vprintf((Monitor *)stream, fmt, ap);
- va_end(ap);
- return 0;
-}
-
/* Disassembler for the monitor.
See target_disas for a description of flags. */
void monitor_disas(Monitor *mon, CPUState *cpu,
diff --git a/include/monitor/monitor-common.h b/include/monitor/monitor-common.h
index 7d1ec5a..abd7a6c 100644
--- a/include/monitor/monitor-common.h
+++ b/include/monitor/monitor-common.h
@@ -37,6 +37,7 @@ typedef struct MonitorDef {
const MonitorDef *target_monitor_defs(void);
CPUArchState *mon_get_cpu_env(void);
+CPUState *mon_get_cpu(void);
void hmp_info_mem(Monitor *mon, const QDict *qdict);
void hmp_info_tlb(Monitor *mon, const QDict *qdict);
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 9aff47e..f95a384 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -34,6 +34,7 @@ int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp);
void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
GCC_FMT_ATTR(2, 0);
void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
+int monitor_fprintf(FILE *stream, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
void monitor_flush(Monitor *mon);
int monitor_set_cpu(int cpu_index);
int monitor_get_cpu_index(void);
diff --git a/monitor.c b/monitor.c
index e4a5653..989c685 100644
--- a/monitor.c
+++ b/monitor.c
@@ -372,8 +372,7 @@ void monitor_printf(Monitor *mon, const char *fmt, ...)
va_end(ap);
}
-static int GCC_FMT_ATTR(2, 3) monitor_fprintf(FILE *stream,
- const char *fmt, ...)
+int monitor_fprintf(FILE *stream, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
@@ -942,7 +941,7 @@ int monitor_set_cpu(int cpu_index)
return 0;
}
-static CPUState *mon_get_cpu(void)
+CPUState *mon_get_cpu(void)
{
if (!cur_mon->mon_cpu) {
monitor_set_cpu(0);
--
2.1.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 6/9] hmp: added local apic dump state
2015-09-15 9:22 [Qemu-devel] [PATCH v2 0/9] hmp command IO- and Local APIC dump state Denis V. Lunev
` (4 preceding siblings ...)
2015-09-15 9:23 ` [Qemu-devel] [PATCH 5/9] monitor: make monitor_fprintf and mon_get_cpu externally visible Denis V. Lunev
@ 2015-09-15 9:23 ` Denis V. Lunev
2015-09-15 10:20 ` Paolo Bonzini
2015-09-15 9:23 ` [Qemu-devel] [PATCH 7/9] ioapic_internal.h: added more constants Denis V. Lunev
` (2 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Denis V. Lunev @ 2015-09-15 9:23 UTC (permalink / raw)
Cc: Denis V. Lunev, Andreas Färber, 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: Andreas Färber <andreas.faerber@web.de>
CC: Paolo Bonzini <pbonzini@redhat.com>
---
hmp-commands-info.hx | 16 ++++
include/monitor/monitor-common.h | 1 +
target-i386/cpu.h | 3 +
target-i386/helper.c | 155 +++++++++++++++++++++++++++++++++++++++
target-i386/monitor.c | 6 ++
5 files changed, 181 insertions(+)
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 9f5a158..5ffc181 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -112,6 +112,22 @@ STEXI
Show the cpu registers.
ETEXI
+#if defined(TARGET_I386)
+ {
+ .name = "apic-local",
+ .args_type = "",
+ .params = "",
+ .help = "show local apic state",
+ .mhandler.cmd = hmp_info_apic_local,
+ },
+#endif
+
+STEXI
+@item info apic-local
+@findex apic-local
+Show local APIC state
+ETEXI
+
{
.name = "cpus",
.args_type = "",
diff --git a/include/monitor/monitor-common.h b/include/monitor/monitor-common.h
index abd7a6c..462c35e 100644
--- a/include/monitor/monitor-common.h
+++ b/include/monitor/monitor-common.h
@@ -42,5 +42,6 @@ CPUState *mon_get_cpu(void);
void hmp_info_mem(Monitor *mon, const QDict *qdict);
void hmp_info_tlb(Monitor *mon, const QDict *qdict);
void hmp_mce(Monitor *mon, const QDict *qdict);
+void hmp_info_apic_local(Monitor *mon, const QDict *qdict);
#endif /* MONITOR_COMMON */
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index af97772..f37a9c6 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1347,4 +1347,7 @@ void enable_compat_apic_id_mode(void);
#define APIC_DEFAULT_ADDRESS 0xfee00000
#define APIC_SPACE_SIZE 0x100000
+void x86_cpu_dump_apic_local_state(CPUState *cs, FILE *f,
+ fprintf_function cpu_fprintf, int flags);
+
#endif /* CPU_I386_H */
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
diff --git a/target-i386/monitor.c b/target-i386/monitor.c
index e775561..fbc9fcd 100644
--- a/target-i386/monitor.c
+++ b/target-i386/monitor.c
@@ -492,3 +492,9 @@ const MonitorDef *target_monitor_defs(void)
{
return monitor_defs;
}
+
+void hmp_info_apic_local(Monitor *mon, const QDict *qdict)
+{
+ x86_cpu_dump_apic_local_state(mon_get_cpu(), (FILE *)mon, monitor_fprintf,
+ CPU_DUMP_FPU);
+}
--
2.1.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH 6/9] hmp: added local apic dump state
2015-09-15 9:23 ` [Qemu-devel] [PATCH 6/9] hmp: added local apic dump state Denis V. Lunev
@ 2015-09-15 10:20 ` Paolo Bonzini
0 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2015-09-15 10:20 UTC (permalink / raw)
To: Denis V. Lunev; +Cc: Andreas Färber, qemu-devel, Pavel Butsykin
On 15/09/2015 11:23, Denis V. Lunev wrote:
> 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".
I would call them "info lapic" and "info ioapic"
>
> (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
This is not very readable :)
What about:
Dumping local APIC state for CPU 0
LVT0 0x0001001f activehi edge masked Fixed (vec 31)
LVT1 0x000004ff activehi edge NMI
LVTPC 0x000000fe activehi edge Fixed (vec 254)
LVTERR 0x000000e3 activehi edge Fixed (vec 243)
LVTTHMR 0x00010000 activehi edge masked Fixed (vec 0)
LVTT 0x000300fd activehi edge masked periodic Fixed (vec 253)
Timer DCR=0xb (divide by 1), initial count = 1000090000
SPIV 0x0000011f APIC enabled, focus=off, spurious vec 31
ICR 0x000c00d1 physical edge deassert all
ICR2 0x02000000
ESR 0x00000000
ISR 31(level) 65
IRR 31(level) 42(level)
APR 0x00 TPR 0x20 DFR 0xf0 LDR 0x01 PPR 0x40
Some notes:
- no need to detail ESR, it's never used
- no need to detail ICR2 if ICR uses a shorthand, otherwise could be one of
these formats
"cpu NN" if this APIC is in xapic flat mode
"cluster NN mask BBBB" if this APIC is in xapic cluster mode
"cluster NN mask BBBBBBBBBBBBBBBB" if this APIC is in x2apic mode
- the empty space after "masked" is for "pending"
- please add support for TSC deadline mode too
Paolo
>
> Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Andreas Färber <andreas.faerber@web.de>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> ---
> hmp-commands-info.hx | 16 ++++
> include/monitor/monitor-common.h | 1 +
> target-i386/cpu.h | 3 +
> target-i386/helper.c | 155 +++++++++++++++++++++++++++++++++++++++
> target-i386/monitor.c | 6 ++
> 5 files changed, 181 insertions(+)
>
> diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
> index 9f5a158..5ffc181 100644
> --- a/hmp-commands-info.hx
> +++ b/hmp-commands-info.hx
> @@ -112,6 +112,22 @@ STEXI
> Show the cpu registers.
> ETEXI
>
> +#if defined(TARGET_I386)
> + {
> + .name = "apic-local",
> + .args_type = "",
> + .params = "",
> + .help = "show local apic state",
> + .mhandler.cmd = hmp_info_apic_local,
> + },
> +#endif
> +
> +STEXI
> +@item info apic-local
> +@findex apic-local
> +Show local APIC state
> +ETEXI
> +
> {
> .name = "cpus",
> .args_type = "",
> diff --git a/include/monitor/monitor-common.h b/include/monitor/monitor-common.h
> index abd7a6c..462c35e 100644
> --- a/include/monitor/monitor-common.h
> +++ b/include/monitor/monitor-common.h
> @@ -42,5 +42,6 @@ CPUState *mon_get_cpu(void);
> void hmp_info_mem(Monitor *mon, const QDict *qdict);
> void hmp_info_tlb(Monitor *mon, const QDict *qdict);
> void hmp_mce(Monitor *mon, const QDict *qdict);
> +void hmp_info_apic_local(Monitor *mon, const QDict *qdict);
>
> #endif /* MONITOR_COMMON */
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index af97772..f37a9c6 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -1347,4 +1347,7 @@ void enable_compat_apic_id_mode(void);
> #define APIC_DEFAULT_ADDRESS 0xfee00000
> #define APIC_SPACE_SIZE 0x100000
>
> +void x86_cpu_dump_apic_local_state(CPUState *cs, FILE *f,
> + fprintf_function cpu_fprintf, int flags);
> +
> #endif /* CPU_I386_H */
> 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
>
> diff --git a/target-i386/monitor.c b/target-i386/monitor.c
> index e775561..fbc9fcd 100644
> --- a/target-i386/monitor.c
> +++ b/target-i386/monitor.c
> @@ -492,3 +492,9 @@ const MonitorDef *target_monitor_defs(void)
> {
> return monitor_defs;
> }
> +
> +void hmp_info_apic_local(Monitor *mon, const QDict *qdict)
> +{
> + x86_cpu_dump_apic_local_state(mon_get_cpu(), (FILE *)mon, monitor_fprintf,
> + CPU_DUMP_FPU);
> +}
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 7/9] ioapic_internal.h: added more constants
2015-09-15 9:22 [Qemu-devel] [PATCH v2 0/9] hmp command IO- and Local APIC dump state Denis V. Lunev
` (5 preceding siblings ...)
2015-09-15 9:23 ` [Qemu-devel] [PATCH 6/9] hmp: added local apic dump state Denis V. Lunev
@ 2015-09-15 9:23 ` Denis V. Lunev
2015-09-15 9:23 ` [Qemu-devel] [PATCH 8/9] hmp: added io apic dump state Denis V. Lunev
2015-09-15 9:23 ` [Qemu-devel] [PATCH 9/9] hmp: implemented io apic dump state for TCG Denis V. Lunev
8 siblings, 0 replies; 14+ messages in thread
From: Denis V. Lunev @ 2015-09-15 9:23 UTC (permalink / raw)
Cc: Denis V. Lunev, Andreas Färber, 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: Andreas Färber <andreas.faerber@web.de>
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
--
2.1.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 8/9] hmp: added io apic dump state
2015-09-15 9:22 [Qemu-devel] [PATCH v2 0/9] hmp command IO- and Local APIC dump state Denis V. Lunev
` (6 preceding siblings ...)
2015-09-15 9:23 ` [Qemu-devel] [PATCH 7/9] ioapic_internal.h: added more constants Denis V. Lunev
@ 2015-09-15 9:23 ` Denis V. Lunev
2015-09-15 10:32 ` Paolo Bonzini
2015-09-15 9:23 ` [Qemu-devel] [PATCH 9/9] hmp: implemented io apic dump state for TCG Denis V. Lunev
8 siblings, 1 reply; 14+ messages in thread
From: Denis V. Lunev @ 2015-09-15 9:23 UTC (permalink / raw)
Cc: Denis V. Lunev, Andreas Färber, 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: Andreas Färber <andreas.faerber@web.de>
CC: Paolo Bonzini <pbonzini@redhat.com>
---
hmp-commands-info.hx | 16 ++++++++++++++++
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 ++++
include/monitor/monitor-common.h | 1 +
target-i386/monitor.c | 9 +++++++++
7 files changed, 73 insertions(+)
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 5ffc181..c65b7d2 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -128,6 +128,22 @@ STEXI
Show local APIC state
ETEXI
+#if defined(TARGET_I386)
+ {
+ .name = "apic-io",
+ .args_type = "",
+ .params = "",
+ .help = "show io apic state",
+ .mhandler.cmd = hmp_info_apic_io,
+ },
+#endif
+
+STEXI
+@item info apic-io
+@findex apic-io
+Show io APIC state
+ETEXI
+
{
.name = "cpus",
.args_type = "",
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 3e002c9..539cf64 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/include/monitor/monitor-common.h b/include/monitor/monitor-common.h
index 462c35e..71f224b 100644
--- a/include/monitor/monitor-common.h
+++ b/include/monitor/monitor-common.h
@@ -43,5 +43,6 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict);
void hmp_info_tlb(Monitor *mon, const QDict *qdict);
void hmp_mce(Monitor *mon, const QDict *qdict);
void hmp_info_apic_local(Monitor *mon, const QDict *qdict);
+void hmp_info_apic_io(Monitor *mon, const QDict *qdict);
#endif /* MONITOR_COMMON */
diff --git a/target-i386/monitor.c b/target-i386/monitor.c
index fbc9fcd..797ea2d 100644
--- a/target-i386/monitor.c
+++ b/target-i386/monitor.c
@@ -24,6 +24,8 @@
#include "cpu.h"
#include "monitor/monitor.h"
#include "monitor/monitor-common.h"
+#include "hw/i386/pc.h"
+#include "sysemu/kvm.h"
#include "hmp.h"
@@ -498,3 +500,10 @@ void hmp_info_apic_local(Monitor *mon, const QDict *qdict)
x86_cpu_dump_apic_local_state(mon_get_cpu(), (FILE *)mon, monitor_fprintf,
CPU_DUMP_FPU);
}
+
+void hmp_info_apic_io(Monitor *mon, const QDict *qdict)
+{
+ if (kvm_irqchip_in_kernel()) {
+ kvm_ioapic_dump_state(mon, qdict);
+ }
+}
--
2.1.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH 8/9] hmp: added io apic dump state
2015-09-15 9:23 ` [Qemu-devel] [PATCH 8/9] hmp: added io apic dump state Denis V. Lunev
@ 2015-09-15 10:32 ` Paolo Bonzini
0 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2015-09-15 10:32 UTC (permalink / raw)
To: Denis V. Lunev; +Cc: Andreas Färber, qemu-devel, Pavel Butsykin
On 15/09/2015 11:23, Denis V. Lunev wrote:
>
> 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
I would call the command "info ioapic" and would use a format like
ioapic id=0x00 sel=0x18 (redir[4])
pin 0 0x00000000000100ff dest=0 vec=255 activehi edge masked fixed physical
pin 1 0x0300000000000993 dest=3 vec=147 activehi edge lowest logical
...
pin 23 0x00000000000100ff dest=0 vec=255 activehi edge masked fixed physical
IRR (none)
(both suggestions for the format are inspired by the KVM trace events)
Paolo
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 9/9] hmp: implemented io apic dump state for TCG
2015-09-15 9:22 [Qemu-devel] [PATCH v2 0/9] hmp command IO- and Local APIC dump state Denis V. Lunev
` (7 preceding siblings ...)
2015-09-15 9:23 ` [Qemu-devel] [PATCH 8/9] hmp: added io apic dump state Denis V. Lunev
@ 2015-09-15 9:23 ` Denis V. Lunev
8 siblings, 0 replies; 14+ messages in thread
From: Denis V. Lunev @ 2015-09-15 9:23 UTC (permalink / raw)
Cc: Denis V. Lunev, Andreas Färber, 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: Andreas Färber <andreas.faerber@web.de>
CC: Paolo Bonzini <pbonzini@redhat.com>
---
hw/intc/ioapic.c | 12 ++++++++++++
include/hw/i386/pc.h | 1 +
target-i386/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 539cf64..7c9f3a5 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/target-i386/monitor.c b/target-i386/monitor.c
index 797ea2d..f0774a3 100644
--- a/target-i386/monitor.c
+++ b/target-i386/monitor.c
@@ -505,5 +505,7 @@ 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);
}
}
--
2.1.4
^ permalink raw reply related [flat|nested] 14+ messages in thread