|
| 1 | +# Design Document for GCS |
| 2 | + |
| 3 | +## Feature test |
| 4 | + |
| 5 | +GCS support has three levels: |
| 6 | + |
| 7 | +(1) Code generation is GCS compatible. (Compile time decision.) |
| 8 | + |
| 9 | +(2) HW supports GCS instructions. (Might be known at compile time, |
| 10 | + but this is a runtime feature.) |
| 11 | + |
| 12 | +(3) GCS is enabled at runtime. (Only known at runtime.) |
| 13 | + |
| 14 | +Where (3) implies (1) and (2). In principle a user may decide to |
| 15 | +enable GCS even if (1) was false at compile time, but this is |
| 16 | +a user error. The runtime system is responsible for enabling GCS |
| 17 | +when (1) and (2) holds and GCS protection was requested for the |
| 18 | +program. |
| 19 | + |
| 20 | +(1) and (2) need feature test macros since they can be known at |
| 21 | +compile time. |
| 22 | + |
| 23 | +(3) can be detected using `__chkfeat(_CHKFEAT_GCS)` which is |
| 24 | +available without GCS support. |
| 25 | + |
| 26 | +## Intrinsics |
| 27 | + |
| 28 | +Alternative designs for the support levels at which the intrinsics |
| 29 | +are well defined: |
| 30 | + |
| 31 | +(A) require (3), |
| 32 | + |
| 33 | +(B) require (1) and (2) but not (3), |
| 34 | + |
| 35 | +(C) require (2) only. |
| 36 | + |
| 37 | +Simplest is (A), but it does not allow asynchronously disabling GCS, |
| 38 | +for that at least (B) is needed since the intrinsics must do something |
| 39 | +reasonable if GCS is disabled. Asynchronous disable is e.g. needed to |
| 40 | +allow disabling GCS at dlopen time in a multi-threaded process when |
| 41 | +the loaded module is not GCS compatible. |
| 42 | + |
| 43 | +(C) is similar to (B) but allows using the intrinsics even if GCS is |
| 44 | +guaranteed to be disabled. The intrinsics are expected to be used |
| 45 | +behind runtime check for (3) since they don't do anything useful |
| 46 | +otherwise and thus (1) and (2) are true when the intrinsics are used |
| 47 | +either way. With (B) it is possible to only expose the intrinsics |
| 48 | +at compile time if (1) is true which can be feature tested. With (C) |
| 49 | +there is no obvious feature test for the presence of the intrinsics. |
| 50 | + |
| 51 | +The future direction is to make intrinsics available unconditionally |
| 52 | +and rely on runtime checks (e.g. via function multi-versioning). So |
| 53 | +it makes sense to go with (C), have separate semantics defined for |
| 54 | +the enabled and disabled case and let user code deal with the runtime |
| 55 | +checks. |
| 56 | + |
| 57 | +The type of the intrinsics is based on `const void *` GCS pointer |
| 58 | +type and `uint64_t` GCS entry type. The GCS pointer could be |
| 59 | +`const uint64_t *`, but void is more general in that it allows |
| 60 | +different access to the GCS (e.g. accessing entries as pointers or |
| 61 | +bytes). A GCS entry is usually a code pointer, but the architecture |
| 62 | +requires it to be 8 bytes (even with ILP32) and it may be a special |
| 63 | +token that requires bit operations to detect, so fixed width |
| 64 | +unsigned int type is the most appropriate. |
| 65 | + |
| 66 | +The const qualifier is justified for GCS even if GCS stores are |
| 67 | +enabled because normal stores cannot modify the GCS only specific |
| 68 | +instructions can. |
0 commit comments