[PATCH v2] ppc: use rfid when running under a CPU from the 970 family.

A recent attempt to restrict the use of rfi on 64bit cpus in qemu broke 32bit OpenBIOS when run under a 970. This patches memory to replace rfi instructions with rfid in the vector code. Signed-off-by: Cédric Le Goater <clg@kaod.org> Suggested-by: Alexander Graf <agraf@suse.de> --- Tested on qemu. arch/ppc/qemu/ofmem.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) Index: openbios.git/arch/ppc/qemu/ofmem.c =================================================================== --- openbios.git.orig/arch/ppc/qemu/ofmem.c +++ openbios.git/arch/ppc/qemu/ofmem.c @@ -478,6 +478,26 @@ isi_exception(void) hash_page(nip, phys, mode); } +/* When running on ppc64, we cannot use rfi anymore. Let's patch the + * vectors to use rfid instead. + */ +#define RFI 0x4c000064 +#define RFID 0x4c000024 + +static void patch_rfi(char *from, uint32_t len) +{ + int i; + + for (i = 0; i < len; i += 4) { + uint32_t* addr = (uint32_t *) (from + i); + if (*addr == RFI) + *addr = RFID; + } + flush_icache_range(from, from + len); +} + +extern char __vectors[]; +extern char __vectors_end[]; /************************************************************************/ /* init / cleanup */ @@ -532,6 +552,10 @@ setup_mmu(unsigned long ramsize) memcpy((void *)get_rom_base(), (void *)OF_CODE_START, OF_CODE_SIZE); + if (is_ppc64()) { + patch_rfi(0x0, (uint32_t) __vectors_end - (uint32_t) __vectors); + } + /* Enable MMU */ mtmsr(mfmsr() | MSR_IR | MSR_DR);

Am 21.06.2016 um 23:36 schrieb Cédric Le Goater <clg@kaod.org>:
A recent attempt to restrict the use of rfi on 64bit cpus in qemu broke 32bit OpenBIOS when run under a 970.
This patches memory to replace rfi instructions with rfid in the vector code.
Signed-off-by: Cédric Le Goater <clg@kaod.org> Suggested-by: Alexander Graf <agraf@suse.de> ---
Tested on qemu.
arch/ppc/qemu/ofmem.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
Index: openbios.git/arch/ppc/qemu/ofmem.c =================================================================== --- openbios.git.orig/arch/ppc/qemu/ofmem.c +++ openbios.git/arch/ppc/qemu/ofmem.c @@ -478,6 +478,26 @@ isi_exception(void) hash_page(nip, phys, mode); }
+/* When running on ppc64, we cannot use rfi anymore. Let's patch the + * vectors to use rfid instead. + */ +#define RFI 0x4c000064 +#define RFID 0x4c000024 + +static void patch_rfi(char *from, uint32_t len) +{ + int i; + + for (i = 0; i < len; i += 4) { + uint32_t* addr = (uint32_t *) (from + i);
If you use a uint32* here you can just increment by 1 ...
+ if (*addr == RFI) + *addr = RFID; + } + flush_icache_range(from, from + len); +} + +extern char __vectors[]; +extern char __vectors_end[];
And in fact you can just loop from vectors until ptr==vectors_end. uint32_t *ptr; for (ptr = __vectors; ptr != __vectors_end; ptr++)
/************************************************************************/ /* init / cleanup */ @@ -532,6 +552,10 @@ setup_mmu(unsigned long ramsize)
memcpy((void *)get_rom_base(), (void *)OF_CODE_START, OF_CODE_SIZE);
+ if (is_ppc64()) { + patch_rfi(0x0, (uint32_t) __vectors_end - (uint32_t) __vectors); + }
Just fold all of this together. Make patch_rfi have no parameters and just call it unconditionally. Then check for ppc64 in there. Alex
+ /* Enable MMU */
mtmsr(mfmsr() | MSR_IR | MSR_DR);

