Skip to content

Commit

Permalink
Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
Browse files Browse the repository at this point in the history
Pull ARM fixes from Russell King:

 - Fix latent bug with DC21285 (Footbridge PCI bridge) configuration
   accessors that affects GCC >= 4.9.2

 - Fix misplaced tegra_uart_config in decompressor

 - Ensure signal page contents are initialised

 - Fix kexec oops

* tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm:
  ARM: kexec: fix oops after TLB are invalidated
  ARM: ensure the signal page contains defined contents
  ARM: 9043/1: tegra: Fix misplaced tegra_uart_config in decompressor
  ARM: footbridge: fix dc21285 PCI configuration accessors
  • Loading branch information
torvalds committed Feb 6, 2021
2 parents 368afec + 4d62e81 commit 4a7859e
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 78 deletions.
12 changes: 12 additions & 0 deletions arch/arm/include/asm/kexec-internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ARM_KEXEC_INTERNAL_H
#define _ARM_KEXEC_INTERNAL_H

struct kexec_relocate_data {
unsigned long kexec_start_address;
unsigned long kexec_indirection_page;
unsigned long kexec_mach_type;
unsigned long kexec_r2;
};

#endif
54 changes: 27 additions & 27 deletions arch/arm/include/debug/tegra.S
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,34 @@

.align
99: .word .
#if defined(ZIMAGE)
.word . + 4
/*
* Storage for the state maintained by the macro.
*
* In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c.
* That's because this header is included from multiple files, and we only
* want a single copy of the data. In particular, the UART probing code above
* assumes it's running using physical addresses. This is true when this file
* is included from head.o, but not when included from debug.o. So we need
* to share the probe results between the two copies, rather than having
* to re-run the probing again later.
*
* In the decompressor, we put the storage right here, since common.c
* isn't included in the decompressor build. This storage data gets put in
* .text even though it's really data, since .data is discarded from the
* decompressor. Luckily, .text is writeable in the decompressor, unless
* CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug.
*/
/* Debug UART initialization required */
.word 1
/* Debug UART physical address */
.word 0
/* Debug UART virtual address */
.word 0
#else
.word tegra_uart_config
#endif
.ltorg

/* Load previously selected UART address */
Expand Down Expand Up @@ -189,30 +216,3 @@

.macro waituarttxrdy,rd,rx
.endm

/*
* Storage for the state maintained by the macros above.
*
* In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c.
* That's because this header is included from multiple files, and we only
* want a single copy of the data. In particular, the UART probing code above
* assumes it's running using physical addresses. This is true when this file
* is included from head.o, but not when included from debug.o. So we need
* to share the probe results between the two copies, rather than having
* to re-run the probing again later.
*
* In the decompressor, we put the symbol/storage right here, since common.c
* isn't included in the decompressor build. This symbol gets put in .text
* even though it's really data, since .data is discarded from the
* decompressor. Luckily, .text is writeable in the decompressor, unless
* CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug.
*/
#if defined(ZIMAGE)
tegra_uart_config:
/* Debug UART initialization required */
.word 1
/* Debug UART physical address */
.word 0
/* Debug UART virtual address */
.word 0
#endif
5 changes: 5 additions & 0 deletions arch/arm/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <linux/mm.h>
#include <linux/dma-mapping.h>
#include <asm/cacheflush.h>
#include <asm/kexec-internal.h>
#include <asm/glue-df.h>
#include <asm/glue-pf.h>
#include <asm/mach/arch.h>
Expand Down Expand Up @@ -170,5 +171,9 @@ int main(void)
DEFINE(MPU_RGN_PRBAR, offsetof(struct mpu_rgn, prbar));
DEFINE(MPU_RGN_PRLAR, offsetof(struct mpu_rgn, prlar));
#endif
DEFINE(KEXEC_START_ADDR, offsetof(struct kexec_relocate_data, kexec_start_address));
DEFINE(KEXEC_INDIR_PAGE, offsetof(struct kexec_relocate_data, kexec_indirection_page));
DEFINE(KEXEC_MACH_TYPE, offsetof(struct kexec_relocate_data, kexec_mach_type));
DEFINE(KEXEC_R2, offsetof(struct kexec_relocate_data, kexec_r2));
return 0;
}
20 changes: 8 additions & 12 deletions arch/arm/kernel/machine_kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <linux/of_fdt.h>
#include <asm/mmu_context.h>
#include <asm/cacheflush.h>
#include <asm/kexec-internal.h>
#include <asm/fncpy.h>
#include <asm/mach-types.h>
#include <asm/smp_plat.h>
Expand All @@ -22,11 +23,6 @@
extern void relocate_new_kernel(void);
extern const unsigned int relocate_new_kernel_size;

extern unsigned long kexec_start_address;
extern unsigned long kexec_indirection_page;
extern unsigned long kexec_mach_type;
extern unsigned long kexec_boot_atags;

static atomic_t waiting_for_crash_ipi;

