We currently unconditionally try to emulate newer instructions on older
Power versions that could cause issues. Gate it.

Signed-off-by: Ananth N Mavinakayanahalli <ana...@linux.ibm.com>
---
 arch/powerpc/lib/sstep.c |   40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index bf7a7d62ae8b..ed119858e5e9 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1528,6 +1528,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                goto compute_done;
 
        case 19:
+               if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                       return -1;
                if (((word >> 1) & 0x1f) == 2) {
                        /* addpcis */
                        imm = (short) (word & 0xffc1);  /* d0 + d2 fields */
@@ -2439,6 +2441,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                        break;
 
                case 268:       /* lxvx */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->reg = rd | ((word & 1) << 5);
                        op->type = MKOP(LOAD_VSX, 0, 16);
                        op->element_size = 16;
@@ -2448,6 +2452,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                case 269:       /* lxvl */
                case 301: {     /* lxvll */
                        int nb;
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->reg = rd | ((word & 1) << 5);
                        op->ea = ra ? regs->gpr[ra] : 0;
                        nb = regs->gpr[rb] & 0xff;
@@ -2475,6 +2481,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                        break;
 
                case 364:       /* lxvwsx */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->reg = rd | ((word & 1) << 5);
                        op->type = MKOP(LOAD_VSX, 0, 4);
                        op->element_size = 4;
@@ -2482,6 +2490,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                        break;
 
                case 396:       /* stxvx */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->reg = rd | ((word & 1) << 5);
                        op->type = MKOP(STORE_VSX, 0, 16);
                        op->element_size = 16;
@@ -2491,6 +2501,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                case 397:       /* stxvl */
                case 429: {     /* stxvll */
                        int nb;
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->reg = rd | ((word & 1) << 5);
                        op->ea = ra ? regs->gpr[ra] : 0;
                        nb = regs->gpr[rb] & 0xff;
@@ -2542,6 +2554,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                        break;
 
                case 781:       /* lxsibzx */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->reg = rd | ((word & 1) << 5);
                        op->type = MKOP(LOAD_VSX, 0, 1);
                        op->element_size = 8;
@@ -2549,6 +2563,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                        break;
 
                case 812:       /* lxvh8x */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->reg = rd | ((word & 1) << 5);
                        op->type = MKOP(LOAD_VSX, 0, 16);
                        op->element_size = 2;
@@ -2556,6 +2572,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                        break;
 
                case 813:       /* lxsihzx */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->reg = rd | ((word & 1) << 5);
                        op->type = MKOP(LOAD_VSX, 0, 2);
                        op->element_size = 8;
@@ -2569,6 +2587,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                        break;
 
                case 876:       /* lxvb16x */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->reg = rd | ((word & 1) << 5);
                        op->type = MKOP(LOAD_VSX, 0, 16);
                        op->element_size = 1;
@@ -2582,6 +2602,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                        break;
 
                case 909:       /* stxsibx */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->reg = rd | ((word & 1) << 5);
                        op->type = MKOP(STORE_VSX, 0, 1);
                        op->element_size = 8;
@@ -2589,6 +2611,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                        break;
 
                case 940:       /* stxvh8x */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->reg = rd | ((word & 1) << 5);
                        op->type = MKOP(STORE_VSX, 0, 16);
                        op->element_size = 2;
@@ -2596,6 +2620,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                        break;
 
                case 941:       /* stxsihx */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->reg = rd | ((word & 1) << 5);
                        op->type = MKOP(STORE_VSX, 0, 2);
                        op->element_size = 8;
@@ -2609,6 +2635,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                        break;
 
                case 1004:      /* stxvb16x */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->reg = rd | ((word & 1) << 5);
                        op->type = MKOP(STORE_VSX, 0, 16);
                        op->element_size = 1;
@@ -2717,12 +2745,16 @@ int analyse_instr(struct instruction_op *op, const 
struct pt_regs *regs,
                        op->type = MKOP(LOAD_FP, 0, 16);
                        break;
                case 2:         /* lxsd */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->reg = rd + 32;
                        op->type = MKOP(LOAD_VSX, 0, 8);
                        op->element_size = 8;
                        op->vsx_flags = VSX_CHECK_VEC;
                        break;
                case 3:         /* lxssp */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->reg = rd + 32;
                        op->type = MKOP(LOAD_VSX, 0, 4);
                        op->element_size = 8;
@@ -2775,6 +2807,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                        break;
 
                case 1:         /* lxv */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->ea = dqform_ea(word, regs);
                        if (word & 8)
                                op->reg = rd + 32;
@@ -2785,6 +2819,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
 
                case 2:         /* stxsd with LSB of DS field = 0 */
                case 6:         /* stxsd with LSB of DS field = 1 */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->ea = dsform_ea(word, regs);
                        op->reg = rd + 32;
                        op->type = MKOP(STORE_VSX, 0, 8);
@@ -2794,6 +2830,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
 
                case 3:         /* stxssp with LSB of DS field = 0 */
                case 7:         /* stxssp with LSB of DS field = 1 */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->ea = dsform_ea(word, regs);
                        op->reg = rd + 32;
                        op->type = MKOP(STORE_VSX, 0, 4);
@@ -2802,6 +2840,8 @@ int analyse_instr(struct instruction_op *op, const struct 
pt_regs *regs,
                        break;
 
                case 5:         /* stxv */
+                       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+                               return -1;
                        op->ea = dqform_ea(word, regs);
                        if (word & 8)
                                op->reg = rd + 32;


Reply via email to