11965aae3SH. Peter Anvin #ifndef _ASM_X86_VM86_H 21965aae3SH. Peter Anvin #define _ASM_X86_VM86_H 3bb898558SAl Viro 4bb898558SAl Viro #include <asm/ptrace.h> 5af170c50SDavid Howells #include <uapi/asm/vm86.h> 6bb898558SAl Viro 7bb898558SAl Viro /* 8bb898558SAl Viro * This is the (kernel) stack-layout when we have done a "SAVE_ALL" from vm86 9bb898558SAl Viro * mode - the main change is that the old segment descriptors aren't 10bb898558SAl Viro * useful any more and are forced to be zero by the kernel (and the 11bb898558SAl Viro * hardware when a trap occurs), and the real segment descriptors are 12bb898558SAl Viro * at the end of the structure. Look at ptrace.h to see the "normal" 13bb898558SAl Viro * setup. For user space layout see 'struct vm86_regs' above. 14bb898558SAl Viro */ 15bb898558SAl Viro 16bb898558SAl Viro struct kernel_vm86_regs { 17bb898558SAl Viro /* 18bb898558SAl Viro * normal regs, with special meaning for the segment descriptors.. 19bb898558SAl Viro */ 20bb898558SAl Viro struct pt_regs pt; 21bb898558SAl Viro /* 22bb898558SAl Viro * these are specific to v86 mode: 23bb898558SAl Viro */ 24bb898558SAl Viro unsigned short es, __esh; 25bb898558SAl Viro unsigned short ds, __dsh; 26bb898558SAl Viro unsigned short fs, __fsh; 27bb898558SAl Viro unsigned short gs, __gsh; 28bb898558SAl Viro }; 29bb898558SAl Viro 30bb898558SAl Viro struct kernel_vm86_struct { 31bb898558SAl Viro struct kernel_vm86_regs regs; 32bb898558SAl Viro /* 33bb898558SAl Viro * the below part remains on the kernel stack while we are in VM86 mode. 34bb898558SAl Viro * 'tss.esp0' then contains the address of VM86_TSS_ESP0 below, and when we 35bb898558SAl Viro * get forced back from VM86, the CPU and "SAVE_ALL" will restore the above 36bb898558SAl Viro * 'struct kernel_vm86_regs' with the then actual values. 37bb898558SAl Viro * Therefore, pt_regs in fact points to a complete 'kernel_vm86_struct' 38bb898558SAl Viro * in kernelspace, hence we need not reget the data from userspace. 39bb898558SAl Viro */ 40bb898558SAl Viro #define VM86_TSS_ESP0 flags 41bb898558SAl Viro unsigned long flags; 42bb898558SAl Viro unsigned long screen_bitmap; 43bb898558SAl Viro unsigned long cpu_type; 44bb898558SAl Viro struct revectored_struct int_revectored; 45bb898558SAl Viro struct revectored_struct int21_revectored; 46bb898558SAl Viro struct vm86plus_info_struct vm86plus; 47bb898558SAl Viro struct pt_regs *regs32; /* here we save the pointer to the old regs */ 48bb898558SAl Viro /* 49bb898558SAl Viro * The below is not part of the structure, but the stack layout continues 50bb898558SAl Viro * this way. In front of 'return-eip' may be some data, depending on 51bb898558SAl Viro * compilation, so we don't rely on this and save the pointer to 'oldregs' 52bb898558SAl Viro * in 'regs32' above. 53bb898558SAl Viro * However, with GCC-2.7.2 and the current CFLAGS you see exactly this: 54bb898558SAl Viro 55bb898558SAl Viro long return-eip; from call to vm86() 56bb898558SAl Viro struct pt_regs oldregs; user space registers as saved by syscall 57bb898558SAl Viro */ 58bb898558SAl Viro }; 59bb898558SAl Viro 60*9fda6a06SBrian Gerst struct vm86 { 61*9fda6a06SBrian Gerst struct vm86plus_struct __user *vm86_info; 62*9fda6a06SBrian Gerst unsigned long screen_bitmap; 63*9fda6a06SBrian Gerst unsigned long v86flags; 64*9fda6a06SBrian Gerst unsigned long v86mask; 65*9fda6a06SBrian Gerst unsigned long saved_sp0; 66*9fda6a06SBrian Gerst }; 67*9fda6a06SBrian Gerst 68bb898558SAl Viro #ifdef CONFIG_VM86 69bb898558SAl Viro 70bb898558SAl Viro void handle_vm86_fault(struct kernel_vm86_regs *, long); 71bb898558SAl Viro int handle_vm86_trap(struct kernel_vm86_regs *, long, int); 72bb898558SAl Viro struct pt_regs *save_v86_state(struct kernel_vm86_regs *); 73bb898558SAl Viro 74bb898558SAl Viro struct task_struct; 75bb898558SAl Viro void release_vm86_irqs(struct task_struct *); 76bb898558SAl Viro 77*9fda6a06SBrian Gerst #define free_vm86(t) do { \ 78*9fda6a06SBrian Gerst struct thread_struct *__t = (t); \ 79*9fda6a06SBrian Gerst if (__t->vm86 != NULL) { \ 80*9fda6a06SBrian Gerst kfree(__t->vm86); \ 81*9fda6a06SBrian Gerst __t->vm86 = NULL; \ 82*9fda6a06SBrian Gerst } \ 83*9fda6a06SBrian Gerst } while (0) 84*9fda6a06SBrian Gerst 85bb898558SAl Viro #else 86bb898558SAl Viro 87bb898558SAl Viro #define handle_vm86_fault(a, b) 88bb898558SAl Viro #define release_vm86_irqs(a) 89bb898558SAl Viro 90bb898558SAl Viro static inline int handle_vm86_trap(struct kernel_vm86_regs *a, long b, int c) 91bb898558SAl Viro { 92bb898558SAl Viro return 0; 93bb898558SAl Viro } 94bb898558SAl Viro 95*9fda6a06SBrian Gerst #define free_vm86(t) do { } while(0) 96*9fda6a06SBrian Gerst 97bb898558SAl Viro #endif /* CONFIG_VM86 */ 98bb898558SAl Viro 991965aae3SH. Peter Anvin #endif /* _ASM_X86_VM86_H */ 100