Closed PandaZ3D closed 1 year ago
Can you add a basic kernel test for TLS? Just a test case to make sure it's working, something like having a pre-defined TLS variable with a non-zero magic number, and then testing that loading that value is correct, doesn't have to be crazy.
aarch64
passes the test, but TLS is not being initialized properly for x86-64
. Essentially the offset from the initial TLS allocation area is wrong. The reason why TLS seemed like it worked before was because all initial values of TLS variables were zero. The workaround is to set to the size of the TLS block, plus padding. With this fix, it passes the test.
- let tcb_base = VirtAddr::from_ptr(tls).offset(full_tls_size).unwrap();
+ let tcb_base = VirtAddr::from_ptr(tls).offset(tls_size).unwrap();
Great, I suspected there was a bug there!
Thread Local Storage (TLS) has two variants and that choice is architecture specific. A summary of TLS can be found here.
x86-64
uses variant II for backwards compatibility, andaarch64
uses variant I. Given this difference, we cannot assume a particular variant when initializing TLS (processor::init_tls
). We move TLS initialization out of theprocessor
module and into theimage
, where both variants are implemented. The choice of which variant to choose is done in an architecture specificimage
module.Summary
TPDIR_EL1
when compiled foraarch64
.aarch64
) so that TLS sections show up.aarch64
)