IRC channel logs

2023-08-18.log

back to list of logs

<damo22>whats next folks
<damo22>i ran out of rabbits to pull out of my hat
<damo22>:P
<damo22>solid_black: how is %gs supposed to work on x86_64 ?
<damo22>i have no clue about 64 bit
<damo22>does MSR 0xc0000100 101 and 102 work on intel?
<solid_black>hi damo22!
<damo22>hi
<solid_black>there's an MSR for GS_BASE, and one for KERNEL_GS_BASE
<damo22>101 and 102
<damo22>+ 0xc0000000
<solid_black>you write stuff there, then you can do %gs:offset to access stuff at *(base + offset)
<solid_black>then there's swapgs to atomically swap the two msr's values
<damo22>ah nice
<solid_black>which you're supposed to do when entering/existing the kernel
<solid_black>except you have to be really really careful with it, apparently
<solid_black>see https://wiki.osdev.org/SWAPGS#Complications
<damo22>i saw
<damo22>i cant use kernel_gs_base on i386
<damo22>rihgt?
<solid_black>I don't think you can, yes
<damo22>swapgs is a .code64 instruction
<damo22>ok
<damo22>i dont have 64 bit running here
<solid_black>maybe you should get it :)
<damo22>i can wait until it works out of the box
<damo22>i have other things to fix
<damo22>i need to figure out why smp is so slow
<damo22>i suppose when 64 bit lands, we will discontinue i386?
<solid_black>I wouldn't want that
<solid_black>and Samuel has previously said we're not going to, but we're not going to deal with 2038 problem either
<damo22>is that 32 bit epoch?
<solid_black>yeah
<damo22>yeah i dont really care
<solid_black>so in a way 2038 is the hard deadline for 64-bit
<solid_black>btw wasn't there someone working on a risc-v port?
<damo22>idk
<damo22>maybe i cant fix i386 properly unless i use %gs
<damo22>since the msr is 64 bit wide, doesnt that mean you can store a 64 bit address in the gs_base and kernel_gs_base ?
<solid_black>yes, of course
<solid_black>how would it work if it wasn't 64-bit?
<damo22>so it can be any kalloc'd address
<solid_black>yes
<damo22>ok
<damo22>why does the gs:0 need to store a pointer to itself?
<solid_black>see, there's no way (other than reading from MSR) to actually get the base
<solid_black>you can only dereference pointers at offset from it
<solid_black>as far as I 've heard even leaq %gs:0 doesn't work
<damo22>ah
<damo22>ok
<damo22>so you just put a pointer to the struct as the first member
<solid_black>so either you always specify an offset when trying to access things (but that quickly gets awkward when you want the data to be a real structure), or you store self-pointer at a known offset and then read that
<solid_black>yes
<damo22>what a hack
<solid_black>also in userspace that is a requirement per x86_64 TLS ABI
<solid_black>perhaps on other arches too, not sure
<damo22>what is TLS here?
<solid_black>thread-local storage
<damo22>ok
<solid_black>hm interesting, so from quickly glancing at linux source, they seem to be setting up the descriptors/GDTs (I have little idea how this works) for each CPU separately on i386, so they can load a fixed value into %gs and have it point into the percpu area
<damo22>that makes sense
<damo22>is %gs unused for anything else on i386?
<solid_black>by userspace, for tls
<solid_black>you should assume both %fs and %gs are used by userspace
<damo22>ok
<solid_black>so you cannot clobber their values as far as userland is concerned
<damo22>but its simple enough to save thse
<damo22>on a stack
<solid_black>not on a stack
<solid_black>in the register save area
<solid_black>struct i386_saved_state
<damo22>ok
<solid_black>in fact the code might already be saving them, not sure
<solid_black>(check locore.S)
<solid_black>yeah they do
<solid_black>except that to save your gs value (and others) there, you should get a pointer there, somehow
<solid_black>and for that you already need to know your CPU id
<solid_black>so you'll probably need to alter that code path
<solid_black>to spill %gs onto the stack first, load your per-cpu structure, find the i386_saved_state, and then save gs there
<damo22>i386_saved_state should have per cpu gs slots
<solid_black>and you should coordinate this with Luca, he understands this much better than me
<solid_black>that state is-per thread
<damo22>ok
<solid_black>like, it's the saved state of one userspace thread
<solid_black>userspace expects to keep the same gs value even if the thread gets migrated to another cpu, for example
<damo22>each gs per cpu is different
<solid_black>in kernel mode, yes
<solid_black>in userspace, it's per-thread
<solid_black>same as all other registers
<damo22>well that sucks, you could use the msr
<solid_black>not on i386, you couldn't
<solid_black>on x86_64, you can
<damo22>i386 gs is tricky
<damo22>i dont know if i can be bothered working it out
<solid_black>again, you should really talk to Luca about this
<solid_black>you could also look at https://github.com/SerenityOS/serenity/blob/a38b3e112bd3d835c8e473c5487315c7e3501d70/Kernel/Arch/x86/Processor.h
<solid_black>note that this is from a commit before i686 support was removed