kvm_para.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #ifndef _ASM_X86_KVM_PARA_H
  2. #define _ASM_X86_KVM_PARA_H
  3. #include <asm/processor.h>
  4. #include <uapi/asm/kvm_para.h>
  5. extern void kvmclock_init(void);
  6. extern int kvm_register_clock(char *txt);
  7. #ifdef CONFIG_KVM_GUEST
  8. bool kvm_check_and_clear_guest_paused(void);
  9. #else
  10. static inline bool kvm_check_and_clear_guest_paused(void)
  11. {
  12. return false;
  13. }
  14. #endif /* CONFIG_KVM_GUEST */
  15. /* This instruction is vmcall. On non-VT architectures, it will generate a
  16. * trap that we will then rewrite to the appropriate instruction.
  17. */
  18. #define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1"
  19. /* For KVM hypercalls, a three-byte sequence of either the vmcall or the vmmcall
  20. * instruction. The hypervisor may replace it with something else but only the
  21. * instructions are guaranteed to be supported.
  22. *
  23. * Up to four arguments may be passed in rbx, rcx, rdx, and rsi respectively.
  24. * The hypercall number should be placed in rax and the return value will be
  25. * placed in rax. No other registers will be clobbered unless explicitly
  26. * noted by the particular hypercall.
  27. */
  28. static inline long kvm_hypercall0(unsigned int nr)
  29. {
  30. long ret;
  31. asm volatile(KVM_HYPERCALL
  32. : "=a"(ret)
  33. : "a"(nr)
  34. : "memory");
  35. return ret;
  36. }
  37. static inline long kvm_hypercall1(unsigned int nr, unsigned long p1)
  38. {
  39. long ret;
  40. asm volatile(KVM_HYPERCALL
  41. : "=a"(ret)
  42. : "a"(nr), "b"(p1)
  43. : "memory");
  44. return ret;
  45. }
  46. static inline long kvm_hypercall2(unsigned int nr, unsigned long p1,
  47. unsigned long p2)
  48. {
  49. long ret;
  50. asm volatile(KVM_HYPERCALL
  51. : "=a"(ret)
  52. : "a"(nr), "b"(p1), "c"(p2)
  53. : "memory");
  54. return ret;
  55. }
  56. static inline long kvm_hypercall3(unsigned int nr, unsigned long p1,
  57. unsigned long p2, unsigned long p3)
  58. {
  59. long ret;
  60. asm volatile(KVM_HYPERCALL
  61. : "=a"(ret)
  62. : "a"(nr), "b"(p1), "c"(p2), "d"(p3)
  63. : "memory");
  64. return ret;
  65. }
  66. static inline long kvm_hypercall4(unsigned int nr, unsigned long p1,
  67. unsigned long p2, unsigned long p3,
  68. unsigned long p4)
  69. {
  70. long ret;
  71. asm volatile(KVM_HYPERCALL
  72. : "=a"(ret)
  73. : "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4)
  74. : "memory");
  75. return ret;
  76. }
  77. static inline bool kvm_para_available(void)
  78. {
  79. unsigned int eax, ebx, ecx, edx;
  80. char signature[13];
  81. if (boot_cpu_data.cpuid_level < 0)
  82. return false; /* So we don't blow up on old processors */
  83. if (cpu_has_hypervisor) {
  84. cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx);
  85. memcpy(signature + 0, &ebx, 4);
  86. memcpy(signature + 4, &ecx, 4);
  87. memcpy(signature + 8, &edx, 4);
  88. signature[12] = 0;
  89. if (strcmp(signature, "KVMKVMKVM") == 0)
  90. return true;
  91. }
  92. return false;
  93. }
  94. static inline unsigned int kvm_arch_para_features(void)
  95. {
  96. return cpuid_eax(KVM_CPUID_FEATURES);
  97. }
  98. #ifdef CONFIG_KVM_GUEST
  99. void __init kvm_guest_init(void);
  100. void kvm_async_pf_task_wait(u32 token);
  101. void kvm_async_pf_task_wake(u32 token);
  102. u32 kvm_read_and_reset_pf_reason(void);
  103. extern void kvm_disable_steal_time(void);
  104. #else
  105. #define kvm_guest_init() do { } while (0)
  106. #define kvm_async_pf_task_wait(T) do {} while(0)
  107. #define kvm_async_pf_task_wake(T) do {} while(0)
  108. static inline u32 kvm_read_and_reset_pf_reason(void)
  109. {
  110. return 0;
  111. }
  112. static inline void kvm_disable_steal_time(void)
  113. {
  114. return;
  115. }
  116. #endif
  117. #endif /* _ASM_X86_KVM_PARA_H */