xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] x86emul: don't allow INVLPG in real mode
@ 2016-04-22 14:17 Jan Beulich
  2016-04-22 14:40 ` Wei Liu
  2016-04-22 16:08 ` Andrew Cooper
  0 siblings, 2 replies; 5+ messages in thread
From: Jan Beulich @ 2016-04-22 14:17 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Wei Liu

[-- Attachment #1: Type: text/plain, Size: 2182 bytes --]

As both INVLPG and INVLPGA have basically the same exception rules
(leaving aside that INVLPGA requires SVME enabled, which so far isn't
being taken care of, and that INVLPG requires ModRM.mod != 3), fold
the handling of the two as much as possible alongside achieving the
goal of the patch (at once doing the #UD checks pror to the #GP one,
which ought to be more in line with how hardware does things).

But please note that AMD and Intel disagree on what exceptions INVLPG
may raise, and the more reasonable Intel variant is being followed.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -3880,13 +3880,14 @@ x86_emulate(
         switch( modrm )
         {
         case 0xdf: /* invlpga */
-            generate_exception_if(!in_protmode(ctxt, ops), EXC_UD, -1);
-            generate_exception_if(!mode_ring0(), EXC_GP, 0);
-            fail_if(ops->invlpg == NULL);
-            if ( (rc = ops->invlpg(x86_seg_none, truncate_ea(_regs.eax),
-                                   ctxt)) )
-                goto done;
-            goto no_writeback;
+            ea.mem.off = truncate_ea(_regs.eax);
+            /*
+             * This is questionable: AMD's PM calls the address used here both
+             * virtual and linear. They've informally indicated "linear" is
+             * meant there.
+             */
+            ea.mem.seg = x86_seg_none;
+            goto invlpg;
         case 0xf9: /* rdtscp */ {
             uint64_t tsc_aux;
             fail_if(ops->read_msr == NULL);
@@ -4006,8 +4007,10 @@ x86_emulate(
                 goto done;
             break;
         case 7: /* invlpg */
-            generate_exception_if(!mode_ring0(), EXC_GP, 0);
             generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
+        invlpg:
+            generate_exception_if(!in_protmode(ctxt, ops), EXC_UD, -1);
+            generate_exception_if(!mode_ring0(), EXC_GP, 0);
             fail_if(ops->invlpg == NULL);
             if ( (rc = ops->invlpg(ea.mem.seg, ea.mem.off, ctxt)) )
                 goto done;




[-- Attachment #2: x86emul-invlpg.patch --]
[-- Type: text/plain, Size: 2220 bytes --]

x86emul: don't allow INVLPG in real mode

As both INVLPG and INVLPGA have basically the same exception rules
(leaving aside that INVLPGA requires SVME enabled, which so far isn't
being taken care of, and that INVLPG requires ModRM.mod != 3), fold
the handling of the two as much as possible alongside achieving the
goal of the patch (at once doing the #UD checks pror to the #GP one,
which ought to be more in line with how hardware does things).

But please note that AMD and Intel disagree on what exceptions INVLPG
may raise, and the more reasonable Intel variant is being followed.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -3880,13 +3880,14 @@ x86_emulate(
         switch( modrm )
         {
         case 0xdf: /* invlpga */
-            generate_exception_if(!in_protmode(ctxt, ops), EXC_UD, -1);
-            generate_exception_if(!mode_ring0(), EXC_GP, 0);
-            fail_if(ops->invlpg == NULL);
-            if ( (rc = ops->invlpg(x86_seg_none, truncate_ea(_regs.eax),
-                                   ctxt)) )
-                goto done;
-            goto no_writeback;
+            ea.mem.off = truncate_ea(_regs.eax);
+            /*
+             * This is questionable: AMD's PM calls the address used here both
+             * virtual and linear. They've informally indicated "linear" is
+             * meant there.
+             */
+            ea.mem.seg = x86_seg_none;
+            goto invlpg;
         case 0xf9: /* rdtscp */ {
             uint64_t tsc_aux;
             fail_if(ops->read_msr == NULL);
@@ -4006,8 +4007,10 @@ x86_emulate(
                 goto done;
             break;
         case 7: /* invlpg */
-            generate_exception_if(!mode_ring0(), EXC_GP, 0);
             generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
+        invlpg:
+            generate_exception_if(!in_protmode(ctxt, ops), EXC_UD, -1);
+            generate_exception_if(!mode_ring0(), EXC_GP, 0);
             fail_if(ops->invlpg == NULL);
             if ( (rc = ops->invlpg(ea.mem.seg, ea.mem.off, ctxt)) )
                 goto done;

[-- Attachment #3: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-04-25  7:28 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-22 14:17 [PATCH] x86emul: don't allow INVLPG in real mode Jan Beulich
2016-04-22 14:40 ` Wei Liu
2016-04-22 15:09   ` Jan Beulich
2016-04-22 16:08 ` Andrew Cooper
2016-04-25  7:28   ` Jan Beulich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).