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-linus' of git://git.armlinux.org.uk/~rmk/linux-arm

Pull ARM development updates from Russell King:

- Rename "mod_init" and "mod_exit" so that initcall debug output is
actually useful (Randy Dunlap)

- Update maintainers entries for linux-arm-kernel to indicate it is
moderated for non-subscribers (Randy Dunlap)

- Move install rules to arch/arm/Makefile (Masahiro Yamada)

- Drop unnecessary ARCH_NR_GPIOS definition (Linus Walleij)

- Don't warn about atags_to_fdt() stack size (David Heidelberg)

- Speed up unaligned copy_{from,to}_kernel_nofault (Arnd Bergmann)

- Get rid of set_fs() usage (Arnd Bergmann)

- Remove checks for GCC prior to v4.6 (Geert Uytterhoeven)

* tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm:
ARM: 9118/1: div64: Remove always-true __div64_const32_is_OK() duplicate
ARM: 9117/1: asm-generic: div64: Remove always-true __div64_const32_is_OK()
ARM: 9116/1: unified: Remove check for gcc < 4
ARM: 9110/1: oabi-compat: fix oabi epoll sparse warning
ARM: 9113/1: uaccess: remove set_fs() implementation
ARM: 9112/1: uaccess: add __{get,put}_kernel_nofault
ARM: 9111/1: oabi-compat: rework fcntl64() emulation
ARM: 9114/1: oabi-compat: rework sys_semtimedop emulation
ARM: 9108/1: oabi-compat: rework epoll_wait/epoll_pwait emulation
ARM: 9107/1: syscall: always store thread_info->abi_syscall
ARM: 9109/1: oabi-compat: add epoll_pwait handler
ARM: 9106/1: traps: use get_kernel_nofault instead of set_fs()
ARM: 9115/1: mm/maccess: fix unaligned copy_{from,to}_kernel_nofault
ARM: 9105/1: atags_to_fdt: don't warn about stack size
ARM: 9103/1: Drop ARCH_NR_GPIOS definition
ARM: 9102/1: move theinstall rules to arch/arm/Makefile
ARM: 9100/1: MAINTAINERS: mark all linux-arm-kernel@infradead list as moderated
ARM: 9099/1: crypto: rename 'mod_init' & 'mod_exit' functions to be module-specific

