Skip to content

Commit 1ad4e54

Browse files
robert-hoobonzini
authored andcommitted
KVM: VMX: Detect Tertiary VM-Execution control when setup VMCS config
Check VMX features on tertiary execution control in VMCS config setup. Sub-features in tertiary execution control to be enabled are adjusted according to hardware capabilities although no sub-feature is enabled in this patch. EVMCSv1 doesn't support tertiary VM-execution control, so disable it when EVMCSv1 is in use. And define the auxiliary functions for Tertiary control field here, using the new BUILD_CONTROLS_SHADOW(). Reviewed-by: Maxim Levitsky <[email protected]> Signed-off-by: Robert Hoo <[email protected]> Signed-off-by: Zeng Guang <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent ed3905b commit 1ad4e54

File tree

7 files changed

+43
-1
lines changed

7 files changed

+43
-1
lines changed

arch/x86/include/asm/vmx.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#define CPU_BASED_RDTSC_EXITING VMCS_CONTROL_BIT(RDTSC_EXITING)
3232
#define CPU_BASED_CR3_LOAD_EXITING VMCS_CONTROL_BIT(CR3_LOAD_EXITING)
3333
#define CPU_BASED_CR3_STORE_EXITING VMCS_CONTROL_BIT(CR3_STORE_EXITING)
34+
#define CPU_BASED_ACTIVATE_TERTIARY_CONTROLS VMCS_CONTROL_BIT(TERTIARY_CONTROLS)
3435
#define CPU_BASED_CR8_LOAD_EXITING VMCS_CONTROL_BIT(CR8_LOAD_EXITING)
3536
#define CPU_BASED_CR8_STORE_EXITING VMCS_CONTROL_BIT(CR8_STORE_EXITING)
3637
#define CPU_BASED_TPR_SHADOW VMCS_CONTROL_BIT(VIRTUAL_TPR)
@@ -221,6 +222,8 @@ enum vmcs_field {
221222
ENCLS_EXITING_BITMAP_HIGH = 0x0000202F,
222223
TSC_MULTIPLIER = 0x00002032,
223224
TSC_MULTIPLIER_HIGH = 0x00002033,
225+
TERTIARY_VM_EXEC_CONTROL = 0x00002034,
226+
TERTIARY_VM_EXEC_CONTROL_HIGH = 0x00002035,
224227
GUEST_PHYSICAL_ADDRESS = 0x00002400,
225228
GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401,
226229
VMCS_LINK_POINTER = 0x00002800,

arch/x86/kvm/vmx/capabilities.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ struct vmcs_config {
5959
u32 pin_based_exec_ctrl;
6060
u32 cpu_based_exec_ctrl;
6161
u32 cpu_based_2nd_exec_ctrl;
62+
u64 cpu_based_3rd_exec_ctrl;
6263
u32 vmexit_ctrl;
6364
u32 vmentry_ctrl;
6465
struct nested_vmx_msrs nested;
@@ -131,6 +132,12 @@ static inline bool cpu_has_secondary_exec_ctrls(void)
131132
CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
132133
}
133134

135+
static inline bool cpu_has_tertiary_exec_ctrls(void)
136+
{
137+
return vmcs_config.cpu_based_exec_ctrl &
138+
CPU_BASED_ACTIVATE_TERTIARY_CONTROLS;
139+
}
140+
134141
static inline bool cpu_has_vmx_virtualize_apic_accesses(void)
135142
{
136143
return vmcs_config.cpu_based_2nd_exec_ctrl &

arch/x86/kvm/vmx/evmcs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,10 @@ const unsigned int nr_evmcs_1_fields = ARRAY_SIZE(vmcs_field_to_evmcs_1);
297297
#if IS_ENABLED(CONFIG_HYPERV)
298298
__init void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf)
299299
{
300+
vmcs_conf->cpu_based_exec_ctrl &= ~EVMCS1_UNSUPPORTED_EXEC_CTRL;
300301
vmcs_conf->pin_based_exec_ctrl &= ~EVMCS1_UNSUPPORTED_PINCTRL;
301302
vmcs_conf->cpu_based_2nd_exec_ctrl &= ~EVMCS1_UNSUPPORTED_2NDEXEC;
303+
vmcs_conf->cpu_based_3rd_exec_ctrl = 0;
302304

303305
vmcs_conf->vmexit_ctrl &= ~EVMCS1_UNSUPPORTED_VMEXIT_CTRL;
304306
vmcs_conf->vmentry_ctrl &= ~EVMCS1_UNSUPPORTED_VMENTRY_CTRL;

arch/x86/kvm/vmx/evmcs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ DECLARE_STATIC_KEY_FALSE(enable_evmcs);
5050
*/
5151
#define EVMCS1_UNSUPPORTED_PINCTRL (PIN_BASED_POSTED_INTR | \
5252
PIN_BASED_VMX_PREEMPTION_TIMER)
53+
#define EVMCS1_UNSUPPORTED_EXEC_CTRL (CPU_BASED_ACTIVATE_TERTIARY_CONTROLS)
5354
#define EVMCS1_UNSUPPORTED_2NDEXEC \
5455
(SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | \
5556
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | \

arch/x86/kvm/vmx/vmcs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct vmcs_controls_shadow {
5050
u32 pin;
5151
u32 exec;
5252
u32 secondary_exec;
53+
u64 tertiary_exec;
5354
};
5455

5556
/*

arch/x86/kvm/vmx/vmx.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2412,6 +2412,15 @@ static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt,
24122412
return 0;
24132413
}
24142414

2415+
static __init u64 adjust_vmx_controls64(u64 ctl_opt, u32 msr)
2416+
{
2417+
u64 allowed;
2418+
2419+
rdmsrl(msr, allowed);
2420+
2421+
return ctl_opt & allowed;
2422+
}
2423+
24152424
static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf,
24162425
struct vmx_capability *vmx_cap)
24172426
{
@@ -2420,6 +2429,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf,
24202429
u32 _pin_based_exec_control = 0;
24212430
u32 _cpu_based_exec_control = 0;
24222431
u32 _cpu_based_2nd_exec_control = 0;
2432+
u64 _cpu_based_3rd_exec_control = 0;
24232433
u32 _vmexit_control = 0;
24242434
u32 _vmentry_control = 0;
24252435

@@ -2441,7 +2451,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf,
24412451

24422452
opt = CPU_BASED_TPR_SHADOW |
24432453
CPU_BASED_USE_MSR_BITMAPS |
2444-
CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
2454+
CPU_BASED_ACTIVATE_SECONDARY_CONTROLS |
2455+
CPU_BASED_ACTIVATE_TERTIARY_CONTROLS;
24452456
if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS,
24462457
&_cpu_based_exec_control) < 0)
24472458
return -EIO;
@@ -2515,6 +2526,13 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf,
25152526
"1-setting enable VPID VM-execution control\n");
25162527
}
25172528

2529+
if (_cpu_based_exec_control & CPU_BASED_ACTIVATE_TERTIARY_CONTROLS) {
2530+
u64 opt3 = 0;
2531+
2532+
_cpu_based_3rd_exec_control = adjust_vmx_controls64(opt3,
2533+
MSR_IA32_VMX_PROCBASED_CTLS3);
2534+
}
2535+
25182536
min = VM_EXIT_SAVE_DEBUG_CONTROLS | VM_EXIT_ACK_INTR_ON_EXIT;
25192537
#ifdef CONFIG_X86_64
25202538
min |= VM_EXIT_HOST_ADDR_SPACE_SIZE;
@@ -2601,6 +2619,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf,
26012619
vmcs_conf->pin_based_exec_ctrl = _pin_based_exec_control;
26022620
vmcs_conf->cpu_based_exec_ctrl = _cpu_based_exec_control;
26032621
vmcs_conf->cpu_based_2nd_exec_ctrl = _cpu_based_2nd_exec_control;
2622+
vmcs_conf->cpu_based_3rd_exec_ctrl = _cpu_based_3rd_exec_control;
26042623
vmcs_conf->vmexit_ctrl = _vmexit_control;
26052624
vmcs_conf->vmentry_ctrl = _vmentry_control;
26062625

@@ -4222,6 +4241,11 @@ static u32 vmx_exec_control(struct vcpu_vmx *vmx)
42224241
return exec_control;
42234242
}
42244243

4244+
static u64 vmx_tertiary_exec_control(struct vcpu_vmx *vmx)
4245+
{
4246+
return vmcs_config.cpu_based_3rd_exec_ctrl;
4247+
}
4248+
42254249
/*
42264250
* Adjust a single secondary execution control bit to intercept/allow an
42274251
* instruction in the guest. This is usually done based on whether or not a
@@ -4387,6 +4411,9 @@ static void init_vmcs(struct vcpu_vmx *vmx)
43874411
if (cpu_has_secondary_exec_ctrls())
43884412
secondary_exec_controls_set(vmx, vmx_secondary_exec_control(vmx));
43894413

4414+
if (cpu_has_tertiary_exec_ctrls())
4415+
tertiary_exec_controls_set(vmx, vmx_tertiary_exec_control(vmx));
4416+
43904417
if (enable_apicv && lapic_in_kernel(&vmx->vcpu)) {
43914418
vmcs_write64(EOI_EXIT_BITMAP0, 0);
43924419
vmcs_write64(EOI_EXIT_BITMAP1, 0);

arch/x86/kvm/vmx/vmx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ BUILD_CONTROLS_SHADOW(vm_exit, VM_EXIT_CONTROLS, 32)
485485
BUILD_CONTROLS_SHADOW(pin, PIN_BASED_VM_EXEC_CONTROL, 32)
486486
BUILD_CONTROLS_SHADOW(exec, CPU_BASED_VM_EXEC_CONTROL, 32)
487487
BUILD_CONTROLS_SHADOW(secondary_exec, SECONDARY_VM_EXEC_CONTROL, 32)
488+
BUILD_CONTROLS_SHADOW(tertiary_exec, TERTIARY_VM_EXEC_CONTROL, 64)
488489

489490
/*
490491
* VMX_REGS_LAZY_LOAD_SET - The set of registers that will be updated in the

0 commit comments

Comments
 (0)