diff mbox series

powerpc: Allow relative pointers in bug table entries

Message ID 20201127030238.763-1-jniethe5@gmail.com (mailing list archive)
State Changes Requested
Headers show
Series powerpc: Allow relative pointers in bug table entries | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success Successfully applied on branch powerpc/merge (4c202167192a77481310a3cacae9f12618b92216)
snowpatch_ozlabs/build-ppc64le success Build succeeded
snowpatch_ozlabs/build-ppc64be success Build succeeded
snowpatch_ozlabs/build-ppc64e success Build succeeded
snowpatch_ozlabs/build-pmac32 success Build succeeded
snowpatch_ozlabs/checkpatch warning total: 2 errors, 1 warnings, 0 checks, 110 lines checked
snowpatch_ozlabs/needsstable success Patch has no Fixes tags

Commit Message

Jordan Niethe Nov. 27, 2020, 3:02 a.m. UTC
This enables GENERIC_BUG_RELATIVE_POINTERS on Power so that 32-bit
offsets are stored in the bug entries rather than 64-bit pointers.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
 arch/powerpc/Kconfig           |  4 ++++
 arch/powerpc/include/asm/bug.h | 37 ++++++++++++++++++++++++++++++++--
 arch/powerpc/xmon/xmon.c       | 17 ++++++++++++++--
 3 files changed, 54 insertions(+), 4 deletions(-)

Comments

Christophe Leroy Nov. 28, 2020, 7 p.m. UTC | #1
Le 27/11/2020 à 04:02, Jordan Niethe a écrit :
> This enables GENERIC_BUG_RELATIVE_POINTERS on Power so that 32-bit
> offsets are stored in the bug entries rather than 64-bit pointers.
> 
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
>   arch/powerpc/Kconfig           |  4 ++++
>   arch/powerpc/include/asm/bug.h | 37 ++++++++++++++++++++++++++++++++--
>   arch/powerpc/xmon/xmon.c       | 17 ++++++++++++++--
>   3 files changed, 54 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index e9f13fe08492..294108e0e5c6 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -311,6 +311,10 @@ config GENERIC_BUG
>   	default y
>   	depends on BUG
>   
> +config GENERIC_BUG_RELATIVE_POINTERS
> +	def_bool y
> +	depends on GENERIC_BUG
> +
>   config SYS_SUPPORTS_APM_EMULATION
>   	default y if PMAC_APM_EMU
>   	bool
> diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
> index 338f36cd9934..d03d834042a1 100644
> --- a/arch/powerpc/include/asm/bug.h
> +++ b/arch/powerpc/include/asm/bug.h
> @@ -12,7 +12,11 @@
>   #ifdef CONFIG_DEBUG_BUGVERBOSE
>   .macro EMIT_BUG_ENTRY addr,file,line,flags
>   	 .section __bug_table,"aw"
> +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS

As far as I understand, as soon as CONFIG_BUG is selected, GENERIC_BUG is automatically selected so 
GENERIC_BUG_RELATIVE_POINTERS is selected as well. Therefore this #ifndef is never possible.

>   5001:	 PPC_LONG \addr, 5002f
> +#else
> +5001:	 .4byte \addr - 5001b, 5002f - 5001b
> +#endif /* CONFIG_GENERIC_BUG_RELATIVE_POINTERS */
>   	 .short \line, \flags
>   	 .org 5001b+BUG_ENTRY_SIZE
>   	 .previous
> @@ -23,7 +27,11 @@
>   #else
>   .macro EMIT_BUG_ENTRY addr,file,line,flags
>   	 .section __bug_table,"aw"
> +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS

Same

>   5001:	 PPC_LONG \addr
> +#else
> +5001:	 .4byte \addr - 5001b
> +#endif /* CONFIG_GENERIC_BUG_RELATIVE_POINTERS */
>   	 .short \flags
>   	 .org 5001b+BUG_ENTRY_SIZE
>   	 .previous
> @@ -34,20 +42,45 @@
>   /* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and
>      sizeof(struct bug_entry), respectively */
>   #ifdef CONFIG_DEBUG_BUGVERBOSE
> +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS

Same

