xen-vtx-unstable

annotate extras/mini-os/include/hypervisor.h @ 6774:4d899a738d59

merge?
author cl349@firebug.cl.cam.ac.uk
date Tue Sep 13 15:05:49 2005 +0000 (2005-09-13)
parents f752e0c873a6 cdfa7dd00c44
children e7c7196fa329 8ca0f98ba8e2
rev   line source
kaf24@5675 1 /******************************************************************************
kaf24@5675 2 * hypervisor.h
kaf24@5675 3 *
kaf24@5675 4 * Hypervisor handling.
kaf24@5675 5 *
kaf24@5675 6 * TODO - x86_64 broken!
kaf24@5675 7 *
kaf24@5675 8 * Copyright (c) 2002, K A Fraser
kaf24@5675 9 * Copyright (c) 2005, Grzegorz Milos
kaf24@5675 10 */
kaf24@5675 11
kaf24@5675 12 #ifndef _HYPERVISOR_H_
kaf24@5675 13 #define _HYPERVISOR_H_
kaf24@5675 14
kaf24@5675 15 #include <types.h>
kaf24@5675 16 #include <xen/xen.h>
kaf24@5675 17 #include <xen/io/domain_controller.h>
kaf24@5675 18
kaf24@5675 19
kaf24@5675 20
kaf24@5675 21 /*
kaf24@5675 22 * a placeholder for the start of day information passed up from the hypervisor
kaf24@5675 23 */
kaf24@5675 24 union start_info_union
kaf24@5675 25 {
kaf24@5675 26 start_info_t start_info;
kaf24@5675 27 char padding[512];
kaf24@5675 28 };
kaf24@5675 29 extern union start_info_union start_info_union;
kaf24@5675 30 #define start_info (start_info_union.start_info)
kaf24@5675 31
kaf24@5675 32
kaf24@5675 33 /* hypervisor.c */
kaf24@5675 34 //void do_hypervisor_callback(struct pt_regs *regs);
kaf24@5675 35 void mask_evtchn(u32 port);
kaf24@5675 36 void unmask_evtchn(u32 port);
kaf24@5675 37 void clear_evtchn(u32 port);
kaf24@5675 38
kaf24@5675 39 /*
kaf24@5675 40 * Assembler stubs for hyper-calls.
kaf24@5675 41 */
kaf24@6696 42 #if defined(__i386__)
kaf24@6696 43 static inline int
kaf24@6696 44 HYPERVISOR_set_trap_table(
kaf24@6696 45 trap_info_t *table)
kaf24@5675 46 {
kaf24@5675 47 int ret;
kaf24@5675 48 unsigned long ignore;
kaf24@6696 49
kaf24@5675 50 __asm__ __volatile__ (
kaf24@5675 51 TRAP_INSTR
kaf24@5675 52 : "=a" (ret), "=b" (ignore)
kaf24@6696 53 : "0" (__HYPERVISOR_set_trap_table), "1" (table)
kaf24@5675 54 : "memory" );
kaf24@5675 55
kaf24@5675 56 return ret;
kaf24@5675 57 }
kaf24@5675 58
kaf24@6696 59 static inline int
kaf24@6696 60 HYPERVISOR_mmu_update(
kaf24@6696 61 mmu_update_t *req, int count, int *success_count, domid_t domid)
kaf24@5675 62 {
kaf24@5675 63 int ret;
kaf24@6696 64 unsigned long ign1, ign2, ign3, ign4;
kaf24@6696 65
kaf24@5675 66 __asm__ __volatile__ (
kaf24@5675 67 TRAP_INSTR
kaf24@6696 68 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
kaf24@6696 69 : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
kaf24@6696 70 "3" (success_count), "4" (domid)
kaf24@6696 71 : "memory" );
kaf24@5675 72
kaf24@5675 73 return ret;
kaf24@5675 74 }
kaf24@5675 75
kaf24@6696 76 static inline int
kaf24@6696 77 HYPERVISOR_mmuext_op(
kaf24@6696 78 struct mmuext_op *op, int count, int *success_count, domid_t domid)
kaf24@5675 79 {
kaf24@5675 80 int ret;
kaf24@6401 81 unsigned long ign1, ign2, ign3, ign4;
kaf24@6401 82
kaf24@5675 83 __asm__ __volatile__ (
kaf24@5675 84 TRAP_INSTR
kaf24@6401 85 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
kaf24@6696 86 : "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count),
kaf24@6696 87 "3" (success_count), "4" (domid)
kaf24@6696 88 : "memory" );
kaf24@5675 89
kaf24@5675 90 return ret;
kaf24@5675 91 }
kaf24@5675 92
kaf24@6696 93 static inline int
kaf24@6696 94 HYPERVISOR_set_gdt(
kaf24@6696 95 unsigned long *frame_list, int entries)
kaf24@6696 96 {
kaf24@6696 97 int ret;
kaf24@6696 98 unsigned long ign1, ign2;
kaf24@6401 99
kaf24@6696 100 __asm__ __volatile__ (
kaf24@6696 101 TRAP_INSTR
kaf24@6696 102 : "=a" (ret), "=b" (ign1), "=c" (ign2)
kaf24@6696 103 : "0" (__HYPERVISOR_set_gdt), "1" (frame_list), "2" (entries)
kaf24@6696 104 : "memory" );
kaf24@6696 105
kaf24@6696 106
kaf24@6696 107 return ret;
kaf24@6696 108 }
kaf24@6696 109
kaf24@6696 110 static inline int
kaf24@6696 111 HYPERVISOR_stack_switch(
kaf24@6696 112 unsigned long ss, unsigned long esp)
kaf24@6696 113 {
kaf24@6696 114 int ret;
kaf24@6696 115 unsigned long ign1, ign2;
kaf24@6696 116
kaf24@6696 117 __asm__ __volatile__ (
kaf24@6696 118 TRAP_INSTR
kaf24@6696 119 : "=a" (ret), "=b" (ign1), "=c" (ign2)
kaf24@6696 120 : "0" (__HYPERVISOR_stack_switch), "1" (ss), "2" (esp)
kaf24@6696 121 : "memory" );
kaf24@6696 122
kaf24@6696 123 return ret;
kaf24@6696 124 }
kaf24@6696 125
kaf24@6696 126 static inline int
kaf24@6696 127 HYPERVISOR_set_callbacks(
kaf24@6696 128 unsigned long event_selector, unsigned long event_address,
kaf24@6696 129 unsigned long failsafe_selector, unsigned long failsafe_address)
kaf24@6401 130 {
kaf24@6401 131 int ret;
kaf24@6401 132 unsigned long ign1, ign2, ign3, ign4;
kaf24@6401 133
kaf24@6401 134 __asm__ __volatile__ (
kaf24@6401 135 TRAP_INSTR
kaf24@6401 136 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
kaf24@6696 137 : "0" (__HYPERVISOR_set_callbacks), "1" (event_selector),
kaf24@6696 138 "2" (event_address), "3" (failsafe_selector), "4" (failsafe_address)
kaf24@6696 139 : "memory" );
kaf24@5675 140
kaf24@5675 141 return ret;
kaf24@5675 142 }
kaf24@5675 143
kaf24@6696 144 static inline int
kaf24@5675 145 HYPERVISOR_fpu_taskswitch(
kaf24@5675 146 int set)
kaf24@5675 147 {
kaf24@5675 148 int ret;
kaf24@5675 149 unsigned long ign;
kaf24@5675 150
kaf24@5675 151 __asm__ __volatile__ (
kaf24@5675 152 TRAP_INSTR
kaf24@5675 153 : "=a" (ret), "=b" (ign)
kaf24@5675 154 : "0" (__HYPERVISOR_fpu_taskswitch), "1" (set)
kaf24@5675 155 : "memory" );
kaf24@5675 156
kaf24@5675 157 return ret;
kaf24@5675 158 }
kaf24@5675 159
kaf24@6696 160 static inline int
kaf24@6696 161 HYPERVISOR_yield(
kaf24@6696 162 void)
kaf24@5675 163 {
kaf24@5675 164 int ret;
kaf24@6696 165 unsigned long ign;
kaf24@6696 166
kaf24@5675 167 __asm__ __volatile__ (
kaf24@5675 168 TRAP_INSTR
kaf24@6696 169 : "=a" (ret), "=b" (ign)
kaf24@6696 170 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield)
kaf24@6696 171 : "memory", "ecx" );
kaf24@5675 172
kaf24@5675 173 return ret;
kaf24@5675 174 }
kaf24@5675 175
kaf24@6696 176 static inline int
kaf24@6696 177 HYPERVISOR_block(
kaf24@6696 178 void)
kaf24@5675 179 {
kaf24@5675 180 int ret;
kaf24@6696 181 unsigned long ign1;
kaf24@5675 182 __asm__ __volatile__ (
kaf24@5675 183 TRAP_INSTR
kaf24@6696 184 : "=a" (ret), "=b" (ign1)
kaf24@6696 185 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block)
kaf24@6696 186 : "memory", "ecx" );
kaf24@6696 187
kaf24@6696 188 return ret;
kaf24@6696 189 }
kaf24@6696 190
kaf24@6696 191 static inline int
kaf24@6696 192 HYPERVISOR_shutdown(
kaf24@6696 193 void)
kaf24@6696 194 {
kaf24@6696 195 int ret;
kaf24@6696 196 unsigned long ign1;
kaf24@6696 197 __asm__ __volatile__ (
kaf24@6696 198 TRAP_INSTR
kaf24@6696 199 : "=a" (ret), "=b" (ign1)
kaf24@6696 200 : "0" (__HYPERVISOR_sched_op),
kaf24@6696 201 "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
kaf24@6696 202 : "memory", "ecx" );
kaf24@5675 203
kaf24@5675 204 return ret;
kaf24@5675 205 }
kaf24@5675 206
kaf24@6696 207 static inline int
kaf24@6696 208 HYPERVISOR_reboot(
kaf24@6696 209 void)
kaf24@5675 210 {
kaf24@5675 211 int ret;
kaf24@6696 212 unsigned long ign1;
kaf24@5675 213 __asm__ __volatile__ (
kaf24@5675 214 TRAP_INSTR
kaf24@6696 215 : "=a" (ret), "=b" (ign1)
kaf24@6696 216 : "0" (__HYPERVISOR_sched_op),
kaf24@6696 217 "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
kaf24@6696 218 : "memory", "ecx" );
kaf24@5675 219
kaf24@5675 220 return ret;
kaf24@5675 221 }
kaf24@5675 222
kaf24@6696 223 static inline int
kaf24@6696 224 HYPERVISOR_suspend(
kaf24@6696 225 unsigned long srec)
kaf24@5675 226 {
kaf24@5675 227 int ret;
kaf24@6696 228 unsigned long ign1, ign2;
kaf24@6696 229
kaf24@6696 230 /* NB. On suspend, control software expects a suspend record in %esi. */
kaf24@5675 231 __asm__ __volatile__ (
kaf24@5675 232 TRAP_INSTR
kaf24@6696 233 : "=a" (ret), "=b" (ign1), "=S" (ign2)
kaf24@6696 234 : "0" (__HYPERVISOR_sched_op),
kaf24@6696 235 "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)),
kaf24@6696 236 "S" (srec) : "memory", "ecx");
kaf24@5675 237
kaf24@5675 238 return ret;
kaf24@5675 239 }
kaf24@5675 240
kaf24@6696 241 static inline int
kaf24@6696 242 HYPERVISOR_crash(
kaf24@6696 243 void)
kaf24@5675 244 {
kaf24@5675 245 int ret;
kaf24@6696 246 unsigned long ign1;
kaf24@5675 247 __asm__ __volatile__ (
kaf24@5675 248 TRAP_INSTR
kaf24@6696 249 : "=a" (ret), "=b" (ign1)
kaf24@6696 250 : "0" (__HYPERVISOR_sched_op),
kaf24@6696 251 "1" (SCHEDOP_shutdown | (SHUTDOWN_crash << SCHEDOP_reasonshift))
kaf24@6696 252 : "memory", "ecx" );
kaf24@5675 253
kaf24@5675 254 return ret;
kaf24@5675 255 }
kaf24@5675 256
kaf24@6696 257 static inline long
kaf24@6696 258 HYPERVISOR_set_timer_op(
kaf24@6696 259 u64 timeout)
kaf24@5675 260 {
kaf24@5675 261 int ret;
kaf24@5675 262 unsigned long timeout_hi = (unsigned long)(timeout>>32);
kaf24@5675 263 unsigned long timeout_lo = (unsigned long)timeout;
kaf24@5675 264 unsigned long ign1, ign2;
kaf24@5675 265
kaf24@5675 266 __asm__ __volatile__ (
kaf24@5675 267 TRAP_INSTR
kaf24@5675 268 : "=a" (ret), "=b" (ign1), "=c" (ign2)
kaf24@5675 269 : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_lo), "c" (timeout_hi)
kaf24@5675 270 : "memory");
kaf24@5675 271
kaf24@5675 272 return ret;
kaf24@5675 273 }
kaf24@6696 274
kaf24@6696 275 #if 0
kaf24@6696 276 static inline int
kaf24@6696 277 HYPERVISOR_dom0_op(
kaf24@6696 278 dom0_op_t *dom0_op)
kaf24@6696 279 {
kaf24@6696 280 int ret;
kaf24@6696 281 unsigned long ign1;
kaf24@6696 282
kaf24@6696 283 dom0_op->interface_version = DOM0_INTERFACE_VERSION;
kaf24@6696 284 __asm__ __volatile__ (
kaf24@6696 285 TRAP_INSTR
kaf24@6696 286 : "=a" (ret), "=b" (ign1)
kaf24@6696 287 : "0" (__HYPERVISOR_dom0_op), "1" (dom0_op)
kaf24@6696 288 : "memory");
kaf24@6696 289
kaf24@6696 290 return ret;
kaf24@6696 291 }
kaf24@6696 292 #endif
kaf24@6696 293
kaf24@6696 294 static inline int
kaf24@6696 295 HYPERVISOR_set_debugreg(
kaf24@6696 296 int reg, unsigned long value)
kaf24@6696 297 {
kaf24@6696 298 int ret;
kaf24@6696 299 unsigned long ign1, ign2;
kaf24@6696 300 __asm__ __volatile__ (
kaf24@6696 301 TRAP_INSTR
kaf24@6696 302 : "=a" (ret), "=b" (ign1), "=c" (ign2)
kaf24@6696 303 : "0" (__HYPERVISOR_set_debugreg), "1" (reg), "2" (value)
kaf24@6696 304 : "memory" );
kaf24@6696 305
kaf24@6696 306 return ret;
kaf24@6696 307 }
kaf24@6696 308
kaf24@6696 309 static inline unsigned long
kaf24@6696 310 HYPERVISOR_get_debugreg(
kaf24@6696 311 int reg)
kaf24@6696 312 {
kaf24@6696 313 unsigned long ret;
kaf24@6696 314 unsigned long ign;
kaf24@6696 315 __asm__ __volatile__ (
kaf24@6696 316 TRAP_INSTR
kaf24@6696 317 : "=a" (ret), "=b" (ign)
kaf24@6696 318 : "0" (__HYPERVISOR_get_debugreg), "1" (reg)
kaf24@6696 319 : "memory" );
kaf24@6696 320
kaf24@6696 321 return ret;
kaf24@6696 322 }
kaf24@6696 323
kaf24@6696 324 static inline int
kaf24@6696 325 HYPERVISOR_update_descriptor(
kaf24@6696 326 u64 ma, u64 desc)
kaf24@6696 327 {
kaf24@6696 328 int ret;
kaf24@6696 329 unsigned long ign1, ign2, ign3, ign4;
kaf24@6696 330
kaf24@6696 331 __asm__ __volatile__ (
kaf24@6696 332 TRAP_INSTR
kaf24@6696 333 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
kaf24@6696 334 : "0" (__HYPERVISOR_update_descriptor),
kaf24@6696 335 "1" ((unsigned long)ma), "2" ((unsigned long)(ma>>32)),
kaf24@6696 336 "3" ((unsigned long)desc), "4" ((unsigned long)(desc>>32))
kaf24@6696 337 : "memory" );
kaf24@6696 338
kaf24@6696 339 return ret;
kaf24@6696 340 }
kaf24@6696 341
kaf24@6696 342 static inline int
kaf24@6696 343 HYPERVISOR_dom_mem_op(
kaf24@6696 344 unsigned int op, unsigned long *extent_list,
kaf24@6696 345 unsigned long nr_extents, unsigned int extent_order)
kaf24@6696 346 {
kaf24@6696 347 int ret;
kaf24@6696 348 unsigned long ign1, ign2, ign3, ign4, ign5;
kaf24@6696 349
kaf24@6696 350 __asm__ __volatile__ (
kaf24@6696 351 TRAP_INSTR
kaf24@6696 352 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
kaf24@6696 353 "=D" (ign5)
kaf24@6696 354 : "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list),
kaf24@6696 355 "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF)
kaf24@6696 356 : "memory" );
kaf24@6696 357
kaf24@6696 358 return ret;
kaf24@6696 359 }
kaf24@6696 360
kaf24@6696 361 static inline int
kaf24@6696 362 HYPERVISOR_multicall(
kaf24@6696 363 void *call_list, int nr_calls)
kaf24@6696 364 {
kaf24@6696 365 int ret;
kaf24@6696 366 unsigned long ign1, ign2;
kaf24@6696 367
kaf24@6696 368 __asm__ __volatile__ (
kaf24@6696 369 TRAP_INSTR
kaf24@6696 370 : "=a" (ret), "=b" (ign1), "=c" (ign2)
kaf24@6696 371 : "0" (__HYPERVISOR_multicall), "1" (call_list), "2" (nr_calls)
kaf24@6696 372 : "memory" );
kaf24@6696 373
kaf24@6696 374 return ret;
kaf24@6696 375 }
kaf24@6696 376
kaf24@6696 377 static inline int
kaf24@6696 378 HYPERVISOR_update_va_mapping(
kaf24@6696 379 unsigned long va, pte_t new_val, unsigned long flags)
kaf24@6696 380 {
kaf24@6696 381 int ret;
kaf24@6696 382 unsigned long ign1, ign2, ign3, ign4;
kaf24@6696 383
kaf24@6696 384 __asm__ __volatile__ (
kaf24@6696 385 TRAP_INSTR
kaf24@6696 386 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
kaf24@6696 387 : "0" (__HYPERVISOR_update_va_mapping),
kaf24@6696 388 "1" (va), "2" ((new_val).pte_low),
kaf24@6696 389 #ifdef CONFIG_X86_PAE
kaf24@6696 390 "3" ((new_val).pte_high),
kaf24@5675 391 #else
kaf24@6696 392 "3" (0),
kaf24@6696 393 #endif
kaf24@6696 394 "4" (flags)
kaf24@6696 395 : "memory" );
kaf24@6696 396
kaf24@6696 397 return ret;
kaf24@6696 398 }
kaf24@6696 399
kaf24@6696 400 static inline int
kaf24@6696 401 HYPERVISOR_event_channel_op(
kaf24@6696 402 void *op)
kaf24@6696 403 {
kaf24@6696 404 int ret;
kaf24@6696 405 unsigned long ignore;
kaf24@6696 406 __asm__ __volatile__ (
kaf24@6696 407 TRAP_INSTR
kaf24@6696 408 : "=a" (ret), "=b" (ignore)
kaf24@6696 409 : "0" (__HYPERVISOR_event_channel_op), "1" (op)
kaf24@6696 410 : "memory" );
kaf24@6696 411
kaf24@6696 412 return ret;
kaf24@6696 413 }
kaf24@6696 414
kaf24@6696 415 static inline int
kaf24@6696 416 HYPERVISOR_xen_version(
kaf24@6734 417 int cmd, void *arg)
kaf24@6696 418 {
kaf24@6696 419 int ret;
kaf24@6734 420 unsigned long ignore, ign2;
kaf24@6696 421
kaf24@6696 422 __asm__ __volatile__ (
kaf24@6696 423 TRAP_INSTR
kaf24@6734 424 : "=a" (ret), "=b" (ignore), "=c" (ign2)
kaf24@6734 425 : "0" (__HYPERVISOR_xen_version), "1" (cmd), "2" (arg)
kaf24@6696 426 : "memory" );
kaf24@6696 427
kaf24@6696 428 return ret;
kaf24@6696 429 }
kaf24@6696 430
kaf24@6696 431 static inline int
kaf24@6696 432 HYPERVISOR_console_io(
kaf24@6696 433 int cmd, int count, char *str)
kaf24@6696 434 {
kaf24@6696 435 int ret;
kaf24@6696 436 unsigned long ign1, ign2, ign3;
kaf24@6696 437 __asm__ __volatile__ (
kaf24@6696 438 TRAP_INSTR
kaf24@6696 439 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
kaf24@6696 440 : "0" (__HYPERVISOR_console_io), "1" (cmd), "2" (count), "3" (str)
kaf24@6696 441 : "memory" );
kaf24@6696 442
kaf24@6696 443 return ret;
kaf24@6696 444 }
kaf24@6696 445
kaf24@6696 446 static inline int
kaf24@6696 447 HYPERVISOR_physdev_op(
kaf24@6696 448 void *physdev_op)
kaf24@6696 449 {
kaf24@6696 450 int ret;
kaf24@6696 451 unsigned long ign;
kaf24@6696 452
kaf24@6696 453 __asm__ __volatile__ (
kaf24@6696 454 TRAP_INSTR
kaf24@6696 455 : "=a" (ret), "=b" (ign)
kaf24@6696 456 : "0" (__HYPERVISOR_physdev_op), "1" (physdev_op)
kaf24@6696 457 : "memory" );
kaf24@6696 458
kaf24@6696 459 return ret;
kaf24@6696 460 }
kaf24@6696 461
kaf24@6696 462 static inline int
kaf24@6696 463 HYPERVISOR_grant_table_op(
kaf24@6696 464 unsigned int cmd, void *uop, unsigned int count)
kaf24@6696 465 {
kaf24@6696 466 int ret;
kaf24@6696 467 unsigned long ign1, ign2, ign3;
kaf24@6696 468
kaf24@6696 469 __asm__ __volatile__ (
kaf24@6696 470 TRAP_INSTR
kaf24@6696 471 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
kaf24@6696 472 : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (uop), "3" (count)
kaf24@6696 473 : "memory" );
kaf24@6696 474
kaf24@6696 475 return ret;
kaf24@6696 476 }
kaf24@6696 477
kaf24@6696 478 static inline int
kaf24@6696 479 HYPERVISOR_update_va_mapping_otherdomain(
kaf24@6696 480 unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
kaf24@6696 481 {
kaf24@6696 482 int ret;
kaf24@6696 483 unsigned long ign1, ign2, ign3, ign4, ign5;
kaf24@6696 484
kaf24@6696 485 __asm__ __volatile__ (
kaf24@6696 486 TRAP_INSTR
kaf24@6696 487 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3),
kaf24@6696 488 "=S" (ign4), "=D" (ign5)
kaf24@6696 489 : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
kaf24@6696 490 "1" (va), "2" ((new_val).pte_low),
kaf24@6696 491 #ifdef CONFIG_X86_PAE
kaf24@6696 492 "3" ((new_val).pte_high),
kaf24@6696 493 #else
kaf24@6696 494 "3" (0),
kaf24@6696 495 #endif
kaf24@6696 496 "4" (flags), "5" (domid) :
kaf24@6696 497 "memory" );
kaf24@6696 498
kaf24@6696 499 return ret;
kaf24@6696 500 }
kaf24@6696 501
kaf24@6696 502 static inline int
kaf24@6696 503 HYPERVISOR_vm_assist(
kaf24@6696 504 unsigned int cmd, unsigned int type)
kaf24@6696 505 {
kaf24@6696 506 int ret;
kaf24@6696 507 unsigned long ign1, ign2;
kaf24@6696 508
kaf24@6696 509 __asm__ __volatile__ (
kaf24@6696 510 TRAP_INSTR
kaf24@6696 511 : "=a" (ret), "=b" (ign1), "=c" (ign2)
kaf24@6696 512 : "0" (__HYPERVISOR_vm_assist), "1" (cmd), "2" (type)
kaf24@6696 513 : "memory" );
kaf24@6696 514
kaf24@6696 515 return ret;
kaf24@6696 516 }
kaf24@6696 517
kaf24@6696 518 static inline int
kaf24@6696 519 HYPERVISOR_boot_vcpu(
kaf24@6696 520 unsigned long vcpu, vcpu_guest_context_t *ctxt)
kaf24@6696 521 {
kaf24@6696 522 int ret;
kaf24@6696 523 unsigned long ign1, ign2;
kaf24@6696 524
kaf24@6696 525 __asm__ __volatile__ (
kaf24@6696 526 TRAP_INSTR
kaf24@6696 527 : "=a" (ret), "=b" (ign1), "=c" (ign2)
kaf24@6696 528 : "0" (__HYPERVISOR_boot_vcpu), "1" (vcpu), "2" (ctxt)
kaf24@6696 529 : "memory");
kaf24@6696 530
kaf24@6696 531 return ret;
kaf24@6696 532 }
kaf24@6696 533
kaf24@6696 534 static inline int
kaf24@6696 535 HYPERVISOR_vcpu_down(
kaf24@6696 536 int vcpu)
kaf24@6696 537 {
kaf24@6696 538 int ret;
kaf24@6696 539 unsigned long ign1;
kaf24@6696 540 /* Yes, I really do want to clobber edx here: when we resume a
kaf24@6696 541 vcpu after unpickling a multi-processor domain, it returns
kaf24@6696 542 here, but clobbers all of the call clobbered registers. */
kaf24@6696 543 __asm__ __volatile__ (
kaf24@6696 544 TRAP_INSTR
kaf24@6696 545 : "=a" (ret), "=b" (ign1)
kaf24@6696 546 : "0" (__HYPERVISOR_sched_op),
kaf24@6696 547 "1" (SCHEDOP_vcpu_down | (vcpu << SCHEDOP_vcpushift))
kaf24@6696 548 : "memory", "ecx", "edx" );
kaf24@6696 549
kaf24@6696 550 return ret;
kaf24@6696 551 }
kaf24@6696 552
kaf24@6696 553 static inline int
kaf24@6696 554 HYPERVISOR_vcpu_up(
kaf24@6696 555 int vcpu)
kaf24@6696 556 {
kaf24@6696 557 int ret;
kaf24@6696 558 unsigned long ign1;
kaf24@6696 559 __asm__ __volatile__ (
kaf24@6696 560 TRAP_INSTR
kaf24@6696 561 : "=a" (ret), "=b" (ign1)
kaf24@6696 562 : "0" (__HYPERVISOR_sched_op),
kaf24@6696 563 "1" (SCHEDOP_vcpu_up | (vcpu << SCHEDOP_vcpushift))
kaf24@6696 564 : "memory", "ecx" );
kaf24@6696 565
kaf24@6696 566 return ret;
kaf24@6696 567 }
kaf24@6696 568
kaf24@6696 569 static inline int
kaf24@6696 570 HYPERVISOR_vcpu_pickle(
kaf24@6696 571 int vcpu, vcpu_guest_context_t *ctxt)
kaf24@6696 572 {
kaf24@6696 573 int ret;
kaf24@6696 574 unsigned long ign1, ign2;
kaf24@6696 575 __asm__ __volatile__ (
kaf24@6696 576 TRAP_INSTR
kaf24@6696 577 : "=a" (ret), "=b" (ign1), "=c" (ign2)
kaf24@6696 578 : "0" (__HYPERVISOR_sched_op),
kaf24@6696 579 "1" (SCHEDOP_vcpu_pickle | (vcpu << SCHEDOP_vcpushift)),
kaf24@6696 580 "2" (ctxt)
kaf24@6696 581 : "memory" );
kaf24@6696 582
kaf24@6696 583 return ret;
kaf24@6696 584 }
kaf24@6696 585 #elif defined(__x86_64__)
kaf24@6696 586
kaf24@6696 587 #define __syscall_clobber "r11","rcx","memory"
kaf24@6696 588
kaf24@6696 589 /*
kaf24@6696 590 * Assembler stubs for hyper-calls.
kaf24@6696 591 */
kaf24@6696 592 static inline int
kaf24@6696 593 HYPERVISOR_set_trap_table(
kaf24@6696 594 trap_info_t *table)
kaf24@6696 595 {
kaf24@6696 596 int ret;
kaf24@6696 597
kaf24@6696 598 __asm__ __volatile__ (
kaf24@6696 599 TRAP_INSTR
kaf24@6696 600 : "=a" (ret)
kaf24@6696 601 : "0" ((unsigned long)__HYPERVISOR_set_trap_table), "D" (table)
kaf24@6696 602 : __syscall_clobber );
kaf24@6696 603
kaf24@6696 604 return ret;
kaf24@6696 605 }
kaf24@6696 606
kaf24@6696 607 static inline int
kaf24@6696 608 HYPERVISOR_mmu_update(
kaf24@6696 609 mmu_update_t *req, int count, int *success_count, domid_t domid)
kaf24@6696 610 {
kaf24@6696 611 int ret;
kaf24@6696 612
kaf24@6696 613 __asm__ __volatile__ (
kaf24@6696 614 "movq %5, %%r10;" TRAP_INSTR
kaf24@6696 615 : "=a" (ret)
kaf24@6696 616 : "0" ((unsigned long)__HYPERVISOR_mmu_update), "D" (req), "S" ((long)count),
kaf24@6696 617 "d" (success_count), "g" ((unsigned long)domid)
kaf24@6696 618 : __syscall_clobber, "r10" );
kaf24@6696 619
kaf24@6696 620 return ret;
kaf24@6696 621 }
kaf24@6696 622
kaf24@6696 623 static inline int
kaf24@6696 624 HYPERVISOR_mmuext_op(
kaf24@6696 625 struct mmuext_op *op, int count, int *success_count, domid_t domid)
kaf24@6696 626 {
kaf24@6696 627 int ret;
kaf24@6696 628
kaf24@6696 629 __asm__ __volatile__ (
kaf24@6696 630 "movq %5, %%r10;" TRAP_INSTR
kaf24@6696 631 : "=a" (ret)
kaf24@6696 632 : "0" (__HYPERVISOR_mmuext_op), "D" (op), "S" ((long)count),
kaf24@6696 633 "d" (success_count), "g" ((unsigned long)domid)
kaf24@6696 634 : __syscall_clobber, "r10" );
kaf24@6696 635
kaf24@6696 636 return ret;
kaf24@6696 637 }
kaf24@6696 638
kaf24@6696 639 static inline int
kaf24@6696 640 HYPERVISOR_set_gdt(
kaf24@6696 641 unsigned long *frame_list, int entries)
kaf24@6696 642 {
kaf24@6696 643 int ret;
kaf24@6696 644
kaf24@6696 645 __asm__ __volatile__ (
kaf24@6696 646 TRAP_INSTR
kaf24@6696 647 : "=a" (ret)
kaf24@6696 648 : "0" ((unsigned long)__HYPERVISOR_set_gdt), "D" (frame_list), "S" ((long)entries)
kaf24@6696 649 : __syscall_clobber );
kaf24@6696 650
kaf24@6696 651
kaf24@6696 652 return ret;
kaf24@6696 653 }
kaf24@6696 654 static inline int
kaf24@6696 655 HYPERVISOR_stack_switch(
kaf24@6696 656 unsigned long ss, unsigned long esp)
kaf24@6696 657 {
kaf24@6696 658 int ret;
kaf24@6696 659
kaf24@6696 660 __asm__ __volatile__ (
kaf24@6696 661 TRAP_INSTR
kaf24@6696 662 : "=a" (ret)
kaf24@6696 663 : "0" ((unsigned long)__HYPERVISOR_stack_switch), "D" (ss), "S" (esp)
kaf24@6696 664 : __syscall_clobber );
kaf24@6696 665
kaf24@6696 666 return ret;
kaf24@6696 667 }
kaf24@6696 668
kaf24@6696 669 static inline int
kaf24@6696 670 HYPERVISOR_set_callbacks(
kaf24@6696 671 unsigned long event_address, unsigned long failsafe_address,
kaf24@6696 672 unsigned long syscall_address)
kaf24@6696 673 {
kaf24@6696 674 int ret;
kaf24@6696 675
kaf24@6696 676 __asm__ __volatile__ (
kaf24@6696 677 TRAP_INSTR
kaf24@6696 678 : "=a" (ret)
kaf24@6696 679 : "0" ((unsigned long)__HYPERVISOR_set_callbacks), "D" (event_address),
kaf24@6696 680 "S" (failsafe_address), "d" (syscall_address)
kaf24@6696 681 : __syscall_clobber );
kaf24@6696 682
kaf24@6696 683 return ret;
kaf24@6696 684 }
kaf24@6696 685
kaf24@6696 686 static inline int
kaf24@6696 687 HYPERVISOR_fpu_taskswitch(
kaf24@6696 688 int set)
kaf24@6696 689 {
kaf24@6696 690 int ret;
kaf24@6696 691 __asm__ __volatile__ (
kaf24@6696 692 TRAP_INSTR
kaf24@6696 693 : "=a" (ret) : "0" ((unsigned long)__HYPERVISOR_fpu_taskswitch),
kaf24@6696 694 "D" ((unsigned long) set) : __syscall_clobber );
kaf24@6696 695
kaf24@6696 696 return ret;
kaf24@6696 697 }
kaf24@6696 698
kaf24@6696 699 static inline int
kaf24@6696 700 HYPERVISOR_yield(
kaf24@6696 701 void)
kaf24@6696 702 {
kaf24@6696 703 int ret;
kaf24@6696 704
kaf24@6696 705 __asm__ __volatile__ (
kaf24@6696 706 TRAP_INSTR
kaf24@6696 707 : "=a" (ret)
kaf24@6696 708 : "0" ((unsigned long)__HYPERVISOR_sched_op), "D" ((unsigned long)SCHEDOP_yield)
kaf24@6696 709 : __syscall_clobber );
kaf24@6696 710
kaf24@6696 711 return ret;
kaf24@6696 712 }
kaf24@6696 713
kaf24@6696 714 static inline int
kaf24@6696 715 HYPERVISOR_block(
kaf24@6696 716 void)
kaf24@6696 717 {
kaf24@6696 718 int ret;
kaf24@6696 719 __asm__ __volatile__ (
kaf24@6696 720 TRAP_INSTR
kaf24@6696 721 : "=a" (ret)
kaf24@6696 722 : "0" ((unsigned long)__HYPERVISOR_sched_op), "D" ((unsigned long)SCHEDOP_block)
kaf24@6696 723 : __syscall_clobber );
kaf24@6696 724
kaf24@6696 725 return ret;
kaf24@6696 726 }
kaf24@6696 727
kaf24@6696 728 static inline int
kaf24@6696 729 HYPERVISOR_shutdown(
kaf24@6696 730 void)
kaf24@6696 731 {
kaf24@6696 732 int ret;
kaf24@6696 733 __asm__ __volatile__ (
kaf24@6696 734 TRAP_INSTR
kaf24@6696 735 : "=a" (ret)
kaf24@6696 736 : "0" ((unsigned long)__HYPERVISOR_sched_op),
kaf24@6696 737 "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift)))
kaf24@6696 738 : __syscall_clobber );
kaf24@6696 739
kaf24@6696 740 return ret;
kaf24@6696 741 }
kaf24@6696 742
kaf24@6696 743 static inline int
kaf24@6696 744 HYPERVISOR_reboot(
kaf24@6696 745 void)
kaf24@6696 746 {
kaf24@6696 747 int ret;
kaf24@6696 748
kaf24@6696 749 __asm__ __volatile__ (
kaf24@6696 750 TRAP_INSTR
kaf24@6696 751 : "=a" (ret)
kaf24@6696 752 : "0" ((unsigned long)__HYPERVISOR_sched_op),
kaf24@6696 753 "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift)))
kaf24@6696 754 : __syscall_clobber );
kaf24@6696 755
kaf24@6696 756 return ret;
kaf24@6696 757 }
kaf24@6696 758
kaf24@6696 759 static inline int
kaf24@6696 760 HYPERVISOR_suspend(
kaf24@6696 761 unsigned long srec)
kaf24@6696 762 {
kaf24@6696 763 int ret;
kaf24@6696 764
kaf24@6696 765 /* NB. On suspend, control software expects a suspend record in %esi. */
kaf24@6696 766 __asm__ __volatile__ (
kaf24@6696 767 TRAP_INSTR
kaf24@6696 768 : "=a" (ret)
kaf24@6696 769 : "0" ((unsigned long)__HYPERVISOR_sched_op),
kaf24@6696 770 "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift))),
kaf24@6696 771 "S" (srec)
kaf24@6696 772 : __syscall_clobber );
kaf24@6696 773
kaf24@6696 774 return ret;
kaf24@6696 775 }
kaf24@6696 776
kaf24@6696 777 /*
kaf24@6696 778 * We can have the timeout value in a single argument for the hypercall, but
kaf24@6696 779 * that will break the common code.
kaf24@6696 780 */
kaf24@6696 781 static inline long
kaf24@6696 782 HYPERVISOR_set_timer_op(
kaf24@6696 783 u64 timeout)
kaf24@5675 784 {
kaf24@5675 785 int ret;
kaf24@5675 786
kaf24@5675 787 __asm__ __volatile__ (
kaf24@5675 788 TRAP_INSTR
kaf24@5675 789 : "=a" (ret)
kaf24@5675 790 : "0" ((unsigned long)__HYPERVISOR_set_timer_op),
kaf24@5675 791 "D" (timeout)
kaf24@5675 792 : __syscall_clobber );
kaf24@5675 793
kaf24@5675 794 return ret;
kaf24@5675 795 }
kaf24@5675 796 #endif
kaf24@5675 797
kaf24@5675 798
kaf24@5675 799 static __inline__ int HYPERVISOR_dom0_op(void *dom0_op)
kaf24@5675 800 {
kaf24@5675 801 int ret;
kaf24@5675 802 __asm__ __volatile__ (
kaf24@5675 803 TRAP_INSTR
kaf24@5675 804 : "=a" (ret) : "0" (__HYPERVISOR_dom0_op),
kaf24@5675 805 _a1 (dom0_op) : "memory" );
kaf24@5675 806
kaf24@5675 807 return ret;
kaf24@5675 808 }
kaf24@5675 809
kaf24@5675 810 static __inline__ int HYPERVISOR_set_debugreg(int reg, unsigned long value)
kaf24@5675 811 {
kaf24@5675 812 int ret;
kaf24@5675 813 __asm__ __volatile__ (
kaf24@5675 814 TRAP_INSTR
kaf24@5675 815 : "=a" (ret) : "0" (__HYPERVISOR_set_debugreg),
kaf24@5675 816 _a1 (reg), _a2 (value) : "memory" );
kaf24@5675 817
kaf24@5675 818 return ret;
kaf24@5675 819 }
kaf24@5675 820
kaf24@5675 821 static __inline__ unsigned long HYPERVISOR_get_debugreg(int reg)
kaf24@5675 822 {
kaf24@5675 823 unsigned long ret;
kaf24@5675 824 __asm__ __volatile__ (
kaf24@5675 825 TRAP_INSTR
kaf24@5675 826 : "=a" (ret) : "0" (__HYPERVISOR_get_debugreg),
kaf24@5675 827 _a1 (reg) : "memory" );
kaf24@5675 828
kaf24@5675 829 return ret;
kaf24@5675 830 }
kaf24@5675 831
kaf24@5675 832 static __inline__ int HYPERVISOR_update_descriptor(
kaf24@5675 833 unsigned long pa, unsigned long word1, unsigned long word2)
kaf24@5675 834 {
kaf24@5675 835 int ret;
kaf24@5675 836 __asm__ __volatile__ (
kaf24@5675 837 TRAP_INSTR
kaf24@5675 838 : "=a" (ret) : "0" (__HYPERVISOR_update_descriptor),
kaf24@5675 839 _a1 (pa), _a2 (word1), _a3 (word2) : "memory" );
kaf24@5675 840
kaf24@5675 841 return ret;
kaf24@5675 842 }
kaf24@5675 843
kaf24@5675 844 static __inline__ int HYPERVISOR_dom_mem_op(void *dom_mem_op)
kaf24@5675 845 {
kaf24@5675 846 int ret;
kaf24@5675 847 __asm__ __volatile__ (
kaf24@5675 848 TRAP_INSTR
kaf24@6584 849 : "=a" (ret) : "0" (__HYPERVISOR_memory_op),
kaf24@5675 850 _a1 (dom_mem_op) : "memory" );
kaf24@5675 851
kaf24@5675 852 return ret;
kaf24@5675 853 }
kaf24@5675 854
kaf24@5675 855 static __inline__ int HYPERVISOR_multicall(void *call_list, int nr_calls)
kaf24@5675 856 {
kaf24@5675 857 int ret;
kaf24@5675 858 __asm__ __volatile__ (
kaf24@5675 859 TRAP_INSTR
kaf24@5675 860 : "=a" (ret) : "0" (__HYPERVISOR_multicall),
kaf24@5675 861 _a1 (call_list), _a2 (nr_calls) : "memory" );
kaf24@5675 862
kaf24@5675 863 return ret;
kaf24@5675 864 }
kaf24@5675 865
kaf24@5675 866 static __inline__ int HYPERVISOR_update_va_mapping(
kaf24@5675 867 unsigned long page_nr, unsigned long new_val, unsigned long flags)
kaf24@5675 868 {
kaf24@5675 869 int ret;
kaf24@5675 870 __asm__ __volatile__ (
kaf24@5675 871 TRAP_INSTR
kaf24@5675 872 : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping),
kaf24@5675 873 _a1 (page_nr), _a2 (new_val), _a3 (flags) : "memory" );
kaf24@5675 874
kaf24@5675 875 return ret;
kaf24@5675 876 }
kaf24@5675 877
kaf24@5675 878 static __inline__ int HYPERVISOR_xen_version(int cmd)
kaf24@5675 879 {
kaf24@5675 880 int ret;
kaf24@5675 881 __asm__ __volatile__ (
kaf24@5675 882 TRAP_INSTR
kaf24@5675 883 : "=a" (ret) : "0" (__HYPERVISOR_xen_version),
kaf24@5675 884 _a1 (cmd) : "memory" );
kaf24@5675 885
kaf24@5675 886 return ret;
kaf24@5675 887 }
kaf24@5675 888
kaf24@5675 889 static __inline__ int HYPERVISOR_console_io(int cmd, int count, char *str)
kaf24@5675 890 {
kaf24@5675 891 int ret;
kaf24@5675 892 __asm__ __volatile__ (
kaf24@5675 893 TRAP_INSTR
kaf24@5675 894 : "=a" (ret) : "0" (__HYPERVISOR_console_io),
kaf24@5675 895 _a1 (cmd), _a2 (count), _a3 (str) : "memory" );
kaf24@5675 896
kaf24@5675 897 return ret;
kaf24@5675 898 }
kaf24@5675 899
kaf24@5675 900 #endif /* __HYPERVISOR_H__ */