xen-asm_64.S 3.8 KB

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