>   #define _EMIT_BUG_ENTRY				\
>   	".section __bug_table,\"aw\"\n"		\
>   	"2:\t" PPC_LONG "1b, %0\n"		\
>   	"\t.short %1, %2\n"			\
>   	".org 2b+%3\n"				\
>   	".previous\n"
> -#else
> +
> +#else /* relative pointers */
> +
> +#define _EMIT_BUG_ENTRY				\
> +	".section __bug_table,\"aw\"\n"		\
> +	"2:\t.4byte 1b - 2b, %0 - 2b\n"		\
> +	"\t.short %1, %2\n"			\
> +	".org 2b+%3\n"				\
> +	".previous\n"
> +#endif /* relative pointers */
> +
> +#else /* verbose */
> +
> +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS

Same

>   #define _EMIT_BUG_ENTRY				\
>   	".section __bug_table,\"aw\"\n"		\
>   	"2:\t" PPC_LONG "1b\n"			\
>   	"\t.short %2\n"				\
>   	".org 2b+%3\n"				\
>   	".previous\n"
> -#endif
> +
> +#else /* relative pointers */
> +
> +#define _EMIT_BUG_ENTRY				\
> +	".section __bug_table,\"aw\"\n"		\
> +	"2:\t.4byte 1b - 2b\n"		\
> +	"\t.short %2\n"				\
> +	".org 2b+%3\n"				\
> +	".previous\n"
> +
> +#endif /* relative pointers */
> +#endif /* verbose */
>   
>   #define BUG_ENTRY(insn, flags, ...)			\
>   	__asm__ __volatile__(				\
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index 55c43a6c9111..5f7cf7e95767 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -1731,6 +1731,9 @@ static void print_bug_trap(struct pt_regs *regs)
>   #ifdef CONFIG_BUG
>   	const struct bug_entry *bug;
>   	unsigned long addr;
> +#ifdef CONFIG_DEBUG_BUGVERBOSE
> +	char *file;
> +#endif
>   
>   	if (regs->msr & MSR_PR)
>   		return;		/* not in kernel */
> @@ -1744,10 +1747,20 @@ static void print_bug_trap(struct pt_regs *regs)
>   		return;
>   
>   #ifdef CONFIG_DEBUG_BUGVERBOSE
> +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS

Same

> +	file = bug->file;
> +#else /* relative pointers */
> +	file = (char *)bug + bug->file_disp;
> +#endif /* relative pointers */
>   	printf("kernel BUG at %s:%u!\n",
> -	       bug->file, bug->line);
> +	       file, bug->line);
>   #else
> -	printf("kernel BUG at %px!\n", (void *)bug->bug_addr);
> +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS

Same

> +	addr = bug->addr;
> +#else /* relative pointers */
> +	addr = (unsigned long)bug + bug->bug_addr_disp;
> +#endif /* relative pointers */
> +	printf("kernel BUG at %px!\n", (void *)addr);
>   #endif
>   #endif /* CONFIG_BUG */
>   }
> 

