Merge tag 'fbdev-v4.14' of git://github.com/bzolnier/linux
[linux-2.6-microblaze.git] / arch / x86 / xen / xen-asm_64.S
1 /*
2  * Asm versions of Xen pv-ops, suitable for direct use.
3  *
4  * We only bother with direct forms (ie, vcpu in pda) of the
5  * operations here; the indirect forms are better handled in C.
6  */
7
8 #include <asm/errno.h>
9 #include <asm/percpu.h>
10 #include <asm/processor-flags.h>
11 #include <asm/segment.h>
12 #include <asm/asm-offsets.h>
13 #include <asm/thread_info.h>
14
15 #include <xen/interface/xen.h>
16
17 #include <linux/linkage.h>
18
19 .macro xen_pv_trap name
20 ENTRY(xen_\name)
21         pop %rcx
22         pop %r11
23         jmp  \name
24 END(xen_\name)
25 .endm
26
27 xen_pv_trap divide_error
28 xen_pv_trap debug
29 xen_pv_trap xendebug
30 xen_pv_trap int3
31 xen_pv_trap xenint3
32 xen_pv_trap nmi
33 xen_pv_trap overflow
34 xen_pv_trap bounds
35 xen_pv_trap invalid_op
36 xen_pv_trap device_not_available
37 xen_pv_trap double_fault
38 xen_pv_trap coprocessor_segment_overrun
39 xen_pv_trap invalid_TSS
40 xen_pv_trap segment_not_present
41 xen_pv_trap stack_segment
42 xen_pv_trap general_protection
43 xen_pv_trap page_fault
44 xen_pv_trap spurious_interrupt_bug
45 xen_pv_trap coprocessor_error
46 xen_pv_trap alignment_check
47 #ifdef CONFIG_X86_MCE
48 xen_pv_trap machine_check
49 #endif /* CONFIG_X86_MCE */
50 xen_pv_trap simd_coprocessor_error
51 #ifdef CONFIG_IA32_EMULATION
52 xen_pv_trap entry_INT80_compat
53 #endif
54 xen_pv_trap hypervisor_callback
55
56 hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32
57 /*
58  * Xen64 iret frame:
59  *
60  *      ss
61  *      rsp
62  *      rflags
63  *      cs
64  *      rip             <-- standard iret frame
65  *
66  *      flags
67  *
68  *      rcx             }
69  *      r11             }<-- pushed by hypercall page
70  * rsp->rax             }
71  */
72 ENTRY(xen_iret)
73         pushq $0
74         jmp hypercall_iret
75
76 ENTRY(xen_sysret64)
77         /*
78          * We're already on the usermode stack at this point, but
79          * still with the kernel gs, so we can easily switch back
80          */
81         movq %rsp, PER_CPU_VAR(rsp_scratch)
82         movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
83
84         pushq $__USER_DS
85         pushq PER_CPU_VAR(rsp_scratch)
86         pushq %r11
87         pushq $__USER_CS
88         pushq %rcx
89
90         pushq $VGCF_in_syscall
91         jmp hypercall_iret
92
93 /*
94  * Xen handles syscall callbacks much like ordinary exceptions, which
95  * means we have:
96  * - kernel gs
97  * - kernel rsp
98  * - an iret-like stack frame on the stack (including rcx and r11):
99  *      ss
100  *      rsp
101  *      rflags
102  *      cs
103  *      rip
104  *      r11
105  * rsp->rcx
106  */
107
108 /* Normal 64-bit system call target */
109 ENTRY(xen_syscall_target)
110         popq %rcx
111         popq %r11
112
113         /*
114          * Neither Xen nor the kernel really knows what the old SS and
115          * CS were.  The kernel expects __USER_DS and __USER_CS, so
116          * report those values even though Xen will guess its own values.
117          */
118         movq $__USER_DS, 4*8(%rsp)
119         movq $__USER_CS, 1*8(%rsp)
120
121         jmp entry_SYSCALL_64_after_hwframe
122 ENDPROC(xen_syscall_target)
123
124 #ifdef CONFIG_IA32_EMULATION
125
126 /* 32-bit compat syscall target */
127 ENTRY(xen_syscall32_target)
128         popq %rcx
129         popq %r11
130
131         /*
132          * Neither Xen nor the kernel really knows what the old SS and
133          * CS were.  The kernel expects __USER32_DS and __USER32_CS, so
134          * report those values even though Xen will guess its own values.
135          */
136         movq $__USER32_DS, 4*8(%rsp)
137         movq $__USER32_CS, 1*8(%rsp)
138
139         jmp entry_SYSCALL_compat_after_hwframe
140 ENDPROC(xen_syscall32_target)
141
142 /* 32-bit compat sysenter target */
143 ENTRY(xen_sysenter_target)
144         mov 0*8(%rsp), %rcx
145         mov 1*8(%rsp), %r11
146         mov 5*8(%rsp), %rsp
147         jmp entry_SYSENTER_compat
148 ENDPROC(xen_sysenter_target)
149
150 #else /* !CONFIG_IA32_EMULATION */
151
152 ENTRY(xen_syscall32_target)
153 ENTRY(xen_sysenter_target)
154         lea 16(%rsp), %rsp      /* strip %rcx, %r11 */
155         mov $-ENOSYS, %rax
156         pushq $0
157         jmp hypercall_iret
158 ENDPROC(xen_syscall32_target)
159 ENDPROC(xen_sysenter_target)
160
161 #endif  /* CONFIG_IA32_EMULATION */