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