Line data Source code
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 : extern void kvmclock_init(void); 11 : 12 : #ifdef CONFIG_KVM_GUEST 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 : } 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 : 34 : static inline long kvm_hypercall0(unsigned int nr) 35 : { 36 : long ret; 37 : asm volatile(KVM_HYPERCALL 38 : : "=a"(ret) 39 : : "a"(nr) 40 : : "memory"); 41 : return ret; 42 : } 43 : 44 32 : static inline long kvm_hypercall1(unsigned int nr, unsigned long p1) 45 : { 46 32 : long ret; 47 32 : asm volatile(KVM_HYPERCALL 48 : : "=a"(ret) 49 : : "a"(nr), "b"(p1) 50 : : "memory"); 51 32 : return ret; 52 : } 53 : 54 76 : static inline long kvm_hypercall2(unsigned int nr, unsigned long p1, 55 : unsigned long p2) 56 : { 57 76 : long ret; 58 76 : asm volatile(KVM_HYPERCALL 59 : : "=a"(ret) 60 : : "a"(nr), "b"(p1), "c"(p2) 61 : : "memory"); 62 76 : return ret; 63 : } 64 : 65 : static inline long kvm_hypercall3(unsigned int nr, unsigned long p1, 66 : unsigned long p2, unsigned long p3) 67 : { 68 : long ret; 69 : asm volatile(KVM_HYPERCALL 70 : : "=a"(ret) 71 : : "a"(nr), "b"(p1), "c"(p2), "d"(p3) 72 : : "memory"); 73 : return ret; 74 : } 75 : 76 14417 : static inline long kvm_hypercall4(unsigned int nr, unsigned long p1, 77 : unsigned long p2, unsigned long p3, 78 : unsigned long p4) 79 : { 80 14417 : long ret; 81 14417 : asm volatile(KVM_HYPERCALL 82 : : "=a"(ret) 83 : : "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4) 84 : : "memory"); 85 14417 : return ret; 86 : } 87 : 88 : #ifdef CONFIG_KVM_GUEST 89 : bool kvm_para_available(void); 90 : unsigned int kvm_arch_para_features(void); 91 : unsigned int kvm_arch_para_hints(void); 92 : void kvm_async_pf_task_wait_schedule(u32 token); 93 : void kvm_async_pf_task_wake(u32 token); 94 : u32 kvm_read_and_reset_apf_flags(void); 95 : void kvm_disable_steal_time(void); 96 : bool __kvm_handle_async_pf(struct pt_regs *regs, u32 token); 97 : 98 : DECLARE_STATIC_KEY_FALSE(kvm_async_pf_enabled); 99 : 100 295871 : static __always_inline bool kvm_handle_async_pf(struct pt_regs *regs, u32 token) 101 : { 102 295871 : if (static_branch_unlikely(&kvm_async_pf_enabled)) 103 0 : return __kvm_handle_async_pf(regs, token); 104 : else 105 : return false; 106 : } 107 : 108 : #ifdef CONFIG_PARAVIRT_SPINLOCKS 109 : void __init kvm_spinlock_init(void); 110 : #else /* !CONFIG_PARAVIRT_SPINLOCKS */ 111 : static inline void kvm_spinlock_init(void) 112 : { 113 : } 114 : #endif /* CONFIG_PARAVIRT_SPINLOCKS */ 115 : 116 : #else /* CONFIG_KVM_GUEST */ 117 : #define kvm_async_pf_task_wait_schedule(T) do {} while(0) 118 : #define kvm_async_pf_task_wake(T) do {} while(0) 119 : 120 : static inline bool kvm_para_available(void) 121 : { 122 : return false; 123 : } 124 : 125 : static inline unsigned int kvm_arch_para_features(void) 126 : { 127 : return 0; 128 : } 129 : 130 : static inline unsigned int kvm_arch_para_hints(void) 131 : { 132 : return 0; 133 : } 134 : 135 : static inline u32 kvm_read_and_reset_apf_flags(void) 136 : { 137 : return 0; 138 : } 139 : 140 : static inline void kvm_disable_steal_time(void) 141 : { 142 : return; 143 : } 144 : 145 : static __always_inline bool kvm_handle_async_pf(struct pt_regs *regs, u32 token) 146 : { 147 : return false; 148 : } 149 : #endif 150 : 151 : #endif /* _ASM_X86_KVM_PARA_H */