mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-15 15:04:27 +08:00
3891a04aaf
The IRET instruction, when returning to a 16-bit segment, only
restores the bottom 16 bits of the user space stack pointer. This
causes some 16-bit software to break, but it also leaks kernel state
to user space. We have a software workaround for that ("espfix") for
the 32-bit kernel, but it relies on a nonzero stack segment base which
is not available in 64-bit mode.
In checkin:
b3b42ac2cb
x86-64, modify_ldt: Ban 16-bit segments on 64-bit kernels
we "solved" this by forbidding 16-bit segments on 64-bit kernels, with
the logic that 16-bit support is crippled on 64-bit kernels anyway (no
V86 support), but it turns out that people are doing stuff like
running old Win16 binaries under Wine and expect it to work.
This works around this by creating percpu "ministacks", each of which
is mapped 2^16 times 64K apart. When we detect that the return SS is
on the LDT, we copy the IRET frame to the ministack and use the
relevant alias to return to userspace. The ministacks are mapped
readonly, so if IRET faults we promote #GP to #DF which is an IST
vector and thus has its own stack; we then do the fixup in the #DF
handler.
(Making #GP an IST exception would make the msr_safe functions unsafe
in NMI/MC context, and quite possibly have other effects.)
Special thanks to:
- Andy Lutomirski, for the suggestion of using very small stack slots
and copy (as opposed to map) the IRET frame there, and for the
suggestion to mark them readonly and let the fault promote to #DF.
- Konrad Wilk for paravirt fixup and testing.
- Borislav Petkov for testing help and useful comments.
Reported-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Link: http://lkml.kernel.org/r/1398816946-3351-1-git-send-email-hpa@linux.intel.com
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Andrew Lutomriski <amluto@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Dirk Hohndel <dirk@hohndel.org>
Cc: Arjan van de Ven <arjan.van.de.ven@intel.com>
Cc: comex <comexk@gmail.com>
Cc: Alexander van Heukelum <heukelum@fastmail.fm>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: <stable@vger.kernel.org> # consider after upstream merge
41 lines
1.6 KiB
Plaintext
41 lines
1.6 KiB
Plaintext
|
|
<previous description obsolete, deleted>
|
|
|
|
Virtual memory map with 4 level page tables:
|
|
|
|
0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm
|
|
hole caused by [48:63] sign extension
|
|
ffff800000000000 - ffff80ffffffffff (=40 bits) guard hole
|
|
ffff880000000000 - ffffc7ffffffffff (=64 TB) direct mapping of all phys. memory
|
|
ffffc80000000000 - ffffc8ffffffffff (=40 bits) hole
|
|
ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space
|
|
ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
|
|
ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
|
|
... unused hole ...
|
|
ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
|
|
... unused hole ...
|
|
ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0
|
|
ffffffffa0000000 - ffffffffff5fffff (=1525 MB) module mapping space
|
|
ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
|
|
ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole
|
|
|
|
The direct mapping covers all memory in the system up to the highest
|
|
memory address (this means in some cases it can also include PCI memory
|
|
holes).
|
|
|
|
vmalloc space is lazily synchronized into the different PML4 pages of
|
|
the processes using the page fault handler, with init_level4_pgt as
|
|
reference.
|
|
|
|
Current X86-64 implementations only support 40 bits of address space,
|
|
but we support up to 46 bits. This expands into MBZ space in the page tables.
|
|
|
|
->trampoline_pgd:
|
|
|
|
We map EFI runtime services in the aforementioned PGD in the virtual
|
|
range of 64Gb (arbitrarily set, can be raised if needed)
|
|
|
|
0xffffffef00000000 - 0xffffffff00000000
|
|
|
|
-Andi Kleen, Jul 2004
|