29 #include <linux/kernel.h>
31 #include <linux/string.h>
33 #include <linux/screen_info.h>
41 #include <asm/paravirt.h>
42 #include <asm/param.h>
44 #include <asm/pgtable.h>
46 #include <asm/setup.h>
48 #include <asm/uaccess.h>
52 static int cpu_had_pge;
60 static unsigned long switcher_offset(
void)
115 pages->
state.guest_tss.ss1 = cpu->
ss1;
136 unsigned int clobber;
142 copy_in_guest_info(cpu, pages);
149 cpu->
regs->trapnum = 256;
161 asm volatile(
"pushf; lcall *lguest_entry"
166 :
"=a"(clobber),
"=b"(clobber)
179 :
"memory",
"%edx",
"%ecx",
"%edi",
"%esi");
206 if (cpu->
ts && user_has_fpu())
238 if (cpu->
ts && user_has_fpu())
247 if (cpu->
regs->trapnum == 14)
248 cpu->
arch.last_pagefault = read_cr2();
256 else if (cpu->
regs->trapnum == 7 && !user_has_fpu())
273 static int emulate_insn(
struct lg_cpu *cpu)
276 unsigned int insnlen = 0,
in = 0, small_operand = 0;
313 insn =
lgread(cpu, physaddr + insnlen,
u8);
320 switch (insn & 0xFE) {
349 cpu->
regs->eax |= 0xFFFF;
351 cpu->
regs->eax = 0xFFFFFFFF;
353 cpu->
regs->eax |= 0xFF;
356 cpu->
regs->eip += insnlen;
364 switch (cpu->
regs->trapnum) {
371 if (cpu->
regs->errcode == 0) {
372 if (emulate_insn(cpu))
400 if (cpu->
lg->lguest_data &&
402 &cpu->
lg->lguest_data->cr2))
438 kill_guest(cpu,
"unhandled trap %li at %#lx (%#lx)",
440 cpu->
regs->trapnum == 14 ? cpu->
arch.last_pagefault
441 : cpu->
regs->errcode);
451 static void adjust_pge(
void *on)
615 switch (args->
arg0) {
642 sizeof(*cpu->
lg->lguest_data)))
652 cpu->
lg->lguest_data = cpu->
lg->mem_base + cpu->
hcall->arg1;
667 if (
put_user(tsc_speed, &cpu->
lg->lguest_data->tsc_khz))