[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [XEN] Fix compatibility with future guests which may try to



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 833d05bdb4a49591928624517d0f496822a05c97
# Parent  e913081f20f380c20e381deeb33d25232b36907c
[XEN] Fix compatibility with future guests which may try to
use hypercalls >= NR_hypercalls. These must fail with ENOSYS,
but the current strategy of masking off the high-order bits of
the hypercall number means we instead map those hypercalls onto
lower-numbered hypercalls with unpredictable results. This patch
replaces masking with an explicit compare-and-jump.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/x86_32/entry.S     |    7 +++
 xen/arch/x86/x86_64/entry.S     |   10 +++--
 xen/include/asm-ia64/config.h   |    5 --
 xen/include/asm-x86/config.h    |    5 --
 xen/include/asm-x86/multicall.h |   79 ++++++++++++++++++++++------------------
 5 files changed, 58 insertions(+), 48 deletions(-)

diff -r e913081f20f3 -r 833d05bdb4a4 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S       Tue Jun 13 10:14:20 2006 +0100
+++ b/xen/arch/x86/x86_32/entry.S       Tue Jun 13 11:28:20 2006 +0100
@@ -171,7 +171,8 @@ ENTRY(hypercall)
        SAVE_ALL(b)
         sti
         GET_CURRENT(%ebx)
-        andl $(NR_hypercalls-1),%eax
+        cmpl  $NR_hypercalls,%eax
+        jae   bad_hypercall
         PERFC_INCR(PERFC_hypercalls, %eax)
 #ifndef NDEBUG
         /* Deliberately corrupt parameter regs not used by this hypercall. */
@@ -260,6 +261,10 @@ process_nmi:
         jmp  test_all_events
 1:      bts  $_VCPUF_nmi_pending,VCPU_flags(%ebx)
         jmp  test_guest_events
+
+bad_hypercall:
+        movl $-ENOSYS,UREGS_eax(%esp)
+        jmp  test_all_events
 
 /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK:            */
 /*   {EIP, CS, EFLAGS, [ESP, SS]}                                        */
diff -r e913081f20f3 -r 833d05bdb4a4 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S       Tue Jun 13 10:14:20 2006 +0100
+++ b/xen/arch/x86/x86_64/entry.S       Tue Jun 13 11:28:20 2006 +0100
@@ -130,7 +130,8 @@ ENTRY(syscall_enter)
 
 /*hypercall:*/
         movq  %r10,%rcx
-        andq  $(NR_hypercalls-1),%rax
+        cmpq  $NR_hypercalls,%rax
+        jae   bad_hypercall
 #ifndef NDEBUG
         /* Deliberately corrupt parameter regs not used by this hypercall. */
         pushq %rdi; pushq %rsi; pushq %rdx; pushq %rcx; pushq %r8 ; pushq %r9 
@@ -142,7 +143,6 @@ ENTRY(syscall_enter)
         rep   stosq
         popq  %r9 ; popq  %r8 ; popq  %rcx; popq  %rdx; popq  %rsi; popq  %rdi
         movq  UREGS_rax(%rsp),%rax
-        andq  $(NR_hypercalls-1),%rax
         pushq %rax
         pushq UREGS_rip+8(%rsp)
 #endif
@@ -217,7 +217,11 @@ process_nmi:
         jmp  test_all_events
 1:      bts  $_VCPUF_nmi_pending,VCPU_flags(%rbx)
         jmp  test_guest_events
-       
+
+bad_hypercall:
+        movq $-ENOSYS,UREGS_rax(%rsp)
+        jmp  test_all_events
+
 /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS STACK:                     */
 /*   { RCX, R11, [DS-GS,] [CR2,] [ERRCODE,] RIP, CS, RFLAGS, RSP, SS }   */
 /* %rdx: trap_bounce, %rbx: struct vcpu                           */
diff -r e913081f20f3 -r 833d05bdb4a4 xen/include/asm-ia64/config.h
--- a/xen/include/asm-ia64/config.h     Tue Jun 13 10:14:20 2006 +0100
+++ b/xen/include/asm-ia64/config.h     Tue Jun 13 11:28:20 2006 +0100
@@ -97,12 +97,7 @@ extern char _end[]; /* standard ELF symb
 //#define HZ 1000
 // FIXME SMP: leave SMP for a later time
 
-/* A power-of-two value greater than or equal to number of hypercalls. */
 #define NR_hypercalls 64
-
-#if NR_hypercalls & (NR_hypercalls - 1)
-#error "NR_hypercalls must be a power-of-two value"
-#endif
 
 ///////////////////////////////////////////////////////////////
 // xen/include/asm/config.h
diff -r e913081f20f3 -r 833d05bdb4a4 xen/include/asm-x86/config.h
--- a/xen/include/asm-x86/config.h      Tue Jun 13 10:14:20 2006 +0100
+++ b/xen/include/asm-x86/config.h      Tue Jun 13 11:28:20 2006 +0100
@@ -63,12 +63,7 @@
   name:
 #endif
 
-/* A power-of-two value greater than or equal to number of hypercalls. */
 #define NR_hypercalls 64
-
-#if NR_hypercalls & (NR_hypercalls - 1)
-#error "NR_hypercalls must be a power-of-two value"
-#endif
 
 #ifndef NDEBUG
 #define MEMORY_GUARD
diff -r e913081f20f3 -r 833d05bdb4a4 xen/include/asm-x86/multicall.h
--- a/xen/include/asm-x86/multicall.h   Tue Jun 13 10:14:20 2006 +0100
+++ b/xen/include/asm-x86/multicall.h   Tue Jun 13 11:28:20 2006 +0100
@@ -5,48 +5,59 @@
 #ifndef __ASM_X86_MULTICALL_H__
 #define __ASM_X86_MULTICALL_H__
 
+#include <xen/errno.h>
 #include <asm/asm_defns.h>
 
 #ifdef __x86_64__
 
-#define do_multicall_call(_call)                         \
-    do {                                                 \
-        __asm__ __volatile__ (                           \
-            "movq  "STR(MULTICALL_op)"(%0),%%rax; "      \
-            "andq  $("STR(NR_hypercalls)"-1),%%rax; "    \
-            "leaq  "STR(hypercall_table)"(%%rip),%%rdi; "\
-            "leaq  (%%rdi,%%rax,8),%%rax; "              \
-            "movq  "STR(MULTICALL_arg0)"(%0),%%rdi; "    \
-            "movq  "STR(MULTICALL_arg1)"(%0),%%rsi; "    \
-            "movq  "STR(MULTICALL_arg2)"(%0),%%rdx; "    \
-            "movq  "STR(MULTICALL_arg3)"(%0),%%rcx; "    \
-            "movq  "STR(MULTICALL_arg4)"(%0),%%r8; "     \
-            "callq *(%%rax); "                           \
-            "movq  %%rax,"STR(MULTICALL_result)"(%0); "  \
-            : : "b" (_call)                              \
-              /* all the caller-saves registers */       \
-            : "rax", "rcx", "rdx", "rsi", "rdi",         \
-              "r8",  "r9",  "r10", "r11" );              \
+#define do_multicall_call(_call)                             \
+    do {                                                     \
+        __asm__ __volatile__ (                               \
+            "    movq  "STR(MULTICALL_op)"(%0),%%rax; "      \
+            "    cmpq  $("STR(NR_hypercalls)"),%%rax; "      \
+            "    jae   2f; "                                 \
+            "    leaq  "STR(hypercall_table)"(%%rip),%%rdi; "\
+            "    leaq  (%%rdi,%%rax,8),%%rax; "              \
+            "    movq  "STR(MULTICALL_arg0)"(%0),%%rdi; "    \
+            "    movq  "STR(MULTICALL_arg1)"(%0),%%rsi; "    \
+            "    movq  "STR(MULTICALL_arg2)"(%0),%%rdx; "    \
+            "    movq  "STR(MULTICALL_arg3)"(%0),%%rcx; "    \
+            "    movq  "STR(MULTICALL_arg4)"(%0),%%r8; "     \
+            "    callq *(%%rax); "                           \
+            "1:  movq  %%rax,"STR(MULTICALL_result)"(%0)\n"  \
+            ".section .fixup,\"ax\"\n"                       \
+            "2:  movq  $-"STR(ENOSYS)",%%rax\n"              \
+            "    jmp   1b\n"                                 \
+            ".previous\n"                                    \
+            : : "b" (_call)                                  \
+              /* all the caller-saves registers */           \
+            : "rax", "rcx", "rdx", "rsi", "rdi",             \
+              "r8",  "r9",  "r10", "r11" );                  \
     } while ( 0 )
 
 #else
 
-#define do_multicall_call(_call)                       \
-    do {                                               \
-        __asm__ __volatile__ (                         \
-            "pushl "STR(MULTICALL_arg4)"(%0); "        \
-            "pushl "STR(MULTICALL_arg3)"(%0); "        \
-            "pushl "STR(MULTICALL_arg2)"(%0); "        \
-            "pushl "STR(MULTICALL_arg1)"(%0); "        \
-            "pushl "STR(MULTICALL_arg0)"(%0); "        \
-            "movl  "STR(MULTICALL_op)"(%0),%%eax; "    \
-            "andl  $("STR(NR_hypercalls)"-1),%%eax; "  \
-            "call  *hypercall_table(,%%eax,4); "       \
-            "movl  %%eax,"STR(MULTICALL_result)"(%0); "\
-            "addl  $20,%%esp; "                        \
-            : : "b" (_call)                            \
-              /* all the caller-saves registers */     \
-            : "eax", "ecx", "edx" );                   \
+#define do_multicall_call(_call)                             \
+    do {                                                     \
+        __asm__ __volatile__ (                               \
+            "    pushl "STR(MULTICALL_arg4)"(%0); "          \
+            "    pushl "STR(MULTICALL_arg3)"(%0); "          \
+            "    pushl "STR(MULTICALL_arg2)"(%0); "          \
+            "    pushl "STR(MULTICALL_arg1)"(%0); "          \
+            "    pushl "STR(MULTICALL_arg0)"(%0); "          \
+            "    movl  "STR(MULTICALL_op)"(%0),%%eax; "      \
+            "    cmpl  $("STR(NR_hypercalls)"),%%eax; "      \
+            "    jae   2f; "                                 \
+            "    call  *hypercall_table(,%%eax,4); "         \
+            "1:  movl  %%eax,"STR(MULTICALL_result)"(%0); "  \
+            "    addl  $20,%%esp\n"                          \
+            ".section .fixup,\"ax\"\n"                       \
+            "2:  movl  $-"STR(ENOSYS)",%%eax\n"              \
+            "    jmp   1b\n"                                 \
+            ".previous\n"                                    \
+            : : "b" (_call)                                  \
+              /* all the caller-saves registers */           \
+            : "eax", "ecx", "edx" );                         \
     } while ( 0 )
 
 #endif

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.