• Will Deacon's avatar
    Revert "arm64: Remove unnecessary ISBs from set_{pte,pmd,pud}" · d0b7a302
    Will Deacon authored
    This reverts commit 24fe1b0e.
    
    Commit 24fe1b0e ("arm64: Remove unnecessary ISBs from
    set_{pte,pmd,pud}") removed ISB instructions immediately following updates
    to the page table, on the grounds that they are not required by the
    architecture and a DSB alone is sufficient to ensure that subsequent data
    accesses use the new translation:
    
      DDI0487E_a, B2-128:
    
      | ... no instruction that appears in program order after the DSB
      | instruction can alter any state of the system or perform any part of
      | its functionality until the DSB completes other than:
      |
      | * Being fetched from memory and decoded
      | * Reading the general-purpose, SIMD and floating-point,
      |   Special-purpose, or System registers that are directly or indirectly
      |   read without causing side-effects.
    
    However, the same document also states the following:
    
      DDI0487E_a, B2-125:
    
      | DMB and DSB instructions affect reads and writes to the memory system
      | generated by Load/Store instructions and data or unified cache
      | maintenance instructions being executed by the PE. Instruction fetches
      | or accesses caused by a hardware translation table access are not
      | explicit accesses.
    
    which appears to claim that the DSB alone is insufficient.  Unfortunately,
    some CPU designers have followed the second clause above, whereas in Linux
    we've been relying on the first. This means that our mapping sequence:
    
    	MOV	X0, <valid pte>
    	STR	X0, [Xptep]	// Store new PTE to page table
    	DSB	ISHST
    	LDR	X1, [X2]	// Translates using the new PTE
    
    can actually raise a translation fault on the load instruction because the
    translation can be performed speculatively before the page table update and
    then marked as "faulting" by the CPU. For user PTEs, this is ok because we
    can handle the spurious fault, but for kernel PTEs and intermediate table
    entries this results in a panic().
    
    Revert the offending commit to reintroduce the missing barriers.
    
    Cc: <stable@vger.kernel.org>
    Fixes: 24fe1b0e ("arm64: Remove unnecessary ISBs from set_{pte,pmd,pud}")
    Reviewed-by: default avatarMark Rutland <mark.rutland@arm.com>
    Signed-off-by: default avatarWill Deacon <will@kernel.org>
    d0b7a302
pgtable.h 24.8 KB