hmp: added io apic dump state

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 ioapic
ioapic id=0x00 sel=0x26 (redir[11])
pin 0  0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
pin 1  0x0000000000000031 dest=0 vec=49  active-hi edge         fixed  physical
...
pin 23 0x0000000000010000 dest=0 vec=0   active-hi edge  masked fixed  physical
IRR        (none)
Remote IRR (none)

Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Andreas Färber <afaerber@suse.de>
Message-Id: <1442927901-1084-9-git-send-email-den@openvz.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
master
Pavel Butsykin 2015-09-22 16:18:20 +03:00 committed by Paolo Bonzini
parent af59940735
commit d665d696c5
7 changed files with 97 additions and 0 deletions

View File

@ -126,6 +126,22 @@ STEXI
@item info lapic
@findex lapic
Show local APIC state
ETEXI
#if defined(TARGET_I386)
{
.name = "ioapic",
.args_type = "",
.params = "",
.help = "show io apic state",
.mhandler.cmd = hmp_info_io_apic,
},
#endif
STEXI
@item info ioapic
@findex ioapic
Show io APIC state
ETEXI
{

View File

@ -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);

View File

@ -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,60 @@
*/
int ioapic_no;
static void ioapic_irr_dump(Monitor *mon, const char *name, uint32_t bitmap)
{
int i;
monitor_printf(mon, "%-10s ", name);
if (bitmap == 0) {
monitor_printf(mon, "(none)\n");
return;
}
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
if (bitmap & (1 << i)) {
monitor_printf(mon, "%-2u ", i);
}
}
monitor_printf(mon, "\n");
}
void ioapic_print_redtbl(Monitor *mon, IOAPICCommonState *s)
{
static const char *delm_str[] = {
"fixed", "lowest", "SMI", "...", "NMI", "INIT", "...", "extINT"};
uint32_t remote_irr = 0;
int i;
monitor_printf(mon, "ioapic id=0x%02x sel=0x%02x", s->id, s->ioregsel);
if (s->ioregsel) {
monitor_printf(mon, " (redir[%u])\n",
(s->ioregsel - IOAPIC_REG_REDTBL_BASE) >> 1);
} else {
monitor_printf(mon, "\n");
}
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, "pin %-2u 0x%016"PRIx64" dest=%"PRIx64
" vec=%-3"PRIu64" %s %-5s %-6s %-6s %s\n",
i, entry,
(entry >> IOAPIC_LVT_DEST_SHIFT) &
(entry & IOAPIC_LVT_DEST_MODE ? 0xff : 0xf),
entry & IOAPIC_VECTOR_MASK,
entry & IOAPIC_LVT_POLARITY ? "active-lo" : "active-hi",
entry & IOAPIC_LVT_TRIGGER_MODE ? "level" : "edge",
entry & IOAPIC_LVT_MASKED ? "masked" : "",
delm_str[delm],
entry & IOAPIC_LVT_DEST_MODE ? "logical" : "physical");
remote_irr |= entry & IOAPIC_LVT_TRIGGER_MODE ?
(entry & IOAPIC_LVT_REMOTE_IRR ? (1 << i) : 0) : 0;
}
ioapic_irr_dump(mon, "IRR", s->irr);
ioapic_irr_dump(mon, "Remote IRR", remote_irr);
}
void ioapic_reset_common(DeviceState *dev)
{
IOAPICCommonState *s = IOAPIC_COMMON(dev);

View File

@ -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 */

View File

@ -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

View File

@ -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_local_apic(Monitor *mon, const QDict *qdict);
void hmp_info_io_apic(Monitor *mon, const QDict *qdict);
#endif /* MONITOR_COMMON */

View File

@ -24,6 +24,8 @@
#include "cpu.h"
#include "monitor/monitor.h"
#include "monitor/hmp-target.h"
#include "hw/i386/pc.h"
#include "sysemu/kvm.h"
#include "hmp.h"
@ -498,3 +500,10 @@ void hmp_info_local_apic(Monitor *mon, const QDict *qdict)
x86_cpu_dump_local_apic_state(mon_get_cpu(), (FILE *)mon, monitor_fprintf,
CPU_DUMP_FPU);
}
void hmp_info_io_apic(Monitor *mon, const QDict *qdict)
{
if (kvm_irqchip_in_kernel()) {
kvm_ioapic_dump_state(mon, qdict);
}
}