Skip to content

Commit 45ec368

Browse files
jsmattsonjrbonzini
authored andcommitted
kvm: vmx: Raise #UD on unsupported RDRAND
A guest may not be configured to support RDRAND, even when the host does. If the guest does not support RDRAND, intercept the instruction and synthesize #UD. Also clear the "allowed-1" bit for RDRAND exiting in the IA32_VMX_PROCBASED_CTLS2 MSR. Signed-off-by: Jim Mattson <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 80154d7 commit 45ec368

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

arch/x86/kvm/vmx.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2818,7 +2818,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
28182818
vmx->nested.nested_vmx_secondary_ctls_high);
28192819
vmx->nested.nested_vmx_secondary_ctls_low = 0;
28202820
vmx->nested.nested_vmx_secondary_ctls_high &=
2821-
SECONDARY_EXEC_RDRAND | SECONDARY_EXEC_RDSEED |
2821+
SECONDARY_EXEC_RDSEED |
28222822
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
28232823
SECONDARY_EXEC_DESC |
28242824
SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
@@ -3671,6 +3671,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
36713671
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
36723672
SECONDARY_EXEC_SHADOW_VMCS |
36733673
SECONDARY_EXEC_XSAVES |
3674+
SECONDARY_EXEC_RDRAND |
36743675
SECONDARY_EXEC_ENABLE_PML |
36753676
SECONDARY_EXEC_TSC_SCALING |
36763677
SECONDARY_EXEC_ENABLE_VMFUNC;
@@ -5273,6 +5274,12 @@ static u32 vmx_exec_control(struct vcpu_vmx *vmx)
52735274
return exec_control;
52745275
}
52755276

5277+
static bool vmx_rdrand_supported(void)
5278+
{
5279+
return vmcs_config.cpu_based_2nd_exec_ctrl &
5280+
SECONDARY_EXEC_RDRAND;
5281+
}
5282+
52765283
static void vmx_compute_secondary_exec_control(struct vcpu_vmx *vmx)
52775284
{
52785285
struct kvm_vcpu *vcpu = &vmx->vcpu;
@@ -5342,6 +5349,21 @@ static void vmx_compute_secondary_exec_control(struct vcpu_vmx *vmx)
53425349
}
53435350
}
53445351

5352+
if (vmx_rdrand_supported()) {
5353+
bool rdrand_enabled = guest_cpuid_has(vcpu, X86_FEATURE_RDRAND);
5354+
if (rdrand_enabled)
5355+
exec_control &= ~SECONDARY_EXEC_RDRAND;
5356+
5357+
if (nested) {
5358+
if (rdrand_enabled)
5359+
vmx->nested.nested_vmx_secondary_ctls_high |=
5360+
SECONDARY_EXEC_RDRAND;
5361+
else
5362+
vmx->nested.nested_vmx_secondary_ctls_high &=
5363+
~SECONDARY_EXEC_RDRAND;
5364+
}
5365+
}
5366+
53455367
vmx->secondary_exec_control = exec_control;
53465368
}
53475369

@@ -6847,6 +6869,12 @@ static int handle_mwait(struct kvm_vcpu *vcpu)
68476869
return handle_nop(vcpu);
68486870
}
68496871

6872+
static int handle_invalid_op(struct kvm_vcpu *vcpu)
6873+
{
6874+
kvm_queue_exception(vcpu, UD_VECTOR);
6875+
return 1;
6876+
}
6877+
68506878
static int handle_monitor_trap(struct kvm_vcpu *vcpu)
68516879
{
68526880
return 1;
@@ -8090,6 +8118,7 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
80908118
[EXIT_REASON_MONITOR_INSTRUCTION] = handle_monitor,
80918119
[EXIT_REASON_INVEPT] = handle_invept,
80928120
[EXIT_REASON_INVVPID] = handle_invvpid,
8121+
[EXIT_REASON_RDRAND] = handle_invalid_op,
80938122
[EXIT_REASON_XSAVES] = handle_xsaves,
80948123
[EXIT_REASON_XRSTORS] = handle_xrstors,
80958124
[EXIT_REASON_PML_FULL] = handle_pml_full,

0 commit comments

Comments
 (0)