• Ard Biesheuvel's avatar
    drivers/char: kmem: disable on arm64 · 06c35ef1
    Ard Biesheuvel authored
    As it turns out, arm64 deviates from other architectures in the way it
    maps the VMALLOC region: on most (all?) other architectures, it resides
    strictly above the kernel's direct mapping of DRAM, but on arm64, this
    is the other way around. For instance, for a 48-bit VA configuration,
    we have
    
      modules : 0xffff000000000000 - 0xffff000008000000   (   128 MB)
      vmalloc : 0xffff000008000000 - 0xffff7dffbfff0000   (129022 GB)
      ...
      vmemmap : 0xffff7e0000000000 - 0xffff800000000000   (  2048 GB maximum)
                0xffff7e0000000000 - 0xffff7e0003ff0000   (    63 MB actual)
      memory  : 0xffff800000000000 - 0xffff8000ffc00000   (  4092 MB)
    
    This has mostly gone unnoticed until now, but it does appear that it
    breaks an assumption in the kmem read/write code, which does something
    like
    
      if (p < (unsigned long) high_memory) {
        ... use straight copy_[to|from]_user() using p as virtual address ...
      }
      ...
      if (count > 0) {
        ... use vread/vwrite for accesses past high_memory ...
      }
    
    The first condition will inadvertently hold for the VMALLOC region if
    VMALLOC_START < PAGE_OFFSET [which is the case on arm64], but the read
    or write will subsequently fail the virt_addr_valid() check, resulting
    in a -ENXIO return value.
    
    Given how kmem seems to be living in borrowed time anyway, and given
    the fact that nobody noticed that the read/write interface is broken
    on arm64 in the first place, let's not bother trying to fix it, but
    simply disable the /dev/kmem interface entirely for arm64.
    Acked-by: default avatarMark Rutland <mark.rutland@arm.com>
    Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
    Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
    06c35ef1
Kconfig 20.3 KB