diff mbox

[2/2] x86/pv: Defer I/O bitmap checks even in 64bit mode for emulate_privilege_op()

Message ID 1483617604-4990-2-git-send-email-andrew.cooper3@citrix.com (mailing list archive)
State New, archived
Headers show

Commit Message

Andrew Cooper Jan. 5, 2017, noon UTC
The I/O bitmap doesn't change function depending on mode.  64bit userspace
such as an X server still needs to enter guest_io_okay() to find that the PV
kernel did set up an appropriate virtual I/O bitmap to permit access.

While moving the check, alter its representation to be easier to read.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/traps.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

Comments

Jan Beulich Jan. 5, 2017, 12:15 p.m. UTC | #1
>>> On 05.01.17 at 13:00, <andrew.cooper3@citrix.com> wrote:
> --- a/xen/arch/x86/traps.c
> +++ b/xen/arch/x86/traps.c
> @@ -2169,6 +2169,19 @@ static int priv_op_read_segment(enum x86_segment seg,
>                                  struct segment_register *reg,
>                                  struct x86_emulate_ctxt *ctxt)
>  {
> +    /* Check if this is an attempt to access to I/O bitmap. */
> +    if ( seg == x86_seg_tr )
> +    {
> +        switch ( ctxt->opcode )
> +        {
> +        case 0x6c ... 0x6f: /* ins / outs */
> +        case 0xe4 ... 0xe7: /* in / out (immediate port) */
> +        case 0xec ... 0xef: /* in / out (port in %dx) */
> +            /* Defer the check to priv_op_{read,write}_io(). */
> +            return X86EMUL_DONE;
> +        }
> +    }

Well, I think I did like the old way a little better, but if you prefer this
switch(), then fine. When putting together my variant of the change for
testing I did notice the comment to have a wrong "to" (should be "the"),
so with that adjusted
Reviewed-by: Jan Beulich <jbeulich@suse.com>

Jan
Andrew Cooper Jan. 5, 2017, 12:20 p.m. UTC | #2
On 05/01/17 12:15, Jan Beulich wrote:
>>>> On 05.01.17 at 13:00, <andrew.cooper3@citrix.com> wrote:
>> --- a/xen/arch/x86/traps.c
>> +++ b/xen/arch/x86/traps.c
>> @@ -2169,6 +2169,19 @@ static int priv_op_read_segment(enum x86_segment seg,
>>                                  struct segment_register *reg,
>>                                  struct x86_emulate_ctxt *ctxt)
>>  {
>> +    /* Check if this is an attempt to access to I/O bitmap. */
>> +    if ( seg == x86_seg_tr )
>> +    {
>> +        switch ( ctxt->opcode )
>> +        {
>> +        case 0x6c ... 0x6f: /* ins / outs */
>> +        case 0xe4 ... 0xe7: /* in / out (immediate port) */
>> +        case 0xec ... 0xef: /* in / out (port in %dx) */
>> +            /* Defer the check to priv_op_{read,write}_io(). */
>> +            return X86EMUL_DONE;
>> +        }
>> +    }
> Well, I think I did like the old way a little better, but if you prefer this
> switch(), then fine. When putting together my variant of the change for
> testing I did notice the comment to have a wrong "to" (should be "the"),

So it is.  Will fix.

> so with that adjusted
> Reviewed-by: Jan Beulich <jbeulich@suse.com>

Thanks.

~Andrew
diff mbox

Patch

diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index a33109d..ea559e9 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -2169,6 +2169,19 @@  static int priv_op_read_segment(enum x86_segment seg,
                                 struct segment_register *reg,
                                 struct x86_emulate_ctxt *ctxt)
 {
+    /* Check if this is an attempt to access to I/O bitmap. */
+    if ( seg == x86_seg_tr )
+    {
+        switch ( ctxt->opcode )
+        {
+        case 0x6c ... 0x6f: /* ins / outs */
+        case 0xe4 ... 0xe7: /* in / out (immediate port) */
+        case 0xec ... 0xef: /* in / out (port in %dx) */
+            /* Defer the check to priv_op_{read,write}_io(). */
+            return X86EMUL_DONE;
+        }
+    }
+
     if ( ctxt->addr_size < 64 )
     {
         unsigned long limit;
@@ -2182,11 +2195,6 @@  static int priv_op_read_segment(enum x86_segment seg,
         case x86_seg_fs: sel = read_sreg(fs);  break;
         case x86_seg_gs: sel = read_sreg(gs);  break;
         case x86_seg_ss: sel = ctxt->regs->ss; break;
-        case x86_seg_tr:
-            /* Check if this is an attempt to access to I/O bitmap. */
-            if ( (ctxt->opcode & ~0xb) == 0xe4 || (ctxt->opcode & ~3) == 0x6c )
-                return X86EMUL_DONE;
-            /* fall through */
         default: return X86EMUL_UNHANDLEABLE;
         }