#include "libcflat.h"
#include <alloc_page.h>
#include "x86/desc.h"
#include "x86/processor.h"
#include "x86/vm.h"

volatile int pf_count = 0;
volatile int save;
volatile unsigned test;

void do_pf_tss(unsigned long error_code);

// When doing ring 3 tests, page fault handlers will always run on a
// separate stack (the ring 0 stack).  Seems easier to use the alt_stack
// mechanism for both ring 0 and ring 3.

void do_pf_tss(unsigned long error_code)
{
	pf_count++;
	save = test;

#ifndef __x86_64__
	tss[0].eflags |= X86_EFLAGS_AC;
#endif
}

extern void pf_tss(void);
asm ("pf_tss:\n"
#ifdef __x86_64__
        // no task on x86_64, save/restore caller-save regs
        "push %rax; push %rcx; push %rdx; push %rsi; push %rdi\n"
        "push %r8; push %r9; push %r10; push %r11\n"
	"mov 9*8(%rsp),%rdi\n"
#endif
	"call do_pf_tss\n"
#ifdef __x86_64__
        "pop %r11; pop %r10; pop %r9; pop %r8\n"
        "pop %rdi; pop %rsi; pop %rdx; pop %rcx; pop %rax\n"
#endif
	"add $"S", %"R "sp\n"
#ifdef __x86_64__
	"orl $(1 << " xstr(X86_EFLAGS_AC_BIT) "), 2*"S"(%"R "sp)\n"  // set EFLAGS.AC and retry
#endif
        "iret"W" \n\t"
        "jmp pf_tss\n\t");


#define USER_BASE	(1 << 23)
#define USER_VAR(v)	(*((__typeof__(&(v))) (((unsigned long)&v) + USER_BASE)))
#define USER_ADDR(v)   ((void *)((unsigned long)(&v) + USER_BASE))

static void init_test(int i)
{
	pf_count = 0;
	if (i) {
		invlpg(&test);
		invlpg(&USER_VAR(test));
	}
}

static void check_smap_nowp(void)
{
	test = 0x99;

	*get_pte(phys_to_virt(read_cr3()), USER_ADDR(test)) &= ~PT_WRITABLE_MASK;

	write_cr4(read_cr4() & ~X86_CR4_SMAP);
	write_cr0(read_cr0() & ~X86_CR0_WP);
	clac();
	write_cr3(read_cr3());

	init_test(0);
	USER_VAR(test) = 0x99;
	report(pf_count == 0,
	       "write from user page with SMAP=0, AC=0, WP=0, PTE.U=1 && PTE.W=0");

	write_cr4(read_cr4() | X86_CR4_SMAP);
	write_cr3(read_cr3());

	init_test(0);
	(void)USER_VAR(test);
	report(pf_count == 1 && save == 0x99,
	       "read from user page with SMAP=1, AC=0, WP=0, PTE.U=1 && PTE.W=0");

	/* Undo changes */
	*get_pte(phys_to_virt(read_cr3()), USER_ADDR(test)) |= PT_WRITABLE_MASK;

	write_cr0(read_cr0() | X86_CR0_WP);
	write_cr3(read_cr3());
}

int main(int ac, char **av)
{
	unsigned long i;

	if (!this_cpu_has(X86_FEATURE_SMAP)) {
		printf("SMAP not enabled\n");
		return report_summary();
	}

	setup_vm();
	setup_alt_stack();
	set_intr_alt_stack(14, pf_tss);

	if (reserve_pages(USER_BASE, USER_BASE >> 12))
		report_abort("Could not reserve memory");
	// Map first 8MB as supervisor pages
	for (i = 0; i < USER_BASE; i += PAGE_SIZE) {
		*get_pte(phys_to_virt(read_cr3()), phys_to_virt(i)) &= ~PT_USER_MASK;
		invlpg((void *)i);
	}

	// Present the same 8MB as user pages in the 8MB-16MB range
	for (i = USER_BASE; i < 2 * USER_BASE; i += PAGE_SIZE) {
		*get_pte(phys_to_virt(read_cr3()), phys_to_virt(i)) &= ~USER_BASE;
		invlpg((void *)i);
	}

	clac();
	write_cr4(read_cr4() | X86_CR4_SMAP);
	write_cr3(read_cr3());

	for (i = 0; i < 2; i++) {
		if (i)
			printf("testing with INVLPG\n");
		else
			printf("testing without INVLPG\n");

		init_test(i);
		clac();
		test = 42;
		report(pf_count == 0 && test == 42,
		       "write to supervisor page");

		init_test(i);
		stac();
		(void)USER_VAR(test);
		report(pf_count == 0, "read from user page with AC=1");

		init_test(i);
		clac();
		(void)USER_VAR(test);
		report(pf_count == 1 && save == 42,
		       "read from user page with AC=0");

		init_test(i);
		stac();
		save = 0;
		USER_VAR(test) = 43;
		report(pf_count == 0 && test == 43,
		       "write to user page with AC=1");

		init_test(i);
		clac();
		USER_VAR(test) = 44;
		report(pf_count == 1 && test == 44 && save == 43,
		       "read from user page with AC=0");

		init_test(i);
		stac();
		test = -1;
#ifndef __x86_64__
		#define TEST "test"
#else
		#define TEST "test(%rip)"
#endif
		asm("or $(" xstr(USER_BASE) "), %"R "sp \n"
		    "push $44 \n "
		    "decl " TEST "\n"
		    "and $~(" xstr(USER_BASE) "), %"R "sp \n"
		    "pop %"R "ax\n"
		    "movl %eax, " TEST "\n");
		report(pf_count == 0 && test == 44,
		       "write to user stack with AC=1");

		init_test(i);
		clac();
		test = -1;
		asm("or $(" xstr(USER_BASE) "), %"R "sp \n"
		    "push $45 \n "
		    "decl " TEST "\n"
		    "and $~(" xstr(USER_BASE) "), %"R "sp \n"
		    "pop %"R "ax\n"
		    "movl %eax, " TEST "\n");
		report(pf_count == 1 && test == 45 && save == -1,
		       "write to user stack with AC=0");

		/* This would be trapped by SMEP */
		init_test(i);
		clac();
		asm("jmp 1f + "xstr(USER_BASE)" \n"
		    "1: jmp 2f - "xstr(USER_BASE)" \n"
		    "2:");
		report(pf_count == 0, "executing on user page with AC=0");
	}

	check_smap_nowp();

	// TODO: implicit kernel access from ring 3 (e.g. int)

	return report_summary();
}
