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 */ 40*d4ce0f26SBrian Gerst #define VM86_TSS_ESP0 regs32 41bb898558SAl Viro struct pt_regs *regs32; /* here we save the pointer to the old regs */ 42bb898558SAl Viro /* 43bb898558SAl Viro * The below is not part of the structure, but the stack layout continues 44bb898558SAl Viro * this way. In front of 'return-eip' may be some data, depending on 45bb898558SAl Viro * compilation, so we don't rely on this and save the pointer to 'oldregs' 46bb898558SAl Viro * in 'regs32' above. 47bb898558SAl Viro * However, with GCC-2.7.2 and the current CFLAGS you see exactly this: 48bb898558SAl Viro 49bb898558SAl Viro long return-eip; from call to vm86() 50bb898558SAl Viro struct pt_regs oldregs; user space registers as saved by syscall 51bb898558SAl Viro */ 52bb898558SAl Viro }; 53bb898558SAl Viro 549fda6a06SBrian Gerst struct vm86 { 559fda6a06SBrian Gerst struct vm86plus_struct __user *vm86_info; 569fda6a06SBrian Gerst unsigned long v86flags; 579fda6a06SBrian Gerst unsigned long v86mask; 589fda6a06SBrian Gerst unsigned long saved_sp0; 59*d4ce0f26SBrian Gerst 60*d4ce0f26SBrian Gerst unsigned long flags; 61*d4ce0f26SBrian Gerst unsigned long screen_bitmap; 62*d4ce0f26SBrian Gerst unsigned long cpu_type; 63*d4ce0f26SBrian Gerst struct revectored_struct int_revectored; 64*d4ce0f26SBrian Gerst struct revectored_struct int21_revectored; 65*d4ce0f26SBrian Gerst struct vm86plus_info_struct vm86plus; 669fda6a06SBrian Gerst }; 679fda6a06SBrian 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 779fda6a06SBrian Gerst #define free_vm86(t) do { \ 789fda6a06SBrian Gerst struct thread_struct *__t = (t); \ 799fda6a06SBrian Gerst if (__t->vm86 != NULL) { \ 809fda6a06SBrian Gerst kfree(__t->vm86); \ 819fda6a06SBrian Gerst __t->vm86 = NULL; \ 829fda6a06SBrian Gerst } \ 839fda6a06SBrian Gerst } while (0) 849fda6a06SBrian 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 959fda6a06SBrian Gerst #define free_vm86(t) do { } while(0) 969fda6a06SBrian Gerst 97bb898558SAl Viro #endif /* CONFIG_VM86 */ 98bb898558SAl Viro 991965aae3SH. Peter Anvin #endif /* _ASM_X86_VM86_H */ 100