1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _ASM_LOONGARCH_KVM_PARA_H 3 #define _ASM_LOONGARCH_KVM_PARA_H 4 5 #include <uapi/asm/kvm_para.h> 6 7 /* 8 * Hypercall code field 9 */ 10 #define HYPERVISOR_KVM 1 11 #define HYPERVISOR_VENDOR_SHIFT 8 12 #define HYPERCALL_ENCODE(vendor, code) ((vendor << HYPERVISOR_VENDOR_SHIFT) + code) 13 14 #define KVM_HCALL_CODE_SERVICE 0 15 #define KVM_HCALL_CODE_SWDBG 1 16 #define KVM_HCALL_CODE_USER_SERVICE 2 17 18 #define KVM_HCALL_SERVICE HYPERCALL_ENCODE(HYPERVISOR_KVM, KVM_HCALL_CODE_SERVICE) 19 #define KVM_HCALL_FUNC_IPI 1 20 #define KVM_HCALL_FUNC_NOTIFY 2 21 22 #define KVM_HCALL_SWDBG HYPERCALL_ENCODE(HYPERVISOR_KVM, KVM_HCALL_CODE_SWDBG) 23 24 #define KVM_HCALL_USER_SERVICE HYPERCALL_ENCODE(HYPERVISOR_KVM, KVM_HCALL_CODE_USER_SERVICE) 25 26 /* 27 * LoongArch hypercall return code 28 */ 29 #define KVM_HCALL_SUCCESS 0 30 #define KVM_HCALL_INVALID_CODE -1UL 31 #define KVM_HCALL_INVALID_PARAMETER -2UL 32 33 #define KVM_STEAL_PHYS_VALID BIT_ULL(0) 34 #define KVM_STEAL_PHYS_MASK GENMASK_ULL(63, 6) 35 36 struct kvm_steal_time { 37 __u64 steal; 38 __u32 version; 39 __u32 flags; 40 __u8 preempted; 41 __u8 pad[47]; 42 }; 43 #define KVM_VCPU_PREEMPTED (1 << 0) 44 45 /* 46 * Hypercall interface for KVM hypervisor 47 * 48 * a0: function identifier 49 * a1-a5: args 50 * Return value will be placed in a0. 51 * Up to 5 arguments are passed in a1, a2, a3, a4, a5. 52 */ 53 static __always_inline long kvm_hypercall0(u64 fid) 54 { 55 register long ret asm("a0"); 56 register unsigned long fun asm("a0") = fid; 57 58 __asm__ __volatile__( 59 "hvcl "__stringify(KVM_HCALL_SERVICE) 60 : "=r" (ret) 61 : "r" (fun) 62 : "memory" 63 ); 64 65 return ret; 66 } 67 68 static __always_inline long kvm_hypercall1(u64 fid, unsigned long arg0) 69 { 70 register long ret asm("a0"); 71 register unsigned long fun asm("a0") = fid; 72 register unsigned long a1 asm("a1") = arg0; 73 74 __asm__ __volatile__( 75 "hvcl "__stringify(KVM_HCALL_SERVICE) 76 : "=r" (ret) 77 : "r" (fun), "r" (a1) 78 : "memory" 79 ); 80 81 return ret; 82 } 83 84 static __always_inline long kvm_hypercall2(u64 fid, 85 unsigned long arg0, unsigned long arg1) 86 { 87 register long ret asm("a0"); 88 register unsigned long fun asm("a0") = fid; 89 register unsigned long a1 asm("a1") = arg0; 90 register unsigned long a2 asm("a2") = arg1; 91 92 __asm__ __volatile__( 93 "hvcl "__stringify(KVM_HCALL_SERVICE) 94 : "=r" (ret) 95 : "r" (fun), "r" (a1), "r" (a2) 96 : "memory" 97 ); 98 99 return ret; 100 } 101 102 static __always_inline long kvm_hypercall3(u64 fid, 103 unsigned long arg0, unsigned long arg1, unsigned long arg2) 104 { 105 register long ret asm("a0"); 106 register unsigned long fun asm("a0") = fid; 107 register unsigned long a1 asm("a1") = arg0; 108 register unsigned long a2 asm("a2") = arg1; 109 register unsigned long a3 asm("a3") = arg2; 110 111 __asm__ __volatile__( 112 "hvcl "__stringify(KVM_HCALL_SERVICE) 113 : "=r" (ret) 114 : "r" (fun), "r" (a1), "r" (a2), "r" (a3) 115 : "memory" 116 ); 117 118 return ret; 119 } 120 121 static __always_inline long kvm_hypercall4(u64 fid, 122 unsigned long arg0, unsigned long arg1, 123 unsigned long arg2, unsigned long arg3) 124 { 125 register long ret asm("a0"); 126 register unsigned long fun asm("a0") = fid; 127 register unsigned long a1 asm("a1") = arg0; 128 register unsigned long a2 asm("a2") = arg1; 129 register unsigned long a3 asm("a3") = arg2; 130 register unsigned long a4 asm("a4") = arg3; 131 132 __asm__ __volatile__( 133 "hvcl "__stringify(KVM_HCALL_SERVICE) 134 : "=r" (ret) 135 : "r"(fun), "r" (a1), "r" (a2), "r" (a3), "r" (a4) 136 : "memory" 137 ); 138 139 return ret; 140 } 141 142 static __always_inline long kvm_hypercall5(u64 fid, 143 unsigned long arg0, unsigned long arg1, 144 unsigned long arg2, unsigned long arg3, unsigned long arg4) 145 { 146 register long ret asm("a0"); 147 register unsigned long fun asm("a0") = fid; 148 register unsigned long a1 asm("a1") = arg0; 149 register unsigned long a2 asm("a2") = arg1; 150 register unsigned long a3 asm("a3") = arg2; 151 register unsigned long a4 asm("a4") = arg3; 152 register unsigned long a5 asm("a5") = arg4; 153 154 __asm__ __volatile__( 155 "hvcl "__stringify(KVM_HCALL_SERVICE) 156 : "=r" (ret) 157 : "r"(fun), "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5) 158 : "memory" 159 ); 160 161 return ret; 162 } 163 164 #ifdef CONFIG_PARAVIRT 165 bool kvm_para_available(void); 166 unsigned int kvm_arch_para_features(void); 167 #else 168 static inline bool kvm_para_available(void) 169 { 170 return false; 171 } 172 173 static inline unsigned int kvm_arch_para_features(void) 174 { 175 return 0; 176 } 177 #endif 178 179 static inline unsigned int kvm_arch_para_hints(void) 180 { 181 return 0; 182 } 183 184 static inline bool kvm_check_and_clear_guest_paused(void) 185 { 186 return false; 187 } 188 189 #endif /* _ASM_LOONGARCH_KVM_PARA_H */ 190