On Wed, Jan 11, 2023 at 03:37:20PM +0300, Kirill A. Shutemov wrote: > The functions get_user() and put_user() check that the target address > range resides in the user space portion of the virtual address space. > In order to perform this check, the functions compare the end of the > range against TASK_SIZE_MAX. > > For kernels compiled with CONFIG_X86_5LEVEL, this process requires some > additional trickery using ALTERNATIVE, as TASK_SIZE_MAX depends on the > paging mode in use. > > Linus suggested that this check could be simplified for 64-bit kernels. > It is sufficient to check bit 63 of the address to ensure that the range > belongs to user space. Additionally, the use of branches can be avoided > by setting the target address to all ones if bit 63 is set. > > There's no need to check the end of the access range as there's huge > gap between end of userspace range and start of the kernel range. The > gap consists of canonical hole and unused ranges on both kernel and > userspace sides. So far I can follow, however > If an address with bit 63 set is passed down, it will trigger a #GP > exception. _ASM_EXTABLE_UA() complains about this. Replace it with > plain _ASM_EXTABLE() as it is expected behaviour now. here I don't. The new logic basically squishes every kernel address to -1L -- a known unmapped address, but getting that address in {get,put}_user() is still a fail, right? We used to manually branch to bad_get_user when outside TASK_SIZE_MAX, now we rely on #GP. So why silence it?