Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-5.17/parisc-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull parisc architecture updates from Helge Deller:

- Fix lpa and lpa_user defines (John David Anglin)

- Fix symbol lookup of init functions with an __is_kernel() fix (Helge
Deller)

- Fix wrong pdc_toc_pim_11 and pdc_toc_pim_20 definitions (Helge
Deller)

- Add lws_atomic_xchg and lws_atomic_store syscalls (John David Anglin)

- Rewrite light-weight syscall and futex code (John David Anglin)

- Enable TOC (transfer of contents) feature unconditionally (Helge
Deller)

- Improve fault handler messages (John David Anglin)

- Improve build process (Masahiro Yamada)

- Reduce kernel code footprint of user access functions (Helge Deller)

- Fix build error due to outX() macros (Bart Van Assche)

- Ue default_groups in kobj_type in pdc_stable (Greg Kroah-Hartman)

- Default to 16 CPUs on 32-bit kernel (Helge Deller)

* tag 'for-5.17/parisc-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
parisc: Default to 16 CPUs on 32-bit kernel
sections: Fix __is_kernel() to include init ranges
parisc: Re-use toc_stack as hpmc_stack
parisc: Enable TOC (transfer of contents) feature unconditionally
parisc: io: Improve the outb(), outw() and outl() macros
parisc: pdc_stable: use default_groups in kobj_type
parisc: Add kgdb io_module to read chars via PDC
parisc: Fix pdc_toc_pim_11 and pdc_toc_pim_20 definitions
parisc: Add lws_atomic_xchg and lws_atomic_store syscalls
parisc: Rewrite light-weight syscall and futex code
parisc: Enhance page fault termination message
parisc: Don't call faulthandler_disabled() in do_page_fault()
parisc: Switch user access functions to signal errors in r29 instead of r8
parisc: Avoid calling faulthandler_disabled() twice
parisc: Fix lpa and lpa_user defines
parisc: Define depi_safe macro
parisc: decompressor: do not copy source files while building

