Skip to content

Commit 4a7859e

Browse files
committed
Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
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
2 parents 368afec + 4d62e81 commit 4a7859e

File tree

7 files changed

+77
-78
lines changed

7 files changed

+77
-78
lines changed

arch/arm/include/asm/kexec-internal.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef _ARM_KEXEC_INTERNAL_H
3+
#define _ARM_KEXEC_INTERNAL_H
4+
5+
struct kexec_relocate_data {
6+
unsigned long kexec_start_address;
7+
unsigned long kexec_indirection_page;
8+
unsigned long kexec_mach_type;
9+
unsigned long kexec_r2;
10+
};
11+
12+
#endif

arch/arm/include/debug/tegra.S

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,34 @@
149149

150150
.align
151151
99: .word .
152+
#if defined(ZIMAGE)
153+
.word . + 4
154+
/*
155+
* Storage for the state maintained by the macro.
156+
*
157+
* In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c.
158+
* That's because this header is included from multiple files, and we only
159+
* want a single copy of the data. In particular, the UART probing code above
160+
* assumes it's running using physical addresses. This is true when this file
161+
* is included from head.o, but not when included from debug.o. So we need
162+
* to share the probe results between the two copies, rather than having
163+
* to re-run the probing again later.
164+
*
165+
* In the decompressor, we put the storage right here, since common.c
166+
* isn't included in the decompressor build. This storage data gets put in
167+
* .text even though it's really data, since .data is discarded from the
168+
* decompressor. Luckily, .text is writeable in the decompressor, unless
169+
* CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug.
170+
*/
171+
/* Debug UART initialization required */
172+
.word 1
173+
/* Debug UART physical address */
174+
.word 0
175+
/* Debug UART virtual address */
176+
.word 0
177+
#else
152178
.word tegra_uart_config
179+
#endif
153180
.ltorg
154181

155182
/* Load previously selected UART address */
@@ -189,30 +216,3 @@
189216

190217
.macro waituarttxrdy,rd,rx
191218
.endm
192-
193-
/*
194-
* Storage for the state maintained by the macros above.
195-
*
196-
* In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c.
197-
* That's because this header is included from multiple files, and we only
198-
* want a single copy of the data. In particular, the UART probing code above
199-
* assumes it's running using physical addresses. This is true when this file
200-
* is included from head.o, but not when included from debug.o. So we need
201-
* to share the probe results between the two copies, rather than having
202-
* to re-run the probing again later.
203-
*
204-
* In the decompressor, we put the symbol/storage right here, since common.c
205-
* isn't included in the decompressor build. This symbol gets put in .text
206-
* even though it's really data, since .data is discarded from the
207-
* decompressor. Luckily, .text is writeable in the decompressor, unless
208-
* CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug.
209-
*/
210-
#if defined(ZIMAGE)
211-
tegra_uart_config:
212-
/* Debug UART initialization required */
213-
.word 1
214-
/* Debug UART physical address */
215-
.word 0
216-
/* Debug UART virtual address */
217-
.word 0
218-
#endif

arch/arm/kernel/asm-offsets.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/mm.h>
1313
#include <linux/dma-mapping.h>
1414
#include <asm/cacheflush.h>
15+
#include <asm/kexec-internal.h>
1516
#include <asm/glue-df.h>
1617
#include <asm/glue-pf.h>
1718
#include <asm/mach/arch.h>
@@ -170,5 +171,9 @@ int main(void)
170171
DEFINE(MPU_RGN_PRBAR, offsetof(struct mpu_rgn, prbar));
171172
DEFINE(MPU_RGN_PRLAR, offsetof(struct mpu_rgn, prlar));
172173
#endif
174+
DEFINE(KEXEC_START_ADDR, offsetof(struct kexec_relocate_data, kexec_start_address));
175+
DEFINE(KEXEC_INDIR_PAGE, offsetof(struct kexec_relocate_data, kexec_indirection_page));
176+
DEFINE(KEXEC_MACH_TYPE, offsetof(struct kexec_relocate_data, kexec_mach_type));
177+
DEFINE(KEXEC_R2, offsetof(struct kexec_relocate_data, kexec_r2));
173178
return 0;
174179
}

arch/arm/kernel/machine_kexec.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/of_fdt.h>
1414
#include <asm/mmu_context.h>
1515
#include <asm/cacheflush.h>
16+
#include <asm/kexec-internal.h>
1617
#include <asm/fncpy.h>
1718
#include <asm/mach-types.h>
1819
#include <asm/smp_plat.h>
@@ -22,11 +23,6 @@
2223
extern void relocate_new_kernel(void);
2324
extern const unsigned int relocate_new_kernel_size;
2425

25-
extern unsigned long kexec_start_address;
26-
extern unsigned long kexec_indirection_page;
27-
extern unsigned long kexec_mach_type;
28-
extern unsigned long kexec_boot_atags;
29-
3026
static atomic_t waiting_for_crash_ipi;
3127