/*
Expand Down Expand Up @@ -159,6 +155,7 @@ void (*kexec_reinit)(void);
void machine_kexec(struct kimage *image)
{
unsigned long page_list, reboot_entry_phys;
struct kexec_relocate_data *data;
void (*reboot_entry)(void);
void *reboot_code_buffer;

Expand All @@ -174,18 +171,17 @@ void machine_kexec(struct kimage *image)

reboot_code_buffer = page_address(image->control_code_page);

/* Prepare parameters for reboot_code_buffer*/
set_kernel_text_rw();
kexec_start_address = image->start;
kexec_indirection_page = page_list;
kexec_mach_type = machine_arch_type;
kexec_boot_atags = image->arch.kernel_r2;

/* copy our kernel relocation code to the control code page */
reboot_entry = fncpy(reboot_code_buffer,
&relocate_new_kernel,
relocate_new_kernel_size);

data = reboot_code_buffer + relocate_new_kernel_size;
data->kexec_start_address = image->start;
data->kexec_indirection_page = page_list;
data->kexec_mach_type = machine_arch_type;
data->kexec_r2 = image->arch.kernel_r2;

/* get the identity mapping physical address for the reboot code */
reboot_entry_phys = virt_to_idmap(reboot_entry);

Expand Down
38 changes: 11 additions & 27 deletions arch/arm/kernel/relocate_kernel.S
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@

#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/kexec.h>

.align 3 /* not needed for this code, but keeps fncpy() happy */

ENTRY(relocate_new_kernel)

ldr r0,kexec_indirection_page
ldr r1,kexec_start_address
adr r7, relocate_new_kernel_end
ldr r0, [r7, #KEXEC_INDIR_PAGE]
ldr r1, [r7, #KEXEC_START_ADDR]

/*
* If there is no indirection page (we are doing crashdumps)
Expand Down Expand Up @@ -57,34 +59,16 @@ ENTRY(relocate_new_kernel)

2:
/* Jump to relocated kernel */
mov lr,r1
mov r0,#0
ldr r1,kexec_mach_type
ldr r2,kexec_boot_atags
ARM( ret lr )
THUMB( bx lr )

.align

.globl kexec_start_address
kexec_start_address:
.long 0x0

.globl kexec_indirection_page
kexec_indirection_page:
.long 0x0

.globl kexec_mach_type
kexec_mach_type:
.long 0x0

/* phy addr of the atags for the new kernel */
.globl kexec_boot_atags
kexec_boot_atags:
.long 0x0
mov lr, r1
mov r0, #0
ldr r1, [r7, #KEXEC_MACH_TYPE]
ldr r2, [r7, #KEXEC_R2]
ARM( ret lr )
THUMB( bx lr )

ENDPROC(relocate_new_kernel)

.align 3
relocate_new_kernel_end:

.globl relocate_new_kernel_size
Expand Down
14 changes: 8 additions & 6 deletions arch/arm/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -693,18 +693,20 @@ struct page *get_signal_page(void)

addr = page_address(page);

/* Poison the entire page */
memset32(addr, __opcode_to_mem_arm(0xe7fddef1),
PAGE_SIZE / sizeof(u32));

/* Give the signal return code some randomness */
offset = 0x200 + (get_random_int() & 0x7fc);
signal_return_offset = offset;

/*
* Copy signal return handlers into the vector page, and
* set sigreturn to be a pointer to these.
*/
/* Copy signal return handlers into the page */
memcpy(addr + offset, sigreturn_codes, sizeof(sigreturn_codes));

ptr = (unsigned long)addr + offset;
flush_icache_range(ptr, ptr + sizeof(sigreturn_codes));
/* Flush out all instructions in this page */
ptr = (unsigned long)addr;
flush_icache_range(ptr, ptr + PAGE_SIZE);

return page;
}
Expand Down
12 changes: 6 additions & 6 deletions arch/arm/mach-footbridge/dc21285.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where,
if (addr)
switch (size) {
case 1:
asm("ldrb %0, [%1, %2]"
asm volatile("ldrb %0, [%1, %2]"
: "=r" (v) : "r" (addr), "r" (where) : "cc");
break;
case 2:
asm("ldrh %0, [%1, %2]"
asm volatile("ldrh %0, [%1, %2]"
: "=r" (v) : "r" (addr), "r" (where) : "cc");
break;
case 4:
asm("ldr %0, [%1, %2]"
asm volatile("ldr %0, [%1, %2]"
: "=r" (v) : "r" (addr), "r" (where) : "cc");
break;
}
Expand All @@ -99,17 +99,17 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where,
if (addr)
switch (size) {
case 1:
asm("strb %0, [%1, %2]"
asm volatile("strb %0, [%1, %2]"
: : "r" (value), "r" (addr), "r" (where)
: "cc");
break;
case 2:
asm("strh %0, [%1, %2]"
asm volatile("strh %0, [%1, %2]"
: : "r" (value), "r" (addr), "r" (where)
: "cc");
break;
case 4:
asm("str %0, [%1, %2]"
asm volatile("str %0, [%1, %2]"
: : "r" (value), "r" (addr), "r" (where)
: "cc");
break;
Expand Down

0 comments on commit 4a7859e

Please sign in to comment.