+778 -320
+2 -15
arch/parisc/Kconfig
··· 287 287 288 288 If you don't know what to do here, say N. 289 289 290 - config TOC 291 - bool "Support TOC switch" 292 - default y if 64BIT || !SMP 293 - help 294 - Most PA-RISC machines have either a switch at the back of the machine 295 - or a command in BMC to trigger a TOC interrupt. If you say Y here a 296 - handler will be installed which will either show a backtrace on all 297 - CPUs, or enter a possible configured debugger like kgdb/kdb. 298 - 299 - Note that with this option enabled, the kernel will use an additional 16KB 300 - per possible CPU as a special stack for the TOC handler. 301 - 302 - If you don't want to debug the Kernel, say N. 303 - 304 290 config PARISC_CPU_TOPOLOGY 305 291 bool "Support cpu topology definition" 306 292 depends on SMP ··· 356 370 int "Maximum number of CPUs (2-32)" 357 371 range 2 32 358 372 depends on SMP 359 - default "4" 373 + default "4" if 64BIT 374 + default "16" 360 375 361 376 config KEXEC 362 377 bool "Kexec system call"
-2
arch/parisc/boot/compressed/.gitignore
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 - firmware.c 3 - real2.S 4 2 sizes.h 5 3 vmlinux 6 4 vmlinux.lds
-8
arch/parisc/boot/compressed/Makefile
··· 13 13 targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 14 14 targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4 15 15 targets += $(OBJECTS) sizes.h 16 - targets += real2.S firmware.c 17 16 18 17 KBUILD_CFLAGS := -D__KERNEL__ -O2 -DBOOTLOADER 19 18 KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING ··· 41 42 CFLAGS_misc.o += -I$(objtree)/$(obj) 42 43 $(obj)/misc.o: $(obj)/sizes.h 43 44 44 - $(obj)/firmware.o: $(obj)/firmware.c 45 - $(obj)/firmware.c: $(srctree)/arch/$(SRCARCH)/kernel/firmware.c 46 - $(call cmd,shipped) 47 - 48 45 AFLAGS_real2.o += -DBOOTLOADER 49 - $(obj)/real2.o: $(obj)/real2.S 50 - $(obj)/real2.S: $(srctree)/arch/$(SRCARCH)/kernel/real2.S 51 - $(call cmd,shipped) 52 46 53 47 CPPFLAGS_vmlinux.lds += -I$(objtree)/$(obj) -DBOOTLOADER 54 48 $(obj)/vmlinux.lds: $(obj)/sizes.h
+2
arch/parisc/boot/compressed/firmware.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + #include "../../kernel/firmware.c"
+2
arch/parisc/boot/compressed/real2.S
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + #include "../../kernel/real2.S"
+10
arch/parisc/include/asm/assembly.h
··· 158 158 #endif 159 159 .endm 160 160 161 + /* The depi instruction leaves the most significant 32 bits of the 162 + * target register in an undefined state on PA 2.0 systems. */ 163 + .macro depi_safe i, p, len, t 164 + #ifdef CONFIG_64BIT 165 + depdi \i, 32+(\p), \len, \t 166 + #else 167 + depi \i, \p, \len, \t 168 + #endif 169 + .endm 170 + 161 171 /* load 32-bit 'value' into 'reg' compensating for the ldil 162 172 * sign-extension when running in wide mode. 163 173 * WARNING!! neither 'value' nor 'reg' can be expressions
+37 -22
arch/parisc/include/asm/futex.h
··· 8 8 #include <asm/errno.h> 9 9 10 10 /* The following has to match the LWS code in syscall.S. We have 11 - sixteen four-word locks. */ 11 + * 256 four-word locks. We use bits 20-27 of the futex virtual 12 + * address for the hash index. 13 + */ 14 + 15 + static inline unsigned long _futex_hash_index(unsigned long ua) 16 + { 17 + return (ua >> 2) & 0x3fc; 18 + } 12 19 13 20 static inline void 14 - _futex_spin_lock(u32 __user *uaddr) 21 + _futex_spin_lock_irqsave(arch_spinlock_t *s, unsigned long *flags) 15 22 { 16 - extern u32 lws_lock_start[]; 17 - long index = ((long)uaddr & 0x7f8) >> 1; 18 - arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; 19 - preempt_disable(); 23 + local_irq_save(*flags); 20 24 arch_spin_lock(s); 21 25 } 22 26 23 27 static inline void 24 - _futex_spin_unlock(u32 __user *uaddr) 28 + _futex_spin_unlock_irqrestore(arch_spinlock_t *s, unsigned long *flags) 25 29 { 26 - extern u32 lws_lock_start[]; 27 - long index = ((long)uaddr & 0x7f8) >> 1; 28 - arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; 29 30 arch_spin_unlock(s); 30 - preempt_enable(); 31 + local_irq_restore(*flags); 31 32 } 32 33 33 34 static inline int 34 35 arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) 35 36 { 37 + extern u32 lws_lock_start[]; 38 + unsigned long ua = (unsigned long)uaddr; 39 + arch_spinlock_t *s; 40 + unsigned long flags; 36 41 int oldval, ret; 37 42 u32 tmp; 38 43 39 - ret = -EFAULT; 44 + s = (arch_spinlock_t *)&lws_lock_start[_futex_hash_index(ua)]; 45 + _futex_spin_lock_irqsave(s, &flags); 40 46 41 - _futex_spin_lock(uaddr); 42 - if (unlikely(get_user(oldval, uaddr) != 0)) 47 + /* Return -EFAULT if we encounter a page fault or COW break */ 48 + if (unlikely(get_user(oldval, uaddr) != 0)) { 49 + ret = -EFAULT; 43 50 goto out_pagefault_enable; 51 + } 44 52 45 53 ret = 0; 46 54 tmp = oldval; ··· 71 63 break; 72 64 default: 73 65 ret = -ENOSYS; 66 + goto out_pagefault_enable; 74 67 } 75 68 76 - if (ret == 0 && unlikely(put_user(tmp, uaddr) != 0)) 69 + if (unlikely(put_user(tmp, uaddr) != 0)) 77 70 ret = -EFAULT; 78 71 79 72 out_pagefault_enable: 80 - _futex_spin_unlock(uaddr); 73 + _futex_spin_unlock_irqrestore(s, &flags); 81 74 82 75 if (!ret) 83 76 *oval = oldval; ··· 90 81 futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, 91 82 u32 oldval, u32 newval) 92 83 { 84 + extern u32 lws_lock_start[]; 85 + unsigned long ua = (unsigned long)uaddr; 86 + arch_spinlock_t *s; 93 87 u32 val; 88 + unsigned long flags; 94 89 95 90 /* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is 96 91 * our gateway page, and causes no end of trouble... ··· 107 94 108 95 /* HPPA has no cmpxchg in hardware and therefore the 109 96 * best we can do here is use an array of locks. The 110 - * lock selected is based on a hash of the userspace 111 - * address. This should scale to a couple of CPUs. 97 + * lock selected is based on a hash of the virtual 98 + * address of the futex. This should scale to a couple 99 + * of CPUs. 112 100 */ 113 101 114 - _futex_spin_lock(uaddr); 102 + s = (arch_spinlock_t *)&lws_lock_start[_futex_hash_index(ua)]; 103 + _futex_spin_lock_irqsave(s, &flags); 115 104 if (unlikely(get_user(val, uaddr) != 0)) { 116 - _futex_spin_unlock(uaddr); 105 + _futex_spin_unlock_irqrestore(s, &flags); 117 106 return -EFAULT; 118 107 } 119 108 120 109 if (val == oldval && unlikely(put_user(newval, uaddr) != 0)) { 121 - _futex_spin_unlock(uaddr); 110 + _futex_spin_unlock_irqrestore(s, &flags); 122 111 return -EFAULT; 123 112 } 124 113 125 114 *uval = val; 126 - _futex_spin_unlock(uaddr); 115 + _futex_spin_unlock_irqrestore(s, &flags); 127 116 128 117 return 0; 129 118 }
+3 -3
arch/parisc/include/asm/io.h
··· 273 273 return -1; 274 274 } 275 275 276 - #define outb(x, y) BUG() 277 - #define outw(x, y) BUG() 278 - #define outl(x, y) BUG() 276 + #define outb(x, y) ({(void)(x); (void)(y); BUG(); 0;}) 277 + #define outw(x, y) ({(void)(x); (void)(y); BUG(); 0;}) 278 + #define outl(x, y) ({(void)(x); (void)(y); BUG(); 0;}) 279 279 #endif 280 280 281 281 /*
+24 -20
arch/parisc/include/asm/special_insns.h
··· 2 2 #ifndef __PARISC_SPECIAL_INSNS_H 3 3 #define __PARISC_SPECIAL_INSNS_H 4 4 5 - #define lpa(va) ({ \ 6 - unsigned long pa; \ 7 - __asm__ __volatile__( \ 8 - "copy %%r0,%0\n\t" \ 9 - "lpa %%r0(%1),%0" \ 10 - : "=r" (pa) \ 11 - : "r" (va) \ 12 - : "memory" \ 13 - ); \ 14 - pa; \ 5 + #define lpa(va) ({ \ 6 + unsigned long pa; \ 7 + __asm__ __volatile__( \ 8 + "copy %%r0,%0\n" \ 9 + "8:\tlpa %%r0(%1),%0\n" \ 10 + "9:\n" \ 11 + ASM_EXCEPTIONTABLE_ENTRY(8b, 9b) \ 12 + : "=&r" (pa) \ 13 + : "r" (va) \ 14 + : "memory" \ 15 + ); \ 16 + pa; \ 15 17 }) 16 18 17 - #define lpa_user(va) ({ \ 18 - unsigned long pa; \ 19 - __asm__ __volatile__( \ 20 - "copy %%r0,%0\n\t" \ 21 - "lpa %%r0(%%sr3,%1),%0" \ 22 - : "=r" (pa) \ 23 - : "r" (va) \ 24 - : "memory" \ 25 - ); \ 26 - pa; \ 19 + #define lpa_user(va) ({ \ 20 + unsigned long pa; \ 21 + __asm__ __volatile__( \ 22 + "copy %%r0,%0\n" \ 23 + "8:\tlpa %%r0(%%sr3,%1),%0\n" \ 24 + "9:\n" \ 25 + ASM_EXCEPTIONTABLE_ENTRY(8b, 9b) \ 26 + : "=&r" (pa) \ 27 + : "r" (va) \ 28 + : "memory" \ 29 + ); \ 30 + pa; \ 27 31 }) 28 32 29 33 #define mfctl(reg) ({ \
+8 -4
arch/parisc/include/asm/uaccess.h
··· 53 53 /* 54 54 * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() creates a special exception table entry 55 55 * (with lowest bit set) for which the fault handler in fixup_exception() will 56 - * load -EFAULT into %r8 for a read or write fault, and zeroes the target 56 + * load -EFAULT into %r29 for a read or write fault, and zeroes the target 57 57 * register in case of a read fault in get_user(). 58 58 */ 59 + #define ASM_EXCEPTIONTABLE_REG 29 60 + #define ASM_EXCEPTIONTABLE_VAR(__variable) \ 61 + register long __variable __asm__ ("r29") = 0 59 62 #define ASM_EXCEPTIONTABLE_ENTRY_EFAULT( fault_addr, except_addr )\ 60 63 ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr + 1) 61 64 62 65 #define __get_user_internal(sr, val, ptr) \ 63 66 ({ \ 64 - register long __gu_err __asm__ ("r8") = 0; \ 67 + ASM_EXCEPTIONTABLE_VAR(__gu_err); \ 65 68 \ 66 69 switch (sizeof(*(ptr))) { \ 67 70 case 1: __get_user_asm(sr, val, "ldb", ptr); break; \ ··· 134 131 135 132 #define __put_user_internal(sr, x, ptr) \ 136 133 ({ \ 137 - register long __pu_err __asm__ ("r8") = 0; \ 134 + ASM_EXCEPTIONTABLE_VAR(__pu_err); \ 138 135 __typeof__(*(ptr)) __x = (__typeof__(*(ptr)))(x); \ 139 136 \ 140 137 switch (sizeof(*(ptr))) { \ ··· 171 168 * gcc knows about, so there are no aliasing issues. These macros must 172 169 * also be aware that fixups are executed in the context of the fault, 173 170 * and any registers used there must be listed as clobbers. 174 - * r8 is already listed as err. 171 + * The register holding the possible EFAULT error (ASM_EXCEPTIONTABLE_REG) 172 + * is already listed as input and output register. 175 173 */ 176 174 177 175 #define __put_user_asm(sr, stx, x, ptr) \
+23 -9
arch/parisc/include/uapi/asm/pdc.h
··· 4 4 5 5 /* 6 6 * PDC return values ... 7 - * All PDC calls return a subset of these errors. 7 + * All PDC calls return a subset of these errors. 8 8 */ 9 9 10 10 #define PDC_WARN 3 /* Call completed with a warning */ ··· 165 165 #define PDC_PSW_GET_DEFAULTS 1 /* Return defaults */ 166 166 #define PDC_PSW_SET_DEFAULTS 2 /* Set default */ 167 167 #define PDC_PSW_ENDIAN_BIT 1 /* set for big endian */ 168 - #define PDC_PSW_WIDE_BIT 2 /* set for wide mode */ 168 + #define PDC_PSW_WIDE_BIT 2 /* set for wide mode */ 169 169 170 170 #define PDC_SYSTEM_MAP 22 /* find system modules */ 171 171 #define PDC_FIND_MODULE 0 ··· 274 274 #define PDC_PCI_PCI_INT_ROUTE_SIZE 13 275 275 #define PDC_PCI_GET_INT_TBL_SIZE PDC_PCI_PCI_INT_ROUTE_SIZE 276 276 #define PDC_PCI_PCI_INT_ROUTE 14 277 - #define PDC_PCI_GET_INT_TBL PDC_PCI_PCI_INT_ROUTE 277 + #define PDC_PCI_GET_INT_TBL PDC_PCI_PCI_INT_ROUTE 278 278 #define PDC_PCI_READ_MON_TYPE 15 279 279 #define PDC_PCI_WRITE_MON_TYPE 16 280 280 ··· 345 345 346 346 /* constants for PDC_CHASSIS */ 347 347 #define OSTAT_OFF 0 348 - #define OSTAT_FLT 1 348 + #define OSTAT_FLT 1 349 349 #define OSTAT_TEST 2 350 350 #define OSTAT_INIT 3 351 351 #define OSTAT_SHUT 4 ··· 403 403 int vec_pad1[6]; 404 404 405 405 /* [0x040] reserved processor dependent */ 406 - int pad0[112]; 406 + int pad0[112]; /* in QEMU pad0[0] holds "SeaBIOS\0" */ 407 407 408 408 /* [0x200] reserved */ 409 409 int pad1[84]; ··· 691 691 unsigned long long fr[32]; 692 692 }; 693 693 694 + struct pim_cpu_state_cf { 695 + union { 696 + unsigned int 697 + iqv : 1, /* IIA queue Valid */ 698 + iqf : 1, /* IIA queue Failure */ 699 + ipv : 1, /* IPRs Valid */ 700 + grv : 1, /* GRs Valid */ 701 + crv : 1, /* CRs Valid */ 702 + srv : 1, /* SRs Valid */ 703 + trv : 1, /* CR24 through CR31 valid */ 704 + pad : 24, /* reserved */ 705 + td : 1; /* TOC did not cause any damage to the system state */ 706 + unsigned int val; 707 + }; 708 + }; 709 + 694 710 struct pdc_toc_pim_11 { 695 711 unsigned int gr[32]; 696 712 unsigned int cr[32]; ··· 714 698 unsigned int iasq_back; 715 699 unsigned int iaoq_back; 716 700 unsigned int check_type; 717 - unsigned int hversion; 718 - unsigned int cpu_state; 701 + struct pim_cpu_state_cf cpu_state; 719 702 }; 720 703 721 704 struct pdc_toc_pim_20 { ··· 724 709 unsigned long long iasq_back; 725 710 unsigned long long iaoq_back; 726 711 unsigned int check_type; 727 - unsigned int hversion; 728 - unsigned int cpu_state; 712 + struct pim_cpu_state_cf cpu_state; 729 713 }; 730 714 731 715 #endif /* !defined(__ASSEMBLY__) */
+1 -2
arch/parisc/kernel/Makefile
··· 10 10 ptrace.o hardware.o inventory.o drivers.o alternative.o \ 11 11 signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \ 12 12 process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \ 13 - patch.o 13 + patch.o toc.o toc_asm.o 14 14 15 15 ifdef CONFIG_FUNCTION_TRACER 16 16 # Do not profile debug and lowlevel utilities ··· 39 39 obj-$(CONFIG_KPROBES) += kprobes.o 40 40 obj-$(CONFIG_KEXEC_CORE) += kexec.o relocate_kernel.o 41 41 obj-$(CONFIG_KEXEC_FILE) += kexec_file.o 42 - obj-$(CONFIG_TOC) += toc.o toc_asm.o
+4
arch/parisc/kernel/asm-offsets.c
··· 36 36 int main(void) 37 37 { 38 38 DEFINE(TASK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags)); 39 + #ifdef CONFIG_SMP 40 + DEFINE(TASK_TI_CPU, offsetof(struct task_struct, thread_info.cpu)); 41 + #endif 39 42 DEFINE(TASK_STACK, offsetof(struct task_struct, stack)); 43 + DEFINE(TASK_PAGEFAULT_DISABLED, offsetof(struct task_struct, pagefault_disabled)); 40 44 BLANK(); 41 45 DEFINE(TASK_REGS, offsetof(struct task_struct, thread.regs)); 42 46 DEFINE(TASK_PT_PSW, offsetof(struct task_struct, thread.regs.gr[ 0]));
+2 -4
arch/parisc/kernel/hpmc.S
··· 43 43 * IODC requires 7K byte stack. That leaves 1K byte for os_hpmc. 44 44 */ 45 45 46 - __PAGE_ALIGNED_BSS 47 - .align 4096 48 - hpmc_stack: 49 - .block 16384 46 + .import toc_stack,data 47 + #define hpmc_stack toc_stack /* re-use the TOC stack */ 50 48 51 49 #define HPMC_IODC_BUF_SIZE 0x8000 52 50
+21
arch/parisc/kernel/kgdb.c
··· 3 3 * PA-RISC KGDB support 4 4 * 5 5 * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org> 6 + * Copyright (c) 2022 Helge Deller <deller@gmx.de> 6 7 * 7 8 */ 8 9 ··· 208 207 } 209 208 return -1; 210 209 } 210 + 211 + /* KGDB console driver which uses PDC to read chars from keyboard */ 212 + 213 + static void kgdb_pdc_write_char(u8 chr) 214 + { 215 + /* no need to print char. kgdb will do it. */ 216 + } 217 + 218 + static struct kgdb_io kgdb_pdc_io_ops = { 219 + .name = "kgdb_pdc", 220 + .read_char = pdc_iodc_getc, 221 + .write_char = kgdb_pdc_write_char, 222 + }; 223 + 224 + static int __init kgdb_pdc_init(void) 225 + { 226 + kgdb_register_io_module(&kgdb_pdc_io_ops); 227 + return 0; 228 + } 229 + early_initcall(kgdb_pdc_init);
+585 -191
arch/parisc/kernel/syscall.S
··· 50 50 51 51 .level PA_ASM_LEVEL 52 52 53 + .macro lws_pagefault_disable reg1,reg2 54 + mfctl %cr30, \reg2 55 + ldo TASK_PAGEFAULT_DISABLED(\reg2), \reg2 56 + ldw 0(%sr2,\reg2), \reg1 57 + ldo 1(\reg1), \reg1 58 + stw \reg1, 0(%sr2,\reg2) 59 + .endm 60 + 61 + .macro lws_pagefault_enable reg1,reg2 62 + mfctl %cr30, \reg2 63 + ldo TASK_PAGEFAULT_DISABLED(\reg2), \reg2 64 + ldw 0(%sr2,\reg2), \reg1 65 + ldo -1(\reg1), \reg1 66 + stw \reg1, 0(%sr2,\reg2) 67 + .endm 68 + 53 69 .text 54 70 55 71 .import syscall_exit,code ··· 90 74 /* ADDRESS 0xb0 to 0xb8, lws uses two insns for entry */ 91 75 /* Light-weight-syscall entry must always be located at 0xb0 */ 92 76 /* WARNING: Keep this number updated with table size changes */ 93 - #define __NR_lws_entries (3) 77 + #define __NR_lws_entries (5) 94 78 95 79 lws_entry: 96 80 gate lws_start, %r0 /* increase privilege */ ··· 506 490 /* Jump to lws, lws table pointers already relocated */ 507 491 be,n 0(%sr2,%r21) 508 492 493 + lws_exit_noerror: 494 + lws_pagefault_enable %r1,%r21 495 + stw,ma %r20, 0(%sr2,%r20) 496 + ssm PSW_SM_I, %r0 497 + b lws_exit 498 + copy %r0, %r21 499 + 500 + lws_wouldblock: 501 + ssm PSW_SM_I, %r0 502 + ldo 2(%r0), %r28 503 + b lws_exit 504 + ldo -EAGAIN(%r0), %r21 505 + 506 + lws_pagefault: 507 + lws_pagefault_enable %r1,%r21 508 + stw,ma %r20, 0(%sr2,%r20) 509 + ssm PSW_SM_I, %r0 510 + ldo 3(%r0),%r28 511 + b lws_exit 512 + ldo -EAGAIN(%r0),%r21 513 + 514 + lws_fault: 515 + ldo 1(%r0),%r28 516 + b lws_exit 517 + ldo -EFAULT(%r0),%r21 518 + 509 519 lws_exit_nosys: 510 - ldo -ENOSYS(%r0),%r21 /* set errno */ 520 + ldo -ENOSYS(%r0),%r21 511 521 /* Fall through: Return to userspace */ 512 522 513 523 lws_exit: ··· 560 518 %r28 - Return prev through this register. 561 519 %r21 - Kernel error code 562 520 563 - If debugging is DISabled: 564 - 565 - %r21 has the following meanings: 566 - 521 + %r21 returns the following error codes: 567 522 EAGAIN - CAS is busy, ldcw failed, try again. 568 523 EFAULT - Read or write failed. 569 524 570 - If debugging is enabled: 571 - 572 - EDEADLOCK - CAS called recursively. 573 - EAGAIN && r28 == 1 - CAS is busy. Lock contended. 574 - EAGAIN && r28 == 2 - CAS is busy. ldcw failed. 575 - EFAULT - Read or write failed. 525 + If EAGAIN is returned, %r28 indicates the busy reason: 526 + r28 == 1 - CAS is busy. lock contended. 527 + r28 == 2 - CAS is busy. ldcw failed. 528 + r28 == 3 - CAS is busy. page fault. 576 529 577 530 Scratch: r20, r28, r1 578 531 579 532 ****************************************************/ 580 - 581 - /* Do not enable LWS debugging */ 582 - #define ENABLE_LWS_DEBUG 0 583 533 584 534 /* ELF64 Process entry path */ 585 535 lws_compare_and_swap64: ··· 585 551 b,n lws_exit_nosys 586 552 #endif 587 553 588 - /* ELF32 Process entry path */ 554 + /* ELF32/ELF64 Process entry path */ 589 555 lws_compare_and_swap32: 590 556 #ifdef CONFIG_64BIT 591 - /* Clip all the input registers */ 557 + /* Wide mode user process? */ 558 + bb,<,n %sp, 31, lws_compare_and_swap 559 + 560 + /* Clip all the input registers for 32-bit processes */ 592 561 depdi 0, 31, 32, %r26 593 562 depdi 0, 31, 32, %r25 594 563 depdi 0, 31, 32, %r24 595 564 #endif 596 565 597 566 lws_compare_and_swap: 567 + /* Trigger memory reference interruptions without writing to memory */ 568 + 1: ldw 0(%r26), %r28 569 + 2: stbys,e %r0, 0(%r26) 570 + 571 + /* Calculate 8-bit hash index from virtual address */ 572 + extru_safe %r26, 27, 8, %r20 573 + 598 574 /* Load start of lock table */ 599 - ldil L%lws_lock_start, %r20 600 - ldo R%lws_lock_start(%r20), %r28 575 + ldil L%lws_lock_start, %r28 576 + ldo R%lws_lock_start(%r28), %r28 601 577 602 - /* Extract eight bits from r26 and hash lock (Bits 3-11) */ 603 - extru_safe %r26, 28, 8, %r20 604 - 605 - /* Find lock to use, the hash is either one of 0 to 606 - 15, multiplied by 16 (keep it 16-byte aligned) 578 + /* Find lock to use, the hash index is one of 0 to 579 + 255, multiplied by 16 (keep it 16-byte aligned) 607 580 and add to the lock table offset. */ 608 581 shlw %r20, 4, %r20 609 582 add %r20, %r28, %r20 610 583 611 - # if ENABLE_LWS_DEBUG 612 - /* 613 - DEBUG, check for deadlock! 614 - If the thread register values are the same 615 - then we were the one that locked it last and 616 - this is a recurisve call that will deadlock. 617 - We *must* giveup this call and fail. 618 - */ 619 - ldw 4(%sr2,%r20), %r28 /* Load thread register */ 620 - /* WARNING: If cr27 cycles to the same value we have problems */ 621 - mfctl %cr27, %r21 /* Get current thread register */ 622 - cmpb,<>,n %r21, %r28, cas_lock /* Called recursive? */ 623 - b lws_exit /* Return error! */ 624 - ldo -EDEADLOCK(%r0), %r21 625 - cas_lock: 626 - cmpb,=,n %r0, %r28, cas_nocontend /* Is nobody using it? */ 627 - ldo 1(%r0), %r28 /* 1st case */ 628 - b lws_exit /* Contended... */ 629 - ldo -EAGAIN(%r0), %r21 /* Spin in userspace */ 630 - cas_nocontend: 631 - # endif 632 - /* ENABLE_LWS_DEBUG */ 584 + rsm PSW_SM_I, %r0 /* Disable interrupts */ 633 585 634 - /* COW breaks can cause contention on UP systems */ 635 - LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */ 636 - cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */ 637 - cas_wouldblock: 638 - ldo 2(%r0), %r28 /* 2nd case */ 639 - b lws_exit /* Contended... */ 640 - ldo -EAGAIN(%r0), %r21 /* Spin in userspace */ 586 + /* Try to acquire the lock */ 587 + LDCW 0(%sr2,%r20), %r28 588 + comclr,<> %r0, %r28, %r0 589 + b,n lws_wouldblock 590 + 591 + /* Disable page faults to prevent sleeping in critical region */ 592 + lws_pagefault_disable %r21,%r28 641 593 642 594 /* 643 595 prev = *addr; ··· 633 613 */ 634 614 635 615 /* NOTES: 636 - This all works becuse intr_do_signal 616 + This all works because intr_do_signal 637 617 and schedule both check the return iasq 638 618 and see that we are on the kernel page 639 619 so this process is never scheduled off 640 620 or is ever sent any signal of any sort, 641 - thus it is wholly atomic from usrspaces 621 + thus it is wholly atomic from usrspace's 642 622 perspective 643 623 */ 644 - cas_action: 645 - #if defined CONFIG_SMP && ENABLE_LWS_DEBUG 646 - /* DEBUG */ 647 - mfctl %cr27, %r1 648 - stw %r1, 4(%sr2,%r20) 649 - #endif 650 624 /* The load and store could fail */ 651 - 1: ldw 0(%r26), %r28 625 + 3: ldw 0(%r26), %r28 652 626 sub,<> %r28, %r25, %r0 653 - 2: stw %r24, 0(%r26) 654 - /* Free lock */ 655 - stw,ma %r20, 0(%sr2,%r20) 656 - #if ENABLE_LWS_DEBUG 657 - /* Clear thread register indicator */ 658 - stw %r0, 4(%sr2,%r20) 659 - #endif 660 - /* Return to userspace, set no error */ 661 - b lws_exit 662 - copy %r0, %r21 627 + 4: stw %r24, 0(%r26) 628 + b,n lws_exit_noerror 663 629 664 - 3: 665 - /* Error occurred on load or store */ 666 - /* Free lock */ 667 - stw,ma %r20, 0(%sr2,%r20) 668 - #if ENABLE_LWS_DEBUG 669 - stw %r0, 4(%sr2,%r20) 670 - #endif 671 - b lws_exit 672 - ldo -EFAULT(%r0),%r21 /* set errno */ 673 - nop 674 - nop 675 - nop 676 - nop 630 + /* A fault occurred on load or stbys,e store */ 631 + 5: b,n lws_fault 632 + ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 5b-linux_gateway_page) 633 + ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 5b-linux_gateway_page) 677 634 678 - /* Two exception table entries, one for the load, 679 - the other for the store. Either return -EFAULT. 680 - Each of the entries must be relocated. */ 681 - ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 3b-linux_gateway_page) 682 - ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 3b-linux_gateway_page) 635 + /* A page fault occurred in critical region */ 636 + 6: b,n lws_pagefault 637 + ASM_EXCEPTIONTABLE_ENTRY(3b-linux_gateway_page, 6b-linux_gateway_page) 638 + ASM_EXCEPTIONTABLE_ENTRY(4b-linux_gateway_page, 6b-linux_gateway_page) 683 639 684 640 685 641 /*************************************************** 686 642 New CAS implementation which uses pointers and variable size 687 643 information. The value pointed by old and new MUST NOT change 688 - while performing CAS. The lock only protect the value at %r26. 644 + while performing CAS. The lock only protects the value at %r26. 689 645 690 646 %r26 - Address to examine 691 647 %r25 - Pointer to the value to check (old) ··· 670 674 %r28 - Return non-zero on failure 671 675 %r21 - Kernel error code 672 676 673 - %r21 has the following meanings: 674 - 677 + %r21 returns the following error codes: 675 678 EAGAIN - CAS is busy, ldcw failed, try again. 676 679 EFAULT - Read or write failed. 680 + 681 + If EAGAIN is returned, %r28 indicates the busy reason: 682 + r28 == 1 - CAS is busy. lock contended. 683 + r28 == 2 - CAS is busy. ldcw failed. 684 + r28 == 3 - CAS is busy. page fault. 677 685 678 686 Scratch: r20, r22, r28, r29, r1, fr4 (32bit for 64bit CAS only) 679 687 680 688 ****************************************************/ 681 689 682 - /* ELF32 Process entry path */ 683 690 lws_compare_and_swap_2: 684 691 #ifdef CONFIG_64BIT 685 - /* Clip the input registers. We don't need to clip %r23 as we 686 - only use it for word operations */ 692 + /* Wide mode user process? */ 693 + bb,<,n %sp, 31, cas2_begin 694 + 695 + /* Clip the input registers for 32-bit processes. We don't 696 + need to clip %r23 as we only use it for word operations */ 687 697 depdi 0, 31, 32, %r26 688 698 depdi 0, 31, 32, %r25 689 699 depdi 0, 31, 32, %r24 690 700 #endif 691 701 702 + cas2_begin: 692 703 /* Check the validity of the size pointer */ 693 704 subi,>>= 3, %r23, %r0 694 705 b,n lws_exit_nosys ··· 706 703 blr %r29, %r0 707 704 nop 708 705 709 - /* 8bit load */ 710 - 4: ldb 0(%r25), %r25 706 + /* 8-bit load */ 707 + 1: ldb 0(%r25), %r25 711 708 b cas2_lock_start 712 - 5: ldb 0(%r24), %r24 709 + 2: ldb 0(%r24), %r24 713 710 nop 714 711 nop 715 712 nop 716 713 nop 717 714 nop 718 715 719 - /* 16bit load */ 720 - 6: ldh 0(%r25), %r25 716 + /* 16-bit load */ 717 + 3: ldh 0(%r25), %r25 721 718 b cas2_lock_start 722 - 7: ldh 0(%r24), %r24 719 + 4: ldh 0(%r24), %r24 723 720 nop 724 721 nop 725 722 nop 726 723 nop 727 724 nop 728 725 729 - /* 32bit load */ 730 - 8: ldw 0(%r25), %r25 726 + /* 32-bit load */ 727 + 5: ldw 0(%r25), %r25 731 728 b cas2_lock_start 732 - 9: ldw 0(%r24), %r24 729 + 6: ldw 0(%r24), %r24 733 730 nop 734 731 nop 735 732 nop 736 733 nop 737 734 nop 738 735 739 - /* 64bit load */ 736 + /* 64-bit load */ 740 737 #ifdef CONFIG_64BIT 741 - 10: ldd 0(%r25), %r25 742 - 11: ldd 0(%r24), %r24 738 + 7: ldd 0(%r25), %r25 739 + 8: ldd 0(%r24), %r24 743 740 #else 744 741 /* Load old value into r22/r23 - high/low */ 745 - 10: ldw 0(%r25), %r22 746 - 11: ldw 4(%r25), %r23 742 + 7: ldw 0(%r25), %r22 743 + 8: ldw 4(%r25), %r23 747 744 /* Load new value into fr4 for atomic store later */ 748 - 12: flddx 0(%r24), %fr4 745 + 9: flddx 0(%r24), %fr4 749 746 #endif 750 747 751 748 cas2_lock_start: 749 + /* Trigger memory reference interruptions without writing to memory */ 750 + copy %r26, %r28 751 + depi_safe 0, 31, 2, %r28 752 + 10: ldw 0(%r28), %r1 753 + 11: stbys,e %r0, 0(%r28) 754 + 755 + /* Calculate 8-bit hash index from virtual address */ 756 + extru_safe %r26, 27, 8, %r20 757 + 752 758 /* Load start of lock table */ 753 - ldil L%lws_lock_start, %r20 754 - ldo R%lws_lock_start(%r20), %r28 759 + ldil L%lws_lock_start, %r28 760 + ldo R%lws_lock_start(%r28), %r28 755 761 756 - /* Extract eight bits from r26 and hash lock (Bits 3-11) */ 757 - extru_safe %r26, 28, 8, %r20 758 - 759 - /* Find lock to use, the hash is either one of 0 to 760 - 15, multiplied by 16 (keep it 16-byte aligned) 762 + /* Find lock to use, the hash index is one of 0 to 763 + 255, multiplied by 16 (keep it 16-byte aligned) 761 764 and add to the lock table offset. */ 762 765 shlw %r20, 4, %r20 763 766 add %r20, %r28, %r20 764 767 765 - /* COW breaks can cause contention on UP systems */ 766 - LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */ 767 - cmpb,<>,n %r0, %r28, cas2_action /* Did we get it? */ 768 - cas2_wouldblock: 769 - ldo 2(%r0), %r28 /* 2nd case */ 770 - b lws_exit /* Contended... */ 771 - ldo -EAGAIN(%r0), %r21 /* Spin in userspace */ 768 + rsm PSW_SM_I, %r0 /* Disable interrupts */ 769 + 770 + /* Try to acquire the lock */ 771 + LDCW 0(%sr2,%r20), %r28 772 + comclr,<> %r0, %r28, %r0 773 + b,n lws_wouldblock 774 + 775 + /* Disable page faults to prevent sleeping in critical region */ 776 + lws_pagefault_disable %r21,%r28 772 777 773 778 /* 774 779 prev = *addr; ··· 786 775 */ 787 776 788 777 /* NOTES: 789 - This all works becuse intr_do_signal 778 + This all works because intr_do_signal 790 779 and schedule both check the return iasq 791 780 and see that we are on the kernel page 792 781 so this process is never scheduled off 793 782 or is ever sent any signal of any sort, 794 - thus it is wholly atomic from usrspaces 783 + thus it is wholly atomic from usrspace's 795 784 perspective 796 785 */ 797 - cas2_action: 786 + 798 787 /* Jump to the correct function */ 799 788 blr %r29, %r0 800 789 /* Set %r28 as non-zero for now */ 801 790 ldo 1(%r0),%r28 802 791 803 - /* 8bit CAS */ 804 - 13: ldb 0(%r26), %r29 792 + /* 8-bit CAS */ 793 + 12: ldb 0(%r26), %r29 805 794 sub,= %r29, %r25, %r0 806 - b,n cas2_end 807 - 14: stb %r24, 0(%r26) 808 - b cas2_end 795 + b,n lws_exit_noerror 796 + 13: stb %r24, 0(%r26) 797 + b lws_exit_noerror 809 798 copy %r0, %r28 810 799 nop 811 800 nop 812 801 813 - /* 16bit CAS */ 814 - 15: ldh 0(%r26), %r29 802 + /* 16-bit CAS */ 803 + 14: ldh 0(%r26), %r29 815 804 sub,= %r29, %r25, %r0 816 - b,n cas2_end 817 - 16: sth %r24, 0(%r26) 818 - b cas2_end 805 + b,n lws_exit_noerror 806 + 15: sth %r24, 0(%r26) 807 + b lws_exit_noerror 819 808 copy %r0, %r28 820 809 nop 821 810 nop 822 811 823 - /* 32bit CAS */ 824 - 17: ldw 0(%r26), %r29 812 + /* 32-bit CAS */ 813 + 16: ldw 0(%r26), %r29 825 814 sub,= %r29, %r25, %r0 826 - b,n cas2_end 827 - 18: stw %r24, 0(%r26) 828 - b cas2_end 815 + b,n lws_exit_noerror 816 + 17: stw %r24, 0(%r26) 817 + b lws_exit_noerror 829 818 copy %r0, %r28 830 819 nop 831 820 nop 832 821 833 - /* 64bit CAS */ 822 + /* 64-bit CAS */ 834 823 #ifdef CONFIG_64BIT 835 - 19: ldd 0(%r26), %r29 824 + 18: ldd 0(%r26), %r29 836 825 sub,*= %r29, %r25, %r0 837 - b,n cas2_end 838 - 20: std %r24, 0(%r26) 826 + b,n lws_exit_noerror 827 + 19: std %r24, 0(%r26) 839 828 copy %r0, %r28 840 829 #else 841 830 /* Compare first word */ 842 - 19: ldw 0(%r26), %r29 831 + 18: ldw 0(%r26), %r29 843 832 sub,= %r29, %r22, %r0 844 - b,n cas2_end 833 + b,n lws_exit_noerror 845 834 /* Compare second word */ 846 - 20: ldw 4(%r26), %r29 835 + 19: ldw 4(%r26), %r29 847 836 sub,= %r29, %r23, %r0 848 - b,n cas2_end 837 + b,n lws_exit_noerror 849 838 /* Perform the store */ 850 - 21: fstdx %fr4, 0(%r26) 839 + 20: fstdx %fr4, 0(%r26) 851 840 copy %r0, %r28 852 841 #endif 842 + b lws_exit_noerror 843 + copy %r0, %r28 853 844 854 - cas2_end: 855 - /* Free lock */ 856 - stw,ma %r20, 0(%sr2,%r20) 857 - /* Return to userspace, set no error */ 858 - b lws_exit 859 - copy %r0, %r21 860 - 861 - 22: 862 - /* Error occurred on load or store */ 863 - /* Free lock */ 864 - stw,ma %r20, 0(%sr2,%r20) 865 - ldo 1(%r0),%r28 866 - b lws_exit 867 - ldo -EFAULT(%r0),%r21 /* set errno */ 868 - nop 869 - nop 870 - nop 871 - 872 - /* Exception table entries, for the load and store, return EFAULT. 873 - Each of the entries must be relocated. */ 874 - ASM_EXCEPTIONTABLE_ENTRY(4b-linux_gateway_page, 22b-linux_gateway_page) 875 - ASM_EXCEPTIONTABLE_ENTRY(5b-linux_gateway_page, 22b-linux_gateway_page) 876 - ASM_EXCEPTIONTABLE_ENTRY(6b-linux_gateway_page, 22b-linux_gateway_page) 877 - ASM_EXCEPTIONTABLE_ENTRY(7b-linux_gateway_page, 22b-linux_gateway_page) 878 - ASM_EXCEPTIONTABLE_ENTRY(8b-linux_gateway_page, 22b-linux_gateway_page) 879 - ASM_EXCEPTIONTABLE_ENTRY(9b-linux_gateway_page, 22b-linux_gateway_page) 880 - ASM_EXCEPTIONTABLE_ENTRY(10b-linux_gateway_page, 22b-linux_gateway_page) 881 - ASM_EXCEPTIONTABLE_ENTRY(11b-linux_gateway_page, 22b-linux_gateway_page) 882 - ASM_EXCEPTIONTABLE_ENTRY(13b-linux_gateway_page, 22b-linux_gateway_page) 883 - ASM_EXCEPTIONTABLE_ENTRY(14b-linux_gateway_page, 22b-linux_gateway_page) 884 - ASM_EXCEPTIONTABLE_ENTRY(15b-linux_gateway_page, 22b-linux_gateway_page) 885 - ASM_EXCEPTIONTABLE_ENTRY(16b-linux_gateway_page, 22b-linux_gateway_page) 886 - ASM_EXCEPTIONTABLE_ENTRY(17b-linux_gateway_page, 22b-linux_gateway_page) 887 - ASM_EXCEPTIONTABLE_ENTRY(18b-linux_gateway_page, 22b-linux_gateway_page) 888 - ASM_EXCEPTIONTABLE_ENTRY(19b-linux_gateway_page, 22b-linux_gateway_page) 889 - ASM_EXCEPTIONTABLE_ENTRY(20b-linux_gateway_page, 22b-linux_gateway_page) 845 + /* A fault occurred on load or stbys,e store */ 846 + 30: b,n lws_fault 847 + ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 30b-linux_gateway_page) 848 + ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 30b-linux_gateway_page) 849 + ASM_EXCEPTIONTABLE_ENTRY(3b-linux_gateway_page, 30b-linux_gateway_page) 850 + ASM_EXCEPTIONTABLE_ENTRY(4b-linux_gateway_page, 30b-linux_gateway_page) 851 + ASM_EXCEPTIONTABLE_ENTRY(5b-linux_gateway_page, 30b-linux_gateway_page) 852 + ASM_EXCEPTIONTABLE_ENTRY(6b-linux_gateway_page, 30b-linux_gateway_page) 853 + ASM_EXCEPTIONTABLE_ENTRY(7b-linux_gateway_page, 30b-linux_gateway_page) 854 + ASM_EXCEPTIONTABLE_ENTRY(8b-linux_gateway_page, 30b-linux_gateway_page) 890 855 #ifndef CONFIG_64BIT 891 - ASM_EXCEPTIONTABLE_ENTRY(12b-linux_gateway_page, 22b-linux_gateway_page) 892 - ASM_EXCEPTIONTABLE_ENTRY(21b-linux_gateway_page, 22b-linux_gateway_page) 856 + ASM_EXCEPTIONTABLE_ENTRY(9b-linux_gateway_page, 30b-linux_gateway_page) 893 857 #endif 858 + 859 + ASM_EXCEPTIONTABLE_ENTRY(10b-linux_gateway_page, 30b-linux_gateway_page) 860 + ASM_EXCEPTIONTABLE_ENTRY(11b-linux_gateway_page, 30b-linux_gateway_page) 861 + 862 + /* A page fault occurred in critical region */ 863 + 31: b,n lws_pagefault 864 + ASM_EXCEPTIONTABLE_ENTRY(12b-linux_gateway_page, 31b-linux_gateway_page) 865 + ASM_EXCEPTIONTABLE_ENTRY(13b-linux_gateway_page, 31b-linux_gateway_page) 866 + ASM_EXCEPTIONTABLE_ENTRY(14b-linux_gateway_page, 31b-linux_gateway_page) 867 + ASM_EXCEPTIONTABLE_ENTRY(15b-linux_gateway_page, 31b-linux_gateway_page) 868 + ASM_EXCEPTIONTABLE_ENTRY(16b-linux_gateway_page, 31b-linux_gateway_page) 869 + ASM_EXCEPTIONTABLE_ENTRY(17b-linux_gateway_page, 31b-linux_gateway_page) 870 + ASM_EXCEPTIONTABLE_ENTRY(18b-linux_gateway_page, 31b-linux_gateway_page) 871 + ASM_EXCEPTIONTABLE_ENTRY(19b-linux_gateway_page, 31b-linux_gateway_page) 872 + #ifndef CONFIG_64BIT 873 + ASM_EXCEPTIONTABLE_ENTRY(20b-linux_gateway_page, 31b-linux_gateway_page) 874 + #endif 875 + 876 + 877 + /*************************************************** 878 + LWS atomic exchange. 879 + 880 + %r26 - Exchange address 881 + %r25 - Size of the variable (0/1/2/3 for 8/16/32/64 bit) 882 + %r24 - Address of new value 883 + %r23 - Address of old value 884 + %r28 - Return non-zero on failure 885 + %r21 - Kernel error code 886 + 887 + %r21 returns the following error codes: 888 + EAGAIN - CAS is busy, ldcw failed, try again. 889 + EFAULT - Read or write failed. 890 + 891 + If EAGAIN is returned, %r28 indicates the busy reason: 892 + r28 == 1 - CAS is busy. lock contended. 893 + r28 == 2 - CAS is busy. ldcw failed. 894 + r28 == 3 - CAS is busy. page fault. 895 + 896 + Scratch: r20, r1 897 + 898 + ****************************************************/ 899 + 900 + lws_atomic_xchg: 901 + #ifdef CONFIG_64BIT 902 + /* Wide mode user process? */ 903 + bb,<,n %sp, 31, atomic_xchg_begin 904 + 905 + /* Clip the input registers for 32-bit processes. We don't 906 + need to clip %r23 as we only use it for word operations */ 907 + depdi 0, 31, 32, %r26 908 + depdi 0, 31, 32, %r25 909 + depdi 0, 31, 32, %r24 910 + depdi 0, 31, 32, %r23 911 + #endif 912 + 913 + atomic_xchg_begin: 914 + /* Check the validity of the size pointer */ 915 + subi,>>= 3, %r25, %r0 916 + b,n lws_exit_nosys 917 + 918 + /* Jump to the functions which will load the old and new values into 919 + registers depending on the their size */ 920 + shlw %r25, 2, %r1 921 + blr %r1, %r0 922 + nop 923 + 924 + /* Perform exception checks */ 925 + 926 + /* 8-bit exchange */ 927 + 1: ldb 0(%r24), %r20 928 + copy %r23, %r20 929 + depi_safe 0, 31, 2, %r20 930 + b atomic_xchg_start 931 + 2: stbys,e %r0, 0(%r20) 932 + nop 933 + nop 934 + nop 935 + 936 + /* 16-bit exchange */ 937 + 3: ldh 0(%r24), %r20 938 + copy %r23, %r20 939 + depi_safe 0, 31, 2, %r20 940 + b atomic_xchg_start 941 + 4: stbys,e %r0, 0(%r20) 942 + nop 943 + nop 944 + nop 945 + 946 + /* 32-bit exchange */ 947 + 5: ldw 0(%r24), %r20 948 + b atomic_xchg_start 949 + 6: stbys,e %r0, 0(%r23) 950 + nop 951 + nop 952 + nop 953 + nop 954 + nop 955 + 956 + /* 64-bit exchange */ 957 + #ifdef CONFIG_64BIT 958 + 7: ldd 0(%r24), %r20 959 + 8: stdby,e %r0, 0(%r23) 960 + #else 961 + 7: ldw 0(%r24), %r20 962 + 8: ldw 4(%r24), %r20 963 + copy %r23, %r20 964 + depi_safe 0, 31, 2, %r20 965 + 9: stbys,e %r0, 0(%r20) 966 + 10: stbys,e %r0, 4(%r20) 967 + #endif 968 + 969 + atomic_xchg_start: 970 + /* Trigger memory reference interruptions without writing to memory */ 971 + copy %r26, %r28 972 + depi_safe 0, 31, 2, %r28 973 + 11: ldw 0(%r28), %r1 974 + 12: stbys,e %r0, 0(%r28) 975 + 976 + /* Calculate 8-bit hash index from virtual address */ 977 + extru_safe %r26, 27, 8, %r20 978 + 979 + /* Load start of lock table */ 980 + ldil L%lws_lock_start, %r28 981 + ldo R%lws_lock_start(%r28), %r28 982 + 983 + /* Find lock to use, the hash index is one of 0 to 984 + 255, multiplied by 16 (keep it 16-byte aligned) 985 + and add to the lock table offset. */ 986 + shlw %r20, 4, %r20 987 + add %r20, %r28, %r20 988 + 989 + rsm PSW_SM_I, %r0 /* Disable interrupts */ 990 + 991 + /* Try to acquire the lock */ 992 + LDCW 0(%sr2,%r20), %r28 993 + comclr,<> %r0, %r28, %r0 994 + b,n lws_wouldblock 995 + 996 + /* Disable page faults to prevent sleeping in critical region */ 997 + lws_pagefault_disable %r21,%r28 998 + 999 + /* NOTES: 1000 + This all works because intr_do_signal 1001 + and schedule both check the return iasq 1002 + and see that we are on the kernel page 1003 + so this process is never scheduled off 1004 + or is ever sent any signal of any sort, 1005 + thus it is wholly atomic from userspace's 1006 + perspective 1007 + */ 1008 + 1009 + /* Jump to the correct function */ 1010 + blr %r1, %r0 1011 + /* Set %r28 as non-zero for now */ 1012 + ldo 1(%r0),%r28 1013 + 1014 + /* 8-bit exchange */ 1015 + 14: ldb 0(%r26), %r1 1016 + 15: stb %r1, 0(%r23) 1017 + 15: ldb 0(%r24), %r1 1018 + 17: stb %r1, 0(%r26) 1019 + b lws_exit_noerror 1020 + copy %r0, %r28 1021 + nop 1022 + nop 1023 + 1024 + /* 16-bit exchange */ 1025 + 18: ldh 0(%r26), %r1 1026 + 19: sth %r1, 0(%r23) 1027 + 20: ldh 0(%r24), %r1 1028 + 21: sth %r1, 0(%r26) 1029 + b lws_exit_noerror 1030 + copy %r0, %r28 1031 + nop 1032 + nop 1033 + 1034 + /* 32-bit exchange */ 1035 + 22: ldw 0(%r26), %r1 1036 + 23: stw %r1, 0(%r23) 1037 + 24: ldw 0(%r24), %r1 1038 + 25: stw %r1, 0(%r26) 1039 + b lws_exit_noerror 1040 + copy %r0, %r28 1041 + nop 1042 + nop 1043 + 1044 + /* 64-bit exchange */ 1045 + #ifdef CONFIG_64BIT 1046 + 26: ldd 0(%r26), %r1 1047 + 27: std %r1, 0(%r23) 1048 + 28: ldd 0(%r24), %r1 1049 + 29: std %r1, 0(%r26) 1050 + #else 1051 + 26: flddx 0(%r26), %fr4 1052 + 27: fstdx %fr4, 0(%r23) 1053 + 28: flddx 0(%r24), %fr4 1054 + 29: fstdx %fr4, 0(%r26) 1055 + #endif 1056 + b lws_exit_noerror 1057 + copy %r0, %r28 1058 + 1059 + /* A fault occurred on load or stbys,e store */ 1060 + 30: b,n lws_fault 1061 + ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 30b-linux_gateway_page) 1062 + ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 30b-linux_gateway_page) 1063 + ASM_EXCEPTIONTABLE_ENTRY(3b-linux_gateway_page, 30b-linux_gateway_page) 1064 + ASM_EXCEPTIONTABLE_ENTRY(4b-linux_gateway_page, 30b-linux_gateway_page) 1065 + ASM_EXCEPTIONTABLE_ENTRY(5b-linux_gateway_page, 30b-linux_gateway_page) 1066 + ASM_EXCEPTIONTABLE_ENTRY(6b-linux_gateway_page, 30b-linux_gateway_page) 1067 + ASM_EXCEPTIONTABLE_ENTRY(7b-linux_gateway_page, 30b-linux_gateway_page) 1068 + ASM_EXCEPTIONTABLE_ENTRY(8b-linux_gateway_page, 30b-linux_gateway_page) 1069 + #ifndef CONFIG_64BIT 1070 + ASM_EXCEPTIONTABLE_ENTRY(9b-linux_gateway_page, 30b-linux_gateway_page) 1071 + ASM_EXCEPTIONTABLE_ENTRY(10b-linux_gateway_page, 30b-linux_gateway_page) 1072 + #endif 1073 + 1074 + ASM_EXCEPTIONTABLE_ENTRY(11b-linux_gateway_page, 30b-linux_gateway_page) 1075 + ASM_EXCEPTIONTABLE_ENTRY(12b-linux_gateway_page, 30b-linux_gateway_page) 1076 + 1077 + /* A page fault occurred in critical region */ 1078 + 31: b,n lws_pagefault 1079 + ASM_EXCEPTIONTABLE_ENTRY(14b-linux_gateway_page, 31b-linux_gateway_page) 1080 + ASM_EXCEPTIONTABLE_ENTRY(15b-linux_gateway_page, 31b-linux_gateway_page) 1081 + ASM_EXCEPTIONTABLE_ENTRY(16b-linux_gateway_page, 31b-linux_gateway_page) 1082 + ASM_EXCEPTIONTABLE_ENTRY(17b-linux_gateway_page, 31b-linux_gateway_page) 1083 + ASM_EXCEPTIONTABLE_ENTRY(18b-linux_gateway_page, 31b-linux_gateway_page) 1084 + ASM_EXCEPTIONTABLE_ENTRY(19b-linux_gateway_page, 31b-linux_gateway_page) 1085 + ASM_EXCEPTIONTABLE_ENTRY(20b-linux_gateway_page, 31b-linux_gateway_page) 1086 + ASM_EXCEPTIONTABLE_ENTRY(21b-linux_gateway_page, 31b-linux_gateway_page) 1087 + ASM_EXCEPTIONTABLE_ENTRY(22b-linux_gateway_page, 31b-linux_gateway_page) 1088 + ASM_EXCEPTIONTABLE_ENTRY(23b-linux_gateway_page, 31b-linux_gateway_page) 1089 + ASM_EXCEPTIONTABLE_ENTRY(24b-linux_gateway_page, 31b-linux_gateway_page) 1090 + ASM_EXCEPTIONTABLE_ENTRY(25b-linux_gateway_page, 31b-linux_gateway_page) 1091 + ASM_EXCEPTIONTABLE_ENTRY(26b-linux_gateway_page, 31b-linux_gateway_page) 1092 + ASM_EXCEPTIONTABLE_ENTRY(27b-linux_gateway_page, 31b-linux_gateway_page) 1093 + ASM_EXCEPTIONTABLE_ENTRY(28b-linux_gateway_page, 31b-linux_gateway_page) 1094 + ASM_EXCEPTIONTABLE_ENTRY(29b-linux_gateway_page, 31b-linux_gateway_page) 1095 + 1096 + /*************************************************** 1097 + LWS atomic store. 1098 + 1099 + %r26 - Address to store 1100 + %r25 - Size of the variable (0/1/2/3 for 8/16/32/64 bit) 1101 + %r24 - Address of value to store 1102 + %r28 - Return non-zero on failure 1103 + %r21 - Kernel error code 1104 + 1105 + %r21 returns the following error codes: 1106 + EAGAIN - CAS is busy, ldcw failed, try again. 1107 + EFAULT - Read or write failed. 1108 + 1109 + If EAGAIN is returned, %r28 indicates the busy reason: 1110 + r28 == 1 - CAS is busy. lock contended. 1111 + r28 == 2 - CAS is busy. ldcw failed. 1112 + r28 == 3 - CAS is busy. page fault. 1113 + 1114 + Scratch: r20, r1 1115 + 1116 + ****************************************************/ 1117 + 1118 + lws_atomic_store: 1119 + #ifdef CONFIG_64BIT 1120 + /* Wide mode user process? */ 1121 + bb,<,n %sp, 31, atomic_store_begin 1122 + 1123 + /* Clip the input registers for 32-bit processes. We don't 1124 + need to clip %r23 as we only use it for word operations */ 1125 + depdi 0, 31, 32, %r26 1126 + depdi 0, 31, 32, %r25 1127 + depdi 0, 31, 32, %r24 1128 + #endif 1129 + 1130 + atomic_store_begin: 1131 + /* Check the validity of the size pointer */ 1132 + subi,>>= 3, %r25, %r0 1133 + b,n lws_exit_nosys 1134 + 1135 + shlw %r25, 1, %r1 1136 + blr %r1, %r0 1137 + nop 1138 + 1139 + /* Perform exception checks */ 1140 + 1141 + /* 8-bit store */ 1142 + 1: ldb 0(%r24), %r20 1143 + b,n atomic_store_start 1144 + nop 1145 + nop 1146 + 1147 + /* 16-bit store */ 1148 + 2: ldh 0(%r24), %r20 1149 + b,n atomic_store_start 1150 + nop 1151 + nop 1152 + 1153 + /* 32-bit store */ 1154 + 3: ldw 0(%r24), %r20 1155 + b,n atomic_store_start 1156 + nop 1157 + nop 1158 + 1159 + /* 64-bit store */ 1160 + #ifdef CONFIG_64BIT 1161 + 4: ldd 0(%r24), %r20 1162 + #else 1163 + 4: ldw 0(%r24), %r20 1164 + 5: ldw 4(%r24), %r20 1165 + #endif 1166 + 1167 + atomic_store_start: 1168 + /* Trigger memory reference interruptions without writing to memory */ 1169 + copy %r26, %r28 1170 + depi_safe 0, 31, 2, %r28 1171 + 6: ldw 0(%r28), %r1 1172 + 7: stbys,e %r0, 0(%r28) 1173 + 1174 + /* Calculate 8-bit hash index from virtual address */ 1175 + extru_safe %r26, 27, 8, %r20 1176 + 1177 + /* Load start of lock table */ 1178 + ldil L%lws_lock_start, %r28 1179 + ldo R%lws_lock_start(%r28), %r28 1180 + 1181 + /* Find lock to use, the hash index is one of 0 to 1182 + 255, multiplied by 16 (keep it 16-byte aligned) 1183 + and add to the lock table offset. */ 1184 + shlw %r20, 4, %r20 1185 + add %r20, %r28, %r20 1186 + 1187 + rsm PSW_SM_I, %r0 /* Disable interrupts */ 1188 + 1189 + /* Try to acquire the lock */ 1190 + LDCW 0(%sr2,%r20), %r28 1191 + comclr,<> %r0, %r28, %r0 1192 + b,n lws_wouldblock 1193 + 1194 + /* Disable page faults to prevent sleeping in critical region */ 1195 + lws_pagefault_disable %r21,%r28 1196 + 1197 + /* NOTES: 1198 + This all works because intr_do_signal 1199 + and schedule both check the return iasq 1200 + and see that we are on the kernel page 1201 + so this process is never scheduled off 1202 + or is ever sent any signal of any sort, 1203 + thus it is wholly atomic from userspace's 1204 + perspective 1205 + */ 1206 + 1207 + /* Jump to the correct function */ 1208 + blr %r1, %r0 1209 + /* Set %r28 as non-zero for now */ 1210 + ldo 1(%r0),%r28 1211 + 1212 + /* 8-bit store */ 1213 + 9: ldb 0(%r24), %r1 1214 + 10: stb %r1, 0(%r26) 1215 + b lws_exit_noerror 1216 + copy %r0, %r28 1217 + 1218 + /* 16-bit store */ 1219 + 11: ldh 0(%r24), %r1 1220 + 12: sth %r1, 0(%r26) 1221 + b lws_exit_noerror 1222 + copy %r0, %r28 1223 + 1224 + /* 32-bit store */ 1225 + 13: ldw 0(%r24), %r1 1226 + 14: stw %r1, 0(%r26) 1227 + b lws_exit_noerror 1228 + copy %r0, %r28 1229 + 1230 + /* 64-bit store */ 1231 + #ifdef CONFIG_64BIT 1232 + 15: ldd 0(%r24), %r1 1233 + 16: std %r1, 0(%r26) 1234 + #else 1235 + 15: flddx 0(%r24), %fr4 1236 + 16: fstdx %fr4, 0(%r26) 1237 + #endif 1238 + b lws_exit_noerror 1239 + copy %r0, %r28 1240 + 1241 + /* A fault occurred on load or stbys,e store */ 1242 + 30: b,n lws_fault 1243 + ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 30b-linux_gateway_page) 1244 + ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 30b-linux_gateway_page) 1245 + ASM_EXCEPTIONTABLE_ENTRY(3b-linux_gateway_page, 30b-linux_gateway_page) 1246 + ASM_EXCEPTIONTABLE_ENTRY(4b-linux_gateway_page, 30b-linux_gateway_page) 1247 + #ifndef CONFIG_64BIT 1248 + ASM_EXCEPTIONTABLE_ENTRY(5b-linux_gateway_page, 30b-linux_gateway_page) 1249 + #endif 1250 + 1251 + ASM_EXCEPTIONTABLE_ENTRY(6b-linux_gateway_page, 30b-linux_gateway_page) 1252 + ASM_EXCEPTIONTABLE_ENTRY(7b-linux_gateway_page, 30b-linux_gateway_page) 1253 + 1254 + /* A page fault occurred in critical region */ 1255 + 31: b,n lws_pagefault 1256 + ASM_EXCEPTIONTABLE_ENTRY(9b-linux_gateway_page, 31b-linux_gateway_page) 1257 + ASM_EXCEPTIONTABLE_ENTRY(10b-linux_gateway_page, 31b-linux_gateway_page) 1258 + ASM_EXCEPTIONTABLE_ENTRY(11b-linux_gateway_page, 31b-linux_gateway_page) 1259 + ASM_EXCEPTIONTABLE_ENTRY(12b-linux_gateway_page, 31b-linux_gateway_page) 1260 + ASM_EXCEPTIONTABLE_ENTRY(13b-linux_gateway_page, 31b-linux_gateway_page) 1261 + ASM_EXCEPTIONTABLE_ENTRY(14b-linux_gateway_page, 31b-linux_gateway_page) 1262 + ASM_EXCEPTIONTABLE_ENTRY(15b-linux_gateway_page, 31b-linux_gateway_page) 1263 + ASM_EXCEPTIONTABLE_ENTRY(16b-linux_gateway_page, 31b-linux_gateway_page) 894 1264 895 1265 /* Make sure nothing else is placed on this page */ 896 1266 .align PAGE_SIZE ··· 1291 899 ENTRY(lws_table) 1292 900 LWS_ENTRY(compare_and_swap32) /* 0 - ELF32 Atomic 32bit CAS */ 1293 901 LWS_ENTRY(compare_and_swap64) /* 1 - ELF64 Atomic 32bit CAS */ 1294 - LWS_ENTRY(compare_and_swap_2) /* 2 - ELF32 Atomic 64bit CAS */ 902 + LWS_ENTRY(compare_and_swap_2) /* 2 - Atomic 64bit CAS */ 903 + LWS_ENTRY(atomic_xchg) /* 3 - Atomic Exchange */ 904 + LWS_ENTRY(atomic_store) /* 4 - Atomic Store */ 1295 905 END(lws_table) 1296 906 /* End of lws table */ 1297 907
+16 -2
arch/parisc/kernel/toc.c
··· 9 9 10 10 #include <asm/pdc.h> 11 11 #include <asm/pdc_chassis.h> 12 + #include <asm/ldcw.h> 12 13 13 - unsigned int __aligned(16) toc_lock = 1; 14 + static unsigned int __aligned(16) toc_lock = 1; 15 + DEFINE_PER_CPU_PAGE_ALIGNED(char [16384], toc_stack); 14 16 15 17 static void toc20_to_pt_regs(struct pt_regs *regs, struct pdc_toc_pim_20 *toc) 16 18 { ··· 65 63 struct pdc_toc_pim_20 pim_data20; 66 64 struct pdc_toc_pim_11 pim_data11; 67 65 68 - nmi_enter(); 66 + /* verify we wrote regs to the correct stack */ 67 + BUG_ON(regs != (struct pt_regs *)&per_cpu(toc_stack, raw_smp_processor_id())); 69 68 70 69 if (boot_cpu_data.cpu_type >= pcxu) { 71 70 if (pdc_pim_toc20(&pim_data20)) ··· 79 76 } 80 77 81 78 #ifdef CONFIG_KGDB 79 + nmi_enter(); 80 + 82 81 if (atomic_read(&kgdb_active) != -1) 83 82 kgdb_nmicallback(raw_smp_processor_id(), regs); 84 83 kgdb_handle_exception(9, SIGTRAP, 0, regs); 85 84 #endif 85 + 86 + /* serialize output, otherwise all CPUs write backtrace at once */ 87 + while (__ldcw(&toc_lock) == 0) 88 + ; /* wait */ 86 89 show_regs(regs); 90 + toc_lock = 1; /* release lock for next CPU */ 91 + 92 + if (raw_smp_processor_id() != 0) 93 + while (1) ; /* all but monarch CPU will wait endless. */ 87 94 88 95 /* give other CPUs time to show their backtrace */ 89 96 mdelay(2000); 97 + 90 98 machine_restart("TOC"); 91 99 92 100 /* should never reach this */
+10 -23
arch/parisc/kernel/toc_asm.S
··· 5 5 .level 1.1 6 6 7 7 #include <asm/assembly.h> 8 - #include <asm/psw.h> 9 8 #include <linux/threads.h> 10 9 #include <linux/linkage.h> 11 10 12 11 .text 13 12 .import toc_intr,code 14 - .import toc_lock,data 13 + .import toc_stack,data 15 14 .align 16 16 15 ENTRY_CFI(toc_handler) 17 - /* 18 - * synchronize CPUs and obtain offset 19 - * for stack setup. 20 - */ 21 - load32 PA(toc_lock),%r1 22 - 0: ldcw,co 0(%r1),%r2 23 - cmpib,= 0,%r2,0b 24 - nop 25 - addi 1,%r2,%r4 26 - stw %r4,0(%r1) 27 - addi -1,%r2,%r4 28 - 29 16 load32 PA(toc_stack),%sp 30 - /* 31 - * deposit CPU number into stack address, 32 - * so every CPU will have its own stack. 33 - */ 34 - SHLREG %r4,14,%r4 17 + 18 + #ifdef CONFIG_SMP 19 + /* get per-cpu toc_stack address. */ 20 + mfctl %cr30, %r1 21 + tophys %r1,%r2 /* task_struct */ 22 + LDREG TASK_TI_CPU(%r2),%r4 /* cpu */ 23 + load32 PA(__per_cpu_offset),%r1 24 + LDREGX %r4(%r1),%r4 35 25 add %r4,%sp,%sp 26 + #endif 36 27 37 28 /* 38 29 * setup pt_regs on stack and save the ··· 73 82 */ 74 83 SYM_DATA(toc_handler_csum, .long 0) 75 84 SYM_DATA(toc_handler_size, .long . - toc_handler) 76 - 77 - __PAGE_ALIGNED_BSS 78 - .align 64 79 - SYM_DATA(toc_stack, .block 16384*NR_CPUS)
+1 -1
arch/parisc/kernel/traps.c
··· 785 785 * unless pagefault_disable() was called before. 786 786 */ 787 787 788 - if (fault_space == 0 && !faulthandler_disabled()) 788 + if (faulthandler_disabled() || fault_space == 0) 789 789 { 790 790 /* Clean up and return if in exception table. */ 791 791 if (fixup_exception(regs))
+13 -10
arch/parisc/mm/fault.c
··· 148 148 * Fix up get_user() and put_user(). 149 149 * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() sets the least-significant 150 150 * bit in the relative address of the fixup routine to indicate 151 - * that %r8 should be loaded with -EFAULT to report a userspace 152 - * access error. 151 + * that gr[ASM_EXCEPTIONTABLE_REG] should be loaded with 152 + * -EFAULT to report a userspace access error. 153 153 */ 154 154 if (fix->fixup & 1) { 155 - regs->gr[8] = -EFAULT; 155 + regs->gr[ASM_EXCEPTIONTABLE_REG] = -EFAULT; 156 156 157 157 /* zero target register for get_user() */ 158 158 if (parisc_acctyp(0, regs->iir) == VM_READ) { ··· 266 266 unsigned long acc_type; 267 267 vm_fault_t fault = 0; 268 268 unsigned int flags; 269 - 270 - if (faulthandler_disabled()) 271 - goto no_context; 269 + char *msg; 272 270 273 271 tsk = current; 274 272 mm = tsk->mm; 275 - if (!mm) 273 + if (!mm) { 274 + msg = "Page fault: no context"; 276 275 goto no_context; 276 + } 277 277 278 278 flags = FAULT_FLAG_DEFAULT; 279 279 if (user_mode(regs)) ··· 409 409 force_sig_fault(signo, si_code, (void __user *) address); 410 410 return; 411 411 } 412 + msg = "Page fault: bad address"; 412 413 413 414 no_context: 414 415 ··· 417 416 return; 418 417 } 419 418 420 - parisc_terminate("Bad Address (null pointer deref?)", regs, code, address); 419 + parisc_terminate(msg, regs, code, address); 421 420 422 - out_of_memory: 421 + out_of_memory: 423 422 mmap_read_unlock(mm); 424 - if (!user_mode(regs)) 423 + if (!user_mode(regs)) { 424 + msg = "Page fault: out of memory"; 425 425 goto no_context; 426 + } 426 427 pagefault_out_of_memory(); 427 428 }
+2 -1
drivers/parisc/pdc_stable.c
··· 482 482 &paths_attr_layer.attr, 483 483 NULL, 484 484 }; 485 + ATTRIBUTE_GROUPS(paths_subsys); 485 486 486 487 /* Specific kobject type for our PDC paths */ 487 488 static struct kobj_type ktype_pdcspath = { 488 489 .sysfs_ops = &pdcspath_attr_ops, 489 - .default_attrs = paths_subsys_attrs, 490 + .default_groups = paths_subsys_groups, 490 491 }; 491 492 492 493 /* We hard define the 4 types of path we expect to find */
+7 -3
include/asm-generic/sections.h
··· 199 199 * @addr: address to check 200 200 * 201 201 * Returns: true if the address is located in the kernel range, false otherwise. 202 - * Note: an internal helper, only check the range of _stext to _end. 202 + * Note: an internal helper, check the range of _stext to _end, 203 + * and range from __init_begin to __init_end, which can be outside 204 + * of the _stext to _end range. 203 205 */ 204 206 static inline bool __is_kernel(unsigned long addr) 205 207 { 206 - return addr >= (unsigned long)_stext && 207 - addr < (unsigned long)_end; 208 + return ((addr >= (unsigned long)_stext && 209 + addr < (unsigned long)_end) || 210 + (addr >= (unsigned long)__init_begin && 211 + addr < (unsigned long)__init_end)); 208 212 } 209 213 210 214 #endif /* _ASM_GENERIC_SECTIONS_H_ */
+5
scripts/remove-stale-files
··· 33 33 do 34 34 rm -f arch/mips/boot/compressed/${f} 35 35 done 36 + 37 + for f in firmware.c real2.S 38 + do 39 + rm -f arch/parisc/boot/compressed/${f} 40 + done 36 41 fi