-
Notifications
You must be signed in to change notification settings - Fork 701
Clarify the Usage and Mechanism of Guard Values and Bits in the Docs #1457
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Welcome to one of the most tricky parts of using seL4, CSpace management! Instead of repeating myself more, I'll link to a thread on the devel mailinglist which discusses some details and complexities. Like the thread you linked to says, sizes are to support sparse multilevel CSpaces, so the kernel knows how many bits to resolve to find a slot to the next level CNode. If you didn't configure the size, the kernel would need to use the CNode size. However, to me it is unclear why that would prevent supporting sparse multi-level CSpace, it would just mean that the indices for the top-level CNode are the top bits of the CPtr, so you can't have nice, low numbers anymore. E.g. The nice property of this would be that you don't need to know how many levels your CSpace will have beforehand, you just resolve bits from high to low until you reach a destination slot. The less nice property is that all your addressing changes when you resize a CNode. The definition of So to answer your question, people didn't want e.g. 0x10000000000000 as Guard values aren't removed, so the thread is wrong there. Once you have sizes, you can as well have guard bits instead of hard-coding them to zero. They can be used to make CNode addressing more robust. Top level guards are a way to create namespaces, both to distinguish other integers from Cptrs and well as make them distinct from normal pointers. Intermediate guard bits can be used to partition the CSpace further. For instance, the initial thread's CSpace has all very low numbers. If you give it a higher bits guard, it reduces the chance that random numbers are valid CPtrs. It makes it harder for bugs to mess up things (and hence harder to exploit the code too). Imagine you have a 2-level CSpace where T in 0xTTTT0000 bits define the top level CNode's guard + slot index and L in 0x0000LLLL define the second level CNode bits. Say your cnode2 has starting address 0x12340000 and its last slot is at 0x123400ff, as it is 8 bits big. If you overflow the space size and try to address 0x12340100, you could accidentally address another cap by accident, if there is another CNode starting at 0x12340100. To guard against this, instead of padding the address with zeroes, you can give each sub-CNode it's own unique guard, e.g. 0xa0 for our cnode2, and 0xb1 for its sibling. Now if you overflow to 0x1234a100, you don't accidentally address the sibling's CNode any more.
Yes, and that's exactly the point: All the capabilities in the initial CNode need to be addressable, which means that they are reached after resolving Only Cnode operating syscalls (CNode ops and retyping) can address such indirect slots, and they do it via the convoluted root + index + depth way. Anyway, when starting, ignore guards and use zero for them. Once you have that working and understand how CSpace addressing practically works, you can add non-zero guards where you want. Guards and sizes could be better documented. One thing that is currently unclear is that they are part of the CNode cap, not part of the CNode itself, so it's stored for each CNode reference and that's why it's part of a TCB's configuration, as it not only needs to know the CNode, but also how to address it. |
We are currently experimenting with CSpaces, VSpace, TCBs, etc ... but have some problem with regards to addressing CNodes and Capabilities in a CSpace hierarchy. Especially Guard Values and Sizes are confusing and poorly documented.
It would be nice if the documentation could explain why they exist, how they should be used as well as how they work. Also why does the kernel assume
GUARD_SIZE = WORD_SIZE - RADIX_SIZE
for the roottask? In my understanding this would prevent the root task from addressing capabilities in nested CNodes?This Thread hints that Guard Values were removed, but the current API and documentation still include them?
The text was updated successfully, but these errors were encountered: