lkml.org 
[lkml]   [2019]   [Oct]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.2 275/313] i40e: check __I40E_VF_DISABLE bit in i40e_sync_filters_subtask
    Date
    From: Stefan Assmann <sassmann@kpanic.de>

    commit a7542b87607560d0b89e7ff81d870bd6ff8835cb upstream.

    While testing VF spawn/destroy the following panic occurred.

    BUG: unable to handle kernel NULL pointer dereference at 0000000000000029
    [...]
    Workqueue: i40e i40e_service_task [i40e]
    RIP: 0010:i40e_sync_vsi_filters+0x6fd/0xc60 [i40e]
    [...]
    Call Trace:
    ? __switch_to_asm+0x35/0x70
    ? __switch_to_asm+0x41/0x70
    ? __switch_to_asm+0x35/0x70
    ? _cond_resched+0x15/0x30
    i40e_sync_filters_subtask+0x56/0x70 [i40e]
    i40e_service_task+0x382/0x11b0 [i40e]
    ? __switch_to_asm+0x41/0x70
    ? __switch_to_asm+0x41/0x70
    process_one_work+0x1a7/0x3b0
    worker_thread+0x30/0x390
    ? create_worker+0x1a0/0x1a0
    kthread+0x112/0x130
    ? kthread_bind+0x30/0x30
    ret_from_fork+0x35/0x40

    Investigation revealed a race where pf->vf[vsi->vf_id].trusted may get
    accessed by the watchdog via i40e_sync_filters_subtask() although
    i40e_free_vfs() already free'd pf->vf.
    To avoid this the call to i40e_sync_vsi_filters() in
    i40e_sync_filters_subtask() needs to be guarded by __I40E_VF_DISABLE,
    which is also used by i40e_free_vfs().

    Note: put the __I40E_VF_DISABLE check after the
    __I40E_MACVLAN_SYNC_PENDING check as the latter is more likely to
    trigger.

    CC: stable@vger.kernel.org
    Signed-off-by: Stefan Assmann <sassmann@kpanic.de>
    Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
    Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/net/ethernet/intel/i40e/i40e_main.c | 5 +++++
    1 file changed, 5 insertions(+)

    --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
    +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
    @@ -2586,6 +2586,10 @@ static void i40e_sync_filters_subtask(st
    return;
    if (!test_and_clear_bit(__I40E_MACVLAN_SYNC_PENDING, pf->state))
    return;
    + if (test_and_set_bit(__I40E_VF_DISABLE, pf->state)) {
    + set_bit(__I40E_MACVLAN_SYNC_PENDING, pf->state);
    + return;
    + }

    for (v = 0; v < pf->num_alloc_vsi; v++) {
    if (pf->vsi[v] &&
    @@ -2600,6 +2604,7 @@ static void i40e_sync_filters_subtask(st
    }
    }
    }
    + clear_bit(__I40E_VF_DISABLE, pf->state);
    }

    /**

    \
     
     \ /
      Last update: 2019-10-03 18:36    [W:2.313 / U:1.744 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site