]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
powerpc/pseries/eeh: Fix get PE state translation
authorNarayana Murty N <nnmlinux@linux.ibm.com>
Thu, 16 Jan 2025 10:39:54 +0000 (04:39 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 21 Feb 2025 12:49:44 +0000 (13:49 +0100)
commit 11b93559000c686ad7e5ab0547e76f21cc143844 upstream.

The PE Reset State "0" returned by RTAS calls
"ibm_read_slot_reset_[state|state2]" indicates that the reset is
deactivated and the PE is in a state where MMIO and DMA are allowed.
However, the current implementation of "pseries_eeh_get_state()" does
not reflect this, causing drivers to incorrectly assume that MMIO and
DMA operations cannot be resumed.

The userspace drivers as a part of EEH recovery using VFIO ioctls fail
to detect when the recovery process is complete. The VFIO_EEH_PE_GET_STATE
ioctl does not report the expected EEH_PE_STATE_NORMAL state, preventing
userspace drivers from functioning properly on pseries systems.

The patch addresses this issue by updating 'pseries_eeh_get_state()'
to include "EEH_STATE_MMIO_ENABLED" and "EEH_STATE_DMA_ENABLED" in
the result mask for PE Reset State "0". This ensures correct state
reporting to the callers, aligning the behavior with the PAPR specification
and fixing the bug in EEH recovery for VFIO user workflows.

Fixes: 00ba05a12b3c ("powerpc/pseries: Cleanup on pseries_eeh_get_state()")
Cc: stable@vger.kernel.org
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Signed-off-by: Narayana Murty N <nnmlinux@linux.ibm.com>
Link: https://lore.kernel.org/stable/20241212075044.10563-1-nnmlinux%40linux.ibm.com
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20250116103954.17324-1-nnmlinux@linux.ibm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/powerpc/platforms/pseries/eeh_pseries.c

index e5a58a9b2fe9fb20c9057bcb5d4c1607f45a777b..ce6759e082a7562cb2cfdd3ec4cf4093094eeafc 100644 (file)
@@ -580,8 +580,10 @@ static int pseries_eeh_get_state(struct eeh_pe *pe, int *delay)
 
        switch(rets[0]) {
        case 0:
-               result = EEH_STATE_MMIO_ACTIVE |
-                        EEH_STATE_DMA_ACTIVE;
+               result = EEH_STATE_MMIO_ACTIVE  |
+                        EEH_STATE_DMA_ACTIVE   |
+                        EEH_STATE_MMIO_ENABLED |
+                        EEH_STATE_DMA_ENABLED;
                break;
        case 1:
                result = EEH_STATE_RESET_ACTIVE |