IRC channel logs
2023-08-19.log
back to list of logs
<damo22>luckyluke: hi, do you know how to make use of %gs on i386? <damo22>i want to make some per-cpu variables with a segment reg pointing at it <damo22>but the saved state is per thread right? <damo22>actually i found out %gs is used for TLS on i386, and %fs is unused by userspace <damo22>mach seems to use %fs a fair bit <luckyluke>Hi damo22, IIRC fs/gs are already saved and restored by the trap handlers for 32-bit userspace, and in kernel %fs is used during syscall entry to access the user stack <luckyluke>on a 64 bit kernel, fs/fs are not used AFAIK <damo22>luckyluke: in userspace, gs is used for i386 TLS, but fs is unused. I can use gs for syscall entry instead of fs? <damo22>so i can use fs as a percpu pointer basically <luckyluke>I guess either fs or gs are the same on 32-bit (no swapgs) <luckyluke>but their use in userspace is unrelated to the use in kernel space <damo22>but i can make fs only accessible in kernel land <damo22>i cant do that with gs because userspace needs to use it <luckyluke>I think you cannot restrict userspace from setting fs <luckyluke>but fs/gs are always saved and restored when entering and exiting userspace <damo22>in kernel land, i want fs to always be pointing to a percpu struct <damo22>except when exiting to userpsace <luckyluke>so maybe you could have an GDT or LDT entry to point to the per-cpu structure, the tables should be already per-cpu <damo22>do i need to allocate it in the ldscript? <damo22>kalloc a struct and then add it to gdt? <luckyluke>I think in ldt.c or gdt.c, just add an entry to the table <damo22>its a bit difficult to compute a pointer to a struct before paging is set up isnt it? <damo22>so i mean how do i allocate the percpu struct itself <luckyluke>I think most (if not all) are statically allocated currently, so that could be an option <luckyluke>e.g. there are user GST and LDT slots that can be changed per-thread <luckyluke>in that case, the descriptor table is probably reloaded when returning to userspace, but I guess you can force a reload with lldt/lgdt <damo22>wouldnt it be best if the gdt entry was different per cpu so that it actually pointed to the struct itself? <damo22>i dont quite understand the segmentation <luckyluke>sure, I think the descriptor tables are already specific to one cpu, and currently we already load different tables from mp_desc_table <damo22>so i need to choose a memory location for the array of structs <damo22>and have each entry point to cpu_number() * offset of struct <luckyluke>yes that should work, and when entering kernel space you need to set fs to the correct segment descriptor in locore.S <luckyluke>is anybody working on enabling a bigger physical alignment in vm_allocate_contiguous()? <solid_black>damo22: you absolutely can not assume that one of fs/gs is unused by userspace <solid_black>it is typically unused indeed, but userspace may make use of it <solid_black>Darling does, too, though obviously Darling doesn't run on Hurd (yet) <solid_black>you must preserve both gs/fs as seen from user space <solid_black>and use something like swapgs to use it for kernel purposes too