direct-io.hg
changeset 7550:bcccadcc56e5
Merged.
author | emellor@leeni.uk.xensource.com |
---|---|
date | Sun Oct 30 14:00:35 2005 +0100 (2005-10-30) |
parents | dc36edf1102f b5903c9aeda5 |
children | 47ba7a4bed45 |
files | tools/examples/Makefile tools/python/xen/xm/create.py |
line diff
1.1 --- a/extras/mini-os/include/events.h Sun Oct 30 13:52:38 2005 +0100 1.2 +++ b/extras/mini-os/include/events.h Sun Oct 30 14:00:35 2005 +0100 1.3 @@ -47,7 +47,7 @@ static inline int notify_via_evtchn(int 1.4 { 1.5 evtchn_op_t op; 1.6 op.cmd = EVTCHNOP_send; 1.7 - op.u.send.local_port = port; 1.8 + op.u.send.port = port; 1.9 return HYPERVISOR_event_channel_op(&op); 1.10 } 1.11
2.1 --- a/extras/mini-os/include/hypervisor.h Sun Oct 30 13:52:38 2005 +0100 2.2 +++ b/extras/mini-os/include/hypervisor.h Sun Oct 30 14:00:35 2005 +0100 2.3 @@ -14,6 +14,7 @@ 2.4 2.5 #include <types.h> 2.6 #include <xen/xen.h> 2.7 +#include <xen/dom0_ops.h> 2.8 2.9 /* 2.10 * a placeholder for the start of day information passed up from the hypervisor 2.11 @@ -37,548 +38,281 @@ void clear_evtchn(u32 port); 2.12 * Assembler stubs for hyper-calls. 2.13 */ 2.14 #if defined(__i386__) 2.15 +/* Taken from Linux */ 2.16 + 2.17 +#ifndef __HYPERCALL_H__ 2.18 +#define __HYPERCALL_H__ 2.19 + 2.20 +#include <xen/sched.h> 2.21 + 2.22 +#define _hypercall0(type, name) \ 2.23 +({ \ 2.24 + long __res; \ 2.25 + asm volatile ( \ 2.26 + TRAP_INSTR \ 2.27 + : "=a" (__res) \ 2.28 + : "0" (__HYPERVISOR_##name) \ 2.29 + : "memory" ); \ 2.30 + (type)__res; \ 2.31 +}) 2.32 + 2.33 +#define _hypercall1(type, name, a1) \ 2.34 +({ \ 2.35 + long __res, __ign1; \ 2.36 + asm volatile ( \ 2.37 + TRAP_INSTR \ 2.38 + : "=a" (__res), "=b" (__ign1) \ 2.39 + : "0" (__HYPERVISOR_##name), "1" ((long)(a1)) \ 2.40 + : "memory" ); \ 2.41 + (type)__res; \ 2.42 +}) 2.43 + 2.44 +#define _hypercall2(type, name, a1, a2) \ 2.45 +({ \ 2.46 + long __res, __ign1, __ign2; \ 2.47 + asm volatile ( \ 2.48 + TRAP_INSTR \ 2.49 + : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \ 2.50 + : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ 2.51 + "2" ((long)(a2)) \ 2.52 + : "memory" ); \ 2.53 + (type)__res; \ 2.54 +}) 2.55 + 2.56 +#define _hypercall3(type, name, a1, a2, a3) \ 2.57 +({ \ 2.58 + long __res, __ign1, __ign2, __ign3; \ 2.59 + asm volatile ( \ 2.60 + TRAP_INSTR \ 2.61 + : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ 2.62 + "=d" (__ign3) \ 2.63 + : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ 2.64 + "2" ((long)(a2)), "3" ((long)(a3)) \ 2.65 + : "memory" ); \ 2.66 + (type)__res; \ 2.67 +}) 2.68 + 2.69 +#define _hypercall4(type, name, a1, a2, a3, a4) \ 2.70 +({ \ 2.71 + long __res, __ign1, __ign2, __ign3, __ign4; \ 2.72 + asm volatile ( \ 2.73 + TRAP_INSTR \ 2.74 + : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ 2.75 + "=d" (__ign3), "=S" (__ign4) \ 2.76 + : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ 2.77 + "2" ((long)(a2)), "3" ((long)(a3)), \ 2.78 + "4" ((long)(a4)) \ 2.79 + : "memory" ); \ 2.80 + (type)__res; \ 2.81 +}) 2.82 + 2.83 +#define _hypercall5(type, name, a1, a2, a3, a4, a5) \ 2.84 +({ \ 2.85 + long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \ 2.86 + asm volatile ( \ 2.87 + TRAP_INSTR \ 2.88 + : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ 2.89 + "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \ 2.90 + : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ 2.91 + "2" ((long)(a2)), "3" ((long)(a3)), \ 2.92 + "4" ((long)(a4)), "5" ((long)(a5)) \ 2.93 + : "memory" ); \ 2.94 + (type)__res; \ 2.95 +}) 2.96 + 2.97 static inline int 2.98 HYPERVISOR_set_trap_table( 2.99 - trap_info_t *table) 2.100 + trap_info_t *table) 2.101 { 2.102 - int ret; 2.103 - unsigned long ignore; 2.104 - 2.105 - __asm__ __volatile__ ( 2.106 - TRAP_INSTR 2.107 - : "=a" (ret), "=b" (ignore) 2.108 - : "0" (__HYPERVISOR_set_trap_table), "1" (table) 2.109 - : "memory" ); 2.110 - 2.111 - return ret; 2.112 + return _hypercall1(int, set_trap_table, table); 2.113 } 2.114 2.115 static inline int 2.116 HYPERVISOR_mmu_update( 2.117 - mmu_update_t *req, int count, int *success_count, domid_t domid) 2.118 + mmu_update_t *req, int count, int *success_count, domid_t domid) 2.119 { 2.120 - int ret; 2.121 - unsigned long ign1, ign2, ign3, ign4; 2.122 - 2.123 - __asm__ __volatile__ ( 2.124 - TRAP_INSTR 2.125 - : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) 2.126 - : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count), 2.127 - "3" (success_count), "4" (domid) 2.128 - : "memory" ); 2.129 - 2.130 - return ret; 2.131 + return _hypercall4(int, mmu_update, req, count, success_count, domid); 2.132 } 2.133 2.134 static inline int 2.135 HYPERVISOR_mmuext_op( 2.136 - struct mmuext_op *op, int count, int *success_count, domid_t domid) 2.137 + struct mmuext_op *op, int count, int *success_count, domid_t domid) 2.138 { 2.139 - int ret; 2.140 - unsigned long ign1, ign2, ign3, ign4; 2.141 - 2.142 - __asm__ __volatile__ ( 2.143 - TRAP_INSTR 2.144 - : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) 2.145 - : "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count), 2.146 - "3" (success_count), "4" (domid) 2.147 - : "memory" ); 2.148 - 2.149 - return ret; 2.150 + return _hypercall4(int, mmuext_op, op, count, success_count, domid); 2.151 } 2.152 2.153 static inline int 2.154 HYPERVISOR_set_gdt( 2.155 - unsigned long *frame_list, int entries) 2.156 + unsigned long *frame_list, int entries) 2.157 { 2.158 - int ret; 2.159 - unsigned long ign1, ign2; 2.160 - 2.161 - __asm__ __volatile__ ( 2.162 - TRAP_INSTR 2.163 - : "=a" (ret), "=b" (ign1), "=c" (ign2) 2.164 - : "0" (__HYPERVISOR_set_gdt), "1" (frame_list), "2" (entries) 2.165 - : "memory" ); 2.166 - 2.167 - 2.168 - return ret; 2.169 + return _hypercall2(int, set_gdt, frame_list, entries); 2.170 } 2.171 2.172 static inline int 2.173 HYPERVISOR_stack_switch( 2.174 - unsigned long ss, unsigned long esp) 2.175 + unsigned long ss, unsigned long esp) 2.176 { 2.177 - int ret; 2.178 - unsigned long ign1, ign2; 2.179 - 2.180 - __asm__ __volatile__ ( 2.181 - TRAP_INSTR 2.182 - : "=a" (ret), "=b" (ign1), "=c" (ign2) 2.183 - : "0" (__HYPERVISOR_stack_switch), "1" (ss), "2" (esp) 2.184 - : "memory" ); 2.185 - 2.186 - return ret; 2.187 + return _hypercall2(int, stack_switch, ss, esp); 2.188 } 2.189 2.190 static inline int 2.191 HYPERVISOR_set_callbacks( 2.192 - unsigned long event_selector, unsigned long event_address, 2.193 - unsigned long failsafe_selector, unsigned long failsafe_address) 2.194 + unsigned long event_selector, unsigned long event_address, 2.195 + unsigned long failsafe_selector, unsigned long failsafe_address) 2.196 { 2.197 - int ret; 2.198 - unsigned long ign1, ign2, ign3, ign4; 2.199 - 2.200 - __asm__ __volatile__ ( 2.201 - TRAP_INSTR 2.202 - : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) 2.203 - : "0" (__HYPERVISOR_set_callbacks), "1" (event_selector), 2.204 - "2" (event_address), "3" (failsafe_selector), "4" (failsafe_address) 2.205 - : "memory" ); 2.206 - 2.207 - return ret; 2.208 + return _hypercall4(int, set_callbacks, 2.209 + event_selector, event_address, 2.210 + failsafe_selector, failsafe_address); 2.211 } 2.212 2.213 static inline int 2.214 HYPERVISOR_fpu_taskswitch( 2.215 - int set) 2.216 -{ 2.217 - int ret; 2.218 - unsigned long ign; 2.219 - 2.220 - __asm__ __volatile__ ( 2.221 - TRAP_INSTR 2.222 - : "=a" (ret), "=b" (ign) 2.223 - : "0" (__HYPERVISOR_fpu_taskswitch), "1" (set) 2.224 - : "memory" ); 2.225 - 2.226 - return ret; 2.227 -} 2.228 - 2.229 -static inline int 2.230 -HYPERVISOR_yield( 2.231 - void) 2.232 + int set) 2.233 { 2.234 - int ret; 2.235 - unsigned long ign; 2.236 - 2.237 - __asm__ __volatile__ ( 2.238 - TRAP_INSTR 2.239 - : "=a" (ret), "=b" (ign) 2.240 - : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield) 2.241 - : "memory", "ecx" ); 2.242 - 2.243 - return ret; 2.244 -} 2.245 - 2.246 -static inline int 2.247 -HYPERVISOR_block( 2.248 - void) 2.249 -{ 2.250 - int ret; 2.251 - unsigned long ign1; 2.252 - __asm__ __volatile__ ( 2.253 - TRAP_INSTR 2.254 - : "=a" (ret), "=b" (ign1) 2.255 - : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block) 2.256 - : "memory", "ecx" ); 2.257 - 2.258 - return ret; 2.259 + return _hypercall1(int, fpu_taskswitch, set); 2.260 } 2.261 2.262 static inline int 2.263 -HYPERVISOR_shutdown( 2.264 - void) 2.265 -{ 2.266 - int ret; 2.267 - unsigned long ign1; 2.268 - __asm__ __volatile__ ( 2.269 - TRAP_INSTR 2.270 - : "=a" (ret), "=b" (ign1) 2.271 - : "0" (__HYPERVISOR_sched_op), 2.272 - "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift)) 2.273 - : "memory", "ecx" ); 2.274 - 2.275 - return ret; 2.276 -} 2.277 - 2.278 -static inline int 2.279 -HYPERVISOR_reboot( 2.280 - void) 2.281 +HYPERVISOR_sched_op( 2.282 + int cmd, unsigned long arg) 2.283 { 2.284 - int ret; 2.285 - unsigned long ign1; 2.286 - __asm__ __volatile__ ( 2.287 - TRAP_INSTR 2.288 - : "=a" (ret), "=b" (ign1) 2.289 - : "0" (__HYPERVISOR_sched_op), 2.290 - "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift)) 2.291 - : "memory", "ecx" ); 2.292 - 2.293 - return ret; 2.294 -} 2.295 - 2.296 -static inline int 2.297 -HYPERVISOR_suspend( 2.298 - unsigned long srec) 2.299 -{ 2.300 - int ret; 2.301 - unsigned long ign1, ign2; 2.302 - 2.303 - /* NB. On suspend, control software expects a suspend record in %esi. */ 2.304 - __asm__ __volatile__ ( 2.305 - TRAP_INSTR 2.306 - : "=a" (ret), "=b" (ign1), "=S" (ign2) 2.307 - : "0" (__HYPERVISOR_sched_op), 2.308 - "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), 2.309 - "S" (srec) : "memory", "ecx"); 2.310 - 2.311 - return ret; 2.312 -} 2.313 - 2.314 -static inline int 2.315 -HYPERVISOR_crash( 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, cmd, arg); 2.329 } 2.330 2.331 static inline long 2.332 HYPERVISOR_set_timer_op( 2.333 - u64 timeout) 2.334 + u64 timeout) 2.335 { 2.336 - int ret; 2.337 - unsigned long timeout_hi = (unsigned long)(timeout>>32); 2.338 - unsigned long timeout_lo = (unsigned long)timeout; 2.339 - unsigned long ign1, ign2; 2.340 - 2.341 - __asm__ __volatile__ ( 2.342 - TRAP_INSTR 2.343 - : "=a" (ret), "=b" (ign1), "=c" (ign2) 2.344 - : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_lo), "c" (timeout_hi) 2.345 - : "memory"); 2.346 - 2.347 - return ret; 2.348 + unsigned long timeout_hi = (unsigned long)(timeout>>32); 2.349 + unsigned long timeout_lo = (unsigned long)timeout; 2.350 + return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi); 2.351 } 2.352 2.353 -#if 0 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 -#endif 2.374 2.375 static inline int 2.376 HYPERVISOR_set_debugreg( 2.377 - int reg, unsigned long value) 2.378 + int reg, unsigned long value) 2.379 { 2.380 - int ret; 2.381 - unsigned long ign1, ign2; 2.382 - __asm__ __volatile__ ( 2.383 - TRAP_INSTR 2.384 - : "=a" (ret), "=b" (ign1), "=c" (ign2) 2.385 - : "0" (__HYPERVISOR_set_debugreg), "1" (reg), "2" (value) 2.386 - : "memory" ); 2.387 - 2.388 - return ret; 2.389 + return _hypercall2(int, set_debugreg, reg, value); 2.390 } 2.391 2.392 static inline unsigned long 2.393 HYPERVISOR_get_debugreg( 2.394 - int reg) 2.395 + int reg) 2.396 { 2.397 - unsigned long ret; 2.398 - unsigned long ign; 2.399 - __asm__ __volatile__ ( 2.400 - TRAP_INSTR 2.401 - : "=a" (ret), "=b" (ign) 2.402 - : "0" (__HYPERVISOR_get_debugreg), "1" (reg) 2.403 - : "memory" ); 2.404 - 2.405 - return ret; 2.406 + return _hypercall1(unsigned long, get_debugreg, reg); 2.407 } 2.408 2.409 static inline int 2.410 HYPERVISOR_update_descriptor( 2.411 - u64 ma, u64 desc) 2.412 + u64 ma, u64 desc) 2.413 { 2.414 - int ret; 2.415 - unsigned long ign1, ign2, ign3, ign4; 2.416 - 2.417 - __asm__ __volatile__ ( 2.418 - TRAP_INSTR 2.419 - : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) 2.420 - : "0" (__HYPERVISOR_update_descriptor), 2.421 - "1" ((unsigned long)ma), "2" ((unsigned long)(ma>>32)), 2.422 - "3" ((unsigned long)desc), "4" ((unsigned long)(desc>>32)) 2.423 - : "memory" ); 2.424 - 2.425 - return ret; 2.426 + return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32); 2.427 } 2.428 2.429 static inline int 2.430 -HYPERVISOR_dom_mem_op( 2.431 - unsigned int op, unsigned long *extent_list, 2.432 - unsigned long nr_extents, unsigned int extent_order) 2.433 +HYPERVISOR_memory_op( 2.434 + unsigned int cmd, void *arg) 2.435 { 2.436 - int ret; 2.437 - unsigned long ign1, ign2, ign3, ign4, ign5; 2.438 - 2.439 - __asm__ __volatile__ ( 2.440 - TRAP_INSTR 2.441 - : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4), 2.442 - "=D" (ign5) 2.443 - : "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list), 2.444 - "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF) 2.445 - : "memory" ); 2.446 - 2.447 - return ret; 2.448 + return _hypercall2(int, memory_op, cmd, arg); 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, void *arg) 2.517 + int cmd, void *arg) 2.518 { 2.519 - int ret; 2.520 - unsigned long ignore, ign2; 2.521 - 2.522 - __asm__ __volatile__ ( 2.523 - TRAP_INSTR 2.524 - : "=a" (ret), "=b" (ignore), "=c" (ign2) 2.525 - : "0" (__HYPERVISOR_xen_version), "1" (cmd), "2" (arg) 2.526 - : "memory" ); 2.527 - 2.528 - return ret; 2.529 + return _hypercall2(int, xen_version, cmd, arg); 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 -} 2.630 - 2.631 -static inline int 2.632 -HYPERVISOR_boot_vcpu( 2.633 - unsigned long vcpu, vcpu_guest_context_t *ctxt) 2.634 -{ 2.635 - int ret; 2.636 - unsigned long ign1, ign2; 2.637 - 2.638 - __asm__ __volatile__ ( 2.639 - TRAP_INSTR 2.640 - : "=a" (ret), "=b" (ign1), "=c" (ign2) 2.641 - : "0" (__HYPERVISOR_boot_vcpu), "1" (vcpu), "2" (ctxt) 2.642 - : "memory"); 2.643 - 2.644 - return ret; 2.645 + return _hypercall2(int, vm_assist, cmd, type); 2.646 } 2.647 2.648 static inline int 2.649 -HYPERVISOR_vcpu_down( 2.650 - int vcpu) 2.651 +HYPERVISOR_vcpu_op( 2.652 + int cmd, int vcpuid, void *extra_args) 2.653 { 2.654 - int ret; 2.655 - unsigned long ign1; 2.656 - /* Yes, I really do want to clobber edx here: when we resume a 2.657 - vcpu after unpickling a multi-processor domain, it returns 2.658 - here, but clobbers all of the call clobbered registers. */ 2.659 - __asm__ __volatile__ ( 2.660 - TRAP_INSTR 2.661 - : "=a" (ret), "=b" (ign1) 2.662 - : "0" (__HYPERVISOR_sched_op), 2.663 - "1" (SCHEDOP_vcpu_down | (vcpu << SCHEDOP_vcpushift)) 2.664 - : "memory", "ecx", "edx" ); 2.665 - 2.666 - return ret; 2.667 + return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args); 2.668 } 2.669 2.670 static inline int 2.671 -HYPERVISOR_vcpu_up( 2.672 - int vcpu) 2.673 +HYPERVISOR_suspend( 2.674 + unsigned long srec) 2.675 { 2.676 - int ret; 2.677 - unsigned long ign1; 2.678 - __asm__ __volatile__ ( 2.679 - TRAP_INSTR 2.680 - : "=a" (ret), "=b" (ign1) 2.681 - : "0" (__HYPERVISOR_sched_op), 2.682 - "1" (SCHEDOP_vcpu_up | (vcpu << SCHEDOP_vcpushift)) 2.683 - : "memory", "ecx" ); 2.684 - 2.685 - return ret; 2.686 + return _hypercall3(int, sched_op, SCHEDOP_shutdown, 2.687 + SHUTDOWN_suspend, srec); 2.688 } 2.689 2.690 -static inline int 2.691 -HYPERVISOR_vcpu_pickle( 2.692 - int vcpu, vcpu_guest_context_t *ctxt) 2.693 -{ 2.694 - int ret; 2.695 - unsigned long ign1, ign2; 2.696 - __asm__ __volatile__ ( 2.697 - TRAP_INSTR 2.698 - : "=a" (ret), "=b" (ign1), "=c" (ign2) 2.699 - : "0" (__HYPERVISOR_sched_op), 2.700 - "1" (SCHEDOP_vcpu_pickle | (vcpu << SCHEDOP_vcpushift)), 2.701 - "2" (ctxt) 2.702 - : "memory" ); 2.703 - 2.704 - return ret; 2.705 -} 2.706 +#endif /* __HYPERCALL_H__ */ 2.707 #elif defined(__x86_64__) 2.708 2.709 #define __syscall_clobber "r11","rcx","memory" 2.710 @@ -792,106 +526,4 @@ HYPERVISOR_set_timer_op( 2.711 } 2.712 #endif 2.713 2.714 - 2.715 -static __inline__ int HYPERVISOR_dom0_op(void *dom0_op) 2.716 -{ 2.717 - int ret; 2.718 - __asm__ __volatile__ ( 2.719 - TRAP_INSTR 2.720 - : "=a" (ret) : "0" (__HYPERVISOR_dom0_op), 2.721 - _a1 (dom0_op) : "memory" ); 2.722 - 2.723 - return ret; 2.724 -} 2.725 - 2.726 -static __inline__ int HYPERVISOR_set_debugreg(int reg, unsigned long value) 2.727 -{ 2.728 - int ret; 2.729 - __asm__ __volatile__ ( 2.730 - TRAP_INSTR 2.731 - : "=a" (ret) : "0" (__HYPERVISOR_set_debugreg), 2.732 - _a1 (reg), _a2 (value) : "memory" ); 2.733 - 2.734 - return ret; 2.735 -} 2.736 - 2.737 -static __inline__ unsigned long HYPERVISOR_get_debugreg(int reg) 2.738 -{ 2.739 - unsigned long ret; 2.740 - __asm__ __volatile__ ( 2.741 - TRAP_INSTR 2.742 - : "=a" (ret) : "0" (__HYPERVISOR_get_debugreg), 2.743 - _a1 (reg) : "memory" ); 2.744 - 2.745 - return ret; 2.746 -} 2.747 - 2.748 -static __inline__ int HYPERVISOR_update_descriptor( 2.749 - unsigned long pa, unsigned long word1, unsigned long word2) 2.750 -{ 2.751 - int ret; 2.752 - __asm__ __volatile__ ( 2.753 - TRAP_INSTR 2.754 - : "=a" (ret) : "0" (__HYPERVISOR_update_descriptor), 2.755 - _a1 (pa), _a2 (word1), _a3 (word2) : "memory" ); 2.756 - 2.757 - return ret; 2.758 -} 2.759 - 2.760 -static __inline__ int HYPERVISOR_dom_mem_op(void *dom_mem_op) 2.761 -{ 2.762 - int ret; 2.763 - __asm__ __volatile__ ( 2.764 - TRAP_INSTR 2.765 - : "=a" (ret) : "0" (__HYPERVISOR_memory_op), 2.766 - _a1 (dom_mem_op) : "memory" ); 2.767 - 2.768 - return ret; 2.769 -} 2.770 - 2.771 -static __inline__ int HYPERVISOR_multicall(void *call_list, int nr_calls) 2.772 -{ 2.773 - int ret; 2.774 - __asm__ __volatile__ ( 2.775 - TRAP_INSTR 2.776 - : "=a" (ret) : "0" (__HYPERVISOR_multicall), 2.777 - _a1 (call_list), _a2 (nr_calls) : "memory" ); 2.778 - 2.779 - return ret; 2.780 -} 2.781 - 2.782 -static __inline__ int HYPERVISOR_update_va_mapping( 2.783 - unsigned long page_nr, unsigned long new_val, unsigned long flags) 2.784 -{ 2.785 - int ret; 2.786 - __asm__ __volatile__ ( 2.787 - TRAP_INSTR 2.788 - : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping), 2.789 - _a1 (page_nr), _a2 (new_val), _a3 (flags) : "memory" ); 2.790 - 2.791 - return ret; 2.792 -} 2.793 - 2.794 -static __inline__ int HYPERVISOR_xen_version(int cmd) 2.795 -{ 2.796 - int ret; 2.797 - __asm__ __volatile__ ( 2.798 - TRAP_INSTR 2.799 - : "=a" (ret) : "0" (__HYPERVISOR_xen_version), 2.800 - _a1 (cmd) : "memory" ); 2.801 - 2.802 - return ret; 2.803 -} 2.804 - 2.805 -static __inline__ int HYPERVISOR_console_io(int cmd, int count, char *str) 2.806 -{ 2.807 - int ret; 2.808 - __asm__ __volatile__ ( 2.809 - TRAP_INSTR 2.810 - : "=a" (ret) : "0" (__HYPERVISOR_console_io), 2.811 - _a1 (cmd), _a2 (count), _a3 (str) : "memory" ); 2.812 - 2.813 - return ret; 2.814 -} 2.815 - 2.816 #endif /* __HYPERVISOR_H__ */
3.1 --- a/extras/mini-os/include/os.h Sun Oct 30 13:52:38 2005 +0100 3.2 +++ b/extras/mini-os/include/os.h Sun Oct 30 14:00:35 2005 +0100 3.3 @@ -24,7 +24,7 @@ 3.4 #include <xen/xen.h> 3.5 3.6 3.7 -#define force_evtchn_callback() ((void)HYPERVISOR_xen_version(0)) 3.8 +#define force_evtchn_callback() ((void)HYPERVISOR_xen_version(0, 0)) 3.9 3.10 #define __KERNEL_CS FLAT_KERNEL_CS 3.11 #define __KERNEL_DS FLAT_KERNEL_DS 3.12 @@ -55,6 +55,8 @@ 3.13 /* Everything below this point is not included by assembler (.S) files. */ 3.14 #ifndef __ASSEMBLY__ 3.15 3.16 +extern shared_info_t *HYPERVISOR_shared_info; 3.17 + 3.18 void trap_init(void); 3.19 3.20 /*
4.1 --- a/extras/mini-os/include/types.h Sun Oct 30 13:52:38 2005 +0100 4.2 +++ b/extras/mini-os/include/types.h Sun Oct 30 14:00:35 2005 +0100 4.3 @@ -54,7 +54,14 @@ typedef unsigned long uintptr_t; 4.4 typedef struct { unsigned long pte; } pte_t; 4.5 #endif 4.6 4.7 - 4.8 +typedef u8 uint8_t; 4.9 +typedef s8 int8_t; 4.10 +typedef u16 uint16_t; 4.11 +typedef s16 int16_t; 4.12 +typedef u32 uint32_t; 4.13 +typedef s32 int32_t; 4.14 +typedef u64 uint64_t; 4.15 +typedef s64 int64_t; 4.16 4.17 4.18 #define INT_MAX ((int)(~0U>>1))
5.1 --- a/extras/mini-os/kernel.c Sun Oct 30 13:52:38 2005 +0100 5.2 +++ b/extras/mini-os/kernel.c Sun Oct 30 14:00:35 2005 +0100 5.3 @@ -61,7 +61,7 @@ void failsafe_callback(void); 5.4 5.5 extern char shared_info[PAGE_SIZE]; 5.6 5.7 -#define __pte(x) ((pte_t) { (0) } ) 5.8 +#define __pte(x) ((pte_t) { (x) } ) 5.9 5.10 static shared_info_t *map_shared_info(unsigned long pa) 5.11 { 5.12 @@ -150,5 +150,5 @@ void start_kernel(start_info_t *si) 5.13 void do_exit(void) 5.14 { 5.15 printk("do_exit called!\n"); 5.16 - for ( ;; ) HYPERVISOR_shutdown(); 5.17 + for ( ;; ) HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_crash); 5.18 }
6.1 --- a/extras/mini-os/time.c Sun Oct 30 13:52:38 2005 +0100 6.2 +++ b/extras/mini-os/time.c Sun Oct 30 14:00:35 2005 +0100 6.3 @@ -208,7 +208,7 @@ void block_domain(u32 millisecs) 6.4 struct timeval tv; 6.5 gettimeofday(&tv); 6.6 HYPERVISOR_set_timer_op(monotonic_clock() + 1000000LL * (s64) millisecs); 6.7 - HYPERVISOR_block(); 6.8 + HYPERVISOR_sched_op(SCHEDOP_block, 0); 6.9 } 6.10 6.11
7.1 --- a/extras/mini-os/xenbus/xenbus_xs.c Sun Oct 30 13:52:38 2005 +0100 7.2 +++ b/extras/mini-os/xenbus/xenbus_xs.c Sun Oct 30 14:00:35 2005 +0100 7.3 @@ -39,7 +39,7 @@ 7.4 #include <wait.h> 7.5 #include <sched.h> 7.6 #include <semaphore.h> 7.7 -#include "xenstored.h" 7.8 +#include <xen/io/xs_wire.h> 7.9 #include "xenbus_comms.h" 7.10 7.11 #define streq(a, b) (strcmp((a), (b)) == 0) 7.12 @@ -408,7 +408,12 @@ static char *xs_read_watch(char **token) 7.13 7.14 static int xs_acknowledge_watch(const char *token) 7.15 { 7.16 +#if 0 7.17 return xs_error(xs_single(XS_WATCH_ACK, token, NULL)); 7.18 +#else 7.19 + /* XS_WATCH_ACK is no longer available */ 7.20 + return 0; 7.21 +#endif 7.22 } 7.23 7.24 static int xs_unwatch(const char *path, const char *token)
8.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c Sun Oct 30 13:52:38 2005 +0100 8.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c Sun Oct 30 14:00:35 2005 +0100 8.3 @@ -29,7 +29,7 @@ unsigned int bind_virq_to_evtchn(int vir 8.4 return op.u.bind_virq.port; 8.5 } 8.6 8.7 -int bind_virq_to_irq(int virq) 8.8 +int bind_virq_to_irq(int virq, int cpu) 8.9 { 8.10 printk("bind_virq_to_irq called... FIXME??\n"); 8.11 while(1); 8.12 @@ -66,7 +66,11 @@ int bind_evtchn_to_irqhandler(unsigned i 8.13 evtchns[evtchn].handler = handler; 8.14 evtchns[evtchn].dev_id = dev_id; 8.15 unmask_evtchn(evtchn); 8.16 - return 0; 8.17 + //return 0; 8.18 + /* On ia64, there's only one irq vector allocated for all event channels, 8.19 + * so let's just return evtchn as handle for later communication 8.20 + */ 8.21 + return evtchn; 8.22 } 8.23 8.24 void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id)
9.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S Sun Oct 30 13:52:38 2005 +0100 9.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S Sun Oct 30 14:00:35 2005 +0100 9.3 @@ -46,8 +46,6 @@ GLOBAL_ENTRY(ia64_switch_to) 9.4 .prologue 9.5 alloc r16=ar.pfs,1,0,0,0 9.6 #endif 9.7 - .prologue 9.8 - alloc r16=ar.pfs,1,0,0,0 9.9 DO_SAVE_SWITCH_STACK 9.10 .body 9.11
10.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Sun Oct 30 13:52:38 2005 +0100 10.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Sun Oct 30 14:00:35 2005 +0100 10.3 @@ -653,7 +653,7 @@ ENTRY(simd_coprocessor_error) 10.4 ENTRY(device_not_available) 10.5 pushl $-1 # mark this as an int 10.6 SAVE_ALL 10.7 - preempt_stop 10.8 + #preempt_stop /* This is already an interrupt gate on Xen. */ 10.9 call math_state_restore 10.10 jmp ret_from_exception 10.11
11.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c Sun Oct 30 13:52:38 2005 +0100 11.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c Sun Oct 30 14:00:35 2005 +0100 11.3 @@ -483,6 +483,9 @@ struct task_struct fastcall * __switch_t 11.4 mcl->args[0] = 1; 11.5 mcl++; 11.6 } 11.7 +#if 0 /* lazy fpu sanity check */ 11.8 + else BUG_ON(!(read_cr0() & 8)); 11.9 +#endif 11.10 11.11 /* 11.12 * Reload esp0, LDT and the page table pointer:
12.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Sun Oct 30 13:52:38 2005 +0100 12.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Sun Oct 30 14:00:35 2005 +0100 12.3 @@ -648,6 +648,12 @@ fastcall void do_int3(struct pt_regs *re 12.4 } 12.5 #endif 12.6 12.7 +static inline void conditional_sti(struct pt_regs *regs) 12.8 +{ 12.9 + if ((uint8_t)(regs->xcs >> 16) == 0) 12.10 + local_irq_enable(); 12.11 +} 12.12 + 12.13 /* 12.14 * Our handling of the processor debug registers is non-trivial. 12.15 * We do not clear them on entry and exit from the kernel. Therefore 12.16 @@ -680,11 +686,9 @@ fastcall void do_debug(struct pt_regs * 12.17 if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, 12.18 SIGTRAP) == NOTIFY_STOP) 12.19 return; 12.20 -#if 0 12.21 + 12.22 /* It's safe to allow irq's after DR6 has been saved */ 12.23 - if (regs->eflags & X86_EFLAGS_IF) 12.24 - local_irq_enable(); 12.25 -#endif 12.26 + conditional_sti(regs); 12.27 12.28 /* Mask out spurious debug traps due to lazy DR7 setting */ 12.29 if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { 12.30 @@ -967,15 +971,18 @@ void __init trap_init_f00f_bug(void) 12.31 #endif 12.32 12.33 12.34 -/* NB. All these are "trap gates" (i.e. events_mask isn't cleared). */ 12.35 +/* 12.36 + * NB. All these are "trap gates" (i.e. events_mask isn't cleared) except 12.37 + * for those that specify <dpl>|4 in the second field. 12.38 + */ 12.39 static trap_info_t trap_table[] = { 12.40 { 0, 0, __KERNEL_CS, (unsigned long)divide_error }, 12.41 - { 1, 0, __KERNEL_CS, (unsigned long)debug }, 12.42 - { 3, 3, __KERNEL_CS, (unsigned long)int3 }, 12.43 + { 1, 0|4, __KERNEL_CS, (unsigned long)debug }, 12.44 + { 3, 3|4, __KERNEL_CS, (unsigned long)int3 }, 12.45 { 4, 3, __KERNEL_CS, (unsigned long)overflow }, 12.46 { 5, 3, __KERNEL_CS, (unsigned long)bounds }, 12.47 { 6, 0, __KERNEL_CS, (unsigned long)invalid_op }, 12.48 - { 7, 0, __KERNEL_CS, (unsigned long)device_not_available }, 12.49 + { 7, 0|4, __KERNEL_CS, (unsigned long)device_not_available }, 12.50 { 9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun }, 12.51 { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS }, 12.52 { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present },
13.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c Sun Oct 30 13:52:38 2005 +0100 13.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c Sun Oct 30 14:00:35 2005 +0100 13.3 @@ -733,6 +733,7 @@ void __init setup_arch(char **cmdline_p) 13.4 #ifdef CONFIG_XEN 13.5 { 13.6 int i, j, k, fpp; 13.7 + unsigned long va; 13.8 13.9 /* Make sure we have a large enough P->M table. */ 13.10 phys_to_machine_mapping = alloc_bootmem( 13.11 @@ -746,9 +747,21 @@ void __init setup_arch(char **cmdline_p) 13.12 __pa(xen_start_info->mfn_list), 13.13 PFN_PHYS(PFN_UP(xen_start_info->nr_pages * 13.14 sizeof(unsigned long)))); 13.15 - make_pages_readonly((void *)xen_start_info->mfn_list, 13.16 - PFN_UP(xen_start_info->nr_pages * 13.17 - sizeof(unsigned long))); 13.18 + 13.19 + /* 'Initial mapping' of old p2m table must be destroyed. */ 13.20 + for (va = xen_start_info->mfn_list; 13.21 + va < (xen_start_info->mfn_list + 13.22 + (xen_start_info->nr_pages*sizeof(unsigned long))); 13.23 + va += PAGE_SIZE) { 13.24 + HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0); 13.25 + } 13.26 + 13.27 + /* 'Initial mapping' of initrd must be destroyed. */ 13.28 + for (va = xen_start_info->mod_start; 13.29 + va < (xen_start_info->mod_start+xen_start_info->mod_len); 13.30 + va += PAGE_SIZE) { 13.31 + HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0); 13.32 + } 13.33 13.34 /* 13.35 * Initialise the list of the frames that specify the list of
14.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S Sun Oct 30 13:52:38 2005 +0100 14.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S Sun Oct 30 14:00:35 2005 +0100 14.3 @@ -5,7 +5,7 @@ 14.4 #define evtchn_upcall_pending 0 14.5 #define evtchn_upcall_mask 1 14.6 14.7 -#define sizeof_vcpu_shift 3 14.8 +#define sizeof_vcpu_shift 4 14.9 14.10 #ifdef CONFIG_SMP 14.11 //#define preempt_disable(reg) incl threadinfo_preempt_count(reg)
15.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Sun Oct 30 13:52:38 2005 +0100 15.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Sun Oct 30 14:00:35 2005 +0100 15.3 @@ -191,12 +191,13 @@ static int increase_reservation(unsigned 15.4 rc = HYPERVISOR_memory_op( 15.5 XENMEM_increase_reservation, &reservation); 15.6 if (rc < nr_pages) { 15.7 + int ret; 15.8 /* We hit the Xen hard limit: reprobe. */ 15.9 reservation.extent_start = mfn_list; 15.10 reservation.nr_extents = rc; 15.11 - BUG_ON(HYPERVISOR_memory_op( 15.12 - XENMEM_decrease_reservation, 15.13 - &reservation) != rc); 15.14 + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, 15.15 + &reservation); 15.16 + BUG_ON(ret != rc); 15.17 hard_limit = current_pages + rc - driver_pages; 15.18 goto out; 15.19 } 15.20 @@ -213,11 +214,14 @@ static int increase_reservation(unsigned 15.21 xen_machphys_update(mfn_list[i], pfn); 15.22 15.23 /* Link back into the page tables if not highmem. */ 15.24 - if (pfn < max_low_pfn) 15.25 - BUG_ON(HYPERVISOR_update_va_mapping( 15.26 + if (pfn < max_low_pfn) { 15.27 + int ret; 15.28 + ret = HYPERVISOR_update_va_mapping( 15.29 (unsigned long)__va(pfn << PAGE_SHIFT), 15.30 pfn_pte_ma(mfn_list[i], PAGE_KERNEL), 15.31 - 0)); 15.32 + 0); 15.33 + BUG_ON(ret); 15.34 + } 15.35 15.36 /* Relinquish the page back to the allocator. */ 15.37 ClearPageReserved(page); 15.38 @@ -242,6 +246,7 @@ static int decrease_reservation(unsigned 15.39 struct page *page; 15.40 void *v; 15.41 int need_sleep = 0; 15.42 + int ret; 15.43 struct xen_memory_reservation reservation = { 15.44 .address_bits = 0, 15.45 .extent_order = 0, 15.46 @@ -268,8 +273,9 @@ static int decrease_reservation(unsigned 15.47 if (!PageHighMem(page)) { 15.48 v = phys_to_virt(pfn << PAGE_SHIFT); 15.49 scrub_pages(v, 1); 15.50 - BUG_ON(HYPERVISOR_update_va_mapping( 15.51 - (unsigned long)v, __pte_ma(0), 0)); 15.52 + ret = HYPERVISOR_update_va_mapping( 15.53 + (unsigned long)v, __pte_ma(0), 0); 15.54 + BUG_ON(ret); 15.55 } 15.56 #ifdef CONFIG_XEN_SCRUB_PAGES 15.57 else { 15.58 @@ -295,8 +301,8 @@ static int decrease_reservation(unsigned 15.59 15.60 reservation.extent_start = mfn_list; 15.61 reservation.nr_extents = nr_pages; 15.62 - BUG_ON(HYPERVISOR_memory_op( 15.63 - XENMEM_decrease_reservation, &reservation) != nr_pages); 15.64 + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); 15.65 + BUG_ON(ret != nr_pages); 15.66 15.67 current_pages -= nr_pages; 15.68 totalram_pages = current_pages; 15.69 @@ -501,6 +507,7 @@ static int dealloc_pte_fn( 15.70 pte_t *pte, struct page *pte_page, unsigned long addr, void *data) 15.71 { 15.72 unsigned long mfn = pte_mfn(*pte); 15.73 + int ret; 15.74 struct xen_memory_reservation reservation = { 15.75 .extent_start = &mfn, 15.76 .nr_extents = 1, 15.77 @@ -510,8 +517,8 @@ static int dealloc_pte_fn( 15.78 set_pte_at(&init_mm, addr, pte, __pte_ma(0)); 15.79 phys_to_machine_mapping[__pa(addr) >> PAGE_SHIFT] = 15.80 INVALID_P2M_ENTRY; 15.81 - BUG_ON(HYPERVISOR_memory_op( 15.82 - XENMEM_decrease_reservation, &reservation) != 1); 15.83 + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); 15.84 + BUG_ON(ret != 1); 15.85 return 0; 15.86 } 15.87 15.88 @@ -519,6 +526,7 @@ struct page *balloon_alloc_empty_page_ra 15.89 { 15.90 unsigned long vstart, flags; 15.91 unsigned int order = get_order(nr_pages * PAGE_SIZE); 15.92 + int ret; 15.93 15.94 vstart = __get_free_pages(GFP_KERNEL, order); 15.95 if (vstart == 0) 15.96 @@ -527,8 +535,9 @@ struct page *balloon_alloc_empty_page_ra 15.97 scrub_pages(vstart, 1 << order); 15.98 15.99 balloon_lock(flags); 15.100 - BUG_ON(generic_page_range( 15.101 - &init_mm, vstart, PAGE_SIZE << order, dealloc_pte_fn, NULL)); 15.102 + ret = generic_page_range( 15.103 + &init_mm, vstart, PAGE_SIZE << order, dealloc_pte_fn, NULL); 15.104 + BUG_ON(ret); 15.105 current_pages -= 1UL << order; 15.106 balloon_unlock(flags); 15.107
16.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Sun Oct 30 13:52:38 2005 +0100 16.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Sun Oct 30 14:00:35 2005 +0100 16.3 @@ -108,6 +108,7 @@ static void fast_flush_area(int idx, int 16.4 struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; 16.5 unsigned int i, invcount = 0; 16.6 u16 handle; 16.7 + int ret; 16.8 16.9 for (i = 0; i < nr_pages; i++) { 16.10 handle = pending_handle(idx, i); 16.11 @@ -120,8 +121,9 @@ static void fast_flush_area(int idx, int 16.12 invcount++; 16.13 } 16.14 16.15 - BUG_ON(HYPERVISOR_grant_table_op( 16.16 - GNTTABOP_unmap_grant_ref, unmap, invcount)); 16.17 + ret = HYPERVISOR_grant_table_op( 16.18 + GNTTABOP_unmap_grant_ref, unmap, invcount); 16.19 + BUG_ON(ret); 16.20 } 16.21 16.22 16.23 @@ -338,6 +340,7 @@ static void dispatch_rw_block_io(blkif_t 16.24 struct bio *bio = NULL, *biolist[BLKIF_MAX_SEGMENTS_PER_REQUEST]; 16.25 int nbio = 0; 16.26 request_queue_t *q; 16.27 + int ret; 16.28 16.29 /* Check that number of segments is sane. */ 16.30 nseg = req->nr_segments; 16.31 @@ -367,8 +370,8 @@ static void dispatch_rw_block_io(blkif_t 16.32 map[i].flags |= GNTMAP_readonly; 16.33 } 16.34 16.35 - BUG_ON(HYPERVISOR_grant_table_op( 16.36 - GNTTABOP_map_grant_ref, map, nseg)); 16.37 + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg); 16.38 + BUG_ON(ret); 16.39 16.40 for (i = 0; i < nseg; i++) { 16.41 if (unlikely(map[i].handle < 0)) { 16.42 @@ -493,6 +496,7 @@ static int __init blkif_init(void) 16.43 { 16.44 int i; 16.45 struct page *page; 16.46 + int ret; 16.47 16.48 blkif_interface_init(); 16.49 16.50 @@ -509,7 +513,8 @@ static int __init blkif_init(void) 16.51 spin_lock_init(&blkio_schedule_list_lock); 16.52 INIT_LIST_HEAD(&blkio_schedule_list); 16.53 16.54 - BUG_ON(kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES) < 0); 16.55 + ret = kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES); 16.56 + BUG_ON(ret < 0); 16.57 16.58 blkif_xenbus_init(); 16.59
17.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Sun Oct 30 13:52:38 2005 +0100 17.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Sun Oct 30 14:00:35 2005 +0100 17.3 @@ -31,6 +31,7 @@ blkif_t *alloc_blkif(domid_t domid) 17.4 static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) 17.5 { 17.6 struct gnttab_map_grant_ref op; 17.7 + int ret; 17.8 17.9 op.host_addr = (unsigned long)blkif->blk_ring_area->addr; 17.10 op.flags = GNTMAP_host_map; 17.11 @@ -38,8 +39,9 @@ static int map_frontend_page(blkif_t *bl 17.12 op.dom = blkif->domid; 17.13 17.14 lock_vm_area(blkif->blk_ring_area); 17.15 - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)); 17.16 + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); 17.17 unlock_vm_area(blkif->blk_ring_area); 17.18 + BUG_ON(ret); 17.19 17.20 if (op.handle < 0) { 17.21 DPRINTK(" Grant table operation failure !\n"); 17.22 @@ -55,14 +57,16 @@ static int map_frontend_page(blkif_t *bl 17.23 static void unmap_frontend_page(blkif_t *blkif) 17.24 { 17.25 struct gnttab_unmap_grant_ref op; 17.26 + int ret; 17.27 17.28 op.host_addr = (unsigned long)blkif->blk_ring_area->addr; 17.29 op.handle = blkif->shmem_handle; 17.30 op.dev_bus_addr = 0; 17.31 17.32 lock_vm_area(blkif->blk_ring_area); 17.33 - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); 17.34 + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); 17.35 unlock_vm_area(blkif->blk_ring_area); 17.36 + BUG_ON(ret); 17.37 } 17.38 17.39 int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
18.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Sun Oct 30 13:52:38 2005 +0100 18.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Sun Oct 30 14:00:35 2005 +0100 18.3 @@ -305,6 +305,7 @@ static irqreturn_t blkif_int(int irq, vo 18.4 18.5 for (i = info->ring.rsp_cons; i != rp; i++) { 18.6 unsigned long id; 18.7 + int ret; 18.8 18.9 bret = RING_GET_RESPONSE(&info->ring, i); 18.10 id = bret->id; 18.11 @@ -321,9 +322,10 @@ static irqreturn_t blkif_int(int irq, vo 18.12 DPRINTK("Bad return from blkdev data " 18.13 "request: %x\n", bret->status); 18.14 18.15 - BUG_ON(end_that_request_first( 18.16 + ret = end_that_request_first( 18.17 req, (bret->status == BLKIF_RSP_OKAY), 18.18 - req->hard_nr_sectors)); 18.19 + req->hard_nr_sectors); 18.20 + BUG_ON(ret); 18.21 end_that_request_last(req); 18.22 break; 18.23 default:
19.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Sun Oct 30 13:52:38 2005 +0100 19.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Sun Oct 30 14:00:35 2005 +0100 19.3 @@ -413,6 +413,7 @@ static void fast_flush_area(int idx, int 19.4 unsigned int i, op = 0; 19.5 struct grant_handle_pair *handle; 19.6 unsigned long ptep; 19.7 + int ret; 19.8 19.9 for ( i = 0; i < nr_pages; i++) 19.10 { 19.11 @@ -440,8 +441,8 @@ static void fast_flush_area(int idx, int 19.12 BLKTAP_INVALIDATE_HANDLE(handle); 19.13 } 19.14 19.15 - BUG_ON(HYPERVISOR_grant_table_op( 19.16 - GNTTABOP_unmap_grant_ref, unmap, op)); 19.17 + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap, op); 19.18 + BUG_ON(ret); 19.19 19.20 if (blktap_vma != NULL) 19.21 zap_page_range(blktap_vma, 19.22 @@ -673,6 +674,7 @@ static void dispatch_rw_block_io(blkif_t 19.23 struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST*2]; 19.24 int op, ret; 19.25 unsigned int nseg; 19.26 + int retval; 19.27 19.28 /* Check that number of segments is sane. */ 19.29 nseg = req->nr_segments; 19.30 @@ -740,8 +742,8 @@ static void dispatch_rw_block_io(blkif_t 19.31 op++; 19.32 } 19.33 19.34 - BUG_ON(HYPERVISOR_grant_table_op( 19.35 - GNTTABOP_map_grant_ref, map, op)); 19.36 + retval = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, op); 19.37 + BUG_ON(retval); 19.38 19.39 op = 0; 19.40 for (i = 0; i < (req->nr_segments*2); i += 2) { 19.41 @@ -877,7 +879,8 @@ static int __init blkif_init(void) 19.42 spin_lock_init(&blkio_schedule_list_lock); 19.43 INIT_LIST_HEAD(&blkio_schedule_list); 19.44 19.45 - BUG_ON(kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES) < 0); 19.46 + i = kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES); 19.47 + BUG_ON(i<0); 19.48 19.49 blkif_xenbus_init(); 19.50
20.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Sun Oct 30 13:52:38 2005 +0100 20.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Sun Oct 30 14:00:35 2005 +0100 20.3 @@ -31,6 +31,7 @@ blkif_t *alloc_blkif(domid_t domid) 20.4 static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) 20.5 { 20.6 struct gnttab_map_grant_ref op; 20.7 + int ret; 20.8 20.9 op.host_addr = (unsigned long)blkif->blk_ring_area->addr; 20.10 op.flags = GNTMAP_host_map; 20.11 @@ -38,8 +39,9 @@ static int map_frontend_page(blkif_t *bl 20.12 op.dom = blkif->domid; 20.13 20.14 lock_vm_area(blkif->blk_ring_area); 20.15 - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)); 20.16 + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); 20.17 unlock_vm_area(blkif->blk_ring_area); 20.18 + BUG_ON(ret); 20.19 20.20 if (op.handle < 0) { 20.21 DPRINTK(" Grant table operation failure !\n"); 20.22 @@ -55,14 +57,16 @@ static int map_frontend_page(blkif_t *bl 20.23 static void unmap_frontend_page(blkif_t *blkif) 20.24 { 20.25 struct gnttab_unmap_grant_ref op; 20.26 + int ret; 20.27 20.28 op.host_addr = (unsigned long)blkif->blk_ring_area->addr; 20.29 op.handle = blkif->shmem_handle; 20.30 op.dev_bus_addr = 0; 20.31 20.32 lock_vm_area(blkif->blk_ring_area); 20.33 - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); 20.34 + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); 20.35 unlock_vm_area(blkif->blk_ring_area); 20.36 + BUG_ON(ret); 20.37 } 20.38 20.39 int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
21.1 --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Sun Oct 30 13:52:38 2005 +0100 21.2 +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Sun Oct 30 14:00:35 2005 +0100 21.3 @@ -282,6 +282,7 @@ static int evtchn_ioctl(struct inode *in 21.4 21.5 case IOCTL_EVTCHN_UNBIND: { 21.6 struct ioctl_evtchn_unbind unbind; 21.7 + int ret; 21.8 21.9 rc = -EFAULT; 21.10 if (copy_from_user(&unbind, (void *)arg, sizeof(unbind))) 21.11 @@ -306,7 +307,8 @@ static int evtchn_ioctl(struct inode *in 21.12 21.13 op.cmd = EVTCHNOP_close; 21.14 op.u.close.port = unbind.port; 21.15 - BUG_ON(HYPERVISOR_event_channel_op(&op)); 21.16 + ret = HYPERVISOR_event_channel_op(&op); 21.17 + BUG_ON(ret); 21.18 21.19 rc = 0; 21.20 break; 21.21 @@ -399,6 +401,7 @@ static int evtchn_release(struct inode * 21.22 21.23 for (i = 0; i < NR_EVENT_CHANNELS; i++) 21.24 { 21.25 + int ret; 21.26 if (port_user[i] != u) 21.27 continue; 21.28 21.29 @@ -407,7 +410,8 @@ static int evtchn_release(struct inode * 21.30 21.31 op.cmd = EVTCHNOP_close; 21.32 op.u.close.port = i; 21.33 - BUG_ON(HYPERVISOR_event_channel_op(&op)); 21.34 + ret = HYPERVISOR_event_channel_op(&op); 21.35 + BUG_ON(ret); 21.36 } 21.37 21.38 spin_unlock_irq(&port_user_lock);
22.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Sun Oct 30 13:52:38 2005 +0100 22.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Sun Oct 30 14:00:35 2005 +0100 22.3 @@ -115,6 +115,7 @@ static int map_frontend_pages( 22.4 netif_t *netif, grant_ref_t tx_ring_ref, grant_ref_t rx_ring_ref) 22.5 { 22.6 struct gnttab_map_grant_ref op; 22.7 + int ret; 22.8 22.9 op.host_addr = (unsigned long)netif->comms_area->addr; 22.10 op.flags = GNTMAP_host_map; 22.11 @@ -122,8 +123,9 @@ static int map_frontend_pages( 22.12 op.dom = netif->domid; 22.13 22.14 lock_vm_area(netif->comms_area); 22.15 - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)); 22.16 + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); 22.17 unlock_vm_area(netif->comms_area); 22.18 + BUG_ON(ret); 22.19 22.20 if (op.handle < 0) { 22.21 DPRINTK(" Gnttab failure mapping tx_ring_ref!\n"); 22.22 @@ -139,8 +141,9 @@ static int map_frontend_pages( 22.23 op.dom = netif->domid; 22.24 22.25 lock_vm_area(netif->comms_area); 22.26 - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)); 22.27 + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); 22.28 unlock_vm_area(netif->comms_area); 22.29 + BUG_ON(ret); 22.30 22.31 if (op.handle < 0) { 22.32 DPRINTK(" Gnttab failure mapping rx_ring_ref!\n"); 22.33 @@ -156,22 +159,25 @@ static int map_frontend_pages( 22.34 static void unmap_frontend_pages(netif_t *netif) 22.35 { 22.36 struct gnttab_unmap_grant_ref op; 22.37 + int ret; 22.38 22.39 op.host_addr = (unsigned long)netif->comms_area->addr; 22.40 op.handle = netif->tx_shmem_handle; 22.41 op.dev_bus_addr = 0; 22.42 22.43 lock_vm_area(netif->comms_area); 22.44 - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); 22.45 + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); 22.46 unlock_vm_area(netif->comms_area); 22.47 + BUG_ON(ret); 22.48 22.49 op.host_addr = (unsigned long)netif->comms_area->addr + PAGE_SIZE; 22.50 op.handle = netif->rx_shmem_handle; 22.51 op.dev_bus_addr = 0; 22.52 22.53 lock_vm_area(netif->comms_area); 22.54 - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); 22.55 + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); 22.56 unlock_vm_area(netif->comms_area); 22.57 + BUG_ON(ret); 22.58 } 22.59 22.60 int netif_map(netif_t *netif, unsigned long tx_ring_ref,
23.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Sun Oct 30 13:52:38 2005 +0100 23.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Sun Oct 30 14:00:35 2005 +0100 23.3 @@ -112,9 +112,12 @@ static void free_mfn(unsigned long mfn) 23.4 spin_lock_irqsave(&mfn_lock, flags); 23.5 if ( alloc_index != MAX_MFN_ALLOC ) 23.6 mfn_list[alloc_index++] = mfn; 23.7 - else 23.8 - BUG_ON(HYPERVISOR_memory_op(XENMEM_decrease_reservation, 23.9 - &reservation) != 1); 23.10 + else { 23.11 + int ret; 23.12 + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, 23.13 + &reservation); 23.14 + BUG_ON(ret != 1); 23.15 + } 23.16 spin_unlock_irqrestore(&mfn_lock, flags); 23.17 } 23.18 #endif 23.19 @@ -159,13 +162,15 @@ int netif_be_start_xmit(struct sk_buff * 23.20 */ 23.21 if (skb_shared(skb) || skb_cloned(skb) || !is_xen_skb(skb)) { 23.22 int hlen = skb->data - skb->head; 23.23 + int ret; 23.24 struct sk_buff *nskb = dev_alloc_skb(hlen + skb->len); 23.25 if ( unlikely(nskb == NULL) ) 23.26 goto drop; 23.27 skb_reserve(nskb, hlen); 23.28 __skb_put(nskb, skb->len); 23.29 - BUG_ON(skb_copy_bits(skb, -hlen, nskb->data - hlen, 23.30 - skb->len + hlen)); 23.31 + ret = skb_copy_bits(skb, -hlen, nskb->data - hlen, 23.32 + skb->len + hlen); 23.33 + BUG_ON(ret); 23.34 nskb->dev = skb->dev; 23.35 nskb->proto_csum_valid = skb->proto_csum_valid; 23.36 dev_kfree_skb(skb); 23.37 @@ -218,6 +223,7 @@ static void net_rx_action(unsigned long 23.38 struct sk_buff *skb; 23.39 u16 notify_list[NETIF_RX_RING_SIZE]; 23.40 int notify_nr = 0; 23.41 + int ret; 23.42 23.43 skb_queue_head_init(&rxq); 23.44 23.45 @@ -279,7 +285,8 @@ static void net_rx_action(unsigned long 23.46 mcl++; 23.47 23.48 mcl[-2].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; 23.49 - BUG_ON(HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl) != 0); 23.50 + ret = HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl); 23.51 + BUG_ON(ret != 0); 23.52 23.53 mcl = rx_mcl; 23.54 if( HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, 23.55 @@ -421,6 +428,7 @@ inline static void net_tx_action_dealloc 23.56 u16 pending_idx; 23.57 PEND_RING_IDX dc, dp; 23.58 netif_t *netif; 23.59 + int ret; 23.60 23.61 dc = dealloc_cons; 23.62 dp = dealloc_prod; 23.63 @@ -436,8 +444,9 @@ inline static void net_tx_action_dealloc 23.64 gop->handle = grant_tx_ref[pending_idx]; 23.65 gop++; 23.66 } 23.67 - BUG_ON(HYPERVISOR_grant_table_op( 23.68 - GNTTABOP_unmap_grant_ref, tx_unmap_ops, gop - tx_unmap_ops)); 23.69 + ret = HYPERVISOR_grant_table_op( 23.70 + GNTTABOP_unmap_grant_ref, tx_unmap_ops, gop - tx_unmap_ops); 23.71 + BUG_ON(ret); 23.72 23.73 while (dealloc_cons != dp) { 23.74 pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)]; 23.75 @@ -477,6 +486,7 @@ static void net_tx_action(unsigned long 23.76 NETIF_RING_IDX i; 23.77 gnttab_map_grant_ref_t *mop; 23.78 unsigned int data_len; 23.79 + int ret; 23.80 23.81 if (dealloc_cons != dealloc_prod) 23.82 net_tx_action_dealloc(); 23.83 @@ -599,8 +609,9 @@ static void net_tx_action(unsigned long 23.84 if (mop == tx_map_ops) 23.85 return; 23.86 23.87 - BUG_ON(HYPERVISOR_grant_table_op( 23.88 - GNTTABOP_map_grant_ref, tx_map_ops, mop - tx_map_ops)); 23.89 + ret = HYPERVISOR_grant_table_op( 23.90 + GNTTABOP_map_grant_ref, tx_map_ops, mop - tx_map_ops); 23.91 + BUG_ON(ret); 23.92 23.93 mop = tx_map_ops; 23.94 while ((skb = __skb_dequeue(&tx_queue)) != NULL) {
24.1 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Sun Oct 30 13:52:38 2005 +0100 24.2 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Sun Oct 30 14:00:35 2005 +0100 24.3 @@ -25,8 +25,8 @@ 24.4 #include <asm/pgtable.h> 24.5 #include <asm/uaccess.h> 24.6 #include <asm/tlb.h> 24.7 +#include <asm/hypervisor.h> 24.8 #include <asm-xen/linux-public/privcmd.h> 24.9 -#include <asm/hypervisor.h> 24.10 #include <asm-xen/xen-public/xen.h> 24.11 #include <asm-xen/xen-public/dom0_ops.h> 24.12 #include <asm-xen/xen_proc.h>
25.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Sun Oct 30 13:52:38 2005 +0100 25.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Sun Oct 30 14:00:35 2005 +0100 25.3 @@ -78,6 +78,7 @@ tpmif_find(domid_t domid, long int insta 25.4 static int 25.5 map_frontend_page(tpmif_t *tpmif, unsigned long shared_page) 25.6 { 25.7 + int ret; 25.8 struct gnttab_map_grant_ref op = { 25.9 .host_addr = (unsigned long)tpmif->tx_area->addr, 25.10 .flags = GNTMAP_host_map, 25.11 @@ -86,8 +87,9 @@ map_frontend_page(tpmif_t *tpmif, unsign 25.12 }; 25.13 25.14 lock_vm_area(tpmif->tx_area); 25.15 - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)); 25.16 + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); 25.17 unlock_vm_area(tpmif->tx_area); 25.18 + BUG_ON(ret); 25.19 25.20 if (op.handle < 0) { 25.21 DPRINTK(" Grant table operation failure !\n"); 25.22 @@ -104,14 +106,16 @@ static void 25.23 unmap_frontend_page(tpmif_t *tpmif) 25.24 { 25.25 struct gnttab_unmap_grant_ref op; 25.26 + int ret; 25.27 25.28 op.host_addr = (unsigned long)tpmif->tx_area->addr; 25.29 op.handle = tpmif->shmem_handle; 25.30 op.dev_bus_addr = 0; 25.31 25.32 lock_vm_area(tpmif->tx_area); 25.33 - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); 25.34 + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); 25.35 unlock_vm_area(tpmif->tx_area); 25.36 + BUG_ON(ret); 25.37 } 25.38 25.39 int
26.1 --- a/linux-2.6-xen-sparse/drivers/xen/util.c Sun Oct 30 13:52:38 2005 +0100 26.2 +++ b/linux-2.6-xen-sparse/drivers/xen/util.c Sun Oct 30 14:00:35 2005 +0100 26.3 @@ -34,7 +34,9 @@ struct vm_struct *alloc_vm_area(unsigned 26.4 26.5 void free_vm_area(struct vm_struct *area) 26.6 { 26.7 - BUG_ON(remove_vm_area(area->addr) != area); 26.8 + struct vm_struct *ret; 26.9 + ret = remove_vm_area(area->addr); 26.10 + BUG_ON(ret != area); 26.11 kfree(area); 26.12 } 26.13
27.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Sun Oct 30 13:52:38 2005 +0100 27.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Sun Oct 30 14:00:35 2005 +0100 27.3 @@ -714,11 +714,7 @@ static int xsd_port_read(char *page, cha 27.4 27.5 static int __init xenbus_probe_init(void) 27.6 { 27.7 - int err = 0; 27.8 - /* 27.9 - ** Domain0 doesn't have a store_evtchn or store_mfn yet. 27.10 - */ 27.11 - int dom0 = (xen_start_info->store_evtchn == 0); 27.12 + int err = 0, dom0; 27.13 27.14 printk("xenbus_probe_init\n"); 27.15 27.16 @@ -733,10 +729,16 @@ static int __init xenbus_probe_init(void 27.17 device_register(&xenbus_frontend.dev); 27.18 device_register(&xenbus_backend.dev); 27.19 27.20 + /* 27.21 + ** Domain0 doesn't have a store_evtchn or store_mfn yet. 27.22 + */ 27.23 + dom0 = (xen_start_info->store_evtchn == 0); 27.24 + 27.25 if (dom0) { 27.26 27.27 unsigned long page; 27.28 evtchn_op_t op = { 0 }; 27.29 + int ret; 27.30 27.31 27.32 /* Allocate page. */ 27.33 @@ -757,7 +759,8 @@ static int __init xenbus_probe_init(void 27.34 op.u.alloc_unbound.dom = DOMID_SELF; 27.35 op.u.alloc_unbound.remote_dom = 0; 27.36 27.37 - BUG_ON(HYPERVISOR_event_channel_op(&op)); 27.38 + ret = HYPERVISOR_event_channel_op(&op); 27.39 + BUG_ON(ret); 27.40 xen_start_info->store_evtchn = op.u.alloc_unbound.port; 27.41 27.42 /* And finally publish the above info in /proc/xen */
28.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Sun Oct 30 13:52:38 2005 +0100 28.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Sun Oct 30 14:00:35 2005 +0100 28.3 @@ -28,6 +28,7 @@ 28.4 * IN THE SOFTWARE. 28.5 */ 28.6 28.7 +#include <linux/unistd.h> 28.8 #include <linux/errno.h> 28.9 #include <linux/types.h> 28.10 #include <linux/uio.h>
29.1 --- a/tools/examples/Makefile Sun Oct 30 13:52:38 2005 +0100 29.2 +++ b/tools/examples/Makefile Sun Oct 30 14:00:35 2005 +0100 29.3 @@ -17,6 +17,7 @@ XEN_CONFIGS = xend-config.sxp 29.4 XEN_CONFIGS += xmexample1 29.5 XEN_CONFIGS += xmexample2 29.6 XEN_CONFIGS += xmexample.vmx 29.7 +XEN_CONFIGS += xmexample.vti 29.8 29.9 # Xen script dir and scripts to go there. 29.10 XEN_SCRIPT_DIR = /etc/xen/scripts
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/tools/examples/xmexample.vti Sun Oct 30 14:00:35 2005 +0100 30.3 @@ -0,0 +1,100 @@ 30.4 +# -*- mode: python; -*- 30.5 +#============================================================================ 30.6 +# Python configuration setup for 'xm create'. 30.7 +# This script sets the parameters used when a domain is created using 'xm create'. 30.8 +# You use a separate script for each domain you want to create, or 30.9 +# you can set the parameters for the domain on the xm command line. 30.10 +#============================================================================ 30.11 + 30.12 +import os, re 30.13 +arch = os.uname()[4] 30.14 +arch_libdir = 'lib' 30.15 + 30.16 +#---------------------------------------------------------------------------- 30.17 +# Kernel image file. 30.18 +kernel = "/boot/Flash.fd" 30.19 + 30.20 +# The domain build function. VMX domain uses 'vmx'. 30.21 +builder='vmx' 30.22 + 30.23 +# Initial memory allocation (in megabytes) for the new domain. 30.24 +memory = 256 30.25 + 30.26 +# A name for your domain. All domains must have different names. 30.27 +name = "ExampleVMXDomain" 30.28 + 30.29 +# Which CPU to start domain on? 30.30 +#cpu = -1 # leave to Xen to pick 30.31 + 30.32 +# Optionally define mac and/or bridge for the network interfaces. 30.33 +# Random MACs are assigned if not given. 30.34 +#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ] 30.35 + 30.36 +#---------------------------------------------------------------------------- 30.37 +# Define the disk devices you want the domain to have access to, and 30.38 +# what you want them accessible as. 30.39 +# Each disk entry is of the form phy:UNAME,DEV,MODE 30.40 +# where UNAME is the device, DEV is the device name the domain will see, 30.41 +# and MODE is r for read-only, w for read-write. 30.42 + 30.43 +#disk = [ 'phy:hda1,hda1,r' ] 30.44 +disk = [ 'file:/var/images/xenia64.img,ioemu:hda,w' ] 30.45 + 30.46 +#---------------------------------------------------------------------------- 30.47 +# Set according to whether you want the domain restarted when it exits. 30.48 +# The default is 'onreboot', which restarts the domain when it shuts down 30.49 +# with exit code reboot. 30.50 +# Other values are 'always', and 'never'. 30.51 + 30.52 +#restart = 'onreboot' 30.53 + 30.54 +#============================================================================ 30.55 + 30.56 +# New stuff 30.57 +device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm.debug' 30.58 + 30.59 +# Advanced users only. Don't touch if you don't know what you're doing 30.60 +memmap = '/usr/lib/xen/boot/mem-map.sxp' 30.61 + 30.62 +#----------------------------------------------------------------------------- 30.63 +# Disk image for 30.64 +#cdrom= 30.65 + 30.66 +#----------------------------------------------------------------------------- 30.67 +# boot on floppy (a), hard disk (c) or CD-ROM (d) 30.68 +#boot=[a|c|d] 30.69 +#----------------------------------------------------------------------------- 30.70 +# write to temporary files instead of disk image files 30.71 +#snapshot=1 30.72 + 30.73 +#---------------------------------------------------------------------------- 30.74 +# enable SDL library for graphics, default = 0 30.75 +sdl=1 30.76 + 30.77 +stdvga=1 30.78 +#---------------------------------------------------------------------------- 30.79 +# enable VNC library for graphics, default = 1 30.80 +vnc=0 30.81 + 30.82 +#---------------------------------------------------------------------------- 30.83 +# enable spawning vncviewer(only valid when vnc=1), default = 1 30.84 +vncviewer=0 30.85 + 30.86 +#---------------------------------------------------------------------------- 30.87 +# no graphics, use serial port 30.88 +#nographic=0 30.89 + 30.90 + 30.91 +#----------------------------------------------------------------------------- 30.92 +# enable audio support 30.93 +#enable-audio=1 30.94 + 30.95 + 30.96 +#----------------------------------------------------------------------------- 30.97 +# set the real time clock to local time [default=0 i.e. set to utc] 30.98 +#localtime=1 30.99 + 30.100 + 30.101 +#----------------------------------------------------------------------------- 30.102 +# start in full screen 30.103 +#full-screen=1 diff -r 42cab8724273 tools/libxc/xc_ia64_stubs.c
31.1 --- a/tools/ioemu/hw/ide.c Sun Oct 30 13:52:38 2005 +0100 31.2 +++ b/tools/ioemu/hw/ide.c Sun Oct 30 14:00:35 2005 +0100 31.3 @@ -22,6 +22,7 @@ 31.4 * THE SOFTWARE. 31.5 */ 31.6 #include "vl.h" 31.7 +#include <pthread.h> 31.8 31.9 /* debug IDE devices */ 31.10 //#define DEBUG_IDE 31.11 @@ -360,6 +361,48 @@ typedef struct PCIIDEState { 31.12 BMDMAState bmdma[2]; 31.13 } PCIIDEState; 31.14 31.15 +#define DMA_MULTI_THREAD 31.16 + 31.17 +#ifdef DMA_MULTI_THREAD 31.18 + 31.19 +static int file_pipes[2]; 31.20 + 31.21 +static void ide_dma_loop(BMDMAState *bm); 31.22 +static void dma_thread_loop(BMDMAState *bm); 31.23 + 31.24 +static void *dma_thread_func(void* opaque) 31.25 +{ 31.26 + BMDMAState* req; 31.27 + 31.28 + while (read(file_pipes[0], &req, sizeof(req))) { 31.29 + dma_thread_loop(req); 31.30 + } 31.31 + 31.32 + return NULL; 31.33 +} 31.34 + 31.35 +static void dma_create_thread() 31.36 +{ 31.37 + pthread_t tid; 31.38 + int rt; 31.39 + 31.40 + if (pipe(file_pipes) != 0){ 31.41 + fprintf(stderr, "create pipe failed\n"); 31.42 + exit(1); 31.43 + } 31.44 + 31.45 + if ( (rt = pthread_create(&tid, NULL, dma_thread_func, NULL)) ) { 31.46 + fprintf(stderr, "Oops, dma thread creation failed, errno=%d\n", rt); 31.47 + exit(1); 31.48 + } 31.49 + 31.50 + if ( (rt = pthread_detach(tid)) ) { 31.51 + fprintf(stderr, "Oops, dma thread detachment failed, errno=%d\n", rt); 31.52 + exit(1); 31.53 + } 31.54 +} 31.55 +#endif //DMA_MULTI_THREAD 31.56 + 31.57 static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb); 31.58 31.59 static void padstr(char *str, const char *src, int len) 31.60 @@ -1978,8 +2021,16 @@ static void ide_map(PCIDevice *pci_dev, 31.61 31.62 /* XXX: full callback usage to prepare non blocking I/Os support - 31.63 error handling */ 31.64 +#ifdef DMA_MULTI_THREAD 31.65 static void ide_dma_loop(BMDMAState *bm) 31.66 { 31.67 + write(file_pipes[1], &bm, sizeof(bm)); 31.68 +} 31.69 +static void dma_thread_loop(BMDMAState *bm) 31.70 +#else 31.71 +static void ide_dma_loop(BMDMAState *bm) 31.72 +#endif //DMA_MULTI_THREAD 31.73 +{ 31.74 struct { 31.75 uint32_t addr; 31.76 uint32_t size; 31.77 @@ -2166,6 +2217,9 @@ void pci_ide_init(PCIBus *bus, BlockDriv 31.78 d->ide_if[i].pci_dev = (PCIDevice *)d; 31.79 ide_init2(&d->ide_if[0], 16, hd_table[0], hd_table[1]); 31.80 ide_init2(&d->ide_if[2], 16, hd_table[2], hd_table[3]); 31.81 +#ifdef DMA_MULTI_THREAD 31.82 + dma_create_thread(); 31.83 +#endif //DMA_MULTI_THREAD 31.84 } 31.85 31.86 /* hd_table must contain 4 block drivers */ 31.87 @@ -2196,6 +2250,9 @@ void pci_piix3_ide_init(PCIBus *bus, Blo 31.88 ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]); 31.89 ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); 31.90 ide_init_ioport(&d->ide_if[2], 0x170, 0x376); 31.91 +#ifdef DMA_MULTI_THREAD 31.92 + dma_create_thread(); 31.93 +#endif //DMA_MULTI_THREAD 31.94 } 31.95 31.96 /***********************************************************/
32.1 --- a/tools/libxc/xc_elf.h Sun Oct 30 13:52:38 2005 +0100 32.2 +++ b/tools/libxc/xc_elf.h Sun Oct 30 14:00:35 2005 +0100 32.3 @@ -24,26 +24,26 @@ 32.4 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32.5 */ 32.6 32.7 -typedef u_int8_t Elf_Byte; 32.8 +typedef uint8_t Elf_Byte; 32.9 32.10 -typedef u_int32_t Elf32_Addr; /* Unsigned program address */ 32.11 -typedef u_int32_t Elf32_Off; /* Unsigned file offset */ 32.12 +typedef uint32_t Elf32_Addr; /* Unsigned program address */ 32.13 +typedef uint32_t Elf32_Off; /* Unsigned file offset */ 32.14 typedef int32_t Elf32_Sword; /* Signed large integer */ 32.15 -typedef u_int32_t Elf32_Word; /* Unsigned large integer */ 32.16 -typedef u_int16_t Elf32_Half; /* Unsigned medium integer */ 32.17 +typedef uint32_t Elf32_Word; /* Unsigned large integer */ 32.18 +typedef uint16_t Elf32_Half; /* Unsigned medium integer */ 32.19 32.20 -typedef u_int64_t Elf64_Addr; 32.21 -typedef u_int64_t Elf64_Off; 32.22 +typedef uint64_t Elf64_Addr; 32.23 +typedef uint64_t Elf64_Off; 32.24 typedef int32_t Elf64_Shalf; 32.25 32.26 typedef int32_t Elf64_Sword; 32.27 -typedef u_int32_t Elf64_Word; 32.28 +typedef uint32_t Elf64_Word; 32.29 32.30 typedef int64_t Elf64_Sxword; 32.31 -typedef u_int64_t Elf64_Xword; 32.32 +typedef uint64_t Elf64_Xword; 32.33 32.34 -typedef u_int32_t Elf64_Half; 32.35 -typedef u_int16_t Elf64_Quarter; 32.36 +typedef uint32_t Elf64_Half; 32.37 +typedef uint16_t Elf64_Quarter; 32.38 32.39 /* 32.40 * e_ident[] identification indexes
33.1 --- a/tools/libxc/xc_ia64_stubs.c Sun Oct 30 13:52:38 2005 +0100 33.2 +++ b/tools/libxc/xc_ia64_stubs.c Sun Oct 30 14:00:35 2005 +0100 33.3 @@ -1,5 +1,11 @@ 33.4 #include "xg_private.h" 33.5 #include "xenguest.h" 33.6 +#include "xc_private.h" 33.7 +#include "xc_elf.h" 33.8 +#include <stdlib.h> 33.9 +#include <zlib.h> 33.10 +#include "xen/arch-ia64.h" 33.11 +#include <xen/io/ioreq.h> 33.12 33.13 int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, 33.14 uint32_t max_factor, uint32_t flags) 33.15 @@ -16,22 +22,6 @@ int xc_linux_restore(int xc_handle, int 33.16 return -1; 33.17 } 33.18 33.19 -int xc_vmx_build(int xc_handle, 33.20 - uint32_t domid, 33.21 - int memsize, 33.22 - const char *image_name, 33.23 - struct mem_map *mem_mapp, 33.24 - const char *ramdisk_name, 33.25 - const char *cmdline, 33.26 - unsigned int control_evtchn, 33.27 - unsigned int vcpus, 33.28 - unsigned int store_evtchn, 33.29 - unsigned long *store_mfn) 33.30 -{ 33.31 - PERROR("xc_vmx_build not implemented\n"); 33.32 - return -1; 33.33 -} 33.34 - 33.35 int 33.36 xc_plan9_build(int xc_handle, 33.37 uint32_t domid, 33.38 @@ -43,6 +33,653 @@ xc_plan9_build(int xc_handle, 33.39 return -1; 33.40 } 33.41 33.42 +int xc_ia64_get_pfn_list(int xc_handle, 33.43 + uint32_t domid, 33.44 + unsigned long *pfn_buf, 33.45 + unsigned int start_page, 33.46 + unsigned int nr_pages) 33.47 +{ 33.48 + dom0_op_t op; 33.49 + int ret; 33.50 + unsigned long max_pfns = ((unsigned long)start_page << 32) | nr_pages; 33.51 + 33.52 + op.cmd = DOM0_GETMEMLIST; 33.53 + op.u.getmemlist.domain = (domid_t)domid; 33.54 + op.u.getmemlist.max_pfns = max_pfns; 33.55 + op.u.getmemlist.buffer = pfn_buf; 33.56 + 33.57 + if ( (max_pfns != -1UL) 33.58 + && mlock(pfn_buf, nr_pages * sizeof(unsigned long)) != 0 ) 33.59 + { 33.60 + PERROR("Could not lock pfn list buffer"); 33.61 + return -1; 33.62 + } 33.63 + 33.64 + ret = do_dom0_op(xc_handle, &op); 33.65 + 33.66 + if (max_pfns != -1UL) 33.67 + (void)munlock(pfn_buf, nr_pages * sizeof(unsigned long)); 33.68 + 33.69 + return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; 33.70 +} 33.71 + 33.72 +long xc_get_max_pages(int xc_handle, uint32_t domid) 33.73 +{ 33.74 + dom0_op_t op; 33.75 + op.cmd = DOM0_GETDOMAININFO; 33.76 + op.u.getdomaininfo.domain = (domid_t)domid; 33.77 + return (do_dom0_op(xc_handle, &op) < 0) ? 33.78 + -1 : op.u.getdomaininfo.max_pages; 33.79 +} 33.80 + 33.81 +int xc_ia64_copy_to_domain_pages(int xc_handle, uint32_t domid, 33.82 + void* src_page, unsigned long dst_pfn, int nr_pages) 33.83 +{ 33.84 + // N.B. gva should be page aligned 33.85 + 33.86 + unsigned long *page_array=NULL; 33.87 + int i; 33.88 + 33.89 + if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL ){ 33.90 + PERROR("Could not allocate memory"); 33.91 + goto error_out; 33.92 + } 33.93 + if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, 33.94 + dst_pfn>>PAGE_SHIFT, nr_pages) != nr_pages ){ 33.95 + PERROR("Could not get the page frame list"); 33.96 + goto error_out; 33.97 + } 33.98 + 33.99 + for ( i=0; i< nr_pages; i++ ){ 33.100 + if (xc_copy_to_domain_page(xc_handle, domid, page_array[i], 33.101 + src_page + (i << PAGE_SHIFT))) 33.102 + goto error_out; 33.103 + } 33.104 + free(page_array); 33.105 + return 0; 33.106 + 33.107 +error_out: 33.108 + if (page_array) 33.109 + free(page_array); 33.110 + return -1; 33.111 +} 33.112 + 33.113 + 33.114 +#define HOB_SIGNATURE 0x3436474953424f48 // "HOBSIG64" 33.115 +#define GFW_HOB_START ((4UL<<30)-(14UL<<20)) //4G -14M 33.116 +#define GFW_HOB_SIZE (1UL<<20) //1M 33.117 +#define MEM_G (1UL << 30) 33.118 +#define MEM_M (1UL << 20) 33.119 + 33.120 +typedef struct { 33.121 + unsigned long signature; 33.122 + unsigned int type; 33.123 + unsigned int length; 33.124 +} HOB_GENERIC_HEADER; 33.125 + 33.126 +/* 33.127 + * INFO HOB is the first data data in one HOB list 33.128 + * it contains the control information of the HOB list 33.129 + */ 33.130 +typedef struct { 33.131 + HOB_GENERIC_HEADER header; 33.132 + unsigned long length; // current length of hob 33.133 + unsigned long cur_pos; // current poisiton of hob 33.134 + unsigned long buf_size; // size of hob buffer 33.135 +}HOB_INFO; 33.136 + 33.137 +typedef struct{ 33.138 + unsigned long start; 33.139 + unsigned long size; 33.140 +}hob_mem_t; 33.141 + 33.142 +typedef enum { 33.143 + HOB_TYPE_INFO=0, 33.144 + HOB_TYPE_TERMINAL, 33.145 + HOB_TYPE_MEM, 33.146 + HOB_TYPE_PAL_BUS_GET_FEATURES_DATA, 33.147 + HOB_TYPE_PAL_CACHE_SUMMARY, 33.148 + HOB_TYPE_PAL_MEM_ATTRIB, 33.149 + HOB_TYPE_PAL_CACHE_INFO, 33.150 + HOB_TYPE_PAL_CACHE_PROT_INFO, 33.151 + HOB_TYPE_PAL_DEBUG_INFO, 33.152 + HOB_TYPE_PAL_FIXED_ADDR, 33.153 + HOB_TYPE_PAL_FREQ_BASE, 33.154 + HOB_TYPE_PAL_FREQ_RATIOS, 33.155 + HOB_TYPE_PAL_HALT_INFO, 33.156 + HOB_TYPE_PAL_PERF_MON_INFO, 33.157 + HOB_TYPE_PAL_PROC_GET_FEATURES, 33.158 + HOB_TYPE_PAL_PTCE_INFO, 33.159 + HOB_TYPE_PAL_REGISTER_INFO, 33.160 + HOB_TYPE_PAL_RSE_INFO, 33.161 + HOB_TYPE_PAL_TEST_INFO, 33.162 + HOB_TYPE_PAL_VM_SUMMARY, 33.163 + HOB_TYPE_PAL_VM_INFO, 33.164 + HOB_TYPE_PAL_VM_PAGE_SIZE, 33.165 + HOB_TYPE_MAX 33.166 +}hob_type_t; 33.167 + 33.168 +static int hob_init( void *buffer ,unsigned long buf_size); 33.169 +static int add_pal_hob(void* hob_buf); 33.170 +static int add_mem_hob(void* hob_buf, unsigned long dom_mem_size); 33.171 +static int build_hob (void* hob_buf, unsigned long hob_buf_size, 33.172 + unsigned long dom_mem_size); 33.173 +static int load_hob(int xc_handle,uint32_t dom, void *hob_buf); 33.174 + 33.175 +int xc_ia64_build_hob(int xc_handle, uint32_t dom, unsigned long memsize){ 33.176 + 33.177 + char hob_buf[GFW_HOB_SIZE]; 33.178 + 33.179 + if ( build_hob( hob_buf, GFW_HOB_SIZE, memsize<<20) < 0){ 33.180 + PERROR("Could not build hob"); 33.181 + return -1; 33.182 + } 33.183 + 33.184 + if ( load_hob( xc_handle, dom, hob_buf) <0){ 33.185 + PERROR("Could not load hob"); 33.186 + return -1; 33.187 + } 33.188 + 33.189 + return 0; 33.190 + 33.191 +} 33.192 +static int 33.193 +hob_init( void *buffer ,unsigned long buf_size) 33.194 +{ 33.195 + HOB_INFO *phit; 33.196 + HOB_GENERIC_HEADER *terminal; 33.197 + 33.198 + if (sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER) > buf_size){ 33.199 + // buffer too small 33.200 + return -1; 33.201 + } 33.202 + 33.203 + phit = (HOB_INFO*)buffer; 33.204 + phit->header.signature = HOB_SIGNATURE; 33.205 + phit->header.type = HOB_TYPE_INFO; 33.206 + phit->header.length = sizeof(HOB_INFO); 33.207 + phit->length = sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER); 33.208 + phit->cur_pos = 0; 33.209 + phit->buf_size = buf_size; 33.210 + 33.211 + terminal = (HOB_GENERIC_HEADER*) (buffer + sizeof(HOB_INFO)); 33.212 + terminal->signature= HOB_SIGNATURE; 33.213 + terminal->type = HOB_TYPE_TERMINAL; 33.214 + terminal->length = sizeof(HOB_GENERIC_HEADER); 33.215 + 33.216 + return 0; 33.217 +} 33.218 + 33.219 +/* 33.220 + * Add a new HOB to the HOB List. 33.221 + * 33.222 + * hob_start - start address of hob buffer 33.223 + * type - type of the hob to be added 33.224 + * data - data of the hob to be added 33.225 + * data_size - size of the data 33.226 + */ 33.227 +static int 33.228 +hob_add( 33.229 + void* hob_start, 33.230 + int type, 33.231 + void* data, 33.232 + int data_size 33.233 +) 33.234 +{ 33.235 + HOB_INFO *phit; 33.236 + HOB_GENERIC_HEADER *newhob,*tail; 33.237 + 33.238 + phit = (HOB_INFO*)hob_start; 33.239 + 33.240 + if (phit->length + data_size > phit->buf_size){ 33.241 + // no space for new hob 33.242 + return -1; 33.243 + } 33.244 + 33.245 + //append new HOB 33.246 + newhob = (HOB_GENERIC_HEADER*) 33.247 + (hob_start + phit->length - sizeof(HOB_GENERIC_HEADER)); 33.248 + newhob->signature = HOB_SIGNATURE; 33.249 + newhob->type = type; 33.250 + newhob->length = data_size + sizeof(HOB_GENERIC_HEADER); 33.251 + memcpy((void*)newhob + sizeof(HOB_GENERIC_HEADER), data, data_size); 33.252 + 33.253 + // append terminal HOB 33.254 + tail = (HOB_GENERIC_HEADER*) ( hob_start + phit->length + data_size); 33.255 + tail->signature = HOB_SIGNATURE; 33.256 + tail->type = HOB_TYPE_TERMINAL; 33.257 + tail->length = sizeof(HOB_GENERIC_HEADER); 33.258 + 33.259 + // adjust HOB list length 33.260 + phit->length += sizeof(HOB_GENERIC_HEADER)+ data_size; 33.261 + 33.262 + return 0; 33.263 + 33.264 +} 33.265 + 33.266 +int get_hob_size(void* hob_buf){ 33.267 + 33.268 + HOB_INFO *phit = (HOB_INFO*)hob_buf; 33.269 + 33.270 + if (phit->header.signature != HOB_SIGNATURE){ 33.271 + PERROR("xc_get_hob_size:Incorrect signature"); 33.272 + return -1; 33.273 + } 33.274 + return phit->length; 33.275 +} 33.276 + 33.277 +int build_hob (void* hob_buf, unsigned long hob_buf_size, 33.278 + unsigned long dom_mem_size) 33.279 +{ 33.280 + //Init HOB List 33.281 + if (hob_init (hob_buf, hob_buf_size)<0){ 33.282 + PERROR("buffer too small"); 33.283 + goto err_out; 33.284 + } 33.285 + 33.286 + if ( add_mem_hob( hob_buf,dom_mem_size) < 0){ 33.287 + PERROR("Add memory hob failed, buffer too small"); 33.288 + goto err_out; 33.289 + } 33.290 + 33.291 + if ( add_pal_hob( hob_buf ) < 0 ){ 33.292 + PERROR("Add PAL hob failed, buffer too small"); 33.293 + goto err_out; 33.294 + } 33.295 + 33.296 + return 0; 33.297 + 33.298 +err_out: 33.299 + return -1; 33.300 +} 33.301 + 33.302 +static int 33.303 +load_hob(int xc_handle, uint32_t dom, void *hob_buf) 33.304 +{ 33.305 + // hob_buf should be page aligned 33.306 + int hob_size; 33.307 + int nr_pages; 33.308 + 33.309 + if ((hob_size = get_hob_size(hob_buf)) < 0){ 33.310 + PERROR("Invalid hob data"); 33.311 + return -1; 33.312 + } 33.313 + 33.314 + if (hob_size > GFW_HOB_SIZE){ 33.315 + PERROR("No enough memory for hob data"); 33.316 + return -1; 33.317 + } 33.318 + 33.319 + nr_pages = (hob_size + PAGE_SIZE -1) >> PAGE_SHIFT; 33.320 + 33.321 + return xc_ia64_copy_to_domain_pages(xc_handle, dom, 33.322 + hob_buf, GFW_HOB_START, nr_pages ); 33.323 +} 33.324 + 33.325 +#define MIN(x, y) ((x) < (y)) ? (x) : (y) 33.326 +static int 33.327 +add_mem_hob(void* hob_buf, unsigned long dom_mem_size){ 33.328 + hob_mem_t memhob; 33.329 + 33.330 + // less than 3G 33.331 + memhob.start = 0; 33.332 + memhob.size = MIN(dom_mem_size, 0xC0000000); 33.333 + 33.334 + if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0){ 33.335 + return -1; 33.336 + } 33.337 + 33.338 + if (dom_mem_size > 0xC0000000) { 33.339 + // 4G ~ 4G+remain 33.340 + memhob.start = 0x100000000; //4G 33.341 + memhob.size = dom_mem_size - 0xC0000000; 33.342 + if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0) 33.343 + return -1; 33.344 + } 33.345 + return 0; 33.346 +} 33.347 + 33.348 +unsigned char config_pal_bus_get_features_data[24] = { 33.349 + 0, 0, 0, 32, 0, 0, 240, 189, 0, 0, 0, 0, 0, 0, 33.350 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 33.351 +}; 33.352 +unsigned char config_pal_cache_summary[16] = { 33.353 + 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0}; 33.354 +unsigned char config_pal_mem_attrib[8] = { 33.355 + 241, 0, 0, 0, 0, 0, 0, 0 33.356 +}; 33.357 +unsigned char config_pal_cache_info[152] = { 33.358 + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.359 + 6, 4, 6, 7, 255, 1, 0, 1, 0, 64, 0, 0, 12, 12, 33.360 + 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 7, 0, 1, 33.361 + 0, 1, 0, 64, 0, 0, 12, 12, 49, 0, 0, 0, 0, 0, 0, 33.362 + 0, 0, 0, 6, 8, 7, 7, 255, 7, 0, 11, 0, 0, 16, 0, 33.363 + 12, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7, 33.364 + 7, 7, 5, 9, 11, 0, 0, 4, 0, 12, 15, 49, 0, 254, 255, 33.365 + 255, 255, 255, 255, 255, 255, 2, 8, 7, 7, 7, 5, 9, 33.366 + 11, 0, 0, 4, 0, 12, 15, 49, 0, 0, 0, 0, 0, 0, 0, 0, 33.367 + 0, 3, 12, 7, 7, 7, 14, 1, 3, 0, 0, 192, 0, 12, 20, 49, 0 33.368 +}; 33.369 +unsigned char config_pal_cache_prot_info[200] = { 33.370 + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.371 + 45, 0, 16, 8, 0, 76, 12, 64, 0, 0, 0, 0, 0, 0, 0, 33.372 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.373 + 8, 0, 16, 4, 0, 76, 44, 68, 0, 0, 0, 0, 0, 0, 0, 0, 33.374 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33.375 + 0, 16, 8, 0, 81, 44, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.376 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 33.377 + 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.378 + 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 33.379 + 32, 0, 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.380 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 160, 33.381 + 12, 0, 84, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.382 + 0, 0, 0 33.383 +}; 33.384 +unsigned char config_pal_debug_info[16] = { 33.385 + 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 33.386 +}; 33.387 +unsigned char config_pal_fixed_addr[8] = { 33.388 + 0, 0, 0, 0, 0, 0, 0, 0 33.389 +}; 33.390 +unsigned char config_pal_freq_base[8] = { 33.391 + 109, 219, 182, 13, 0, 0, 0, 0 33.392 +}; 33.393 +unsigned char config_pal_freq_ratios[24] = { 33.394 + 11, 1, 0, 0, 77, 7, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 4, 33.395 + 0, 0, 0, 7, 0, 0, 0 33.396 +}; 33.397 +unsigned char config_pal_halt_info[64] = { 33.398 + 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 33.399 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.400 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.401 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 33.402 +}; 33.403 +unsigned char config_pal_perf_mon_info[136] = { 33.404 + 12, 47, 18, 8, 0, 0, 0, 0, 241, 255, 0, 0, 255, 7, 0, 0, 33.405 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.406 + 0, 0, 0, 0, 0, 0, 0, 0, 241, 255, 0, 0, 223, 0, 255, 255, 33.407 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.408 + 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0, 33.409 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.410 + 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0, 33.411 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.412 + 0, 0, 0, 0, 0, 0, 0, 0 33.413 +}; 33.414 +unsigned char config_pal_proc_get_features[104] = { 33.415 + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.416 + 0, 0, 0, 0, 64, 6, 64, 49, 0, 0, 0, 0, 64, 6, 0, 0, 33.417 + 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 33.418 + 231, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 33.419 + 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 33.420 + 63, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 33.421 + 0, 0, 0, 0, 0, 0, 0, 0 33.422 +}; 33.423 +unsigned char config_pal_ptce_info[24] = { 33.424 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 33.425 + 0, 0, 0, 0, 0, 0, 0, 0 33.426 +}; 33.427 +unsigned char config_pal_register_info[64] = { 33.428 + 255, 0, 47, 127, 17, 17, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 33.429 + 255, 208, 128, 238, 238, 0, 0, 248, 255, 255, 255, 255, 255, 0, 0, 7, 3, 33.430 + 251, 3, 0, 0, 0, 0, 255, 7, 3, 0, 0, 0, 0, 0, 248, 252, 4, 33.431 + 252, 255, 255, 255, 255, 2, 248, 252, 255, 255, 255, 255, 255 33.432 +}; 33.433 +unsigned char config_pal_rse_info[16] = { 33.434 + 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 33.435 +}; 33.436 +unsigned char config_pal_test_info[48] = { 33.437 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.438 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.439 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 33.440 +}; 33.441 +unsigned char config_pal_vm_summary[16] = { 33.442 + 101, 18, 15, 2, 7, 7, 4, 2, 59, 18, 0, 0, 0, 0, 0, 0 33.443 +}; 33.444 +unsigned char config_pal_vm_info[104] = { 33.445 + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 33.446 + 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0, 0, 0, 33.447 + 0, 0, 0, 0, 0, 0, 1, 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, 33.448 + 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 128, 0, 33.449 + 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.450 + 0, 0, 0, 1, 128, 128, 0, 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0 33.451 +}; 33.452 +unsigned char config_pal_vm_page_size[16] = { 33.453 + 0, 112, 85, 21, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0 33.454 +}; 33.455 + 33.456 +typedef struct{ 33.457 + hob_type_t type; 33.458 + void* data; 33.459 + unsigned long size; 33.460 +}hob_batch_t; 33.461 + 33.462 +hob_batch_t hob_batch[]={ 33.463 + { HOB_TYPE_PAL_BUS_GET_FEATURES_DATA, 33.464 + &config_pal_bus_get_features_data, 33.465 + sizeof(config_pal_bus_get_features_data) 33.466 + }, 33.467 + { HOB_TYPE_PAL_CACHE_SUMMARY, 33.468 + &config_pal_cache_summary, 33.469 + sizeof(config_pal_cache_summary) 33.470 + }, 33.471 + { HOB_TYPE_PAL_MEM_ATTRIB, 33.472 + &config_pal_mem_attrib, 33.473 + sizeof(config_pal_mem_attrib) 33.474 + }, 33.475 + { HOB_TYPE_PAL_CACHE_INFO, 33.476 + &config_pal_cache_info, 33.477 + sizeof(config_pal_cache_info) 33.478 + }, 33.479 + { HOB_TYPE_PAL_CACHE_PROT_INFO, 33.480 + &config_pal_cache_prot_info, 33.481 + sizeof(config_pal_cache_prot_info) 33.482 + }, 33.483 + { HOB_TYPE_PAL_DEBUG_INFO, 33.484 + &config_pal_debug_info, 33.485 + sizeof(config_pal_debug_info) 33.486 + }, 33.487 + { HOB_TYPE_PAL_FIXED_ADDR, 33.488 + &config_pal_fixed_addr, 33.489 + sizeof(config_pal_fixed_addr) 33.490 + }, 33.491 + { HOB_TYPE_PAL_FREQ_BASE, 33.492 + &config_pal_freq_base, 33.493 + sizeof(config_pal_freq_base) 33.494 + }, 33.495 + { HOB_TYPE_PAL_FREQ_RATIOS, 33.496 + &config_pal_freq_ratios, 33.497 + sizeof(config_pal_freq_ratios) 33.498 + }, 33.499 + { HOB_TYPE_PAL_HALT_INFO, 33.500 + &config_pal_halt_info, 33.501 + sizeof(config_pal_halt_info) 33.502 + }, 33.503 + { HOB_TYPE_PAL_PERF_MON_INFO, 33.504 + &config_pal_perf_mon_info, 33.505 + sizeof(config_pal_perf_mon_info) 33.506 + }, 33.507 + { HOB_TYPE_PAL_PROC_GET_FEATURES, 33.508 + &config_pal_proc_get_features, 33.509 + sizeof(config_pal_proc_get_features) 33.510 + }, 33.511 + { HOB_TYPE_PAL_PTCE_INFO, 33.512 + &config_pal_ptce_info, 33.513 + sizeof(config_pal_ptce_info) 33.514 + }, 33.515 + { HOB_TYPE_PAL_REGISTER_INFO, 33.516 + &config_pal_register_info, 33.517 + sizeof(config_pal_register_info) 33.518 + }, 33.519 + { HOB_TYPE_PAL_RSE_INFO, 33.520 + &config_pal_rse_info, 33.521 + sizeof(config_pal_rse_info) 33.522 + }, 33.523 + { HOB_TYPE_PAL_TEST_INFO, 33.524 + &config_pal_test_info, 33.525 + sizeof(config_pal_test_info) 33.526 + }, 33.527 + { HOB_TYPE_PAL_VM_SUMMARY, 33.528 + &config_pal_vm_summary, 33.529 + sizeof(config_pal_vm_summary) 33.530 + }, 33.531 + { HOB_TYPE_PAL_VM_INFO, 33.532 + &config_pal_vm_info, 33.533 + sizeof(config_pal_vm_info) 33.534 + }, 33.535 + { HOB_TYPE_PAL_VM_PAGE_SIZE, 33.536 + &config_pal_vm_page_size, 33.537 + sizeof(config_pal_vm_page_size) 33.538 + }, 33.539 +}; 33.540 + 33.541 +static int add_pal_hob(void* hob_buf){ 33.542 + int i; 33.543 + for (i=0; i<sizeof(hob_batch)/sizeof(hob_batch_t); i++){ 33.544 + if (hob_add(hob_buf, hob_batch[i].type, 33.545 + hob_batch[i].data, 33.546 + hob_batch[i].size)<0) 33.547 + return -1; 33.548 + } 33.549 + return 0; 33.550 +} 33.551 + 33.552 +static int setup_guest( int xc_handle, 33.553 + uint32_t dom, unsigned long memsize, 33.554 + char *image, unsigned long image_size, 33.555 + unsigned int control_evtchn, 33.556 + unsigned int store_evtchn, 33.557 + unsigned long *store_mfn) 33.558 +{ 33.559 + unsigned long page_array[2]; 33.560 + shared_iopage_t *sp; 33.561 + // FIXME: initialize pfn list for a temp hack 33.562 + if (xc_ia64_get_pfn_list(xc_handle, dom, NULL, -1, -1) == -1) { 33.563 + PERROR("Could not allocate continuous memory"); 33.564 + goto error_out; 33.565 + } 33.566 + 33.567 + if ((image_size > 12 * MEM_M) || (image_size & (PAGE_SIZE - 1))) { 33.568 + PERROR("Guest firmware size is incorrect [%ld]?", image_size); 33.569 + return -1; 33.570 + } 33.571 + 33.572 + /* Load guest firmware */ 33.573 + if( xc_ia64_copy_to_domain_pages( xc_handle, dom, 33.574 + image, 4*MEM_G-image_size, image_size>>PAGE_SHIFT)) { 33.575 + PERROR("Could not load guest firmware into domain"); 33.576 + goto error_out; 33.577 + } 33.578 + 33.579 + /* Hand-off state passed to guest firmware */ 33.580 + if (xc_ia64_build_hob(xc_handle, dom, memsize) < 0){ 33.581 + PERROR("Could not build hob\n"); 33.582 + goto error_out; 33.583 + } 33.584 + 33.585 + /* Retrieve special pages like io, xenstore, etc. */ 33.586 + if ( xc_ia64_get_pfn_list(xc_handle, dom, page_array, IO_PAGE_START>>PAGE_SHIFT, 2) != 2 ) 33.587 + { 33.588 + PERROR("Could not get the page frame list"); 33.589 + goto error_out; 33.590 + } 33.591 + 33.592 + *store_mfn = page_array[1]; 33.593 + if ((sp = (shared_iopage_t *) xc_map_foreign_range( 33.594 + xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, 33.595 + page_array[0])) == 0) 33.596 + goto error_out; 33.597 + memset(sp, 0, PAGE_SIZE); 33.598 + sp->sp_global.eport = control_evtchn; 33.599 + munmap(sp, PAGE_SIZE); 33.600 + 33.601 + return 0; 33.602 + 33.603 + error_out: 33.604 + return -1; 33.605 +} 33.606 + 33.607 +int xc_vmx_build(int xc_handle, 33.608 + uint32_t domid, 33.609 + int memsize, 33.610 + const char *image_name, 33.611 + unsigned int control_evtchn, 33.612 + unsigned int vcpus, 33.613 + unsigned int store_evtchn, 33.614 + unsigned long *store_mfn) 33.615 +{ 33.616 + dom0_op_t launch_op, op; 33.617 + int rc ; 33.618 + vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt; 33.619 + char *image = NULL; 33.620 + unsigned long image_size; 33.621 + unsigned long nr_pages; 33.622 + 33.623 + if ( (nr_pages = xc_get_max_pages(xc_handle, domid)) < 0 ) 33.624 + { 33.625 + PERROR("Could not find total pages for domain"); 33.626 + goto error_out; 33.627 + } 33.628 + 33.629 + if ( (image = xc_read_kernel_image(image_name, &image_size)) == NULL ){ 33.630 + PERROR("Could not read guest firmware image %s",image_name); 33.631 + goto error_out; 33.632 + } 33.633 + 33.634 + image_size = (image_size + PAGE_SIZE - 1) & PAGE_MASK; 33.635 + 33.636 + if ( mlock(&st_ctxt, sizeof(st_ctxt) ) ){ 33.637 + PERROR("Unable to mlock ctxt"); 33.638 + return 1; 33.639 + } 33.640 + 33.641 + op.cmd = DOM0_GETDOMAININFO; 33.642 + op.u.getdomaininfo.domain = (domid_t)domid; 33.643 + if ( (do_dom0_op(xc_handle, &op) < 0) || 33.644 + ((uint16_t)op.u.getdomaininfo.domain != domid) ) { 33.645 + PERROR("Could not get info on domain"); 33.646 + goto error_out; 33.647 + } 33.648 + 33.649 + if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) ){ 33.650 + PERROR("Could not get vcpu context"); 33.651 + goto error_out; 33.652 + } 33.653 + 33.654 + if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ) { 33.655 + ERROR("Domain is already constructed"); 33.656 + goto error_out; 33.657 + } 33.658 + 33.659 + if ( setup_guest(xc_handle, domid, (unsigned long)memsize, image, image_size, 33.660 + control_evtchn, store_evtchn, store_mfn ) < 0 ){ 33.661 + ERROR("Error constructing guest OS"); 33.662 + goto error_out; 33.663 + } 33.664 + 33.665 + if ( image != NULL ) 33.666 + free(image); 33.667 + 33.668 + ctxt->flags = VGCF_VMX_GUEST; 33.669 + ctxt->regs.cr_iip = 0x80000000ffffffb0UL; 33.670 + ctxt->vcpu.privregs = 0; 33.671 + 33.672 + memset( &launch_op, 0, sizeof(launch_op) ); 33.673 + 33.674 + launch_op.u.setdomaininfo.domain = (domid_t)domid; 33.675 + launch_op.u.setdomaininfo.vcpu = 0; 33.676 + launch_op.u.setdomaininfo.ctxt = ctxt; 33.677 + 33.678 + launch_op.cmd = DOM0_SETDOMAININFO; 33.679 + rc = do_dom0_op(xc_handle, &launch_op); 33.680 + return rc; 33.681 + 33.682 + error_out: 33.683 + if ( image != NULL ) 33.684 + free(image); 33.685 + 33.686 + return -1; 33.687 +} 33.688 + 33.689 /* 33.690 * Local variables: 33.691 * mode: C
34.1 --- a/tools/libxc/xc_linux_build.c Sun Oct 30 13:52:38 2005 +0100 34.2 +++ b/tools/libxc/xc_linux_build.c Sun Oct 30 14:00:35 2005 +0100 34.3 @@ -350,6 +350,8 @@ static int setup_guest(int xc_handle, 34.4 start_info = xc_map_foreign_range( 34.5 xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, page_array[0]); 34.6 memset(start_info, 0, sizeof(*start_info)); 34.7 + rc = xc_version(xc_handle, XENVER_version, NULL); 34.8 + sprintf(start_info->magic, "Xen-%i.%i", rc >> 16, rc & (0xFFFF)); 34.9 start_info->flags = flags; 34.10 start_info->store_mfn = nr_pages - 2; 34.11 start_info->store_evtchn = store_evtchn; 34.12 @@ -624,6 +626,8 @@ static int setup_guest(int xc_handle, 34.13 xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, 34.14 page_array[(vstartinfo_start-dsi.v_start)>>PAGE_SHIFT]); 34.15 memset(start_info, 0, sizeof(*start_info)); 34.16 + rc = xc_version(xc_handle, XENVER_version, NULL); 34.17 + sprintf(start_info->magic, "Xen-%i.%i", rc >> 16, rc & (0xFFFF)); 34.18 start_info->nr_pages = nr_pages; 34.19 start_info->shared_info = shared_info_frame << PAGE_SHIFT; 34.20 start_info->flags = flags;
35.1 --- a/tools/libxc/xc_private.c Sun Oct 30 13:52:38 2005 +0100 35.2 +++ b/tools/libxc/xc_private.c Sun Oct 30 14:00:35 2005 +0100 35.3 @@ -313,46 +313,6 @@ int xc_get_pfn_list(int xc_handle, 35.4 return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; 35.5 } 35.6 35.7 -#ifdef __ia64__ 35.8 -int xc_ia64_get_pfn_list(int xc_handle, 35.9 - uint32_t domid, 35.10 - unsigned long *pfn_buf, 35.11 - unsigned int start_page, 35.12 - unsigned int nr_pages) 35.13 -{ 35.14 - dom0_op_t op; 35.15 - int ret; 35.16 - 35.17 - op.cmd = DOM0_GETMEMLIST; 35.18 - op.u.getmemlist.domain = (domid_t)domid; 35.19 - op.u.getmemlist.max_pfns = ((unsigned long)start_page << 32) | nr_pages; 35.20 - op.u.getmemlist.buffer = pfn_buf; 35.21 - 35.22 - if ( mlock(pfn_buf, nr_pages * sizeof(unsigned long)) != 0 ) 35.23 - { 35.24 - PERROR("Could not lock pfn list buffer"); 35.25 - return -1; 35.26 - } 35.27 - 35.28 - /* XXX Hack to put pages in TLB, hypervisor should be able to handle this */ 35.29 - memset(pfn_buf, 0, nr_pages * sizeof(unsigned long)); 35.30 - ret = do_dom0_op(xc_handle, &op); 35.31 - 35.32 - (void)munlock(pfn_buf, nr_pages * sizeof(unsigned long)); 35.33 - 35.34 - return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; 35.35 -} 35.36 - 35.37 -long xc_get_max_pages(int xc_handle, uint32_t domid) 35.38 -{ 35.39 - dom0_op_t op; 35.40 - op.cmd = DOM0_GETDOMAININFO; 35.41 - op.u.getdomaininfo.domain = (domid_t)domid; 35.42 - return (do_dom0_op(xc_handle, &op) < 0) ? 35.43 - -1 : op.u.getdomaininfo.max_pages; 35.44 -} 35.45 -#endif 35.46 - 35.47 long xc_get_tot_pages(int xc_handle, uint32_t domid) 35.48 { 35.49 dom0_op_t op;
36.1 --- a/tools/libxc/xc_vmx_build.c Sun Oct 30 13:52:38 2005 +0100 36.2 +++ b/tools/libxc/xc_vmx_build.c Sun Oct 30 14:00:35 2005 +0100 36.3 @@ -279,6 +279,7 @@ static int setup_guest(int xc_handle, 36.4 vcpu_guest_context_t *ctxt, 36.5 unsigned long shared_info_frame, 36.6 unsigned int control_evtchn, 36.7 + unsigned int lapic, 36.8 unsigned int vcpus, 36.9 unsigned int store_evtchn, 36.10 unsigned long *store_mfn) 36.11 @@ -554,7 +555,7 @@ static int setup_guest(int xc_handle, 36.12 ctxt->user_regs.eax = 0; 36.13 ctxt->user_regs.esp = 0; 36.14 ctxt->user_regs.ebx = 0; /* startup_32 expects this to be 0 to signal boot cpu */ 36.15 - ctxt->user_regs.ecx = 0; 36.16 + ctxt->user_regs.ecx = lapic; 36.17 ctxt->user_regs.esi = 0; 36.18 ctxt->user_regs.edi = 0; 36.19 ctxt->user_regs.ebp = 0; 36.20 @@ -597,6 +598,7 @@ int xc_vmx_build(int xc_handle, 36.21 int memsize, 36.22 const char *image_name, 36.23 unsigned int control_evtchn, 36.24 + unsigned int lapic, 36.25 unsigned int vcpus, 36.26 unsigned int store_evtchn, 36.27 unsigned long *store_mfn) 36.28 @@ -651,9 +653,9 @@ int xc_vmx_build(int xc_handle, 36.29 goto error_out; 36.30 } 36.31 36.32 - if ( setup_guest(xc_handle, domid, memsize, image, image_size, 36.33 - nr_pages, ctxt, op.u.getdomaininfo.shared_info_frame, 36.34 - control_evtchn, vcpus, store_evtchn, store_mfn) < 0) 36.35 + if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages, 36.36 + ctxt, op.u.getdomaininfo.shared_info_frame, control_evtchn, 36.37 + lapic, vcpus, store_evtchn, store_mfn) < 0) 36.38 { 36.39 ERROR("Error constructing guest OS"); 36.40 goto error_out;
37.1 --- a/tools/libxc/xenctrl.h Sun Oct 30 13:52:38 2005 +0100 37.2 +++ b/tools/libxc/xenctrl.h Sun Oct 30 14:00:35 2005 +0100 37.3 @@ -414,6 +414,12 @@ int xc_ia64_get_pfn_list(int xc_handle, 37.4 unsigned long *pfn_buf, 37.5 unsigned int start_page, unsigned int nr_pages); 37.6 37.7 +int xc_copy_to_domain_page(int xc_handle, uint32_t domid, 37.8 + unsigned long dst_pfn, void *src_page); 37.9 + 37.10 +int xc_ia64_copy_to_domain_pages(int xc_handle, uint32_t domid, 37.11 + void* src_page, unsigned long dst_pfn, int nr_pages); 37.12 + 37.13 long xc_get_max_pages(int xc_handle, uint32_t domid); 37.14 37.15 int xc_mmuext_op(int xc_handle, struct mmuext_op *op, unsigned int nr_ops,
38.1 --- a/tools/libxc/xenguest.h Sun Oct 30 13:52:38 2005 +0100 38.2 +++ b/tools/libxc/xenguest.h Sun Oct 30 14:00:35 2005 +0100 38.3 @@ -56,6 +56,7 @@ int xc_vmx_build(int xc_handle, 38.4 int memsize, 38.5 const char *image_name, 38.6 unsigned int control_evtchn, 38.7 + unsigned int lapic, 38.8 unsigned int vcpus, 38.9 unsigned int store_evtchn, 38.10 unsigned long *store_mfn);
39.1 --- a/tools/misc/cpuperf/cpuperf.c Sun Oct 30 13:52:38 2005 +0100 39.2 +++ b/tools/misc/cpuperf/cpuperf.c Sun Oct 30 14:00:35 2005 +0100 39.3 @@ -16,7 +16,6 @@ 39.4 39.5 #include <sys/types.h> 39.6 #include <sched.h> 39.7 -#include <error.h> 39.8 #include <stdio.h> 39.9 #include <unistd.h> 39.10 #include <stdlib.h>
40.1 --- a/tools/misc/miniterm/miniterm.c Sun Oct 30 13:52:38 2005 +0100 40.2 +++ b/tools/misc/miniterm/miniterm.c Sun Oct 30 14:00:35 2005 +0100 40.3 @@ -29,7 +29,7 @@ 40.4 #include <stdlib.h> 40.5 #include <unistd.h> 40.6 #include <fcntl.h> 40.7 -#include <sys/signal.h> 40.8 +#include <signal.h> 40.9 #include <sys/types.h> 40.10 #include <sys/wait.h> 40.11
41.1 --- a/tools/python/xen/lowlevel/xc/xc.c Sun Oct 30 13:52:38 2005 +0100 41.2 +++ b/tools/python/xen/lowlevel/xc/xc.c Sun Oct 30 14:00:35 2005 +0100 41.3 @@ -438,19 +438,20 @@ static PyObject *pyxc_vmx_build(PyObject 41.4 char *image; 41.5 int control_evtchn, store_evtchn; 41.6 int vcpus = 1; 41.7 + int lapic = 0; 41.8 int memsize; 41.9 unsigned long store_mfn = 0; 41.10 41.11 static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn", 41.12 - "memsize", "image", "vcpus", NULL }; 41.13 + "memsize", "image", "lapic", "vcpus", NULL }; 41.14 41.15 - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisi", kwd_list, 41.16 + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisii", kwd_list, 41.17 &dom, &control_evtchn, &store_evtchn, 41.18 - &memsize, &image, &vcpus) ) 41.19 + &memsize, &image, &lapic, &vcpus) ) 41.20 return NULL; 41.21 41.22 if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, control_evtchn, 41.23 - vcpus, store_evtchn, &store_mfn) != 0 ) 41.24 + lapic, vcpus, store_evtchn, &store_mfn) != 0 ) 41.25 return PyErr_SetFromErrno(xc_error); 41.26 41.27 return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
42.1 --- a/tools/python/xen/web/tcp.py Sun Oct 30 13:52:38 2005 +0100 42.2 +++ b/tools/python/xen/web/tcp.py Sun Oct 30 14:00:35 2005 +0100 42.3 @@ -99,7 +99,7 @@ def listenTCP(port, factory, interface=' 42.4 return l 42.5 42.6 def SetCloExec(SocketListener): 42.7 - SocketListener.SetCloExec() 42.8 + SocketListener.setCloExec() 42.9 42.10 def connectTCP(host, port, factory, timeout=None, bindAddress=None): 42.11 c = TCPConnector(host, port, factory, timeout=timeout, bindAddress=bindAddress)
43.1 --- a/tools/python/xen/xend/image.py Sun Oct 30 13:52:38 2005 +0100 43.2 +++ b/tools/python/xen/xend/image.py Sun Oct 30 14:00:35 2005 +0100 43.3 @@ -203,6 +203,10 @@ class VmxImageHandler(ImageHandler): 43.4 43.5 self.dmargs += self.configVNC(imageConfig) 43.6 43.7 + self.lapic = 0 43.8 + lapic = sxp.child_value(imageConfig, 'lapic') 43.9 + if not lapic is None: 43.10 + self.lapic = int(lapic) 43.11 43.12 def buildDomain(self): 43.13 # Create an event channel 43.14 @@ -217,6 +221,7 @@ class VmxImageHandler(ImageHandler): 43.15 log.debug("control_evtchn = %d", self.device_channel) 43.16 log.debug("store_evtchn = %d", store_evtchn) 43.17 log.debug("memsize = %d", self.vm.getMemoryTarget() / 1024) 43.18 + log.debug("lapic = %d", self.lapic) 43.19 log.debug("vcpus = %d", self.vm.getVCpuCount()) 43.20 43.21 return xc.vmx_build(dom = self.vm.getDomid(), 43.22 @@ -224,6 +229,7 @@ class VmxImageHandler(ImageHandler): 43.23 control_evtchn = self.device_channel, 43.24 store_evtchn = store_evtchn, 43.25 memsize = self.vm.getMemoryTarget() / 1024, 43.26 + lapic = self.lapic, 43.27 vcpus = self.vm.getVCpuCount()) 43.28 43.29 43.30 @@ -342,12 +348,15 @@ class VmxImageHandler(ImageHandler): 43.31 43.32 def getDomainMemory(self, mem): 43.33 """@see ImageHandler.getDomainMemory""" 43.34 + page_kb = 4 43.35 + if os.uname()[4] == 'ia64': 43.36 + page_kb = 16 43.37 # for ioreq_t and xenstore 43.38 static_pages = 2 43.39 - return mem + self.getPageTableSize(mem / 1024) + 4 * static_pages 43.40 + return mem + (self.getPageTableSize(mem / 1024) + static_pages) * page_kb 43.41 43.42 def getPageTableSize(self, mem_mb): 43.43 - """Return the size of memory needed for 1:1 page tables for physical 43.44 + """Return the pages of memory needed for 1:1 page tables for physical 43.45 mode. 43.46 43.47 @param mem_mb: size in MB 43.48 @@ -355,13 +364,13 @@ class VmxImageHandler(ImageHandler): 43.49 """ 43.50 # 1 page for the PGD + 1 pte page for 4MB of memory (rounded) 43.51 if os.uname()[4] == 'x86_64': 43.52 - return (5 + ((mem_mb + 1) >> 1)) * 4 43.53 + return 5 + ((mem_mb + 1) >> 1) 43.54 elif os.uname()[4] == 'ia64': 43.55 - # XEN/IA64 has p2m table allocated on demand, so only return 43.56 - # guest firmware size here. 43.57 - return 16 * 1024 43.58 + # 1:1 pgtable is allocated on demand ia64, so just return rom size 43.59 + # for guest firmware 43.60 + return 1024 43.61 else: 43.62 - return (1 + ((mem_mb + 3) >> 2)) * 4 43.63 + return 1 + ((mem_mb + 3) >> 2) 43.64 43.65 43.66 """Table of image handler classes for virtual machine images. Indexed by
44.1 --- a/tools/python/xen/xend/server/event.py Sun Oct 30 13:52:38 2005 +0100 44.2 +++ b/tools/python/xen/xend/server/event.py Sun Oct 30 14:00:35 2005 +0100 44.3 @@ -192,4 +192,5 @@ def listenEvent(daemon): 44.4 if xroot.get_xend_http_server(): 44.5 port = xroot.get_xend_event_port() 44.6 interface = xroot.get_xend_address() 44.7 - tcp.listenTCP(port, factory, interface=interface) 44.8 + l = tcp.listenTCP(port, factory, interface=interface) 44.9 + l.setCloExec()
46.1 --- a/tools/python/xen/xm/create.py Sun Oct 30 13:52:38 2005 +0100 46.2 +++ b/tools/python/xen/xm/create.py Sun Oct 30 14:00:35 2005 +0100 46.3 @@ -157,6 +157,10 @@ gopts.var('cpu', val='CPU', 46.4 fn=set_int, default=None, 46.5 use="CPU to run the domain on.") 46.6 46.7 +gopts.var('lapic', val='LAPIC', 46.8 + fn=set_int, default=0, 46.9 + use="Disable or enable local APIC of VMX domain.") 46.10 + 46.11 gopts.var('vcpus', val='VCPUS', 46.12 fn=set_int, default=1, 46.13 use="# of Virtual CPUS in domain.") 46.14 @@ -315,10 +319,6 @@ gopts.var('nfs_root', val="PATH", 46.15 fn=set_value, default=None, 46.16 use="Set the path of the root NFS directory.") 46.17 46.18 -gopts.var('memmap', val='FILE', 46.19 - fn=set_value, default='', 46.20 - use="Path to memap SXP file.") 46.21 - 46.22 gopts.var('device_model', val='FILE', 46.23 fn=set_value, default='', 46.24 use="Path to device model program.") 46.25 @@ -556,9 +556,9 @@ def configure_vfr(config, vals): 46.26 def configure_vmx(config_image, vals): 46.27 """Create the config for VMX devices. 46.28 """ 46.29 - args = [ 'memmap', 'device_model', 'vcpus', 'cdrom', 46.30 - 'boot', 'fda', 'fdb', 'localtime', 'serial', 'macaddr', 'stdvga', 46.31 - 'isa', 'nographic', 'vnc', 'vncviewer', 'sdl', 'display', 'ne2000'] 46.32 + args = [ 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb', 46.33 + 'localtime', 'serial', 'macaddr', 'stdvga', 'isa', 'nographic', 46.34 + 'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'lapic'] 46.35 for a in args: 46.36 if (vals.__dict__[a]): 46.37 config_image.append([a, vals.__dict__[a]])
47.1 --- a/tools/python/xen/xm/main.py Sun Oct 30 13:52:38 2005 +0100 47.2 +++ b/tools/python/xen/xm/main.py Sun Oct 30 14:00:35 2005 +0100 47.3 @@ -61,6 +61,8 @@ xm common subcommands: 47.4 top monitor system and domains in real-time 47.5 unpause <DomId> unpause a paused domain 47.6 47.7 +<DomName> can be substituted for <DomId> in xm subcommands. 47.8 + 47.9 For a complete list of subcommands run 'xm help --long' 47.10 For more help on xm see the xm(1) man page 47.11 For more help on xm create, see the xmdomain.cfg(5) man page""" 47.12 @@ -119,6 +121,8 @@ xm full list of subcommands: 47.13 vnet-create <config> create a vnet from a config file 47.14 vnet-delete <vnetid> delete a vnet 47.15 47.16 +<DomName> can be substituted for <DomId> in xm subcommands. 47.17 + 47.18 For a short list of subcommands run 'xm help' 47.19 For more help on xm see the xm(1) man page 47.20 For more help on xm create, see the xmdomain.cfg(5) man page"""
48.1 --- a/tools/security/getlabel.sh Sun Oct 30 13:52:38 2005 +0100 48.2 +++ b/tools/security/getlabel.sh Sun Oct 30 14:00:35 2005 +0100 48.3 @@ -36,18 +36,21 @@ source labelfuncs.sh 48.4 48.5 usage () 48.6 { 48.7 - echo "Usage: $0 -sid <ssidref> [<policy name>] or" 48.8 - echo " $0 -dom <domid> [<policy name>] " 48.9 - echo "" 48.10 - echo "policy name : the name of the policy, i.e. 'chwall'" 48.11 - echo " If the policy name is omitted, the grub.conf" 48.12 - echo " entry of the running system is tried to be read" 48.13 - echo " and the policy name determined from there." 48.14 - echo "ssidref : an ssidref in hex or decimal format, i.e., '0x00010002'" 48.15 - echo " or '65538'" 48.16 - echo "domid : id of the domain, i.e., '1'; Use numbers from the 2nd" 48.17 - echo " column shown when invoking 'xm list'" 48.18 - echo "" 48.19 +echo "Use this tool to display the label of a domain or the label that is 48.20 +corresponding to an ssidref given the name of the running policy. 48.21 + 48.22 +Usage: $0 -sid <ssidref> [<policy name>] or 48.23 + $0 -dom <domid> [<policy name>] 48.24 + 48.25 +policy name : the name of the policy, i.e. 'chwall' 48.26 + If the policy name is omitted, the grub.conf 48.27 + entry of the running system is tried to be read 48.28 + and the policy name determined from there. 48.29 +ssidref : an ssidref in hex or decimal format, i.e., '0x00010002' 48.30 + or '65538' 48.31 +domid : id of the domain, i.e., '1'; Use numbers from the 2nd 48.32 + column shown when invoking 'xm list' 48.33 +" 48.34 } 48.35 48.36
49.1 --- a/tools/security/setlabel.sh Sun Oct 30 13:52:38 2005 +0100 49.2 +++ b/tools/security/setlabel.sh Sun Oct 30 14:00:35 2005 +0100 49.3 @@ -39,21 +39,27 @@ source labelfuncs.sh 49.4 49.5 usage () 49.6 { 49.7 - echo "Usage: $0 [Option] <vmfile> <label> [<policy name>]" 49.8 - echo " or $0 -l [<policy name>]" 49.9 - echo "" 49.10 - echo "Valid options are:" 49.11 - echo "-r : to relabel a file without being prompted" 49.12 - echo "" 49.13 - echo "vmfile : XEN vm configuration file" 49.14 - echo "label : the label to map to an ssidref" 49.15 - echo "policy name : the name of the policy, i.e. 'chwall'" 49.16 - echo " If the policy name is omitted, it is attempted" 49.17 - echo " to find the current policy's name in grub.conf." 49.18 - echo "" 49.19 - echo "-l [<policy name>] is used to show valid labels in the map file of" 49.20 - echo " the given or current policy." 49.21 - echo "" 49.22 +echo "Use this tool to put the ssidref corresponding to a label of a policy into 49.23 +the VM configuration file, or use it to display all labels of a policy. 49.24 + 49.25 +Usage: $0 [Option] <vmfile> <label> [<policy name>] 49.26 + or $0 -l [<policy name>] 49.27 + 49.28 +Valid options are: 49.29 +-r : to relabel a file without being prompted 49.30 + 49.31 +vmfile : XEN vm configuration file; give complete path 49.32 +label : the label to map to an ssidref 49.33 +policy name : the name of the policy, i.e. 'chwall' 49.34 + If the policy name is omitted, it is attempted 49.35 + to find the current policy's name in grub.conf. 49.36 + 49.37 +-l [<policy name>] is used to show valid labels in the map file of 49.38 + the given or current policy. If the policy name 49.39 + is omitted, it will be tried to determine the 49.40 + current policy from grub.conf (/boot/grub/grub.conf) 49.41 + 49.42 +" 49.43 } 49.44 49.45 49.46 @@ -83,7 +89,7 @@ if [ "$mode" == "show" ]; then 49.47 exit -1; 49.48 fi 49.49 else 49.50 - policy=$3; 49.51 + policy=$1; 49.52 fi 49.53 49.54 49.55 @@ -92,7 +98,7 @@ if [ "$mode" == "show" ]; then 49.56 if [ "$res" != "0" ]; then 49.57 showLabels $mapfile 49.58 else 49.59 - echo "Could not find map file for policy '$1'." 49.60 + echo "Could not find map file for policy '$policy'." 49.61 fi 49.62 elif [ "$mode" == "usage" ]; then 49.63 usage
50.1 --- a/tools/security/updategrub.sh Sun Oct 30 13:52:38 2005 +0100 50.2 +++ b/tools/security/updategrub.sh Sun Oct 30 14:00:35 2005 +0100 50.3 @@ -26,11 +26,16 @@ fi 50.4 # Show usage of this program 50.5 usage () 50.6 { 50.7 - echo "Usage: $0 <policy name> <root of xen repository>" 50.8 - echo "" 50.9 - echo "<policy name> : The name of the policy, i.e. xen_null" 50.10 - echo "<root of xen repository> : The root of the XEN repositrory." 50.11 - echo "" 50.12 +echo "Use this tool to add the binary policy to the Xen grub entry and 50.13 +have Xen automatically enforce the policy when starting. 50.14 + 50.15 +Usage: $0 <policy name> <root of xen repository> 50.16 + 50.17 +<policy name> : The name of the policy, i.e. xen_null 50.18 +<root of xen repository> : The root of the XEN repository. Give 50.19 + complete path. 50.20 + 50.21 +" 50.22 } 50.23 50.24 # This function sets the global variable 'linux' 50.25 @@ -43,11 +48,24 @@ getLinuxVersion () 50.26 for f in $path/linux-*-xen0 ; do 50.27 versionfile=$f/include/linux/version.h 50.28 if [ -r $versionfile ]; then 50.29 - lnx=`cat $versionfile | \ 50.30 - grep UTS_RELEASE | \ 50.31 - awk '{ \ 50.32 - len=length($3); \ 50.33 - print substr($3,2,len-2) }'` 50.34 + lnx=`cat $versionfile | \ 50.35 + grep UTS_RELEASE | \ 50.36 + awk '{ \ 50.37 + len=length($3); \ 50.38 + version=substr($3,2,len-2); \ 50.39 + split(version,numbers,"."); \ 50.40 + if (numbers[4]=="") { \ 50.41 + printf("%s.%s.%s", \ 50.42 + numbers[1], \ 50.43 + numbers[2], \ 50.44 + numbers[3]); \ 50.45 + } else { \ 50.46 + printf("%s.%s.%s[.0-9]*-xen0",\ 50.47 + numbers[1], \ 50.48 + numbers[2], \ 50.49 + numbers[3]); \ 50.50 + } \ 50.51 + }'` 50.52 fi 50.53 if [ "$lnx" != "" ]; then 50.54 linux="[./0-9a-zA-z]*$lnx" 50.55 @@ -143,10 +161,19 @@ updateGrub () 50.56 echo "Could not create temporary file! Aborting." 50.57 exit -1 50.58 fi 50.59 - mv -f $tmpfile $grubconf 50.60 + diff $tmpfile $grubconf > /dev/null 50.61 + RES=$? 50.62 + if [ "$RES" == "0" ]; then 50.63 + echo "No changes were made to $grubconf." 50.64 + else 50.65 + echo "Successfully updated $grubconf." 50.66 + mv -f $tmpfile $grubconf 50.67 + fi 50.68 } 50.69 50.70 if [ "$1" == "" -o "$2" == "" ]; then 50.71 + echo "Error: Not enough command line parameters." 50.72 + echo "" 50.73 usage 50.74 exit -1 50.75 fi
51.1 --- a/tools/xenstore/Makefile Sun Oct 30 13:52:38 2005 +0100 51.2 +++ b/tools/xenstore/Makefile Sun Oct 30 14:00:35 2005 +0100 51.3 @@ -77,7 +77,7 @@ libxenstore.so: xs.opic xs_lib.opic 51.4 clean: testsuite-clean 51.5 rm -f *.o *.opic *.so 51.6 rm -f xenstored xs_random xs_stress xs_crashme 51.7 - rm -f xs_test xenstored_test 51.8 + rm -f xs_test xenstored_test xs_tdb_dump 51.9 $(RM) $(PROG_DEP) 51.10 51.11 print-dir:
52.1 --- a/xen/acm/acm_simple_type_enforcement_hooks.c Sun Oct 30 13:52:38 2005 +0100 52.2 +++ b/xen/acm/acm_simple_type_enforcement_hooks.c Sun Oct 30 14:00:35 2005 +0100 52.3 @@ -392,8 +392,11 @@ check_cache(struct domain *dom, domid_t 52.4 int i; 52.5 52.6 printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom); 52.7 + 52.8 + if (dom->ssid == NULL) 52.9 + return 0; 52.10 ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 52.11 - (struct acm_ssid_domain *)(dom)->ssid); 52.12 + (struct acm_ssid_domain *)(dom->ssid)); 52.13 52.14 for(i=0; i< ACM_TE_CACHE_SIZE; i++) { 52.15 if ((ste_ssid->ste_cache[i].valid == VALID) && 52.16 @@ -412,6 +415,8 @@ cache_result(struct domain *subj, struct 52.17 struct ste_ssid *ste_ssid; 52.18 int i; 52.19 printkd("caching from doms: %x --> %x.\n", subj->domain_id, obj->domain_id); 52.20 + if (subj->ssid == NULL) 52.21 + return; 52.22 ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 52.23 (struct acm_ssid_domain *)(subj)->ssid); 52.24 for(i=0; i< ACM_TE_CACHE_SIZE; i++) 52.25 @@ -431,26 +436,34 @@ clean_id_from_cache(domid_t id) 52.26 struct ste_ssid *ste_ssid; 52.27 int i; 52.28 struct domain **pd; 52.29 + struct acm_ssid_domain *ssid; 52.30 52.31 printkd("deleting cache for dom %x.\n", id); 52.32 - 52.33 read_lock(&domlist_lock); /* look through caches of all domains */ 52.34 pd = &domain_list; 52.35 for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) { 52.36 - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 52.37 - (struct acm_ssid_domain *)(*pd)->ssid); 52.38 + ssid = (struct acm_ssid_domain *)((*pd)->ssid); 52.39 + 52.40 + if (ssid == NULL) 52.41 + continue; /* hanging domain structure, no ssid any more ... */ 52.42 + ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssid); 52.43 + if (!ste_ssid) { 52.44 + printk("%s: deleting ID from cache ERROR (no ste_ssid)!\n", 52.45 + __func__); 52.46 + goto out; 52.47 + } 52.48 for (i=0; i<ACM_TE_CACHE_SIZE; i++) 52.49 if ((ste_ssid->ste_cache[i].valid == VALID) && 52.50 - (ste_ssid->ste_cache[i].id = id)) 52.51 + (ste_ssid->ste_cache[i].id == id)) 52.52 ste_ssid->ste_cache[i].valid = FREE; 52.53 } 52.54 + out: 52.55 read_unlock(&domlist_lock); 52.56 } 52.57 52.58 /*************************** 52.59 * Authorization functions 52.60 **************************/ 52.61 - 52.62 static int 52.63 ste_pre_domain_create(void *subject_ssid, ssidref_t ssidref) 52.64 { 52.65 @@ -484,44 +497,13 @@ ste_post_domain_destroy(void *subject_ss 52.66 52.67 /* -------- EVENTCHANNEL OPERATIONS -----------*/ 52.68 static int 52.69 -ste_pre_eventchannel_unbound(domid_t id) { 52.70 - struct domain *subj, *obj; 52.71 - int ret; 52.72 - traceprintk("%s: dom%x-->dom%x.\n", 52.73 - __func__, current->domain->domain_id, id); 52.74 - 52.75 - if (check_cache(current->domain, id)) { 52.76 - atomic_inc(&ste_bin_pol.ec_cachehit_count); 52.77 - return ACM_ACCESS_PERMITTED; 52.78 - } 52.79 - atomic_inc(&ste_bin_pol.ec_eval_count); 52.80 - subj = current->domain; 52.81 - obj = find_domain_by_id(id); 52.82 - 52.83 - if (share_common_type(subj, obj)) { 52.84 - cache_result(subj, obj); 52.85 - ret = ACM_ACCESS_PERMITTED; 52.86 - } else { 52.87 - atomic_inc(&ste_bin_pol.ec_denied_count); 52.88 - ret = ACM_ACCESS_DENIED; 52.89 - } 52.90 - if (obj != NULL) 52.91 - put_domain(obj); 52.92 - return ret; 52.93 -} 52.94 - 52.95 -static int 52.96 -ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2) 52.97 -{ 52.98 +ste_pre_eventchannel_unbound(domid_t id1, domid_t id2) { 52.99 struct domain *subj, *obj; 52.100 int ret; 52.101 traceprintk("%s: dom%x-->dom%x.\n", __func__, 52.102 (id1 == DOMID_SELF) ? current->domain->domain_id : id1, 52.103 (id2 == DOMID_SELF) ? current->domain->domain_id : id2); 52.104 52.105 - /* following is a bit longer but ensures that we 52.106 - * "put" only domains that we where "find"-ing 52.107 - */ 52.108 if (id1 == DOMID_SELF) id1 = current->domain->domain_id; 52.109 if (id2 == DOMID_SELF) id2 = current->domain->domain_id; 52.110 52.111 @@ -531,7 +513,7 @@ ste_pre_eventchannel_interdomain(domid_t 52.112 ret = ACM_ACCESS_DENIED; 52.113 goto out; 52.114 } 52.115 - /* cache check late, but evtchn is not on performance critical path */ 52.116 + /* cache check late */ 52.117 if (check_cache(subj, obj->domain_id)) { 52.118 atomic_inc(&ste_bin_pol.ec_cachehit_count); 52.119 ret = ACM_ACCESS_PERMITTED; 52.120 @@ -546,7 +528,7 @@ ste_pre_eventchannel_interdomain(domid_t 52.121 atomic_inc(&ste_bin_pol.ec_denied_count); 52.122 ret = ACM_ACCESS_DENIED; 52.123 } 52.124 - out: 52.125 + out: 52.126 if (obj != NULL) 52.127 put_domain(obj); 52.128 if (subj != NULL) 52.129 @@ -554,6 +536,50 @@ ste_pre_eventchannel_interdomain(domid_t 52.130 return ret; 52.131 } 52.132 52.133 +static int 52.134 +ste_pre_eventchannel_interdomain(domid_t id) 52.135 +{ 52.136 + struct domain *subj=NULL, *obj=NULL; 52.137 + int ret; 52.138 + 52.139 + traceprintk("%s: dom%x-->dom%x.\n", __func__, 52.140 + current->domain->domain_id, 52.141 + (id == DOMID_SELF) ? current->domain->domain_id : id); 52.142 + 52.143 + /* following is a bit longer but ensures that we 52.144 + * "put" only domains that we where "find"-ing 52.145 + */ 52.146 + if (id == DOMID_SELF) id = current->domain->domain_id; 52.147 + 52.148 + subj = current->domain; 52.149 + obj = find_domain_by_id(id); 52.150 + if (obj == NULL) { 52.151 + ret = ACM_ACCESS_DENIED; 52.152 + goto out; 52.153 + } 52.154 + 52.155 + /* cache check late, but evtchn is not on performance critical path */ 52.156 + if (check_cache(subj, obj->domain_id)) { 52.157 + atomic_inc(&ste_bin_pol.ec_cachehit_count); 52.158 + ret = ACM_ACCESS_PERMITTED; 52.159 + goto out; 52.160 + } 52.161 + 52.162 + atomic_inc(&ste_bin_pol.ec_eval_count); 52.163 + 52.164 + if (share_common_type(subj, obj)) { 52.165 + cache_result(subj, obj); 52.166 + ret = ACM_ACCESS_PERMITTED; 52.167 + } else { 52.168 + atomic_inc(&ste_bin_pol.ec_denied_count); 52.169 + ret = ACM_ACCESS_DENIED; 52.170 + } 52.171 + out: 52.172 + if (obj != NULL) 52.173 + put_domain(obj); 52.174 + return ret; 52.175 +} 52.176 + 52.177 /* -------- SHARED MEMORY OPERATIONS -----------*/ 52.178 52.179 static int
53.1 --- a/xen/arch/ia64/asm-offsets.c Sun Oct 30 13:52:38 2005 +0100 53.2 +++ b/xen/arch/ia64/asm-offsets.c Sun Oct 30 14:00:35 2005 +0100 53.3 @@ -59,6 +59,8 @@ void foo(void) 53.4 DEFINE(XSI_BANKNUM_OFS, offsetof(mapped_regs_t, banknum)); 53.5 DEFINE(XSI_BANK0_OFS, offsetof(mapped_regs_t, bank0_regs[0])); 53.6 DEFINE(XSI_BANK1_OFS, offsetof(mapped_regs_t, bank1_regs[0])); 53.7 + DEFINE(XSI_B0NATS_OFS, offsetof(mapped_regs_t, vbnat)); 53.8 + DEFINE(XSI_B1NATS_OFS, offsetof(mapped_regs_t, vnat)); 53.9 DEFINE(XSI_RR0_OFS, offsetof(mapped_regs_t, rrs[0])); 53.10 DEFINE(XSI_METAPHYS_OFS, offsetof(mapped_regs_t, metaphysical_mode)); 53.11 DEFINE(XSI_PRECOVER_IFS_OFS, offsetof(mapped_regs_t, precover_ifs)); 53.12 @@ -79,13 +81,17 @@ void foo(void) 53.13 //DEFINE(IA64_TASK_SIGHAND_OFFSET,offsetof (struct task_struct, sighand)); 53.14 //DEFINE(IA64_TASK_SIGNAL_OFFSET,offsetof (struct task_struct, signal)); 53.15 //DEFINE(IA64_TASK_TGID_OFFSET, offsetof (struct task_struct, tgid)); 53.16 + DEFINE(IA64_PGD, offsetof(struct domain, arch.mm)); 53.17 DEFINE(IA64_TASK_THREAD_KSP_OFFSET, offsetof (struct vcpu, arch._thread.ksp)); 53.18 DEFINE(IA64_TASK_THREAD_ON_USTACK_OFFSET, offsetof (struct vcpu, arch._thread.on_ustack)); 53.19 53.20 + DEFINE(IA64_VCPU_DOMAIN_OFFSET, offsetof (struct vcpu, domain)); 53.21 DEFINE(IA64_VCPU_META_RR0_OFFSET, offsetof (struct vcpu, arch.metaphysical_rr0)); 53.22 DEFINE(IA64_VCPU_META_SAVED_RR0_OFFSET, offsetof (struct vcpu, arch.metaphysical_saved_rr0)); 53.23 DEFINE(IA64_VCPU_BREAKIMM_OFFSET, offsetof (struct vcpu, arch.breakimm)); 53.24 DEFINE(IA64_VCPU_IVA_OFFSET, offsetof (struct vcpu, arch.iva)); 53.25 + DEFINE(IA64_VCPU_DTLB_PTE_OFFSET, offsetof (struct vcpu, arch.dtlb_pte)); 53.26 + DEFINE(IA64_VCPU_ITLB_PTE_OFFSET, offsetof (struct vcpu, arch.itlb_pte)); 53.27 DEFINE(IA64_VCPU_IRR0_OFFSET, offsetof (struct vcpu, arch.irr[0])); 53.28 DEFINE(IA64_VCPU_IRR3_OFFSET, offsetof (struct vcpu, arch.irr[3])); 53.29 DEFINE(IA64_VCPU_INSVC3_OFFSET, offsetof (struct vcpu, arch.insvc[3]));
54.1 --- a/xen/arch/ia64/linux-xen/entry.S Sun Oct 30 13:52:38 2005 +0100 54.2 +++ b/xen/arch/ia64/linux-xen/entry.S Sun Oct 30 14:00:35 2005 +0100 54.3 @@ -900,10 +900,17 @@ GLOBAL_ENTRY(ia64_leave_kernel) 54.4 adds r7 = PT(EML_UNAT)+16,r12 54.5 ;; 54.6 ld8 r7 = [r7] 54.7 + ;; 54.8 +#if 0 54.9 +leave_kernel_self: 54.10 + cmp.ne p8,p0 = r0, r7 54.11 +(p8) br.sptk.few leave_kernel_self 54.12 + ;; 54.13 +#endif 54.14 (p6) br.call.sptk.many b0=deliver_pending_interrupt 54.15 ;; 54.16 mov ar.pfs=loc0 54.17 - mov ar.unat=r7 /* load eml_unat */ 54.18 + mov ar.unat=r7 /* load eml_unat */ 54.19 mov r31=r0 54.20 54.21
55.1 --- a/xen/arch/ia64/linux-xen/head.S Sun Oct 30 13:52:38 2005 +0100 55.2 +++ b/xen/arch/ia64/linux-xen/head.S Sun Oct 30 14:00:35 2005 +0100 55.3 @@ -324,6 +324,9 @@ 1: // now we are in virtual mode 55.4 mov r16=-1 55.5 (isBP) br.cond.dpnt .load_current // BP stack is on region 5 --- no need to map it 55.6 55.7 +#ifndef XEN 55.8 + // XEN: stack is allocated in xenheap, which is currently always 55.9 + // mapped. 55.10 // load mapping for stack (virtaddr in r2, physaddr in r3) 55.11 rsm psr.ic 55.12 movl r17=PAGE_KERNEL 55.13 @@ -353,7 +356,8 @@ 1: // now we are in virtual mode 55.14 ssm psr.ic 55.15 srlz.d 55.16 ;; 55.17 - 55.18 +#endif 55.19 + 55.20 .load_current: 55.21 // load the "current" pointer (r13) and ar.k6 with the current task 55.22 #if defined(XEN) && defined(VALIDATE_VT)
56.1 --- a/xen/arch/ia64/linux-xen/irq_ia64.c Sun Oct 30 13:52:38 2005 +0100 56.2 +++ b/xen/arch/ia64/linux-xen/irq_ia64.c Sun Oct 30 14:00:35 2005 +0100 56.3 @@ -281,5 +281,8 @@ ia64_send_ipi (int cpu, int vector, int 56.4 ipi_data = (delivery_mode << 8) | (vector & 0xff); 56.5 ipi_addr = ipi_base_addr + ((phys_cpu_id << 4) | ((redirect & 1) << 3)); 56.6 56.7 +#ifdef XEN 56.8 + printf ("send_ipi to %d (%x)\n", cpu, phys_cpu_id); 56.9 +#endif 56.10 writeq(ipi_data, ipi_addr); 56.11 }
57.1 --- a/xen/arch/ia64/linux-xen/mm_contig.c Sun Oct 30 13:52:38 2005 +0100 57.2 +++ b/xen/arch/ia64/linux-xen/mm_contig.c Sun Oct 30 14:00:35 2005 +0100 57.3 @@ -193,8 +193,8 @@ per_cpu_init (void) 57.4 */ 57.5 if (smp_processor_id() == 0) { 57.6 #ifdef XEN 57.7 - cpu_data = alloc_xenheap_pages(PERCPU_PAGE_SHIFT - 57.8 - PAGE_SHIFT + get_order(NR_CPUS)); 57.9 + cpu_data = alloc_xenheap_pages(get_order(NR_CPUS 57.10 + * PERCPU_PAGE_SIZE)); 57.11 #else 57.12 cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS, 57.13 PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
58.1 --- a/xen/arch/ia64/linux-xen/setup.c Sun Oct 30 13:52:38 2005 +0100 58.2 +++ b/xen/arch/ia64/linux-xen/setup.c Sun Oct 30 14:00:35 2005 +0100 58.3 @@ -366,6 +366,7 @@ check_for_logical_procs (void) 58.4 } 58.5 #endif 58.6 58.7 +void __init 58.8 #ifdef XEN 58.9 early_setup_arch (char **cmdline_p) 58.10 #else 58.11 @@ -377,14 +378,12 @@ setup_arch (char **cmdline_p) 58.12 ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist); 58.13 58.14 *cmdline_p = __va(ia64_boot_param->command_line); 58.15 -#ifdef XEN 58.16 - efi_init(); 58.17 -#else 58.18 +#ifndef XEN 58.19 strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE); 58.20 +#endif 58.21 58.22 efi_init(); 58.23 io_port_init(); 58.24 -#endif 58.25 58.26 #ifdef CONFIG_IA64_GENERIC 58.27 { 58.28 @@ -414,11 +413,17 @@ setup_arch (char **cmdline_p) 58.29 #ifdef XEN 58.30 early_cmdline_parse(cmdline_p); 58.31 cmdline_parse(*cmdline_p); 58.32 -#undef CONFIG_ACPI_BOOT 58.33 #endif 58.34 if (early_console_setup(*cmdline_p) == 0) 58.35 mark_bsp_online(); 58.36 58.37 +#ifdef XEN 58.38 +} 58.39 + 58.40 +void __init 58.41 +late_setup_arch (char **cmdline_p) 58.42 +{ 58.43 +#endif 58.44 #ifdef CONFIG_ACPI_BOOT 58.45 /* Initialize the ACPI boot-time table parser */ 58.46 acpi_table_init(); 58.47 @@ -433,20 +438,16 @@ setup_arch (char **cmdline_p) 58.48 58.49 #ifndef XEN 58.50 find_memory(); 58.51 -#else 58.52 - io_port_init(); 58.53 -} 58.54 +#endif 58.55 58.56 -void __init 58.57 -late_setup_arch (char **cmdline_p) 58.58 -{ 58.59 -#undef CONFIG_ACPI_BOOT 58.60 - acpi_table_init(); 58.61 -#endif 58.62 /* process SAL system table: */ 58.63 ia64_sal_init(efi.sal_systab); 58.64 58.65 #ifdef CONFIG_SMP 58.66 +#ifdef XEN 58.67 + init_smp_config (); 58.68 +#endif 58.69 + 58.70 cpu_physical_id(0) = hard_smp_processor_id(); 58.71 58.72 cpu_set(0, cpu_sibling_map[0]); 58.73 @@ -768,6 +769,11 @@ cpu_init (void) 58.74 58.75 cpu_data = per_cpu_init(); 58.76 58.77 +#ifdef XEN 58.78 + printf ("cpu_init: current=%p, current->domain->arch.mm=%p\n", 58.79 + current, current->domain->arch.mm); 58.80 +#endif 58.81 + 58.82 /* 58.83 * We set ar.k3 so that assembly code in MCA handler can compute 58.84 * physical addresses of per cpu variables with a simple: 58.85 @@ -887,6 +893,16 @@ cpu_init (void) 58.86 #ifndef XEN 58.87 pm_idle = default_idle; 58.88 #endif 58.89 + 58.90 +#ifdef XEN 58.91 + /* surrender usage of kernel registers to domain, use percpu area instead */ 58.92 + __get_cpu_var(cpu_kr)._kr[IA64_KR_IO_BASE] = ia64_get_kr(IA64_KR_IO_BASE); 58.93 + __get_cpu_var(cpu_kr)._kr[IA64_KR_PER_CPU_DATA] = ia64_get_kr(IA64_KR_PER_CPU_DATA); 58.94 + __get_cpu_var(cpu_kr)._kr[IA64_KR_CURRENT_STACK] = ia64_get_kr(IA64_KR_CURRENT_STACK); 58.95 + __get_cpu_var(cpu_kr)._kr[IA64_KR_FPU_OWNER] = ia64_get_kr(IA64_KR_FPU_OWNER); 58.96 + __get_cpu_var(cpu_kr)._kr[IA64_KR_CURRENT] = ia64_get_kr(IA64_KR_CURRENT); 58.97 + __get_cpu_var(cpu_kr)._kr[IA64_KR_PT_BASE] = ia64_get_kr(IA64_KR_PT_BASE); 58.98 +#endif 58.99 } 58.100 58.101 void
59.1 --- a/xen/arch/ia64/linux-xen/smp.c Sun Oct 30 13:52:38 2005 +0100 59.2 +++ b/xen/arch/ia64/linux-xen/smp.c Sun Oct 30 14:00:35 2005 +0100 59.3 @@ -63,9 +63,18 @@ void flush_tlb_mask(cpumask_t mask) 59.4 //Huh? This seems to be used on ia64 even if !CONFIG_SMP 59.5 void smp_send_event_check_mask(cpumask_t mask) 59.6 { 59.7 - printf("smp_send_event_check_mask called\n"); 59.8 - //dummy(); 59.9 - //send_IPI_mask(cpu_mask, EVENT_CHECK_VECTOR); 59.10 + int cpu; 59.11 + 59.12 + /* Not for me. */ 59.13 + cpu_clear(smp_processor_id(), mask); 59.14 + if (cpus_empty(mask)) 59.15 + return; 59.16 + 59.17 + printf("smp_send_event_check_mask called\n"); 59.18 + 59.19 + for (cpu = 0; cpu < NR_CPUS; ++cpu) 59.20 + if (cpu_isset(cpu, mask)) 59.21 + platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0); 59.22 } 59.23 59.24 59.25 @@ -249,6 +258,7 @@ send_IPI_self (int op) 59.26 send_IPI_single(smp_processor_id(), op); 59.27 } 59.28 59.29 +#ifndef XEN 59.30 /* 59.31 * Called with preeemption disabled. 59.32 */ 59.33 @@ -257,6 +267,7 @@ smp_send_reschedule (int cpu) 59.34 { 59.35 platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0); 59.36 } 59.37 +#endif 59.38 59.39 void 59.40 smp_flush_tlb_all (void) 59.41 @@ -395,15 +406,14 @@ smp_call_function (void (*func) (void *i 59.42 if (wait) 59.43 atomic_set(&data.finished, 0); 59.44 59.45 - printk("smp_call_function: about to spin_lock \n"); 59.46 spin_lock(&call_lock); 59.47 - printk("smp_call_function: done with spin_lock \n"); 59.48 +#if 0 //def XEN 59.49 + printk("smp_call_function: %d lock\n", smp_processor_id ()); 59.50 +#endif 59.51 59.52 call_data = &data; 59.53 mb(); /* ensure store to call_data precedes setting of IPI_CALL_FUNC */ 59.54 - printk("smp_call_function: about to send_IPI \n"); 59.55 send_IPI_allbutself(IPI_CALL_FUNC); 59.56 - printk("smp_call_function: done with send_IPI \n"); 59.57 59.58 /* Wait for response */ 59.59 while (atomic_read(&data.started) != cpus) 59.60 @@ -414,9 +424,10 @@ smp_call_function (void (*func) (void *i 59.61 cpu_relax(); 59.62 call_data = NULL; 59.63 59.64 - printk("smp_call_function: about to spin_unlock \n"); 59.65 spin_unlock(&call_lock); 59.66 +#if 0 //def XEN 59.67 printk("smp_call_function: DONE WITH spin_unlock, returning \n"); 59.68 +#endif 59.69 return 0; 59.70 } 59.71 EXPORT_SYMBOL(smp_call_function);
60.1 --- a/xen/arch/ia64/linux-xen/smpboot.c Sun Oct 30 13:52:38 2005 +0100 60.2 +++ b/xen/arch/ia64/linux-xen/smpboot.c Sun Oct 30 14:00:35 2005 +0100 60.3 @@ -477,6 +477,22 @@ do_boot_cpu (int sapicid, int cpu) 60.4 60.5 do_rest: 60.6 task_for_booting_cpu = c_idle.idle; 60.7 +#else 60.8 + struct domain *idle; 60.9 + struct vcpu *v; 60.10 + void *stack; 60.11 + 60.12 + if ( (idle = do_createdomain(IDLE_DOMAIN_ID, cpu)) == NULL ) 60.13 + panic("failed 'createdomain' for CPU %d", cpu); 60.14 + set_bit(_DOMF_idle_domain, &idle->domain_flags); 60.15 + v = idle->vcpu[0]; 60.16 + 60.17 + printf ("do_boot_cpu: cpu=%d, domain=%p, vcpu=%p\n", cpu, idle, v); 60.18 + 60.19 + task_for_booting_cpu = v; 60.20 + 60.21 + /* Set cpu number. */ 60.22 + get_thread_info(v)->cpu = cpu; 60.23 #endif 60.24 60.25 Dprintk("Sending wakeup vector %lu to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid);
61.1 --- a/xen/arch/ia64/vmx/mm.c Sun Oct 30 13:52:38 2005 +0100 61.2 +++ b/xen/arch/ia64/vmx/mm.c Sun Oct 30 14:00:35 2005 +0100 61.3 @@ -87,7 +87,7 @@ 61.4 */ 61.5 61.6 #include <xen/config.h> 61.7 -#include <public/xen.h> 61.8 +//#include <public/xen.h> 61.9 #include <xen/init.h> 61.10 #include <xen/lib.h> 61.11 #include <xen/mm.h>
62.1 --- a/xen/arch/ia64/vmx/vmx_entry.S Sun Oct 30 13:52:38 2005 +0100 62.2 +++ b/xen/arch/ia64/vmx/vmx_entry.S Sun Oct 30 14:00:35 2005 +0100 62.3 @@ -720,11 +720,11 @@ 1: 62.4 62.5 // re-pin mappings for guest_vhpt 62.6 62.7 - mov r24=IA64_TR_VHPT 62.8 + mov r24=IA64_TR_PERVP_VHPT 62.9 movl r25=PAGE_KERNEL 62.10 ;; 62.11 or loc5 = r25,loc5 // construct PA | page properties 62.12 - mov r23 = VCPU_TLB_SHIFT<<2 62.13 + mov r23 = IA64_GRANULE_SHIFT <<2 62.14 ;; 62.15 ptr.d in3,r23 62.16 ;;
63.1 --- a/xen/arch/ia64/vmx/vmx_hypercall.c Sun Oct 30 13:52:38 2005 +0100 63.2 +++ b/xen/arch/ia64/vmx/vmx_hypercall.c Sun Oct 30 14:00:35 2005 +0100 63.3 @@ -22,7 +22,7 @@ 63.4 #include <xen/config.h> 63.5 #include <xen/errno.h> 63.6 #include <asm/vmx_vcpu.h> 63.7 -#include <public/xen.h> 63.8 +//#include <public/xen.h> 63.9 #include <public/event_channel.h> 63.10 #include <asm/vmmu.h> 63.11 #include <asm/tlb.h>
64.1 --- a/xen/arch/ia64/vmx/vmx_init.c Sun Oct 30 13:52:38 2005 +0100 64.2 +++ b/xen/arch/ia64/vmx/vmx_init.c Sun Oct 30 14:00:35 2005 +0100 64.3 @@ -47,6 +47,7 @@ 64.4 #include <asm/processor.h> 64.5 #include <asm/vmx.h> 64.6 #include <xen/mm.h> 64.7 +#include <public/arch-ia64.h> 64.8 64.9 /* Global flag to identify whether Intel vmx feature is on */ 64.10 u32 vmx_enabled = 0; 64.11 @@ -136,39 +137,6 @@ vmx_init_env(void) 64.12 #endif 64.13 } 64.14 64.15 -void vmx_setup_platform(struct vcpu *v, struct vcpu_guest_context *c) 64.16 -{ 64.17 - struct domain *d = v->domain; 64.18 - shared_iopage_t *sp; 64.19 - 64.20 - ASSERT(d != dom0); /* only for non-privileged vti domain */ 64.21 - d->arch.vmx_platform.shared_page_va = __va(c->share_io_pg); 64.22 - sp = get_sp(d); 64.23 - memset((char *)sp,0,PAGE_SIZE); 64.24 - /* FIXME: temp due to old CP */ 64.25 - sp->sp_global.eport = 2; 64.26 -#ifdef V_IOSAPIC_READY 64.27 - sp->vcpu_number = 1; 64.28 -#endif 64.29 - /* TEMP */ 64.30 - d->arch.vmx_platform.pib_base = 0xfee00000UL; 64.31 - 64.32 - /* One more step to enable interrupt assist */ 64.33 - set_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags); 64.34 - /* Only open one port for I/O and interrupt emulation */ 64.35 - if (v == d->vcpu[0]) { 64.36 - memset(&d->shared_info->evtchn_mask[0], 0xff, 64.37 - sizeof(d->shared_info->evtchn_mask)); 64.38 - clear_bit(iopacket_port(d), &d->shared_info->evtchn_mask[0]); 64.39 - } 64.40 - 64.41 - /* FIXME: only support PMT table continuously by far */ 64.42 -// d->arch.pmt = __va(c->pt_base); 64.43 - 64.44 - 64.45 - vmx_final_setup_domain(d); 64.46 -} 64.47 - 64.48 typedef union { 64.49 u64 value; 64.50 struct { 64.51 @@ -376,40 +344,6 @@ vmx_final_setup_domain(struct domain *d) 64.52 /* Other vmx specific initialization work */ 64.53 } 64.54 64.55 -/* 64.56 - * Following stuff should really move to domain builder. However currently 64.57 - * XEN/IA64 doesn't export physical -> machine page table to domain builder, 64.58 - * instead only the copy. Also there's no hypercall to notify hypervisor 64.59 - * IO ranges by far. Let's enhance it later. 64.60 - */ 64.61 - 64.62 -#define MEM_G (1UL << 30) 64.63 -#define MEM_M (1UL << 20) 64.64 - 64.65 -#define MMIO_START (3 * MEM_G) 64.66 -#define MMIO_SIZE (512 * MEM_M) 64.67 - 64.68 -#define VGA_IO_START 0xA0000UL 64.69 -#define VGA_IO_SIZE 0x20000 64.70 - 64.71 -#define LEGACY_IO_START (MMIO_START + MMIO_SIZE) 64.72 -#define LEGACY_IO_SIZE (64*MEM_M) 64.73 - 64.74 -#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE) 64.75 -#define IO_PAGE_SIZE PAGE_SIZE 64.76 - 64.77 -#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE) 64.78 -#define STORE_PAGE_SIZE PAGE_SIZE 64.79 - 64.80 -#define IO_SAPIC_START 0xfec00000UL 64.81 -#define IO_SAPIC_SIZE 0x100000 64.82 - 64.83 -#define PIB_START 0xfee00000UL 64.84 -#define PIB_SIZE 0x100000 64.85 - 64.86 -#define GFW_START (4*MEM_G -16*MEM_M) 64.87 -#define GFW_SIZE (16*MEM_M) 64.88 - 64.89 typedef struct io_range { 64.90 unsigned long start; 64.91 unsigned long size; 64.92 @@ -424,18 +358,26 @@ io_range_t io_ranges[] = { 64.93 {PIB_START, PIB_SIZE, GPFN_PIB}, 64.94 }; 64.95 64.96 -#define VMX_SYS_PAGES (2 + GFW_SIZE >> PAGE_SHIFT) 64.97 +#define VMX_SYS_PAGES (2 + (GFW_SIZE >> PAGE_SHIFT)) 64.98 #define VMX_CONFIG_PAGES(d) ((d)->max_pages - VMX_SYS_PAGES) 64.99 64.100 int vmx_alloc_contig_pages(struct domain *d) 64.101 { 64.102 - unsigned int order, i, j; 64.103 - unsigned long start, end, pgnr, conf_nr; 64.104 + unsigned int order; 64.105 + unsigned long i, j, start, end, pgnr, conf_nr; 64.106 struct pfn_info *page; 64.107 struct vcpu *v = d->vcpu[0]; 64.108 64.109 ASSERT(!test_bit(ARCH_VMX_CONTIG_MEM, &v->arch.arch_vmx.flags)); 64.110 64.111 + /* Mark I/O ranges */ 64.112 + for (i = 0; i < (sizeof(io_ranges) / sizeof(io_range_t)); i++) { 64.113 + for (j = io_ranges[i].start; 64.114 + j < io_ranges[i].start + io_ranges[i].size; 64.115 + j += PAGE_SIZE) 64.116 + map_domain_page(d, j, io_ranges[i].type); 64.117 + } 64.118 + 64.119 conf_nr = VMX_CONFIG_PAGES(d); 64.120 order = get_order_from_pages(conf_nr); 64.121 if (unlikely((page = alloc_domheap_pages(d, order, 0)) == NULL)) { 64.122 @@ -462,32 +404,64 @@ int vmx_alloc_contig_pages(struct domain 64.123 64.124 d->arch.max_pfn = end >> PAGE_SHIFT; 64.125 64.126 - order = get_order_from_pages(VMX_SYS_PAGES); 64.127 + order = get_order_from_pages(GFW_SIZE >> PAGE_SHIFT); 64.128 if (unlikely((page = alloc_domheap_pages(d, order, 0)) == NULL)) { 64.129 printk("Could not allocate order=%d pages for vmx contig alloc\n", 64.130 order); 64.131 return -1; 64.132 } 64.133 64.134 + /* Map guest firmware */ 64.135 + pgnr = page_to_pfn(page); 64.136 + for (i = GFW_START; i < GFW_START + GFW_SIZE; i += PAGE_SIZE, pgnr++) 64.137 + map_domain_page(d, i, pgnr << PAGE_SHIFT); 64.138 + 64.139 + if (unlikely((page = alloc_domheap_pages(d, 1, 0)) == NULL)) { 64.140 + printk("Could not allocate order=1 pages for vmx contig alloc\n"); 64.141 + return -1; 64.142 + } 64.143 + 64.144 /* Map for shared I/O page and xenstore */ 64.145 pgnr = page_to_pfn(page); 64.146 map_domain_page(d, IO_PAGE_START, pgnr << PAGE_SHIFT); 64.147 pgnr++; 64.148 map_domain_page(d, STORE_PAGE_START, pgnr << PAGE_SHIFT); 64.149 - pgnr++; 64.150 - 64.151 - /* Map guest firmware */ 64.152 - for (i = GFW_START; i < GFW_START + GFW_SIZE; i += PAGE_SIZE, pgnr++) 64.153 - map_domain_page(d, i, pgnr << PAGE_SHIFT); 64.154 - 64.155 - /* Mark I/O ranges */ 64.156 - for (i = 0; i < (sizeof(io_ranges) / sizeof(io_range_t)); i++) { 64.157 - for (j = io_ranges[i].start; 64.158 - j < io_ranges[i].start + io_ranges[i].size; 64.159 - j += PAGE_SIZE) 64.160 - map_domain_page(d, j, io_ranges[i].type); 64.161 - } 64.162 64.163 set_bit(ARCH_VMX_CONTIG_MEM, &v->arch.arch_vmx.flags); 64.164 return 0; 64.165 } 64.166 + 64.167 +void vmx_setup_platform(struct vcpu *v, struct vcpu_guest_context *c) 64.168 +{ 64.169 + struct domain *d = v->domain; 64.170 + shared_iopage_t *sp; 64.171 + 64.172 + ASSERT(d != dom0); /* only for non-privileged vti domain */ 64.173 + d->arch.vmx_platform.shared_page_va = 64.174 + __va(__gpa_to_mpa(d, IO_PAGE_START)); 64.175 + sp = get_sp(d); 64.176 + //memset((char *)sp,0,PAGE_SIZE); 64.177 + //sp->sp_global.eport = 2; 64.178 +#ifdef V_IOSAPIC_READY 64.179 + sp->vcpu_number = 1; 64.180 +#endif 64.181 + /* TEMP */ 64.182 + d->arch.vmx_platform.pib_base = 0xfee00000UL; 64.183 + 64.184 + /* One more step to enable interrupt assist */ 64.185 + set_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags); 64.186 + /* Only open one port for I/O and interrupt emulation */ 64.187 + if (v == d->vcpu[0]) { 64.188 + memset(&d->shared_info->evtchn_mask[0], 0xff, 64.189 + sizeof(d->shared_info->evtchn_mask)); 64.190 + clear_bit(iopacket_port(d), &d->shared_info->evtchn_mask[0]); 64.191 + } 64.192 + 64.193 + /* FIXME: only support PMT table continuously by far */ 64.194 +// d->arch.pmt = __va(c->pt_base); 64.195 + 64.196 + 64.197 + vmx_final_setup_domain(d); 64.198 +} 64.199 + 64.200 +
65.1 --- a/xen/arch/ia64/vmx/vmx_irq_ia64.c Sun Oct 30 13:52:38 2005 +0100 65.2 +++ b/xen/arch/ia64/vmx/vmx_irq_ia64.c Sun Oct 30 14:00:35 2005 +0100 65.3 @@ -101,7 +101,10 @@ vmx_ia64_handle_irq (ia64_vector vector, 65.4 65.5 if (vector != IA64_TIMER_VECTOR) { 65.6 /* FIXME: Leave IRQ re-route later */ 65.7 - vmx_vcpu_pend_interrupt(dom0->vcpu[0],vector); 65.8 + if (!VMX_DOMAIN(dom0->vcpu[0])) 65.9 + vcpu_pend_interrupt(dom0->vcpu[0],vector); 65.10 + else 65.11 + vmx_vcpu_pend_interrupt(dom0->vcpu[0],vector); 65.12 wake_dom0 = 1; 65.13 } 65.14 else { // FIXME: Handle Timer only now
66.1 --- a/xen/arch/ia64/vmx/vmx_phy_mode.c Sun Oct 30 13:52:38 2005 +0100 66.2 +++ b/xen/arch/ia64/vmx/vmx_phy_mode.c Sun Oct 30 14:00:35 2005 +0100 66.3 @@ -157,13 +157,6 @@ physical_itlb_miss_domn(VCPU *vcpu, u64 66.4 #endif 66.5 66.6 void 66.7 -physical_itlb_miss(VCPU *vcpu, u64 vadr) 66.8 -{ 66.9 - physical_itlb_miss_dom0(vcpu, vadr); 66.10 -} 66.11 - 66.12 - 66.13 -void 66.14 physical_itlb_miss_dom0(VCPU *vcpu, u64 vadr) 66.15 { 66.16 u64 psr; 66.17 @@ -187,6 +180,13 @@ physical_itlb_miss_dom0(VCPU *vcpu, u64 66.18 66.19 66.20 void 66.21 +physical_itlb_miss(VCPU *vcpu, u64 vadr) 66.22 +{ 66.23 + physical_itlb_miss_dom0(vcpu, vadr); 66.24 +} 66.25 + 66.26 + 66.27 +void 66.28 physical_dtlb_miss(VCPU *vcpu, u64 vadr) 66.29 { 66.30 u64 psr;
67.1 --- a/xen/arch/ia64/vmx/vmx_process.c Sun Oct 30 13:52:38 2005 +0100 67.2 +++ b/xen/arch/ia64/vmx/vmx_process.c Sun Oct 30 14:00:35 2005 +0100 67.3 @@ -56,6 +56,38 @@ extern struct ia64_sal_retval pal_emulat 67.4 extern struct ia64_sal_retval sal_emulator(UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64); 67.5 extern void rnat_consumption (VCPU *vcpu); 67.6 #define DOMN_PAL_REQUEST 0x110000 67.7 + 67.8 +static UINT64 vec2off[68] = {0x0,0x400,0x800,0xc00,0x1000, 0x1400,0x1800, 67.9 + 0x1c00,0x2000,0x2400,0x2800,0x2c00,0x3000,0x3400,0x3800,0x3c00,0x4000, 67.10 + 0x4400,0x4800,0x4c00,0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600, 67.11 + 0x5700,0x5800,0x5900,0x5a00,0x5b00,0x5c00,0x5d00,0x5e00,0x5f00,0x6000, 67.12 + 0x6100,0x6200,0x6300,0x6400,0x6500,0x6600,0x6700,0x6800,0x6900,0x6a00, 67.13 + 0x6b00,0x6c00,0x6d00,0x6e00,0x6f00,0x7000,0x7100,0x7200,0x7300,0x7400, 67.14 + 0x7500,0x7600,0x7700,0x7800,0x7900,0x7a00,0x7b00,0x7c00,0x7d00,0x7e00, 67.15 + 0x7f00, 67.16 +}; 67.17 + 67.18 + 67.19 + 67.20 +void vmx_reflect_interruption(UINT64 ifa,UINT64 isr,UINT64 iim, 67.21 + UINT64 vector,REGS *regs) 67.22 +{ 67.23 + VCPU *vcpu = current; 67.24 + UINT64 viha,vpsr = vmx_vcpu_get_psr(vcpu); 67.25 + if(!(vpsr&IA64_PSR_IC)&&(vector!=5)){ 67.26 + panic("Guest nested fault!"); 67.27 + } 67.28 + VCPU(vcpu,isr)=isr; 67.29 + VCPU(vcpu,iipa) = regs->cr_iip; 67.30 + vector=vec2off[vector]; 67.31 + if (vector == IA64_BREAK_VECTOR || vector == IA64_SPECULATION_VECTOR) 67.32 + VCPU(vcpu,iim) = iim; 67.33 + else { 67.34 + set_ifa_itir_iha(vcpu,ifa,1,1,1); 67.35 + } 67.36 + inject_guest_interruption(vcpu, vector); 67.37 +} 67.38 + 67.39 IA64FAULT 67.40 vmx_ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long isr, unsigned long iim) 67.41 { 67.42 @@ -157,37 +189,6 @@ vmx_ia64_handle_break (unsigned long ifa 67.43 vmx_reflect_interruption(ifa,isr,iim,11,regs); 67.44 } 67.45 67.46 -static UINT64 vec2off[68] = {0x0,0x400,0x800,0xc00,0x1000, 0x1400,0x1800, 67.47 - 0x1c00,0x2000,0x2400,0x2800,0x2c00,0x3000,0x3400,0x3800,0x3c00,0x4000, 67.48 - 0x4400,0x4800,0x4c00,0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600, 67.49 - 0x5700,0x5800,0x5900,0x5a00,0x5b00,0x5c00,0x5d00,0x5e00,0x5f00,0x6000, 67.50 - 0x6100,0x6200,0x6300,0x6400,0x6500,0x6600,0x6700,0x6800,0x6900,0x6a00, 67.51 - 0x6b00,0x6c00,0x6d00,0x6e00,0x6f00,0x7000,0x7100,0x7200,0x7300,0x7400, 67.52 - 0x7500,0x7600,0x7700,0x7800,0x7900,0x7a00,0x7b00,0x7c00,0x7d00,0x7e00, 67.53 - 0x7f00, 67.54 -}; 67.55 - 67.56 - 67.57 - 67.58 -void vmx_reflect_interruption(UINT64 ifa,UINT64 isr,UINT64 iim, 67.59 - UINT64 vector,REGS *regs) 67.60 -{ 67.61 - VCPU *vcpu = current; 67.62 - UINT64 viha,vpsr = vmx_vcpu_get_psr(vcpu); 67.63 - if(!(vpsr&IA64_PSR_IC)&&(vector!=5)){ 67.64 - panic("Guest nested fault!"); 67.65 - } 67.66 - VCPU(vcpu,isr)=isr; 67.67 - VCPU(vcpu,iipa) = regs->cr_iip; 67.68 - vector=vec2off[vector]; 67.69 - if (vector == IA64_BREAK_VECTOR || vector == IA64_SPECULATION_VECTOR) 67.70 - VCPU(vcpu,iim) = iim; 67.71 - else { 67.72 - set_ifa_itir_iha(vcpu,ifa,1,1,1); 67.73 - } 67.74 - inject_guest_interruption(vcpu, vector); 67.75 -} 67.76 - 67.77 67.78 void save_banked_regs_to_vpd(VCPU *v, REGS *regs) 67.79 { 67.80 @@ -271,10 +272,10 @@ void vmx_hpw_miss(u64 vadr , u64 vec, RE 67.81 { 67.82 IA64_PSR vpsr; 67.83 CACHE_LINE_TYPE type; 67.84 - u64 vhpt_adr; 67.85 + u64 vhpt_adr, gppa; 67.86 ISR misr; 67.87 ia64_rr vrr; 67.88 - REGS *regs; 67.89 +// REGS *regs; 67.90 thash_cb_t *vtlb, *vhpt; 67.91 thash_data_t *data, me; 67.92 VCPU *v = current; 67.93 @@ -314,9 +315,9 @@ void vmx_hpw_miss(u64 vadr , u64 vec, RE 67.94 // prepare_if_physical_mode(v); 67.95 67.96 if(data=vtlb_lookup_ex(vtlb, vrr.rid, vadr,type)){ 67.97 - if(v->domain!=dom0&&type==DSIDE_TLB && __gpfn_is_io(v->domain,data->ppn>>(PAGE_SHIFT-12))){ 67.98 - vadr=(vadr&((1UL<<data->ps)-1))+(data->ppn>>(data->ps-12)<<data->ps); 67.99 - emulate_io_inst(v, vadr, data->ma); 67.100 + gppa = (vadr&((1UL<<data->ps)-1))+(data->ppn>>(data->ps-12)<<data->ps); 67.101 + if(v->domain!=dom0&&type==DSIDE_TLB && __gpfn_is_io(v->domain,gppa>>PAGE_SHIFT)){ 67.102 + emulate_io_inst(v, gppa, data->ma); 67.103 return IA64_FAULT; 67.104 } 67.105
68.1 --- a/xen/arch/ia64/vmx/vmx_support.c Sun Oct 30 13:52:38 2005 +0100 68.2 +++ b/xen/arch/ia64/vmx/vmx_support.c Sun Oct 30 14:00:35 2005 +0100 68.3 @@ -158,7 +158,7 @@ void vmx_intr_assist(struct vcpu *v) 68.4 #ifdef V_IOSAPIC_READY 68.5 vlapic_update_ext_irq(v); 68.6 #else 68.7 - panic("IOSAPIC model is missed in qemu\n"); 68.8 + //panic("IOSAPIC model is missed in qemu\n"); 68.9 #endif 68.10 return; 68.11 }
69.1 --- a/xen/arch/ia64/vmx/vtlb.c Sun Oct 30 13:52:38 2005 +0100 69.2 +++ b/xen/arch/ia64/vmx/vtlb.c Sun Oct 30 14:00:35 2005 +0100 69.3 @@ -387,6 +387,15 @@ void vtlb_insert(thash_cb_t *hcb, thash_ 69.4 thash_insert(hcb->ts->vhpt, entry, va); 69.5 return; 69.6 } 69.7 + 69.8 +#if 1 69.9 + vrr=vmx_vcpu_rr(current, va); 69.10 + if (vrr.ps != entry->ps) { 69.11 + printk("not preferred ps with va: 0x%lx\n", va); 69.12 + return; 69.13 + } 69.14 +#endif 69.15 + 69.16 flag = 1; 69.17 gppn = (POFFSET(va,entry->ps)|PAGEALIGN((entry->ppn<<12),entry->ps))>>PAGE_SHIFT; 69.18 ppns = PAGEALIGN((entry->ppn<<12),entry->ps);
70.1 --- a/xen/arch/ia64/xen/acpi.c Sun Oct 30 13:52:38 2005 +0100 70.2 +++ b/xen/arch/ia64/xen/acpi.c Sun Oct 30 14:00:35 2005 +0100 70.3 @@ -121,6 +121,7 @@ acpi_get_sysname (void) 70.4 #ifdef CONFIG_ACPI_BOOT 70.5 70.6 #define ACPI_MAX_PLATFORM_INTERRUPTS 256 70.7 +#define NR_IOSAPICS 4 70.8 70.9 #if 0 70.10 /* Array to record platform interrupt vectors for generic interrupt routing. */ 70.11 @@ -162,7 +163,6 @@ static int available_cpus __initdata; 70.12 struct acpi_table_madt * acpi_madt __initdata; 70.13 static u8 has_8259; 70.14 70.15 -#if 0 70.16 static int __init 70.17 acpi_parse_lapic_addr_ovr ( 70.18 acpi_table_entry_header *header, const unsigned long end) 70.19 @@ -247,12 +247,13 @@ acpi_parse_iosapic (acpi_table_entry_hea 70.20 70.21 acpi_table_print_madt_entry(header); 70.22 70.23 +#if 0 70.24 iosapic_init(iosapic->address, iosapic->global_irq_base); 70.25 +#endif 70.26 70.27 return 0; 70.28 } 70.29 70.30 - 70.31 static int __init 70.32 acpi_parse_plat_int_src ( 70.33 acpi_table_entry_header *header, const unsigned long end) 70.34 @@ -267,6 +268,7 @@ acpi_parse_plat_int_src ( 70.35 70.36 acpi_table_print_madt_entry(header); 70.37 70.38 +#if 0 70.39 /* 70.40 * Get vector assignment for this interrupt, set attributes, 70.41 * and program the IOSAPIC routing table. 70.42 @@ -280,6 +282,7 @@ acpi_parse_plat_int_src ( 70.43 (plintsrc->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); 70.44 70.45 platform_intr_list[plintsrc->type] = vector; 70.46 +#endif 70.47 return 0; 70.48 } 70.49 70.50 @@ -297,13 +300,14 @@ acpi_parse_int_src_ovr ( 70.51 70.52 acpi_table_print_madt_entry(header); 70.53 70.54 +#if 0 70.55 iosapic_override_isa_irq(p->bus_irq, p->global_irq, 70.56 (p->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, 70.57 (p->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); 70.58 +#endif 70.59 return 0; 70.60 } 70.61 70.62 - 70.63 static int __init 70.64 acpi_parse_nmi_src (acpi_table_entry_header *header, const unsigned long end) 70.65 { 70.66 @@ -331,8 +335,10 @@ void __init acpi_madt_oem_check(char *oe 70.67 */ 70.68 sal_platform_features |= IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT; 70.69 70.70 +#if 0 70.71 /*Start cyclone clock*/ 70.72 cyclone_setup(0); 70.73 +#endif 70.74 } 70.75 } 70.76 70.77 @@ -350,7 +356,9 @@ acpi_parse_madt (unsigned long phys_addr 70.78 #else 70.79 has_8259 = acpi_madt->flags.pcat_compat; 70.80 #endif 70.81 +#if 0 70.82 iosapic_system_init(has_8259); 70.83 +#endif 70.84 70.85 /* Get base address of IPI Message Block */ 70.86 70.87 @@ -364,7 +372,6 @@ acpi_parse_madt (unsigned long phys_addr 70.88 70.89 return 0; 70.90 } 70.91 -#endif 70.92 70.93 #ifdef CONFIG_ACPI_NUMA 70.94 70.95 @@ -529,6 +536,7 @@ acpi_register_gsi (u32 gsi, int polarity 70.96 return acpi_register_irq(gsi, polarity, trigger); 70.97 } 70.98 EXPORT_SYMBOL(acpi_register_gsi); 70.99 +#endif 70.100 static int __init 70.101 acpi_parse_fadt (unsigned long phys_addr, unsigned long size) 70.102 { 70.103 @@ -550,10 +558,11 @@ acpi_parse_fadt (unsigned long phys_addr 70.104 if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES) 70.105 acpi_legacy_devices = 1; 70.106 70.107 +#if 0 70.108 acpi_register_gsi(fadt->sci_int, ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE); 70.109 +#endif 70.110 return 0; 70.111 } 70.112 -#endif 70.113 70.114 unsigned long __init 70.115 acpi_find_rsdp (void) 70.116 @@ -567,7 +576,6 @@ acpi_find_rsdp (void) 70.117 return rsdp_phys; 70.118 } 70.119 70.120 -#if 0 70.121 int __init 70.122 acpi_boot_init (void) 70.123 { 70.124 @@ -646,6 +654,7 @@ acpi_boot_init (void) 70.125 printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus); 70.126 return 0; 70.127 } 70.128 +#if 0 70.129 int 70.130 acpi_gsi_to_irq (u32 gsi, unsigned int *irq) 70.131 {
71.1 --- a/xen/arch/ia64/xen/dom0_ops.c Sun Oct 30 13:52:38 2005 +0100 71.2 +++ b/xen/arch/ia64/xen/dom0_ops.c Sun Oct 30 14:00:35 2005 +0100 71.3 @@ -177,13 +177,8 @@ long arch_do_dom0_op(dom0_op_t *op, dom0 71.4 71.5 for ( i = start_page; i < (start_page + nr_pages); i++ ) 71.6 { 71.7 - page = map_new_domain_page(d, i << PAGE_SHIFT); 71.8 - if ( page == NULL ) 71.9 - { 71.10 - ret = -ENOMEM; 71.11 - break; 71.12 - } 71.13 - pfn = page_to_pfn(page); 71.14 + pfn = __gpfn_to_mfn_foreign(d, i); 71.15 + 71.16 if ( put_user(pfn, buffer) ) 71.17 { 71.18 ret = -EFAULT;
72.1 --- a/xen/arch/ia64/xen/dom_fw.c Sun Oct 30 13:52:38 2005 +0100 72.2 +++ b/xen/arch/ia64/xen/dom_fw.c Sun Oct 30 14:00:35 2005 +0100 72.3 @@ -301,7 +301,7 @@ xen_pal_emulator(unsigned long index, un 72.4 // pal code must be mapped by a TR when pal is called, however 72.5 // calls are rare enough that we will map it lazily rather than 72.6 // at every context switch 72.7 - efi_map_pal_code(); 72.8 + //efi_map_pal_code(); 72.9 switch (index) { 72.10 case PAL_MEM_ATTRIB: 72.11 status = ia64_pal_mem_attrib(&r9);
73.1 --- a/xen/arch/ia64/xen/domain.c Sun Oct 30 13:52:38 2005 +0100 73.2 +++ b/xen/arch/ia64/xen/domain.c Sun Oct 30 14:00:35 2005 +0100 73.3 @@ -23,11 +23,13 @@ 73.4 #include <asm/io.h> 73.5 #include <asm/processor.h> 73.6 #include <asm/desc.h> 73.7 +#include <asm/hw_irq.h> 73.8 //#include <asm/mpspec.h> 73.9 #include <xen/irq.h> 73.10 #include <xen/event.h> 73.11 //#include <xen/shadow.h> 73.12 #include <xen/console.h> 73.13 +#include <xen/compile.h> 73.14 73.15 #include <xen/elf.h> 73.16 //#include <asm/page.h> 73.17 @@ -58,6 +60,7 @@ unsigned long *domU_staging_area; 73.18 73.19 // initialized by arch/ia64/setup.c:find_initrd() 73.20 unsigned long initrd_start = 0, initrd_end = 0; 73.21 +extern unsigned long running_on_sim; 73.22 73.23 #define IS_XEN_ADDRESS(d,a) ((a >= d->xen_vastart) && (a <= d->xen_vaend)) 73.24 73.25 @@ -75,35 +78,21 @@ void free_perdomain_pt(struct domain *d) 73.26 //free_page((unsigned long)d->mm.perdomain_pt); 73.27 } 73.28 73.29 -int hlt_counter; 73.30 - 73.31 -void disable_hlt(void) 73.32 +static void default_idle(void) 73.33 { 73.34 - hlt_counter++; 73.35 -} 73.36 - 73.37 -void enable_hlt(void) 73.38 -{ 73.39 - hlt_counter--; 73.40 + int cpu = smp_processor_id(); 73.41 + local_irq_disable(); 73.42 + if ( !softirq_pending(cpu)) 73.43 + safe_halt(); 73.44 + local_irq_enable(); 73.45 } 73.46 73.47 -static void default_idle(void) 73.48 -{ 73.49 - if ( hlt_counter == 0 ) 73.50 - { 73.51 - local_irq_disable(); 73.52 - if ( !softirq_pending(smp_processor_id()) ) 73.53 - safe_halt(); 73.54 - //else 73.55 - local_irq_enable(); 73.56 - } 73.57 -} 73.58 - 73.59 -void continue_cpu_idle_loop(void) 73.60 +static void continue_cpu_idle_loop(void) 73.61 { 73.62 int cpu = smp_processor_id(); 73.63 for ( ; ; ) 73.64 { 73.65 + printf ("idle%dD\n", cpu); 73.66 #ifdef IA64 73.67 // __IRQ_STAT(cpu, idle_timestamp) = jiffies 73.68 #else 73.69 @@ -111,23 +100,32 @@ void continue_cpu_idle_loop(void) 73.70 #endif 73.71 while ( !softirq_pending(cpu) ) 73.72 default_idle(); 73.73 + add_preempt_count(SOFTIRQ_OFFSET); 73.74 raise_softirq(SCHEDULE_SOFTIRQ); 73.75 do_softirq(); 73.76 + sub_preempt_count(SOFTIRQ_OFFSET); 73.77 } 73.78 } 73.79 73.80 void startup_cpu_idle_loop(void) 73.81 { 73.82 + int cpu = smp_processor_id (); 73.83 /* Just some sanity to ensure that the scheduler is set up okay. */ 73.84 ASSERT(current->domain == IDLE_DOMAIN_ID); 73.85 + printf ("idle%dA\n", cpu); 73.86 raise_softirq(SCHEDULE_SOFTIRQ); 73.87 +#if 0 /* All this work is done within continue_cpu_idle_loop */ 73.88 + printf ("idle%dB\n", cpu); 73.89 + asm volatile ("mov ar.k2=r0"); 73.90 do_softirq(); 73.91 + printf ("idle%dC\n", cpu); 73.92 73.93 /* 73.94 * Declares CPU setup done to the boot processor. 73.95 * Therefore memory barrier to ensure state is visible. 73.96 */ 73.97 smp_mb(); 73.98 +#endif 73.99 #if 0 73.100 //do we have to ensure the idle task has a shared page so that, for example, 73.101 //region registers can be loaded from it. Apparently not... 73.102 @@ -204,6 +202,15 @@ void arch_do_createdomain(struct vcpu *v 73.103 while (1); 73.104 } 73.105 memset(d->shared_info, 0, PAGE_SIZE); 73.106 + if (v == d->vcpu[0]) 73.107 + memset(&d->shared_info->evtchn_mask[0], 0xff, 73.108 + sizeof(d->shared_info->evtchn_mask)); 73.109 +#if 0 73.110 + d->vcpu[0].arch.privregs = 73.111 + alloc_xenheap_pages(get_order(sizeof(mapped_regs_t))); 73.112 + printf("arch_vcpu_info=%p\n", d->vcpu[0].arch.privregs); 73.113 + memset(d->vcpu.arch.privregs, 0, PAGE_SIZE); 73.114 +#endif 73.115 v->vcpu_info = &(d->shared_info->vcpu_data[0]); 73.116 73.117 d->max_pages = (128UL*1024*1024)/PAGE_SIZE; // 128MB default // FIXME 73.118 @@ -233,17 +240,21 @@ void arch_do_createdomain(struct vcpu *v 73.119 v->arch.breakimm = d->arch.breakimm; 73.120 73.121 d->arch.sys_pgnr = 0; 73.122 - d->arch.mm = xmalloc(struct mm_struct); 73.123 - if (unlikely(!d->arch.mm)) { 73.124 - printk("Can't allocate mm_struct for domain %d\n",d->domain_id); 73.125 - return -ENOMEM; 73.126 - } 73.127 - memset(d->arch.mm, 0, sizeof(*d->arch.mm)); 73.128 - d->arch.mm->pgd = pgd_alloc(d->arch.mm); 73.129 - if (unlikely(!d->arch.mm->pgd)) { 73.130 - printk("Can't allocate pgd for domain %d\n",d->domain_id); 73.131 - return -ENOMEM; 73.132 - } 73.133 + if (d->domain_id != IDLE_DOMAIN_ID) { 73.134 + d->arch.mm = xmalloc(struct mm_struct); 73.135 + if (unlikely(!d->arch.mm)) { 73.136 + printk("Can't allocate mm_struct for domain %d\n",d->domain_id); 73.137 + return -ENOMEM; 73.138 + } 73.139 + memset(d->arch.mm, 0, sizeof(*d->arch.mm)); 73.140 + d->arch.mm->pgd = pgd_alloc(d->arch.mm); 73.141 + if (unlikely(!d->arch.mm->pgd)) { 73.142 + printk("Can't allocate pgd for domain %d\n",d->domain_id); 73.143 + return -ENOMEM; 73.144 + } 73.145 + } else 73.146 + d->arch.mm = NULL; 73.147 + printf ("arch_do_create_domain: domain=%p\n", d); 73.148 } 73.149 73.150 void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c) 73.151 @@ -268,6 +279,14 @@ int arch_set_info_guest(struct vcpu *v, 73.152 if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) ) 73.153 return 0; 73.154 73.155 + /* Sync d/i cache conservatively */ 73.156 + if (!running_on_sim) { 73.157 + ret = ia64_pal_cache_flush(4, 0, &progress, NULL); 73.158 + if (ret != PAL_STATUS_SUCCESS) 73.159 + panic("PAL CACHE FLUSH failed for domain.\n"); 73.160 + printk("Sync i/d cache for dom0 image SUCC\n"); 73.161 + } 73.162 + 73.163 if (c->flags & VGCF_VMX_GUEST) { 73.164 if (!vmx_enabled) { 73.165 printk("No VMX hardware feature for vmx domain.\n"); 73.166 @@ -527,7 +546,8 @@ tryagain: 73.167 if (pte_present(*pte)) { 73.168 //printk("lookup_domain_page: found mapping for %lx, pte=%lx\n",mpaddr,pte_val(*pte)); 73.169 return *(unsigned long *)pte; 73.170 - } 73.171 + } else if (VMX_DOMAIN(d->vcpu[0])) 73.172 + return GPFN_INV_MASK; 73.173 } 73.174 } 73.175 } 73.176 @@ -779,7 +799,6 @@ void physdev_init_dom0(struct domain *d) 73.177 set_bit(_DOMF_physdev_access, &d->domain_flags); 73.178 } 73.179 73.180 -extern unsigned long running_on_sim; 73.181 unsigned int vmx_dom0 = 0; 73.182 int construct_dom0(struct domain *d, 73.183 unsigned long image_start, unsigned long image_len, 73.184 @@ -930,6 +949,7 @@ int construct_dom0(struct domain *d, 73.185 si = (start_info_t *)alloc_xenheap_page(); 73.186 memset(si, 0, PAGE_SIZE); 73.187 d->shared_info->arch.start_info_pfn = __pa(si) >> PAGE_SHIFT; 73.188 + sprintf(si->magic, "Xen-%i.%i", XEN_VERSION, XEN_SUBVERSION); 73.189 73.190 #if 0 73.191 si->nr_pages = d->tot_pages;
74.1 --- a/xen/arch/ia64/xen/hyperprivop.S Sun Oct 30 13:52:38 2005 +0100 74.2 +++ b/xen/arch/ia64/xen/hyperprivop.S Sun Oct 30 14:00:35 2005 +0100 74.3 @@ -14,6 +14,10 @@ 74.4 #include <asm/system.h> 74.5 #include <public/arch-ia64.h> 74.6 74.7 +#define _PAGE_PPN_MASK 0x0003fffffffff000 //asm/pgtable.h doesn't do assembly 74.8 +#define PAGE_PHYS 0x0010000000000761 //__pgprot(__DIRTY_BITS|_PAGE_PL_2|_PAGE_AR_RWX) 74.9 +#define _PAGE_PL_2 (2<<7) 74.10 + 74.11 #if 1 // change to 0 to turn off all fast paths 74.12 #define FAST_HYPERPRIVOPS 74.13 #define FAST_HYPERPRIVOP_CNT 74.14 @@ -24,6 +28,7 @@ 74.15 #define FAST_RFI 74.16 #define FAST_SSM_I 74.17 #define FAST_PTC_GA 74.18 +#undef FAST_ITC // working but default off for now 74.19 #undef RFI_TO_INTERRUPT // not working yet 74.20 #endif 74.21 74.22 @@ -802,8 +807,11 @@ just_do_rfi: 74.23 // OK, now all set to go except for switch to virtual bank1 74.24 mov r22=1;; st4 [r20]=r22; 74.25 mov r30=r2; mov r29=r3;; 74.26 + adds r16=XSI_B1NATS_OFS-XSI_PSR_IC_OFS,r18 74.27 adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18; 74.28 adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;; 74.29 + ld8 r16=[r16];; 74.30 + mov ar.unat=r16;; 74.31 bsw.1;; 74.32 // FIXME?: ar.unat is not really handled correctly, 74.33 // but may not matter if the OS is NaT-clean 74.34 @@ -1663,10 +1671,159 @@ 2: 74.35 ;; 74.36 END(hyper_ptc_ga) 74.37 74.38 +// Registers at entry 74.39 +// r17 = break immediate (XEN_HYPER_ITC_D or I) 74.40 +// r18 == XSI_PSR_IC_OFS 74.41 +// r31 == pr 74.42 +GLOBAL_ENTRY(hyper_itc) 74.43 +ENTRY(hyper_itc_i) 74.44 + // fall through, hyper_itc_d handles both i and d 74.45 ENTRY(hyper_itc_d) 74.46 +#ifndef FAST_ITC 74.47 br.spnt.many dispatch_break_fault ;; 74.48 -END(hyper_itc_d) 74.49 +#endif 74.50 + adds r23=XSI_ITIR_OFS-XSI_PSR_IC_OFS,r18 ;; 74.51 + ld8 r23=[r23];; 74.52 + extr.u r24=r23,2,6;; // r24==logps 74.53 + cmp.gt p7,p0=PAGE_SHIFT,r24 74.54 +(p7) br.spnt.many dispatch_break_fault ;; 74.55 + // translate_domain_pte(r8=pteval,PSCB(ifa)=address,r24=itir) 74.56 + mov r19=1;; 74.57 + shl r20=r19,r24;; 74.58 + adds r20=-1,r20;; // r20 == mask 74.59 + movl r19=_PAGE_PPN_MASK;; 74.60 + and r22=r8,r19;; // r22 == pteval & _PAGE_PPN_MASK 74.61 + andcm r19=r22,r20;; 74.62 + adds r21=XSI_IFA_OFS-XSI_PSR_IC_OFS,r18 ;; 74.63 + ld8 r21=[r21];; 74.64 + and r20=r21,r20;; 74.65 + or r19=r19,r20;; // r19 == mpaddr 74.66 + movl r27=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;; 74.67 + ld8 r27=[r27];; 74.68 + adds r27=IA64_VCPU_DOMAIN_OFFSET,r27;; 74.69 + ld8 r27=[r27];; 74.70 +// FIXME: is the global var dom0 always pinned? assume so for now 74.71 + movl r28=dom0;; 74.72 + ld8 r28=[r28];; 74.73 +// FIXME: for now, only handle dom0 (see lookup_domain_mpa below) 74.74 + cmp.ne p7,p0=r27,r28 74.75 +(p7) br.spnt.many dispatch_break_fault ;; 74.76 + // if region 6, go slow way 74.77 +#ifdef FAST_HYPERPRIVOP_CNT 74.78 + cmp.eq p6,p7=XEN_HYPER_ITC_D,r17;; 74.79 +(p6) movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_ITC_D);; 74.80 +(p7) movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_ITC_I);; 74.81 + ld8 r21=[r20];; 74.82 + adds r21=1,r21;; 74.83 + st8 [r20]=r21;; 74.84 +#endif 74.85 +// FIXME: for now, just do domain0 and skip mpaddr range checks 74.86 + dep r20=r0,r19,0,PAGE_SHIFT 74.87 + movl r21=PAGE_PHYS ;; 74.88 + or r20=r20,r21 ;; // r20==return value from lookup_domain_mpa 74.89 + // r8=pteval,r20=pteval2 74.90 + movl r19=_PAGE_PPN_MASK 74.91 + movl r21=_PAGE_PL_2;; 74.92 + andcm r25=r8,r19;; // r25==pteval & ~_PAGE_PPN_MASK 74.93 + and r22=r20,r19;; 74.94 + or r22=r22,r21;; 74.95 + or r22=r22,r25;; // r22==return value from translate_domain_pte 74.96 + // done with translate_domain_pte 74.97 + // now do vcpu_itc_no_srlz(vcpu,IorD,ifa,r22=pte,r8=mppte,r24=logps) 74.98 +// FIXME: for now, just domain0 and skip range check 74.99 + // psr.ic already cleared 74.100 + // NOTE: r24 still contains ps (from above) 74.101 + shladd r24=r24,2,r0;; 74.102 + mov cr.itir=r24;; 74.103 + adds r23=XSI_IFA_OFS-XSI_PSR_IC_OFS,r18 ;; 74.104 + ld8 r23=[r23];; 74.105 + mov cr.ifa=r23;; 74.106 + cmp.eq p6,p7=XEN_HYPER_ITC_D,r17;; 74.107 +(p6) itc.d r22;; 74.108 +(p7) itc.i r22;; 74.109 + dv_serialize_data 74.110 + // FIXME: how do I make assembler warnings go away here? 74.111 + // vhpt_insert(r23=vaddr,r22=pte,r24=logps<<2) 74.112 + thash r28=r23 74.113 + or r26=1,r22;; 74.114 + ttag r21=r23 74.115 + adds r25=8,r28 74.116 + mov r19=r28;; 74.117 + st8 [r25]=r24 74.118 + adds r20=16,r28;; 74.119 + st8 [r19]=r26 74.120 + st8 [r20]=r21;; 74.121 + // vcpu_set_tr_entry(trp,r22=pte|1,r24=itir,r23=ifa) 74.122 + // TR_ENTRY = {page_flags,itir,addr,rid} 74.123 + cmp.eq p6,p7=XEN_HYPER_ITC_D,r17 74.124 + movl r27=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;; 74.125 + ld8 r27=[r27];; 74.126 + adds r28=IA64_VCPU_STARTING_RID_OFFSET,r27 74.127 +(p6) adds r27=IA64_VCPU_DTLB_OFFSET,r27 74.128 +(p7) adds r27=IA64_VCPU_ITLB_OFFSET,r27;; 74.129 + st8 [r27]=r22,8;; // page_flags: already has pl >= 2 and p==1 74.130 + st8 [r27]=r24,8;; // itir 74.131 + mov r19=-4096;; 74.132 + and r23=r23,r19;; 74.133 + st8 [r27]=r23,8;; // ifa & ~0xfff 74.134 +// ?? is virtualize_rid(v,get_rr(ifa))==vcpu_get_rr(ifa)?? YES!! 74.135 + adds r29 = XSI_RR0_OFS-XSI_PSR_IC_OFS,r18 74.136 + extr.u r25=r23,61,3;; 74.137 + shladd r29=r25,3,r29;; 74.138 + ld8 r29=[r29];; 74.139 + movl r20=0xffffff00;; 74.140 + and r29=r29,r20;; 74.141 + st8 [r27]=r29,-8;; // rid 74.142 + //if ps > 12 74.143 + cmp.eq p7,p0=12<<2,r24 74.144 +(p7) br.cond.sptk.many 1f;; 74.145 + // if (ps > 12) { 74.146 + // trp->ppn &= ~((1UL<<(ps-12))-1); trp->vadr &= ~((1UL<<ps)-1); } 74.147 + extr.u r29=r24,2,6 74.148 + mov r28=1;; 74.149 + shl r26=r28,r29;; 74.150 + adds r29=-12,r29;; 74.151 + shl r25=r28,r29;; 74.152 + mov r29=-1 74.153 + adds r26=-1,r26 74.154 + adds r25=-1,r25;; 74.155 + andcm r26=r29,r26 // ~((1UL<<ps)-1) 74.156 + andcm r25=r29,r25;; // ~((1UL<<(ps-12))-1) 74.157 + ld8 r29=[r27];; 74.158 + and r29=r29,r26;; 74.159 + st8 [r27]=r29,-16;; 74.160 + ld8 r29=[r27];; 74.161 + extr.u r28=r29,12,38;; 74.162 + movl r26=0xfffc000000000fff;; 74.163 + and r29=r29,r26 74.164 + and r28=r28,r25;; 74.165 + shl r28=r28,12;; 74.166 + or r29=r29,r28;; 74.167 + st8 [r27]=r29;; 74.168 +1: // done with vcpu_set_tr_entry 74.169 + //PSCBX(vcpu,i/dtlb_pte) = mp_pte 74.170 + movl r27=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;; 74.171 + ld8 r27=[r27];; 74.172 + cmp.eq p6,p7=XEN_HYPER_ITC_D,r17;; 74.173 +(p6) adds r27=IA64_VCPU_DTLB_PTE_OFFSET,r27 74.174 +(p7) adds r27=IA64_VCPU_ITLB_PTE_OFFSET,r27;; 74.175 + st8 [r27]=r8;; 74.176 + // done with vcpu_itc_no_srlz 74.177 74.178 -ENTRY(hyper_itc_i) 74.179 - br.spnt.many dispatch_break_fault ;; 74.180 -END(hyper_itc_i) 74.181 + // done, increment to point to next instruction 74.182 + mov r29=cr.ipsr 74.183 + mov r30=cr.iip;; 74.184 + extr.u r26=r29,41,2 ;; 74.185 + cmp.eq p6,p7=2,r26 ;; 74.186 +(p6) mov r26=0 74.187 +(p6) adds r30=16,r30 74.188 +(p7) adds r26=1,r26 74.189 + ;; 74.190 + dep r29=r26,r29,41,2 74.191 + ;; 74.192 + mov cr.ipsr=r29 74.193 + mov cr.iip=r30 74.194 + mov pr=r31,-1 ;; 74.195 + rfi 74.196 + ;; 74.197 +END(hyper_itc_d)
75.1 --- a/xen/arch/ia64/xen/ivt.S Sun Oct 30 13:52:38 2005 +0100 75.2 +++ b/xen/arch/ia64/xen/ivt.S Sun Oct 30 14:00:35 2005 +0100 75.3 @@ -484,6 +484,7 @@ END(alt_dtlb_miss) 75.4 ///////////////////////////////////////////////////////////////////////////////////////// 75.5 // 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45) 75.6 ENTRY(nested_dtlb_miss) 75.7 + DBG_FAULT(5) 75.8 /* 75.9 * In the absence of kernel bugs, we get here when the virtually mapped linear 75.10 * page table is accessed non-speculatively (e.g., in the Dirty-bit, Instruction 75.11 @@ -552,10 +553,10 @@ END(nested_dtlb_miss) 75.12 ///////////////////////////////////////////////////////////////////////////////////////// 75.13 // 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24) 75.14 ENTRY(ikey_miss) 75.15 + DBG_FAULT(6) 75.16 #ifdef XEN 75.17 REFLECT(6) 75.18 #endif 75.19 - DBG_FAULT(6) 75.20 FAULT(6) 75.21 END(ikey_miss) 75.22 75.23 @@ -597,10 +598,10 @@ END(page_fault) 75.24 ///////////////////////////////////////////////////////////////////////////////////////// 75.25 // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51) 75.26 ENTRY(dkey_miss) 75.27 + DBG_FAULT(7) 75.28 #ifdef XEN 75.29 REFLECT(7) 75.30 #endif 75.31 - DBG_FAULT(7) 75.32 FAULT(7) 75.33 END(dkey_miss) 75.34 75.35 @@ -608,10 +609,10 @@ END(dkey_miss) 75.36 ///////////////////////////////////////////////////////////////////////////////////////// 75.37 // 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54) 75.38 ENTRY(dirty_bit) 75.39 + DBG_FAULT(8) 75.40 #ifdef XEN 75.41 REFLECT(8) 75.42 #endif 75.43 - DBG_FAULT(8) 75.44 /* 75.45 * What we do here is to simply turn on the dirty bit in the PTE. We need to 75.46 * update both the page-table and the TLB entry. To efficiently access the PTE, 75.47 @@ -673,6 +674,7 @@ END(dirty_bit) 75.48 ///////////////////////////////////////////////////////////////////////////////////////// 75.49 // 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27) 75.50 ENTRY(iaccess_bit) 75.51 + DBG_FAULT(9) 75.52 #ifdef XEN 75.53 mov r31=pr; 75.54 mov r16=cr.isr 75.55 @@ -681,7 +683,6 @@ ENTRY(iaccess_bit) 75.56 movl r20=0x2400 75.57 br.sptk.many fast_access_reflect;; 75.58 #endif 75.59 - DBG_FAULT(9) 75.60 // Like Entry 8, except for instruction access 75.61 mov r16=cr.ifa // get the address that caused the fault 75.62 movl r30=1f // load continuation point in case of nested fault 75.63 @@ -746,6 +747,7 @@ END(iaccess_bit) 75.64 ///////////////////////////////////////////////////////////////////////////////////////// 75.65 // 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55) 75.66 ENTRY(daccess_bit) 75.67 + DBG_FAULT(10) 75.68 #ifdef XEN 75.69 mov r31=pr; 75.70 mov r16=cr.isr 75.71 @@ -754,7 +756,6 @@ ENTRY(daccess_bit) 75.72 movl r20=0x2800 75.73 br.sptk.many fast_access_reflect;; 75.74 #endif 75.75 - DBG_FAULT(10) 75.76 // Like Entry 8, except for data access 75.77 mov r16=cr.ifa // get the address that caused the fault 75.78 movl r30=1f // load continuation point in case of nested fault 75.79 @@ -971,8 +972,10 @@ slow_interrupt: 75.80 mov out0=cr.ivr // pass cr.ivr as first arg 75.81 #endif 75.82 add out1=16,sp // pass pointer to pt_regs as second arg 75.83 +#ifndef XEN 75.84 ;; 75.85 srlz.d // make sure we see the effect of cr.ivr 75.86 +#endif 75.87 movl r14=ia64_leave_kernel 75.88 ;; 75.89 mov rp=r14 75.90 @@ -1363,10 +1366,10 @@ END(dispatch_to_fault_handler) 75.91 ///////////////////////////////////////////////////////////////////////////////////////// 75.92 // 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49) 75.93 ENTRY(page_not_present) 75.94 + DBG_FAULT(20) 75.95 #ifdef XEN 75.96 REFLECT(20) 75.97 #endif 75.98 - DBG_FAULT(20) 75.99 mov r16=cr.ifa 75.100 rsm psr.dt 75.101 /* 75.102 @@ -1386,10 +1389,10 @@ END(page_not_present) 75.103 ///////////////////////////////////////////////////////////////////////////////////////// 75.104 // 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52) 75.105 ENTRY(key_permission) 75.106 + DBG_FAULT(21) 75.107 #ifdef XEN 75.108 REFLECT(21) 75.109 #endif 75.110 - DBG_FAULT(21) 75.111 mov r16=cr.ifa 75.112 rsm psr.dt 75.113 mov r31=pr 75.114 @@ -1402,10 +1405,10 @@ END(key_permission) 75.115 ///////////////////////////////////////////////////////////////////////////////////////// 75.116 // 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26) 75.117 ENTRY(iaccess_rights) 75.118 + DBG_FAULT(22) 75.119 #ifdef XEN 75.120 REFLECT(22) 75.121 #endif 75.122 - DBG_FAULT(22) 75.123 mov r16=cr.ifa 75.124 rsm psr.dt 75.125 mov r31=pr 75.126 @@ -1418,6 +1421,7 @@ END(iaccess_rights) 75.127 ///////////////////////////////////////////////////////////////////////////////////////// 75.128 // 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53) 75.129 ENTRY(daccess_rights) 75.130 + DBG_FAULT(23) 75.131 #ifdef XEN 75.132 mov r31=pr; 75.133 mov r16=cr.isr 75.134 @@ -1426,7 +1430,6 @@ ENTRY(daccess_rights) 75.135 movl r20=0x5300 75.136 br.sptk.many fast_access_reflect;; 75.137 #endif 75.138 - DBG_FAULT(23) 75.139 mov r16=cr.ifa 75.140 rsm psr.dt 75.141 mov r31=pr 75.142 @@ -1459,10 +1462,31 @@ END(general_exception) 75.143 ///////////////////////////////////////////////////////////////////////////////////////// 75.144 // 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35) 75.145 ENTRY(disabled_fp_reg) 75.146 + DBG_FAULT(25) 75.147 #ifdef XEN 75.148 +#if 0 75.149 + mov r20=pr 75.150 + movl r16=0x2000000000000000 75.151 + movl r17=0x2000000000176b60 75.152 + mov r18=cr.iip 75.153 + mov r19=rr[r16] 75.154 + movl r22=0xe95d0439 75.155 + ;; 75.156 + mov pr=r0,-1 75.157 + ;; 75.158 + cmp.eq p6,p7=r22,r19 75.159 + ;; 75.160 + (p6) cmp.eq p8,p9=r17,r18 75.161 + (p8) br.sptk.few floating_panic 75.162 + ;; 75.163 + mov pr=r20,-1 75.164 + ;; 75.165 +#endif 75.166 REFLECT(25) 75.167 +//floating_panic: 75.168 +// br.sptk.many floating_panic 75.169 + ;; 75.170 #endif 75.171 - DBG_FAULT(25) 75.172 rsm psr.dfh // ensure we can access fph 75.173 ;; 75.174 srlz.d 75.175 @@ -1475,10 +1499,10 @@ END(disabled_fp_reg) 75.176 ///////////////////////////////////////////////////////////////////////////////////////// 75.177 // 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50) 75.178 ENTRY(nat_consumption) 75.179 + DBG_FAULT(26) 75.180 #ifdef XEN 75.181 REFLECT(26) 75.182 #endif 75.183 - DBG_FAULT(26) 75.184 FAULT(26) 75.185 END(nat_consumption) 75.186 75.187 @@ -1486,11 +1510,11 @@ END(nat_consumption) 75.188 ///////////////////////////////////////////////////////////////////////////////////////// 75.189 // 0x5700 Entry 27 (size 16 bundles) Speculation (40) 75.190 ENTRY(speculation_vector) 75.191 + DBG_FAULT(27) 75.192 #ifdef XEN 75.193 // this probably need not reflect... 75.194 REFLECT(27) 75.195 #endif 75.196 - DBG_FAULT(27) 75.197 /* 75.198 * A [f]chk.[as] instruction needs to take the branch to the recovery code but 75.199 * this part of the architecture is not implemented in hardware on some CPUs, such 75.200 @@ -1533,10 +1557,10 @@ END(speculation_vector) 75.201 ///////////////////////////////////////////////////////////////////////////////////////// 75.202 // 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56) 75.203 ENTRY(debug_vector) 75.204 + DBG_FAULT(29) 75.205 #ifdef XEN 75.206 REFLECT(29) 75.207 #endif 75.208 - DBG_FAULT(29) 75.209 FAULT(29) 75.210 END(debug_vector) 75.211 75.212 @@ -1544,10 +1568,10 @@ END(debug_vector) 75.213 ///////////////////////////////////////////////////////////////////////////////////////// 75.214 // 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57) 75.215 ENTRY(unaligned_access) 75.216 + DBG_FAULT(30) 75.217 #ifdef XEN 75.218 REFLECT(30) 75.219 #endif 75.220 - DBG_FAULT(30) 75.221 mov r16=cr.ipsr 75.222 mov r31=pr // prepare to save predicates 75.223 ;; 75.224 @@ -1558,10 +1582,10 @@ END(unaligned_access) 75.225 ///////////////////////////////////////////////////////////////////////////////////////// 75.226 // 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57) 75.227 ENTRY(unsupported_data_reference) 75.228 + DBG_FAULT(31) 75.229 #ifdef XEN 75.230 REFLECT(31) 75.231 #endif 75.232 - DBG_FAULT(31) 75.233 FAULT(31) 75.234 END(unsupported_data_reference) 75.235 75.236 @@ -1569,10 +1593,10 @@ END(unsupported_data_reference) 75.237 ///////////////////////////////////////////////////////////////////////////////////////// 75.238 // 0x5c00 Entry 32 (size 16 bundles) Floating-Point Fault (64) 75.239 ENTRY(floating_point_fault) 75.240 + DBG_FAULT(32) 75.241 #ifdef XEN 75.242 REFLECT(32) 75.243 #endif 75.244 - DBG_FAULT(32) 75.245 FAULT(32) 75.246 END(floating_point_fault) 75.247 75.248 @@ -1580,10 +1604,10 @@ END(floating_point_fault) 75.249 ///////////////////////////////////////////////////////////////////////////////////////// 75.250 // 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66) 75.251 ENTRY(floating_point_trap) 75.252 + DBG_FAULT(33) 75.253 #ifdef XEN 75.254 REFLECT(33) 75.255 #endif 75.256 - DBG_FAULT(33) 75.257 FAULT(33) 75.258 END(floating_point_trap) 75.259 75.260 @@ -1591,10 +1615,10 @@ END(floating_point_trap) 75.261 ///////////////////////////////////////////////////////////////////////////////////////// 75.262 // 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66) 75.263 ENTRY(lower_privilege_trap) 75.264 + DBG_FAULT(34) 75.265 #ifdef XEN 75.266 REFLECT(34) 75.267 #endif 75.268 - DBG_FAULT(34) 75.269 FAULT(34) 75.270 END(lower_privilege_trap) 75.271 75.272 @@ -1602,10 +1626,10 @@ END(lower_privilege_trap) 75.273 ///////////////////////////////////////////////////////////////////////////////////////// 75.274 // 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68) 75.275 ENTRY(taken_branch_trap) 75.276 + DBG_FAULT(35) 75.277 #ifdef XEN 75.278 REFLECT(35) 75.279 #endif 75.280 - DBG_FAULT(35) 75.281 FAULT(35) 75.282 END(taken_branch_trap) 75.283 75.284 @@ -1613,10 +1637,10 @@ END(taken_branch_trap) 75.285 ///////////////////////////////////////////////////////////////////////////////////////// 75.286 // 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69) 75.287 ENTRY(single_step_trap) 75.288 + DBG_FAULT(36) 75.289 #ifdef XEN 75.290 REFLECT(36) 75.291 #endif 75.292 - DBG_FAULT(36) 75.293 FAULT(36) 75.294 END(single_step_trap) 75.295 75.296 @@ -1672,10 +1696,10 @@ END(single_step_trap) 75.297 ///////////////////////////////////////////////////////////////////////////////////////// 75.298 // 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception (17,18,29,41,42,43,44,58,60,61,62,72,73,75,76,77) 75.299 ENTRY(ia32_exception) 75.300 + DBG_FAULT(45) 75.301 #ifdef XEN 75.302 REFLECT(45) 75.303 #endif 75.304 - DBG_FAULT(45) 75.305 FAULT(45) 75.306 END(ia32_exception) 75.307 75.308 @@ -1683,10 +1707,10 @@ END(ia32_exception) 75.309 ///////////////////////////////////////////////////////////////////////////////////////// 75.310 // 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept (30,31,59,70,71) 75.311 ENTRY(ia32_intercept) 75.312 + DBG_FAULT(46) 75.313 #ifdef XEN 75.314 REFLECT(46) 75.315 #endif 75.316 - DBG_FAULT(46) 75.317 #ifdef CONFIG_IA32_SUPPORT 75.318 mov r31=pr 75.319 mov r16=cr.isr 75.320 @@ -1716,10 +1740,10 @@ END(ia32_intercept) 75.321 ///////////////////////////////////////////////////////////////////////////////////////// 75.322 // 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt (74) 75.323 ENTRY(ia32_interrupt) 75.324 + DBG_FAULT(47) 75.325 #ifdef XEN 75.326 REFLECT(47) 75.327 #endif 75.328 - DBG_FAULT(47) 75.329 #ifdef CONFIG_IA32_SUPPORT 75.330 mov r31=pr 75.331 br.sptk.many dispatch_to_ia32_handler
76.1 --- a/xen/arch/ia64/xen/process.c Sun Oct 30 13:52:38 2005 +0100 76.2 +++ b/xen/arch/ia64/xen/process.c Sun Oct 30 14:00:35 2005 +0100 76.3 @@ -62,11 +62,23 @@ long do_iopl(domid_t domain, unsigned in 76.4 return 0; 76.5 } 76.6 76.7 +#include <xen/sched-if.h> 76.8 + 76.9 +extern struct schedule_data schedule_data[NR_CPUS]; 76.10 + 76.11 void schedule_tail(struct vcpu *next) 76.12 { 76.13 unsigned long rr7; 76.14 //printk("current=%lx,shared_info=%lx\n",current,current->vcpu_info); 76.15 //printk("next=%lx,shared_info=%lx\n",next,next->vcpu_info); 76.16 + 76.17 + // TG: Real HACK FIXME. 76.18 + // This is currently necessary because when a new domain is started, 76.19 + // the context_switch function of xen/common/schedule.c(__enter_scheduler) 76.20 + // never returns. Therefore, the lock must be released. 76.21 + // schedule_tail is only called when a domain is started. 76.22 + spin_unlock_irq(&schedule_data[current->processor].schedule_lock); 76.23 + 76.24 /* rr7 will be postponed to last point when resuming back to guest */ 76.25 if(VMX_DOMAIN(current)){ 76.26 vmx_load_all_rr(current); 76.27 @@ -733,6 +745,8 @@ ia64_handle_reflection (unsigned long if 76.28 case 26: 76.29 printf("*** NaT fault... attempting to handle as privop\n"); 76.30 printf("isr=%p, ifa=%p,iip=%p,ipsr=%p\n",isr,ifa,regs->cr_iip,psr); 76.31 + regs->eml_unat = 0; 76.32 + return; 76.33 vector = priv_emulate(v,regs,isr); 76.34 if (vector == IA64_NO_FAULT) { 76.35 printf("*** Handled privop masquerading as NaT fault\n");
77.1 --- a/xen/arch/ia64/xen/regionreg.c Sun Oct 30 13:52:38 2005 +0100 77.2 +++ b/xen/arch/ia64/xen/regionreg.c Sun Oct 30 14:00:35 2005 +0100 77.3 @@ -15,7 +15,8 @@ 77.4 #include <asm/regionreg.h> 77.5 #include <asm/vhpt.h> 77.6 #include <asm/vcpu.h> 77.7 -extern void ia64_new_rr7(unsigned long rid,void *shared_info, void *shared_arch_info); 77.8 +extern void ia64_new_rr7(unsigned long rid,void *shared_info, void *shared_arch_info, unsigned long p_vhpt, unsigned long v_pal); 77.9 +extern void *pal_vaddr; 77.10 77.11 77.12 #define IA64_MIN_IMPL_RID_BITS (IA64_MIN_IMPL_RID_MSB+1) 77.13 @@ -66,9 +67,12 @@ unsigned long allocate_metaphysical_rr(v 77.14 { 77.15 ia64_rr rrv; 77.16 77.17 + rrv.rrval = 0; // Or else may see reserved bit fault 77.18 rrv.rid = allocate_reserved_rid(); 77.19 rrv.ps = PAGE_SHIFT; 77.20 rrv.ve = 0; 77.21 + /* Mangle metaphysical rid */ 77.22 + rrv.rrval = vmMangleRID(rrv.rrval); 77.23 return rrv.rrval; 77.24 } 77.25 77.26 @@ -213,6 +217,7 @@ int set_one_rr(unsigned long rr, unsigne 77.27 unsigned long rreg = REGION_NUMBER(rr); 77.28 ia64_rr rrv, newrrv, memrrv; 77.29 unsigned long newrid; 77.30 + extern unsigned long vhpt_paddr; 77.31 77.32 if (val == -1) return 1; 77.33 77.34 @@ -250,9 +255,10 @@ int set_one_rr(unsigned long rr, unsigne 77.35 newrrv.rid = newrid; 77.36 newrrv.ve = 1; // VHPT now enabled for region 7!! 77.37 newrrv.ps = PAGE_SHIFT; 77.38 - if (rreg == 0) v->arch.metaphysical_saved_rr0 = newrrv.rrval; 77.39 + if (rreg == 0) v->arch.metaphysical_saved_rr0 = 77.40 + vmMangleRID(newrrv.rrval); 77.41 if (rreg == 7) ia64_new_rr7(vmMangleRID(newrrv.rrval),v->vcpu_info, 77.42 - v->arch.privregs); 77.43 + v->arch.privregs, vhpt_paddr, pal_vaddr); 77.44 else set_rr(rr,newrrv.rrval); 77.45 #endif 77.46 return 1; 77.47 @@ -265,7 +271,8 @@ int set_metaphysical_rr0(void) 77.48 ia64_rr rrv; 77.49 77.50 // rrv.ve = 1; FIXME: TURN ME BACK ON WHEN VHPT IS WORKING 77.51 - set_rr(0,v->arch.metaphysical_rr0); 77.52 + ia64_set_rr(0,v->arch.metaphysical_rr0); 77.53 + ia64_srlz_d(); 77.54 } 77.55 77.56 // validates/changes region registers 0-6 in the currently executing domain 77.57 @@ -290,7 +297,7 @@ void init_all_rr(struct vcpu *v) 77.58 ia64_rr rrv; 77.59 77.60 rrv.rrval = 0; 77.61 - rrv.rrval = v->domain->arch.metaphysical_rr0; 77.62 + //rrv.rrval = v->domain->arch.metaphysical_rr0; 77.63 rrv.ps = PAGE_SHIFT; 77.64 rrv.ve = 1; 77.65 if (!v->vcpu_info) { printf("Stopping in init_all_rr\n"); dummy(); } 77.66 @@ -343,12 +350,16 @@ unsigned long load_region_regs(struct vc 77.67 if (VCPU(v,metaphysical_mode)) { 77.68 ia64_rr rrv; 77.69 77.70 +#if 0 77.71 rrv.rrval = 0; 77.72 rrv.rid = v->domain->arch.metaphysical_rr0; 77.73 rrv.ps = PAGE_SHIFT; 77.74 rrv.ve = 1; 77.75 rr0 = rrv.rrval; 77.76 set_rr_no_srlz(0x0000000000000000L, rr0); 77.77 +#endif 77.78 + rr0 = v->domain->arch.metaphysical_rr0; 77.79 + ia64_set_rr(0x0000000000000000L, rr0); 77.80 ia64_srlz_d(); 77.81 } 77.82 else {
78.1 --- a/xen/arch/ia64/xen/vcpu.c Sun Oct 30 13:52:38 2005 +0100 78.2 +++ b/xen/arch/ia64/xen/vcpu.c Sun Oct 30 14:00:35 2005 +0100 78.3 @@ -66,8 +66,16 @@ unsigned long phys_translate_count = 0; 78.4 unsigned long vcpu_verbose = 0; 78.5 #define verbose(a...) do {if (vcpu_verbose) printf(a);} while(0) 78.6 78.7 -extern TR_ENTRY *match_tr(VCPU *vcpu, unsigned long ifa); 78.8 -extern TR_ENTRY *match_dtlb(VCPU *vcpu, unsigned long ifa); 78.9 +//#define vcpu_quick_region_check(_tr_regions,_ifa) 1 78.10 +#define vcpu_quick_region_check(_tr_regions,_ifa) \ 78.11 + (_tr_regions & (1 << ((unsigned long)_ifa >> 61))) 78.12 +#define vcpu_quick_region_set(_tr_regions,_ifa) \ 78.13 + do {_tr_regions |= (1 << ((unsigned long)_ifa >> 61)); } while (0) 78.14 + 78.15 +// FIXME: also need to check && (!trp->key || vcpu_pkr_match(trp->key)) 78.16 +#define vcpu_match_tr_entry(_trp,_ifa,_rid) \ 78.17 + ((_trp->p && (_trp->rid==_rid) && (_ifa >= _trp->vadr) && \ 78.18 + (_ifa < (_trp->vadr + (1L<< _trp->ps)) - 1))) 78.19 78.20 /************************************************************************** 78.21 VCPU general register access routines 78.22 @@ -620,7 +628,7 @@ void vcpu_pend_interrupt(VCPU *vcpu, UIN 78.23 return; 78.24 } 78.25 if ( VMX_DOMAIN(vcpu) ) { 78.26 - set_bit(vector,VCPU(vcpu,irr)); 78.27 + set_bit(vector,VCPU(vcpu,irr)); 78.28 } else 78.29 { 78.30 /* if (!test_bit(vector,PSCB(vcpu,delivery_mask))) return; */ 78.31 @@ -630,16 +638,6 @@ void vcpu_pend_interrupt(VCPU *vcpu, UIN 78.32 set_bit(vector,PSCBX(vcpu,irr)); 78.33 PSCB(vcpu,pending_interruption) = 1; 78.34 } 78.35 - 78.36 -#if 0 78.37 - /* Keir: I think you should unblock when an interrupt is pending. */ 78.38 - { 78.39 - int running = test_bit(_VCPUF_running, &vcpu->vcpu_flags); 78.40 - vcpu_unblock(vcpu); 78.41 - if ( running ) 78.42 - smp_send_event_check_cpu(vcpu->processor); 78.43 - } 78.44 -#endif 78.45 } 78.46 78.47 void early_tick(VCPU *vcpu) 78.48 @@ -710,14 +708,6 @@ UINT64 vcpu_check_pending_interrupts(VCP 78.49 } 78.50 78.51 //printf("returned to caller\n"); 78.52 -#if 0 78.53 -if (vector == (PSCB(vcpu,itv) & 0xff)) { 78.54 - UINT64 now = ia64_get_itc(); 78.55 - UINT64 itm = PSCBX(vcpu,domain_itm); 78.56 - if (now < itm) early_tick(vcpu); 78.57 - 78.58 -} 78.59 -#endif 78.60 return vector; 78.61 } 78.62 78.63 @@ -775,6 +765,7 @@ IA64FAULT vcpu_get_ivr(VCPU *vcpu, UINT6 78.64 } 78.65 #ifdef HEARTBEAT_FREQ 78.66 if (domid >= N_DOMS) domid = N_DOMS-1; 78.67 +#if 0 78.68 if (vector == (PSCB(vcpu,itv) & 0xff)) { 78.69 if (!(++count[domid] & ((HEARTBEAT_FREQ*1024)-1))) { 78.70 printf("Dom%d heartbeat... ticks=%lx,nonticks=%lx\n", 78.71 @@ -783,6 +774,7 @@ IA64FAULT vcpu_get_ivr(VCPU *vcpu, UINT6 78.72 //dump_runq(); 78.73 } 78.74 } 78.75 +#endif 78.76 else nonclockcount[domid]++; 78.77 #endif 78.78 // now have an unmasked, pending, deliverable vector! 78.79 @@ -1068,23 +1060,6 @@ void vcpu_set_next_timer(VCPU *vcpu) 78.80 /* gloss over the wraparound problem for now... we know it exists 78.81 * but it doesn't matter right now */ 78.82 78.83 -#if 0 78.84 - /* ensure at least next SP tick is in the future */ 78.85 - if (!interval) PSCBX(vcpu,xen_itm) = now + 78.86 -#if 0 78.87 - (running_on_sim() ? SIM_DEFAULT_CLOCK_RATE : 78.88 - DEFAULT_CLOCK_RATE); 78.89 -#else 78.90 - 3000000; 78.91 -//printf("vcpu_set_next_timer: HACK!\n"); 78.92 -#endif 78.93 -#if 0 78.94 - if (PSCBX(vcpu,xen_itm) < now) 78.95 - while (PSCBX(vcpu,xen_itm) < now + (interval>>1)) 78.96 - PSCBX(vcpu,xen_itm) += interval; 78.97 -#endif 78.98 -#endif 78.99 - 78.100 if (is_idle_task(vcpu->domain)) { 78.101 // printf("****** vcpu_set_next_timer called during idle!!\n"); 78.102 vcpu_safe_set_itm(s); 78.103 @@ -1175,14 +1150,6 @@ void vcpu_pend_timer(VCPU *vcpu) 78.104 // don't deliver another 78.105 return; 78.106 } 78.107 -#if 0 78.108 - // attempt to flag "timer tick before its due" source 78.109 - { 78.110 - UINT64 itm = PSCBX(vcpu,domain_itm); 78.111 - UINT64 now = ia64_get_itc(); 78.112 - if (now < itm) printf("******* vcpu_pend_timer: pending before due!\n"); 78.113 - } 78.114 -#endif 78.115 vcpu_pend_interrupt(vcpu, itv); 78.116 } 78.117 78.118 @@ -1197,33 +1164,6 @@ UINT64 vcpu_timer_pending_early(VCPU *vc 78.119 return (vcpu_deliverable_timer(vcpu) && (now < itm)); 78.120 } 78.121 78.122 -//FIXME: This is a hack because everything dies if a timer tick is lost 78.123 -void vcpu_poke_timer(VCPU *vcpu) 78.124 -{ 78.125 - UINT64 itv = PSCB(vcpu,itv) & 0xff; 78.126 - UINT64 now = ia64_get_itc(); 78.127 - UINT64 itm = PSCBX(vcpu,domain_itm); 78.128 - UINT64 irr; 78.129 - 78.130 - if (vcpu_timer_disabled(vcpu)) return; 78.131 - if (!itm) return; 78.132 - if (itv != 0xefL) { 78.133 - printf("vcpu_poke_timer: unimplemented itv=%lx!\n",itv); 78.134 - while(1); 78.135 - } 78.136 - // using 0xef instead of itv so can get real irr 78.137 - if (now > itm && !test_bit(0xefL, PSCBX(vcpu,insvc))) { 78.138 - if (!test_bit(0xefL,PSCBX(vcpu,irr))) { 78.139 - irr = ia64_getreg(_IA64_REG_CR_IRR3); 78.140 - if (irr & (1L<<(0xef-0xc0))) return; 78.141 -if (now-itm>0x800000) 78.142 -printf("*** poking timer: now=%lx,vitm=%lx,xitm=%lx,itm=%lx\n",now,itm,local_cpu_data->itm_next,ia64_get_itm()); 78.143 - vcpu_pend_timer(vcpu); 78.144 - } 78.145 - } 78.146 -} 78.147 - 78.148 - 78.149 /************************************************************************** 78.150 Privileged operation emulation routines 78.151 **************************************************************************/ 78.152 @@ -1316,13 +1256,6 @@ IA64FAULT vcpu_thash(VCPU *vcpu, UINT64 78.153 UINT64 VHPT_addr = VHPT_addr1 | ((VHPT_addr2a | VHPT_addr2b) << 15) | 78.154 VHPT_addr3; 78.155 78.156 -#if 0 78.157 - if (VHPT_addr1 == 0xe000000000000000L) { 78.158 - printf("vcpu_thash: thash unsupported with rr7 @%lx\n", 78.159 - PSCB(vcpu,iip)); 78.160 - return (IA64_ILLOP_FAULT); 78.161 - } 78.162 -#endif 78.163 //verbose("vcpu_thash: vadr=%p, VHPT_addr=%p\n",vadr,VHPT_addr); 78.164 *pval = VHPT_addr; 78.165 return (IA64_NO_FAULT); 78.166 @@ -1341,9 +1274,9 @@ unsigned long vhpt_translate_count = 0; 78.167 78.168 IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pteval, UINT64 *itir, UINT64 *iha) 78.169 { 78.170 - unsigned long pta, pta_mask, pte, ps; 78.171 + unsigned long pta, pte, rid, rr; 78.172 + int i; 78.173 TR_ENTRY *trp; 78.174 - ia64_rr rr; 78.175 78.176 if (!(address >> 61)) { 78.177 if (!PSCB(vcpu,metaphysical_mode)) { 78.178 @@ -1361,67 +1294,80 @@ IA64FAULT vcpu_translate(VCPU *vcpu, UIN 78.179 return IA64_NO_FAULT; 78.180 } 78.181 78.182 - /* check translation registers */ 78.183 - if ((trp = match_tr(vcpu,address))) { 78.184 - tr_translate_count++; 78.185 - *pteval = trp->page_flags; 78.186 - *itir = trp->itir; 78.187 - return IA64_NO_FAULT; 78.188 + rr = PSCB(vcpu,rrs)[address>>61]; 78.189 + rid = rr & RR_RID_MASK; 78.190 + if (is_data) { 78.191 + if (vcpu_quick_region_check(vcpu->arch.dtr_regions,address)) { 78.192 + for (trp = vcpu->arch.dtrs, i = NDTRS; i; i--, trp++) { 78.193 + if (vcpu_match_tr_entry(trp,address,rid)) { 78.194 + *pteval = trp->page_flags; 78.195 + *itir = trp->itir; 78.196 + tr_translate_count++; 78.197 + return IA64_NO_FAULT; 78.198 + } 78.199 + } 78.200 + } 78.201 + } 78.202 + // FIXME?: check itr's for data accesses too, else bad things happen? 78.203 + /* else */ { 78.204 + if (vcpu_quick_region_check(vcpu->arch.itr_regions,address)) { 78.205 + for (trp = vcpu->arch.itrs, i = NITRS; i; i--, trp++) { 78.206 + if (vcpu_match_tr_entry(trp,address,rid)) { 78.207 + *pteval = trp->page_flags; 78.208 + *itir = trp->itir; 78.209 + tr_translate_count++; 78.210 + return IA64_NO_FAULT; 78.211 + } 78.212 + } 78.213 + } 78.214 } 78.215 78.216 /* check 1-entry TLB */ 78.217 - if ((trp = match_dtlb(vcpu,address))) { 78.218 - dtlb_translate_count++; 78.219 + // FIXME?: check dtlb for inst accesses too, else bad things happen? 78.220 + trp = &vcpu->arch.dtlb; 78.221 + if (/* is_data && */ vcpu_match_tr_entry(trp,address,rid)) { 78.222 if (vcpu->domain==dom0 && !in_tpa) *pteval = trp->page_flags; 78.223 else *pteval = vcpu->arch.dtlb_pte; 78.224 -// printf("DTLB MATCH... NEW, DOM%s, %s\n", vcpu->domain==dom0? 78.225 -// "0":"U", in_tpa?"vcpu_tpa":"ia64_do_page_fault"); 78.226 *itir = trp->itir; 78.227 + dtlb_translate_count++; 78.228 return IA64_NO_FAULT; 78.229 } 78.230 78.231 /* check guest VHPT */ 78.232 pta = PSCB(vcpu,pta); 78.233 - rr.rrval = PSCB(vcpu,rrs)[address>>61]; 78.234 - if (!rr.ve || !(pta & IA64_PTA_VE)) { 78.235 -// FIXME? does iha get set for alt faults? does xenlinux depend on it? 78.236 - vcpu_thash(vcpu, address, iha); 78.237 -// FIXME?: does itir get set for alt faults? 78.238 - *itir = vcpu_get_itir_on_fault(vcpu,address); 78.239 - return (is_data ? IA64_ALT_DATA_TLB_VECTOR : 78.240 - IA64_ALT_INST_TLB_VECTOR); 78.241 - } 78.242 if (pta & IA64_PTA_VF) { /* long format VHPT - not implemented */ 78.243 - // thash won't work right? 78.244 panic_domain(vcpu_regs(vcpu),"can't do long format VHPT\n"); 78.245 //return (is_data ? IA64_DATA_TLB_VECTOR:IA64_INST_TLB_VECTOR); 78.246 } 78.247 78.248 + *itir = rr & (RR_RID_MASK | RR_PS_MASK); 78.249 + // note: architecturally, iha is optionally set for alt faults but 78.250 + // xenlinux depends on it so should document it as part of PV interface 78.251 + vcpu_thash(vcpu, address, iha); 78.252 + if (!(rr & RR_VE_MASK) || !(pta & IA64_PTA_VE)) 78.253 + return (is_data ? IA64_ALT_DATA_TLB_VECTOR : IA64_ALT_INST_TLB_VECTOR); 78.254 + 78.255 /* avoid recursively walking (short format) VHPT */ 78.256 - pta_mask = (itir_mask(pta) << 3) >> 3; 78.257 - if (((address ^ pta) & pta_mask) == 0) 78.258 + if (((address ^ pta) & ((itir_mask(pta) << 3) >> 3)) == 0) 78.259 return (is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR); 78.260 78.261 - vcpu_thash(vcpu, address, iha); 78.262 - if (__copy_from_user(&pte, (void *)(*iha), sizeof(pte)) != 0) { 78.263 -// FIXME?: does itir get set for vhpt faults? 78.264 - *itir = vcpu_get_itir_on_fault(vcpu,*iha); 78.265 + if (__copy_from_user(&pte, (void *)(*iha), sizeof(pte)) != 0) 78.266 + // virtual VHPT walker "missed" in TLB 78.267 return IA64_VHPT_FAULT; 78.268 - } 78.269 78.270 /* 78.271 - * Optimisation: this VHPT walker aborts on not-present pages 78.272 - * instead of inserting a not-present translation, this allows 78.273 - * vectoring directly to the miss handler. 78.274 - */ 78.275 - if (pte & _PAGE_P) { 78.276 - *pteval = pte; 78.277 - *itir = vcpu_get_itir_on_fault(vcpu,address); 78.278 - vhpt_translate_count++; 78.279 - return IA64_NO_FAULT; 78.280 - } 78.281 - *itir = vcpu_get_itir_on_fault(vcpu,address); 78.282 - return (is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR); 78.283 + * Optimisation: this VHPT walker aborts on not-present pages 78.284 + * instead of inserting a not-present translation, this allows 78.285 + * vectoring directly to the miss handler. 78.286 + */ 78.287 + if (!(pte & _PAGE_P)) 78.288 + return (is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR); 78.289 + 78.290 + /* found mapping in guest VHPT! */ 78.291 + *itir = rr & RR_PS_MASK; 78.292 + *pteval = pte; 78.293 + vhpt_translate_count++; 78.294 + return IA64_NO_FAULT; 78.295 } 78.296 78.297 IA64FAULT vcpu_tpa(VCPU *vcpu, UINT64 vadr, UINT64 *padr) 78.298 @@ -1736,33 +1682,6 @@ static void vcpu_set_tr_entry(TR_ENTRY * 78.299 } 78.300 } 78.301 78.302 -TR_ENTRY *vcpu_match_tr_entry(VCPU *vcpu, TR_ENTRY *trp, UINT64 ifa, int count) 78.303 -{ 78.304 - unsigned long rid = (get_rr(ifa) & RR_RID_MASK); 78.305 - int i; 78.306 - 78.307 - for (i = 0; i < count; i++, trp++) { 78.308 - if (!trp->p) continue; 78.309 - if (physicalize_rid(vcpu,trp->rid) != rid) continue; 78.310 - if (ifa < trp->vadr) continue; 78.311 - if (ifa >= (trp->vadr + (1L << trp->ps)) - 1) continue; 78.312 - //if (trp->key && !match_pkr(vcpu,trp->key)) continue; 78.313 - return trp; 78.314 - } 78.315 - return 0; 78.316 -} 78.317 - 78.318 -TR_ENTRY *match_tr(VCPU *vcpu, unsigned long ifa) 78.319 -{ 78.320 - TR_ENTRY *trp; 78.321 - 78.322 - trp = vcpu_match_tr_entry(vcpu,vcpu->arch.dtrs,ifa,NDTRS); 78.323 - if (trp) return trp; 78.324 - trp = vcpu_match_tr_entry(vcpu,vcpu->arch.itrs,ifa,NITRS); 78.325 - if (trp) return trp; 78.326 - return 0; 78.327 -} 78.328 - 78.329 IA64FAULT vcpu_itr_d(VCPU *vcpu, UINT64 slot, UINT64 pte, 78.330 UINT64 itir, UINT64 ifa) 78.331 { 78.332 @@ -1772,6 +1691,7 @@ IA64FAULT vcpu_itr_d(VCPU *vcpu, UINT64 78.333 trp = &PSCBX(vcpu,dtrs[slot]); 78.334 //printf("***** itr.d: setting slot %d: ifa=%p\n",slot,ifa); 78.335 vcpu_set_tr_entry(trp,pte,itir,ifa); 78.336 + vcpu_quick_region_set(PSCBX(vcpu,dtr_regions),ifa); 78.337 return IA64_NO_FAULT; 78.338 } 78.339 78.340 @@ -1784,6 +1704,7 @@ IA64FAULT vcpu_itr_i(VCPU *vcpu, UINT64 78.341 trp = &PSCBX(vcpu,itrs[slot]); 78.342 //printf("***** itr.i: setting slot %d: ifa=%p\n",slot,ifa); 78.343 vcpu_set_tr_entry(trp,pte,itir,ifa); 78.344 + vcpu_quick_region_set(PSCBX(vcpu,itr_regions),ifa); 78.345 return IA64_NO_FAULT; 78.346 } 78.347 78.348 @@ -1835,17 +1756,6 @@ void vcpu_itc_no_srlz(VCPU *vcpu, UINT64 78.349 } 78.350 } 78.351 78.352 -// NOTE: returns a physical pte, NOT a "metaphysical" pte, so do not check 78.353 -// the physical address contained for correctness 78.354 -TR_ENTRY *match_dtlb(VCPU *vcpu, unsigned long ifa) 78.355 -{ 78.356 - TR_ENTRY *trp; 78.357 - 78.358 - if (trp = vcpu_match_tr_entry(vcpu,&vcpu->arch.dtlb,ifa,1)) 78.359 - return (&vcpu->arch.dtlb); 78.360 - return 0UL; 78.361 -} 78.362 - 78.363 IA64FAULT vcpu_itc_d(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa) 78.364 { 78.365 unsigned long pteval, logps = (itir >> 2) & 0x3f; 78.366 @@ -1952,12 +1862,14 @@ IA64FAULT vcpu_ptc_ga(VCPU *vcpu,UINT64 78.367 IA64FAULT vcpu_ptr_d(VCPU *vcpu,UINT64 vadr,UINT64 addr_range) 78.368 { 78.369 printf("vcpu_ptr_d: Purging TLB is unsupported\n"); 78.370 + // don't forget to recompute dtr_regions 78.371 return (IA64_ILLOP_FAULT); 78.372 } 78.373 78.374 IA64FAULT vcpu_ptr_i(VCPU *vcpu,UINT64 vadr,UINT64 addr_range) 78.375 { 78.376 printf("vcpu_ptr_i: Purging TLB is unsupported\n"); 78.377 + // don't forget to recompute itr_regions 78.378 return (IA64_ILLOP_FAULT); 78.379 } 78.380
79.1 --- a/xen/arch/ia64/xen/xenasm.S Sun Oct 30 13:52:38 2005 +0100 79.2 +++ b/xen/arch/ia64/xen/xenasm.S Sun Oct 30 14:00:35 2005 +0100 79.3 @@ -48,11 +48,11 @@ END(platform_is_hp_ski) 79.4 // FIXME? Note that this turns off the DB bit (debug) 79.5 #define PSR_BITS_TO_SET IA64_PSR_BN 79.6 79.7 -//extern void ia64_new_rr7(unsigned long rid,void *shared_info, void *shared_arch_info); 79.8 +//extern void ia64_new_rr7(unsigned long rid,void *shared_info, void *shared_arch_info, unsigned long p_vhpt, unsigned long v_pal); 79.9 GLOBAL_ENTRY(ia64_new_rr7) 79.10 // not sure this unwind statement is correct... 79.11 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(1) 79.12 - alloc loc1 = ar.pfs, 3, 8, 0, 0 79.13 + alloc loc1 = ar.pfs, 5, 9, 0, 0 79.14 1: { 79.15 mov r28 = in0 // copy procedure index 79.16 mov r8 = ip // save ip to compute branch 79.17 @@ -63,10 +63,12 @@ 1: { 79.18 ;; 79.19 tpa loc2=loc2 // grab this BEFORE changing rr7 79.20 ;; 79.21 + dep loc8=0,in4,60,4 79.22 + ;; 79.23 #if VHPT_ENABLED 79.24 - movl loc6=VHPT_ADDR 79.25 + mov loc6=in3 79.26 ;; 79.27 - tpa loc6=loc6 // grab this BEFORE changing rr7 79.28 + //tpa loc6=loc6 // grab this BEFORE changing rr7 79.29 ;; 79.30 #endif 79.31 mov loc5=in1 79.32 @@ -231,6 +233,21 @@ 1: 79.33 itr.d dtr[r25]=r23 // wire in new mapping... 79.34 ;; 79.35 79.36 + //Purge/insert PAL TR 79.37 + mov r24=IA64_TR_PALCODE 79.38 + movl r25=PAGE_KERNEL 79.39 + ;; 79.40 + or loc8=r25,loc8 79.41 + mov r23=IA64_GRANULE_SHIFT<<2 79.42 + ;; 79.43 + ptr.i in4,r23 79.44 + ;; 79.45 + mov cr.itir=r23 79.46 + mov cr.ifa=in4 79.47 + ;; 79.48 + itr.i itr[r24]=loc8 79.49 + ;; 79.50 + 79.51 // done, switch back to virtual and return 79.52 mov r16=loc3 // r16= original psr 79.53 br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
80.1 --- a/xen/arch/ia64/xen/xenirq.c Sun Oct 30 13:52:38 2005 +0100 80.2 +++ b/xen/arch/ia64/xen/xenirq.c Sun Oct 30 14:00:35 2005 +0100 80.3 @@ -35,7 +35,7 @@ xen_debug_irq(ia64_vector vector, struct 80.4 int 80.5 xen_do_IRQ(ia64_vector vector) 80.6 { 80.7 - if (vector != 0xef) { 80.8 + if (vector != IA64_TIMER_VECTOR && vector != IA64_IPI_VECTOR) { 80.9 extern void vcpu_pend_interrupt(void *, int); 80.10 #if 0 80.11 if (firsttime[vector]) { 80.12 @@ -57,22 +57,18 @@ xen_do_IRQ(ia64_vector vector) 80.13 return(0); 80.14 } 80.15 80.16 -/* From linux/kernel/softirq.c */ 80.17 -#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED 80.18 -# define invoke_softirq() __do_softirq() 80.19 -#else 80.20 -# define invoke_softirq() do_softirq() 80.21 -#endif 80.22 - 80.23 /* 80.24 * Exit an interrupt context. Process softirqs if needed and possible: 80.25 */ 80.26 void irq_exit(void) 80.27 { 80.28 //account_system_vtime(current); 80.29 - //sub_preempt_count(IRQ_EXIT_OFFSET); 80.30 - if (!in_interrupt() && local_softirq_pending()) 80.31 - invoke_softirq(); 80.32 + sub_preempt_count(IRQ_EXIT_OFFSET); 80.33 + if (!in_interrupt() && local_softirq_pending()) { 80.34 + add_preempt_count(SOFTIRQ_OFFSET); 80.35 + do_softirq(); 80.36 + sub_preempt_count(SOFTIRQ_OFFSET); 80.37 + } 80.38 //preempt_enable_no_resched(); 80.39 } 80.40 /* end from linux/kernel/softirq.c */
81.1 --- a/xen/arch/ia64/xen/xenmisc.c Sun Oct 30 13:52:38 2005 +0100 81.2 +++ b/xen/arch/ia64/xen/xenmisc.c Sun Oct 30 14:00:35 2005 +0100 81.3 @@ -17,6 +17,7 @@ 81.4 #include <asm/io.h> 81.5 #include <xen/softirq.h> 81.6 #include <public/sched.h> 81.7 +#include <asm/vhpt.h> 81.8 81.9 efi_memory_desc_t ia64_efi_io_md; 81.10 EXPORT_SYMBOL(ia64_efi_io_md); 81.11 @@ -280,6 +281,8 @@ void cs01foo(void) {} 81.12 81.13 unsigned long context_switch_count = 0; 81.14 81.15 +#include <asm/vcpu.h> 81.16 + 81.17 void context_switch(struct vcpu *prev, struct vcpu *next) 81.18 { 81.19 //printk("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); 81.20 @@ -287,7 +290,8 @@ void context_switch(struct vcpu *prev, s 81.21 //prev->domain->domain_id,(long)prev&0xffffff,next->domain->domain_id,(long)next&0xffffff); 81.22 //if (prev->domain->domain_id == 1 && next->domain->domain_id == 0) cs10foo(); 81.23 //if (prev->domain->domain_id == 0 && next->domain->domain_id == 1) cs01foo(); 81.24 -//printk("@@sw %d->%d\n",prev->domain->domain_id,next->domain->domain_id); 81.25 +printk("@@sw%d/%x %d->%d\n",smp_processor_id(), hard_smp_processor_id (), 81.26 + prev->domain->domain_id,next->domain->domain_id); 81.27 if(VMX_DOMAIN(prev)){ 81.28 vtm_domain_out(prev); 81.29 } 81.30 @@ -307,9 +311,13 @@ if (!cnt[id]--) { printk("%x",id); cnt[i 81.31 if (!i--) { printk("+",id); i = 1000000; } 81.32 } 81.33 81.34 - if (VMX_DOMAIN(current)){ 81.35 + if (VMX_DOMAIN(current)){ 81.36 vmx_load_all_rr(current); 81.37 }else{ 81.38 + extern char ia64_ivt; 81.39 + ia64_set_iva(&ia64_ivt); 81.40 + ia64_set_pta(VHPT_ADDR | (1 << 8) | (VHPT_SIZE_LOG2 << 2) | 81.41 + VHPT_ENABLED); 81.42 if (!is_idle_task(current->domain)) { 81.43 load_region_regs(current); 81.44 if (vcpu_timer_expired(current)) vcpu_pend_timer(current);
82.1 --- a/xen/arch/ia64/xen/xensetup.c Sun Oct 30 13:52:38 2005 +0100 82.2 +++ b/xen/arch/ia64/xen/xensetup.c Sun Oct 30 14:00:35 2005 +0100 82.3 @@ -253,11 +253,11 @@ void start_kernel(void) 82.4 printk("About to call scheduler_init()\n"); 82.5 scheduler_init(); 82.6 local_irq_disable(); 82.7 + init_IRQ (); 82.8 printk("About to call init_xen_time()\n"); 82.9 init_xen_time(); /* initialise the time */ 82.10 printk("About to call ac_timer_init()\n"); 82.11 ac_timer_init(); 82.12 -// init_xen_time(); ??? 82.13 82.14 #ifdef CONFIG_SMP 82.15 if ( opt_nosmp ) 82.16 @@ -276,6 +276,9 @@ printk("About to call ac_timer_init()\n" 82.17 82.18 //BUG_ON(!local_irq_is_enabled()); 82.19 82.20 + /* Enable IRQ to receive IPI (needed for ITC sync). */ 82.21 + local_irq_enable(); 82.22 + 82.23 printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus); 82.24 for_each_present_cpu ( i ) 82.25 { 82.26 @@ -287,24 +290,16 @@ printk("About to call __cpu_up(%d)\n",i) 82.27 } 82.28 } 82.29 82.30 + local_irq_disable(); 82.31 + 82.32 printk("Brought up %ld CPUs\n", (long)num_online_cpus()); 82.33 smp_cpus_done(max_cpus); 82.34 #endif 82.35 82.36 - 82.37 - // FIXME: Should the following be swapped and moved later? 82.38 - schedulers_start(); 82.39 do_initcalls(); 82.40 printk("About to call sort_main_extable()\n"); 82.41 sort_main_extable(); 82.42 82.43 - /* surrender usage of kernel registers to domain, use percpu area instead */ 82.44 - __get_cpu_var(cpu_kr)._kr[IA64_KR_IO_BASE] = ia64_get_kr(IA64_KR_IO_BASE); 82.45 - __get_cpu_var(cpu_kr)._kr[IA64_KR_PER_CPU_DATA] = ia64_get_kr(IA64_KR_PER_CPU_DATA); 82.46 - __get_cpu_var(cpu_kr)._kr[IA64_KR_CURRENT_STACK] = ia64_get_kr(IA64_KR_CURRENT_STACK); 82.47 - __get_cpu_var(cpu_kr)._kr[IA64_KR_FPU_OWNER] = ia64_get_kr(IA64_KR_FPU_OWNER); 82.48 - __get_cpu_var(cpu_kr)._kr[IA64_KR_CURRENT] = ia64_get_kr(IA64_KR_CURRENT); 82.49 - __get_cpu_var(cpu_kr)._kr[IA64_KR_PT_BASE] = ia64_get_kr(IA64_KR_PT_BASE); 82.50 82.51 /* Create initial domain 0. */ 82.52 printk("About to call do_createdomain()\n"); 82.53 @@ -342,6 +337,11 @@ printk("About to call construct_dom0()\n 82.54 0, 82.55 0) != 0) 82.56 panic("Could not set up DOM0 guest OS\n"); 82.57 + 82.58 + /* PIN domain0 on CPU 0. */ 82.59 + dom0->vcpu[0]->cpumap=1; 82.60 + set_bit(_VCPUF_cpu_pinned, &dom0->vcpu[0]->vcpu_flags); 82.61 + 82.62 #ifdef CLONE_DOMAIN0 82.63 { 82.64 int i; 82.65 @@ -379,9 +379,16 @@ printk("About to call init_trace_bufs()\ 82.66 domain_unpause_by_systemcontroller(clones[i]); 82.67 } 82.68 #endif 82.69 + domain0_ready = 1; 82.70 + 82.71 + local_irq_enable(); 82.72 + 82.73 + printf("About to call schedulers_start dom0=%p, idle0_dom=%p\n", 82.74 + dom0, &idle0_domain); 82.75 + schedulers_start(); 82.76 + 82.77 domain_unpause_by_systemcontroller(dom0); 82.78 - domain0_ready = 1; 82.79 - local_irq_enable(); 82.80 + 82.81 printk("About to call startup_cpu_idle_loop()\n"); 82.82 startup_cpu_idle_loop(); 82.83 }
83.1 --- a/xen/arch/ia64/xen/xentime.c Sun Oct 30 13:52:38 2005 +0100 83.2 +++ b/xen/arch/ia64/xen/xentime.c Sun Oct 30 14:00:35 2005 +0100 83.3 @@ -38,6 +38,20 @@ static s_time_t stime_irq = 0x0; 83.4 unsigned long itc_scale, ns_scale; 83.5 unsigned long itc_at_irq; 83.6 83.7 +/* We don't expect an absolute cycle value here, since then no way 83.8 + * to prevent overflow for large norminator. Normally this conversion 83.9 + * is used for relative offset. 83.10 + */ 83.11 +u64 cycle_to_ns(u64 cycle) 83.12 +{ 83.13 + return (cycle * itc_scale) >> 32; 83.14 +} 83.15 + 83.16 +u64 ns_to_cycle(u64 ns) 83.17 +{ 83.18 + return (ns * ns_scale) >> 32; 83.19 +} 83.20 + 83.21 static inline u64 get_time_delta(void) 83.22 { 83.23 s64 delta_itc; 83.24 @@ -52,19 +66,6 @@ static inline u64 get_time_delta(void) 83.25 return cycle_to_ns(delta_itc); 83.26 } 83.27 83.28 -/* We don't expect an absolute cycle value here, since then no way 83.29 - * to prevent overflow for large norminator. Normally this conversion 83.30 - * is used for relative offset. 83.31 - */ 83.32 -u64 cycle_to_ns(u64 cycle) 83.33 -{ 83.34 - return (cycle * itc_scale) >> 32; 83.35 -} 83.36 - 83.37 -u64 ns_to_cycle(u64 ns) 83.38 -{ 83.39 - return (ns * ns_scale) >> 32; 83.40 -} 83.41 83.42 s_time_t get_s_time(void) 83.43 { 83.44 @@ -99,17 +100,19 @@ xen_timer_interrupt (int irq, void *dev_ 83.45 { 83.46 unsigned long new_itm, old_itc; 83.47 83.48 +#if 0 83.49 #define HEARTBEAT_FREQ 16 // period in seconds 83.50 #ifdef HEARTBEAT_FREQ 83.51 static long count = 0; 83.52 if (!(++count & ((HEARTBEAT_FREQ*1024)-1))) { 83.53 - printf("Heartbeat... iip=%p,psr.i=%d,pend=%d\n", 83.54 - regs->cr_iip, 83.55 + printf("Heartbeat... iip=%p\n", /*",psr.i=%d,pend=%d\n", */ 83.56 + regs->cr_iip /*, 83.57 VCPU(current,interrupt_delivery_enabled), 83.58 - VCPU(current,pending_interruption)); 83.59 + VCPU(current,pending_interruption) */); 83.60 count = 0; 83.61 } 83.62 #endif 83.63 +#endif 83.64 if (current->domain == dom0) { 83.65 // FIXME: there's gotta be a better way of doing this... 83.66 // We have to ensure that domain0 is launched before we 83.67 @@ -117,12 +120,14 @@ xen_timer_interrupt (int irq, void *dev_ 83.68 //domain0_ready = 1; // moved to xensetup.c 83.69 VCPU(current,pending_interruption) = 1; 83.70 } 83.71 - if (domain0_ready && vcpu_timer_expired(dom0->vcpu[0])) { 83.72 - vcpu_pend_timer(dom0->vcpu[0]); 83.73 - //vcpu_set_next_timer(dom0->vcpu[0]); 83.74 - vcpu_wake(dom0->vcpu[0]); 83.75 + if (domain0_ready && current->domain != dom0) { 83.76 + if(vcpu_timer_expired(dom0->vcpu[0])) { 83.77 + vcpu_pend_timer(dom0->vcpu[0]); 83.78 + //vcpu_set_next_timer(dom0->vcpu[0]); 83.79 + vcpu_wake(dom0->vcpu[0]); 83.80 + } 83.81 } 83.82 - if (!is_idle_task(current->domain) && current->domain != dom0) { 83.83 + if (!is_idle_task(current->domain)) { 83.84 if (vcpu_timer_expired(current)) { 83.85 vcpu_pend_timer(current); 83.86 // ensure another timer interrupt happens even if domain doesn't 83.87 @@ -132,9 +137,12 @@ xen_timer_interrupt (int irq, void *dev_ 83.88 } 83.89 new_itm = local_cpu_data->itm_next; 83.90 83.91 - if (!time_after(ia64_get_itc(), new_itm)) 83.92 + if (!VMX_DOMAIN(current) && !time_after(ia64_get_itc(), new_itm)) 83.93 return; 83.94 83.95 + if (VMX_DOMAIN(current)) 83.96 + vcpu_wake(current); 83.97 + 83.98 while (1) { 83.99 new_itm += local_cpu_data->itm_delta; 83.100 83.101 @@ -233,7 +241,7 @@ int reprogram_ac_timer(s_time_t timeout) 83.102 s_time_t expire; 83.103 unsigned long seq, cur_itc, itm_next; 83.104 83.105 - if (!domain0_ready) return 1; 83.106 + if (!domain0_ready || timeout == 0) return 1; 83.107 83.108 do { 83.109 seq = read_seqbegin(&xtime_lock);
84.1 --- a/xen/arch/x86/apic.c Sun Oct 30 13:52:38 2005 +0100 84.2 +++ b/xen/arch/x86/apic.c Sun Oct 30 14:00:35 2005 +0100 84.3 @@ -815,6 +815,10 @@ int __init calibrate_APIC_clock(void) 84.4 return result; 84.5 } 84.6 84.7 +unsigned int get_apic_bus_scale(void) 84.8 +{ 84.9 + return bus_scale; 84.10 +} 84.11 84.12 static unsigned int calibration_result; 84.13
85.1 --- a/xen/arch/x86/dm/i8259.c Sun Oct 30 13:52:38 2005 +0100 85.2 +++ b/xen/arch/x86/dm/i8259.c Sun Oct 30 14:00:35 2005 +0100 85.3 @@ -32,8 +32,8 @@ 85.4 #include <public/io/ioreq.h> 85.5 #include <asm/vmx.h> 85.6 #include <public/io/vmx_vpic.h> 85.7 -#include <public/io/vmx_vlapic.h> 85.8 #include <asm/current.h> 85.9 +#include <asm/vmx_vlapic.h> 85.10 85.11 /* set irq level. If an edge is detected, then the IRR is set to 1 */ 85.12 static inline void pic_set_irq1(PicState *s, int irq, int level) 85.13 @@ -135,7 +135,6 @@ void do_pic_irqs (struct vmx_virpic *s, 85.14 { 85.15 s->pics[1].irr |= (uint8_t)(irqs >> 8); 85.16 s->pics[0].irr |= (uint8_t) irqs; 85.17 - /* TODO for alt_irq_func */ 85.18 pic_update_irq(s); 85.19 } 85.20 85.21 @@ -505,14 +504,22 @@ int cpu_get_pic_interrupt(struct vcpu *v 85.22 { 85.23 int intno; 85.24 struct vmx_virpic *s = &v->domain->arch.vmx_platform.vmx_pic; 85.25 - 85.26 + struct vmx_platform *plat = &v->domain->arch.vmx_platform; 85.27 + 85.28 + if ( !vlapic_accept_pic_intr(v) ) 85.29 + return -1; 85.30 + 85.31 + if ( !plat->interrupt_request ) 85.32 + return -1; 85.33 + 85.34 /* read the irq from the PIC */ 85.35 intno = pic_read_irq(s); 85.36 *type = VLAPIC_DELIV_MODE_EXT; 85.37 + plat->interrupt_request = 0; 85.38 return intno; 85.39 } 85.40 85.41 -int is_pit_irq(struct vcpu *v, int irq) 85.42 +int is_pit_irq(struct vcpu *v, int irq, int type) 85.43 { 85.44 int pit_vec = v->domain->arch.vmx_platform.vmx_pic.pics[0].irq_base; 85.45
86.1 --- a/xen/arch/x86/domain_build.c Sun Oct 30 13:52:38 2005 +0100 86.2 +++ b/xen/arch/x86/domain_build.c Sun Oct 30 14:00:35 2005 +0100 86.3 @@ -15,6 +15,7 @@ 86.4 #include <xen/elf.h> 86.5 #include <xen/kernel.h> 86.6 #include <xen/domain.h> 86.7 +#include <xen/compile.h> 86.8 #include <asm/regs.h> 86.9 #include <asm/system.h> 86.10 #include <asm/io.h> 86.11 @@ -582,26 +583,23 @@ int construct_dom0(struct domain *d, 86.12 _initrd_start, (_initrd_start+initrd_len+PAGE_SIZE-1) & PAGE_MASK); 86.13 } 86.14 86.15 - d->next_io_page = max_page; 86.16 - 86.17 /* Set up start info area. */ 86.18 si = (start_info_t *)vstartinfo_start; 86.19 memset(si, 0, PAGE_SIZE); 86.20 si->nr_pages = nr_pages; 86.21 86.22 + si->shared_info = virt_to_phys(d->shared_info); 86.23 if ( opt_dom0_translate ) 86.24 { 86.25 - si->shared_info = d->next_io_page << PAGE_SHIFT; 86.26 - set_pfn_from_mfn(virt_to_phys(d->shared_info) >> PAGE_SHIFT, d->next_io_page); 86.27 - d->next_io_page++; 86.28 + si->shared_info = max_page << PAGE_SHIFT; 86.29 + set_pfn_from_mfn(virt_to_phys(d->shared_info) >> PAGE_SHIFT, max_page); 86.30 } 86.31 - else 86.32 - si->shared_info = virt_to_phys(d->shared_info); 86.33 86.34 si->flags = SIF_PRIVILEGED | SIF_INITDOMAIN; 86.35 si->pt_base = vpt_start; 86.36 si->nr_pt_frames = nr_pt_pages; 86.37 si->mfn_list = vphysmap_start; 86.38 + sprintf(si->magic, "Xen-%i.%i", XEN_VERSION, XEN_SUBVERSION); 86.39 86.40 /* Write the phys->machine and machine->phys table entries. */ 86.41 for ( pfn = 0; pfn < d->tot_pages; pfn++ )
87.1 --- a/xen/arch/x86/mm.c Sun Oct 30 13:52:38 2005 +0100 87.2 +++ b/xen/arch/x86/mm.c Sun Oct 30 14:00:35 2005 +0100 87.3 @@ -1164,6 +1164,7 @@ static int mod_l3_entry(l3_pgentry_t *pl 87.4 { 87.5 l3_pgentry_t ol3e; 87.6 unsigned long vaddr; 87.7 + int okay; 87.8 87.9 if ( unlikely(!is_guest_l3_slot(pgentry_ptr_to_slot(pl3e))) ) 87.10 { 87.11 @@ -1218,7 +1219,9 @@ static int mod_l3_entry(l3_pgentry_t *pl 87.12 return 0; 87.13 } 87.14 87.15 - BUG_ON(!create_pae_xen_mappings(pl3e)); 87.16 + okay = create_pae_xen_mappings(pl3e); 87.17 + BUG_ON(!okay); 87.18 + 87.19 put_page_from_l3e(ol3e, pfn); 87.20 return 1; 87.21 }
88.1 --- a/xen/arch/x86/time.c Sun Oct 30 13:52:38 2005 +0100 88.2 +++ b/xen/arch/x86/time.c Sun Oct 30 14:00:35 2005 +0100 88.3 @@ -323,7 +323,7 @@ static u64 read_pit_count(void) 88.4 return pit_counter64 + (u16)(pit_stamp - pit_read_counter()); 88.5 } 88.6 88.7 -static int init_pit(void) 88.8 +static void init_pit(void) 88.9 { 88.10 read_platform_count = read_pit_count; 88.11 88.12 @@ -333,8 +333,6 @@ static int init_pit(void) 88.13 88.14 printk("Platform timer is %s PIT\n", freq_string(CLOCK_TICK_RATE)); 88.15 using_pit = 1; 88.16 - 88.17 - return 1; 88.18 } 88.19 88.20 /************************************************************ 88.21 @@ -563,7 +561,7 @@ static void platform_time_calibration(vo 88.22 static void init_platform_timer(void) 88.23 { 88.24 if ( !init_cyclone() && !init_hpet() ) 88.25 - BUG_ON(!init_pit()); 88.26 + init_pit(); 88.27 } 88.28 88.29
89.1 --- a/xen/arch/x86/traps.c Sun Oct 30 13:52:38 2005 +0100 89.2 +++ b/xen/arch/x86/traps.c Sun Oct 30 14:00:35 2005 +0100 89.3 @@ -1147,6 +1147,9 @@ asmlinkage void do_nmi(struct cpu_user_r 89.4 89.5 asmlinkage int math_state_restore(struct cpu_user_regs *regs) 89.6 { 89.7 + struct trap_bounce *tb; 89.8 + trap_info_t *ti; 89.9 + 89.10 /* Prevent recursion. */ 89.11 clts(); 89.12 89.13 @@ -1154,10 +1157,15 @@ asmlinkage int math_state_restore(struct 89.14 89.15 if ( current->arch.guest_context.ctrlreg[0] & X86_CR0_TS ) 89.16 { 89.17 - struct trap_bounce *tb = ¤t->arch.trap_bounce; 89.18 + tb = ¤t->arch.trap_bounce; 89.19 + ti = ¤t->arch.guest_context.trap_ctxt[TRAP_no_device]; 89.20 + 89.21 tb->flags = TBF_EXCEPTION; 89.22 - tb->cs = current->arch.guest_context.trap_ctxt[7].cs; 89.23 - tb->eip = current->arch.guest_context.trap_ctxt[7].address; 89.24 + tb->cs = ti->cs; 89.25 + tb->eip = ti->address; 89.26 + if ( TI_GET_IF(ti) ) 89.27 + tb->flags |= TBF_INTERRUPT; 89.28 + 89.29 current->arch.guest_context.ctrlreg[0] &= ~X86_CR0_TS; 89.30 } 89.31 89.32 @@ -1169,6 +1177,7 @@ asmlinkage int do_debug(struct cpu_user_ 89.33 unsigned long condition; 89.34 struct vcpu *v = current; 89.35 struct trap_bounce *tb = &v->arch.trap_bounce; 89.36 + trap_info_t *ti; 89.37 89.38 __asm__ __volatile__("mov %%db6,%0" : "=r" (condition)); 89.39 89.40 @@ -1198,9 +1207,12 @@ asmlinkage int do_debug(struct cpu_user_ 89.41 /* Save debug status register where guest OS can peek at it */ 89.42 v->arch.guest_context.debugreg[6] = condition; 89.43 89.44 + ti = &v->arch.guest_context.trap_ctxt[TRAP_debug]; 89.45 tb->flags = TBF_EXCEPTION; 89.46 - tb->cs = v->arch.guest_context.trap_ctxt[TRAP_debug].cs; 89.47 - tb->eip = v->arch.guest_context.trap_ctxt[TRAP_debug].address; 89.48 + tb->cs = ti->cs; 89.49 + tb->eip = ti->address; 89.50 + if ( TI_GET_IF(ti) ) 89.51 + tb->flags |= TBF_INTERRUPT; 89.52 89.53 out: 89.54 return EXCRET_not_a_fault;
90.1 --- a/xen/arch/x86/vmx.c Sun Oct 30 13:52:38 2005 +0100 90.2 +++ b/xen/arch/x86/vmx.c Sun Oct 30 14:00:35 2005 +0100 90.3 @@ -65,6 +65,11 @@ void vmx_final_setup_guest(struct vcpu * 90.4 90.5 if ( v == v->domain->vcpu[0] ) 90.6 { 90.7 + v->domain->arch.vmx_platform.lapic_enable = 90.8 + v->arch.guest_context.user_regs.ecx; 90.9 + v->arch.guest_context.user_regs.ecx = 0; 90.10 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "lapic enable is %d.\n", 90.11 + v->domain->arch.vmx_platform.lapic_enable); 90.12 /* 90.13 * Required to do this once per domain 90.14 * XXX todo: add a seperate function to do these. 90.15 @@ -96,6 +101,10 @@ void vmx_relinquish_resources(struct vcp 90.16 destroy_vmcs(&v->arch.arch_vmx); 90.17 free_monitor_pagetable(v); 90.18 rem_ac_timer(&v->domain->arch.vmx_platform.vmx_pit.pit_timer); 90.19 + if ( vmx_apic_support(v->domain) ) { 90.20 + rem_ac_timer( &(VLAPIC(v)->vlapic_timer) ); 90.21 + xfree( VLAPIC(v) ); 90.22 + } 90.23 } 90.24 90.25 #ifdef __x86_64__ 90.26 @@ -442,7 +451,9 @@ static int vmx_do_page_fault(unsigned lo 90.27 90.28 /* Use 1:1 page table to identify MMIO address space */ 90.29 if ( mmio_space(gpa) ){ 90.30 - if (gpa >= 0xFEE00000) { /* workaround for local APIC */ 90.31 + struct vcpu *v = current; 90.32 + /* No support for APIC */ 90.33 + if (!vmx_apic_support(v->domain) && gpa >= 0xFEC00000) { 90.34 u32 inst_len; 90.35 __vmread(VM_EXIT_INSTRUCTION_LEN, &(inst_len)); 90.36 __update_guest_eip(inst_len); 90.37 @@ -487,6 +498,7 @@ static void vmx_vmexit_do_cpuid(unsigned 90.38 { 90.39 unsigned int eax, ebx, ecx, edx; 90.40 unsigned long eip; 90.41 + struct vcpu *v = current; 90.42 90.43 __vmread(GUEST_RIP, &eip); 90.44 90.45 @@ -500,6 +512,9 @@ static void vmx_vmexit_do_cpuid(unsigned 90.46 cpuid(input, &eax, &ebx, &ecx, &edx); 90.47 90.48 if (input == 1) { 90.49 + if ( vmx_apic_support(v->domain) && 90.50 + !vlapic_global_enabled((VLAPIC(v))) ) 90.51 + clear_bit(X86_FEATURE_APIC, &edx); 90.52 #ifdef __i386__ 90.53 clear_bit(X86_FEATURE_PSE, &edx); 90.54 clear_bit(X86_FEATURE_PAE, &edx); 90.55 @@ -1441,6 +1456,7 @@ static int vmx_cr_access(unsigned long e 90.56 static inline void vmx_do_msr_read(struct cpu_user_regs *regs) 90.57 { 90.58 u64 msr_content = 0; 90.59 + struct vcpu *v = current; 90.60 90.61 VMX_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_read: ecx=%lx, eax=%lx, edx=%lx", 90.62 (unsigned long)regs->ecx, (unsigned long)regs->eax, 90.63 @@ -1455,6 +1471,9 @@ static inline void vmx_do_msr_read(struc 90.64 case MSR_IA32_SYSENTER_EIP: 90.65 __vmread(GUEST_SYSENTER_EIP, &msr_content); 90.66 break; 90.67 + case MSR_IA32_APICBASE: 90.68 + msr_content = VLAPIC(v) ? VLAPIC(v)->apic_base_msr : 0; 90.69 + break; 90.70 default: 90.71 if(long_mode_do_msr_read(regs)) 90.72 return; 90.73 @@ -1474,6 +1493,7 @@ static inline void vmx_do_msr_read(struc 90.74 static inline void vmx_do_msr_write(struct cpu_user_regs *regs) 90.75 { 90.76 u64 msr_content; 90.77 + struct vcpu *v = current; 90.78 90.79 VMX_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_write: ecx=%lx, eax=%lx, edx=%lx", 90.80 (unsigned long)regs->ecx, (unsigned long)regs->eax, 90.81 @@ -1491,6 +1511,9 @@ static inline void vmx_do_msr_write(stru 90.82 case MSR_IA32_SYSENTER_EIP: 90.83 __vmwrite(GUEST_SYSENTER_EIP, msr_content); 90.84 break; 90.85 + case MSR_IA32_APICBASE: 90.86 + vlapic_msr_set(VLAPIC(v), msr_content); 90.87 + break; 90.88 default: 90.89 long_mode_do_msr_write(regs); 90.90 break;
91.1 --- a/xen/arch/x86/vmx_intercept.c Sun Oct 30 13:52:38 2005 +0100 91.2 +++ b/xen/arch/x86/vmx_intercept.c Sun Oct 30 14:00:35 2005 +0100 91.3 @@ -23,6 +23,7 @@ 91.4 #include <asm/vmx_platform.h> 91.5 #include <asm/vmx_virpit.h> 91.6 #include <asm/vmx_intercept.h> 91.7 +#include <asm/vmx_vlapic.h> 91.8 #include <public/io/ioreq.h> 91.9 #include <xen/lib.h> 91.10 #include <xen/sched.h> 91.11 @@ -32,6 +33,123 @@ 91.12 91.13 #ifdef CONFIG_VMX 91.14 91.15 +struct vmx_mmio_handler vmx_mmio_handers[VMX_MMIO_HANDLER_NR] = 91.16 +{ 91.17 + { 91.18 + .check_handler = vlapic_range, 91.19 + .read_handler = vlapic_read, 91.20 + .write_handler = vlapic_write 91.21 + } 91.22 +}; 91.23 + 91.24 +static inline void vmx_mmio_access(struct vcpu *v, 91.25 + ioreq_t *p, 91.26 + vmx_mmio_read_t read_handler, 91.27 + vmx_mmio_write_t write_handler) 91.28 +{ 91.29 + ioreq_t *req; 91.30 + vcpu_iodata_t *vio = get_vio(v->domain, v->vcpu_id); 91.31 + unsigned int tmp1, tmp2; 91.32 + unsigned long data; 91.33 + 91.34 + if (vio == NULL) { 91.35 + printk("vlapic_access: bad shared page\n"); 91.36 + domain_crash_synchronous(); 91.37 + } 91.38 + 91.39 + req = &vio->vp_ioreq; 91.40 + 91.41 + switch (req->type) { 91.42 + case IOREQ_TYPE_COPY: 91.43 + { 91.44 + int sign = (req->df) ? -1 : 1, i; 91.45 + 91.46 + if (!req->pdata_valid) { 91.47 + if (req->dir == IOREQ_READ){ 91.48 + req->u.data = read_handler(v, req->addr, req->size); 91.49 + } else { /* req->dir != IOREQ_READ */ 91.50 + write_handler(v, req->addr, req->size, req->u.data); 91.51 + } 91.52 + } else { /* !req->pdata_valid */ 91.53 + if (req->dir == IOREQ_READ) { 91.54 + for (i = 0; i < req->count; i++) { 91.55 + data = read_handler(v, 91.56 + req->addr + (sign * i * req->size), 91.57 + req->size); 91.58 + vmx_copy(&data, 91.59 + (unsigned long)p->u.pdata + (sign * i * req->size), 91.60 + p->size, 91.61 + VMX_COPY_OUT); 91.62 + } 91.63 + } else { /* !req->dir == IOREQ_READ */ 91.64 + for (i = 0; i < req->count; i++) { 91.65 + vmx_copy(&data, 91.66 + (unsigned long)p->u.pdata + (sign * i * req->size), 91.67 + p->size, 91.68 + VMX_COPY_IN); 91.69 + write_handler(v, 91.70 + req->addr + (sign * i * req->size), 91.71 + req->size, data); 91.72 + } 91.73 + } 91.74 + } 91.75 + break; 91.76 + } 91.77 + 91.78 + case IOREQ_TYPE_AND: 91.79 + tmp1 = read_handler(v, req->addr, req->size); 91.80 + if (req->dir == IOREQ_WRITE) { 91.81 + tmp2 = tmp1 & (unsigned long) req->u.data; 91.82 + write_handler(v, req->addr, req->size, tmp2); 91.83 + } 91.84 + req->u.data = tmp1; 91.85 + break; 91.86 + 91.87 + case IOREQ_TYPE_OR: 91.88 + tmp1 = read_handler(v, req->addr, req->size); 91.89 + if (req->dir == IOREQ_WRITE) { 91.90 + tmp2 = tmp1 | (unsigned long) req->u.data; 91.91 + write_handler(v, req->addr, req->size, tmp2); 91.92 + } 91.93 + req->u.data = tmp1; 91.94 + break; 91.95 + 91.96 + case IOREQ_TYPE_XOR: 91.97 + tmp1 = read_handler(v, req->addr, req->size); 91.98 + if (req->dir == IOREQ_WRITE) { 91.99 + tmp2 = tmp1 ^ (unsigned long) req->u.data; 91.100 + write_handler(v, req->addr, req->size, tmp2); 91.101 + } 91.102 + req->u.data = tmp1; 91.103 + break; 91.104 + 91.105 + default: 91.106 + printk("error ioreq type for local APIC %x\n", req->type); 91.107 + domain_crash_synchronous(); 91.108 + break; 91.109 + } 91.110 +} 91.111 + 91.112 +int vmx_mmio_intercept(ioreq_t *p) 91.113 +{ 91.114 + struct vcpu *v = current; 91.115 + int i; 91.116 + struct vmx_mmio_handler *handler = vmx_mmio_handers; 91.117 + 91.118 + /* XXX currently only APIC use intercept */ 91.119 + if ( !vmx_apic_support(v->domain) ) 91.120 + return 0; 91.121 + 91.122 + for ( i = 0; i < VMX_MMIO_HANDLER_NR; i++ ) { 91.123 + if ( handler[i].check_handler(v, p->addr) ) { 91.124 + vmx_mmio_access(v, p, 91.125 + handler[i].read_handler, handler[i].write_handler); 91.126 + return 1; 91.127 + } 91.128 + } 91.129 + return 0; 91.130 +} 91.131 + 91.132 /* 91.133 * Check if the request is handled inside xen 91.134 * return value: 0 --not handled; 1 --handled
92.1 --- a/xen/arch/x86/vmx_io.c Sun Oct 30 13:52:38 2005 +0100 92.2 +++ b/xen/arch/x86/vmx_io.c Sun Oct 30 14:00:35 2005 +0100 92.3 @@ -36,9 +36,9 @@ 92.4 #include <asm/apic.h> 92.5 #include <asm/shadow.h> 92.6 92.7 +#include <asm/vmx_vlapic.h> 92.8 #include <public/io/ioreq.h> 92.9 #include <public/io/vmx_vpic.h> 92.10 -#include <public/io/vmx_vlapic.h> 92.11 92.12 #ifdef CONFIG_VMX 92.13 #if defined (__i386__) 92.14 @@ -732,48 +732,6 @@ void vmx_wait_io() 92.15 } while(1); 92.16 } 92.17 92.18 -#if defined(__i386__) || defined(__x86_64__) 92.19 -static inline int __fls(u32 word) 92.20 -{ 92.21 - int bit; 92.22 - 92.23 - __asm__("bsrl %1,%0" 92.24 - :"=r" (bit) 92.25 - :"rm" (word)); 92.26 - return word ? bit : -1; 92.27 -} 92.28 -#else 92.29 -#define __fls(x) generic_fls(x) 92.30 -static __inline__ int generic_fls(u32 x) 92.31 -{ 92.32 - int r = 31; 92.33 - 92.34 - if (!x) 92.35 - return -1; 92.36 - if (!(x & 0xffff0000u)) { 92.37 - x <<= 16; 92.38 - r -= 16; 92.39 - } 92.40 - if (!(x & 0xff000000u)) { 92.41 - x <<= 8; 92.42 - r -= 8; 92.43 - } 92.44 - if (!(x & 0xf0000000u)) { 92.45 - x <<= 4; 92.46 - r -= 4; 92.47 - } 92.48 - if (!(x & 0xc0000000u)) { 92.49 - x <<= 2; 92.50 - r -= 2; 92.51 - } 92.52 - if (!(x & 0x80000000u)) { 92.53 - x <<= 1; 92.54 - r -= 1; 92.55 - } 92.56 - return r; 92.57 -} 92.58 -#endif 92.59 - 92.60 /* Simple minded Local APIC priority implementation. Fix later */ 92.61 static __inline__ int find_highest_irq(u32 *pintr) 92.62 { 92.63 @@ -801,31 +759,31 @@ interrupt_post_injection(struct vcpu * v 92.64 struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit); 92.65 u64 drift; 92.66 92.67 + if ( is_pit_irq(v, vector, type) ) { 92.68 + if ( !vpit->first_injected ) { 92.69 + vpit->first_injected = 1; 92.70 + vpit->pending_intr_nr = 0; 92.71 + } else { 92.72 + vpit->pending_intr_nr--; 92.73 + } 92.74 + vpit->inject_point = NOW(); 92.75 + drift = vpit->period_cycles * vpit->pending_intr_nr; 92.76 + drift = v->arch.arch_vmx.tsc_offset - drift; 92.77 + __vmwrite(TSC_OFFSET, drift); 92.78 + 92.79 +#if defined (__i386__) 92.80 + __vmwrite(TSC_OFFSET_HIGH, (drift >> 32)); 92.81 +#endif 92.82 + 92.83 + } 92.84 + 92.85 switch(type) 92.86 { 92.87 case VLAPIC_DELIV_MODE_EXT: 92.88 - if ( is_pit_irq(v, vector) ) { 92.89 - if ( !vpit->first_injected ) { 92.90 - vpit->first_injected = 1; 92.91 - vpit->pending_intr_nr = 0; 92.92 - } 92.93 - else { 92.94 - vpit->pending_intr_nr--; 92.95 - } 92.96 - vpit->inject_point = NOW(); 92.97 - drift = vpit->period_cycles * vpit->pending_intr_nr; 92.98 - drift = v->arch.arch_vmx.tsc_offset - drift; 92.99 - __vmwrite(TSC_OFFSET, drift); 92.100 - 92.101 -#if defined (__i386__) 92.102 - __vmwrite(TSC_OFFSET_HIGH, (drift >> 32)); 92.103 -#endif 92.104 - 92.105 - } 92.106 break; 92.107 92.108 default: 92.109 - printk("Not support interrupt type\n"); 92.110 + vlapic_post_injection(v, vector, type); 92.111 break; 92.112 } 92.113 } 92.114 @@ -885,6 +843,24 @@ void vmx_pic_assist(struct vcpu *v) 92.115 92.116 } 92.117 92.118 +int cpu_get_interrupt(struct vcpu *v, int *type) 92.119 +{ 92.120 + int intno; 92.121 + struct vmx_virpic *s = &v->domain->arch.vmx_platform.vmx_pic; 92.122 + 92.123 + if ( (intno = cpu_get_apic_interrupt(v, type)) != -1 ) { 92.124 + /* set irq request if a PIC irq is still pending */ 92.125 + /* XXX: improve that */ 92.126 + pic_update_irq(s); 92.127 + return intno; 92.128 + } 92.129 + /* read the irq from the PIC */ 92.130 + if ( (intno = cpu_get_pic_interrupt(v, type)) != -1 ) 92.131 + return intno; 92.132 + 92.133 + return -1; 92.134 +} 92.135 + 92.136 asmlinkage void vmx_intr_assist(void) 92.137 { 92.138 int intr_type = 0; 92.139 @@ -902,11 +878,6 @@ asmlinkage void vmx_intr_assist(void) 92.140 pic_set_irq(pic, 0, 1); 92.141 } 92.142 92.143 - if ( !plat->interrupt_request ) { 92.144 - disable_irq_window(cpu_exec_control); 92.145 - return; 92.146 - } 92.147 - 92.148 __vmread(VM_ENTRY_INTR_INFO_FIELD, &intr_fields); 92.149 92.150 if (intr_fields & INTR_INFO_VALID_MASK) { 92.151 @@ -928,16 +899,21 @@ asmlinkage void vmx_intr_assist(void) 92.152 enable_irq_window(cpu_exec_control); 92.153 return; 92.154 } 92.155 - plat->interrupt_request = 0; 92.156 - highest_vector = cpu_get_pic_interrupt(v, &intr_type); 92.157 + 92.158 + highest_vector = cpu_get_interrupt(v, &intr_type); 92.159 + 92.160 + if (highest_vector == -1) { 92.161 + disable_irq_window(cpu_exec_control); 92.162 + return; 92.163 + } 92.164 92.165 switch (intr_type) { 92.166 case VLAPIC_DELIV_MODE_EXT: 92.167 + case VLAPIC_DELIV_MODE_FIXED: 92.168 + case VLAPIC_DELIV_MODE_LPRI: 92.169 vmx_inject_extint(v, highest_vector, VMX_INVALID_ERROR_CODE); 92.170 TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0); 92.171 break; 92.172 - case VLAPIC_DELIV_MODE_FIXED: 92.173 - case VLAPIC_DELIV_MODE_LPRI: 92.174 case VLAPIC_DELIV_MODE_SMI: 92.175 case VLAPIC_DELIV_MODE_NMI: 92.176 case VLAPIC_DELIV_MODE_INIT:
93.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 93.2 +++ b/xen/arch/x86/vmx_vlapic.c Sun Oct 30 14:00:35 2005 +0100 93.3 @@ -0,0 +1,997 @@ 93.4 +/* 93.5 + * vmx_vlapic.c: virtualize LAPIC for VMX vcpus. 93.6 + * Copyright (c) 2004, Intel Corporation. 93.7 + * 93.8 + * This program is free software; you can redistribute it and/or modify it 93.9 + * under the terms and conditions of the GNU General Public License, 93.10 + * version 2, as published by the Free Software Foundation. 93.11 + * 93.12 + * This program is distributed in the hope it will be useful, but WITHOUT 93.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 93.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 93.15 + * more details. 93.16 + * 93.17 + * You should have received a copy of the GNU General Public License along with 93.18 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 93.19 + * Place - Suite 330, Boston, MA 02111-1307 USA. 93.20 + * 93.21 + */ 93.22 + 93.23 +#include <xen/config.h> 93.24 +#include <xen/types.h> 93.25 +#include <xen/mm.h> 93.26 +#include <xen/xmalloc.h> 93.27 +#include <asm/shadow.h> 93.28 +#include <asm/page.h> 93.29 +#include <xen/event.h> 93.30 +#include <xen/trace.h> 93.31 +#include <asm/vmx.h> 93.32 +#include <asm/vmx_platform.h> 93.33 +#include <asm/vmx_vlapic.h> 93.34 + 93.35 +#include <xen/lib.h> 93.36 +#include <xen/sched.h> 93.37 +#include <asm/current.h> 93.38 +#include <public/io/ioreq.h> 93.39 + 93.40 +#ifdef CONFIG_VMX 93.41 + 93.42 +/* XXX remove this definition after GFW enabled */ 93.43 +#define VLAPIC_NO_BIOS 93.44 + 93.45 +extern unsigned int get_apic_bus_scale(void); 93.46 + 93.47 +static unsigned int vlapic_lvt_mask[VLAPIC_LVT_NUM] = 93.48 +{ 93.49 + 0x310ff, 0x117ff, 0x117ff, 0x1f7ff, 0x1f7ff, 0x117ff 93.50 +}; 93.51 + 93.52 +int vlapic_find_highest_irr(struct vlapic *vlapic) 93.53 +{ 93.54 + int result; 93.55 + 93.56 + result = find_highest_bit((uint32_t *)&vlapic->irr[0], INTR_LEN_32); 93.57 + 93.58 + if (result != -1 && result < 16) { 93.59 + printk("VLAPIC: irr on reserved bits %d\n ", result); 93.60 + domain_crash_synchronous(); 93.61 + } 93.62 + 93.63 + return result; 93.64 +} 93.65 + 93.66 +inline int vmx_apic_support(struct domain *d) 93.67 +{ 93.68 + return d->arch.vmx_platform.lapic_enable; 93.69 +} 93.70 + 93.71 +int vlapic_find_highest_isr(struct vlapic *vlapic) 93.72 +{ 93.73 + int result; 93.74 + 93.75 + result = find_highest_bit((uint32_t *)&vlapic->isr[0], INTR_LEN_32); 93.76 + 93.77 + if (result != -1 && result < 16) { 93.78 + int i = 0; 93.79 + printk("VLAPIC: isr on reserved bits %d, isr is\n ", result); 93.80 + for (i = 0; i < INTR_LEN_32; i += 2) 93.81 + printk("%d: 0x%08x%08x\n", i, vlapic->isr[i], vlapic->isr[i+1]); 93.82 + return -1; 93.83 + } 93.84 + 93.85 + return result; 93.86 +} 93.87 + 93.88 +uint32_t vlapic_update_ppr(struct vlapic *vlapic) 93.89 +{ 93.90 + uint32_t tpr, isrv, ppr; 93.91 + int isr; 93.92 + 93.93 + tpr = (vlapic->task_priority >> 4) & 0xf; /* we want 7:4 */ 93.94 + 93.95 + isr = vlapic_find_highest_isr(vlapic); 93.96 + if (isr != -1) 93.97 + isrv = (isr >> 4) & 0xf; /* ditto */ 93.98 + else 93.99 + isrv = 0; 93.100 + 93.101 + if (tpr >= isrv) 93.102 + ppr = vlapic->task_priority & 0xff; 93.103 + else 93.104 + ppr = isrv << 4; /* low 4 bits of PPR have to be cleared */ 93.105 + 93.106 + vlapic->processor_priority = ppr; 93.107 + 93.108 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC_INTERRUPT, 93.109 + "vlapic_update_ppr: vlapic %p ppr %x isr %x isrv %x", 93.110 + vlapic, ppr, isr, isrv); 93.111 + 93.112 + return ppr; 93.113 +} 93.114 + 93.115 +/* This only for fixed delivery mode */ 93.116 +int vlapic_match_dest(struct vlapic *target, struct vlapic *source, 93.117 + int short_hand, int dest, int dest_mode, 93.118 + int delivery_mode) 93.119 +{ 93.120 + int result = 0; 93.121 + 93.122 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_match_dest: " 93.123 + "target %p source %p dest %x dest_mode %x short_hand %x " 93.124 + "delivery_mode %x", 93.125 + target, source, dest, dest_mode, short_hand, delivery_mode); 93.126 + 93.127 + switch (short_hand) { 93.128 + case VLAPIC_NO_SHORTHAND: 93.129 + if (!dest_mode) { /* Physical */ 93.130 + result = (target->id == dest); 93.131 + } else { /* Logical */ 93.132 + if (((target->dest_format >> 28) & 0xf) == 0xf) { /* Flat mode */ 93.133 + result = (target->logical_dest >> 24) & dest; 93.134 + } else { 93.135 + if ((delivery_mode == VLAPIC_DELIV_MODE_LPRI) && 93.136 + (dest == 0xff)) { 93.137 + /* What shall we do now? */ 93.138 + printk("Broadcast IPI with lowest priority " 93.139 + "delivery mode\n"); 93.140 + domain_crash_synchronous(); 93.141 + } 93.142 + result = (target->logical_dest == (dest & 0xf)) ? 93.143 + ((target->logical_dest >> 4) & (dest >> 4)) : 0; 93.144 + } 93.145 + } 93.146 + break; 93.147 + 93.148 + case VLAPIC_SHORTHAND_SELF: 93.149 + if (target == source) 93.150 + result = 1; 93.151 + break; 93.152 + 93.153 + case VLAPIC_SHORTHAND_INCLUDE_SELF: 93.154 + result = 1; 93.155 + break; 93.156 + 93.157 + case VLAPIC_SHORTHAND_EXCLUDE_SELF: 93.158 + if (target != source) 93.159 + result = 1; 93.160 + break; 93.161 + 93.162 + default: 93.163 + break; 93.164 + } 93.165 + 93.166 + return result; 93.167 +} 93.168 + 93.169 +/* 93.170 + * Add a pending IRQ into lapic. 93.171 + * Return 1 if successfully added and 0 if discarded. 93.172 + */ 93.173 +int vlapic_accept_irq(struct vlapic *vlapic, int delivery_mode, 93.174 + int vector, int level, int trig_mode) 93.175 +{ 93.176 + int result = 1; 93.177 + 93.178 + switch (delivery_mode) { 93.179 + case VLAPIC_DELIV_MODE_FIXED: 93.180 + case VLAPIC_DELIV_MODE_LPRI: 93.181 + /* FIXME add logic for vcpu on reset */ 93.182 + if (!vlapic->vcpu || !vlapic_enabled(vlapic)) 93.183 + return 0; 93.184 + 93.185 + if (test_and_set_bit(vector, &vlapic->irr[0])) { 93.186 + printk("<vlapic_accept_irq>" 93.187 + "level trig mode repeatedly for vector %d\n", vector); 93.188 + result = 0; 93.189 + } else { 93.190 + if (level) { 93.191 + printk("<vlapic_accept_irq> level trig mode for vector %d\n", vector); 93.192 + set_bit(vector, &vlapic->tmr[0]); 93.193 + } 93.194 + } 93.195 + evtchn_set_pending(vlapic->vcpu, iopacket_port(vlapic->domain)); 93.196 + break; 93.197 + 93.198 + case VLAPIC_DELIV_MODE_RESERVED: 93.199 + printk("Ignore deliver mode 3 in vlapic_accept_irq\n"); 93.200 + break; 93.201 + 93.202 + case VLAPIC_DELIV_MODE_SMI: 93.203 + case VLAPIC_DELIV_MODE_NMI: 93.204 + /* Fixme */ 93.205 + printk("TODO: for guest SMI/NMI\n"); 93.206 + break; 93.207 + 93.208 + case VLAPIC_DELIV_MODE_INIT: 93.209 + if (!level && trig_mode == 1) { //Deassert 93.210 + printk("This vmx_vlapic is for P4, no work for De-assert init\n"); 93.211 + } else { 93.212 + /* FIXME How to check the situation after vcpu reset? */ 93.213 + vlapic->init_sipi_sipi_state = VLAPIC_INIT_SIPI_SIPI_STATE_WAIT_SIPI; 93.214 + if (vlapic->vcpu) { 93.215 + vcpu_pause(vlapic->vcpu); 93.216 + } 93.217 + } 93.218 + break; 93.219 + 93.220 + case VLAPIC_DELIV_MODE_STARTUP: 93.221 + if (vlapic->init_sipi_sipi_state != VLAPIC_INIT_SIPI_SIPI_STATE_WAIT_SIPI) 93.222 + break; 93.223 + vlapic->init_sipi_sipi_state = VLAPIC_INIT_SIPI_SIPI_STATE_NORM; 93.224 + if (!vlapic->vcpu) { 93.225 + /* XXX Call vmx_bringup_ap here */ 93.226 + result = 0; 93.227 + }else{ 93.228 + //vmx_vcpu_reset(vlapic->vcpu); 93.229 + } 93.230 + break; 93.231 + 93.232 + default: 93.233 + printk("TODO: not support interrup type %x\n", delivery_mode); 93.234 + domain_crash_synchronous(); 93.235 + break; 93.236 + } 93.237 + 93.238 + return result; 93.239 +} 93.240 +/* 93.241 + This function is used by both ioapic and local APIC 93.242 + The bitmap is for vcpu_id 93.243 + */ 93.244 +struct vlapic* apic_round_robin(struct domain *d, 93.245 + uint8_t dest_mode, 93.246 + uint8_t vector, 93.247 + uint32_t bitmap) 93.248 +{ 93.249 + int next, old; 93.250 + struct vlapic* target = NULL; 93.251 + 93.252 + if (dest_mode == 0) { //Physical mode 93.253 + printk("<apic_round_robin> lowest priority for physical mode\n"); 93.254 + return NULL; 93.255 + } 93.256 + 93.257 + if (!bitmap) { 93.258 + printk("<apic_round_robin> no bit on bitmap\n"); 93.259 + return NULL; 93.260 + } 93.261 + 93.262 + spin_lock(&d->arch.vmx_platform.round_robin_lock); 93.263 + 93.264 + old = next = d->arch.vmx_platform.round_info[vector]; 93.265 + 93.266 + next++; 93.267 + if (next == MAX_VIRT_CPUS || !d->vcpu[next]) 93.268 + next = 0; 93.269 + 93.270 + do { 93.271 + /* the vcpu array is arranged according to vcpu_id */ 93.272 + if (test_bit(next, &bitmap)) { 93.273 + target = d->vcpu[next]->arch.arch_vmx.vlapic; 93.274 + if (!vlapic_enabled(target)) { 93.275 + printk("warning: targe round robin local apic disabled\n"); 93.276 + /* XXX should we domain crash?? Or should we return NULL */ 93.277 + } 93.278 + break; 93.279 + } 93.280 + 93.281 + next ++; 93.282 + if (next == MAX_VIRT_CPUS || !d->vcpu[next]) 93.283 + next = 0; 93.284 + }while(next != old); 93.285 + 93.286 + d->arch.vmx_platform.round_info[vector] = next; 93.287 + spin_unlock(&d->arch.vmx_platform.round_robin_lock); 93.288 + return target; 93.289 +} 93.290 + 93.291 +void 93.292 +vlapic_EOI_set(struct vlapic *vlapic) 93.293 +{ 93.294 + int vector = vlapic_find_highest_isr(vlapic); 93.295 + 93.296 + /* Not every write EOI will has correpsoning ISR, 93.297 + one example is when Kernel check timer on setup_IO_APIC */ 93.298 + if (vector == -1) { 93.299 + return ; 93.300 + } 93.301 + 93.302 + vlapic_clear_isr(vlapic, vector); 93.303 + vlapic_update_ppr(vlapic); 93.304 +} 93.305 + 93.306 +int vlapic_check_vector(struct vlapic *vlapic, 93.307 + unsigned char dm, int vector) 93.308 +{ 93.309 + if ((dm == VLAPIC_DELIV_MODE_FIXED) && (vector < 16)) { 93.310 + vlapic->err_status |= 0x40; 93.311 + vlapic_accept_irq(vlapic, VLAPIC_DELIV_MODE_FIXED, 93.312 + vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR), 0, 0); 93.313 + printk("<vlapic_check_vector>: check fail\n"); 93.314 + return 0; 93.315 + } 93.316 + return 1; 93.317 +} 93.318 + 93.319 + 93.320 +void vlapic_ipi(struct vlapic *vlapic) 93.321 +{ 93.322 + unsigned int dest = (vlapic->icr_high >> 24) & 0xff; 93.323 + unsigned int short_hand = (vlapic->icr_low >> 18) & 3; 93.324 + unsigned int trig_mode = (vlapic->icr_low >> 15) & 1; 93.325 + unsigned int level = (vlapic->icr_low >> 14) & 1; 93.326 + unsigned int dest_mode = (vlapic->icr_low >> 11) & 1; 93.327 + unsigned int delivery_mode = (vlapic->icr_low >> 8) & 7; 93.328 + unsigned int vector = (vlapic->icr_low & 0xff); 93.329 + 93.330 + struct vlapic *target; 93.331 + struct vcpu *v = NULL; 93.332 + int result = 0; 93.333 + uint32_t lpr_map; 93.334 + 93.335 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_ipi: " 93.336 + "icr_high %x icr_low %x " 93.337 + "short_hand %x dest %x trig_mode %x level %x " 93.338 + "dest_mode %x delivery_mode %x vector %x", 93.339 + vlapic->icr_high, vlapic->icr_low, 93.340 + short_hand, dest, trig_mode, level, dest_mode, 93.341 + delivery_mode, vector); 93.342 + 93.343 + for_each_vcpu ( vlapic->domain, v ) { 93.344 + target = VLAPIC(v); 93.345 + if (vlapic_match_dest(target, vlapic, short_hand, 93.346 + dest, dest_mode, delivery_mode)) { 93.347 + if (delivery_mode == VLAPIC_DELIV_MODE_LPRI) { 93.348 + set_bit(v->vcpu_id, &lpr_map); 93.349 + }else 93.350 + result = vlapic_accept_irq(target, delivery_mode, 93.351 + vector, level, trig_mode); 93.352 + } 93.353 + } 93.354 + 93.355 + if (delivery_mode == VLAPIC_DELIV_MODE_LPRI) { 93.356 + extern struct vlapic* 93.357 + apic_round_robin(struct domain *d, 93.358 + uint8_t dest_mode, uint8_t vector, uint32_t bitmap); 93.359 + 93.360 + v = vlapic->vcpu; 93.361 + target = apic_round_robin(v->domain, dest_mode, vector, lpr_map); 93.362 + 93.363 + if (target) 93.364 + vlapic_accept_irq(target, delivery_mode, 93.365 + vector, level, trig_mode); 93.366 + } 93.367 +} 93.368 + 93.369 +void vlapic_begin_timer(struct vlapic *vlapic) 93.370 +{ 93.371 + s_time_t cur = NOW(), offset; 93.372 + 93.373 + offset = vlapic->timer_current * 93.374 + (262144 / get_apic_bus_scale()) * vlapic->timer_divide_counter; 93.375 + vlapic->vlapic_timer.expires = cur + offset; 93.376 + 93.377 + set_ac_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires ); 93.378 + 93.379 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_begin_timer: " 93.380 + "bus_scale %x now %08x%08x expire %08x%08x " 93.381 + "offset %08x%08x current %x", 93.382 + get_apic_bus_scale(), (uint32_t)(cur >> 32), (uint32_t)cur, 93.383 + (uint32_t)(vlapic->vlapic_timer.expires >> 32), 93.384 + (uint32_t) vlapic->vlapic_timer.expires, 93.385 + (uint32_t)(offset >> 32), (uint32_t)offset, 93.386 + vlapic->timer_current); 93.387 +} 93.388 + 93.389 +void vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset, 93.390 + unsigned int len, unsigned int *result) 93.391 +{ 93.392 + if (len != 4) { 93.393 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC, 93.394 + "local apic read with len=%d (should be 4)", len); 93.395 + } 93.396 + 93.397 + *result = 0; 93.398 + 93.399 + switch (offset) { 93.400 + case APIC_ID: 93.401 + *result = (vlapic->id) << 24; 93.402 + break; 93.403 + 93.404 + case APIC_LVR: 93.405 + *result = vlapic->version; 93.406 + break; 93.407 + 93.408 + case APIC_TASKPRI: 93.409 + *result = vlapic->task_priority; 93.410 + break; 93.411 + 93.412 + case APIC_ARBPRI: 93.413 + printk("Access local APIC ARBPRI register which is for P6\n"); 93.414 + break; 93.415 + 93.416 + case APIC_PROCPRI: 93.417 + *result = vlapic->processor_priority; 93.418 + break; 93.419 + 93.420 + case APIC_EOI: /* EOI is write only */ 93.421 + break; 93.422 + 93.423 + case APIC_LDR: 93.424 + *result = vlapic->logical_dest; 93.425 + break; 93.426 + 93.427 + case APIC_DFR: 93.428 + *result = vlapic->dest_format; 93.429 + break; 93.430 + 93.431 + case APIC_SPIV: 93.432 + *result = vlapic->spurious_vec; 93.433 + break; 93.434 + 93.435 + case APIC_ISR: 93.436 + case 0x110: 93.437 + case 0x120: 93.438 + case 0x130: 93.439 + case 0x140: 93.440 + case 0x150: 93.441 + case 0x160: 93.442 + case 0x170: 93.443 + *result = vlapic->isr[(offset - APIC_ISR) >> 4]; 93.444 + break; 93.445 + 93.446 + case APIC_TMR: 93.447 + case 0x190: 93.448 + case 0x1a0: 93.449 + case 0x1b0: 93.450 + case 0x1c0: 93.451 + case 0x1d0: 93.452 + case 0x1e0: 93.453 + case 0x1f0: 93.454 + *result = vlapic->tmr[(offset - APIC_TMR) >> 4]; 93.455 + break; 93.456 + 93.457 + case APIC_IRR: 93.458 + case 0x210: 93.459 + case 0x220: 93.460 + case 0x230: 93.461 + case 0x240: 93.462 + case 0x250: 93.463 + case 0x260: 93.464 + case 0x270: 93.465 + *result = vlapic->irr[(offset - APIC_IRR) >> 4]; 93.466 + break; 93.467 + 93.468 + case APIC_ESR: 93.469 + if (vlapic->err_write_count) 93.470 + *result = vlapic->err_status; 93.471 + break; 93.472 + 93.473 + case APIC_ICR: 93.474 + *result = vlapic->icr_low; 93.475 + break; 93.476 + 93.477 + case APIC_ICR2: 93.478 + *result = vlapic->icr_high; 93.479 + break; 93.480 + 93.481 + case APIC_LVTT: /* LVT Timer Reg */ 93.482 + case APIC_LVTTHMR: /* LVT Thermal Monitor */ 93.483 + case APIC_LVTPC: /* LVT Performance Counter */ 93.484 + case APIC_LVT0: /* LVT LINT0 Reg */ 93.485 + case APIC_LVT1: /* LVT Lint1 Reg */ 93.486 + case APIC_LVTERR: /* LVT Error Reg */ 93.487 + *result = vlapic->lvt[(offset - APIC_LVTT) >> 4]; 93.488 + break; 93.489 + 93.490 + case APIC_TMICT: 93.491 + *result = vlapic->timer_initial; 93.492 + break; 93.493 + 93.494 + case APIC_TMCCT: //Timer CCR 93.495 + { 93.496 + uint32_t counter; 93.497 + s_time_t passed, cur = NOW(); 93.498 + 93.499 + if (cur <= vlapic->timer_current_update) { 93.500 + passed = ~0x0LL - vlapic->timer_current_update + cur; 93.501 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC,"time elapsed"); 93.502 + }else 93.503 + passed = cur - vlapic->timer_current_update; 93.504 + 93.505 + counter = (passed * get_apic_bus_scale()) / (262144* vlapic->timer_divide_counter); 93.506 + if (vlapic->timer_current > counter) 93.507 + *result = vlapic->timer_current - counter; 93.508 + else { 93.509 + if (!vlapic_lvt_timer_period(vlapic)) 93.510 + *result = 0; 93.511 + //FIXME should we add interrupt here? 93.512 + else 93.513 + //*result = counter % vlapic->timer_initial; 93.514 + *result = vlapic->timer_initial - (counter - vlapic->timer_current); 93.515 + } 93.516 + vlapic->timer_current = *result; 93.517 + vlapic->timer_current_update = NOW(); 93.518 + 93.519 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, 93.520 + "initial %x timer current %x " 93.521 + "update %08x%08x cur %08x%08x offset %d", 93.522 + vlapic->timer_initial, vlapic->timer_current, 93.523 + (uint32_t)(vlapic->timer_current_update >> 32), 93.524 + (uint32_t)vlapic->timer_current_update , 93.525 + (uint32_t)(cur >> 32), (uint32_t)cur, counter); 93.526 + } 93.527 + break; 93.528 + 93.529 + case APIC_TDCR: 93.530 + *result = vlapic->timer_divconf; 93.531 + break; 93.532 + 93.533 + default: 93.534 + printk("Read local APIC address %x not implemented\n",offset); 93.535 + *result = 0; 93.536 + break; 93.537 + } 93.538 +} 93.539 + 93.540 +unsigned long vlapic_read(struct vcpu *v, unsigned long address, 93.541 + unsigned long len) 93.542 +{ 93.543 + unsigned int alignment; 93.544 + unsigned int tmp; 93.545 + unsigned long result; 93.546 + struct vlapic *vlapic = VLAPIC(v); 93.547 + unsigned int offset = address - vlapic->base_address; 93.548 + 93.549 + if ( len != 4) { 93.550 + /* some bugs on kernel cause read this with byte*/ 93.551 + printk("Local APIC read with len = %lx, should be 4 instead\n", len); 93.552 + } 93.553 + 93.554 + alignment = offset & 0x3; 93.555 + 93.556 + vlapic_read_aligned(vlapic, offset & ~0x3, 4, &tmp); 93.557 + switch (len) { 93.558 + case 1: 93.559 + result = *((unsigned char *)&tmp + alignment); 93.560 + break; 93.561 + 93.562 + case 2: 93.563 + result = *(unsigned short *)((unsigned char *)&tmp + alignment); 93.564 + break; 93.565 + 93.566 + case 4: 93.567 + result = *(unsigned int *)((unsigned char *)&tmp + alignment); 93.568 + break; 93.569 + 93.570 + default: 93.571 + printk("Local APIC read with len = %lx, should be 4 instead\n", len); 93.572 + domain_crash_synchronous(); 93.573 + break; 93.574 + } 93.575 + 93.576 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC, 93.577 + "vlapic_read offset %x with length %lx and the result is %lx", 93.578 + offset, len, result); 93.579 + return result; 93.580 +} 93.581 + 93.582 +unsigned long vlapic_write(struct vcpu *v, unsigned long address, 93.583 + unsigned long len, unsigned long val) 93.584 +{ 93.585 + struct vlapic *vlapic = VLAPIC(v); 93.586 + unsigned int offset = address - vlapic->base_address; 93.587 + 93.588 + if (offset != 0xb0) 93.589 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC, 93.590 + "vlapic_write offset %x with length %lx source %lx", 93.591 + offset, len, val); 93.592 + 93.593 + /* 93.594 + * According to IA 32 Manual, all resgiters should be accessed with 93.595 + * 32 bits alignment. 93.596 + */ 93.597 + if (len != 4) { 93.598 + unsigned int tmp; 93.599 + unsigned char alignment; 93.600 + 93.601 + /* Some kernel do will access with byte/word alignment*/ 93.602 + printk("Notice: Local APIC write with len = %lx\n",len); 93.603 + alignment = offset & 0x3; 93.604 + tmp = vlapic_read(v, offset & (~0x3), 4); 93.605 + switch (len) { 93.606 + case 1: 93.607 + /* XXX the saddr is a tmp variable from caller, so should be ok 93.608 + But we should still change the following ref to val to 93.609 + local variable later */ 93.610 + val = (tmp & ~(0xff << alignment)) | 93.611 + ((val & 0xff) << alignment); 93.612 + break; 93.613 + 93.614 + case 2: 93.615 + if (alignment != 0x0 && alignment != 0x2) { 93.616 + printk("alignment error for vlapic with len == 2\n"); 93.617 + domain_crash_synchronous(); 93.618 + } 93.619 + 93.620 + val = (tmp & ~(0xffff << alignment)) | 93.621 + ((val & 0xffff) << alignment); 93.622 + break; 93.623 + 93.624 + case 3: 93.625 + /* will it happen? */ 93.626 + printk("vlapic_write with len = 3 !!!\n"); 93.627 + domain_crash_synchronous(); 93.628 + break; 93.629 + 93.630 + default: 93.631 + printk("Local APIC write with len = %lx, should be 4 instead\n", len); 93.632 + domain_crash_synchronous(); 93.633 + break; 93.634 + } 93.635 + } 93.636 + 93.637 + offset &= 0xff0; 93.638 + 93.639 + switch (offset) { 93.640 + case APIC_ID: /* Local APIC ID */ 93.641 + vlapic->id = ((val) >> 24) & VAPIC_ID_MASK; 93.642 + break; 93.643 + 93.644 + case APIC_TASKPRI: 93.645 + vlapic->task_priority = val & 0xff; 93.646 + vlapic_update_ppr(vlapic); 93.647 + break; 93.648 + 93.649 + case APIC_EOI: 93.650 + vlapic_EOI_set(vlapic); 93.651 + break; 93.652 + 93.653 + case APIC_LDR: 93.654 + vlapic->logical_dest = val & VAPIC_LDR_MASK; 93.655 + break; 93.656 + 93.657 + case APIC_DFR: 93.658 + vlapic->dest_format = val ; 93.659 + break; 93.660 + 93.661 + case APIC_SPIV: 93.662 + vlapic->spurious_vec = val & 0x1ff; 93.663 + if (!(vlapic->spurious_vec & 0x100)) { 93.664 + int i = 0; 93.665 + for (i=0; i < VLAPIC_LVT_NUM; i++) 93.666 + vlapic->lvt[i] |= 0x10000; 93.667 + vlapic->status |= VLAPIC_SOFTWARE_DISABLE_MASK; 93.668 + } 93.669 + else 93.670 + vlapic->status &= ~VLAPIC_SOFTWARE_DISABLE_MASK; 93.671 + break; 93.672 + 93.673 + case APIC_ESR: 93.674 + vlapic->err_write_count = !vlapic->err_write_count; 93.675 + if (!vlapic->err_write_count) 93.676 + vlapic->err_status = 0; 93.677 + break; 93.678 + 93.679 + case APIC_ICR: 93.680 + /* No delay here, so we always clear the pending bit*/ 93.681 + vlapic->icr_low = val & ~(1 << 12); 93.682 + vlapic_ipi(vlapic); 93.683 + break; 93.684 + 93.685 + case APIC_ICR2: 93.686 + vlapic->icr_high = val & 0xff000000; 93.687 + break; 93.688 + 93.689 + case APIC_LVTT: // LVT Timer Reg 93.690 + case APIC_LVTTHMR: // LVT Thermal Monitor 93.691 + case APIC_LVTPC: // LVT Performance Counter 93.692 + case APIC_LVT0: // LVT LINT0 Reg 93.693 + case APIC_LVT1: // LVT Lint1 Reg 93.694 + case APIC_LVTERR: // LVT Error Reg 93.695 + { 93.696 + int vt = (offset - APIC_LVTT) >> 4; 93.697 + 93.698 + vlapic->lvt[vt] = val & vlapic_lvt_mask[vt]; 93.699 + if (vlapic->status & VLAPIC_SOFTWARE_DISABLE_MASK) 93.700 + vlapic->lvt[vt] |= VLAPIC_LVT_BIT_MASK; 93.701 + 93.702 + /* On hardware, when write vector less than 0x20 will error */ 93.703 + vlapic_check_vector(vlapic, vlapic_lvt_dm(vlapic->lvt[vt]), 93.704 + vlapic_lvt_vector(vlapic, vt)); 93.705 + 93.706 + if (!vlapic->vcpu_id && (offset == APIC_LVT0)) { 93.707 + if ((vlapic->lvt[VLAPIC_LVT_LINT0] & VLAPIC_LVT_BIT_DELIMOD) 93.708 + == 0x700) { 93.709 + if (!(vlapic->lvt[VLAPIC_LVT_LINT0] & VLAPIC_LVT_BIT_MASK)) { 93.710 + set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); 93.711 + }else 93.712 + clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); 93.713 + } 93.714 + else 93.715 + clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); 93.716 + } 93.717 + 93.718 + } 93.719 + break; 93.720 + 93.721 + case APIC_TMICT: 93.722 + if (vlapic_timer_active(vlapic)) 93.723 + rem_ac_timer(&(vlapic->vlapic_timer)); 93.724 + 93.725 + vlapic->timer_initial = val; 93.726 + vlapic->timer_current = val; 93.727 + vlapic->timer_current_update = NOW(); 93.728 + 93.729 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC, 93.730 + "timer_init %x timer_current %x timer_current_update %08x%08x", 93.731 + vlapic->timer_initial, vlapic->timer_current, (uint32_t)(vlapic->timer_current_update>>32), (uint32_t)vlapic->timer_current_update); 93.732 + vlapic_begin_timer(vlapic); 93.733 + break; 93.734 + 93.735 + case APIC_TDCR: 93.736 + { 93.737 + //FIXME clean this code 93.738 + unsigned char tmp1,tmp2; 93.739 + tmp1 = (val & 0xf); 93.740 + tmp2 = ((tmp1 & 0x3 )|((tmp1 & 0x8) >>1)) + 1; 93.741 + vlapic->timer_divide_counter = 0x1<<tmp2; 93.742 + 93.743 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, 93.744 + "timer divider is 0x%x", 93.745 + vlapic->timer_divide_counter); 93.746 + } 93.747 + break; 93.748 + 93.749 + default: 93.750 + printk("Local APIC Write to read-only register\n"); 93.751 + break; 93.752 + } 93.753 + return 1; 93.754 +} 93.755 + 93.756 +int vlapic_range(struct vcpu *v, unsigned long addr) 93.757 +{ 93.758 + struct vlapic *vlapic = VLAPIC(v); 93.759 + 93.760 + if (vlapic_global_enabled(vlapic) && 93.761 + (addr >= vlapic->base_address) && 93.762 + (addr <= (vlapic->base_address + VLOCAL_APIC_MEM_LENGTH))) 93.763 + return 1; 93.764 + 93.765 + return 0; 93.766 +} 93.767 + 93.768 +void vlapic_msr_set(struct vlapic *vlapic, uint64_t value) 93.769 +{ 93.770 + /* When apic disabled */ 93.771 + if (!vlapic) 93.772 + return; 93.773 + 93.774 + if (vlapic->vcpu_id) 93.775 + value &= ~MSR_IA32_APICBASE_BSP; 93.776 + 93.777 + vlapic->apic_base_msr = value; 93.778 + vlapic->base_address = vlapic_get_base_address(vlapic); 93.779 + 93.780 + if (!(value & 0x800)) 93.781 + set_bit(_VLAPIC_GLOB_DISABLE, &vlapic->status ); 93.782 + 93.783 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC, 93.784 + "apic base msr = 0x%08x%08x,\nbase address = 0x%lx", 93.785 + (uint32_t)(vlapic->apic_base_msr >> 32), 93.786 + (uint32_t)vlapic->apic_base_msr, 93.787 + vlapic->base_address); 93.788 +} 93.789 + 93.790 +static inline int vlapic_get_init_id(struct vcpu *v) 93.791 +{ 93.792 + return v->vcpu_id; 93.793 +} 93.794 + 93.795 +void vlapic_timer_fn(void *data) 93.796 +{ 93.797 + struct vlapic *vlapic; 93.798 + 93.799 + vlapic = data; 93.800 + if (!vlapic_enabled(vlapic)) return; 93.801 + 93.802 + vlapic->timer_current_update = NOW(); 93.803 + 93.804 + if (vlapic_lvt_timer_enabled(vlapic)) { 93.805 + if (!vlapic_irr_status(vlapic, 93.806 + vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER))) { 93.807 + test_and_set_bit(vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER), 93.808 + &vlapic->irr[0]); 93.809 + } 93.810 + else 93.811 + vlapic->intr_pending_count[vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER)]++; 93.812 + } 93.813 + 93.814 + vlapic->timer_current_update = NOW(); 93.815 + if (vlapic_lvt_timer_period(vlapic)) { 93.816 + s_time_t offset; 93.817 + 93.818 + vlapic->timer_current = vlapic->timer_initial; 93.819 + offset = vlapic->timer_current * (262144/get_apic_bus_scale()) * vlapic->timer_divide_counter; 93.820 + vlapic->vlapic_timer.expires = NOW() + offset; 93.821 + set_ac_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires); 93.822 + }else { 93.823 + vlapic->timer_current = 0; 93.824 + } 93.825 + 93.826 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, 93.827 + "vlapic_timer_fn: now: %08x%08x expire %08x%08x init %x current %x", 93.828 + (uint32_t)(NOW() >> 32),(uint32_t)NOW(), 93.829 + (uint32_t)(vlapic->vlapic_timer.expires >> 32), 93.830 + (uint32_t)vlapic->vlapic_timer.expires, 93.831 + vlapic->timer_initial,vlapic->timer_current); 93.832 +} 93.833 + 93.834 +#if 0 93.835 +static int 93.836 +vlapic_check_direct_intr(struct vcpu *v, int * mode) 93.837 +{ 93.838 + struct vlapic *vlapic = VLAPIC(v); 93.839 + int type; 93.840 + 93.841 + type = __fls(vlapic->direct_intr.deliver_mode); 93.842 + if (type == -1) 93.843 + return -1; 93.844 + 93.845 + *mode = type; 93.846 + return 0; 93.847 +} 93.848 +#endif 93.849 + 93.850 +int 93.851 +vlapic_accept_pic_intr(struct vcpu *v) 93.852 +{ 93.853 + struct vlapic *vlapic = VLAPIC(v); 93.854 + 93.855 + return vlapic ? test_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status) : 1; 93.856 +} 93.857 + 93.858 +int cpu_get_apic_interrupt(struct vcpu* v, int *mode) 93.859 +{ 93.860 + struct vlapic *vlapic = VLAPIC(v); 93.861 + 93.862 + if (vlapic && vlapic_enabled(vlapic)) { 93.863 + int highest_irr = vlapic_find_highest_irr(vlapic); 93.864 + 93.865 + if (highest_irr != -1 && highest_irr >= vlapic->processor_priority) { 93.866 + if (highest_irr < 0x10) { 93.867 + vlapic->err_status |= 0x20; 93.868 + /* XXX What will happen if this vector illegal stil */ 93.869 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC, 93.870 + "vmx_intr_assist: illegal vector number %x err_status %x", 93.871 + highest_irr, vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR)); 93.872 + 93.873 + set_bit(vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR), &vlapic->irr[0]); 93.874 + highest_irr = vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR); 93.875 + } 93.876 + 93.877 + *mode = VLAPIC_DELIV_MODE_FIXED; 93.878 + return highest_irr; 93.879 + } 93.880 + } 93.881 + return -1; 93.882 +} 93.883 + 93.884 +void vlapic_post_injection(struct vcpu *v, int vector, int deliver_mode) { 93.885 + struct vlapic *vlapic = VLAPIC(v); 93.886 + 93.887 + if (!vlapic) 93.888 + return; 93.889 + 93.890 + switch (deliver_mode) { 93.891 + case VLAPIC_DELIV_MODE_FIXED: 93.892 + case VLAPIC_DELIV_MODE_LPRI: 93.893 + vlapic_set_isr(vlapic, vector); 93.894 + vlapic_clear_irr(vlapic, vector); 93.895 + vlapic_update_ppr(vlapic); 93.896 + 93.897 + if (vector == vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER)) { 93.898 + vlapic->intr_pending_count[vector]--; 93.899 + if (vlapic->intr_pending_count[vector] > 0) 93.900 + test_and_set_bit(vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER), 93.901 + &vlapic->irr[0]); 93.902 + } 93.903 + 93.904 + break; 93.905 + /*XXX deal with these later */ 93.906 + 93.907 + case VLAPIC_DELIV_MODE_RESERVED: 93.908 + printk("Ignore deliver mode 3 in vlapic_post_injection\n"); 93.909 + break; 93.910 + 93.911 + case VLAPIC_DELIV_MODE_SMI: 93.912 + case VLAPIC_DELIV_MODE_NMI: 93.913 + case VLAPIC_DELIV_MODE_INIT: 93.914 + case VLAPIC_DELIV_MODE_STARTUP: 93.915 + vlapic->direct_intr.deliver_mode &= ~(1 << deliver_mode); 93.916 + break; 93.917 + 93.918 + default: 93.919 + printk("<vlapic_post_injection> error deliver mode\n"); 93.920 + break; 93.921 + } 93.922 +} 93.923 + 93.924 +static int vlapic_reset(struct vlapic *vlapic) 93.925 +{ 93.926 + struct vcpu *v = vlapic->vcpu; 93.927 + int apic_id = v->vcpu_id, i; 93.928 + 93.929 + if (!v || !vlapic) 93.930 + return 0; 93.931 + 93.932 + memset(vlapic, 0,sizeof(struct vlapic)); 93.933 + 93.934 + v->arch.arch_vmx.vlapic = vlapic; 93.935 + 93.936 + vlapic->domain = v->domain; 93.937 + 93.938 + vlapic->id = apic_id; 93.939 + 93.940 + vlapic->version = VLAPIC_VERSION; 93.941 + 93.942 + vlapic->apic_base_msr = VLAPIC_BASE_MSR_INIT_VALUE; 93.943 + 93.944 + if (apic_id == 0) 93.945 + vlapic->apic_base_msr |= MSR_IA32_APICBASE_BSP; 93.946 + vlapic->base_address = vlapic_get_base_address(vlapic); 93.947 + 93.948 + for (i = 0; i < VLAPIC_LVT_NUM; i++) 93.949 + vlapic->lvt[i] = VLAPIC_LVT_BIT_MASK; 93.950 + 93.951 + vlapic->dest_format = 0xffffffffU; 93.952 + 93.953 + vlapic->spurious_vec = 0xff; 93.954 + 93.955 + 93.956 + init_ac_timer(&vlapic->vlapic_timer, 93.957 + vlapic_timer_fn, vlapic, v->processor); 93.958 + 93.959 +#ifdef VLAPIC_NO_BIOS 93.960 + /* 93.961 + * XXX According to mp sepcific, BIOS will enable LVT0/1, 93.962 + * remove it after BIOS enabled 93.963 + */ 93.964 + if (!v->vcpu_id) { 93.965 + vlapic->lvt[VLAPIC_LVT_LINT0] = 0x700; 93.966 + vlapic->lvt[VLAPIC_LVT_LINT1] = 0x500; 93.967 + set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status); 93.968 + } 93.969 +#endif 93.970 + 93.971 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_reset: " 93.972 + "vcpu=%p id=%d vlapic_apic_base_msr=%08x%08x " 93.973 + "vlapic_base_address=%0lx", 93.974 + v, vlapic->id, (uint32_t)(vlapic->apic_base_msr >> 32), 93.975 + (uint32_t)vlapic->apic_base_msr, vlapic->base_address); 93.976 + 93.977 + return 1; 93.978 +} 93.979 + 93.980 +int vlapic_init(struct vcpu *v) 93.981 +{ 93.982 + struct vlapic *vlapic = NULL; 93.983 + 93.984 + VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_init %d", v->vcpu_id); 93.985 + 93.986 + vlapic = xmalloc_bytes(sizeof(struct vlapic)); 93.987 + 93.988 + if (!vlapic) { 93.989 + printk("malloc vlapic error for vcpu %x\n", v->vcpu_id); 93.990 + return -ENOMEM; 93.991 + } 93.992 + 93.993 + vlapic->vcpu = v; 93.994 + 93.995 + vlapic_reset(vlapic); 93.996 + 93.997 + return 0; 93.998 +} 93.999 + 93.1000 +#endif /* CONFIG_VMX */
94.1 --- a/xen/arch/x86/vmx_vmcs.c Sun Oct 30 13:52:38 2005 +0100 94.2 +++ b/xen/arch/x86/vmx_vmcs.c Sun Oct 30 14:00:35 2005 +0100 94.3 @@ -252,6 +252,10 @@ static void vmx_setup_platform(struct do 94.4 pic_init(&platform->vmx_pic, pic_irq_request, 94.5 &platform->interrupt_request); 94.6 register_pic_io_hook(); 94.7 + 94.8 + if ( vmx_apic_support(d) ) { 94.9 + spin_lock_init(&d->arch.vmx_platform.round_robin_lock); 94.10 + } 94.11 } 94.12 94.13 static void vmx_set_host_env(struct vcpu *v) 94.14 @@ -313,6 +317,9 @@ static void vmx_do_launch(struct vcpu *v 94.15 94.16 vmx_stts(); 94.17 94.18 + if(vmx_apic_support(v->domain)) 94.19 + vlapic_init(v); 94.20 + 94.21 vmx_set_host_env(v); 94.22 94.23 error |= __vmwrite(GUEST_LDTR_SELECTOR, 0);
95.1 --- a/xen/common/acm_ops.c Sun Oct 30 13:52:38 2005 +0100 95.2 +++ b/xen/common/acm_ops.c Sun Oct 30 14:00:35 2005 +0100 95.3 @@ -133,7 +133,10 @@ long do_acm_op(struct acm_op * u_acm_op) 95.4 struct domain *subj = find_domain_by_id(op->u.getssid.id.domainid); 95.5 if (!subj) 95.6 return -ESRCH; /* domain not found */ 95.7 - 95.8 + if (subj->ssid == NULL) { 95.9 + put_domain(subj); 95.10 + return -ESRCH; 95.11 + } 95.12 ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; 95.13 put_domain(subj); 95.14 } else 95.15 @@ -167,6 +170,10 @@ long do_acm_op(struct acm_op * u_acm_op) 95.16 ret = -ESRCH; /* domain not found */ 95.17 goto out; 95.18 } 95.19 + if (subj->ssid == NULL) { 95.20 + put_domain(subj); 95.21 + ret = -ESRCH; 95.22 + } 95.23 ssidref1 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; 95.24 put_domain(subj); 95.25 } else { 95.26 @@ -182,6 +189,10 @@ long do_acm_op(struct acm_op * u_acm_op) 95.27 ret = -ESRCH; /* domain not found */ 95.28 goto out; 95.29 } 95.30 + if (subj->ssid == NULL) { 95.31 + put_domain(subj); 95.32 + return -ESRCH; 95.33 + } 95.34 ssidref2 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; 95.35 put_domain(subj); 95.36 } else {
96.1 --- a/xen/common/schedule.c Sun Oct 30 13:52:38 2005 +0100 96.2 +++ b/xen/common/schedule.c Sun Oct 30 14:00:35 2005 +0100 96.3 @@ -514,7 +514,7 @@ static void dom_timer_fn(void *data) 96.4 /* Initialise the data structures. */ 96.5 void __init scheduler_init(void) 96.6 { 96.7 - int i; 96.8 + int i, rc; 96.9 96.10 open_softirq(SCHEDULE_SOFTIRQ, __enter_scheduler); 96.11 96.12 @@ -540,7 +540,9 @@ void __init scheduler_init(void) 96.13 96.14 printk("Using scheduler: %s (%s)\n", ops.name, ops.opt_name); 96.15 96.16 - BUG_ON(SCHED_OP(alloc_task, idle_task[0]) < 0); 96.17 + rc = SCHED_OP(alloc_task, idle_task[0]); 96.18 + BUG_ON(rc < 0); 96.19 + 96.20 sched_add_domain(idle_task[0]); 96.21 } 96.22
97.1 --- a/xen/include/acm/acm_hooks.h Sun Oct 30 13:52:38 2005 +0100 97.2 +++ b/xen/include/acm/acm_hooks.h Sun Oct 30 14:00:35 2005 +0100 97.3 @@ -100,10 +100,10 @@ struct acm_operations { 97.4 void (*fail_domain_create) (void *subject_ssid, ssidref_t ssidref); 97.5 void (*post_domain_destroy) (void *object_ssid, domid_t id); 97.6 /* event channel control hooks (can be NULL) */ 97.7 - int (*pre_eventchannel_unbound) (domid_t id); 97.8 - void (*fail_eventchannel_unbound) (domid_t id); 97.9 - int (*pre_eventchannel_interdomain) (domid_t id1, domid_t id2); 97.10 - int (*fail_eventchannel_interdomain) (domid_t id1, domid_t id2); 97.11 + int (*pre_eventchannel_unbound) (domid_t id1, domid_t id2); 97.12 + void (*fail_eventchannel_unbound) (domid_t id1, domid_t id2); 97.13 + int (*pre_eventchannel_interdomain) (domid_t id); 97.14 + void (*fail_eventchannel_interdomain) (domid_t id); 97.15 /* grant table control hooks (can be NULL) */ 97.16 int (*pre_grant_map_ref) (domid_t id); 97.17 void (*fail_grant_map_ref) (domid_t id); 97.18 @@ -193,31 +193,31 @@ static inline void acm_post_domain_destr 97.19 return; 97.20 } 97.21 97.22 -static inline int acm_pre_eventchannel_unbound(domid_t id) 97.23 +static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2) 97.24 { 97.25 if ((acm_primary_ops->pre_eventchannel_unbound != NULL) && 97.26 - acm_primary_ops->pre_eventchannel_unbound(id)) 97.27 + acm_primary_ops->pre_eventchannel_unbound(id1, id2)) 97.28 return ACM_ACCESS_DENIED; 97.29 else if ((acm_secondary_ops->pre_eventchannel_unbound != NULL) && 97.30 - acm_secondary_ops->pre_eventchannel_unbound(id)) { 97.31 + acm_secondary_ops->pre_eventchannel_unbound(id1, id2)) { 97.32 /* roll-back primary */ 97.33 if (acm_primary_ops->fail_eventchannel_unbound != NULL) 97.34 - acm_primary_ops->fail_eventchannel_unbound(id); 97.35 + acm_primary_ops->fail_eventchannel_unbound(id1, id2); 97.36 return ACM_ACCESS_DENIED; 97.37 } else 97.38 return ACM_ACCESS_PERMITTED; 97.39 } 97.40 97.41 -static inline int acm_pre_eventchannel_interdomain(domid_t id1, domid_t id2) 97.42 +static inline int acm_pre_eventchannel_interdomain(domid_t id) 97.43 { 97.44 if ((acm_primary_ops->pre_eventchannel_interdomain != NULL) && 97.45 - acm_primary_ops->pre_eventchannel_interdomain(id1, id2)) 97.46 + acm_primary_ops->pre_eventchannel_interdomain(id)) 97.47 return ACM_ACCESS_DENIED; 97.48 else if ((acm_secondary_ops->pre_eventchannel_interdomain != NULL) && 97.49 - acm_secondary_ops->pre_eventchannel_interdomain(id1, id2)) { 97.50 + acm_secondary_ops->pre_eventchannel_interdomain(id)) { 97.51 /* roll-back primary */ 97.52 if (acm_primary_ops->fail_eventchannel_interdomain != NULL) 97.53 - acm_primary_ops->fail_eventchannel_interdomain(id1, id2); 97.54 + acm_primary_ops->fail_eventchannel_interdomain(id); 97.55 return ACM_ACCESS_DENIED; 97.56 } else 97.57 return ACM_ACCESS_PERMITTED; 97.58 @@ -234,10 +234,22 @@ static inline int acm_pre_dom0_op(dom0_o 97.59 current->domain->ssid, op->u.createdomain.ssidref); 97.60 break; 97.61 case DOM0_DESTROYDOMAIN: 97.62 + if (*ssid != NULL) { 97.63 + printkd("%s: Warning. Overlapping destruction.\n", 97.64 + __func__); 97.65 + return -EACCES; 97.66 + } 97.67 d = find_domain_by_id(op->u.destroydomain.domain); 97.68 if (d != NULL) { 97.69 *ssid = d->ssid; /* save for post destroy when d is gone */ 97.70 - /* no policy-specific hook */ 97.71 + if (*ssid == NULL) { 97.72 + printk("%s: Warning. Destroying domain without ssid pointer.\n", 97.73 + __func__); 97.74 + put_domain(d); 97.75 + return -EACCES; 97.76 + } 97.77 + d->ssid = NULL; /* make sure it's not used any more */ 97.78 + /* no policy-specific hook */ 97.79 put_domain(d); 97.80 ret = 0; 97.81 } 97.82 @@ -248,7 +260,7 @@ static inline int acm_pre_dom0_op(dom0_o 97.83 return ret; 97.84 } 97.85 97.86 -static inline void acm_post_dom0_op(dom0_op_t *op, void *ssid) 97.87 +static inline void acm_post_dom0_op(dom0_op_t *op, void **ssid) 97.88 { 97.89 switch(op->cmd) { 97.90 case DOM0_CREATEDOMAIN: 97.91 @@ -261,7 +273,8 @@ static inline void acm_post_dom0_op(dom0 97.92 case DOM0_DESTROYDOMAIN: 97.93 acm_post_domain_destroy(ssid, op->u.destroydomain.domain); 97.94 /* free security ssid for the destroyed domain (also if null policy */ 97.95 - acm_free_domain_ssid((struct acm_ssid_domain *)ssid); 97.96 + acm_free_domain_ssid((struct acm_ssid_domain *)(*ssid)); 97.97 + *ssid = NULL; 97.98 break; 97.99 } 97.100 } 97.101 @@ -282,12 +295,13 @@ static inline int acm_pre_event_channel( 97.102 97.103 switch(op->cmd) { 97.104 case EVTCHNOP_alloc_unbound: 97.105 - ret = acm_pre_eventchannel_unbound(op->u.alloc_unbound.dom); 97.106 + ret = acm_pre_eventchannel_unbound( 97.107 + op->u.alloc_unbound.dom, 97.108 + op->u.alloc_unbound.remote_dom); 97.109 break; 97.110 case EVTCHNOP_bind_interdomain: 97.111 ret = acm_pre_eventchannel_interdomain( 97.112 - current->domain->domain_id, 97.113 - op->u.bind_interdomain.remote_dom); 97.114 + op->u.bind_interdomain.remote_dom); 97.115 break; 97.116 default: 97.117 ret = 0; /* ok */
98.1 --- a/xen/include/asm-ia64/config.h Sun Oct 30 13:52:38 2005 +0100 98.2 +++ b/xen/include/asm-ia64/config.h Sun Oct 30 14:00:35 2005 +0100 98.3 @@ -28,8 +28,8 @@ 98.4 98.5 #ifdef CONFIG_XEN_SMP 98.6 #define CONFIG_SMP 1 98.7 -#define NR_CPUS 2 98.8 -#define CONFIG_NR_CPUS 2 98.9 +#define NR_CPUS 8 98.10 +#define CONFIG_NR_CPUS 8 98.11 #else 98.12 #undef CONFIG_SMP 98.13 #define NR_CPUS 1 98.14 @@ -102,7 +102,7 @@ extern char _end[]; /* standard ELF symb 98.15 #endif 98.16 98.17 // xen/include/asm/config.h 98.18 -#define HZ 100 98.19 +//#define HZ 1000 98.20 // FIXME SMP: leave SMP for a later time 98.21 #define barrier() __asm__ __volatile__("": : :"memory") 98.22 98.23 @@ -123,8 +123,7 @@ extern char _end[]; /* standard ELF symb 98.24 #ifdef CONFIG_SMP 98.25 #warning "Lots of things to fix to enable CONFIG_SMP!" 98.26 #endif 98.27 -// FIXME SMP 98.28 -#define get_cpu() 0 98.29 +#define get_cpu() smp_processor_id() 98.30 #define put_cpu() do {} while(0) 98.31 98.32 // needed for common/dom0_ops.c until hyperthreading is supported 98.33 @@ -140,6 +139,7 @@ struct page; 98.34 // function calls; see decl in xen/include/xen/sched.h 98.35 #undef free_task_struct 98.36 #undef alloc_task_struct 98.37 +#define get_thread_info(v) alloc_thread_info(v) 98.38 98.39 // initial task has a different name in Xen 98.40 //#define idle0_task init_task 98.41 @@ -299,7 +299,11 @@ extern int ht_per_core; 98.42 #endif /* __XEN_IA64_CONFIG_H__ */ 98.43 98.44 // needed for include/xen/smp.h 98.45 +#ifdef CONFIG_SMP 98.46 +#define __smp_processor_id() current_thread_info()->cpu 98.47 +#else 98.48 #define __smp_processor_id() 0 98.49 +#endif 98.50 98.51 98.52 // FOLLOWING ADDED FOR XEN POST-NGIO and/or LINUX 2.6.7
99.1 --- a/xen/include/asm-ia64/domain.h Sun Oct 30 13:52:38 2005 +0100 99.2 +++ b/xen/include/asm-ia64/domain.h Sun Oct 30 14:00:35 2005 +0100 99.3 @@ -49,6 +49,8 @@ struct arch_vcpu { 99.4 TR_ENTRY dtrs[NDTRS]; 99.5 TR_ENTRY itlb; 99.6 TR_ENTRY dtlb; 99.7 + unsigned int itr_regions; 99.8 + unsigned int dtr_regions; 99.9 unsigned long itlb_pte; 99.10 unsigned long dtlb_pte; 99.11 unsigned long irr[4];
100.1 --- a/xen/include/asm-ia64/event.h Sun Oct 30 13:52:38 2005 +0100 100.2 +++ b/xen/include/asm-ia64/event.h Sun Oct 30 14:00:35 2005 +0100 100.3 @@ -14,6 +14,21 @@ 100.4 100.5 static inline void evtchn_notify(struct vcpu *v) 100.6 { 100.7 + /* 100.8 + * NB1. 'vcpu_flags' and 'processor' must be checked /after/ update of 100.9 + * pending flag. These values may fluctuate (after all, we hold no 100.10 + * locks) but the key insight is that each change will cause 100.11 + * evtchn_upcall_pending to be polled. 100.12 + * 100.13 + * NB2. We save VCPUF_running across the unblock to avoid a needless 100.14 + * IPI for domains that we IPI'd to unblock. 100.15 + */ 100.16 + int running = test_bit(_VCPUF_running, &v->vcpu_flags); 100.17 + vcpu_unblock(v); 100.18 + if ( running ) 100.19 + smp_send_event_check_cpu(v->processor); 100.20 + 100.21 + if(!VMX_DOMAIN(v)) 100.22 vcpu_pend_interrupt(v, v->vcpu_info->arch.evtchn_vector); 100.23 } 100.24
101.1 --- a/xen/include/asm-ia64/linux-xen/asm/spinlock.h Sun Oct 30 13:52:38 2005 +0100 101.2 +++ b/xen/include/asm-ia64/linux-xen/asm/spinlock.h Sun Oct 30 14:00:35 2005 +0100 101.3 @@ -17,11 +17,16 @@ 101.4 #include <asm/intrinsics.h> 101.5 #include <asm/system.h> 101.6 101.7 +#define DEBUG_SPINLOCK 101.8 + 101.9 typedef struct { 101.10 volatile unsigned int lock; 101.11 #ifdef CONFIG_PREEMPT 101.12 unsigned int break_lock; 101.13 #endif 101.14 +#ifdef DEBUG_SPINLOCK 101.15 + void *locker; 101.16 +#endif 101.17 #ifdef XEN 101.18 unsigned char recurse_cpu; 101.19 unsigned char recurse_cnt; 101.20 @@ -96,6 +101,10 @@ static inline void 101.21 : "=r"(ptr) : "r"(ptr), "r" (flags) : IA64_SPINLOCK_CLOBBERS); 101.22 # endif /* CONFIG_MCKINLEY */ 101.23 #endif 101.24 + 101.25 +#ifdef DEBUG_SPINLOCK 101.26 + asm volatile ("mov %0=ip" : "=r" (lock->locker)); 101.27 +#endif 101.28 } 101.29 #define _raw_spin_lock(lock) _raw_spin_lock_flags(lock, 0) 101.30 #else /* !ASM_SUPPORTED */
102.1 --- a/xen/include/asm-ia64/linux-xen/linux/hardirq.h Sun Oct 30 13:52:38 2005 +0100 102.2 +++ b/xen/include/asm-ia64/linux-xen/linux/hardirq.h Sun Oct 30 14:00:35 2005 +0100 102.3 @@ -67,11 +67,7 @@ 102.4 */ 102.5 #define in_irq() (hardirq_count()) 102.6 #define in_softirq() (softirq_count()) 102.7 -#ifdef XEN 102.8 -#define in_interrupt() 0 // FIXME SMP LATER 102.9 -#else 102.10 #define in_interrupt() (irq_count()) 102.11 -#endif 102.12 102.13 #if defined(CONFIG_PREEMPT) && !defined(CONFIG_PREEMPT_BKL) 102.14 # define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
103.1 --- a/xen/include/asm-ia64/linux-xen/linux/interrupt.h Sun Oct 30 13:52:38 2005 +0100 103.2 +++ b/xen/include/asm-ia64/linux-xen/linux/interrupt.h Sun Oct 30 14:00:35 2005 +0100 103.3 @@ -88,6 +88,7 @@ static inline void __deprecated save_and 103.4 #define save_and_cli(x) save_and_cli(&x) 103.5 #endif /* CONFIG_SMP */ 103.6 103.7 +#ifndef XEN 103.8 /* SoftIRQ primitives. */ 103.9 #define local_bh_disable() \ 103.10 do { add_preempt_count(SOFTIRQ_OFFSET); barrier(); } while (0) 103.11 @@ -95,6 +96,7 @@ static inline void __deprecated save_and 103.12 do { barrier(); sub_preempt_count(SOFTIRQ_OFFSET); } while (0) 103.13 103.14 extern void local_bh_enable(void); 103.15 +#endif 103.16 103.17 /* PLEASE, avoid to allocate new softirqs, if you need not _really_ high 103.18 frequency threaded job scheduling. For almost all the purposes
104.1 --- a/xen/include/asm-ia64/mm.h Sun Oct 30 13:52:38 2005 +0100 104.2 +++ b/xen/include/asm-ia64/mm.h Sun Oct 30 14:00:35 2005 +0100 104.3 @@ -405,6 +405,7 @@ extern unsigned long totalram_pages; 104.4 extern int nr_swap_pages; 104.5 104.6 extern unsigned long *mpt_table; 104.7 +extern unsigned long lookup_domain_mpa(struct domain *d, unsigned long mpaddr); 104.8 #undef machine_to_phys_mapping 104.9 #define machine_to_phys_mapping mpt_table 104.10 104.11 @@ -433,10 +434,10 @@ extern unsigned long *mpt_table; 104.12 104.13 #define __gpfn_is_mem(_d, gpfn) \ 104.14 (__gpfn_valid(_d, gpfn) ? \ 104.15 - (lookup_domain_mpa((_d), ((gpfn)<<PAGE_SHIFT) & GPFN_IO_MASK) == GPFN_MEM) : 0) 104.16 + ((lookup_domain_mpa((_d), ((gpfn)<<PAGE_SHIFT)) & GPFN_IO_MASK) == GPFN_MEM) : 0) 104.17 104.18 104.19 -//#define __gpa_to_mpa(_d, gpa) \ 104.20 -// ((__gpfn_to_mfn((_d),(gpa)>>PAGE_SHIFT)<<PAGE_SHIFT)|((gpa)&~PAGE_MASK)) 104.21 +#define __gpa_to_mpa(_d, gpa) \ 104.22 + ((__gpfn_to_mfn((_d),(gpa)>>PAGE_SHIFT)<<PAGE_SHIFT)|((gpa)&~PAGE_MASK)) 104.23 104.24 #endif /* __ASM_IA64_MM_H__ */
105.1 --- a/xen/include/asm-ia64/vhpt.h Sun Oct 30 13:52:38 2005 +0100 105.2 +++ b/xen/include/asm-ia64/vhpt.h Sun Oct 30 14:00:35 2005 +0100 105.3 @@ -5,27 +5,16 @@ 105.4 #define VHPT_ENABLED_REGION_0_TO_6 1 105.5 #define VHPT_ENABLED_REGION_7 0 105.6 105.7 +/* Size of the VHPT. */ 105.8 +#define VHPT_SIZE_LOG2 24 105.9 105.10 -#if 0 105.11 +/* Number of entries in the VHPT. The size of an entry is 4*8B == 32B */ 105.12 +#define VHPT_NUM_ENTRIES (1 << (VHPT_SIZE_LOG2 - 5)) 105.13 + 105.14 +#define VHPT_CACHE_MASK (VHPT_NUM_ENTRIES - 1) 105.15 #define VHPT_CACHE_ENTRY_SIZE 64 105.16 -#define VHPT_CACHE_MASK 2097151 105.17 -#define VHPT_CACHE_NUM_ENTRIES 32768 105.18 -#define VHPT_NUM_ENTRIES 2097152 105.19 -#define VHPT_CACHE_ENTRY_SIZE_LOG2 6 105.20 -#define VHPT_SIZE_LOG2 26 //???? 105.21 -#define VHPT_PAGE_SHIFT 26 //???? 105.22 -#else 105.23 -//#define VHPT_CACHE_NUM_ENTRIES 2048 105.24 -//#define VHPT_NUM_ENTRIES 131072 105.25 -//#define VHPT_CACHE_MASK 131071 105.26 -//#define VHPT_SIZE_LOG2 22 //???? 105.27 -#define VHPT_CACHE_ENTRY_SIZE 64 105.28 -#define VHPT_CACHE_NUM_ENTRIES 8192 105.29 -#define VHPT_NUM_ENTRIES 524288 105.30 -#define VHPT_CACHE_MASK 524287 105.31 -#define VHPT_SIZE_LOG2 24 //???? 105.32 -#define VHPT_PAGE_SHIFT 24 //???? 105.33 -#endif 105.34 + 105.35 +#define VHPT_PAGE_SHIFT VHPT_SIZE_LOG2 105.36 105.37 // FIXME: These should be automatically generated 105.38 105.39 @@ -52,7 +41,7 @@ 105.40 // VHPT collison chain entry (part of the "V-Cache") 105.41 // DO NOT CHANGE THE SIZE OF THIS STRUCTURE (see vhpt.S banked regs calculations) 105.42 // 105.43 -typedef struct vcache_entry { 105.44 +struct vcache_entry { 105.45 union { 105.46 struct { 105.47 unsigned long tag : 63; // 0-62 105.48 @@ -123,12 +112,21 @@ struct vhpt_lf_entry { 105.49 105.50 #define INVALID_TI_TAG 0x8000000000000000L 105.51 105.52 +extern void vhpt_init (void); 105.53 +extern void zero_vhpt_stats(void); 105.54 +extern int dump_vhpt_stats(char *buf); 105.55 +extern void vhpt_flush_address(unsigned long vadr, unsigned long addr_range); 105.56 +extern void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte, 105.57 + unsigned long logps); 105.58 +extern void vhpt_insert (unsigned long vadr, unsigned long ptr, 105.59 + unsigned logps); 105.60 +extern void vhpt_flush(void); 105.61 #endif /* !__ASSEMBLY */ 105.62 105.63 #if !VHPT_ENABLED 105.64 #define VHPT_CCHAIN_LOOKUP(Name, i_or_d) 105.65 #else 105.66 -#ifdef CONFIG_SMP 105.67 +#if 0 /* One VHPT per cpu! def CONFIG_SMP */ 105.68 #warning "FIXME SMP: VHPT_CCHAIN_LOOKUP needs a semaphore on the VHPT!" 105.69 #endif 105.70
106.1 --- a/xen/include/asm-ia64/vmx.h Sun Oct 30 13:52:38 2005 +0100 106.2 +++ b/xen/include/asm-ia64/vmx.h Sun Oct 30 14:00:35 2005 +0100 106.3 @@ -25,6 +25,7 @@ 106.4 #define RR7_SWITCH_SHIFT 12 /* 4k enough */ 106.5 #include <public/io/ioreq.h> 106.6 106.7 + 106.8 extern void identify_vmx_feature(void); 106.9 extern unsigned int vmx_enabled; 106.10 extern void vmx_init_env(void);
107.1 --- a/xen/include/asm-ia64/xenkregs.h Sun Oct 30 13:52:38 2005 +0100 107.2 +++ b/xen/include/asm-ia64/xenkregs.h Sun Oct 30 14:00:35 2005 +0100 107.3 @@ -6,7 +6,8 @@ 107.4 */ 107.5 #define IA64_TR_SHARED_INFO 3 /* dtr3: page shared with domain */ 107.6 #define IA64_TR_VHPT 4 /* dtr4: vhpt */ 107.7 -#define IA64_TR_ARCH_INFO 5 107.8 +#define IA64_TR_ARCH_INFO 5 107.9 +#define IA64_TR_PERVP_VHPT 6 107.10 107.11 /* Processor status register bits: */ 107.12 #define IA64_PSR_VM_BIT 46
108.1 --- a/xen/include/asm-x86/vmx_intercept.h Sun Oct 30 13:52:38 2005 +0100 108.2 +++ b/xen/include/asm-x86/vmx_intercept.h Sun Oct 30 14:00:35 2005 +0100 108.3 @@ -14,6 +14,16 @@ 108.4 #define VMX_MMIO 1 108.5 108.6 typedef int (*intercept_action_t)(ioreq_t *); 108.7 +typedef unsigned long (*vmx_mmio_read_t)(struct vcpu *v, 108.8 + unsigned long addr, 108.9 + unsigned long length); 108.10 + 108.11 +typedef unsigned long (*vmx_mmio_write_t)(struct vcpu *v, 108.12 + unsigned long addr, 108.13 + unsigned long length, 108.14 + unsigned long val); 108.15 + 108.16 +typedef int (*vmx_mmio_check_t)(struct vcpu *v, unsigned long addr); 108.17 108.18 struct io_handler { 108.19 int type; 108.20 @@ -27,6 +37,16 @@ struct vmx_io_handler { 108.21 struct io_handler hdl_list[MAX_IO_HANDLER]; 108.22 }; 108.23 108.24 +struct vmx_mmio_handler { 108.25 + vmx_mmio_check_t check_handler; 108.26 + vmx_mmio_read_t read_handler; 108.27 + vmx_mmio_write_t write_handler; 108.28 +}; 108.29 + 108.30 +#define VMX_MMIO_HANDLER_NR 1 108.31 + 108.32 +extern struct vmx_mmio_handler vmx_mmio_handers[VMX_MMIO_HANDLER_NR]; 108.33 + 108.34 /* global io interception point in HV */ 108.35 extern int vmx_io_intercept(ioreq_t *p, int type); 108.36 extern int register_io_handler(unsigned long addr, unsigned long size, 108.37 @@ -37,10 +57,7 @@ static inline int vmx_portio_intercept(i 108.38 return vmx_io_intercept(p, VMX_PORTIO); 108.39 } 108.40 108.41 -static inline int vmx_mmio_intercept(ioreq_t *p) 108.42 -{ 108.43 - return vmx_io_intercept(p, VMX_MMIO); 108.44 -} 108.45 +int vmx_mmio_intercept(ioreq_t *p); 108.46 108.47 static inline int register_portio_handler(unsigned long addr, 108.48 unsigned long size, 108.49 @@ -49,11 +66,4 @@ static inline int register_portio_handle 108.50 return register_io_handler(addr, size, action, VMX_PORTIO); 108.51 } 108.52 108.53 -static inline int register_mmio_handler(unsigned long addr, 108.54 - unsigned long size, 108.55 - intercept_action_t action) 108.56 -{ 108.57 - return register_io_handler(addr, size, action, VMX_MMIO); 108.58 -} 108.59 - 108.60 #endif /* _VMX_INTERCEPT_H */
109.1 --- a/xen/include/asm-x86/vmx_platform.h Sun Oct 30 13:52:38 2005 +0100 109.2 +++ b/xen/include/asm-x86/vmx_platform.h Sun Oct 30 14:00:35 2005 +0100 109.3 @@ -80,10 +80,13 @@ struct instruction { 109.4 struct vmx_platform { 109.5 unsigned long shared_page_va; 109.6 unsigned int nr_vcpu; 109.7 + unsigned int lapic_enable; 109.8 109.9 struct vmx_virpit vmx_pit; 109.10 struct vmx_io_handler vmx_io_handler; 109.11 struct vmx_virpic vmx_pic; 109.12 + unsigned char round_info[256]; 109.13 + spinlock_t round_robin_lock; 109.14 int interrupt_request; 109.15 }; 109.16
110.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 110.2 +++ b/xen/include/asm-x86/vmx_vlapic.h Sun Oct 30 14:00:35 2005 +0100 110.3 @@ -0,0 +1,245 @@ 110.4 +/* 110.5 + * vmx_vlapic.h: virtualize LAPIC definitions. 110.6 + * Copyright (c) 2004, Intel Corporation. 110.7 + * 110.8 + * This program is free software; you can redistribute it and/or modify it 110.9 + * under the terms and conditions of the GNU General Public License, 110.10 + * version 2, as published by the Free Software Foundation. 110.11 + * 110.12 + * This program is distributed in the hope it will be useful, but WITHOUT 110.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 110.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 110.15 + * more details. 110.16 + * 110.17 + * You should have received a copy of the GNU General Public License along with 110.18 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 110.19 + * Place - Suite 330, Boston, MA 02111-1307 USA. 110.20 + * 110.21 + */ 110.22 + 110.23 +#ifndef VMX_VLAPIC_H 110.24 +#define VMX_VLAPIC_H 110.25 + 110.26 +#include <asm/msr.h> 110.27 +#include <public/io/ioreq.h> 110.28 + 110.29 +#if defined(__i386__) || defined(__x86_64__) 110.30 +static inline int __fls(uint32_t word) 110.31 +{ 110.32 + int bit; 110.33 + 110.34 + __asm__("bsrl %1,%0" 110.35 + :"=r" (bit) 110.36 + :"rm" (word)); 110.37 + return word ? bit : -1; 110.38 +} 110.39 +#else 110.40 +#define __fls(x) generic_fls(x) 110.41 +static __inline__ int generic_fls(uint32_t x) 110.42 +{ 110.43 + int r = 31; 110.44 + 110.45 + if (!x) 110.46 + return -1; 110.47 + if (!(x & 0xffff0000u)) { 110.48 + x <<= 16; 110.49 + r -= 16; 110.50 + } 110.51 + if (!(x & 0xff000000u)) { 110.52 + x <<= 8; 110.53 + r -= 8; 110.54 + } 110.55 + if (!(x & 0xf0000000u)) { 110.56 + x <<= 4; 110.57 + r -= 4; 110.58 + } 110.59 + if (!(x & 0xc0000000u)) { 110.60 + x <<= 2; 110.61 + r -= 2; 110.62 + } 110.63 + if (!(x & 0x80000000u)) { 110.64 + x <<= 1; 110.65 + r -= 1; 110.66 + } 110.67 + return r; 110.68 +} 110.69 +#endif 110.70 + 110.71 +static __inline__ int find_highest_bit(uint32_t *data, int length) 110.72 +{ 110.73 + while(length && !data[--length]); 110.74 + return __fls(data[length]) + 32 * length; 110.75 +} 110.76 + 110.77 +#define VLAPIC(v) (v->arch.arch_vmx.vlapic) 110.78 + 110.79 +#define VAPIC_ID_MASK 0xff 110.80 +#define VAPIC_LDR_MASK (VAPIC_ID_MASK << 24) 110.81 +#define VLAPIC_VERSION 0x00050014 110.82 + 110.83 +#define VLAPIC_BASE_MSR_MASK 0x00000000fffff900ULL 110.84 +#define VLAPIC_BASE_MSR_INIT_BASE_ADDR 0xfee00000U 110.85 +#define VLAPIC_BASE_MSR_BASE_ADDR_MASK 0xfffff000U 110.86 +#define VLAPIC_BASE_MSR_INIT_VALUE (VLAPIC_BASE_MSR_INIT_BASE_ADDR | \ 110.87 + MSR_IA32_APICBASE_ENABLE) 110.88 +#define VLOCAL_APIC_MEM_LENGTH (1 << 12) 110.89 + 110.90 +#define VLAPIC_LVT_TIMER 0 110.91 +#define VLAPIC_LVT_THERMAL 1 110.92 +#define VLAPIC_LVT_PERFORM 2 110.93 +#define VLAPIC_LVT_LINT0 3 110.94 +#define VLAPIC_LVT_LINT1 4 110.95 +#define VLAPIC_LVT_ERROR 5 110.96 +#define VLAPIC_LVT_NUM 6 110.97 + 110.98 +#define VLAPIC_LVT_BIT_MASK (1 << 16) 110.99 +#define VLAPIC_LVT_BIT_VECTOR 0xff 110.100 +#define VLAPIC_LVT_BIT_DELIMOD (0x7 << 8) 110.101 +#define VLAPIC_LVT_BIT_DELISTATUS (1 << 12) 110.102 +#define VLAPIC_LVT_BIT_POLARITY (1 << 13) 110.103 +#define VLAPIC_LVT_BIT_IRR (1 << 14) 110.104 +#define VLAPIC_LVT_BIT_TRIG (1 << 15) 110.105 +#define VLAPIC_LVT_TIMERMODE (1 << 17) 110.106 + 110.107 +#define VLAPIC_DELIV_MODE_FIXED 0x0 110.108 +#define VLAPIC_DELIV_MODE_LPRI 0x1 110.109 +#define VLAPIC_DELIV_MODE_SMI 0x2 110.110 +#define VLAPIC_DELIV_MODE_RESERVED 0x3 110.111 +#define VLAPIC_DELIV_MODE_NMI 0x4 110.112 +#define VLAPIC_DELIV_MODE_INIT 0x5 110.113 +#define VLAPIC_DELIV_MODE_STARTUP 0x6 110.114 +#define VLAPIC_DELIV_MODE_EXT 0x7 110.115 + 110.116 + 110.117 + 110.118 +#define VLAPIC_NO_SHORTHAND 0x0 110.119 +#define VLAPIC_SHORTHAND_SELF 0x1 110.120 +#define VLAPIC_SHORTHAND_INCLUDE_SELF 0x2 110.121 +#define VLAPIC_SHORTHAND_EXCLUDE_SELF 0x3 110.122 + 110.123 +#define vlapic_lvt_timer_enabled(vlapic) \ 110.124 + (!(vlapic->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_BIT_MASK)) 110.125 + 110.126 +#define vlapic_lvt_vector(vlapic, type) \ 110.127 + (vlapic->lvt[type] & VLAPIC_LVT_BIT_VECTOR) 110.128 + 110.129 +#define vlapic_lvt_dm(value) ((value >> 8) && 7) 110.130 +#define vlapic_lvt_timer_period(vlapic) \ 110.131 + (vlapic->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_TIMERMODE) 110.132 + 110.133 +#define vlapic_isr_status(vlapic,vector) \ 110.134 + test_bit(vector, &vlapic->isr[0]) 110.135 + 110.136 +#define vlapic_irr_status(vlapic,vector) \ 110.137 + test_bit(vector, &vlapic->irr[0]) 110.138 + 110.139 +#define vlapic_set_isr(vlapic,vector) \ 110.140 + test_and_set_bit(vector, &vlapic->isr[0]) 110.141 + 110.142 +#define vlapic_set_irr(vlapic,vector) \ 110.143 + test_and_set_bit(vector, &vlapic->irr[0]) 110.144 + 110.145 +#define vlapic_clear_irr(vlapic,vector) \ 110.146 + clear_bit(vector, &vlapic->irr[0]) 110.147 +#define vlapic_clear_isr(vlapic,vector) \ 110.148 + clear_bit(vector, &vlapic->isr[0]) 110.149 + 110.150 +#define vlapic_enabled(vlapic) \ 110.151 + (!(vlapic->status & \ 110.152 + (VLAPIC_GLOB_DISABLE_MASK | VLAPIC_SOFTWARE_DISABLE_MASK))) 110.153 + 110.154 +#define vlapic_global_enabled(vlapic) \ 110.155 + !(test_bit(_VLAPIC_GLOB_DISABLE, &(vlapic)->status)) 110.156 + 110.157 +typedef struct direct_intr_info { 110.158 + int deliver_mode; 110.159 + int source[6]; 110.160 +} direct_intr_info_t; 110.161 + 110.162 +#define VLAPIC_INIT_SIPI_SIPI_STATE_NORM 0 110.163 +#define VLAPIC_INIT_SIPI_SIPI_STATE_WAIT_SIPI 1 110.164 + 110.165 +struct vlapic 110.166 +{ 110.167 + //FIXME check what would be 64 bit on EM64T 110.168 + uint32_t version; 110.169 +#define _VLAPIC_GLOB_DISABLE 0x0 110.170 +#define VLAPIC_GLOB_DISABLE_MASK 0x1 110.171 +#define VLAPIC_SOFTWARE_DISABLE_MASK 0x2 110.172 +#define _VLAPIC_BSP_ACCEPT_PIC 0x3 110.173 + uint32_t status; 110.174 + uint32_t id; 110.175 + uint32_t vcpu_id; 110.176 + unsigned long base_address; 110.177 + uint32_t isr[8]; 110.178 + uint32_t irr[INTR_LEN_32]; 110.179 + uint32_t tmr[INTR_LEN_32]; 110.180 + uint32_t task_priority; 110.181 + uint32_t processor_priority; 110.182 + uint32_t logical_dest; 110.183 + uint32_t dest_format; 110.184 + uint32_t spurious_vec; 110.185 + uint32_t lvt[6]; 110.186 + uint32_t timer_initial; 110.187 + uint32_t timer_current; 110.188 + uint32_t timer_divconf; 110.189 + uint32_t timer_divide_counter; 110.190 + struct ac_timer vlapic_timer; 110.191 + int intr_pending_count[MAX_VECTOR]; 110.192 + s_time_t timer_current_update; 110.193 + uint32_t icr_high; 110.194 + uint32_t icr_low; 110.195 + direct_intr_info_t direct_intr; 110.196 + uint32_t err_status; 110.197 + unsigned long init_ticks; 110.198 + uint32_t err_write_count; 110.199 + uint64_t apic_base_msr; 110.200 + uint32_t init_sipi_sipi_state; 110.201 + struct vcpu *vcpu; 110.202 + struct domain *domain; 110.203 +}; 110.204 + 110.205 +static inline int vlapic_timer_active(struct vlapic *vlapic) 110.206 +{ 110.207 + return active_ac_timer(&(vlapic->vlapic_timer)); 110.208 +} 110.209 + 110.210 +int vlapic_find_highest_irr(struct vlapic *vlapic); 110.211 + 110.212 +int vlapic_find_highest_isr(struct vlapic *vlapic); 110.213 + 110.214 +static uint32_t inline vlapic_get_base_address(struct vlapic *vlapic) 110.215 +{ 110.216 + return (vlapic->apic_base_msr & VLAPIC_BASE_MSR_BASE_ADDR_MASK); 110.217 +} 110.218 + 110.219 +void vlapic_post_injection(struct vcpu* v, int vector, int deliver_mode); 110.220 + 110.221 +int cpu_get_apic_interrupt(struct vcpu* v, int *mode); 110.222 + 110.223 +extern uint32_t vlapic_update_ppr(struct vlapic *vlapic); 110.224 + 110.225 +int vlapic_update(struct vcpu *v); 110.226 + 110.227 +extern int vlapic_init(struct vcpu *vc); 110.228 + 110.229 +extern void vlapic_msr_set(struct vlapic *vlapic, uint64_t value); 110.230 + 110.231 +int vlapic_range(struct vcpu *v, unsigned long addr); 110.232 + 110.233 +unsigned long vlapic_write(struct vcpu *v, unsigned long address, 110.234 + unsigned long len, unsigned long val); 110.235 + 110.236 +unsigned long vlapic_read(struct vcpu *v, unsigned long address, 110.237 + unsigned long len); 110.238 + 110.239 +int vlapic_accept_pic_intr(struct vcpu *v); 110.240 + 110.241 +struct vlapic* apic_round_robin(struct domain *d, 110.242 + uint8_t dest_mode, 110.243 + uint8_t vector, 110.244 + uint32_t bitmap); 110.245 + 110.246 +int vmx_apic_support(struct domain *d); 110.247 + 110.248 +#endif /* VMX_VLAPIC_H */
111.1 --- a/xen/include/asm-x86/vmx_vmcs.h Sun Oct 30 13:52:38 2005 +0100 111.2 +++ b/xen/include/asm-x86/vmx_vmcs.h Sun Oct 30 14:00:35 2005 +0100 111.3 @@ -22,6 +22,7 @@ 111.4 #include <asm/config.h> 111.5 #include <asm/vmx_cpu.h> 111.6 #include <asm/vmx_platform.h> 111.7 +#include <asm/vmx_vlapic.h> 111.8 #include <public/vmx_assist.h> 111.9 111.10 extern int start_vmx(void); 111.11 @@ -96,6 +97,7 @@ struct arch_vmx_struct { 111.12 struct msr_state msr_content; 111.13 struct mmio_op mmio_op; /* MMIO */ 111.14 void *io_bitmap_a, *io_bitmap_b; 111.15 + struct vlapic *vlapic; 111.16 u64 tsc_offset; 111.17 }; 111.18 111.19 @@ -272,18 +274,21 @@ enum vmcs_field { 111.20 111.21 #define VMX_DEBUG 1 111.22 #if VMX_DEBUG 111.23 -#define DBG_LEVEL_0 (1 << 0) 111.24 -#define DBG_LEVEL_1 (1 << 1) 111.25 -#define DBG_LEVEL_2 (1 << 2) 111.26 -#define DBG_LEVEL_3 (1 << 3) 111.27 -#define DBG_LEVEL_IO (1 << 4) 111.28 -#define DBG_LEVEL_VMMU (1 << 5) 111.29 +#define DBG_LEVEL_0 (1 << 0) 111.30 +#define DBG_LEVEL_1 (1 << 1) 111.31 +#define DBG_LEVEL_2 (1 << 2) 111.32 +#define DBG_LEVEL_3 (1 << 3) 111.33 +#define DBG_LEVEL_IO (1 << 4) 111.34 +#define DBG_LEVEL_VMMU (1 << 5) 111.35 +#define DBG_LEVEL_VLAPIC (1 << 6) 111.36 +#define DBG_LEVEL_VLAPIC_TIMER (1 << 7) 111.37 +#define DBG_LEVEL_VLAPIC_INTERRUPT (1 << 7) 111.38 111.39 extern unsigned int opt_vmx_debug_level; 111.40 #define VMX_DBG_LOG(level, _f, _a...) \ 111.41 if ((level) & opt_vmx_debug_level) \ 111.42 printk("[VMX:%d.%d] " _f "\n", \ 111.43 - current->domain->domain_id, current->vcpu_id, ## _a) 111.44 + current->domain->domain_id, current->vcpu_id, ## _a) 111.45 #else 111.46 #define VMX_DBG_LOG(level, _f, _a...) 111.47 #endif
112.1 --- a/xen/include/public/arch-ia64.h Sun Oct 30 13:52:38 2005 +0100 112.2 +++ b/xen/include/public/arch-ia64.h Sun Oct 30 14:00:35 2005 +0100 112.3 @@ -38,6 +38,33 @@ typedef struct { 112.4 112.5 #define INVALID_MFN (~0UL) 112.6 112.7 +#define MEM_G (1UL << 30) 112.8 +#define MEM_M (1UL << 20) 112.9 + 112.10 +#define MMIO_START (3 * MEM_G) 112.11 +#define MMIO_SIZE (512 * MEM_M) 112.12 + 112.13 +#define VGA_IO_START 0xA0000UL 112.14 +#define VGA_IO_SIZE 0x20000 112.15 + 112.16 +#define LEGACY_IO_START (MMIO_START + MMIO_SIZE) 112.17 +#define LEGACY_IO_SIZE (64*MEM_M) 112.18 + 112.19 +#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE) 112.20 +#define IO_PAGE_SIZE PAGE_SIZE 112.21 + 112.22 +#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE) 112.23 +#define STORE_PAGE_SIZE PAGE_SIZE 112.24 + 112.25 +#define IO_SAPIC_START 0xfec00000UL 112.26 +#define IO_SAPIC_SIZE 0x100000 112.27 + 112.28 +#define PIB_START 0xfee00000UL 112.29 +#define PIB_SIZE 0x100000 112.30 + 112.31 +#define GFW_START (4*MEM_G -16*MEM_M) 112.32 +#define GFW_SIZE (16*MEM_M) 112.33 + 112.34 /* 112.35 * NB. This may become a 64-bit count with no shift. If this happens then the 112.36 * structure size will still be 8 bytes, so no other alignments will change.
113.1 --- a/xen/include/public/io/ioreq.h Sun Oct 30 13:52:38 2005 +0100 113.2 +++ b/xen/include/public/io/ioreq.h Sun Oct 30 14:00:35 2005 +0100 113.3 @@ -29,11 +29,11 @@ 113.4 #define STATE_IORESP_READY 3 113.5 #define STATE_IORESP_HOOK 4 113.6 113.7 -#define IOREQ_TYPE_PIO 0 /* pio */ 113.8 -#define IOREQ_TYPE_COPY 1 /* mmio ops */ 113.9 -#define IOREQ_TYPE_AND 2 113.10 -#define IOREQ_TYPE_OR 3 113.11 -#define IOREQ_TYPE_XOR 4 113.12 +#define IOREQ_TYPE_PIO 0 /* pio */ 113.13 +#define IOREQ_TYPE_COPY 1 /* mmio ops */ 113.14 +#define IOREQ_TYPE_AND 2 113.15 +#define IOREQ_TYPE_OR 3 113.16 +#define IOREQ_TYPE_XOR 4 113.17 113.18 /* 113.19 * VMExit dispatcher should cooperate with instruction decoder to 113.20 @@ -55,9 +55,10 @@ typedef struct { 113.21 uint8_t type; /* I/O type */ 113.22 } ioreq_t; 113.23 113.24 -#define MAX_VECTOR 256 113.25 +#define MAX_VECTOR 256 113.26 #define BITS_PER_BYTE 8 113.27 #define INTR_LEN (MAX_VECTOR/(BITS_PER_BYTE * sizeof(uint64_t))) 113.28 +#define INTR_LEN_32 (MAX_VECTOR/(BITS_PER_BYTE * sizeof(uint32_t))) 113.29 113.30 typedef struct { 113.31 uint16_t pic_elcr;
114.1 --- a/xen/include/public/io/vmx_vpic.h Sun Oct 30 13:52:38 2005 +0100 114.2 +++ b/xen/include/public/io/vmx_vpic.h Sun Oct 30 14:00:35 2005 +0100 114.3 @@ -76,7 +76,7 @@ void pic_update_irq(struct vmx_virpic *s 114.4 uint32_t pic_intack_read(struct vmx_virpic *s); 114.5 void register_pic_io_hook (void); 114.6 int cpu_get_pic_interrupt(struct vcpu *v, int *type); 114.7 -int is_pit_irq(struct vcpu *v, int irq); 114.8 +int is_pit_irq(struct vcpu *v, int irq, int type); 114.9 void do_pic_irqs (struct vmx_virpic *s, uint16_t irqs); 114.10 void do_pic_irqs_clear (struct vmx_virpic *s, uint16_t irqs); 114.11
115.1 --- a/xen/include/public/xen.h Sun Oct 30 13:52:38 2005 +0100 115.2 +++ b/xen/include/public/xen.h Sun Oct 30 14:00:35 2005 +0100 115.3 @@ -410,6 +410,7 @@ typedef struct shared_info { 115.4 #define MAX_GUEST_CMDLINE 1024 115.5 typedef struct start_info { 115.6 /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME. */ 115.7 + char magic[32]; /* "Xen-<version>.<subversion>". */ 115.8 unsigned long nr_pages; /* Total pages allocated to this domain. */ 115.9 unsigned long shared_info; /* MACHINE address of shared info struct. */ 115.10 uint32_t flags; /* SIF_xxx flags. */
116.1 --- a/xen/include/xen/sched.h Sun Oct 30 13:52:38 2005 +0100 116.2 +++ b/xen/include/xen/sched.h Sun Oct 30 14:00:35 2005 +0100 116.3 @@ -101,7 +101,6 @@ struct domain 116.4 struct list_head xenpage_list; /* linked list, of size xenheap_pages */ 116.5 unsigned int tot_pages; /* number of pages currently possesed */ 116.6 unsigned int max_pages; /* maximum value for tot_pages */ 116.7 - unsigned int next_io_page; /* next io pfn to give to domain */ 116.8 unsigned int xenheap_pages; /* # pages allocated from Xen heap */ 116.9 116.10 /* Scheduling. */