Commit 94afd069 authored by Jordan Niethe's avatar Jordan Niethe Committed by Michael Ellerman

powerpc: Use a datatype for instructions

Currently unsigned ints are used to represent instructions on powerpc.
This has worked well as instructions have always been 4 byte words.

However, ISA v3.1 introduces some changes to instructions that mean
this scheme will no longer work as well. This change is Prefixed
Instructions. A prefixed instruction is made up of a word prefix
followed by a word suffix to make an 8 byte double word instruction.
No matter the endianness of the system the prefix always comes first.
Prefixed instructions are only planned for powerpc64.

Introduce a ppc_inst type to represent both prefixed and word
instructions on powerpc64 while keeping it possible to exclusively
have word instructions on powerpc32.
Signed-off-by: default avatarJordan Niethe <jniethe5@gmail.com>
[mpe: Fix compile error in emulate_spe()]
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200506034050.24806-12-jniethe5@gmail.com
parent 217862d9
...@@ -23,33 +23,33 @@ ...@@ -23,33 +23,33 @@
#define BRANCH_ABSOLUTE 0x2 #define BRANCH_ABSOLUTE 0x2
bool is_offset_in_branch_range(long offset); bool is_offset_in_branch_range(long offset);
int create_branch(unsigned int *instr, const unsigned int *addr, int create_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
unsigned long target, int flags); unsigned long target, int flags);
int create_cond_branch(unsigned int *instr, const unsigned int *addr, int create_cond_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
unsigned long target, int flags); unsigned long target, int flags);
int patch_branch(unsigned int *addr, unsigned long target, int flags); int patch_branch(struct ppc_inst *addr, unsigned long target, int flags);
int patch_instruction(unsigned int *addr, unsigned int instr); int patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
int raw_patch_instruction(unsigned int *addr, unsigned int instr); int raw_patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
static inline unsigned long patch_site_addr(s32 *site) static inline unsigned long patch_site_addr(s32 *site)
{ {
return (unsigned long)site + *site; return (unsigned long)site + *site;
} }
static inline int patch_instruction_site(s32 *site, unsigned int instr) static inline int patch_instruction_site(s32 *site, struct ppc_inst instr)
{ {
return patch_instruction((unsigned int *)patch_site_addr(site), instr); return patch_instruction((struct ppc_inst *)patch_site_addr(site), instr);
} }
static inline int patch_branch_site(s32 *site, unsigned long target, int flags) static inline int patch_branch_site(s32 *site, unsigned long target, int flags)
{ {
return patch_branch((unsigned int *)patch_site_addr(site), target, flags); return patch_branch((struct ppc_inst *)patch_site_addr(site), target, flags);
} }
static inline int modify_instruction(unsigned int *addr, unsigned int clr, static inline int modify_instruction(unsigned int *addr, unsigned int clr,
unsigned int set) unsigned int set)
{ {
return patch_instruction(addr, ppc_inst((*addr & ~clr) | set)); return patch_instruction((struct ppc_inst *)addr, ppc_inst((*addr & ~clr) | set));
} }
static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned int set) static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned int set)
...@@ -57,13 +57,13 @@ static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned ...@@ -57,13 +57,13 @@ static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned
return modify_instruction((unsigned int *)patch_site_addr(site), clr, set); return modify_instruction((unsigned int *)patch_site_addr(site), clr, set);
} }
int instr_is_relative_branch(unsigned int instr); int instr_is_relative_branch(struct ppc_inst instr);
int instr_is_relative_link_branch(unsigned int instr); int instr_is_relative_link_branch(struct ppc_inst instr);
int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr); int instr_is_branch_to_addr(const struct ppc_inst *instr, unsigned long addr);
unsigned long branch_target(const unsigned int *instr); unsigned long branch_target(const struct ppc_inst *instr);
int translate_branch(unsigned int *instr, const unsigned int *dest, int translate_branch(struct ppc_inst *instr, const struct ppc_inst *dest,
const unsigned int *src); const struct ppc_inst *src);
extern bool is_conditional_branch(unsigned int instr); extern bool is_conditional_branch(struct ppc_inst instr);
#ifdef CONFIG_PPC_BOOK3E_64 #ifdef CONFIG_PPC_BOOK3E_64
void __patch_exception(int exc, unsigned long addr); void __patch_exception(int exc, unsigned long addr);
#define patch_exception(exc, name) do { \ #define patch_exception(exc, name) do { \
......
...@@ -6,26 +6,30 @@ ...@@ -6,26 +6,30 @@
* Instruction data type for POWER * Instruction data type for POWER
*/ */
#define ppc_inst(x) (x) struct ppc_inst {
u32 val;
} __packed;
static inline u32 ppc_inst_val(u32 x) #define ppc_inst(x) ((struct ppc_inst){ .val = x })
static inline u32 ppc_inst_val(struct ppc_inst x)
{ {
return x; return x.val;
} }
static inline int ppc_inst_primary_opcode(u32 x) static inline int ppc_inst_primary_opcode(struct ppc_inst x)
{ {
return ppc_inst_val(x) >> 26; return ppc_inst_val(x) >> 26;
} }
static inline u32 ppc_inst_swab(u32 x) static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
{ {
return ppc_inst(swab32(ppc_inst_val(x))); return ppc_inst(swab32(ppc_inst_val(x)));
} }
static inline bool ppc_inst_equal(u32 x, u32 y) static inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y)
{ {
return x == y; return ppc_inst_val(x) == ppc_inst_val(y);
} }
#endif /* _ASM_POWERPC_INST_H */ #endif /* _ASM_POWERPC_INST_H */
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
/* /*
* Copyright (C) 2004 Paul Mackerras <paulus@au.ibm.com>, IBM * Copyright (C) 2004 Paul Mackerras <paulus@au.ibm.com>, IBM
*/ */
#include <asm/inst.h>
struct pt_regs; struct pt_regs;
...@@ -132,7 +133,7 @@ union vsx_reg { ...@@ -132,7 +133,7 @@ union vsx_reg {
* otherwise. * otherwise.
*/ */
extern int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, extern int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
unsigned int instr); struct ppc_inst instr);
/* /*
* Emulate an instruction that can be executed just by updating * Emulate an instruction that can be executed just by updating
...@@ -149,7 +150,7 @@ void emulate_update_regs(struct pt_regs *reg, struct instruction_op *op); ...@@ -149,7 +150,7 @@ void emulate_update_regs(struct pt_regs *reg, struct instruction_op *op);
* 0 if it could not be emulated, or -1 for an instruction that * 0 if it could not be emulated, or -1 for an instruction that
* should not be emulated (rfid, mtmsrd clearing MSR_RI, etc.). * should not be emulated (rfid, mtmsrd clearing MSR_RI, etc.).
*/ */
extern int emulate_step(struct pt_regs *regs, unsigned int instr); extern int emulate_step(struct pt_regs *regs, struct ppc_inst instr);
/* /*
* Emulate a load or store instruction by reading/writing the * Emulate a load or store instruction by reading/writing the
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/notifier.h> #include <linux/notifier.h>
#include <asm/probes.h> #include <asm/probes.h>
#include <asm/inst.h>
typedef ppc_opcode_t uprobe_opcode_t; typedef ppc_opcode_t uprobe_opcode_t;
...@@ -23,8 +24,8 @@ typedef ppc_opcode_t uprobe_opcode_t; ...@@ -23,8 +24,8 @@ typedef ppc_opcode_t uprobe_opcode_t;
struct arch_uprobe { struct arch_uprobe {
union { union {
u32 insn; struct ppc_inst insn;
u32 ixol; struct ppc_inst ixol;
}; };
}; };
......
...@@ -105,7 +105,7 @@ static struct aligninfo spe_aligninfo[32] = { ...@@ -105,7 +105,7 @@ static struct aligninfo spe_aligninfo[32] = {
* so we don't need the address swizzling. * so we don't need the address swizzling.
*/ */
static int emulate_spe(struct pt_regs *regs, unsigned int reg, static int emulate_spe(struct pt_regs *regs, unsigned int reg,
unsigned int instr) struct ppc_inst ppc_instr)
{ {
int ret; int ret;
union { union {
...@@ -116,8 +116,9 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg, ...@@ -116,8 +116,9 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg,
} data, temp; } data, temp;
unsigned char __user *p, *addr; unsigned char __user *p, *addr;
unsigned long *evr = &current->thread.evr[reg]; unsigned long *evr = &current->thread.evr[reg];
unsigned int nb, flags; unsigned int nb, flags, instr;
instr = ppc_inst_val(ppc_instr);
instr = (instr >> 1) & 0x1f; instr = (instr >> 1) & 0x1f;
/* DAR has the operand effective address */ /* DAR has the operand effective address */
...@@ -294,7 +295,7 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg, ...@@ -294,7 +295,7 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg,
int fix_alignment(struct pt_regs *regs) int fix_alignment(struct pt_regs *regs)
{ {
unsigned int instr; struct ppc_inst instr;
struct instruction_op op; struct instruction_op op;
int r, type; int r, type;
...@@ -304,7 +305,7 @@ int fix_alignment(struct pt_regs *regs) ...@@ -304,7 +305,7 @@ int fix_alignment(struct pt_regs *regs)
*/ */
CHECK_FULL_REGS(regs); CHECK_FULL_REGS(regs);
if (unlikely(__get_user(instr, (unsigned int __user *)regs->nip))) if (unlikely(__get_user(instr.val, (unsigned int __user *)regs->nip)))
return -EFAULT; return -EFAULT;
if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) { if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) {
/* We don't handle PPC little-endian any more... */ /* We don't handle PPC little-endian any more... */
......
...@@ -35,7 +35,7 @@ void __init reserve_kdump_trampoline(void) ...@@ -35,7 +35,7 @@ void __init reserve_kdump_trampoline(void)
static void __init create_trampoline(unsigned long addr) static void __init create_trampoline(unsigned long addr)
{ {
unsigned int *p = (unsigned int *)addr; struct ppc_inst *p = (struct ppc_inst *)addr;
/* The maximum range of a single instruction branch, is the current /* The maximum range of a single instruction branch, is the current
* instruction's address + (32 MB - 4) bytes. For the trampoline we * instruction's address + (32 MB - 4) bytes. For the trampoline we
......
...@@ -37,10 +37,10 @@ static int __init early_init_dt_scan_epapr(unsigned long node, ...@@ -37,10 +37,10 @@ static int __init early_init_dt_scan_epapr(unsigned long node,
return -1; return -1;
for (i = 0; i < (len / 4); i++) { for (i = 0; i < (len / 4); i++) {
u32 inst = ppc_inst(be32_to_cpu(insts[i])); struct ppc_inst inst = ppc_inst(be32_to_cpu(insts[i]));
patch_instruction(epapr_hypercall_start + i, inst); patch_instruction((struct ppc_inst *)(epapr_hypercall_start + i), inst);
#if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64) #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64)
patch_instruction(epapr_ev_idle_start + i, inst); patch_instruction((struct ppc_inst *)(epapr_ev_idle_start + i), inst);
#endif #endif
} }
......
...@@ -244,12 +244,12 @@ dar_range_overlaps(unsigned long dar, int size, struct arch_hw_breakpoint *info) ...@@ -244,12 +244,12 @@ dar_range_overlaps(unsigned long dar, int size, struct arch_hw_breakpoint *info)
static bool stepping_handler(struct pt_regs *regs, struct perf_event *bp, static bool stepping_handler(struct pt_regs *regs, struct perf_event *bp,
struct arch_hw_breakpoint *info) struct arch_hw_breakpoint *info)
{ {
unsigned int instr = ppc_inst(0); struct ppc_inst instr = ppc_inst(0);
int ret, type, size; int ret, type, size;
struct instruction_op op; struct instruction_op op;
unsigned long addr = info->address; unsigned long addr = info->address;
if (__get_user_inatomic(instr, (unsigned int *)regs->nip)) if (__get_user_inatomic(instr.val, (unsigned int *)regs->nip))
goto fail; goto fail;
ret = analyse_instr(&op, regs, instr); ret = analyse_instr(&op, regs, instr);
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
void arch_jump_label_transform(struct jump_entry *entry, void arch_jump_label_transform(struct jump_entry *entry,
enum jump_label_type type) enum jump_label_type type)
{ {
u32 *addr = (u32 *)(unsigned long)entry->code; struct ppc_inst *addr = (struct ppc_inst *)(unsigned long)entry->code;
if (type == JUMP_LABEL_JMP) if (type == JUMP_LABEL_JMP)
patch_branch(addr, entry->target, 0); patch_branch(addr, entry->target, 0);
......
...@@ -419,7 +419,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) ...@@ -419,7 +419,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
{ {
int err; int err;
unsigned int instr; unsigned int instr;
unsigned int *addr = (unsigned int *)bpt->bpt_addr; struct ppc_inst *addr = (struct ppc_inst *)bpt->bpt_addr;
err = probe_kernel_address(addr, instr); err = probe_kernel_address(addr, instr);
if (err) if (err)
...@@ -438,7 +438,7 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) ...@@ -438,7 +438,7 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
{ {
int err; int err;
unsigned int instr = *(unsigned int *)bpt->saved_instr; unsigned int instr = *(unsigned int *)bpt->saved_instr;
unsigned int *addr = (unsigned int *)bpt->bpt_addr; struct ppc_inst *addr = (struct ppc_inst *)bpt->bpt_addr;
err = patch_instruction(addr, ppc_inst(instr)); err = patch_instruction(addr, ppc_inst(instr));
if (err) if (err)
......
...@@ -106,7 +106,7 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset) ...@@ -106,7 +106,7 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset)
int arch_prepare_kprobe(struct kprobe *p) int arch_prepare_kprobe(struct kprobe *p)
{ {
int ret = 0; int ret = 0;
kprobe_opcode_t insn = *p->addr; struct ppc_inst insn = *(struct ppc_inst *)p->addr;
if ((unsigned long)p->addr & 0x03) { if ((unsigned long)p->addr & 0x03) {
printk("Attempt to register kprobe at an unaligned address\n"); printk("Attempt to register kprobe at an unaligned address\n");
...@@ -139,13 +139,13 @@ NOKPROBE_SYMBOL(arch_prepare_kprobe); ...@@ -139,13 +139,13 @@ NOKPROBE_SYMBOL(arch_prepare_kprobe);
void arch_arm_kprobe(struct kprobe *p) void arch_arm_kprobe(struct kprobe *p)
{ {
patch_instruction(p->addr, ppc_inst(BREAKPOINT_INSTRUCTION)); patch_instruction((struct ppc_inst *)p->addr, ppc_inst(BREAKPOINT_INSTRUCTION));
} }
NOKPROBE_SYMBOL(arch_arm_kprobe); NOKPROBE_SYMBOL(arch_arm_kprobe);
void arch_disarm_kprobe(struct kprobe *p) void arch_disarm_kprobe(struct kprobe *p)
{ {
patch_instruction(p->addr, ppc_inst(p->opcode)); patch_instruction((struct ppc_inst *)p->addr, ppc_inst(p->opcode));
} }
NOKPROBE_SYMBOL(arch_disarm_kprobe); NOKPROBE_SYMBOL(arch_disarm_kprobe);
...@@ -217,7 +217,7 @@ NOKPROBE_SYMBOL(arch_prepare_kretprobe); ...@@ -217,7 +217,7 @@ NOKPROBE_SYMBOL(arch_prepare_kretprobe);
static int try_to_emulate(struct kprobe *p, struct pt_regs *regs) static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
{ {
int ret; int ret;
unsigned int insn = *p->ainsn.insn; struct ppc_inst insn = *(struct ppc_inst *)p->ainsn.insn;
/* regs->nip is also adjusted if emulate_step returns 1 */ /* regs->nip is also adjusted if emulate_step returns 1 */
ret = emulate_step(regs, insn); ret = emulate_step(regs, insn);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <asm/sstep.h> #include <asm/sstep.h>
#include <asm/exception-64s.h> #include <asm/exception-64s.h>
#include <asm/extable.h> #include <asm/extable.h>
#include <asm/inst.h>
/* /*
* Convert an address related to an mm to a PFN. NOTE: we are in real * Convert an address related to an mm to a PFN. NOTE: we are in real
...@@ -369,7 +370,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr, ...@@ -369,7 +370,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr,
* in real-mode is tricky and can lead to recursive * in real-mode is tricky and can lead to recursive
* faults * faults
*/ */
int instr; struct ppc_inst instr;
unsigned long pfn, instr_addr; unsigned long pfn, instr_addr;
struct instruction_op op; struct instruction_op op;
struct pt_regs tmp = *regs; struct pt_regs tmp = *regs;
...@@ -377,7 +378,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr, ...@@ -377,7 +378,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr,
pfn = addr_to_pfn(regs, regs->nip); pfn = addr_to_pfn(regs, regs->nip);
if (pfn != ULONG_MAX) { if (pfn != ULONG_MAX) {
instr_addr = (pfn << PAGE_SHIFT) + (regs->nip & ~PAGE_MASK); instr_addr = (pfn << PAGE_SHIFT) + (regs->nip & ~PAGE_MASK);
instr = *(unsigned int *)(instr_addr); instr = *(struct ppc_inst *)(instr_addr);
if (!analyse_instr(&op, &tmp, instr)) { if (!analyse_instr(&op, &tmp, instr)) {
pfn = addr_to_pfn(regs, op.ea); pfn = addr_to_pfn(regs, op.ea);
*addr = op.ea; *addr = op.ea;
......
...@@ -100,8 +100,9 @@ static unsigned long can_optimize(struct kprobe *p) ...@@ -100,8 +100,9 @@ static unsigned long can_optimize(struct kprobe *p)
* Ensure that the instruction is not a conditional branch, * Ensure that the instruction is not a conditional branch,
* and that can be emulated. * and that can be emulated.
*/ */
if (!is_conditional_branch(*p->ainsn.insn) && if (!is_conditional_branch(*(struct ppc_inst *)p->ainsn.insn) &&
analyse_instr(&op, &regs, *p->ainsn.insn) == 1) { analyse_instr(&op, &regs,
*(struct ppc_inst *)p->ainsn.insn) == 1) {
emulate_update_regs(&regs, &op); emulate_update_regs(&regs, &op);
nip = regs.nip; nip = regs.nip;
} }
...@@ -148,13 +149,15 @@ void arch_remove_optimized_kprobe(struct optimized_kprobe *op) ...@@ -148,13 +149,15 @@ void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
void patch_imm32_load_insns(unsigned int val, kprobe_opcode_t *addr) void patch_imm32_load_insns(unsigned int val, kprobe_opcode_t *addr)
{ {
/* addis r4,0,(insn)@h */ /* addis r4,0,(insn)@h */
patch_instruction(addr, ppc_inst(PPC_INST_ADDIS | ___PPC_RT(4) | patch_instruction((struct ppc_inst *)addr,
((val >> 16) & 0xffff))); ppc_inst(PPC_INST_ADDIS | ___PPC_RT(4) |
((val >> 16) & 0xffff)));
addr++; addr++;
/* ori r4,r4,(insn)@l */ /* ori r4,r4,(insn)@l */
patch_instruction(addr, ppc_inst(PPC_INST_ORI | ___PPC_RA(4) | patch_instruction((struct ppc_inst *)addr,
___PPC_RS(4) | (val & 0xffff))); ppc_inst(PPC_INST_ORI | ___PPC_RA(4) |
___PPC_RS(4) | (val & 0xffff)));
} }
/* /*
...@@ -164,34 +167,39 @@ void patch_imm32_load_insns(unsigned int val, kprobe_opcode_t *addr) ...@@ -164,34 +167,39 @@ void patch_imm32_load_insns(unsigned int val, kprobe_opcode_t *addr)
void patch_imm64_load_insns(unsigned long val, kprobe_opcode_t *addr) void patch_imm64_load_insns(unsigned long val, kprobe_opcode_t *addr)
{ {
/* lis r3,(op)@highest */ /* lis r3,(op)@highest */
patch_instruction(addr, ppc_inst(PPC_INST_ADDIS | ___PPC_RT(3) | patch_instruction((struct ppc_inst *)addr,
((val >> 48) & 0xffff))); ppc_inst(PPC_INST_ADDIS | ___PPC_RT(3) |
((val >> 48) & 0xffff)));
addr++; addr++;
/* ori r3,r3,(op)@higher */ /* ori r3,r3,(op)@higher */
patch_instruction(addr, ppc_inst(PPC_INST_ORI | ___PPC_RA(3) | patch_instruction((struct ppc_inst *)addr,
___PPC_RS(3) | ((val >> 32) & 0xffff))); ppc_inst(PPC_INST_ORI | ___PPC_RA(3) |
___PPC_RS(3) | ((val >> 32) & 0xffff)));
addr++; addr++;
/* rldicr r3,r3,32,31 */ /* rldicr r3,r3,32,31 */
patch_instruction(addr, ppc_inst(PPC_INST_RLDICR | ___PPC_RA(3) | patch_instruction((struct ppc_inst *)addr,
___PPC_RS(3) | __PPC_SH64(32) | __PPC_ME64(31))); ppc_inst(PPC_INST_RLDICR | ___PPC_RA(3) |
___PPC_RS(3) | __PPC_SH64(32) | __PPC_ME64(31)));
addr++; addr++;
/* oris r3,r3,(op)@h */ /* oris r3,r3,(op)@h */
patch_instruction(addr, ppc_inst(PPC_INST_ORIS | ___PPC_RA(3) | patch_instruction((struct ppc_inst *)addr,
___PPC_RS(3) | ((val >> 16) & 0xffff))); ppc_inst(PPC_INST_ORIS | ___PPC_RA(3) |
___PPC_RS(3) | ((val >> 16) & 0xffff)));
addr++; addr++;
/* ori r3,r3,(op)@l */ /* ori r3,r3,(op)@l */
patch_instruction(addr, ppc_inst(PPC_INST_ORI | ___PPC_RA(3) | patch_instruction((struct ppc_inst *)addr,
___PPC_RS(3) | (val & 0xffff))); ppc_inst(PPC_INST_ORI | ___PPC_RA(3) |
___PPC_RS(3) | (val & 0xffff)));
} }
int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
{ {
kprobe_opcode_t *buff, branch_op_callback, branch_emulate_step; struct ppc_inst branch_op_callback, branch_emulate_step;
kprobe_opcode_t *op_callback_addr, *emulate_step_addr; kprobe_opcode_t *op_callback_addr, *emulate_step_addr, *buff;
long b_offset; long b_offset;
unsigned long nip, size; unsigned long nip, size;
int rc, i; int rc, i;
...@@ -231,7 +239,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) ...@@ -231,7 +239,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
size = (TMPL_END_IDX * sizeof(kprobe_opcode_t)) / sizeof(int); size = (TMPL_END_IDX * sizeof(kprobe_opcode_t)) / sizeof(int);
pr_devel("Copying template to %p, size %lu\n", buff, size); pr_devel("Copying template to %p, size %lu\n", buff, size);
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
rc = patch_instruction(buff + i, rc = patch_instruction((struct ppc_inst *)(buff + i),
ppc_inst(*(optprobe_template_entry + i))); ppc_inst(*(optprobe_template_entry + i)));
if (rc < 0) if (rc < 0)
goto error; goto error;
...@@ -254,20 +262,22 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) ...@@ -254,20 +262,22 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
} }
rc = create_branch(&branch_op_callback, rc = create_branch(&branch_op_callback,
(unsigned int *)buff + TMPL_CALL_HDLR_IDX, (struct ppc_inst *)(buff + TMPL_CALL_HDLR_IDX),
(unsigned long)op_callback_addr, (unsigned long)op_callback_addr,
BRANCH_SET_LINK); BRANCH_SET_LINK);
rc |= create_branch(&branch_emulate_step, rc |= create_branch(&branch_emulate_step,
(unsigned int *)buff + TMPL_EMULATE_IDX, (struct ppc_inst *)(buff + TMPL_EMULATE_IDX),
(unsigned long)emulate_step_addr, (unsigned long)emulate_step_addr,
BRANCH_SET_LINK); BRANCH_SET_LINK);
if (rc) if (rc)
goto error; goto error;
patch_instruction(buff + TMPL_CALL_HDLR_IDX, branch_op_callback); patch_instruction((struct ppc_inst *)(buff + TMPL_CALL_HDLR_IDX),
patch_instruction(buff + TMPL_EMULATE_IDX, branch_emulate_step); branch_op_callback);
patch_instruction((struct ppc_inst *)(buff + TMPL_EMULATE_IDX),
branch_emulate_step);
/* /*
* 3. load instruction to be emulated into relevant register, and * 3. load instruction to be emulated into relevant register, and
...@@ -277,7 +287,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) ...@@ -277,7 +287,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
/* /*
* 4. branch back from trampoline * 4. branch back from trampoline
*/ */
patch_branch(buff + TMPL_RET_IDX, (unsigned long)nip, 0); patch_branch((struct ppc_inst *)(buff + TMPL_RET_IDX), (unsigned long)nip, 0);
flush_icache_range((unsigned long)buff, flush_icache_range((unsigned long)buff,
(unsigned long)(&buff[TMPL_END_IDX])); (unsigned long)(&buff[TMPL_END_IDX]));
...@@ -309,7 +319,7 @@ int arch_check_optimized_kprobe(struct optimized_kprobe *op) ...@@ -309,7 +319,7 @@ int arch_check_optimized_kprobe(struct optimized_kprobe *op)
void arch_optimize_kprobes(struct list_head *oplist) void arch_optimize_kprobes(struct list_head *oplist)
{ {
unsigned int instr; struct ppc_inst instr;
struct optimized_kprobe *op; struct optimized_kprobe *op;
struct optimized_kprobe *tmp; struct optimized_kprobe *tmp;
...@@ -321,9 +331,9 @@ void arch_optimize_kprobes(struct list_head *oplist) ...@@ -321,9 +331,9 @@ void arch_optimize_kprobes(struct list_head *oplist)
memcpy(op->optinsn.copied_insn, op->kp.addr, memcpy(op->optinsn.copied_insn, op->kp.addr,
RELATIVEJUMP_SIZE); RELATIVEJUMP_SIZE);
create_branch(&instr, create_branch(&instr,
(unsigned int *)op->kp.addr, (struct ppc_inst *)op->kp.addr,
(unsigned long)op->optinsn.insn, 0); (unsigned long)op->optinsn.insn, 0);
patch_instruction(op->kp.addr, instr); patch_instruction((struct ppc_inst *)op->kp.addr, instr);
list_del_init(&op->list); list_del_init(&op->list);
} }
} }
......
...@@ -74,8 +74,8 @@ EXPORT_SYMBOL(DMA_MODE_WRITE); ...@@ -74,8 +74,8 @@ EXPORT_SYMBOL(DMA_MODE_WRITE);
*/ */
notrace void __init machine_init(u64 dt_ptr) notrace void __init machine_init(u64 dt_ptr)
{ {
unsigned int *addr = (unsigned int *)patch_site_addr(&patch__memset_nocache); struct ppc_inst *addr = (struct ppc_inst *)patch_site_addr(&patch__memset_nocache);
unsigned int insn; struct ppc_inst insn;
/* Configure static keys first, now that we're relocated. */ /* Configure static keys first, now that we're relocated. */
setup_feature_keys(); setup_feature_keys();
......
...@@ -41,23 +41,23 @@ ...@@ -41,23 +41,23 @@
#define NUM_FTRACE_TRAMPS 8 #define NUM_FTRACE_TRAMPS 8
static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS]; static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
static unsigned int static struct ppc_inst
ftrace_call_replace(unsigned long ip, unsigned long addr, int link) ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
{ {
unsigned int op; struct ppc_inst op;
addr = ppc_function_entry((void *)addr); addr = ppc_function_entry((void *)addr);
/* if (link) set op to 'bl' else 'b' */ /* if (link) set op to 'bl' else 'b' */
create_branch(&op, (unsigned int *)ip, addr, link ? 1 : 0); create_branch(&op, (struct ppc_inst *)ip, addr, link ? 1 : 0);
return op; return op;
} }
static int static int
ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new) ftrace_modify_code(unsigned long ip, struct ppc_inst old, struct ppc_inst new)
{ {
unsigned int replaced; struct ppc_inst replaced;
/* /*
* Note: * Note:
...@@ -79,7 +79,7 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new) ...@@ -79,7 +79,7 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
} }
/* replace the text with the new text */ /* replace the text with the new text */
if (patch_instruction((unsigned int *)ip, new)) if (patch_instruction((struct ppc_inst *)ip, new))
return -EPERM; return -EPERM;
return 0; return 0;
...@@ -90,24 +90,24 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new) ...@@ -90,24 +90,24 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
*/ */
static int test_24bit_addr(unsigned long ip, unsigned long addr) static int test_24bit_addr(unsigned long ip, unsigned long addr)
{ {
unsigned int op; struct ppc_inst op;
addr = ppc_function_entry((void *)addr); addr = ppc_function_entry((void *)addr);
/* use the create_branch to verify that this offset can be branched */ /* use the create_branch to verify that this offset can be branched */
return create_branch(&op, (unsigned int *)ip, addr, 0) == 0; return create_branch(&op, (struct ppc_inst *)ip, addr, 0) == 0;
} }
static int is_bl_op(unsigned int op) static int is_bl_op(struct ppc_inst op)
{ {
return (ppc_inst_val(op) & 0xfc000003) == 0x48000001; return (ppc_inst_val(op) & 0xfc000003) == 0x48000001;
} }
static int is_b_op(unsigned int op) static int is_b_op(struct ppc_inst op)
{ {
return (ppc_inst_val(op) & 0xfc000003) == 0x48000000; return (ppc_inst_val(op) & 0xfc000003) == 0x48000000;
} }
static unsigned long find_bl_target(unsigned long ip, unsigned int op) static unsigned long find_bl_target(unsigned long ip, struct ppc_inst op)
{ {
int offset; int offset;
...@@ -127,7 +127,7 @@ __ftrace_make_nop(struct module *mod, ...@@ -127,7 +127,7 @@ __ftrace_make_nop(struct module *mod,
{ {
unsigned long entry, ptr, tramp; unsigned long entry, ptr, tramp;
unsigned long ip = rec->ip; unsigned long ip = rec->ip;
unsigned int op, pop; struct ppc_inst op, pop;
/* read where this goes */ /* read where this goes */
if (probe_kernel_read(&op, (void *)ip, sizeof(int))) { if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
...@@ -208,7 +208,7 @@ __ftrace_make_nop(struct module *mod, ...@@ -208,7 +208,7 @@ __ftrace_make_nop(struct module *mod,
} }
#endif /* CONFIG_MPROFILE_KERNEL */ #endif /* CONFIG_MPROFILE_KERNEL */
if (patch_instruction((unsigned int *)ip, pop)) { if (patch_instruction((struct ppc_inst *)ip, pop)) {
pr_err("Patching NOP failed.\n"); pr_err("Patching NOP failed.\n");
return -EPERM; return -EPERM;
} }
...@@ -221,7 +221,7 @@ static int ...@@ -221,7 +221,7 @@ static int
__ftrace_make_nop(struct module *mod, __ftrace_make_nop(struct module *mod,
struct dyn_ftrace *rec, unsigned long addr) struct dyn_ftrace *rec, unsigned long addr)
{ {
unsigned int op; struct ppc_inst op;
unsigned int jmp[4]; unsigned int jmp[4];
unsigned long ip = rec->ip; unsigned long ip = rec->ip;
unsigned long tramp; unsigned long tramp;
...@@ -280,7 +280,7 @@ __ftrace_make_nop(struct module *mod, ...@@ -280,7 +280,7 @@ __ftrace_make_nop(struct module *mod,
op = ppc_inst(PPC_INST_NOP); op = ppc_inst(PPC_INST_NOP);
if (patch_instruction((unsigned int *)ip, op)) if (patch_instruction((struct ppc_inst *)ip, op))
return -EPERM; return -EPERM;
return 0; return 0;
...@@ -291,7 +291,7 @@ __ftrace_make_nop(struct module *mod, ...@@ -291,7 +291,7 @@ __ftrace_make_nop(struct module *mod,
static unsigned long find_ftrace_tramp(unsigned long ip) static unsigned long find_ftrace_tramp(unsigned long ip)
{ {
int i; int i;
unsigned int instr; struct ppc_inst instr;
/* /*
* We have the compiler generated long_branch tramps at the end * We have the compiler generated long_branch tramps at the end
...@@ -328,9 +328,10 @@ static int add_ftrace_tramp(unsigned long tramp) ...@@ -328,9 +328,10 @@ static int add_ftrace_tramp(unsigned long tramp)
*/ */
static int setup_mcount_compiler_tramp(unsigned long tramp) static int setup_mcount_compiler_tramp(unsigned long tramp)
{ {
int i, op; int i;
struct ppc_inst op;
unsigned long ptr; unsigned long ptr;
unsigned int instr; struct ppc_inst instr;
static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS]; static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
/* Is this a known long jump tramp? */ /* Is this a known long jump tramp? */
...@@ -379,7 +380,7 @@ static int setup_mcount_compiler_tramp(unsigned long tramp) ...@@ -379,7 +380,7 @@ static int setup_mcount_compiler_tramp(unsigned long tramp)
return -1; return -1;
} }
if (patch_branch((unsigned int *)tramp, ptr, 0)) { if (patch_branch((struct ppc_inst *)tramp, ptr, 0)) {
pr_debug("REL24 out of range!\n"); pr_debug("REL24 out of range!\n");
return -1; return -1;
} }
...@@ -395,7 +396,7 @@ static int setup_mcount_compiler_tramp(unsigned long tramp) ...@@ -395,7 +396,7 @@ static int setup_mcount_compiler_tramp(unsigned long tramp)
static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr) static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr)
{ {
unsigned long tramp, ip = rec->ip; unsigned long tramp, ip = rec->ip;
unsigned int op; struct ppc_inst op;
/* Read where this goes */ /* Read where this goes */
if (probe_kernel_read(&op, (void *)ip, sizeof(int))) { if (probe_kernel_read(&op, (void *)ip, sizeof(int))) {
...@@ -423,7 +424,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr) ...@@ -423,7 +424,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr)
} }
} }
if (patch_instruction((unsigned int *)ip, ppc_inst(PPC_INST_NOP))) { if (patch_instruction((struct ppc_inst *)ip, ppc_inst(PPC_INST_NOP))) {
pr_err("Patching NOP failed.\n"); pr_err("Patching NOP failed.\n");
return -EPERM; return -EPERM;
} }
...@@ -435,7 +436,7 @@ int ftrace_make_nop(struct module *mod, ...@@ -435,7 +436,7 @@ int ftrace_make_nop(struct module *mod,
struct dyn_ftrace *rec, unsigned long addr) struct dyn_ftrace *rec, unsigned long addr)
{ {
unsigned long ip = rec->ip; unsigned long ip = rec->ip;
unsigned int old, new; struct ppc_inst old, new;
/* /*
* If the calling address is more that 24 bits away, * If the calling address is more that 24 bits away,
...@@ -488,7 +489,7 @@ int ftrace_make_nop(struct module *mod, ...@@ -488,7 +489,7 @@ int ftrace_make_nop(struct module *mod,
*/ */
#ifndef CONFIG_MPROFILE_KERNEL #ifndef CONFIG_MPROFILE_KERNEL
static int static int
expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1) expected_nop_sequence(void *ip, struct ppc_inst op0, struct ppc_inst op1)
{ {
/* /*
* We expect to see: * We expect to see:
...@@ -506,7 +507,7 @@ expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1) ...@@ -506,7 +507,7 @@ expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
} }
#else #else
static int static int
expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1) expected_nop_sequence(void *ip, struct ppc_inst op0, struct ppc_inst op1)
{ {
/* look for patched "NOP" on ppc64 with -mprofile-kernel */ /* look for patched "NOP" on ppc64 with -mprofile-kernel */
if (!ppc_inst_equal(op0, ppc_inst(PPC_INST_NOP))) if (!ppc_inst_equal(op0, ppc_inst(PPC_INST_NOP)))
...@@ -518,8 +519,8 @@ expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1) ...@@ -518,8 +519,8 @@ expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1)
static int static int
__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{ {
unsigned int op[2]; struct ppc_inst op[2];
unsigned int instr; struct ppc_inst instr;
void *ip = (void *)rec->ip; void *ip = (void *)rec->ip;
unsigned long entry, ptr, tramp; unsigned long entry, ptr, tramp;
struct module *mod = rec->arch.mod; struct module *mod = rec->arch.mod;
...@@ -584,7 +585,7 @@ static int ...@@ -584,7 +585,7 @@ static int
__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{ {
int err; int err;
unsigned int op; struct ppc_inst op;
unsigned long ip = rec->ip; unsigned long ip = rec->ip;
/* read where this goes */ /* read where this goes */
...@@ -604,7 +605,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) ...@@ -604,7 +605,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
} }
/* create the branch to the trampoline */ /* create the branch to the trampoline */
err = create_branch(&op, (unsigned int *)ip, err = create_branch(&op, (struct ppc_inst *)ip,
rec->arch.mod->arch.tramp, BRANCH_SET_LINK); rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
if (err) { if (err) {
pr_err("REL24 out of range!\n"); pr_err("REL24 out of range!\n");
...@@ -613,7 +614,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) ...@@ -613,7 +614,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
pr_devel("write to %lx\n", rec->ip); pr_devel("write to %lx\n", rec->ip);
if (patch_instruction((unsigned int *)ip, op)) if (patch_instruction((struct ppc_inst *)ip, op))
return -EPERM; return -EPERM;
return 0; return 0;
...@@ -623,7 +624,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) ...@@ -623,7 +624,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr) static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr)
{ {
unsigned int op; struct ppc_inst op;
void *ip = (void *)rec->ip; void *ip = (void *)rec->ip;
unsigned long tramp, entry, ptr; unsigned long tramp, entry, ptr;
...@@ -671,7 +672,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr) ...@@ -671,7 +672,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr)
int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{ {
unsigned long ip = rec->ip; unsigned long ip = rec->ip;
unsigned int old, new; struct ppc_inst old, new;
/* /*
* If the calling address is more that 24 bits away, * If the calling address is more that 24 bits away,
...@@ -710,7 +711,7 @@ static int ...@@ -710,7 +711,7 @@ static int
__ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
unsigned long addr) unsigned long addr)
{ {
unsigned int op; struct ppc_inst op;
unsigned long ip = rec->ip; unsigned long ip = rec->ip;
unsigned long entry, ptr, tramp; unsigned long entry, ptr, tramp;
struct module *mod = rec->arch.mod; struct module *mod = rec->arch.mod;
...@@ -758,7 +759,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, ...@@ -758,7 +759,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
/* The new target may be within range */ /* The new target may be within range */
if (test_24bit_addr(ip, addr)) { if (test_24bit_addr(ip, addr)) {
/* within range */ /* within range */
if (patch_branch((unsigned int *)ip, addr, BRANCH_SET_LINK)) { if (patch_branch((struct ppc_inst *)ip, addr, BRANCH_SET_LINK)) {
pr_err("REL24 out of range!\n"); pr_err("REL24 out of range!\n");
return -EINVAL; return -EINVAL;
} }
...@@ -786,12 +787,12 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, ...@@ -786,12 +787,12 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
} }
/* Ensure branch is within 24 bits */ /* Ensure branch is within 24 bits */
if (create_branch(&op, (unsigned int *)ip, tramp, BRANCH_SET_LINK)) { if (create_branch(&op, (struct ppc_inst *)ip, tramp, BRANCH_SET_LINK)) {
pr_err("Branch out of range\n"); pr_err("Branch out of range\n");
return -EINVAL; return -EINVAL;
} }
if (patch_branch((unsigned int *)ip, tramp, BRANCH_SET_LINK)) { if (patch_branch((struct ppc_inst *)ip, tramp, BRANCH_SET_LINK)) {
pr_err("REL24 out of range!\n"); pr_err("REL24 out of range!\n");
return -EINVAL; return -EINVAL;
} }
...@@ -804,7 +805,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, ...@@ -804,7 +805,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
unsigned long addr) unsigned long addr)
{ {
unsigned long ip = rec->ip; unsigned long ip = rec->ip;
unsigned int old, new; struct ppc_inst old, new;
/* /*
* If the calling address is more that 24 bits away, * If the calling address is more that 24 bits away,
...@@ -844,10 +845,10 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, ...@@ -844,10 +845,10 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
int ftrace_update_ftrace_func(ftrace_func_t func) int ftrace_update_ftrace_func(ftrace_func_t func)
{ {
unsigned long ip = (unsigned long)(&ftrace_call); unsigned long ip = (unsigned long)(&ftrace_call);
unsigned int old, new; struct ppc_inst old, new;
int ret; int ret;
old = *(unsigned int *)&ftrace_call; old = *(struct ppc_inst *)&ftrace_call;
new = ftrace_call_replace(ip, (unsigned long)func, 1); new = ftrace_call_replace(ip, (unsigned long)func, 1);
ret = ftrace_modify_code(ip, old, new); ret = ftrace_modify_code(ip, old, new);
...@@ -855,7 +856,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func) ...@@ -855,7 +856,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
/* Also update the regs callback function */ /* Also update the regs callback function */
if (!ret) { if (!ret) {
ip = (unsigned long)(&ftrace_regs_call); ip = (unsigned long)(&ftrace_regs_call);
old = *(unsigned int *)&ftrace_regs_call; old = *(struct ppc_inst *)&ftrace_regs_call;
new = ftrace_call_replace(ip, (unsigned long)func, 1); new = ftrace_call_replace(ip, (unsigned long)func, 1);
ret = ftrace_modify_code(ip, old, new); ret = ftrace_modify_code(ip, old, new);
} }
...@@ -929,7 +930,7 @@ int ftrace_enable_ftrace_graph_caller(void) ...@@ -929,7 +930,7 @@ int ftrace_enable_ftrace_graph_caller(void)
unsigned long ip = (unsigned long)(&ftrace_graph_call); unsigned long ip = (unsigned long)(&ftrace_graph_call);
unsigned long addr = (unsigned long)(&ftrace_graph_caller); unsigned long addr = (unsigned long)(&ftrace_graph_caller);
unsigned long stub = (unsigned long)(&ftrace_graph_stub); unsigned long stub = (unsigned long)(&ftrace_graph_stub);
unsigned int old, new; struct ppc_inst old, new;
old = ftrace_call_replace(ip, stub, 0); old = ftrace_call_replace(ip, stub, 0);
new = ftrace_call_replace(ip, addr, 0); new = ftrace_call_replace(ip, addr, 0);
...@@ -942,7 +943,7 @@ int ftrace_disable_ftrace_graph_caller(void) ...@@ -942,7 +943,7 @@ int ftrace_disable_ftrace_graph_caller(void)
unsigned long ip = (unsigned long)(&ftrace_graph_call); unsigned long ip = (unsigned long)(&ftrace_graph_call);
unsigned long addr = (unsigned long)(&ftrace_graph_caller); unsigned long addr = (unsigned long)(&ftrace_graph_caller);
unsigned long stub = (unsigned long)(&ftrace_graph_stub); unsigned long stub = (unsigned long)(&ftrace_graph_stub);
unsigned int old, new; struct ppc_inst old, new;
old = ftrace_call_replace(ip, addr, 0); old = ftrace_call_replace(ip, addr, 0);
new = ftrace_call_replace(ip, stub, 0); new = ftrace_call_replace(ip, stub, 0);
......
...@@ -261,11 +261,12 @@ static unsigned int rfin(unsigned int x) ...@@ -261,11 +261,12 @@ static unsigned int rfin(unsigned int x)
int emulate_altivec(struct pt_regs *regs) int emulate_altivec(struct pt_regs *regs)
{ {
unsigned int instr, i, word; struct ppc_inst instr;
unsigned int i, word;
unsigned int va, vb, vc, vd; unsigned int va, vb, vc, vd;
vector128 *vrs; vector128 *vrs;
if (get_user(instr, (unsigned int __user *) regs->nip)) if (get_user(instr.val, (unsigned int __user *)regs->nip))
return -EFAULT; return -EFAULT;
word = ppc_inst_val(instr); word = ppc_inst_val(instr);
......
...@@ -19,12 +19,12 @@ ...@@ -19,12 +19,12 @@
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/inst.h> #include <asm/inst.h>
static int __patch_instruction(unsigned int *exec_addr, unsigned int instr, static int __patch_instruction(struct ppc_inst *exec_addr, struct ppc_inst instr,
unsigned int *patch_addr) struct ppc_inst *patch_addr)
{ {
int err = 0; int err = 0;
__put_user_asm(instr, patch_addr, err, "stw"); __put_user_asm(ppc_inst_val(instr), patch_addr, err, "stw");
if (err) if (err)
return err; return err;
...@@ -34,7 +34,7 @@ static int __patch_instruction(unsigned int *exec_addr, unsigned int instr, ...@@ -34,7 +34,7 @@ static int __patch_instruction(unsigned int *exec_addr, unsigned int instr,
return 0; return 0;
} }
int raw_patch_instruction(unsigned int *addr, unsigned int instr) int raw_patch_instruction(struct ppc_inst *addr, struct ppc_inst instr)
{ {
return __patch_instruction(addr, instr, addr); return __patch_instruction(addr, instr, addr);
} }
...@@ -137,10 +137,10 @@ static inline int unmap_patch_area(unsigned long addr) ...@@ -137,10 +137,10 @@ static inline int unmap_patch_area(unsigned long addr)
return 0; return 0;
} }
static int do_patch_instruction(unsigned int *addr, unsigned int instr) static int do_patch_instruction(struct ppc_inst *addr, struct ppc_inst instr)
{ {
int err; int err;
unsigned int *patch_addr = NULL; struct ppc_inst *patch_addr = NULL;
unsigned long flags; unsigned long flags;
unsigned long text_poke_addr; unsigned long text_poke_addr;
unsigned long kaddr = (unsigned long)addr; unsigned long kaddr = (unsigned long)addr;
...@@ -161,8 +161,7 @@ static int do_patch_instruction(unsigned int *addr, unsigned int instr) ...@@ -161,8 +161,7 @@ static int do_patch_instruction(unsigned int *addr, unsigned int instr)
goto out; goto out;
} }
patch_addr = (unsigned int *)(text_poke_addr) + patch_addr = (struct ppc_inst *)(text_poke_addr + (kaddr & ~PAGE_MASK));
((kaddr & ~PAGE_MASK) / sizeof(unsigned int));
__patch_instruction(addr, instr, patch_addr); __patch_instruction(addr, instr, patch_addr);
...@@ -177,14 +176,14 @@ static int do_patch_instruction(unsigned int *addr, unsigned int instr) ...@@ -177,14 +176,14 @@ static int do_patch_instruction(unsigned int *addr, unsigned int instr)
} }
#else /* !CONFIG_STRICT_KERNEL_RWX */ #else /* !CONFIG_STRICT_KERNEL_RWX */
static int do_patch_instruction(unsigned int *addr, unsigned int instr) static int do_patch_instruction(struct ppc_inst *addr, struct ppc_inst instr)
{ {
return raw_patch_instruction(addr, instr); return raw_patch_instruction(addr, instr);
} }
#endif /* CONFIG_STRICT_KERNEL_RWX */ #endif /* CONFIG_STRICT_KERNEL_RWX */
int patch_instruction(unsigned int *addr, unsigned int instr) int patch_instruction(struct ppc_inst *addr, struct ppc_inst instr)
{ {
/* Make sure we aren't patching a freed init section */ /* Make sure we aren't patching a freed init section */
if (init_mem_is_free && init_section_contains(addr, 4)) { if (init_mem_is_free && init_section_contains(addr, 4)) {
...@@ -195,9 +194,9 @@ int patch_instruction(unsigned int *addr, unsigned int instr) ...@@ -195,9 +194,9 @@ int patch_instruction(unsigned int *addr, unsigned int instr)
} }
NOKPROBE_SYMBOL(patch_instruction); NOKPROBE_SYMBOL(patch_instruction);
int patch_branch(unsigned int *addr, unsigned long target, int flags) int patch_branch(struct ppc_inst *addr, unsigned long target, int flags)
{ {
unsigned int instr; struct ppc_inst instr;
create_branch(&instr, addr, target, flags); create_branch(&instr, addr, target, flags);
return patch_instruction(addr, instr); return patch_instruction(addr, instr);
...@@ -229,7 +228,7 @@ bool is_offset_in_branch_range(long offset) ...@@ -229,7 +228,7 @@ bool is_offset_in_branch_range(long offset)
* Helper to check if a given instruction is a conditional branch * Helper to check if a given instruction is a conditional branch
* Derived from the conditional checks in analyse_instr() * Derived from the conditional checks in analyse_instr()
*/ */
bool is_conditional_branch(unsigned int instr) bool is_conditional_branch(struct ppc_inst instr)
{ {
unsigned int opcode = ppc_inst_primary_opcode(instr); unsigned int opcode = ppc_inst_primary_opcode(instr);
...@@ -247,13 +246,13 @@ bool is_conditional_branch(unsigned int instr) ...@@ -247,13 +246,13 @@ bool is_conditional_branch(unsigned int instr)
} }
NOKPROBE_SYMBOL(is_conditional_branch); NOKPROBE_SYMBOL(is_conditional_branch);
int create_branch(unsigned int *instr, int create_branch(struct ppc_inst *instr,
const unsigned int *addr, const struct ppc_inst *addr,
unsigned long target, int flags) unsigned long target, int flags)
{ {
long offset; long offset;
*instr = 0; *instr = ppc_inst(0);
offset = target; offset = target;
if (! (flags & BRANCH_ABSOLUTE)) if (! (flags & BRANCH_ABSOLUTE))
offset = offset - (unsigned long)addr; offset = offset - (unsigned long)addr;
...@@ -263,12 +262,12 @@ int create_branch(unsigned int *instr, ...@@ -263,12 +262,12 @@ int create_branch(unsigned int *instr,
return 1; return 1;
/* Mask out the flags and target, so they don't step on each other. */ /* Mask out the flags and target, so they don't step on each other. */
*instr = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC); *instr = ppc_inst(0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC));
return 0; return 0;
} }
int create_cond_branch(unsigned int *instr, const unsigned int *addr, int create_cond_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
unsigned long target, int flags) unsigned long target, int flags)
{ {
long offset; long offset;
...@@ -282,27 +281,27 @@ int create_cond_branch(unsigned int *instr, const unsigned int *addr, ...@@ -282,27 +281,27 @@ int create_cond_branch(unsigned int *instr, const unsigned int *addr,
return 1; return 1;
/* Mask out the flags and target, so they don't step on each other. */ /* Mask out the flags and target, so they don't step on each other. */
*instr = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC); *instr = ppc_inst(0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC));
return 0; return 0;
} }
static unsigned int branch_opcode(unsigned int instr) static unsigned int branch_opcode(struct ppc_inst instr)
{ {
return ppc_inst_primary_opcode(instr) & 0x3F; return ppc_inst_primary_opcode(instr) & 0x3F;
} }
static int instr_is_branch_iform(unsigned int instr) static int instr_is_branch_iform(struct ppc_inst instr)
{ {
return branch_opcode(instr) == 18; return branch_opcode(instr) == 18;
} }
static int instr_is_branch_bform(unsigned int instr) static int instr_is_branch_bform(struct ppc_inst instr)
{ {
return branch_opcode(instr) == 16; return branch_opcode(instr) == 16;
} }
int instr_is_relative_branch(unsigned int instr) int instr_is_relative_branch(struct ppc_inst instr)
{ {
if (ppc_inst_val(instr) & BRANCH_ABSOLUTE) if (ppc_inst_val(instr) & BRANCH_ABSOLUTE)
return 0; return 0;
...@@ -310,12 +309,12 @@ int instr_is_relative_branch(unsigned int instr) ...@@ -310,12 +309,12 @@ int instr_is_relative_branch(unsigned int instr)
return instr_is_branch_iform(instr) || instr_is_branch_bform(instr); return instr_is_branch_iform(instr) || instr_is_branch_bform(instr);
} }
int instr_is_relative_link_branch(unsigned int instr) int instr_is_relative_link_branch(struct ppc_inst instr)
{ {
return instr_is_relative_branch(instr) && (ppc_inst_val(instr) & BRANCH_SET_LINK); return instr_is_relative_branch(instr) && (ppc_inst_val(instr) & BRANCH_SET_LINK);
} }
static unsigned long branch_iform_target(const unsigned int *instr) static unsigned long branch_iform_target(const struct ppc_inst *instr)
{ {
signed long imm; signed long imm;
...@@ -331,7 +330,7 @@ static unsigned long branch_iform_target(const unsigned int *instr) ...@@ -331,7 +330,7 @@ static unsigned long branch_iform_target(const unsigned int *instr)
return (unsigned long)imm; return (unsigned long)imm;
} }
static unsigned long branch_bform_target(const unsigned int *instr) static unsigned long branch_bform_target(const struct ppc_inst *instr)
{ {
signed long imm; signed long imm;
...@@ -347,7 +346,7 @@ static unsigned long branch_bform_target(const unsigned int *instr) ...@@ -347,7 +346,7 @@ static unsigned long branch_bform_target(const unsigned int *instr)
return (unsigned long)imm; return (unsigned long)imm;
} }
unsigned long branch_target(const unsigned int *instr) unsigned long branch_target(const struct ppc_inst *instr)
{ {
if (instr_is_branch_iform(*instr)) if (instr_is_branch_iform(*instr))
return branch_iform_target(instr); return branch_iform_target(instr);
...@@ -357,7 +356,7 @@ unsigned long branch_target(const unsigned int *instr) ...@@ -357,7 +356,7 @@ unsigned long branch_target(const unsigned int *instr)
return 0; return 0;
} }
int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr) int instr_is_branch_to_addr(const struct ppc_inst *instr, unsigned long addr)
{ {
if (instr_is_branch_iform(*instr) || instr_is_branch_bform(*instr)) if (instr_is_branch_iform(*instr) || instr_is_branch_bform(*instr))
return branch_target(instr) == addr; return branch_target(instr) == addr;
...@@ -365,8 +364,8 @@ int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr) ...@@ -365,8 +364,8 @@ int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr)
return 0; return 0;
} }
int translate_branch(unsigned int *instr, const unsigned int *dest, int translate_branch(struct ppc_inst *instr, const struct ppc_inst *dest,
const unsigned int *src) const struct ppc_inst *src)
{ {
unsigned long target; unsigned long target;
...@@ -392,7 +391,7 @@ void __patch_exception(int exc, unsigned long addr) ...@@ -392,7 +391,7 @@ void __patch_exception(int exc, unsigned long addr)
* instruction of the exception, not the first one * instruction of the exception, not the first one
*/ */
patch_branch(ibase + (exc / 4) + 1, addr, 0); patch_branch((struct ppc_inst *)(ibase + (exc / 4) + 1), addr, 0);
} }
#endif #endif
...@@ -409,7 +408,7 @@ static void __init test_trampoline(void) ...@@ -409,7 +408,7 @@ static void __init test_trampoline(void)
static void __init test_branch_iform(void) static void __init test_branch_iform(void)
{ {
int err; int err;
unsigned int instr; struct ppc_inst instr;
unsigned long addr; unsigned long addr;
addr = (unsigned long)&instr; addr = (unsigned long)&instr;
...@@ -484,12 +483,12 @@ static void __init test_branch_iform(void) ...@@ -484,12 +483,12 @@ static void __init test_branch_iform(void)
static void __init test_create_function_call(void) static void __init test_create_function_call(void)
{ {
unsigned int *iptr; struct ppc_inst *iptr;
unsigned long dest; unsigned long dest;
unsigned int instr; struct ppc_inst instr;
/* Check we can create a function call */ /* Check we can create a function call */
iptr = (unsigned int *)ppc_function_entry(test_trampoline); iptr = (struct ppc_inst *)ppc_function_entry(test_trampoline);
dest = ppc_function_entry(test_create_function_call); dest = ppc_function_entry(test_create_function_call);
create_branch(&instr, iptr, dest, BRANCH_SET_LINK); create_branch(&instr, iptr, dest, BRANCH_SET_LINK);
patch_instruction(iptr, instr); patch_instruction(iptr, instr);
...@@ -500,7 +499,8 @@ static void __init test_branch_bform(void) ...@@ -500,7 +499,8 @@ static void __init test_branch_bform(void)
{ {
int err; int err;
unsigned long addr; unsigned long addr;
unsigned int *iptr, instr, flags; struct ppc_inst *iptr, instr;
unsigned int flags;
iptr = &instr; iptr = &instr;
addr = (unsigned long)iptr; addr = (unsigned long)iptr;
...@@ -570,8 +570,8 @@ static void __init test_branch_bform(void) ...@@ -570,8 +570,8 @@ static void __init test_branch_bform(void)
static void __init test_translate_branch(void) static void __init test_translate_branch(void)
{ {
unsigned long addr; unsigned long addr;
unsigned int *p, *q; struct ppc_inst *p, *q;
unsigned int instr; struct ppc_inst instr;
void *buf; void *buf;
buf = vmalloc(PAGE_ALIGN(0x2000000 + 1)); buf = vmalloc(PAGE_ALIGN(0x2000000 + 1));
......
...@@ -32,26 +32,26 @@ struct fixup_entry { ...@@ -32,26 +32,26 @@ struct fixup_entry {
long alt_end_off; long alt_end_off;
}; };
static unsigned int *calc_addr(struct fixup_entry *fcur, long offset) static struct ppc_inst *calc_addr(struct fixup_entry *fcur, long offset)
{ {
/* /*
* We store the offset to the code as a negative offset from * We store the offset to the code as a negative offset from
* the start of the alt_entry, to support the VDSO. This * the start of the alt_entry, to support the VDSO. This
* routine converts that back into an actual address. * routine converts that back into an actual address.
*/ */
return (unsigned int *)((unsigned long)fcur + offset); return (struct ppc_inst *)((unsigned long)fcur + offset);
} }
static int patch_alt_instruction(unsigned int *src, unsigned int *dest, static int patch_alt_instruction(struct ppc_inst *src, struct ppc_inst *dest,
unsigned int *alt_start, unsigned int *alt_end) struct ppc_inst *alt_start, struct ppc_inst *alt_end)
{ {
int err; int err;
unsigned int instr; struct ppc_inst instr;
instr = *src; instr = *src;
if (instr_is_relative_branch(*src)) { if (instr_is_relative_branch(*src)) {
unsigned int *target = (unsigned int *)branch_target(src); struct ppc_inst *target = (struct ppc_inst *)branch_target(src);
/* Branch within the section doesn't need translating */ /* Branch within the section doesn't need translating */
if (target < alt_start || target > alt_end) { if (target < alt_start || target > alt_end) {
...@@ -68,7 +68,7 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest, ...@@ -68,7 +68,7 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
static int patch_feature_section(unsigned long value, struct fixup_entry *fcur) static int patch_feature_section(unsigned long value, struct fixup_entry *fcur)
{ {
unsigned int *start, *end, *alt_start, *alt_end, *src, *dest; struct ppc_inst *start, *end, *alt_start, *alt_end, *src, *dest;
start = calc_addr(fcur, fcur->start_off); start = calc_addr(fcur, fcur->start_off);
end = calc_addr(fcur, fcur->end_off); end = calc_addr(fcur, fcur->end_off);
...@@ -147,15 +147,17 @@ static void do_stf_entry_barrier_fixups(enum stf_barrier_type types) ...@@ -147,15 +147,17 @@ static void do_stf_entry_barrier_fixups(enum stf_barrier_type types)
pr_devel("patching dest %lx\n", (unsigned long)dest); pr_devel("patching dest %lx\n", (unsigned long)dest);
patch_instruction(dest, ppc_inst(instrs[0])); patch_instruction((struct ppc_inst *)dest, ppc_inst(instrs[0]));
if (types & STF_BARRIER_FALLBACK) if (types & STF_BARRIER_FALLBACK)
patch_branch(dest + 1, (unsigned long)&stf_barrier_fallback, patch_branch((struct ppc_inst *)(dest + 1),
(unsigned long)&stf_barrier_fallback,
BRANCH_SET_LINK); BRANCH_SET_LINK);
else else
patch_instruction(dest + 1, ppc_inst(instrs[1])); patch_instruction((struct ppc_inst *)(dest + 1),
ppc_inst(instrs[1]));
patch_instruction(dest + 2, ppc_inst(instrs[2])); patch_instruction((struct ppc_inst *)(dest + 2), ppc_inst(instrs[2]));
} }
printk(KERN_DEBUG "stf-barrier: patched %d entry locations (%s barrier)\n", i, printk(KERN_DEBUG "stf-barrier: patched %d entry locations (%s barrier)\n", i,
...@@ -208,12 +210,12 @@ static void do_stf_exit_barrier_fixups(enum stf_barrier_type types) ...@@ -208,12 +210,12 @@ static void do_stf_exit_barrier_fixups(enum stf_barrier_type types)
pr_devel("patching dest %lx\n", (unsigned long)dest); pr_devel("patching dest %lx\n", (unsigned long)dest);
patch_instruction(dest, ppc_inst(instrs[0])); patch_instruction((struct ppc_inst *)dest, ppc_inst(instrs[0]));
patch_instruction(dest + 1, ppc_inst(instrs[1])); patch_instruction((struct ppc_inst *)(dest + 1), ppc_inst(instrs[1]));
patch_instruction(dest + 2, ppc_inst(instrs[2])); patch_instruction((struct ppc_inst *)(dest + 2), ppc_inst(instrs[2]));
patch_instruction(dest + 3, ppc_inst(instrs[3])); patch_instruction((struct ppc_inst *)(dest + 3), ppc_inst(instrs[3]));
patch_instruction(dest + 4, ppc_inst(instrs[4])); patch_instruction((struct ppc_inst *)(dest + 4), ppc_inst(instrs[4]));
patch_instruction(dest + 5, ppc_inst(instrs[5])); patch_instruction((struct ppc_inst *)(dest + 5), ppc_inst(instrs[5]));
} }
printk(KERN_DEBUG "stf-barrier: patched %d exit locations (%s barrier)\n", i, printk(KERN_DEBUG "stf-barrier: patched %d exit locations (%s barrier)\n", i,
(types == STF_BARRIER_NONE) ? "no" : (types == STF_BARRIER_NONE) ? "no" :
...@@ -261,9 +263,9 @@ void do_rfi_flush_fixups(enum l1d_flush_type types) ...@@ -261,9 +263,9 @@ void do_rfi_flush_fixups(enum l1d_flush_type types)
pr_devel("patching dest %lx\n", (unsigned long)dest); pr_devel("patching dest %lx\n", (unsigned long)dest);
patch_instruction(dest, ppc_inst(instrs[0])); patch_instruction((struct ppc_inst *)dest, ppc_inst(instrs[0]));
patch_instruction(dest + 1, ppc_inst(instrs[1])); patch_instruction((struct ppc_inst *)(dest + 1), ppc_inst(instrs[1]));
patch_instruction(dest + 2, ppc_inst(instrs[2])); patch_instruction((struct ppc_inst *)(dest + 2), ppc_inst(instrs[2]));
} }
printk(KERN_DEBUG "rfi-flush: patched %d locations (%s flush)\n", i, printk(KERN_DEBUG "rfi-flush: patched %d locations (%s flush)\n", i,
...@@ -296,7 +298,7 @@ void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_ ...@@ -296,7 +298,7 @@ void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_
dest = (void *)start + *start; dest = (void *)start + *start;
pr_devel("patching dest %lx\n", (unsigned long)dest); pr_devel("patching dest %lx\n", (unsigned long)dest);
patch_instruction(dest, ppc_inst(instr)); patch_instruction((struct ppc_inst *)dest, ppc_inst(instr));
} }
printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i); printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
...@@ -339,8 +341,8 @@ void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_ ...@@ -339,8 +341,8 @@ void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_
dest = (void *)start + *start; dest = (void *)start + *start;
pr_devel("patching dest %lx\n", (unsigned long)dest); pr_devel("patching dest %lx\n", (unsigned long)dest);
patch_instruction(dest, ppc_inst(instr[0])); patch_instruction((struct ppc_inst *)dest, ppc_inst(instr[0]));
patch_instruction(dest + 1, ppc_inst(instr[1])); patch_instruction((struct ppc_inst *)(dest + 1), ppc_inst(instr[1]));
} }
printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i); printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
...@@ -354,7 +356,7 @@ static void patch_btb_flush_section(long *curr) ...@@ -354,7 +356,7 @@ static void patch_btb_flush_section(long *curr)
end = (void *)curr + *(curr + 1); end = (void *)curr + *(curr + 1);
for (; start < end; start++) { for (; start < end; start++) {
pr_devel("patching dest %lx\n", (unsigned long)start); pr_devel("patching dest %lx\n", (unsigned long)start);
patch_instruction(start, ppc_inst(PPC_INST_NOP)); patch_instruction((struct ppc_inst *)start, ppc_inst(PPC_INST_NOP));
} }
} }
...@@ -373,7 +375,7 @@ void do_btb_flush_fixups(void) ...@@ -373,7 +375,7 @@ void do_btb_flush_fixups(void)
void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
{ {
long *start, *end; long *start, *end;
unsigned int *dest; struct ppc_inst *dest;
if (!(value & CPU_FTR_LWSYNC)) if (!(value & CPU_FTR_LWSYNC))
return ; return ;
...@@ -390,18 +392,18 @@ void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) ...@@ -390,18 +392,18 @@ void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
static void do_final_fixups(void) static void do_final_fixups(void)
{ {
#if defined(CONFIG_PPC64) && defined(CONFIG_RELOCATABLE) #if defined(CONFIG_PPC64) && defined(CONFIG_RELOCATABLE)
int *src, *dest; struct ppc_inst *src, *dest;
unsigned long length; unsigned long length;
if (PHYSICAL_START == 0) if (PHYSICAL_START == 0)
return; return;
src = (int *)(KERNELBASE + PHYSICAL_START); src = (struct ppc_inst *)(KERNELBASE + PHYSICAL_START);
dest = (int *)KERNELBASE; dest = (struct ppc_inst *)KERNELBASE;
length = (__end_interrupts - _stext) / sizeof(int); length = (__end_interrupts - _stext) / sizeof(struct ppc_inst);
while (length--) { while (length--) {
raw_patch_instruction(dest, ppc_inst(*src)); raw_patch_instruction(dest, *src);
src++; src++;
dest++; dest++;
} }
......
...@@ -1163,7 +1163,7 @@ static nokprobe_inline int trap_compare(long v1, long v2) ...@@ -1163,7 +1163,7 @@ static nokprobe_inline int trap_compare(long v1, long v2)
* otherwise. * otherwise.
*/ */
int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
unsigned int instr) struct ppc_inst instr)
{ {
unsigned int opcode, ra, rb, rc, rd, spr, u; unsigned int opcode, ra, rb, rc, rd, spr, u;
unsigned long int imm; unsigned long int imm;
...@@ -3103,7 +3103,7 @@ NOKPROBE_SYMBOL(emulate_loadstore); ...@@ -3103,7 +3103,7 @@ NOKPROBE_SYMBOL(emulate_loadstore);
* or -1 if the instruction is one that should not be stepped, * or -1 if the instruction is one that should not be stepped,
* such as an rfid, or a mtmsrd that would clear MSR_RI. * such as an rfid, or a mtmsrd that would clear MSR_RI.
*/ */
int emulate_step(struct pt_regs *regs, unsigned int instr) int emulate_step(struct pt_regs *regs, struct ppc_inst instr)
{ {
struct instruction_op op; struct instruction_op op;
int r, err, type; int r, err, type;
......
...@@ -462,7 +462,7 @@ struct compute_test { ...@@ -462,7 +462,7 @@ struct compute_test {
struct { struct {
char *descr; char *descr;
unsigned long flags; unsigned long flags;
unsigned int instr; struct ppc_inst instr;
struct pt_regs regs; struct pt_regs regs;
} subtests[MAX_SUBTESTS + 1]; } subtests[MAX_SUBTESTS + 1];
}; };
...@@ -843,7 +843,7 @@ static struct compute_test compute_tests[] = { ...@@ -843,7 +843,7 @@ static struct compute_test compute_tests[] = {
}; };
static int __init emulate_compute_instr(struct pt_regs *regs, static int __init emulate_compute_instr(struct pt_regs *regs,
unsigned int instr) struct ppc_inst instr)
{ {
struct instruction_op op; struct instruction_op op;
...@@ -861,7 +861,7 @@ static int __init emulate_compute_instr(struct pt_regs *regs, ...@@ -861,7 +861,7 @@ static int __init emulate_compute_instr(struct pt_regs *regs,
} }
static int __init execute_compute_instr(struct pt_regs *regs, static int __init execute_compute_instr(struct pt_regs *regs,
unsigned int instr) struct ppc_inst instr)
{ {
extern int exec_instr(struct pt_regs *regs); extern int exec_instr(struct pt_regs *regs);
extern s32 patch__exec_instr; extern s32 patch__exec_instr;
...@@ -892,7 +892,8 @@ static void __init run_tests_compute(void) ...@@ -892,7 +892,8 @@ static void __init run_tests_compute(void)
unsigned long flags; unsigned long flags;
struct compute_test *test; struct compute_test *test;
struct pt_regs *regs, exp, got; struct pt_regs *regs, exp, got;
unsigned int i, j, k, instr; unsigned int i, j, k;
struct ppc_inst instr;
bool ignore_gpr, ignore_xer, ignore_ccr, passed; bool ignore_gpr, ignore_xer, ignore_ccr, passed;
for (i = 0; i < ARRAY_SIZE(compute_tests); i++) { for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
* Check whether the instruction inst is a store using * Check whether the instruction inst is a store using
* an update addressing form which will update r1. * an update addressing form which will update r1.
*/ */
static bool store_updates_sp(unsigned int inst) static bool store_updates_sp(struct ppc_inst inst)
{ {
/* check for 1 in the rA field */ /* check for 1 in the rA field */
if (((ppc_inst_val(inst) >> 16) & 0x1f) != 1) if (((ppc_inst_val(inst) >> 16) & 0x1f) != 1)
...@@ -305,7 +305,7 @@ static bool bad_stack_expansion(struct pt_regs *regs, unsigned long address, ...@@ -305,7 +305,7 @@ static bool bad_stack_expansion(struct pt_regs *regs, unsigned long address,
if ((flags & FAULT_FLAG_WRITE) && (flags & FAULT_FLAG_USER) && if ((flags & FAULT_FLAG_WRITE) && (flags & FAULT_FLAG_USER) &&
access_ok(nip, sizeof(*nip))) { access_ok(nip, sizeof(*nip))) {
unsigned int inst; struct ppc_inst inst;
if (!probe_user_read(&inst, nip, sizeof(inst))) if (!probe_user_read(&inst, nip, sizeof(inst)))
return !store_updates_sp(inst); return !store_updates_sp(inst);
......
...@@ -421,14 +421,14 @@ static __u64 power_pmu_bhrb_to(u64 addr) ...@@ -421,14 +421,14 @@ static __u64 power_pmu_bhrb_to(u64 addr)
if (probe_kernel_read(&instr, (void *)addr, sizeof(instr))) if (probe_kernel_read(&instr, (void *)addr, sizeof(instr)))
return 0; return 0;
return branch_target(&instr); return branch_target((struct ppc_inst *)&instr);
} }
/* Userspace: need copy instruction here then translate it */ /* Userspace: need copy instruction here then translate it */
if (probe_user_read(&instr, (unsigned int __user *)addr, sizeof(instr))) if (probe_user_read(&instr, (unsigned int __user *)addr, sizeof(instr)))
return 0; return 0;
target = branch_target(&instr); target = branch_target((struct ppc_inst *)&instr);
if ((!target) || (instr & BRANCH_ABSOLUTE)) if ((!target) || (instr & BRANCH_ABSOLUTE))
return target; return target;
......
...@@ -73,7 +73,7 @@ smp_86xx_kick_cpu(int nr) ...@@ -73,7 +73,7 @@ smp_86xx_kick_cpu(int nr)
/* Setup fake reset vector to call __secondary_start_mpc86xx. */ /* Setup fake reset vector to call __secondary_start_mpc86xx. */
target = (unsigned long) __secondary_start_mpc86xx; target = (unsigned long) __secondary_start_mpc86xx;
patch_branch(vector, target, BRANCH_SET_LINK); patch_branch((struct ppc_inst *)vector, target, BRANCH_SET_LINK);
/* Kick that CPU */ /* Kick that CPU */
smp_86xx_release_core(nr); smp_86xx_release_core(nr);
...@@ -83,7 +83,7 @@ smp_86xx_kick_cpu(int nr) ...@@ -83,7 +83,7 @@ smp_86xx_kick_cpu(int nr)
mdelay(1); mdelay(1);
/* Restore the exception vector */ /* Restore the exception vector */
patch_instruction(vector, ppc_inst(save_vector)); patch_instruction((struct ppc_inst *)vector, ppc_inst(save_vector));
local_irq_restore(flags); local_irq_restore(flags);
......
...@@ -814,7 +814,7 @@ static int smp_core99_kick_cpu(int nr) ...@@ -814,7 +814,7 @@ static int smp_core99_kick_cpu(int nr)
* b __secondary_start_pmac_0 + nr*8 * b __secondary_start_pmac_0 + nr*8
*/ */
target = (unsigned long) __secondary_start_pmac_0 + nr * 8; target = (unsigned long) __secondary_start_pmac_0 + nr * 8;
patch_branch(vector, target, BRANCH_SET_LINK); patch_branch((struct ppc_inst *)vector, target, BRANCH_SET_LINK);
/* Put some life in our friend */ /* Put some life in our friend */
pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0); pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
...@@ -827,7 +827,7 @@ static int smp_core99_kick_cpu(int nr) ...@@ -827,7 +827,7 @@ static int smp_core99_kick_cpu(int nr)
mdelay(1); mdelay(1);
/* Restore our exception vector */ /* Restore our exception vector */
patch_instruction(vector, ppc_inst(save_vector)); patch_instruction((struct ppc_inst *)vector, ppc_inst(save_vector));
local_irq_restore(flags); local_irq_restore(flags);
if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347); if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
......
...@@ -100,7 +100,7 @@ static long *xmon_fault_jmp[NR_CPUS]; ...@@ -100,7 +100,7 @@ static long *xmon_fault_jmp[NR_CPUS];
/* Breakpoint stuff */ /* Breakpoint stuff */
struct bpt { struct bpt {
unsigned long address; unsigned long address;
unsigned int *instr; struct ppc_inst *instr;
atomic_t ref_count; atomic_t ref_count;
int enabled; int enabled;
unsigned long pad; unsigned long pad;
...@@ -876,8 +876,8 @@ static struct bpt *new_breakpoint(unsigned long a) ...@@ -876,8 +876,8 @@ static struct bpt *new_breakpoint(unsigned long a)
for (bp = bpts; bp < &bpts[NBPTS]; ++bp) { for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
if (!bp->enabled && atomic_read(&bp->ref_count) == 0) { if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
bp->address = a; bp->address = a;
bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS); bp->instr = (void *)(bpt_table + ((bp - bpts) * BPT_WORDS));
patch_instruction(bp->instr + 1, bpinstr); patch_instruction(bp->instr + 1, ppc_inst(bpinstr));
return bp; return bp;
} }
} }
...@@ -889,7 +889,7 @@ static struct bpt *new_breakpoint(unsigned long a) ...@@ -889,7 +889,7 @@ static struct bpt *new_breakpoint(unsigned long a)
static void insert_bpts(void) static void insert_bpts(void)
{ {
int i; int i;
unsigned int instr; struct ppc_inst instr;
struct bpt *bp; struct bpt *bp;
bp = bpts; bp = bpts;
...@@ -911,8 +911,8 @@ static void insert_bpts(void) ...@@ -911,8 +911,8 @@ static void insert_bpts(void)
patch_instruction(bp->instr, instr); patch_instruction(bp->instr, instr);
if (bp->enabled & BP_CIABR) if (bp->enabled & BP_CIABR)
continue; continue;
if (patch_instruction((unsigned int *)bp->address, if (patch_instruction((struct ppc_inst *)bp->address,
bpinstr) != 0) { ppc_inst(bpinstr)) != 0) {
printf("Couldn't write instruction at %lx, " printf("Couldn't write instruction at %lx, "
"disabling breakpoint there\n", bp->address); "disabling breakpoint there\n", bp->address);
bp->enabled &= ~BP_TRAP; bp->enabled &= ~BP_TRAP;
...@@ -940,7 +940,7 @@ static void remove_bpts(void) ...@@ -940,7 +940,7 @@ static void remove_bpts(void)
{ {
int i; int i;
struct bpt *bp; struct bpt *bp;
unsigned instr; struct ppc_inst instr;
bp = bpts; bp = bpts;
for (i = 0; i < NBPTS; ++i, ++bp) { for (i = 0; i < NBPTS; ++i, ++bp) {
...@@ -949,7 +949,7 @@ static void remove_bpts(void) ...@@ -949,7 +949,7 @@ static void remove_bpts(void)
if (mread(bp->address, &instr, 4) == 4 if (mread(bp->address, &instr, 4) == 4
&& ppc_inst_equal(instr, ppc_inst(bpinstr)) && ppc_inst_equal(instr, ppc_inst(bpinstr))
&& patch_instruction( && patch_instruction(
(unsigned int *)bp->address, bp->instr[0]) != 0) (struct ppc_inst *)bp->address, bp->instr[0]) != 0)
printf("Couldn't remove breakpoint at %lx\n", printf("Couldn't remove breakpoint at %lx\n",
bp->address); bp->address);
} }
...@@ -1156,7 +1156,7 @@ static int do_step(struct pt_regs *regs) ...@@ -1156,7 +1156,7 @@ static int do_step(struct pt_regs *regs)
*/ */
static int do_step(struct pt_regs *regs) static int do_step(struct pt_regs *regs)
{ {
unsigned int instr; struct ppc_inst instr;
int stepped; int stepped;
force_enable_xmon(); force_enable_xmon();
...@@ -1322,7 +1322,7 @@ csum(void) ...@@ -1322,7 +1322,7 @@ csum(void)
*/ */
static long check_bp_loc(unsigned long addr) static long check_bp_loc(unsigned long addr)
{ {
unsigned int instr; struct ppc_inst instr;
addr &= ~3; addr &= ~3;
if (!is_kernel_addr(addr)) { if (!is_kernel_addr(addr)) {
...@@ -2848,7 +2848,7 @@ generic_inst_dump(unsigned long adr, long count, int praddr, ...@@ -2848,7 +2848,7 @@ generic_inst_dump(unsigned long adr, long count, int praddr,
{ {
int nr, dotted; int nr, dotted;
unsigned long first_adr; unsigned long first_adr;
unsigned int inst, last_inst = ppc_inst(0); struct ppc_inst inst, last_inst = ppc_inst(0);
unsigned char val[4]; unsigned char val[4];
dotted = 0; dotted = 0;
......
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
#define NBPTS 256 #define NBPTS 256
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#define BPT_SIZE (sizeof(unsigned int) * 2) #include <asm/inst.h>
#define BPT_WORDS (BPT_SIZE / sizeof(unsigned int)) #define BPT_SIZE (sizeof(struct ppc_inst) * 2)
#define BPT_WORDS (BPT_SIZE / sizeof(struct ppc_inst))
extern unsigned int bpt_table[NBPTS * BPT_WORDS]; extern unsigned int bpt_table[NBPTS * BPT_WORDS];
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* XMON_BPTS_H */ #endif /* XMON_BPTS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment