# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID dd974a4e20fd71cccc7307950062bdd9b3246f18
# Parent 15089a58a425cfd556f485d37fd2874e59b3e6bf
[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-unstable changeset: 10332:833d05bdb4a49591928624517d0f496822a05c97
xen-unstable date: Tue Jun 13 11:28:20 2006 +0100
---
xen/arch/x86/x86_32/entry.S | 7 +++
xen/arch/x86/x86_64/entry.S | 10 +++--
xen/include/asm-x86/multicall.h | 79 ++++++++++++++++++++++------------------
3 files changed, 58 insertions(+), 38 deletions(-)
diff -r 15089a58a425 -r dd974a4e20fd xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S Mon Jun 12 14:18:52 2006 +0100
+++ b/xen/arch/x86/x86_32/entry.S Tue Jun 13 11:32:16 2006 +0100
@@ -168,7 +168,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. */
@@ -257,6 +258,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 15089a58a425 -r dd974a4e20fd xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S Mon Jun 12 14:18:52 2006 +0100
+++ b/xen/arch/x86/x86_64/entry.S Tue Jun 13 11:32:16 2006 +0100
@@ -124,7 +124,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
@@ -136,7 +137,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
@@ -211,7 +211,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 15089a58a425 -r dd974a4e20fd xen/include/asm-x86/multicall.h
--- a/xen/include/asm-x86/multicall.h Mon Jun 12 14:18:52 2006 +0100
+++ b/xen/include/asm-x86/multicall.h Tue Jun 13 11:32:16 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
|