• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2023 MediaTek Inc.
4  */
5 
6 #include <linux/arm-smccc.h>
7 #include <linux/err.h>
8 #include <linux/uaccess.h>
9 
10 #include <linux/gzvm.h>
11 #include <linux/soc/mediatek/gzvm_drv.h>
12 #include "gzvm_arch_common.h"
13 
gzvm_vcpu_arch_get_timer_delay_ns(struct gzvm_vcpu * vcpu)14 u64 gzvm_vcpu_arch_get_timer_delay_ns(struct gzvm_vcpu *vcpu)
15 {
16 	u64 ns;
17 
18 	if (vcpu->hwstate->vtimer_migrate) {
19 		ns = clocksource_cyc2ns(le64_to_cpu(vcpu->hwstate->vtimer_delay),
20 					gzvm_vtimer_get_clock_mult(),
21 					gzvm_vtimer_get_clock_shift());
22 	} else {
23 		ns = 0;
24 	}
25 
26 	/* 0: no migrate, otherwise: migrate  */
27 	return ns;
28 }
29 
gzvm_arch_vcpu_update_one_reg(struct gzvm_vcpu * vcpu,__u64 reg_id,bool is_write,__u64 * data)30 int gzvm_arch_vcpu_update_one_reg(struct gzvm_vcpu *vcpu, __u64 reg_id,
31 				  bool is_write, __u64 *data)
32 {
33 	struct arm_smccc_res res;
34 	unsigned long a1;
35 	int ret;
36 
37 	a1 = assemble_vm_vcpu_tuple(vcpu->gzvm->vm_id, vcpu->vcpuid);
38 	if (!is_write) {
39 		ret = gzvm_hypcall_wrapper(MT_HVC_GZVM_GET_ONE_REG,
40 					   a1, reg_id, 0, 0, 0, 0, 0, &res);
41 		if (ret == 0)
42 			*data = res.a1;
43 	} else {
44 		ret = gzvm_hypcall_wrapper(MT_HVC_GZVM_SET_ONE_REG,
45 					   a1, reg_id, *data, 0, 0, 0, 0, &res);
46 	}
47 
48 	return ret;
49 }
50 
gzvm_arch_vcpu_run(struct gzvm_vcpu * vcpu,__u64 * exit_reason)51 int gzvm_arch_vcpu_run(struct gzvm_vcpu *vcpu, __u64 *exit_reason)
52 {
53 	struct arm_smccc_res res;
54 	unsigned long a1;
55 	int ret;
56 
57 	a1 = assemble_vm_vcpu_tuple(vcpu->gzvm->vm_id, vcpu->vcpuid);
58 	ret = gzvm_hypcall_wrapper(MT_HVC_GZVM_RUN, a1, 0, 0, 0, 0, 0,
59 				   0, &res);
60 	*exit_reason = res.a1;
61 	return ret;
62 }
63 
gzvm_arch_destroy_vcpu(u16 vm_id,int vcpuid)64 int gzvm_arch_destroy_vcpu(u16 vm_id, int vcpuid)
65 {
66 	struct arm_smccc_res res;
67 	unsigned long a1;
68 
69 	a1 = assemble_vm_vcpu_tuple(vm_id, vcpuid);
70 	gzvm_hypcall_wrapper(MT_HVC_GZVM_DESTROY_VCPU, a1, 0, 0, 0, 0, 0, 0,
71 			     &res);
72 
73 	return 0;
74 }
75 
76 /**
77  * gzvm_arch_create_vcpu() - Call smc to gz hypervisor to create vcpu
78  * @vm_id: vm id
79  * @vcpuid: vcpu id
80  * @run: Virtual address of vcpu->run
81  *
82  * Return: The wrapper helps caller to convert geniezone errno to Linux errno.
83  */
gzvm_arch_create_vcpu(u16 vm_id,int vcpuid,void * run)84 int gzvm_arch_create_vcpu(u16 vm_id, int vcpuid, void *run)
85 {
86 	struct arm_smccc_res res;
87 	unsigned long a1, a2;
88 	int ret;
89 
90 	a1 = assemble_vm_vcpu_tuple(vm_id, vcpuid);
91 	a2 = (__u64)virt_to_phys(run);
92 	ret = gzvm_hypcall_wrapper(MT_HVC_GZVM_CREATE_VCPU, a1, a2, 0, 0, 0, 0,
93 				   0, &res);
94 
95 	return ret;
96 }
97