Skip to content

Commit

Permalink
powerpc: Emulate the dcbz instruction
Browse files Browse the repository at this point in the history
This adds code to analyse_instr() and emulate_step() to understand the
dcbz (data cache block zero) instruction.  The emulate_dcbz() function
is made public so it can be used by the alignment handler in future.
(The apparently unnecessary cropping of the address to 32 bits is
there because it will be needed in that situation.)

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
  • Loading branch information
Paul Mackerras authored and Michael Ellerman committed Sep 1, 2017
1 parent 1f41fb7 commit b2543f7
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
2 changes: 2 additions & 0 deletions arch/powerpc/include/asm/sstep.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ enum instruction_type {
#define DCBTST 0x200
#define DCBT 0x300
#define ICBI 0x400
#define DCBZ 0x500

/* VSX flags values */
#define VSX_FPCONV 1 /* do floating point SP/DP conversion */
Expand Down Expand Up @@ -155,3 +156,4 @@ extern void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,
const void *mem);
extern void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg,
void *mem);
extern int emulate_dcbz(unsigned long ea, struct pt_regs *regs);
32 changes: 32 additions & 0 deletions arch/powerpc/lib/sstep.c
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,30 @@ static nokprobe_inline int do_vsx_store(struct instruction_op *op,
}
#endif /* CONFIG_VSX */

int emulate_dcbz(unsigned long ea, struct pt_regs *regs)
{
int err;
unsigned long i, size;

#ifdef __powerpc64__
size = ppc64_caches.l1d.block_size;
if (!(regs->msr & MSR_64BIT))
ea &= 0xffffffffUL;
#else
size = L1_CACHE_BYTES;
#endif
ea &= ~(size - 1);
if (!address_ok(regs, ea, size))
return -EFAULT;
for (i = 0; i < size; i += sizeof(long)) {
err = __put_user(0, (unsigned long __user *) (ea + i));
if (err)
return err;
}
return 0;
}
NOKPROBE_SYMBOL(emulate_dcbz);

#define __put_user_asmx(x, addr, err, op, cr) \
__asm__ __volatile__( \
"1: " op " %2,0,%3\n" \
Expand Down Expand Up @@ -1748,6 +1772,11 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
op->type = MKOP(CACHEOP, ICBI, 0);
op->ea = xform_ea(instr, regs);
return 0;

case 1014: /* dcbz */
op->type = MKOP(CACHEOP, DCBZ, 0);
op->ea = xform_ea(instr, regs);
return 0;
}
break;
}
Expand Down Expand Up @@ -2607,6 +2636,9 @@ int emulate_step(struct pt_regs *regs, unsigned int instr)
case ICBI:
__cacheop_user_asmx(ea, err, "icbi");
break;
case DCBZ:
err = emulate_dcbz(ea, regs);
break;
}
if (err)
return 0;
Expand Down

0 comments on commit b2543f7

Please sign in to comment.