File Index
Files and directories
Sign in
FILE

kvm_para.h

File preview with syntax highlighting.

linux-6.19.14/arch/x86/include/asm/kvm_para.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  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#include <asm/tdx.h>
 11
 12#ifdef CONFIG_KVM_GUEST
 13bool kvm_check_and_clear_guest_paused(void);
 14#else
 15static inline bool kvm_check_and_clear_guest_paused(void)
 16{
 17	return false;
 18}
 19#endif /* CONFIG_KVM_GUEST */
 20
 21#define KVM_HYPERCALL \
 22        ALTERNATIVE("vmcall", "vmmcall", X86_FEATURE_VMMCALL)
 23
 24/* For KVM hypercalls, a three-byte sequence of either the vmcall or the vmmcall
 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
 30 * placed in rax.  No other registers will be clobbered unless explicitly
 31 * noted by the particular hypercall.
 32 */
 33
 34static inline long kvm_hypercall0(unsigned int nr)
 35{
 36	long ret;
 37
 38	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
 39		return tdx_kvm_hypercall(nr, 0, 0, 0, 0);
 40
 41	asm volatile(KVM_HYPERCALL
 42		     : "=a"(ret)
 43		     : "a"(nr)
 44		     : "memory");
 45	return ret;
 46}
 47
 48static inline long kvm_hypercall1(unsigned int nr, unsigned long p1)
 49{
 50	long ret;
 51
 52	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
 53		return tdx_kvm_hypercall(nr, p1, 0, 0, 0);
 54
 55	asm volatile(KVM_HYPERCALL
 56		     : "=a"(ret)
 57		     : "a"(nr), "b"(p1)
 58		     : "memory");
 59	return ret;
 60}
 61
 62static inline long kvm_hypercall2(unsigned int nr, unsigned long p1,
 63				  unsigned long p2)
 64{
 65	long ret;
 66
 67	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
 68		return tdx_kvm_hypercall(nr, p1, p2, 0, 0);
 69
 70	asm volatile(KVM_HYPERCALL
 71		     : "=a"(ret)
 72		     : "a"(nr), "b"(p1), "c"(p2)
 73		     : "memory");
 74	return ret;
 75}
 76
 77static inline long kvm_hypercall3(unsigned int nr, unsigned long p1,
 78				  unsigned long p2, unsigned long p3)
 79{
 80	long ret;
 81
 82	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
 83		return tdx_kvm_hypercall(nr, p1, p2, p3, 0);
 84
 85	asm volatile(KVM_HYPERCALL
 86		     : "=a"(ret)
 87		     : "a"(nr), "b"(p1), "c"(p2), "d"(p3)
 88		     : "memory");
 89	return ret;
 90}
 91
 92static 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;
 97
 98	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
 99		return tdx_kvm_hypercall(nr, p1, p2, p3, p4);
100
101	asm volatile(KVM_HYPERCALL
102		     : "=a"(ret)
103		     : "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4)
104		     : "memory");
105	return ret;
106}
107
108static 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
120#ifdef CONFIG_KVM_GUEST
121void kvmclock_init(void);
122void kvmclock_disable(void);
123bool kvm_para_available(void);
124unsigned int kvm_arch_para_features(void);
125unsigned int kvm_arch_para_hints(void);
126void kvm_async_pf_task_wait_schedule(u32 token);
127u32 kvm_read_and_reset_apf_flags(void);
128bool __kvm_handle_async_pf(struct pt_regs *regs, u32 token);
129
130DECLARE_STATIC_KEY_FALSE(kvm_async_pf_enabled);
131
132static __always_inline bool kvm_handle_async_pf(struct pt_regs *regs, u32 token)
133{
134	if (static_branch_unlikely(&kvm_async_pf_enabled))
135		return __kvm_handle_async_pf(regs, token);
136	else
137		return false;
138}
139
140#ifdef CONFIG_PARAVIRT_SPINLOCKS
141void __init kvm_spinlock_init(void);
142#else /* !CONFIG_PARAVIRT_SPINLOCKS */
143static inline void kvm_spinlock_init(void)
144{
145}
146#endif /* CONFIG_PARAVIRT_SPINLOCKS */
147
148#else /* CONFIG_KVM_GUEST */
149#define kvm_async_pf_task_wait_schedule(T) do {} while(0)
150
151static inline bool kvm_para_available(void)
152{
153	return false;
154}
155
156static inline unsigned int kvm_arch_para_features(void)
157{
158	return 0;
159}
160
161static inline unsigned int kvm_arch_para_hints(void)
162{
163	return 0;
164}
165
166static inline u32 kvm_read_and_reset_apf_flags(void)
167{
168	return 0;
169}
170
171static __always_inline bool kvm_handle_async_pf(struct pt_regs *regs, u32 token)
172{
173	return false;
174}
175#endif
176
177#endif /* _ASM_X86_KVM_PARA_H */
~/ Read-only file preview.