+399 -371
+28 -28
MAINTAINERS
··· 2334 2334 2335 2335 ARM/PALM TREO SUPPORT 2336 2336 M: Tomas Cech <sleep_walker@suse.com> 2337 - L: linux-arm-kernel@lists.infradead.org 2337 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 2338 2338 S: Maintained 2339 2339 W: http://hackndev.com 2340 2340 F: arch/arm/mach-pxa/palmtreo.* 2341 2341 2342 2342 ARM/PALMTX,PALMT5,PALMLD,PALMTE2,PALMTC SUPPORT 2343 2343 M: Marek Vasut <marek.vasut@gmail.com> 2344 - L: linux-arm-kernel@lists.infradead.org 2344 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 2345 2345 S: Maintained 2346 2346 W: http://hackndev.com 2347 2347 F: arch/arm/mach-pxa/include/mach/palmld.h ··· 2355 2355 2356 2356 ARM/PALMZ72 SUPPORT 2357 2357 M: Sergey Lapin <slapin@ossfans.org> 2358 - L: linux-arm-kernel@lists.infradead.org 2358 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 2359 2359 S: Maintained 2360 2360 W: http://hackndev.com 2361 2361 F: arch/arm/mach-pxa/palmz72.* ··· 2525 2525 2526 2526 ARM/SAMSUNG S5P SERIES 2D GRAPHICS ACCELERATION (G2D) SUPPORT 2527 2527 M: Andrzej Hajda <a.hajda@samsung.com> 2528 - L: linux-arm-kernel@lists.infradead.org 2528 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 2529 2529 L: linux-media@vger.kernel.org 2530 2530 S: Maintained 2531 2531 F: drivers/media/platform/s5p-g2d/ ··· 2542 2542 M: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com> 2543 2543 M: Jacek Anaszewski <jacek.anaszewski@gmail.com> 2544 2544 M: Sylwester Nawrocki <s.nawrocki@samsung.com> 2545 - L: linux-arm-kernel@lists.infradead.org 2545 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 2546 2546 L: linux-media@vger.kernel.org 2547 2547 S: Maintained 2548 2548 F: drivers/media/platform/s5p-jpeg/ 2549 2549 2550 2550 ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT 2551 2551 M: Andrzej Hajda <a.hajda@samsung.com> 2552 - L: linux-arm-kernel@lists.infradead.org 2552 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 2553 2553 L: linux-media@vger.kernel.org 2554 2554 S: Maintained 2555 2555 F: drivers/media/platform/s5p-mfc/ ··· 3568 3568 M: Hauke Mehrtens <hauke@hauke-m.de> 3569 3569 M: Rafał Miłecki <zajec5@gmail.com> 3570 3570 M: bcm-kernel-feedback-list@broadcom.com 3571 - L: linux-arm-kernel@lists.infradead.org 3571 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 3572 3572 S: Maintained 3573 3573 F: arch/arm/boot/dts/bcm470* 3574 3574 F: arch/arm/boot/dts/bcm5301* ··· 3578 3578 BROADCOM BCM53573 ARM ARCHITECTURE 3579 3579 M: Rafał Miłecki <rafal@milecki.pl> 3580 3580 L: bcm-kernel-feedback-list@broadcom.com 3581 - L: linux-arm-kernel@lists.infradead.org 3581 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 3582 3582 S: Maintained 3583 3583 F: arch/arm/boot/dts/bcm47189* 3584 3584 F: arch/arm/boot/dts/bcm53573* ··· 4874 4874 M: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> 4875 4875 M: Daniel Lezcano <daniel.lezcano@linaro.org> 4876 4876 L: linux-pm@vger.kernel.org 4877 - L: linux-arm-kernel@lists.infradead.org 4877 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 4878 4878 S: Maintained 4879 4879 T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git 4880 4880 F: drivers/cpuidle/cpuidle-big_little.c ··· 4894 4894 M: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> 4895 4895 M: Sudeep Holla <sudeep.holla@arm.com> 4896 4896 L: linux-pm@vger.kernel.org 4897 - L: linux-arm-kernel@lists.infradead.org 4897 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 4898 4898 S: Supported 4899 4899 F: drivers/cpuidle/cpuidle-psci.c 4900 4900 4901 4901 CPUIDLE DRIVER - ARM PSCI PM DOMAIN 4902 4902 M: Ulf Hansson <ulf.hansson@linaro.org> 4903 4903 L: linux-pm@vger.kernel.org 4904 - L: linux-arm-kernel@lists.infradead.org 4904 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 4905 4905 S: Supported 4906 4906 F: drivers/cpuidle/cpuidle-psci.h 4907 4907 F: drivers/cpuidle/cpuidle-psci-domain.c ··· 7272 7272 7273 7273 FIRMWARE FRAMEWORK FOR ARMV8-A 7274 7274 M: Sudeep Holla <sudeep.holla@arm.com> 7275 - L: linux-arm-kernel@lists.infradead.org 7275 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 7276 7276 S: Maintained 7277 7277 F: drivers/firmware/arm_ffa/ 7278 7278 F: include/linux/arm_ffa.h ··· 7451 7451 7452 7452 FREESCALE IMX DDR PMU DRIVER 7453 7453 M: Frank Li <Frank.li@nxp.com> 7454 - L: linux-arm-kernel@lists.infradead.org 7454 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 7455 7455 S: Maintained 7456 7456 F: Documentation/admin-guide/perf/imx-ddr.rst 7457 7457 F: Documentation/devicetree/bindings/perf/fsl-imx-ddr.yaml ··· 7543 7543 FREESCALE SOC DRIVERS 7544 7544 M: Li Yang <leoyang.li@nxp.com> 7545 7545 L: linuxppc-dev@lists.ozlabs.org 7546 - L: linux-arm-kernel@lists.infradead.org 7546 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 7547 7547 S: Maintained 7548 7548 F: Documentation/devicetree/bindings/misc/fsl,dpaa2-console.yaml 7549 7549 F: Documentation/devicetree/bindings/soc/fsl/ ··· 11191 11191 11192 11192 MARVELL MACCHIATOBIN SUPPORT 11193 11193 M: Russell King <linux@armlinux.org.uk> 11194 - L: linux-arm-kernel@lists.infradead.org 11194 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 11195 11195 S: Maintained 11196 11196 F: arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts 11197 11197 ··· 14272 14272 PCI DRIVER FOR APPLIEDMICRO XGENE 14273 14273 M: Toan Le <toan@os.amperecomputing.com> 14274 14274 L: linux-pci@vger.kernel.org 14275 - L: linux-arm-kernel@lists.infradead.org 14275 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 14276 14276 S: Maintained 14277 14277 F: Documentation/devicetree/bindings/pci/xgene-pci.txt 14278 14278 F: drivers/pci/controller/pci-xgene.c ··· 14280 14280 PCI DRIVER FOR ARM VERSATILE PLATFORM 14281 14281 M: Rob Herring <robh@kernel.org> 14282 14282 L: linux-pci@vger.kernel.org 14283 - L: linux-arm-kernel@lists.infradead.org 14283 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 14284 14284 S: Maintained 14285 14285 F: Documentation/devicetree/bindings/pci/versatile.yaml 14286 14286 F: drivers/pci/controller/pci-versatile.c ··· 14288 14288 PCI DRIVER FOR ARMADA 8K 14289 14289 M: Thomas Petazzoni <thomas.petazzoni@bootlin.com> 14290 14290 L: linux-pci@vger.kernel.org 14291 - L: linux-arm-kernel@lists.infradead.org 14291 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 14292 14292 S: Maintained 14293 14293 F: Documentation/devicetree/bindings/pci/pci-armada8k.txt 14294 14294 F: drivers/pci/controller/dwc/pcie-armada8k.c ··· 14306 14306 M: Roy Zang <roy.zang@nxp.com> 14307 14307 L: linuxppc-dev@lists.ozlabs.org 14308 14308 L: linux-pci@vger.kernel.org 14309 - L: linux-arm-kernel@lists.infradead.org 14309 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 14310 14310 S: Maintained 14311 14311 F: drivers/pci/controller/dwc/*layerscape* 14312 14312 ··· 14386 14386 PCI DRIVER FOR NXP LAYERSCAPE GEN4 CONTROLLER 14387 14387 M: Hou Zhiqiang <Zhiqiang.Hou@nxp.com> 14388 14388 L: linux-pci@vger.kernel.org 14389 - L: linux-arm-kernel@lists.infradead.org 14389 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 14390 14390 S: Maintained 14391 14391 F: Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt 14392 14392 F: drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c ··· 14421 14421 M: Kishon Vijay Abraham I <kishon@ti.com> 14422 14422 L: linux-omap@vger.kernel.org 14423 14423 L: linux-pci@vger.kernel.org 14424 - L: linux-arm-kernel@lists.infradead.org 14424 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 14425 14425 S: Supported 14426 14426 F: Documentation/devicetree/bindings/pci/ti-pci.txt 14427 14427 F: drivers/pci/controller/cadence/pci-j721e.c ··· 14477 14477 PCI MSI DRIVER FOR APPLIEDMICRO XGENE 14478 14478 M: Toan Le <toan@os.amperecomputing.com> 14479 14479 L: linux-pci@vger.kernel.org 14480 - L: linux-arm-kernel@lists.infradead.org 14480 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 14481 14481 S: Maintained 14482 14482 F: Documentation/devicetree/bindings/pci/xgene-pci-msi.txt 14483 14483 F: drivers/pci/controller/pci-xgene-msi.c ··· 14994 14994 POWER STATE COORDINATION INTERFACE (PSCI) 14995 14995 M: Mark Rutland <mark.rutland@arm.com> 14996 14996 M: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> 14997 - L: linux-arm-kernel@lists.infradead.org 14997 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 14998 14998 S: Maintained 14999 14999 F: drivers/firmware/psci/ 15000 15000 F: include/linux/psci.h ··· 15519 15519 15520 15520 QUALCOMM HIDMA DRIVER 15521 15521 M: Sinan Kaya <okaya@kernel.org> 15522 - L: linux-arm-kernel@lists.infradead.org 15522 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 15523 15523 L: linux-arm-msm@vger.kernel.org 15524 15524 L: dmaengine@vger.kernel.org 15525 15525 S: Supported ··· 17233 17233 M: Mark Rutland <mark.rutland@arm.com> 17234 17234 M: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> 17235 17235 M: Sudeep Holla <sudeep.holla@arm.com> 17236 - L: linux-arm-kernel@lists.infradead.org 17236 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 17237 17237 S: Maintained 17238 17238 F: drivers/firmware/smccc/ 17239 17239 F: include/linux/arm-smccc.h ··· 17350 17350 17351 17351 SOFTWARE DELEGATED EXCEPTION INTERFACE (SDEI) 17352 17352 M: James Morse <james.morse@arm.com> 17353 - L: linux-arm-kernel@lists.infradead.org 17353 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 17354 17354 S: Maintained 17355 17355 F: Documentation/devicetree/bindings/arm/firmware/sdei.txt 17356 17356 F: drivers/firmware/arm_sdei.c ··· 18137 18137 SYSTEM CONTROL & POWER/MANAGEMENT INTERFACE (SCPI/SCMI) Message Protocol drivers 18138 18138 M: Sudeep Holla <sudeep.holla@arm.com> 18139 18139 R: Cristian Marussi <cristian.marussi@arm.com> 18140 - L: linux-arm-kernel@lists.infradead.org 18140 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 18141 18141 S: Maintained 18142 18142 F: Documentation/devicetree/bindings/firmware/arm,sc[mp]i.yaml 18143 18143 F: drivers/clk/clk-sc[mp]i.c ··· 18510 18510 M: Nishanth Menon <nm@ti.com> 18511 18511 M: Tero Kristo <kristo@kernel.org> 18512 18512 M: Santosh Shilimkar <ssantosh@kernel.org> 18513 - L: linux-arm-kernel@lists.infradead.org 18513 + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 18514 18514 S: Maintained 18515 18515 F: Documentation/devicetree/bindings/arm/keystone/ti,k3-sci-common.yaml 18516 18516 F: Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
-1
arch/arm/Kconfig
··· 124 124 select PCI_SYSCALL if PCI 125 125 select PERF_USE_VMALLOC 126 126 select RTC_LIB 127 - select SET_FS 128 127 select SYS_SUPPORTS_APM_EMULATION 129 128 select TRACE_IRQFLAGS_SUPPORT if !CPU_V7M 130 129 # Above selects are sorted alphabetically; please add new ones
+2 -1
arch/arm/Makefile
··· 308 308 @$(kecho) ' Kernel: $(boot)/$@ is ready' 309 309 310 310 $(INSTALL_TARGETS): 311 - $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ 311 + $(CONFIG_SHELL) $(srctree)/$(boot)/install.sh "$(KERNELRELEASE)" \ 312 + $(boot)/$(patsubst %install,%Image,$@) System.map "$(INSTALL_PATH)" 312 313 313 314 PHONY += vdso_install 314 315 vdso_install:
+1 -13
arch/arm/boot/Makefile
··· 96 96 $(obj)/bootpImage: $(obj)/bootp/bootp FORCE 97 97 $(call if_changed,objcopy) 98 98 99 - PHONY += initrd install zinstall uinstall 99 + PHONY += initrd 100 100 initrd: 101 101 @test "$(INITRD_PHYS)" != "" || \ 102 102 (echo This machine does not support INITRD; exit -1) 103 103 @test "$(INITRD)" != "" || \ 104 104 (echo You must specify INITRD; exit -1) 105 - 106 - install: 107 - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ 108 - $(obj)/Image System.map "$(INSTALL_PATH)" 109 - 110 - zinstall: 111 - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ 112 - $(obj)/zImage System.map "$(INSTALL_PATH)" 113 - 114 - uinstall: 115 - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ 116 - $(obj)/uImage System.map "$(INSTALL_PATH)" 117 105 118 106 subdir- := bootp compressed dts
+2
arch/arm/boot/compressed/Makefile
··· 85 85 libfdt_objs := fdt_rw.o fdt_ro.o fdt_wip.o fdt.o 86 86 87 87 ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y) 88 + CFLAGS_REMOVE_atags_to_fdt.o += -Wframe-larger-than=${CONFIG_FRAME_WARN} 89 + CFLAGS_atags_to_fdt.o += -Wframe-larger-than=1280 88 90 OBJS += $(libfdt_objs) atags_to_fdt.o 89 91 endif 90 92 ifeq ($(CONFIG_USE_OF),y)
-11
arch/arm/include/asm/div64.h
··· 52 52 53 53 #else 54 54 55 - /* 56 - * gcc versions earlier than 4.0 are simply too problematic for the 57 - * __div64_const32() code in asm-generic/div64.h. First there is 58 - * gcc PR 15089 that tend to trig on more complex constructs, spurious 59 - * .global __udivsi3 are inserted even if none of those symbols are 60 - * referenced in the generated code, and those gcc versions are not able 61 - * to do constant propagation on long long values anyway. 62 - */ 63 - 64 - #define __div64_const32_is_OK (__GNUC__ >= 4) 65 - 66 55 static inline uint64_t __arch_xprod_64(uint64_t m, uint64_t n, bool bias) 67 56 { 68 57 unsigned long long res;
-4
arch/arm/include/asm/gpio.h
··· 2 2 #ifndef _ARCH_ARM_GPIO_H 3 3 #define _ARCH_ARM_GPIO_H 4 4 5 - #if CONFIG_ARCH_NR_GPIO > 0 6 - #define ARCH_NR_GPIOS CONFIG_ARCH_NR_GPIO 7 - #endif 8 - 9 5 /* Note: this may rely upon the value of ARCH_NR_GPIOS set in mach/gpio.h */ 10 6 #include <asm-generic/gpio.h> 11 7
-1
arch/arm/include/asm/ptrace.h
··· 19 19 struct svc_pt_regs { 20 20 struct pt_regs regs; 21 21 u32 dacr; 22 - u32 addr_limit; 23 22 }; 24 23 25 24 #define to_svc_pt_regs(r) container_of(r, struct svc_pt_regs, regs)
+15 -1
arch/arm/include/asm/syscall.h
··· 22 22 static inline int syscall_get_nr(struct task_struct *task, 23 23 struct pt_regs *regs) 24 24 { 25 - return task_thread_info(task)->syscall; 25 + if (IS_ENABLED(CONFIG_AEABI) && !IS_ENABLED(CONFIG_OABI_COMPAT)) 26 + return task_thread_info(task)->abi_syscall; 27 + 28 + return task_thread_info(task)->abi_syscall & __NR_SYSCALL_MASK; 29 + } 30 + 31 + static inline bool __in_oabi_syscall(struct task_struct *task) 32 + { 33 + return IS_ENABLED(CONFIG_OABI_COMPAT) && 34 + (task_thread_info(task)->abi_syscall & __NR_OABI_SYSCALL_BASE); 35 + } 36 + 37 + static inline bool in_oabi_syscall(void) 38 + { 39 + return __in_oabi_syscall(current); 26 40 } 27 41 28 42 static inline void syscall_rollback(struct task_struct *task,
+1 -5
arch/arm/include/asm/thread_info.h
··· 31 31 32 32 #include <asm/types.h> 33 33 34 - typedef unsigned long mm_segment_t; 35 - 36 34 struct cpu_context_save { 37 35 __u32 r4; 38 36 __u32 r5; ··· 52 54 struct thread_info { 53 55 unsigned long flags; /* low level flags */ 54 56 int preempt_count; /* 0 => preemptable, <0 => bug */ 55 - mm_segment_t addr_limit; /* address limit */ 56 57 struct task_struct *task; /* main task structure */ 57 58 __u32 cpu; /* cpu */ 58 59 __u32 cpu_domain; /* cpu domain */ ··· 59 62 unsigned long stack_canary; 60 63 #endif 61 64 struct cpu_context_save cpu_context; /* cpu context */ 62 - __u32 syscall; /* syscall number */ 65 + __u32 abi_syscall; /* ABI type and syscall nr */ 63 66 __u8 used_cp[16]; /* thread used copro */ 64 67 unsigned long tp_value[2]; /* TLS registers */ 65 68 union fp_state fpstate __attribute__((aligned(8))); ··· 74 77 .task = &tsk, \ 75 78 .flags = 0, \ 76 79 .preempt_count = INIT_PREEMPT_COUNT, \ 77 - .addr_limit = KERNEL_DS, \ 78 80 } 79 81 80 82 /*
-6
arch/arm/include/asm/uaccess-asm.h
··· 84 84 * if \disable is set. 85 85 */ 86 86 .macro uaccess_entry, tsk, tmp0, tmp1, tmp2, disable 87 - ldr \tmp1, [\tsk, #TI_ADDR_LIMIT] 88 - ldr \tmp2, =TASK_SIZE 89 - str \tmp2, [\tsk, #TI_ADDR_LIMIT] 90 87 DACR( mrc p15, 0, \tmp0, c3, c0, 0) 91 88 DACR( str \tmp0, [sp, #SVC_DACR]) 92 - str \tmp1, [sp, #SVC_ADDR_LIMIT] 93 89 .if \disable && IS_ENABLED(CONFIG_CPU_SW_DOMAIN_PAN) 94 90 /* kernel=client, user=no access */ 95 91 mov \tmp2, #DACR_UACCESS_DISABLE ··· 102 106 103 107 /* Restore the user access state previously saved by uaccess_entry */ 104 108 .macro uaccess_exit, tsk, tmp0, tmp1 105 - ldr \tmp1, [sp, #SVC_ADDR_LIMIT] 106 109 DACR( ldr \tmp0, [sp, #SVC_DACR]) 107 - str \tmp1, [\tsk, #TI_ADDR_LIMIT] 108 110 DACR( mcr p15, 0, \tmp0, c3, c0, 0) 109 111 .endm 110 112
+87 -82
arch/arm/include/asm/uaccess.h
··· 52 52 extern int __get_user_bad(void); 53 53 extern int __put_user_bad(void); 54 54 55 - /* 56 - * Note that this is actually 0x1,0000,0000 57 - */ 58 - #define KERNEL_DS 0x00000000 59 - 60 55 #ifdef CONFIG_MMU 61 - 62 - #define USER_DS TASK_SIZE 63 - #define get_fs() (current_thread_info()->addr_limit) 64 - 65 - static inline void set_fs(mm_segment_t fs) 66 - { 67 - current_thread_info()->addr_limit = fs; 68 - 69 - /* 70 - * Prevent a mispredicted conditional call to set_fs from forwarding 71 - * the wrong address limit to access_ok under speculation. 72 - */ 73 - dsb(nsh); 74 - isb(); 75 - 76 - modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER); 77 - } 78 - 79 - #define uaccess_kernel() (get_fs() == KERNEL_DS) 80 56 81 57 /* 82 58 * We use 33-bit arithmetic here. Success returns zero, failure returns ··· 65 89 __asm__(".syntax unified\n" \ 66 90 "adds %1, %2, %3; sbcscc %1, %1, %0; movcc %0, #0" \ 67 91 : "=&r" (flag), "=&r" (roksum) \ 68 - : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \ 92 + : "r" (addr), "Ir" (size), "0" (TASK_SIZE) \ 69 93 : "cc"); \ 70 94 flag; }) 71 95 ··· 96 120 " subshs %1, %1, %2\n" 97 121 " movlo %0, #0\n" 98 122 : "+r" (safe_ptr), "=&r" (tmp) 99 - : "r" (size), "r" (current_thread_info()->addr_limit) 123 + : "r" (size), "r" (TASK_SIZE) 100 124 : "cc"); 101 125 102 126 csdb(); ··· 170 194 171 195 #define __get_user_check(x, p) \ 172 196 ({ \ 173 - unsigned long __limit = current_thread_info()->addr_limit - 1; \ 197 + unsigned long __limit = TASK_SIZE - 1; \ 174 198 register typeof(*(p)) __user *__p asm("r0") = (p); \ 175 199 register __inttype(x) __r2 asm("r2"); \ 176 200 register unsigned long __l asm("r1") = __limit; \ ··· 221 245 222 246 #define __put_user_check(__pu_val, __ptr, __err, __s) \ 223 247 ({ \ 224 - unsigned long __limit = current_thread_info()->addr_limit - 1; \ 248 + unsigned long __limit = TASK_SIZE - 1; \ 225 249 register typeof(__pu_val) __r2 asm("r2") = __pu_val; \ 226 250 register const void __user *__p asm("r0") = __ptr; \ 227 251 register unsigned long __l asm("r1") = __limit; \ ··· 238 262 239 263 #else /* CONFIG_MMU */ 240 264 241 - /* 242 - * uClinux has only one addr space, so has simplified address limits. 243 - */ 244 - #define USER_DS KERNEL_DS 245 - 246 - #define uaccess_kernel() (true) 247 265 #define __addr_ok(addr) ((void)(addr), 1) 248 266 #define __range_ok(addr, size) ((void)(addr), 0) 249 - #define get_fs() (KERNEL_DS) 250 - 251 - static inline void set_fs(mm_segment_t fs) 252 - { 253 - } 254 267 255 268 #define get_user(x, p) __get_user(x, p) 256 269 #define __put_user_check __put_user_nocheck ··· 247 282 #endif /* CONFIG_MMU */ 248 283 249 284 #define access_ok(addr, size) (__range_ok(addr, size) == 0) 250 - 251 - #define user_addr_max() \ 252 - (uaccess_kernel() ? ~0UL : get_fs()) 253 285 254 286 #ifdef CONFIG_CPU_SPECTRE 255 287 /* ··· 270 308 #define __get_user(x, ptr) \ 271 309 ({ \ 272 310 long __gu_err = 0; \ 273 - __get_user_err((x), (ptr), __gu_err); \ 311 + __get_user_err((x), (ptr), __gu_err, TUSER()); \ 274 312 __gu_err; \ 275 313 }) 276 314 277 - #define __get_user_err(x, ptr, err) \ 315 + #define __get_user_err(x, ptr, err, __t) \ 278 316 do { \ 279 317 unsigned long __gu_addr = (unsigned long)(ptr); \ 280 318 unsigned long __gu_val; \ ··· 283 321 might_fault(); \ 284 322 __ua_flags = uaccess_save_and_enable(); \ 285 323 switch (sizeof(*(ptr))) { \ 286 - case 1: __get_user_asm_byte(__gu_val, __gu_addr, err); break; \ 287 - case 2: __get_user_asm_half(__gu_val, __gu_addr, err); break; \ 288 - case 4: __get_user_asm_word(__gu_val, __gu_addr, err); break; \ 324 + case 1: __get_user_asm_byte(__gu_val, __gu_addr, err, __t); break; \ 325 + case 2: __get_user_asm_half(__gu_val, __gu_addr, err, __t); break; \ 326 + case 4: __get_user_asm_word(__gu_val, __gu_addr, err, __t); break; \ 289 327 default: (__gu_val) = __get_user_bad(); \ 290 328 } \ 291 329 uaccess_restore(__ua_flags); \ 292 330 (x) = (__typeof__(*(ptr)))__gu_val; \ 293 331 } while (0) 332 + #endif 294 333 295 334 #define __get_user_asm(x, addr, err, instr) \ 296 335 __asm__ __volatile__( \ 297 - "1: " TUSER(instr) " %1, [%2], #0\n" \ 336 + "1: " instr " %1, [%2], #0\n" \ 298 337 "2:\n" \ 299 338 " .pushsection .text.fixup,\"ax\"\n" \ 300 339 " .align 2\n" \ ··· 311 348 : "r" (addr), "i" (-EFAULT) \ 312 349 : "cc") 313 350 314 - #define __get_user_asm_byte(x, addr, err) \ 315 - __get_user_asm(x, addr, err, ldrb) 351 + #define __get_user_asm_byte(x, addr, err, __t) \ 352 + __get_user_asm(x, addr, err, "ldrb" __t) 316 353 317 354 #if __LINUX_ARM_ARCH__ >= 6 318 355 319 - #define __get_user_asm_half(x, addr, err) \ 320 - __get_user_asm(x, addr, err, ldrh) 356 + #define __get_user_asm_half(x, addr, err, __t) \ 357 + __get_user_asm(x, addr, err, "ldrh" __t) 321 358 322 359 #else 323 360 324 361 #ifndef __ARMEB__ 325 - #define __get_user_asm_half(x, __gu_addr, err) \ 362 + #define __get_user_asm_half(x, __gu_addr, err, __t) \ 326 363 ({ \ 327 364 unsigned long __b1, __b2; \ 328 - __get_user_asm_byte(__b1, __gu_addr, err); \ 329 - __get_user_asm_byte(__b2, __gu_addr + 1, err); \ 365 + __get_user_asm_byte(__b1, __gu_addr, err, __t); \ 366 + __get_user_asm_byte(__b2, __gu_addr + 1, err, __t); \ 330 367 (x) = __b1 | (__b2 << 8); \ 331 368 }) 332 369 #else 333 - #define __get_user_asm_half(x, __gu_addr, err) \ 370 + #define __get_user_asm_half(x, __gu_addr, err, __t) \ 334 371 ({ \ 335 372 unsigned long __b1, __b2; \ 336 - __get_user_asm_byte(__b1, __gu_addr, err); \ 337 - __get_user_asm_byte(__b2, __gu_addr + 1, err); \ 373 + __get_user_asm_byte(__b1, __gu_addr, err, __t); \ 374 + __get_user_asm_byte(__b2, __gu_addr + 1, err, __t); \ 338 375 (x) = (__b1 << 8) | __b2; \ 339 376 }) 340 377 #endif 341 378 342 379 #endif /* __LINUX_ARM_ARCH__ >= 6 */ 343 380 344 - #define __get_user_asm_word(x, addr, err) \ 345 - __get_user_asm(x, addr, err, ldr) 346 - #endif 347 - 381 + #define __get_user_asm_word(x, addr, err, __t) \ 382 + __get_user_asm(x, addr, err, "ldr" __t) 348 383 349 384 #define __put_user_switch(x, ptr, __err, __fn) \ 350 385 do { \ ··· 386 425 #define __put_user_nocheck(x, __pu_ptr, __err, __size) \ 387 426 do { \ 388 427 unsigned long __pu_addr = (unsigned long)__pu_ptr; \ 389 - __put_user_nocheck_##__size(x, __pu_addr, __err); \ 428 + __put_user_nocheck_##__size(x, __pu_addr, __err, TUSER());\ 390 429 } while (0) 391 430 392 431 #define __put_user_nocheck_1 __put_user_asm_byte ··· 394 433 #define __put_user_nocheck_4 __put_user_asm_word 395 434 #define __put_user_nocheck_8 __put_user_asm_dword 396 435 436 + #endif /* !CONFIG_CPU_SPECTRE */ 437 + 397 438 #define __put_user_asm(x, __pu_addr, err, instr) \ 398 439 __asm__ __volatile__( \ 399 - "1: " TUSER(instr) " %1, [%2], #0\n" \ 440 + "1: " instr " %1, [%2], #0\n" \ 400 441 "2:\n" \ 401 442 " .pushsection .text.fixup,\"ax\"\n" \ 402 443 " .align 2\n" \ ··· 413 450 : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \ 414 451 : "cc") 415 452 416 - #define __put_user_asm_byte(x, __pu_addr, err) \ 417 - __put_user_asm(x, __pu_addr, err, strb) 453 + #define __put_user_asm_byte(x, __pu_addr, err, __t) \ 454 + __put_user_asm(x, __pu_addr, err, "strb" __t) 418 455 419 456 #if __LINUX_ARM_ARCH__ >= 6 420 457 421 - #define __put_user_asm_half(x, __pu_addr, err) \ 422 - __put_user_asm(x, __pu_addr, err, strh) 458 + #define __put_user_asm_half(x, __pu_addr, err, __t) \ 459 + __put_user_asm(x, __pu_addr, err, "strh" __t) 423 460 424 461 #else 425 462 426 463 #ifndef __ARMEB__ 427 - #define __put_user_asm_half(x, __pu_addr, err) \ 464 + #define __put_user_asm_half(x, __pu_addr, err, __t) \ 428 465 ({ \ 429 466 unsigned long __temp = (__force unsigned long)(x); \ 430 - __put_user_asm_byte(__temp, __pu_addr, err); \ 431 - __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \ 467 + __put_user_asm_byte(__temp, __pu_addr, err, __t); \ 468 + __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err, __t);\ 432 469 }) 433 470 #else 434 - #define __put_user_asm_half(x, __pu_addr, err) \ 471 + #define __put_user_asm_half(x, __pu_addr, err, __t) \ 435 472 ({ \ 436 473 unsigned long __temp = (__force unsigned long)(x); \ 437 - __put_user_asm_byte(__temp >> 8, __pu_addr, err); \ 438 - __put_user_asm_byte(__temp, __pu_addr + 1, err); \ 474 + __put_user_asm_byte(__temp >> 8, __pu_addr, err, __t); \ 475 + __put_user_asm_byte(__temp, __pu_addr + 1, err, __t); \ 439 476 }) 440 477 #endif 441 478 442 479 #endif /* __LINUX_ARM_ARCH__ >= 6 */ 443 480 444 - #define __put_user_asm_word(x, __pu_addr, err) \ 445 - __put_user_asm(x, __pu_addr, err, str) 481 + #define __put_user_asm_word(x, __pu_addr, err, __t) \ 482 + __put_user_asm(x, __pu_addr, err, "str" __t) 446 483 447 484 #ifndef __ARMEB__ 448 485 #define __reg_oper0 "%R2" ··· 452 489 #define __reg_oper1 "%R2" 453 490 #endif 454 491 455 - #define __put_user_asm_dword(x, __pu_addr, err) \ 492 + #define __put_user_asm_dword(x, __pu_addr, err, __t) \ 456 493 __asm__ __volatile__( \ 457 - ARM( "1: " TUSER(str) " " __reg_oper1 ", [%1], #4\n" ) \ 458 - ARM( "2: " TUSER(str) " " __reg_oper0 ", [%1]\n" ) \ 459 - THUMB( "1: " TUSER(str) " " __reg_oper1 ", [%1]\n" ) \ 460 - THUMB( "2: " TUSER(str) " " __reg_oper0 ", [%1, #4]\n" ) \ 494 + ARM( "1: str" __t " " __reg_oper1 ", [%1], #4\n" ) \ 495 + ARM( "2: str" __t " " __reg_oper0 ", [%1]\n" ) \ 496 + THUMB( "1: str" __t " " __reg_oper1 ", [%1]\n" ) \ 497 + THUMB( "2: str" __t " " __reg_oper0 ", [%1, #4]\n" ) \ 461 498 "3:\n" \ 462 499 " .pushsection .text.fixup,\"ax\"\n" \ 463 500 " .align 2\n" \ ··· 473 510 : "r" (x), "i" (-EFAULT) \ 474 511 : "cc") 475 512 476 - #endif /* !CONFIG_CPU_SPECTRE */ 513 + #define HAVE_GET_KERNEL_NOFAULT 514 + 515 + #define __get_kernel_nofault(dst, src, type, err_label) \ 516 + do { \ 517 + const type *__pk_ptr = (src); \ 518 + unsigned long __src = (unsigned long)(__pk_ptr); \ 519 + type __val; \ 520 + int __err = 0; \ 521 + switch (sizeof(type)) { \ 522 + case 1: __get_user_asm_byte(__val, __src, __err, ""); break; \ 523 + case 2: __get_user_asm_half(__val, __src, __err, ""); break; \ 524 + case 4: __get_user_asm_word(__val, __src, __err, ""); break; \ 525 + case 8: { \ 526 + u32 *__v32 = (u32*)&__val; \ 527 + __get_user_asm_word(__v32[0], __src, __err, ""); \ 528 + if (__err) \ 529 + break; \ 530 + __get_user_asm_word(__v32[1], __src+4, __err, ""); \ 531 + break; \ 532 + } \ 533 + default: __err = __get_user_bad(); break; \ 534 + } \ 535 + *(type *)(dst) = __val; \ 536 + if (__err) \ 537 + goto err_label; \ 538 + } while (0) 539 + 540 + #define __put_kernel_nofault(dst, src, type, err_label) \ 541 + do { \ 542 + const type *__pk_ptr = (dst); \ 543 + unsigned long __dst = (unsigned long)__pk_ptr; \ 544 + int __err = 0; \ 545 + type __val = *(type *)src; \ 546 + switch (sizeof(type)) { \ 547 + case 1: __put_user_asm_byte(__val, __dst, __err, ""); break; \ 548 + case 2: __put_user_asm_half(__val, __dst, __err, ""); break; \ 549 + case 4: __put_user_asm_word(__val, __dst, __err, ""); break; \ 550 + case 8: __put_user_asm_dword(__val, __dst, __err, ""); break; \ 551 + default: __err = __put_user_bad(); break; \ 552 + } \ 553 + if (__err) \ 554 + goto err_label; \ 555 + } while (0) 477 556 478 557 #ifdef CONFIG_MMU 479 558 extern unsigned long __must_check
-4
arch/arm/include/asm/unified.h
··· 24 24 25 25 #ifdef CONFIG_THUMB2_KERNEL 26 26 27 - #if __GNUC__ < 4 28 - #error Thumb-2 kernel requires gcc >= 4 29 - #endif 30 - 31 27 /* The CPSR bit describing the instruction set (Thumb) */ 32 28 #define PSR_ISETSTATE PSR_T_BIT 33 29
+1
arch/arm/include/uapi/asm/unistd.h
··· 15 15 #define _UAPI__ASM_ARM_UNISTD_H 16 16 17 17 #define __NR_OABI_SYSCALL_BASE 0x900000 18 + #define __NR_SYSCALL_MASK 0x0fffff 18 19 19 20 #if defined(__thumb__) || defined(__ARM_EABI__) 20 21 #define __NR_SYSCALL_BASE 0
+1 -2
arch/arm/kernel/asm-offsets.c
··· 43 43 BLANK(); 44 44 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); 45 45 DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); 46 - DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit)); 47 46 DEFINE(TI_TASK, offsetof(struct thread_info, task)); 48 47 DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); 49 48 DEFINE(TI_CPU_DOMAIN, offsetof(struct thread_info, cpu_domain)); 50 49 DEFINE(TI_CPU_SAVE, offsetof(struct thread_info, cpu_context)); 50 + DEFINE(TI_ABI_SYSCALL, offsetof(struct thread_info, abi_syscall)); 51 51 DEFINE(TI_USED_CP, offsetof(struct thread_info, used_cp)); 52 52 DEFINE(TI_TP_VALUE, offsetof(struct thread_info, tp_value)); 53 53 DEFINE(TI_FPSTATE, offsetof(struct thread_info, fpstate)); ··· 88 88 DEFINE(S_OLD_R0, offsetof(struct pt_regs, ARM_ORIG_r0)); 89 89 DEFINE(PT_REGS_SIZE, sizeof(struct pt_regs)); 90 90 DEFINE(SVC_DACR, offsetof(struct svc_pt_regs, dacr)); 91 - DEFINE(SVC_ADDR_LIMIT, offsetof(struct svc_pt_regs, addr_limit)); 92 91 DEFINE(SVC_REGS_SIZE, sizeof(struct svc_pt_regs)); 93 92 BLANK(); 94 93 DEFINE(SIGFRAME_RC3_OFFSET, offsetof(struct sigframe, retcode[3]));
+6 -14
arch/arm/kernel/entry-common.S
··· 49 49 UNWIND(.fnstart ) 50 50 UNWIND(.cantunwind ) 51 51 disable_irq_notrace @ disable interrupts 52 - ldr r2, [tsk, #TI_ADDR_LIMIT] 53 - ldr r1, =TASK_SIZE 54 - cmp r2, r1 55 - blne addr_limit_check_failed 56 52 ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing 57 53 movs r1, r1, lsl #16 58 54 bne fast_work_pending ··· 83 87 bl do_rseq_syscall 84 88 #endif 85 89 disable_irq_notrace @ disable interrupts 86 - ldr r2, [tsk, #TI_ADDR_LIMIT] 87 - ldr r1, =TASK_SIZE 88 - cmp r2, r1 89 - blne addr_limit_check_failed 90 90 ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing 91 91 movs r1, r1, lsl #16 92 92 beq no_work_pending ··· 121 129 #endif 122 130 disable_irq_notrace @ disable interrupts 123 131 ENTRY(ret_to_user_from_irq) 124 - ldr r2, [tsk, #TI_ADDR_LIMIT] 125 - ldr r1, =TASK_SIZE 126 - cmp r2, r1 127 - blne addr_limit_check_failed 128 132 ldr r1, [tsk, #TI_FLAGS] 129 133 movs r1, r1, lsl #16 130 134 bne slow_work_pending ··· 214 226 /* saved_psr and saved_pc are now dead */ 215 227 216 228 uaccess_disable tbl 229 + get_thread_info tsk 217 230 218 231 adr tbl, sys_call_table @ load syscall table pointer 219 232 ··· 226 237 * get the old ABI syscall table address. 227 238 */ 228 239 bics r10, r10, #0xff000000 240 + strne r10, [tsk, #TI_ABI_SYSCALL] 241 + streq scno, [tsk, #TI_ABI_SYSCALL] 229 242 eorne scno, r10, #__NR_OABI_SYSCALL_BASE 230 243 ldrne tbl, =sys_oabi_call_table 231 244 #elif !defined(CONFIG_AEABI) 232 245 bic scno, scno, #0xff000000 @ mask off SWI op-code 246 + str scno, [tsk, #TI_ABI_SYSCALL] 233 247 eor scno, scno, #__NR_SYSCALL_BASE @ check OS number 248 + #else 249 + str scno, [tsk, #TI_ABI_SYSCALL] 234 250 #endif 235 - get_thread_info tsk 236 251 /* 237 252 * Reload the registers that may have been corrupted on entry to 238 253 * the syscall assembly (by tracing or context tracking.) ··· 281 288 * context switches, and waiting for our parent to respond. 282 289 */ 283 290 __sys_trace: 284 - mov r1, scno 285 291 add r0, sp, #S_OFF 286 292 bl syscall_trace_enter 287 293 mov scno, r0
+1 -6
arch/arm/kernel/process.c
··· 106 106 unsigned long flags; 107 107 char buf[64]; 108 108 #ifndef CONFIG_CPU_V7M 109 - unsigned int domain, fs; 109 + unsigned int domain; 110 110 #ifdef CONFIG_CPU_SW_DOMAIN_PAN 111 111 /* 112 112 * Get the domain register for the parent context. In user ··· 115 115 */ 116 116 if (user_mode(regs)) { 117 117 domain = DACR_UACCESS_ENABLE; 118 - fs = get_fs(); 119 118 } else { 120 119 domain = to_svc_pt_regs(regs)->dacr; 121 - fs = to_svc_pt_regs(regs)->addr_limit; 122 120 } 123 121 #else 124 122 domain = get_domain(); 125 - fs = get_fs(); 126 123 #endif 127 124 #endif 128 125 ··· 155 158 if ((domain & domain_mask(DOMAIN_USER)) == 156 159 domain_val(DOMAIN_USER, DOMAIN_NOACCESS)) 157 160 segment = "none"; 158 - else if (fs == KERNEL_DS) 159 - segment = "kernel"; 160 161 else 161 162 segment = "user"; 162 163
+8 -6
arch/arm/kernel/ptrace.c
··· 25 25 #include <linux/tracehook.h> 26 26 #include <linux/unistd.h> 27 27 28 + #include <asm/syscall.h> 28 29 #include <asm/traps.h> 29 30 30 31 #define CREATE_TRACE_POINTS ··· 786 785 break; 787 786 788 787 case PTRACE_SET_SYSCALL: 789 - task_thread_info(child)->syscall = data; 788 + task_thread_info(child)->abi_syscall = data & 789 + __NR_SYSCALL_MASK; 790 790 ret = 0; 791 791 break; 792 792 ··· 846 844 if (dir == PTRACE_SYSCALL_EXIT) 847 845 tracehook_report_syscall_exit(regs, 0); 848 846 else if (tracehook_report_syscall_entry(regs)) 849 - current_thread_info()->syscall = -1; 847 + current_thread_info()->abi_syscall = -1; 850 848 851 849 regs->ARM_ip = ip; 852 850 } 853 851 854 - asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno) 852 + asmlinkage int syscall_trace_enter(struct pt_regs *regs) 855 853 { 856 - current_thread_info()->syscall = scno; 854 + int scno; 857 855 858 856 if (test_thread_flag(TIF_SYSCALL_TRACE)) 859 857 tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER); ··· 864 862 return -1; 865 863 #else 866 864 /* XXX: remove this once OABI gets fixed */ 867 - secure_computing_strict(current_thread_info()->syscall); 865 + secure_computing_strict(syscall_get_nr(current, regs)); 868 866 #endif 869 867 870 868 /* Tracer or seccomp may have changed syscall. */ 871 - scno = current_thread_info()->syscall; 869 + scno = syscall_get_nr(current, regs); 872 870 873 871 if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) 874 872 trace_sys_enter(regs, scno);
-8
arch/arm/kernel/signal.c
··· 669 669 return page; 670 670 } 671 671 672 - /* Defer to generic check */ 673 - asmlinkage void addr_limit_check_failed(void) 674 - { 675 - #ifdef CONFIG_MMU 676 - addr_limit_user_check(); 677 - #endif 678 - } 679 - 680 672 #ifdef CONFIG_DEBUG_RSEQ 681 673 asmlinkage void do_rseq_syscall(struct pt_regs *regs) 682 674 {
+126 -90
arch/arm/kernel/sys_oabi-compat.c
··· 80 80 #include <linux/socket.h> 81 81 #include <linux/net.h> 82 82 #include <linux/ipc.h> 83 + #include <linux/ipc_namespace.h> 83 84 #include <linux/uaccess.h> 84 85 #include <linux/slab.h> 86 + 87 + #include <asm/syscall.h> 85 88 86 89 struct oldabi_stat64 { 87 90 unsigned long long st_dev; ··· 194 191 pid_t l_pid; 195 192 } __attribute__ ((packed,aligned(4))); 196 193 197 - static long do_locks(unsigned int fd, unsigned int cmd, 198 - unsigned long arg) 194 + static int get_oabi_flock(struct flock64 *kernel, struct oabi_flock64 __user *arg) 199 195 { 200 - struct flock64 kernel; 201 196 struct oabi_flock64 user; 202 - mm_segment_t fs; 203 - long ret; 204 197 205 198 if (copy_from_user(&user, (struct oabi_flock64 __user *)arg, 206 199 sizeof(user))) 207 200 return -EFAULT; 208 - kernel.l_type = user.l_type; 209 - kernel.l_whence = user.l_whence; 210 - kernel.l_start = user.l_start; 211 - kernel.l_len = user.l_len; 212 - kernel.l_pid = user.l_pid; 213 201 214 - fs = get_fs(); 215 - set_fs(KERNEL_DS); 216 - ret = sys_fcntl64(fd, cmd, (unsigned long)&kernel); 217 - set_fs(fs); 202 + kernel->l_type = user.l_type; 203 + kernel->l_whence = user.l_whence; 204 + kernel->l_start = user.l_start; 205 + kernel->l_len = user.l_len; 206 + kernel->l_pid = user.l_pid; 218 207 219 - if (!ret && (cmd == F_GETLK64 || cmd == F_OFD_GETLK)) { 220 - user.l_type = kernel.l_type; 221 - user.l_whence = kernel.l_whence; 222 - user.l_start = kernel.l_start; 223 - user.l_len = kernel.l_len; 224 - user.l_pid = kernel.l_pid; 225 - if (copy_to_user((struct oabi_flock64 __user *)arg, 226 - &user, sizeof(user))) 227 - ret = -EFAULT; 228 - } 229 - return ret; 208 + return 0; 209 + } 210 + 211 + static int put_oabi_flock(struct flock64 *kernel, struct oabi_flock64 __user *arg) 212 + { 213 + struct oabi_flock64 user; 214 + 215 + user.l_type = kernel->l_type; 216 + user.l_whence = kernel->l_whence; 217 + user.l_start = kernel->l_start; 218 + user.l_len = kernel->l_len; 219 + user.l_pid = kernel->l_pid; 220 + 221 + if (copy_to_user((struct oabi_flock64 __user *)arg, 222 + &user, sizeof(user))) 223 + return -EFAULT; 224 + 225 + return 0; 230 226 } 231 227 232 228 asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd, 233 229 unsigned long arg) 234 230 { 231 + void __user *argp = (void __user *)arg; 232 + struct fd f = fdget_raw(fd); 233 + struct flock64 flock; 234 + long err = -EBADF; 235 + 236 + if (!f.file) 237 + goto out; 238 + 235 239 switch (cmd) { 236 - case F_OFD_GETLK: 237 - case F_OFD_SETLK: 238 - case F_OFD_SETLKW: 239 240 case F_GETLK64: 241 + case F_OFD_GETLK: 242 + err = security_file_fcntl(f.file, cmd, arg); 243 + if (err) 244 + break; 245 + err = get_oabi_flock(&flock, argp); 246 + if (err) 247 + break; 248 + err = fcntl_getlk64(f.file, cmd, &flock); 249 + if (!err) 250 + err = put_oabi_flock(&flock, argp); 251 + break; 240 252 case F_SETLK64: 241 253 case F_SETLKW64: 242 - return do_locks(fd, cmd, arg); 243 - 254 + case F_OFD_SETLK: 255 + case F_OFD_SETLKW: 256 + err = security_file_fcntl(f.file, cmd, arg); 257 + if (err) 258 + break; 259 + err = get_oabi_flock(&flock, argp); 260 + if (err) 261 + break; 262 + err = fcntl_setlk64(fd, f.file, cmd, &flock); 263 + break; 244 264 default: 245 - return sys_fcntl64(fd, cmd, arg); 265 + err = sys_fcntl64(fd, cmd, arg); 266 + break; 246 267 } 268 + fdput(f); 269 + out: 270 + return err; 247 271 } 248 272 249 273 struct oabi_epoll_event { 250 - __u32 events; 274 + __poll_t events; 251 275 __u64 data; 252 276 } __attribute__ ((packed,aligned(4))); 253 277 ··· 294 264 295 265 return do_epoll_ctl(epfd, op, fd, &kernel, false); 296 266 } 297 - 298 - asmlinkage long sys_oabi_epoll_wait(int epfd, 299 - struct oabi_epoll_event __user *events, 300 - int maxevents, int timeout) 301 - { 302 - struct epoll_event *kbuf; 303 - struct oabi_epoll_event e; 304 - mm_segment_t fs; 305 - long ret, err, i; 306 - 307 - if (maxevents <= 0 || 308 - maxevents > (INT_MAX/sizeof(*kbuf)) || 309 - maxevents > (INT_MAX/sizeof(*events))) 310 - return -EINVAL; 311 - if (!access_ok(events, sizeof(*events) * maxevents)) 312 - return -EFAULT; 313 - kbuf = kmalloc_array(maxevents, sizeof(*kbuf), GFP_KERNEL); 314 - if (!kbuf) 315 - return -ENOMEM; 316 - fs = get_fs(); 317 - set_fs(KERNEL_DS); 318 - ret = sys_epoll_wait(epfd, kbuf, maxevents, timeout); 319 - set_fs(fs); 320 - err = 0; 321 - for (i = 0; i < ret; i++) { 322 - e.events = kbuf[i].events; 323 - e.data = kbuf[i].data; 324 - err = __copy_to_user(events, &e, sizeof(e)); 325 - if (err) 326 - break; 327 - events++; 328 - } 329 - kfree(kbuf); 330 - return err ? -EFAULT : ret; 331 - } 332 267 #else 333 268 asmlinkage long sys_oabi_epoll_ctl(int epfd, int op, int fd, 334 269 struct oabi_epoll_event __user *event) 335 270 { 336 271 return -EINVAL; 337 272 } 338 - 339 - asmlinkage long sys_oabi_epoll_wait(int epfd, 340 - struct oabi_epoll_event __user *events, 341 - int maxevents, int timeout) 342 - { 343 - return -EINVAL; 344 - } 345 273 #endif 274 + 275 + struct epoll_event __user * 276 + epoll_put_uevent(__poll_t revents, __u64 data, 277 + struct epoll_event __user *uevent) 278 + { 279 + if (in_oabi_syscall()) { 280 + struct oabi_epoll_event __user *oevent = (void __user *)uevent; 281 + 282 + if (__put_user(revents, &oevent->events) || 283 + __put_user(data, &oevent->data)) 284 + return NULL; 285 + 286 + return (void __user *)(oevent+1); 287 + } 288 + 289 + if (__put_user(revents, &uevent->events) || 290 + __put_user(data, &uevent->data)) 291 + return NULL; 292 + 293 + return uevent+1; 294 + } 346 295 347 296 struct oabi_sembuf { 348 297 unsigned short sem_num; ··· 330 321 unsigned short __pad; 331 322 }; 332 323 324 + #define sc_semopm sem_ctls[2] 325 + 326 + #ifdef CONFIG_SYSVIPC 333 327 asmlinkage long sys_oabi_semtimedop(int semid, 334 328 struct oabi_sembuf __user *tsops, 335 329 unsigned nsops, 336 330 const struct old_timespec32 __user *timeout) 337 331 { 332 + struct ipc_namespace *ns; 338 333 struct sembuf *sops; 339 - struct old_timespec32 local_timeout; 340 334 long err; 341 335 int i; 342 336 337 + ns = current->nsproxy->ipc_ns; 338 + if (nsops > ns->sc_semopm) 339 + return -E2BIG; 343 340 if (nsops < 1 || nsops > SEMOPM) 344 341 return -EINVAL; 345 - if (!access_ok(tsops, sizeof(*tsops) * nsops)) 346 - return -EFAULT; 347 - sops = kmalloc_array(nsops, sizeof(*sops), GFP_KERNEL); 342 + sops = kvmalloc_array(nsops, sizeof(*sops), GFP_KERNEL); 348 343 if (!sops) 349 344 return -ENOMEM; 350 345 err = 0; 351 346 for (i = 0; i < nsops; i++) { 352 347 struct oabi_sembuf osb; 353 - err |= __copy_from_user(&osb, tsops, sizeof(osb)); 348 + err |= copy_from_user(&osb, tsops, sizeof(osb)); 354 349 sops[i].sem_num = osb.sem_num; 355 350 sops[i].sem_op = osb.sem_op; 356 351 sops[i].sem_flg = osb.sem_flg; 357 352 tsops++; 358 353 } 359 - if (timeout) { 360 - /* copy this as well before changing domain protection */ 361 - err |= copy_from_user(&local_timeout, timeout, sizeof(*timeout)); 362 - timeout = &local_timeout; 363 - } 364 354 if (err) { 365 355 err = -EFAULT; 366 - } else { 367 - mm_segment_t fs = get_fs(); 368 - set_fs(KERNEL_DS); 369 - err = sys_semtimedop_time32(semid, sops, nsops, timeout); 370 - set_fs(fs); 356 + goto out; 371 357 } 372 - kfree(sops); 358 + 359 + if (timeout) { 360 + struct timespec64 ts; 361 + err = get_old_timespec32(&ts, timeout); 362 + if (err) 363 + goto out; 364 + err = __do_semtimedop(semid, sops, nsops, &ts, ns); 365 + goto out; 366 + } 367 + err = __do_semtimedop(semid, sops, nsops, NULL, ns); 368 + out: 369 + kvfree(sops); 373 370 return err; 374 371 } 375 372 ··· 402 387 return sys_ipc(call, first, second, third, ptr, fifth); 403 388 } 404 389 } 390 + #else 391 + asmlinkage long sys_oabi_semtimedop(int semid, 392 + struct oabi_sembuf __user *tsops, 393 + unsigned nsops, 394 + const struct old_timespec32 __user *timeout) 395 + { 396 + return -ENOSYS; 397 + } 398 + 399 + asmlinkage long sys_oabi_semop(int semid, struct oabi_sembuf __user *tsops, 400 + unsigned nsops) 401 + { 402 + return -ENOSYS; 403 + } 404 + 405 + asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third, 406 + void __user *ptr, long fifth) 407 + { 408 + return -ENOSYS; 409 + } 410 + #endif 405 411 406 412 asmlinkage long sys_oabi_bind(int fd, struct sockaddr __user *addr, int addrlen) 407 413 {
+16 -31
arch/arm/kernel/traps.c
··· 122 122 unsigned long top) 123 123 { 124 124 unsigned long first; 125 - mm_segment_t fs; 126 125 int i; 127 - 128 - /* 129 - * We need to switch to kernel mode so that we can use __get_user 130 - * to safely read from kernel space. Note that we now dump the 131 - * code first, just in case the backtrace kills us. 132 - */ 133 - fs = get_fs(); 134 - set_fs(KERNEL_DS); 135 126 136 127 printk("%s%s(0x%08lx to 0x%08lx)\n", lvl, str, bottom, top); 137 128 ··· 136 145 for (p = first, i = 0; i < 8 && p < top; i++, p += 4) { 137 146 if (p >= bottom && p < top) { 138 147 unsigned long val; 139 - if (__get_user(val, (unsigned long *)p) == 0) 148 + if (get_kernel_nofault(val, (unsigned long *)p)) 140 149 sprintf(str + i * 9, " %08lx", val); 141 150 else 142 151 sprintf(str + i * 9, " ????????"); ··· 144 153 } 145 154 printk("%s%04lx:%s\n", lvl, first & 0xffff, str); 146 155 } 147 - 148 - set_fs(fs); 149 156 } 150 157 151 - static void __dump_instr(const char *lvl, struct pt_regs *regs) 158 + static void dump_instr(const char *lvl, struct pt_regs *regs) 152 159 { 153 160 unsigned long addr = instruction_pointer(regs); 154 161 const int thumb = thumb_mode(regs); ··· 162 173 for (i = -4; i < 1 + !!thumb; i++) { 163 174 unsigned int val, bad; 164 175 165 - if (thumb) 166 - bad = get_user(val, &((u16 *)addr)[i]); 167 - else 168 - bad = get_user(val, &((u32 *)addr)[i]); 176 + if (!user_mode(regs)) { 177 + if (thumb) { 178 + u16 val16; 179 + bad = get_kernel_nofault(val16, &((u16 *)addr)[i]); 180 + val = val16; 181 + } else { 182 + bad = get_kernel_nofault(val, &((u32 *)addr)[i]); 183 + } 184 + } else { 185 + if (thumb) 186 + bad = get_user(val, &((u16 *)addr)[i]); 187 + else 188 + bad = get_user(val, &((u32 *)addr)[i]); 189 + } 169 190 170 191 if (!bad) 171 192 p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ", ··· 186 187 } 187 188 } 188 189 printk("%sCode: %s\n", lvl, str); 189 - } 190 - 191 - static void dump_instr(const char *lvl, struct pt_regs *regs) 192 - { 193 - mm_segment_t fs; 194 - 195 - if (!user_mode(regs)) { 196 - fs = get_fs(); 197 - set_fs(KERNEL_DS); 198 - __dump_instr(lvl, regs); 199 - set_fs(fs); 200 - } else { 201 - __dump_instr(lvl, regs); 202 - } 203 190 } 204 191 205 192 #ifdef CONFIG_ARM_UNWIND
+1 -2
arch/arm/lib/copy_from_user.S
··· 109 109 110 110 ENTRY(arm_copy_from_user) 111 111 #ifdef CONFIG_CPU_SPECTRE 112 - get_thread_info r3 113 - ldr r3, [r3, #TI_ADDR_LIMIT] 112 + ldr r3, =TASK_SIZE 114 113 uaccess_mask_range_ptr r1, r2, r3, ip 115 114 #endif 116 115
+1 -2
arch/arm/lib/copy_to_user.S
··· 109 109 ENTRY(__copy_to_user_std) 110 110 WEAK(arm_copy_to_user) 111 111 #ifdef CONFIG_CPU_SPECTRE 112 - get_thread_info r3 113 - ldr r3, [r3, #TI_ADDR_LIMIT] 112 + ldr r3, =TASK_SIZE 114 113 uaccess_mask_range_ptr r0, r2, r3, ip 115 114 #endif 116 115
+1 -1
arch/arm/tools/syscall.tbl
··· 266 266 249 common lookup_dcookie sys_lookup_dcookie 267 267 250 common epoll_create sys_epoll_create 268 268 251 common epoll_ctl sys_epoll_ctl sys_oabi_epoll_ctl 269 - 252 common epoll_wait sys_epoll_wait sys_oabi_epoll_wait 269 + 252 common epoll_wait sys_epoll_wait 270 270 253 common remap_file_pages sys_remap_file_pages 271 271 # 254 for set_thread_area 272 272 # 255 for get_thread_area
+2 -3
fs/eventpoll.c
··· 1686 1686 if (!revents) 1687 1687 continue; 1688 1688 1689 - if (__put_user(revents, &events->events) || 1690 - __put_user(epi->event.data, &events->data)) { 1689 + events = epoll_put_uevent(revents, epi->event.data, events); 1690 + if (!events) { 1691 1691 list_add(&epi->rdllink, &txlist); 1692 1692 ep_pm_stay_awake(epi); 1693 1693 if (!res) ··· 1695 1695 break; 1696 1696 } 1697 1697 res++; 1698 - events++; 1699 1698 if (epi->event.events & EPOLLONESHOT) 1700 1699 epi->event.events &= EP_PRIVATE_BITS; 1701 1700 else if (!(epi->event.events & EPOLLET)) {
+4 -10
include/asm-generic/div64.h
··· 57 57 /* 58 58 * If the divisor happens to be constant, we determine the appropriate 59 59 * inverse at compile time to turn the division into a few inline 60 - * multiplications which ought to be much faster. And yet only if compiling 61 - * with a sufficiently recent gcc version to perform proper 64-bit constant 62 - * propagation. 60 + * multiplications which ought to be much faster. 63 61 * 64 62 * (It is unfortunate that gcc doesn't perform all this internally.) 65 63 */ 66 - 67 - #ifndef __div64_const32_is_OK 68 - #define __div64_const32_is_OK (__GNUC__ >= 4) 69 - #endif 70 64 71 65 #define __div64_const32(n, ___b) \ 72 66 ({ \ ··· 224 230 is_power_of_2(__base)) { \ 225 231 __rem = (n) & (__base - 1); \ 226 232 (n) >>= ilog2(__base); \ 227 - } else if (__div64_const32_is_OK && \ 228 - __builtin_constant_p(__base) && \ 233 + } else if (__builtin_constant_p(__base) && \ 229 234 __base != 0) { \ 230 235 uint32_t __res_lo, __n_lo = (n); \ 231 236 (n) = __div64_const32(n, __base); \ ··· 234 241 } else if (likely(((n) >> 32) == 0)) { \ 235 242 __rem = (uint32_t)(n) % __base; \ 236 243 (n) = (uint32_t)(n) / __base; \ 237 - } else \ 244 + } else { \ 238 245 __rem = __div64_32(&(n), __base); \ 246 + } \ 239 247 __rem; \ 240 248 }) 241 249
+18
include/linux/eventpoll.h
··· 68 68 69 69 #endif 70 70 71 + #if defined(CONFIG_ARM) && defined(CONFIG_OABI_COMPAT) 72 + /* ARM OABI has an incompatible struct layout and needs a special handler */ 73 + extern struct epoll_event __user * 74 + epoll_put_uevent(__poll_t revents, __u64 data, 75 + struct epoll_event __user *uevent); 76 + #else 77 + static inline struct epoll_event __user * 78 + epoll_put_uevent(__poll_t revents, __u64 data, 79 + struct epoll_event __user *uevent) 80 + { 81 + if (__put_user(revents, &uevent->events) || 82 + __put_user(data, &uevent->data)) 83 + return NULL; 84 + 85 + return uevent+1; 86 + } 87 + #endif 88 + 71 89 #endif /* #ifndef _LINUX_EVENTPOLL_H */
+3
include/linux/syscalls.h
··· 1373 1373 long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems, 1374 1374 unsigned int nsops, 1375 1375 const struct old_timespec32 __user *timeout); 1376 + long __do_semtimedop(int semid, struct sembuf *tsems, unsigned int nsops, 1377 + const struct timespec64 *timeout, 1378 + struct ipc_namespace *ns); 1376 1379 1377 1380 int __sys_getsockopt(int fd, int level, int optname, char __user *optval, 1378 1381 int __user *optlen);
+52 -33
ipc/sem.c
··· 1984 1984 return un; 1985 1985 } 1986 1986 1987 - static long do_semtimedop(int semid, struct sembuf __user *tsops, 1988 - unsigned nsops, const struct timespec64 *timeout) 1987 + long __do_semtimedop(int semid, struct sembuf *sops, 1988 + unsigned nsops, const struct timespec64 *timeout, 1989 + struct ipc_namespace *ns) 1989 1990 { 1990 1991 int error = -EINVAL; 1991 1992 struct sem_array *sma; 1992 - struct sembuf fast_sops[SEMOPM_FAST]; 1993 - struct sembuf *sops = fast_sops, *sop; 1993 + struct sembuf *sop; 1994 1994 struct sem_undo *un; 1995 1995 int max, locknum; 1996 1996 bool undos = false, alter = false, dupsop = false; 1997 1997 struct sem_queue queue; 1998 1998 unsigned long dup = 0, jiffies_left = 0; 1999 - struct ipc_namespace *ns; 2000 - 2001 - ns = current->nsproxy->ipc_ns; 2002 1999 2003 2000 if (nsops < 1 || semid < 0) 2004 2001 return -EINVAL; 2005 2002 if (nsops > ns->sc_semopm) 2006 2003 return -E2BIG; 2007 - if (nsops > SEMOPM_FAST) { 2008 - sops = kvmalloc_array(nsops, sizeof(*sops), 2009 - GFP_KERNEL_ACCOUNT); 2010 - if (sops == NULL) 2011 - return -ENOMEM; 2012 - } 2013 - 2014 - if (copy_from_user(sops, tsops, nsops * sizeof(*tsops))) { 2015 - error = -EFAULT; 2016 - goto out_free; 2017 - } 2018 2004 2019 2005 if (timeout) { 2020 2006 if (timeout->tv_sec < 0 || timeout->tv_nsec < 0 || 2021 2007 timeout->tv_nsec >= 1000000000L) { 2022 2008 error = -EINVAL; 2023 - goto out_free; 2009 + goto out; 2024 2010 } 2025 2011 jiffies_left = timespec64_to_jiffies(timeout); 2026 2012 } 2013 + 2027 2014 2028 2015 max = 0; 2029 2016 for (sop = sops; sop < sops + nsops; sop++) { ··· 2040 2053 un = find_alloc_undo(ns, semid); 2041 2054 if (IS_ERR(un)) { 2042 2055 error = PTR_ERR(un); 2043 - goto out_free; 2056 + goto out; 2044 2057 } 2045 2058 } else { 2046 2059 un = NULL; ··· 2051 2064 if (IS_ERR(sma)) { 2052 2065 rcu_read_unlock(); 2053 2066 error = PTR_ERR(sma); 2054 - goto out_free; 2067 + goto out; 2055 2068 } 2056 2069 2057 2070 error = -EFBIG; 2058 2071 if (max >= sma->sem_nsems) { 2059 2072 rcu_read_unlock(); 2060 - goto out_free; 2073 + goto out; 2061 2074 } 2062 2075 2063 2076 error = -EACCES; 2064 2077 if (ipcperms(ns, &sma->sem_perm, alter ? S_IWUGO : S_IRUGO)) { 2065 2078 rcu_read_unlock(); 2066 - goto out_free; 2079 + goto out; 2067 2080 } 2068 2081 2069 2082 error = security_sem_semop(&sma->sem_perm, sops, nsops, alter); 2070 2083 if (error) { 2071 2084 rcu_read_unlock(); 2072 - goto out_free; 2085 + goto out; 2073 2086 } 2074 2087 2075 2088 error = -EIDRM; ··· 2083 2096 * entangled here and why it's RMID race safe on comments at sem_lock() 2084 2097 */ 2085 2098 if (!ipc_valid_object(&sma->sem_perm)) 2086 - goto out_unlock_free; 2099 + goto out_unlock; 2087 2100 /* 2088 2101 * semid identifiers are not unique - find_alloc_undo may have 2089 2102 * allocated an undo structure, it was invalidated by an RMID ··· 2092 2105 * "un" itself is guaranteed by rcu. 2093 2106 */ 2094 2107 if (un && un->semid == -1) 2095 - goto out_unlock_free; 2108 + goto out_unlock; 2096 2109 2097 2110 queue.sops = sops; 2098 2111 queue.nsops = nsops; ··· 2118 2131 rcu_read_unlock(); 2119 2132 wake_up_q(&wake_q); 2120 2133 2121 - goto out_free; 2134 + goto out; 2122 2135 } 2123 2136 if (error < 0) /* non-blocking error path */ 2124 - goto out_unlock_free; 2137 + goto out_unlock; 2125 2138 2126 2139 /* 2127 2140 * We need to sleep on this operation, so we put the current ··· 2186 2199 if (error != -EINTR) { 2187 2200 /* see SEM_BARRIER_2 for purpose/pairing */ 2188 2201 smp_acquire__after_ctrl_dep(); 2189 - goto out_free; 2202 + goto out; 2190 2203 } 2191 2204 2192 2205 rcu_read_lock(); 2193 2206 locknum = sem_lock(sma, sops, nsops); 2194 2207 2195 2208 if (!ipc_valid_object(&sma->sem_perm)) 2196 - goto out_unlock_free; 2209 + goto out_unlock; 2197 2210 2198 2211 /* 2199 2212 * No necessity for any barrier: We are protect by sem_lock() ··· 2205 2218 * Leave without unlink_queue(), but with sem_unlock(). 2206 2219 */ 2207 2220 if (error != -EINTR) 2208 - goto out_unlock_free; 2221 + goto out_unlock; 2209 2222 2210 2223 /* 2211 2224 * If an interrupt occurred we have to clean up the queue. ··· 2216 2229 2217 2230 unlink_queue(sma, &queue); 2218 2231 2219 - out_unlock_free: 2232 + out_unlock: 2220 2233 sem_unlock(sma, locknum); 2221 2234 rcu_read_unlock(); 2235 + out: 2236 + return error; 2237 + } 2238 + 2239 + static long do_semtimedop(int semid, struct sembuf __user *tsops, 2240 + unsigned nsops, const struct timespec64 *timeout) 2241 + { 2242 + struct sembuf fast_sops[SEMOPM_FAST]; 2243 + struct sembuf *sops = fast_sops; 2244 + struct ipc_namespace *ns; 2245 + int ret; 2246 + 2247 + ns = current->nsproxy->ipc_ns; 2248 + if (nsops > ns->sc_semopm) 2249 + return -E2BIG; 2250 + if (nsops < 1) 2251 + return -EINVAL; 2252 + 2253 + if (nsops > SEMOPM_FAST) { 2254 + sops = kvmalloc_array(nsops, sizeof(*sops), GFP_KERNEL_ACCOUNT); 2255 + if (sops == NULL) 2256 + return -ENOMEM; 2257 + } 2258 + 2259 + if (copy_from_user(sops, tsops, nsops * sizeof(*tsops))) { 2260 + ret = -EFAULT; 2261 + goto out_free; 2262 + } 2263 + 2264 + ret = __do_semtimedop(semid, sops, nsops, timeout, ns); 2265 + 2222 2266 out_free: 2223 2267 if (sops != fast_sops) 2224 2268 kvfree(sops); 2225 - return error; 2269 + 2270 + return ret; 2226 2271 } 2227 2272 2228 2273 long ksys_semtimedop(int semid, struct sembuf __user *tsops,
+22 -6
mm/maccess.c
··· 24 24 25 25 long copy_from_kernel_nofault(void *dst, const void *src, size_t size) 26 26 { 27 + unsigned long align = 0; 28 + 29 + if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) 30 + align = (unsigned long)dst | (unsigned long)src; 31 + 27 32 if (!copy_from_kernel_nofault_allowed(src, size)) 28 33 return -ERANGE; 29 34 30 35 pagefault_disable(); 31 - copy_from_kernel_nofault_loop(dst, src, size, u64, Efault); 32 - copy_from_kernel_nofault_loop(dst, src, size, u32, Efault); 33 - copy_from_kernel_nofault_loop(dst, src, size, u16, Efault); 36 + if (!(align & 7)) 37 + copy_from_kernel_nofault_loop(dst, src, size, u64, Efault); 38 + if (!(align & 3)) 39 + copy_from_kernel_nofault_loop(dst, src, size, u32, Efault); 40 + if (!(align & 1)) 41 + copy_from_kernel_nofault_loop(dst, src, size, u16, Efault); 34 42 copy_from_kernel_nofault_loop(dst, src, size, u8, Efault); 35 43 pagefault_enable(); 36 44 return 0; ··· 58 50 59 51 long copy_to_kernel_nofault(void *dst, const void *src, size_t size) 60 52 { 53 + unsigned long align = 0; 54 + 55 + if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) 56 + align = (unsigned long)dst | (unsigned long)src; 57 + 61 58 pagefault_disable(); 62 - copy_to_kernel_nofault_loop(dst, src, size, u64, Efault); 63 - copy_to_kernel_nofault_loop(dst, src, size, u32, Efault); 64 - copy_to_kernel_nofault_loop(dst, src, size, u16, Efault); 59 + if (!(align & 7)) 60 + copy_to_kernel_nofault_loop(dst, src, size, u64, Efault); 61 + if (!(align & 3)) 62 + copy_to_kernel_nofault_loop(dst, src, size, u32, Efault); 63 + if (!(align & 1)) 64 + copy_to_kernel_nofault_loop(dst, src, size, u16, Efault); 65 65 copy_to_kernel_nofault_loop(dst, src, size, u8, Efault); 66 66 pagefault_enable(); 67 67 return 0;