xref: /linux/arch/arm64/kvm/hyp/nvhe/pkvm.c (revision 06bc7ff0a1e0f2b0102e1314e3527a7ec0997851)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2021 Google LLC
4  * Author: Fuad Tabba <tabba@google.com>
5  */
6 
7 #include <kvm/arm_hypercalls.h>
8 
9 #include <linux/kvm_host.h>
10 #include <linux/mm.h>
11 
12 #include <asm/kvm_emulate.h>
13 
14 #include <nvhe/mem_protect.h>
15 #include <nvhe/memory.h>
16 #include <nvhe/pkvm.h>
17 #include <nvhe/trap_handler.h>
18 
19 /* Used by icache_is_aliasing(). */
20 unsigned long __icache_flags;
21 
22 /* Used by kvm_get_vttbr(). */
23 unsigned int kvm_arm_vmid_bits;
24 
25 unsigned int kvm_host_sve_max_vl;
26 
27 /*
28  * The currently loaded hyp vCPU for each physical CPU. Used in protected mode
29  * for both protected and non-protected VMs.
30  */
31 static DEFINE_PER_CPU(struct pkvm_hyp_vcpu *, loaded_hyp_vcpu);
32 
pkvm_vcpu_reset_hcr(struct kvm_vcpu * vcpu)33 static void pkvm_vcpu_reset_hcr(struct kvm_vcpu *vcpu)
34 {
35 	vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
36 
37 	if (has_hvhe())
38 		vcpu->arch.hcr_el2 |= HCR_E2H;
39 
40 	if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN)) {
41 		/* route synchronous external abort exceptions to EL2 */
42 		vcpu->arch.hcr_el2 |= HCR_TEA;
43 		/* trap error record accesses */
44 		vcpu->arch.hcr_el2 |= HCR_TERR;
45 	}
46 
47 	if (cpus_have_final_cap(ARM64_HAS_STAGE2_FWB))
48 		vcpu->arch.hcr_el2 |= HCR_FWB;
49 
50 	if (cpus_have_final_cap(ARM64_HAS_EVT) &&
51 	    !cpus_have_final_cap(ARM64_MISMATCHED_CACHE_TYPE) &&
52 	    kvm_read_vm_id_reg(vcpu->kvm, SYS_CTR_EL0) == read_cpuid(CTR_EL0))
53 		vcpu->arch.hcr_el2 |= HCR_TID4;
54 	else
55 		vcpu->arch.hcr_el2 |= HCR_TID2;
56 
57 	if (vcpu_has_ptrauth(vcpu))
58 		vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK);
59 
60 	if (kvm_has_mte(vcpu->kvm))
61 		vcpu->arch.hcr_el2 |= HCR_ATA;
62 }
63 
pvm_init_traps_hcr(struct kvm_vcpu * vcpu)64 static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
65 {
66 	struct kvm *kvm = vcpu->kvm;
67 	u64 val = vcpu->arch.hcr_el2;
68 
69 	/* No support for AArch32. */
70 	val |= HCR_RW;
71 
72 	/*
73 	 * Always trap:
74 	 * - Feature id registers: to control features exposed to guests
75 	 * - Implementation-defined features
76 	 */
77 	val |= HCR_TACR | HCR_TIDCP | HCR_TID3 | HCR_TID1;
78 
79 	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP)) {
80 		val |= HCR_TERR | HCR_TEA;
81 		val &= ~(HCR_FIEN);
82 	}
83 
84 	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP))
85 		val &= ~(HCR_AMVOFFEN);
86 
87 	if (!kvm_has_mte(kvm)) {
88 		val |= HCR_TID5;
89 		val &= ~(HCR_DCT | HCR_ATA);
90 	}
91 
92 	if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, LO, IMP))
93 		val |= HCR_TLOR;
94 
95 	vcpu->arch.hcr_el2 = val;
96 }
97 
pvm_init_traps_mdcr(struct kvm_vcpu * vcpu)98 static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
99 {
100 	struct kvm *kvm = vcpu->kvm;
101 	u64 val = vcpu->arch.mdcr_el2;
102 
103 	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP)) {
104 		val |= MDCR_EL2_TPM | MDCR_EL2_TPMCR;
105 		val &= ~(MDCR_EL2_HPME | MDCR_EL2_MTPME | MDCR_EL2_HPMN_MASK);
106 	}
107 
108 	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DebugVer, IMP))
109 		val |= MDCR_EL2_TDRA | MDCR_EL2_TDA;
110 
111 	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DoubleLock, IMP))
112 		val |= MDCR_EL2_TDOSA;
113 
114 	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSVer, IMP)) {
115 		val |= MDCR_EL2_TPMS;
116 		val &= ~MDCR_EL2_E2PB_MASK;
117 	}
118 
119 	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceFilt, IMP))
120 		val |= MDCR_EL2_TTRF;
121 
122 	if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
123 		val &= ~MDCR_EL2_E2TB_MASK;
124 
125 	/* Trap Debug Communications Channel registers */
126 	if (!kvm_has_feat(kvm, ID_AA64MMFR0_EL1, FGT, IMP))
127 		val |= MDCR_EL2_TDCC;
128 
129 	vcpu->arch.mdcr_el2 = val;
130 }
131 
132 /*
133  * Check that cpu features that are neither trapped nor supported are not
134  * enabled for protected VMs.
135  */
pkvm_check_pvm_cpu_features(struct kvm_vcpu * vcpu)136 static int pkvm_check_pvm_cpu_features(struct kvm_vcpu *vcpu)
137 {
138 	struct kvm *kvm = vcpu->kvm;
139 
140 	/* No AArch32 support for protected guests. */
141 	if (kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL0, AARCH32) ||
142 	    kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL1, AARCH32))
143 		return -EINVAL;
144 
145 	/*
146 	 * Linux guests assume support for floating-point and Advanced SIMD. Do
147 	 * not change the trapping behavior for these from the KVM default.
148 	 */
149 	if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, FP, IMP) ||
150 	    !kvm_has_feat(kvm, ID_AA64PFR0_EL1, AdvSIMD, IMP))
151 		return -EINVAL;
152 
153 	/* No SME support in KVM right now. Check to catch if it changes. */
154 	if (kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP))
155 		return -EINVAL;
156 
157 	return 0;
158 }
159 
160 /*
161  * Initialize trap register values in protected mode.
162  */
pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu * hyp_vcpu)163 static int pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
164 {
165 	struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
166 	int ret;
167 
168 	vcpu->arch.mdcr_el2 = 0;
169 
170 	pkvm_vcpu_reset_hcr(vcpu);
171 
172 	if ((!pkvm_hyp_vcpu_is_protected(hyp_vcpu))) {
173 		struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
174 
175 		/* Trust the host for non-protected vcpu features. */
176 		vcpu->arch.hcrx_el2 = host_vcpu->arch.hcrx_el2;
177 		return 0;
178 	}
179 
180 	ret = pkvm_check_pvm_cpu_features(vcpu);
181 	if (ret)
182 		return ret;
183 
184 	pvm_init_traps_hcr(vcpu);
185 	pvm_init_traps_mdcr(vcpu);
186 	vcpu_set_hcrx(vcpu);
187 
188 	return 0;
189 }
190 
191 /*
192  * Start the VM table handle at the offset defined instead of at 0.
193  * Mainly for sanity checking and debugging.
194  */
195 #define HANDLE_OFFSET 0x1000
196 
197 /*
198  * Marks a reserved but not yet used entry in the VM table.
199  */
200 #define RESERVED_ENTRY ((void *)0xa110ca7ed)
201 
vm_handle_to_idx(pkvm_handle_t handle)202 static unsigned int vm_handle_to_idx(pkvm_handle_t handle)
203 {
204 	return handle - HANDLE_OFFSET;
205 }
206 
idx_to_vm_handle(unsigned int idx)207 static pkvm_handle_t idx_to_vm_handle(unsigned int idx)
208 {
209 	return idx + HANDLE_OFFSET;
210 }
211 
212 /*
213  * Spinlock for protecting state related to the VM table. Protects writes
214  * to 'vm_table', 'nr_table_entries', and other per-vm state on initialization.
215  * Also protects reads and writes to 'last_hyp_vcpu_lookup'.
216  */
217 DEFINE_HYP_SPINLOCK(vm_table_lock);
218 
219 /*
220  * A table that tracks all VMs in protected mode.
221  * Allocated during hyp initialization and setup.
222  */
223 static struct pkvm_hyp_vm **vm_table;
224 
pkvm_hyp_vm_table_init(void * tbl)225 void pkvm_hyp_vm_table_init(void *tbl)
226 {
227 	BUILD_BUG_ON((u64)HANDLE_OFFSET + KVM_MAX_PVMS > (pkvm_handle_t)-1);
228 	WARN_ON(vm_table);
229 	vm_table = tbl;
230 }
231 
232 /*
233  * Return the hyp vm structure corresponding to the handle.
234  */
get_vm_by_handle(pkvm_handle_t handle)235 struct pkvm_hyp_vm *get_vm_by_handle(pkvm_handle_t handle)
236 {
237 	unsigned int idx = vm_handle_to_idx(handle);
238 
239 	hyp_assert_lock_held(&vm_table_lock);
240 
241 	if (unlikely(idx >= KVM_MAX_PVMS))
242 		return NULL;
243 
244 	/* A reserved entry doesn't represent an initialized VM. */
245 	if (unlikely(vm_table[idx] == RESERVED_ENTRY))
246 		return NULL;
247 
248 	return vm_table[idx];
249 }
250 
pkvm_load_hyp_vcpu(pkvm_handle_t handle,unsigned int vcpu_idx)251 struct pkvm_hyp_vcpu *pkvm_load_hyp_vcpu(pkvm_handle_t handle,
252 					 unsigned int vcpu_idx)
253 {
254 	struct pkvm_hyp_vcpu *hyp_vcpu = NULL;
255 	struct pkvm_hyp_vm *hyp_vm;
256 
257 	/* Cannot load a new vcpu without putting the old one first. */
258 	if (__this_cpu_read(loaded_hyp_vcpu))
259 		return NULL;
260 
261 	hyp_spin_lock(&vm_table_lock);
262 	hyp_vm = get_vm_by_handle(handle);
263 	if (!hyp_vm || hyp_vm->kvm.arch.pkvm.is_dying)
264 		goto unlock;
265 
266 	if (hyp_vm->kvm.created_vcpus <= vcpu_idx)
267 		goto unlock;
268 
269 	/* Pairs with smp_store_release() in register_hyp_vcpu(). */
270 	hyp_vcpu = smp_load_acquire(&hyp_vm->vcpus[vcpu_idx]);
271 	if (!hyp_vcpu)
272 		goto unlock;
273 
274 	/* Ensure vcpu isn't loaded on more than one cpu simultaneously. */
275 	if (unlikely(hyp_vcpu->loaded_hyp_vcpu)) {
276 		hyp_vcpu = NULL;
277 		goto unlock;
278 	}
279 
280 	hyp_vcpu->loaded_hyp_vcpu = this_cpu_ptr(&loaded_hyp_vcpu);
281 	hyp_page_ref_inc(hyp_virt_to_page(hyp_vm));
282 unlock:
283 	hyp_spin_unlock(&vm_table_lock);
284 
285 	if (hyp_vcpu)
286 		__this_cpu_write(loaded_hyp_vcpu, hyp_vcpu);
287 	return hyp_vcpu;
288 }
289 
pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu * hyp_vcpu)290 void pkvm_put_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
291 {
292 	struct pkvm_hyp_vm *hyp_vm = pkvm_hyp_vcpu_to_hyp_vm(hyp_vcpu);
293 
294 	hyp_spin_lock(&vm_table_lock);
295 	hyp_vcpu->loaded_hyp_vcpu = NULL;
296 	__this_cpu_write(loaded_hyp_vcpu, NULL);
297 	hyp_page_ref_dec(hyp_virt_to_page(hyp_vm));
298 	hyp_spin_unlock(&vm_table_lock);
299 }
300 
pkvm_get_loaded_hyp_vcpu(void)301 struct pkvm_hyp_vcpu *pkvm_get_loaded_hyp_vcpu(void)
302 {
303 	return __this_cpu_read(loaded_hyp_vcpu);
304 
305 }
306 
get_pkvm_hyp_vm(pkvm_handle_t handle)307 struct pkvm_hyp_vm *get_pkvm_hyp_vm(pkvm_handle_t handle)
308 {
309 	struct pkvm_hyp_vm *hyp_vm;
310 
311 	hyp_spin_lock(&vm_table_lock);
312 	hyp_vm = get_vm_by_handle(handle);
313 	if (hyp_vm)
314 		hyp_page_ref_inc(hyp_virt_to_page(hyp_vm));
315 	hyp_spin_unlock(&vm_table_lock);
316 
317 	return hyp_vm;
318 }
319 
put_pkvm_hyp_vm(struct pkvm_hyp_vm * hyp_vm)320 void put_pkvm_hyp_vm(struct pkvm_hyp_vm *hyp_vm)
321 {
322 	hyp_spin_lock(&vm_table_lock);
323 	hyp_page_ref_dec(hyp_virt_to_page(hyp_vm));
324 	hyp_spin_unlock(&vm_table_lock);
325 }
326 
get_np_pkvm_hyp_vm(pkvm_handle_t handle)327 struct pkvm_hyp_vm *get_np_pkvm_hyp_vm(pkvm_handle_t handle)
328 {
329 	struct pkvm_hyp_vm *hyp_vm = get_pkvm_hyp_vm(handle);
330 
331 	if (hyp_vm && pkvm_hyp_vm_is_protected(hyp_vm)) {
332 		put_pkvm_hyp_vm(hyp_vm);
333 		hyp_vm = NULL;
334 	}
335 
336 	return hyp_vm;
337 }
338 
pkvm_init_features_from_host(struct pkvm_hyp_vm * hyp_vm,const struct kvm * host_kvm)339 static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struct kvm *host_kvm)
340 {
341 	struct kvm *kvm = &hyp_vm->kvm;
342 	unsigned long host_arch_flags = READ_ONCE(host_kvm->arch.flags);
343 	DECLARE_BITMAP(allowed_features, KVM_VCPU_MAX_FEATURES);
344 
345 	/* CTR_EL0 is always under host control, even for protected VMs. */
346 	hyp_vm->kvm.arch.ctr_el0 = host_kvm->arch.ctr_el0;
347 
348 	/* Preserve the vgic model so that GICv3 emulation works */
349 	hyp_vm->kvm.arch.vgic.vgic_model = host_kvm->arch.vgic.vgic_model;
350 
351 	/* No restrictions for non-protected VMs. */
352 	if (!kvm_vm_is_protected(kvm)) {
353 		hyp_vm->kvm.arch.flags = host_arch_flags;
354 		hyp_vm->kvm.arch.flags &= ~BIT_ULL(KVM_ARCH_FLAG_ID_REGS_INITIALIZED);
355 
356 		bitmap_copy(kvm->arch.vcpu_features,
357 			    host_kvm->arch.vcpu_features,
358 			    KVM_VCPU_MAX_FEATURES);
359 
360 		if (test_bit(KVM_ARCH_FLAG_WRITABLE_IMP_ID_REGS, &host_arch_flags))
361 			hyp_vm->kvm.arch.midr_el1 = host_kvm->arch.midr_el1;
362 
363 		return;
364 	}
365 
366 	if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_MTE))
367 		kvm->arch.flags |= host_arch_flags & BIT(KVM_ARCH_FLAG_MTE_ENABLED);
368 
369 	bitmap_zero(allowed_features, KVM_VCPU_MAX_FEATURES);
370 
371 	set_bit(KVM_ARM_VCPU_PSCI_0_2, allowed_features);
372 
373 	if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_PMU_V3))
374 		set_bit(KVM_ARM_VCPU_PMU_V3, allowed_features);
375 
376 	if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_PTRAUTH_ADDRESS))
377 		set_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, allowed_features);
378 
379 	if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_PTRAUTH_GENERIC))
380 		set_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, allowed_features);
381 
382 	if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_SVE)) {
383 		set_bit(KVM_ARM_VCPU_SVE, allowed_features);
384 		kvm->arch.flags |= host_arch_flags & BIT(KVM_ARCH_FLAG_GUEST_HAS_SVE);
385 	}
386 
387 	bitmap_and(kvm->arch.vcpu_features, host_kvm->arch.vcpu_features,
388 		   allowed_features, KVM_VCPU_MAX_FEATURES);
389 }
390 
unpin_host_vcpu(struct kvm_vcpu * host_vcpu)391 static void unpin_host_vcpu(struct kvm_vcpu *host_vcpu)
392 {
393 	if (host_vcpu)
394 		hyp_unpin_shared_mem(host_vcpu, host_vcpu + 1);
395 }
396 
unpin_host_sve_state(struct pkvm_hyp_vcpu * hyp_vcpu)397 static void unpin_host_sve_state(struct pkvm_hyp_vcpu *hyp_vcpu)
398 {
399 	void *sve_state;
400 
401 	if (!vcpu_has_feature(&hyp_vcpu->vcpu, KVM_ARM_VCPU_SVE))
402 		return;
403 
404 	sve_state = hyp_vcpu->vcpu.arch.sve_state;
405 	hyp_unpin_shared_mem(sve_state,
406 			     sve_state + vcpu_sve_state_size(&hyp_vcpu->vcpu));
407 }
408 
unpin_host_vcpus(struct pkvm_hyp_vcpu * hyp_vcpus[],unsigned int nr_vcpus)409 static void unpin_host_vcpus(struct pkvm_hyp_vcpu *hyp_vcpus[],
410 			     unsigned int nr_vcpus)
411 {
412 	int i;
413 
414 	for (i = 0; i < nr_vcpus; i++) {
415 		struct pkvm_hyp_vcpu *hyp_vcpu = hyp_vcpus[i];
416 
417 		if (!hyp_vcpu)
418 			continue;
419 
420 		unpin_host_vcpu(hyp_vcpu->host_vcpu);
421 		unpin_host_sve_state(hyp_vcpu);
422 	}
423 }
424 
init_pkvm_hyp_vm(struct kvm * host_kvm,struct pkvm_hyp_vm * hyp_vm,unsigned int nr_vcpus,pkvm_handle_t handle)425 static void init_pkvm_hyp_vm(struct kvm *host_kvm, struct pkvm_hyp_vm *hyp_vm,
426 			     unsigned int nr_vcpus, pkvm_handle_t handle)
427 {
428 	struct kvm_s2_mmu *mmu = &hyp_vm->kvm.arch.mmu;
429 	int idx = vm_handle_to_idx(handle);
430 
431 	hyp_vm->kvm.arch.pkvm.handle = handle;
432 
433 	hyp_vm->host_kvm = host_kvm;
434 	hyp_vm->kvm.created_vcpus = nr_vcpus;
435 	hyp_vm->kvm.arch.pkvm.is_protected = READ_ONCE(host_kvm->arch.pkvm.is_protected);
436 	hyp_vm->kvm.arch.pkvm.is_created = true;
437 	hyp_vm->kvm.arch.flags = 0;
438 	pkvm_init_features_from_host(hyp_vm, host_kvm);
439 
440 	/* VMID 0 is reserved for the host */
441 	atomic64_set(&mmu->vmid.id, idx + 1);
442 
443 	mmu->vtcr = host_mmu.arch.mmu.vtcr;
444 	mmu->arch = &hyp_vm->kvm.arch;
445 	mmu->pgt = &hyp_vm->pgt;
446 }
447 
pkvm_vcpu_init_sve(struct pkvm_hyp_vcpu * hyp_vcpu,struct kvm_vcpu * host_vcpu)448 static int pkvm_vcpu_init_sve(struct pkvm_hyp_vcpu *hyp_vcpu, struct kvm_vcpu *host_vcpu)
449 {
450 	struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
451 	unsigned int sve_max_vl;
452 	size_t sve_state_size;
453 	void *sve_state;
454 	int ret = 0;
455 
456 	if (!vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE)) {
457 		vcpu_clear_flag(vcpu, VCPU_SVE_FINALIZED);
458 		return 0;
459 	}
460 
461 	/* Limit guest vector length to the maximum supported by the host. */
462 	sve_max_vl = min(READ_ONCE(host_vcpu->arch.sve_max_vl), kvm_host_sve_max_vl);
463 	sve_state_size = sve_state_size_from_vl(sve_max_vl);
464 	sve_state = kern_hyp_va(READ_ONCE(host_vcpu->arch.sve_state));
465 
466 	if (!sve_state || !sve_state_size) {
467 		ret = -EINVAL;
468 		goto err;
469 	}
470 
471 	ret = hyp_pin_shared_mem(sve_state, sve_state + sve_state_size);
472 	if (ret)
473 		goto err;
474 
475 	vcpu->arch.sve_state = sve_state;
476 	vcpu->arch.sve_max_vl = sve_max_vl;
477 
478 	return 0;
479 err:
480 	clear_bit(KVM_ARM_VCPU_SVE, vcpu->kvm->arch.vcpu_features);
481 	return ret;
482 }
483 
vm_copy_id_regs(struct pkvm_hyp_vcpu * hyp_vcpu)484 static int vm_copy_id_regs(struct pkvm_hyp_vcpu *hyp_vcpu)
485 {
486 	struct pkvm_hyp_vm *hyp_vm = pkvm_hyp_vcpu_to_hyp_vm(hyp_vcpu);
487 	const struct kvm *host_kvm = hyp_vm->host_kvm;
488 	struct kvm *kvm = &hyp_vm->kvm;
489 
490 	if (!test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &host_kvm->arch.flags))
491 		return -EINVAL;
492 
493 	if (test_and_set_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags))
494 		return 0;
495 
496 	memcpy(kvm->arch.id_regs, host_kvm->arch.id_regs, sizeof(kvm->arch.id_regs));
497 
498 	return 0;
499 }
500 
pkvm_vcpu_init_sysregs(struct pkvm_hyp_vcpu * hyp_vcpu)501 static int pkvm_vcpu_init_sysregs(struct pkvm_hyp_vcpu *hyp_vcpu)
502 {
503 	int ret = 0;
504 
505 	if (pkvm_hyp_vcpu_is_protected(hyp_vcpu))
506 		kvm_init_pvm_id_regs(&hyp_vcpu->vcpu);
507 	else
508 		ret = vm_copy_id_regs(hyp_vcpu);
509 
510 	return ret;
511 }
512 
init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu * hyp_vcpu,struct pkvm_hyp_vm * hyp_vm,struct kvm_vcpu * host_vcpu)513 static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu,
514 			      struct pkvm_hyp_vm *hyp_vm,
515 			      struct kvm_vcpu *host_vcpu)
516 {
517 	int ret = 0;
518 
519 	if (hyp_pin_shared_mem(host_vcpu, host_vcpu + 1))
520 		return -EBUSY;
521 
522 	hyp_vcpu->host_vcpu = host_vcpu;
523 
524 	hyp_vcpu->vcpu.kvm = &hyp_vm->kvm;
525 	hyp_vcpu->vcpu.vcpu_id = READ_ONCE(host_vcpu->vcpu_id);
526 	hyp_vcpu->vcpu.vcpu_idx = READ_ONCE(host_vcpu->vcpu_idx);
527 
528 	hyp_vcpu->vcpu.arch.hw_mmu = &hyp_vm->kvm.arch.mmu;
529 	hyp_vcpu->vcpu.arch.cflags = READ_ONCE(host_vcpu->arch.cflags);
530 	hyp_vcpu->vcpu.arch.mp_state.mp_state = KVM_MP_STATE_STOPPED;
531 
532 	ret = pkvm_vcpu_init_sysregs(hyp_vcpu);
533 	if (ret)
534 		goto done;
535 
536 	ret = pkvm_vcpu_init_traps(hyp_vcpu);
537 	if (ret)
538 		goto done;
539 
540 	ret = pkvm_vcpu_init_sve(hyp_vcpu, host_vcpu);
541 done:
542 	if (ret)
543 		unpin_host_vcpu(host_vcpu);
544 	return ret;
545 }
546 
find_free_vm_table_entry(void)547 static int find_free_vm_table_entry(void)
548 {
549 	int i;
550 
551 	for (i = 0; i < KVM_MAX_PVMS; ++i) {
552 		if (!vm_table[i])
553 			return i;
554 	}
555 
556 	return -ENOMEM;
557 }
558 
559 /*
560  * Reserve a VM table entry.
561  *
562  * Return a unique handle to the VM on success,
563  * negative error code on failure.
564  */
allocate_vm_table_entry(void)565 static int allocate_vm_table_entry(void)
566 {
567 	int idx;
568 
569 	hyp_assert_lock_held(&vm_table_lock);
570 
571 	/*
572 	 * Initializing protected state might have failed, yet a malicious
573 	 * host could trigger this function. Thus, ensure that 'vm_table'
574 	 * exists.
575 	 */
576 	if (unlikely(!vm_table))
577 		return -EINVAL;
578 
579 	idx = find_free_vm_table_entry();
580 	if (unlikely(idx < 0))
581 		return idx;
582 
583 	vm_table[idx] = RESERVED_ENTRY;
584 
585 	return idx;
586 }
587 
__insert_vm_table_entry(pkvm_handle_t handle,struct pkvm_hyp_vm * hyp_vm)588 static int __insert_vm_table_entry(pkvm_handle_t handle,
589 				   struct pkvm_hyp_vm *hyp_vm)
590 {
591 	unsigned int idx;
592 
593 	hyp_assert_lock_held(&vm_table_lock);
594 
595 	/*
596 	 * Initializing protected state might have failed, yet a malicious
597 	 * host could trigger this function. Thus, ensure that 'vm_table'
598 	 * exists.
599 	 */
600 	if (unlikely(!vm_table))
601 		return -EINVAL;
602 
603 	idx = vm_handle_to_idx(handle);
604 	if (unlikely(idx >= KVM_MAX_PVMS))
605 		return -EINVAL;
606 
607 	if (unlikely(vm_table[idx] != RESERVED_ENTRY))
608 		return -EINVAL;
609 
610 	vm_table[idx] = hyp_vm;
611 
612 	return 0;
613 }
614 
615 /*
616  * Insert a pointer to the initialized VM into the VM table.
617  *
618  * Return 0 on success, or negative error code on failure.
619  */
insert_vm_table_entry(pkvm_handle_t handle,struct pkvm_hyp_vm * hyp_vm)620 static int insert_vm_table_entry(pkvm_handle_t handle,
621 				 struct pkvm_hyp_vm *hyp_vm)
622 {
623 	int ret;
624 
625 	hyp_spin_lock(&vm_table_lock);
626 	ret = __insert_vm_table_entry(handle, hyp_vm);
627 	hyp_spin_unlock(&vm_table_lock);
628 
629 	return ret;
630 }
631 
632 /*
633  * Deallocate and remove the VM table entry corresponding to the handle.
634  */
remove_vm_table_entry(pkvm_handle_t handle)635 static void remove_vm_table_entry(pkvm_handle_t handle)
636 {
637 	hyp_assert_lock_held(&vm_table_lock);
638 	vm_table[vm_handle_to_idx(handle)] = NULL;
639 }
640 
pkvm_get_hyp_vm_size(unsigned int nr_vcpus)641 static size_t pkvm_get_hyp_vm_size(unsigned int nr_vcpus)
642 {
643 	return size_add(sizeof(struct pkvm_hyp_vm),
644 		size_mul(sizeof(struct pkvm_hyp_vcpu *), nr_vcpus));
645 }
646 
map_donated_memory_noclear(unsigned long host_va,size_t size)647 static void *map_donated_memory_noclear(unsigned long host_va, size_t size)
648 {
649 	void *va = (void *)kern_hyp_va(host_va);
650 
651 	if (!PAGE_ALIGNED(va))
652 		return NULL;
653 
654 	if (__pkvm_host_donate_hyp(hyp_virt_to_pfn(va),
655 				   PAGE_ALIGN(size) >> PAGE_SHIFT))
656 		return NULL;
657 
658 	return va;
659 }
660 
map_donated_memory(unsigned long host_va,size_t size)661 static void *map_donated_memory(unsigned long host_va, size_t size)
662 {
663 	void *va = map_donated_memory_noclear(host_va, size);
664 
665 	if (va)
666 		memset(va, 0, size);
667 
668 	return va;
669 }
670 
__unmap_donated_memory(void * va,size_t size)671 static void __unmap_donated_memory(void *va, size_t size)
672 {
673 	kvm_flush_dcache_to_poc(va, size);
674 	WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(va),
675 				       PAGE_ALIGN(size) >> PAGE_SHIFT));
676 }
677 
unmap_donated_memory(void * va,size_t size)678 static void unmap_donated_memory(void *va, size_t size)
679 {
680 	if (!va)
681 		return;
682 
683 	memset(va, 0, size);
684 	__unmap_donated_memory(va, size);
685 }
686 
unmap_donated_memory_noclear(void * va,size_t size)687 static void unmap_donated_memory_noclear(void *va, size_t size)
688 {
689 	if (!va)
690 		return;
691 
692 	__unmap_donated_memory(va, size);
693 }
694 
695 /*
696  * Reserves an entry in the hypervisor for a new VM in protected mode.
697  *
698  * Return a unique handle to the VM on success, negative error code on failure.
699  */
__pkvm_reserve_vm(void)700 int __pkvm_reserve_vm(void)
701 {
702 	int ret;
703 
704 	hyp_spin_lock(&vm_table_lock);
705 	ret = allocate_vm_table_entry();
706 	hyp_spin_unlock(&vm_table_lock);
707 
708 	if (ret < 0)
709 		return ret;
710 
711 	return idx_to_vm_handle(ret);
712 }
713 
714 /*
715  * Removes a reserved entry, but only if is hasn't been used yet.
716  * Otherwise, the VM needs to be destroyed.
717  */
__pkvm_unreserve_vm(pkvm_handle_t handle)718 void __pkvm_unreserve_vm(pkvm_handle_t handle)
719 {
720 	unsigned int idx = vm_handle_to_idx(handle);
721 
722 	if (unlikely(!vm_table))
723 		return;
724 
725 	hyp_spin_lock(&vm_table_lock);
726 	if (likely(idx < KVM_MAX_PVMS && vm_table[idx] == RESERVED_ENTRY))
727 		remove_vm_table_entry(handle);
728 	hyp_spin_unlock(&vm_table_lock);
729 }
730 
731 #ifdef CONFIG_NVHE_EL2_DEBUG
732 static struct pkvm_hyp_vm selftest_vm = {
733 	.kvm = {
734 		.arch = {
735 			.mmu = {
736 				.arch = &selftest_vm.kvm.arch,
737 				.pgt = &selftest_vm.pgt,
738 			},
739 		},
740 	},
741 };
742 
743 static struct pkvm_hyp_vcpu selftest_vcpu = {
744 	.vcpu = {
745 		.arch = {
746 			.hw_mmu = &selftest_vm.kvm.arch.mmu,
747 		},
748 		.kvm = &selftest_vm.kvm,
749 	},
750 };
751 
init_selftest_vm(void * virt)752 struct pkvm_hyp_vcpu *init_selftest_vm(void *virt)
753 {
754 	struct hyp_page *p = hyp_virt_to_page(virt);
755 	int i;
756 
757 	selftest_vm.kvm.arch.mmu.vtcr = host_mmu.arch.mmu.vtcr;
758 	WARN_ON(kvm_guest_prepare_stage2(&selftest_vm, virt));
759 
760 	for (i = 0; i < pkvm_selftest_pages(); i++) {
761 		if (p[i].refcount)
762 			continue;
763 		p[i].refcount = 1;
764 		hyp_put_page(&selftest_vm.pool, hyp_page_to_virt(&p[i]));
765 	}
766 
767 	selftest_vm.kvm.arch.pkvm.handle = __pkvm_reserve_vm();
768 	insert_vm_table_entry(selftest_vm.kvm.arch.pkvm.handle, &selftest_vm);
769 	return &selftest_vcpu;
770 }
771 
teardown_selftest_vm(void)772 void teardown_selftest_vm(void)
773 {
774 	hyp_spin_lock(&vm_table_lock);
775 	remove_vm_table_entry(selftest_vm.kvm.arch.pkvm.handle);
776 	hyp_spin_unlock(&vm_table_lock);
777 }
778 #endif /* CONFIG_NVHE_EL2_DEBUG */
779 
780 /*
781  * Initialize the hypervisor copy of the VM state using host-donated memory.
782  *
783  * Unmap the donated memory from the host at stage 2.
784  *
785  * host_kvm: A pointer to the host's struct kvm.
786  * vm_hva: The host va of the area being donated for the VM state.
787  *	   Must be page aligned.
788  * pgd_hva: The host va of the area being donated for the stage-2 PGD for
789  *	    the VM. Must be page aligned. Its size is implied by the VM's
790  *	    VTCR.
791  *
792  * Return 0 success, negative error code on failure.
793  */
__pkvm_init_vm(struct kvm * host_kvm,unsigned long vm_hva,unsigned long pgd_hva)794 int __pkvm_init_vm(struct kvm *host_kvm, unsigned long vm_hva,
795 		   unsigned long pgd_hva)
796 {
797 	struct pkvm_hyp_vm *hyp_vm = NULL;
798 	size_t vm_size, pgd_size;
799 	unsigned int nr_vcpus;
800 	pkvm_handle_t handle;
801 	void *pgd = NULL;
802 	int ret;
803 
804 	ret = hyp_pin_shared_mem(host_kvm, host_kvm + 1);
805 	if (ret)
806 		return ret;
807 
808 	nr_vcpus = READ_ONCE(host_kvm->created_vcpus);
809 	if (nr_vcpus < 1) {
810 		ret = -EINVAL;
811 		goto err_unpin_kvm;
812 	}
813 
814 	handle = READ_ONCE(host_kvm->arch.pkvm.handle);
815 	if (unlikely(handle < HANDLE_OFFSET)) {
816 		ret = -EINVAL;
817 		goto err_unpin_kvm;
818 	}
819 
820 	vm_size = pkvm_get_hyp_vm_size(nr_vcpus);
821 	pgd_size = kvm_pgtable_stage2_pgd_size(host_mmu.arch.mmu.vtcr);
822 
823 	ret = -ENOMEM;
824 
825 	hyp_vm = map_donated_memory(vm_hva, vm_size);
826 	if (!hyp_vm)
827 		goto err_remove_mappings;
828 
829 	pgd = map_donated_memory_noclear(pgd_hva, pgd_size);
830 	if (!pgd)
831 		goto err_remove_mappings;
832 
833 	init_pkvm_hyp_vm(host_kvm, hyp_vm, nr_vcpus, handle);
834 
835 	ret = kvm_guest_prepare_stage2(hyp_vm, pgd);
836 	if (ret)
837 		goto err_remove_mappings;
838 
839 	/* Must be called last since this publishes the VM. */
840 	ret = insert_vm_table_entry(handle, hyp_vm);
841 	if (ret)
842 		goto err_remove_mappings;
843 
844 	return 0;
845 
846 err_remove_mappings:
847 	unmap_donated_memory(hyp_vm, vm_size);
848 	unmap_donated_memory(pgd, pgd_size);
849 err_unpin_kvm:
850 	hyp_unpin_shared_mem(host_kvm, host_kvm + 1);
851 	return ret;
852 }
853 
854 /*
855  * Initialize the hypervisor copy of the vCPU state using host-donated memory.
856  *
857  * handle: The hypervisor handle for the vm.
858  * host_vcpu: A pointer to the corresponding host vcpu.
859  * vcpu_hva: The host va of the area being donated for the vcpu state.
860  *	     Must be page aligned. The size of the area must be equal to
861  *	     the page-aligned size of 'struct pkvm_hyp_vcpu'.
862  * Return 0 on success, negative error code on failure.
863  */
register_hyp_vcpu(struct pkvm_hyp_vm * hyp_vm,struct pkvm_hyp_vcpu * hyp_vcpu)864 static int register_hyp_vcpu(struct pkvm_hyp_vm *hyp_vm,
865 			      struct pkvm_hyp_vcpu *hyp_vcpu)
866 {
867 	unsigned int idx = hyp_vcpu->vcpu.vcpu_idx;
868 
869 	if (idx >= hyp_vm->kvm.created_vcpus)
870 		return -EINVAL;
871 
872 	if (hyp_vm->vcpus[idx])
873 		return -EINVAL;
874 
875 	/*
876 	 * Ensure the hyp_vcpu is initialised before publishing it to
877 	 * the vCPU-load path via 'hyp_vm->vcpus[]'.
878 	 */
879 	smp_store_release(&hyp_vm->vcpus[idx], hyp_vcpu);
880 	return 0;
881 }
882 
__pkvm_init_vcpu(pkvm_handle_t handle,struct kvm_vcpu * host_vcpu,unsigned long vcpu_hva)883 int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu,
884 		     unsigned long vcpu_hva)
885 {
886 	struct pkvm_hyp_vcpu *hyp_vcpu;
887 	struct pkvm_hyp_vm *hyp_vm;
888 	int ret;
889 
890 	hyp_vcpu = map_donated_memory(vcpu_hva, sizeof(*hyp_vcpu));
891 	if (!hyp_vcpu)
892 		return -ENOMEM;
893 
894 	hyp_spin_lock(&vm_table_lock);
895 
896 	hyp_vm = get_vm_by_handle(handle);
897 	if (!hyp_vm) {
898 		ret = -ENOENT;
899 		goto unlock;
900 	}
901 
902 	ret = init_pkvm_hyp_vcpu(hyp_vcpu, hyp_vm, host_vcpu);
903 	if (ret)
904 		goto unlock;
905 
906 	ret = register_hyp_vcpu(hyp_vm, hyp_vcpu);
907 	if (ret) {
908 		unpin_host_vcpu(host_vcpu);
909 		unpin_host_sve_state(hyp_vcpu);
910 	}
911 unlock:
912 	hyp_spin_unlock(&vm_table_lock);
913 
914 	if (ret)
915 		unmap_donated_memory(hyp_vcpu, sizeof(*hyp_vcpu));
916 	return ret;
917 }
918 
919 static void
teardown_donated_memory(struct kvm_hyp_memcache * mc,void * addr,size_t size)920 teardown_donated_memory(struct kvm_hyp_memcache *mc, void *addr, size_t size)
921 {
922 	size = PAGE_ALIGN(size);
923 	memset(addr, 0, size);
924 
925 	for (void *start = addr; start < addr + size; start += PAGE_SIZE)
926 		push_hyp_memcache(mc, start, hyp_virt_to_phys);
927 
928 	unmap_donated_memory_noclear(addr, size);
929 }
930 
__pkvm_reclaim_dying_guest_page(pkvm_handle_t handle,u64 gfn)931 int __pkvm_reclaim_dying_guest_page(pkvm_handle_t handle, u64 gfn)
932 {
933 	struct pkvm_hyp_vm *hyp_vm = get_pkvm_hyp_vm(handle);
934 	int ret = -EINVAL;
935 
936 	if (!hyp_vm)
937 		return ret;
938 
939 	if (hyp_vm->kvm.arch.pkvm.is_dying)
940 		ret = __pkvm_host_reclaim_page_guest(gfn, hyp_vm);
941 
942 	put_pkvm_hyp_vm(hyp_vm);
943 	return ret;
944 }
945 
get_pkvm_unref_hyp_vm_locked(pkvm_handle_t handle)946 static struct pkvm_hyp_vm *get_pkvm_unref_hyp_vm_locked(pkvm_handle_t handle)
947 {
948 	struct pkvm_hyp_vm *hyp_vm;
949 
950 	hyp_assert_lock_held(&vm_table_lock);
951 
952 	hyp_vm = get_vm_by_handle(handle);
953 	if (!hyp_vm || hyp_page_count(hyp_vm))
954 		return NULL;
955 
956 	return hyp_vm;
957 }
958 
__pkvm_start_teardown_vm(pkvm_handle_t handle)959 int __pkvm_start_teardown_vm(pkvm_handle_t handle)
960 {
961 	struct pkvm_hyp_vm *hyp_vm;
962 	int ret = 0;
963 
964 	hyp_spin_lock(&vm_table_lock);
965 	hyp_vm = get_pkvm_unref_hyp_vm_locked(handle);
966 	if (!hyp_vm || hyp_vm->kvm.arch.pkvm.is_dying) {
967 		ret = -EINVAL;
968 		goto unlock;
969 	}
970 
971 	hyp_vm->kvm.arch.pkvm.is_dying = true;
972 unlock:
973 	hyp_spin_unlock(&vm_table_lock);
974 
975 	return ret;
976 }
977 
__pkvm_finalize_teardown_vm(pkvm_handle_t handle)978 int __pkvm_finalize_teardown_vm(pkvm_handle_t handle)
979 {
980 	struct kvm_hyp_memcache *mc, *stage2_mc;
981 	struct pkvm_hyp_vm *hyp_vm;
982 	struct kvm *host_kvm;
983 	unsigned int idx;
984 	size_t vm_size;
985 	int err;
986 
987 	hyp_spin_lock(&vm_table_lock);
988 	hyp_vm = get_pkvm_unref_hyp_vm_locked(handle);
989 	if (!hyp_vm || !hyp_vm->kvm.arch.pkvm.is_dying) {
990 		err = -EINVAL;
991 		goto err_unlock;
992 	}
993 
994 	host_kvm = hyp_vm->host_kvm;
995 
996 	/* Ensure the VMID is clean before it can be reallocated */
997 	__kvm_tlb_flush_vmid(&hyp_vm->kvm.arch.mmu);
998 	remove_vm_table_entry(handle);
999 	hyp_spin_unlock(&vm_table_lock);
1000 
1001 	/* Reclaim guest pages (including page-table pages) */
1002 	mc = &host_kvm->arch.pkvm.teardown_mc;
1003 	stage2_mc = &host_kvm->arch.pkvm.stage2_teardown_mc;
1004 	reclaim_pgtable_pages(hyp_vm, stage2_mc);
1005 	unpin_host_vcpus(hyp_vm->vcpus, hyp_vm->kvm.created_vcpus);
1006 
1007 	/* Push the metadata pages to the teardown memcache */
1008 	for (idx = 0; idx < hyp_vm->kvm.created_vcpus; ++idx) {
1009 		struct pkvm_hyp_vcpu *hyp_vcpu = hyp_vm->vcpus[idx];
1010 		struct kvm_hyp_memcache *vcpu_mc;
1011 
1012 		if (!hyp_vcpu)
1013 			continue;
1014 
1015 		vcpu_mc = &hyp_vcpu->vcpu.arch.pkvm_memcache;
1016 
1017 		while (vcpu_mc->nr_pages) {
1018 			void *addr = pop_hyp_memcache(vcpu_mc, hyp_phys_to_virt);
1019 
1020 			push_hyp_memcache(stage2_mc, addr, hyp_virt_to_phys);
1021 			unmap_donated_memory_noclear(addr, PAGE_SIZE);
1022 		}
1023 
1024 		teardown_donated_memory(mc, hyp_vcpu, sizeof(*hyp_vcpu));
1025 	}
1026 
1027 	vm_size = pkvm_get_hyp_vm_size(hyp_vm->kvm.created_vcpus);
1028 	teardown_donated_memory(mc, hyp_vm, vm_size);
1029 	hyp_unpin_shared_mem(host_kvm, host_kvm + 1);
1030 	return 0;
1031 
1032 err_unlock:
1033 	hyp_spin_unlock(&vm_table_lock);
1034 	return err;
1035 }
1036 
__pkvm_memshare_page_req(struct kvm_vcpu * vcpu,u64 ipa)1037 static u64 __pkvm_memshare_page_req(struct kvm_vcpu *vcpu, u64 ipa)
1038 {
1039 	u64 elr;
1040 
1041 	/* Fake up a data abort (level 3 translation fault on write) */
1042 	vcpu->arch.fault.esr_el2 = (ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT) |
1043 				   ESR_ELx_WNR | ESR_ELx_FSC_FAULT |
1044 				   FIELD_PREP(ESR_ELx_FSC_LEVEL, 3);
1045 
1046 	/* Shuffle the IPA around into the HPFAR */
1047 	vcpu->arch.fault.hpfar_el2 = (HPFAR_EL2_NS | (ipa >> 8)) & HPFAR_MASK;
1048 
1049 	/* This is a virtual address. 0's good. Let's go with 0. */
1050 	vcpu->arch.fault.far_el2 = 0;
1051 
1052 	/* Rewind the ELR so we return to the HVC once the IPA is mapped */
1053 	elr = read_sysreg(elr_el2);
1054 	elr -= 4;
1055 	write_sysreg(elr, elr_el2);
1056 
1057 	return ARM_EXCEPTION_TRAP;
1058 }
1059 
pkvm_memshare_call(u64 * ret,struct kvm_vcpu * vcpu,u64 * exit_code)1060 static bool pkvm_memshare_call(u64 *ret, struct kvm_vcpu *vcpu, u64 *exit_code)
1061 {
1062 	struct pkvm_hyp_vcpu *hyp_vcpu;
1063 	u64 ipa = smccc_get_arg1(vcpu);
1064 
1065 	if (!PAGE_ALIGNED(ipa))
1066 		goto out_guest;
1067 
1068 	hyp_vcpu = container_of(vcpu, struct pkvm_hyp_vcpu, vcpu);
1069 	switch (__pkvm_guest_share_host(hyp_vcpu, hyp_phys_to_pfn(ipa))) {
1070 	case 0:
1071 		ret[0] = SMCCC_RET_SUCCESS;
1072 		goto out_guest;
1073 	case -ENOENT:
1074 		/*
1075 		 * Convert the exception into a data abort so that the page
1076 		 * being shared is mapped into the guest next time.
1077 		 */
1078 		*exit_code = __pkvm_memshare_page_req(vcpu, ipa);
1079 		goto out_host;
1080 	}
1081 
1082 out_guest:
1083 	return true;
1084 out_host:
1085 	return false;
1086 }
1087 
pkvm_memunshare_call(u64 * ret,struct kvm_vcpu * vcpu)1088 static void pkvm_memunshare_call(u64 *ret, struct kvm_vcpu *vcpu)
1089 {
1090 	struct pkvm_hyp_vcpu *hyp_vcpu;
1091 	u64 ipa = smccc_get_arg1(vcpu);
1092 
1093 	if (!PAGE_ALIGNED(ipa))
1094 		return;
1095 
1096 	hyp_vcpu = container_of(vcpu, struct pkvm_hyp_vcpu, vcpu);
1097 	if (!__pkvm_guest_unshare_host(hyp_vcpu, hyp_phys_to_pfn(ipa)))
1098 		ret[0] = SMCCC_RET_SUCCESS;
1099 }
1100 
1101 /*
1102  * Handler for protected VM HVC calls.
1103  *
1104  * Returns true if the hypervisor has handled the exit (and control
1105  * should return to the guest) or false if it hasn't (and the handling
1106  * should be performed by the host).
1107  */
kvm_handle_pvm_hvc64(struct kvm_vcpu * vcpu,u64 * exit_code)1108 bool kvm_handle_pvm_hvc64(struct kvm_vcpu *vcpu, u64 *exit_code)
1109 {
1110 	u64 val[4] = { SMCCC_RET_INVALID_PARAMETER };
1111 	bool handled = true;
1112 
1113 	switch (smccc_get_function(vcpu)) {
1114 	case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID:
1115 		val[0] = BIT(ARM_SMCCC_KVM_FUNC_FEATURES);
1116 		val[0] |= BIT(ARM_SMCCC_KVM_FUNC_HYP_MEMINFO);
1117 		val[0] |= BIT(ARM_SMCCC_KVM_FUNC_MEM_SHARE);
1118 		val[0] |= BIT(ARM_SMCCC_KVM_FUNC_MEM_UNSHARE);
1119 		break;
1120 	case ARM_SMCCC_VENDOR_HYP_KVM_HYP_MEMINFO_FUNC_ID:
1121 		if (smccc_get_arg1(vcpu) ||
1122 		    smccc_get_arg2(vcpu) ||
1123 		    smccc_get_arg3(vcpu)) {
1124 			break;
1125 		}
1126 
1127 		val[0] = PAGE_SIZE;
1128 		break;
1129 	case ARM_SMCCC_VENDOR_HYP_KVM_MEM_SHARE_FUNC_ID:
1130 		if (smccc_get_arg2(vcpu) ||
1131 		    smccc_get_arg3(vcpu)) {
1132 			break;
1133 		}
1134 
1135 		handled = pkvm_memshare_call(val, vcpu, exit_code);
1136 		break;
1137 	case ARM_SMCCC_VENDOR_HYP_KVM_MEM_UNSHARE_FUNC_ID:
1138 		if (smccc_get_arg2(vcpu) ||
1139 		    smccc_get_arg3(vcpu)) {
1140 			break;
1141 		}
1142 
1143 		pkvm_memunshare_call(val, vcpu);
1144 		break;
1145 	default:
1146 		/* Punt everything else back to the host, for now. */
1147 		handled = false;
1148 	}
1149 
1150 	if (handled)
1151 		smccc_set_retval(vcpu, val[0], val[1], val[2], val[3]);
1152 	return handled;
1153 }
1154