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