On 06/22/2016 06:50 AM, Alexander Graf wrote:
Am 21.06.2016 um 23:36 schrieb Cédric Le Goater <clg@kaod.org>:
A recent attempt to restrict the use of rfi on 64bit cpus in qemu broke 32bit OpenBIOS when run under a 970.
This patches memory to replace rfi instructions with rfid in the vector code.
Signed-off-by: Cédric Le Goater <clg@kaod.org> Suggested-by: Alexander Graf <agraf@suse.de> ---
Tested on qemu.
arch/ppc/qemu/ofmem.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
Index: openbios.git/arch/ppc/qemu/ofmem.c =================================================================== --- openbios.git.orig/arch/ppc/qemu/ofmem.c +++ openbios.git/arch/ppc/qemu/ofmem.c @@ -478,6 +478,26 @@ isi_exception(void) hash_page(nip, phys, mode); }
+/* When running on ppc64, we cannot use rfi anymore. Let's patch the + * vectors to use rfid instead. + */ +#define RFI 0x4c000064 +#define RFID 0x4c000024 + +static void patch_rfi(char *from, uint32_t len) +{ + int i; + + for (i = 0; i < len; i += 4) { + uint32_t* addr = (uint32_t *) (from + i);
If you use a uint32* here you can just increment by 1 ...
yes. I tried a couple of versions and that was the most friendly for the flush_icache_range.
+ if (*addr == RFI) + *addr = RFID; + } + flush_icache_range(from, from + len); +} + +extern char __vectors[]; +extern char __vectors_end[];
And in fact you can just loop from vectors until ptr==vectors_end.
uint32_t *ptr;
for (ptr = __vectors; ptr != __vectors_end; ptr++)
/************************************************************************/ /* init / cleanup */ @@ -532,6 +552,10 @@ setup_mmu(unsigned long ramsize)
memcpy((void *)get_rom_base(), (void *)OF_CODE_START, OF_CODE_SIZE);
+ if (is_ppc64()) { + patch_rfi(0x0, (uint32_t) __vectors_end - (uint32_t) __vectors); + }
Just fold all of this together. Make patch_rfi have no parameters and just call it unconditionally. Then check for ppc64 in there.
ok. v3 on the way. Thanks, C.
Alex
+ /* Enable MMU */
mtmsr(mfmsr() | MSR_IR | MSR_DR);

Am 22.06.2016 um 08:42 schrieb Cédric Le Goater <clg@kaod.org>:
On 06/22/2016 06:50 AM, Alexander Graf wrote:
Am 21.06.2016 um 23:36 schrieb Cédric Le Goater <clg@kaod.org>:
A recent attempt to restrict the use of rfi on 64bit cpus in qemu broke 32bit OpenBIOS when run under a 970.
This patches memory to replace rfi instructions with rfid in the vector code.
Signed-off-by: Cédric Le Goater <clg@kaod.org> Suggested-by: Alexander Graf <agraf@suse.de> ---
Tested on qemu.
arch/ppc/qemu/ofmem.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
Index: openbios.git/arch/ppc/qemu/ofmem.c =================================================================== --- openbios.git.orig/arch/ppc/qemu/ofmem.c +++ openbios.git/arch/ppc/qemu/ofmem.c @@ -478,6 +478,26 @@ isi_exception(void) hash_page(nip, phys, mode); }
+/* When running on ppc64, we cannot use rfi anymore. Let's patch the + * vectors to use rfid instead. + */ +#define RFI 0x4c000064 +#define RFID 0x4c000024 + +static void patch_rfi(char *from, uint32_t len) +{ + int i; + + for (i = 0; i < len; i += 4) { + uint32_t* addr = (uint32_t *) (from + i);
If you use a uint32* here you can just increment by 1 ...
yes. I tried a couple of versions and that was the most friendly for the flush_icache_range.
Just call it for every instruction :) Alex
+ if (*addr == RFI) + *addr = RFID; + } + flush_icache_range(from, from + len); +} + +extern char __vectors[]; +extern char __vectors_end[];
And in fact you can just loop from vectors until ptr==vectors_end.
uint32_t *ptr;
for (ptr = __vectors; ptr != __vectors_end; ptr++)
/************************************************************************/ /* init / cleanup */ @@ -532,6 +552,10 @@ setup_mmu(unsigned long ramsize)
memcpy((void *)get_rom_base(), (void *)OF_CODE_START, OF_CODE_SIZE);
+ if (is_ppc64()) { + patch_rfi(0x0, (uint32_t) __vectors_end - (uint32_t) __vectors); + }
Just fold all of this together. Make patch_rfi have no parameters and just call it unconditionally. Then check for ppc64 in there.
ok. v3 on the way.
Thanks,
C.
Alex
+ /* Enable MMU */
mtmsr(mfmsr() | MSR_IR | MSR_DR);

