Skip to content

Commit 9d9fa23

Browse files
jrtc27davem330
authored andcommitted
sparc: Handle negative offsets in arch_jump_label_transform
Additionally, if the offset will overflow the immediate for a ba,pt instruction, fall back on a standard ba to get an extra 3 bits. Signed-off-by: James Clarke <jrtc27@jrtc27.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent b429ae4 commit 9d9fa23

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

arch/sparc/kernel/jump_label.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,30 @@
1313
void arch_jump_label_transform(struct jump_entry *entry,
1414
enum jump_label_type type)
1515
{
16-
u32 val;
1716
u32 *insn = (u32 *) (unsigned long) entry->code;
17+
u32 val;
1818

1919
if (type == JUMP_LABEL_JMP) {
2020
s32 off = (s32)entry->target - (s32)entry->code;
21+
bool use_v9_branch = false;
22+
23+
BUG_ON(off & 3);
2124

2225
#ifdef CONFIG_SPARC64
23-
/* ba,pt %xcc, . + (off << 2) */
24-
val = 0x10680000 | ((u32) off >> 2);
25-
#else
26-
/* ba . + (off << 2) */
27-
val = 0x10800000 | ((u32) off >> 2);
26+
if (off <= 0xfffff && off >= -0x100000)
27+
use_v9_branch = true;
2828
#endif
29+
if (use_v9_branch) {
30+
/* WDISP19 - target is . + immed << 2 */
31+
/* ba,pt %xcc, . + off */
32+
val = 0x10680000 | (((u32) off >> 2) & 0x7ffff);
33+
} else {
34+
/* WDISP22 - target is . + immed << 2 */
35+
BUG_ON(off > 0x7fffff);
36+
BUG_ON(off < -0x800000);
37+
/* ba . + off */
38+
val = 0x10800000 | (((u32) off >> 2) & 0x3fffff);
39+
}
2940
} else {
3041
val = 0x01000000;
3142
}

0 commit comments

Comments
 (0)