1 /*
2  * Copyright (C) 2018-2022 Intel Corporation.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <types.h>
8 #include <errno.h>
9 #include <profiling.h>
10 #include <sbuf.h>
11 #include <hypercall.h>
12 #include <npk_log.h>
13 #include <asm/guest/vm.h>
14 #include <logmsg.h>
15 
16 #ifdef PROFILING_ON
17 /**
18  * @brief Execute profiling operation
19  *
20  * @param vcpu Pointer to vCPU that initiates the hypercall
21  * @param param1 profiling command to be executed
22  * @param param2 guest physical address. This gpa points to
23  *             data structure required by each command
24  *
25  * @pre is_service_vm(vcpu->vm)
26  * @return 0 on success, non-zero on error.
27  */
hcall_profiling_ops(struct acrn_vcpu * vcpu,__unused struct acrn_vm * target_vm,uint64_t param1,uint64_t param2)28 int32_t hcall_profiling_ops(struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
29 		uint64_t param1, uint64_t param2)
30 {
31 	struct acrn_vm *vm = vcpu->vm;
32 	int32_t ret;
33 	uint64_t cmd = param1;
34 
35 	switch (cmd) {
36 	case PROFILING_MSR_OPS:
37 		ret = profiling_msr_ops_all_cpus(vm, param2);
38 		break;
39 	case PROFILING_GET_VMINFO:
40 		ret = profiling_vm_list_info(vm, param2);
41 		break;
42 	case PROFILING_GET_VERSION:
43 		ret = profiling_get_version_info(vm, param2);
44 		break;
45 	case PROFILING_GET_CONTROL_SWITCH:
46 		ret = profiling_get_control(vm, param2);
47 		break;
48 	case PROFILING_SET_CONTROL_SWITCH:
49 		ret = profiling_set_control(vm, param2);
50 		break;
51 	case PROFILING_CONFIG_PMI:
52 		ret = profiling_configure_pmi(vm, param2);
53 		break;
54 	case PROFILING_CONFIG_VMSWITCH:
55 		ret = profiling_configure_vmsw(vm, param2);
56 		break;
57 	case PROFILING_GET_PCPUID:
58 		ret = profiling_get_pcpu_id(vm, param2);
59 		break;
60 	case PROFILING_GET_STATUS:
61 		ret = profiling_get_status_info(vm, param2);
62 		break;
63 	default:
64 		pr_err("%s: invalid profiling command %lu\n", __func__, cmd);
65 		ret = -1;
66 		break;
67 	}
68  	return ret;
69 }
70 #endif /* PROFILING_ON */
71 
72 /**
73  * @brief Setup the hypervisor NPK log.
74  *
75  * @param vcpu Pointer to vCPU that initiates the hypercall
76  * @param param1 guest physical address. This gpa points to
77  *              struct hv_npk_log_param
78  *
79  * @pre is_service_vm(vcpu->vm)
80  * @return 0 on success, non-zero on error.
81  */
hcall_setup_hv_npk_log(struct acrn_vcpu * vcpu,__unused struct acrn_vm * target_vm,uint64_t param1,__unused uint64_t param2)82 int32_t hcall_setup_hv_npk_log(struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
83 		uint64_t param1, __unused uint64_t param2)
84 {
85 	struct acrn_vm *vm = vcpu->vm;
86 	struct hv_npk_log_param npk_param;
87 
88 	if (copy_from_gpa(vm, &npk_param, param1, sizeof(npk_param)) != 0) {
89 		return -1;
90 	}
91 
92 	npk_log_setup(&npk_param);
93 
94 	return copy_to_gpa(vm, &npk_param, param1, sizeof(npk_param));
95 }
96 
97 /**
98  * @brief Get hardware related info
99  *
100  * @param vcpu Pointer to vCPU that initiates the hypercall
101  * @param param1 Guest physical address pointing to struct acrn_hw_info
102  *
103  * @pre is_service_vm(vcpu->vm)
104  * @pre param1 shall be a valid physical address
105  *
106  * @retval 0 on success
107  * @retval -1 in case of error
108  */
hcall_get_hw_info(struct acrn_vcpu * vcpu,__unused struct acrn_vm * target_vm,uint64_t param1,__unused uint64_t param2)109 int32_t hcall_get_hw_info(struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
110 		uint64_t param1, __unused uint64_t param2)
111 {
112 	struct acrn_hw_info hw_info;
113 
114 	(void)memset((void *)&hw_info, 0U, sizeof(hw_info));
115 
116 	hw_info.cpu_num = get_pcpu_nums();
117 	return copy_to_gpa(vcpu->vm, &hw_info, param1, sizeof(hw_info));
118 }
119