From patchwork Sat Jan 4 17:59:19 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 3434231 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4791E9F2E9 for ; Sat, 4 Jan 2014 17:59:50 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4DD662014A for ; Sat, 4 Jan 2014 17:59:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6CC422015E for ; Sat, 4 Jan 2014 17:59:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754858AbaADR7m (ORCPT ); Sat, 4 Jan 2014 12:59:42 -0500 Received: from mout.web.de ([212.227.15.14]:51301 "EHLO mout.web.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754780AbaADR7l (ORCPT ); Sat, 4 Jan 2014 12:59:41 -0500 Received: from mchn199C.home ([95.157.58.223]) by smtp.web.de (mrweb004) with ESMTPSA (Nemesis) id 0Lpyh5-1VWmvz1oil-00flJT for ; Sat, 04 Jan 2014 18:59:40 +0100 From: Jan Kiszka To: Gleb Natapov , Paolo Bonzini , Marcelo Tosatti Cc: kvm Subject: [PATCH 13/13] x86: Add debug facility test case Date: Sat, 4 Jan 2014 18:59:19 +0100 Message-Id: <9b5cf4498bf00c4be5338ffd3324fdd7b138b20f.1388858359.git.jan.kiszka@web.de> X-Mailer: git-send-email 1.8.1.1.298.ge7eed54 In-Reply-To: References: In-Reply-To: References: X-Provags-ID: V03:K0:+8OzIYhAIH8UPN1qtde8OeGB7EFoVtIbJVkDMllZjGcY9xGRGv+ IgNttaIi/yniQ/p0C4GIDgtqocOV5UPYRTZ9UZYmakcXGnvWCP8QjwRGubv3DVrcYNRnev7 BQ20kVdA4pBYIXz7B7XYRwpnGlrt2ptWb8Bwoh+d5JakYBZ6a6dv922cwJpi20Obaj8XjZX Aoo+9HJulqZyAbO1DXRQQ== Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-7.3 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Jan Kiszka This adds a basic test for INT3/#BP, hardware breakpoints, hardware watchpoints and single-stepping. Signed-off-by: Jan Kiszka --- config-x86-common.mak | 2 + config-x86_64.mak | 2 +- lib/x86/desc.h | 2 + x86/debug.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++ x86/unittests.cfg | 3 ++ 5 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 x86/debug.c diff --git a/config-x86-common.mak b/config-x86-common.mak index 32da7fb..aa5a439 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -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 diff --git a/config-x86_64.mak b/config-x86_64.mak index bb8ee89..a9a2a9e 100644 --- a/config-x86_64.mak +++ b/config-x86_64.mak @@ -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 diff --git a/lib/x86/desc.h b/lib/x86/desc.h index 5c850b2..b795aad 100644 --- a/lib/x86/desc.h +++ b/lib/x86/desc.h @@ -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 diff --git a/x86/debug.c b/x86/debug.c new file mode 100644 index 0000000..154c7fe --- /dev/null +++ b/x86/debug.c @@ -0,0 +1,113 @@ +/* + * Test for x86 debugging facilities + * + * Copyright (c) Siemens AG, 2014 + * + * Authors: + * Jan Kiszka + * + * 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; +} diff --git a/x86/unittests.cfg b/x86/unittests.cfg index 85c36aa..7930c02 100644 --- a/x86/unittests.cfg +++ b/x86/unittests.cfg @@ -155,3 +155,6 @@ file = vmx.flat extra_params = -cpu host,+vmx arch = x86_64 +[debug] +file = debug.flag +arch = x86_64