diff options
Diffstat (limited to 'arch/powerpc/lib/code-patching.c')
-rw-r--r-- | arch/powerpc/lib/code-patching.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index 638dde313cbc..430f4c15d786 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c | |||
@@ -26,12 +26,18 @@ unsigned int create_branch(const unsigned int *addr, | |||
26 | unsigned long target, int flags) | 26 | unsigned long target, int flags) |
27 | { | 27 | { |
28 | unsigned int instruction; | 28 | unsigned int instruction; |
29 | long offset; | ||
29 | 30 | ||
31 | offset = target; | ||
30 | if (! (flags & BRANCH_ABSOLUTE)) | 32 | if (! (flags & BRANCH_ABSOLUTE)) |
31 | target = target - (unsigned long)addr; | 33 | offset = offset - (unsigned long)addr; |
34 | |||
35 | /* Check we can represent the target in the instruction format */ | ||
36 | if (offset < -0x2000000 || offset > 0x1fffffc || offset & 0x3) | ||
37 | return 0; | ||
32 | 38 | ||
33 | /* Mask out the flags and target, so they don't step on each other. */ | 39 | /* Mask out the flags and target, so they don't step on each other. */ |
34 | instruction = 0x48000000 | (flags & 0x3) | (target & 0x03FFFFFC); | 40 | instruction = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC); |
35 | 41 | ||
36 | return instruction; | 42 | return instruction; |
37 | } | 43 | } |