/*
 * 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 <asm/debugreg.h>

#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];
static volatile unsigned int n;
static volatile unsigned long value;

static inline void write_dr4(ulong val)
{
    asm volatile ("mov %0, %%dr4" : : "r"(val) : "memory");
}

static inline ulong read_dr4(void)
{
    ulong val;
    asm volatile ("mov %%dr4, %0" : "=r"(val));
    return val;
}

static void handle_db(struct ex_regs *regs)
{
	db_addr[n] = regs->rip;
	dr6[n] = read_dr6();

	if (dr6[n] & 0x1)
		regs->rflags |= X86_EFLAGS_RF;

	if (++n >= 10) {
		regs->rflags &= ~X86_EFLAGS_TF;
		write_dr7(0x00000400);
	}
}

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;
}

extern unsigned char handle_db_save_rip;
asm("handle_db_save_rip:\n"
   "stc\n"
   "nop;nop;nop\n"
   "rclq $1, n(%rip)\n"
   "iretq\n");

static void handle_bp(struct ex_regs *regs)
{
	bp_addr = regs->rip;
}

bool got_ud;
static void handle_ud(struct ex_regs *regs)
{
	unsigned long cr4 = read_cr4();
	write_cr4(cr4 & ~X86_CR4_DE);
	got_ud = 1;
}

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;
	bool ign;

	n = 0;
	write_dr6(0);

	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
	 * 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, 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 basic test", usermode);
}

static noinline 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(%%rip), %0\n\t"
		: "=r" (start) : : "rax"
	);
	return start;
}

static void report_singlestep_emulated_instructions(unsigned long start,
						    const char *usermode)
{
	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 + 1 &&
	       is_single_step_db(dr6[6]) && db_addr[6] == start + 1 + 3 + 2 + 5 + 1 + 1,
	       "%sSingle-step #DB on emulated instructions", usermode);
}

static noinline 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 $0x3fd, %%edx\n\t"
		"inb %%dx, %%al\n\t"
		"popf\n\t"
		"lea 1b(%%rip),%0\n\t"
		: "=r" (start) : : "rax", "ebx", "ecx", "edx"
	);
	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 noinline 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(%%rip),%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 noinline 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(%%rip),%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 noinline 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(%%rip),%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 noinline 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(%%rip),%0\n\t"
		: "=r" (start_rip) : : "rax"
	);
	return start_rip;
}

int main(int ac, char **av)
{
	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);
	write_dr4(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);
	read_dr4();
	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);
	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] == (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(DR6_BS | DR6_TRAP1);
	asm volatile("hw_bp2: nop");
	report(n == 1 &&
	       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);
	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);
	write_dr6(DR6_BS);
	write_dr7(0x00d0040a); // 4-byte write

	extern unsigned char hw_wp1;
	asm volatile(
		"mov $42,%%rax\n\t"
		"mov %%rax,%0\n\t; hw_wp1:"
		: "=m" (value) : : "rax");
	report(n == 1 &&
	       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;
	write_dr6(0);

	extern unsigned char hw_wp2;
	asm volatile(
		"mov $42,%%rax\n\t"
		"mov %%rax,%0\n\t; hw_wp2:"
		: "=m" (value) : : "rax");
	report(n == 1 &&
	       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;
	write_dr6(0);
	extern unsigned char sw_icebp;
	asm volatile(".byte 0xf1; sw_icebp:");
	report(n == 1 &&
	       db_addr[0] == (unsigned long)&sw_icebp && dr6[0] == DR6_ACTIVE_LOW,
	       "icebp");

	write_dr7(0x400);
	value = KERNEL_DS;
	write_dr7(0x00f0040a); // 4-byte read or write

	/*
	 * Each invocation of the handler should shift n by 1 and set bit 0 to 1.
	 * We expect a single invocation, so n should become 3.  If the entry
	 * RIP is wrong, or if the handler is executed more than once, the value
	 * will not match.
	 */
	set_idt_entry(1, &handle_db_save_rip, 0);

	n = 1;
	asm volatile(
		"clc\n\t"
		"mov %0,%%ss\n\t"
		".byte 0x2e, 0x2e, 0xf1"
		: "=m" (value) : : "rax");
	report(n == 3, "MOV SS + watchpoint + ICEBP");

	/*
	 * Here the #DB handler is invoked twice, once as a software exception
	 * and once as a software interrupt.
	 */
	n = 1;
	asm volatile(
		"clc\n\t"
		"mov %0,%%ss\n\t"
		"int $1"
		: "=m" (value) : : "rax");
	report(n == 7, "MOV SS + watchpoint + int $1");

	/*
	 * Here the #DB and #BP handlers are invoked once each.
	 */
	n = 1;
	bp_addr = 0;
	asm volatile(
		"mov %0,%%ss\n\t"
		".byte 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0xcc\n\t"
		"sw_bp2:"
		: "=m" (value) : : "rax");
	extern unsigned char sw_bp2;
	report(n == 3 && bp_addr == (unsigned long)&sw_bp2,
	       "MOV SS + watchpoint + INT3");
	return report_summary();
}
