• Hari Bathini's avatar
    powerpc/book3s64: Fix branching to OOL handlers in relocatable kernel · 8ed8ab40
    Hari Bathini authored
    Some of the interrupt vectors on 64-bit POWER server processors are only
    32 bytes long (8 instructions), which is not enough for the full
    first-level interrupt handler. For these we need to branch to an
    out-of-line (OOL) handler. But when we are running a relocatable kernel,
    interrupt vectors till __end_interrupts marker are copied down to real
    address 0x100. So, branching to labels (ie. OOL handlers) outside this
    section must be handled differently (see LOAD_HANDLER()), considering
    relocatable kernel, which would need at least 4 instructions.
    
    However, branching from interrupt vector means that we corrupt the
    CFAR (come-from address register) on POWER7 and later processors as
    mentioned in commit 1707dd16. So, EXCEPTION_PROLOG_0 (6 instructions)
    that contains the part up to the point where the CFAR is saved in the
    PACA should be part of the short interrupt vectors before we branch out
    to OOL handlers.
    
    But as mentioned already, there are interrupt vectors on 64-bit POWER
    server processors that are only 32 bytes long (like vectors 0x4f00,
    0x4f20, etc.), which cannot accomodate the above two cases at the same
    time owing to space constraint. Currently, in these interrupt vectors,
    we simply branch out to OOL handlers, without using LOAD_HANDLER(),
    which leaves us vulnerable when running a relocatable kernel (eg. kdump
    case). While this has been the case for sometime now and kdump is used
    widely, we were fortunate not to see any problems so far, for three
    reasons:
    
      1. In almost all cases, production kernel (relocatable) is used for
         kdump as well, which would mean that crashed kernel's OOL handler
         would be at the same place where we end up branching to, from short
         interrupt vector of kdump kernel.
      2. Also, OOL handler was unlikely the reason for crash in almost all
         the kdump scenarios, which meant we had a sane OOL handler from
         crashed kernel that we branched to.
      3. On most 64-bit POWER server processors, page size is large enough
         that marking interrupt vector code as executable (see commit
         429d2e83) leads to marking OOL handler code from crashed kernel,
         that sits right below interrupt vector code from kdump kernel, as
         executable as well.
    
    Let us fix this by moving the __end_interrupts marker down past OOL
    handlers to make sure that we also copy OOL handlers to real address
    0x100 when running a relocatable kernel.
    
    This fix has been tested successfully in kdump scenario, on an LPAR with
    4K page size by using different default/production kernel and kdump
    kernel.
    
    Also tested by manually corrupting the OOL handlers in the first kernel
    and then kdump'ing, and then causing the OOL handlers to fire - mpe.
    
    Fixes: c1fb6816 ("powerpc: Add relocation on exception vector handlers")
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarHari Bathini <hbathini@linux.vnet.ibm.com>
    Signed-off-by: default avatarMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    8ed8ab40
exceptions-64s.S 42.6 KB