18 #include <linux/module.h>
19 #include <linux/sched.h>
27 static unsigned long idt_address(
u32 lo,
u32 hi)
29 return (lo & 0x0000FFFF) | (hi & 0xFFFF0000);
36 static int idt_type(
u32 lo,
u32 hi)
38 return (hi >> 8) & 0xF;
42 static bool idt_present(
u32 lo,
u32 hi)
51 static void push_guest_stack(
struct lg_cpu *
cpu,
unsigned long *gstack,
u32 val)
75 unsigned long gstack, origstack;
77 unsigned long virtstack;
89 virtstack = cpu->
esp1;
92 origstack = gstack =
guest_pa(cpu, virtstack);
99 push_guest_stack(cpu, &gstack, cpu->
regs->ss);
100 push_guest_stack(cpu, &gstack, cpu->
regs->esp);
103 virtstack = cpu->
regs->esp;
106 origstack = gstack =
guest_pa(cpu, virtstack);
115 eflags = cpu->
regs->eflags;
116 if (
get_user(irq_enable, &cpu->
lg->lguest_data->irq_enabled) == 0
118 eflags &= ~X86_EFLAGS_IF;
125 push_guest_stack(cpu, &gstack, eflags);
126 push_guest_stack(cpu, &gstack, cpu->
regs->cs);
127 push_guest_stack(cpu, &gstack, cpu->
regs->eip);
131 push_guest_stack(cpu, &gstack, cpu->
regs->errcode);
138 cpu->
regs->esp = virtstack + (gstack - origstack);
140 cpu->
regs->eip = idt_address(lo, hi);
146 if (idt_type(lo, hi) == 0xE)
147 if (
put_user(0, &cpu->
lg->lguest_data->irq_enabled))
164 if (!cpu->
lg->lguest_data)
197 if (cpu->
regs->eip >= cpu->
lg->noirq_start &&
198 (cpu->
regs->eip < cpu->
lg->noirq_end))
204 if (
put_user(X86_EFLAGS_IF, &cpu->
lg->lguest_data->irq_enabled))
210 if (
get_user(irq_enabled, &cpu->
lg->lguest_data->irq_enabled))
215 &cpu->
lg->lguest_data->irq_pending);
227 if (idt_present(idt->
a, idt->
b)) {
235 set_guest_interrupt(cpu, idt->
a, idt->
b,
false);
252 put_user(0, &cpu->
lg->lguest_data->irq_pending);
262 set_bit(irq, cpu->irqs_pending);
269 kick_process(cpu->
tsk);
281 static bool could_be_syscall(
unsigned int num)
295 return could_be_syscall(vector);
325 static bool has_err(
unsigned int trap)
327 return (trap == 8 || (trap >= 10 && trap <= 14) || trap == 17);
344 if (!idt_present(cpu->
arch.idt[num].a, cpu->
arch.idt[num].b))
346 set_guest_interrupt(cpu, cpu->
arch.idt[num].a,
347 cpu->
arch.idt[num].b, has_err(num));
366 static bool direct_trap(
unsigned int num)
418 for (i = 0; i < cpu->
lg->stack_pages; i++)
466 unsigned int num,
u32 lo,
u32 hi)
468 u8 type = idt_type(lo, hi);
471 if (!idt_present(lo, hi)) {
472 trap->
a = trap->
b = 0;
477 if (type != 0xE && type != 0xF)
487 trap->
b = (hi&0xFFFFEF00);
518 set_trap(cpu, &cpu->
arch.idt[num], num, lo, hi);
528 const unsigned long handler,
545 flags |= (base->
b & 0x6000);
548 idt->
a = (
LGUEST_CS<<16) | (handler&0x0000FFFF);
549 idt->
b = (handler&0xFFFF0000) | flags;
554 const unsigned long *def)
568 const unsigned long *def)
593 if (idt_type(gidt->
a, gidt->
b) == 0xF)
596 default_idt_entry(&idt[i], i, def[i], gidt);
646 cpu->
hrt.function = clockdev_fn;