direct-io.hg

changeset 6452:37e9c9cd6c14

Clean up and fix hypercall macros in XenLinux: we must assume that
all register parameters are clobbered on return. Furthermore,
multicall arrays are clobbered on return from a multicall (only the
result field can be trusted!).

These restrictions are enforced by debug builds of Xen in the
following ways:
1. On completion of a multicall, the call array is overwritten
with garbage before writing in the result fields.
2. On completion of a hypercall, all parameter registers are
overwritten with garbage.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Aug 26 17:42:34 2005 +0000 (2005-08-26)
parents 2b95125015a5
children 3bbc9384be3f
files linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h xen/arch/x86/x86_32/asm-offsets.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_64/asm-offsets.c xen/arch/x86/x86_64/entry.S xen/common/multicall.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Fri Aug 26 13:06:49 2005 +0000
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Fri Aug 26 17:42:34 2005 +0000
     1.3 @@ -63,16 +63,19 @@ static int privcmd_ioctl(struct inode *i
     1.4              "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
     1.5              : "=a" (ret) : "0" (&hypercall) : "memory" );
     1.6  #elif defined (__x86_64__)
     1.7 -	__asm__ __volatile__ (
     1.8 -	    "movq   %5,%%r10; movq %6,%%r8;" TRAP_INSTR
     1.9 -	    : "=a" (ret)
    1.10 -	    : "a" ((unsigned long)hypercall.op), 
    1.11 -	      "D" ((unsigned long)hypercall.arg[0]), 
    1.12 -	      "S" ((unsigned long)hypercall.arg[1]),
    1.13 -	      "d" ((unsigned long)hypercall.arg[2]), 
    1.14 -	      "g" ((unsigned long)hypercall.arg[3]),
    1.15 -	      "g" ((unsigned long)hypercall.arg[4])
    1.16 -	    : "r11","rcx","r8","r10","memory");
    1.17 +        {
    1.18 +            long ign1, ign2, ign3;
    1.19 +            __asm__ __volatile__ (
    1.20 +                "movq   %5,%%r10; movq %6,%%r8;" TRAP_INSTR
    1.21 +                : "=a" (ret), "=D" (ign1), "=S" (ign2), "=d" (ign3)
    1.22 +                : "0" ((unsigned long)hypercall.op), 
    1.23 +                "1" ((unsigned long)hypercall.arg[0]), 
    1.24 +                "2" ((unsigned long)hypercall.arg[1]),
    1.25 +                "3" ((unsigned long)hypercall.arg[2]), 
    1.26 +                "g" ((unsigned long)hypercall.arg[3]),
    1.27 +                "g" ((unsigned long)hypercall.arg[4])
    1.28 +                : "r11","rcx","r8","r10","memory");
    1.29 +        }
    1.30  #endif
    1.31      }
    1.32      break;
     2.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h	Fri Aug 26 13:06:49 2005 +0000
     2.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h	Fri Aug 26 17:42:34 2005 +0000
     2.3 @@ -29,551 +29,362 @@
     2.4  
     2.5  #ifndef __HYPERCALL_H__
     2.6  #define __HYPERCALL_H__
     2.7 +
     2.8  #include <asm-xen/xen-public/xen.h>
     2.9  
    2.10 -/*
    2.11 - * Assembler stubs for hyper-calls.
    2.12 - */
    2.13 +#define _hypercall0(type, name)			\
    2.14 +({						\
    2.15 +	long __res;				\
    2.16 +	asm volatile (				\
    2.17 +		TRAP_INSTR			\
    2.18 +		: "=a" (__res)			\
    2.19 +		: "0" (__HYPERVISOR_##name)	\
    2.20 +		: "memory" );			\
    2.21 +	(type)__res;				\
    2.22 +})
    2.23 +
    2.24 +#define _hypercall1(type, name, a1)				\
    2.25 +({								\
    2.26 +	long __res, __ign1;					\
    2.27 +	asm volatile (						\
    2.28 +		TRAP_INSTR					\
    2.29 +		: "=a" (__res), "=b" (__ign1)			\
    2.30 +		: "0" (__HYPERVISOR_##name), "1" ((long)(a1))	\
    2.31 +		: "memory" );					\
    2.32 +	(type)__res;						\
    2.33 +})
    2.34 +
    2.35 +#define _hypercall2(type, name, a1, a2)				\
    2.36 +({								\
    2.37 +	long __res, __ign1, __ign2;				\
    2.38 +	asm volatile (						\
    2.39 +		TRAP_INSTR					\
    2.40 +		: "=a" (__res), "=b" (__ign1), "=c" (__ign2)	\
    2.41 +		: "0" (__HYPERVISOR_##name), "1" ((long)(a1)),	\
    2.42 +		"2" ((long)(a2))				\
    2.43 +		: "memory" );					\
    2.44 +	(type)__res;						\
    2.45 +})
    2.46 +
    2.47 +#define _hypercall3(type, name, a1, a2, a3)			\
    2.48 +({								\
    2.49 +	long __res, __ign1, __ign2, __ign3;			\
    2.50 +	asm volatile (						\
    2.51 +		TRAP_INSTR					\
    2.52 +		: "=a" (__res), "=b" (__ign1), "=c" (__ign2), 	\
    2.53 +		"=d" (__ign3)					\
    2.54 +		: "0" (__HYPERVISOR_##name), "1" ((long)(a1)),	\
    2.55 +		"2" ((long)(a2)), "3" ((long)(a3))		\
    2.56 +		: "memory" );					\
    2.57 +	(type)__res;						\
    2.58 +})
    2.59 +
    2.60 +#define _hypercall4(type, name, a1, a2, a3, a4)			\
    2.61 +({								\
    2.62 +	long __res, __ign1, __ign2, __ign3, __ign4;		\
    2.63 +	asm volatile (						\
    2.64 +		TRAP_INSTR					\
    2.65 +		: "=a" (__res), "=b" (__ign1), "=c" (__ign2),	\
    2.66 +		"=d" (__ign3), "=S" (__ign4)			\
    2.67 +		: "0" (__HYPERVISOR_##name), "1" ((long)(a1)),	\
    2.68 +		"2" ((long)(a2)), "3" ((long)(a3)),		\
    2.69 +		"4" ((long)(a4))				\
    2.70 +		: "memory" );					\
    2.71 +	(type)__res;						\
    2.72 +})
    2.73 +
    2.74 +#define _hypercall5(type, name, a1, a2, a3, a4, a5)		\
    2.75 +({								\
    2.76 +	long __res, __ign1, __ign2, __ign3, __ign4, __ign5;	\
    2.77 +	asm volatile (						\
    2.78 +		TRAP_INSTR					\
    2.79 +		: "=a" (__res), "=b" (__ign1), "=c" (__ign2),	\
    2.80 +		"=d" (__ign3), "=S" (__ign4), "=D" (__ign5)	\
    2.81 +		: "0" (__HYPERVISOR_##name), "1" ((long)(a1)),	\
    2.82 +		"2" ((long)(a2)), "3" ((long)(a3)),		\
    2.83 +		"4" ((long)(a4)), "5" ((long)(a5))		\
    2.84 +		: "memory" );					\
    2.85 +	(type)__res;						\
    2.86 +})
    2.87  
    2.88  static inline int
    2.89  HYPERVISOR_set_trap_table(
    2.90 -    trap_info_t *table)
    2.91 +	trap_info_t *table)
    2.92  {
    2.93 -    int ret;
    2.94 -    unsigned long ignore;
    2.95 -
    2.96 -    __asm__ __volatile__ (
    2.97 -        TRAP_INSTR
    2.98 -        : "=a" (ret), "=b" (ignore)
    2.99 -	: "0" (__HYPERVISOR_set_trap_table), "1" (table)
   2.100 -	: "memory" );
   2.101 -
   2.102 -    return ret;
   2.103 +	return _hypercall1(int, set_trap_table, table);
   2.104  }
   2.105  
   2.106  static inline int
   2.107  HYPERVISOR_mmu_update(
   2.108 -    mmu_update_t *req, int count, int *success_count, domid_t domid)
   2.109 +	mmu_update_t *req, int count, int *success_count, domid_t domid)
   2.110  {
   2.111 -    int ret;
   2.112 -    unsigned long ign1, ign2, ign3, ign4;
   2.113 -
   2.114 -    __asm__ __volatile__ (
   2.115 -        TRAP_INSTR
   2.116 -        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
   2.117 -	: "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
   2.118 -        "3" (success_count), "4" (domid)
   2.119 -	: "memory" );
   2.120 -
   2.121 -    return ret;
   2.122 +	return _hypercall4(int, mmu_update, req, count, success_count, domid);
   2.123  }
   2.124  
   2.125  static inline int
   2.126  HYPERVISOR_mmuext_op(
   2.127 -    struct mmuext_op *op, int count, int *success_count, domid_t domid)
   2.128 +	struct mmuext_op *op, int count, int *success_count, domid_t domid)
   2.129  {
   2.130 -    int ret;
   2.131 -    unsigned long ign1, ign2, ign3, ign4;
   2.132 -
   2.133 -    __asm__ __volatile__ (
   2.134 -        TRAP_INSTR
   2.135 -        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
   2.136 -	: "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count),
   2.137 -        "3" (success_count), "4" (domid)
   2.138 -	: "memory" );
   2.139 -
   2.140 -    return ret;
   2.141 +	return _hypercall4(int, mmuext_op, op, count, success_count, domid);
   2.142  }
   2.143  
   2.144  static inline int
   2.145  HYPERVISOR_set_gdt(
   2.146 -    unsigned long *frame_list, int entries)
   2.147 +	unsigned long *frame_list, int entries)
   2.148  {
   2.149 -    int ret;
   2.150 -    unsigned long ign1, ign2;
   2.151 -
   2.152 -    __asm__ __volatile__ (
   2.153 -        TRAP_INSTR
   2.154 -        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   2.155 -	: "0" (__HYPERVISOR_set_gdt), "1" (frame_list), "2" (entries)
   2.156 -	: "memory" );
   2.157 -
   2.158 -
   2.159 -    return ret;
   2.160 +	return _hypercall2(int, set_gdt, frame_list, entries);
   2.161  }
   2.162  
   2.163  static inline int
   2.164  HYPERVISOR_stack_switch(
   2.165 -    unsigned long ss, unsigned long esp)
   2.166 +	unsigned long ss, unsigned long esp)
   2.167  {
   2.168 -    int ret;
   2.169 -    unsigned long ign1, ign2;
   2.170 -
   2.171 -    __asm__ __volatile__ (
   2.172 -        TRAP_INSTR
   2.173 -        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   2.174 -	: "0" (__HYPERVISOR_stack_switch), "1" (ss), "2" (esp)
   2.175 -	: "memory" );
   2.176 -
   2.177 -    return ret;
   2.178 +	return _hypercall2(int, stack_switch, ss, esp);
   2.179  }
   2.180  
   2.181  static inline int
   2.182  HYPERVISOR_set_callbacks(
   2.183 -    unsigned long event_selector, unsigned long event_address,
   2.184 -    unsigned long failsafe_selector, unsigned long failsafe_address)
   2.185 +	unsigned long event_selector, unsigned long event_address,
   2.186 +	unsigned long failsafe_selector, unsigned long failsafe_address)
   2.187  {
   2.188 -    int ret;
   2.189 -    unsigned long ign1, ign2, ign3, ign4;
   2.190 -
   2.191 -    __asm__ __volatile__ (
   2.192 -        TRAP_INSTR
   2.193 -        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
   2.194 -	: "0" (__HYPERVISOR_set_callbacks), "1" (event_selector),
   2.195 -	  "2" (event_address), "3" (failsafe_selector), "4" (failsafe_address)
   2.196 -	: "memory" );
   2.197 -
   2.198 -    return ret;
   2.199 +	return _hypercall4(int, set_callbacks,
   2.200 +			   event_selector, event_address,
   2.201 +			   failsafe_selector, failsafe_address);
   2.202  }
   2.203  
   2.204  static inline int
   2.205  HYPERVISOR_fpu_taskswitch(
   2.206 -    int set)
   2.207 +	int set)
   2.208  {
   2.209 -    int ret;
   2.210 -    unsigned long ign;
   2.211 -
   2.212 -    __asm__ __volatile__ (
   2.213 -        TRAP_INSTR
   2.214 -        : "=a" (ret), "=b" (ign)
   2.215 -        : "0" (__HYPERVISOR_fpu_taskswitch), "1" (set)
   2.216 -        : "memory" );
   2.217 -
   2.218 -    return ret;
   2.219 +	return _hypercall1(int, fpu_taskswitch, set);
   2.220  }
   2.221  
   2.222  static inline int
   2.223  HYPERVISOR_yield(
   2.224 -    void)
   2.225 +	void)
   2.226  {
   2.227 -    int ret;
   2.228 -    unsigned long ign;
   2.229 -
   2.230 -    __asm__ __volatile__ (
   2.231 -        TRAP_INSTR
   2.232 -        : "=a" (ret), "=b" (ign)
   2.233 -	: "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield)
   2.234 -	: "memory", "ecx" );
   2.235 -
   2.236 -    return ret;
   2.237 +	return _hypercall2(int, sched_op, SCHEDOP_yield, 0);
   2.238  }
   2.239  
   2.240  static inline int
   2.241  HYPERVISOR_block(
   2.242 -    void)
   2.243 +	void)
   2.244  {
   2.245 -    int ret;
   2.246 -    unsigned long ign1;
   2.247 -    __asm__ __volatile__ (
   2.248 -        TRAP_INSTR
   2.249 -        : "=a" (ret), "=b" (ign1)
   2.250 -	: "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block)
   2.251 -	: "memory", "ecx" );
   2.252 -
   2.253 -    return ret;
   2.254 +	return _hypercall2(int, sched_op, SCHEDOP_block, 0);
   2.255  }
   2.256  
   2.257  static inline int
   2.258  HYPERVISOR_shutdown(
   2.259 -    void)
   2.260 +	void)
   2.261  {
   2.262 -    int ret;
   2.263 -    unsigned long ign1;
   2.264 -    __asm__ __volatile__ (
   2.265 -        TRAP_INSTR
   2.266 -        : "=a" (ret), "=b" (ign1)
   2.267 -	: "0" (__HYPERVISOR_sched_op),
   2.268 -	  "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
   2.269 -        : "memory", "ecx" );
   2.270 -
   2.271 -    return ret;
   2.272 +	return _hypercall2(int, sched_op, SCHEDOP_shutdown |
   2.273 +			   (SHUTDOWN_poweroff << SCHEDOP_reasonshift), 0);
   2.274  }
   2.275  
   2.276  static inline int
   2.277  HYPERVISOR_reboot(
   2.278 -    void)
   2.279 +	void)
   2.280  {
   2.281 -    int ret;
   2.282 -    unsigned long ign1;
   2.283 -    __asm__ __volatile__ (
   2.284 -        TRAP_INSTR
   2.285 -        : "=a" (ret), "=b" (ign1)
   2.286 -	: "0" (__HYPERVISOR_sched_op),
   2.287 -	  "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
   2.288 -        : "memory", "ecx" );
   2.289 -
   2.290 -    return ret;
   2.291 -}
   2.292 -
   2.293 -static inline int
   2.294 -HYPERVISOR_suspend(
   2.295 -    unsigned long srec)
   2.296 -{
   2.297 -    int ret;
   2.298 -    unsigned long ign1, ign2;
   2.299 -
   2.300 -    /* NB. On suspend, control software expects a suspend record in %esi. */
   2.301 -    __asm__ __volatile__ (
   2.302 -        TRAP_INSTR
   2.303 -        : "=a" (ret), "=b" (ign1), "=S" (ign2)
   2.304 -	: "0" (__HYPERVISOR_sched_op),
   2.305 -        "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), 
   2.306 -        "S" (srec) : "memory", "ecx");
   2.307 -
   2.308 -    return ret;
   2.309 +	return _hypercall2(int, sched_op, SCHEDOP_shutdown |
   2.310 +			   (SHUTDOWN_reboot << SCHEDOP_reasonshift), 0);
   2.311  }
   2.312  
   2.313  static inline int
   2.314  HYPERVISOR_crash(
   2.315 -    void)
   2.316 +	void)
   2.317  {
   2.318 -    int ret;
   2.319 -    unsigned long ign1;
   2.320 -    __asm__ __volatile__ (
   2.321 -        TRAP_INSTR
   2.322 -        : "=a" (ret), "=b" (ign1)
   2.323 -	: "0" (__HYPERVISOR_sched_op),
   2.324 -	  "1" (SCHEDOP_shutdown | (SHUTDOWN_crash << SCHEDOP_reasonshift))
   2.325 -        : "memory", "ecx" );
   2.326 -
   2.327 -    return ret;
   2.328 +	return _hypercall2(int, sched_op, SCHEDOP_shutdown |
   2.329 +			   (SHUTDOWN_crash << SCHEDOP_reasonshift), 0);
   2.330  }
   2.331  
   2.332  static inline long
   2.333  HYPERVISOR_set_timer_op(
   2.334 -    u64 timeout)
   2.335 +	u64 timeout)
   2.336  {
   2.337 -    int ret;
   2.338 -    unsigned long timeout_hi = (unsigned long)(timeout>>32);
   2.339 -    unsigned long timeout_lo = (unsigned long)timeout;
   2.340 -    unsigned long ign1, ign2;
   2.341 -
   2.342 -    __asm__ __volatile__ (
   2.343 -        TRAP_INSTR
   2.344 -        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   2.345 -	: "0" (__HYPERVISOR_set_timer_op), "b" (timeout_lo), "c" (timeout_hi)
   2.346 -	: "memory");
   2.347 -
   2.348 -    return ret;
   2.349 +	unsigned long timeout_hi = (unsigned long)(timeout>>32);
   2.350 +	unsigned long timeout_lo = (unsigned long)timeout;
   2.351 +	return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
   2.352  }
   2.353  
   2.354  static inline int
   2.355  HYPERVISOR_dom0_op(
   2.356 -    dom0_op_t *dom0_op)
   2.357 +	dom0_op_t *dom0_op)
   2.358  {
   2.359 -    int ret;
   2.360 -    unsigned long ign1;
   2.361 -
   2.362 -    dom0_op->interface_version = DOM0_INTERFACE_VERSION;
   2.363 -    __asm__ __volatile__ (
   2.364 -        TRAP_INSTR
   2.365 -        : "=a" (ret), "=b" (ign1)
   2.366 -	: "0" (__HYPERVISOR_dom0_op), "1" (dom0_op)
   2.367 -	: "memory");
   2.368 -
   2.369 -    return ret;
   2.370 +	dom0_op->interface_version = DOM0_INTERFACE_VERSION;
   2.371 +	return _hypercall1(int, dom0_op, dom0_op);
   2.372  }
   2.373  
   2.374  static inline int
   2.375  HYPERVISOR_set_debugreg(
   2.376 -    int reg, unsigned long value)
   2.377 +	int reg, unsigned long value)
   2.378  {
   2.379 -    int ret;
   2.380 -    unsigned long ign1, ign2;
   2.381 -    __asm__ __volatile__ (
   2.382 -        TRAP_INSTR
   2.383 -        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   2.384 -	: "0" (__HYPERVISOR_set_debugreg), "1" (reg), "2" (value)
   2.385 -	: "memory" );
   2.386 -
   2.387 -    return ret;
   2.388 +	return _hypercall2(int, set_debugreg, reg, value);
   2.389  }
   2.390  
   2.391  static inline unsigned long
   2.392  HYPERVISOR_get_debugreg(
   2.393 -    int reg)
   2.394 +	int reg)
   2.395  {
   2.396 -    unsigned long ret;
   2.397 -    unsigned long ign;
   2.398 -    __asm__ __volatile__ (
   2.399 -        TRAP_INSTR
   2.400 -        : "=a" (ret), "=b" (ign)
   2.401 -	: "0" (__HYPERVISOR_get_debugreg), "1" (reg)
   2.402 -	: "memory" );
   2.403 -
   2.404 -    return ret;
   2.405 +	return _hypercall1(unsigned long, get_debugreg, reg);
   2.406  }
   2.407  
   2.408  static inline int
   2.409  HYPERVISOR_update_descriptor(
   2.410 -    u64 ma, u64 desc)
   2.411 +	u64 ma, u64 desc)
   2.412  {
   2.413 -    int ret;
   2.414 -    unsigned long ign1, ign2, ign3, ign4;
   2.415 -
   2.416 -    __asm__ __volatile__ (
   2.417 -        TRAP_INSTR
   2.418 -        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
   2.419 -	: "0" (__HYPERVISOR_update_descriptor),
   2.420 -	  "1" ((unsigned long)ma), "2" ((unsigned long)(ma>>32)),
   2.421 -	  "3" ((unsigned long)desc), "4" ((unsigned long)(desc>>32))
   2.422 -	: "memory" );
   2.423 -
   2.424 -    return ret;
   2.425 +	return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32);
   2.426  }
   2.427  
   2.428  static inline int
   2.429  HYPERVISOR_dom_mem_op(
   2.430 -    unsigned int op, unsigned long *extent_list,
   2.431 -    unsigned long nr_extents, unsigned int extent_order)
   2.432 +	unsigned int op, unsigned long *extent_list,
   2.433 +	unsigned long nr_extents, unsigned int extent_order)
   2.434  {
   2.435 -    int ret;
   2.436 -    unsigned long ign1, ign2, ign3, ign4, ign5;
   2.437 -
   2.438 -    __asm__ __volatile__ (
   2.439 -        TRAP_INSTR
   2.440 -        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
   2.441 -	  "=D" (ign5)
   2.442 -	: "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list),
   2.443 -	  "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF)
   2.444 -        : "memory" );
   2.445 -
   2.446 -    return ret;
   2.447 +	return _hypercall5(int, dom_mem_op, op, extent_list,
   2.448 +			   nr_extents, extent_order, DOMID_SELF);
   2.449  }
   2.450  
   2.451  static inline int
   2.452  HYPERVISOR_multicall(
   2.453 -    void *call_list, int nr_calls)
   2.454 +	void *call_list, int nr_calls)
   2.455  {
   2.456 -    int ret;
   2.457 -    unsigned long ign1, ign2;
   2.458 -
   2.459 -    __asm__ __volatile__ (
   2.460 -        TRAP_INSTR
   2.461 -        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   2.462 -	: "0" (__HYPERVISOR_multicall), "1" (call_list), "2" (nr_calls)
   2.463 -	: "memory" );
   2.464 -
   2.465 -    return ret;
   2.466 +	return _hypercall2(int, multicall, call_list, nr_calls);
   2.467  }
   2.468  
   2.469  static inline int
   2.470  HYPERVISOR_update_va_mapping(
   2.471 -    unsigned long va, pte_t new_val, unsigned long flags)
   2.472 +	unsigned long va, pte_t new_val, unsigned long flags)
   2.473  {
   2.474 -    int ret;
   2.475 -    unsigned long ign1, ign2, ign3, ign4;
   2.476 -
   2.477 -    __asm__ __volatile__ (
   2.478 -        TRAP_INSTR
   2.479 -        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
   2.480 -	: "0" (__HYPERVISOR_update_va_mapping), 
   2.481 -          "1" (va), "2" ((new_val).pte_low),
   2.482 +	unsigned long pte_hi = 0;
   2.483  #ifdef CONFIG_X86_PAE
   2.484 -	  "3" ((new_val).pte_high),
   2.485 -#else
   2.486 -	  "3" (0),
   2.487 +	pte_hi = new_val.pte_high;
   2.488  #endif
   2.489 -	  "4" (flags)
   2.490 -	: "memory" );
   2.491 -
   2.492 -    return ret;
   2.493 +	return _hypercall4(int, update_va_mapping, va,
   2.494 +			   new_val.pte_low, pte_hi, flags);
   2.495  }
   2.496  
   2.497  static inline int
   2.498  HYPERVISOR_event_channel_op(
   2.499 -    void *op)
   2.500 +	void *op)
   2.501  {
   2.502 -    int ret;
   2.503 -    unsigned long ignore;
   2.504 -    __asm__ __volatile__ (
   2.505 -        TRAP_INSTR
   2.506 -        : "=a" (ret), "=b" (ignore)
   2.507 -	: "0" (__HYPERVISOR_event_channel_op), "1" (op)
   2.508 -	: "memory" );
   2.509 -
   2.510 -    return ret;
   2.511 +	return _hypercall1(int, event_channel_op, op);
   2.512  }
   2.513  
   2.514  static inline int
   2.515  HYPERVISOR_xen_version(
   2.516 -    int cmd)
   2.517 +	int cmd)
   2.518  {
   2.519 -    int ret;
   2.520 -    unsigned long ignore;
   2.521 -
   2.522 -    __asm__ __volatile__ (
   2.523 -        TRAP_INSTR
   2.524 -        : "=a" (ret), "=b" (ignore)
   2.525 -	: "0" (__HYPERVISOR_xen_version), "1" (cmd)
   2.526 -	: "memory" );
   2.527 -
   2.528 -    return ret;
   2.529 +	return _hypercall1(int, xen_version, cmd);
   2.530  }
   2.531  
   2.532  static inline int
   2.533  HYPERVISOR_console_io(
   2.534 -    int cmd, int count, char *str)
   2.535 +	int cmd, int count, char *str)
   2.536  {
   2.537 -    int ret;
   2.538 -    unsigned long ign1, ign2, ign3;
   2.539 -    __asm__ __volatile__ (
   2.540 -        TRAP_INSTR
   2.541 -        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
   2.542 -	: "0" (__HYPERVISOR_console_io), "1" (cmd), "2" (count), "3" (str)
   2.543 -	: "memory" );
   2.544 -
   2.545 -    return ret;
   2.546 +	return _hypercall3(int, console_io, cmd, count, str);
   2.547  }
   2.548  
   2.549  static inline int
   2.550  HYPERVISOR_physdev_op(
   2.551 -    void *physdev_op)
   2.552 +	void *physdev_op)
   2.553  {
   2.554 -    int ret;
   2.555 -    unsigned long ign;
   2.556 -
   2.557 -    __asm__ __volatile__ (
   2.558 -        TRAP_INSTR
   2.559 -        : "=a" (ret), "=b" (ign)
   2.560 -	: "0" (__HYPERVISOR_physdev_op), "1" (physdev_op)
   2.561 -	: "memory" );
   2.562 -
   2.563 -    return ret;
   2.564 +	return _hypercall1(int, physdev_op, physdev_op);
   2.565  }
   2.566  
   2.567  static inline int
   2.568  HYPERVISOR_grant_table_op(
   2.569 -    unsigned int cmd, void *uop, unsigned int count)
   2.570 +	unsigned int cmd, void *uop, unsigned int count)
   2.571  {
   2.572 -    int ret;
   2.573 -    unsigned long ign1, ign2, ign3;
   2.574 -
   2.575 -    __asm__ __volatile__ (
   2.576 -        TRAP_INSTR
   2.577 -        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
   2.578 -	: "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (uop), "3" (count)
   2.579 -	: "memory" );
   2.580 -
   2.581 -    return ret;
   2.582 +	return _hypercall3(int, grant_table_op, cmd, uop, count);
   2.583  }
   2.584  
   2.585  static inline int
   2.586  HYPERVISOR_update_va_mapping_otherdomain(
   2.587 -    unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
   2.588 +	unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
   2.589  {
   2.590 -    int ret;
   2.591 -    unsigned long ign1, ign2, ign3, ign4, ign5;
   2.592 -
   2.593 -    __asm__ __volatile__ (
   2.594 -        TRAP_INSTR
   2.595 -        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3),
   2.596 -	  "=S" (ign4), "=D" (ign5)
   2.597 -	: "0" (__HYPERVISOR_update_va_mapping_otherdomain),
   2.598 -          "1" (va), "2" ((new_val).pte_low),
   2.599 +	unsigned long pte_hi = 0;
   2.600  #ifdef CONFIG_X86_PAE
   2.601 -	  "3" ((new_val).pte_high),
   2.602 -#else
   2.603 -	  "3" (0),
   2.604 +	pte_hi = new_val.pte_high;
   2.605  #endif
   2.606 -	  "4" (flags), "5" (domid) :
   2.607 -        "memory" );
   2.608 -    
   2.609 -    return ret;
   2.610 +	return _hypercall5(int, update_va_mapping_otherdomain, va,
   2.611 +			   new_val.pte_low, pte_hi, flags, domid);
   2.612  }
   2.613  
   2.614  static inline int
   2.615  HYPERVISOR_vm_assist(
   2.616 -    unsigned int cmd, unsigned int type)
   2.617 +	unsigned int cmd, unsigned int type)
   2.618  {
   2.619 -    int ret;
   2.620 -    unsigned long ign1, ign2;
   2.621 -
   2.622 -    __asm__ __volatile__ (
   2.623 -        TRAP_INSTR
   2.624 -        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   2.625 -	: "0" (__HYPERVISOR_vm_assist), "1" (cmd), "2" (type)
   2.626 -	: "memory" );
   2.627 -
   2.628 -    return ret;
   2.629 +	return _hypercall2(int, vm_assist, cmd, type);
   2.630  }
   2.631  
   2.632  static inline int
   2.633  HYPERVISOR_boot_vcpu(
   2.634 -    unsigned long vcpu, vcpu_guest_context_t *ctxt)
   2.635 +	unsigned long vcpu, vcpu_guest_context_t *ctxt)
   2.636  {
   2.637 -    int ret;
   2.638 -    unsigned long ign1, ign2;
   2.639 +	return _hypercall2(int, boot_vcpu, vcpu, ctxt);
   2.640 +}
   2.641 +
   2.642 +static inline int
   2.643 +HYPERVISOR_vcpu_up(
   2.644 +	int vcpu)
   2.645 +{
   2.646 +	return _hypercall2(int, sched_op, SCHEDOP_vcpu_up |
   2.647 +			   (vcpu << SCHEDOP_vcpushift), 0);
   2.648 +}
   2.649  
   2.650 -    __asm__ __volatile__ (
   2.651 -        TRAP_INSTR
   2.652 -        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   2.653 -	: "0" (__HYPERVISOR_boot_vcpu), "1" (vcpu), "2" (ctxt)
   2.654 -	: "memory");
   2.655 +static inline int
   2.656 +HYPERVISOR_vcpu_pickle(
   2.657 +	int vcpu, vcpu_guest_context_t *ctxt)
   2.658 +{
   2.659 +	return _hypercall2(int, sched_op, SCHEDOP_vcpu_pickle |
   2.660 +			   (vcpu << SCHEDOP_vcpushift), ctxt);
   2.661 +}
   2.662  
   2.663 -    return ret;
   2.664 +static inline int
   2.665 +HYPERVISOR_suspend(
   2.666 +	unsigned long srec)
   2.667 +{
   2.668 +	int ret;
   2.669 +	unsigned long ign1, ign2;
   2.670 +
   2.671 +	/* On suspend, control software expects a suspend record in %esi. */
   2.672 +	__asm__ __volatile__ (
   2.673 +		TRAP_INSTR
   2.674 +		: "=a" (ret), "=b" (ign1), "=S" (ign2)
   2.675 +		: "0" (__HYPERVISOR_sched_op),
   2.676 +		"1" (SCHEDOP_shutdown | (SHUTDOWN_suspend <<
   2.677 +					 SCHEDOP_reasonshift)), 
   2.678 +		"2" (srec) : "memory", "ecx");
   2.679 +
   2.680 +	return ret;
   2.681  }
   2.682  
   2.683  static inline int
   2.684  HYPERVISOR_vcpu_down(
   2.685 -    int vcpu)
   2.686 -{
   2.687 -    int ret;
   2.688 -    unsigned long ign1;
   2.689 -    /* Yes, I really do want to clobber edx here: when we resume a
   2.690 -       vcpu after unpickling a multi-processor domain, it returns
   2.691 -       here, but clobbers all of the call clobbered registers. */
   2.692 -    __asm__ __volatile__ (
   2.693 -        TRAP_INSTR
   2.694 -        : "=a" (ret), "=b" (ign1)
   2.695 -	: "0" (__HYPERVISOR_sched_op),
   2.696 -	  "1" (SCHEDOP_vcpu_down | (vcpu << SCHEDOP_vcpushift))
   2.697 -        : "memory", "ecx", "edx" );
   2.698 -
   2.699 -    return ret;
   2.700 -}
   2.701 -
   2.702 -static inline int
   2.703 -HYPERVISOR_vcpu_up(
   2.704 -    int vcpu)
   2.705 +	int vcpu)
   2.706  {
   2.707 -    int ret;
   2.708 -    unsigned long ign1;
   2.709 -    __asm__ __volatile__ (
   2.710 -        TRAP_INSTR
   2.711 -        : "=a" (ret), "=b" (ign1)
   2.712 -	: "0" (__HYPERVISOR_sched_op),
   2.713 -	  "1" (SCHEDOP_vcpu_up | (vcpu << SCHEDOP_vcpushift))
   2.714 -        : "memory", "ecx" );
   2.715 -
   2.716 -    return ret;
   2.717 -}
   2.718 -
   2.719 -static inline int
   2.720 -HYPERVISOR_vcpu_pickle(
   2.721 -    int vcpu, vcpu_guest_context_t *ctxt)
   2.722 -{
   2.723 -    int ret;
   2.724 -    unsigned long ign1, ign2;
   2.725 -    __asm__ __volatile__ (
   2.726 -        TRAP_INSTR
   2.727 -        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   2.728 -	: "0" (__HYPERVISOR_sched_op),
   2.729 -	  "1" (SCHEDOP_vcpu_pickle | (vcpu << SCHEDOP_vcpushift)),
   2.730 -	  "2" (ctxt)
   2.731 -        : "memory" );
   2.732 -
   2.733 -    return ret;
   2.734 +	int ret;
   2.735 +	unsigned long ign1;
   2.736 +	/* Yes, I really do want to clobber edx here: when we resume a
   2.737 +	   vcpu after unpickling a multi-processor domain, it returns
   2.738 +	   here, but clobbers all of the call clobbered registers. */
   2.739 +	__asm__ __volatile__ (
   2.740 +		TRAP_INSTR
   2.741 +		: "=a" (ret), "=b" (ign1)
   2.742 +		: "0" (__HYPERVISOR_sched_op),
   2.743 +		"1" (SCHEDOP_vcpu_down | (vcpu << SCHEDOP_vcpushift))
   2.744 +		: "memory", "ecx", "edx" );
   2.745 +	return ret;
   2.746  }
   2.747  
   2.748  #endif /* __HYPERCALL_H__ */
   2.749 +
   2.750 +/*
   2.751 + * Local variables:
   2.752 + *  c-file-style: "linux"
   2.753 + *  indent-tabs-mode: t
   2.754 + *  c-indent-level: 8
   2.755 + *  c-basic-offset: 8
   2.756 + *  tab-width: 8
   2.757 + * End:
   2.758 + */
     3.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h	Fri Aug 26 13:06:49 2005 +0000
     3.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h	Fri Aug 26 17:42:34 2005 +0000
     3.3 @@ -5,6 +5,10 @@
     3.4   * 
     3.5   * Copyright (c) 2002-2004, K A Fraser
     3.6   * 
     3.7 + * 64-bit updates:
     3.8 + *   Benjamin Liu <benjamin.liu@intel.com>
     3.9 + *   Jun Nakajima <jun.nakajima@intel.com>
    3.10 + * 
    3.11   * This file may be distributed separately from the Linux kernel, or
    3.12   * incorporated into other software packages, subject to the following license:
    3.13   * 
    3.14 @@ -26,497 +30,331 @@
    3.15   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    3.16   * IN THE SOFTWARE.
    3.17   */
    3.18 -/*
    3.19 - * Benjamin Liu <benjamin.liu@intel.com>
    3.20 - * Jun Nakajima <jun.nakajima@intel.com>
    3.21 - *   Ported to x86-64.
    3.22 - * 
    3.23 - */
    3.24  
    3.25  #ifndef __HYPERCALL_H__
    3.26  #define __HYPERCALL_H__
    3.27 +
    3.28  #include <asm-xen/xen-public/xen.h>
    3.29  
    3.30  #define __syscall_clobber "r11","rcx","memory"
    3.31  
    3.32 -/*
    3.33 - * Assembler stubs for hyper-calls.
    3.34 - */
    3.35 +#define _hypercall0(type, name)			\
    3.36 +({						\
    3.37 +	long __res;				\
    3.38 +	asm volatile (				\
    3.39 +		TRAP_INSTR			\
    3.40 +		: "=a" (__res)			\
    3.41 +		: "0" (__HYPERVISOR_##name)	\
    3.42 +		: __syscall_clobber );		\
    3.43 +	(type)__res;				\
    3.44 +})
    3.45 +
    3.46 +#define _hypercall1(type, name, a1)				\
    3.47 +({								\
    3.48 +	long __res, __ign1;					\
    3.49 +	asm volatile (						\
    3.50 +		TRAP_INSTR					\
    3.51 +		: "=a" (__res), "=D" (__ign1)			\
    3.52 +		: "0" (__HYPERVISOR_##name), "1" ((long)(a1))	\
    3.53 +		: __syscall_clobber );				\
    3.54 +	(type)__res;						\
    3.55 +})
    3.56 +
    3.57 +#define _hypercall2(type, name, a1, a2)				\
    3.58 +({								\
    3.59 +	long __res, __ign1, __ign2;				\
    3.60 +	asm volatile (						\
    3.61 +		TRAP_INSTR					\
    3.62 +		: "=a" (__res), "=D" (__ign1), "=S" (__ign2)	\
    3.63 +		: "0" (__HYPERVISOR_##name), "1" ((long)(a1)),	\
    3.64 +		"2" ((long)(a2))				\
    3.65 +		: __syscall_clobber );				\
    3.66 +	(type)__res;						\
    3.67 +})
    3.68 +
    3.69 +#define _hypercall3(type, name, a1, a2, a3)			\
    3.70 +({								\
    3.71 +	long __res, __ign1, __ign2, __ign3;			\
    3.72 +	asm volatile (						\
    3.73 +		TRAP_INSTR					\
    3.74 +		: "=a" (__res), "=D" (__ign1), "=S" (__ign2), 	\
    3.75 +		"=d" (__ign3)					\
    3.76 +		: "0" (__HYPERVISOR_##name), "1" ((long)(a1)),	\
    3.77 +		"2" ((long)(a2)), "3" ((long)(a3))		\
    3.78 +		: __syscall_clobber );				\
    3.79 +	(type)__res;						\
    3.80 +})
    3.81 +
    3.82 +#define _hypercall4(type, name, a1, a2, a3, a4)			\
    3.83 +({								\
    3.84 +	long __res, __ign1, __ign2, __ign3;			\
    3.85 +	asm volatile (						\
    3.86 +		"movq %8,%%r10; " TRAP_INSTR			\
    3.87 +		: "=a" (__res), "=D" (__ign1), "=S" (__ign2),	\
    3.88 +		"=d" (__ign3)					\
    3.89 +		: "0" (__HYPERVISOR_##name), "1" ((long)(a1)),	\
    3.90 +		"2" ((long)(a2)), "3" ((long)(a3)),		\
    3.91 +		"g" ((long)(a4))				\
    3.92 +		: __syscall_clobber, "r10" );			\
    3.93 +	(type)__res;						\
    3.94 +})
    3.95 +
    3.96 +#define _hypercall5(type, name, a1, a2, a3, a4, a5)		\
    3.97 +({								\
    3.98 +	long __res, __ign1, __ign2, __ign3;			\
    3.99 +	asm volatile (						\
   3.100 +		"movq %8,%%r10; movq %9,%%r8; " TRAP_INSTR	\
   3.101 +		: "=a" (__res), "=D" (__ign1), "=S" (__ign2),	\
   3.102 +		"=d" (__ign3)					\
   3.103 +		: "0" (__HYPERVISOR_##name), "1" ((long)(a1)),	\
   3.104 +		"2" ((long)(a2)), "3" ((long)(a3)),		\
   3.105 +		"g" ((long)(a4)), "g" ((long)(a5))		\
   3.106 +		: __syscall_clobber, "r10", "r8" );		\
   3.107 +	(type)__res;						\
   3.108 +})
   3.109 +
   3.110  static inline int
   3.111  HYPERVISOR_set_trap_table(
   3.112 -    trap_info_t *table)
   3.113 +	trap_info_t *table)
   3.114  {
   3.115 -    int ret;
   3.116 -
   3.117 -    __asm__ __volatile__ (
   3.118 -        TRAP_INSTR
   3.119 -        : "=a" (ret)
   3.120 -	: "0" ((unsigned long)__HYPERVISOR_set_trap_table), "D" (table)
   3.121 -	: __syscall_clobber );
   3.122 -
   3.123 -    return ret;
   3.124 +	return _hypercall1(int, set_trap_table, table);
   3.125  }
   3.126  
   3.127  static inline int
   3.128  HYPERVISOR_mmu_update(
   3.129 -    mmu_update_t *req, int count, int *success_count, domid_t domid)
   3.130 +	mmu_update_t *req, int count, int *success_count, domid_t domid)
   3.131  {
   3.132 -    int ret;
   3.133 -
   3.134 -    __asm__ __volatile__ (
   3.135 -        "movq %5, %%r10;" TRAP_INSTR
   3.136 -        : "=a" (ret)
   3.137 -	: "0" ((unsigned long)__HYPERVISOR_mmu_update), "D" (req), "S" ((long)count),
   3.138 -	  "d" (success_count), "g" ((unsigned long)domid)
   3.139 -	: __syscall_clobber, "r10" );
   3.140 -
   3.141 -    return ret;
   3.142 +	return _hypercall4(int, mmu_update, req, count, success_count, domid);
   3.143  }
   3.144  
   3.145  static inline int
   3.146  HYPERVISOR_mmuext_op(
   3.147 -    struct mmuext_op *op, int count, int *success_count, domid_t domid)
   3.148 +	struct mmuext_op *op, int count, int *success_count, domid_t domid)
   3.149  {
   3.150 -    int ret;
   3.151 -
   3.152 -    __asm__ __volatile__ (
   3.153 -        "movq %5, %%r10;" TRAP_INSTR
   3.154 -        : "=a" (ret)
   3.155 -        : "0" (__HYPERVISOR_mmuext_op), "D" (op), "S" ((long)count), 
   3.156 -          "d" (success_count), "g" ((unsigned long)domid)
   3.157 -        : __syscall_clobber, "r10" );
   3.158 -
   3.159 -    return ret;
   3.160 +	return _hypercall4(int, mmuext_op, op, count, success_count, domid);
   3.161  }
   3.162  
   3.163  static inline int
   3.164  HYPERVISOR_set_gdt(
   3.165 -    unsigned long *frame_list, int entries)
   3.166 +	unsigned long *frame_list, int entries)
   3.167  {
   3.168 -    int ret;
   3.169 +	return _hypercall2(int, set_gdt, frame_list, entries);
   3.170 +}
   3.171  
   3.172 -    __asm__ __volatile__ (
   3.173 -        TRAP_INSTR
   3.174 -        : "=a" (ret)
   3.175 -	: "0" ((unsigned long)__HYPERVISOR_set_gdt), "D" (frame_list), "S" ((long)entries)
   3.176 -	: __syscall_clobber );
   3.177 -
   3.178 -
   3.179 -    return ret;
   3.180 -}
   3.181  static inline int
   3.182  HYPERVISOR_stack_switch(
   3.183 -    unsigned long ss, unsigned long esp)
   3.184 +	unsigned long ss, unsigned long esp)
   3.185  {
   3.186 -    int ret;
   3.187 -
   3.188 -    __asm__ __volatile__ (
   3.189 -        TRAP_INSTR
   3.190 -        : "=a" (ret)
   3.191 -	: "0" ((unsigned long)__HYPERVISOR_stack_switch), "D" (ss), "S" (esp)
   3.192 -	: __syscall_clobber );
   3.193 -
   3.194 -    return ret;
   3.195 +	return _hypercall2(int, stack_switch, ss, esp);
   3.196  }
   3.197  
   3.198  static inline int
   3.199  HYPERVISOR_set_callbacks(
   3.200 -    unsigned long event_address, unsigned long failsafe_address, 
   3.201 -    unsigned long syscall_address)
   3.202 +	unsigned long event_address, unsigned long failsafe_address, 
   3.203 +	unsigned long syscall_address)
   3.204  {
   3.205 -    int ret;
   3.206 -
   3.207 -    __asm__ __volatile__ (
   3.208 -        TRAP_INSTR
   3.209 -        : "=a" (ret)
   3.210 -	: "0" ((unsigned long)__HYPERVISOR_set_callbacks), "D" (event_address),
   3.211 -	  "S" (failsafe_address), "d" (syscall_address)
   3.212 -	: __syscall_clobber );
   3.213 -
   3.214 -    return ret;
   3.215 +	return _hypercall3(int, set_callbacks,
   3.216 +			   event_address, failsafe_address, syscall_address);
   3.217  }
   3.218  
   3.219  static inline int
   3.220  HYPERVISOR_fpu_taskswitch(
   3.221 -    int set)
   3.222 +	int set)
   3.223  {
   3.224 -    int ret;
   3.225 -    __asm__ __volatile__ (
   3.226 -        TRAP_INSTR
   3.227 -        : "=a" (ret) : "0" ((unsigned long)__HYPERVISOR_fpu_taskswitch),
   3.228 -          "D" ((unsigned long) set) : __syscall_clobber );
   3.229 -
   3.230 -    return ret;
   3.231 +	return _hypercall1(int, fpu_taskswitch, set);
   3.232  }
   3.233  
   3.234  static inline int
   3.235  HYPERVISOR_yield(
   3.236 -    void)
   3.237 +	void)
   3.238  {
   3.239 -    int ret;
   3.240 -
   3.241 -    __asm__ __volatile__ (
   3.242 -        TRAP_INSTR
   3.243 -        : "=a" (ret)
   3.244 -	: "0" ((unsigned long)__HYPERVISOR_sched_op), "D" ((unsigned long)SCHEDOP_yield)
   3.245 -	: __syscall_clobber );
   3.246 -
   3.247 -    return ret;
   3.248 +	return _hypercall2(int, sched_op, SCHEDOP_yield, 0);
   3.249  }
   3.250  
   3.251  static inline int
   3.252  HYPERVISOR_block(
   3.253 -    void)
   3.254 +	void)
   3.255  {
   3.256 -    int ret;
   3.257 -    __asm__ __volatile__ (
   3.258 -        TRAP_INSTR
   3.259 -        : "=a" (ret)
   3.260 -	: "0" ((unsigned long)__HYPERVISOR_sched_op), "D" ((unsigned long)SCHEDOP_block)
   3.261 -	: __syscall_clobber );
   3.262 -
   3.263 -    return ret;
   3.264 +	return _hypercall2(int, sched_op, SCHEDOP_block, 0);
   3.265  }
   3.266  
   3.267  static inline int
   3.268  HYPERVISOR_shutdown(
   3.269 -    void)
   3.270 +	void)
   3.271  {
   3.272 -    int ret;
   3.273 -    __asm__ __volatile__ (
   3.274 -        TRAP_INSTR
   3.275 -        : "=a" (ret)
   3.276 -	: "0" ((unsigned long)__HYPERVISOR_sched_op),
   3.277 -	  "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift)))
   3.278 -	: __syscall_clobber );
   3.279 -
   3.280 -    return ret;
   3.281 +	return _hypercall2(int, sched_op, SCHEDOP_shutdown |
   3.282 +			   (SHUTDOWN_poweroff << SCHEDOP_reasonshift), 0);
   3.283  }
   3.284  
   3.285  static inline int
   3.286  HYPERVISOR_reboot(
   3.287 -    void)
   3.288 +	void)
   3.289  {
   3.290 -    int ret;
   3.291 -
   3.292 -    __asm__ __volatile__ (
   3.293 -        TRAP_INSTR
   3.294 -        : "=a" (ret)
   3.295 -	: "0" ((unsigned long)__HYPERVISOR_sched_op),
   3.296 -	  "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift)))
   3.297 -	: __syscall_clobber );
   3.298 -
   3.299 -    return ret;
   3.300 +	return _hypercall2(int, sched_op, SCHEDOP_shutdown |
   3.301 +			   (SHUTDOWN_reboot << SCHEDOP_reasonshift), 0);
   3.302  }
   3.303  
   3.304 -static inline int
   3.305 -HYPERVISOR_suspend(
   3.306 -    unsigned long srec)
   3.307 -{
   3.308 -    int ret;
   3.309 -
   3.310 -    /* NB. On suspend, control software expects a suspend record in %esi. */
   3.311 -    __asm__ __volatile__ (
   3.312 -        TRAP_INSTR
   3.313 -        : "=a" (ret)
   3.314 -	: "0" ((unsigned long)__HYPERVISOR_sched_op),
   3.315 -        "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift))), 
   3.316 -        "S" (srec)
   3.317 -	: __syscall_clobber );
   3.318 -
   3.319 -    return ret;
   3.320 -}
   3.321 -
   3.322 -/*
   3.323 - * We can have the timeout value in a single argument for the hypercall, but
   3.324 - * that will break the common code. 
   3.325 - */
   3.326  static inline long
   3.327  HYPERVISOR_set_timer_op(
   3.328 -    u64 timeout)
   3.329 +	u64 timeout)
   3.330  {
   3.331 -    int ret;
   3.332 -
   3.333 -    __asm__ __volatile__ (
   3.334 -        TRAP_INSTR
   3.335 -        : "=a" (ret)
   3.336 -	: "0" ((unsigned long)__HYPERVISOR_set_timer_op),
   3.337 -	  "D" (timeout)
   3.338 -	: __syscall_clobber );
   3.339 -
   3.340 -    return ret;
   3.341 +	return _hypercall1(long, set_timer_op, timeout);
   3.342  }
   3.343  
   3.344  static inline int
   3.345  HYPERVISOR_dom0_op(
   3.346 -    dom0_op_t *dom0_op)
   3.347 +	dom0_op_t *dom0_op)
   3.348  {
   3.349 -    int ret;
   3.350 -
   3.351 -    dom0_op->interface_version = DOM0_INTERFACE_VERSION;
   3.352 -    __asm__ __volatile__ (
   3.353 -        TRAP_INSTR
   3.354 -        : "=a" (ret)
   3.355 -	: "0" ((unsigned long)__HYPERVISOR_dom0_op), "D" (dom0_op)
   3.356 -	: __syscall_clobber );
   3.357 -
   3.358 -    return ret;
   3.359 +	dom0_op->interface_version = DOM0_INTERFACE_VERSION;
   3.360 +	return _hypercall1(int, dom0_op, dom0_op);
   3.361  }
   3.362  
   3.363  static inline int
   3.364  HYPERVISOR_set_debugreg(
   3.365 -    int reg, unsigned long value)
   3.366 +	int reg, unsigned long value)
   3.367  {
   3.368 -    int ret;
   3.369 -
   3.370 -    __asm__ __volatile__ (
   3.371 -        TRAP_INSTR
   3.372 -        : "=a" (ret)
   3.373 -	: "0" ((unsigned long)__HYPERVISOR_set_debugreg), "D" ((unsigned long)reg), "S" (value)
   3.374 -	: __syscall_clobber );
   3.375 -
   3.376 -    return ret;
   3.377 +	return _hypercall2(int, set_debugreg, reg, value);
   3.378  }
   3.379  
   3.380  static inline unsigned long
   3.381  HYPERVISOR_get_debugreg(
   3.382 -    int reg)
   3.383 +	int reg)
   3.384  {
   3.385 -    unsigned long ret;
   3.386 -
   3.387 -    __asm__ __volatile__ (
   3.388 -        TRAP_INSTR
   3.389 -        : "=a" (ret)
   3.390 -	: "0" ((unsigned long)__HYPERVISOR_get_debugreg), "D" ((unsigned long)reg)
   3.391 -	: __syscall_clobber );
   3.392 -
   3.393 -    return ret;
   3.394 +	return _hypercall1(unsigned long, get_debugreg, reg);
   3.395  }
   3.396  
   3.397  static inline int
   3.398  HYPERVISOR_update_descriptor(
   3.399 -    unsigned long ma, unsigned long word)
   3.400 +	unsigned long ma, unsigned long word)
   3.401  {
   3.402 -    int ret;
   3.403 -
   3.404 -    __asm__ __volatile__ (
   3.405 -        TRAP_INSTR
   3.406 -        : "=a" (ret)
   3.407 -	: "0" ((unsigned long)__HYPERVISOR_update_descriptor), "D" (ma),
   3.408 -	  "S" (word)
   3.409 -	: __syscall_clobber );
   3.410 -
   3.411 -    return ret;
   3.412 +	return _hypercall2(int, update_descriptor, ma, word);
   3.413  }
   3.414  
   3.415  static inline int
   3.416  HYPERVISOR_dom_mem_op(
   3.417 -    unsigned int op, unsigned long *extent_list,
   3.418 -    unsigned long nr_extents, unsigned int extent_order)
   3.419 +	unsigned int op, unsigned long *extent_list,
   3.420 +	unsigned long nr_extents, unsigned int extent_order)
   3.421  {
   3.422 -    int ret;
   3.423 -
   3.424 -    __asm__ __volatile__ (
   3.425 -        "movq %5,%%r10; movq %6,%%r8;" TRAP_INSTR
   3.426 -        : "=a" (ret)
   3.427 -	: "0" ((unsigned long)__HYPERVISOR_dom_mem_op), "D" ((unsigned long)op), "S" (extent_list),
   3.428 -	  "d" (nr_extents), "g" ((unsigned long) extent_order), "g" ((unsigned long) DOMID_SELF)
   3.429 -	: __syscall_clobber,"r8","r10");
   3.430 -
   3.431 -    return ret;
   3.432 +	return _hypercall5(int, dom_mem_op, op, extent_list,
   3.433 +			   nr_extents, extent_order, DOMID_SELF);
   3.434  }
   3.435  
   3.436  static inline int
   3.437  HYPERVISOR_multicall(
   3.438 -    void *call_list, int nr_calls)
   3.439 +	void *call_list, int nr_calls)
   3.440  {
   3.441 -    int ret;
   3.442 -
   3.443 -    __asm__ __volatile__ (
   3.444 -        TRAP_INSTR
   3.445 -        : "=a" (ret)
   3.446 -	: "0" ((unsigned long)__HYPERVISOR_multicall), "D" (call_list), "S" ((unsigned long)nr_calls)
   3.447 -	: __syscall_clobber);
   3.448 -
   3.449 -    return ret;
   3.450 +	return _hypercall2(int, multicall, call_list, nr_calls);
   3.451  }
   3.452  
   3.453  static inline int
   3.454  HYPERVISOR_update_va_mapping(
   3.455 -    unsigned long page_nr, pte_t new_val, unsigned long flags)
   3.456 +	unsigned long va, pte_t new_val, unsigned long flags)
   3.457  {
   3.458 -    int ret;
   3.459 -
   3.460 -    __asm__ __volatile__ (
   3.461 -        TRAP_INSTR
   3.462 -        : "=a" (ret)
   3.463 -	: "0" ((unsigned long)__HYPERVISOR_update_va_mapping), 
   3.464 -          "D" (page_nr), "S" (new_val.pte), "d" (flags)
   3.465 -	: __syscall_clobber);
   3.466 -
   3.467 -    return ret;
   3.468 +	return _hypercall3(int, update_va_mapping, va, new_val.pte, flags);
   3.469  }
   3.470  
   3.471  static inline int
   3.472  HYPERVISOR_event_channel_op(
   3.473 -    void *op)
   3.474 +	void *op)
   3.475  {
   3.476 -    int ret;
   3.477 -    __asm__ __volatile__ (
   3.478 -        TRAP_INSTR
   3.479 -        : "=a" (ret)
   3.480 -	: "0" ((unsigned long)__HYPERVISOR_event_channel_op), "D" (op)
   3.481 -	: __syscall_clobber);
   3.482 -
   3.483 -    return ret;
   3.484 +	return _hypercall1(int, event_channel_op, op);
   3.485  }
   3.486  
   3.487  static inline int
   3.488  HYPERVISOR_xen_version(
   3.489 -    int cmd)
   3.490 +	int cmd)
   3.491  {
   3.492 -    int ret;
   3.493 -
   3.494 -    __asm__ __volatile__ (
   3.495 -        TRAP_INSTR
   3.496 -        : "=a" (ret)
   3.497 -	: "0" ((unsigned long)__HYPERVISOR_xen_version), "D" ((unsigned long)cmd)
   3.498 -	: __syscall_clobber);
   3.499 -
   3.500 -    return ret;
   3.501 +	return _hypercall1(int, xen_version, cmd);
   3.502  }
   3.503  
   3.504  static inline int
   3.505  HYPERVISOR_console_io(
   3.506 -    int cmd, int count, char *str)
   3.507 +	int cmd, int count, char *str)
   3.508  {
   3.509 -    int ret;
   3.510 -    __asm__ __volatile__ (
   3.511 -        TRAP_INSTR
   3.512 -        : "=a" (ret)
   3.513 -	: "0" ((unsigned long)__HYPERVISOR_console_io), "D" ((unsigned long)cmd), "S" ((unsigned long)count), "d" (str)
   3.514 -	: __syscall_clobber);
   3.515 -
   3.516 -    return ret;
   3.517 +	return _hypercall3(int, console_io, cmd, count, str);
   3.518  }
   3.519  
   3.520  static inline int
   3.521  HYPERVISOR_physdev_op(
   3.522 -    void *physdev_op)
   3.523 +	void *physdev_op)
   3.524  {
   3.525 -    int ret;
   3.526 -
   3.527 -    __asm__ __volatile__ (
   3.528 -        TRAP_INSTR
   3.529 -        : "=a" (ret)
   3.530 -	: "0" ((unsigned long)__HYPERVISOR_physdev_op), "D" (physdev_op)
   3.531 -	: __syscall_clobber);
   3.532 -
   3.533 -    return ret;
   3.534 +	return _hypercall1(int, physdev_op, physdev_op);
   3.535  }
   3.536  
   3.537  static inline int
   3.538  HYPERVISOR_grant_table_op(
   3.539 -    unsigned int cmd, void *uop, unsigned int count)
   3.540 +	unsigned int cmd, void *uop, unsigned int count)
   3.541  {
   3.542 -    int ret;
   3.543 -
   3.544 -    __asm__ __volatile__ (
   3.545 -        TRAP_INSTR
   3.546 -        : "=a" (ret)
   3.547 -	: "0" ((unsigned long)__HYPERVISOR_grant_table_op), "D" ((unsigned long)cmd), "S" ((unsigned long)uop), "d" (count)
   3.548 -	: __syscall_clobber);
   3.549 -
   3.550 -    return ret;
   3.551 +	return _hypercall3(int, grant_table_op, cmd, uop, count);
   3.552  }
   3.553  
   3.554  static inline int
   3.555  HYPERVISOR_update_va_mapping_otherdomain(
   3.556 -    unsigned long page_nr, pte_t new_val, unsigned long flags, domid_t domid)
   3.557 +	unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
   3.558  {
   3.559 -    int ret;
   3.560 -
   3.561 -    __asm__ __volatile__ (
   3.562 -        "movq %5, %%r10;" TRAP_INSTR
   3.563 -        : "=a" (ret)
   3.564 -	: "0" ((unsigned long)__HYPERVISOR_update_va_mapping_otherdomain),
   3.565 -          "D" (page_nr), "S" (new_val.pte), "d" (flags), "g" ((unsigned long)domid)
   3.566 -	: __syscall_clobber,"r10");
   3.567 -    
   3.568 -    return ret;
   3.569 +	return _hypercall4(int, update_va_mapping_otherdomain, va,
   3.570 +			   new_val.pte, flags, domid);
   3.571  }
   3.572  
   3.573  static inline int
   3.574  HYPERVISOR_vm_assist(
   3.575 -    unsigned int cmd, unsigned int type)
   3.576 +	unsigned int cmd, unsigned int type)
   3.577  {
   3.578 -    int ret;
   3.579 +	return _hypercall2(int, vm_assist, cmd, type);
   3.580 +}
   3.581 +
   3.582 +static inline int
   3.583 +HYPERVISOR_boot_vcpu(
   3.584 +	unsigned long vcpu, vcpu_guest_context_t *ctxt)
   3.585 +{
   3.586 +	return _hypercall2(int, boot_vcpu, vcpu, ctxt);
   3.587 +}
   3.588  
   3.589 -    __asm__ __volatile__ (
   3.590 -        TRAP_INSTR
   3.591 -        : "=a" (ret)
   3.592 -	: "0" ((unsigned long)__HYPERVISOR_vm_assist), "D" ((unsigned long)cmd), "S" ((unsigned long)type)
   3.593 -	: __syscall_clobber);
   3.594 +static inline int
   3.595 +HYPERVISOR_vcpu_up(
   3.596 +	int vcpu)
   3.597 +{
   3.598 +	return _hypercall2(int, sched_op, SCHEDOP_vcpu_up |
   3.599 +			   (vcpu << SCHEDOP_vcpushift), 0);
   3.600 +}
   3.601  
   3.602 -    return ret;
   3.603 +static inline int
   3.604 +HYPERVISOR_vcpu_pickle(
   3.605 +	int vcpu, vcpu_guest_context_t *ctxt)
   3.606 +{
   3.607 +	return _hypercall2(int, sched_op, SCHEDOP_vcpu_pickle |
   3.608 +			   (vcpu << SCHEDOP_vcpushift), ctxt);
   3.609  }
   3.610  
   3.611  static inline int
   3.612  HYPERVISOR_switch_to_user(void)
   3.613  {
   3.614 -    int ret;
   3.615 -    __asm__ __volatile__ (
   3.616 -        TRAP_INSTR
   3.617 -        : "=a" (ret) : "0" ((unsigned long)__HYPERVISOR_switch_to_user) : __syscall_clobber );
   3.618 -
   3.619 -    return ret;
   3.620 -}
   3.621 -
   3.622 -static inline int
   3.623 -HYPERVISOR_boot_vcpu(
   3.624 -    unsigned long vcpu, vcpu_guest_context_t *ctxt)
   3.625 -{
   3.626 -    int ret;
   3.627 -
   3.628 -    __asm__ __volatile__ (
   3.629 -        TRAP_INSTR
   3.630 -        : "=a" (ret)
   3.631 -	: "0" (__HYPERVISOR_boot_vcpu), "D" (vcpu), "S" (ctxt)
   3.632 -	: __syscall_clobber);
   3.633 -
   3.634 -    return ret;
   3.635 +	return _hypercall0(int, switch_to_user);
   3.636  }
   3.637  
   3.638  static inline int
   3.639  HYPERVISOR_set_segment_base(
   3.640 -    int reg, unsigned long value)
   3.641 +	int reg, unsigned long value)
   3.642  {
   3.643 -    int ret;
   3.644 -
   3.645 -    __asm__ __volatile__ (
   3.646 -        TRAP_INSTR
   3.647 -        : "=a" (ret)
   3.648 -	: "0" ((unsigned long)__HYPERVISOR_set_segment_base), "D" ((unsigned long)reg), "S" (value)
   3.649 -	: __syscall_clobber );
   3.650 -
   3.651 -    return ret;
   3.652 +	return _hypercall2(int, set_segment_base, reg, value);
   3.653  }
   3.654  
   3.655  static inline int
   3.656 -HYPERVISOR_vcpu_pickle(
   3.657 -    int vcpu, vcpu_guest_context_t *ctxt)
   3.658 +HYPERVISOR_suspend(
   3.659 +	unsigned long srec)
   3.660  {
   3.661 -    int ret;
   3.662 -
   3.663 -    __asm__ __volatile__ (
   3.664 -        TRAP_INSTR
   3.665 -        : "=a" (ret)
   3.666 -	: "0" ((unsigned long)__HYPERVISOR_sched_op),
   3.667 -	"D" ((unsigned long)SCHEDOP_vcpu_pickle | (vcpu << SCHEDOP_vcpushift)),
   3.668 -	"S" ((unsigned long)ctxt)
   3.669 -	: __syscall_clobber );
   3.670 -
   3.671 -    return ret;
   3.672 +	return _hypercall2(int, sched_op, SCHEDOP_shutdown |
   3.673 +			   (SHUTDOWN_suspend << SCHEDOP_reasonshift), srec);
   3.674  }
   3.675  
   3.676  #endif /* __HYPERCALL_H__ */
   3.677 +
   3.678 +/*
   3.679 + * Local variables:
   3.680 + *  c-file-style: "linux"
   3.681 + *  indent-tabs-mode: t
   3.682 + *  c-indent-level: 8
   3.683 + *  c-basic-offset: 8
   3.684 + *  tab-width: 8
   3.685 + * End:
   3.686 + */
     4.1 --- a/xen/arch/x86/x86_32/asm-offsets.c	Fri Aug 26 13:06:49 2005 +0000
     4.2 +++ b/xen/arch/x86/x86_32/asm-offsets.c	Fri Aug 26 17:42:34 2005 +0000
     4.3 @@ -71,6 +71,9 @@ void __dummy__(void)
     4.4      OFFSET(VCPUINFO_upcall_mask, vcpu_info_t, evtchn_upcall_mask);
     4.5      BLANK();
     4.6  
     4.7 +    DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info));
     4.8 +    BLANK();
     4.9 +
    4.10      OFFSET(TRAPBOUNCE_error_code, struct trap_bounce, error_code);
    4.11      OFFSET(TRAPBOUNCE_cr2, struct trap_bounce, cr2);
    4.12      OFFSET(TRAPBOUNCE_flags, struct trap_bounce, flags);
     5.1 --- a/xen/arch/x86/x86_32/entry.S	Fri Aug 26 13:06:49 2005 +0000
     5.2 +++ b/xen/arch/x86/x86_32/entry.S	Fri Aug 26 17:42:34 2005 +0000
     5.3 @@ -61,6 +61,11 @@
     5.4  #include <asm/page.h>
     5.5  #include <public/xen.h>
     5.6  
     5.7 +#define GET_GUEST_REGS(reg)                     \
     5.8 +        movl $~(STACK_SIZE-1),reg;              \
     5.9 +        andl %esp,reg;                          \
    5.10 +        orl  $(STACK_SIZE-CPUINFO_sizeof),reg;
    5.11 +
    5.12  #define GET_CURRENT(reg)         \
    5.13          movl $STACK_SIZE-4, reg; \
    5.14          orl  %esp, reg;          \
    5.15 @@ -273,7 +278,41 @@ ENTRY(hypercall)
    5.16          GET_CURRENT(%ebx)
    5.17          andl $(NR_hypercalls-1),%eax
    5.18          PERFC_INCR(PERFC_hypercalls, %eax)
    5.19 +#ifndef NDEBUG
    5.20 +        /* Deliberately corrupt parameter regs not used by this hypercall. */
    5.21 +        pushl %eax
    5.22 +        pushl UREGS_eip+4(%esp)
    5.23 +        pushl 28(%esp) # EBP
    5.24 +        pushl 28(%esp) # EDI
    5.25 +        pushl 28(%esp) # ESI
    5.26 +        pushl 28(%esp) # EDX
    5.27 +        pushl 28(%esp) # ECX
    5.28 +        pushl 28(%esp) # EBX
    5.29 +        movzb hypercall_args_table(,%eax,1),%ecx
    5.30 +        leal  (%esp,%ecx,4),%edi
    5.31 +        subl  $6,%ecx
    5.32 +        negl  %ecx
    5.33 +        movl  %eax,%esi
    5.34 +        movl  $0xDEADBEEF,%eax
    5.35 +        rep   stosl
    5.36 +        movl  %esi,%eax
    5.37 +#endif
    5.38          call *hypercall_table(,%eax,4)
    5.39 +#ifndef NDEBUG
    5.40 +        /* Deliberately corrupt parameter regs used by this hypercall. */
    5.41 +        addl  $24,%esp     # Shadow parameters
    5.42 +        popl  %ecx         # Shadow EIP
    5.43 +        cmpl  %ecx,UREGS_eip(%esp)
    5.44 +        popl  %ecx         # Shadow hypercall index
    5.45 +        jne   skip_clobber # If EIP has changed then don't clobber
    5.46 +        movzb hypercall_args_table(,%ecx,1),%ecx
    5.47 +        movl  %esp,%edi
    5.48 +        movl  %eax,%esi
    5.49 +        movl  $0xDEADBEEF,%eax
    5.50 +        rep   stosl
    5.51 +        movl  %esi,%eax
    5.52 +skip_clobber:
    5.53 +#endif
    5.54          movl %eax,UREGS_eax(%esp)       # save the return value
    5.55  
    5.56  test_all_events:
    5.57 @@ -674,12 +713,14 @@ ENTRY(setup_vm86_frame)
    5.58  do_arch_sched_op:
    5.59          # Ensure we return success even if we return via schedule_tail()
    5.60          xorl %eax,%eax
    5.61 -        movl %eax,UREGS_eax+4(%esp)
    5.62 +        GET_GUEST_REGS(%ecx)
    5.63 +        movl %eax,UREGS_eax(%ecx)
    5.64          jmp  do_sched_op
    5.65  
    5.66  do_switch_vm86:
    5.67 -        # Discard the return address
    5.68 -        addl $4,%esp
    5.69 +        # Reset the stack pointer
    5.70 +        GET_GUEST_REGS(%ecx)
    5.71 +        movl %ecx,%esp
    5.72  
    5.73          # GS:ESI == Ring-1 stack activation
    5.74          movl UREGS_esp(%esp),%esi
    5.75 @@ -768,3 +809,36 @@ ENTRY(hypercall_table)
    5.76          .rept NR_hypercalls-((.-hypercall_table)/4)
    5.77          .long do_ni_hypercall
    5.78          .endr
    5.79 +
    5.80 +ENTRY(hypercall_args_table)
    5.81 +        .byte 1 /* do_set_trap_table    */  /*  0 */
    5.82 +        .byte 4 /* do_mmu_update        */
    5.83 +        .byte 2 /* do_set_gdt           */
    5.84 +        .byte 2 /* do_stack_switch      */
    5.85 +        .byte 4 /* do_set_callbacks     */
    5.86 +        .byte 1 /* do_fpu_taskswitch    */  /*  5 */
    5.87 +        .byte 2 /* do_arch_sched_op     */
    5.88 +        .byte 1 /* do_dom0_op           */
    5.89 +        .byte 2 /* do_set_debugreg      */
    5.90 +        .byte 1 /* do_get_debugreg      */
    5.91 +        .byte 4 /* do_update_descriptor */  /* 10 */
    5.92 +        .byte 0 /* do_ni_hypercall      */
    5.93 +        .byte 5 /* do_dom_mem_op        */
    5.94 +        .byte 2 /* do_multicall         */
    5.95 +        .byte 4 /* do_update_va_mapping */
    5.96 +        .byte 2 /* do_set_timer_op      */  /* 15 */
    5.97 +        .byte 1 /* do_event_channel_op  */
    5.98 +        .byte 1 /* do_xen_version       */
    5.99 +        .byte 3 /* do_console_io        */
   5.100 +        .byte 1 /* do_physdev_op        */
   5.101 +        .byte 3 /* do_grant_table_op    */  /* 20 */
   5.102 +        .byte 2 /* do_vm_assist         */
   5.103 +        .byte 5 /* do_update_va_mapping_otherdomain */
   5.104 +        .byte 0 /* do_switch_vm86       */
   5.105 +        .byte 2 /* do_boot_vcpu         */
   5.106 +        .byte 0 /* do_ni_hypercall      */  /* 25 */
   5.107 +        .byte 4 /* do_mmuext_op         */
   5.108 +        .byte 1 /* do_acm_op            */
   5.109 +        .rept NR_hypercalls-(.-hypercall_args_table)
   5.110 +        .byte 0 /* do_ni_hypercall      */
   5.111 +        .endr
     6.1 --- a/xen/arch/x86/x86_64/asm-offsets.c	Fri Aug 26 13:06:49 2005 +0000
     6.2 +++ b/xen/arch/x86/x86_64/asm-offsets.c	Fri Aug 26 17:42:34 2005 +0000
     6.3 @@ -71,6 +71,9 @@ void __dummy__(void)
     6.4      OFFSET(VCPUINFO_upcall_mask, vcpu_info_t, evtchn_upcall_mask);
     6.5      BLANK();
     6.6  
     6.7 +    DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info));
     6.8 +    BLANK();
     6.9 +
    6.10      OFFSET(TRAPBOUNCE_error_code, struct trap_bounce, error_code);
    6.11      OFFSET(TRAPBOUNCE_cr2, struct trap_bounce, cr2);
    6.12      OFFSET(TRAPBOUNCE_flags, struct trap_bounce, flags);
     7.1 --- a/xen/arch/x86/x86_64/entry.S	Fri Aug 26 13:06:49 2005 +0000
     7.2 +++ b/xen/arch/x86/x86_64/entry.S	Fri Aug 26 17:42:34 2005 +0000
     7.3 @@ -12,6 +12,11 @@
     7.4  #include <asm/page.h>
     7.5  #include <public/xen.h>
     7.6  
     7.7 +#define GET_GUEST_REGS(reg)                     \
     7.8 +        movq $~(STACK_SIZE-1),reg;              \
     7.9 +        andq %rsp,reg;                          \
    7.10 +        orq  $(STACK_SIZE-CPUINFO_sizeof),reg;
    7.11 +
    7.12  #define GET_CURRENT(reg)         \
    7.13          movq $STACK_SIZE-8, reg; \
    7.14          orq  %rsp, reg;          \
    7.15 @@ -120,10 +125,42 @@ ENTRY(syscall_enter)
    7.16  /*hypercall:*/
    7.17          movq  %r10,%rcx
    7.18          andq  $(NR_hypercalls-1),%rax
    7.19 +#ifndef NDEBUG
    7.20 +        /* Deliberately corrupt parameter regs not used by this hypercall. */
    7.21 +        pushq %rdi; pushq %rsi; pushq %rdx; pushq %rcx; pushq %r8 ; pushq %r9 
    7.22 +        leaq  hypercall_args_table(%rip),%r10
    7.23 +        movq  $6,%rcx
    7.24 +        sub   (%r10,%rax,1),%cl
    7.25 +        movq  %rsp,%rdi
    7.26 +        movl  $0xDEADBEEF,%eax
    7.27 +        rep   stosq
    7.28 +        popq  %r9 ; popq  %r8 ; popq  %rcx; popq  %rdx; popq  %rsi; popq  %rdi
    7.29 +        movq  UREGS_rax(%rsp),%rax
    7.30 +        andq  $(NR_hypercalls-1),%rax
    7.31 +        pushq %rax
    7.32 +        pushq UREGS_rip+8(%rsp)
    7.33 +#endif
    7.34          leaq  hypercall_table(%rip),%r10
    7.35          PERFC_INCR(PERFC_hypercalls, %rax)
    7.36          callq *(%r10,%rax,8)
    7.37 -        movq %rax,UREGS_rax(%rsp)       # save the return value
    7.38 +#ifndef NDEBUG
    7.39 +        /* Deliberately corrupt parameter regs used by this hypercall. */
    7.40 +        popq  %r10         # Shadow RIP
    7.41 +        cmpq  %r10,UREGS_rip(%rsp)
    7.42 +        popq  %rcx         # Shadow hypercall index
    7.43 +        jne   skip_clobber /* If RIP has changed then don't clobber. */
    7.44 +        leaq  hypercall_args_table(%rip),%r10
    7.45 +        movb  (%r10,%rcx,1),%cl
    7.46 +        movl  $0xDEADBEEF,%r10d
    7.47 +        cmpb  $1,%cl; jb skip_clobber; movq %r10,UREGS_rdi(%rsp)
    7.48 +        cmpb  $2,%cl; jb skip_clobber; movq %r10,UREGS_rsi(%rsp)
    7.49 +        cmpb  $3,%cl; jb skip_clobber; movq %r10,UREGS_rdx(%rsp)
    7.50 +        cmpb  $4,%cl; jb skip_clobber; movq %r10,UREGS_r10(%rsp)
    7.51 +        cmpb  $5,%cl; jb skip_clobber; movq %r10,UREGS_r8(%rsp)
    7.52 +        cmpb  $6,%cl; jb skip_clobber; movq %r10,UREGS_r9(%rsp)
    7.53 +skip_clobber:
    7.54 +#endif
    7.55 +        movq  %rax,UREGS_rax(%rsp)       # save the return value
    7.56  
    7.57  /* %rbx: struct vcpu */
    7.58  test_all_events:
    7.59 @@ -538,7 +575,8 @@ ENTRY(nmi)
    7.60  do_arch_sched_op:
    7.61          # Ensure we return success even if we return via schedule_tail()
    7.62          xorl  %eax,%eax
    7.63 -        movq  %rax,UREGS_rax+8(%rsp)
    7.64 +        GET_GUEST_REGS(%r10)
    7.65 +        movq  %rax,UREGS_rax(%r10)
    7.66          jmp   do_sched_op
    7.67  
    7.68  .data
    7.69 @@ -597,3 +635,36 @@ ENTRY(hypercall_table)
    7.70          .rept NR_hypercalls-((.-hypercall_table)/4)
    7.71          .quad do_ni_hypercall
    7.72          .endr
    7.73 +
    7.74 +ENTRY(hypercall_args_table)
    7.75 +        .byte 1 /* do_set_trap_table    */  /*  0 */
    7.76 +        .byte 4 /* do_mmu_update        */
    7.77 +        .byte 2 /* do_set_gdt           */
    7.78 +        .byte 2 /* do_stack_switch      */
    7.79 +        .byte 3 /* do_set_callbacks     */
    7.80 +        .byte 1 /* do_fpu_taskswitch    */  /*  5 */
    7.81 +        .byte 2 /* do_arch_sched_op     */
    7.82 +        .byte 1 /* do_dom0_op           */
    7.83 +        .byte 2 /* do_set_debugreg      */
    7.84 +        .byte 1 /* do_get_debugreg      */
    7.85 +        .byte 2 /* do_update_descriptor */  /* 10 */
    7.86 +        .byte 0 /* do_ni_hypercall      */
    7.87 +        .byte 5 /* do_dom_mem_op        */
    7.88 +        .byte 2 /* do_multicall         */
    7.89 +        .byte 3 /* do_update_va_mapping */
    7.90 +        .byte 1 /* do_set_timer_op      */  /* 15 */
    7.91 +        .byte 1 /* do_event_channel_op  */
    7.92 +        .byte 1 /* do_xen_version       */
    7.93 +        .byte 3 /* do_console_io        */
    7.94 +        .byte 1 /* do_physdev_op        */
    7.95 +        .byte 3 /* do_grant_table_op    */  /* 20 */
    7.96 +        .byte 2 /* do_vm_assist         */
    7.97 +        .byte 4 /* do_update_va_mapping_otherdomain */
    7.98 +        .byte 0 /* do_switch_to_user    */
    7.99 +        .byte 2 /* do_boot_vcpu         */
   7.100 +        .byte 2 /* do_set_segment_base  */  /* 25 */
   7.101 +        .byte 4 /* do_mmuext_op         */
   7.102 +        .byte 1 /* do_acm_op            */
   7.103 +        .rept NR_hypercalls-(.-hypercall_args_table)
   7.104 +        .byte 0 /* do_ni_hypercall      */
   7.105 +        .endr
     8.1 --- a/xen/common/multicall.c	Fri Aug 26 13:06:49 2005 +0000
     8.2 +++ b/xen/common/multicall.c	Fri Aug 26 17:42:34 2005 +0000
     8.3 @@ -45,6 +45,18 @@ long do_multicall(multicall_entry_t *cal
     8.4  
     8.5          do_multicall_call(&mcs->call);
     8.6  
     8.7 +#ifndef NDEBUG
     8.8 +        {
     8.9 +            /*
    8.10 +             * Deliberately corrupt the contents of the multicall structure.
    8.11 +             * The caller must depend only on the 'result' field on return.
    8.12 +             */
    8.13 +            multicall_entry_t corrupt;
    8.14 +            memset(&corrupt, 0xAA, sizeof(corrupt));
    8.15 +            (void)__copy_to_user(&call_list[i], &corrupt, sizeof(corrupt));
    8.16 +        }
    8.17 +#endif
    8.18 +
    8.19          if ( unlikely(__put_user(mcs->call.result, &call_list[i].result)) )
    8.20          {
    8.21              DPRINTK("Error writing result back to multicall block.\n");