• Balbir Singh's avatar
    powerpc/hash64: Be more careful when generating tlbiel · f923efbc
    Balbir Singh authored
    In ISA v2.05, the tlbiel instruction takes two arguments, RB and L:
    
    tlbiel RB,L
    
    +---------+---------+----+---------+---------+---------+----+
    |    31   |    /    | L  |    /    |    RB   |   274   | /  |
    | 31 - 26 | 25 - 22 | 21 | 20 - 16 | 15 - 11 |  10 - 1 | 0  |
    +---------+---------+----+---------+---------+---------+----+
    
    In ISA v2.06 tlbiel takes only one argument, RB:
    
    tlbiel RB
    
    +---------+---------+---------+---------+---------+----+
    |    31   |    /    |    /    |    RB   |   274   | /  |
    | 31 - 26 | 25 - 21 | 20 - 16 | 15 - 11 |  10 - 1 | 0  |
    +---------+---------+---------+---------+---------+----+
    
    And in ISA v3.00 tlbiel takes five arguments:
    
    tlbiel RB,RS,RIC,PRS,R
    
    +---------+---------+----+---------+----+----+---------+---------+----+
    |    31   |    RS   | /  |   RIC   |PRS | R  |    RB   |   274   | /  |
    | 31 - 26 | 25 - 21 | 20 | 19 - 18 | 17 | 16 | 15 - 11 |  10 - 1 | 0  |
    +---------+---------+----+---------+----+----+---------+---------+----+
    
    However the assembler also accepts "tlbiel RB", and generates
    "tlbiel RB,r0,0,0,0".
    
    As you can see above the L field from the v2.05 encoding overlaps with the
    reserved field of the v2.06 encoding, and the low bit of the RS field of the
    v3.00 encoding.
    
    Currently in __tlbiel() we generate two tlbiel instructions manually using hex
    constants. In the first case, for MMU_PAGE_4K, we generate "tlbiel RB,0", which
    is safe in all cases, because the L bit is zero.
    
    However in the default case we generate "tlbiel RB,1", therefore setting bit 21
    to 1.
    
    This is not an actual bug on v2.06 processors, because the CPU ignores the value
    of the reserved field. However software is supposed to encode the reserved
    fields as zero to enable forward compatibility.
    
    On v3.00 processors setting bit 21 to 1 and no other bits of RS, means we are
    using r1 for the value of RS.
    
    Although it's not obvious, the code sets the IS field (bits 10-11) to 0 (by
    omission), and L=1, in the va value, which is passed as RB. We also pass R=0 in
    the instruction.
    
    The combination of IS=0, L=1 and R=0 means the value of RS is not used, so even
    on ISA v3.00 there is no actual bug.
    
    We should still fix it, as setting a reserved bit on v2.06 is naughty, and we
    are only avoiding a bug on v3.00 by accident rather than design. Use
    ASM_FTR_IFSET() to generate the single argument form on ISA v2.06 and later, and
    the two argument form on pre v2.06.
    
    Although there may be very old toolchains which don't understand tlbiel, we have
    other code in the tree which has been using tlbiel for over five years, and no
    one has reported any build failures, so just let the assembler generate the
    instructions.
    Signed-off-by: default avatarBalbir Singh <bsingharora@gmail.com>
    [mpe: Rewrite change log, use IFSET instead of IFCLR]
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    f923efbc
hash_native_64.c 19.1 KB