Christophe
Jordan Niethe Nov. 30, 2020, 12:59 a.m. UTC | #2
On Sun, Nov 29, 2020 at 6:00 AM Christophe Leroy
<christophe.leroy@csgroup.eu> wrote:
>
>
>
> Le 27/11/2020 à 04:02, Jordan Niethe a écrit :
> > This enables GENERIC_BUG_RELATIVE_POINTERS on Power so that 32-bit
> > offsets are stored in the bug entries rather than 64-bit pointers.
> >
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > ---
> >   arch/powerpc/Kconfig           |  4 ++++
> >   arch/powerpc/include/asm/bug.h | 37 ++++++++++++++++++++++++++++++++--
> >   arch/powerpc/xmon/xmon.c       | 17 ++++++++++++++--
> >   3 files changed, 54 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> > index e9f13fe08492..294108e0e5c6 100644
> > --- a/arch/powerpc/Kconfig
> > +++ b/arch/powerpc/Kconfig
> > @@ -311,6 +311,10 @@ config GENERIC_BUG
> >       default y
> >       depends on BUG
> >
> > +config GENERIC_BUG_RELATIVE_POINTERS
> > +     def_bool y
> > +     depends on GENERIC_BUG
> > +
> >   config SYS_SUPPORTS_APM_EMULATION
> >       default y if PMAC_APM_EMU
> >       bool
> > diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
> > index 338f36cd9934..d03d834042a1 100644
> > --- a/arch/powerpc/include/asm/bug.h
> > +++ b/arch/powerpc/include/asm/bug.h
> > @@ -12,7 +12,11 @@
> >   #ifdef CONFIG_DEBUG_BUGVERBOSE
> >   .macro EMIT_BUG_ENTRY addr,file,line,flags
> >        .section __bug_table,"aw"
> > +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
>
> As far as I understand, as soon as CONFIG_BUG is selected, GENERIC_BUG is automatically selected so
> GENERIC_BUG_RELATIVE_POINTERS is selected as well. Therefore this #ifndef is never possible.
Thanks, you are right. I'll fix that up.
>
> >   5001:        PPC_LONG \addr, 5002f
> > +#else
> > +5001:         .4byte \addr - 5001b, 5002f - 5001b
> > +#endif /* CONFIG_GENERIC_BUG_RELATIVE_POINTERS */
> >        .short \line, \flags
> >        .org 5001b+BUG_ENTRY_SIZE
> >        .previous
> > @@ -23,7 +27,11 @@
> >   #else
> >   .macro EMIT_BUG_ENTRY addr,file,line,flags
> >        .section __bug_table,"aw"
> > +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
>
> Same
>
> >   5001:        PPC_LONG \addr
> > +#else
> > +5001:         .4byte \addr - 5001b
> > +#endif /* CONFIG_GENERIC_BUG_RELATIVE_POINTERS */
> >        .short \flags
> >        .org 5001b+BUG_ENTRY_SIZE
> >        .previous
> > @@ -34,20 +42,45 @@
> >   /* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and
> >      sizeof(struct bug_entry), respectively */
> >   #ifdef CONFIG_DEBUG_BUGVERBOSE
> > +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
>
> Same
>
> >   #define _EMIT_BUG_ENTRY                             \
> >       ".section __bug_table,\"aw\"\n"         \
> >       "2:\t" PPC_LONG "1b, %0\n"              \
> >       "\t.short %1, %2\n"                     \
> >       ".org 2b+%3\n"                          \
> >       ".previous\n"
> > -#else
> > +
> > +#else /* relative pointers */
> > +
> > +#define _EMIT_BUG_ENTRY                              \
> > +     ".section __bug_table,\"aw\"\n"         \
> > +     "2:\t.4byte 1b - 2b, %0 - 2b\n"         \
> > +     "\t.short %1, %2\n"                     \
> > +     ".org 2b+%3\n"                          \
> > +     ".previous\n"
> > +#endif /* relative pointers */
> > +
> > +#else /* verbose */
> > +
> > +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
>
> Same
>
> >   #define _EMIT_BUG_ENTRY                             \
> >       ".section __bug_table,\"aw\"\n"         \
> >       "2:\t" PPC_LONG "1b\n"                  \
> >       "\t.short %2\n"                         \
> >       ".org 2b+%3\n"                          \
> >       ".previous\n"
> > -#endif
> > +
> > +#else /* relative pointers */
> > +
> > +#define _EMIT_BUG_ENTRY                              \
> > +     ".section __bug_table,\"aw\"\n"         \
> > +     "2:\t.4byte 1b - 2b\n"          \
> > +     "\t.short %2\n"                         \
> > +     ".org 2b+%3\n"                          \
> > +     ".previous\n"
> > +
> > +#endif /* relative pointers */
> > +#endif /* verbose */
> >
> >   #define BUG_ENTRY(insn, flags, ...)                 \
> >       __asm__ __volatile__(                           \
> > diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> > index 55c43a6c9111..5f7cf7e95767 100644
> > --- a/arch/powerpc/xmon/xmon.c
> > +++ b/arch/powerpc/xmon/xmon.c
> > @@ -1731,6 +1731,9 @@ static void print_bug_trap(struct pt_regs *regs)
> >   #ifdef CONFIG_BUG
> >       const struct bug_entry *bug;
> >       unsigned long addr;
> > +#ifdef CONFIG_DEBUG_BUGVERBOSE
> > +     char *file;
> > +#endif
> >
> >       if (regs->msr & MSR_PR)
> >               return;         /* not in kernel */
> > @@ -1744,10 +1747,20 @@ static void print_bug_trap(struct pt_regs *regs)
> >               return;
> >
> >   #ifdef CONFIG_DEBUG_BUGVERBOSE
> > +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
>
> Same
>
> > +     file = bug->file;
> > +#else /* relative pointers */
> > +     file = (char *)bug + bug->file_disp;
> > +#endif /* relative pointers */
> >       printf("kernel BUG at %s:%u!\n",
> > -            bug->file, bug->line);
> > +            file, bug->line);
> >   #else
> > -     printf("kernel BUG at %px!\n", (void *)bug->bug_addr);
> > +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
>
> Same
>
> > +     addr = bug->addr;
> > +#else /* relative pointers */
> > +     addr = (unsigned long)bug + bug->bug_addr_disp;
> > +#endif /* relative pointers */
> > +     printf("kernel BUG at %px!\n", (void *)addr);
> >   #endif
> >   #endif /* CONFIG_BUG */
> >   }
> >
>
> Christophe
Michael Ellerman Nov. 30, 2020, 1:42 a.m. UTC | #3
Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> Le 27/11/2020 à 04:02, Jordan Niethe a écrit :
>> This enables GENERIC_BUG_RELATIVE_POINTERS on Power so that 32-bit
>> offsets are stored in the bug entries rather than 64-bit pointers.
>> 
>> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
>> ---
>>   arch/powerpc/Kconfig           |  4 ++++
>>   arch/powerpc/include/asm/bug.h | 37 ++++++++++++++++++++++++++++++++--
>>   arch/powerpc/xmon/xmon.c       | 17 ++++++++++++++--
>>   3 files changed, 54 insertions(+), 4 deletions(-)
>> 
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index e9f13fe08492..294108e0e5c6 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -311,6 +311,10 @@ config GENERIC_BUG
>>   	default y
>>   	depends on BUG
>>   
>> +config GENERIC_BUG_RELATIVE_POINTERS
>> +	def_bool y
>> +	depends on GENERIC_BUG
>> +
>>   config SYS_SUPPORTS_APM_EMULATION
>>   	default y if PMAC_APM_EMU
>>   	bool
>> diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
>> index 338f36cd9934..d03d834042a1 100644
>> --- a/arch/powerpc/include/asm/bug.h
>> +++ b/arch/powerpc/include/asm/bug.h
>> @@ -12,7 +12,11 @@
>>   #ifdef CONFIG_DEBUG_BUGVERBOSE
>>   .macro EMIT_BUG_ENTRY addr,file,line,flags
>>   	 .section __bug_table,"aw"
>> +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
>
> As far as I understand, as soon as CONFIG_BUG is selected, GENERIC_BUG is automatically selected so 
> GENERIC_BUG_RELATIVE_POINTERS is selected as well. Therefore this #ifndef is never possible.

