Commit 478027f5 authored by Jan Kiszka's avatar Jan Kiszka Committed by Paolo Bonzini
Browse files

x86: Add debug facility test case



This adds a basic test for INT3/#BP, hardware breakpoints, hardware
watchpoints and single-stepping.
Signed-off-by: default avatarJan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 3bd8e001
......@@ -103,6 +103,8 @@ $(TEST_DIR)/pcid.elf: $(cstart.o) $(TEST_DIR)/pcid.o
$(TEST_DIR)/vmx.elf: $(cstart.o) $(TEST_DIR)/vmx.o $(TEST_DIR)/vmx_tests.o
$(TEST_DIR)/debug.elf: $(cstart.o) $(TEST_DIR)/debug.o
arch_clean:
$(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \
$(TEST_DIR)/.*.d $(TEST_DIR)/lib/.*.d $(TEST_DIR)/lib/*.o
......
......@@ -7,7 +7,7 @@ CFLAGS += -D__x86_64__
tests = $(TEST_DIR)/access.flat $(TEST_DIR)/apic.flat \
$(TEST_DIR)/emulator.flat $(TEST_DIR)/idt_test.flat \
$(TEST_DIR)/xsave.flat $(TEST_DIR)/rmap_chain.flat \
$(TEST_DIR)/pcid.flat
$(TEST_DIR)/pcid.flat $(TEST_DIR)/debug.flat
tests += $(TEST_DIR)/svm.flat
tests += $(TEST_DIR)/vmx.flat
......
......@@ -66,6 +66,8 @@ typedef struct {
".popsection \n\t" \
"1111:"
#define DB_VECTOR 1
#define BP_VECTOR 3
#define UD_VECTOR 6
#define GP_VECTOR 13
......
/*
* Test for x86 debugging facilities
*
* Copyright (c) Siemens AG, 2014
*
* Authors:
* Jan Kiszka <jan.kiszka@siemens.com>
*
* This work is licensed under the terms of the GNU GPL, version 2.
*/
#include "libcflat.h"
#include "desc.h"
static volatile unsigned long bp_addr[10], dr6[10];
static volatile unsigned int n;
static volatile unsigned long value;
static unsigned long get_dr6(void)
{
unsigned long value;
asm volatile("mov %%dr6,%0" : "=r" (value));
return value;
}
static void set_dr0(void *value)
{
asm volatile("mov %0,%%dr0" : : "r" (value));
}
static void set_dr1(void *value)
{
asm volatile("mov %0,%%dr1" : : "r" (value));
}
static void set_dr7(unsigned long value)
{
asm volatile("mov %0,%%dr7" : : "r" (value));
}
static void handle_db(struct ex_regs *regs)
{
bp_addr[n] = regs->rip;
dr6[n] = get_dr6();
if (dr6[n] & 0x1)
regs->rflags |= (1 << 16);
if (++n >= 10) {
regs->rflags &= ~(1 << 8);
set_dr7(0x00000400);
}
}
static void handle_bp(struct ex_regs *regs)
{
bp_addr[0] = regs->rip;
}
int main(int ac, char **av)
{
unsigned long start;
setup_idt();
handle_exception(DB_VECTOR, handle_db);
handle_exception(BP_VECTOR, handle_bp);
sw_bp:
asm volatile("int3");
report("#BP", bp_addr[0] == (unsigned long)&&sw_bp + 1);
set_dr0(&&hw_bp);
set_dr7(0x00000402);
hw_bp:
asm volatile("nop");
report("hw breakpoint",
n == 1 &&
bp_addr[0] == ((unsigned long)&&hw_bp) && dr6[0] == 0xffff0ff1);
n = 0;
asm volatile(
"pushf\n\t"
"pop %%rax\n\t"
"or $(1<<8),%%rax\n\t"
"push %%rax\n\t"
"lea (%%rip),%0\n\t"
"popf\n\t"
"and $~(1<<8),%%rax\n\t"
"push %%rax\n\t"
"popf\n\t"
: "=g" (start) : : "rax");
report("single step",
n == 3 &&
bp_addr[0] == start+1+6 && dr6[0] == 0xffff4ff0 &&
bp_addr[1] == start+1+6+1 && dr6[1] == 0xffff4ff0 &&
bp_addr[2] == start+1+6+1+1 && dr6[2] == 0xffff4ff0);
n = 0;
set_dr1((void *)&value);
set_dr7(0x00d0040a);
asm volatile(
"mov $42,%%rax\n\t"
"mov %%rax,%0\n\t"
: "=m" (value) : : "rax");
hw_wp:
report("hw watchpoint",
n == 1 &&
bp_addr[0] == ((unsigned long)&&hw_wp) && dr6[0] == 0xffff4ff2);
return 0;
}
......@@ -155,3 +155,6 @@ file = vmx.flat
extra_params = -cpu host,+vmx
arch = x86_64
[debug]
file = debug.flag
arch = x86_64
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment