Commit 69d4d6e5 authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman
Browse files

powerpc: Don't use 'struct ppc_inst' to reference instruction location



'struct ppc_inst' is an internal representation of an instruction, but
in-memory instructions are and will remain a table of 'u32' forever.

Replace all 'struct ppc_inst *' used for locating an instruction in
memory by 'u32 *'. This removes a lot of undue casts to 'struct
ppc_inst *'.

It also helps locating ab-use of 'struct ppc_inst' dereference.

Signed-off-by: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
[mpe: Fix ppc_inst_next(), use u32 instead of unsigned int]
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/7062722b087228e42cbd896e39bfdf526d6a340a.1621516826.git.christophe.leroy@csgroup.eu
parent e90a21ea
Loading
Loading
Loading
Loading
+10 −11
Original line number Diff line number Diff line
@@ -23,13 +23,13 @@
#define BRANCH_ABSOLUTE	0x2

bool is_offset_in_branch_range(long offset);
int create_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
int create_branch(struct ppc_inst *instr, const u32 *addr,
		  unsigned long target, int flags);
int create_cond_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
int create_cond_branch(struct ppc_inst *instr, const u32 *addr,
		       unsigned long target, int flags);
int patch_branch(struct ppc_inst *addr, unsigned long target, int flags);
int patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
int raw_patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
int patch_branch(u32 *addr, unsigned long target, int flags);
int patch_instruction(u32 *addr, struct ppc_inst instr);
int raw_patch_instruction(u32 *addr, struct ppc_inst instr);

static inline unsigned long patch_site_addr(s32 *site)
{
@@ -38,18 +38,18 @@ static inline unsigned long patch_site_addr(s32 *site)

static inline int patch_instruction_site(s32 *site, struct ppc_inst instr)
{
	return patch_instruction((struct ppc_inst *)patch_site_addr(site), instr);
	return patch_instruction((u32 *)patch_site_addr(site), instr);
}

static inline int patch_branch_site(s32 *site, unsigned long target, int flags)
{
	return patch_branch((struct ppc_inst *)patch_site_addr(site), target, flags);
	return patch_branch((u32 *)patch_site_addr(site), target, flags);
}

static inline int modify_instruction(unsigned int *addr, unsigned int clr,
				     unsigned int set)
{
	return patch_instruction((struct ppc_inst *)addr, ppc_inst((*addr & ~clr) | set));
	return patch_instruction(addr, ppc_inst((*addr & ~clr) | set));
}

static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned int set)
@@ -59,9 +59,8 @@ static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned

int instr_is_relative_branch(struct ppc_inst instr);
int instr_is_relative_link_branch(struct ppc_inst instr);
unsigned long branch_target(const struct ppc_inst *instr);
int translate_branch(struct ppc_inst *instr, const struct ppc_inst *dest,
		     const struct ppc_inst *src);
unsigned long branch_target(const u32 *instr);
int translate_branch(struct ppc_inst *instr, const u32 *dest, const u32 *src);
extern bool is_conditional_branch(struct ppc_inst instr);
#ifdef CONFIG_PPC_BOOK3E_64
void __patch_exception(int exc, unsigned long addr);
+8 −8
Original line number Diff line number Diff line
@@ -80,13 +80,13 @@ static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
	return ppc_inst_prefix(swab32(ppc_inst_val(x)), swab32(ppc_inst_suffix(x)));
}

static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
static inline struct ppc_inst ppc_inst_read(const u32 *ptr)
{
	u32 val, suffix;

	val = *(u32 *)ptr;
	val = *ptr;
	if ((val >> 26) == OP_PREFIX) {
		suffix = *((u32 *)ptr + 1);
		suffix = *(ptr + 1);
		return ppc_inst_prefix(val, suffix);
	} else {
		return ppc_inst(val);
@@ -114,9 +114,9 @@ static inline struct ppc_inst ppc_inst_swab(struct ppc_inst x)
	return ppc_inst(swab32(ppc_inst_val(x)));
}

static inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr)
static inline struct ppc_inst ppc_inst_read(const u32 *ptr)
{
	return *ptr;
	return ppc_inst(*ptr);
}

#endif /* CONFIG_PPC64 */
@@ -139,13 +139,13 @@ static inline int ppc_inst_len(struct ppc_inst x)
 * Return the address of the next instruction, if the instruction @value was
 * located at @location.
 */
static inline struct ppc_inst *ppc_inst_next(void *location, struct ppc_inst *value)
static inline u32 *ppc_inst_next(u32 *location, u32 *value)
{
	struct ppc_inst tmp;

	tmp = ppc_inst_read(value);

	return location + ppc_inst_len(tmp);
	return (void *)location + ppc_inst_len(tmp);
}

static inline unsigned long ppc_inst_as_ulong(struct ppc_inst x)
@@ -177,6 +177,6 @@ static inline char *__ppc_inst_as_str(char str[PPC_INST_STR_LEN], struct ppc_ins
	__str;				\
})

int copy_inst_from_kernel_nofault(struct ppc_inst *inst, struct ppc_inst *src);
int copy_inst_from_kernel_nofault(struct ppc_inst *inst, u32 *src);

#endif /* _ASM_POWERPC_INST_H */
+2 −2
Original line number Diff line number Diff line
@@ -24,8 +24,8 @@ typedef ppc_opcode_t uprobe_opcode_t;

struct arch_uprobe {
	union {
		struct ppc_inst	insn;
		struct ppc_inst	ixol;
		u32 insn[2];
		u32 ixol[2];
	};
};

+2 −2
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ void __init reserve_kdump_trampoline(void)

static void __init create_trampoline(unsigned long addr)
{
	struct ppc_inst *p = (struct ppc_inst *)addr;
	u32 *p = (u32 *)addr;

	/* The maximum range of a single instruction branch, is the current
	 * instruction's address + (32 MB - 4) bytes. For the trampoline we
@@ -46,7 +46,7 @@ static void __init create_trampoline(unsigned long addr)
	 * two instructions it doesn't require any registers.
	 */
	patch_instruction(p, ppc_inst(PPC_RAW_NOP()));
	patch_branch((void *)p + 4, addr + PHYSICAL_START, 0);
	patch_branch(p + 1, addr + PHYSICAL_START, 0);
}

void __init setup_kdump_trampoline(void)
+2 −2
Original line number Diff line number Diff line
@@ -38,9 +38,9 @@ static int __init early_init_dt_scan_epapr(unsigned long node,

	for (i = 0; i < (len / 4); i++) {
		struct ppc_inst inst = ppc_inst(be32_to_cpu(insts[i]));
		patch_instruction((struct ppc_inst *)(epapr_hypercall_start + i), inst);
		patch_instruction(epapr_hypercall_start + i, inst);
#if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64)
		patch_instruction((struct ppc_inst *)(epapr_ev_idle_start + i), inst);
		patch_instruction(epapr_ev_idle_start + i, inst);
#endif
	}

Loading