1
2#ifndef _ASM_X86_KVM_PARA_H
3#define _ASM_X86_KVM_PARA_H
4
5#include <asm/processor.h>
6#include <asm/alternative.h>
7#include <linux/interrupt.h>
8#include <uapi/asm/kvm_para.h>
9
10#ifdef CONFIG_KVM_GUEST
11bool kvm_check_and_clear_guest_paused(void);
12#else
13static inline bool kvm_check_and_clear_guest_paused(void)
14{
15 return false;
16}
17#endif
18
19#define KVM_HYPERCALL \
20 ALTERNATIVE("vmcall", "vmmcall", X86_FEATURE_VMMCALL)
21
22
23
24
25
26
27
28
29
30
31
32static inline long kvm_hypercall0(unsigned int nr)
33{
34 long ret;
35 asm volatile(KVM_HYPERCALL
36 : "=a"(ret)
37 : "a"(nr)
38 : "memory");
39 return ret;
40}
41
42static inline long kvm_hypercall1(unsigned int nr, unsigned long p1)
43{
44 long ret;
45 asm volatile(KVM_HYPERCALL
46 : "=a"(ret)
47 : "a"(nr), "b"(p1)
48 : "memory");
49 return ret;
50}
51
52static inline long kvm_hypercall2(unsigned int nr, unsigned long p1,
53 unsigned long p2)
54{
55 long ret;
56 asm volatile(KVM_HYPERCALL
57 : "=a"(ret)
58 : "a"(nr), "b"(p1), "c"(p2)
59 : "memory");
60 return ret;
61}
62
63static inline long kvm_hypercall3(unsigned int nr, unsigned long p1,
64 unsigned long p2, unsigned long p3)
65{
66 long ret;
67 asm volatile(KVM_HYPERCALL
68 : "=a"(ret)
69 : "a"(nr), "b"(p1), "c"(p2), "d"(p3)
70 : "memory");
71 return ret;
72}
73
74static inline long kvm_hypercall4(unsigned int nr, unsigned long p1,
75 unsigned long p2, unsigned long p3,
76 unsigned long p4)
77{
78 long ret;
79 asm volatile(KVM_HYPERCALL
80 : "=a"(ret)
81 : "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4)
82 : "memory");
83 return ret;
84}
85
86#ifdef CONFIG_KVM_GUEST
87void kvmclock_init(void);
88void kvmclock_disable(void);
89bool kvm_para_available(void);
90unsigned int kvm_arch_para_features(void);
91unsigned int kvm_arch_para_hints(void);
92void kvm_async_pf_task_wait_schedule(u32 token);
93void kvm_async_pf_task_wake(u32 token);
94u32 kvm_read_and_reset_apf_flags(void);
95bool __kvm_handle_async_pf(struct pt_regs *regs, u32 token);
96
97DECLARE_STATIC_KEY_FALSE(kvm_async_pf_enabled);
98
99static __always_inline bool kvm_handle_async_pf(struct pt_regs *regs, u32 token)
100{
101 if (static_branch_unlikely(&kvm_async_pf_enabled))
102 return __kvm_handle_async_pf(regs, token);
103 else
104 return false;
105}
106
107#ifdef CONFIG_PARAVIRT_SPINLOCKS
108void __init kvm_spinlock_init(void);
109#else
110static inline void kvm_spinlock_init(void)
111{
112}
113#endif
114
115#else
116#define kvm_async_pf_task_wait_schedule(T) do {} while(0)
117#define kvm_async_pf_task_wake(T) do {} while(0)
118
119static inline bool kvm_para_available(void)
120{
121 return false;
122}
123
124static inline unsigned int kvm_arch_para_features(void)
125{
126 return 0;
127}
128
129static inline unsigned int kvm_arch_para_hints(void)
130{
131 return 0;
132}
133
134static inline u32 kvm_read_and_reset_apf_flags(void)
135{
136 return 0;
137}
138
139static __always_inline bool kvm_handle_async_pf(struct pt_regs *regs, u32 token)
140{
141 return false;
142}
143#endif
144
145#endif
146