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
<luckyluke>fs/gs ^
<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>i want to free up 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)
<damo22>yea
<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>ok
<damo22>in kernel land, i want fs to always be pointing to a percpu struct
<damo22>and never be changed
<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>yes
<damo22>do i need to allocate it in the ldscript?
<luckyluke>I don't think so, why?
<damo22>how do i set it up
<damo22>kalloc a struct and then add it to gdt?
<damo22>while setting up the APs
<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>but you can change the segment base later
<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
<luckyluke>they are just the same now
<damo22>yes
<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
<damo22>right
<luckyluke>is anybody working on enabling a bigger physical alignment in vm_allocate_contiguous()?
<solid_black>damo22, luckyluke: hi!
<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>Wine does
<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
<luckyluke>hi solid_black