ia64/xen-unstable

view xen/include/xen/sched.h @ 17571:b6aa55ca599e

shadow: track video RAM dirty bits

This adds a new HVM op that enables tracking dirty bits of a range of
video RAM. The idea is to optimize just for the most common case
(only one guest mapping, with sometimes some temporary other
mappings), which permits to keep the overhead on shadow as low as
possible.

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri May 02 15:08:27 2008 +0100 (2008-05-02)
parents 7fc474368ba8
children 62f1c837057f
line source
2 #ifndef __SCHED_H__
3 #define __SCHED_H__
5 #include <xen/config.h>
6 #include <xen/types.h>
7 #include <xen/spinlock.h>
8 #include <xen/smp.h>
9 #include <xen/shared.h>
10 #include <public/xen.h>
11 #include <public/domctl.h>
12 #include <public/vcpu.h>
13 #include <public/xsm/acm.h>
14 #include <xen/time.h>
15 #include <xen/timer.h>
16 #include <xen/grant_table.h>
17 #include <xen/rangeset.h>
18 #include <asm/domain.h>
19 #include <xen/xenoprof.h>
20 #include <xen/rcupdate.h>
21 #include <xen/irq.h>
23 #ifdef CONFIG_COMPAT
24 #include <compat/vcpu.h>
25 DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t);
26 #endif
28 /* A global pointer to the initial domain (DOM0). */
29 extern struct domain *dom0;
31 #ifndef CONFIG_COMPAT
32 #define MAX_EVTCHNS(d) NR_EVENT_CHANNELS
33 #else
34 #define MAX_EVTCHNS(d) (!IS_COMPAT(d) ? \
35 NR_EVENT_CHANNELS : \
36 sizeof(unsigned int) * sizeof(unsigned int) * 64)
37 #endif
38 #define EVTCHNS_PER_BUCKET 128
39 #define NR_EVTCHN_BUCKETS (NR_EVENT_CHANNELS / EVTCHNS_PER_BUCKET)
41 struct evtchn
42 {
43 #define ECS_FREE 0 /* Channel is available for use. */
44 #define ECS_RESERVED 1 /* Channel is reserved. */
45 #define ECS_UNBOUND 2 /* Channel is waiting to bind to a remote domain. */
46 #define ECS_INTERDOMAIN 3 /* Channel is bound to another domain. */
47 #define ECS_PIRQ 4 /* Channel is bound to a physical IRQ line. */
48 #define ECS_VIRQ 5 /* Channel is bound to a virtual IRQ line. */
49 #define ECS_IPI 6 /* Channel is bound to a virtual IPI line. */
50 u8 state; /* ECS_* */
51 u8 consumer_is_xen; /* Consumed by Xen or by guest? */
52 u16 notify_vcpu_id; /* VCPU for local delivery notification */
53 union {
54 struct {
55 domid_t remote_domid;
56 } unbound; /* state == ECS_UNBOUND */
57 struct {
58 u16 remote_port;
59 struct domain *remote_dom;
60 } interdomain; /* state == ECS_INTERDOMAIN */
61 u16 pirq; /* state == ECS_PIRQ */
62 u16 virq; /* state == ECS_VIRQ */
63 } u;
64 #ifdef FLASK_ENABLE
65 void *ssid;
66 #endif
67 };
69 int evtchn_init(struct domain *d);
70 void evtchn_destroy(struct domain *d);
72 struct vcpu
73 {
74 int vcpu_id;
76 int processor;
78 vcpu_info_t *vcpu_info;
80 struct domain *domain;
82 struct vcpu *next_in_list;
84 uint64_t periodic_period;
85 uint64_t periodic_last_event;
86 struct timer periodic_timer;
87 struct timer singleshot_timer;
89 struct timer poll_timer; /* timeout for SCHEDOP_poll */
91 void *sched_priv; /* scheduler-specific data */
93 struct vcpu_runstate_info runstate;
94 #ifndef CONFIG_COMPAT
95 # define runstate_guest(v) ((v)->runstate_guest)
96 XEN_GUEST_HANDLE(vcpu_runstate_info_t) runstate_guest; /* guest address */
97 #else
98 # define runstate_guest(v) ((v)->runstate_guest.native)
99 union {
100 XEN_GUEST_HANDLE(vcpu_runstate_info_t) native;
101 XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t) compat;
102 } runstate_guest; /* guest address */
103 #endif
105 /* Has the FPU been initialised? */
106 bool_t fpu_initialised;
107 /* Has the FPU been used since it was last saved? */
108 bool_t fpu_dirtied;
109 /* Is this VCPU polling any event channels (SCHEDOP_poll)? */
110 bool_t is_polling;
111 /* Initialization completed for this VCPU? */
112 bool_t is_initialised;
113 /* Currently running on a CPU? */
114 bool_t is_running;
115 /* NMI callback pending for this VCPU? */
116 bool_t nmi_pending;
117 /* Avoid NMI reentry by allowing NMIs to be masked for short periods. */
118 bool_t nmi_masked;
119 /* Require shutdown to be deferred for some asynchronous operation? */
120 bool_t defer_shutdown;
121 /* VCPU is paused following shutdown request (d->is_shutting_down)? */
122 bool_t paused_for_shutdown;
123 /* VCPU affinity is temporarily locked from controller changes? */
124 bool_t affinity_locked;
126 unsigned long pause_flags;
127 atomic_t pause_count;
129 u16 virq_to_evtchn[NR_VIRQS];
131 /* Bitmask of CPUs on which this VCPU may run. */
132 cpumask_t cpu_affinity;
134 /* Bitmask of CPUs which are holding onto this VCPU's state. */
135 cpumask_t vcpu_dirty_cpumask;
137 struct arch_vcpu arch;
138 };
140 /* Per-domain lock can be recursively acquired in fault handlers. */
141 #define domain_lock(d) spin_lock_recursive(&(d)->domain_lock)
142 #define domain_unlock(d) spin_unlock_recursive(&(d)->domain_lock)
143 #define domain_is_locked(d) spin_is_locked(&(d)->domain_lock)
145 struct domain
146 {
147 domid_t domain_id;
149 shared_info_t *shared_info; /* shared data area */
151 spinlock_t domain_lock;
153 spinlock_t page_alloc_lock; /* protects all the following fields */
154 struct list_head page_list; /* linked list, of size tot_pages */
155 struct list_head xenpage_list; /* linked list, of size xenheap_pages */
156 unsigned int tot_pages; /* number of pages currently possesed */
157 unsigned int max_pages; /* maximum value for tot_pages */
158 unsigned int xenheap_pages; /* # pages allocated from Xen heap */
160 /* Scheduling. */
161 void *sched_priv; /* scheduler-specific data */
163 struct domain *next_in_list;
164 struct domain *next_in_hashbucket;
166 struct list_head rangesets;
167 spinlock_t rangesets_lock;
169 /* Event channel information. */
170 struct evtchn *evtchn[NR_EVTCHN_BUCKETS];
171 spinlock_t evtchn_lock;
173 struct grant_table *grant_table;
175 /*
176 * Interrupt to event-channel mappings. Updates should be protected by the
177 * domain's event-channel spinlock. Read accesses can also synchronise on
178 * the lock, but races don't usually matter.
179 */
180 u16 pirq_to_evtchn[NR_IRQS];
181 DECLARE_BITMAP(pirq_mask, NR_IRQS);
183 /* I/O capabilities (access to IRQs and memory-mapped I/O). */
184 struct rangeset *iomem_caps;
185 struct rangeset *irq_caps;
187 /* Is this an HVM guest? */
188 bool_t is_hvm;
189 /* Is this guest fully privileged (aka dom0)? */
190 bool_t is_privileged;
191 /* Which guest this guest has privileges on */
192 struct domain *target;
193 /* Is this guest being debugged by dom0? */
194 bool_t debugger_attached;
195 /* Are any VCPUs polling event channels (SCHEDOP_poll)? */
196 bool_t is_polling;
197 /* Is this guest dying (i.e., a zombie)? */
198 enum { DOMDYING_alive, DOMDYING_dying, DOMDYING_dead } is_dying;
199 /* Domain is paused by controller software? */
200 bool_t is_paused_by_controller;
201 /* Domain's VCPUs are pinned 1:1 to physical CPUs? */
202 bool_t is_pinned;
204 /* Guest has shut down (inc. reason code)? */
205 spinlock_t shutdown_lock;
206 bool_t is_shutting_down; /* in process of shutting down? */
207 bool_t is_shut_down; /* fully shut down? */
208 int shutdown_code;
210 atomic_t pause_count;
212 unsigned long vm_assist;
214 atomic_t refcnt;
216 struct vcpu *vcpu[MAX_VIRT_CPUS];
218 /* Bitmask of CPUs which are holding onto this domain's state. */
219 cpumask_t domain_dirty_cpumask;
221 struct arch_domain arch;
223 void *ssid; /* sHype security subject identifier */
225 /* Control-plane tools handle for this domain. */
226 xen_domain_handle_t handle;
228 /* OProfile support. */
229 struct xenoprof *xenoprof;
230 int32_t time_offset_seconds;
232 struct rcu_head rcu;
234 /*
235 * Hypercall deadlock avoidance lock. Used if a hypercall might
236 * cause a deadlock. Acquirers don't spin waiting; they preempt.
237 */
238 spinlock_t hypercall_deadlock_mutex;
240 /* VRAM dirty support. */
241 struct sh_dirty_vram *dirty_vram;
242 };
244 struct domain_setup_info
245 {
246 /* Initialised by caller. */
247 unsigned long image_addr;
248 unsigned long image_len;
249 /* Initialised by loader: Public. */
250 unsigned long v_start;
251 unsigned long v_end;
252 unsigned long v_kernstart;
253 unsigned long v_kernend;
254 unsigned long v_kernentry;
255 #define PAEKERN_no 0
256 #define PAEKERN_yes 1
257 #define PAEKERN_extended_cr3 2
258 #define PAEKERN_bimodal 3
259 unsigned int pae_kernel;
260 /* Initialised by loader: Private. */
261 unsigned long elf_paddr_offset;
262 unsigned int load_symtab;
263 unsigned long symtab_addr;
264 unsigned long symtab_len;
265 };
267 extern struct vcpu *idle_vcpu[NR_CPUS];
268 #define IDLE_DOMAIN_ID (0x7FFFU)
269 #define is_idle_domain(d) ((d)->domain_id == IDLE_DOMAIN_ID)
270 #define is_idle_vcpu(v) (is_idle_domain((v)->domain))
272 #define DOMAIN_DESTROYED (1<<31) /* assumes atomic_t is >= 32 bits */
273 #define put_domain(_d) \
274 if ( atomic_dec_and_test(&(_d)->refcnt) ) domain_destroy(_d)
276 /*
277 * Use this when you don't have an existing reference to @d. It returns
278 * FALSE if @d is being destroyed.
279 */
280 static always_inline int get_domain(struct domain *d)
281 {
282 atomic_t old, new, seen = d->refcnt;
283 do
284 {
285 old = seen;
286 if ( unlikely(_atomic_read(old) & DOMAIN_DESTROYED) )
287 return 0;
288 _atomic_set(new, _atomic_read(old) + 1);
289 seen = atomic_compareandswap(old, new, &d->refcnt);
290 }
291 while ( unlikely(_atomic_read(seen) != _atomic_read(old)) );
292 return 1;
293 }
295 /*
296 * Use this when you already have, or are borrowing, a reference to @d.
297 * In this case we know that @d cannot be destroyed under our feet.
298 */
299 static inline void get_knownalive_domain(struct domain *d)
300 {
301 atomic_inc(&d->refcnt);
302 ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTROYED));
303 }
305 /* Obtain a reference to the currently-running domain. */
306 static inline struct domain *get_current_domain(void)
307 {
308 struct domain *d = current->domain;
309 get_knownalive_domain(d);
310 return d;
311 }
313 struct domain *domain_create(
314 domid_t domid, unsigned int domcr_flags, ssidref_t ssidref);
315 /* DOMCRF_hvm: Create an HVM domain, as opposed to a PV domain. */
316 #define _DOMCRF_hvm 0
317 #define DOMCRF_hvm (1U<<_DOMCRF_hvm)
318 #define _DOMCRF_hap 1
319 #define DOMCRF_hap (1U<<_DOMCRF_hap)
321 int construct_dom0(
322 struct domain *d,
323 unsigned long image_start, unsigned long image_len,
324 unsigned long initrd_start, unsigned long initrd_len,
325 char *cmdline);
327 /*
328 * rcu_lock_domain_by_id() is more efficient than get_domain_by_id().
329 * This is the preferred function if the returned domain reference
330 * is short lived, but it cannot be used if the domain reference needs
331 * to be kept beyond the current scope (e.g., across a softirq).
332 * The returned domain reference must be discarded using rcu_unlock_domain().
333 */
334 struct domain *rcu_lock_domain_by_id(domid_t dom);
336 /* Finish a RCU critical region started by rcu_lock_domain_by_id(). */
337 static inline void rcu_unlock_domain(struct domain *d)
338 {
339 rcu_read_unlock(&domlist_read_lock);
340 }
342 static inline struct domain *rcu_lock_domain(struct domain *d)
343 {
344 rcu_read_lock(d);
345 return d;
346 }
348 static inline struct domain *rcu_lock_current_domain(void)
349 {
350 return rcu_lock_domain(current->domain);
351 }
353 struct domain *get_domain_by_id(domid_t dom);
354 void domain_destroy(struct domain *d);
355 int domain_kill(struct domain *d);
356 void domain_shutdown(struct domain *d, u8 reason);
357 void domain_resume(struct domain *d);
358 void domain_pause_for_debugger(void);
360 int vcpu_start_shutdown_deferral(struct vcpu *v);
361 void vcpu_end_shutdown_deferral(struct vcpu *v);
363 /*
364 * Mark specified domain as crashed. This function always returns, even if the
365 * caller is the specified domain. The domain is not synchronously descheduled
366 * from any processor.
367 */
368 void __domain_crash(struct domain *d);
369 #define domain_crash(d) do { \
370 printk("domain_crash called from %s:%d\n", __FILE__, __LINE__); \
371 __domain_crash(d); \
372 } while (0)
374 /*
375 * Mark current domain as crashed and synchronously deschedule from the local
376 * processor. This function never returns.
377 */
378 void __domain_crash_synchronous(void) __attribute__((noreturn));
379 #define domain_crash_synchronous() do { \
380 printk("domain_crash_sync called from %s:%d\n", __FILE__, __LINE__); \
381 __domain_crash_synchronous(); \
382 } while (0)
384 #define set_current_state(_s) do { current->state = (_s); } while (0)
385 void scheduler_init(void);
386 int sched_init_vcpu(struct vcpu *v, unsigned int processor);
387 void sched_destroy_vcpu(struct vcpu *v);
388 int sched_init_domain(struct domain *d);
389 void sched_destroy_domain(struct domain *d);
390 long sched_adjust(struct domain *, struct xen_domctl_scheduler_op *);
391 int sched_id(void);
392 void vcpu_wake(struct vcpu *d);
393 void vcpu_sleep_nosync(struct vcpu *d);
394 void vcpu_sleep_sync(struct vcpu *d);
396 /*
397 * Force synchronisation of given VCPU's state. If it is currently descheduled,
398 * this call will ensure that all its state is committed to memory and that
399 * no CPU is using critical state (e.g., page tables) belonging to the VCPU.
400 */
401 void sync_vcpu_execstate(struct vcpu *v);
403 /*
404 * Called by the scheduler to switch to another VCPU. This function must
405 * call context_saved(@prev) when the local CPU is no longer running in
406 * @prev's context, and that context is saved to memory. Alternatively, if
407 * implementing lazy context switching, it suffices to ensure that invoking
408 * sync_vcpu_execstate() will switch and commit @prev's state.
409 */
410 void context_switch(
411 struct vcpu *prev,
412 struct vcpu *next);
414 /*
415 * As described above, context_switch() must call this function when the
416 * local CPU is no longer running in @prev's context, and @prev's context is
417 * saved to memory. Alternatively, if implementing lazy context switching,
418 * ensure that invoking sync_vcpu_execstate() will switch and commit @prev.
419 */
420 void context_saved(struct vcpu *prev);
422 /* Called by the scheduler to continue running the current VCPU. */
423 void continue_running(
424 struct vcpu *same);
426 void startup_cpu_idle_loop(void);
428 /*
429 * Creates a continuation to resume the current hypercall. The caller should
430 * return immediately, propagating the value returned from this invocation.
431 * The format string specifies the types and number of hypercall arguments.
432 * It contains one character per argument as follows:
433 * 'i' [unsigned] {char, int}
434 * 'l' [unsigned] long
435 * 'h' guest handle (XEN_GUEST_HANDLE(foo))
436 */
437 unsigned long hypercall_create_continuation(
438 unsigned int op, const char *format, ...);
440 #define hypercall_preempt_check() (unlikely( \
441 softirq_pending(smp_processor_id()) | \
442 local_events_need_delivery() \
443 ))
445 /* Protect updates/reads (resp.) of domain_list and domain_hash. */
446 extern spinlock_t domlist_update_lock;
447 extern rcu_read_lock_t domlist_read_lock;
449 extern struct domain *domain_list;
451 /* Caller must hold the domlist_read_lock or domlist_update_lock. */
452 #define for_each_domain(_d) \
453 for ( (_d) = rcu_dereference(domain_list); \
454 (_d) != NULL; \
455 (_d) = rcu_dereference((_d)->next_in_list )) \
457 #define for_each_vcpu(_d,_v) \
458 for ( (_v) = (_d)->vcpu[0]; \
459 (_v) != NULL; \
460 (_v) = (_v)->next_in_list )
462 /*
463 * Per-VCPU pause flags.
464 */
465 /* Domain is blocked waiting for an event. */
466 #define _VPF_blocked 0
467 #define VPF_blocked (1UL<<_VPF_blocked)
468 /* VCPU is offline. */
469 #define _VPF_down 1
470 #define VPF_down (1UL<<_VPF_down)
471 /* VCPU is blocked awaiting an event to be consumed by Xen. */
472 #define _VPF_blocked_in_xen 2
473 #define VPF_blocked_in_xen (1UL<<_VPF_blocked_in_xen)
474 /* VCPU affinity has changed: migrating to a new CPU. */
475 #define _VPF_migrating 3
476 #define VPF_migrating (1UL<<_VPF_migrating)
478 static inline int vcpu_runnable(struct vcpu *v)
479 {
480 return !(v->pause_flags |
481 atomic_read(&v->pause_count) |
482 atomic_read(&v->domain->pause_count));
483 }
485 void vcpu_pause(struct vcpu *v);
486 void vcpu_pause_nosync(struct vcpu *v);
487 void domain_pause(struct domain *d);
488 void vcpu_unpause(struct vcpu *v);
489 void domain_unpause(struct domain *d);
490 void domain_pause_by_systemcontroller(struct domain *d);
491 void domain_unpause_by_systemcontroller(struct domain *d);
492 void cpu_init(void);
494 void vcpu_force_reschedule(struct vcpu *v);
495 int vcpu_set_affinity(struct vcpu *v, cpumask_t *affinity);
496 int vcpu_lock_affinity(struct vcpu *v, cpumask_t *affinity);
497 void vcpu_unlock_affinity(struct vcpu *v, cpumask_t *affinity);
499 void vcpu_runstate_get(struct vcpu *v, struct vcpu_runstate_info *runstate);
501 static inline void vcpu_unblock(struct vcpu *v)
502 {
503 if ( test_and_clear_bit(_VPF_blocked, &v->pause_flags) )
504 vcpu_wake(v);
505 }
507 #define IS_PRIV(_d) ((_d)->is_privileged)
508 #define IS_PRIV_FOR(_d, _t) (IS_PRIV(_d) || ((_d)->target && (_d)->target == (_t)))
510 #ifndef IS_COMPAT
511 #define IS_COMPAT(d) 0
512 #endif
514 #define VM_ASSIST(_d,_t) (test_bit((_t), &(_d)->vm_assist))
516 #define is_hvm_domain(d) ((d)->is_hvm)
517 #define is_hvm_vcpu(v) (is_hvm_domain(v->domain))
519 extern enum cpufreq_controller {
520 FREQCTL_none, FREQCTL_dom0_kernel
521 } cpufreq_controller;
523 #endif /* __SCHED_H__ */
525 /*
526 * Local variables:
527 * mode: C
528 * c-set-style: "BSD"
529 * c-basic-offset: 4
530 * tab-width: 4
531 * indent-tabs-mode: nil
532 * End:
533 */