Dear Maintainers,
Please find attached a .patch that adds support for the UMIP cpu feature to x86
TCG. Apologies for the patch being via attachment, I can not get git send-email
to play nice with office365.
This is my first time committing to the project, so please be nice and point
out any issues or omissions.
Kind Regards
Gareth Webb
From f26c7d99193ffe9313c67cad5de66020b65eb9eb Mon Sep 17 00:00:00 2001
From: Gareth Webb <gareth.w...@umbralsoftware.co.uk>
Date: Sun, 6 Feb 2022 19:16:59 +0000
Subject: [PATCH] Add TCG support for UMIP
Signed-off-by: Gareth Webb <gareth.w...@umbralsoftware.co.uk>
---
target/i386/cpu.c | 2 +-
target/i386/cpu.h | 4 +++-
target/i386/helper.c | 8 +++++++-
target/i386/tcg/translate.c | 12 ++++++++++++
4 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index aa9e636800..20639c375a 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -645,7 +645,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
CPUID_7_0_EBX_RDSEED */
-#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | \
+#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | \
/* CPUID_7_0_ECX_OSPKE is dynamic */ \
CPUID_7_0_ECX_LA57 | CPUID_7_0_ECX_PKS)
#define TCG_7_0_EDX_FEATURES 0
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 9911d7c871..f5cf46e53c 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -167,6 +167,7 @@ typedef enum X86Seg {
#define HF_IOBPT_SHIFT 24 /* an io breakpoint enabled */
#define HF_MPX_EN_SHIFT 25 /* MPX Enabled (CR4+XCR0+BNDCFGx) */
#define HF_MPX_IU_SHIFT 26 /* BND registers in-use */
+#define HF_UMIP_SHIFT 27 /* CR4.UMIP registers in-use */
#define HF_CPL_MASK (3 << HF_CPL_SHIFT)
#define HF_INHIBIT_IRQ_MASK (1 << HF_INHIBIT_IRQ_SHIFT)
@@ -192,6 +193,7 @@ typedef enum X86Seg {
#define HF_IOBPT_MASK (1 << HF_IOBPT_SHIFT)
#define HF_MPX_EN_MASK (1 << HF_MPX_EN_SHIFT)
#define HF_MPX_IU_MASK (1 << HF_MPX_IU_SHIFT)
+#define HF_UMIP_MASK (1 << HF_UMIP_SHIFT)
/* hflags2 */
@@ -258,7 +260,7 @@ typedef enum X86Seg {
(~(target_ulong)(CR4_VME_MASK | CR4_PVI_MASK | CR4_TSD_MASK \
| CR4_DE_MASK | CR4_PSE_MASK | CR4_PAE_MASK \
| CR4_MCE_MASK | CR4_PGE_MASK | CR4_PCE_MASK \
- | CR4_OSFXSR_MASK | CR4_OSXMMEXCPT_MASK |CR4_UMIP_MASK \
+ | CR4_OSFXSR_MASK | CR4_OSXMMEXCPT_MASK | CR4_UMIP_MASK \
| CR4_LA57_MASK \
| CR4_FSGSBASE_MASK | CR4_PCIDE_MASK | CR4_OSXSAVE_MASK \
| CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_PKE_MASK | CR4_PKS_MASK))
diff --git a/target/i386/helper.c b/target/i386/helper.c
index 533b29cb91..a4315048c0 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -174,7 +174,7 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
}
/* Clear bits we're going to recompute. */
- hflags = env->hflags & ~(HF_OSFXSR_MASK | HF_SMAP_MASK);
+ hflags = env->hflags & ~(HF_OSFXSR_MASK | HF_SMAP_MASK | HF_UMIP_MASK);
/* SSE handling */
if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) {
@@ -190,6 +190,12 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
if (new_cr4 & CR4_SMAP_MASK) {
hflags |= HF_SMAP_MASK;
}
+ if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_UMIP)) {
+ new_cr4 &= ~CR4_UMIP_MASK;
+ }
+ if (new_cr4 & CR4_UMIP_MASK) {
+ hflags |= HF_UMIP_MASK;
+ }
if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKU)) {
new_cr4 &= ~CR4_PKE_MASK;
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 77878cd832..69a8f8af2f 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -112,6 +112,7 @@ typedef struct DisasContext {
int cpuid_ext2_features;
int cpuid_ext3_features;
int cpuid_7_0_ebx_features;
+ int cpuid_7_0_ecx_features;
int cpuid_xsave_features;
/* TCG local temps */
@@ -7382,6 +7383,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0: /* sldt */
if (!PE(s) || VM86(s))
goto illegal_op;
+ if ((PE(s) || LMA(s)) && s->cpuid_7_0_ecx_features & CPUID_7_0_ECX_UMIP && s->flags & HF_UMIP_MASK)
+ gen_exception_gpf(s);
gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ);
tcg_gen_ld32u_tl(s->T0, cpu_env,
offsetof(CPUX86State, ldt.selector));
@@ -7401,6 +7404,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 1: /* str */
if (!PE(s) || VM86(s))
goto illegal_op;
+ if ((PE(s) || LMA(s)) && s->cpuid_7_0_ecx_features & CPUID_7_0_ECX_UMIP && s->flags & HF_UMIP_MASK)
+ gen_exception_gpf(s);
gen_svm_check_intercept(s, SVM_EXIT_TR_READ);
tcg_gen_ld32u_tl(s->T0, cpu_env,
offsetof(CPUX86State, tr.selector));
@@ -7439,6 +7444,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
modrm = x86_ldub_code(env, s);
switch (modrm) {
CASE_MODRM_MEM_OP(0): /* sgdt */
+ if ((PE(s) || LMA(s)) && s->cpuid_7_0_ecx_features & CPUID_7_0_ECX_UMIP && s->flags & HF_UMIP_MASK)
+ gen_exception_gpf(s);
gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ);
gen_lea_modrm(env, s, modrm);
tcg_gen_ld32u_tl(s->T0,
@@ -7495,6 +7502,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
break;
CASE_MODRM_MEM_OP(1): /* sidt */
+ if ((PE(s) || LMA(s)) && s->cpuid_7_0_ecx_features & CPUID_7_0_ECX_UMIP && s->flags & HF_UMIP_MASK)
+ gen_exception_gpf(s);
gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ);
gen_lea_modrm(env, s, modrm);
tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.limit));
@@ -7670,6 +7679,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
break;
CASE_MODRM_OP(4): /* smsw */
+ if ((PE(s) || LMA(s)) && s->cpuid_7_0_ecx_features & CPUID_7_0_ECX_UMIP && s->flags & HF_UMIP_MASK)
+ gen_exception_gpf(s);
gen_svm_check_intercept(s, SVM_EXIT_READ_CR0);
tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, cr[0]));
/*
@@ -8585,6 +8596,7 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
+ dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX];
dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) ||
(flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)));
--
2.32.0