HV: trap and validate px request

Currently acrn partitions cpus between SOS and UOS, so the default
policy is to allow guest managing CPU px state. However we would
not blindly passthrough perf_ctrl MSR to guest. Instead guest access
is always trapped and validated by acrn hypervisor before forwarding
to pcpu. Doing so leaves room for future power budget control in
hypervisor, e.g. limiting turbo percentage that a cpu can enter.

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 19:08:38 +08:00 committed by lijinxia
parent 0cca1feab2
commit d0b7c172d4
3 changed files with 42 additions and 0 deletions

View File

@ -107,6 +107,31 @@ void load_cpu_state_data(void)
}
int validate_pstate(struct vm *vm, uint64_t perf_ctl)
{
struct cpu_px_data *px_data;
int i, px_cnt;
if (is_vm0(vm)) {
return 0;
}
px_cnt = vm->pm.px_cnt;
px_data = vm->pm.px_data;
if (!px_cnt || !px_data) {
return -1;
}
for (i = 0; i < px_cnt; i++) {
if ((px_data + i)->control == (perf_ctl & 0xffff)) {
return 0;
}
}
return -1;
}
void vm_setup_cpu_px(struct vm *vm)
{
uint32_t px_data_size;

View File

@ -33,6 +33,7 @@
#include <hv_arch.h>
#include <hv_debug.h>
#include <ucode.h>
#include <cpu_state_tbl.h>
/*MRS need to be emulated, the order in this array better as freq of ops*/
static const uint32_t emulated_msrs[] = {
@ -135,6 +136,8 @@ void init_msr_emulation(struct vcpu *vcpu)
for (i = 0; i < msrs_count; i++)
enable_msr_interception(msr_bitmap, emulated_msrs[i]);
enable_msr_interception(msr_bitmap, MSR_IA32_PERF_CTL);
/* below MSR protected from guest OS, if access to inject gp*/
enable_msr_interception(msr_bitmap, MSR_IA32_MTRR_CAP);
enable_msr_interception(msr_bitmap, MSR_IA32_MTRR_DEF_TYPE);
@ -207,6 +210,11 @@ int rdmsr_handler(struct vcpu *vcpu)
v = get_microcode_version();
break;
}
case MSR_IA32_PERF_CTL:
{
v = msr_read(msr);
break;
}
/* following MSR not emulated now just left for future */
case MSR_IA32_SYSENTER_CS:
@ -303,6 +311,14 @@ int wrmsr_handler(struct vcpu *vcpu)
acrn_update_ucode(vcpu, v);
break;
}
case MSR_IA32_PERF_CTL:
{
if (validate_pstate(vcpu->vm, v)) {
break;
}
msr_write(msr, v);
break;
}
/* following MSR not emulated now just left for future */
case MSR_IA32_SYSENTER_CS:

View File

@ -39,5 +39,6 @@ struct cpu_state_table {
void load_cpu_state_data(void);
void vm_setup_cpu_state(struct vm *vm);
int validate_pstate(struct vm *vm, uint64_t perf_ctl);
#endif /* CPU_STATE_TBL_H */