[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 5/5] target-i386: implement PKE for TCG
From: |
Richard Henderson |
Subject: |
Re: [Qemu-devel] [PATCH 5/5] target-i386: implement PKE for TCG |
Date: |
Wed, 10 Feb 2016 05:13:45 +1100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.5.0 |
On 02/10/2016 04:13 AM, Paolo Bonzini wrote:
@@ -157,6 +157,7 @@
#define HF_SMAP_SHIFT 23 /* CR4.SMAP */
#define HF_IOBPT_SHIFT 24 /* an io breakpoint enabled */
#define HF_OSXSAVE_SHIFT 25 /* CR4.OSXSAVE */
+#define HF_PKE_SHIFT 26 /* CR4.PKE enabled */
I don't believe you need this bit at all. Certainly you don't use it in
translate.c, where any such test ought to have been.
static uint64_t get_xinuse(CPUX86State *env)
{
- /* We don't track XINUSE. We could calculate it here, but it's
- probably less work to simply indicate all components in use. */
- return -1;
+ uint64_t inuse = -1;
+
+ /* For the most part, we don't track XINUSE. We could calculate it
+ * here for all components, but it's probably less work to simply
+ * indicate in use. That said, for state that is important
+ * enough to track in HFLAGS, we might as well use that here.
+ */
+ if ((env->hflags & HF_PKE_MASK) == 0) {
+ inuse &= ~XSTATE_PKRU;
+ }
+ return inuse;
+}
That does change this of course. But the entire state of the feature is one
32-bit integer -- it's just as easy to test that.
@@ -1357,6 +1399,10 @@ void helper_xrstor(CPUX86State *env, target_ulong ptr,
uint64_t rfbm)
memset(env->xmm_regs, 0, sizeof(env->xmm_regs));
}
}
+
+ if (rfbm & XSTATE_PKRU) {
+ do_xrstor_pkru(env, ptr, GETPC());
+ }
There should be an "ra" variable at the top of this function that already holds
GETPC. Are you forgetting a check on xstate_bv here, to clear pkru?
diff --git a/target-i386/helper.c b/target-i386/helper.c
index f5f0bec..a55628f 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -689,6 +689,16 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
hflags |= HF_SMAP_MASK;
}
+ if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKU)) {
+ new_cr4 &= ~CR4_PKE_MASK;
+ }
+ env->hflags &= ~HF_PKE_MASK;
+ env->features[FEAT_7_0_ECX] &= ~CPUID_7_0_ECX_OSPKE;
+ if (new_cr4 & CR4_PKE_MASK) {
+ env->hflags |= HF_PKE_MASK;
+ env->features[FEAT_7_0_ECX] |= CPUID_7_0_ECX_OSPKE;
+ }
Don't change features bits. Do this test in cpu_x86_cpuid instead. See where
we give the same treatment to OSXSAVE.
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index 460257f..b517559 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -600,3 +600,35 @@ void helper_debug(CPUX86State *env)
cs->exception_index = EXCP_DEBUG;
cpu_loop_exit(cs);
}
+
+void helper_rdpkru(CPUX86State *env)
+{
+ if ((env->cr[4] & CR4_PKE_MASK) == 0) {
+ raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC());
+ return;
+ }
The document I have says #GP for this case, not #UD.
+ if (env->regs[R_ECX] != 0) {
+ raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
+ return;
+ }
In 64-bit mode, ecx 63:32 are ignored.
+
+ env->regs[R_EAX] = env->pkru;
+ env->regs[R_EDX] = 0;
+}
It would be better to return a 64-bit value, split and assign it to eax:edx in
the translator, so that this function does not modify tcg registers.
+
+void helper_wrpkru(CPUX86State *env)
+{
+ CPUState *cs = CPU(x86_env_get_cpu(env));
+
+ if ((env->cr[4] & CR4_PKE_MASK) == 0) {
+ raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC());
+ return;
+ }
Similarly.
diff --git a/target-i386/translate.c b/target-i386/translate.c
index b84ce3b..e2726d4 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -7262,6 +7262,16 @@ static target_ulong disas_insn(CPUX86State *env,
DisasContext *s,
#endif
gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 1);
break;
+ case 0xee: /* rdpkru */
+ gen_update_cc_op(s);
+ gen_jmp_im(pc_start - s->cs_base);
+ gen_helper_rdpkru(cpu_env);
+ break;
No need for either update_cc_op or gen_jmp_im, now that we've got
raise_exception_err_ra.
Missing check for lock prefix.
If you make the change to return a 64-bit value, this would look like
gen_helper_rdpkru(cpu_tmp1_i64, cpu_env);
tcg_gen_extr_i64_tl(cpu_regs[REG_EAX], cpu_regs[REG_EDX], cpu_tmp1_i64);
+ case 0xef: /* wrpkru */
+ gen_update_cc_op(s);
+ gen_jmp_im(pc_start - s->cs_base);
+ gen_helper_wrpkru(cpu_env);
+ break;
CASE_MEM_OP(6): /* lmsw */
if (s->cpl != 0) {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
r~
- [Qemu-devel] [PATCH 0/5] TCG support for XSAVE and PKE, Paolo Bonzini, 2016/02/09
- [Qemu-devel] [PATCH 1/5] target-i386: Split fxsave/fxrstor implementation, Paolo Bonzini, 2016/02/09
- [Qemu-devel] [PATCH 4/5] target-i386: Implement XSAVEOPT, Paolo Bonzini, 2016/02/09
- [Qemu-devel] [PATCH 2/5] target-i386: Rearrange processing of 0F 01, Paolo Bonzini, 2016/02/09
- [Qemu-devel] [PATCH 3/5] target-i386: Add XSAVE extension, Paolo Bonzini, 2016/02/09
- [Qemu-devel] [PATCH 5/5] target-i386: implement PKE for TCG, Paolo Bonzini, 2016/02/09
- Re: [Qemu-devel] [PATCH 5/5] target-i386: implement PKE for TCG,
Richard Henderson <=
- Re: [Qemu-devel] [PATCH 0/5] TCG support for XSAVE and PKE, Richard Henderson, 2016/02/09