Skip to content

Commit 7647517

Browse files
jsun26inteljren1
authored andcommitted
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>
1 parent 1d0d4d3 commit 7647517

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

hypervisor/arch/x86/cpu_state_tbl.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,31 @@ void load_cpu_state_data(void)
107107

108108
}
109109

110+
int validate_pstate(struct vm *vm, uint64_t perf_ctl)
111+
{
112+
struct cpu_px_data *px_data;
113+
int i, px_cnt;
114+
115+
if (is_vm0(vm)) {
116+
return 0;
117+
}
118+
119+
px_cnt = vm->pm.px_cnt;
120+
px_data = vm->pm.px_data;
121+
122+
if (!px_cnt || !px_data) {
123+
return -1;
124+
}
125+
126+
for (i = 0; i < px_cnt; i++) {
127+
if ((px_data + i)->control == (perf_ctl & 0xffff)) {
128+
return 0;
129+
}
130+
}
131+
132+
return -1;
133+
}
134+
110135
void vm_setup_cpu_px(struct vm *vm)
111136
{
112137
uint32_t px_data_size;

hypervisor/arch/x86/guest/vmsr.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <hv_arch.h>
3434
#include <hv_debug.h>
3535
#include <ucode.h>
36+
#include <cpu_state_tbl.h>
3637

3738
/*MRS need to be emulated, the order in this array better as freq of ops*/
3839
static const uint32_t emulated_msrs[] = {
@@ -135,6 +136,8 @@ void init_msr_emulation(struct vcpu *vcpu)
135136
for (i = 0; i < msrs_count; i++)
136137
enable_msr_interception(msr_bitmap, emulated_msrs[i]);
137138

139+
enable_msr_interception(msr_bitmap, MSR_IA32_PERF_CTL);
140+
138141
/* below MSR protected from guest OS, if access to inject gp*/
139142
enable_msr_interception(msr_bitmap, MSR_IA32_MTRR_CAP);
140143
enable_msr_interception(msr_bitmap, MSR_IA32_MTRR_DEF_TYPE);
@@ -207,6 +210,11 @@ int rdmsr_handler(struct vcpu *vcpu)
207210
v = get_microcode_version();
208211
break;
209212
}
213+
case MSR_IA32_PERF_CTL:
214+
{
215+
v = msr_read(msr);
216+
break;
217+
}
210218

211219
/* following MSR not emulated now just left for future */
212220
case MSR_IA32_SYSENTER_CS:
@@ -303,6 +311,14 @@ int wrmsr_handler(struct vcpu *vcpu)
303311
acrn_update_ucode(vcpu, v);
304312
break;
305313
}
314+
case MSR_IA32_PERF_CTL:
315+
{
316+
if (validate_pstate(vcpu->vm, v)) {
317+
break;
318+
}
319+
msr_write(msr, v);
320+
break;
321+
}
306322

307323
/* following MSR not emulated now just left for future */
308324
case MSR_IA32_SYSENTER_CS:

hypervisor/include/arch/x86/cpu_state_tbl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,6 @@ struct cpu_state_table {
3939

4040
void load_cpu_state_data(void);
4141
void vm_setup_cpu_state(struct vm *vm);
42+
int validate_pstate(struct vm *vm, uint64_t perf_ctl);
4243

4344
#endif /* CPU_STATE_TBL_H */

0 commit comments

Comments
 (0)