Yeah.

There is one place in the generic code that has an ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
but that's because it has to support arches that don't select it.

In the arch code we know that it's enabled, so there should be no need
for any ifdefs.

cheers
Jordan Niethe Nov. 30, 2020, 1:50 a.m. UTC | #4
On Mon, Nov 30, 2020 at 12:42 PM Michael Ellerman <mpe@ellerman.id.au> wrote:
>
> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> > Le 27/11/2020 à 04:02, Jordan Niethe a écrit :
> >> This enables GENERIC_BUG_RELATIVE_POINTERS on Power so that 32-bit
> >> offsets are stored in the bug entries rather than 64-bit pointers.
> >>
> >> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> >> ---
> >>   arch/powerpc/Kconfig           |  4 ++++
> >>   arch/powerpc/include/asm/bug.h | 37 ++++++++++++++++++++++++++++++++--
> >>   arch/powerpc/xmon/xmon.c       | 17 ++++++++++++++--
> >>   3 files changed, 54 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> >> index e9f13fe08492..294108e0e5c6 100644
> >> --- a/arch/powerpc/Kconfig
> >> +++ b/arch/powerpc/Kconfig
> >> @@ -311,6 +311,10 @@ config GENERIC_BUG
> >>      default y
> >>      depends on BUG
> >>
> >> +config GENERIC_BUG_RELATIVE_POINTERS
> >> +    def_bool y
> >> +    depends on GENERIC_BUG
> >> +
> >>   config SYS_SUPPORTS_APM_EMULATION
> >>      default y if PMAC_APM_EMU
> >>      bool
> >> diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
> >> index 338f36cd9934..d03d834042a1 100644
> >> --- a/arch/powerpc/include/asm/bug.h
> >> +++ b/arch/powerpc/include/asm/bug.h
> >> @@ -12,7 +12,11 @@
> >>   #ifdef CONFIG_DEBUG_BUGVERBOSE
> >>   .macro EMIT_BUG_ENTRY addr,file,line,flags
> >>       .section __bug_table,"aw"
> >> +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
> >
> > As far as I understand, as soon as CONFIG_BUG is selected, GENERIC_BUG is automatically selected so
> > GENERIC_BUG_RELATIVE_POINTERS is selected as well. Therefore this #ifndef is never possible.
>
> Yeah.
>
> There is one place in the generic code that has an ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
> but that's because it has to support arches that don't select it.
>
> In the arch code we know that it's enabled, so there should be no need
> for any ifdefs.
For 32bit, pointers are 4 bytes anyway so it would be pointless to
store a displacement, so won't we need some ifdefs for that?
>
> cheers
Christophe Leroy Nov. 30, 2020, 6:27 a.m. UTC | #5
Le 30/11/2020 à 02:50, Jordan Niethe a écrit :
> On Mon, Nov 30, 2020 at 12:42 PM Michael Ellerman <mpe@ellerman.id.au> wrote:
>>
>> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>>> Le 27/11/2020 à 04:02, Jordan Niethe a écrit :
>>>> This enables GENERIC_BUG_RELATIVE_POINTERS on Power so that 32-bit
>>>> offsets are stored in the bug entries rather than 64-bit pointers.
>>>>
>>>> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
>>>> ---
>>>>    arch/powerpc/Kconfig           |  4 ++++
>>>>    arch/powerpc/include/asm/bug.h | 37 ++++++++++++++++++++++++++++++++--
>>>>    arch/powerpc/xmon/xmon.c       | 17 ++++++++++++++--
>>>>    3 files changed, 54 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>>>> index e9f13fe08492..294108e0e5c6 100644
>>>> --- a/arch/powerpc/Kconfig
>>>> +++ b/arch/powerpc/Kconfig
>>>> @@ -311,6 +311,10 @@ config GENERIC_BUG
>>>>       default y
>>>>       depends on BUG
>>>>
>>>> +config GENERIC_BUG_RELATIVE_POINTERS
>>>> +    def_bool y
>>>> +    depends on GENERIC_BUG
>>>> +
>>>>    config SYS_SUPPORTS_APM_EMULATION
>>>>       default y if PMAC_APM_EMU
>>>>       bool
>>>> diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
>>>> index 338f36cd9934..d03d834042a1 100644
>>>> --- a/arch/powerpc/include/asm/bug.h
>>>> +++ b/arch/powerpc/include/asm/bug.h
>>>> @@ -12,7 +12,11 @@
>>>>    #ifdef CONFIG_DEBUG_BUGVERBOSE
>>>>    .macro EMIT_BUG_ENTRY addr,file,line,flags
>>>>        .section __bug_table,"aw"
>>>> +#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
>>>
>>> As far as I understand, as soon as CONFIG_BUG is selected, GENERIC_BUG is automatically selected so
>>> GENERIC_BUG_RELATIVE_POINTERS is selected as well. Therefore this #ifndef is never possible.
>>
>> Yeah.
>>
>> There is one place in the generic code that has an ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
>> but that's because it has to support arches that don't select it.
>>
>> In the arch code we know that it's enabled, so there should be no need
>> for any ifdefs.
> For 32bit, pointers are 4 bytes anyway so it would be pointless to
> store a displacement, so won't we need some ifdefs for that?

