ia64/xen-unstable

changeset 10370:833d05bdb4a4

[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@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Jun 13 11:28:20 2006 +0100 (2006-06-13)
parents e913081f20f3
children 360f9dc71f51
files xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_64/entry.S xen/include/asm-ia64/config.h xen/include/asm-x86/config.h xen/include/asm-x86/multicall.h
line diff
     1.1 --- a/xen/arch/x86/x86_32/entry.S	Tue Jun 13 10:14:20 2006 +0100
     1.2 +++ b/xen/arch/x86/x86_32/entry.S	Tue Jun 13 11:28:20 2006 +0100
     1.3 @@ -171,7 +171,8 @@ ENTRY(hypercall)
     1.4  	SAVE_ALL(b)
     1.5          sti
     1.6          GET_CURRENT(%ebx)
     1.7 -        andl $(NR_hypercalls-1),%eax
     1.8 +        cmpl  $NR_hypercalls,%eax
     1.9 +        jae   bad_hypercall
    1.10          PERFC_INCR(PERFC_hypercalls, %eax)
    1.11  #ifndef NDEBUG
    1.12          /* Deliberately corrupt parameter regs not used by this hypercall. */
    1.13 @@ -261,6 +262,10 @@ process_nmi:
    1.14  1:      bts  $_VCPUF_nmi_pending,VCPU_flags(%ebx)
    1.15          jmp  test_guest_events
    1.16  
    1.17 +bad_hypercall:
    1.18 +        movl $-ENOSYS,UREGS_eax(%esp)
    1.19 +        jmp  test_all_events
    1.20 +
    1.21  /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK:            */
    1.22  /*   {EIP, CS, EFLAGS, [ESP, SS]}                                        */
    1.23  /* %edx == trap_bounce, %ebx == struct vcpu                       */
     2.1 --- a/xen/arch/x86/x86_64/entry.S	Tue Jun 13 10:14:20 2006 +0100
     2.2 +++ b/xen/arch/x86/x86_64/entry.S	Tue Jun 13 11:28:20 2006 +0100
     2.3 @@ -130,7 +130,8 @@ ENTRY(syscall_enter)
     2.4  
     2.5  /*hypercall:*/
     2.6          movq  %r10,%rcx
     2.7 -        andq  $(NR_hypercalls-1),%rax
     2.8 +        cmpq  $NR_hypercalls,%rax
     2.9 +        jae   bad_hypercall
    2.10  #ifndef NDEBUG
    2.11          /* Deliberately corrupt parameter regs not used by this hypercall. */
    2.12          pushq %rdi; pushq %rsi; pushq %rdx; pushq %rcx; pushq %r8 ; pushq %r9 
    2.13 @@ -142,7 +143,6 @@ ENTRY(syscall_enter)
    2.14          rep   stosq
    2.15          popq  %r9 ; popq  %r8 ; popq  %rcx; popq  %rdx; popq  %rsi; popq  %rdi
    2.16          movq  UREGS_rax(%rsp),%rax
    2.17 -        andq  $(NR_hypercalls-1),%rax
    2.18          pushq %rax
    2.19          pushq UREGS_rip+8(%rsp)
    2.20  #endif
    2.21 @@ -217,7 +217,11 @@ process_nmi:
    2.22          jmp  test_all_events
    2.23  1:      bts  $_VCPUF_nmi_pending,VCPU_flags(%rbx)
    2.24          jmp  test_guest_events
    2.25 -	
    2.26 +
    2.27 +bad_hypercall:
    2.28 +        movq $-ENOSYS,UREGS_rax(%rsp)
    2.29 +        jmp  test_all_events
    2.30 +
    2.31  /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS STACK:                     */
    2.32  /*   { RCX, R11, [DS-GS,] [CR2,] [ERRCODE,] RIP, CS, RFLAGS, RSP, SS }   */
    2.33  /* %rdx: trap_bounce, %rbx: struct vcpu                           */
     3.1 --- a/xen/include/asm-ia64/config.h	Tue Jun 13 10:14:20 2006 +0100
     3.2 +++ b/xen/include/asm-ia64/config.h	Tue Jun 13 11:28:20 2006 +0100
     3.3 @@ -97,13 +97,8 @@ extern char _end[]; /* standard ELF symb
     3.4  //#define HZ 1000
     3.5  // FIXME SMP: leave SMP for a later time
     3.6  
     3.7 -/* A power-of-two value greater than or equal to number of hypercalls. */
     3.8  #define NR_hypercalls 64
     3.9  
    3.10 -#if NR_hypercalls & (NR_hypercalls - 1)
    3.11 -#error "NR_hypercalls must be a power-of-two value"
    3.12 -#endif
    3.13 -
    3.14  ///////////////////////////////////////////////////////////////
    3.15  // xen/include/asm/config.h
    3.16  // Natural boundary upon TR size to define xenheap space
     4.1 --- a/xen/include/asm-x86/config.h	Tue Jun 13 10:14:20 2006 +0100
     4.2 +++ b/xen/include/asm-x86/config.h	Tue Jun 13 11:28:20 2006 +0100
     4.3 @@ -63,13 +63,8 @@
     4.4    name:
     4.5  #endif
     4.6  
     4.7 -/* A power-of-two value greater than or equal to number of hypercalls. */
     4.8  #define NR_hypercalls 64
     4.9  
    4.10 -#if NR_hypercalls & (NR_hypercalls - 1)
    4.11 -#error "NR_hypercalls must be a power-of-two value"
    4.12 -#endif
    4.13 -
    4.14  #ifndef NDEBUG
    4.15  #define MEMORY_GUARD
    4.16  #ifdef __x86_64__
     5.1 --- a/xen/include/asm-x86/multicall.h	Tue Jun 13 10:14:20 2006 +0100
     5.2 +++ b/xen/include/asm-x86/multicall.h	Tue Jun 13 11:28:20 2006 +0100
     5.3 @@ -5,48 +5,59 @@
     5.4  #ifndef __ASM_X86_MULTICALL_H__
     5.5  #define __ASM_X86_MULTICALL_H__
     5.6  
     5.7 +#include <xen/errno.h>
     5.8  #include <asm/asm_defns.h>
     5.9  
    5.10  #ifdef __x86_64__
    5.11  
    5.12 -#define do_multicall_call(_call)                         \
    5.13 -    do {                                                 \
    5.14 -        __asm__ __volatile__ (                           \
    5.15 -            "movq  "STR(MULTICALL_op)"(%0),%%rax; "      \
    5.16 -            "andq  $("STR(NR_hypercalls)"-1),%%rax; "    \
    5.17 -            "leaq  "STR(hypercall_table)"(%%rip),%%rdi; "\
    5.18 -            "leaq  (%%rdi,%%rax,8),%%rax; "              \
    5.19 -            "movq  "STR(MULTICALL_arg0)"(%0),%%rdi; "    \
    5.20 -            "movq  "STR(MULTICALL_arg1)"(%0),%%rsi; "    \
    5.21 -            "movq  "STR(MULTICALL_arg2)"(%0),%%rdx; "    \
    5.22 -            "movq  "STR(MULTICALL_arg3)"(%0),%%rcx; "    \
    5.23 -            "movq  "STR(MULTICALL_arg4)"(%0),%%r8; "     \
    5.24 -            "callq *(%%rax); "                           \
    5.25 -            "movq  %%rax,"STR(MULTICALL_result)"(%0); "  \
    5.26 -            : : "b" (_call)                              \
    5.27 -              /* all the caller-saves registers */       \
    5.28 -            : "rax", "rcx", "rdx", "rsi", "rdi",         \
    5.29 -              "r8",  "r9",  "r10", "r11" );              \
    5.30 +#define do_multicall_call(_call)                             \
    5.31 +    do {                                                     \
    5.32 +        __asm__ __volatile__ (                               \
    5.33 +            "    movq  "STR(MULTICALL_op)"(%0),%%rax; "      \
    5.34 +            "    cmpq  $("STR(NR_hypercalls)"),%%rax; "      \
    5.35 +            "    jae   2f; "                                 \
    5.36 +            "    leaq  "STR(hypercall_table)"(%%rip),%%rdi; "\
    5.37 +            "    leaq  (%%rdi,%%rax,8),%%rax; "              \
    5.38 +            "    movq  "STR(MULTICALL_arg0)"(%0),%%rdi; "    \
    5.39 +            "    movq  "STR(MULTICALL_arg1)"(%0),%%rsi; "    \
    5.40 +            "    movq  "STR(MULTICALL_arg2)"(%0),%%rdx; "    \
    5.41 +            "    movq  "STR(MULTICALL_arg3)"(%0),%%rcx; "    \
    5.42 +            "    movq  "STR(MULTICALL_arg4)"(%0),%%r8; "     \
    5.43 +            "    callq *(%%rax); "                           \
    5.44 +            "1:  movq  %%rax,"STR(MULTICALL_result)"(%0)\n"  \
    5.45 +            ".section .fixup,\"ax\"\n"                       \
    5.46 +            "2:  movq  $-"STR(ENOSYS)",%%rax\n"              \
    5.47 +            "    jmp   1b\n"                                 \
    5.48 +            ".previous\n"                                    \
    5.49 +            : : "b" (_call)                                  \
    5.50 +              /* all the caller-saves registers */           \
    5.51 +            : "rax", "rcx", "rdx", "rsi", "rdi",             \
    5.52 +              "r8",  "r9",  "r10", "r11" );                  \
    5.53      } while ( 0 )
    5.54  
    5.55  #else
    5.56  
    5.57 -#define do_multicall_call(_call)                       \
    5.58 -    do {                                               \
    5.59 -        __asm__ __volatile__ (                         \
    5.60 -            "pushl "STR(MULTICALL_arg4)"(%0); "        \
    5.61 -            "pushl "STR(MULTICALL_arg3)"(%0); "        \
    5.62 -            "pushl "STR(MULTICALL_arg2)"(%0); "        \
    5.63 -            "pushl "STR(MULTICALL_arg1)"(%0); "        \
    5.64 -            "pushl "STR(MULTICALL_arg0)"(%0); "        \
    5.65 -            "movl  "STR(MULTICALL_op)"(%0),%%eax; "    \
    5.66 -            "andl  $("STR(NR_hypercalls)"-1),%%eax; "  \
    5.67 -            "call  *hypercall_table(,%%eax,4); "       \
    5.68 -            "movl  %%eax,"STR(MULTICALL_result)"(%0); "\
    5.69 -            "addl  $20,%%esp; "                        \
    5.70 -            : : "b" (_call)                            \
    5.71 -              /* all the caller-saves registers */     \
    5.72 -            : "eax", "ecx", "edx" );                   \
    5.73 +#define do_multicall_call(_call)                             \
    5.74 +    do {                                                     \
    5.75 +        __asm__ __volatile__ (                               \
    5.76 +            "    pushl "STR(MULTICALL_arg4)"(%0); "          \
    5.77 +            "    pushl "STR(MULTICALL_arg3)"(%0); "          \
    5.78 +            "    pushl "STR(MULTICALL_arg2)"(%0); "          \
    5.79 +            "    pushl "STR(MULTICALL_arg1)"(%0); "          \
    5.80 +            "    pushl "STR(MULTICALL_arg0)"(%0); "          \
    5.81 +            "    movl  "STR(MULTICALL_op)"(%0),%%eax; "      \
    5.82 +            "    cmpl  $("STR(NR_hypercalls)"),%%eax; "      \
    5.83 +            "    jae   2f; "                                 \
    5.84 +            "    call  *hypercall_table(,%%eax,4); "         \
    5.85 +            "1:  movl  %%eax,"STR(MULTICALL_result)"(%0); "  \
    5.86 +            "    addl  $20,%%esp\n"                          \
    5.87 +            ".section .fixup,\"ax\"\n"                       \
    5.88 +            "2:  movl  $-"STR(ENOSYS)",%%eax\n"              \
    5.89 +            "    jmp   1b\n"                                 \
    5.90 +            ".previous\n"                                    \
    5.91 +            : : "b" (_call)                                  \
    5.92 +              /* all the caller-saves registers */           \
    5.93 +            : "eax", "ecx", "edx" );                         \
    5.94      } while ( 0 )
    5.95  
    5.96  #endif