mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-02 04:15:31 +00:00
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:
parent
0cca1feab2
commit
d0b7c172d4
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user