diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index b7e820d81..4fba7468b 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -729,6 +729,40 @@ int64_t hcall_get_cpu_pm_state(struct vm *vm, uint64_t cmd, uint64_t param) return 0; } + case PMCMD_GET_CX_CNT: { + + if (!target_vm->pm.cx_cnt) { + return -1; + } + + if (copy_to_vm(vm, &(target_vm->pm.cx_cnt), param)) { + pr_err("%s: Unable copy param to vm\n", __func__); + return -1; + } + return 0; + } + case PMCMD_GET_CX_DATA: { + uint8_t cx_idx; + struct cpu_cx_data *cx_data; + + if (!target_vm->pm.cx_cnt) { + return -1; + } + + cx_idx = (cmd & PMCMD_STATE_NUM_MASK) >> PMCMD_STATE_NUM_SHIFT; + if (!cx_idx || (cx_idx > target_vm->pm.cx_cnt)) { + return -1; + } + + cx_data = target_vm->pm.cx_data + cx_idx; + + if (copy_to_vm(vm, cx_data, param)) { + pr_err("%s: Unable copy param to vm\n", __func__); + return -1; + } + + return 0; + } default: return -1; diff --git a/hypervisor/include/arch/x86/guest/pm.h b/hypervisor/include/arch/x86/guest/pm.h index cd463eebe..557a0d501 100644 --- a/hypervisor/include/arch/x86/guest/pm.h +++ b/hypervisor/include/arch/x86/guest/pm.h @@ -33,5 +33,6 @@ void vm_setup_cpu_state(struct vm *vm); int validate_pstate(struct vm *vm, uint64_t perf_ctl); +struct cpu_cx_data* get_target_cx(struct vm *vm, uint8_t cn); #endif /* PM_H */ diff --git a/hypervisor/include/public/acrn_common.h b/hypervisor/include/public/acrn_common.h index 6b474ef38..cf55e0104 100644 --- a/hypervisor/include/public/acrn_common.h +++ b/hypervisor/include/public/acrn_common.h @@ -328,8 +328,10 @@ struct cpu_px_data { /** * @brief Info PM command from DM/VHM. * - * The command would specify request type(i.e. get px count or data) for - * specific VM and specific VCPU with specific state number.like P(n). + * The command would specify request type(e.g. get px count or data) for + * specific VM and specific VCPU with specific state number. + * For Px, PMCMD_STATE_NUM means Px number from 0 to (MAX_PSTATE - 1), + * For Cx, PMCMD_STATE_NUM means Cx entry index from 1 to MAX_CX_ENTRY. */ #define PMCMD_VMID_MASK 0xff000000 #define PMCMD_VCPUID_MASK 0x00ff0000 @@ -343,6 +345,8 @@ struct cpu_px_data { enum pm_cmd_type { PMCMD_GET_PX_CNT, PMCMD_GET_PX_DATA, + PMCMD_GET_CX_CNT, + PMCMD_GET_CX_DATA, }; /**