|
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 |
|