1# Zircon Kernel Invariants 2 3On x86, Zircon needs to maintain the following invariants for code running 4in ring 0 (kernel mode). 5 6These invariants are documented here because they are not necessarily easy 7to test -- breaking an invariant will not necessarily be caught by 8Zircon's test suite. 9 10* Flags register: 11 12 * The direction flag (DF) should be 0. This is required by the x86 13 calling conventions. 14 15 If this flag is set to 1, uses of x86 string instructions (e.g. `rep 16 movs` in `memcpy()` or inlined by the compiler) can go wrong and copy 17 in the wrong direction. It is OK for a function to set this flag to 1 18 temporarily as long as it changes it back to 0 before returning or 19 calling other functions. 20 21 * The alignment check flag (AC) should normally be 0. On CPUs that 22 support SMAP, this prevents the kernel from accidentally reading or 23 writing userland data. 24 25* The `gs_base` register must point to the current CPU's `x86_percpu` 26 struct whenever running in kernel mode with interrupts enabled. 27 `gs_base` should only be changed to point to something else while 28 interrupts are disabled. For example, the `swapgs` instruction should 29 only be used when interrupts are disabled. 30 31* The following are partially enforced by the compiler: 32 33 * No use of extended registers (SSE, AVX, x87, etc.) is allowed, because 34 that would clobber userland's register state. 35 36 This is partially achieved by passing `-mno-sse` to the compiler. This 37 option is necessary to prevent the compiler from using SSE registers in 38 optimizations (e.g. memory copies). 39 40 We would like to prevent accidentally using the `float` or `double` 41 types in kernel code, but GCC and Clang won't do that for us in all 42 cases. `-mno-sse` does not prevent using `float`/`double` with either 43 compiler -- the compilers will use x87 instructions instead. 44 45 We compile with `-msoft-float`, which seems to prevent GCC from 46 generating x87 instructions (and hence using x87 registers): GCC 6.3.0 47 will give an error on `float`/`double` arithmetic and return values, 48 but it does not prevent passing these types around as arguments. 49 However, passing `-msoft-float` to Clang seems to have no effect: Clang 50 7.0.0 will still generate x87 instructions (and use x87 registers) for 51 code using `float` or `double`. 52 53 * No storing data below `%rsp` on the stack. Note that userland code can 54 do this: the SysV x86-64 ABI allows functions to store data in the "red 55 zone", which is the 128 bytes below %rsp. However, kernel code cannot 56 use the red zone because interrupts may clobber this region -- the CPU 57 pushes data onto the stack immediately below %rsp when it invokes an 58 interrupt handler. 59 60 This is generally enforced by passing `-mno-red-zone` to the compiler. 61