3228
/*
@@ -159,6 +155,7 @@ void (*kexec_reinit)(void);
159155
void machine_kexec(struct kimage *image)
160156
{
161157
unsigned long page_list, reboot_entry_phys;
158+
struct kexec_relocate_data *data;
162159
void (*reboot_entry)(void);
163160
void *reboot_code_buffer;
164161

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

175172
reboot_code_buffer = page_address(image->control_code_page);
176173

177-
/* Prepare parameters for reboot_code_buffer*/
178-
set_kernel_text_rw();
179-
kexec_start_address = image->start;
180-
kexec_indirection_page = page_list;
181-
kexec_mach_type = machine_arch_type;
182-
kexec_boot_atags = image->arch.kernel_r2;
183-
184174
/* copy our kernel relocation code to the control code page */
185175
reboot_entry = fncpy(reboot_code_buffer,
186176
&relocate_new_kernel,
187177
relocate_new_kernel_size);
188178

179+
data = reboot_code_buffer + relocate_new_kernel_size;
180+
data->kexec_start_address = image->start;
181+
data->kexec_indirection_page = page_list;
182+
data->kexec_mach_type = machine_arch_type;
183+
data->kexec_r2 = image->arch.kernel_r2;
184+
189185
/* get the identity mapping physical address for the reboot code */
190186
reboot_entry_phys = virt_to_idmap(reboot_entry);
191187

arch/arm/kernel/relocate_kernel.S

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@
55

66
#include <linux/linkage.h>
77
#include <asm/assembler.h>
8+
#include <asm/asm-offsets.h>
89
#include <asm/kexec.h>
910

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

1213
ENTRY(relocate_new_kernel)
1314

14-
ldr r0,kexec_indirection_page
15-
ldr r1,kexec_start_address
15+
adr r7, relocate_new_kernel_end
16+
ldr r0, [r7, #KEXEC_INDIR_PAGE]
17+
ldr r1, [r7, #KEXEC_START_ADDR]
1618

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

5860
2:
5961
/* Jump to relocated kernel */
60-
mov lr,r1
61-
mov r0,#0
62-
ldr r1,kexec_mach_type
63-
ldr r2,kexec_boot_atags
64-
ARM( ret lr )
65-
THUMB( bx lr )
66-
67-
.align
68-
69-
.globl kexec_start_address
70-
kexec_start_address:
71-
.long 0x0
72-
73-
.globl kexec_indirection_page
74-
kexec_indirection_page:
75-
.long 0x0
76-
77-
.globl kexec_mach_type
78-
kexec_mach_type:
79-
.long 0x0
80-
81-
/* phy addr of the atags for the new kernel */
82-
.globl kexec_boot_atags
83-
kexec_boot_atags:
84-
.long 0x0
62+
mov lr, r1
63+
mov r0, #0
64+
ldr r1, [r7, #KEXEC_MACH_TYPE]
65+
ldr r2, [r7, #KEXEC_R2]
66+
ARM( ret lr )
67+
THUMB( bx lr )
8568

8669
ENDPROC(relocate_new_kernel)
8770

71+
.align 3
8872
relocate_new_kernel_end:
8973

9074
.globl relocate_new_kernel_size

arch/arm/kernel/signal.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -693,18 +693,20 @@ struct page *get_signal_page(void)
693693

694694
addr = page_address(page);
695695

696+
/* Poison the entire page */
697+
memset32(addr, __opcode_to_mem_arm(0xe7fddef1),
698+
PAGE_SIZE / sizeof(u32));
699+
696700
/* Give the signal return code some randomness */
697701
offset = 0x200 + (get_random_int() & 0x7fc);
698702
signal_return_offset = offset;
699703

700-
/*
701-
* Copy signal return handlers into the vector page, and
702-
* set sigreturn to be a pointer to these.
703-
*/
704+
/* Copy signal return handlers into the page */
704705
memcpy(addr + offset, sigreturn_codes, sizeof(sigreturn_codes));
705706

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

709711
return page;
710712
}

arch/arm/mach-footbridge/dc21285.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,15 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where,
6565
if (addr)
6666
switch (size) {
6767
case 1:
68-
asm("ldrb %0, [%1, %2]"
68+
asm volatile("ldrb %0, [%1, %2]"
6969
: "=r" (v) : "r" (addr), "r" (where) : "cc");
7070
break;
7171
case 2:
72-
asm("ldrh %0, [%1, %2]"
72+
asm volatile("ldrh %0, [%1, %2]"
7373
: "=r" (v) : "r" (addr), "r" (where) : "cc");
7474
break;
7575
case 4:
76-
asm("ldr %0, [%1, %2]"
76+
asm volatile("ldr %0, [%1, %2]"
7777
: "=r" (v) : "r" (addr), "r" (where) : "cc");
7878
break;
7979
}
@@ -99,17 +99,17 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where,
9999
if (addr)
100100
switch (size) {
101101
case 1:
102-
asm("strb %0, [%1, %2]"
102+
asm volatile("strb %0, [%1, %2]"
103103
: : "r" (value), "r" (addr), "r" (where)
104104
: "cc");
105105
break;
106106
case 2:
107-
asm("strh %0, [%1, %2]"
107+
asm volatile("strh %0, [%1, %2]"
108108
: : "r" (value), "r" (addr), "r" (where)
109109
: "cc");
110110
break;
111111
case 4:
112-
asm("str %0, [%1, %2]"
112+
asm volatile("str %0, [%1, %2]"
113113
: : "r" (value), "r" (addr), "r" (where)
114114
: "cc");
115115
break;

0 commit comments

Comments
 (0)