/*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
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
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 */
#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