HV: add hypercall interface of get vcpu state data

We can use this interface for VHM to pass per-cpu power state data
to guest per its request.

For now the vcpu power state is per-vm, this could be changed if
per-cpu power state support is required in the future.

Signed-off-by: Victor Sun <victor.sun@intel.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
This commit is contained in:
Victor Sun 2018-04-05 17:57:09 +08:00 committed by Jack Ren
parent 0e2b9fc7fa
commit 1d0d4d3185
5 changed files with 97 additions and 0 deletions

View File

@ -142,6 +142,10 @@ int vmcall_handler(struct vcpu *vcpu)
ret = hcall_initialize_trusty(vcpu, param1);
break;
case HC_PM_GET_CPU_STATE:
ret = hcall_get_cpu_pm_state(vm, param1, param2);
break;
default:
pr_err("op %d: Invalid hypercall\n", hypcall_id);
ret = -1;

View File

@ -37,6 +37,7 @@
#include <acrn_hv_defs.h>
#include <hv_debug.h>
#include <version.h>
#include <cpu_state_tbl.h>
#define ACRN_DBG_HYCALL 6
@ -664,6 +665,63 @@ int64_t hcall_setup_sbuf(struct vm *vm, uint64_t param)
return sbuf_share_setup(ssp.pcpu_id, ssp.sbuf_id, hva);
}
int64_t hcall_get_cpu_pm_state(struct vm *vm, uint64_t cmd, uint64_t param)
{
int target_vm_id, target_vcpu_id;
struct vm *target_vm;
struct vcpu *target_vcpu;
target_vm_id = (cmd & PMCMD_VMID_MASK) >> PMCMD_VMID_SHIFT;
target_vm = get_vm_from_vmid(target_vm_id);
if (!target_vm) {
return -1;
}
switch (cmd & PMCMD_TYPE_MASK) {
case PMCMD_GET_PX_CNT: {
if (!target_vm->pm.px_cnt) {
return -1;
}
if (copy_to_vm(vm, &(target_vm->pm.px_cnt), param)) {
pr_err("%s: Unable copy param to vm\n", __func__);
return -1;
}
return 0;
}
case PMCMD_GET_PX_DATA: {
int pn;
struct cpu_px_data *px_data;
/* For now we put px data as per-vm,
* If it is stored as per-cpu in the future,
* we need to check PMCMD_VCPUID_MASK in cmd.
*/
if (!target_vm->pm.px_cnt) {
return -1;
}
pn = (cmd & PMCMD_STATE_NUM_MASK) >> PMCMD_STATE_NUM_SHIFT;
if (pn >= target_vm->pm.px_cnt) {
return -1;
}
px_data = target_vm->pm.px_data + pn;
if (copy_to_vm(vm, px_data, param)) {
pr_err("%s: Unable copy param to vm\n", __func__);
return -1;
}
return 0;
}
default:
return -1;
}
}
static void fire_vhm_interrupt(void)
{
/*

View File

@ -333,6 +333,17 @@ int64_t hcall_setup_sbuf(struct vm *vm, uint64_t param);
*
* @return 0 on success, non-zero on error.
*/
int64_t hcall_get_cpu_pm_state(struct vm *vm, uint64_t cmd, uint64_t param);
/**
* @brief Get VCPU Power state.
*
* @param VCPU power state data
*
* @return 0 on success, non-zero on error.
*/
int64_t hcall_world_switch(struct vcpu *vcpu);
/**

View File

@ -301,6 +301,26 @@ struct cpu_px_data {
uint64_t status; /* success indicator */
} __attribute__((aligned(8)));
/**
* @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).
*/
#define PMCMD_VMID_MASK 0xff000000
#define PMCMD_VCPUID_MASK 0x00ff0000
#define PMCMD_STATE_NUM_MASK 0x0000ff00
#define PMCMD_TYPE_MASK 0x000000ff
#define PMCMD_VMID_SHIFT 24
#define PMCMD_VCPUID_SHIFT 16
#define PMCMD_STATE_NUM_SHIFT 8
enum pm_cmd_type {
PMCMD_GET_PX_CNT,
PMCMD_GET_PX_DATA,
};
/**
* @}
*/

View File

@ -99,6 +99,10 @@
#define HC_WORLD_SWITCH _HC_ID(HC_ID, HC_ID_TRUSTY_BASE + 0x01)
#define HC_GET_SEC_INFO _HC_ID(HC_ID, HC_ID_TRUSTY_BASE + 0x02)
/* Power management */
#define HC_ID_PM_BASE 0x80UL
#define HC_PM_GET_CPU_STATE _HC_ID(HC_ID, HC_ID_PM_BASE + 0x00)
#define ACRN_DOM0_VMID (0UL)
#define ACRN_INVALID_VMID (-1)
#define ACRN_INVALID_HPA (-1UL)