I'd say it the other way round:

For 32bit, pointers are 4 bytes anyway so it would be pointless to
make it different from 64bit.

We are definitely not on a performance critical path when dealing with bug entries, so I think it is 
better to keep a common code for PPC32 and PPC64.

Christophe
diff mbox series

Patch

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index e9f13fe08492..294108e0e5c6 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -311,6 +311,10 @@  config GENERIC_BUG
 	default y
 	depends on BUG
 
+config GENERIC_BUG_RELATIVE_POINTERS
+	def_bool y
+	depends on GENERIC_BUG
+
 config SYS_SUPPORTS_APM_EMULATION
 	default y if PMAC_APM_EMU
 	bool
diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
index 338f36cd9934..d03d834042a1 100644
--- a/arch/powerpc/include/asm/bug.h
+++ b/arch/powerpc/include/asm/bug.h
@@ -12,7 +12,11 @@ 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 .macro EMIT_BUG_ENTRY addr,file,line,flags
 	 .section __bug_table,"aw"
+#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
 5001:	 PPC_LONG \addr, 5002f
+#else
+5001:	 .4byte \addr - 5001b, 5002f - 5001b
+#endif /* CONFIG_GENERIC_BUG_RELATIVE_POINTERS */
 	 .short \line, \flags
 	 .org 5001b+BUG_ENTRY_SIZE
 	 .previous
