Michal Suchanek 9c1ced
From bbda4b6c7d7c7f79da71f95c92a5d76be22c3efd Mon Sep 17 00:00:00 2001
Michal Suchanek 9c1ced
From: Sandipan Das <sandipan@linux.ibm.com>
Michal Suchanek 9c1ced
Date: Thu, 4 Feb 2021 13:37:43 +0530
Michal Suchanek 9c1ced
Subject: [PATCH] powerpc/sstep: Fix load-store and update emulation
Michal Suchanek 9c1ced
Michal Suchanek 9c1ced
References: bsc#1156395
Michal Suchanek 9c1ced
Patch-mainline: v5.12-rc1
Michal Suchanek 9c1ced
Git-commit: bbda4b6c7d7c7f79da71f95c92a5d76be22c3efd
Michal Suchanek 9c1ced
Michal Suchanek 9c1ced
The Power ISA says that the fixed-point load and update instructions
Michal Suchanek 9c1ced
must neither use R0 for the base address (RA) nor have the
Michal Suchanek 9c1ced
destination (RT) and the base address (RA) as the same register.
Michal Suchanek 9c1ced
Similarly, for fixed-point stores and floating-point loads and stores,
Michal Suchanek 9c1ced
the instruction is invalid when R0 is used as the base address (RA).
Michal Suchanek 9c1ced
Michal Suchanek 9c1ced
This is applicable to the following instructions.
Michal Suchanek 9c1ced
  * Load Byte and Zero with Update (lbzu)
Michal Suchanek 9c1ced
  * Load Byte and Zero with Update Indexed (lbzux)
Michal Suchanek 9c1ced
  * Load Halfword and Zero with Update (lhzu)
Michal Suchanek 9c1ced
  * Load Halfword and Zero with Update Indexed (lhzux)
Michal Suchanek 9c1ced
  * Load Halfword Algebraic with Update (lhau)
Michal Suchanek 9c1ced
  * Load Halfword Algebraic with Update Indexed (lhaux)
Michal Suchanek 9c1ced
  * Load Word and Zero with Update (lwzu)
Michal Suchanek 9c1ced
  * Load Word and Zero with Update Indexed (lwzux)
Michal Suchanek 9c1ced
  * Load Word Algebraic with Update Indexed (lwaux)
Michal Suchanek 9c1ced
  * Load Doubleword with Update (ldu)
Michal Suchanek 9c1ced
  * Load Doubleword with Update Indexed (ldux)
Michal Suchanek 9c1ced
  * Load Floating Single with Update (lfsu)
Michal Suchanek 9c1ced
  * Load Floating Single with Update Indexed (lfsux)
Michal Suchanek 9c1ced
  * Load Floating Double with Update (lfdu)
Michal Suchanek 9c1ced
  * Load Floating Double with Update Indexed (lfdux)
Michal Suchanek 9c1ced
  * Store Byte with Update (stbu)
Michal Suchanek 9c1ced
  * Store Byte with Update Indexed (stbux)
Michal Suchanek 9c1ced
  * Store Halfword with Update (sthu)
Michal Suchanek 9c1ced
  * Store Halfword with Update Indexed (sthux)
Michal Suchanek 9c1ced
  * Store Word with Update (stwu)
Michal Suchanek 9c1ced
  * Store Word with Update Indexed (stwux)
Michal Suchanek 9c1ced
  * Store Doubleword with Update (stdu)
Michal Suchanek 9c1ced
  * Store Doubleword with Update Indexed (stdux)
Michal Suchanek 9c1ced
  * Store Floating Single with Update (stfsu)
Michal Suchanek 9c1ced
  * Store Floating Single with Update Indexed (stfsux)
Michal Suchanek 9c1ced
  * Store Floating Double with Update (stfdu)
Michal Suchanek 9c1ced
  * Store Floating Double with Update Indexed (stfdux)
