#ifndef _LGUEST_H #define _LGUEST_H #ifndef __ASSEMBLY__ #include #include #include #include #include #include #include #include #include #include struct pgdir { unsigned long gpgdir; bool switcher_mapped; int last_host_cpu; pgd_t *pgdir; }; /* We have two pages shared with guests, per cpu. */ struct lguest_pages { /* This is the stack page mapped rw in guest */ char spare[PAGE_SIZE - sizeof(struct lguest_regs)]; struct lguest_regs regs; /* This is the host state & guest descriptor page, ro in guest */ struct lguest_ro_state state; } __attribute__((aligned(PAGE_SIZE))); #define CHANGED_IDT 1 #define CHANGED_GDT 2 #define CHANGED_GDT_TLS 4 /* Actually a subset of CHANGED_GDT */ #define CHANGED_ALL 3 struct lg_cpu { unsigned int id; struct lguest *lg; struct task_struct *tsk; struct mm_struct *mm; /* == tsk->mm, but that becomes NULL on exit */ u32 cr2; int ts; u32 esp1; u16 ss1; /* Bitmap of what has changed: see CHANGED_* above. */ int changed; /* Pending operation. */ struct lguest_pending pending; unsigned long *reg_read; /* register from LHREQ_GETREG */ /* At end of a page shared mapped over lguest_pages in guest. */ unsigned long regs_page; struct lguest_regs *regs; struct lguest_pages *last_pages; /* Initialization mode: linear map everything. */ bool linear_pages; int cpu_pgd; /* Which pgd this cpu is currently using */ /* If a hypercall was asked for, this points to the arguments. */ struct hcall_args *hcall; u32 next_hcall; /* Virtual clock device */ struct hrtimer hrt; /* Did the Guest tell us to halt? */ int halted; /* Pending virtual interrupts */ DECLARE_BITMAP(irqs_pending, LGUEST_IRQS); struct lg_cpu_arch arch; }; /* The private info the thread maintains about the guest. */ struct lguest { struct lguest_data __user *lguest_data; struct lg_cpu cpus[NR_CPUS]; unsigned int nr_cpus; /* Valid guest memory pages must be < this. */ u32 pfn_limit; /* Device memory is >= pfn_limit and < device_limit. */ u32 device_limit; /* * This provides the offset to the base of guest-physical memory in the * Launcher. */ void __user *mem_base; unsigned long kernel_address; struct pgdir pgdirs[4]; unsigned long noirq_iret; unsigned int stack_pages; u32 tsc_khz; /* Dead? */ const char *dead; }; extern struct mutex lguest_lock; /* core.c: */ bool lguest_address_ok(const struct lguest *lg, unsigned long addr, unsigned long len); void __lgread(struct lg_cpu *, void *, unsigned long, unsigned); void __lgwrite(struct lg_cpu *, unsigned long, const void *, unsigned); extern struct page **lg_switcher_pages; /*H:035 * Using memory-copy operations like that is usually inconvient, so we * have the following helper macros which read and write a specific type (often * an unsigned long). * * This reads into a variable of the given type then returns that. */ #define lgread(cpu, addr, type) \ ({ type _v; __lgread((cpu), &_v, (addr), sizeof(_v)); _v; }) /* This checks that the variable is of the given type, then writes it out. */ #define lgwrite(cpu, addr, type, val) \ do { \ typecheck(type, val); \ __lgwrite((cpu), (addr), &(val), sizeof(val)); \ } while(0) /* (end of memory access helper routines) :*/ int run_guest(struct lg_cpu *cpu, unsigned long __user *user); /* * Helper macros to obtai