#include <linux/uaccess.h>
#include "lg.h"

static unsigned long idt_address(u32 lo, u32 hi)
{
	return (lo & 0x0000FFFF) | (hi & 0xFFFF0000);
}

static int idt_type(u32 lo, u32 hi)
{
	return (hi >> 8) & 0xF;
}

static int idt_present(u32 lo, u32 hi)
{
	return (hi & 0x8000);
}

static void push_guest_stack(struct lguest *lg, unsigned long *gstack, u32 val)
{
	*gstack -= 4;
	lgwrite_u32(lg, *gstack, val);
}

static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err)
{
	unsigned long gstack;
	u32 eflags, ss, irq_enable;

	/* If they want a ring change, we use new stack and push old ss/esp */
	if ((lg->regs->ss&0x3) != GUEST_PL) {
		gstack = guest_pa(lg, lg->esp1);
		ss = lg->ss1;
		push_guest_stack(lg, &gstack, lg->regs->ss);
		push_guest_stack(lg, &gstack, lg->regs->esp);
	} else {
		gstack = guest_pa(lg, lg->regs->esp);
		ss = lg->regs->ss;
	}

	/* We use IF bit in eflags to indicate whether irqs were disabled
	   (it's always 0, since irqs are enabled when guest is running). */
	eflags = lg->regs->eflags;
	if (get_user(irq_enable, &lg->lguest_data->irq_enabled))
		irq_enable = 0;
	eflags |= (irq_enable & X86_EFLAGS_IF);

	push_guest_stack(lg, &gstack, eflags);
	push_guest_stack(lg, &gstack, lg->regs->cs);
	push_guest_stack(lg, &gstack, lg->regs->eip);

	if (has_err)
		push_guest_stack(lg, &gstack, lg->regs->errcode);

	/* Change the real stack so switcher returns to trap handler */
	lg->regs->ss = ss;
	lg->regs->esp = gstack + lg->page_offset;
	lg->regs->cs = (__KERNEL_CS|GUEST_PL);
	lg->regs->eip = idt_address(lo, hi);

	/* Disable interrupts for an interrupt gate. */
	if (idt_type(lo, hi) == 0xE)
		if (put_user(0, &lg->lguest_data->irq_enabled))
			kill_guest(lg, "Disabling interrupts");
}

void maybe_do_interrupt(struct lguest *lg)
{
	unsigned int irq;
	DECLARE_BITMAP(blk, LGUEST_IRQS);
	struct desc_struct *idt;

	if (!lg->lguest_data)
		return;

	/* Mask out any interrupts they have blocked. */
	if (copy_from_user(&blk, lg->lguest_data->blocked_interrupts,
			   sizeof(blk)))
		return;

	bitmap_andnot(blk, lg->irqs_pending, blk, LGUEST_IRQS);

	irq = find_first_bit(blk, LGUEST_IRQS);
	if (irq >= LGUEST_IRQS)
		return;

	if (lg->regs->eip >= lg->noirq_start && lg->regs->eip < lg->noirq_end)
		return;

	/* If they're halted, we re-enable interrupts. */
	if (lg->halted) {
		/* Re-enable interrupts. */
		if (put_user(X86_EFLAGS_IF, &lg->lguest_data->irq_enabled))
			kill_guest(lg, "Re-enabling interrupts");
		lg->halted = 0;
	} else {
		/* Maybe they have interrupts disabled? */
		u32 irq_enabled;
		if (get_user(irq_enabled, &lg->lguest_data->irq_enabled))
			irq_enabled = 0;
		if (!irq_enabled)
			return;
	}

	idt = &lg->idt[FIRST_EXTERNAL_VECTOR+irq];
	if (idt_present(idt->a, idt->b)) {
		clear_bit(irq, lg->irqs_pending);
		set_guest_interrupt(lg, idt->a, idt->b, 0);
	}
}

static int has_err(unsigned int trap)
{
	return (trap == 8 || (trap >= 10 && trap <= 14) || trap == 17);
}

int deliver_trap(struct lguest *lg, unsigned int num)
{
	u32 lo = lg->idt[num].a, hi = lg->idt[num].b;

	if (!idt_present(lo, hi))
		return 0;
	set_guest_interrupt(lg, lo, hi, has_err(num));
	return 1;
}

