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