WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] linux/i386: hypervisor_callback adjustments

To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] linux/i386: hypervisor_callback adjustments
From: "Jan Beulich" <JBeulich@xxxxxxxxxx>
Date: Wed, 13 May 2009 15:21:42 +0100
Delivery-date: Wed, 13 May 2009 07:22:08 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
The missing check of the interrupted code's code selector in
hypervisor_callback() allowed a user mode application to oops (and
perhaps crash) the kernel.

Further adjustments:
- the 'main' critical region does not include the jmp following the
  disabling of interrupts
- the sysexit_[se]crit range checks got broken at some point - the
  sysexit ciritcal region is always at higher addresses than the 'main'
  one, yielding the check pointless (but consuming execution time);
  since the supervisor mode kernel isn't actively used afaict, I moved
  that code into an #ifdef using a hypothetical config option
- the use of a numeric label across more than 300 lines of code always
  seemed pretty fragile to me, so the patch replaces this with a local
  named label
- streamlined the critical_region_fixup code to eliminate a branch

As usual, written and tested on 2.6.30-rc4 and made apply to the 2.6.18
tree without further testing.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>

--- head-2009-05-04.orig/arch/i386/kernel/entry-xen.S   2009-05-13 
14:06:24.000000000 +0200
+++ head-2009-05-04/arch/i386/kernel/entry-xen.S        2009-05-13 
14:11:53.000000000 +0200
@@ -529,8 +531,8 @@ scrit:      /**** START OF CRITICAL REGION **
 .previous
 14:    __DISABLE_INTERRUPTS
        TRACE_IRQS_OFF
-       jmp  11f
 ecrit:  /**** END OF CRITICAL REGION ****/
+       jmp  .Ldo_upcall
 
        CFI_RESTORE_STATE
 hypervisor_iret:
@@ -788,17 +790,23 @@ ENTRY(hypervisor_callback)
        pushl %eax
        CFI_ADJUST_CFA_OFFSET 4
        SAVE_ALL
+       testb $2,CS(%esp)
        movl EIP(%esp),%eax
+       jnz  .Ldo_upcall
        cmpl $scrit,%eax
-       jb   11f
+       jb   0f
        cmpl $ecrit,%eax
        jb   critical_region_fixup
+0:
+#ifdef CONFIG_XEN_SUPERVISOR_MODE_KERNEL
        cmpl $sysexit_scrit,%eax
-       jb   11f
+       jb   .Ldo_upcall
        cmpl $sysexit_ecrit,%eax
-       ja   11f
+       ja   .Ldo_upcall
        addl $OLDESP,%esp               # Remove eflags...ebx from stack frame.
-11:    push %esp
+#endif
+.Ldo_upcall:
+       push %esp
        CFI_ADJUST_CFA_OFFSET 4
        call evtchn_do_upcall
        add  $4,%esp
@@ -814,39 +822,35 @@ ENTRY(hypervisor_callback)
 # provides the number of bytes which have already been popped from the
 # interrupted stack frame.
 critical_region_fixup:
-       movzbl critical_fixup_table-scrit(%eax),%ecx # %eax contains num bytes 
popped
-       cmpb $0xff,%cl                  # 0xff => vcpu_info critical region
-       jne  15f
-       xorl %ecx,%ecx
-15:    leal (%esp,%ecx),%esi           # %esi points at end of src region
+       movsbl critical_fixup_table-scrit(%eax),%ecx # %ecx contains num slots 
popped
+       testl %ecx,%ecx
+       leal (%esp,%ecx,4),%esi         # %esi points at end of src region
        leal OLDESP(%esp),%edi          # %edi points at end of dst region
-       shrl $2,%ecx                    # convert words to bytes
-       je   17f                        # skip loop if nothing to copy
+       jle   17f                       # skip loop if nothing to copy
 16:    subl $4,%esi                    # pre-decrementing copy loop
        subl $4,%edi
        movl (%esi),%eax
        movl %eax,(%edi)
        loop 16b
 17:    movl %edi,%esp                  # final %edi is top of merged stack
-       jmp  11b
+       jmp  .Ldo_upcall
 
 .section .rodata,"a"
 critical_fixup_table:
-       .byte 0xff,0xff,0xff            # testb $0xff,(%esi) = __TEST_PENDING
-       .byte 0xff,0xff                 # jnz  14f
-       .byte 0x00                      # pop  %ebx
-       .byte 0x04                      # pop  %ecx
-       .byte 0x08                      # pop  %edx
-       .byte 0x0c                      # pop  %esi
-       .byte 0x10                      # pop  %edi
-       .byte 0x14                      # pop  %ebp
-       .byte 0x18                      # pop  %eax
-       .byte 0x1c                      # pop  %ds
-       .byte 0x20                      # pop  %es
-       .byte 0x24,0x24,0x24            # add  $4,%esp
-       .byte 0x28                      # iret
-       .byte 0xff,0xff,0xff,0xff       # movb $1,1(%esi)
-       .byte 0x00,0x00                 # jmp  11b
+       .byte -1,-1,-1                  # testb $0xff,(%esi) = __TEST_PENDING
+       .byte -1,-1                     # jnz  14f
+       .byte 0                         # pop  %ebx
+       .byte 1                         # pop  %ecx
+       .byte 2                         # pop  %edx
+       .byte 3                         # pop  %esi
+       .byte 4                         # pop  %edi
+       .byte 5                         # pop  %ebp
+       .byte 6                         # pop  %eax
+       .byte 7                         # pop  %ds
+       .byte 8                         # pop  %es
+       .byte 9,9,9                     # add  $4,%esp
+       .byte 10                        # iret
+       .byte -1,-1,-1,-1               # movb $1,1(%esi) = __DISABLE_INTERRUPTS
 .previous
 
 # Hypervisor uses this for application faults while it executes.




_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] linux/i386: hypervisor_callback adjustments, Jan Beulich <=