185 lines
4.2 KiB
C
185 lines
4.2 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _ASM_LOONGARCH_KVM_PARA_H
|
|
#define _ASM_LOONGARCH_KVM_PARA_H
|
|
|
|
#include <uapi/asm/kvm_para.h>
|
|
|
|
/*
|
|
* Hypercall code field
|
|
*/
|
|
#define HYPERVISOR_KVM 1
|
|
#define HYPERVISOR_VENDOR_SHIFT 8
|
|
#define HYPERCALL_ENCODE(vendor, code) ((vendor << HYPERVISOR_VENDOR_SHIFT) + code)
|
|
|
|
#define KVM_HCALL_CODE_SERVICE 0
|
|
#define KVM_HCALL_CODE_SWDBG 1
|
|
|
|
#define KVM_HCALL_SERVICE HYPERCALL_ENCODE(HYPERVISOR_KVM, KVM_HCALL_CODE_SERVICE)
|
|
#define KVM_HCALL_FUNC_IPI 1
|
|
#define KVM_HCALL_FUNC_NOTIFY 2
|
|
|
|
#define KVM_HCALL_SWDBG HYPERCALL_ENCODE(HYPERVISOR_KVM, KVM_HCALL_CODE_SWDBG)
|
|
|
|
/*
|
|
* LoongArch hypercall return code
|
|
*/
|
|
#define KVM_HCALL_SUCCESS 0
|
|
#define KVM_HCALL_INVALID_CODE -1UL
|
|
#define KVM_HCALL_INVALID_PARAMETER -2UL
|
|
|
|
#define KVM_STEAL_PHYS_VALID BIT_ULL(0)
|
|
#define KVM_STEAL_PHYS_MASK GENMASK_ULL(63, 6)
|
|
|
|
struct kvm_steal_time {
|
|
__u64 steal;
|
|
__u32 version;
|
|
__u32 flags;
|
|
__u32 pad[12];
|
|
};
|
|
|
|
/*
|
|
* Hypercall interface for KVM hypervisor
|
|
*
|
|
* a0: function identifier
|
|
* a1-a5: args
|
|
* Return value will be placed in a0.
|
|
* Up to 5 arguments are passed in a1, a2, a3, a4, a5.
|
|
*/
|
|
static __always_inline long kvm_hypercall0(u64 fid)
|
|
{
|
|
register long ret asm("a0");
|
|
register unsigned long fun asm("a0") = fid;
|
|
|
|
__asm__ __volatile__(
|
|
"hvcl "__stringify(KVM_HCALL_SERVICE)
|
|
: "=r" (ret)
|
|
: "r" (fun)
|
|
: "memory"
|
|
);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static __always_inline long kvm_hypercall1(u64 fid, unsigned long arg0)
|
|
{
|
|
register long ret asm("a0");
|
|
register unsigned long fun asm("a0") = fid;
|
|
register unsigned long a1 asm("a1") = arg0;
|
|
|
|
__asm__ __volatile__(
|
|
"hvcl "__stringify(KVM_HCALL_SERVICE)
|
|
: "=r" (ret)
|
|
: "r" (fun), "r" (a1)
|
|
: "memory"
|
|
);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static __always_inline long kvm_hypercall2(u64 fid,
|
|
unsigned long arg0, unsigned long arg1)
|
|
{
|
|
register long ret asm("a0");
|
|
register unsigned long fun asm("a0") = fid;
|
|
register unsigned long a1 asm("a1") = arg0;
|
|
register unsigned long a2 asm("a2") = arg1;
|
|
|
|
__asm__ __volatile__(
|
|
"hvcl "__stringify(KVM_HCALL_SERVICE)
|
|
: "=r" (ret)
|
|
: "r" (fun), "r" (a1), "r" (a2)
|
|
: "memory"
|
|
);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static __always_inline long kvm_hypercall3(u64 fid,
|
|
unsigned long arg0, unsigned long arg1, unsigned long arg2)
|
|
{
|
|
register long ret asm("a0");
|
|
register unsigned long fun asm("a0") = fid;
|
|
register unsigned long a1 asm("a1") = arg0;
|
|
register unsigned long a2 asm("a2") = arg1;
|
|
register unsigned long a3 asm("a3") = arg2;
|
|
|
|
__asm__ __volatile__(
|
|
"hvcl "__stringify(KVM_HCALL_SERVICE)
|
|
: "=r" (ret)
|
|
: "r" (fun), "r" (a1), "r" (a2), "r" (a3)
|
|
: "memory"
|
|
);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static __always_inline long kvm_hypercall4(u64 fid,
|
|
unsigned long arg0, unsigned long arg1,
|
|
unsigned long arg2, unsigned long arg3)
|
|
{
|
|
register long ret asm("a0");
|
|
register unsigned long fun asm("a0") = fid;
|
|
register unsigned long a1 asm("a1") = arg0;
|
|
register unsigned long a2 asm("a2") = arg1;
|
|
register unsigned long a3 asm("a3") = arg2;
|
|
register unsigned long a4 asm("a4") = arg3;
|
|
|
|
__asm__ __volatile__(
|
|
"hvcl "__stringify(KVM_HCALL_SERVICE)
|
|
: "=r" (ret)
|
|
: "r"(fun), "r" (a1), "r" (a2), "r" (a3), "r" (a4)
|
|
: "memory"
|
|
);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static __always_inline long kvm_hypercall5(u64 fid,
|
|
unsigned long arg0, unsigned long arg1,
|
|
unsigned long arg2, unsigned long arg3, unsigned long arg4)
|
|
{
|
|
register long ret asm("a0");
|
|
register unsigned long fun asm("a0") = fid;
|
|
register unsigned long a1 asm("a1") = arg0;
|
|
register unsigned long a2 asm("a2") = arg1;
|
|
register unsigned long a3 asm("a3") = arg2;
|
|
register unsigned long a4 asm("a4") = arg3;
|
|
register unsigned long a5 asm("a5") = arg4;
|
|
|
|
__asm__ __volatile__(
|
|
"hvcl "__stringify(KVM_HCALL_SERVICE)
|
|
: "=r" (ret)
|
|
: "r"(fun), "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5)
|
|
: "memory"
|
|
);
|
|
|
|
return ret;
|
|
}
|
|
|
|
#ifdef CONFIG_PARAVIRT
|
|
bool kvm_para_available(void);
|
|
unsigned int kvm_arch_para_features(void);
|
|
#else
|
|
static inline bool kvm_para_available(void)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline unsigned int kvm_arch_para_features(void)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
static inline unsigned int kvm_arch_para_hints(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline bool kvm_check_and_clear_guest_paused(void)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
#endif /* _ASM_LOONGARCH_KVM_PARA_H */
|