ia64/xen-unstable

annotate xen/include/xen/sched.h @ 19788:2f9e1348aa98

x86_64: allow more vCPU-s per guest

Since the shared info layout is fixed, guests are required to use
VCPUOP_register_vcpu_info prior to booting any vCPU beyond the
traditional limit of 32.

MAX_VIRT_CPUS, being an implemetation detail of the hypervisor, is no
longer being exposed in the public headers.

The tools changes are clearly incomplete (and done only so things
would
build again), and the current state of the tools (using scalar
variables all over the place to represent vCPU bitmaps) very likely
doesn't permit booting DomU-s with more than the traditional number of
vCPU-s. Testing of the extended functionality was done with Dom0 (96
vCPU-s, as well as 128 vCPU-s out of which the kernel elected - by way
of a simple kernel side patch - to use only some, resulting in a
sparse
bitmap).

ia64 changes only to make things build, and build-tested only (and the
tools part only as far as the build would go without encountering
unrelated problems in the blktap code).

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jun 18 10:14:16 2009 +0100 (2009-06-18)
parents 8dd5c3cae086
children
rev   line source
kaf24@3677 1
kaf24@1506 2 #ifndef __SCHED_H__
kaf24@1506 3 #define __SCHED_H__
kaf24@1210 4
kaf24@1210 5 #include <xen/config.h>
kaf24@1210 6 #include <xen/types.h>
kaf24@1210 7 #include <xen/spinlock.h>
kaf24@1210 8 #include <xen/smp.h>
ack@13292 9 #include <xen/shared.h>
kaf24@2789 10 #include <public/xen.h>
kfraser@11296 11 #include <public/domctl.h>
kaf24@9022 12 #include <public/vcpu.h>
kfraser@15819 13 #include <public/xsm/acm.h>
cl349@5294 14 #include <xen/time.h>
kaf24@8586 15 #include <xen/timer.h>
kaf24@2344 16 #include <xen/grant_table.h>
kaf24@8468 17 #include <xen/rangeset.h>
kaf24@3674 18 #include <asm/domain.h>
ack@9625 19 #include <xen/xenoprof.h>
kfraser@14058 20 #include <xen/rcupdate.h>
kaf24@9897 21 #include <xen/irq.h>
keir@19147 22 #include <xen/mm.h>
kaf24@1210 23
ack@13298 24 #ifdef CONFIG_COMPAT
ack@13298 25 #include <compat/vcpu.h>
ack@13298 26 DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t);
ack@13298 27 #endif
ack@13298 28
kaf24@2806 29 /* A global pointer to the initial domain (DOM0). */
kaf24@2806 30 extern struct domain *dom0;
kaf24@2806 31
ack@13292 32 #ifndef CONFIG_COMPAT
keir@19268 33 #define BITS_PER_EVTCHN_WORD(d) BITS_PER_LONG
ack@13292 34 #else
keir@19268 35 #define BITS_PER_EVTCHN_WORD(d) (has_32bit_shinfo(d) ? 32 : BITS_PER_LONG)
ack@13292 36 #endif
keir@19370 37 #define MAX_EVTCHNS(d) (BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d))
kaf24@5308 38 #define EVTCHNS_PER_BUCKET 128
ack@13292 39 #define NR_EVTCHN_BUCKETS (NR_EVENT_CHANNELS / EVTCHNS_PER_BUCKET)
kaf24@5308 40
kaf24@5308 41 struct evtchn
kaf24@1210 42 {
kaf24@1218 43 #define ECS_FREE 0 /* Channel is available for use. */
cl349@3297 44 #define ECS_RESERVED 1 /* Channel is reserved. */
cl349@3297 45 #define ECS_UNBOUND 2 /* Channel is waiting to bind to a remote domain. */
cl349@3297 46 #define ECS_INTERDOMAIN 3 /* Channel is bound to another domain. */
cl349@3297 47 #define ECS_PIRQ 4 /* Channel is bound to a physical IRQ line. */
cl349@3297 48 #define ECS_VIRQ 5 /* Channel is bound to a virtual IRQ line. */
cl349@3297 49 #define ECS_IPI 6 /* Channel is bound to a virtual IPI line. */
kfraser@10977 50 u8 state; /* ECS_* */
kfraser@10977 51 u8 consumer_is_xen; /* Consumed by Xen or by guest? */
kaf24@5308 52 u16 notify_vcpu_id; /* VCPU for local delivery notification */
kaf24@1218 53 union {
kaf24@1218 54 struct {
kaf24@2710 55 domid_t remote_domid;
kaf24@5308 56 } unbound; /* state == ECS_UNBOUND */
kaf24@2710 57 struct {
kaf24@5308 58 u16 remote_port;
kaf24@5308 59 struct domain *remote_dom;
kaf24@5308 60 } interdomain; /* state == ECS_INTERDOMAIN */
kaf24@5308 61 u16 pirq; /* state == ECS_PIRQ */
kaf24@5308 62 u16 virq; /* state == ECS_VIRQ */
kaf24@1218 63 } u;
kfraser@15819 64 #ifdef FLASK_ENABLE
kfraser@15819 65 void *ssid;
kfraser@15819 66 #endif
kaf24@5308 67 };
kaf24@1210 68
kaf24@5308 69 int evtchn_init(struct domain *d);
kaf24@5308 70 void evtchn_destroy(struct domain *d);
kaf24@1218 71
kaf24@5289 72 struct vcpu
kaf24@1210 73 {
kaf24@4877 74 int vcpu_id;
kaf24@1210 75
kaf24@4798 76 int processor;
kaf24@1210 77
kaf24@4798 78 vcpu_info_t *vcpu_info;
kaf24@4798 79
kaf24@4798 80 struct domain *domain;
kaf24@7364 81
kaf24@7364 82 struct vcpu *next_in_list;
cl349@2919 83
kfraser@14340 84 uint64_t periodic_period;
kfraser@14340 85 uint64_t periodic_last_event;
kfraser@14340 86 struct timer periodic_timer;
kfraser@14340 87 struct timer singleshot_timer;
cl349@2938 88
kaf24@9262 89 struct timer poll_timer; /* timeout for SCHEDOP_poll */
kaf24@9262 90
kaf24@4798 91 void *sched_priv; /* scheduler-specific data */
cl349@2919 92
kaf24@9022 93 struct vcpu_runstate_info runstate;
ack@13298 94 #ifndef CONFIG_COMPAT
ack@13298 95 # define runstate_guest(v) ((v)->runstate_guest)
kfraser@12477 96 XEN_GUEST_HANDLE(vcpu_runstate_info_t) runstate_guest; /* guest address */
ack@13298 97 #else
ack@13298 98 # define runstate_guest(v) ((v)->runstate_guest.native)
ack@13298 99 union {
ack@13298 100 XEN_GUEST_HANDLE(vcpu_runstate_info_t) native;
ack@13298 101 XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t) compat;
ack@13298 102 } runstate_guest; /* guest address */
ack@13298 103 #endif
kaf24@9022 104
keir@19313 105 /* last time when vCPU is scheduled out */
keir@19313 106 uint64_t last_run_time;
keir@19313 107
kfraser@14657 108 /* Has the FPU been initialised? */
kfraser@14657 109 bool_t fpu_initialised;
kfraser@14657 110 /* Has the FPU been used since it was last saved? */
kfraser@14657 111 bool_t fpu_dirtied;
kfraser@14657 112 /* Initialization completed for this VCPU? */
kfraser@14657 113 bool_t is_initialised;
kfraser@14657 114 /* Currently running on a CPU? */
kfraser@14657 115 bool_t is_running;
keir@17971 116 /* MCE callback pending for this VCPU? */
keir@17971 117 bool_t mce_pending;
kfraser@14661 118 /* NMI callback pending for this VCPU? */
kfraser@14661 119 bool_t nmi_pending;
keir@17971 120
keir@17971 121 /* Higher priorized traps may interrupt lower priorized traps,
keir@17971 122 * lower priorized traps wait until higher priorized traps finished.
keir@17971 123 * Note: This concept is known as "system priority level" (spl)
keir@17971 124 * in the UNIX world. */
keir@17971 125 uint16_t old_trap_priority;
keir@17971 126 uint16_t trap_priority;
keir@17971 127 #define VCPU_TRAP_NONE 0
keir@17971 128 #define VCPU_TRAP_NMI 1
keir@17971 129 #define VCPU_TRAP_MCE 2
keir@17971 130
kfraser@14705 131 /* Require shutdown to be deferred for some asynchronous operation? */
kfraser@14705 132 bool_t defer_shutdown;
kfraser@14705 133 /* VCPU is paused following shutdown request (d->is_shutting_down)? */
kfraser@14705 134 bool_t paused_for_shutdown;
keir@16896 135 /* VCPU affinity is temporarily locked from controller changes? */
keir@16896 136 bool_t affinity_locked;
kfraser@14657 137
keir@18441 138 /*
keir@18441 139 * > 0: a single port is being polled;
keir@18441 140 * = 0: nothing is being polled (vcpu should be clear in d->poll_mask);
keir@18441 141 * < 0: multiple ports may be being polled.
keir@18441 142 */
keir@18441 143 int poll_evtchn;
keir@18441 144
kfraser@14663 145 unsigned long pause_flags;
kfraser@14661 146 atomic_t pause_count;
kfraser@10655 147
keir@18208 148 /* IRQ-safe virq_lock protects against delivering VIRQ to stale evtchn. */
kaf24@4798 149 u16 virq_to_evtchn[NR_VIRQS];
keir@18208 150 spinlock_t virq_lock;
cl349@2929 151
kaf24@8512 152 /* Bitmask of CPUs on which this VCPU may run. */
kaf24@8507 153 cpumask_t cpu_affinity;
keir@17965 154 /* Used to change affinity temporarily. */
keir@17965 155 cpumask_t cpu_affinity_tmp;
cl349@4845 156
kaf24@8512 157 /* Bitmask of CPUs which are holding onto this VCPU's state. */
kaf24@8512 158 cpumask_t vcpu_dirty_cpumask;
kaf24@8512 159
kaf24@5289 160 struct arch_vcpu arch;
cl349@2919 161 };
cl349@2919 162
kaf24@4193 163 /* Per-domain lock can be recursively acquired in fault handlers. */
keir@17449 164 #define domain_lock(d) spin_lock_recursive(&(d)->domain_lock)
keir@17449 165 #define domain_unlock(d) spin_unlock_recursive(&(d)->domain_lock)
keir@17449 166 #define domain_is_locked(d) spin_is_locked(&(d)->domain_lock)
cl349@2998 167
kaf24@3677 168 struct domain
kaf24@3677 169 {
kaf24@4877 170 domid_t domain_id;
kaf24@1210 171
cl349@2944 172 shared_info_t *shared_info; /* shared data area */
cl349@2921 173
keir@17449 174 spinlock_t domain_lock;
kaf24@1210 175
kaf24@1640 176 spinlock_t page_alloc_lock; /* protects all the following fields */
keir@19134 177 struct page_list_head page_list; /* linked list, of size tot_pages */
keir@19134 178 struct page_list_head xenpage_list; /* linked list (size xenheap_pages) */
kaf24@1640 179 unsigned int tot_pages; /* number of pages currently possesed */
kaf24@1640 180 unsigned int max_pages; /* maximum value for tot_pages */
kaf24@1640 181 unsigned int xenheap_pages; /* # pages allocated from Xen heap */
kaf24@1210 182
keir@19788 183 unsigned int max_vcpus;
keir@19788 184
kaf24@1210 185 /* Scheduling. */
kaf24@1506 186 void *sched_priv; /* scheduler-specific data */
kaf24@1210 187
kaf24@4798 188 struct domain *next_in_list;
kaf24@4798 189 struct domain *next_in_hashbucket;
kaf24@1210 190
kaf24@8456 191 struct list_head rangesets;
kaf24@8456 192 spinlock_t rangesets_lock;
kaf24@8456 193
kaf24@1210 194 /* Event channel information. */
kaf24@5308 195 struct evtchn *evtchn[NR_EVTCHN_BUCKETS];
keir@18602 196 spinlock_t event_lock;
kaf24@1210 197
kaf24@9723 198 struct grant_table *grant_table;
kaf24@2322 199
kaf24@1218 200 /*
kaf24@1218 201 * Interrupt to event-channel mappings. Updates should be protected by the
kaf24@1218 202 * domain's event-channel spinlock. Read accesses can also synchronise on
kaf24@1218 203 * the lock, but races don't usually matter.
kaf24@1218 204 */
keir@19650 205 unsigned int nr_pirqs;
keir@19650 206 u16 *pirq_to_evtchn;
keir@19650 207 unsigned long *pirq_mask;
kaf24@1218 208
kaf24@8468 209 /* I/O capabilities (access to IRQs and memory-mapped I/O). */
kaf24@8468 210 struct rangeset *iomem_caps;
kaf24@8468 211 struct rangeset *irq_caps;
kaf24@8468 212
keir@14635 213 /* Is this an HVM guest? */
keir@14635 214 bool_t is_hvm;
keir@17726 215 /* Does this guest need iommu mappings? */
keir@17726 216 bool_t need_iommu;
keir@14635 217 /* Is this guest fully privileged (aka dom0)? */
keir@14635 218 bool_t is_privileged;
keir@16856 219 /* Which guest this guest has privileges on */
keir@16856 220 struct domain *target;
keir@14635 221 /* Is this guest being debugged by dom0? */
keir@14635 222 bool_t debugger_attached;
kfraser@14642 223 /* Is this guest dying (i.e., a zombie)? */
kfraser@15825 224 enum { DOMDYING_alive, DOMDYING_dying, DOMDYING_dead } is_dying;
kfraser@14642 225 /* Domain is paused by controller software? */
kfraser@14642 226 bool_t is_paused_by_controller;
keir@17187 227 /* Domain's VCPUs are pinned 1:1 to physical CPUs? */
keir@17187 228 bool_t is_pinned;
kfraser@12210 229
keir@18441 230 /* Are any VCPUs polling event channels (SCHEDOP_poll)? */
keir@19788 231 #if MAX_VIRT_CPUS <= BITS_PER_LONG
keir@18441 232 DECLARE_BITMAP(poll_mask, MAX_VIRT_CPUS);
keir@19788 233 #else
keir@19788 234 unsigned long *poll_mask;
keir@19788 235 #endif
keir@18441 236
kfraser@14642 237 /* Guest has shut down (inc. reason code)? */
kfraser@14705 238 spinlock_t shutdown_lock;
kfraser@14705 239 bool_t is_shutting_down; /* in process of shutting down? */
kfraser@14705 240 bool_t is_shut_down; /* fully shut down? */
kfraser@14642 241 int shutdown_code;
kfraser@14642 242
keir@17965 243 /* If this is not 0, send suspend notification here instead of
keir@17965 244 * raising DOM_EXC */
keir@17965 245 int suspend_evtchn;
keir@17965 246
kfraser@14642 247 atomic_t pause_count;
kfraser@10655 248
kaf24@4798 249 unsigned long vm_assist;
kaf24@1210 250
kaf24@4798 251 atomic_t refcnt;
cl349@2919 252
keir@19788 253 struct vcpu **vcpu;
kaf24@3677 254
kaf24@5301 255 /* Bitmask of CPUs which are holding onto this domain's state. */
kaf24@8512 256 cpumask_t domain_dirty_cpumask;
kaf24@4373 257
kaf24@3677 258 struct arch_domain arch;
smh22@5514 259
smh22@5514 260 void *ssid; /* sHype security subject identifier */
kaf24@7388 261
kaf24@7388 262 /* Control-plane tools handle for this domain. */
kaf24@7388 263 xen_domain_handle_t handle;
ack@9625 264
kaf24@9629 265 /* OProfile support. */
kaf24@9629 266 struct xenoprof *xenoprof;
kaf24@10506 267 int32_t time_offset_seconds;
kfraser@14058 268
kfraser@14058 269 struct rcu_head rcu;
keir@16064 270
keir@16064 271 /*
keir@16064 272 * Hypercall deadlock avoidance lock. Used if a hypercall might
keir@16064 273 * cause a deadlock. Acquirers don't spin waiting; they preempt.
keir@16064 274 */
keir@16064 275 spinlock_t hypercall_deadlock_mutex;
keir@17571 276
keir@19646 277 /* transcendent memory, auto-allocated on first tmem op by each domain */
keir@19646 278 void *tmem;
kaf24@1210 279 };
kaf24@1210 280
cl349@2448 281 struct domain_setup_info
cl349@2448 282 {
kaf24@4452 283 /* Initialised by caller. */
kaf24@4452 284 unsigned long image_addr;
kaf24@4452 285 unsigned long image_len;
kaf24@4452 286 /* Initialised by loader: Public. */
cl349@2448 287 unsigned long v_start;
cl349@4447 288 unsigned long v_end;
cl349@2448 289 unsigned long v_kernstart;
cl349@2448 290 unsigned long v_kernend;
cl349@2448 291 unsigned long v_kernentry;
ian@11284 292 #define PAEKERN_no 0
ian@11284 293 #define PAEKERN_yes 1
ian@11284 294 #define PAEKERN_extended_cr3 2
kfraser@13016 295 #define PAEKERN_bimodal 3
ian@11284 296 unsigned int pae_kernel;
kaf24@4452 297 /* Initialised by loader: Private. */
cl349@10048 298 unsigned long elf_paddr_offset;
kaf24@4452 299 unsigned int load_symtab;
cl349@4447 300 unsigned long symtab_addr;
cl349@4447 301 unsigned long symtab_len;
cl349@2448 302 };
cl349@2448 303
kaf24@8533 304 extern struct vcpu *idle_vcpu[NR_CPUS];
kaf24@2110 305 #define IDLE_DOMAIN_ID (0x7FFFU)
kaf24@8533 306 #define is_idle_domain(d) ((d)->domain_id == IDLE_DOMAIN_ID)
kaf24@8533 307 #define is_idle_vcpu(v) (is_idle_domain((v)->domain))
kaf24@1210 308
kaf24@8611 309 #define DOMAIN_DESTROYED (1<<31) /* assumes atomic_t is >= 32 bits */
kaf24@1505 310 #define put_domain(_d) \
kaf24@8611 311 if ( atomic_dec_and_test(&(_d)->refcnt) ) domain_destroy(_d)
kaf24@2298 312
kaf24@2298 313 /*
kaf24@2298 314 * Use this when you don't have an existing reference to @d. It returns
kaf24@8611 315 * FALSE if @d is being destroyed.
kaf24@2298 316 */
kaf24@2344 317 static always_inline int get_domain(struct domain *d)
kaf24@1505 318 {
kaf24@2344 319 atomic_t old, new, seen = d->refcnt;
kaf24@2344 320 do
kaf24@2344 321 {
kaf24@2344 322 old = seen;
kaf24@8611 323 if ( unlikely(_atomic_read(old) & DOMAIN_DESTROYED) )
kaf24@2344 324 return 0;
kaf24@2344 325 _atomic_set(new, _atomic_read(old) + 1);
kaf24@2344 326 seen = atomic_compareandswap(old, new, &d->refcnt);
kaf24@2344 327 }
kaf24@2344 328 while ( unlikely(_atomic_read(seen) != _atomic_read(old)) );
kaf24@2344 329 return 1;
kaf24@1505 330 }
kaf24@2298 331
kaf24@2298 332 /*
kaf24@2298 333 * Use this when you already have, or are borrowing, a reference to @d.
kaf24@8611 334 * In this case we know that @d cannot be destroyed under our feet.
kaf24@2298 335 */
kaf24@2298 336 static inline void get_knownalive_domain(struct domain *d)
kaf24@2298 337 {
kaf24@2298 338 atomic_inc(&d->refcnt);
kaf24@8611 339 ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTROYED));
kaf24@2298 340 }
kaf24@4696 341
kfraser@14196 342 /* Obtain a reference to the currently-running domain. */
kfraser@14196 343 static inline struct domain *get_current_domain(void)
kfraser@14196 344 {
kfraser@14196 345 struct domain *d = current->domain;
kfraser@14196 346 get_knownalive_domain(d);
kfraser@14196 347 return d;
kfraser@14196 348 }
kfraser@14196 349
kfraser@14911 350 struct domain *domain_create(
kfraser@14911 351 domid_t domid, unsigned int domcr_flags, ssidref_t ssidref);
kfraser@12210 352 /* DOMCRF_hvm: Create an HVM domain, as opposed to a PV domain. */
keir@19266 353 #define _DOMCRF_hvm 0
keir@19266 354 #define DOMCRF_hvm (1U<<_DOMCRF_hvm)
keir@17898 355 /* DOMCRF_hap: Create a domain with hardware-assisted paging. */
keir@19266 356 #define _DOMCRF_hap 1
keir@19266 357 #define DOMCRF_hap (1U<<_DOMCRF_hap)
keir@19266 358 /* DOMCRF_s3_integrity: Create a domain with tboot memory integrity protection
keir@19266 359 by tboot */
keir@19266 360 #define _DOMCRF_s3_integrity 2
keir@19266 361 #define DOMCRF_s3_integrity (1U<<_DOMCRF_s3_integrity)
keir@17898 362 /* DOMCRF_dummy: Create a dummy domain (not scheduled; not on domain list) */
keir@19266 363 #define _DOMCRF_dummy 3
keir@19266 364 #define DOMCRF_dummy (1U<<_DOMCRF_dummy)
kfraser@12210 365
kfraser@14059 366 /*
kfraser@14191 367 * rcu_lock_domain_by_id() is more efficient than get_domain_by_id().
kfraser@14059 368 * This is the preferred function if the returned domain reference
kfraser@14059 369 * is short lived, but it cannot be used if the domain reference needs
kfraser@14059 370 * to be kept beyond the current scope (e.g., across a softirq).
kfraser@14191 371 * The returned domain reference must be discarded using rcu_unlock_domain().
kfraser@14059 372 */
kfraser@14191 373 struct domain *rcu_lock_domain_by_id(domid_t dom);
kfraser@14059 374
keir@18574 375 /*
keir@18574 376 * As above function, but accounts for current domain context:
keir@18574 377 * - Translates target DOMID_SELF into caller's domain id; and
keir@18574 378 * - Checks that caller has permission to act on the target domain.
keir@18574 379 */
keir@18574 380 int rcu_lock_target_domain_by_id(domid_t dom, struct domain **d);
keir@18574 381
kfraser@14191 382 /* Finish a RCU critical region started by rcu_lock_domain_by_id(). */
kfraser@14191 383 static inline void rcu_unlock_domain(struct domain *d)
kfraser@14059 384 {
kfraser@14059 385 rcu_read_unlock(&domlist_read_lock);
kfraser@14059 386 }
kfraser@14059 387
kfraser@14197 388 static inline struct domain *rcu_lock_domain(struct domain *d)
kfraser@14197 389 {
kfraser@14197 390 rcu_read_lock(d);
kfraser@14197 391 return d;
kfraser@14197 392 }
kfraser@14197 393
kfraser@14196 394 static inline struct domain *rcu_lock_current_domain(void)
kfraser@14196 395 {
kfraser@14197 396 return rcu_lock_domain(current->domain);
kfraser@14196 397 }
kfraser@14196 398
kaf24@13663 399 struct domain *get_domain_by_id(domid_t dom);
kfraser@12210 400 void domain_destroy(struct domain *d);
kfraser@15825 401 int domain_kill(struct domain *d);
kfraser@12210 402 void domain_shutdown(struct domain *d, u8 reason);
kfraser@14705 403 void domain_resume(struct domain *d);
kfraser@12210 404 void domain_pause_for_debugger(void);
cl349@4339 405
kfraser@14705 406 int vcpu_start_shutdown_deferral(struct vcpu *v);
kfraser@14705 407 void vcpu_end_shutdown_deferral(struct vcpu *v);
kfraser@14705 408
cl349@4339 409 /*
kaf24@7809 410 * Mark specified domain as crashed. This function always returns, even if the
kaf24@7809 411 * caller is the specified domain. The domain is not synchronously descheduled
kaf24@7809 412 * from any processor.
cl349@4339 413 */
kfraser@12210 414 void __domain_crash(struct domain *d);
sos22@8660 415 #define domain_crash(d) do { \
kaf24@8663 416 printk("domain_crash called from %s:%d\n", __FILE__, __LINE__); \
sos22@8660 417 __domain_crash(d); \
sos22@8660 418 } while (0)
cl349@4339 419
cl349@4339 420 /*
cl349@4339 421 * Mark current domain as crashed and synchronously deschedule from the local
cl349@4339 422 * processor. This function never returns.
cl349@4339 423 */
kfraser@12210 424 void __domain_crash_synchronous(void) __attribute__((noreturn));
sos22@8660 425 #define domain_crash_synchronous() do { \
kaf24@8663 426 printk("domain_crash_sync called from %s:%d\n", __FILE__, __LINE__); \
sos22@8660 427 __domain_crash_synchronous(); \
sos22@8660 428 } while (0)
kaf24@1210 429
kaf24@1210 430 #define set_current_state(_s) do { current->state = (_s); } while (0)
kaf24@1210 431 void scheduler_init(void);
ack@11622 432 int sched_init_vcpu(struct vcpu *v, unsigned int processor);
kfraser@12260 433 void sched_destroy_vcpu(struct vcpu *v);
kfraser@12260 434 int sched_init_domain(struct domain *d);
kfraser@12260 435 void sched_destroy_domain(struct domain *d);
kfraser@11296 436 long sched_adjust(struct domain *, struct xen_domctl_scheduler_op *);
kaf24@9224 437 int sched_id(void);
keir@19462 438 void sched_tick_suspend(void);
keir@19462 439 void sched_tick_resume(void);
kaf24@6445 440 void vcpu_wake(struct vcpu *d);
kaf24@6445 441 void vcpu_sleep_nosync(struct vcpu *d);
kaf24@6445 442 void vcpu_sleep_sync(struct vcpu *d);
kaf24@1210 443
kaf24@4373 444 /*
kaf24@6471 445 * Force synchronisation of given VCPU's state. If it is currently descheduled,
kaf24@6471 446 * this call will ensure that all its state is committed to memory and that
kaf24@6471 447 * no CPU is using critical state (e.g., page tables) belonging to the VCPU.
kaf24@4373 448 */
kfraser@12210 449 void sync_vcpu_execstate(struct vcpu *v);
kaf24@4373 450
kaf24@6214 451 /*
kaf24@8517 452 * Called by the scheduler to switch to another VCPU. This function must
kaf24@8517 453 * call context_saved(@prev) when the local CPU is no longer running in
kaf24@8517 454 * @prev's context, and that context is saved to memory. Alternatively, if
kaf24@8517 455 * implementing lazy context switching, it suffices to ensure that invoking
kaf24@8517 456 * sync_vcpu_execstate() will switch and commit @prev's state.
kaf24@6214 457 */
kfraser@12210 458 void context_switch(
kaf24@5289 459 struct vcpu *prev,
kaf24@5289 460 struct vcpu *next);
kaf24@1210 461
kaf24@6214 462 /*
kaf24@8517 463 * As described above, context_switch() must call this function when the
kaf24@8517 464 * local CPU is no longer running in @prev's context, and @prev's context is
kaf24@8517 465 * saved to memory. Alternatively, if implementing lazy context switching,
kaf24@8517 466 * ensure that invoking sync_vcpu_execstate() will switch and commit @prev.
kaf24@6214 467 */
kfraser@12210 468 void context_saved(struct vcpu *prev);
kaf24@6214 469
kaf24@6214 470 /* Called by the scheduler to continue running the current VCPU. */
kfraser@12210 471 void continue_running(
kaf24@5289 472 struct vcpu *same);
kaf24@4696 473
kaf24@1210 474 void startup_cpu_idle_loop(void);
kaf24@1210 475
kaf24@9068 476 /*
kaf24@9068 477 * Creates a continuation to resume the current hypercall. The caller should
kaf24@9068 478 * return immediately, propagating the value returned from this invocation.
kaf24@9068 479 * The format string specifies the types and number of hypercall arguments.
kaf24@9068 480 * It contains one character per argument as follows:
kaf24@9068 481 * 'i' [unsigned] {char, int}
kaf24@9068 482 * 'l' [unsigned] long
kaf24@9873 483 * 'h' guest handle (XEN_GUEST_HANDLE(foo))
kaf24@9068 484 */
kaf24@9068 485 unsigned long hypercall_create_continuation(
kaf24@9068 486 unsigned int op, const char *format, ...);
kaf24@3702 487
kaf24@6110 488 #define hypercall_preempt_check() (unlikely( \
kaf24@6110 489 softirq_pending(smp_processor_id()) | \
kaf24@10354 490 local_events_need_delivery() \
kaf24@4639 491 ))
kaf24@3091 492
kfraser@14058 493 /* Protect updates/reads (resp.) of domain_list and domain_hash. */
kfraser@14058 494 extern spinlock_t domlist_update_lock;
kfraser@14058 495 extern rcu_read_lock_t domlist_read_lock;
kfraser@14058 496
kaf24@2806 497 extern struct domain *domain_list;
kaf24@1210 498
kfraser@14058 499 /* Caller must hold the domlist_read_lock or domlist_update_lock. */
kaf24@7364 500 #define for_each_domain(_d) \
kfraser@14058 501 for ( (_d) = rcu_dereference(domain_list); \
kaf24@7364 502 (_d) != NULL; \
kfraser@14058 503 (_d) = rcu_dereference((_d)->next_in_list )) \
kaf24@1210 504
kaf24@7364 505 #define for_each_vcpu(_d,_v) \
keir@19788 506 for ( (_v) = (_d)->vcpu ? (_d)->vcpu[0] : NULL; \
kaf24@7364 507 (_v) != NULL; \
kaf24@7364 508 (_v) = (_v)->next_in_list )
kaf24@1505 509
kaf24@4877 510 /*
kfraser@14663 511 * Per-VCPU pause flags.
kaf24@4877 512 */
kaf24@4877 513 /* Domain is blocked waiting for an event. */
kfraser@14663 514 #define _VPF_blocked 0
kfraser@14663 515 #define VPF_blocked (1UL<<_VPF_blocked)
kaf24@10357 516 /* VCPU is offline. */
kfraser@14663 517 #define _VPF_down 1
kfraser@14663 518 #define VPF_down (1UL<<_VPF_down)
kfraser@11567 519 /* VCPU is blocked awaiting an event to be consumed by Xen. */
kfraser@14663 520 #define _VPF_blocked_in_xen 2
kfraser@14663 521 #define VPF_blocked_in_xen (1UL<<_VPF_blocked_in_xen)
kfraser@11567 522 /* VCPU affinity has changed: migrating to a new CPU. */
kfraser@14663 523 #define _VPF_migrating 3
kfraser@14663 524 #define VPF_migrating (1UL<<_VPF_migrating)
cl349@2919 525
kaf24@8517 526 static inline int vcpu_runnable(struct vcpu *v)
kaf24@1505 527 {
kfraser@14663 528 return !(v->pause_flags |
kfraser@14663 529 atomic_read(&v->pause_count) |
kfraser@14663 530 atomic_read(&v->domain->pause_count));
cl349@2919 531 }
cl349@2919 532
keir@18441 533 void vcpu_unblock(struct vcpu *v);
kaf24@5289 534 void vcpu_pause(struct vcpu *v);
ack@13011 535 void vcpu_pause_nosync(struct vcpu *v);
cl349@5246 536 void domain_pause(struct domain *d);
kaf24@5289 537 void vcpu_unpause(struct vcpu *v);
cl349@5246 538 void domain_unpause(struct domain *d);
cl349@5246 539 void domain_pause_by_systemcontroller(struct domain *d);
cl349@5246 540 void domain_unpause_by_systemcontroller(struct domain *d);
kaf24@6014 541 void cpu_init(void);
cl349@2919 542
kfraser@14340 543 void vcpu_force_reschedule(struct vcpu *v);
keir@18477 544 void cpu_disable_scheduler(void);
kaf24@8511 545 int vcpu_set_affinity(struct vcpu *v, cpumask_t *affinity);
keir@16896 546 int vcpu_lock_affinity(struct vcpu *v, cpumask_t *affinity);
keir@18512 547 int vcpu_locked_change_affinity(struct vcpu *v, cpumask_t *affinity);
keir@16896 548 void vcpu_unlock_affinity(struct vcpu *v, cpumask_t *affinity);
kaf24@8511 549
kaf24@9022 550 void vcpu_runstate_get(struct vcpu *v, struct vcpu_runstate_info *runstate);
keir@18908 551 uint64_t get_cpu_idle_time(unsigned int cpu);
kaf24@9022 552
kfraser@12210 553 #define IS_PRIV(_d) ((_d)->is_privileged)
keir@16856 554 #define IS_PRIV_FOR(_d, _t) (IS_PRIV(_d) || ((_d)->target && (_d)->target == (_t)))
kaf24@1210 555
kaf24@2073 556 #define VM_ASSIST(_d,_t) (test_bit((_t), &(_d)->vm_assist))
kaf24@2073 557
kfraser@12238 558 #define is_hvm_domain(d) ((d)->is_hvm)
kfraser@12238 559 #define is_hvm_vcpu(v) (is_hvm_domain(v->domain))
keir@17726 560 #define need_iommu(d) ((d)->need_iommu && !(d)->is_hvm)
kfraser@12238 561
keir@19504 562 void set_vcpu_migration_delay(unsigned int delay);
keir@19504 563 unsigned int get_vcpu_migration_delay(void);
keir@19504 564
keir@19417 565 extern int sched_smt_power_savings;
keir@19417 566
keir@15948 567 extern enum cpufreq_controller {
keir@18181 568 FREQCTL_none, FREQCTL_dom0_kernel, FREQCTL_xen
keir@15948 569 } cpufreq_controller;
keir@15948 570
kaf24@1506 571 #endif /* __SCHED_H__ */
kaf24@3914 572
kaf24@3914 573 /*
kaf24@3914 574 * Local variables:
kaf24@3914 575 * mode: C
kaf24@3914 576 * c-set-style: "BSD"
kaf24@3914 577 * c-basic-offset: 4
kaf24@3914 578 * tab-width: 4
kaf24@3914 579 * indent-tabs-mode: nil
kaf24@3988 580 * End:
kaf24@3914 581 */