~vcs-imports/qemu/svntrunk

« back to all changes in this revision

Viewing changes to gdbstub.c

  • Committer: aliguori
  • Date: 2009-03-12 20:12:48 UTC
  • Revision ID: vcs-imports@canonical.com-20090312201248-9r6i72ct1bd45xez
Guest debugging support for KVM (Jan Kiszka)

This is a backport of the guest debugging support for the KVM
accelerator that is now part of the KVM tree. It implements the reworked
KVM kernel API for guest debugging (KVM_CAP_SET_GUEST_DEBUG) which is
not yet part of any mainline kernel but will probably be 2.6.30 stuff.
So far supported is x86, but PPC is expected to catch up soon.

Core features are:
 - unlimited soft-breakpoints via code patching
 - hardware-assisted x86 breakpoints and watchpoints

Changes in this version:
 - use generic hook cpu_synchronize_state to transfer registers between
   user space and kvm
 - push kvm_sw_breakpoints into KVMState

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
#define MAX_PACKET_LENGTH 4096
40
40
 
41
41
#include "qemu_socket.h"
 
42
#include "kvm.h"
42
43
 
43
44
 
44
45
enum {
1418
1419
    }
1419
1420
}
1420
1421
 
1421
 
/* GDB breakpoint/watchpoint types */
1422
 
#define GDB_BREAKPOINT_SW        0
1423
 
#define GDB_BREAKPOINT_HW        1
1424
 
#define GDB_WATCHPOINT_WRITE     2
1425
 
#define GDB_WATCHPOINT_READ      3
1426
 
#define GDB_WATCHPOINT_ACCESS    4
1427
 
 
1428
1422
#ifndef CONFIG_USER_ONLY
1429
1423
static const int xlat_gdb_type[] = {
1430
1424
    [GDB_WATCHPOINT_WRITE]  = BP_GDB | BP_MEM_WRITE,
1438
1432
    CPUState *env;
1439
1433
    int err = 0;
1440
1434
 
 
1435
    if (kvm_enabled())
 
1436
        return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
 
1437
 
1441
1438
    switch (type) {
1442
1439
    case GDB_BREAKPOINT_SW:
1443
1440
    case GDB_BREAKPOINT_HW:
1469
1466
    CPUState *env;
1470
1467
    int err = 0;
1471
1468
 
 
1469
    if (kvm_enabled())
 
1470
        return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
 
1471
 
1472
1472
    switch (type) {
1473
1473
    case GDB_BREAKPOINT_SW:
1474
1474
    case GDB_BREAKPOINT_HW:
1498
1498
{
1499
1499
    CPUState *env;
1500
1500
 
 
1501
    if (kvm_enabled()) {
 
1502
        kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
 
1503
        return;
 
1504
    }
 
1505
 
1501
1506
    for (env = first_cpu; env != NULL; env = env->next_cpu) {
1502
1507
        cpu_breakpoint_remove_all(env, BP_GDB);
1503
1508
#ifndef CONFIG_USER_ONLY
1538
1543
            addr = strtoull(p, (char **)&p, 16);
1539
1544
#if defined(TARGET_I386)
1540
1545
            s->c_cpu->eip = addr;
 
1546
            cpu_synchronize_state(s->c_cpu, 1);
1541
1547
#elif defined (TARGET_PPC)
1542
1548
            s->c_cpu->nip = addr;
1543
1549
#elif defined (TARGET_SPARC)
1579
1585
            addr = strtoull(p, (char **)&p, 16);
1580
1586
#if defined(TARGET_I386)
1581
1587
            s->c_cpu->eip = addr;
 
1588
            cpu_synchronize_state(s->c_cpu, 1);
1582
1589
#elif defined (TARGET_PPC)
1583
1590
            s->c_cpu->nip = addr;
1584
1591
#elif defined (TARGET_SPARC)
1624
1631
        }
1625
1632
        break;
1626
1633
    case 'g':
 
1634
        cpu_synchronize_state(s->g_cpu, 0);
1627
1635
        len = 0;
1628
1636
        for (addr = 0; addr < num_g_regs; addr++) {
1629
1637
            reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
1641
1649
            len -= reg_size;
1642
1650
            registers += reg_size;
1643
1651
        }
 
1652
        cpu_synchronize_state(s->g_cpu, 1);
1644
1653
        put_packet(s, "OK");
1645
1654
        break;
1646
1655
    case 'm':
1799
1808
            thread = strtoull(p+16, (char **)&p, 16);
1800
1809
            for (env = first_cpu; env != NULL; env = env->next_cpu)
1801
1810
                if (env->cpu_index + 1 == thread) {
 
1811
                    cpu_synchronize_state(env, 0);
1802
1812
                    len = snprintf((char *)mem_buf, sizeof(mem_buf),
1803
1813
                                   "CPU#%d [%s]", env->cpu_index,
1804
1814
                                   env->halted ? "halted " : "running");