]> xenbits.xensource.com Git - xen.git/commitdiff
x86: Special case __HYPERVISOR_iret rather more when writing hypercall pages
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 16 Jul 2013 09:10:45 +0000 (11:10 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 16 Jul 2013 09:10:45 +0000 (11:10 +0200)
In all cases when a hypercall page is written, __HYPERVISOR_iret is first
written as a regular hypercall, then subsequently rewritten in its special
case.

For VMX and SVM, this means that following the ud2a instruction is 3 bytes of
an imm32 parameter.  For a ring3 kernel, this means that following the syscall
instruction is the second half of 'pop %r11'.

For a ring1 kernel, the iret case ends up as the same number of bytes as the
rest of the hypercalls, but it is pointless writing it twice, and is changed
for consistency.

Therefore, skip the loop iteration which would write the incorrect
__HYPERVISOR_iret hypercall.  This removes junk machine code from the tail and
makes disassemblers rather more happy when looking at the hypercall page.

Also, a miscellaneous whitespace fix in the comment for ring3 kernel.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/vmx/vmx.c
xen/arch/x86/x86_64/compat/traps.c
xen/arch/x86/x86_64/traps.c

index 4a7aeeecf594affa9dc58e18ad9e872d30604af3..4cc4b15315c635d8de6bb718522c003a9b121e12 100644 (file)
@@ -759,6 +759,9 @@ static void svm_init_hypercall_page(struct domain *d, void *hypercall_page)
 
     for ( i = 0; i < (PAGE_SIZE / 32); i++ )
     {
+        if ( i == __HYPERVISOR_iret )
+            continue;
+
         p = (char *)(hypercall_page + (i * 32));
         *(u8  *)(p + 0) = 0xb8; /* mov imm32, %eax */
         *(u32 *)(p + 1) = i;
index 059d258d2d5a157e67f4c70997979b6179866466..d6540e3d79cb8797906e84e30225f04b97fc7047 100644 (file)
@@ -950,6 +950,9 @@ static void vmx_init_hypercall_page(struct domain *d, void *hypercall_page)
 
     for ( i = 0; i < (PAGE_SIZE / 32); i++ )
     {
+        if ( i == __HYPERVISOR_iret )
+            continue;
+
         p = (char *)(hypercall_page + (i * 32));
         *(u8  *)(p + 0) = 0xb8; /* mov imm32, %eax */
         *(u32 *)(p + 1) = i;
index 6816b0ed6aab4110ada4ee6e576a2454cfb6d0ef..21a82b91eb7322cb7bf26fdd0ff7bfca8fc27670 100644 (file)
@@ -367,6 +367,9 @@ static void hypercall_page_initialise_ring1_kernel(void *hypercall_page)
 
     for ( i = 0; i < (PAGE_SIZE / 32); i++ )
     {
+        if ( i == __HYPERVISOR_iret )
+            continue;
+
         p = (char *)(hypercall_page + (i * 32));
         *(u8  *)(p+ 0) = 0xb8;    /* mov  $<i>,%eax */
         *(u32 *)(p+ 1) = i;
index eec919aebb6db0bec90bba07f3056abfde816d57..bcd760908e8c2855eb16cbda3f85f3859839aa3e 100644 (file)
@@ -590,6 +590,9 @@ static void hypercall_page_initialise_ring3_kernel(void *hypercall_page)
     /* Fill in all the transfer points with template machine code. */
     for ( i = 0; i < (PAGE_SIZE / 32); i++ )
     {
+        if ( i == __HYPERVISOR_iret )
+            continue;
+
         p = (char *)(hypercall_page + (i * 32));
         *(u8  *)(p+ 0) = 0x51;    /* push %rcx */
         *(u16 *)(p+ 1) = 0x5341;  /* push %r11 */
@@ -602,8 +605,8 @@ static void hypercall_page_initialise_ring3_kernel(void *hypercall_page)
     }
 
     /*
-     * HYPERVISOR_iret is special because it doesn't return and expects a 
-     * special stack frame. Guests jump at this transfer point instead of 
+     * HYPERVISOR_iret is special because it doesn't return and expects a
+     * special stack frame. Guests jump at this transfer point instead of
      * calling it.
      */
     p = (char *)(hypercall_page + (__HYPERVISOR_iret * 32));