The hypercalls can be called with various parameters number. Both x86_64 and i386 are supported.
Signed-off-by: Dor Laor <[EMAIL PROTECTED]> --- include/asm-i386/hypercall.h | 142 ++++++++++++++++++++++++++++++++++++++++ include/asm-x86_64/hypercall.h | 105 +++++++++++++++++++++++++++++ 2 files changed, 247 insertions(+), 0 deletions(-) create mode 100644 include/asm-i386/hypercall.h create mode 100644 include/asm-x86_64/hypercall.h diff --git a/include/asm-i386/hypercall.h b/include/asm-i386/hypercall.h new file mode 100644 index 0000000..40fd31e --- /dev/null +++ b/include/asm-i386/hypercall.h @@ -0,0 +1,142 @@ +#ifndef __ASM_HYPERCALL_H +#define __ASM_HYPERCALL_H + +#define CONFIG_PARAVIRT 1 +#ifdef CONFIG_PARAVIRT + +/* + * Hypercalls, according to the calling convention + * documented in include/linux/kvm_para.h + * + * Copyright (C) 2007, Red Hat, Inc., Ingo Molnar <[EMAIL PROTECTED]> + * Copyright (C) 2007, Qumranet, Inc., Dor Laor <[EMAIL PROTECTED]> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +static inline int __hypercall0(unsigned int nr) +{ + int ret; + asm (" call hypercall_addr\n" + : "=a" (ret) + : "b" (nr) + : "memory", "cc" + ); + return ret; +} + +static inline int __hypercall1(unsigned int nr, unsigned long p1) +{ + int ret; + asm (" call hypercall_addr\n" + : "=a" (ret) + : "b" (nr), + "a" (p1) + : "memory", "cc" + ); + return ret; +} + +static inline int +__hypercall2(unsigned int nr, unsigned long p1, unsigned long p2) +{ + int ret; + asm (" call hypercall_addr\n" + : "=a" (ret) + : "b" (nr), + "a" (p1), + "c" (p2) + : "memory", "cc" + ); + return ret; +} + +static inline int +__hypercall3(unsigned int nr, unsigned long p1, unsigned long p2, + unsigned long p3) +{ + int ret; + asm (" call hypercall_addr\n" + : "=a" (ret) + : "b" (nr), + "a" (p1), + "c" (p2), + "d" (p3) + : "memory", "cc" + ); + return ret; +} + +static inline int +__hypercall4(unsigned int nr, unsigned long p1, unsigned long p2, + unsigned long p3, unsigned long p4) +{ + int ret; + asm (" call hypercall_addr\n" + : "=a" (ret) + : "b" (nr), + "a" (p1), + "c" (p2), + "d" (p3), + "S" (p4) + : "memory", "cc" + ); + return ret; +} + +static inline int +__hypercall5(unsigned int nr, unsigned long p1, unsigned long p2, + unsigned long p3, unsigned long p4, unsigned long p5) +{ + int ret; + asm (" call hypercall_addr\n" + : "=a" (ret) + : "b" (nr), + "a" (p1), + "c" (p2), + "d" (p3), + "S" (p4), + "D" (p5) + : "memory", "cc" + ); + return ret; +} + +static inline int +__hypercall6(unsigned int nr, unsigned long p1, unsigned long p2, + unsigned long p3, unsigned long p4, unsigned long p5, + unsigned long p6) +{ + int ret; + asm (" call hypercall_addr\n" + : "=a" (ret) + : "b" (nr), + "a" (p1), + "c" (p2), + "d" (p3), + "S" (p4), + "D" (p5), + "bp" (p6) + : "memory", "cc" + ); + return ret; +} + +#define hypercall(nr_params, args...) \ +({ \ + /* __ret is volatile to make sure call to this \ + * function isn't optimized away by gcc. Just \ + * having the __hypercallN() functions mention \ + * memory is clobbered isn't enough \ + */ \ + volatile int __ret; \ + \ + __ret = __hypercall##nr_params(args); \ + \ + __ret; \ +}) + +#endif /* CONFIG_PARAVIRT */ + +#endif /* __ASM_HYPERCALL_H */ diff --git a/include/asm-x86_64/hypercall.h b/include/asm-x86_64/hypercall.h new file mode 100644 index 0000000..a331a9f --- /dev/null +++ b/include/asm-x86_64/hypercall.h @@ -0,0 +1,105 @@ +#ifndef __ASM_HYPERCALL_H +#define __ASM_HYPERCALL_H + +#define CONFIG_PARAVIRT 1 +#ifdef CONFIG_PARAVIRT + +/* + * Hypercalls, according to the calling convention + * documented in include/linux/kvm_para.h + * + * Copyright (C) 2007, Red Hat, Inc., Ingo Molnar <[EMAIL PROTECTED]> + * Copyright (C) 2007, Qumranet, Inc., Dor Laor <[EMAIL PROTECTED]> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +static inline int __hypercall0(unsigned int nr) +{ + int ret; + asm (" call hypercall_addr\n" + : "=a" (ret) + : "a" (nr) + : "memory", "cc" + ); + return ret; +} + +static inline int __hypercall1(unsigned int nr, unsigned long p1) +{ + int ret; + asm (" call hypercall_addr\n" + : "=a" (ret) + : "a" (nr), + "D" (p1) + : "memory", "cc" + ); + return ret; +} + +static inline int +__hypercall2(unsigned int nr, unsigned long p1, unsigned long p2) +{ + int ret; + asm (" call hypercall_addr\n" + : "=a" (ret) + : "a" (nr), + "D" (p1), + "S" (p2) + : "memory", "cc" + ); + return ret; +} + +static inline int +__hypercall3(unsigned int nr, unsigned long p1, unsigned long p2, + unsigned long p3) +{ + int ret; + asm (" call hypercall_addr\n" + : "=a" (ret) + : "a" (nr), + "D" (p1), + "S" (p2), + "d" (p3) + : "memory", "cc" + ); + return ret; +} + +static inline int +__hypercall4(unsigned int nr, unsigned long p1, unsigned long p2, + unsigned long p3, unsigned long p4) +{ + int ret; + asm (" call hypercall_addr\n" + : "=a" (ret) + : "a" (nr), + "D" (p1), + "S" (p2), + "d" (p3), + "c" (p4) + : "memory", "cc" + ); + return ret; +} + + +#define hypercall(nr_params, args...) \ +({ \ + /* __ret is volatile to make sure call to this \ + * function isn't optimized away by gcc. Just \ + * having the __hypercallN() functions mention \ + * memory is clobbered isn't enough \ + */ \ + volatile int __ret; \ + \ + __ret = __hypercall##nr_params(args); \ + \ + __ret; \ +}) + +#endif /* CONFIG_PARAVIRT */ + +#endif /* __ASM_HYPERCALL_H */ ----- In simplicity there is elegance. Dor Laor ;) ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel