blob: 08078dcc4eb7b9178da8e1ca49d704b50d49b4d7 [file] [log] [blame] [view]
Andrew Walbran6e524d72019-11-12 17:36:57 +00001# Scheduler VM expectations
2
3Hafnium requires there to be a special 'primary' or 'scheduler' VM which is
4responsible for scheduling the other VMs. There are some particular expectations
5on this VM that are required for the rest of the system to function normally.
6
7## Scheduling
8
9The scheduler VM is responsible for scheduling the vCPUs of all the other VMs.
10It should request information about the VMs in the system using the
11`SPCI_PARTITION_INFO_GET` function, and then schedule their vCPUs as it wishes.
12The recommended way of doing this is to create a kernel thread for each vCPU,
13which will repeatedly run that vCPU by calling `SPCI_RUN`.
14
15`SPCI_RUN` will return one of several possible functions, which must be handled
16as follows:
17
18### `SPCI_INTERRUPT`
19
20The vCPU has been preempted but still has work to do. If the scheduling quantum
21has not expired, the scheduler MUST call `hf_vcpu_run` on the vCPU to allow it
22to continue.
23
24### `SPCI_YIELD`
25
26The vCPU has voluntarily yielded the CPU. The scheduler SHOULD take a scheduling
27decision to give cycles to those that need them but MUST call `hf_vcpu_run` on
28the vCPU at a later point.
29
30### `SPCI_MSG_WAIT`
31
32The vCPU is blocked waiting for a message. The scheduler MUST take it off the
33run queue and not call `SPCI_RUN` on the vCPU until it has either:
34
35* injected an interrupt
36* sent it a message
37* received `HF_SPCI_RUN_WAKE_UP` for it from another vCPU
38* the timeout provided in `w2` is not `SPCI_SLEEP_INDEFINITE` and the
39 specified duration has expired.
40
41### `SPCI_MSG_SEND`
42
43A message has been sent by the vCPU. If the recipient is the scheduler VM itself
44then it can handle it as it pleases. Otherwise the scheduler MUST run a vCPU
45from the recipient VM and priority SHOULD be given to those vCPUs that are
46waiting for a message. The scheduler should call SPCI_RUN again on the sending
47VM as usual.
48
49### `SPCI_RX_RELEASE`
50
51The vCPU has made the mailbox writable and there are pending waiters. The
52scheduler MUST call `hf_mailbox_waiter_get()` repeatedly and notify all waiters
53by injecting an `HF_MAILBOX_WRITABLE_INTID` interrupt. The scheduler should call
54SPCI_RUN again on the sending VM as usual.
55
56### `HF_SPCI_RUN_WAIT_FOR_INTERRUPT`
57
58_This is a Hafnium-specific function not part of the SPCI standard._
59
60The vCPU is blocked waiting for an interrupt. The scheduler MUST take it off the
61run queue and not call `SPCI_RUN` on the vCPU until it has either:
62
63* injected an interrupt
64* received `HF_SPCI_RUN_WAKE_UP` for it from another vCPU
65* the timeout provided in `w2` is not `SPCI_SLEEP_INDEFINITE` and the
66 specified duration has expired.
67
68### `HF_SPCI_RUN_WAKE_UP`
69
70_This is a Hafnium-specific function not part of the SPCI standard._
71
72Hafnium would like `hf_vcpu_run` to be called on another vCPU, specified by
73`hf_vcpu_run_return.wake_up`. The scheduler MUST either wake the vCPU in
74question up if it is blocked, or preempt and re-run it if it is already running
75somewhere. This gives Hafnium a chance to update any CPU state which might have
76changed. The scheduler should call SPCI_RUN again on the sending VM as usual.
77
78### `SPCI_ERROR`
79
80#### `SPCI_ABORTED`
81
82The vCPU has aborted triggering the whole VM to abort. The scheduler MUST treat
83this the same as `HF_SPCI_RUN_WAKE_UP` for all the other vCPUs of the VM. For
84this vCPU the scheduler SHOULD either never call SPCI_RUN on the vCPU again, or
85treat it the same as `HF_SPCI_RUN_WAIT_FOR_INTERRUPT`.
86
87#### Any other error code
88
89This should not happen if the scheduler VM has called `SPCI_RUN` correctly, but
90in case there is some other error it should be logged. The scheduler SHOULD
91either try again or suspend the vCPU indefinitely.
92
93## Interrupt handling
94
95The scheduler VM is responsible for handling all hardware interrupts. Many of
96these will be intended for the scheduler VM itself and it can handle them as
97usual. However, it must also:
98
99* Enable, handle and ignore interrupts for the non-secure hypervisor physical
100 timer (PPI 10, IRQ 26).
101* Forward interrupts intended for secondary VMs to an appropriate vCPU of the
102 VM by calling `hf_interrupt_inject` and then running the vCPU as usual with
103 `SPCI_RUN`. (If the vCPU is already running at the time that
104 `hf_interrupt_inject` is called then it must be preempted and run again so
105 that Hafnium can inject the interrupt.)