Patch "sparc64: Fix opcode filtering in handling of no fault loads" has been added to the 5.11-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    sparc64: Fix opcode filtering in handling of no fault loads

to the 5.11-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     sparc64-fix-opcode-filtering-in-handling-of-no-fault.patch
and it can be found in the queue-5.11 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit dd108e3cd5ed813519680e23268db704816b1a90
Author: Rob Gardner <rob.gardner@xxxxxxxxxx>
Date:   Sun Feb 28 22:48:16 2021 -0700

    sparc64: Fix opcode filtering in handling of no fault loads
    
    [ Upstream commit e5e8b80d352ec999d2bba3ea584f541c83f4ca3f ]
    
    is_no_fault_exception() has two bugs which were discovered via random
    opcode testing with stress-ng. Both are caused by improper filtering
    of opcodes.
    
    The first bug can be triggered by a floating point store with a no-fault
    ASI, for instance "sta %f0, [%g0] #ASI_PNF", opcode C1A01040.
    
    The code first tests op3[5] (0x1000000), which denotes a floating
    point instruction, and then tests op3[2] (0x200000), which denotes a
    store instruction. But these bits are not mutually exclusive, and the
    above mentioned opcode has both bits set. The intent is to filter out
    stores, so the test for stores must be done first in order to have
    any effect.
    
    The second bug can be triggered by a floating point load with one of
    the invalid ASI values 0x8e or 0x8f, which pass this check in
    is_no_fault_exception():
         if ((asi & 0xf2) == ASI_PNF)
    
    An example instruction is "ldqa [%l7 + %o7] #ASI 0x8f, %f38",
    opcode CF95D1EF. Asi values greater than 0x8b (ASI_SNFL) are fatal
    in handle_ldf_stq(), and is_no_fault_exception() must not allow these
    invalid asi values to make it that far.
    
    In both of these cases, handle_ldf_stq() reacts by calling
    sun4v_data_access_exception() or spitfire_data_access_exception(),
    which call is_no_fault_exception() and results in an infinite
    recursion.
    
    Signed-off-by: Rob Gardner <rob.gardner@xxxxxxxxxx>
    Tested-by: Anatoly Pugachev <matorola@xxxxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index d92e5eaa4c1d..a850dccd78ea 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -275,14 +275,13 @@ bool is_no_fault_exception(struct pt_regs *regs)
 			asi = (regs->tstate >> 24); /* saved %asi       */
 		else
 			asi = (insn >> 5);	    /* immediate asi    */
-		if ((asi & 0xf2) == ASI_PNF) {
-			if (insn & 0x1000000) {     /* op3[5:4]=3       */
-				handle_ldf_stq(insn, regs);
-				return true;
-			} else if (insn & 0x200000) { /* op3[2], stores */
+		if ((asi & 0xf6) == ASI_PNF) {
+			if (insn & 0x200000)        /* op3[2], stores   */
 				return false;
-			}
-			handle_ld_nf(insn, regs);
+			if (insn & 0x1000000)       /* op3[5:4]=3 (fp)  */
+				handle_ldf_stq(insn, regs);
+			else
+				handle_ld_nf(insn, regs);
 			return true;
 		}
 	}



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux