Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
1965aae3 PA |
2 | #ifndef _ASM_X86_KVM_PARA_H |
3 | #define _ASM_X86_KVM_PARA_H | |
5f43238d | 4 | |
5f43238d | 5 | #include <asm/processor.h> |
c1118b36 | 6 | #include <asm/alternative.h> |
b1d40575 | 7 | #include <linux/interrupt.h> |
af170c50 | 8 | #include <uapi/asm/kvm_para.h> |
5f43238d | 9 | |
cfb8ec7a KS |
10 | #include <asm/tdx.h> |
11 | ||
90993cdd | 12 | #ifdef CONFIG_KVM_GUEST |
3b5d56b9 EM |
13 | bool kvm_check_and_clear_guest_paused(void); |
14 | #else | |
15 | static inline bool kvm_check_and_clear_guest_paused(void) | |
16 | { | |
17 | return false; | |
18 | } | |
90993cdd | 19 | #endif /* CONFIG_KVM_GUEST */ |
18068523 | 20 | |
c1118b36 | 21 | #define KVM_HYPERCALL \ |
4cb5b77e | 22 | ALTERNATIVE("vmcall", "vmmcall", X86_FEATURE_VMMCALL) |
5f43238d | 23 | |
e423ca15 | 24 | /* For KVM hypercalls, a three-byte sequence of either the vmcall or the vmmcall |
5f43238d CB |
25 | * instruction. The hypervisor may replace it with something else but only the |
26 | * instructions are guaranteed to be supported. | |
27 | * | |
28 | * Up to four arguments may be passed in rbx, rcx, rdx, and rsi respectively. | |
29 | * The hypercall number should be placed in rax and the return value will be | |
11393a07 | 30 | * placed in rax. No other registers will be clobbered unless explicitly |
5f43238d CB |
31 | * noted by the particular hypercall. |
32 | */ | |
33 | ||
34 | static inline long kvm_hypercall0(unsigned int nr) | |
35 | { | |
36 | long ret; | |
cfb8ec7a KS |
37 | |
38 | if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) | |
39 | return tdx_kvm_hypercall(nr, 0, 0, 0, 0); | |
40 | ||
5f43238d CB |
41 | asm volatile(KVM_HYPERCALL |
42 | : "=a"(ret) | |
ca373932 AL |
43 | : "a"(nr) |
44 | : "memory"); | |
5f43238d CB |
45 | return ret; |
46 | } | |
47 | ||
48 | static inline long kvm_hypercall1(unsigned int nr, unsigned long p1) | |
49 | { | |
50 | long ret; | |
cfb8ec7a KS |
51 | |
52 | if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) | |
53 | return tdx_kvm_hypercall(nr, p1, 0, 0, 0); | |
54 | ||
5f43238d CB |
55 | asm volatile(KVM_HYPERCALL |
56 | : "=a"(ret) | |
ca373932 AL |
57 | : "a"(nr), "b"(p1) |
58 | : "memory"); | |
5f43238d CB |
59 | return ret; |
60 | } | |
61 | ||
62 | static inline long kvm_hypercall2(unsigned int nr, unsigned long p1, | |
63 | unsigned long p2) | |
64 | { | |
65 | long ret; | |
cfb8ec7a KS |
66 | |
67 | if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) | |
68 | return tdx_kvm_hypercall(nr, p1, p2, 0, 0); | |
69 | ||
5f43238d CB |
70 | asm volatile(KVM_HYPERCALL |
71 | : "=a"(ret) | |
ca373932 AL |
72 | : "a"(nr), "b"(p1), "c"(p2) |
73 | : "memory"); | |
5f43238d CB |
74 | return ret; |
75 | } | |
76 | ||
77 | static inline long kvm_hypercall3(unsigned int nr, unsigned long p1, | |
78 | unsigned long p2, unsigned long p3) | |
79 | { | |
80 | long ret; | |
cfb8ec7a KS |
81 | |
82 | if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) | |
83 | return tdx_kvm_hypercall(nr, p1, p2, p3, 0); | |
84 | ||
5f43238d CB |
85 | asm volatile(KVM_HYPERCALL |
86 | : "=a"(ret) | |
ca373932 AL |
87 | : "a"(nr), "b"(p1), "c"(p2), "d"(p3) |
88 | : "memory"); | |
5f43238d CB |
89 | return ret; |
90 | } | |
91 | ||
92 | static inline long kvm_hypercall4(unsigned int nr, unsigned long p1, | |
93 | unsigned long p2, unsigned long p3, | |
94 | unsigned long p4) | |
95 | { | |
96 | long ret; | |
cfb8ec7a KS |
97 | |
98 | if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) | |
99 | return tdx_kvm_hypercall(nr, p1, p2, p3, p4); | |
100 | ||
5f43238d CB |
101 | asm volatile(KVM_HYPERCALL |
102 | : "=a"(ret) | |
ca373932 AL |
103 | : "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4) |
104 | : "memory"); | |
5f43238d CB |
105 | return ret; |
106 | } | |
107 | ||
08c2336d BS |
108 | static inline long kvm_sev_hypercall3(unsigned int nr, unsigned long p1, |
109 | unsigned long p2, unsigned long p3) | |
110 | { | |
111 | long ret; | |
112 | ||
113 | asm volatile("vmmcall" | |
114 | : "=a"(ret) | |
115 | : "a"(nr), "b"(p1), "c"(p2), "d"(p3) | |
116 | : "memory"); | |
117 | return ret; | |
118 | } | |
119 | ||
ba492962 | 120 | #ifdef CONFIG_KVM_GUEST |
c02027b5 VK |
121 | void kvmclock_init(void); |
122 | void kvmclock_disable(void); | |
1c300a40 | 123 | bool kvm_para_available(void); |
77f01bdf | 124 | unsigned int kvm_arch_para_features(void); |
a4429e53 | 125 | unsigned int kvm_arch_para_hints(void); |
6bca69ad | 126 | void kvm_async_pf_task_wait_schedule(u32 token); |
631bc487 | 127 | void kvm_async_pf_task_wake(u32 token); |
68fd66f1 | 128 | u32 kvm_read_and_reset_apf_flags(void); |
ef68017e AL |
129 | bool __kvm_handle_async_pf(struct pt_regs *regs, u32 token); |
130 | ||
131 | DECLARE_STATIC_KEY_FALSE(kvm_async_pf_enabled); | |
132 | ||
133 | static __always_inline bool kvm_handle_async_pf(struct pt_regs *regs, u32 token) | |
134 | { | |
135 | if (static_branch_unlikely(&kvm_async_pf_enabled)) | |
136 | return __kvm_handle_async_pf(regs, token); | |
137 | else | |
138 | return false; | |
139 | } | |
92b75202 SV |
140 | |
141 | #ifdef CONFIG_PARAVIRT_SPINLOCKS | |
142 | void __init kvm_spinlock_init(void); | |
143 | #else /* !CONFIG_PARAVIRT_SPINLOCKS */ | |
144 | static inline void kvm_spinlock_init(void) | |
145 | { | |
146 | } | |
147 | #endif /* CONFIG_PARAVIRT_SPINLOCKS */ | |
148 | ||
149 | #else /* CONFIG_KVM_GUEST */ | |
6bca69ad | 150 | #define kvm_async_pf_task_wait_schedule(T) do {} while(0) |
631bc487 | 151 | #define kvm_async_pf_task_wake(T) do {} while(0) |
92b75202 | 152 | |
1c300a40 PB |
153 | static inline bool kvm_para_available(void) |
154 | { | |
1d804d07 | 155 | return false; |
1c300a40 PB |
156 | } |
157 | ||
77f01bdf PB |
158 | static inline unsigned int kvm_arch_para_features(void) |
159 | { | |
160 | return 0; | |
161 | } | |
162 | ||
a4429e53 WL |
163 | static inline unsigned int kvm_arch_para_hints(void) |
164 | { | |
165 | return 0; | |
166 | } | |
167 | ||
68fd66f1 | 168 | static inline u32 kvm_read_and_reset_apf_flags(void) |
631bc487 GN |
169 | { |
170 | return 0; | |
171 | } | |
d910f5c1 | 172 | |
2823e83a | 173 | static __always_inline bool kvm_handle_async_pf(struct pt_regs *regs, u32 token) |
ef68017e AL |
174 | { |
175 | return false; | |
176 | } | |
5f43238d CB |
177 | #endif |
178 | ||
1965aae3 | 179 | #endif /* _ASM_X86_KVM_PARA_H */ |