diff mbox

[1/3] target-i386: fix segment flags for SMM and VM86 mode

Message ID 1400173016-27214-2-git-send-email-pbonzini@redhat.com
State New
Headers show

Commit Message

Paolo Bonzini May 15, 2014, 4:56 p.m. UTC
With the next patch, these need to be correct or VM86 tasks
have the wrong CPL.  The flags are basically what the Intel VMX
documentation say is mandatory for entry into a VM86 guest.

For consistency, SMM ought to have the same flags except with
CPL=0.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target-i386/seg_helper.c |  6 ++++--
 target-i386/smm_helper.c | 24 ++++++++++++++++++------
 2 files changed, 22 insertions(+), 8 deletions(-)

Comments

Kevin O'Connor May 15, 2014, 6:45 p.m. UTC | #1
On Thu, May 15, 2014 at 06:56:54PM +0200, Paolo Bonzini wrote:
> With the next patch, these need to be correct or VM86 tasks
> have the wrong CPL.  The flags are basically what the Intel VMX
> documentation say is mandatory for entry into a VM86 guest.
> 
> For consistency, SMM ought to have the same flags except with
> CPL=0.

Does cpu_x86_load_seg() and x86_cpu_gdb_load_seg() then also have to
change?

-Kevin
Paolo Bonzini May 16, 2014, 7:33 a.m. UTC | #2
Il 15/05/2014 20:45, Kevin O'Connor ha scritto:
> On Thu, May 15, 2014 at 06:56:54PM +0200, Paolo Bonzini wrote:
>> With the next patch, these need to be correct or VM86 tasks
>> have the wrong CPL.  The flags are basically what the Intel VMX
>> documentation say is mandatory for entry into a VM86 guest.
>>
>> For consistency, SMM ought to have the same flags except with
>> CPL=0.
>
> Does cpu_x86_load_seg() and x86_cpu_gdb_load_seg() then also have to
> change?

The former is just for user-mode emulation, but it probably doesn't hurt 
to fix it (I just found out about tests/tcg/runcom.c, which can be used 
to test this code path).  For the latter you're right, thanks!

Paolo
diff mbox

Patch

diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 6c0142a..1979520 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -88,8 +88,10 @@  static inline void load_seg_cache_raw_dt(SegmentCache *sc, uint32_t e1,
 static inline void load_seg_vm(CPUX86State *env, int seg, int selector)
 {
     selector &= 0xffff;
-    cpu_x86_load_seg_cache(env, seg, selector,
-                           (selector << 4), 0xffff, 0);
+
+    cpu_x86_load_seg_cache(env, seg, selector, (selector << 4), 0xffff,
+                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+                           DESC_A_MASK | (3 << DESC_DPL_SHIFT));
 }
 
 static inline void get_ss_esp_from_tss(CPUX86State *env, uint32_t *ss_ptr,
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index 2f99493..1e5f5ce 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -170,12 +170,24 @@  void do_smm_enter(X86CPU *cpu)
     env->dr[7] = 0x00000400;
 
     cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase,
-                           0xffffffff, 0);
-    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff, 0);
-    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffffffff, 0);
-    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff, 0);
-    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff, 0);
-    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff, 0);
+                           0xffffffff,
+                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+                           DESC_A_MASK);
+    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff,
+                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+                           DESC_A_MASK);
+    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffffffff,
+                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+                           DESC_A_MASK);
+    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff,
+                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+                           DESC_A_MASK);
+    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff,
+                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+                           DESC_A_MASK);
+    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff,
+                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+                           DESC_A_MASK);
 }
 
 void helper_rsm(CPUX86State *env)