summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-07 22:34:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-07 22:34:17 -0400
commitd3511f53bb2475f2a4e8460bee5a1ae6dea2a433 (patch)
tree8141260e4fb705d8f94548150572433c685e6829
parent02aff8db6438ce29371fd9cd54c57213f4bb4536 (diff)
parent62217beb394e654bbd2bb87c533dadd2d8bf62c6 (diff)
Merge branch 'parisc-5.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull parisc updates from Helge Deller: "Many great new features, fixes and optimizations, including: - Convert page table updates to use per-pagetable spinlocks which overall improves performance on SMP machines a lot, by Mikulas Patocka - Kernel debugger (KGDB) support, by Sven Schnelle - KPROBES support, by Sven Schnelle - Lots of TLB lock/flush improvements, by Dave Anglin - Drop DISCONTIGMEM and switch to SPARSEMEM - Added JUMP_LABEL, branch runtime-patching support - Lots of other small speedups and cleanups, e.g. for QEMU, stack randomization, avoidance of name clashes, documentation updates, etc ..." * 'parisc-5.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: (28 commits) parisc: Add static branch and JUMP_LABEL feature parisc: Use PA_ASM_LEVEL in boot code parisc: Rename LEVEL to PA_ASM_LEVEL to avoid name clash with DRBD code parisc: Update huge TLB page support to use per-pagetable spinlock parisc: Use per-pagetable spinlock parisc: Allow live-patching of __meminit functions parisc: Add memory barrier to asm pdc and sync instructions parisc: Add memory clobber to TLB purges parisc: Use ldcw instruction for SMP spinlock release barrier parisc: Remove lock code to serialize TLB operations in pacache.S parisc: Switch from DISCONTIGMEM to SPARSEMEM parisc: enable wide mode early parisc: update feature lists parisc: Show n/a if product number not available parisc: remove unused flags parameter in __patch_text() doc: update kprobes supported architecture list parisc: Implement kretprobes parisc: remove kprobes.h from generic-y parisc: Implement kprobes parisc: add functions required by KPROBE_EVENTS ...
-rw-r--r--Documentation/features/debug/kgdb/arch-support.txt2
-rw-r--r--Documentation/features/debug/kprobes/arch-support.txt2
-rw-r--r--Documentation/features/debug/kretprobes/arch-support.txt2
-rw-r--r--Documentation/kprobes.txt1
-rw-r--r--arch/parisc/Kconfig17
-rw-r--r--arch/parisc/boot/compressed/head.S6
-rw-r--r--arch/parisc/boot/compressed/misc.c31
-rw-r--r--arch/parisc/include/asm/Kbuild1
-rw-r--r--arch/parisc/include/asm/assembly.h6
-rw-r--r--arch/parisc/include/asm/cache.h10
-rw-r--r--arch/parisc/include/asm/fixmap.h19
-rw-r--r--arch/parisc/include/asm/hardware.h2
-rw-r--r--arch/parisc/include/asm/jump_label.h43
-rw-r--r--arch/parisc/include/asm/kgdb.h68
-rw-r--r--arch/parisc/include/asm/kprobes.h55
-rw-r--r--arch/parisc/include/asm/mmzone.h58
-rw-r--r--arch/parisc/include/asm/page.h4
-rw-r--r--arch/parisc/include/asm/patch.h11
-rw-r--r--arch/parisc/include/asm/pgalloc.h1
-rw-r--r--arch/parisc/include/asm/pgtable.h69
-rw-r--r--arch/parisc/include/asm/ptrace.h13
-rw-r--r--arch/parisc/include/asm/sparsemem.h14
-rw-r--r--arch/parisc/include/asm/spinlock.h4
-rw-r--r--arch/parisc/include/asm/tlbflush.h24
-rw-r--r--arch/parisc/kernel/Makefile6
-rw-r--r--arch/parisc/kernel/cache.c15
-rw-r--r--arch/parisc/kernel/drivers.c25
-rw-r--r--arch/parisc/kernel/entry.S51
-rw-r--r--arch/parisc/kernel/head.S17
-rw-r--r--arch/parisc/kernel/inventory.c7
-rw-r--r--arch/parisc/kernel/jump_label.c55
-rw-r--r--arch/parisc/kernel/kgdb.c209
-rw-r--r--arch/parisc/kernel/kprobes.c291
-rw-r--r--arch/parisc/kernel/pacache.S43
-rw-r--r--arch/parisc/kernel/parisc_ksyms.c6
-rw-r--r--arch/parisc/kernel/patch.c77
-rw-r--r--arch/parisc/kernel/process.c1
-rw-r--r--arch/parisc/kernel/processor.c3
-rw-r--r--arch/parisc/kernel/ptrace.c35
-rw-r--r--arch/parisc/kernel/setup.c6
-rw-r--r--arch/parisc/kernel/sys_parisc.c3
-rw-r--r--arch/parisc/kernel/syscall.S18
-rw-r--r--arch/parisc/kernel/traps.c31
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S3
-rw-r--r--arch/parisc/mm/Makefile2
-rw-r--r--arch/parisc/mm/fixmap.c41
-rw-r--r--arch/parisc/mm/hugetlbpage.c19
-rw-r--r--arch/parisc/mm/init.c118
-rw-r--r--drivers/net/ethernet/i825xx/lasi_82596.c5
-rw-r--r--drivers/parisc/led.c3
50 files changed, 1258 insertions, 295 deletions
diff --git a/Documentation/features/debug/kgdb/arch-support.txt b/Documentation/features/debug/kgdb/arch-support.txt
index 3e6b8f07d5d0..38c40cfa0578 100644
--- a/Documentation/features/debug/kgdb/arch-support.txt
+++ b/Documentation/features/debug/kgdb/arch-support.txt
@@ -21,7 +21,7 @@
21 | nds32: | TODO | 21 | nds32: | TODO |
22 | nios2: | ok | 22 | nios2: | ok |
23 | openrisc: | TODO | 23 | openrisc: | TODO |
24 | parisc: | TODO | 24 | parisc: | ok |
25 | powerpc: | ok | 25 | powerpc: | ok |
26 | riscv: | TODO | 26 | riscv: | TODO |
27 | s390: | TODO | 27 | s390: | TODO |
diff --git a/Documentation/features/debug/kprobes/arch-support.txt b/Documentation/features/debug/kprobes/arch-support.txt
index f4e45bd58fea..e68239b5d2f0 100644
--- a/Documentation/features/debug/kprobes/arch-support.txt
+++ b/Documentation/features/debug/kprobes/arch-support.txt
@@ -21,7 +21,7 @@
21 | nds32: | TODO | 21 | nds32: | TODO |
22 | nios2: | TODO | 22 | nios2: | TODO |
23 | openrisc: | TODO | 23 | openrisc: | TODO |
24 | parisc: | TODO | 24 | parisc: | ok |
25 | powerpc: | ok | 25 | powerpc: | ok |
26 | riscv: | ok | 26 | riscv: | ok |
27 | s390: | ok | 27 | s390: | ok |
diff --git a/Documentation/features/debug/kretprobes/arch-support.txt b/Documentation/features/debug/kretprobes/arch-support.txt
index 1d5651ef11f8..f17131b328e5 100644
--- a/Documentation/features/debug/kretprobes/arch-support.txt
+++ b/Documentation/features/debug/kretprobes/arch-support.txt
@@ -21,7 +21,7 @@
21 | nds32: | TODO | 21 | nds32: | TODO |
22 | nios2: | TODO | 22 | nios2: | TODO |
23 | openrisc: | TODO | 23 | openrisc: | TODO |
24 | parisc: | TODO | 24 | parisc: | ok |
25 | powerpc: | ok | 25 | powerpc: | ok |
26 | riscv: | TODO | 26 | riscv: | TODO |
27 | s390: | ok | 27 | s390: | ok |
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index ee60e519438a..8baab8832c5b 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -321,6 +321,7 @@ architectures:
321- ppc 321- ppc
322- mips 322- mips
323- s390 323- s390
324- parisc
324 325
325Configuring Kprobes 326Configuring Kprobes
326=================== 327===================
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index f1ed8ddfe486..09407ed1aacd 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -36,6 +36,7 @@ config PARISC
36 select GENERIC_STRNCPY_FROM_USER 36 select GENERIC_STRNCPY_FROM_USER
37 select SYSCTL_ARCH_UNALIGN_ALLOW 37 select SYSCTL_ARCH_UNALIGN_ALLOW
38 select SYSCTL_EXCEPTION_TRACE 38 select SYSCTL_EXCEPTION_TRACE
39 select ARCH_DISCARD_MEMBLOCK
39 select HAVE_MOD_ARCH_SPECIFIC 40 select HAVE_MOD_ARCH_SPECIFIC
40 select VIRT_TO_BUS 41 select VIRT_TO_BUS
41 select MODULES_USE_ELF_RELA 42 select MODULES_USE_ELF_RELA
@@ -44,6 +45,8 @@ config PARISC
44 select HAVE_DEBUG_STACKOVERFLOW 45 select HAVE_DEBUG_STACKOVERFLOW
45 select HAVE_ARCH_AUDITSYSCALL 46 select HAVE_ARCH_AUDITSYSCALL
46 select HAVE_ARCH_HASH 47 select HAVE_ARCH_HASH
48 select HAVE_ARCH_JUMP_LABEL
49 select HAVE_ARCH_JUMP_LABEL_RELATIVE
47 select HAVE_ARCH_SECCOMP_FILTER 50 select HAVE_ARCH_SECCOMP_FILTER
48 select HAVE_ARCH_TRACEHOOK 51 select HAVE_ARCH_TRACEHOOK
49 select HAVE_REGS_AND_STACK_ACCESS_API 52 select HAVE_REGS_AND_STACK_ACCESS_API
@@ -54,6 +57,9 @@ config PARISC
54 select CPU_NO_EFFICIENT_FFS 57 select CPU_NO_EFFICIENT_FFS
55 select NEED_DMA_MAP_STATE 58 select NEED_DMA_MAP_STATE
56 select NEED_SG_DMA_LENGTH 59 select NEED_SG_DMA_LENGTH
60 select HAVE_ARCH_KGDB
61 select HAVE_KPROBES
62 select HAVE_KRETPROBES
57 63
58 help 64 help
59 The PA-RISC microprocessor is designed by Hewlett-Packard and used 65 The PA-RISC microprocessor is designed by Hewlett-Packard and used
@@ -305,21 +311,16 @@ config ARCH_SELECT_MEMORY_MODEL
305 def_bool y 311 def_bool y
306 depends on 64BIT 312 depends on 64BIT
307 313
308config ARCH_DISCONTIGMEM_ENABLE 314config ARCH_SPARSEMEM_ENABLE
309 def_bool y 315 def_bool y
310 depends on 64BIT 316 depends on 64BIT
311 317
312config ARCH_FLATMEM_ENABLE 318config ARCH_FLATMEM_ENABLE
313 def_bool y 319 def_bool y
314 320
315config ARCH_DISCONTIGMEM_DEFAULT 321config ARCH_SPARSEMEM_DEFAULT
316 def_bool y 322 def_bool y
317 depends on ARCH_DISCONTIGMEM_ENABLE 323 depends on ARCH_SPARSEMEM_ENABLE
318
319config NODES_SHIFT
320 int
321 default "3"
322 depends on NEED_MULTIPLE_NODES
323 324
324source "kernel/Kconfig.hz" 325source "kernel/Kconfig.hz"
325 326
diff --git a/arch/parisc/boot/compressed/head.S b/arch/parisc/boot/compressed/head.S
index 5aba20fa48aa..e8b798fd0cf0 100644
--- a/arch/parisc/boot/compressed/head.S
+++ b/arch/parisc/boot/compressed/head.S
@@ -22,7 +22,7 @@
22 __HEAD 22 __HEAD
23 23
24ENTRY(startup) 24ENTRY(startup)
25 .level LEVEL 25 .level PA_ASM_LEVEL
26 26
27#define PSW_W_SM 0x200 27#define PSW_W_SM 0x200
28#define PSW_W_BIT 36 28#define PSW_W_BIT 36
@@ -63,7 +63,7 @@ $bss_loop:
63 load32 BOOTADDR(decompress_kernel),%r3 63 load32 BOOTADDR(decompress_kernel),%r3
64 64
65#ifdef CONFIG_64BIT 65#ifdef CONFIG_64BIT
66 .level LEVEL 66 .level PA_ASM_LEVEL
67 ssm PSW_W_SM, %r0 /* set W-bit */ 67 ssm PSW_W_SM, %r0 /* set W-bit */
68 depdi 0, 31, 32, %r3 68 depdi 0, 31, 32, %r3
69#endif 69#endif
@@ -72,7 +72,7 @@ $bss_loop:
72 72
73startup_continue: 73startup_continue:
74#ifdef CONFIG_64BIT 74#ifdef CONFIG_64BIT
75 .level LEVEL 75 .level PA_ASM_LEVEL
76 rsm PSW_W_SM, %r0 /* clear W-bit */ 76 rsm PSW_W_SM, %r0 /* clear W-bit */
77#endif 77#endif
78 78
diff --git a/arch/parisc/boot/compressed/misc.c b/arch/parisc/boot/compressed/misc.c
index 2556bb181813..2d395998f524 100644
--- a/arch/parisc/boot/compressed/misc.c
+++ b/arch/parisc/boot/compressed/misc.c
@@ -145,14 +145,13 @@ static int putchar(int c)
145 145
146void __noreturn error(char *x) 146void __noreturn error(char *x)
147{ 147{
148 puts("\n\n"); 148 if (x) puts(x);
149 puts(x); 149 puts("\n -- System halted\n");
150 puts("\n\n -- System halted");
151 while (1) /* wait forever */ 150 while (1) /* wait forever */
152 ; 151 ;
153} 152}
154 153
155static int print_hex(unsigned long num) 154static int print_num(unsigned long num, int base)
156{ 155{
157 const char hex[] = "0123456789abcdef"; 156 const char hex[] = "0123456789abcdef";
158 char str[40]; 157 char str[40];
@@ -160,12 +159,14 @@ static int print_hex(unsigned long num)
160 159
161 str[i--] = '\0'; 160 str[i--] = '\0';
162 do { 161 do {
163 str[i--] = hex[num & 0x0f]; 162 str[i--] = hex[num % base];
164 num >>= 4; 163 num = num / base;
165 } while (num); 164 } while (num);
166 165
167 str[i--] = 'x'; 166 if (base == 16) {
168 str[i] = '0'; 167 str[i--] = 'x';
168 str[i] = '0';
169 } else i++;
169 puts(&str[i]); 170 puts(&str[i]);
170 171
171 return 0; 172 return 0;
@@ -187,8 +188,9 @@ put:
187 188
188 if (fmt[++i] == '%') 189 if (fmt[++i] == '%')
189 goto put; 190 goto put;
191 print_num(va_arg(args, unsigned long),
192 fmt[i] == 'x' ? 16:10);
190 ++i; 193 ++i;
191 print_hex(va_arg(args, unsigned long));
192 } 194 }
193 195
194 va_end(args); 196 va_end(args);
@@ -327,8 +329,15 @@ unsigned long decompress_kernel(unsigned int started_wide,
327 free_mem_end_ptr = rd_start; 329 free_mem_end_ptr = rd_start;
328#endif 330#endif
329 331
330 if (free_mem_ptr >= free_mem_end_ptr) 332 if (free_mem_ptr >= free_mem_end_ptr) {
331 error("Kernel too big for machine."); 333 int free_ram;
334 free_ram = (free_mem_ptr >> 20) + 1;
335 if (free_ram < 32)
336 free_ram = 32;
337 printf("\nKernel requires at least %d MB RAM.\n",
338 free_ram);
339 error(NULL);
340 }
332 341
333#ifdef DEBUG 342#ifdef DEBUG
334 printf("\n"); 343 printf("\n");
diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild
index b8c7db777144..ed2d8cc94909 100644
--- a/arch/parisc/include/asm/Kbuild
+++ b/arch/parisc/include/asm/Kbuild
@@ -10,7 +10,6 @@ generic-y += hw_irq.h
10generic-y += irq_regs.h 10generic-y += irq_regs.h
11generic-y += irq_work.h 11generic-y += irq_work.h
12generic-y += kdebug.h 12generic-y += kdebug.h
13generic-y += kprobes.h
14generic-y += kvm_para.h 13generic-y += kvm_para.h
15generic-y += local.h 14generic-y += local.h
16generic-y += local64.h 15generic-y += local64.h
diff --git a/arch/parisc/include/asm/assembly.h b/arch/parisc/include/asm/assembly.h
index c17ec0ee6e7c..d85738a7bbe6 100644
--- a/arch/parisc/include/asm/assembly.h
+++ b/arch/parisc/include/asm/assembly.h
@@ -61,14 +61,14 @@
61#define LDCW ldcw,co 61#define LDCW ldcw,co
62#define BL b,l 62#define BL b,l
63# ifdef CONFIG_64BIT 63# ifdef CONFIG_64BIT
64# define LEVEL 2.0w 64# define PA_ASM_LEVEL 2.0w
65# else 65# else
66# define LEVEL 2.0 66# define PA_ASM_LEVEL 2.0
67# endif 67# endif
68#else 68#else
69#define LDCW ldcw 69#define LDCW ldcw
70#define BL bl 70#define BL bl
71#define LEVEL 1.1 71#define PA_ASM_LEVEL 1.1
72#endif 72#endif
73 73
74#ifdef __ASSEMBLY__ 74#ifdef __ASSEMBLY__
diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h
index 006fb939cac8..4016fe1c65a9 100644
--- a/arch/parisc/include/asm/cache.h
+++ b/arch/parisc/include/asm/cache.h
@@ -44,22 +44,22 @@ void parisc_setup_cache_timing(void);
44 44
45#define pdtlb(addr) asm volatile("pdtlb 0(%%sr1,%0)" \ 45#define pdtlb(addr) asm volatile("pdtlb 0(%%sr1,%0)" \
46 ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \ 46 ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \
47 : : "r" (addr)) 47 : : "r" (addr) : "memory")
48#define pitlb(addr) asm volatile("pitlb 0(%%sr1,%0)" \ 48#define pitlb(addr) asm volatile("pitlb 0(%%sr1,%0)" \
49 ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \ 49 ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \
50 ALTERNATIVE(ALT_COND_NO_SPLIT_TLB, INSN_NOP) \ 50 ALTERNATIVE(ALT_COND_NO_SPLIT_TLB, INSN_NOP) \
51 : : "r" (addr)) 51 : : "r" (addr) : "memory")
52#define pdtlb_kernel(addr) asm volatile("pdtlb 0(%0)" \ 52#define pdtlb_kernel(addr) asm volatile("pdtlb 0(%0)" \
53 ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \ 53 ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \
54 : : "r" (addr)) 54 : : "r" (addr) : "memory")
55 55
56#define asm_io_fdc(addr) asm volatile("fdc %%r0(%0)" \ 56#define asm_io_fdc(addr) asm volatile("fdc %%r0(%0)" \
57 ALTERNATIVE(ALT_COND_NO_DCACHE, INSN_NOP) \ 57 ALTERNATIVE(ALT_COND_NO_DCACHE, INSN_NOP) \
58 ALTERNATIVE(ALT_COND_NO_IOC_FDC, INSN_NOP) \ 58 ALTERNATIVE(ALT_COND_NO_IOC_FDC, INSN_NOP) \
59 : : "r" (addr)) 59 : : "r" (addr) : "memory")
60#define asm_io_sync() asm volatile("sync" \ 60#define asm_io_sync() asm volatile("sync" \
61 ALTERNATIVE(ALT_COND_NO_DCACHE, INSN_NOP) \ 61 ALTERNATIVE(ALT_COND_NO_DCACHE, INSN_NOP) \
62 ALTERNATIVE(ALT_COND_NO_IOC_FDC, INSN_NOP) :: ) 62 ALTERNATIVE(ALT_COND_NO_IOC_FDC, INSN_NOP) :::"memory")
63 63
64#endif /* ! __ASSEMBLY__ */ 64#endif /* ! __ASSEMBLY__ */
65 65
diff --git a/arch/parisc/include/asm/fixmap.h b/arch/parisc/include/asm/fixmap.h
index f7c3a0905de4..288da73d4cc0 100644
--- a/arch/parisc/include/asm/fixmap.h
+++ b/arch/parisc/include/asm/fixmap.h
@@ -15,17 +15,34 @@
15 * from areas congruently mapped with user space. It is 8MB large 15 * from areas congruently mapped with user space. It is 8MB large
16 * and must be 16MB aligned */ 16 * and must be 16MB aligned */
17#define TMPALIAS_MAP_START ((__PAGE_OFFSET) - 16*1024*1024) 17#define TMPALIAS_MAP_START ((__PAGE_OFFSET) - 16*1024*1024)
18
19#define FIXMAP_SIZE (FIX_BITMAP_COUNT << PAGE_SHIFT)
20#define FIXMAP_START (TMPALIAS_MAP_START - FIXMAP_SIZE)
18/* This is the kernel area for all maps (vmalloc, dma etc.) most 21/* This is the kernel area for all maps (vmalloc, dma etc.) most
19 * usually, it extends up to TMPALIAS_MAP_START. Virtual addresses 22 * usually, it extends up to TMPALIAS_MAP_START. Virtual addresses
20 * 0..GATEWAY_PAGE_SIZE are reserved for the gateway page */ 23 * 0..GATEWAY_PAGE_SIZE are reserved for the gateway page */
21#define KERNEL_MAP_START (GATEWAY_PAGE_SIZE) 24#define KERNEL_MAP_START (GATEWAY_PAGE_SIZE)
22#define KERNEL_MAP_END (TMPALIAS_MAP_START) 25#define KERNEL_MAP_END (FIXMAP_START)
23 26
24#ifndef __ASSEMBLY__ 27#ifndef __ASSEMBLY__
28
29
30enum fixed_addresses {
31 /* Support writing RO kernel text via kprobes, jump labels, etc. */
32 FIX_TEXT_POKE0,
33 FIX_BITMAP_COUNT
34};
35
25extern void *parisc_vmalloc_start; 36extern void *parisc_vmalloc_start;
26#define PCXL_DMA_MAP_SIZE (8*1024*1024) 37#define PCXL_DMA_MAP_SIZE (8*1024*1024)
27#define VMALLOC_START ((unsigned long)parisc_vmalloc_start) 38#define VMALLOC_START ((unsigned long)parisc_vmalloc_start)
28#define VMALLOC_END (KERNEL_MAP_END) 39#define VMALLOC_END (KERNEL_MAP_END)
40
41#define __fix_to_virt(_x) (FIXMAP_START + ((_x) << PAGE_SHIFT))
42
43void set_fixmap(enum fixed_addresses idx, phys_addr_t phys);
44void clear_fixmap(enum fixed_addresses idx);
45
29#endif /*__ASSEMBLY__*/ 46#endif /*__ASSEMBLY__*/
30 47
31#endif /*_ASM_FIXMAP_H*/ 48#endif /*_ASM_FIXMAP_H*/
diff --git a/arch/parisc/include/asm/hardware.h b/arch/parisc/include/asm/hardware.h
index d6e1ed145031..9d3d7737c58b 100644
--- a/arch/parisc/include/asm/hardware.h
+++ b/arch/parisc/include/asm/hardware.h
@@ -120,7 +120,7 @@ extern void get_pci_node_path(struct pci_dev *dev, struct hardware_path *path);
120extern void init_parisc_bus(void); 120extern void init_parisc_bus(void);
121extern struct device *hwpath_to_device(struct hardware_path *modpath); 121extern struct device *hwpath_to_device(struct hardware_path *modpath);
122extern void device_to_hwpath(struct device *dev, struct hardware_path *path); 122extern void device_to_hwpath(struct device *dev, struct hardware_path *path);
123 123extern int machine_has_merced_bus(void);
124 124
125/* inventory.c: */ 125/* inventory.c: */
126extern void do_memory_inventory(void); 126extern void do_memory_inventory(void);
diff --git a/arch/parisc/include/asm/jump_label.h b/arch/parisc/include/asm/jump_label.h
new file mode 100644
index 000000000000..7efb1aa2f7f8
--- /dev/null
+++ b/arch/parisc/include/asm/jump_label.h
@@ -0,0 +1,43 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _ASM_PARISC_JUMP_LABEL_H
3#define _ASM_PARISC_JUMP_LABEL_H
4
5#ifndef __ASSEMBLY__
6
7#include <linux/types.h>
8#include <asm/assembly.h>
9
10#define JUMP_LABEL_NOP_SIZE 4
11
12static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
13{
14 asm_volatile_goto("1:\n\t"
15 "nop\n\t"
16 ".pushsection __jump_table, \"aw\"\n\t"
17 ".word 1b - ., %l[l_yes] - .\n\t"
18 __stringify(ASM_ULONG_INSN) " %c0 - .\n\t"
19 ".popsection\n\t"
20 : : "i" (&((char *)key)[branch]) : : l_yes);
21
22 return false;
23l_yes:
24 return true;
25}
26
27static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
28{
29 asm_volatile_goto("1:\n\t"
30 "b,n %l[l_yes]\n\t"
31 ".pushsection __jump_table, \"aw\"\n\t"
32 ".word 1b - ., %l[l_yes] - .\n\t"
33 __stringify(ASM_ULONG_INSN) " %c0 - .\n\t"
34 ".popsection\n\t"
35 : : "i" (&((char *)key)[branch]) : : l_yes);
36
37 return false;
38l_yes:
39 return true;
40}
41
42#endif /* __ASSEMBLY__ */
43#endif
diff --git a/arch/parisc/include/asm/kgdb.h b/arch/parisc/include/asm/kgdb.h
new file mode 100644
index 000000000000..f23e7f8f13a5
--- /dev/null
+++ b/arch/parisc/include/asm/kgdb.h
@@ -0,0 +1,68 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * PA-RISC KGDB support
4 *
5 * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org>
6 *
7 */
8
9#ifndef __PARISC_KGDB_H__
10#define __PARISC_KGDB_H__
11
12#define BREAK_INSTR_SIZE 4
13#define PARISC_KGDB_COMPILED_BREAK_INSN 0x3ffc01f
14#define PARISC_KGDB_BREAK_INSN 0x3ffa01f
15
16
17#define NUMREGBYTES sizeof(struct parisc_gdb_regs)
18#define BUFMAX 4096
19
20#define CACHE_FLUSH_IS_SAFE 1
21
22#ifndef __ASSEMBLY__
23
24static inline void arch_kgdb_breakpoint(void)
25{
26 asm(".word %0" : : "i"(PARISC_KGDB_COMPILED_BREAK_INSN) : "memory");
27}
28
29struct parisc_gdb_regs {
30 unsigned long gpr[32];
31 unsigned long sar;
32 unsigned long iaoq_f;
33 unsigned long iasq_f;
34 unsigned long iaoq_b;
35 unsigned long iasq_b;
36 unsigned long eiem;
37 unsigned long iir;
38 unsigned long isr;
39 unsigned long ior;
40 unsigned long ipsw;
41 unsigned long __unused0;
42 unsigned long sr4;
43 unsigned long sr0;
44 unsigned long sr1;
45 unsigned long sr2;
46 unsigned long sr3;
47 unsigned long sr5;
48 unsigned long sr6;
49 unsigned long sr7;
50 unsigned long cr0;
51 unsigned long pid1;
52 unsigned long pid2;
53 unsigned long scrccr;
54 unsigned long pid3;
55 unsigned long pid4;
56 unsigned long cr24;
57 unsigned long cr25;
58 unsigned long cr26;
59 unsigned long cr27;
60 unsigned long cr28;
61 unsigned long cr29;
62 unsigned long cr30;
63
64 u64 fr[32];
65};
66
67#endif
68#endif
diff --git a/arch/parisc/include/asm/kprobes.h b/arch/parisc/include/asm/kprobes.h
new file mode 100644
index 000000000000..e09cf2deeafe
--- /dev/null
+++ b/arch/parisc/include/asm/kprobes.h
@@ -0,0 +1,55 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * arch/parisc/include/asm/kprobes.h
4 *
5 * PA-RISC kprobes implementation
6 *
7 * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org>
8 */
9
10#ifndef _PARISC_KPROBES_H
11#define _PARISC_KPROBES_H
12
13#ifdef CONFIG_KPROBES
14
15#include <asm-generic/kprobes.h>
16#include <linux/types.h>
17#include <linux/ptrace.h>
18#include <linux/notifier.h>
19
20#define PARISC_KPROBES_BREAK_INSN 0x3ff801f
21#define __ARCH_WANT_KPROBES_INSN_SLOT
22#define MAX_INSN_SIZE 1
23
24typedef u32 kprobe_opcode_t;
25struct kprobe;
26
27void arch_remove_kprobe(struct kprobe *p);
28
29#define flush_insn_slot(p) \
30 flush_icache_range((unsigned long)&(p)->ainsn.insn[0], \
31 (unsigned long)&(p)->ainsn.insn[0] + \
32 sizeof(kprobe_opcode_t))
33
34#define kretprobe_blacklist_size 0
35
36struct arch_specific_insn {
37 kprobe_opcode_t *insn;
38};
39
40struct prev_kprobe {
41 struct kprobe *kp;
42 unsigned long status;
43};
44
45struct kprobe_ctlblk {
46 unsigned int kprobe_status;
47 struct prev_kprobe prev_kprobe;
48 unsigned long iaoq[2];
49};
50
51int __kprobes parisc_kprobe_break_handler(struct pt_regs *regs);
52int __kprobes parisc_kprobe_ss_handler(struct pt_regs *regs);
53
54#endif /* CONFIG_KPROBES */
55#endif /* _PARISC_KPROBES_H */
diff --git a/arch/parisc/include/asm/mmzone.h b/arch/parisc/include/asm/mmzone.h
index fafa3893fd70..8d390406d862 100644
--- a/arch/parisc/include/asm/mmzone.h
+++ b/arch/parisc/include/asm/mmzone.h
@@ -2,62 +2,6 @@
2#ifndef _PARISC_MMZONE_H 2#ifndef _PARISC_MMZONE_H
3#define _PARISC_MMZONE_H 3#define _PARISC_MMZONE_H
4 4
5#define MAX_PHYSMEM_RANGES 8 /* Fix the size for now (current known max is 3) */ 5#define MAX_PHYSMEM_RANGES 4 /* Fix the size for now (current known max is 3) */
6 6
7#ifdef CONFIG_DISCONTIGMEM
8
9extern int npmem_ranges;
10
11struct node_map_data {
12 pg_data_t pg_data;
13};
14
15extern struct node_map_data node_data[];
16
17#define NODE_DATA(nid) (&node_data[nid].pg_data)
18
19/* We have these possible memory map layouts:
20 * Astro: 0-3.75, 67.75-68, 4-64
21 * zx1: 0-1, 257-260, 4-256
22 * Stretch (N-class): 0-2, 4-32, 34-xxx
23 */
24
25/* Since each 1GB can only belong to one region (node), we can create
26 * an index table for pfn to nid lookup; each entry in pfnnid_map
27 * represents 1GB, and contains the node that the memory belongs to. */
28
29#define PFNNID_SHIFT (30 - PAGE_SHIFT)
30#define PFNNID_MAP_MAX 512 /* support 512GB */
31extern signed char pfnnid_map[PFNNID_MAP_MAX];
32
33#ifndef CONFIG_64BIT
34#define pfn_is_io(pfn) ((pfn & (0xf0000000UL >> PAGE_SHIFT)) == (0xf0000000UL >> PAGE_SHIFT))
35#else
36/* io can be 0xf0f0f0f0f0xxxxxx or 0xfffffffff0000000 */
37#define pfn_is_io(pfn) ((pfn & (0xf000000000000000UL >> PAGE_SHIFT)) == (0xf000000000000000UL >> PAGE_SHIFT))
38#endif
39
40static inline int pfn_to_nid(unsigned long pfn)
41{
42 unsigned int i;
43
44 if (unlikely(pfn_is_io(pfn)))
45 return 0;
46
47 i = pfn >> PFNNID_SHIFT;
48 BUG_ON(i >= ARRAY_SIZE(pfnnid_map));
49
50 return pfnnid_map[i];
51}
52
53static inline int pfn_valid(int pfn)
54{
55 int nid = pfn_to_nid(pfn);
56
57 if (nid >= 0)
58 return (pfn < node_end_pfn(nid));
59 return 0;
60}
61
62#endif
63#endif /* _PARISC_MMZONE_H */ 7#endif /* _PARISC_MMZONE_H */
diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h
index b77f49ce6220..93caf17ac5e2 100644
--- a/arch/parisc/include/asm/page.h
+++ b/arch/parisc/include/asm/page.h
@@ -147,9 +147,9 @@ extern int npmem_ranges;
147#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) 147#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
148#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) 148#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
149 149
150#ifndef CONFIG_DISCONTIGMEM 150#ifndef CONFIG_SPARSEMEM
151#define pfn_valid(pfn) ((pfn) < max_mapnr) 151#define pfn_valid(pfn) ((pfn) < max_mapnr)
152#endif /* CONFIG_DISCONTIGMEM */ 152#endif
153 153
154#ifdef CONFIG_HUGETLB_PAGE 154#ifdef CONFIG_HUGETLB_PAGE
155#define HPAGE_SHIFT PMD_SHIFT /* fixed for transparent huge pages */ 155#define HPAGE_SHIFT PMD_SHIFT /* fixed for transparent huge pages */
diff --git a/arch/parisc/include/asm/patch.h b/arch/parisc/include/asm/patch.h
new file mode 100644
index 000000000000..685b58a13968
--- /dev/null
+++ b/arch/parisc/include/asm/patch.h
@@ -0,0 +1,11 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _PARISC_KERNEL_PATCH_H
3#define _PARISC_KERNEL_PATCH_H
4
5/* stop machine and patch kernel text */
6void patch_text(void *addr, unsigned int insn);
7
8/* patch kernel text with machine already stopped (e.g. in kgdb) */
9void __patch_text(void *addr, unsigned int insn);
10
11#endif
diff --git a/arch/parisc/include/asm/pgalloc.h b/arch/parisc/include/asm/pgalloc.h
index d05c678c77c4..ea75cc966dae 100644
--- a/arch/parisc/include/asm/pgalloc.h
+++ b/arch/parisc/include/asm/pgalloc.h
@@ -41,6 +41,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
41 __pgd_val_set(*pgd, PxD_FLAG_ATTACHED); 41 __pgd_val_set(*pgd, PxD_FLAG_ATTACHED);
42#endif 42#endif
43 } 43 }
44 spin_lock_init(pgd_spinlock(actual_pgd));
44 return actual_pgd; 45 return actual_pgd;
45} 46}
46 47
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
index c7bb74e22436..a39b079e73f2 100644
--- a/arch/parisc/include/asm/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
@@ -17,7 +17,7 @@
17#include <asm/processor.h> 17#include <asm/processor.h>
18#include <asm/cache.h> 18#include <asm/cache.h>
19 19
20extern spinlock_t pa_tlb_lock; 20static inline spinlock_t *pgd_spinlock(pgd_t *);
21 21
22/* 22/*
23 * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel 23 * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel
@@ -34,16 +34,46 @@ extern spinlock_t pa_tlb_lock;
34 */ 34 */
35#define kern_addr_valid(addr) (1) 35#define kern_addr_valid(addr) (1)
36 36
37/* Purge data and instruction TLB entries. Must be called holding 37/* This is for the serialization of PxTLB broadcasts. At least on the N class
38 * the pa_tlb_lock. The TLB purge instructions are slow on SMP 38 * systems, only one PxTLB inter processor broadcast can be active at any one
39 * machines since the purge must be broadcast to all CPUs. 39 * time on the Merced bus.
40
41 * PTE updates are protected by locks in the PMD.
42 */
43extern spinlock_t pa_tlb_flush_lock;
44extern spinlock_t pa_swapper_pg_lock;
45#if defined(CONFIG_64BIT) && defined(CONFIG_SMP)
46extern int pa_serialize_tlb_flushes;
47#else
48#define pa_serialize_tlb_flushes (0)
49#endif
50
51#define purge_tlb_start(flags) do { \
52 if (pa_serialize_tlb_flushes) \
53 spin_lock_irqsave(&pa_tlb_flush_lock, flags); \
54 else \
55 local_irq_save(flags); \
56 } while (0)
57#define purge_tlb_end(flags) do { \
58 if (pa_serialize_tlb_flushes) \
59 spin_unlock_irqrestore(&pa_tlb_flush_lock, flags); \
60 else \
61 local_irq_restore(flags); \
62 } while (0)
63
64/* Purge data and instruction TLB entries. The TLB purge instructions
65 * are slow on SMP machines since the purge must be broadcast to all CPUs.
40 */ 66 */
41 67
42static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr) 68static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
43{ 69{
70 unsigned long flags;
71
72 purge_tlb_start(flags);
44 mtsp(mm->context, 1); 73 mtsp(mm->context, 1);
45 pdtlb(addr); 74 pdtlb(addr);
46 pitlb(addr); 75 pitlb(addr);
76 purge_tlb_end(flags);
47} 77}
48 78
49/* Certain architectures need to do special things when PTEs 79/* Certain architectures need to do special things when PTEs
@@ -59,11 +89,11 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
59 do { \ 89 do { \
60 pte_t old_pte; \ 90 pte_t old_pte; \
61 unsigned long flags; \ 91 unsigned long flags; \
62 spin_lock_irqsave(&pa_tlb_lock, flags); \ 92 spin_lock_irqsave(pgd_spinlock((mm)->pgd), flags);\
63 old_pte = *ptep; \ 93 old_pte = *ptep; \
64 set_pte(ptep, pteval); \ 94 set_pte(ptep, pteval); \
65 purge_tlb_entries(mm, addr); \ 95 purge_tlb_entries(mm, addr); \
66 spin_unlock_irqrestore(&pa_tlb_lock, flags); \ 96 spin_unlock_irqrestore(pgd_spinlock((mm)->pgd), flags);\
67 } while (0) 97 } while (0)
68 98
69#endif /* !__ASSEMBLY__ */ 99#endif /* !__ASSEMBLY__ */
@@ -88,10 +118,10 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
88#if CONFIG_PGTABLE_LEVELS == 3 118#if CONFIG_PGTABLE_LEVELS == 3
89#define PGD_ORDER 1 /* Number of pages per pgd */ 119#define PGD_ORDER 1 /* Number of pages per pgd */
90#define PMD_ORDER 1 /* Number of pages per pmd */ 120#define PMD_ORDER 1 /* Number of pages per pmd */
91#define PGD_ALLOC_ORDER 2 /* first pgd contains pmd */ 121#define PGD_ALLOC_ORDER (2 + 1) /* first pgd contains pmd */
92#else 122#else
93#define PGD_ORDER 1 /* Number of pages per pgd */ 123#define PGD_ORDER 1 /* Number of pages per pgd */
94#define PGD_ALLOC_ORDER PGD_ORDER 124#define PGD_ALLOC_ORDER (PGD_ORDER + 1)
95#endif 125#endif
96 126
97/* Definitions for 3rd level (we use PLD here for Page Lower directory 127/* Definitions for 3rd level (we use PLD here for Page Lower directory
@@ -459,6 +489,15 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
459#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) 489#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
460#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) 490#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
461 491
492
493static inline spinlock_t *pgd_spinlock(pgd_t *pgd)
494{
495 if (unlikely(pgd == swapper_pg_dir))
496 return &pa_swapper_pg_lock;
497 return (spinlock_t *)((char *)pgd + (PAGE_SIZE << (PGD_ALLOC_ORDER - 1)));
498}
499
500
462static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) 501static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
463{ 502{
464 pte_t pte; 503 pte_t pte;
@@ -467,15 +506,15 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned
467 if (!pte_young(*ptep)) 506 if (!pte_young(*ptep))
468 return 0; 507 return 0;
469 508
470 spin_lock_irqsave(&pa_tlb_lock, flags); 509 spin_lock_irqsave(pgd_spinlock(vma->vm_mm->pgd), flags);
471 pte = *ptep; 510 pte = *ptep;
472 if (!pte_young(pte)) { 511 if (!pte_young(pte)) {
473 spin_unlock_irqrestore(&pa_tlb_lock, flags); 512 spin_unlock_irqrestore(pgd_spinlock(vma->vm_mm->pgd), flags);
474 return 0; 513 return 0;
475 } 514 }
476 set_pte(ptep, pte_mkold(pte)); 515 set_pte(ptep, pte_mkold(pte));
477 purge_tlb_entries(vma->vm_mm, addr); 516 purge_tlb_entries(vma->vm_mm, addr);
478 spin_unlock_irqrestore(&pa_tlb_lock, flags); 517 spin_unlock_irqrestore(pgd_spinlock(vma->vm_mm->pgd), flags);
479 return 1; 518 return 1;
480} 519}
481 520
@@ -485,11 +524,11 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
485 pte_t old_pte; 524 pte_t old_pte;
486 unsigned long flags; 525 unsigned long flags;
487 526
488 spin_lock_irqsave(&pa_tlb_lock, flags); 527 spin_lock_irqsave(pgd_spinlock(mm->pgd), flags);
489 old_pte = *ptep; 528 old_pte = *ptep;
490 set_pte(ptep, __pte(0)); 529 set_pte(ptep, __pte(0));
491 purge_tlb_entries(mm, addr); 530 purge_tlb_entries(mm, addr);
492 spin_unlock_irqrestore(&pa_tlb_lock, flags); 531 spin_unlock_irqrestore(pgd_spinlock(mm->pgd), flags);
493 532
494 return old_pte; 533 return old_pte;
495} 534}
@@ -497,10 +536,10 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
497static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 536static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
498{ 537{
499 unsigned long flags; 538 unsigned long flags;
500 spin_lock_irqsave(&pa_tlb_lock, flags); 539 spin_lock_irqsave(pgd_spinlock(mm->pgd), flags);
501 set_pte(ptep, pte_wrprotect(*ptep)); 540 set_pte(ptep, pte_wrprotect(*ptep));
502 purge_tlb_entries(mm, addr); 541 purge_tlb_entries(mm, addr);
503 spin_unlock_irqrestore(&pa_tlb_lock, flags); 542 spin_unlock_irqrestore(pgd_spinlock(mm->pgd), flags);
504} 543}
505 544
506#define pte_same(A,B) (pte_val(A) == pte_val(B)) 545#define pte_same(A,B) (pte_val(A) == pte_val(B))
diff --git a/arch/parisc/include/asm/ptrace.h b/arch/parisc/include/asm/ptrace.h
index 9ff033d261ab..143fb2a89dd8 100644
--- a/arch/parisc/include/asm/ptrace.h
+++ b/arch/parisc/include/asm/ptrace.h
@@ -37,4 +37,17 @@ extern int regs_query_register_offset(const char *name);
37extern const char *regs_query_register_name(unsigned int offset); 37extern const char *regs_query_register_name(unsigned int offset);
38#define MAX_REG_OFFSET (offsetof(struct pt_regs, ipsw)) 38#define MAX_REG_OFFSET (offsetof(struct pt_regs, ipsw))
39 39
40#define kernel_stack_pointer(regs) ((regs)->gr[30])
41
42static inline unsigned long regs_get_register(struct pt_regs *regs,
43 unsigned int offset)
44{
45 if (unlikely(offset > MAX_REG_OFFSET))
46 return 0;
47 return *(unsigned long *)((unsigned long)regs + offset);
48}
49
50unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n);
51int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr);
52
40#endif 53#endif
diff --git a/arch/parisc/include/asm/sparsemem.h b/arch/parisc/include/asm/sparsemem.h
new file mode 100644
index 000000000000..b5c3a79045b4
--- /dev/null
+++ b/arch/parisc/include/asm/sparsemem.h
@@ -0,0 +1,14 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef ASM_PARISC_SPARSEMEM_H
3#define ASM_PARISC_SPARSEMEM_H
4
5/* We have these possible memory map layouts:
6 * Astro: 0-3.75, 67.75-68, 4-64
7 * zx1: 0-1, 257-260, 4-256
8 * Stretch (N-class): 0-2, 4-32, 34-xxx
9 */
10
11#define MAX_PHYSMEM_BITS 39 /* 512 GB */
12#define SECTION_SIZE_BITS 27 /* 128 MB */
13
14#endif
diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h
index 8a63515f03bf..197d2247e4db 100644
--- a/arch/parisc/include/asm/spinlock.h
+++ b/arch/parisc/include/asm/spinlock.h
@@ -37,7 +37,11 @@ static inline void arch_spin_unlock(arch_spinlock_t *x)
37 volatile unsigned int *a; 37 volatile unsigned int *a;
38 38
39 a = __ldcw_align(x); 39 a = __ldcw_align(x);
40#ifdef CONFIG_SMP
41 (void) __ldcw(a);
42#else
40 mb(); 43 mb();
44#endif
41 *a = 1; 45 *a = 1;
42} 46}
43 47
diff --git a/arch/parisc/include/asm/tlbflush.h b/arch/parisc/include/asm/tlbflush.h
index 6804374efa66..c5ded01d45be 100644
--- a/arch/parisc/include/asm/tlbflush.h
+++ b/arch/parisc/include/asm/tlbflush.h
@@ -8,21 +8,6 @@
8#include <linux/sched.h> 8#include <linux/sched.h>
9#include <asm/mmu_context.h> 9#include <asm/mmu_context.h>
10 10
11
12/* This is for the serialisation of PxTLB broadcasts. At least on the
13 * N class systems, only one PxTLB inter processor broadcast can be
14 * active at any one time on the Merced bus. This tlb purge
15 * synchronisation is fairly lightweight and harmless so we activate
16 * it on all systems not just the N class.
17
18 * It is also used to ensure PTE updates are atomic and consistent
19 * with the TLB.
20 */
21extern spinlock_t pa_tlb_lock;
22
23#define purge_tlb_start(flags) spin_lock_irqsave(&pa_tlb_lock, flags)
24#define purge_tlb_end(flags) spin_unlock_irqrestore(&pa_tlb_lock, flags)
25
26extern void flush_tlb_all(void); 11extern void flush_tlb_all(void);
27extern void flush_tlb_all_local(void *); 12extern void flush_tlb_all_local(void *);
28 13
@@ -79,13 +64,6 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
79static inline void flush_tlb_page(struct vm_area_struct *vma, 64static inline void flush_tlb_page(struct vm_area_struct *vma,
80 unsigned long addr) 65 unsigned long addr)
81{ 66{
82 unsigned long flags, sid; 67 purge_tlb_entries(vma->vm_mm, addr);
83
84 sid = vma->vm_mm->context;
85 purge_tlb_start(flags);
86 mtsp(sid, 1);
87 pdtlb(addr);
88 pitlb(addr);
89 purge_tlb_end(flags);
90} 68}
91#endif 69#endif
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
index 8e5f1ab65c68..fc0df5c44468 100644
--- a/arch/parisc/kernel/Makefile
+++ b/arch/parisc/kernel/Makefile
@@ -9,7 +9,8 @@ obj-y := cache.o pacache.o setup.o pdt.o traps.o time.o irq.o \
9 pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \ 9 pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \
10 ptrace.o hardware.o inventory.o drivers.o alternative.o \ 10 ptrace.o hardware.o inventory.o drivers.o alternative.o \
11 signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \ 11 signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \
12 process.o processor.o pdc_cons.o pdc_chassis.o unwind.o 12 process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \
13 patch.o
13 14
14ifdef CONFIG_FUNCTION_TRACER 15ifdef CONFIG_FUNCTION_TRACER
15# Do not profile debug and lowlevel utilities 16# Do not profile debug and lowlevel utilities
@@ -32,3 +33,6 @@ obj-$(CONFIG_64BIT) += perf.o perf_asm.o $(obj64-y)
32obj-$(CONFIG_PARISC_CPU_TOPOLOGY) += topology.o 33obj-$(CONFIG_PARISC_CPU_TOPOLOGY) += topology.o
33obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o 34obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o
34obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o 35obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
36obj-$(CONFIG_JUMP_LABEL) += jump_label.o
37obj-$(CONFIG_KGDB) += kgdb.o
38obj-$(CONFIG_KPROBES) += kprobes.o
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 804880efa11e..0338561968a4 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -40,12 +40,19 @@ void purge_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
40void flush_icache_page_asm(unsigned long phys_addr, unsigned long vaddr); 40void flush_icache_page_asm(unsigned long phys_addr, unsigned long vaddr);
41 41
42 42
43/* On some machines (e.g. ones with the Merced bus), there can be 43/* On some machines (i.e., ones with the Merced bus), there can be
44 * only a single PxTLB broadcast at a time; this must be guaranteed 44 * only a single PxTLB broadcast at a time; this must be guaranteed
45 * by software. We put a spinlock around all TLB flushes to 45 * by software. We need a spinlock around all TLB flushes to ensure
46 * ensure this. 46 * this.
47 */ 47 */
48DEFINE_SPINLOCK(pa_tlb_lock); 48DEFINE_SPINLOCK(pa_tlb_flush_lock);
49
50/* Swapper page setup lock. */
51DEFINE_SPINLOCK(pa_swapper_pg_lock);
52
53#if defined(CONFIG_64BIT) && defined(CONFIG_SMP)
54int pa_serialize_tlb_flushes __read_mostly;
55#endif
49 56
50struct pdc_cache_info cache_info __read_mostly; 57struct pdc_cache_info cache_info __read_mostly;
51#ifndef CONFIG_PA20 58#ifndef CONFIG_PA20
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index 5eb979d04b90..15e7b3be7b6b 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -38,6 +38,7 @@
38#include <asm/io.h> 38#include <asm/io.h>
39#include <asm/pdc.h> 39#include <asm/pdc.h>
40#include <asm/parisc-device.h> 40#include <asm/parisc-device.h>
41#include <asm/ropes.h>
41 42
42/* See comments in include/asm-parisc/pci.h */ 43/* See comments in include/asm-parisc/pci.h */
43const struct dma_map_ops *hppa_dma_ops __read_mostly; 44const struct dma_map_ops *hppa_dma_ops __read_mostly;
@@ -257,6 +258,30 @@ static struct parisc_device *find_device_by_addr(unsigned long hpa)
257 return ret ? d.dev : NULL; 258 return ret ? d.dev : NULL;
258} 259}
259 260
261static int __init is_IKE_device(struct device *dev, void *data)
262{
263 struct parisc_device *pdev = to_parisc_device(dev);
264
265 if (!check_dev(dev))
266 return 0;
267 if (pdev->id.hw_type != HPHW_BCPORT)
268 return 0;
269 if (IS_IKE(pdev) ||
270 (pdev->id.hversion == REO_MERCED_PORT) ||
271 (pdev->id.hversion == REOG_MERCED_PORT)) {
272 return 1;
273 }
274 return 0;
275}
276
277int __init machine_has_merced_bus(void)
278{
279 int ret;
280
281 ret = for_each_padev(is_IKE_device, NULL);
282 return ret ? 1 : 0;
283}
284
260/** 285/**
261 * find_pa_parent_type - Find a parent of a specific type 286 * find_pa_parent_type - Find a parent of a specific type
262 * @dev: The device to start searching from 287 * @dev: The device to start searching from
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index d5eb19efa65b..a1fc04570ade 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -50,12 +50,8 @@
50 50
51 .import pa_tlb_lock,data 51 .import pa_tlb_lock,data
52 .macro load_pa_tlb_lock reg 52 .macro load_pa_tlb_lock reg
53#if __PA_LDCW_ALIGNMENT > 4 53 mfctl %cr25,\reg
54 load32 PA(pa_tlb_lock) + __PA_LDCW_ALIGNMENT-1, \reg 54 addil L%(PAGE_SIZE << (PGD_ALLOC_ORDER - 1)),\reg
55 depi 0,31,__PA_LDCW_ALIGN_ORDER, \reg
56#else
57 load32 PA(pa_tlb_lock), \reg
58#endif
59 .endm 55 .endm
60 56
61 /* space_to_prot macro creates a prot id from a space id */ 57 /* space_to_prot macro creates a prot id from a space id */
@@ -471,8 +467,9 @@
471 nop 467 nop
472 LDREG 0(\ptp),\pte 468 LDREG 0(\ptp),\pte
473 bb,<,n \pte,_PAGE_PRESENT_BIT,3f 469 bb,<,n \pte,_PAGE_PRESENT_BIT,3f
470 LDCW 0(\tmp),\tmp1
474 b \fault 471 b \fault
475 stw,ma \spc,0(\tmp) 472 stw \spc,0(\tmp)
47699: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) 47399: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
477#endif 474#endif
4782: LDREG 0(\ptp),\pte 4752: LDREG 0(\ptp),\pte
@@ -481,20 +478,22 @@
481 .endm 478 .endm
482 479
483 /* Release pa_tlb_lock lock without reloading lock address. */ 480 /* Release pa_tlb_lock lock without reloading lock address. */
484 .macro tlb_unlock0 spc,tmp 481 .macro tlb_unlock0 spc,tmp,tmp1
485#ifdef CONFIG_SMP 482#ifdef CONFIG_SMP
48698: or,COND(=) %r0,\spc,%r0 48398: or,COND(=) %r0,\spc,%r0
487 stw,ma \spc,0(\tmp) 484 LDCW 0(\tmp),\tmp1
485 or,COND(=) %r0,\spc,%r0
486 stw \spc,0(\tmp)
48899: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) 48799: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
489#endif 488#endif
490 .endm 489 .endm
491 490
492 /* Release pa_tlb_lock lock. */ 491 /* Release pa_tlb_lock lock. */
493 .macro tlb_unlock1 spc,tmp 492 .macro tlb_unlock1 spc,tmp,tmp1
494#ifdef CONFIG_SMP 493#ifdef CONFIG_SMP
49598: load_pa_tlb_lock \tmp 49498: load_pa_tlb_lock \tmp
49699: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) 49599: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
497 tlb_unlock0 \spc,\tmp 496 tlb_unlock0 \spc,\tmp,\tmp1
498#endif 497#endif
499 .endm 498 .endm
500 499
@@ -1177,7 +1176,7 @@ dtlb_miss_20w:
1177 1176
1178 idtlbt pte,prot 1177 idtlbt pte,prot
1179 1178
1180 tlb_unlock1 spc,t0 1179 tlb_unlock1 spc,t0,t1
1181 rfir 1180 rfir
1182 nop 1181 nop
1183 1182
@@ -1203,7 +1202,7 @@ nadtlb_miss_20w:
1203 1202
1204 idtlbt pte,prot 1203 idtlbt pte,prot
1205 1204
1206 tlb_unlock1 spc,t0 1205 tlb_unlock1 spc,t0,t1
1207 rfir 1206 rfir
1208 nop 1207 nop
1209 1208
@@ -1237,7 +1236,7 @@ dtlb_miss_11:
1237 1236
1238 mtsp t1, %sr1 /* Restore sr1 */ 1237 mtsp t1, %sr1 /* Restore sr1 */
1239 1238
1240 tlb_unlock1 spc,t0 1239 tlb_unlock1 spc,t0,t1
1241 rfir 1240 rfir
1242 nop 1241 nop
1243 1242
@@ -1270,7 +1269,7 @@ nadtlb_miss_11:
1270 1269
1271 mtsp t1, %sr1 /* Restore sr1 */ 1270 mtsp t1, %sr1 /* Restore sr1 */
1272 1271
1273 tlb_unlock1 spc,t0 1272 tlb_unlock1 spc,t0,t1
1274 rfir 1273 rfir
1275 nop 1274 nop
1276 1275
@@ -1299,7 +1298,7 @@ dtlb_miss_20:
1299 1298
1300 idtlbt pte,prot 1299 idtlbt pte,prot
1301 1300
1302 tlb_unlock1 spc,t0 1301 tlb_unlock1 spc,t0,t1
1303 rfir 1302 rfir
1304 nop 1303 nop
1305 1304
@@ -1327,7 +1326,7 @@ nadtlb_miss_20:
1327 1326
1328 idtlbt pte,prot 1327 idtlbt pte,prot
1329 1328
1330 tlb_unlock1 spc,t0 1329 tlb_unlock1 spc,t0,t1
1331 rfir 1330 rfir
1332 nop 1331 nop
1333 1332
@@ -1434,7 +1433,7 @@ itlb_miss_20w:
1434 1433
1435 iitlbt pte,prot 1434 iitlbt pte,prot
1436 1435
1437 tlb_unlock1 spc,t0 1436 tlb_unlock1 spc,t0,t1
1438 rfir 1437 rfir
1439 nop 1438 nop
1440 1439
@@ -1458,7 +1457,7 @@ naitlb_miss_20w:
1458 1457
1459 iitlbt pte,prot 1458 iitlbt pte,prot
1460 1459
1461 tlb_unlock1 spc,t0 1460 tlb_unlock1 spc,t0,t1
1462 rfir 1461 rfir
1463 nop 1462 nop
1464 1463
@@ -1492,7 +1491,7 @@ itlb_miss_11:
1492 1491
1493 mtsp t1, %sr1 /* Restore sr1 */ 1492 mtsp t1, %sr1 /* Restore sr1 */
1494 1493
1495 tlb_unlock1 spc,t0 1494 tlb_unlock1 spc,t0,t1
1496 rfir 1495 rfir
1497 nop 1496 nop
1498 1497
@@ -1516,7 +1515,7 @@ naitlb_miss_11:
1516 1515
1517 mtsp t1, %sr1 /* Restore sr1 */ 1516 mtsp t1, %sr1 /* Restore sr1 */
1518 1517
1519 tlb_unlock1 spc,t0 1518 tlb_unlock1 spc,t0,t1
1520 rfir 1519 rfir
1521 nop 1520 nop
1522 1521
@@ -1546,7 +1545,7 @@ itlb_miss_20:
1546 1545
1547 iitlbt pte,prot 1546 iitlbt pte,prot
1548 1547
1549 tlb_unlock1 spc,t0 1548 tlb_unlock1 spc,t0,t1
1550 rfir 1549 rfir
1551 nop 1550 nop
1552 1551
@@ -1566,7 +1565,7 @@ naitlb_miss_20:
1566 1565
1567 iitlbt pte,prot 1566 iitlbt pte,prot
1568 1567
1569 tlb_unlock1 spc,t0 1568 tlb_unlock1 spc,t0,t1
1570 rfir 1569 rfir
1571 nop 1570 nop
1572 1571
@@ -1596,7 +1595,7 @@ dbit_trap_20w:
1596 1595
1597 idtlbt pte,prot 1596 idtlbt pte,prot
1598 1597
1599 tlb_unlock0 spc,t0 1598 tlb_unlock0 spc,t0,t1
1600 rfir 1599 rfir
1601 nop 1600 nop
1602#else 1601#else
@@ -1622,7 +1621,7 @@ dbit_trap_11:
1622 1621
1623 mtsp t1, %sr1 /* Restore sr1 */ 1622 mtsp t1, %sr1 /* Restore sr1 */
1624 1623
1625 tlb_unlock0 spc,t0 1624 tlb_unlock0 spc,t0,t1
1626 rfir 1625 rfir
1627 nop 1626 nop
1628 1627
@@ -1642,7 +1641,7 @@ dbit_trap_20:
1642 1641
1643 idtlbt pte,prot 1642 idtlbt pte,prot
1644 1643
1645 tlb_unlock0 spc,t0 1644 tlb_unlock0 spc,t0,t1
1646 rfir 1645 rfir
1647 nop 1646 nop
1648#endif 1647#endif
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
index fbb4e43fda05..d12de2a13753 100644
--- a/arch/parisc/kernel/head.S
+++ b/arch/parisc/kernel/head.S
@@ -22,7 +22,7 @@
22#include <linux/linkage.h> 22#include <linux/linkage.h>
23#include <linux/init.h> 23#include <linux/init.h>
24 24
25 .level LEVEL 25 .level PA_ASM_LEVEL
26 26
27 __INITDATA 27 __INITDATA
28ENTRY(boot_args) 28ENTRY(boot_args)
@@ -258,7 +258,7 @@ stext_pdc_ret:
258 ldo R%PA(fault_vector_11)(%r10),%r10 258 ldo R%PA(fault_vector_11)(%r10),%r10
259 259
260$is_pa20: 260$is_pa20:
261 .level LEVEL /* restore 1.1 || 2.0w */ 261 .level PA_ASM_LEVEL /* restore 1.1 || 2.0w */
262#endif /*!CONFIG_64BIT*/ 262#endif /*!CONFIG_64BIT*/
263 load32 PA(fault_vector_20),%r10 263 load32 PA(fault_vector_20),%r10
264 264
@@ -329,6 +329,19 @@ smp_slave_stext:
329 mtsp %r0,%sr6 329 mtsp %r0,%sr6
330 mtsp %r0,%sr7 330 mtsp %r0,%sr7
331 331
332#ifdef CONFIG_64BIT
333 /*
334 * Enable Wide mode early, in case the task_struct for the idle
335 * task in smp_init_current_idle_task was allocated above 4GB.
336 */
3371: mfia %rp /* clear upper part of pcoq */
338 ldo 2f-1b(%rp),%rp
339 depdi 0,31,32,%rp
340 bv (%rp)
341 ssm PSW_SM_W,%r0
3422:
343#endif
344
332 /* Initialize the SP - monarch sets up smp_init_current_idle_task */ 345 /* Initialize the SP - monarch sets up smp_init_current_idle_task */
333 load32 PA(smp_init_current_idle_task),%sp 346 load32 PA(smp_init_current_idle_task),%sp
334 LDREG 0(%sp),%sp /* load task address */ 347 LDREG 0(%sp),%sp /* load task address */
diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c
index 35d05fdd7483..6f2d611347a1 100644
--- a/arch/parisc/kernel/inventory.c
+++ b/arch/parisc/kernel/inventory.c
@@ -31,6 +31,7 @@
31#include <asm/processor.h> 31#include <asm/processor.h>
32#include <asm/page.h> 32#include <asm/page.h>
33#include <asm/parisc-device.h> 33#include <asm/parisc-device.h>
34#include <asm/tlbflush.h>
34 35
35/* 36/*
36** Debug options 37** Debug options
@@ -638,4 +639,10 @@ void __init do_device_inventory(void)
638 } 639 }
639 printk(KERN_INFO "Found devices:\n"); 640 printk(KERN_INFO "Found devices:\n");
640 print_parisc_devices(); 641 print_parisc_devices();
642
643#if defined(CONFIG_64BIT) && defined(CONFIG_SMP)
644 pa_serialize_tlb_flushes = machine_has_merced_bus();
645 if (pa_serialize_tlb_flushes)
646 pr_info("Merced bus found: Enable PxTLB serialization.\n");
647#endif
641} 648}
diff --git a/arch/parisc/kernel/jump_label.c b/arch/parisc/kernel/jump_label.c
new file mode 100644
index 000000000000..d2f3cb12e282
--- /dev/null
+++ b/arch/parisc/kernel/jump_label.c
@@ -0,0 +1,55 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2019 Helge Deller <deller@gmx.de>
4 *
5 * Based on arch/arm64/kernel/jump_label.c
6 */
7#include <linux/kernel.h>
8#include <linux/jump_label.h>
9#include <linux/bug.h>
10#include <asm/alternative.h>
11#include <asm/patch.h>
12
13static inline int reassemble_17(int as17)
14{
15 return (((as17 & 0x10000) >> 16) |
16 ((as17 & 0x0f800) << 5) |
17 ((as17 & 0x00400) >> 8) |
18 ((as17 & 0x003ff) << 3));
19}
20
21void arch_jump_label_transform(struct jump_entry *entry,
22 enum jump_label_type type)
23{
24 void *addr = (void *)jump_entry_code(entry);
25 u32 insn;
26
27 if (type == JUMP_LABEL_JMP) {
28 void *target = (void *)jump_entry_target(entry);
29 int distance = target - addr;
30 /*
31 * Encode the PA1.1 "b,n" instruction with a 17-bit
32 * displacement. In case we hit the BUG(), we could use
33 * another branch instruction with a 22-bit displacement on
34 * 64-bit CPUs instead. But this seems sufficient for now.
35 */
36 distance -= 8;
37 BUG_ON(distance > 262143 || distance < -262144);
38 insn = 0xe8000002 | reassemble_17(distance >> 2);
39 } else {
40 insn = INSN_NOP;
41 }
42
43 patch_text(addr, insn);
44}
45
46void arch_jump_label_transform_static(struct jump_entry *entry,
47 enum jump_label_type type)
48{
49 /*
50 * We use the architected NOP in arch_static_branch, so there's no
51 * need to patch an identical NOP over the top of it here. The core
52 * will call arch_jump_label_transform from a module notifier if the
53 * NOP needs to be replaced by a branch.
54 */
55}
diff --git a/arch/parisc/kernel/kgdb.c b/arch/parisc/kernel/kgdb.c
new file mode 100644
index 000000000000..664278db9b97
--- /dev/null
+++ b/arch/parisc/kernel/kgdb.c
@@ -0,0 +1,209 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * PA-RISC KGDB support
4 *
5 * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org>
6 *
7 */
8
9#include <linux/kgdb.h>
10#include <linux/string.h>
11#include <linux/sched.h>
12#include <linux/notifier.h>
13#include <linux/kdebug.h>
14#include <linux/uaccess.h>
15#include <asm/ptrace.h>
16#include <asm/traps.h>
17#include <asm/processor.h>
18#include <asm/patch.h>
19#include <asm/cacheflush.h>
20
21const struct kgdb_arch arch_kgdb_ops = {
22 .gdb_bpt_instr = { 0x03, 0xff, 0xa0, 0x1f }
23};
24
25static int __kgdb_notify(struct die_args *args, unsigned long cmd)
26{
27 struct pt_regs *regs = args->regs;
28
29 if (kgdb_handle_exception(1, args->signr, cmd, regs))
30 return NOTIFY_DONE;
31 return NOTIFY_STOP;
32}
33
34static int kgdb_notify(struct notifier_block *self,
35 unsigned long cmd, void *ptr)
36{
37 unsigned long flags;
38 int ret;
39
40 local_irq_save(flags);
41 ret = __kgdb_notify(ptr, cmd);
42 local_irq_restore(flags);
43
44 return ret;
45}
46
47static struct notifier_block kgdb_notifier = {
48 .notifier_call = kgdb_notify,
49 .priority = -INT_MAX,
50};
51
52int kgdb_arch_init(void)
53{
54 return register_die_notifier(&kgdb_notifier);
55}
56
57void kgdb_arch_exit(void)
58{
59 unregister_die_notifier(&kgdb_notifier);
60}
61
62void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
63{
64 struct parisc_gdb_regs *gr = (struct parisc_gdb_regs *)gdb_regs;
65
66 memset(gr, 0, sizeof(struct parisc_gdb_regs));
67
68 memcpy(gr->gpr, regs->gr, sizeof(gr->gpr));
69 memcpy(gr->fr, regs->fr, sizeof(gr->fr));
70
71 gr->sr0 = regs->sr[0];
72 gr->sr1 = regs->sr[1];
73 gr->sr2 = regs->sr[2];
74 gr->sr3 = regs->sr[3];
75 gr->sr4 = regs->sr[4];
76 gr->sr5 = regs->sr[5];
77 gr->sr6 = regs->sr[6];
78 gr->sr7 = regs->sr[7];
79
80 gr->sar = regs->sar;
81 gr->iir = regs->iir;
82 gr->isr = regs->isr;
83 gr->ior = regs->ior;
84 gr->ipsw = regs->ipsw;
85 gr->cr27 = regs->cr27;
86
87 gr->iaoq_f = regs->iaoq[0];
88 gr->iasq_f = regs->iasq[0];
89
90 gr->iaoq_b = regs->iaoq[1];
91 gr->iasq_b = regs->iasq[1];
92}
93
94void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
95{
96 struct parisc_gdb_regs *gr = (struct parisc_gdb_regs *)gdb_regs;
97
98
99 memcpy(regs->gr, gr->gpr, sizeof(regs->gr));
100 memcpy(regs->fr, gr->fr, sizeof(regs->fr));
101
102 regs->sr[0] = gr->sr0;
103 regs->sr[1] = gr->sr1;
104 regs->sr[2] = gr->sr2;
105 regs->sr[3] = gr->sr3;
106 regs->sr[4] = gr->sr4;
107 regs->sr[5] = gr->sr5;
108 regs->sr[6] = gr->sr6;
109 regs->sr[7] = gr->sr7;
110
111 regs->sar = gr->sar;
112 regs->iir = gr->iir;
113 regs->isr = gr->isr;
114 regs->ior = gr->ior;
115 regs->ipsw = gr->ipsw;
116 regs->cr27 = gr->cr27;
117
118 regs->iaoq[0] = gr->iaoq_f;
119 regs->iasq[0] = gr->iasq_f;
120
121 regs->iaoq[1] = gr->iaoq_b;
122 regs->iasq[1] = gr->iasq_b;
123}
124
125void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs,
126 struct task_struct *task)
127{
128 struct pt_regs *regs = task_pt_regs(task);
129 unsigned long gr30, iaoq;
130
131 gr30 = regs->gr[30];
132 iaoq = regs->iaoq[0];
133
134 regs->gr[30] = regs->ksp;
135 regs->iaoq[0] = regs->kpc;
136 pt_regs_to_gdb_regs(gdb_regs, regs);
137
138 regs->gr[30] = gr30;
139 regs->iaoq[0] = iaoq;
140
141}
142
143static void step_instruction_queue(struct pt_regs *regs)
144{
145 regs->iaoq[0] = regs->iaoq[1];
146 regs->iaoq[1] += 4;
147}
148
149void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
150{
151 regs->iaoq[0] = ip;
152 regs->iaoq[1] = ip + 4;
153}
154
155int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
156{
157 int ret = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
158 BREAK_INSTR_SIZE);
159 if (ret)
160 return ret;
161
162 __patch_text((void *)bpt->bpt_addr,
163 *(unsigned int *)&arch_kgdb_ops.gdb_bpt_instr);
164 return ret;
165}
166
167int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
168{
169 __patch_text((void *)bpt->bpt_addr, *(unsigned int *)&bpt->saved_instr);
170 return 0;
171}
172
173int kgdb_arch_handle_exception(int trap, int signo,
174 int err_code, char *inbuf, char *outbuf,
175 struct pt_regs *regs)
176{
177 unsigned long addr;
178 char *p = inbuf + 1;
179
180 switch (inbuf[0]) {
181 case 'D':
182 case 'c':
183 case 'k':
184 kgdb_contthread = NULL;
185 kgdb_single_step = 0;
186
187 if (kgdb_hex2long(&p, &addr))
188 kgdb_arch_set_pc(regs, addr);
189 else if (trap == 9 && regs->iir ==
190 PARISC_KGDB_COMPILED_BREAK_INSN)
191 step_instruction_queue(regs);
192 return 0;
193 case 's':
194 kgdb_single_step = 1;
195 if (kgdb_hex2long(&p, &addr)) {
196 kgdb_arch_set_pc(regs, addr);
197 } else if (trap == 9 && regs->iir ==
198 PARISC_KGDB_COMPILED_BREAK_INSN) {
199 step_instruction_queue(regs);
200 mtctl(-1, 0);
201 } else {
202 mtctl(0, 0);
203 }
204 regs->gr[0] |= PSW_R;
205 return 0;
206
207 }
208 return -1;
209}
diff --git a/arch/parisc/kernel/kprobes.c b/arch/parisc/kernel/kprobes.c
new file mode 100644
index 000000000000..d58960b33bda
--- /dev/null
+++ b/arch/parisc/kernel/kprobes.c
@@ -0,0 +1,291 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * arch/parisc/kernel/kprobes.c
4 *
5 * PA-RISC kprobes implementation
6 *
7 * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org>
8 */
9
10#include <linux/types.h>
11#include <linux/kprobes.h>
12#include <linux/slab.h>
13#include <asm/cacheflush.h>
14#include <asm/patch.h>
15
16DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
17DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
18
19int __kprobes arch_prepare_kprobe(struct kprobe *p)
20{
21 if ((unsigned long)p->addr & 3UL)
22 return -EINVAL;
23
24 p->ainsn.insn = get_insn_slot();
25 if (!p->ainsn.insn)
26 return -ENOMEM;
27
28 memcpy(p->ainsn.insn, p->addr,
29 MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
30 p->opcode = *p->addr;
31 flush_insn_slot(p);
32 return 0;
33}
34
35void __kprobes arch_remove_kprobe(struct kprobe *p)
36{
37 if (!p->ainsn.insn)
38 return;
39
40 free_insn_slot(p->ainsn.insn, 0);
41 p->ainsn.insn = NULL;
42}
43
44void __kprobes arch_arm_kprobe(struct kprobe *p)
45{
46 patch_text(p->addr, PARISC_KPROBES_BREAK_INSN);
47}
48
49void __kprobes arch_disarm_kprobe(struct kprobe *p)
50{
51 patch_text(p->addr, p->opcode);
52}
53
54static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
55{
56 kcb->prev_kprobe.kp = kprobe_running();
57 kcb->prev_kprobe.status = kcb->kprobe_status;
58}
59
60static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
61{
62 __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
63 kcb->kprobe_status = kcb->prev_kprobe.status;
64}
65
66static inline void __kprobes set_current_kprobe(struct kprobe *p)
67{
68 __this_cpu_write(current_kprobe, p);
69}
70
71static void __kprobes setup_singlestep(struct kprobe *p,
72 struct kprobe_ctlblk *kcb, struct pt_regs *regs)
73{
74 kcb->iaoq[0] = regs->iaoq[0];
75 kcb->iaoq[1] = regs->iaoq[1];
76 regs->iaoq[0] = (unsigned long)p->ainsn.insn;
77 mtctl(0, 0);
78 regs->gr[0] |= PSW_R;
79}
80
81int __kprobes parisc_kprobe_break_handler(struct pt_regs *regs)
82{
83 struct kprobe *p;
84 struct kprobe_ctlblk *kcb;
85
86 preempt_disable();
87
88 kcb = get_kprobe_ctlblk();
89 p = get_kprobe((unsigned long *)regs->iaoq[0]);
90
91 if (!p) {
92 preempt_enable_no_resched();
93 return 0;
94 }
95
96 if (kprobe_running()) {
97 /*
98 * We have reentered the kprobe_handler, since another kprobe
99 * was hit while within the handler, we save the original
100 * kprobes and single step on the instruction of the new probe
101 * without calling any user handlers to avoid recursive
102 * kprobes.
103 */
104 save_previous_kprobe(kcb);
105 set_current_kprobe(p);
106 kprobes_inc_nmissed_count(p);
107 setup_singlestep(p, kcb, regs);
108 kcb->kprobe_status = KPROBE_REENTER;
109 return 1;
110 }
111
112 set_current_kprobe(p);
113 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
114
115 /* If we have no pre-handler or it returned 0, we continue with
116 * normal processing. If we have a pre-handler and it returned
117 * non-zero - which means user handler setup registers to exit
118 * to another instruction, we must skip the single stepping.
119 */
120
121 if (!p->pre_handler || !p->pre_handler(p, regs)) {
122 setup_singlestep(p, kcb, regs);
123 kcb->kprobe_status = KPROBE_HIT_SS;
124 } else {
125 reset_current_kprobe();
126 preempt_enable_no_resched();
127 }
128 return 1;
129}
130
131int __kprobes parisc_kprobe_ss_handler(struct pt_regs *regs)
132{
133 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
134 struct kprobe *p = kprobe_running();
135
136 if (regs->iaoq[0] != (unsigned long)p->ainsn.insn+4)
137 return 0;
138
139 /* restore back original saved kprobe variables and continue */
140 if (kcb->kprobe_status == KPROBE_REENTER) {
141 restore_previous_kprobe(kcb);
142 return 1;
143 }
144
145 /* for absolute branch instructions we can copy iaoq_b. for relative
146 * branch instructions we need to calculate the new address based on the
147 * difference between iaoq_f and iaoq_b. We cannot use iaoq_b without
148 * modificationt because it's based on our ainsn.insn address.
149 */
150
151 if (p->post_handler)
152 p->post_handler(p, regs, 0);
153
154 switch (regs->iir >> 26) {
155 case 0x38: /* BE */
156 case 0x39: /* BE,L */
157 case 0x3a: /* BV */
158 case 0x3b: /* BVE */
159 /* for absolute branches, regs->iaoq[1] has already the right
160 * address
161 */
162 regs->iaoq[0] = kcb->iaoq[1];
163 break;
164 default:
165 regs->iaoq[1] = kcb->iaoq[0];
166 regs->iaoq[1] += (regs->iaoq[1] - regs->iaoq[0]) + 4;
167 regs->iaoq[0] = kcb->iaoq[1];
168 break;
169 }
170 kcb->kprobe_status = KPROBE_HIT_SSDONE;
171 reset_current_kprobe();
172 return 1;
173}
174
175static inline void kretprobe_trampoline(void)
176{
177 asm volatile("nop");
178 asm volatile("nop");
179}
180
181static int __kprobes trampoline_probe_handler(struct kprobe *p,
182 struct pt_regs *regs);
183
184static struct kprobe trampoline_p = {
185 .pre_handler = trampoline_probe_handler
186};
187
188static int __kprobes trampoline_probe_handler(struct kprobe *p,
189 struct pt_regs *regs)
190{
191 struct kretprobe_instance *ri = NULL;
192 struct hlist_head *head, empty_rp;
193 struct hlist_node *tmp;
194 unsigned long flags, orig_ret_address = 0;
195 unsigned long trampoline_address = (unsigned long)trampoline_p.addr;
196 kprobe_opcode_t *correct_ret_addr = NULL;
197
198 INIT_HLIST_HEAD(&empty_rp);
199 kretprobe_hash_lock(current, &head, &flags);
200
201 /*
202 * It is possible to have multiple instances associated with a given
203 * task either because multiple functions in the call path have
204 * a return probe installed on them, and/or more than one return
205 * probe was registered for a target function.
206 *
207 * We can handle this because:
208 * - instances are always inserted at the head of the list
209 * - when multiple return probes are registered for the same
210 * function, the first instance's ret_addr will point to the
211 * real return address, and all the rest will point to
212 * kretprobe_trampoline
213 */
214 hlist_for_each_entry_safe(ri, tmp, head, hlist) {
215 if (ri->task != current)
216 /* another task is sharing our hash bucket */
217 continue;
218
219 orig_ret_address = (unsigned long)ri->ret_addr;
220
221 if (orig_ret_address != trampoline_address)
222 /*
223 * This is the real return address. Any other
224 * instances associated with this task are for
225 * other calls deeper on the call stack
226 */
227 break;
228 }
229
230 kretprobe_assert(ri, orig_ret_address, trampoline_address);
231
232 correct_ret_addr = ri->ret_addr;
233 hlist_for_each_entry_safe(ri, tmp, head, hlist) {
234 if (ri->task != current)
235 /* another task is sharing our hash bucket */
236 continue;
237
238 orig_ret_address = (unsigned long)ri->ret_addr;
239 if (ri->rp && ri->rp->handler) {
240 __this_cpu_write(current_kprobe, &ri->rp->kp);
241 get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
242 ri->ret_addr = correct_ret_addr;
243 ri->rp->handler(ri, regs);
244 __this_cpu_write(current_kprobe, NULL);
245 }
246
247 recycle_rp_inst(ri, &empty_rp);
248
249 if (orig_ret_address != trampoline_address)
250 /*
251 * This is the real return address. Any other
252 * instances associated with this task are for
253 * other calls deeper on the call stack
254 */
255 break;
256 }
257
258 kretprobe_hash_unlock(current, &flags);
259
260 hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
261 hlist_del(&ri->hlist);
262 kfree(ri);
263 }
264 instruction_pointer_set(regs, orig_ret_address);
265 return 1;
266}
267
268void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
269 struct pt_regs *regs)
270{
271 ri->ret_addr = (kprobe_opcode_t *)regs->gr[2];
272
273 /* Replace the return addr with trampoline addr. */
274 regs->gr[2] = (unsigned long)trampoline_p.addr;
275}
276
277int __kprobes arch_trampoline_kprobe(struct kprobe *p)
278{
279 return p->addr == trampoline_p.addr;
280}
281bool arch_kprobe_on_func_entry(unsigned long offset)
282{
283 return !offset;
284}
285
286int __init arch_init_kprobes(void)
287{
288 trampoline_p.addr = (kprobe_opcode_t *)
289 dereference_function_descriptor(kretprobe_trampoline);
290 return register_kprobe(&trampoline_p);
291}
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index 187f032c9dd8..4e4e8eb25874 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -311,39 +311,6 @@ fdsync:
311 nop 311 nop
312ENDPROC_CFI(flush_data_cache_local) 312ENDPROC_CFI(flush_data_cache_local)
313 313
314/* Macros to serialize TLB purge operations on SMP. */
315
316 .macro tlb_lock la,flags,tmp
317#ifdef CONFIG_SMP
31898:
319#if __PA_LDCW_ALIGNMENT > 4
320 load32 pa_tlb_lock + __PA_LDCW_ALIGNMENT-1, \la
321 depi 0,31,__PA_LDCW_ALIGN_ORDER, \la
322#else
323 load32 pa_tlb_lock, \la
324#endif
325 rsm PSW_SM_I,\flags
3261: LDCW 0(\la),\tmp
327 cmpib,<>,n 0,\tmp,3f
3282: ldw 0(\la),\tmp
329 cmpb,<> %r0,\tmp,1b
330 nop
331 b,n 2b
3323:
33399: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
334#endif
335 .endm
336
337 .macro tlb_unlock la,flags,tmp
338#ifdef CONFIG_SMP
33998: ldi 1,\tmp
340 sync
341 stw \tmp,0(\la)
342 mtsm \flags
34399: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
344#endif
345 .endm
346
347/* Clear page using kernel mapping. */ 314/* Clear page using kernel mapping. */
348 315
349ENTRY_CFI(clear_page_asm) 316ENTRY_CFI(clear_page_asm)
@@ -601,10 +568,8 @@ ENTRY_CFI(copy_user_page_asm)
601 pdtlb,l %r0(%r28) 568 pdtlb,l %r0(%r28)
602 pdtlb,l %r0(%r29) 569 pdtlb,l %r0(%r29)
603#else 570#else
604 tlb_lock %r20,%r21,%r22
6050: pdtlb %r0(%r28) 5710: pdtlb %r0(%r28)
6061: pdtlb %r0(%r29) 5721: pdtlb %r0(%r29)
607 tlb_unlock %r20,%r21,%r22
608 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) 573 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
609 ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB) 574 ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB)
610#endif 575#endif
@@ -743,9 +708,7 @@ ENTRY_CFI(clear_user_page_asm)
743#ifdef CONFIG_PA20 708#ifdef CONFIG_PA20
744 pdtlb,l %r0(%r28) 709 pdtlb,l %r0(%r28)
745#else 710#else
746 tlb_lock %r20,%r21,%r22
7470: pdtlb %r0(%r28) 7110: pdtlb %r0(%r28)
748 tlb_unlock %r20,%r21,%r22
749 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) 712 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
750#endif 713#endif
751 714
@@ -821,9 +784,7 @@ ENTRY_CFI(flush_dcache_page_asm)
821#ifdef CONFIG_PA20 784#ifdef CONFIG_PA20
822 pdtlb,l %r0(%r28) 785 pdtlb,l %r0(%r28)
823#else 786#else
824 tlb_lock %r20,%r21,%r22
8250: pdtlb %r0(%r28) 7870: pdtlb %r0(%r28)
826 tlb_unlock %r20,%r21,%r22
827 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) 788 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
828#endif 789#endif
829 790
@@ -882,9 +843,7 @@ ENTRY_CFI(purge_dcache_page_asm)
882#ifdef CONFIG_PA20 843#ifdef CONFIG_PA20
883 pdtlb,l %r0(%r28) 844 pdtlb,l %r0(%r28)
884#else 845#else
885 tlb_lock %r20,%r21,%r22
8860: pdtlb %r0(%r28) 8460: pdtlb %r0(%r28)
887 tlb_unlock %r20,%r21,%r22
888 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) 847 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
889#endif 848#endif
890 849
@@ -948,10 +907,8 @@ ENTRY_CFI(flush_icache_page_asm)
9481: pitlb,l %r0(%sr4,%r28) 9071: pitlb,l %r0(%sr4,%r28)
949 ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP) 908 ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP)
950#else 909#else
951 tlb_lock %r20,%r21,%r22
9520: pdtlb %r0(%r28) 9100: pdtlb %r0(%r28)
9531: pitlb %r0(%sr4,%r28) 9111: pitlb %r0(%sr4,%r28)
954 tlb_unlock %r20,%r21,%r22
955 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) 912 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
956 ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB) 913 ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB)
957 ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP) 914 ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP)
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
index 7baa2265d439..174213b1716e 100644
--- a/arch/parisc/kernel/parisc_ksyms.c
+++ b/arch/parisc/kernel/parisc_ksyms.c
@@ -138,12 +138,6 @@ extern void $$dyncall(void);
138EXPORT_SYMBOL($$dyncall); 138EXPORT_SYMBOL($$dyncall);
139#endif 139#endif
140 140
141#ifdef CONFIG_DISCONTIGMEM
142#include <asm/mmzone.h>
143EXPORT_SYMBOL(node_data);
144EXPORT_SYMBOL(pfnnid_map);
145#endif
146
147#ifdef CONFIG_FUNCTION_TRACER 141#ifdef CONFIG_FUNCTION_TRACER
148extern void _mcount(void); 142extern void _mcount(void);
149EXPORT_SYMBOL(_mcount); 143EXPORT_SYMBOL(_mcount);
diff --git a/arch/parisc/kernel/patch.c b/arch/parisc/kernel/patch.c
new file mode 100644
index 000000000000..cdcd981278b3
--- /dev/null
+++ b/arch/parisc/kernel/patch.c
@@ -0,0 +1,77 @@
1// SPDX-License-Identifier: GPL-2.0
2 /*
3 * functions to patch RO kernel text during runtime
4 *
5 * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org>
6 */
7
8#include <linux/kernel.h>
9#include <linux/spinlock.h>
10#include <linux/kprobes.h>
11#include <linux/mm.h>
12#include <linux/stop_machine.h>
13
14#include <asm/cacheflush.h>
15#include <asm/fixmap.h>
16#include <asm/patch.h>
17
18struct patch {
19 void *addr;
20 unsigned int insn;
21};
22
23static void __kprobes *patch_map(void *addr, int fixmap)
24{
25 unsigned long uintaddr = (uintptr_t) addr;
26 bool module = !core_kernel_text(uintaddr);
27 struct page *page;
28
29 if (module && IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
30 page = vmalloc_to_page(addr);
31 else if (!module && IS_ENABLED(CONFIG_STRICT_KERNEL_RWX))
32 page = virt_to_page(addr);
33 else
34 return addr;
35
36 set_fixmap(fixmap, page_to_phys(page));
37
38 return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK));
39}
40
41static void __kprobes patch_unmap(int fixmap)
42{
43 clear_fixmap(fixmap);
44}
45
46void __kprobes __patch_text(void *addr, unsigned int insn)
47{
48 void *waddr = addr;
49 int size;
50
51 waddr = patch_map(addr, FIX_TEXT_POKE0);
52 *(u32 *)waddr = insn;
53 size = sizeof(u32);
54 flush_kernel_vmap_range(waddr, size);
55 patch_unmap(FIX_TEXT_POKE0);
56 flush_icache_range((uintptr_t)(addr),
57 (uintptr_t)(addr) + size);
58}
59
60static int __kprobes patch_text_stop_machine(void *data)
61{
62 struct patch *patch = data;
63
64 __patch_text(patch->addr, patch->insn);
65
66 return 0;
67}
68
69void __kprobes patch_text(void *addr, unsigned int insn)
70{
71 struct patch patch = {
72 .addr = addr,
73 .insn = insn,
74 };
75
76 stop_machine_cpuslocked(patch_text_stop_machine, &patch, NULL);
77}
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 841db71958cd..97c206734e24 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -193,6 +193,7 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r)
193 */ 193 */
194 194
195int running_on_qemu __read_mostly; 195int running_on_qemu __read_mostly;
196EXPORT_SYMBOL(running_on_qemu);
196 197
197void __cpuidle arch_cpu_idle_dead(void) 198void __cpuidle arch_cpu_idle_dead(void)
198{ 199{
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index 7f4d042856b5..e0a81dedc366 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -305,7 +305,8 @@ void __init collect_boot_cpu_data(void)
305 305
306 if (pdc_model_platform_info(orig_prod_num, current_prod_num, serial_no) == PDC_OK) { 306 if (pdc_model_platform_info(orig_prod_num, current_prod_num, serial_no) == PDC_OK) {
307 printk(KERN_INFO "product %s, original product %s, S/N: %s\n", 307 printk(KERN_INFO "product %s, original product %s, S/N: %s\n",
308 current_prod_num, orig_prod_num, serial_no); 308 current_prod_num[0] ? current_prod_num : "n/a",
309 orig_prod_num, serial_no);
309 add_device_randomness(orig_prod_num, strlen(orig_prod_num)); 310 add_device_randomness(orig_prod_num, strlen(orig_prod_num));
310 add_device_randomness(current_prod_num, strlen(current_prod_num)); 311 add_device_randomness(current_prod_num, strlen(current_prod_num));
311 add_device_randomness(serial_no, strlen(serial_no)); 312 add_device_randomness(serial_no, strlen(serial_no));
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 0964c236e3e5..a3d2fb4e6dd2 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -789,3 +789,38 @@ const char *regs_query_register_name(unsigned int offset)
789 return roff->name; 789 return roff->name;
790 return NULL; 790 return NULL;
791} 791}
792
793/**
794 * regs_within_kernel_stack() - check the address in the stack
795 * @regs: pt_regs which contains kernel stack pointer.
796 * @addr: address which is checked.
797 *
798 * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
799 * If @addr is within the kernel stack, it returns true. If not, returns false.
800 */
801int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
802{
803 return ((addr & ~(THREAD_SIZE - 1)) ==
804 (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
805}
806
807/**
808 * regs_get_kernel_stack_nth() - get Nth entry of the stack
809 * @regs: pt_regs which contains kernel stack pointer.
810 * @n: stack entry number.
811 *
812 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
813 * is specified by @regs. If the @n th entry is NOT in the kernel stack,
814 * this returns 0.
815 */
816unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
817{
818 unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
819
820 addr -= n;
821
822 if (!regs_within_kernel_stack(regs, (unsigned long)addr))
823 return 0;
824
825 return *addr;
826}
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
index d908058d05c1..e05cb2a5c16d 100644
--- a/arch/parisc/kernel/setup.c
+++ b/arch/parisc/kernel/setup.c
@@ -343,6 +343,12 @@ static int __init parisc_init(void)
343 boot_cpu_data.cpu_hz / 1000000, 343 boot_cpu_data.cpu_hz / 1000000,
344 boot_cpu_data.cpu_hz % 1000000 ); 344 boot_cpu_data.cpu_hz % 1000000 );
345 345
346#if defined(CONFIG_64BIT) && defined(CONFIG_SMP)
347 /* Don't serialize TLB flushes if we run on one CPU only. */
348 if (num_online_cpus() == 1)
349 pa_serialize_tlb_flushes = 0;
350#endif
351
346 apply_alternatives_all(); 352 apply_alternatives_all();
347 parisc_setup_cache_timing(); 353 parisc_setup_cache_timing();
348 354
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 376ea0d1b275..4407ac4c1d84 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -86,7 +86,8 @@ static unsigned long mmap_upper_limit(struct rlimit *rlim_stack)
86 stack_base = STACK_SIZE_MAX; 86 stack_base = STACK_SIZE_MAX;
87 87
88 /* Add space for stack randomization. */ 88 /* Add space for stack randomization. */
89 stack_base += (STACK_RND_MASK << PAGE_SHIFT); 89 if (current->flags & PF_RANDOMIZE)
90 stack_base += (STACK_RND_MASK << PAGE_SHIFT);
90 91
91 return PAGE_ALIGN(STACK_TOP - stack_base); 92 return PAGE_ALIGN(STACK_TOP - stack_base);
92} 93}
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index 4f77bd9be66b..e54d5e4d3489 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -48,7 +48,7 @@ registers).
48 */ 48 */
49#define KILL_INSN break 0,0 49#define KILL_INSN break 0,0
50 50
51 .level LEVEL 51 .level PA_ASM_LEVEL
52 52
53 .text 53 .text
54 54
@@ -640,7 +640,9 @@ cas_action:
640 sub,<> %r28, %r25, %r0 640 sub,<> %r28, %r25, %r0
6412: stw %r24, 0(%r26) 6412: stw %r24, 0(%r26)
642 /* Free lock */ 642 /* Free lock */
643 sync 643#ifdef CONFIG_SMP
644 LDCW 0(%sr2,%r20), %r1 /* Barrier */
645#endif
644 stw %r20, 0(%sr2,%r20) 646 stw %r20, 0(%sr2,%r20)
645#if ENABLE_LWS_DEBUG 647#if ENABLE_LWS_DEBUG
646 /* Clear thread register indicator */ 648 /* Clear thread register indicator */
@@ -655,7 +657,9 @@ cas_action:
6553: 6573:
656 /* Error occurred on load or store */ 658 /* Error occurred on load or store */
657 /* Free lock */ 659 /* Free lock */
658 sync 660#ifdef CONFIG_SMP
661 LDCW 0(%sr2,%r20), %r1 /* Barrier */
662#endif
659 stw %r20, 0(%sr2,%r20) 663 stw %r20, 0(%sr2,%r20)
660#if ENABLE_LWS_DEBUG 664#if ENABLE_LWS_DEBUG
661 stw %r0, 4(%sr2,%r20) 665 stw %r0, 4(%sr2,%r20)
@@ -857,7 +861,9 @@ cas2_action:
857 861
858cas2_end: 862cas2_end:
859 /* Free lock */ 863 /* Free lock */
860 sync 864#ifdef CONFIG_SMP
865 LDCW 0(%sr2,%r20), %r1 /* Barrier */
866#endif
861 stw %r20, 0(%sr2,%r20) 867 stw %r20, 0(%sr2,%r20)
862 /* Enable interrupts */ 868 /* Enable interrupts */
863 ssm PSW_SM_I, %r0 869 ssm PSW_SM_I, %r0
@@ -868,7 +874,9 @@ cas2_end:
86822: 87422:
869 /* Error occurred on load or store */ 875 /* Error occurred on load or store */
870 /* Free lock */ 876 /* Free lock */
871 sync 877#ifdef CONFIG_SMP
878 LDCW 0(%sr2,%r20), %r1 /* Barrier */
879#endif
872 stw %r20, 0(%sr2,%r20) 880 stw %r20, 0(%sr2,%r20)
873 ssm PSW_SM_I, %r0 881 ssm PSW_SM_I, %r0
874 ldo 1(%r0),%r28 882 ldo 1(%r0),%r28
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 7e1ccafadf57..096e319adeb3 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -42,6 +42,8 @@
42#include <asm/unwind.h> 42#include <asm/unwind.h>
43#include <asm/tlbflush.h> 43#include <asm/tlbflush.h>
44#include <asm/cacheflush.h> 44#include <asm/cacheflush.h>
45#include <linux/kgdb.h>
46#include <linux/kprobes.h>
45 47
46#include "../math-emu/math-emu.h" /* for handle_fpe() */ 48#include "../math-emu/math-emu.h" /* for handle_fpe() */
47 49
@@ -293,6 +295,22 @@ static void handle_break(struct pt_regs *regs)
293 (tt == BUG_TRAP_TYPE_NONE) ? 9 : 0); 295 (tt == BUG_TRAP_TYPE_NONE) ? 9 : 0);
294 } 296 }
295 297
298#ifdef CONFIG_KPROBES
299 if (unlikely(iir == PARISC_KPROBES_BREAK_INSN)) {
300 parisc_kprobe_break_handler(regs);
301 return;
302 }
303
304#endif
305
306#ifdef CONFIG_KGDB
307 if (unlikely(iir == PARISC_KGDB_COMPILED_BREAK_INSN ||
308 iir == PARISC_KGDB_BREAK_INSN)) {
309 kgdb_handle_exception(9, SIGTRAP, 0, regs);
310 return;
311 }
312#endif
313
296 if (unlikely(iir != GDB_BREAK_INSN)) 314 if (unlikely(iir != GDB_BREAK_INSN))
297 parisc_printk_ratelimited(0, regs, 315 parisc_printk_ratelimited(0, regs,
298 KERN_DEBUG "break %d,%d: pid=%d command='%s'\n", 316 KERN_DEBUG "break %d,%d: pid=%d command='%s'\n",
@@ -518,6 +536,19 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
518 case 3: 536 case 3:
519 /* Recovery counter trap */ 537 /* Recovery counter trap */
520 regs->gr[0] &= ~PSW_R; 538 regs->gr[0] &= ~PSW_R;
539
540#ifdef CONFIG_KPROBES
541 if (parisc_kprobe_ss_handler(regs))
542 return;
543#endif
544
545#ifdef CONFIG_KGDB
546 if (kgdb_single_step) {
547 kgdb_handle_exception(0, SIGTRAP, 0, regs);
548 return;
549 }
550#endif
551
521 if (user_space(regs)) 552 if (user_space(regs))
522 handle_gdb_break(regs, TRAP_TRACE); 553 handle_gdb_break(regs, TRAP_TRACE);
523 /* else this must be the start of a syscall - just let it run */ 554 /* else this must be the start of a syscall - just let it run */
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index c3b1b9c24ede..a8be7a47fcc0 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -18,6 +18,9 @@
18 *(.data..vm0.pgd) \ 18 *(.data..vm0.pgd) \
19 *(.data..vm0.pte) 19 *(.data..vm0.pte)
20 20
21/* No __ro_after_init data in the .rodata section - which will always be ro */
22#define RO_AFTER_INIT_DATA
23
21#include <asm-generic/vmlinux.lds.h> 24#include <asm-generic/vmlinux.lds.h>
22 25
23/* needed for the processor specific cache alignment size */ 26/* needed for the processor specific cache alignment size */
diff --git a/arch/parisc/mm/Makefile b/arch/parisc/mm/Makefile
index 134393de69d2..20e39b043a60 100644
--- a/arch/parisc/mm/Makefile
+++ b/arch/parisc/mm/Makefile
@@ -2,5 +2,5 @@
2# Makefile for arch/parisc/mm 2# Makefile for arch/parisc/mm
3# 3#
4 4
5obj-y := init.o fault.o ioremap.o 5obj-y := init.o fault.o ioremap.o fixmap.o
6obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 6obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
diff --git a/arch/parisc/mm/fixmap.c b/arch/parisc/mm/fixmap.c
new file mode 100644
index 000000000000..c8d41b54fb19
--- /dev/null
+++ b/arch/parisc/mm/fixmap.c
@@ -0,0 +1,41 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * fixmaps for parisc
4 *
5 * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org>
6 */
7
8#include <linux/kprobes.h>
9#include <linux/mm.h>
10#include <asm/cacheflush.h>
11#include <asm/fixmap.h>
12
13void set_fixmap(enum fixed_addresses idx, phys_addr_t phys)
14{
15 unsigned long vaddr = __fix_to_virt(idx);
16 pgd_t *pgd = pgd_offset_k(vaddr);
17 pmd_t *pmd = pmd_offset(pgd, vaddr);
18 pte_t *pte;
19
20 if (pmd_none(*pmd))
21 pmd = pmd_alloc(NULL, pgd, vaddr);
22
23 pte = pte_offset_kernel(pmd, vaddr);
24 if (pte_none(*pte))
25 pte = pte_alloc_kernel(pmd, vaddr);
26
27 set_pte_at(&init_mm, vaddr, pte, __mk_pte(phys, PAGE_KERNEL_RWX));
28 flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE);
29}
30
31void clear_fixmap(enum fixed_addresses idx)
32{
33 unsigned long vaddr = __fix_to_virt(idx);
34 pgd_t *pgd = pgd_offset_k(vaddr);
35 pmd_t *pmd = pmd_offset(pgd, vaddr);
36 pte_t *pte = pte_offset_kernel(pmd, vaddr);
37
38 pte_clear(&init_mm, vaddr, pte);
39
40 flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE);
41}
diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c
index d77479ae3af2..d578809e55cf 100644
--- a/arch/parisc/mm/hugetlbpage.c
+++ b/arch/parisc/mm/hugetlbpage.c
@@ -139,9 +139,9 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
139{ 139{
140 unsigned long flags; 140 unsigned long flags;
141 141
142 purge_tlb_start(flags); 142 spin_lock_irqsave(pgd_spinlock((mm)->pgd), flags);
143 __set_huge_pte_at(mm, addr, ptep, entry); 143 __set_huge_pte_at(mm, addr, ptep, entry);
144 purge_tlb_end(flags); 144 spin_unlock_irqrestore(pgd_spinlock((mm)->pgd), flags);
145} 145}
146 146
147 147
@@ -151,10 +151,10 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
151 unsigned long flags; 151 unsigned long flags;
152 pte_t entry; 152 pte_t entry;
153 153
154 purge_tlb_start(flags); 154 spin_lock_irqsave(pgd_spinlock((mm)->pgd), flags);
155 entry = *ptep; 155 entry = *ptep;
156 __set_huge_pte_at(mm, addr, ptep, __pte(0)); 156 __set_huge_pte_at(mm, addr, ptep, __pte(0));
157 purge_tlb_end(flags); 157 spin_unlock_irqrestore(pgd_spinlock((mm)->pgd), flags);
158 158
159 return entry; 159 return entry;
160} 160}
@@ -166,10 +166,10 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
166 unsigned long flags; 166 unsigned long flags;
167 pte_t old_pte; 167 pte_t old_pte;
168 168
169 purge_tlb_start(flags); 169 spin_lock_irqsave(pgd_spinlock((mm)->pgd), flags);
170 old_pte = *ptep; 170 old_pte = *ptep;
171 __set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); 171 __set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
172 purge_tlb_end(flags); 172 spin_unlock_irqrestore(pgd_spinlock((mm)->pgd), flags);
173} 173}
174 174
175int huge_ptep_set_access_flags(struct vm_area_struct *vma, 175int huge_ptep_set_access_flags(struct vm_area_struct *vma,
@@ -178,13 +178,14 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
178{ 178{
179 unsigned long flags; 179 unsigned long flags;
180 int changed; 180 int changed;
181 struct mm_struct *mm = vma->vm_mm;
181 182
182 purge_tlb_start(flags); 183 spin_lock_irqsave(pgd_spinlock((mm)->pgd), flags);
183 changed = !pte_same(*ptep, pte); 184 changed = !pte_same(*ptep, pte);
184 if (changed) { 185 if (changed) {
185 __set_huge_pte_at(vma->vm_mm, addr, ptep, pte); 186 __set_huge_pte_at(mm, addr, ptep, pte);
186 } 187 }
187 purge_tlb_end(flags); 188 spin_unlock_irqrestore(pgd_spinlock((mm)->pgd), flags);
188 return changed; 189 return changed;
189} 190}
190 191
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index d0b166256f1a..3b0f9eab7f2c 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -32,6 +32,7 @@
32#include <asm/mmzone.h> 32#include <asm/mmzone.h>
33#include <asm/sections.h> 33#include <asm/sections.h>
34#include <asm/msgbuf.h> 34#include <asm/msgbuf.h>
35#include <asm/sparsemem.h>
35 36
36extern int data_start; 37extern int data_start;
37extern void parisc_kernel_start(void); /* Kernel entry point in head.S */ 38extern void parisc_kernel_start(void); /* Kernel entry point in head.S */
@@ -48,11 +49,6 @@ pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((__section__ (".data..vm0.pmd"), aligned
48pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".data..vm0.pgd"), aligned(PAGE_SIZE))); 49pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".data..vm0.pgd"), aligned(PAGE_SIZE)));
49pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data..vm0.pte"), aligned(PAGE_SIZE))); 50pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data..vm0.pte"), aligned(PAGE_SIZE)));
50 51
51#ifdef CONFIG_DISCONTIGMEM
52struct node_map_data node_data[MAX_NUMNODES] __read_mostly;
53signed char pfnnid_map[PFNNID_MAP_MAX] __read_mostly;
54#endif
55
56static struct resource data_resource = { 52static struct resource data_resource = {
57 .name = "Kernel data", 53 .name = "Kernel data",
58 .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, 54 .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
@@ -76,11 +72,11 @@ static struct resource sysram_resources[MAX_PHYSMEM_RANGES] __read_mostly;
76 * information retrieved in kernel/inventory.c. 72 * information retrieved in kernel/inventory.c.
77 */ 73 */
78 74
79physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __read_mostly; 75physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __initdata;
80int npmem_ranges __read_mostly; 76int npmem_ranges __initdata;
81 77
82#ifdef CONFIG_64BIT 78#ifdef CONFIG_64BIT
83#define MAX_MEM (~0UL) 79#define MAX_MEM (1UL << MAX_PHYSMEM_BITS)
84#else /* !CONFIG_64BIT */ 80#else /* !CONFIG_64BIT */
85#define MAX_MEM (3584U*1024U*1024U) 81#define MAX_MEM (3584U*1024U*1024U)
86#endif /* !CONFIG_64BIT */ 82#endif /* !CONFIG_64BIT */
@@ -119,7 +115,7 @@ static void __init mem_limit_func(void)
119static void __init setup_bootmem(void) 115static void __init setup_bootmem(void)
120{ 116{
121 unsigned long mem_max; 117 unsigned long mem_max;
122#ifndef CONFIG_DISCONTIGMEM 118#ifndef CONFIG_SPARSEMEM
123 physmem_range_t pmem_holes[MAX_PHYSMEM_RANGES - 1]; 119 physmem_range_t pmem_holes[MAX_PHYSMEM_RANGES - 1];
124 int npmem_holes; 120 int npmem_holes;
125#endif 121#endif
@@ -137,23 +133,20 @@ static void __init setup_bootmem(void)
137 int j; 133 int j;
138 134
139 for (j = i; j > 0; j--) { 135 for (j = i; j > 0; j--) {
140 unsigned long tmp; 136 physmem_range_t tmp;
141 137
142 if (pmem_ranges[j-1].start_pfn < 138 if (pmem_ranges[j-1].start_pfn <
143 pmem_ranges[j].start_pfn) { 139 pmem_ranges[j].start_pfn) {
144 140
145 break; 141 break;
146 } 142 }
147 tmp = pmem_ranges[j-1].start_pfn; 143 tmp = pmem_ranges[j-1];
148 pmem_ranges[j-1].start_pfn = pmem_ranges[j].start_pfn; 144 pmem_ranges[j-1] = pmem_ranges[j];
149 pmem_ranges[j].start_pfn = tmp; 145 pmem_ranges[j] = tmp;
150 tmp = pmem_ranges[j-1].pages;
151 pmem_ranges[j-1].pages = pmem_ranges[j].pages;
152 pmem_ranges[j].pages = tmp;
153 } 146 }
154 } 147 }
155 148
156#ifndef CONFIG_DISCONTIGMEM 149#ifndef CONFIG_SPARSEMEM
157 /* 150 /*
158 * Throw out ranges that are too far apart (controlled by 151 * Throw out ranges that are too far apart (controlled by
159 * MAX_GAP). 152 * MAX_GAP).
@@ -165,7 +158,7 @@ static void __init setup_bootmem(void)
165 pmem_ranges[i-1].pages) > MAX_GAP) { 158 pmem_ranges[i-1].pages) > MAX_GAP) {
166 npmem_ranges = i; 159 npmem_ranges = i;
167 printk("Large gap in memory detected (%ld pages). " 160 printk("Large gap in memory detected (%ld pages). "
168 "Consider turning on CONFIG_DISCONTIGMEM\n", 161 "Consider turning on CONFIG_SPARSEMEM\n",
169 pmem_ranges[i].start_pfn - 162 pmem_ranges[i].start_pfn -
170 (pmem_ranges[i-1].start_pfn + 163 (pmem_ranges[i-1].start_pfn +
171 pmem_ranges[i-1].pages)); 164 pmem_ranges[i-1].pages));
@@ -230,9 +223,8 @@ static void __init setup_bootmem(void)
230 223
231 printk(KERN_INFO "Total Memory: %ld MB\n",mem_max >> 20); 224 printk(KERN_INFO "Total Memory: %ld MB\n",mem_max >> 20);
232 225
233#ifndef CONFIG_DISCONTIGMEM 226#ifndef CONFIG_SPARSEMEM
234 /* Merge the ranges, keeping track of the holes */ 227 /* Merge the ranges, keeping track of the holes */
235
236 { 228 {
237 unsigned long end_pfn; 229 unsigned long end_pfn;
238 unsigned long hole_pages; 230 unsigned long hole_pages;
@@ -255,18 +247,6 @@ static void __init setup_bootmem(void)
255 } 247 }
256#endif 248#endif
257 249
258#ifdef CONFIG_DISCONTIGMEM
259 for (i = 0; i < MAX_PHYSMEM_RANGES; i++) {
260 memset(NODE_DATA(i), 0, sizeof(pg_data_t));
261 }
262 memset(pfnnid_map, 0xff, sizeof(pfnnid_map));
263
264 for (i = 0; i < npmem_ranges; i++) {
265 node_set_state(i, N_NORMAL_MEMORY);
266 node_set_online(i);
267 }
268#endif
269
270 /* 250 /*
271 * Initialize and free the full range of memory in each range. 251 * Initialize and free the full range of memory in each range.
272 */ 252 */
@@ -314,7 +294,7 @@ static void __init setup_bootmem(void)
314 memblock_reserve(__pa(KERNEL_BINARY_TEXT_START), 294 memblock_reserve(__pa(KERNEL_BINARY_TEXT_START),
315 (unsigned long)(_end - KERNEL_BINARY_TEXT_START)); 295 (unsigned long)(_end - KERNEL_BINARY_TEXT_START));
316 296
317#ifndef CONFIG_DISCONTIGMEM 297#ifndef CONFIG_SPARSEMEM
318 298
319 /* reserve the holes */ 299 /* reserve the holes */
320 300
@@ -360,6 +340,9 @@ static void __init setup_bootmem(void)
360 340
361 /* Initialize Page Deallocation Table (PDT) and check for bad memory. */ 341 /* Initialize Page Deallocation Table (PDT) and check for bad memory. */
362 pdc_pdt_init(); 342 pdc_pdt_init();
343
344 memblock_allow_resize();
345 memblock_dump_all();
363} 346}
364 347
365static int __init parisc_text_address(unsigned long vaddr) 348static int __init parisc_text_address(unsigned long vaddr)
@@ -495,7 +478,7 @@ static void __init map_pages(unsigned long start_vaddr,
495 478
496void __init set_kernel_text_rw(int enable_read_write) 479void __init set_kernel_text_rw(int enable_read_write)
497{ 480{
498 unsigned long start = (unsigned long) _text; 481 unsigned long start = (unsigned long) __init_begin;
499 unsigned long end = (unsigned long) &data_start; 482 unsigned long end = (unsigned long) &data_start;
500 483
501 map_pages(start, __pa(start), end-start, 484 map_pages(start, __pa(start), end-start,
@@ -622,15 +605,19 @@ void __init mem_init(void)
622 * But keep code for debugging purposes. 605 * But keep code for debugging purposes.
623 */ 606 */
624 printk("virtual kernel memory layout:\n" 607 printk("virtual kernel memory layout:\n"
625 " vmalloc : 0x%px - 0x%px (%4ld MB)\n" 608 " vmalloc : 0x%px - 0x%px (%4ld MB)\n"
626 " memory : 0x%px - 0x%px (%4ld MB)\n" 609 " fixmap : 0x%px - 0x%px (%4ld kB)\n"
627 " .init : 0x%px - 0x%px (%4ld kB)\n" 610 " memory : 0x%px - 0x%px (%4ld MB)\n"
628 " .data : 0x%px - 0x%px (%4ld kB)\n" 611 " .init : 0x%px - 0x%px (%4ld kB)\n"
629 " .text : 0x%px - 0x%px (%4ld kB)\n", 612 " .data : 0x%px - 0x%px (%4ld kB)\n"
613 " .text : 0x%px - 0x%px (%4ld kB)\n",
630 614
631 (void*)VMALLOC_START, (void*)VMALLOC_END, 615 (void*)VMALLOC_START, (void*)VMALLOC_END,
632 (VMALLOC_END - VMALLOC_START) >> 20, 616 (VMALLOC_END - VMALLOC_START) >> 20,
633 617
618 (void *)FIXMAP_START, (void *)(FIXMAP_START + FIXMAP_SIZE),
619 (unsigned long)(FIXMAP_SIZE / 1024),
620
634 __va(0), high_memory, 621 __va(0), high_memory,
635 ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20, 622 ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20,
636 623
@@ -709,37 +696,46 @@ static void __init gateway_init(void)
709 PAGE_SIZE, PAGE_GATEWAY, 1); 696 PAGE_SIZE, PAGE_GATEWAY, 1);
710} 697}
711 698
712void __init paging_init(void) 699static void __init parisc_bootmem_free(void)
713{ 700{
701 unsigned long zones_size[MAX_NR_ZONES] = { 0, };
702 unsigned long holes_size[MAX_NR_ZONES] = { 0, };
703 unsigned long mem_start_pfn = ~0UL, mem_end_pfn = 0, mem_size_pfn = 0;
714 int i; 704 int i;
715 705
706 for (i = 0; i < npmem_ranges; i++) {
707 unsigned long start = pmem_ranges[i].start_pfn;
708 unsigned long size = pmem_ranges[i].pages;
709 unsigned long end = start + size;
710
711 if (mem_start_pfn > start)
712 mem_start_pfn = start;
713 if (mem_end_pfn < end)
714 mem_end_pfn = end;
715 mem_size_pfn += size;
716 }
717
718 zones_size[0] = mem_end_pfn - mem_start_pfn;
719 holes_size[0] = zones_size[0] - mem_size_pfn;
720
721 free_area_init_node(0, zones_size, mem_start_pfn, holes_size);
722}
723
724void __init paging_init(void)
725{
716 setup_bootmem(); 726 setup_bootmem();
717 pagetable_init(); 727 pagetable_init();
718 gateway_init(); 728 gateway_init();
719 flush_cache_all_local(); /* start with known state */ 729 flush_cache_all_local(); /* start with known state */
720 flush_tlb_all_local(NULL); 730 flush_tlb_all_local(NULL);
721 731
722 for (i = 0; i < npmem_ranges; i++) { 732 /*
723 unsigned long zones_size[MAX_NR_ZONES] = { 0, }; 733 * Mark all memblocks as present for sparsemem using
724 734 * memory_present() and then initialize sparsemem.
725 zones_size[ZONE_NORMAL] = pmem_ranges[i].pages; 735 */
726 736 memblocks_present();
727#ifdef CONFIG_DISCONTIGMEM 737 sparse_init();
728 /* Need to initialize the pfnnid_map before we can initialize 738 parisc_bootmem_free();
729 the zone */
730 {
731 int j;
732 for (j = (pmem_ranges[i].start_pfn >> PFNNID_SHIFT);
733 j <= ((pmem_ranges[i].start_pfn + pmem_ranges[i].pages) >> PFNNID_SHIFT);
734 j++) {
735 pfnnid_map[j] = i;
736 }
737 }
738#endif
739
740 free_area_init_node(i, zones_size,
741 pmem_ranges[i].start_pfn, NULL);
742 }
743} 739}
744 740
745#ifdef CONFIG_PA20 741#ifdef CONFIG_PA20
diff --git a/drivers/net/ethernet/i825xx/lasi_82596.c b/drivers/net/ethernet/i825xx/lasi_82596.c
index b69c622ba8b2..211c5f74b4c8 100644
--- a/drivers/net/ethernet/i825xx/lasi_82596.c
+++ b/drivers/net/ethernet/i825xx/lasi_82596.c
@@ -105,7 +105,7 @@
105#define DMA_WBACK_INV(ndev, addr, len) \ 105#define DMA_WBACK_INV(ndev, addr, len) \
106 do { dma_cache_sync((ndev)->dev.parent, (void *)addr, len, DMA_BIDIRECTIONAL); } while (0) 106 do { dma_cache_sync((ndev)->dev.parent, (void *)addr, len, DMA_BIDIRECTIONAL); } while (0)
107 107
108#define SYSBUS 0x0000006c; 108#define SYSBUS 0x0000006c
109 109
110/* big endian CPU, 82596 "big" endian mode */ 110/* big endian CPU, 82596 "big" endian mode */
111#define SWAP32(x) (((u32)(x)<<16) | ((((u32)(x)))>>16)) 111#define SWAP32(x) (((u32)(x)<<16) | ((((u32)(x)))>>16))
@@ -141,7 +141,8 @@ static void mpu_port(struct net_device *dev, int c, dma_addr_t x)
141 } 141 }
142 142
143 gsc_writel(a, dev->base_addr + PA_CPU_PORT_L_ACCESS); 143 gsc_writel(a, dev->base_addr + PA_CPU_PORT_L_ACCESS);
144 udelay(1); 144 if (!running_on_qemu)
145 udelay(1);
145 gsc_writel(b, dev->base_addr + PA_CPU_PORT_L_ACCESS); 146 gsc_writel(b, dev->base_addr + PA_CPU_PORT_L_ACCESS);
146} 147}
147 148
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index 0c6e8b44b4ed..c60b465f6fe4 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -568,6 +568,9 @@ int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long d
568 break; 568 break;
569 569
570 case DISPLAY_MODEL_LASI: 570 case DISPLAY_MODEL_LASI:
571 /* Skip to register LED in QEMU */
572 if (running_on_qemu)
573 return 1;
571 LED_DATA_REG = data_reg; 574 LED_DATA_REG = data_reg;
572 led_func_ptr = led_LASI_driver; 575 led_func_ptr = led_LASI_driver;
573 printk(KERN_INFO "LED display at %lx registered\n", LED_DATA_REG); 576 printk(KERN_INFO "LED display at %lx registered\n", LED_DATA_REG);