@@ -23,7 +27,11 @@ 
 #else
 .macro EMIT_BUG_ENTRY addr,file,line,flags
 	 .section __bug_table,"aw"
+#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
 5001:	 PPC_LONG \addr
+#else
+5001:	 .4byte \addr - 5001b
+#endif /* CONFIG_GENERIC_BUG_RELATIVE_POINTERS */
 	 .short \flags
 	 .org 5001b+BUG_ENTRY_SIZE
 	 .previous
@@ -34,20 +42,45 @@ 
 /* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and
    sizeof(struct bug_entry), respectively */
 #ifdef CONFIG_DEBUG_BUGVERBOSE
+#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
 #define _EMIT_BUG_ENTRY				\
 	".section __bug_table,\"aw\"\n"		\
 	"2:\t" PPC_LONG "1b, %0\n"		\
 	"\t.short %1, %2\n"			\
 	".org 2b+%3\n"				\
 	".previous\n"
-#else
+
+#else /* relative pointers */
+
+#define _EMIT_BUG_ENTRY				\
+	".section __bug_table,\"aw\"\n"		\
+	"2:\t.4byte 1b - 2b, %0 - 2b\n"		\
+	"\t.short %1, %2\n"			\
+	".org 2b+%3\n"				\
+	".previous\n"
+#endif /* relative pointers */
+
+#else /* verbose */
+
+#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
 #define _EMIT_BUG_ENTRY				\
 	".section __bug_table,\"aw\"\n"		\
 	"2:\t" PPC_LONG "1b\n"			\
 	"\t.short %2\n"				\
 	".org 2b+%3\n"				\
 	".previous\n"
-#endif
+
+#else /* relative pointers */
+
+#define _EMIT_BUG_ENTRY				\
+	".section __bug_table,\"aw\"\n"		\
+	"2:\t.4byte 1b - 2b\n"		\
+	"\t.short %2\n"				\
+	".org 2b+%3\n"				\
+	".previous\n"
+
+#endif /* relative pointers */
+#endif /* verbose */
 
 #define BUG_ENTRY(insn, flags, ...)			\
 	__asm__ __volatile__(				\
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 55c43a6c9111..5f7cf7e95767 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1731,6 +1731,9 @@  static void print_bug_trap(struct pt_regs *regs)
 #ifdef CONFIG_BUG
 	const struct bug_entry *bug;
 	unsigned long addr;
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+	char *file;
+#endif
 
 	if (regs->msr & MSR_PR)
 		return;		/* not in kernel */
@@ -1744,10 +1747,20 @@  static void print_bug_trap(struct pt_regs *regs)
 		return;
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
+#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
+	file = bug->file;
+#else /* relative pointers */
+	file = (char *)bug + bug->file_disp;
+#endif /* relative pointers */
 	printf("kernel BUG at %s:%u!\n",
-	       bug->file, bug->line);
+	       file, bug->line);
 #else
-	printf("kernel BUG at %px!\n", (void *)bug->bug_addr);
+#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
+	addr = bug->addr;
+#else /* relative pointers */
+	addr = (unsigned long)bug + bug->bug_addr_disp;
+#endif /* relative pointers */
+	printf("kernel BUG at %px!\n", (void *)addr);
 #endif
 #endif /* CONFIG_BUG */
 }