Michal Suchanek 9c1ced
Michal Suchanek 9c1ced
E.g. the following behaviour is observed for an invalid load and
Michal Suchanek 9c1ced
update instruction having RA = RT.
Michal Suchanek 9c1ced
Michal Suchanek 9c1ced
While a userspace program having an instruction word like 0xe9ce0001,
Michal Suchanek 9c1ced
i.e. ldu r14, 0(r14), runs without getting receiving a SIGILL on a
Michal Suchanek 9c1ced
Power system (observed on P8 and P9), the outcome of executing that
Michal Suchanek 9c1ced
instruction word varies and its behaviour can be considered to be
Michal Suchanek 9c1ced
undefined.
Michal Suchanek 9c1ced
Michal Suchanek 9c1ced
Attaching an uprobe at that instruction's address results in emulation
Michal Suchanek 9c1ced
which currently performs the load as well as writes the effective
Michal Suchanek 9c1ced
address back to the base register. This might not match the outcome
Michal Suchanek 9c1ced
from hardware.
Michal Suchanek 9c1ced
Michal Suchanek 9c1ced
To remove any inconsistencies, this adds additional checks for the
Michal Suchanek 9c1ced
aforementioned instructions to make sure that the emulation
Michal Suchanek 9c1ced
infrastructure treats them as unknown. The kernel can then fallback to
Michal Suchanek 9c1ced
executing such instructions on hardware.
Michal Suchanek 9c1ced
Michal Suchanek 9c1ced
Fixes: 0016a4cf5582 ("powerpc: Emulate most Book I instructions in emulate_step()")
Michal Suchanek 9c1ced
Signed-off-by: Sandipan Das <sandipan@linux.ibm.com>
Michal Suchanek 9c1ced
Reviewed-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Michal Suchanek 9c1ced
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Michal Suchanek 9c1ced
Link: https://lore.kernel.org/r/20210204080744.135785-1-sandipan@linux.ibm.com
Michal Suchanek 9c1ced
Acked-by: Michal Suchanek <msuchanek@suse.de>
Michal Suchanek 9c1ced
---
Michal Suchanek 9c1ced
 arch/powerpc/lib/sstep.c | 14 ++++++++++++++
Michal Suchanek 9c1ced
 1 file changed, 14 insertions(+)
Michal Suchanek 9c1ced
Michal Suchanek 9c1ced
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
Michal Suchanek 9c1ced
index e96cff845ef7..11f14b209d7f 100644
Michal Suchanek 9c1ced
--- a/arch/powerpc/lib/sstep.c
Michal Suchanek 9c1ced
+++ b/arch/powerpc/lib/sstep.c
Michal Suchanek 9c1ced
@@ -3017,6 +3017,20 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
Michal Suchanek 9c1ced
 
Michal Suchanek 9c1ced
 	}
Michal Suchanek 9c1ced
 
Michal Suchanek 9c1ced
+	if (OP_IS_LOAD_STORE(op->type) && (op->type & UPDATE)) {
Michal Suchanek 9c1ced
+		switch (GETTYPE(op->type)) {
Michal Suchanek 9c1ced
+		case LOAD:
Michal Suchanek 9c1ced
+			if (ra == rd)
Michal Suchanek 9c1ced
+				goto unknown_opcode;
Michal Suchanek 9c1ced
+			fallthrough;
Michal Suchanek 9c1ced
+		case STORE:
Michal Suchanek 9c1ced
+		case LOAD_FP:
Michal Suchanek 9c1ced
+		case STORE_FP:
Michal Suchanek 9c1ced
+			if (ra == 0)
Michal Suchanek 9c1ced
+				goto unknown_opcode;
Michal Suchanek 9c1ced
+		}
Michal Suchanek 9c1ced
+	}
Michal Suchanek 9c1ced
+
Michal Suchanek 9c1ced
 #ifdef CONFIG_VSX
Michal Suchanek 9c1ced
 	if ((GETTYPE(op->type) == LOAD_VSX ||
Michal Suchanek 9c1ced
 	     GETTYPE(op->type) == STORE_VSX) &&
Michal Suchanek 9c1ced
-- 
Michal Suchanek 9c1ced
2.26.2
Michal Suchanek 9c1ced