Skip to content

Commit 66336ca

Browse files
committed
KVM: x86: add support for emulating UMIP
The User-Mode Instruction Prevention feature present in recent Intel processor prevents a group of instructions (sgdt, sidt, sldt, smsw, and str) from being executed with CPL > 0. Otherwise, a general protection fault is issued. UMIP instructions in general are also able to trigger vmexits, so we can actually emulate UMIP on older processors. This commit sets up the infrastructure so that kvm-intel.ko and kvm-amd.ko can set the UMIP feature bit for CPUID even if the feature is not actually available in hardware. Reviewed-by: Wanpeng Li <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent dd307d0 commit 66336ca

File tree

4 files changed

+15
-0
lines changed

4 files changed

+15
-0
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,7 @@ struct kvm_x86_ops {
10171017
void (*handle_external_intr)(struct kvm_vcpu *vcpu);
10181018
bool (*mpx_supported)(void);
10191019
bool (*xsaves_supported)(void);
1020+
bool (*umip_emulated)(void);
10201021

10211022
int (*check_nested_events)(struct kvm_vcpu *vcpu, bool external_intr);
10221023

arch/x86/kvm/cpuid.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
327327
unsigned f_invpcid = kvm_x86_ops->invpcid_supported() ? F(INVPCID) : 0;
328328
unsigned f_mpx = kvm_mpx_supported() ? F(MPX) : 0;
329329
unsigned f_xsaves = kvm_x86_ops->xsaves_supported() ? F(XSAVES) : 0;
330+
unsigned f_umip = kvm_x86_ops->umip_emulated() ? F(UMIP) : 0;
330331

331332
/* cpuid 1.edx */
332333
const u32 kvm_cpuid_1_edx_x86_features =
@@ -473,6 +474,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
473474
entry->ebx |= F(TSC_ADJUST);
474475
entry->ecx &= kvm_cpuid_7_0_ecx_x86_features;
475476
cpuid_mask(&entry->ecx, CPUID_7_ECX);
477+
entry->ecx |= f_umip;
476478
/* PKU is not yet implemented for shadow paging. */
477479
if (!tdp_enabled || !boot_cpu_has(X86_FEATURE_OSPKE))
478480
entry->ecx &= ~F(PKU);

arch/x86/kvm/svm.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5204,6 +5204,11 @@ static bool svm_xsaves_supported(void)
52045204
return false;
52055205
}
52065206

5207+
static bool svm_umip_emulated(void)
5208+
{
5209+
return false;
5210+
}
5211+
52075212
static bool svm_has_wbinvd_exit(void)
52085213
{
52095214
return true;
@@ -5597,6 +5602,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
55975602
.invpcid_supported = svm_invpcid_supported,
55985603
.mpx_supported = svm_mpx_supported,
55995604
.xsaves_supported = svm_xsaves_supported,
5605+
.umip_emulated = svm_umip_emulated,
56005606

56015607
.set_supported_cpuid = svm_set_supported_cpuid,
56025608

arch/x86/kvm/vmx.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9155,6 +9155,11 @@ static bool vmx_xsaves_supported(void)
91559155
SECONDARY_EXEC_XSAVES;
91569156
}
91579157

9158+
static bool vmx_umip_emulated(void)
9159+
{
9160+
return false;
9161+
}
9162+
91589163
static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
91599164
{
91609165
u32 exit_intr_info;
@@ -12170,6 +12175,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
1217012175
.handle_external_intr = vmx_handle_external_intr,
1217112176
.mpx_supported = vmx_mpx_supported,
1217212177
.xsaves_supported = vmx_xsaves_supported,
12178+
.umip_emulated = vmx_umip_emulated,
1217312179

1217412180
.check_nested_events = vmx_check_nested_events,
1217512181

0 commit comments

Comments
 (0)