On 06/22/2016 06:50 AM, Alexander Graf wrote:
Am 21.06.2016 um 23:36 schrieb Cédric Le Goater <clg@kaod.org>:
A recent attempt to restrict the use of rfi on 64bit cpus in qemu broke 32bit OpenBIOS when run under a 970.
This patches memory to replace rfi instructions with rfid in the vector code.
Signed-off-by: Cédric Le Goater <clg@kaod.org> Suggested-by: Alexander Graf <agraf@suse.de> ---
Tested on qemu.
arch/ppc/qemu/ofmem.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
Index: openbios.git/arch/ppc/qemu/ofmem.c =================================================================== --- openbios.git.orig/arch/ppc/qemu/ofmem.c +++ openbios.git/arch/ppc/qemu/ofmem.c @@ -478,6 +478,26 @@ isi_exception(void) hash_page(nip, phys, mode); }
+/* When running on ppc64, we cannot use rfi anymore. Let's patch the + * vectors to use rfid instead. + */ +#define RFI 0x4c000064 +#define RFID 0x4c000024 + +static void patch_rfi(char *from, uint32_t len) +{ + int i; + + for (i = 0; i < len; i += 4) { + uint32_t* addr = (uint32_t *) (from + i);
If you use a uint32* here you can just increment by 1 ...
+ if (*addr == RFI) + *addr = RFID; + } + flush_icache_range(from, from + len); +} + +extern char __vectors[]; +extern char __vectors_end[];
And in fact you can just loop from vectors until ptr==vectors_end.
uint32_t *ptr;
for (ptr = __vectors; ptr != __vectors_end; ptr++)
ah, we can not do that, we need to patch the memory and not the rom, so [ 0, __vectors_end - __vectors] C.
/************************************************************************/ /* init / cleanup */ @@ -532,6 +552,10 @@ setup_mmu(unsigned long ramsize)
memcpy((void *)get_rom_base(), (void *)OF_CODE_START, OF_CODE_SIZE);
+ if (is_ppc64()) { + patch_rfi(0x0, (uint32_t) __vectors_end - (uint32_t) __vectors); + }
Just fold all of this together. Make patch_rfi have no parameters and just call it unconditionally. Then check for ppc64 in there.
Alex
+ /* Enable MMU */
mtmsr(mfmsr() | MSR_IR | MSR_DR);

Am 22.06.2016 um 09:08 schrieb Cédric Le Goater <clg@kaod.org>:
On 06/22/2016 06:50 AM, Alexander Graf wrote:
Am 21.06.2016 um 23:36 schrieb Cédric Le Goater <clg@kaod.org>:
A recent attempt to restrict the use of rfi on 64bit cpus in qemu broke 32bit OpenBIOS when run under a 970.
This patches memory to replace rfi instructions with rfid in the vector code.
Signed-off-by: Cédric Le Goater <clg@kaod.org> Suggested-by: Alexander Graf <agraf@suse.de> ---
Tested on qemu.
arch/ppc/qemu/ofmem.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
Index: openbios.git/arch/ppc/qemu/ofmem.c =================================================================== --- openbios.git.orig/arch/ppc/qemu/ofmem.c +++ openbios.git/arch/ppc/qemu/ofmem.c @@ -478,6 +478,26 @@ isi_exception(void) hash_page(nip, phys, mode); }
+/* When running on ppc64, we cannot use rfi anymore. Let's patch the + * vectors to use rfid instead. + */ +#define RFI 0x4c000064 +#define RFID 0x4c000024 + +static void patch_rfi(char *from, uint32_t len) +{ + int i; + + for (i = 0; i < len; i += 4) { + uint32_t* addr = (uint32_t *) (from + i);
If you use a uint32* here you can just increment by 1 ...
+ if (*addr == RFI) + *addr = RFID; + } + flush_icache_range(from, from + len); +} + +extern char __vectors[]; +extern char __vectors_end[];
And in fact you can just loop from vectors until ptr==vectors_end.
uint32_t *ptr;
for (ptr = __vectors; ptr != __vectors_end; ptr++)
ah, we can not do that, we need to patch the memory and not the rom, so [ 0, __vectors_end - __vectors]
Aaah, I see. Then your version makes more sense.
C.
/************************************************************************/ /* init / cleanup */ @@ -532,6 +552,10 @@ setup_mmu(unsigned long ramsize)
memcpy((void *)get_rom_base(), (void *)OF_CODE_START, OF_CODE_SIZE);
+ if (is_ppc64()) { + patch_rfi(0x0, (uint32_t) __vectors_end - (uint32_t) __vectors);
Please cast to uintptr_t instead though :) Alex
+ }
Just fold all of this together. Make patch_rfi have no parameters and just call it unconditionally. Then check for ppc64 in there.
Alex
+ /* Enable MMU */
mtmsr(mfmsr() | MSR_IR | MSR_DR);
participants (2)
-
Alexander Graf
-
Cédric Le Goater