summaryrefslogtreecommitdiff
path: root/arch/loongarch/include/asm/kvm_para.h
blob: 43ec61589e6cde88f7120b5052d32e4435c0c13d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_LOONGARCH_KVM_PARA_H
#define _ASM_LOONGARCH_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;
}

static inline unsigned int kvm_arch_para_features(void)
{
	return 0;
}

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 */