lkml.org 
[lkml]   [2018]   [Aug]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 019/124] powerpc/64s: Fix compiler store ordering to SLB shadow area
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Nicholas Piggin <npiggin@gmail.com>

    [ Upstream commit 926bc2f100c24d4842b3064b5af44ae964c1d81c ]

    The stores to update the SLB shadow area must be made as they appear
    in the C code, so that the hypervisor does not see an entry with
    mismatched vsid and esid. Use WRITE_ONCE for this.

    GCC has been observed to elide the first store to esid in the update,
    which means that if the hypervisor interrupts the guest after storing
    to vsid, it could see an entry with old esid and new vsid, which may
    possibly result in memory corruption.

    Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
    Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    arch/powerpc/mm/slb.c | 8 ++++----
    1 file changed, 4 insertions(+), 4 deletions(-)

    --- a/arch/powerpc/mm/slb.c
    +++ b/arch/powerpc/mm/slb.c
    @@ -69,14 +69,14 @@ static inline void slb_shadow_update(uns
    * updating it. No write barriers are needed here, provided
    * we only update the current CPU's SLB shadow buffer.
    */
    - p->save_area[index].esid = 0;
    - p->save_area[index].vsid = cpu_to_be64(mk_vsid_data(ea, ssize, flags));
    - p->save_area[index].esid = cpu_to_be64(mk_esid_data(ea, ssize, index));
    + WRITE_ONCE(p->save_area[index].esid, 0);
    + WRITE_ONCE(p->save_area[index].vsid, cpu_to_be64(mk_vsid_data(ea, ssize, flags)));
    + WRITE_ONCE(p->save_area[index].esid, cpu_to_be64(mk_esid_data(ea, ssize, index)));
    }

    static inline void slb_shadow_clear(enum slb_index index)
    {
    - get_slb_shadow()->save_area[index].esid = 0;
    + WRITE_ONCE(get_slb_shadow()->save_area[index].esid, 0);
    }

    static inline void create_shadowed_slbe(unsigned long ea, int ssize,

    \
     
     \ /
      Last update: 2018-08-04 11:18    [W:3.601 / U:0.096 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site