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#define KVM_HYPERCALL ".word 0x002b8000" 8/* 9 * Hypcall code field 10 */ 11#define KVM_HC_CODE_SERIVCE 0x0 12#define KVM_HC_CODE_SWDBG 0x5 13/* 14 * function id 15 * 0x00000 ~ 0xfffff Standard Hypervisor Calls 16 */ 17#define KVM_HC_FUNC_FEATURE 0x0 18#define KVM_HC_FUNC_NOTIFY 0x1 19#define KVM_HC_FUNC_IPI 0x2 20/* 21 * LoongArch support PV feature list 22 */ 23#define KVM_FEATURE_STEAL_TIME 0 24#define KVM_FEATURE_MULTI_IPI 1 25#define KVM_FEATURE_PARAVIRT_SPINLOCK 2 26/* 27 * LoongArch hypcall return code 28 */ 29#define KVM_RET_SUC 1 30#define KVM_RET_NOT_SUPPORTED -1 31 32#define KVM_VCPU_PREEMPTED (1 << 0) 33 34/* 35 * Hypercalls interface for KVM. 36 * 37 * a0: function identifier 38 * a1-a6: args 39 * Return value will be placed in v0. 40 * Up to 6 arguments are passed in a1, a2, a3, a4, a5, a6. 41 */ 42static inline long kvm_hypercall0(u64 fid) 43{ 44 register long ret asm("v0"); 45 register unsigned long fun asm("a0") = fid; 46 47 __asm__ __volatile__( 48 KVM_HYPERCALL 49 : "=r" (ret) 50 : "r" (fun) 51 : "memory" 52 ); 53 54 return ret; 55} 56 57static inline long kvm_hypercall1(u64 fid, unsigned long arg0) 58{ 59 register long ret asm("v0"); 60 register unsigned long fun asm("a0") = fid; 61 register unsigned long a1 asm("a1") = arg0; 62 63 __asm__ __volatile__( 64 KVM_HYPERCALL 65 : "=r" (ret) 66 : "r" (fun), "r" (a1) 67 : "memory" 68 ); 69 70 return ret; 71} 72 73static inline long kvm_hypercall2(u64 fid, 74 unsigned long arg0, unsigned long arg1) 75{ 76 register long ret asm("v0"); 77 register unsigned long fun asm("a0") = fid; 78 register unsigned long a1 asm("a1") = arg0; 79 register unsigned long a2 asm("a2") = arg1; 80 81 __asm__ __volatile__( 82 KVM_HYPERCALL 83 : "=r" (ret) 84 : "r" (fun), "r" (a1), "r" (a2) 85 : "memory" 86 ); 87 88 return ret; 89} 90 91static inline long kvm_hypercall3(u64 fid, 92 unsigned long arg0, unsigned long arg1, unsigned long arg2) 93{ 94 register long ret asm("v0"); 95 register unsigned long fun asm("a0") = fid; 96 register unsigned long a1 asm("a1") = arg0; 97 register unsigned long a2 asm("a2") = arg1; 98 register unsigned long a3 asm("a3") = arg2; 99 100 __asm__ __volatile__( 101 KVM_HYPERCALL 102 : "=r" (ret) 103 : "r" (fun), "r" (a1), "r" (a2), "r" (a3) 104 : "memory" 105 ); 106 107 return ret; 108} 109 110static inline long kvm_hypercall4(u64 fid, 111 unsigned long arg0, unsigned long arg1, unsigned long arg2, 112 unsigned long arg3) 113{ 114 register long ret asm("v0"); 115 register unsigned long fun asm("a0") = fid; 116 register unsigned long a1 asm("a1") = arg0; 117 register unsigned long a2 asm("a2") = arg1; 118 register unsigned long a3 asm("a3") = arg2; 119 register unsigned long a4 asm("a4") = arg3; 120 121 __asm__ __volatile__( 122 KVM_HYPERCALL 123 : "=r" (ret) 124 : "i"(fun), "r" (a1), "r" (a2), "r" (a3), "r" (a4) 125 : "memory" 126 ); 127 128 return ret; 129} 130 131static inline long kvm_hypercall5(u64 fid, 132 unsigned long arg0, unsigned long arg1, unsigned long arg2, 133 unsigned long arg3, unsigned long arg4) 134{ 135 register long ret asm("v0"); 136 register unsigned long fun asm("a0") = fid; 137 register unsigned long a1 asm("a1") = arg0; 138 register unsigned long a2 asm("a2") = arg1; 139 register unsigned long a3 asm("a3") = arg2; 140 register unsigned long a4 asm("a4") = arg3; 141 register unsigned long a5 asm("a5") = arg4; 142 143 __asm__ __volatile__( 144 KVM_HYPERCALL 145 : "=r" (ret) 146 : "i"(fun), "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5) 147 : "memory" 148 ); 149 150 return ret; 151} 152 153static inline long kvm_hypercall6(u64 fid, 154 unsigned long arg0, unsigned long arg1, unsigned long arg2, 155 unsigned long arg3, unsigned long arg4, unsigned long arg5) 156{ 157 register long ret asm("v0"); 158 register unsigned long fun asm("a0") = fid; 159 register unsigned long a1 asm("a1") = arg0; 160 register unsigned long a2 asm("a2") = arg1; 161 register unsigned long a3 asm("a3") = arg2; 162 register unsigned long a4 asm("a4") = arg3; 163 register unsigned long a5 asm("a5") = arg4; 164 register unsigned long a6 asm("a6") = arg5; 165 166 __asm__ __volatile__( 167 KVM_HYPERCALL 168 : "=r" (ret) 169 : "i"(fun), "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6) 170 : "memory" 171 ); 172 173 return ret; 174} 175 176static inline bool kvm_check_and_clear_guest_paused(void) 177{ 178 return false; 179} 180 181static inline unsigned int kvm_arch_para_features(void) 182{ 183 return 0; 184} 185 186static inline unsigned int kvm_arch_para_hints(void) 187{ 188 return 0; 189} 190 191#ifdef CONFIG_PARAVIRT_SPINLOCKS 192void __init kvm_spinlock_init(void); 193#else /* !CONFIG_PARAVIRT_SPINLOCKS */ 194static inline void kvm_spinlock_init(void) 195{ 196} 197#endif /* CONFIG_PARAVIRT_SPINLOCKS */ 198 199#endif /* _ASM_LOONGARCH_KVM_PARA_H */ 200