• Suzuki K Poulose's avatar
    kvm: arm64: Get rid of fake page table levels · da04fa04
    Suzuki K Poulose authored
    On arm64, the hardware supports concatenation of upto 16 tables,
    at entry level for stage2 translations and we make use that whenever
    possible. This could lead to reduced number of translation levels than
    the normal (stage1 table) table. Also, since the IPA(40bit) is smaller
    than the some of the supported VA_BITS (e.g, 48bit), there could be
    different number of levels in stage-1 vs stage-2 tables. To reuse the
    kernel host page table walker for stage2 we have been using a fake
    software page table level, not known to the hardware. But with 16K
    translations, there could be upto 2 fake software levels (with 48bit VA
    and 40bit IPA), which complicates the code. Hence, we want to get rid of
    the hack.
    
    Now that we have explicit accessors for hyp vs stage2 page tables,
    define the stage2 walker helpers accordingly based on the actual
    table used by the hardware.
    
    Once we know the number of translation levels used by the hardware,
    it is merely a job of defining the helpers based on whether a
    particular level is folded or not, looking at the number of levels.
    
    Some facts before we calculate the translation levels:
    
    1) Smallest page size supported by arm64 is 4K.
    2) The minimum number of bits resolved at any page table level
       is (PAGE_SHIFT - 3) at intermediate levels.
    Both of them implies, minimum number of bits required for a level
    change is 9.
    
    Since we can concatenate upto 16 tables at stage2 entry, the total
    number of page table levels used by the hardware for resolving N bits
    is same as that for (N - 4) bits (with concatenation), as there cannot
    be a level in between (N, N-4) as per the above rules.
    
    Hence, we have
    
     STAGE2_PGTABLE_LEVELS = PGTABLE_LEVELS(KVM_PHYS_SHIFT - 4)
    
    With the current IPA limit (40bit), for all supported translations
    and VA_BITS, we have the following condition (even for 36bit VA with
    16K page size):
    
     CONFIG_PGTABLE_LEVELS >= STAGE2_PGTABLE_LEVELS.
    
    So, for e.g,  if PUD is present in stage2, it is present in the hyp(host).
    Hence, we fall back to the host definition if we find that a level is not
    folded. Otherwise we redefine it accordingly. A build time check is added
    to make sure the above condition holds. If this condition breaks in future,
    we can rearrange the host level helpers and fix our code easily.
    
    Cc: Marc Zyngier <marc.zyngier@arm.com>
    Cc: Christoffer Dall <christoffer.dall@linaro.org>
    Reviewed-by: default avatarChristoffer Dall <christoffer.dall@linaro.org>
    Signed-off-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
    da04fa04
stage2_pgtable-nopud.h 1.24 KB