static int direct_trap(const struct lguest *lg,
		       const struct desc_struct *trap,
		       unsigned int num)
{
	/* Hardware interrupts don't go to guest (except syscall). */
	if (num >= FIRST_EXTERNAL_VECTOR && num != SYSCALL_VECTOR)
		return 0;

	/* We intercept page fault (demand shadow paging & cr2 saving)
	   protection fault (in/out emulation) and device not
	   available (TS handling), and hypercall */
	if (num == 14 || num == 13 || num == 7 || num == LGUEST_TRAP_ENTRY)
		return 0;

	/* Interrupt gates (0xE) or not present (0x0) can't go direct. */
	return idt_type(trap->a, trap->b) == 0xF;
}

void pin_stack_pages(struct lguest *lg)
{
	unsigned int i;

	for (i = 0; i < lg->stack_pages; i++)
		pin_page(lg, lg->esp1 - i * PAGE_SIZE);
}

void guest_set_stack(struct lguest *lg, u32 seg, u32 esp, unsigned int pages)
{
	/* You cannot have a stack segment with priv level 0. */
	if ((seg & 0x3) != GUEST_PL)
		kill_guest(lg, "bad stack segment %i", seg);
	if (pages > 2)
		kill_guest(lg, "bad stack pages %u", pages);
	lg->ss1 = seg;
	lg->esp1 = esp;
	lg->stack_pages = pages;
	pin_stack_pages(lg);
}

/* Set up trap in IDT. */
static void set_trap(struct lguest *lg, struct desc_struct *trap,
		     unsigned int num, u32 lo, u32 hi)
{
	u8 type = idt_type(lo, hi);

	if (!idt_present(lo, hi)) {
		trap->a = trap->b = 0;
		return;
	}

	if (type != 0xE && type != 0xF)
		kill_guest(lg, "bad IDT type %i", type);

	trap->a = ((__KERNEL_CS|GUEST_PL)<<16) | (lo&0x0000FFFF);
	trap->b = (hi&0xFFFFEF00);
}

void load_guest_idt_entry(struct lguest *lg, unsigned int num, u32 lo, u32 hi)
{
	/* Guest never handles: NMI, doublefault, hypercall, spurious irq. */
	if (num == 2 || num == 8 || num == 15 || num == LGUEST_TRAP_ENTRY)
		return;

	lg->changed |= CHANGED_IDT;
	if (num < ARRAY_SIZE(lg->idt))
		set_trap(lg, &lg->idt[num], num, lo, hi);
	else if (num == SYSCALL_VECTOR)
		set_trap(lg, &lg->syscall_idt, num, lo, hi);
}

static void default_idt_entry(struct desc_struct *idt,
			      int trap,
			      const unsigned long handler)
{
	u32 flags = 0x8e00;

	/* They can't "int" into any of them except hypercall. */
	if (trap == LGUEST_TRAP_ENTRY)
		flags |= (GUEST_PL << 13);

	idt->a = (LGUEST_CS<<16) | (handler&0x0000FFFF);
	idt->b = (handler&0xFFFF0000) | flags;
}

void setup_default_idt_entries(struct lguest_ro_state *state,
			       const unsigned long *def)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(state->guest_idt); i++)
		default_idt_entry(&state->guest_idt[i], i, def[i]);
}

void copy_traps(const struct lguest *lg, struct desc_struct *idt,
		const unsigned long *def)
{
	unsigned int i;

	/* All hardware interrupts are same whatever the guest: only the
	 * traps might be different. */
	for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) {
		if (direct_trap(lg, &lg->idt[i], i))
			idt[i] = lg->idt[i];
		else
			default_idt_entry(&idt[i], i, def[i]);
	}
	i = SYSCALL_VECTOR;
	if (direct_trap(lg, &lg->syscall_idt, i))
		idt[i] = lg->syscall_idt;
	else
		default_idt_entry(&idt[i], i, def[i]);
}

void guest_set_clockevent(struct lguest *lg, unsigned long delta)
{
	ktime_t expires;

	if (unlikely(delta == 0)) {
		/* Clock event device is shutting down. */
		hrtimer_cancel(&lg->hrt);
		return;
	}

	expires = ktime_add_ns(ktime_get_real(), delta);
	hrtimer_start(&lg->hrt, expires, HRTIMER_MODE_ABS);
}

static enum hrtimer_restart clockdev_fn(struct hrtimer *timer)
{
	struct lguest *lg = container_of(timer, struct lguest, hrt);

	set_bit(0, lg->irqs_pending);
	if (lg->halted)
		wake_up_process(lg->tsk);
	return HRTIMER_NORESTART;
}

void init_clockdev(struct lguest *lg)
{
	hrtimer_init(&lg->hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS);
	lg->hrt.function = clockdev_fn;
}
