From patchwork Thu Jan 20 00:29:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12718016 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E8E0BC433EF for ; Thu, 20 Jan 2022 00:29:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357786AbiATA33 (ORCPT ); Wed, 19 Jan 2022 19:29:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40492 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344860AbiATA32 (ORCPT ); Wed, 19 Jan 2022 19:29:28 -0500 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 80531C061574 for ; Wed, 19 Jan 2022 16:29:28 -0800 (PST) Received: by mail-pg1-x549.google.com with SMTP id g12-20020a63200c000000b00342cd03227aso2602636pgg.19 for ; Wed, 19 Jan 2022 16:29:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=xEzpTHEoEq/G2HUv56/F7AxziHIAxPWYaVOa6/Yl4Pg=; b=c/GzDa7EgQaKRcAx4Q+UWyj+uNfyioFgcnD9+SvMeG1WteNlyUyctG0TAJOJ6eCc3B qYIbdpXkndSr419hBEYNqopv7psZy/rGb7MmGKFNZDNq1FSZf0pyVF3P/ezcwpbYFBAN RRzgNvVIEePVQZtbqmH78BeRQbRk+vCqw2/EQO2fAF0bTudYtvR1FY3EHvpjWtACdpaJ 9PKJcEO+pQd/SLvD5dr00Jfdcm77FIh6loT7IbzLdIoQQ2nb2AiCnmiOV/u8VIWmj5T6 MxWsWw6/jFWSEBrSbnj03Sbf01onBmp7C8Nat02yHjYL0mcQ823HXC9ZsichM4hskKCH hdtA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=xEzpTHEoEq/G2HUv56/F7AxziHIAxPWYaVOa6/Yl4Pg=; b=cxs9+SITx0yw0H/UjM4Y+AM0wHzg1+JIaDlGHR1xDXMwImOjE8hgguMIaIS/iYX8Y7 FCw8IMoFgLork0w/ZhYAMKVd5imuEu3zmBGZos1R9qCgvduLhsEGPy15snek1gwExIlY fIIZybJBkiwcHuxAT9pkq4ILHnai7OLDjXcNU2b1gzAP3EDi4VkX7fSP801x7qmeMA6U DnrDkJFwCnjGcr4wee4AlwYSrKSork0VZ/TR3034vcWveGHXKKvfGpmjRo4iz8dR67Um 1/h8HvlSwk4+HuiqaKPGS/opvR/GX/IsJD2eKS1DylZw1sfXVR9Q/M/jf0C1x+A/DCPd MBiQ== X-Gm-Message-State: AOAM533KTL0eq8mkJxi1e8ochtYq+5AGuZlmgD4R3JaPA0X0OZ8U5C4a lg2fk/mMiZTc0z6wwNIWfzyJb5cQs2k= X-Google-Smtp-Source: ABdhPJwNEOUEw+J76vOyLCIWpykmV+Ct02d1jMC9kUqwl+CnVwyLCiS8T4o+LEqzhyJgTtd/bsRM4H30j4A= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:90a:56:: with SMTP id 22mr7381810pjb.199.1642638568059; Wed, 19 Jan 2022 16:29:28 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 20 Jan 2022 00:29:17 +0000 In-Reply-To: <20220120002923.668708-1-seanjc@google.com> Message-Id: <20220120002923.668708-2-seanjc@google.com> Mime-Version: 1.0 References: <20220120002923.668708-1-seanjc@google.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog Subject: [kvm-unit-tests PATCH 1/7] bitops: Include stdbool.h and stddef.h as necessary From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Sean Christopherson , David Woodhouse , Alexander Graf Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Include stdbool.h and stddef.h in bitops.h to pick up the definitions for "bool" and "size_t" respectively. Signed-off-by: Sean Christopherson --- lib/bitops.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/bitops.h b/lib/bitops.h index 308aa865..81a06a47 100644 --- a/lib/bitops.h +++ b/lib/bitops.h @@ -1,6 +1,9 @@ #ifndef _BITOPS_H_ #define _BITOPS_H_ +#include +#include + /* * Adapted from * include/linux/bitops.h From patchwork Thu Jan 20 00:29:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12718017 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2B9D8C4332F for ; Thu, 20 Jan 2022 00:29:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357793AbiATA3a (ORCPT ); Wed, 19 Jan 2022 19:29:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40500 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344860AbiATA3a (ORCPT ); Wed, 19 Jan 2022 19:29:30 -0500 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 100C4C061574 for ; Wed, 19 Jan 2022 16:29:30 -0800 (PST) Received: by mail-pg1-x549.google.com with SMTP id j28-20020a637a5c000000b00344d66c3c56so2591853pgn.21 for ; Wed, 19 Jan 2022 16:29:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=El/quCzeSGh8/qkvaNqWRy0AcE59nBWFTdtwXpWBjlM=; b=DWrzh3SxDrY9l8WLLJbwjkeY6YC//x2KSl9uVfZ7NukjFknVNxi0dtzc7kSIWcBHXP K2Y9aKDsxrgXQV7LFRsAcpRUDT2JK9gX+KhUPr9KocrHOrvn+1OvHatb2vE5AMFaocf0 81I9eB+SkE8P1nZYR1/Cl9XaQBnYqKcZBfL3UudhmxKlYqC7ZwG+/ZvqvXBQIICpvylU lCXpvU4v2N17cb5aXGH82F9REPcY2jupC6P295bYuVNIitRf3ClaMQ/x8A461NF/LQ/8 HaYhanhTIDQvR/2S1I0olEbmG1ZRrcO+tsd9p1H+SzY93NSYagmQARU26v7EgsjXC2xr 4uqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=El/quCzeSGh8/qkvaNqWRy0AcE59nBWFTdtwXpWBjlM=; b=OzpLTRZkijbC+EL7ZQL50ASo8tZonmoU9GUQP+y013aq9QibI3FT/QyjQ3Gpo3Uj/u tCIw80IBt7uR6PcTCb1Aw/sv0crViQNsSBRvMucYfBOeErhWK1Q5CN5VhAfgKm9760KD UuFRKDyj8VgaOvqGmDGKt//X9vBEi9rVkPFGrDpQY09vk4+bDAA8RbPTbZyThpq0Eh8o qp58aiHTFBnTO9UMU9bnBA2+HDVs7pzg3pUcqViI3Zui9bsVg5Oxyd0mg8jxQ+gMBVWK HCzgvjiWIi8g1DofbeO7sY/YZtACrjscrvRUzfhga3cgckYr5cp/bQdw5JhH9Jw2+qGb 8SRQ== X-Gm-Message-State: AOAM532IdKejxMPMdsprpK8mAADYqI3OsRgC/pYxPS/Pd5az1UGU9zq0 zZSM0MDiZ754mSJ12KLaudOjF4TdOCQ= X-Google-Smtp-Source: ABdhPJygqksaCOFoJRLLUPJZv/SFUZmYqKL9KNUZUqRc/i+IClXC29qdpEaWLfGFS3sunOHov0FJEiWVlio= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:902:9305:b0:14a:db23:eb5d with SMTP id bc5-20020a170902930500b0014adb23eb5dmr10438886plb.73.1642638569583; Wed, 19 Jan 2022 16:29:29 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 20 Jan 2022 00:29:18 +0000 In-Reply-To: <20220120002923.668708-1-seanjc@google.com> Message-Id: <20220120002923.668708-3-seanjc@google.com> Mime-Version: 1.0 References: <20220120002923.668708-1-seanjc@google.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog Subject: [kvm-unit-tests PATCH 2/7] x86/debug: Add framework for single-step #DB tests From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Sean Christopherson , David Woodhouse , Alexander Graf Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add a framework to the "debug" test for running single-step #DB tests, future commits will extend the single-step tests to run in usermode and to verify interaction with STI and MOVSS blocking. Opportunistically add comments and stop open coding RFLAGS stuff. No functional change intended. Signed-off-by: Sean Christopherson --- x86/debug.c | 168 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 115 insertions(+), 53 deletions(-) diff --git a/x86/debug.c b/x86/debug.c index 0019ebd5..98bdfe36 100644 --- a/x86/debug.c +++ b/x86/debug.c @@ -36,14 +36,24 @@ static void handle_db(struct ex_regs *regs) dr6[n] = read_dr6(); if (dr6[n] & 0x1) - regs->rflags |= (1 << 16); + regs->rflags |= X86_EFLAGS_RF; if (++n >= 10) { - regs->rflags &= ~(1 << 8); + regs->rflags &= ~X86_EFLAGS_TF; write_dr7(0x00000400); } } +static inline bool is_single_step_db(unsigned long dr6_val) +{ + return dr6_val == 0xffff4ff0; +} + +static inline bool is_icebp_db(unsigned long dr6_val) +{ + return dr6_val == 0xffff0ff0; +} + extern unsigned char handle_db_save_rip; asm("handle_db_save_rip:\n" "stc\n" @@ -64,15 +74,106 @@ static void handle_ud(struct ex_regs *regs) got_ud = 1; } +typedef unsigned long (*db_test_fn)(void); +typedef void (*db_report_fn)(unsigned long); + +static void __run_single_step_db_test(db_test_fn test, db_report_fn report_fn) +{ + unsigned long start; + + n = 0; + write_dr6(0); + + start = test(); + report_fn(start); +} + +#define run_ss_db_test(name) __run_single_step_db_test(name, report_##name) + +static void report_singlestep_basic(unsigned long start) +{ + report(n == 3 && + is_single_step_db(dr6[0]) && db_addr[0] == start && + is_single_step_db(dr6[1]) && db_addr[1] == start + 1 && + is_single_step_db(dr6[2]) && db_addr[2] == start + 1 + 1, + "Single-step #DB basic test"); +} + +static unsigned long singlestep_basic(void) +{ + unsigned long start; + + /* + * After being enabled, single-step breakpoints have a one instruction + * delay before the first #DB is generated. + */ + asm volatile ( + "pushf\n\t" + "pop %%rax\n\t" + "or $(1<<8),%%rax\n\t" + "push %%rax\n\t" + "popf\n\t" + "and $~(1<<8),%%rax\n\t" + "1:push %%rax\n\t" + "popf\n\t" + "lea 1b, %0\n\t" + : "=r" (start) : : "rax" + ); + return start; +} + +static void report_singlestep_emulated_instructions(unsigned long start) +{ + report(n == 7 && + is_single_step_db(dr6[0]) && db_addr[0] == start && + is_single_step_db(dr6[1]) && db_addr[1] == start + 1 && + is_single_step_db(dr6[2]) && db_addr[2] == start + 1 + 3 && + is_single_step_db(dr6[3]) && db_addr[3] == start + 1 + 3 + 2 && + is_single_step_db(dr6[4]) && db_addr[4] == start + 1 + 3 + 2 + 5 && + is_single_step_db(dr6[5]) && db_addr[5] == start + 1 + 3 + 2 + 5 + 2 && + is_single_step_db(dr6[6]) && db_addr[6] == start + 1 + 3 + 2 + 5 + 2 + 1, + "Single-step #DB on emulated instructions"); +} + +static unsigned long singlestep_emulated_instructions(void) +{ + unsigned long start; + + /* + * Verify single-step #DB are generated correctly on emulated + * instructions, e.g. CPUID and RDMSR. + */ + asm volatile ( + "pushf\n\t" + "pop %%rax\n\t" + "or $(1<<8),%%rax\n\t" + "push %%rax\n\t" + "popf\n\t" + "and $~(1<<8),%%rax\n\t" + "1:push %%rax\n\t" + "xor %%rax,%%rax\n\t" + "cpuid\n\t" + "movl $0x1a0,%%ecx\n\t" + "rdmsr\n\t" + "popf\n\t" + "lea 1b,%0\n\t" + : "=r" (start) : : "rax", "ebx", "ecx", "edx" + ); + return start; +} + int main(int ac, char **av) { - unsigned long start; unsigned long cr4; handle_exception(DB_VECTOR, handle_db); handle_exception(BP_VECTOR, handle_bp); handle_exception(UD_VECTOR, handle_ud); + /* + * DR4 is an alias for DR6 (and DR5 aliases DR7) if CR4.DE is NOT set, + * and is reserved if CR4.DE=1 (Debug Extensions enabled). + */ got_ud = 0; cr4 = read_cr4(); write_cr4(cr4 & ~X86_CR4_DE); @@ -83,13 +184,21 @@ int main(int ac, char **av) cr4 = read_cr4(); write_cr4(cr4 | X86_CR4_DE); read_dr4(); - report(got_ud, "reading DR4 with CR4.DE == 1"); + report(got_ud, "DR4 read got #UD with CR4.DE == 1"); write_dr6(0); extern unsigned char sw_bp; asm volatile("int3; sw_bp:"); report(bp_addr == (unsigned long)&sw_bp, "#BP"); + /* + * The CPU sets/clears bits 0-3 (trap bits for DR0-3) on #DB based on + * whether or not the corresponding DR0-3 got a match. All other bits + * in DR6 are set if and only if their associated breakpoint condition + * is active, and are never cleared by the CPU. Verify a match on DR0 + * is reported correctly, and that DR6.BS is not set when single-step + * breakpoints are disabled, but is left set (if set by software). + */ n = 0; extern unsigned char hw_bp1; write_dr0(&hw_bp1); @@ -108,55 +217,8 @@ int main(int ac, char **av) db_addr[0] == ((unsigned long)&hw_bp2) && dr6[0] == 0xffff4ff1, "hw breakpoint (test that dr6.BS is not cleared)"); - n = 0; - write_dr6(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" - : "=r" (start) : : "rax"); - report(n == 3 && - db_addr[0] == start + 1 + 6 && dr6[0] == 0xffff4ff0 && - db_addr[1] == start + 1 + 6 + 1 && dr6[1] == 0xffff4ff0 && - db_addr[2] == start + 1 + 6 + 1 + 1 && dr6[2] == 0xffff4ff0, - "single step"); - - /* - * cpuid and rdmsr (among others) trigger VM exits and are then - * emulated. Test that single stepping works on emulated instructions. - */ - n = 0; - write_dr6(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" - "xor %%rax,%%rax\n\t" - "cpuid\n\t" - "movl $0x1a0,%%ecx\n\t" - "rdmsr\n\t" - "popf\n\t" - : "=r" (start) : : "rax", "ebx", "ecx", "edx"); - report(n == 7 && - db_addr[0] == start + 1 + 6 && dr6[0] == 0xffff4ff0 && - db_addr[1] == start + 1 + 6 + 1 && dr6[1] == 0xffff4ff0 && - db_addr[2] == start + 1 + 6 + 1 + 3 && dr6[2] == 0xffff4ff0 && - db_addr[3] == start + 1 + 6 + 1 + 3 + 2 && dr6[3] == 0xffff4ff0 && - db_addr[4] == start + 1 + 6 + 1 + 3 + 2 + 5 && dr6[4] == 0xffff4ff0 && - db_addr[5] == start + 1 + 6 + 1 + 3 + 2 + 5 + 2 && dr6[5] == 0xffff4ff0 && - db_addr[6] == start + 1 + 6 + 1 + 3 + 2 + 5 + 2 + 1 && dr6[6] == 0xffff4ff0, - "single step emulated instructions"); + run_ss_db_test(singlestep_basic); + run_ss_db_test(singlestep_emulated_instructions); n = 0; write_dr1((void *)&value); From patchwork Thu Jan 20 00:29:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12718018 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0488CC433F5 for ; Thu, 20 Jan 2022 00:29:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357795AbiATA3c (ORCPT ); Wed, 19 Jan 2022 19:29:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40508 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344860AbiATA3b (ORCPT ); Wed, 19 Jan 2022 19:29:31 -0500 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 80C43C061574 for ; Wed, 19 Jan 2022 16:29:31 -0800 (PST) Received: by mail-pj1-x104a.google.com with SMTP id c9-20020a17090a8d0900b001b492630839so4973930pjo.0 for ; Wed, 19 Jan 2022 16:29:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=X+D0F7r/0QGpU6311kvR8lHu9GmD3JTKgcWk10yuZeM=; b=RAFnOsHKAzm9aKmrMn+U3SUwIPoONsaRifssMzvttOJ/JevKGsth63tcBYZqfnBlNn +hMGyFXea0w57CETicPLMtiEdK7r5k3axPMxmELppa2Kwv1XErXpfOpzQIhd6FLa7GKV Nj1ITWjeHaaDqFLu0jKH+F+2J0kfnZwvzjd01CQOxm4GYt3ztkWAIR7Fji79rlBR8Tb6 PrkrDMKhCkUtBO/JvLMhzG0zC4pI11fyrm9BK/cipiN5G+tFi/hPDWb0CbRnWJo2j6eG TCC5dWANC7ef20tcbWSbZXQuewqzrQDJW0OGmKLzu8LuKvRmBkipG8O7iwAkpmA0aHYR lLIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=X+D0F7r/0QGpU6311kvR8lHu9GmD3JTKgcWk10yuZeM=; b=APNOn5bCwrzpOtprBYGsr79PPC99lKr8EWXVQMsJZND+qpVG9XqZ7anSVH2+ZuOGpl spvhx4iv1rYocO6ZOOnMWrWs5SbtRot8rF39CMEcG6DSZNZ4ftx5FOLvyWexoFzo1hEA wJHg4qMrsaAAu3i9rOYOrEXWjYLopu+iK8pRsgHqdl+VplGuVa2ruXfxbCed4QKL5ogD Lw7w+mWXUAiQhCc1L3uxbd81hSFk7dO9uDGxtNAaQrM5EJxTFBD9jwFDbnuxQTL1SVjF TgiHGJQJ1MnmwjkpPcFDFn89wJKgDhxedQynA+ov0G1u0bc2lUJCPIVTodNS9Fxopic0 gQAw== X-Gm-Message-State: AOAM5323pP7Uzjwe+74mMoH7A2gpL49kpg5L1GIe13qOSlgGn+CXdT8l XyytRolO0cmLptdQFFHN5cj151W+3H8= X-Google-Smtp-Source: ABdhPJyyl67B2nDuokLD5zXqVA7+UsGMReDAhMd+kXY13REQhq5i7cgs7vd5OdqvV3JyudXHNRXgssTQcp8= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a05:6a00:2306:b0:4c2:83c6:8b8d with SMTP id h6-20020a056a00230600b004c283c68b8dmr27327363pfh.65.1642638570913; Wed, 19 Jan 2022 16:29:30 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 20 Jan 2022 00:29:19 +0000 In-Reply-To: <20220120002923.668708-1-seanjc@google.com> Message-Id: <20220120002923.668708-4-seanjc@google.com> Mime-Version: 1.0 References: <20220120002923.668708-1-seanjc@google.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog Subject: [kvm-unit-tests PATCH 3/7] x86/debug: Test OUT instead of RDMSR for single-step #DB emulation test From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Sean Christopherson , David Woodhouse , Alexander Graf Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Replace RDMSR with OUT so that testing single-step #DBs on emulated instructions can be run in userspace (by modifying IOPL). OUT is also more interesting in that it is guaranteed to exit to host userspace, whereas RDMSR will do so if and only if userspace is filtering the target MSR. Signed-off-by: Sean Christopherson --- x86/debug.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/x86/debug.c b/x86/debug.c index 98bdfe36..4b2fbe97 100644 --- a/x86/debug.c +++ b/x86/debug.c @@ -124,14 +124,13 @@ static unsigned long singlestep_basic(void) static void report_singlestep_emulated_instructions(unsigned long start) { - report(n == 7 && + report(n == 6 && is_single_step_db(dr6[0]) && db_addr[0] == start && is_single_step_db(dr6[1]) && db_addr[1] == start + 1 && is_single_step_db(dr6[2]) && db_addr[2] == start + 1 + 3 && is_single_step_db(dr6[3]) && db_addr[3] == start + 1 + 3 + 2 && - is_single_step_db(dr6[4]) && db_addr[4] == start + 1 + 3 + 2 + 5 && - is_single_step_db(dr6[5]) && db_addr[5] == start + 1 + 3 + 2 + 5 + 2 && - is_single_step_db(dr6[6]) && db_addr[6] == start + 1 + 3 + 2 + 5 + 2 + 1, + is_single_step_db(dr6[4]) && db_addr[4] == start + 1 + 3 + 2 + 2 && + is_single_step_db(dr6[5]) && db_addr[5] == start + 1 + 3 + 2 + 2 + 1, "Single-step #DB on emulated instructions"); } @@ -153,8 +152,7 @@ static unsigned long singlestep_emulated_instructions(void) "1:push %%rax\n\t" "xor %%rax,%%rax\n\t" "cpuid\n\t" - "movl $0x1a0,%%ecx\n\t" - "rdmsr\n\t" + "out %%eax, $0x80\n\t" "popf\n\t" "lea 1b,%0\n\t" : "=r" (start) : : "rax", "ebx", "ecx", "edx" From patchwork Thu Jan 20 00:29:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12718019 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DF4DFC433FE for ; Thu, 20 Jan 2022 00:29:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357791AbiATA3n (ORCPT ); Wed, 19 Jan 2022 19:29:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40516 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357801AbiATA3d (ORCPT ); Wed, 19 Jan 2022 19:29:33 -0500 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 329A8C06161C for ; Wed, 19 Jan 2022 16:29:33 -0800 (PST) Received: by mail-pl1-x649.google.com with SMTP id p16-20020a170902a41000b0014992c5d56bso708065plq.19 for ; Wed, 19 Jan 2022 16:29:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=+D1IJPVTiPM5IAy2LlX0u6UtzX6XcjhBEHovl1KfP10=; b=g7B4ksjsMSGG3i+0Q7HMyVFCPik2oreH1J44wEVtbfUDQ3BWZFsLslPKSBkgfTB04A MSo+JnyN0jIdVjdHspMSgFbA4QWfDoq5YtDlP4Ns+S/mkNUY9zAGahwdfoWd2lciPmLw k9qLkJe859b55Lt1D74Kk86TFTowLZqrPxyxY2Za50mYG5f3VBEzTQuglTvu2h8cFKhd +ktsLVSWIzI+uB1lZPghDl6aVuQkOtynoZWcS8W9hDucXR9lLFZOIEkPpCxbG+WMcVby xn7Lndv0Mm07YXniyogtc2GE8xwVnwxNG/ry63MCu9LVqbHo+H2EH+NI+z/OAaWi6k3O G2mw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=+D1IJPVTiPM5IAy2LlX0u6UtzX6XcjhBEHovl1KfP10=; b=etJIDg8ywsXORIOrz+/7rCHd3msjFVYUBJcH6Rs0J0uyCU+TBDUT1CaWkBvHSoSXpO AauzZGvsbeP0nyCt5W2hYiASQ/5siKiIDG9r50a1B7hhN3TJ47/ZDw0osX/fBdvafR48 AuanFdgpeWtxdwik31aNTvZ3YWp+F5aKyJ0o+s1JNFBcPkdMm/u0zHZa31cONAN+H2ir jWEAenEHYiiKzLarSc6Nz5sGb5F+mfFv8lm6/EcPxEEWBVRfyrFdxIbcelzbV87EVtYN zLoMNN+MkuYAfqCzrcXOtA7EJ32m6J0j4SOqVqAqqdlXfIOig6hUbasBcdAzT1pdFuAv iCpw== X-Gm-Message-State: AOAM530bwZd1SuwlqsewF56CTzXqDaHRVACNJfyho4CauWAtWdVHW8dW p3OKJPrdG1u4hwroCqzJ1mjOcDV4CZE= X-Google-Smtp-Source: ABdhPJyNVr+4oDufMYBZNM9dl722s9zy1neW6szp7ki1BNcICRG/so3XiPdovcsCliUpJSmhRIp5mWqIXgo= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:90a:588f:: with SMTP id j15mr7373394pji.242.1642638572670; Wed, 19 Jan 2022 16:29:32 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 20 Jan 2022 00:29:20 +0000 In-Reply-To: <20220120002923.668708-1-seanjc@google.com> Message-Id: <20220120002923.668708-5-seanjc@google.com> Mime-Version: 1.0 References: <20220120002923.668708-1-seanjc@google.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog Subject: [kvm-unit-tests PATCH 4/7] x86/debug: Run single-step #DB tests in usermode (and kernel mode) From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Sean Christopherson , David Woodhouse , Alexander Graf Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Run the single-step #DB tests in usermode in addition to running them in kernel mode, i.e. run at CPL0 and CPL3. Signed-off-by: Sean Christopherson --- x86/debug.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/x86/debug.c b/x86/debug.c index 4b2fbe97..21f1da0b 100644 --- a/x86/debug.c +++ b/x86/debug.c @@ -12,6 +12,7 @@ #include "libcflat.h" #include "processor.h" #include "desc.h" +#include "usermode.h" static volatile unsigned long bp_addr; static volatile unsigned long db_addr[10], dr6[10]; @@ -75,28 +76,43 @@ static void handle_ud(struct ex_regs *regs) } typedef unsigned long (*db_test_fn)(void); -typedef void (*db_report_fn)(unsigned long); +typedef void (*db_report_fn)(unsigned long, const char *); static void __run_single_step_db_test(db_test_fn test, db_report_fn report_fn) { unsigned long start; + bool ign; n = 0; write_dr6(0); start = test(); - report_fn(start); + report_fn(start, ""); + + n = 0; + write_dr6(0); + /* + * Run the test in usermode. Use the expected start RIP from the first + * run, the usermode framework doesn't make it easy to get the expected + * RIP out of the test, and it shouldn't change in any case. Run the + * test with IOPL=3 so that it can use OUT, CLI, STI, etc... + */ + set_iopl(3); + run_in_user((usermode_func)test, GP_VECTOR, 0, 0, 0, 0, &ign); + set_iopl(0); + + report_fn(start, "Usermode "); } #define run_ss_db_test(name) __run_single_step_db_test(name, report_##name) -static void report_singlestep_basic(unsigned long start) +static void report_singlestep_basic(unsigned long start, const char *usermode) { report(n == 3 && is_single_step_db(dr6[0]) && db_addr[0] == start && is_single_step_db(dr6[1]) && db_addr[1] == start + 1 && is_single_step_db(dr6[2]) && db_addr[2] == start + 1 + 1, - "Single-step #DB basic test"); + "%sSingle-step #DB basic test", usermode); } static unsigned long singlestep_basic(void) @@ -122,7 +138,8 @@ static unsigned long singlestep_basic(void) return start; } -static void report_singlestep_emulated_instructions(unsigned long start) +static void report_singlestep_emulated_instructions(unsigned long start, + const char *usermode) { report(n == 6 && is_single_step_db(dr6[0]) && db_addr[0] == start && @@ -131,7 +148,7 @@ static void report_singlestep_emulated_instructions(unsigned long start) is_single_step_db(dr6[3]) && db_addr[3] == start + 1 + 3 + 2 && is_single_step_db(dr6[4]) && db_addr[4] == start + 1 + 3 + 2 + 2 && is_single_step_db(dr6[5]) && db_addr[5] == start + 1 + 3 + 2 + 2 + 1, - "Single-step #DB on emulated instructions"); + "%sSingle-step #DB on emulated instructions", usermode); } static unsigned long singlestep_emulated_instructions(void) From patchwork Thu Jan 20 00:29:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12718020 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 956C8C433EF for ; Thu, 20 Jan 2022 00:29:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357801AbiATA3o (ORCPT ); Wed, 19 Jan 2022 19:29:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40524 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357817AbiATA3f (ORCPT ); Wed, 19 Jan 2022 19:29:35 -0500 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C2D08C061574 for ; Wed, 19 Jan 2022 16:29:34 -0800 (PST) Received: by mail-pf1-x44a.google.com with SMTP id x11-20020aa7918b000000b004bd70cde509so2572789pfa.9 for ; Wed, 19 Jan 2022 16:29:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=RHhNx8AW5eEssCc3X9AikVAelStrwEI+C97w4CA6zu4=; b=GhpvtdJuunmC4RcLFJPEfdl3heHjOlefYmGgFjZqvJDKmFxh8osN8tioOL5TJbfrcT FTBWlLwSB8Dv5jlwdgv7IP1+AZSuWhXVZqdYobO6LCFQFNUkW/wfzz5GeIkMF1U5kmw8 MHvzHzSyr5ou7/inuWi0lwS+zckpNKxqXQxnuW43sofCrph0GSiZk8ZcBMhqrtV87j5R FpZ8fNREieRZPdihujBF8KRZOFbIo8VHC9cc88pi+DYuNNLyLUhwAzUM515cfb6HR9Ek BuNPCIAVfQqstfGrskI/4tfOpDQC8gCYbRqwg+t+ZRAILacr9uZ2kTOT8Mxk8xUj2mM9 hhCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=RHhNx8AW5eEssCc3X9AikVAelStrwEI+C97w4CA6zu4=; b=ntGekC63cj/FplgeKuhE2ysoUekSS30oKRARbFIlJX2NlGlpHVPvacmCzlY8H5hNt+ WRxqnNxsB9xUi8ew9VIwbrMzqyxcMaeRyg0n8DS5R4y5Rk5m5rmIbsuNU0AyWW2+kfyJ bvc+iF7nKcud+9S53xEMwBXrvhVvS+yf7USSSJx5QVSMKYCs4V2D1XPE38/iBrBMyx+3 YE343JenfqL/iO0WuMB7zXsS6xt0H2xKxkxok85Zz2gkmPByoHu8NaKZI6p70geYCSZo HT0K8oz8Yzn3LG/QZuaytBbz/zJ03e17xVkBhiOyhq5xHdHgjuWWBtPpvyrWP5rf3smF 1oUg== X-Gm-Message-State: AOAM5325/FcuXjGT5v/mjiYrLGIMOq+2ZzkN/MdBq6pCF//jI0D8HhIS HcYTRSfxvgIyhoYYQ5U+nENzryfisEk= X-Google-Smtp-Source: ABdhPJz1fd+P7DqzlpUOvgS616xsarpzcEWL9cIOWwBNAkKE8Mc8sF2rfjnIVtSgxsgX3MMNT5kssCzbbss= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a05:6a00:1693:b0:44c:64a3:d318 with SMTP id k19-20020a056a00169300b0044c64a3d318mr33278308pfc.81.1642638574292; Wed, 19 Jan 2022 16:29:34 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 20 Jan 2022 00:29:21 +0000 In-Reply-To: <20220120002923.668708-1-seanjc@google.com> Message-Id: <20220120002923.668708-6-seanjc@google.com> Mime-Version: 1.0 References: <20220120002923.668708-1-seanjc@google.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog Subject: [kvm-unit-tests PATCH 5/7] x86: Overhaul definitions for DR6 and DR7 bits From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Sean Christopherson , David Woodhouse , Alexander Graf Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Clean up the mess that is debugreg.h to follow the nomenclature used by the SDM and the kernel (as best as possible). Use the "new" defines in various tests. Opportunistically add a define for VMX's extra flag in vmcs.GUEST_PENDING_DBG_EXCEPTIONS that is set if any DR0-3 trap matched and was enabled. No functional change intended. Signed-off-by: Sean Christopherson --- lib/x86/asm/debugreg.h | 125 ++++++++++++++++++----------------------- x86/debug.c | 28 +++++---- x86/emulator.c | 14 +++-- x86/vmx_tests.c | 27 +++++---- 4 files changed, 97 insertions(+), 97 deletions(-) diff --git a/lib/x86/asm/debugreg.h b/lib/x86/asm/debugreg.h index e86f5a62..a30f9493 100644 --- a/lib/x86/asm/debugreg.h +++ b/lib/x86/asm/debugreg.h @@ -2,80 +2,63 @@ #ifndef _ASMX86_DEBUGREG_H_ #define _ASMX86_DEBUGREG_H_ +#include -/* Indicate the register numbers for a number of the specific - debug registers. Registers 0-3 contain the addresses we wish to trap on */ -#define DR_FIRSTADDR 0 /* u_debugreg[DR_FIRSTADDR] */ -#define DR_LASTADDR 3 /* u_debugreg[DR_LASTADDR] */ - -#define DR_STATUS 6 /* u_debugreg[DR_STATUS] */ -#define DR_CONTROL 7 /* u_debugreg[DR_CONTROL] */ - -/* Define a few things for the status register. We can use this to determine - which debugging register was responsible for the trap. The other bits - are either reserved or not of interest to us. */ - -/* Define reserved bits in DR6 which are always set to 1 */ -#define DR6_RESERVED (0xFFFF0FF0) - -#define DR_TRAP0 (0x1) /* db0 */ -#define DR_TRAP1 (0x2) /* db1 */ -#define DR_TRAP2 (0x4) /* db2 */ -#define DR_TRAP3 (0x8) /* db3 */ -#define DR_TRAP_BITS (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3) - -#define DR_STEP (0x4000) /* single-step */ -#define DR_SWITCH (0x8000) /* task switch */ - -/* Now define a bunch of things for manipulating the control register. - The top two bytes of the control register consist of 4 fields of 4 - bits - each field corresponds to one of the four debug registers, - and indicates what types of access we trap on, and how large the data - field is that we are looking at */ - -#define DR_CONTROL_SHIFT 16 /* Skip this many bits in ctl register */ -#define DR_CONTROL_SIZE 4 /* 4 control bits per register */ - -#define DR_RW_EXECUTE (0x0) /* Settings for the access types to trap on */ -#define DR_RW_WRITE (0x1) -#define DR_RW_READ (0x3) - -#define DR_LEN_1 (0x0) /* Settings for data length to trap on */ -#define DR_LEN_2 (0x4) -#define DR_LEN_4 (0xC) -#define DR_LEN_8 (0x8) - -/* The low byte to the control register determine which registers are - enabled. There are 4 fields of two bits. One bit is "local", meaning - that the processor will reset the bit after a task switch and the other - is global meaning that we have to explicitly reset the bit. With linux, - you can use either one, since we explicitly zero the register when we enter - kernel mode. */ - -#define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit */ -#define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit */ -#define DR_LOCAL_ENABLE (0x1) /* Local enable for reg 0 */ -#define DR_GLOBAL_ENABLE (0x2) /* Global enable for reg 0 */ -#define DR_ENABLE_SIZE 2 /* 2 enable bits per register */ - -#define DR_LOCAL_ENABLE_MASK (0x55) /* Set local bits for all 4 regs */ -#define DR_GLOBAL_ENABLE_MASK (0xAA) /* Set global bits for all 4 regs */ - -/* The second byte to the control register has a few special things. - We can slow the instruction pipeline for instructions coming via the - gdt or the ldt if we want to. I am not sure why this is an advantage */ - -#ifdef __i386__ -#define DR_CONTROL_RESERVED (0xFC00) /* Reserved by Intel */ -#else -#define DR_CONTROL_RESERVED (0xFFFFFFFF0000FC00UL) /* Reserved */ -#endif - -#define DR_LOCAL_SLOWDOWN (0x100) /* Local slow the pipeline */ -#define DR_GLOBAL_SLOWDOWN (0x200) /* Global slow the pipeline */ +/* + * DR6_ACTIVE_LOW combines fixed-1 and active-low bits (e.g. RTM), and is also + * the init/reset value for DR6. + */ +#define DR6_ACTIVE_LOW 0xffff0ff0 +#define DR6_VOLATILE 0x0001e80f +#define DR6_FIXED_1 (DR6_ACTIVE_LOW & ~DR6_VOLATILE) + +#define DR6_TRAP0 BIT(0) /* DR0 matched */ +#define DR6_TRAP1 BIT(1) /* DR1 matched */ +#define DR6_TRAP2 BIT(2) /* DR2 matched */ +#define DR6_TRAP3 BIT(3) /* DR3 matched */ +#define DR6_TRAP_BITS (DR6_TRAP0|DR6_TRAP1|DR6_TRAP2|DR6_TRAP3) + +#define DR6_BUS_LOCK BIT(11) /* Bus lock 0x800 */ +#define DR6_BD BIT(13) /* General Detect 0x2000 */ +#define DR6_BS BIT(14) /* Single-Step 0x4000 */ +#define DR6_BT BIT(15) /* Task Switch 0x8000 */ +#define DR6_RTM BIT(16) /* RTM / TSX 0x10000 */ + +#define DR7_FIXED_1 0x00000400 /* init/reset value, too */ +#define DR7_VOLATILE 0xffff2bff +#define DR7_BP_EN_MASK 0x000000ff +#define DR7_LE BIT(8) /* Local Exact 0x100 */ +#define DR7_GE BIT(9) /* Global Exact 0x200 */ +#define DR7_RTM BIT(11) /* RTM / TSX 0x800 */ +#define DR7_GD BIT(13) /* General Detect 0x2000 */ /* - * HW breakpoint additions + * Enable bits for DR0-D3. Bits 0, 2, 4, and 6 are local enable bits (cleared + * by the CPU on task switch), bits 1, 3, 5, and 7 are global enable bits + * (never cleared by the CPU). */ +#define DR7_LOCAL_ENABLE_DRx(x) (BIT(0) << (x)) +#define DR7_GLOBAL_ENABLE_DRx(x) (BIT(1) << (x)) +#define DR7_ENABLE_DRx(x) \ + (DR7_LOCAL_ENABLE_DRx(x) | DR7_GLOBAL_ENABLE_DRx(x)) + +#define DR7_GLOBAL_ENABLE_DR0 DR7_GLOBAL_ENABLE_DRx(0) +#define DR7_GLOBAL_ENABLE_DR1 DR7_GLOBAL_ENABLE_DRx(1) +#define DR7_GLOBAL_ENABLE_DR2 DR7_GLOBAL_ENABLE_DRx(2) +#define DR7_GLOBAL_ENABLE_DR3 DR7_GLOBAL_ENABLE_DRx(3) + +/* Condition/type of the breakpoint for DR0-3. */ +#define DR7_RW_TYPE_DRx(x, rw) ((rw) << (((x) * 4) + 16)) +#define DR7_EXECUTE_DRx(x) DR7_RW_TYPE_DRx(x, 0) +#define DR7_WRITE_DRx(x) DR7_RW_TYPE_DRx(x, 1) +#define DR7_PORT_IO_DRx(x) DR7_RW_TYPE_DRx(x, 2) +#define DR7_DATA_IO_DRx(x) DR7_RW_TYPE_DRx(x, 3) /* Read or Write */ + +/* Length of the breakpoint for DR0-3. */ +#define DR7_LEN_DRx(x, enc) ((enc) << (((x) * 4) + 18)) +#define DR7_LEN_1_DRx(x) DR7_LEN_DRx(x, 0) +#define DR7_LEN_2_DRx(x) DR7_LEN_DRx(x, 1) +#define DR7_LEN_4_DRx(x) DR7_LEN_DRx(x, 3) +#define DR7_LEN_8_DRx(x) DR7_LEN_DRx(x, 2) /* Out of sequence, undefined for 32-bit CPUs. */ #endif /* _ASMX86_DEBUGREG_H_ */ diff --git a/x86/debug.c b/x86/debug.c index 21f1da0b..5835a064 100644 --- a/x86/debug.c +++ b/x86/debug.c @@ -8,6 +8,7 @@ * * This work is licensed under the terms of the GNU GPL, version 2. */ +#include #include "libcflat.h" #include "processor.h" @@ -47,12 +48,12 @@ static void handle_db(struct ex_regs *regs) static inline bool is_single_step_db(unsigned long dr6_val) { - return dr6_val == 0xffff4ff0; + return dr6_val == (DR6_ACTIVE_LOW | DR6_BS); } static inline bool is_icebp_db(unsigned long dr6_val) { - return dr6_val == 0xffff0ff0; + return dr6_val == DR6_ACTIVE_LOW; } extern unsigned char handle_db_save_rip; @@ -193,8 +194,9 @@ int main(int ac, char **av) cr4 = read_cr4(); write_cr4(cr4 & ~X86_CR4_DE); write_dr4(0); - write_dr6(0xffff4ff2); - report(read_dr4() == 0xffff4ff2 && !got_ud, "reading DR4 with CR4.DE == 0"); + write_dr6(DR6_ACTIVE_LOW | DR6_BS | DR6_TRAP1); + report(read_dr4() == (DR6_ACTIVE_LOW | DR6_BS | DR6_TRAP1) && !got_ud, + "DR4==DR6 with CR4.DE == 0"); cr4 = read_cr4(); write_cr4(cr4 | X86_CR4_DE); @@ -217,19 +219,21 @@ int main(int ac, char **av) n = 0; extern unsigned char hw_bp1; write_dr0(&hw_bp1); - write_dr7(0x00000402); + write_dr7(DR7_FIXED_1 | DR7_GLOBAL_ENABLE_DR0); asm volatile("hw_bp1: nop"); report(n == 1 && - db_addr[0] == ((unsigned long)&hw_bp1) && dr6[0] == 0xffff0ff1, + db_addr[0] == ((unsigned long)&hw_bp1) && + dr6[0] == (DR6_ACTIVE_LOW | DR6_TRAP0), "hw breakpoint (test that dr6.BS is not set)"); n = 0; extern unsigned char hw_bp2; write_dr0(&hw_bp2); - write_dr6(0x00004002); + write_dr6(DR6_BS | DR6_TRAP1); asm volatile("hw_bp2: nop"); report(n == 1 && - db_addr[0] == ((unsigned long)&hw_bp2) && dr6[0] == 0xffff4ff1, + db_addr[0] == ((unsigned long)&hw_bp2) && + dr6[0] == (DR6_ACTIVE_LOW | DR6_BS | DR6_TRAP0), "hw breakpoint (test that dr6.BS is not cleared)"); run_ss_db_test(singlestep_basic); @@ -245,7 +249,8 @@ int main(int ac, char **av) "mov %%rax,%0\n\t; hw_wp1:" : "=m" (value) : : "rax"); report(n == 1 && - db_addr[0] == ((unsigned long)&hw_wp1) && dr6[0] == 0xffff4ff2, + db_addr[0] == ((unsigned long)&hw_wp1) && + dr6[0] == (DR6_ACTIVE_LOW | DR6_BS | DR6_TRAP1), "hw watchpoint (test that dr6.BS is not cleared)"); n = 0; @@ -257,7 +262,8 @@ int main(int ac, char **av) "mov %%rax,%0\n\t; hw_wp2:" : "=m" (value) : : "rax"); report(n == 1 && - db_addr[0] == ((unsigned long)&hw_wp2) && dr6[0] == 0xffff0ff2, + db_addr[0] == ((unsigned long)&hw_wp2) && + dr6[0] == (DR6_ACTIVE_LOW | DR6_TRAP1), "hw watchpoint (test that dr6.BS is not set)"); n = 0; @@ -265,7 +271,7 @@ int main(int ac, char **av) extern unsigned char sw_icebp; asm volatile(".byte 0xf1; sw_icebp:"); report(n == 1 && - db_addr[0] == (unsigned long)&sw_icebp && dr6[0] == 0xffff0ff0, + db_addr[0] == (unsigned long)&sw_icebp && dr6[0] == DR6_ACTIVE_LOW, "icebp"); write_dr7(0x400); diff --git a/x86/emulator.c b/x86/emulator.c index 22a518f4..cd78e3cb 100644 --- a/x86/emulator.c +++ b/x86/emulator.c @@ -1,3 +1,5 @@ +#include + #include "ioram.h" #include "vm.h" #include "libcflat.h" @@ -883,12 +885,14 @@ static void test_nop(uint64_t *mem) static void test_mov_dr(uint64_t *mem) { unsigned long rax; - const unsigned long in_rax = 0; - bool rtm_support = this_cpu_has(X86_FEATURE_RTM); - unsigned long dr6_fixed_1 = rtm_support ? 0xfffe0ff0ul : 0xffff0ff0ul; + asm(KVM_FEP "movq %0, %%dr6\n\t" - KVM_FEP "movq %%dr6, %0\n\t" : "=a" (rax) : "a" (in_rax)); - report(rax == dr6_fixed_1, "mov_dr6"); + KVM_FEP "movq %%dr6, %0\n\t" : "=a" (rax) : "a" (0)); + + if (this_cpu_has(X86_FEATURE_RTM)) + report(rax == (DR6_ACTIVE_LOW & ~DR6_RTM), "mov_dr6"); + else + report(rax == DR6_ACTIVE_LOW, "mov_dr6"); } static void test_push16(uint64_t *mem) diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c index 3d57ed6c..e67eaea4 100644 --- a/x86/vmx_tests.c +++ b/x86/vmx_tests.c @@ -22,6 +22,13 @@ #include "delay.h" #include "access.h" +/* + * vmcs.GUEST_PENDING_DEBUG has the same format as DR6, although some bits that + * are legal in DR6 are reserved in vmcs.GUEST_PENDING_DEBUG. And if any data + * or I/O breakpoint matches *and* was enabled, bit 12 is also set. + */ +#define PENDING_DBG_TRAP BIT(12) + #define VPID_CAP_INVVPID_TYPES_SHIFT 40 u64 ia32_pat; @@ -5080,9 +5087,9 @@ static void vmx_mtf_test(void) enter_guest(); report_mtf("OUT", (unsigned long) &test_mtf2); pending_dbg = vmcs_read(GUEST_PENDING_DEBUG); - report(pending_dbg & DR_STEP, + report(pending_dbg & DR6_BS, "'pending debug exceptions' field after MTF VM-exit: 0x%lx (expected 0x%lx)", - pending_dbg, (unsigned long) DR_STEP); + pending_dbg, (unsigned long) DR6_BS); disable_mtf(); disable_tf(); @@ -8931,7 +8938,7 @@ static void vmx_preemption_timer_zero_inject_db(bool intercept_db) static void vmx_preemption_timer_zero_set_pending_dbg(u32 exception_bitmap) { vmx_preemption_timer_zero_activate_preemption_timer(); - vmcs_write(GUEST_PENDING_DEBUG, BIT(12) | DR_TRAP1); + vmcs_write(GUEST_PENDING_DEBUG, PENDING_DBG_TRAP | DR6_TRAP1); vmcs_write(EXC_BITMAP, exception_bitmap); enter_guest(); } @@ -9315,7 +9322,7 @@ static void vmx_db_test(void) * (b) stale bits in DR6 (DR6.BD, in particular) don't leak into * the exit qualification field for a subsequent #DB exception. */ - const u64 starting_dr6 = DR6_RESERVED | BIT(13) | DR_TRAP3 | DR_TRAP1; + const u64 starting_dr6 = DR6_ACTIVE_LOW | DR6_BS | DR6_TRAP3 | DR6_TRAP1; extern char post_nop asm(".Lpost_nop"); extern char post_movss_nop asm(".Lpost_movss_nop"); extern char post_wbinvd asm(".Lpost_wbinvd"); @@ -9339,7 +9346,7 @@ static void vmx_db_test(void) * standard that L0 has to follow for emulated instructions. */ single_step_guest("Hardware delivered single-step", starting_dr6, 0); - check_db_exit(false, false, false, &post_nop, DR_STEP, starting_dr6); + check_db_exit(false, false, false, &post_nop, DR6_BS, starting_dr6); /* * Hardware-delivered #DB trap for single-step in MOVSS shadow @@ -9349,8 +9356,8 @@ static void vmx_db_test(void) * data breakpoint as well as the single-step trap. */ single_step_guest("Hardware delivered single-step in MOVSS shadow", - starting_dr6, BIT(12) | DR_STEP | DR_TRAP0 ); - check_db_exit(false, false, false, &post_movss_nop, DR_STEP | DR_TRAP0, + starting_dr6, DR6_BS | PENDING_DBG_TRAP | DR6_TRAP0); + check_db_exit(false, false, false, &post_movss_nop, DR6_BS | DR6_TRAP0, starting_dr6); /* @@ -9360,7 +9367,7 @@ static void vmx_db_test(void) * modified DR6, but fails miserably. */ single_step_guest("Software synthesized single-step", starting_dr6, 0); - check_db_exit(false, false, false, &post_wbinvd, DR_STEP, starting_dr6); + check_db_exit(false, false, false, &post_wbinvd, DR6_BS, starting_dr6); /* * L0 synthesized #DB trap for single-step in MOVSS shadow is @@ -9369,8 +9376,8 @@ static void vmx_db_test(void) * the exit qualification field for the #DB exception. */ single_step_guest("Software synthesized single-step in MOVSS shadow", - starting_dr6, BIT(12) | DR_STEP | DR_TRAP0); - check_db_exit(true, false, true, &post_movss_wbinvd, DR_STEP | DR_TRAP0, + starting_dr6, DR6_BS | PENDING_DBG_TRAP | DR6_TRAP0); + check_db_exit(true, false, true, &post_movss_wbinvd, DR6_BS | DR6_TRAP0, starting_dr6); /* From patchwork Thu Jan 20 00:29:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12718021 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6A0DFC433F5 for ; Thu, 20 Jan 2022 00:29:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357807AbiATA3o (ORCPT ); Wed, 19 Jan 2022 19:29:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40532 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357836AbiATA3g (ORCPT ); Wed, 19 Jan 2022 19:29:36 -0500 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 58F63C061574 for ; Wed, 19 Jan 2022 16:29:36 -0800 (PST) Received: by mail-pf1-x449.google.com with SMTP id 135-20020a62198d000000b004bf3fe65e1fso2587239pfz.2 for ; Wed, 19 Jan 2022 16:29:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=1kUXIxqc6t4dkTULTtsGkWzcoZoN+peYLXOdlnkF5rQ=; b=gWtkeLIO7bD2WsnoKa3pUqWAExS0zAuqbZ8CKZyWHLxSV4bzq5EOQm0Hn5RgY2n+uG nUg2ihYXvl5m8J5TODvq86LhpJB8zfNeaoDVoLD3wD8kiVFMom18yZZ/DJaBJLG0ajg0 kNjHFLt7M+YtNzhxFf3QVJoAKXb6sPO05Ed1lekqEsFup1V/68GSob3zoj3ENCyXa7+S +xXGxU1RA9UXCI/oUhWaaT1Dge8cilqSavb92GlU7yfIbd9kJVUE9Ng2XcICtG+CQKJA IfqOBc1CBD/+eUlHbiPWHl5/hUza/z/UFc+PhuxHysFyBUyQtQZ6beaETSDGmrEEI819 D3KA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=1kUXIxqc6t4dkTULTtsGkWzcoZoN+peYLXOdlnkF5rQ=; b=33VdASYenq0khUeGborhMEipKSgo8HyaBhGdhnAvip4EUzNfA8BF1SORCjYtbaq7ei IEWXG30NlUmo+swYA4nE/EW28QWsSCKQI2KqpASHnibZEF81iynDacjjkVM0fVtC+4uA OwfiZno0tZLrT/OleEH2Tp4hCoiPPdvEpGjckY0aD9enQNRBYkk+S7fIlQAW5owwUhmR re6l9Wf91ANVt2ideya3e88/C2LYZpvbe1vt4iy/tLHerQury3/ukfpUlhO47VCBPADt Um/YqZyNC8Cqf6+DJBqTpaZy0Ex7u3MMZvFCfghravYoCy/spKuKNsbewYL8kVOk3r8z 2ukQ== X-Gm-Message-State: AOAM533LJVu/DDbommC/1/i6VWvNLfBJiZq5EaV8hZsIYiks44dVOKi8 rvf1WkP0S8jL1e+LqAxZTJrPG6XW5Zg= X-Google-Smtp-Source: ABdhPJyZQ+0Uom1fa3IbOlAE6Ud0n4LVz675Ifg/wFsyhvdu3S15p4d9bybtjyed88MjfKvPzDEDoStIsZo= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:90b:380f:: with SMTP id mq15mr7345233pjb.38.1642638575849; Wed, 19 Jan 2022 16:29:35 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 20 Jan 2022 00:29:22 +0000 In-Reply-To: <20220120002923.668708-1-seanjc@google.com> Message-Id: <20220120002923.668708-7-seanjc@google.com> Mime-Version: 1.0 References: <20220120002923.668708-1-seanjc@google.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog Subject: [kvm-unit-tests PATCH 6/7] x86/debug: Add single-step #DB + STI/MOVSS blocking tests From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Sean Christopherson , David Woodhouse , Alexander Graf Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add a variety of test cases to verify single-step #DB interaction with STI and MOVSS blocking. Of particular note are STI blocking and MOVSS blocking with DR7.GD=1, both of which require manual intervention from the hypervisor to set vmcs.GUEST_PENDING_DBG_EXCEPTION.BS when re-injecting an intercepted #DB with STI/MOVSS blocking active. Cc: David Woodhouse Cc: Alexander Graf Signed-off-by: Sean Christopherson --- x86/debug.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) diff --git a/x86/debug.c b/x86/debug.c index 5835a064..0165dc68 100644 --- a/x86/debug.c +++ b/x86/debug.c @@ -51,6 +51,11 @@ static inline bool is_single_step_db(unsigned long dr6_val) return dr6_val == (DR6_ACTIVE_LOW | DR6_BS); } +static inline bool is_general_detect_db(unsigned long dr6_val) +{ + return dr6_val == (DR6_ACTIVE_LOW | DR6_BD); +} + static inline bool is_icebp_db(unsigned long dr6_val) { return dr6_val == DR6_ACTIVE_LOW; @@ -79,6 +84,8 @@ static void handle_ud(struct ex_regs *regs) typedef unsigned long (*db_test_fn)(void); typedef void (*db_report_fn)(unsigned long, const char *); +static unsigned long singlestep_with_movss_blocking_and_dr7_gd(void); + static void __run_single_step_db_test(db_test_fn test, db_report_fn report_fn) { unsigned long start; @@ -90,8 +97,13 @@ static void __run_single_step_db_test(db_test_fn test, db_report_fn report_fn) start = test(); report_fn(start, ""); + /* MOV DR #GPs at CPL>0, don't try to run the DR7.GD test in usermode. */ + if (test == singlestep_with_movss_blocking_and_dr7_gd) + return; + n = 0; write_dr6(0); + /* * Run the test in usermode. Use the expected start RIP from the first * run, the usermode framework doesn't make it easy to get the expected @@ -178,6 +190,166 @@ static unsigned long singlestep_emulated_instructions(void) return start; } +static void report_singlestep_with_sti_blocking(unsigned long start, + const char *usermode) +{ + report(n == 4 && + is_single_step_db(dr6[0]) && db_addr[0] == start && + is_single_step_db(dr6[1]) && db_addr[1] == start + 6 && + is_single_step_db(dr6[2]) && db_addr[2] == start + 6 + 1 && + is_single_step_db(dr6[3]) && db_addr[3] == start + 6 + 1 + 1, + "%sSingle-step #DB w/ STI blocking", usermode); +} + + +static unsigned long singlestep_with_sti_blocking(void) +{ + unsigned long start_rip; + + /* + * STI blocking doesn't suppress #DBs, thus the first single-step #DB + * should arrive after the standard one instruction delay. + */ + asm volatile( + "cli\n\t" + "pushf\n\t" + "pop %%rax\n\t" + "or $(1<<8),%%rax\n\t" + "push %%rax\n\t" + "popf\n\t" + "sti\n\t" + "1:and $~(1<<8),%%rax\n\t" + "push %%rax\n\t" + "popf\n\t" + "lea 1b,%0\n\t" + : "=r" (start_rip) : : "rax" + ); + return start_rip; +} + +static void report_singlestep_with_movss_blocking(unsigned long start, + const char *usermode) +{ + report(n == 3 && + is_single_step_db(dr6[0]) && db_addr[0] == start && + is_single_step_db(dr6[1]) && db_addr[1] == start + 1 && + is_single_step_db(dr6[2]) && db_addr[2] == start + 1 + 1, + "%sSingle-step #DB w/ MOVSS blocking", usermode); +} + +static unsigned long singlestep_with_movss_blocking(void) +{ + unsigned long start_rip; + + /* + * MOVSS blocking suppresses single-step #DBs (and select other #DBs), + * thus the first single-step #DB should occur after MOVSS blocking + * expires, i.e. two instructions after #DBs are enabled in this case. + */ + asm volatile( + "pushf\n\t" + "pop %%rax\n\t" + "or $(1<<8),%%rax\n\t" + "push %%rax\n\t" + "mov %%ss, %%ax\n\t" + "popf\n\t" + "mov %%ax, %%ss\n\t" + "and $~(1<<8),%%rax\n\t" + "1: push %%rax\n\t" + "popf\n\t" + "lea 1b,%0\n\t" + : "=r" (start_rip) : : "rax" + ); + return start_rip; +} + + +static void report_singlestep_with_movss_blocking_and_icebp(unsigned long start, + const char *usermode) +{ + report(n == 4 && + is_icebp_db(dr6[0]) && db_addr[0] == start && + is_single_step_db(dr6[1]) && db_addr[1] == start + 6 && + is_single_step_db(dr6[2]) && db_addr[2] == start + 6 + 1 && + is_single_step_db(dr6[3]) && db_addr[3] == start + 6 + 1 + 1, + "%sSingle-Step + ICEBP #DB w/ MOVSS blocking", usermode); +} + +static unsigned long singlestep_with_movss_blocking_and_icebp(void) +{ + unsigned long start; + + /* + * ICEBP, a.k.a. INT1 or int1icebrk, is an oddball. It generates a + * trap-like #DB, is intercepted if #DBs are intercepted, and manifests + * as a #DB VM-Exit, but the VM-Exit occurs on the ICEBP itself, i.e. + * it's treated as an instruction intercept. Verify that ICEBP is + * correctly emulated as a trap-like #DB when intercepted, and that + * MOVSS blocking is handled correctly with respect to single-step + * breakpoints being enabled. + */ + asm volatile( + "pushf\n\t" + "pop %%rax\n\t" + "or $(1<<8),%%rax\n\t" + "push %%rax\n\t" + "mov %%ss, %%ax\n\t" + "popf\n\t" + "mov %%ax, %%ss\n\t" + ".byte 0xf1;" + "1:and $~(1<<8),%%rax\n\t" + "push %%rax\n\t" + "popf\n\t" + "lea 1b,%0\n\t" + : "=r" (start) : : "rax" + ); + return start; +} + +static void report_singlestep_with_movss_blocking_and_dr7_gd(unsigned long start, + const char *ign) +{ + report(n == 5 && + is_general_detect_db(dr6[0]) && db_addr[0] == start && + is_single_step_db(dr6[1]) && db_addr[1] == start + 3 && + is_single_step_db(dr6[2]) && db_addr[2] == start + 3 + 6 && + is_single_step_db(dr6[3]) && db_addr[3] == start + 3 + 6 + 1 && + is_single_step_db(dr6[4]) && db_addr[4] == start + 3 + 6 + 1 + 1, + "Single-step #DB w/ MOVSS blocking and DR7.GD=1"); +} + +static unsigned long singlestep_with_movss_blocking_and_dr7_gd(void) +{ + unsigned long start_rip; + + write_dr7(DR7_GD); + + /* + * MOVSS blocking does NOT suppress General Detect #DBs, which have + * fault-like behavior. Note, DR7.GD is cleared by the CPU upon + * successful delivery of the #DB. DR6.BD is NOT cleared by the CPU, + * but the MOV DR6 below will be re-executed after handling the + * General Detect #DB. + */ + asm volatile( + "xor %0, %0\n\t" + "pushf\n\t" + "pop %%rax\n\t" + "or $(1<<8),%%rax\n\t" + "push %%rax\n\t" + "mov %%ss, %%ax\n\t" + "popf\n\t" + "mov %%ax, %%ss\n\t" + "1: mov %0, %%dr6\n\t" + "and $~(1<<8),%%rax\n\t" + "push %%rax\n\t" + "popf\n\t" + "lea 1b,%0\n\t" + : "=r" (start_rip) : : "rax" + ); + return start_rip; +} + int main(int ac, char **av) { unsigned long cr4; @@ -238,6 +410,10 @@ int main(int ac, char **av) run_ss_db_test(singlestep_basic); run_ss_db_test(singlestep_emulated_instructions); + run_ss_db_test(singlestep_with_sti_blocking); + run_ss_db_test(singlestep_with_movss_blocking); + run_ss_db_test(singlestep_with_movss_blocking_and_icebp); + run_ss_db_test(singlestep_with_movss_blocking_and_dr7_gd); n = 0; write_dr1((void *)&value); From patchwork Thu Jan 20 00:29:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 12718022 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E71E9C433FE for ; Thu, 20 Jan 2022 00:29:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357816AbiATA3p (ORCPT ); Wed, 19 Jan 2022 19:29:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40548 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357862AbiATA3i (ORCPT ); Wed, 19 Jan 2022 19:29:38 -0500 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E9BB3C061574 for ; Wed, 19 Jan 2022 16:29:37 -0800 (PST) Received: by mail-pl1-x649.google.com with SMTP id o9-20020a170902d4c900b0014ab4c82aacso708090plg.16 for ; Wed, 19 Jan 2022 16:29:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=4MC6d0yHRYoMsTEg2KKjfkUTAJY8zSLYHw4vhT35czg=; b=MCqnW1IqqPINwTYy4F14Ed4xfyBnPBUYk3aV10/YwT4CD2mOD9pLn84YQ0YV3ZgYQ2 /+kMI2bhl4xyndnjoDknYMvT01lNkiLBULnFlC2YkEWlL3Ikgb9SATyKYXknPNGTzRGi EDl7QiJo7qEcPf2lKM52OW/DjGuBR3AEgVJQ7e4HVjqtAX5SyER9eZSQQMcaKHaIjuqX QClDXiHBUd/QxBQqryTIJby1Tlmvjw80E8PX3uYOl5MbvXKqSiaaPoRCBVzPtDSshcZ4 hztf71VZE/UQahE0FifMlLXM6BCGXLpX6Bo6ujqIi9lV5hDjanA8T+z1S7hAWDhXREWx nYDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=4MC6d0yHRYoMsTEg2KKjfkUTAJY8zSLYHw4vhT35czg=; b=NHqqWxA44fgnxQsj7RJ1l/VmLREiuYWSuCj5OfncscSnFkqYL0DL1t56LxhxsTCbSm raZMPiiV8r6SNyng9e7og/fnuvWicnmpoJN6PHVcu1DJ1ExOKg1GolUivqxGCvJ5M19T yH0MwPVwMklvbIiR87sqAyPYHQdI+Z61aTt3XsZNqYC18QKHuxPGrETd7GLE5KfTuWGd bo5hsjohZQgrv9nj9tSrlZu9kuQ09CF0zQ4AP3q55OyybooD9kIHv7UJPq+NhXRo6hr+ 834OFNl/GIPsIkHZytjXhp+y1czcnhWqDBoTOAXJ7F2eUSQDe681mS+tajumolxWj7MM /5wQ== X-Gm-Message-State: AOAM531n/bd1v3+xqEeVIuf5idh7XpwBPyezL3Rl20VDkIh7BuPxJT82 aE9k3RyvtnxivgPl/+RSaqmfR5iA+TU= X-Google-Smtp-Source: ABdhPJwMsShOerBppp0D3JSJKCJD308OWGxzrSEZp6/ZFzR97724k6Wyz4ia83zSyNcm6QE64CePpbnI63E= X-Received: from seanjc.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3e5]) (user=seanjc job=sendgmr) by 2002:a17:90b:1c8f:: with SMTP id oo15mr7292806pjb.125.1642638577504; Wed, 19 Jan 2022 16:29:37 -0800 (PST) Reply-To: Sean Christopherson Date: Thu, 20 Jan 2022 00:29:23 +0000 In-Reply-To: <20220120002923.668708-1-seanjc@google.com> Message-Id: <20220120002923.668708-8-seanjc@google.com> Mime-Version: 1.0 References: <20220120002923.668708-1-seanjc@google.com> X-Mailer: git-send-email 2.34.1.703.g22d0c6ccf7-goog Subject: [kvm-unit-tests PATCH 7/7] x86/debug: Explicitly write DR6 in the H/W watchpoint + DR6.BS sub-test From: Sean Christopherson To: Paolo Bonzini Cc: kvm@vger.kernel.org, Sean Christopherson , David Woodhouse , Alexander Graf Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Explicitly set DR6.BS for the sub-test that verifies DR6.BS isn't cleared when a data breakpoint (a.k.a. H/W watchpoint) #DB occurs. Relying on the single-step #DB tests to leave DR6 is all kinds of mean. Signed-off-by: Sean Christopherson Reviewed-by: Jim Mattson --- x86/debug.c | 1 + 1 file changed, 1 insertion(+) diff --git a/x86/debug.c b/x86/debug.c index 0165dc68..4fec241f 100644 --- a/x86/debug.c +++ b/x86/debug.c @@ -417,6 +417,7 @@ int main(int ac, char **av) n = 0; write_dr1((void *)&value); + write_dr6(DR6_BS); write_dr7(0x00d0040a); // 4-byte write extern unsigned char hw_wp1;