The virtual address space of Linux process is divided into two areas:
Split on 32 Bit Architectures
On a 32 bit architecture, e.g., arm or i386, the traditional split is 3:1, as shown below:
+--------+ 0xffffffff
| Kernel |
+--------+ 0xc0000000
| |
| User |
| |
+--------+ 0x00000000
- Kernel Space - 1 GiB
- User Space - 3 GiB
Thus kernel can at most map 1 GiB of physical memory at any one time, but there is further split, because we need virtual address space for temporary maps to access the rest of the physical memory. The split is as follows:
- lower 896 MiB (0xc0000000 to 0xf7ffffff) is directly mapped to the kernel physical address space
- the remaining 128 MiB (0xf8000000 to 0xffffffff) is used on demand by the kernel to map to high memory.
The arrangement is as follows:
physical memory 2 GiB
+------> +------------+
| | 1152 MiB |
| | |
+------------------+ 0xffffffff -----+ | HIGH MEM |
| On Demand 128MiB | | |
+------------------+ 0xf8000000 ------------> +------------+
| | ------+
| Direct mapped | +-----> +------------+
| 896 MiB | --+ | 896 MiB |
+------------------+ 0xc0000000 +---------> +------------+
Thus, the Linux kernel through the highmem interface provides indirect access to this physical memory in range of 2/4/6/8 GiB. But, there is associated cost of creating temporary mappings which can be quite high. The arch has to
manipulate the kernel's page tables, the data TLB and/or the MMU's registers.
On 64-bit Architectures
The 3G/1G split does not apply. Due to the huge address space, a split scheme between user space and kernel space can be chosen that allows to map the whole physical memory into kernel address space. Thus saving all the overheads of temporary mappings that a 32 bit architecture incurs.
The high memory support is optional in case Linux kernel on 64 bit Architectures and is even disabled disabled in cases Linux on 64 bit architectures.
Reference: Linux High Memory Handling.