From a736427fa1103158338839813139b20763c7b13e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 20 Oct 2012 21:39:44 -0400 Subject: missing const in alpha callers of do_mount() Signed-off-by: Al Viro --- arch/alpha/kernel/osf_sys.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 9eb090582cf1..ac2ae13bd045 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -445,7 +445,7 @@ struct procfs_args { * unhappy with OSF UFS. [CHECKME] */ static int -osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) +osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags) { int retval; struct cdfs_args tmp; @@ -465,7 +465,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) } static int -osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) +osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags) { int retval; struct cdfs_args tmp; @@ -485,7 +485,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) } static int -osf_procfs_mount(char *dirname, struct procfs_args __user *args, int flags) +osf_procfs_mount(const char *dirname, struct procfs_args __user *args, int flags) { struct procfs_args tmp; -- cgit v1.2.2 From 489f781a5936f4b90cd5c9838e0102933f6eb2b5 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Tue, 23 Oct 2012 14:24:21 +0100 Subject: arm64: Use pgprot_t as the last argument when invoking __ioremap() Even if it works with since the types have the same size, the correct type of the last __ioremap() argument is pgprot_t rather than pteval_t. Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/io.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index 74a2a7d304a9..d10778fe91e5 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h @@ -225,9 +225,9 @@ extern void __iounmap(volatile void __iomem *addr); #define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) #define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC)) -#define ioremap(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) -#define ioremap_nocache(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) -#define ioremap_wc(addr, size) __ioremap((addr), (size), PROT_NORMAL_NC) +#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) +#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) +#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC)) #define iounmap __iounmap #define ARCH_HAS_IOREMAP_WC -- cgit v1.2.2 From e3978cded41dc7b364e74037f56d6bc558c11fd7 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Tue, 23 Oct 2012 14:51:16 +0100 Subject: arm64: Move PCI_IOBASE closer to MODULES_VADDR This is to reuse the same pmd table that is sparsely populated with the modules space. Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/io.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index d10778fe91e5..54f6116697f7 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h @@ -114,7 +114,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) * I/O port access primitives. */ #define IO_SPACE_LIMIT 0xffff -#define PCI_IOBASE ((void __iomem *)0xffffffbbfffe0000UL) +#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M)) static inline u8 inb(unsigned long addr) { -- cgit v1.2.2 From 43993e4af02ec99908d6d99176773fc2a3ee4c57 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 25 Oct 2012 10:30:34 -0700 Subject: ARM: OMAP2+: PM: add missing newline to VC warning message Add missing newline to warning message to avoid annoying wrapping problems during kernel boot like this one: omap_vc_i2c_init: I2C config for vdd_iva does not match other channels (0). omap_vc_i2c_init: I2C config for vdd_mpu does not match other channels (0).Power Management for TI OMAP4. Reported-by: Russell King Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index 880249b17012..75878c37959b 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c @@ -264,7 +264,7 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm) if (initialized) { if (voltdm->pmic->i2c_high_speed != i2c_high_speed) - pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).", + pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).\n", __func__, voltdm->name, i2c_high_speed); return; } -- cgit v1.2.2 From f4221a7a63abd1b6e358d19fe4d05e4d2e44e11a Mon Sep 17 00:00:00 2001 From: Eric Millbrandt Date: Mon, 24 Sep 2012 12:16:47 +0000 Subject: powerpc/pcm030: add pcm030-audio-fabric to dts Add a node for the pcm030-audio-fabric ASoC driver Signed-off-by: Eric Millbrandt Signed-off-by: Anatolij Gustschin --- arch/powerpc/boot/dts/pcm030.dts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/boot/dts/pcm030.dts b/arch/powerpc/boot/dts/pcm030.dts index 9e354997eb7e..96512c058033 100644 --- a/arch/powerpc/boot/dts/pcm030.dts +++ b/arch/powerpc/boot/dts/pcm030.dts @@ -59,7 +59,7 @@ #gpio-cells = <2>; }; - psc@2000 { /* PSC1 in ac97 mode */ + audioplatform: psc@2000 { /* PSC1 in ac97 mode */ compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97"; cell-index = <0>; }; @@ -134,4 +134,9 @@ localbus { status = "disabled"; }; + + sound { + compatible = "phytec,pcm030-audio-fabric"; + asoc-platform = <&audioplatform>; + }; }; -- cgit v1.2.2 From e34298c9a29a4b5bdcbb9a8994cc61f6ba506a94 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 10 Oct 2012 23:19:15 +0000 Subject: powerpc: 52xx: nop out unsupported critical IRQs Currently, when booting MPC52xx based platforms, we get: mpc52xx_irqhost_map: invalid irq: virq=16, l1=0, l2=3 irq: irq-16==>hwirq-0x3 mapping failed: -22 [WARNing skipped] The warning is wrong since the mapping itself is valid. However, there is no support for that type of IRQ currently. Print a proper warning and bind the irq to a no_irq chip. Signed-off-by: Wolfram Sang Cc: John Bonesio Cc: Anatolij Gustschin Cc: Grant Likely Signed-off-by: Anatolij Gustschin --- arch/powerpc/platforms/52xx/mpc52xx_pic.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c index 8520b58a5e9a..b89ef65392dc 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -372,10 +372,11 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq, case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break; case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break; case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break; - default: - pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n", - __func__, virq, l1irq, l2irq); - return -EINVAL; + case MPC52xx_IRQ_L1_CRIT: + pr_warn("%s: Critical IRQ #%d is unsupported! Nopping it.\n", + __func__, l2irq); + irq_set_chip(virq, &no_irq_chip); + return 0; } irq_set_chip_and_handler(virq, irqchip, handle_level_irq); -- cgit v1.2.2 From 7dfb736ec9917883fc9cfe6d0081987b8b110afe Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Fri, 5 Oct 2012 10:23:10 +0000 Subject: powerpc/mpc5200: move lpbfifo node and fix its interrupt property The LPB FIFO interrupt is a peripheral interrupt, thus its L1 cell has to be 2 instead of 3. Fix it and while at it, move the lpbfifo node to the common dtsi file. This patch fixes the irqdomain warning: ... WARNING: at kernel/irq/irqdomain.c:766 Modules linked in: NIP: c00587fc LR: c0058e0c CTR: c0014e54 REGS: c7837c10 TRAP: 0700 Tainted: G W (3.7.0-rc1-00003-g6e51414) MSR: 00029032 CR: 82cd8322 XER: 00000000 TASK = c7834000[1] 'swapper' THREAD: c7836000 GPR00: 00000001 c7837cc0 c7834000 c7806080 000000d7 c7837d20 00000003 c7837cec GPR08: c7837ce8 00000000 00000000 00000008 82cd3342 00000000 c0003f88 00000000 GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c7850ec0 GPR24: c782b010 00000000 00000001 c7852900 00000003 c7df5be0 c7806080 000000d7 NIP [c00587fc] irq_linear_revmap+0x2c/0x4c LR [c0058e0c] irq_create_mapping+0x28/0x124 Reported-by: Stefan Roese Signed-off-by: Anatolij Gustschin --- arch/powerpc/boot/dts/mpc5200b.dtsi | 6 ++++++ arch/powerpc/boot/dts/o2d.dtsi | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/boot/dts/mpc5200b.dtsi b/arch/powerpc/boot/dts/mpc5200b.dtsi index 7ab286ab5300..39ed65a44c5f 100644 --- a/arch/powerpc/boot/dts/mpc5200b.dtsi +++ b/arch/powerpc/boot/dts/mpc5200b.dtsi @@ -231,6 +231,12 @@ interrupts = <2 7 0>; }; + sclpc@3c00 { + compatible = "fsl,mpc5200-lpbfifo"; + reg = <0x3c00 0x60>; + interrupts = <2 23 0>; + }; + i2c@3d00 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/powerpc/boot/dts/o2d.dtsi b/arch/powerpc/boot/dts/o2d.dtsi index 3444eb8f0ade..24f668039295 100644 --- a/arch/powerpc/boot/dts/o2d.dtsi +++ b/arch/powerpc/boot/dts/o2d.dtsi @@ -86,12 +86,6 @@ reg = <0>; }; }; - - sclpc@3c00 { - compatible = "fsl,mpc5200-lpbfifo"; - reg = <0x3c00 0x60>; - interrupts = <3 23 0>; - }; }; localbus { -- cgit v1.2.2 From 2f72d4f6a29cf84c40fc05c76020b347b4774393 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Tue, 23 Oct 2012 20:17:05 -0700 Subject: xtensa: allow multi-inclusion for uapi/unistd.h Xtensa implements a method that allows to generate a arbitrary output for each system call by defining the __SYSCALL(number, function, num_args). This usually requires to include uapi/unistd.h twice. Instead of removing the guard agains multiple inclusion entirely, allow to include unistd.h again only if __SYSCALL is defined. Note that __SYSCALL gets always undefined at the end of the file. Signed-off-by: Chris Zankel --- arch/xtensa/include/asm/unistd.h | 14 ++++---------- arch/xtensa/include/uapi/asm/unistd.h | 14 +++----------- arch/xtensa/kernel/syscall.c | 7 +++---- 3 files changed, 10 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h index 9ef1c31d2c83..d9fa52dbfba0 100644 --- a/arch/xtensa/include/asm/unistd.h +++ b/arch/xtensa/include/asm/unistd.h @@ -1,16 +1,8 @@ -/* - * include/asm-xtensa/unistd.h - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001 - 2005 Tensilica Inc. - */ +#ifndef _XTENSA_UNISTD_H +#define _XTENSA_UNISTD_H #include - /* * "Conditional" syscalls * @@ -37,3 +29,5 @@ #define __IGNORE_mmap /* use mmap2 */ #define __IGNORE_vfork /* use clone */ #define __IGNORE_fadvise64 /* use fadvise64_64 */ + +#endif /* _XTENSA_UNISTD_H */ diff --git a/arch/xtensa/include/uapi/asm/unistd.h b/arch/xtensa/include/uapi/asm/unistd.h index 479abaea5aae..1fd157f31211 100644 --- a/arch/xtensa/include/uapi/asm/unistd.h +++ b/arch/xtensa/include/uapi/asm/unistd.h @@ -1,14 +1,4 @@ -/* - * include/asm-xtensa/unistd.h - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001 - 2012 Tensilica Inc. - */ - -#ifndef _UAPI_XTENSA_UNISTD_H +#if !defined(_UAPI_XTENSA_UNISTD_H) || defined(__SYSCALL) #define _UAPI_XTENSA_UNISTD_H #ifndef __SYSCALL @@ -759,4 +749,6 @@ __SYSCALL(331, sys_kcmp, 5) #define SYS_XTENSA_COUNT 5 /* count */ +#undef __SYSCALL + #endif /* _UAPI_XTENSA_UNISTD_H */ diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c index a5c01e74d5d5..5702065f472a 100644 --- a/arch/xtensa/kernel/syscall.c +++ b/arch/xtensa/kernel/syscall.c @@ -32,10 +32,8 @@ typedef void (*syscall_t)(void); syscall_t sys_call_table[__NR_syscall_count] /* FIXME __cacheline_aligned */= { [0 ... __NR_syscall_count - 1] = (syscall_t)&sys_ni_syscall, -#undef __SYSCALL #define __SYSCALL(nr,symbol,nargs) [ nr ] = (syscall_t)symbol, -#undef __KERNEL_SYSCALLS__ -#include +#include }; asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) @@ -49,7 +47,8 @@ asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) return (long)ret; } -asmlinkage long xtensa_fadvise64_64(int fd, int advice, unsigned long long offset, unsigned long long len) +asmlinkage long xtensa_fadvise64_64(int fd, int advice, + unsigned long long offset, unsigned long long len) { return sys_fadvise64_64(fd, offset, len, advice); } -- cgit v1.2.2 From cddfcbcd05851a3b720055d40fc61c63ea1c2bd1 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Tue, 23 Oct 2012 20:25:37 -0700 Subject: xtensa: use physical addresses for bus addresses Define virt_to_bus and bus_to_virt as virt_to_phys, and phys_to_virt, respectively. Signed-off-by: Chris Zankel --- arch/xtensa/include/asm/io.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h index e6be5b9091c2..700c2e6f2d25 100644 --- a/arch/xtensa/include/asm/io.h +++ b/arch/xtensa/include/asm/io.h @@ -62,6 +62,10 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size) static inline void iounmap(volatile void __iomem *addr) { } + +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + #endif /* CONFIG_MMU */ /* -- cgit v1.2.2 From 6ebe7da25b7879194fdb5c43ea67b383dd9014d6 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Wed, 24 Oct 2012 13:15:21 -0700 Subject: xtensa: reset windowbase/windowstart when cloning the VM When we copy a user thread with CLONE_VM, we also have to reset windowbase and windowstart to start a pristine stack frame. Otherwise, overflows can happen using the address 0 as the stack pointer. Also add a special case for vfork, which continues on the parent stack until it calls execve. Because this could be a call8, we need to spill the stack pointer of the previus frame (if still 'live' in the register file). Signed-off-by: Chris Zankel --- arch/xtensa/kernel/process.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 1908f6642d31..341c151af919 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -220,8 +220,32 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, if (user_mode(regs)) { childregs->areg[1] = usp; + + /* When sharing memory with the parent thread, the child + usually starts on a pristine stack, so we have to reset + windowbase, windowstart and wmask. + (Note that such a new thread is required to always create + an initial call4 frame) + The exception is vfork, where the new thread continues to + run on the parent's stack until it calls execve. This could + be a call8 or call12, which requires a legal stack frame + of the previous caller for the overflow handlers to work. + (Note that it's always legal to overflow live registers). + In this case, ensure to spill at least the stack pointer + of that frame. */ + if (clone_flags & CLONE_VM) { - childregs->wmask = 1; /* can't share live windows */ + /* check that caller window is live and same stack */ + int len = childregs->wmask & ~0xf; + if (regs->areg[1] == usp && len != 0) { + int callinc = (regs->areg[0] >> 30) & 3; + int caller_ars = XCHAL_NUM_AREGS - callinc * 4; + put_user(regs->areg[caller_ars+1], + (unsigned __user*)(usp - 12)); + } + childregs->wmask = 1; + childregs->windowstart = 1; + childregs->windowbase = 0; } else { int len = childregs->wmask & ~0xf; memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4], -- cgit v1.2.2 From 3306a72669a2af23b324540b08e68e82ac5b7dab Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 25 Oct 2012 11:10:50 +0400 Subject: xtensa: switch to generic kernel_thread() Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/Kconfig | 1 + arch/xtensa/include/asm/processor.h | 4 +- arch/xtensa/kernel/entry.S | 41 +++++++------------- arch/xtensa/kernel/process.c | 77 ++++++++++++++++++++++--------------- arch/xtensa/kernel/xtensa_ksyms.c | 1 - 5 files changed, 61 insertions(+), 63 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index cdcb48adee4c..9525b70a13a1 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -13,6 +13,7 @@ config XTENSA select GENERIC_CPU_DEVICES select MODULES_USE_ELF_RELA select GENERIC_PCI_IOMAP + select GENERIC_KERNEL_THREAD select ARCH_WANT_OPTIONAL_GPIOLIB help Xtensa processors are 32-bit RISC machines designed by Tensilica diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index 5c371d8d4528..2d630e7399ca 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h @@ -152,6 +152,7 @@ struct thread_struct { /* Clearing a0 terminates the backtrace. */ #define start_thread(regs, new_pc, new_sp) \ + memset(regs, 0, sizeof(*regs)); \ regs->pc = new_pc; \ regs->ps = USER_PS_VALUE; \ regs->areg[1] = new_sp; \ @@ -168,9 +169,6 @@ struct mm_struct; /* Free all resources held by a thread. */ #define release_thread(thread) do { } while(0) -/* Create a kernel thread without removing it from tasklists */ -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); - /* Copy and release all segment info associated with a VM */ #define copy_segments(p, mm) do { } while(0) #define release_segments(mm) do { } while(0) diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 18453067c258..d4ec1381aebc 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -1832,34 +1832,6 @@ ENTRY(system_call) retw -/* - * Create a kernel thread - * - * int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) - * a2 a2 a3 a4 - */ - -ENTRY(kernel_thread) - entry a1, 16 - - mov a5, a2 # preserve fn over syscall - mov a7, a3 # preserve args over syscall - - movi a3, _CLONE_VM | _CLONE_UNTRACED - movi a2, __NR_clone - or a6, a4, a3 # arg0: flags - mov a3, a1 # arg1: sp - syscall - - beq a3, a1, 1f # branch if parent - mov a6, a7 # args - callx4 a5 # fn(args) - - movi a2, __NR_exit - syscall # return value of fn(args) still in a6 - -1: retw - /* * Do a system call from kernel instead of calling sys_execve, so we end up * with proper pt_regs. @@ -1958,3 +1930,16 @@ ENTRY(ret_from_fork) j common_exception_return +/* + * Kernel thread creation helper + * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg + * left from _switch_to: a6 = prev + */ +ENTRY(ret_from_kernel_thread) + + call4 schedule_tail + mov a6, a3 + callx4 a2 + call4 do_exit + +ENDPROC(ret_from_kernel_thread) diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 341c151af919..be52fe437c1b 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -45,6 +45,7 @@ #include extern void ret_from_fork(void); +extern void ret_from_kernel_thread(void); struct task_struct *current_set[NR_CPUS] = {&init_task, }; @@ -158,18 +159,30 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) /* * Copy thread. * + * There are two modes in which this function is called: + * 1) Userspace thread creation, + * regs != NULL, usp_thread_fn is userspace stack pointer. + * It is expected to copy parent regs (in case CLONE_VM is not set + * in the clone_flags) and set up passed usp in the childregs. + * 2) Kernel thread creation, + * regs == NULL, usp_thread_fn is the function to run in the new thread + * and thread_fn_arg is its parameter. + * childregs are not used for the kernel threads. + * * The stack layout for the new thread looks like this: * - * +------------------------+ <- sp in childregs (= tos) + * +------------------------+ * | childregs | * +------------------------+ <- thread.sp = sp in dummy-frame * | dummy-frame | (saved in dummy-frame spill-area) * +------------------------+ * - * We create a dummy frame to return to ret_from_fork: - * a0 points to ret_from_fork (simulating a call4) + * We create a dummy frame to return to either ret_from_fork or + * ret_from_kernel_thread: + * a0 points to ret_from_fork/ret_from_kernel_thread (simulating a call4) * sp points to itself (thread.sp) - * a2, a3 are unused. + * a2, a3 are unused for userspace threads, + * a2 points to thread_fn, a3 holds thread_fn arg for kernel threads. * * Note: This is a pristine frame, so we don't need any spill region on top of * childregs. @@ -185,41 +198,37 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) * involved. Much simpler to just not copy those live frames across. */ -int copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long unused, - struct task_struct * p, struct pt_regs * regs) +int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, + unsigned long thread_fn_arg, + struct task_struct *p, struct pt_regs *unused) { - struct pt_regs *childregs; - unsigned long tos; - int user_mode = user_mode(regs); + struct pt_regs *childregs = task_pt_regs(p); #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) struct thread_info *ti; #endif - /* Set up new TSS. */ - tos = (unsigned long)task_stack_page(p) + THREAD_SIZE; - if (user_mode) - childregs = (struct pt_regs*)(tos - PT_USER_SIZE); - else - childregs = (struct pt_regs*)tos - 1; - - /* This does not copy all the regs. In a bout of brilliance or madness, - ARs beyond a0-a15 exist past the end of the struct. */ - *childregs = *regs; - /* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */ *((int*)childregs - 3) = (unsigned long)childregs; *((int*)childregs - 4) = 0; - childregs->areg[2] = 0; - p->set_child_tid = p->clear_child_tid = NULL; - p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1); p->thread.sp = (unsigned long)childregs; - if (user_mode(regs)) { + if (!(p->flags & PF_KTHREAD)) { + struct pt_regs *regs = current_pt_regs(); + unsigned long usp = usp_thread_fn ? + usp_thread_fn : regs->areg[1]; + + p->thread.ra = MAKE_RA_FOR_CALL( + (unsigned long)ret_from_fork, 0x1); + /* This does not copy all the regs. + * In a bout of brilliance or madness, + * ARs beyond a0-a15 exist past the end of the struct. + */ + *childregs = *regs; childregs->areg[1] = usp; + childregs->areg[2] = 0; /* When sharing memory with the parent thread, the child usually starts on a pristine stack, so we have to reset @@ -254,11 +263,19 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, // FIXME: we need to set THREADPTR in thread_info... if (clone_flags & CLONE_SETTLS) childregs->areg[2] = childregs->areg[6]; - } else { - /* In kernel space, we start a new thread with a new stack. */ - childregs->wmask = 1; - childregs->areg[1] = tos; + p->thread.ra = MAKE_RA_FOR_CALL( + (unsigned long)ret_from_kernel_thread, 1); + + /* pass parameters to ret_from_kernel_thread: + * a2 = thread_fn, a3 = thread_fn arg + */ + *((int *)childregs - 1) = thread_fn_arg; + *((int *)childregs - 2) = usp_thread_fn; + + /* Childregs are only used when we're going to userspace + * in which case start_thread will set them up. + */ } #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) @@ -354,8 +371,6 @@ long xtensa_clone(unsigned long clone_flags, unsigned long newsp, void __user *child_tid, long a5, struct pt_regs *regs) { - if (!newsp) - newsp = regs->areg[1]; return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); } diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index a8b9f1fd1e17..afe058b24e6e 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c @@ -43,7 +43,6 @@ EXPORT_SYMBOL(__strncpy_user); EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(copy_page); -EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(empty_zero_page); /* -- cgit v1.2.2 From f0a1bf0859ffa059f9009d6a17e8d46241fb2161 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 25 Oct 2012 11:10:51 +0400 Subject: xtensa: switch to generic kernel_execve() Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/Kconfig | 1 + arch/xtensa/kernel/entry.S | 18 +----------------- 2 files changed, 2 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 9525b70a13a1..0d1f36a22c98 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -14,6 +14,7 @@ config XTENSA select MODULES_USE_ELF_RELA select GENERIC_PCI_IOMAP select GENERIC_KERNEL_THREAD + select GENERIC_KERNEL_EXECVE select ARCH_WANT_OPTIONAL_GPIOLIB help Xtensa processors are 32-bit RISC machines designed by Tensilica diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index d4ec1381aebc..90bfc1dbc13d 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -1832,22 +1832,6 @@ ENTRY(system_call) retw -/* - * Do a system call from kernel instead of calling sys_execve, so we end up - * with proper pt_regs. - * - * int kernel_execve(const char *fname, char *const argv[], charg *const envp[]) - * a2 a2 a3 a4 - */ - -ENTRY(kernel_execve) - entry a1, 16 - mov a6, a2 # arg0 is in a6 - movi a2, __NR_execve - syscall - - retw - /* * Task switch. * @@ -1940,6 +1924,6 @@ ENTRY(ret_from_kernel_thread) call4 schedule_tail mov a6, a3 callx4 a2 - call4 do_exit + j common_exception_return ENDPROC(ret_from_kernel_thread) -- cgit v1.2.2 From dc241f2c1761bfdec85915f4bbf7e750663f3442 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 25 Oct 2012 11:10:52 +0400 Subject: xtensa: switch to generic sys_execve() Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/include/asm/syscall.h | 2 +- arch/xtensa/include/asm/unistd.h | 1 + arch/xtensa/include/uapi/asm/unistd.h | 2 +- arch/xtensa/kernel/process.c | 25 ------------------------- 4 files changed, 3 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h index c1dacca312f3..124aeee0d381 100644 --- a/arch/xtensa/include/asm/syscall.h +++ b/arch/xtensa/include/asm/syscall.h @@ -10,7 +10,7 @@ struct pt_regs; struct sigaction; -asmlinkage long xtensa_execve(char*, char**, char**, struct pt_regs*); +asmlinkage long sys_execve(char*, char**, char**, struct pt_regs*); asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*); asmlinkage long xtensa_ptrace(long, long, long, long); asmlinkage long xtensa_sigreturn(struct pt_regs*); diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h index d9fa52dbfba0..f4e6eaa40d1c 100644 --- a/arch/xtensa/include/asm/unistd.h +++ b/arch/xtensa/include/asm/unistd.h @@ -1,6 +1,7 @@ #ifndef _XTENSA_UNISTD_H #define _XTENSA_UNISTD_H +#define __ARCH_WANT_SYS_EXECVE #include /* diff --git a/arch/xtensa/include/uapi/asm/unistd.h b/arch/xtensa/include/uapi/asm/unistd.h index 1fd157f31211..9f36d0e3e0ac 100644 --- a/arch/xtensa/include/uapi/asm/unistd.h +++ b/arch/xtensa/include/uapi/asm/unistd.h @@ -262,7 +262,7 @@ __SYSCALL(115, sys_sendmmsg, 4) #define __NR_clone 116 __SYSCALL(116, xtensa_clone, 5) #define __NR_execve 117 -__SYSCALL(117, xtensa_execve, 3) +__SYSCALL(117, sys_execve, 3) #define __NR_exit 118 __SYSCALL(118, sys_exit, 1) #define __NR_exit_group 119 diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index be52fe437c1b..09ae7bfab9a7 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -373,28 +373,3 @@ long xtensa_clone(unsigned long clone_flags, unsigned long newsp, { return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); } - -/* - * xtensa_execve() executes a new program. - */ - -asmlinkage -long xtensa_execve(const char __user *name, - const char __user *const __user *argv, - const char __user *const __user *envp, - long a3, long a4, long a5, - struct pt_regs *regs) -{ - long error; - struct filename *filename; - - filename = getname(name); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - error = do_execve(filename->name, argv, envp, regs); - putname(filename); -out: - return error; -} - -- cgit v1.2.2 From 156152f84e57bff4d9b5d70be6f3f16116bf6fb1 Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Thu, 25 Oct 2012 17:24:12 +0200 Subject: s390/mm: use pmd_large() instead of pmd_huge() Without CONFIG_HUGETLB_PAGE, pmd_huge() will always return 0. So pmd_large() should be used instead in places where both transparent huge pages and hugetlbfs pages can occur. Signed-off-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky --- arch/s390/lib/uaccess_pt.c | 2 +- arch/s390/mm/gup.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index 2d37bb861faf..9017a63dda3d 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c @@ -39,7 +39,7 @@ static __always_inline unsigned long follow_table(struct mm_struct *mm, pmd = pmd_offset(pud, addr); if (pmd_none(*pmd)) return -0x10UL; - if (pmd_huge(*pmd)) { + if (pmd_large(*pmd)) { if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO)) return -0x04UL; return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK); diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 60acb93a4680..8b8285310b5a 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -126,7 +126,7 @@ static inline int gup_pmd_range(pud_t *pudp, pud_t pud, unsigned long addr, */ if (pmd_none(pmd) || pmd_trans_splitting(pmd)) return 0; - if (unlikely(pmd_huge(pmd))) { + if (unlikely(pmd_large(pmd))) { if (!gup_huge_pmd(pmdp, pmd, addr, next, write, pages, nr)) return 0; -- cgit v1.2.2 From d8e7a33df0976459674dece4b630b5d59796ece7 Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Thu, 25 Oct 2012 17:42:50 +0200 Subject: s390/thp: respect page protection in pmd_none() and pmd_present() Similar to pte_none() and pte_present(), the pmd functions should also respect page protection of huge pages, especially PROT_NONE. This patch also simplifies massage_pgprot_pmd() by adding new definitions for huge page protection. Signed-off-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pgtable.h | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index dd647c919a66..2d3b7cb26005 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -506,12 +506,15 @@ static inline int pud_bad(pud_t pud) static inline int pmd_present(pmd_t pmd) { - return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL; + unsigned long mask = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO; + return (pmd_val(pmd) & mask) == _HPAGE_TYPE_NONE || + !(pmd_val(pmd) & _SEGMENT_ENTRY_INV); } static inline int pmd_none(pmd_t pmd) { - return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL; + return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) && + !(pmd_val(pmd) & _SEGMENT_ENTRY_RO); } static inline int pmd_large(pmd_t pmd) @@ -1223,6 +1226,11 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp) } #ifdef CONFIG_TRANSPARENT_HUGEPAGE + +#define SEGMENT_NONE __pgprot(_HPAGE_TYPE_NONE) +#define SEGMENT_RO __pgprot(_HPAGE_TYPE_RO) +#define SEGMENT_RW __pgprot(_HPAGE_TYPE_RW) + #define __HAVE_ARCH_PGTABLE_DEPOSIT extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); @@ -1242,16 +1250,15 @@ static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) { - unsigned long pgprot_pmd = 0; - - if (pgprot_val(pgprot) & _PAGE_INVALID) { - if (pgprot_val(pgprot) & _PAGE_SWT) - pgprot_pmd |= _HPAGE_TYPE_NONE; - pgprot_pmd |= _SEGMENT_ENTRY_INV; - } - if (pgprot_val(pgprot) & _PAGE_RO) - pgprot_pmd |= _SEGMENT_ENTRY_RO; - return pgprot_pmd; + /* + * pgprot is PAGE_NONE, PAGE_RO, or PAGE_RW (see __Pxxx / __Sxxx) + * Convert to segment table entry format. + */ + if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE)) + return pgprot_val(SEGMENT_NONE); + if (pgprot_val(pgprot) == pgprot_val(PAGE_RO)) + return pgprot_val(SEGMENT_RO); + return pgprot_val(SEGMENT_RW); } static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) @@ -1269,7 +1276,9 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd) static inline pmd_t pmd_mkwrite(pmd_t pmd) { - pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; + /* Do not clobber _HPAGE_TYPE_NONE pages! */ + if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INV)) + pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; return pmd; } -- cgit v1.2.2 From 517ffce4e1a03aea979fe3a18a3dd1761a24fafb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 26 Oct 2012 15:18:37 -0700 Subject: sparc64: Make montmul/montsqr/mpmul usable in 32-bit threads. The Montgomery Multiply, Montgomery Square, and Multiple-Precision Multiply instructions work by loading a combination of the floating point and multiple register windows worth of integer registers with the inputs. These values are 64-bit. But for 32-bit userland processes we only save the low 32-bits of each integer register during a register spill. This is because the register window save area is in the user stack and has a fixed layout. Therefore, the only way to use these instruction in 32-bit mode is to perform the following sequence: 1) Load the top-32bits of a choosen integer register with a sentinel, say "-1". This will be in the outer-most register window. The idea is that we're trying to see if the outer-most register window gets spilled, and thus the 64-bit values were truncated. 2) Load all the inputs for the montmul/montsqr/mpmul instruction, down to the inner-most register window. 3) Execute the opcode. 4) Traverse back up to the outer-most register window. 5) Check the sentinel, if it's still "-1" store the results. Otherwise retry the entire sequence. This retry is extremely troublesome. If you're just unlucky and an interrupt or other trap happens, it'll push that outer-most window to the stack and clear the sentinel when we restore it. We could retry forever and never make forward progress if interrupts arrive at a fast enough rate (consider perf events as one example). So we have do limited retries and fallback to software which is extremely non-deterministic. Luckily it's very straightforward to provide a mechanism to let 32-bit applications use a 64-bit stack. Stacks in 64-bit mode are biased by 2047 bytes, which means that the lowest bit is set in the actual %sp register value. So if we see bit zero set in a 32-bit application's stack we treat it like a 64-bit stack. Runtime detection of such a facility is tricky, and cumbersome at best. For example, just trying to use a biased stack and seeing if it works is hard to recover from (the signal handler will need to use an alt stack, plus something along the lines of longjmp). Therefore, we add a system call to report a bitmask of arch specific features like this in a cheap and less hairy way. With help from Andy Polyakov. Signed-off-by: David S. Miller --- arch/sparc/include/asm/compat.h | 5 ++-- arch/sparc/include/asm/thread_info_64.h | 5 ++++ arch/sparc/include/asm/ttable.h | 24 ++++++++++++------- arch/sparc/include/uapi/asm/unistd.h | 6 ++++- arch/sparc/kernel/perf_event.c | 22 ++++++++++++----- arch/sparc/kernel/process_64.c | 42 ++++++++++++++++++--------------- arch/sparc/kernel/ptrace_64.c | 4 ++-- arch/sparc/kernel/sys_sparc_64.c | 5 ++++ arch/sparc/kernel/systbls_64.S | 2 ++ arch/sparc/kernel/unaligned_64.c | 36 ++++++++++++++++++---------- arch/sparc/kernel/visemul.c | 23 +++++++++++------- arch/sparc/kernel/winfixup.S | 2 ++ arch/sparc/math-emu/math_64.c | 2 +- 13 files changed, 117 insertions(+), 61 deletions(-) (limited to 'arch') diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h index cef99fbc0a21..830502fe62b4 100644 --- a/arch/sparc/include/asm/compat.h +++ b/arch/sparc/include/asm/compat.h @@ -232,9 +232,10 @@ static inline void __user *arch_compat_alloc_user_space(long len) struct pt_regs *regs = current_thread_info()->kregs; unsigned long usp = regs->u_regs[UREG_I6]; - if (!(test_thread_flag(TIF_32BIT))) + if (test_thread_64bit_stack(usp)) usp += STACK_BIAS; - else + + if (test_thread_flag(TIF_32BIT)) usp &= 0xffffffffUL; usp -= len; diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h index 4e2276631081..a3fe4dcc0aa6 100644 --- a/arch/sparc/include/asm/thread_info_64.h +++ b/arch/sparc/include/asm/thread_info_64.h @@ -259,6 +259,11 @@ static inline bool test_and_clear_restore_sigmask(void) #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) +#define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0) +#define test_thread_64bit_stack(__SP) \ + ((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \ + false : true) + #endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/arch/sparc/include/asm/ttable.h b/arch/sparc/include/asm/ttable.h index 48f2807d3265..71b5a67522ab 100644 --- a/arch/sparc/include/asm/ttable.h +++ b/arch/sparc/include/asm/ttable.h @@ -372,7 +372,9 @@ etrap_spill_fixup_64bit: \ /* Normal 32bit spill */ #define SPILL_2_GENERIC(ASI) \ - srl %sp, 0, %sp; \ + and %sp, 1, %g3; \ + brnz,pn %g3, (. - (128 + 4)); \ + srl %sp, 0, %sp; \ stwa %l0, [%sp + %g0] ASI; \ mov 0x04, %g3; \ stwa %l1, [%sp + %g3] ASI; \ @@ -398,14 +400,16 @@ etrap_spill_fixup_64bit: \ stwa %i6, [%g1 + %g0] ASI; \ stwa %i7, [%g1 + %g3] ASI; \ saved; \ - retry; nop; nop; \ + retry; \ b,a,pt %xcc, spill_fixup_dax; \ b,a,pt %xcc, spill_fixup_mna; \ b,a,pt %xcc, spill_fixup; #define SPILL_2_GENERIC_ETRAP \ etrap_user_spill_32bit: \ - srl %sp, 0, %sp; \ + and %sp, 1, %g3; \ + brnz,pn %g3, etrap_user_spill_64bit; \ + srl %sp, 0, %sp; \ stwa %l0, [%sp + 0x00] %asi; \ stwa %l1, [%sp + 0x04] %asi; \ stwa %l2, [%sp + 0x08] %asi; \ @@ -427,7 +431,7 @@ etrap_user_spill_32bit: \ ba,pt %xcc, etrap_save; \ wrpr %g1, %cwp; \ nop; nop; nop; nop; \ - nop; nop; nop; nop; \ + nop; nop; \ ba,a,pt %xcc, etrap_spill_fixup_32bit; \ ba,a,pt %xcc, etrap_spill_fixup_32bit; \ ba,a,pt %xcc, etrap_spill_fixup_32bit; @@ -592,7 +596,9 @@ user_rtt_fill_64bit: \ /* Normal 32bit fill */ #define FILL_2_GENERIC(ASI) \ - srl %sp, 0, %sp; \ + and %sp, 1, %g3; \ + brnz,pn %g3, (. - (128 + 4)); \ + srl %sp, 0, %sp; \ lduwa [%sp + %g0] ASI, %l0; \ mov 0x04, %g2; \ mov 0x08, %g3; \ @@ -616,14 +622,16 @@ user_rtt_fill_64bit: \ lduwa [%g1 + %g3] ASI, %i6; \ lduwa [%g1 + %g5] ASI, %i7; \ restored; \ - retry; nop; nop; nop; nop; \ + retry; nop; nop; \ b,a,pt %xcc, fill_fixup_dax; \ b,a,pt %xcc, fill_fixup_mna; \ b,a,pt %xcc, fill_fixup; #define FILL_2_GENERIC_RTRAP \ user_rtt_fill_32bit: \ - srl %sp, 0, %sp; \ + and %sp, 1, %g3; \ + brnz,pn %g3, user_rtt_fill_64bit; \ + srl %sp, 0, %sp; \ lduwa [%sp + 0x00] %asi, %l0; \ lduwa [%sp + 0x04] %asi, %l1; \ lduwa [%sp + 0x08] %asi, %l2; \ @@ -643,7 +651,7 @@ user_rtt_fill_32bit: \ ba,pt %xcc, user_rtt_pre_restore; \ restored; \ nop; nop; nop; nop; nop; \ - nop; nop; nop; nop; nop; \ + nop; nop; nop; \ ba,a,pt %xcc, user_rtt_fill_fixup; \ ba,a,pt %xcc, user_rtt_fill_fixup; \ ba,a,pt %xcc, user_rtt_fill_fixup; diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h index 8974ef7ae920..bed86a820d09 100644 --- a/arch/sparc/include/uapi/asm/unistd.h +++ b/arch/sparc/include/uapi/asm/unistd.h @@ -405,8 +405,12 @@ #define __NR_setns 337 #define __NR_process_vm_readv 338 #define __NR_process_vm_writev 339 +#define __NR_kern_features 340 -#define NR_syscalls 340 +#define NR_syscalls 341 + +/* Bitmask values returned from kern_features system call. */ +#define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 #ifdef __32bit_syscall_numbers__ /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 885a8af74064..b5c38faa4ead 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -1762,15 +1762,25 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; do { - struct sparc_stackf32 *usf, sf; unsigned long pc; - usf = (struct sparc_stackf32 *) ufp; - if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) - break; + if (thread32_stack_is_64bit(ufp)) { + struct sparc_stackf *usf, sf; - pc = sf.callers_pc; - ufp = (unsigned long)sf.fp; + ufp += STACK_BIAS; + usf = (struct sparc_stackf *) ufp; + if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) + break; + pc = sf.callers_pc & 0xffffffff; + ufp = ((unsigned long) sf.fp) & 0xffffffff; + } else { + struct sparc_stackf32 *usf, sf; + usf = (struct sparc_stackf32 *) ufp; + if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) + break; + pc = sf.callers_pc; + ufp = (unsigned long)sf.fp; + } perf_callchain_store(entry, pc); } while (entry->nr < PERF_MAX_STACK_DEPTH); } diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index d778248ef3f8..c6e0c2910043 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -452,13 +452,16 @@ void flush_thread(void) /* It's a bit more tricky when 64-bit tasks are involved... */ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) { + bool stack_64bit = test_thread_64bit_stack(psp); unsigned long fp, distance, rval; - if (!(test_thread_flag(TIF_32BIT))) { + if (stack_64bit) { csp += STACK_BIAS; psp += STACK_BIAS; __get_user(fp, &(((struct reg_window __user *)psp)->ins[6])); fp += STACK_BIAS; + if (test_thread_flag(TIF_32BIT)) + fp &= 0xffffffff; } else __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); @@ -472,7 +475,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) rval = (csp - distance); if (copy_in_user((void __user *) rval, (void __user *) psp, distance)) rval = 0; - else if (test_thread_flag(TIF_32BIT)) { + else if (!stack_64bit) { if (put_user(((u32)csp), &(((struct reg_window32 __user *)rval)->ins[6]))) rval = 0; @@ -507,18 +510,18 @@ void synchronize_user_stack(void) flush_user_windows(); if ((window = get_thread_wsaved()) != 0) { - int winsize = sizeof(struct reg_window); - int bias = 0; - - if (test_thread_flag(TIF_32BIT)) - winsize = sizeof(struct reg_window32); - else - bias = STACK_BIAS; - window -= 1; do { - unsigned long sp = (t->rwbuf_stkptrs[window] + bias); struct reg_window *rwin = &t->reg_window[window]; + int winsize = sizeof(struct reg_window); + unsigned long sp; + + sp = t->rwbuf_stkptrs[window]; + + if (test_thread_64bit_stack(sp)) + sp += STACK_BIAS; + else + winsize = sizeof(struct reg_window32); if (!copy_to_user((char __user *)sp, rwin, winsize)) { shift_window_buffer(window, get_thread_wsaved() - 1, t); @@ -544,13 +547,6 @@ void fault_in_user_windows(void) { struct thread_info *t = current_thread_info(); unsigned long window; - int winsize = sizeof(struct reg_window); - int bias = 0; - - if (test_thread_flag(TIF_32BIT)) - winsize = sizeof(struct reg_window32); - else - bias = STACK_BIAS; flush_user_windows(); window = get_thread_wsaved(); @@ -558,8 +554,16 @@ void fault_in_user_windows(void) if (likely(window != 0)) { window -= 1; do { - unsigned long sp = (t->rwbuf_stkptrs[window] + bias); struct reg_window *rwin = &t->reg_window[window]; + int winsize = sizeof(struct reg_window); + unsigned long sp; + + sp = t->rwbuf_stkptrs[window]; + + if (test_thread_64bit_stack(sp)) + sp += STACK_BIAS; + else + winsize = sizeof(struct reg_window32); if (unlikely(sp & 0x7UL)) stack_unaligned(sp); diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index 484dabac7045..7ff45e4ba681 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c @@ -151,7 +151,7 @@ static int regwindow64_get(struct task_struct *target, { unsigned long rw_addr = regs->u_regs[UREG_I6]; - if (test_tsk_thread_flag(current, TIF_32BIT)) { + if (!test_thread_64bit_stack(rw_addr)) { struct reg_window32 win32; int i; @@ -176,7 +176,7 @@ static int regwindow64_set(struct task_struct *target, { unsigned long rw_addr = regs->u_regs[UREG_I6]; - if (test_tsk_thread_flag(current, TIF_32BIT)) { + if (!test_thread_64bit_stack(rw_addr)) { struct reg_window32 win32; int i; diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 11c6c9603e71..878ef3d5fec5 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -751,3 +751,8 @@ int kernel_execve(const char *filename, : "cc"); return __res; } + +asmlinkage long sys_kern_features(void) +{ + return KERN_FEATURE_MIXED_MODE_STACK; +} diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 3a58e0d66f51..45ce6be088e4 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -86,6 +86,7 @@ sys_call_table32: .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev +/*340*/ .word sys_kern_features #endif /* CONFIG_COMPAT */ @@ -163,3 +164,4 @@ sys_call_table: .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev +/*340*/ .word sys_kern_features diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index f81d038f7340..8201c25e7669 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c @@ -113,21 +113,24 @@ static inline long sign_extend_imm13(long imm) static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) { - unsigned long value; + unsigned long value, fp; if (reg < 16) return (!reg ? 0 : regs->u_regs[reg]); + + fp = regs->u_regs[UREG_FP]; + if (regs->tstate & TSTATE_PRIV) { struct reg_window *win; - win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); + win = (struct reg_window *)(fp + STACK_BIAS); value = win->locals[reg - 16]; - } else if (test_thread_flag(TIF_32BIT)) { + } else if (!test_thread_64bit_stack(fp)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); get_user(value, &win32->locals[reg - 16]); } else { struct reg_window __user *win; - win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); + win = (struct reg_window __user *)(fp + STACK_BIAS); get_user(value, &win->locals[reg - 16]); } return value; @@ -135,19 +138,24 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) { + unsigned long fp; + if (reg < 16) return ®s->u_regs[reg]; + + fp = regs->u_regs[UREG_FP]; + if (regs->tstate & TSTATE_PRIV) { struct reg_window *win; - win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); + win = (struct reg_window *)(fp + STACK_BIAS); return &win->locals[reg - 16]; - } else if (test_thread_flag(TIF_32BIT)) { + } else if (!test_thread_64bit_stack(fp)) { struct reg_window32 *win32; - win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP])); + win32 = (struct reg_window32 *)((unsigned long)((u32)fp)); return (unsigned long *)&win32->locals[reg - 16]; } else { struct reg_window *win; - win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); + win = (struct reg_window *)(fp + STACK_BIAS); return &win->locals[reg - 16]; } } @@ -392,13 +400,15 @@ int handle_popc(u32 insn, struct pt_regs *regs) if (rd) regs->u_regs[rd] = ret; } else { - if (test_thread_flag(TIF_32BIT)) { + unsigned long fp = regs->u_regs[UREG_FP]; + + if (!test_thread_64bit_stack(fp)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); put_user(ret, &win32->locals[rd - 16]); } else { struct reg_window __user *win; - win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); + win = (struct reg_window __user *)(fp + STACK_BIAS); put_user(ret, &win->locals[rd - 16]); } } @@ -554,7 +564,7 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) reg[0] = 0; if ((insn & 0x780000) == 0x180000) reg[1] = 0; - } else if (test_thread_flag(TIF_32BIT)) { + } else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { put_user(0, (int __user *) reg); if ((insn & 0x780000) == 0x180000) put_user(0, ((int __user *) reg) + 1); diff --git a/arch/sparc/kernel/visemul.c b/arch/sparc/kernel/visemul.c index 08e074b7eb6a..c096c624ac4d 100644 --- a/arch/sparc/kernel/visemul.c +++ b/arch/sparc/kernel/visemul.c @@ -149,21 +149,24 @@ static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2, static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) { - unsigned long value; + unsigned long value, fp; if (reg < 16) return (!reg ? 0 : regs->u_regs[reg]); + + fp = regs->u_regs[UREG_FP]; + if (regs->tstate & TSTATE_PRIV) { struct reg_window *win; - win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); + win = (struct reg_window *)(fp + STACK_BIAS); value = win->locals[reg - 16]; - } else if (test_thread_flag(TIF_32BIT)) { + } else if (!test_thread_64bit_stack(fp)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); get_user(value, &win32->locals[reg - 16]); } else { struct reg_window __user *win; - win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); + win = (struct reg_window __user *)(fp + STACK_BIAS); get_user(value, &win->locals[reg - 16]); } return value; @@ -172,16 +175,18 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg, struct pt_regs *regs) { + unsigned long fp = regs->u_regs[UREG_FP]; + BUG_ON(reg < 16); BUG_ON(regs->tstate & TSTATE_PRIV); - if (test_thread_flag(TIF_32BIT)) { + if (!test_thread_64bit_stack(fp)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); return (unsigned long __user *)&win32->locals[reg - 16]; } else { struct reg_window __user *win; - win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); + win = (struct reg_window __user *)(fp + STACK_BIAS); return &win->locals[reg - 16]; } } @@ -204,7 +209,7 @@ static void store_reg(struct pt_regs *regs, unsigned long val, unsigned long rd) } else { unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs); - if (test_thread_flag(TIF_32BIT)) + if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) __put_user((u32)val, (u32 __user *)rd_user); else __put_user(val, rd_user); diff --git a/arch/sparc/kernel/winfixup.S b/arch/sparc/kernel/winfixup.S index a6b0863c27df..1e67ce958369 100644 --- a/arch/sparc/kernel/winfixup.S +++ b/arch/sparc/kernel/winfixup.S @@ -43,6 +43,8 @@ spill_fixup_mna: spill_fixup_dax: TRAP_LOAD_THREAD_REG(%g6, %g1) ldx [%g6 + TI_FLAGS], %g1 + andcc %sp, 0x1, %g0 + movne %icc, 0, %g1 andcc %g1, _TIF_32BIT, %g0 ldub [%g6 + TI_WSAVED], %g1 sll %g1, 3, %g3 diff --git a/arch/sparc/math-emu/math_64.c b/arch/sparc/math-emu/math_64.c index 1704068da928..034aadbff036 100644 --- a/arch/sparc/math-emu/math_64.c +++ b/arch/sparc/math-emu/math_64.c @@ -320,7 +320,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap) XR = 0; else if (freg < 16) XR = regs->u_regs[freg]; - else if (test_thread_flag(TIF_32BIT)) { + else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { struct reg_window32 __user *win32; flushw_user (); win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); -- cgit v1.2.2 From 2c5594df344cd1ff0cc9bf007dea3235582b3acf Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Fri, 26 Oct 2012 11:40:28 +0200 Subject: rcu: Fix unrecovered RCU user mode in syscall_trace_leave() On x86-64 syscall exit, 3 non exclusive events may happen looping in the following order: 1) Check if we need resched for user preemption, if so call schedule_user() 2) Check if we have pending signals, if so call do_notify_resume() 3) Check if we do syscall tracing, if so call syscall_trace_leave() However syscall_trace_leave() has been written assuming it directly follows the syscall and forget about the above possible 1st and 2nd steps. Now schedule_user() and do_notify_resume() exit in RCU user mode because they have most chances to resume userspace immediately and this avoids an rcu_user_enter() call in the syscall fast path. So by the time we call syscall_trace_leave(), we may well be in RCU user mode. To fix this up, simply call rcu_user_exit() in the beginning of this function. This fixes some reported RCU uses in extended quiescent state. Reported-by: Dave Jones Reported-by: Sergey Senozhatsky Signed-off-by: Frederic Weisbecker Tested-by: Sergey Senozhatsky Signed-off-by: Paul E. McKenney --- arch/x86/kernel/ptrace.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index b00b33a18390..eff5b8c68652 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -1511,6 +1511,13 @@ void syscall_trace_leave(struct pt_regs *regs) { bool step; + /* + * We may come here right after calling schedule_user() + * or do_notify_resume(), in which case we can be in RCU + * user mode. + */ + rcu_user_exit(); + audit_syscall_exit(regs); if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) -- cgit v1.2.2 From 8d6b00f5d639cfc28487ef412589e35b4e6ac7c7 Mon Sep 17 00:00:00 2001 From: Paul Parsons Date: Fri, 19 Oct 2012 13:15:30 +0100 Subject: ARM: pxa: hx4700: Fix backlight PWM device number Recent changes to PXA PWM support changed the PXA27X PWM device numbering scheme. The linux-3.5 PXA PWM driver followed the hardware numbering scheme for the 4 PWMs, while the linux-3.6-rc1 PXA PWM driver has adopted a linear numbering scheme: Address Hardware 3.5 pwm_id 3.6-rc1 pwm_id 0x40b00000 PWM0 0 0 0x40b00010 PWM2 2 1 0x40c00000 PWM1 1 2 0x40c00010 PWM3 3 3 The hx4700 backlight uses PWM1 at 0x40c00000. Consequently the pwm_id must be changed from 1 to 2. This patch fixes the backlight PWM device number and at the same time moves from the legacy PWM API (pwm_id) to the new PWM API (pwm_lookup). Signed-off-by: Paul Parsons Cc: Thierry Reding Signed-off-by: Haojian Zhuang --- arch/arm/mach-pxa/hx4700.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index 5ecbd17b5641..e2c6391863fe 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -556,7 +557,7 @@ static struct platform_device hx4700_lcd = { */ static struct platform_pwm_backlight_data backlight_data = { - .pwm_id = 1, + .pwm_id = -1, /* Superseded by pwm_lookup */ .max_brightness = 200, .dft_brightness = 100, .pwm_period_ns = 30923, @@ -571,6 +572,10 @@ static struct platform_device backlight = { }, }; +static struct pwm_lookup hx4700_pwm_lookup[] = { + PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight", NULL), +}; + /* * USB "Transceiver" */ @@ -872,6 +877,7 @@ static void __init hx4700_init(void) pxa_set_stuart_info(NULL); platform_add_devices(devices, ARRAY_SIZE(devices)); + pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup)); pxa_set_ficp_info(&ficp_info); pxa27x_set_i2c_power_info(NULL); -- cgit v1.2.2 From 510fcb0d331f314cd20d0067d56f29302846f47b Mon Sep 17 00:00:00 2001 From: Marko Katic Date: Thu, 25 Oct 2012 18:51:38 +0200 Subject: ARM: pxa/spitz_pm: Fix hang when resuming from STR Devices that use spitz_pm.c will fail to resume from STR (Suspend To Ram) when the charger plug is inserted or removed when a device is in STR mode. The culprit is a misconfigured gpio line - GPIO18. GPIO18 should be configured as a regular GPIO input but it gets configured as an alternate function GPIO18_RDY. And then later in postsuspend() it gets configured as a regular GPIO18 input line. Fix this by removing the GPIO18_RDY configuration so that GPIO18 only gets configured as a regular gpio input. Signed-off-by: Marko Katic Signed-off-by: Haojian Zhuang --- arch/arm/mach-pxa/spitz_pm.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c index 438f02fe122a..842596d4d31e 100644 --- a/arch/arm/mach-pxa/spitz_pm.c +++ b/arch/arm/mach-pxa/spitz_pm.c @@ -86,10 +86,7 @@ static void spitz_discharge1(int on) gpio_set_value(SPITZ_GPIO_LED_GREEN, on); } -static unsigned long gpio18_config[] = { - GPIO18_RDY, - GPIO18_GPIO, -}; +static unsigned long gpio18_config = GPIO18_GPIO; static void spitz_presuspend(void) { @@ -112,7 +109,7 @@ static void spitz_presuspend(void) PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT; PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0); - pxa2xx_mfp_config(&gpio18_config[0], 1); + pxa2xx_mfp_config(&gpio18_config, 1); gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown"); gpio_free(18); @@ -131,7 +128,6 @@ static void spitz_presuspend(void) static void spitz_postsuspend(void) { - pxa2xx_mfp_config(&gpio18_config[1], 1); } static int spitz_should_wakeup(unsigned int resume_on_alarm) -- cgit v1.2.2 From 270c10e00a1e557e068803a22e0556281ceb1830 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 27 Oct 2012 18:05:20 -0700 Subject: sparc64: Fix cpu strand yielding. For atomic backoff, we just loop over an exponentially backed off counter. This is extremely ineffective as it doesn't actually yield the cpu strand so that other competing strands can use the cpu core. In cpus previous to SPARC-T4 we have to do this in a slightly hackish way, by doing an operation with no side effects that also happens to mark the strand as unavailable. The mechanism we choose for this is three reads of the %ccr (condition-code) register into %g0 (the zero register). SPARC-T4 has an explicit "pause" instruction, and we'll make use of that in a subsequent commit. Yield strands also in cpu_relax(). We really should have done this a very long time ago. Signed-off-by: David S. Miller --- arch/sparc/include/asm/backoff.h | 5 ++++- arch/sparc/include/asm/processor_64.h | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h index db3af0d30fb1..64b077b3b13b 100644 --- a/arch/sparc/include/asm/backoff.h +++ b/arch/sparc/include/asm/backoff.h @@ -13,7 +13,10 @@ #define BACKOFF_SPIN(reg, tmp, label) \ mov reg, tmp; \ -88: brnz,pt tmp, 88b; \ +88: rd %ccr, %g0; \ + rd %ccr, %g0; \ + rd %ccr, %g0; \ + brnz,pt tmp, 88b; \ sub tmp, 1, tmp; \ set BACKOFF_LIMIT, tmp; \ cmp reg, tmp; \ diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h index 4e5a483122a0..986563409469 100644 --- a/arch/sparc/include/asm/processor_64.h +++ b/arch/sparc/include/asm/processor_64.h @@ -196,7 +196,10 @@ extern unsigned long get_wchan(struct task_struct *task); #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) -#define cpu_relax() barrier() +#define cpu_relax() asm volatile("rd %%ccr, %%g0\n\t" \ + "rd %%ccr, %%g0\n\t" \ + "rd %%ccr, %%g0" \ + ::: "memory") /* Prefetch support. This is tuned for UltraSPARC-III and later. * UltraSPARC-I will treat these as nops, and UltraSPARC-II has -- cgit v1.2.2 From e9b9eb59ffcdee09ec96b040f85c919618f4043e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 27 Oct 2012 23:00:41 -0700 Subject: sparc64: Use pause instruction when available. In atomic backoff and cpu_relax(), use the pause instruction found on SPARC-T4 and later. It makes the cpu strand unselectable for the given number of cycles, unless an intervening disrupting trap occurs. Signed-off-by: David S. Miller --- arch/sparc/include/asm/backoff.h | 32 +++++++++++++++++++------------- arch/sparc/include/asm/processor_64.h | 13 ++++++++++--- arch/sparc/kernel/entry.h | 7 +++++++ arch/sparc/kernel/setup_64.c | 21 +++++++++++++++++++++ arch/sparc/kernel/vmlinux.lds.S | 5 +++++ 5 files changed, 62 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h index 64b077b3b13b..20f01df0871b 100644 --- a/arch/sparc/include/asm/backoff.h +++ b/arch/sparc/include/asm/backoff.h @@ -11,19 +11,25 @@ #define BACKOFF_LABEL(spin_label, continue_label) \ spin_label -#define BACKOFF_SPIN(reg, tmp, label) \ - mov reg, tmp; \ -88: rd %ccr, %g0; \ - rd %ccr, %g0; \ - rd %ccr, %g0; \ - brnz,pt tmp, 88b; \ - sub tmp, 1, tmp; \ - set BACKOFF_LIMIT, tmp; \ - cmp reg, tmp; \ - bg,pn %xcc, label; \ - nop; \ - ba,pt %xcc, label; \ - sllx reg, 1, reg; +#define BACKOFF_SPIN(reg, tmp, label) \ + mov reg, tmp; \ +88: rd %ccr, %g0; \ + rd %ccr, %g0; \ + rd %ccr, %g0; \ + .section .pause_patch,"ax"; \ + .word 88b; \ + sllx tmp, 7, tmp; \ + wr tmp, 0, %asr27; \ + clr tmp; \ + .previous; \ + brnz,pt tmp, 88b; \ + sub tmp, 1, tmp; \ + set BACKOFF_LIMIT, tmp; \ + cmp reg, tmp; \ + bg,pn %xcc, label; \ + nop; \ + ba,pt %xcc, label; \ + sllx reg, 1, reg; #else diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h index 986563409469..9cdf52eec48a 100644 --- a/arch/sparc/include/asm/processor_64.h +++ b/arch/sparc/include/asm/processor_64.h @@ -196,9 +196,16 @@ extern unsigned long get_wchan(struct task_struct *task); #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) -#define cpu_relax() asm volatile("rd %%ccr, %%g0\n\t" \ - "rd %%ccr, %%g0\n\t" \ - "rd %%ccr, %%g0" \ +#define cpu_relax() asm volatile("\n99:\n\t" \ + "rd %%ccr, %%g0\n\t" \ + "rd %%ccr, %%g0\n\t" \ + "rd %%ccr, %%g0\n\t" \ + ".section .pause_patch,\"ax\"\n\t"\ + ".word 99b\n\t" \ + "wr %%g0, 128, %%asr27\n\t" \ + "nop\n\t" \ + "nop\n\t" \ + ".previous" \ ::: "memory") /* Prefetch support. This is tuned for UltraSPARC-III and later. diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index 0c218e4c0881..51742df63c75 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h @@ -59,6 +59,13 @@ struct popc_6insn_patch_entry { extern struct popc_6insn_patch_entry __popc_6insn_patch, __popc_6insn_patch_end; +struct pause_patch_entry { + unsigned int addr; + unsigned int insns[3]; +}; +extern struct pause_patch_entry __pause_patch, + __pause_patch_end; + extern void __init per_cpu_patch(void); extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, struct sun4v_1insn_patch_entry *); diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 0800e71d8a88..b45cff408de3 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -316,6 +316,25 @@ static void __init popc_patch(void) } } +static void __init pause_patch(void) +{ + struct pause_patch_entry *p; + + p = &__pause_patch; + while (p < &__pause_patch_end) { + unsigned long i, addr = p->addr; + + for (i = 0; i < 3; i++) { + *(unsigned int *) (addr + (i * 4)) = p->insns[i]; + wmb(); + __asm__ __volatile__("flush %0" + : : "r" (addr + (i * 4))); + } + + p++; + } +} + #ifdef CONFIG_SMP void __init boot_cpu_id_too_large(int cpu) { @@ -528,6 +547,8 @@ static void __init init_sparc64_elf_hwcap(void) if (sparc64_elf_hwcap & AV_SPARC_POPC) popc_patch(); + if (sparc64_elf_hwcap & AV_SPARC_PAUSE) + pause_patch(); } void __init setup_arch(char **cmdline_p) diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 89c2c29f154b..847f9f793618 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -132,6 +132,11 @@ SECTIONS *(.popc_6insn_patch) __popc_6insn_patch_end = .; } + .pause_patch : { + __pause_patch = .; + *(.pause_patch) + __pause_patch_end = .; + } PERCPU_SECTION(SMP_CACHE_BYTES) . = ALIGN(PAGE_SIZE); -- cgit v1.2.2 From 187818cd6a5ab6343eac47e52da2f3e40c544b98 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 28 Oct 2012 13:04:47 -0700 Subject: sparc64: Improvde documentation and readability of atomic backoff code. Document what's going on in asm/backoff.h with a large and descriptive comment. Refer to it above the cpu_relax() definition in asm/processor_64.h Rename the pause patching section to have "3insn" in it's name like the other patching sections do. Based upon feedback from Sam Ravnborg. Signed-off-by: David S. Miller --- arch/sparc/include/asm/backoff.h | 42 ++++++++++++++++++++++++++++++++++- arch/sparc/include/asm/processor_64.h | 7 +++++- arch/sparc/kernel/entry.h | 4 ++-- arch/sparc/kernel/setup_64.c | 4 ++-- arch/sparc/kernel/vmlinux.lds.S | 8 +++---- 5 files changed, 55 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h index 20f01df0871b..4e02086b839c 100644 --- a/arch/sparc/include/asm/backoff.h +++ b/arch/sparc/include/asm/backoff.h @@ -1,6 +1,46 @@ #ifndef _SPARC64_BACKOFF_H #define _SPARC64_BACKOFF_H +/* The macros in this file implement an exponential backoff facility + * for atomic operations. + * + * When multiple threads compete on an atomic operation, it is + * possible for one thread to be continually denied a successful + * completion of the compare-and-swap instruction. Heavily + * threaded cpu implementations like Niagara can compound this + * problem even further. + * + * When an atomic operation fails and needs to be retried, we spin a + * certain number of times. At each subsequent failure of the same + * operation we double the spin count, realizing an exponential + * backoff. + * + * When we spin, we try to use an operation that will cause the + * current cpu strand to block, and therefore make the core fully + * available to any other other runnable strands. There are two + * options, based upon cpu capabilities. + * + * On all cpus prior to SPARC-T4 we do three dummy reads of the + * condition code register. Each read blocks the strand for something + * between 40 and 50 cpu cycles. + * + * For SPARC-T4 and later we have a special "pause" instruction + * available. This is implemented using writes to register %asr27. + * The cpu will block the number of cycles written into the register, + * unless a disrupting trap happens first. SPARC-T4 specifically + * implements pause with a granularity of 8 cycles. Each strand has + * an internal pause counter which decrements every 8 cycles. So the + * chip shifts the %asr27 value down by 3 bits, and writes the result + * into the pause counter. If a value smaller than 8 is written, the + * chip blocks for 1 cycle. + * + * To achieve the same amount of backoff as the three %ccr reads give + * on earlier chips, we shift the backoff value up by 7 bits. (Three + * %ccr reads block for about 128 cycles, 1 << 7 == 128) We write the + * whole amount we want to block into the pause register, rather than + * loop writing 128 each time. + */ + #define BACKOFF_LIMIT (4 * 1024) #ifdef CONFIG_SMP @@ -16,7 +56,7 @@ 88: rd %ccr, %g0; \ rd %ccr, %g0; \ rd %ccr, %g0; \ - .section .pause_patch,"ax"; \ + .section .pause_3insn_patch,"ax";\ .word 88b; \ sllx tmp, 7, tmp; \ wr tmp, 0, %asr27; \ diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h index 9cdf52eec48a..721e25f0e2ea 100644 --- a/arch/sparc/include/asm/processor_64.h +++ b/arch/sparc/include/asm/processor_64.h @@ -196,11 +196,16 @@ extern unsigned long get_wchan(struct task_struct *task); #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) +/* Please see the commentary in asm/backoff.h for a description of + * what these instructions are doing and how they have been choosen. + * To make a long story short, we are trying to yield the current cpu + * strand during busy loops. + */ #define cpu_relax() asm volatile("\n99:\n\t" \ "rd %%ccr, %%g0\n\t" \ "rd %%ccr, %%g0\n\t" \ "rd %%ccr, %%g0\n\t" \ - ".section .pause_patch,\"ax\"\n\t"\ + ".section .pause_3insn_patch,\"ax\"\n\t"\ ".word 99b\n\t" \ "wr %%g0, 128, %%asr27\n\t" \ "nop\n\t" \ diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index 51742df63c75..cc3c5cb47cda 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h @@ -63,8 +63,8 @@ struct pause_patch_entry { unsigned int addr; unsigned int insns[3]; }; -extern struct pause_patch_entry __pause_patch, - __pause_patch_end; +extern struct pause_patch_entry __pause_3insn_patch, + __pause_3insn_patch_end; extern void __init per_cpu_patch(void); extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index b45cff408de3..0eaf0059aaef 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -320,8 +320,8 @@ static void __init pause_patch(void) { struct pause_patch_entry *p; - p = &__pause_patch; - while (p < &__pause_patch_end) { + p = &__pause_3insn_patch; + while (p < &__pause_3insn_patch_end) { unsigned long i, addr = p->addr; for (i = 0; i < 3; i++) { diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 847f9f793618..0bacceb19150 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -132,10 +132,10 @@ SECTIONS *(.popc_6insn_patch) __popc_6insn_patch_end = .; } - .pause_patch : { - __pause_patch = .; - *(.pause_patch) - __pause_patch_end = .; + .pause_3insn_patch : { + __pause_3insn_patch = .; + *(.pause_3insn_patch) + __pause_3insn_patch_end = .; } PERCPU_SECTION(SMP_CACHE_BYTES) -- cgit v1.2.2 From 1df35f80f9d3bba7cd434b64c9eaff8c9109abad Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 28 Oct 2012 13:15:09 -0700 Subject: sparc: Wire up sys_kcmp. Signed-off-by: David S. Miller --- arch/sparc/include/uapi/asm/unistd.h | 3 ++- arch/sparc/kernel/systbls_32.S | 1 + arch/sparc/kernel/systbls_64.S | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h index bed86a820d09..cac719d1bc5c 100644 --- a/arch/sparc/include/uapi/asm/unistd.h +++ b/arch/sparc/include/uapi/asm/unistd.h @@ -406,8 +406,9 @@ #define __NR_process_vm_readv 338 #define __NR_process_vm_writev 339 #define __NR_kern_features 340 +#define __NR_kcmp 341 -#define NR_syscalls 341 +#define NR_syscalls 342 /* Bitmask values returned from kern_features system call. */ #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 63402f9e9f51..5147f574f125 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -85,3 +85,4 @@ sys_call_table: /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev +/*340*/ .long sys_ni_syscall, sys_kcmp diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 45ce6be088e4..1c9af9fa38e9 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -86,7 +86,7 @@ sys_call_table32: .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev -/*340*/ .word sys_kern_features +/*340*/ .word sys_kern_features, sys_kcmp #endif /* CONFIG_COMPAT */ @@ -164,4 +164,4 @@ sys_call_table: .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev -/*340*/ .word sys_kern_features +/*340*/ .word sys_kern_features, sys_kcmp -- cgit v1.2.2 From 6a4dae5e138a32b45ca5218cc2b81802f9d378c3 Mon Sep 17 00:00:00 2001 From: Felipe Balbi 2 Date: Tue, 23 Oct 2012 19:00:03 +0100 Subject: ARM: 7565/1: sched: stop sched_clock() during suspend The scheduler imposes a requirement to sched_clock() which is to stop the clock during suspend, if we don't do that any RT thread will be rescheduled in the future which might cause any sort of problems. This became an issue on OMAP when we converted omap-i2c.c to use threaded IRQs, it turned out that depending on how much time we spent on suspend, the I2C IRQ thread would end up being rescheduled so far in the future that I2C transfers would timeout and, because omap_hsmmc depends on an I2C-connected device to detect if an MMC card is inserted in the slot, our rootfs would just vanish. arch/arm/kernel/sched_clock.c already had an optional implementation (sched_clock_needs_suspend()) which would handle scheduler's requirement properly, what this patch does is simply to make that implementation non-optional. Note that this has the side-effect that printk timings won't reflect the actual time spent on suspend so other methods to measure that will have to be used. This has been tested with beagleboard XM (OMAP3630) and pandaboard rev A3 (OMAP4430). Suspend to RAM is now working after this patch. Thanks to Kevin Hilman for helping out with debugging. Acked-by: Kevin Hilman Acked-by: Linus Walleij Signed-off-by: Felipe Balbi Signed-off-by: Russell King --- arch/arm/include/asm/sched_clock.h | 2 -- arch/arm/kernel/sched_clock.c | 18 ++++-------------- 2 files changed, 4 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h index 05b8e82ec9f5..e3f757263438 100644 --- a/arch/arm/include/asm/sched_clock.h +++ b/arch/arm/include/asm/sched_clock.h @@ -10,7 +10,5 @@ extern void sched_clock_postinit(void); extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); -extern void setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, - unsigned long rate); #endif diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c index e21bac20d90d..fc6692e2b603 100644 --- a/arch/arm/kernel/sched_clock.c +++ b/arch/arm/kernel/sched_clock.c @@ -107,13 +107,6 @@ static void sched_clock_poll(unsigned long wrap_ticks) update_sched_clock(); } -void __init setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, - unsigned long rate) -{ - setup_sched_clock(read, bits, rate); - cd.needs_suspend = true; -} - void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) { unsigned long r, w; @@ -189,18 +182,15 @@ void __init sched_clock_postinit(void) static int sched_clock_suspend(void) { sched_clock_poll(sched_clock_timer.data); - if (cd.needs_suspend) - cd.suspended = true; + cd.suspended = true; return 0; } static void sched_clock_resume(void) { - if (cd.needs_suspend) { - cd.epoch_cyc = read_sched_clock(); - cd.epoch_cyc_copy = cd.epoch_cyc; - cd.suspended = false; - } + cd.epoch_cyc = read_sched_clock(); + cd.epoch_cyc_copy = cd.epoch_cyc; + cd.suspended = false; } static struct syscore_ops sched_clock_ops = { -- cgit v1.2.2 From 39141ddfb63a664f26d3f42f64ee386e879b492c Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 23 Oct 2012 20:32:59 +0100 Subject: ARM: 7566/1: vfp: fix save and restore when running on pre-VFPv3 and CONFIG_VFPv3 set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit 846a136881b8f73c1f74250bf6acfaa309cab1f2 ("ARM: vfp: fix saving d16-d31 vfp registers on v6+ kernels"), the OMAP 2430SDP board started crashing during boot with omap2plus_defconfig: [ 3.875122] mmcblk0: mmc0:e624 SD04G 3.69 GiB [ 3.915954] mmcblk0: p1 [ 4.086639] Internal error: Oops - undefined instruction: 0 [#1] SMP ARM [ 4.093719] Modules linked in: [ 4.096954] CPU: 0 Not tainted (3.6.0-02232-g759e00b #570) [ 4.103149] PC is at vfp_reload_hw+0x1c/0x44 [ 4.107666] LR is at __und_usr_fault_32+0x0/0x8 It turns out that the context save/restore fix unmasked a latent bug in commit 5aaf254409f8d58229107b59507a8235b715a960 ("ARM: 6203/1: Make VFPv3 usable on ARMv6"). When CONFIG_VFPv3 is set, but the kernel is booted on a pre-VFPv3 core, the code attempts to save and restore the d16-d31 VFP registers. These are only present on non-D16 VFPv3+, so this results in an undefined instruction exception. The code didn't crash before commit 846a136 because the save and restore code was only touching d0-d15, present on all VFP. Fix by implementing a request from Russell King to add a new HWCAP flag that affirmatively indicates the presence of the d16-d31 registers: http://marc.info/?l=linux-arm-kernel&m=135013547905283&w=2 and some feedback from Måns to clarify the name of the HWCAP flag. Signed-off-by: Paul Walmsley Cc: Tony Lindgren Cc: Catalin Marinas Cc: Dave Martin Cc: Måns Rullgård Signed-off-by: Russell King --- arch/arm/include/asm/vfpmacros.h | 12 ++++++------ arch/arm/include/uapi/asm/hwcap.h | 3 ++- arch/arm/vfp/vfpmodule.c | 9 ++++++--- 3 files changed, 14 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h index 6a6f1e485f41..301c1db3e99b 100644 --- a/arch/arm/include/asm/vfpmacros.h +++ b/arch/arm/include/asm/vfpmacros.h @@ -27,9 +27,9 @@ #if __LINUX_ARM_ARCH__ <= 6 ldr \tmp, =elf_hwcap @ may not have MVFR regs ldr \tmp, [\tmp, #0] - tst \tmp, #HWCAP_VFPv3D16 - ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} - addne \base, \base, #32*4 @ step over unused register space + tst \tmp, #HWCAP_VFPD32 + ldcnel p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} + addeq \base, \base, #32*4 @ step over unused register space #else VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field @@ -51,9 +51,9 @@ #if __LINUX_ARM_ARCH__ <= 6 ldr \tmp, =elf_hwcap @ may not have MVFR regs ldr \tmp, [\tmp, #0] - tst \tmp, #HWCAP_VFPv3D16 - stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} - addne \base, \base, #32*4 @ step over unused register space + tst \tmp, #HWCAP_VFPD32 + stcnel p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} + addeq \base, \base, #32*4 @ step over unused register space #else VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field diff --git a/arch/arm/include/uapi/asm/hwcap.h b/arch/arm/include/uapi/asm/hwcap.h index f254f6503cce..3688fd15a32d 100644 --- a/arch/arm/include/uapi/asm/hwcap.h +++ b/arch/arm/include/uapi/asm/hwcap.h @@ -18,11 +18,12 @@ #define HWCAP_THUMBEE (1 << 11) #define HWCAP_NEON (1 << 12) #define HWCAP_VFPv3 (1 << 13) -#define HWCAP_VFPv3D16 (1 << 14) +#define HWCAP_VFPv3D16 (1 << 14) /* also set for VFPv4-D16 */ #define HWCAP_TLS (1 << 15) #define HWCAP_VFPv4 (1 << 16) #define HWCAP_IDIVA (1 << 17) #define HWCAP_IDIVT (1 << 18) +#define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */ #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT) diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index c834b32af275..3b44e0dd0a93 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -701,11 +701,14 @@ static int __init vfp_init(void) elf_hwcap |= HWCAP_VFPv3; /* - * Check for VFPv3 D16. CPUs in this configuration - * only have 16 x 64bit registers. + * Check for VFPv3 D16 and VFPv4 D16. CPUs in + * this configuration only have 16 x 64bit + * registers. */ if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1) - elf_hwcap |= HWCAP_VFPv3D16; + elf_hwcap |= HWCAP_VFPv3D16; /* also v4-D16 */ + else + elf_hwcap |= HWCAP_VFPD32; } #endif /* -- cgit v1.2.2 From 7629a9f661f72eb383fb896e59efea1eac74e882 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 26 Oct 2012 18:42:08 +0100 Subject: ARM: 7567/1: io: avoid GCC's offsettable addressing modes for halfword accesses Using the 'o' memory constraint in inline assembly can result in GCC generating invalid immediate offsets for memory access instructions with reduced addressing capabilities (i.e. smaller than 12-bit immediate offsets): http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54983 As there is no constraint to specify the exact addressing mode we need, fallback to using 'Q' exclusively for halfword I/O accesses. This may emit an additional add instruction (using an extra register) in order to construct the address but it will always be accepted by GAS. Reported-by: Bastian Hecht Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/include/asm/io.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 35c1ed89b936..42f042ee4ada 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -64,7 +64,7 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); static inline void __raw_writew(u16 val, volatile void __iomem *addr) { asm volatile("strh %1, %0" - : "+Qo" (*(volatile u16 __force *)addr) + : "+Q" (*(volatile u16 __force *)addr) : "r" (val)); } @@ -72,7 +72,7 @@ static inline u16 __raw_readw(const volatile void __iomem *addr) { u16 val; asm volatile("ldrh %1, %0" - : "+Qo" (*(volatile u16 __force *)addr), + : "+Q" (*(volatile u16 __force *)addr), "=r" (val)); return val; } -- cgit v1.2.2 From 74549de1e439f59465b61b13b6b9de4eff76937f Mon Sep 17 00:00:00 2001 From: Miguel Vadillo Date: Mon, 29 Oct 2012 22:02:13 -0600 Subject: ARM: OMAP2+: clockdomain: Fix OMAP4 ISS clk domain to support only SWSUP Since CAM domain (ISS) has no module wake-up dependency with any other clock domain of the device and the dynamic dependency from L3_main_2 is always disabled, the domain needs to be in force wakeup in order to be able to access it for configure (sysconfig) it or use it. Also since there is no clock in the domain managed automatically by the hardware, there is no use to configure automatic clock domain transition. SW should keep the SW_WKUP domain transition as long as a module in the domain is required to be functional. Signed-off-by: Miguel Vadillo Signed-off-by: Benoit Cousson --- arch/arm/mach-omap2/clockdomains44xx_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index b56d06b48782..95192a062d5d 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -359,7 +359,7 @@ static struct clockdomain iss_44xx_clkdm = { .clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS, .wkdep_srcs = iss_wkup_sleep_deps, .sleepdep_srcs = iss_wkup_sleep_deps, - .flags = CLKDM_CAN_HWSUP_SWSUP, + .flags = CLKDM_CAN_SWSUP, }; static struct clockdomain l3_dss_44xx_clkdm = { -- cgit v1.2.2 From 613ad0e98c3596cd2524172fae2a795c3fc57e4a Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Mon, 29 Oct 2012 22:02:13 -0600 Subject: ARM: OMAP: hwmod: wait for sysreset complete after enabling hwmod When waking up from off-mode, some IP blocks are reset automatically by hardware. For this reason, software must wait until the reset has completed before attempting to access the IP block. This patch fixes for example the bug introduced by commit 6c31b2150ff96755d24e0ab6d6fea08a7bf5c44c ("mmc: omap_hsmmc: remove access to SYSCONFIG register"), in which the MMC IP block is reset during off-mode entry, but the code expects the module to be already available during the execution of context restore. This version includes a fix from Kevin Hilman for GPIO problems on the 37xx EVM - thanks Kevin. Signed-off-by: Tero Kristo Cc: Paul Walmsley Cc: Benoit Cousson Cc: Venkatraman S Tested-by: Kevin Hilman Cc: Kevin Hilman [paul@pwsan.com: moved softreset wait code into separate function; call from top of _enable_sysc() rather than the bottom; include fix from Kevin Hilman for GPIO sluggishness] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 60 ++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index b969ab1d258b..70267d2cf5e5 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -421,6 +421,38 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v) return 0; } +/** + * _wait_softreset_complete - wait for an OCP softreset to complete + * @oh: struct omap_hwmod * to wait on + * + * Wait until the IP block represented by @oh reports that its OCP + * softreset is complete. This can be triggered by software (see + * _ocp_softreset()) or by hardware upon returning from off-mode (one + * example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT + * microseconds. Returns the number of microseconds waited. + */ +static int _wait_softreset_complete(struct omap_hwmod *oh) +{ + struct omap_hwmod_class_sysconfig *sysc; + u32 softrst_mask; + int c = 0; + + sysc = oh->class->sysc; + + if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS) + omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { + softrst_mask = (0x1 << sysc->sysc_fields->srst_shift); + omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs) + & softrst_mask), + MAX_MODULE_SOFTRESET_WAIT, c); + } + + return c; +} + /** * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v * @oh: struct omap_hwmod * @@ -1282,6 +1314,18 @@ static void _enable_sysc(struct omap_hwmod *oh) if (!oh->class->sysc) return; + /* + * Wait until reset has completed, this is needed as the IP + * block is reset automatically by hardware in some cases + * (off-mode for example), and the drivers require the + * IP to be ready when they access it + */ + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) + _enable_optional_clocks(oh); + _wait_softreset_complete(oh); + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) + _disable_optional_clocks(oh); + v = oh->_sysc_cache; sf = oh->class->sysc->sysc_flags; @@ -1804,7 +1848,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh) */ static int _ocp_softreset(struct omap_hwmod *oh) { - u32 v, softrst_mask; + u32 v; int c = 0; int ret = 0; @@ -1834,19 +1878,7 @@ static int _ocp_softreset(struct omap_hwmod *oh) if (oh->class->sysc->srst_udelay) udelay(oh->class->sysc->srst_udelay); - if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) - omap_test_timeout((omap_hwmod_read(oh, - oh->class->sysc->syss_offs) - & SYSS_RESETDONE_MASK), - MAX_MODULE_SOFTRESET_WAIT, c); - else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { - softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); - omap_test_timeout(!(omap_hwmod_read(oh, - oh->class->sysc->sysc_offs) - & softrst_mask), - MAX_MODULE_SOFTRESET_WAIT, c); - } - + c = _wait_softreset_complete(oh); if (c == MAX_MODULE_SOFTRESET_WAIT) pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", oh->name, MAX_MODULE_SOFTRESET_WAIT); -- cgit v1.2.2 From e6d41e8c697e07832efa4a85bf23438bc4c4e1b2 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 29 Oct 2012 18:40:08 +0100 Subject: x86, AMD: Change Boris' email address Move to private email and put in maintained status. Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1351532410-4887-1-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/mcheck/mce_amd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 698b6ec12e0f..1ac581f38dfa 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -6,7 +6,7 @@ * * Written by Jacob Shin - AMD, Inc. * - * Support: borislav.petkov@amd.com + * Maintained by: Borislav Petkov * * April 2006 * - added support for AMD Family 0x10 processors -- cgit v1.2.2 From 943482d07e926128eed0482b879736f912c429e4 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 29 Oct 2012 18:51:38 +0100 Subject: x86, microcode_amd: Change email addresses, MAINTAINERS entry Signed-off-by: Andreas Herrmann Cc: lm-sensors@lm-sensors.org Cc: oprofile-list@lists.sf.net Cc: Stephane Eranian Cc: Robert Richter Cc: Borislav Petkov Cc: Jorg Roedel Cc: Rafael J. Wysocki Cc: Jean Delvare Cc: Guenter Roeck Link: http://lkml.kernel.org/r/20121029175138.GC5024@tweety Signed-off-by: Ingo Molnar --- arch/x86/kernel/microcode_amd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index 7720ff5a9ee2..b3e67ba55b77 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c @@ -8,8 +8,8 @@ * Tigran Aivazian * * Maintainers: - * Andreas Herrmann - * Borislav Petkov + * Andreas Herrmann + * Borislav Petkov * * This driver allows to upgrade microcode on F10h AMD * CPUs and later. -- cgit v1.2.2 From f49f4ab95c301dbccad0efe85296d908b8ae7ad4 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 29 Oct 2012 14:40:18 +0100 Subject: x86/ce4100: Fix pm_poweroff The CE4100 platform is currently missing a proper pm_poweroff implementation leading to poweroff making the CPU spin forever and the CE4100 platform does not enter a low-power mode where the external Power Management Unit can properly power off the system. Power off on this platform is implemented pretty much like reboot, by writing to the SoC built-in 8051 microcontroller mapped at I/O port 0xcf9, the value 0x4. Signed-off-by: Florian Fainelli Acked-by: Sebastian Andrzej Siewior Cc: rui.zhang@intel.com Cc: alan@linux.intel.com Link: http://lkml.kernel.org/r/1351518020-25556-2-git-send-email-ffainelli@freebox.fr Signed-off-by: Ingo Molnar --- arch/x86/platform/ce4100/ce4100.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch') diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c index 4c61b52191eb..5de16e359fe6 100644 --- a/arch/x86/platform/ce4100/ce4100.c +++ b/arch/x86/platform/ce4100/ce4100.c @@ -27,6 +27,18 @@ static int ce4100_i8042_detect(void) return 0; } +/* + * The CE4100 platform has an internal 8051 Microcontroller which is + * responsible for signaling to the external Power Management Unit the + * intention to reset, reboot or power off the system. This 8051 device has + * its command register mapped at I/O port 0xcf9 and the value 0x4 is used + * to power off the system. + */ +static void ce4100_power_off(void) +{ + outb(0x4, 0xcf9); +} + #ifdef CONFIG_SERIAL_8250 static unsigned int mem_serial_in(struct uart_port *p, int offset) @@ -143,4 +155,6 @@ void __init x86_ce4100_early_setup(void) x86_init.pci.init_irq = sdv_pci_init; x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck; #endif + + pm_power_off = ce4100_power_off; } -- cgit v1.2.2 From d7959916026aaae60e1878ae33c7503b2cc4471d Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Mon, 29 Oct 2012 14:40:19 +0100 Subject: x86/ce4100: Fix reboot by forcing the reboot method to be KBD The default reboot is via ACPI for this platform, and the CEFDK bootloader actually supports this, but will issue a system power off instead of a real reboot. Setting the reboot method to be KBD instead of ACPI ensures proper system reboot. Acked-by: Sebastian Andrzej Siewior Signed-off-by: Maxime Bizon Signed-off-by: Florian Fainelli Cc: rui.zhang@intel.com Cc: alan@linux.intel.com Link: http://lkml.kernel.org/r/1351518020-25556-3-git-send-email-ffainelli@freebox.fr Signed-off-by: Ingo Molnar --- arch/x86/platform/ce4100/ce4100.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c index 5de16e359fe6..92525cb8e54c 100644 --- a/arch/x86/platform/ce4100/ce4100.c +++ b/arch/x86/platform/ce4100/ce4100.c @@ -21,6 +21,7 @@ #include #include #include +#include static int ce4100_i8042_detect(void) { @@ -151,6 +152,15 @@ void __init x86_ce4100_early_setup(void) x86_init.mpparse.find_smp_config = x86_init_noop; x86_init.pci.init = ce4100_pci_init; + /* + * By default, the reboot method is ACPI which is supported by the + * CE4100 bootloader CEFDK using FADT.ResetReg Address and ResetValue + * the bootloader will however issue a system power off instead of + * reboot. By using BOOT_KBD we ensure proper system reboot as + * expected. + */ + reboot_type = BOOT_KBD; + #ifdef CONFIG_X86_IO_APIC x86_init.pci.init_irq = sdv_pci_init; x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck; -- cgit v1.2.2 From 37aeec36220c39f1b2e7118287d951fd9cfdd6b7 Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Mon, 29 Oct 2012 14:40:20 +0100 Subject: x86/ce4100: Fix PCI configuration register access for devices without interrupts Some CE4100 devices such as the: - DFX module (01:0b.7) - entertainment encryption device (01:10.0) - multimedia controller (01:12.0) do not have a device interrupt at all. This patch fixes the PCI controller code to declare the missing PCI configuration register space, as well as a fixup method for forcing the interrupt pin to be 0 for these devices. This is required to ensure that pci drivers matching on these devices will be able to honor the various PCI subsystem calls touching the configuration space. Signed-off-by: Maxime Bizon Signed-off-by: Florian Fainelli Acked-by: Sebastian Andrzej Siewior Cc: rui.zhang@intel.com Cc: alan@linux.intel.com Link: http://lkml.kernel.org/r/1351518020-25556-4-git-send-email-ffainelli@freebox.fr Signed-off-by: Ingo Molnar --- arch/x86/pci/ce4100.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'arch') diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c index 41bd2a2d2c50..b914e20b5a00 100644 --- a/arch/x86/pci/ce4100.c +++ b/arch/x86/pci/ce4100.c @@ -115,6 +115,16 @@ static void sata_revid_read(struct sim_dev_reg *reg, u32 *value) reg_read(reg, value); } +static void reg_noirq_read(struct sim_dev_reg *reg, u32 *value) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&pci_config_lock, flags); + /* force interrupt pin value to 0 */ + *value = reg->sim_reg.value & 0xfff00ff; + raw_spin_unlock_irqrestore(&pci_config_lock, flags); +} + static struct sim_dev_reg bus1_fixups[] = { DEFINE_REG(2, 0, 0x10, (16*MB), reg_init, reg_read, reg_write) DEFINE_REG(2, 0, 0x14, (256), reg_init, reg_read, reg_write) @@ -144,6 +154,7 @@ static struct sim_dev_reg bus1_fixups[] = { DEFINE_REG(11, 5, 0x10, (64*KB), reg_init, reg_read, reg_write) DEFINE_REG(11, 6, 0x10, (256), reg_init, reg_read, reg_write) DEFINE_REG(11, 7, 0x10, (64*KB), reg_init, reg_read, reg_write) + DEFINE_REG(11, 7, 0x3c, 256, reg_init, reg_noirq_read, reg_write) DEFINE_REG(12, 0, 0x10, (128*KB), reg_init, reg_read, reg_write) DEFINE_REG(12, 0, 0x14, (256), reg_init, reg_read, reg_write) DEFINE_REG(12, 1, 0x10, (1024), reg_init, reg_read, reg_write) @@ -161,8 +172,10 @@ static struct sim_dev_reg bus1_fixups[] = { DEFINE_REG(16, 0, 0x10, (64*KB), reg_init, reg_read, reg_write) DEFINE_REG(16, 0, 0x14, (64*MB), reg_init, reg_read, reg_write) DEFINE_REG(16, 0, 0x18, (64*MB), reg_init, reg_read, reg_write) + DEFINE_REG(16, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write) DEFINE_REG(17, 0, 0x10, (128*KB), reg_init, reg_read, reg_write) DEFINE_REG(18, 0, 0x10, (1*KB), reg_init, reg_read, reg_write) + DEFINE_REG(18, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write) }; static void __init init_sim_regs(void) -- cgit v1.2.2 From b6514633bdc6a511f7c44b3ecb86d6071374239d Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Thu, 25 Oct 2012 11:00:24 +0200 Subject: x86: remove obsolete comment from asm/xen/hypervisor.h Signed-off-by: Olaf Hering Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/include/asm/xen/hypervisor.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h index 66d0fff1ee84..125f344f06a9 100644 --- a/arch/x86/include/asm/xen/hypervisor.h +++ b/arch/x86/include/asm/xen/hypervisor.h @@ -33,7 +33,6 @@ #ifndef _ASM_X86_XEN_HYPERVISOR_H #define _ASM_X86_XEN_HYPERVISOR_H -/* arch/i386/kernel/setup.c */ extern struct shared_info *HYPERVISOR_shared_info; extern struct start_info *xen_start_info; -- cgit v1.2.2 From c8d258a7b2b6633b79cad4464e8dfb3dc328d897 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Wed, 24 Oct 2012 16:26:08 +0100 Subject: xen/arm: use the __HVC macro Use the new __HVC macro in hypercall.S. Signed-off-by: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk --- arch/arm/xen/hypercall.S | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/xen/hypercall.S b/arch/arm/xen/hypercall.S index 074f5ed101b9..71f723984cbd 100644 --- a/arch/arm/xen/hypercall.S +++ b/arch/arm/xen/hypercall.S @@ -48,20 +48,16 @@ #include #include +#include #include -/* HVC 0xEA1 */ -#ifdef CONFIG_THUMB2_KERNEL -#define xen_hvc .word 0xf7e08ea1 -#else -#define xen_hvc .word 0xe140ea71 -#endif +#define XEN_IMM 0xEA1 #define HYPERCALL_SIMPLE(hypercall) \ ENTRY(HYPERVISOR_##hypercall) \ mov r12, #__HYPERVISOR_##hypercall; \ - xen_hvc; \ + __HVC(XEN_IMM); \ mov pc, lr; \ ENDPROC(HYPERVISOR_##hypercall) @@ -76,7 +72,7 @@ ENTRY(HYPERVISOR_##hypercall) \ stmdb sp!, {r4} \ ldr r4, [sp, #4] \ mov r12, #__HYPERVISOR_##hypercall; \ - xen_hvc \ + __HVC(XEN_IMM); \ ldm sp!, {r4} \ mov pc, lr \ ENDPROC(HYPERVISOR_##hypercall) @@ -100,7 +96,7 @@ ENTRY(privcmd_call) mov r2, r3 ldr r3, [sp, #8] ldr r4, [sp, #4] - xen_hvc + __HVC(XEN_IMM) ldm sp!, {r4} mov pc, lr ENDPROC(privcmd_call); -- cgit v1.2.2 From 322337b8fbd8c392246529d5db924820fc0c7381 Mon Sep 17 00:00:00 2001 From: Pritesh Raithatha Date: Tue, 30 Oct 2012 15:37:09 +0530 Subject: ARM: dt: tegra: fix length of pad control and mux registers The reg property contains not . Fix the length values to be length not last_offset. Cc: stable@vger.kernel.org Signed-off-by: Pritesh Raithatha Signed-off-by: Stephen Warren --- arch/arm/boot/dts/tegra30.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index b1497c7d7d68..df7f2270fc91 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -73,8 +73,8 @@ pinmux: pinmux { compatible = "nvidia,tegra30-pinmux"; - reg = <0x70000868 0xd0 /* Pad control registers */ - 0x70003000 0x3e0>; /* Mux registers */ + reg = <0x70000868 0xd4 /* Pad control registers */ + 0x70003000 0x3e4>; /* Mux registers */ }; serial@70006000 { -- cgit v1.2.2 From 85b97637bb40a9f486459dd254598759af9c3d50 Mon Sep 17 00:00:00 2001 From: Tang Chen Date: Mon, 29 Oct 2012 11:01:50 +0800 Subject: x86/mce: Do not change worker's running cpu in cmci_rediscover(). cmci_rediscover() used set_cpus_allowed_ptr() to change the current process's running cpu, and migrate itself to the dest cpu. But worker processes are not allowed to be migrated. If current is a worker, the worker will be migrated to another cpu, but the corresponding worker_pool is still on the original cpu. In this case, the following BUG_ON in try_to_wake_up_local() will be triggered: BUG_ON(rq != this_rq()); This will cause the kernel panic. The call trace is like the following: [ 6155.451107] ------------[ cut here ]------------ [ 6155.452019] kernel BUG at kernel/sched/core.c:1654! ...... [ 6155.452019] RIP: 0010:[] [] try_to_wake_up_local+0x115/0x130 ...... [ 6155.452019] Call Trace: [ 6155.452019] [] __schedule+0x764/0x880 [ 6155.452019] [] schedule+0x29/0x70 [ 6155.452019] [] schedule_timeout+0x235/0x2d0 [ 6155.452019] [] ? mark_held_locks+0x8d/0x140 [ 6155.452019] [] ? __lock_release+0x133/0x1a0 [ 6155.452019] [] ? _raw_spin_unlock_irq+0x30/0x50 [ 6155.452019] [] ? trace_hardirqs_on_caller+0x105/0x190 [ 6155.452019] [] wait_for_common+0x12b/0x180 [ 6155.452019] [] ? try_to_wake_up+0x2f0/0x2f0 [ 6155.452019] [] wait_for_completion+0x1d/0x20 [ 6155.452019] [] stop_one_cpu+0x8a/0xc0 [ 6155.452019] [] ? __migrate_task+0x1a0/0x1a0 [ 6155.452019] [] ? complete+0x28/0x60 [ 6155.452019] [] set_cpus_allowed_ptr+0x128/0x130 [ 6155.452019] [] cmci_rediscover+0xf5/0x140 [ 6155.452019] [] mce_cpu_callback+0x18d/0x19d [ 6155.452019] [] notifier_call_chain+0x67/0x150 [ 6155.452019] [] __raw_notifier_call_chain+0xe/0x10 [ 6155.452019] [] __cpu_notify+0x20/0x40 [ 6155.452019] [] cpu_notify_nofail+0x15/0x30 [ 6155.452019] [] _cpu_down+0x262/0x2e0 [ 6155.452019] [] cpu_down+0x36/0x50 [ 6155.452019] [] acpi_processor_remove+0x50/0x11e [ 6155.452019] [] acpi_device_remove+0x90/0xb2 [ 6155.452019] [] __device_release_driver+0x7c/0xf0 [ 6155.452019] [] device_release_driver+0x2f/0x50 [ 6155.452019] [] acpi_bus_remove+0x32/0x6d [ 6155.452019] [] acpi_bus_trim+0x87/0xee [ 6155.452019] [] acpi_bus_hot_remove_device+0x88/0x16b [ 6155.452019] [] acpi_os_execute_deferred+0x27/0x34 [ 6155.452019] [] process_one_work+0x219/0x680 [ 6155.452019] [] ? process_one_work+0x1b8/0x680 [ 6155.452019] [] ? acpi_os_wait_events_complete+0x23/0x23 [ 6155.452019] [] worker_thread+0x12e/0x320 [ 6155.452019] [] ? manage_workers+0x110/0x110 [ 6155.452019] [] kthread+0xc6/0xd0 [ 6155.452019] [] kernel_thread_helper+0x4/0x10 [ 6155.452019] [] ? retint_restore_args+0x13/0x13 [ 6155.452019] [] ? __init_kthread_worker+0x70/0x70 [ 6155.452019] [] ? gs_change+0x13/0x13 This patch removes the set_cpus_allowed_ptr() call, and put the cmci rediscover jobs onto all the other cpus using system_wq. This could bring some delay for the jobs. Signed-off-by: Tang Chen Signed-off-by: Miao Xie Signed-off-by: Tony Luck --- arch/x86/kernel/cpu/mcheck/mce_intel.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index 5f88abf07e9c..4f9a3cbfc4a3 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c @@ -285,34 +285,39 @@ void cmci_clear(void) raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); } +static long cmci_rediscover_work_func(void *arg) +{ + int banks; + + /* Recheck banks in case CPUs don't all have the same */ + if (cmci_supported(&banks)) + cmci_discover(banks); + + return 0; +} + /* * After a CPU went down cycle through all the others and rediscover * Must run in process context. */ void cmci_rediscover(int dying) { - int banks; - int cpu; - cpumask_var_t old; + int cpu, banks; if (!cmci_supported(&banks)) return; - if (!alloc_cpumask_var(&old, GFP_KERNEL)) - return; - cpumask_copy(old, ¤t->cpus_allowed); for_each_online_cpu(cpu) { if (cpu == dying) continue; - if (set_cpus_allowed_ptr(current, cpumask_of(cpu))) + + if (cpu == smp_processor_id()) { + cmci_rediscover_work_func(NULL); continue; - /* Recheck banks in case CPUs don't all have the same */ - if (cmci_supported(&banks)) - cmci_discover(banks); - } + } - set_cpus_allowed_ptr(current, old); - free_cpumask_var(old); + work_on_cpu(cpu, cmci_rediscover_work_func, NULL); + } } /* -- cgit v1.2.2 From 5fb3d522efca4b3a369040d37d1380103411db74 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Mon, 29 Oct 2012 22:11:50 -0600 Subject: ARM: OMAP2+: hwmod: add flag to prevent hwmod code from touching IP block during init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add HWMOD_EXT_OPT_MAIN_CLK flag to indicate that this IP block is dependent on an off-chip functional clock that is not guaranteed to be present during initialization. IP blocks marked with this flag are left in the INITIALIZED state during kernel init. This is a workaround for a hardware problem. It should be possible to guarantee that at least one clock source will be present and active for any IP block's main functional clock. This ensures that the hwmod code can enable and reset the IP block. Resetting the IP block during kernel init prevents any bogus bootloader, ROM code, or previous OS configuration from affecting the kernel. Hopefully a clock multiplexer can be added on future SoCs. N.B., at some point in the future, it should be possible to query the clock framework for this type of information. Then this flag should no longer be needed. Signed-off-by: Paul Walmsley Cc: Benoît Cousson --- arch/arm/mach-omap2/omap_hwmod.c | 3 +++ arch/arm/plat-omap/include/plat/omap_hwmod.h | 6 ++++++ 2 files changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 70267d2cf5e5..87cc6d058de2 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2384,6 +2384,9 @@ static int __init _setup_reset(struct omap_hwmod *oh) if (oh->_state != _HWMOD_STATE_INITIALIZED) return -EINVAL; + if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK) + return -EPERM; + if (oh->rst_lines_cnt == 0) { r = _enable(oh); if (r) { diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index b3349f7b1a2c..1db029438022 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -443,6 +443,11 @@ struct omap_hwmod_omap4_prcm { * in order to complete the reset. Optional clocks will be disabled * again after the reset. * HWMOD_16BIT_REG: Module has 16bit registers + * HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for + * this IP block comes from an off-chip source and is not always + * enabled. This prevents the hwmod code from being able to + * enable and reset the IP block early. XXX Eventually it should + * be possible to query the clock framework for this information. */ #define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_MSTANDBY (1 << 1) @@ -453,6 +458,7 @@ struct omap_hwmod_omap4_prcm { #define HWMOD_NO_IDLEST (1 << 6) #define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) #define HWMOD_16BIT_REG (1 << 8) +#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) /* * omap_hwmod._int_flags definitions -- cgit v1.2.2 From bc05244e65f26b7b6f87e0964bfe277803914ed9 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Mon, 29 Oct 2012 22:02:14 -0600 Subject: ARM: OMAP4: hwmod data: do not enable or reset the McPDM during kernel init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve this kernel boot message: omap_hwmod: mcpdm: cannot be enabled for reset (3) The McPDM on OMAP4 can only receive its functional clock from an off-chip source. This source is not guaranteed to be present on the board, and when present, it is controlled by I2C. This would introduce a board dependency to the early hwmod code which it was not designed to handle. Also, neither the driver for this off-chip clock provider nor the I2C code is available early in boot when the hwmod code is attempting to enable and reset IP blocks. This effectively makes it impossible to enable and reset this device during hwmod init. At its core, this patch is a workaround for an OMAP hardware problem. It should be possible to configure the OMAP to provide any IP block's functional clock from an on-chip source. (This is true for almost every IP block on the chip. As far as I know, McPDM is the only exception.) If the kernel cannot reset and configure IP blocks, it cannot guarantee a sane SoC state. Relying on an optional off-chip clock also creates a board dependency which is beyond the scope of the early hwmod code. This patch works around the issue by marking the McPDM hwmod record with the HWMOD_EXT_OPT_MAIN_CLK flag. This prevents the hwmod code from touching the device early during boot. Signed-off-by: Paul Walmsley Cc: Péter Ujfalusi Cc: Benoît Cousson Acked-by: Peter Ujfalusi --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 652d0285bd6d..7bddfa5534f9 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -2125,6 +2125,14 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { .name = "mcpdm", .class = &omap44xx_mcpdm_hwmod_class, .clkdm_name = "abe_clkdm", + /* + * It's suspected that the McPDM requires an off-chip main + * functional clock, controlled via I2C. This IP block is + * currently reset very early during boot, before I2C is + * available, so it doesn't seem that we have any choice in + * the kernel other than to avoid resetting it. + */ + .flags = HWMOD_EXT_OPT_MAIN_CLK, .mpu_irqs = omap44xx_mcpdm_irqs, .sdma_reqs = omap44xx_mcpdm_sdma_reqs, .main_clk = "mcpdm_fck", -- cgit v1.2.2 From 95a7d76897c1e7243d4137037c66d15cbf2cce76 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 31 Oct 2012 12:38:31 -0400 Subject: xen/mmu: Use Xen specific TLB flush instead of the generic one. As Mukesh explained it, the MMUEXT_TLB_FLUSH_ALL allows the hypervisor to do a TLB flush on all active vCPUs. If instead we were using the generic one (which ends up being xen_flush_tlb) we end up making the MMUEXT_TLB_FLUSH_LOCAL hypercall. But before we make that hypercall the kernel will IPI all of the vCPUs (even those that were asleep from the hypervisor perspective). The end result is that we needlessly wake them up and do a TLB flush when we can just let the hypervisor do it correctly. This patch gives around 50% speed improvement when migrating idle guest's from one host to another. Oracle-bug: 14630170 CC: stable@vger.kernel.org Tested-by: Jingjie Jiang Suggested-by: Mukesh Rathor Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/xen/mmu.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 6226c99729b9..dcf5f2dd91ec 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1288,6 +1288,25 @@ unsigned long xen_read_cr2_direct(void) return this_cpu_read(xen_vcpu_info.arch.cr2); } +void xen_flush_tlb_all(void) +{ + struct mmuext_op *op; + struct multicall_space mcs; + + trace_xen_mmu_flush_tlb_all(0); + + preempt_disable(); + + mcs = xen_mc_entry(sizeof(*op)); + + op = mcs.args; + op->cmd = MMUEXT_TLB_FLUSH_ALL; + MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); + + xen_mc_issue(PARAVIRT_LAZY_MMU); + + preempt_enable(); +} static void xen_flush_tlb(void) { struct mmuext_op *op; @@ -2518,7 +2537,7 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma, err = 0; out: - flush_tlb_all(); + xen_flush_tlb_all(); return err; } -- cgit v1.2.2 From 2bbf0a1427c377350f001fbc6260995334739ad7 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 31 Oct 2012 17:20:50 +0100 Subject: x86, amd: Disable way access filter on Piledriver CPUs The Way Access Filter in recent AMD CPUs may hurt the performance of some workloads, caused by aliasing issues in the L1 cache. This patch disables it on the affected CPUs. The issue is similar to that one of last year: http://lkml.indiana.edu/hypermail/linux/kernel/1107.3/00041.html This new patch does not replace the old one, we just need another quirk for newer CPUs. The performance penalty without the patch depends on the circumstances, but is a bit less than the last year's 3%. The workloads affected would be those that access code from the same physical page under different virtual addresses, so different processes using the same libraries with ASLR or multiple instances of PIE-binaries. The code needs to be accessed simultaneously from both cores of the same compute unit. More details can be found here: http://developer.amd.com/Assets/SharedL1InstructionCacheonAMD15hCPU.pdf CPUs affected are anything with the core known as Piledriver. That includes the new parts of the AMD A-Series (aka Trinity) and the just released new CPUs of the FX-Series (aka Vishera). The model numbering is a bit odd here: FX CPUs have model 2, A-Series has model 10h, with possible extensions to 1Fh. Hence the range of model ids. Signed-off-by: Andre Przywara Link: http://lkml.kernel.org/r/1351700450-9277-1-git-send-email-osp@andrep.de Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/amd.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index f7e98a2c0d12..1b7d1656a042 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -631,6 +631,20 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) } } + /* + * The way access filter has a performance penalty on some workloads. + * Disable it on the affected CPUs. + */ + if ((c->x86 == 0x15) && + (c->x86_model >= 0x02) && (c->x86_model < 0x20)) { + u64 val; + + if (!rdmsrl_safe(0xc0011021, &val) && !(val & 0x1E)) { + val |= 0x1E; + wrmsrl_safe(0xc0011021, val); + } + } + cpu_detect_cache_sizes(c); /* Multi core CPU? */ -- cgit v1.2.2 From 87da7e66a40532b743cd50972fcf85a1f15b14ea Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Wed, 24 Oct 2012 14:07:59 +0800 Subject: KVM: x86: fix vcpu->mmio_fragments overflow After commit b3356bf0dbb349 (KVM: emulator: optimize "rep ins" handling), the pieces of io data can be collected and write them to the guest memory or MMIO together Unfortunately, kvm splits the mmio access into 8 bytes and store them to vcpu->mmio_fragments. If the guest uses "rep ins" to move large data, it will cause vcpu->mmio_fragments overflow The bug can be exposed by isapc (-M isapc): [23154.818733] general protection fault: 0000 [#1] SMP DEBUG_PAGEALLOC [ ......] [23154.858083] Call Trace: [23154.859874] [] kvm_get_cr8+0x1d/0x28 [kvm] [23154.861677] [] kvm_arch_vcpu_ioctl_run+0xcda/0xe45 [kvm] [23154.863604] [] ? kvm_arch_vcpu_load+0x17b/0x180 [kvm] Actually, we can use one mmio_fragment to store a large mmio access then split it when we pass the mmio-exit-info to userspace. After that, we only need two entries to store mmio info for the cross-mmio pages access Signed-off-by: Xiao Guangrong Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/x86.c | 60 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 1eefebe5d727..224a7e78cb6c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3779,7 +3779,7 @@ static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, { struct kvm_mmio_fragment *frag = &vcpu->mmio_fragments[0]; - memcpy(vcpu->run->mmio.data, frag->data, frag->len); + memcpy(vcpu->run->mmio.data, frag->data, min(8u, frag->len)); return X86EMUL_CONTINUE; } @@ -3832,18 +3832,11 @@ mmio: bytes -= handled; val += handled; - while (bytes) { - unsigned now = min(bytes, 8U); - - frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; - frag->gpa = gpa; - frag->data = val; - frag->len = now; - - gpa += now; - val += now; - bytes -= now; - } + WARN_ON(vcpu->mmio_nr_fragments >= KVM_MAX_MMIO_FRAGMENTS); + frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; + frag->gpa = gpa; + frag->data = val; + frag->len = bytes; return X86EMUL_CONTINUE; } @@ -3890,7 +3883,7 @@ int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr, vcpu->mmio_needed = 1; vcpu->mmio_cur_fragment = 0; - vcpu->run->mmio.len = vcpu->mmio_fragments[0].len; + vcpu->run->mmio.len = min(8u, vcpu->mmio_fragments[0].len); vcpu->run->mmio.is_write = vcpu->mmio_is_write = ops->write; vcpu->run->exit_reason = KVM_EXIT_MMIO; vcpu->run->mmio.phys_addr = gpa; @@ -5522,28 +5515,44 @@ static int complete_emulated_pio(struct kvm_vcpu *vcpu) * * read: * for each fragment - * write gpa, len - * exit - * copy data + * for each mmio piece in the fragment + * write gpa, len + * exit + * copy data * execute insn * * write: * for each fragment - * write gpa, len - * copy data - * exit + * for each mmio piece in the fragment + * write gpa, len + * copy data + * exit */ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) { struct kvm_run *run = vcpu->run; struct kvm_mmio_fragment *frag; + unsigned len; BUG_ON(!vcpu->mmio_needed); /* Complete previous fragment */ - frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++]; + frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment]; + len = min(8u, frag->len); if (!vcpu->mmio_is_write) - memcpy(frag->data, run->mmio.data, frag->len); + memcpy(frag->data, run->mmio.data, len); + + if (frag->len <= 8) { + /* Switch to the next fragment. */ + frag++; + vcpu->mmio_cur_fragment++; + } else { + /* Go forward to the next mmio piece. */ + frag->data += len; + frag->gpa += len; + frag->len -= len; + } + if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) { vcpu->mmio_needed = 0; if (vcpu->mmio_is_write) @@ -5551,13 +5560,12 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) vcpu->mmio_read_completed = 1; return complete_emulated_io(vcpu); } - /* Initiate next fragment */ - ++frag; + run->exit_reason = KVM_EXIT_MMIO; run->mmio.phys_addr = frag->gpa; if (vcpu->mmio_is_write) - memcpy(run->mmio.data, frag->data, frag->len); - run->mmio.len = frag->len; + memcpy(run->mmio.data, frag->data, min(8u, frag->len)); + run->mmio.len = min(8u, frag->len); run->mmio.is_write = vcpu->mmio_is_write; vcpu->arch.complete_userspace_io = complete_emulated_mmio; return 0; -- cgit v1.2.2 From a5788caa269e446201018bb8879a1dd90f41d32b Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 2 Nov 2012 13:20:42 +0000 Subject: FRV: Add missing linux/export.h #inclusions Add missing linux/export.h #inclusions to the FRV arch. Signed-off-by: David Howells --- arch/frv/mb93090-mb00/pci-dma-nommu.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c index e47857f889b6..b99c2a7cc7a4 100644 --- a/arch/frv/mb93090-mb00/pci-dma-nommu.c +++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include -- cgit v1.2.2 From 5f0231d97b2d361292b090b81479a68123010376 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 2 Nov 2012 13:20:42 +0000 Subject: FRV: Don't objcopy the GNU build_id note Don't let objcopy transfer the GNU build_id note into the loadable image as it is located at address 0 and the image ends up >3G in size. Signed-off-by: David Howells --- arch/frv/boot/Makefile | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/frv/boot/Makefile b/arch/frv/boot/Makefile index 6ae3254da019..636d5bbcd53f 100644 --- a/arch/frv/boot/Makefile +++ b/arch/frv/boot/Makefile @@ -17,6 +17,8 @@ PARAMS_PHYS = 0x0207c000 INITRD_PHYS = 0x02180000 INITRD_VIRT = 0x02180000 +OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment + # # If you don't define ZRELADDR above, # then it defaults to ZTEXTADDR @@ -32,18 +34,18 @@ Image: $(obj)/Image targets: $(obj)/Image $(obj)/Image: vmlinux FORCE - $(OBJCOPY) -O binary -R .note -R .comment -S vmlinux $@ + $(OBJCOPY) $(OBJCOPYFLAGS) -S vmlinux $@ #$(obj)/Image: $(CONFIGURE) $(SYSTEM) -# $(OBJCOPY) -O binary -R .note -R .comment -g -S $(SYSTEM) $@ +# $(OBJCOPY) $(OBJCOPYFLAGS) -g -S $(SYSTEM) $@ bzImage: zImage zImage: $(CONFIGURE) compressed/$(LINUX) - $(OBJCOPY) -O binary -R .note -R .comment -S compressed/$(LINUX) $@ + $(OBJCOPY) $(OBJCOPYFLAGS) -S compressed/$(LINUX) $@ bootpImage: bootp/bootp - $(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@ + $(OBJCOPY) $(OBJCOPYFLAGS) -S bootp/bootp $@ compressed/$(LINUX): $(LINUX) dep @$(MAKE) -C compressed $(LINUX) -- cgit v1.2.2 From 1ee6f5669a7eaba0e2f4e0dd0599b56eb8a9a090 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 2 Nov 2012 13:20:42 +0000 Subject: FRV: Fix the preemption handling Fix the preemption handling in FRV code where the PREEMPT_ACTIVE value is incorrectly loaded into the threadinfo flags rather than the threadinfo preemption count. Unfortunately, the code cannot be simply converted to use preempt_schedule_irq() as is because FRV uses virtual interrupt disablement to cut down on the cost of actually disabling interrupts and thus local_irq_enable() doesn't actually enable interrupts. Reported-by: Al Viro Signed-off-by: David Howells cc: Al Viro --- arch/frv/kernel/entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index ee0beb354e4d..d64c52627961 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S @@ -1086,7 +1086,7 @@ __entry_preempt_need_resched: beq icc0,#1,__entry_return_direct setlos #PREEMPT_ACTIVE,gr5 - sti gr5,@(gr15,#TI_FLAGS) + sti gr5,@(gr15,#TI_PRE_COUNT) andi gr23,#~PSR_PIL,gr23 movgs gr23,psr -- cgit v1.2.2 From e7aa51b2e52274b13be3209e2787d1b2ce9624fd Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 2 Nov 2012 13:20:43 +0000 Subject: FRV: Fix the new-style kernel_thread() stuff The kernel_thread() changes for FRV don't work, and FRV fails to boot, starting with: commit 02ce496f152df87be081a64796498942c433a2fd Author: Al Viro Date: Tue Sep 18 22:18:51 2012 -0400 Subject: frv: split ret_from_fork, simplify kernel_thread() a lot The problem is that the userspace registers are completely cleared when a kernel thread is created and all subsequent user threads are then copied from that. Unfortunately, however, the TBR and PSR registers are restored from the pt_regs and the values they should be set to are clobbered by the memset. Instead, copy across the old user registers as normal, and then merely alter GR8 and GR9 in it if we're going to execute a kernel thread. Signed-off-by: David Howells --- arch/frv/kernel/process.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c index e1e3aa196aa4..7e33215f1d8f 100644 --- a/arch/frv/kernel/process.c +++ b/arch/frv/kernel/process.c @@ -181,6 +181,9 @@ int copy_thread(unsigned long clone_flags, childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE); + /* set up the userspace frame (the only place that the USP is stored) */ + *childregs = *__kernel_frame0_ptr; + p->set_child_tid = p->clear_child_tid = NULL; p->thread.frame = childregs; @@ -191,10 +194,8 @@ int copy_thread(unsigned long clone_flags, p->thread.frame0 = childregs; if (unlikely(!regs)) { - memset(childregs, 0, sizeof(struct pt_regs)); childregs->gr9 = usp; /* function */ childregs->gr8 = arg; - childregs->psr = PSR_S; p->thread.pc = (unsigned long) ret_from_kernel_thread; save_user_regs(p->thread.user); return 0; -- cgit v1.2.2 From 7b7ade117951dcc5ec947595ea7ff622fa56895e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 15 Oct 2012 10:53:17 -0400 Subject: frv: switch to saner kernel_execve() semantics Signed-off-by: Al Viro --- arch/frv/Kconfig | 1 + arch/frv/include/asm/unistd.h | 1 - arch/frv/kernel/entry.S | 5 ----- 3 files changed, 1 insertion(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index b7412504f08a..df2eb4bd9fa2 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -13,6 +13,7 @@ config FRV select GENERIC_CPU_DEVICES select ARCH_WANT_IPC_PARSE_VERSION select GENERIC_KERNEL_THREAD + select GENERIC_KERNEL_EXECVE config ZONE_DMA bool diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h index 266a5b25a0c1..2358634cacca 100644 --- a/arch/frv/include/asm/unistd.h +++ b/arch/frv/include/asm/unistd.h @@ -30,7 +30,6 @@ #define __ARCH_WANT_SYS_RT_SIGACTION #define __ARCH_WANT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_SYS_EXECVE -#define __ARCH_WANT_KERNEL_EXECVE /* * "Conditional" syscalls diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index d64c52627961..b1cd7e8145bb 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S @@ -869,11 +869,6 @@ ret_from_kernel_thread: call schedule_tail calll.p @(gr21,gr0) or gr20,gr20,gr8 - bra sys_exit - - .globl ret_from_kernel_execve -ret_from_kernel_execve: - ori gr28,0,sp bra __syscall_exit ################################################################################################### -- cgit v1.2.2 From 1d72d9f83df057e71c7951def41138a0230bf737 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 2 Nov 2012 12:05:44 -0400 Subject: frv: fix the broken preempt Just get %icc2 into the state we would have after local_irq_disable() and physical IRQ having happened since then. Then we can simply use preempt_schedule_irq() and be done with the whole mess. Acked-by: David Howells Signed-off-by: Al Viro --- arch/frv/kernel/entry.S | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index b1cd7e8145bb..dfcd263c0517 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S @@ -1075,27 +1075,10 @@ __entry_return_from_kernel_interrupt: subicc gr5,#0,gr0,icc0 beq icc0,#0,__entry_return_direct -__entry_preempt_need_resched: - ldi @(gr15,#TI_FLAGS),gr4 - andicc gr4,#_TIF_NEED_RESCHED,gr0,icc0 - beq icc0,#1,__entry_return_direct - - setlos #PREEMPT_ACTIVE,gr5 - sti gr5,@(gr15,#TI_PRE_COUNT) - - andi gr23,#~PSR_PIL,gr23 - movgs gr23,psr - - call schedule - sti gr0,@(gr15,#TI_PRE_COUNT) - - movsg psr,gr23 - ori gr23,#PSR_PIL_14,gr23 - movgs gr23,psr - bra __entry_preempt_need_resched -#else - bra __entry_return_direct + subcc gr0,gr0,gr0,icc2 /* set Z and clear C */ + call preempt_schedule_irq #endif + bra __entry_return_direct ############################################################################### -- cgit v1.2.2 From 6404f0b71c44cfd612ddf28627de31b4604d1d6e Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Wed, 31 Oct 2012 10:40:42 +0100 Subject: ARM: 7569/1: mm: uninitialized warning corrections The variables here are really not used uninitialized. arch/arm/mm/alignment.c: In function 'do_alignment': arch/arm/mm/alignment.c:327:15: warning: 'offset.un' may be used uninitialized in this function [-Wmaybe-uninitialized] arch/arm/mm/alignment.c:748:21: note: 'offset.un' was declared here Signed-off-by: Viresh Kumar Signed-off-by: Russell King --- arch/arm/mm/alignment.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 023f443784ec..b820edaf3184 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -745,7 +745,7 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs, static int do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { - union offset_union offset; + union offset_union uninitialized_var(offset); unsigned long instr = 0, instrptr; int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs); unsigned int type; -- cgit v1.2.2 From cf47a83fb06e42ae1b572ed68326068c7feaceae Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 19 Oct 2012 15:25:37 -0400 Subject: xen/hypercall: fix hypercall fallback code for very old hypervisors While copying the argument structures in HYPERVISOR_event_channel_op() and HYPERVISOR_physdev_op() into the local variable is sufficiently safe even if the actual structure is smaller than the container one, copying back eventual output values the same way isn't: This may collide with on-stack variables (particularly "rc") which may change between the first and second memcpy() (i.e. the second memcpy() could discard that change). Move the fallback code into out-of-line functions, and handle all of the operations known by this old a hypervisor individually: Some don't require copying back anything at all, and for the rest use the individual argument structures' sizes rather than the container's. Reported-by: Dan Carpenter Signed-off-by: Jan Beulich [v2: Reduce #define/#undef usage in HYPERVISOR_physdev_op_compat().] [v3: Fix compile errors when modules use said hypercalls] [v4: Add xen_ prefix to the HYPERCALL_..] [v5: Alter the name and only EXPORT_SYMBOL_GPL one of them] Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/include/asm/xen/hypercall.h | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h index 59c226d120cd..c20d1ce62dc6 100644 --- a/arch/x86/include/asm/xen/hypercall.h +++ b/arch/x86/include/asm/xen/hypercall.h @@ -359,18 +359,14 @@ HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val, return _hypercall4(int, update_va_mapping, va, new_val.pte, new_val.pte >> 32, flags); } +extern int __must_check xen_event_channel_op_compat(int, void *); static inline int HYPERVISOR_event_channel_op(int cmd, void *arg) { int rc = _hypercall2(int, event_channel_op, cmd, arg); - if (unlikely(rc == -ENOSYS)) { - struct evtchn_op op; - op.cmd = cmd; - memcpy(&op.u, arg, sizeof(op.u)); - rc = _hypercall1(int, event_channel_op_compat, &op); - memcpy(arg, &op.u, sizeof(op.u)); - } + if (unlikely(rc == -ENOSYS)) + rc = xen_event_channel_op_compat(cmd, arg); return rc; } @@ -386,17 +382,14 @@ HYPERVISOR_console_io(int cmd, int count, char *str) return _hypercall3(int, console_io, cmd, count, str); } +extern int __must_check HYPERVISOR_physdev_op_compat(int, void *); + static inline int HYPERVISOR_physdev_op(int cmd, void *arg) { int rc = _hypercall2(int, physdev_op, cmd, arg); - if (unlikely(rc == -ENOSYS)) { - struct physdev_op op; - op.cmd = cmd; - memcpy(&op.u, arg, sizeof(op.u)); - rc = _hypercall1(int, physdev_op_compat, &op); - memcpy(arg, &op.u, sizeof(op.u)); - } + if (unlikely(rc == -ENOSYS)) + rc = HYPERVISOR_physdev_op_compat(cmd, arg); return rc; } -- cgit v1.2.2 From 73c503cb981394872db41dd5cde385cb5373b4b9 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 5 Nov 2012 15:46:36 -0800 Subject: ARM: OMAP4: PM: fix regulator name for VDD_MPU commit 24d7b40a (ARM: OMAP2+: PM: MPU DVFS: use generic CPU device for MPU-SS) updated the regulator name used for the MPU regulator, but only updated OMAP3, not OMAP4. Fix the OMAP4 name as well, otherwise CPUfreq fails to find the MPU regulator. Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/twl-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 635e109f5ad3..44c42057b61c 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -366,7 +366,7 @@ static struct regulator_init_data omap4_clk32kg_idata = { }; static struct regulator_consumer_supply omap4_vdd1_supply[] = { - REGULATOR_SUPPLY("vcc", "mpu.0"), + REGULATOR_SUPPLY("vcc", "cpu0"), }; static struct regulator_consumer_supply omap4_vdd2_supply[] = { -- cgit v1.2.2 From e32643544d8d9e7776daf0a4e803c57b54ba77f0 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 25 Oct 2012 22:20:37 -0500 Subject: ARM: highbank: retry wfi on reset request In some cases, an interrupt can occur and prevent cause failure to enter wfi. This causes reset to hang. Retrying the wfi should be enough to prevent reset from hanging. Signed-off-by: Rob Herring Signed-off-by: Olof Johansson --- arch/arm/mach-highbank/system.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-highbank/system.c b/arch/arm/mach-highbank/system.c index 82c27230d4a9..86e37cd9376c 100644 --- a/arch/arm/mach-highbank/system.c +++ b/arch/arm/mach-highbank/system.c @@ -28,6 +28,7 @@ void highbank_restart(char mode, const char *cmd) hignbank_set_pwr_soft_reset(); scu_power_mode(scu_base_addr, SCU_PM_POWEROFF); - cpu_do_idle(); + while (1) + cpu_do_idle(); } -- cgit v1.2.2 From 619506d5dabb49b7f223a4f2f6b8d697574dd799 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 2 Apr 2012 18:22:45 +0200 Subject: s390: Move css limits from drivers/s390/cio/ to include/asm/. There's no need to keep __MAX_SUBCHANNEL and __MAX_SSID private to the common I/O layer when __MAX_CSSID is usable by everybody. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/cio.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index 55bde6035216..ad2b924167d7 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h @@ -9,6 +9,8 @@ #define LPM_ANYPATH 0xff #define __MAX_CSSID 0 +#define __MAX_SUBCHANNEL 65535 +#define __MAX_SSID 3 #include -- cgit v1.2.2 From 99e639b791f5cfae0b8d42f5fe6c1e8839932bea Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 31 Oct 2012 17:14:39 +0100 Subject: s390/sclp: fix addressing mode clobber The early mini sclp driver may be called in zArch mode either in 31 or 64 bit addressing mode. If called in 31 bit addressing mode the new external interrupt psw however would switch to 64 bit addressing mode. This would cause an addressing exception within the interrupt handler, since the code didn't expect the zArch/31 bit addressing mode combination. Fix this by setting the new psw addressing mode bits so they fit the current addressing mode. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/sclp.S | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/kernel/sclp.S b/arch/s390/kernel/sclp.S index bf053898630d..b6506ee32a36 100644 --- a/arch/s390/kernel/sclp.S +++ b/arch/s390/kernel/sclp.S @@ -44,6 +44,12 @@ _sclp_wait_int: #endif mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8) mvc 0(16,%r8),0(%r9) +#ifdef CONFIG_64BIT + epsw %r6,%r7 # set current addressing mode + nill %r6,0x1 # in new psw (31 or 64 bit mode) + nilh %r7,0x8000 + stm %r6,%r7,0(%r8) +#endif lhi %r6,0x0200 # cr mask for ext int (cr0.54) ltr %r2,%r2 jz .LsetctS1 @@ -87,7 +93,7 @@ _sclp_wait_int: .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int #ifdef CONFIG_64BIT .LextpswS1_64: - .quad 0x0000000180000000, .LwaitS1 # PSW to handle ext int, 64 bit + .quad 0, .LwaitS1 # PSW to handle ext int, 64 bit #endif .LwaitpswS1: .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int -- cgit v1.2.2 From 911dec0db4de6ccc544178a8ddaf9cec0a11d533 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 6 Nov 2012 17:06:52 -0500 Subject: xen/arm: Fix compile errors when drivers are compiled as modules. We end up with: ERROR: "HYPERVISOR_event_channel_op" [drivers/xen/xen-gntdev.ko] undefined! ERROR: "privcmd_call" [drivers/xen/xen-privcmd.ko] undefined! ERROR: "HYPERVISOR_grant_table_op" [drivers/net/xen-netback/xen-netback.ko] undefined! and this patch exports said function (which is implemented in hypercall.S). Acked-by: Stefano Stabellini Acked-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- arch/arm/xen/enlighten.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 59bcb96ac369..96d969da5335 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -166,3 +166,8 @@ void free_xenballooned_pages(int nr_pages, struct page **pages) *pages = NULL; } EXPORT_SYMBOL_GPL(free_xenballooned_pages); + +/* In the hypervisor.S file. */ +EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op); +EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op); +EXPORT_SYMBOL_GPL(privcmd_call); -- cgit v1.2.2 From 637874ddb94a78e07ca8ce76ca500c62c4583535 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Sat, 27 Oct 2012 19:05:55 +0530 Subject: ARM: OMAP4: add _dev_attr_ to ocp2scp for representing usb_phy In order to reflect devices(usb_phy) attached to ocp2scp bus, ocp2scp is assigned a device attribute to represent the attached devices. This is needed to fix MUSB regression caused by commit c9e4412a (arm: omap: phy: remove unused functions from omap-phy-internal.c) Signed-off-by: Kishon Vijay Abraham I Cc: Benoit Cousson [tony@atomide.com: updated comments for regression info] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 652d0285bd6d..cf579b55571b 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -2681,6 +2682,32 @@ static struct omap_hwmod_class omap44xx_ocp2scp_hwmod_class = { .sysc = &omap44xx_ocp2scp_sysc, }; +/* ocp2scp dev_attr */ +static struct resource omap44xx_usb_phy_and_pll_addrs[] = { + { + .name = "usb_phy", + .start = 0x4a0ad080, + .end = 0x4a0ae000, + .flags = IORESOURCE_MEM, + }, + { + /* XXX: Remove this once control module driver is in place */ + .name = "ctrl_dev", + .start = 0x4a002300, + .end = 0x4a002303, + .flags = IORESOURCE_MEM, + }, + { } +}; + +static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = { + { + .drv_name = "omap-usb2", + .res = omap44xx_usb_phy_and_pll_addrs, + }, + { } +}; + /* ocp2scp_usb_phy */ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { .name = "ocp2scp_usb_phy", @@ -2694,6 +2721,7 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { .modulemode = MODULEMODE_HWCTRL, }, }, + .dev_attr = ocp2scp_dev_attr, }; /* -- cgit v1.2.2 From 459bc971eba0fe84b3fe857cf0a71c5fd102f06b Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Sat, 27 Oct 2012 19:05:56 +0530 Subject: ARM: OMAP: ocp2scp: create omap device for ocp2scp Platfrom device for ocp2scp is created using omap_device_build in devices file. This is used for both omap4(musb) and omap5(dwc3). This is needed to fix MUSB regression caused by commit c9e4412a (arm: omap: phy: remove unused functions from omap-phy-internal.c) Signed-off-by: Kishon Vijay Abraham I [tony@atomide.com: updated comments for regression info] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/devices.c | 79 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index cba60e05e32e..c72b5a727720 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -613,6 +614,83 @@ static void omap_init_vout(void) static inline void omap_init_vout(void) {} #endif +#if defined(CONFIG_OMAP_OCP2SCP) || defined(CONFIG_OMAP_OCP2SCP_MODULE) +static int count_ocp2scp_devices(struct omap_ocp2scp_dev *ocp2scp_dev) +{ + int cnt = 0; + + while (ocp2scp_dev->drv_name != NULL) { + cnt++; + ocp2scp_dev++; + } + + return cnt; +} + +static void omap_init_ocp2scp(void) +{ + struct omap_hwmod *oh; + struct platform_device *pdev; + int bus_id = -1, dev_cnt = 0, i; + struct omap_ocp2scp_dev *ocp2scp_dev; + const char *oh_name, *name; + struct omap_ocp2scp_platform_data *pdata; + + if (!cpu_is_omap44xx()) + return; + + oh_name = "ocp2scp_usb_phy"; + name = "omap-ocp2scp"; + + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + pr_err("%s: could not find omap_hwmod for %s\n", __func__, + oh_name); + return; + } + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + pr_err("%s: No memory for ocp2scp pdata\n", __func__); + return; + } + + ocp2scp_dev = oh->dev_attr; + dev_cnt = count_ocp2scp_devices(ocp2scp_dev); + + if (!dev_cnt) { + pr_err("%s: No devices connected to ocp2scp\n", __func__); + kfree(pdata); + return; + } + + pdata->devices = kzalloc(sizeof(struct omap_ocp2scp_dev *) + * dev_cnt, GFP_KERNEL); + if (!pdata->devices) { + pr_err("%s: No memory for ocp2scp pdata devices\n", __func__); + kfree(pdata); + return; + } + + for (i = 0; i < dev_cnt; i++, ocp2scp_dev++) + pdata->devices[i] = ocp2scp_dev; + + pdata->dev_cnt = dev_cnt; + + pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata), NULL, + 0, false); + if (IS_ERR(pdev)) { + pr_err("Could not build omap_device for %s %s\n", + name, oh_name); + kfree(pdata->devices); + kfree(pdata); + return; + } +} +#else +static inline void omap_init_ocp2scp(void) { } +#endif + /*-------------------------------------------------------------------------*/ static int __init omap2_init_devices(void) @@ -640,6 +718,7 @@ static int __init omap2_init_devices(void) omap_init_sham(); omap_init_aes(); omap_init_vout(); + omap_init_ocp2scp(); return 0; } -- cgit v1.2.2 From cbf6bae1044286a89955d7c4b3a8d6d84a9916b3 Mon Sep 17 00:00:00 2001 From: Anders Hedlund Date: Mon, 29 Oct 2012 20:25:42 +0100 Subject: ARM: OMAP3: igep0020: Set WIFI/BT GPIO pins in correct mux mode Setup the WIFI/BT GPIO pin muxes to enable WIFI/BT functionality. This is needed to fix regression caused by recent versions of u-boot that only mux essential pins. Signed-off-by: Anders Hedlund Cc: Jonas Zetterberg Cc: Enric Balletbo i Serra Cc: Javier Martinez Canillas Cc: Matthias Brugger [tony@atomide.com: updated comments to describe regression] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-igep0020.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 48d5e41dfbfa..378590694447 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -580,6 +580,11 @@ static void __init igep_wlan_bt_init(void) } else return; + /* Make sure that the GPIO pins are muxed correctly */ + omap_mux_init_gpio(igep_wlan_bt_gpios[0].gpio, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(igep_wlan_bt_gpios[1].gpio, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(igep_wlan_bt_gpios[2].gpio, OMAP_PIN_OUTPUT); + err = gpio_request_array(igep_wlan_bt_gpios, ARRAY_SIZE(igep_wlan_bt_gpios)); if (err) { -- cgit v1.2.2 From 6d369a09ccd8104b35646b507112d3ddca4344eb Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 8 Nov 2012 11:26:34 +0000 Subject: x86: Export asm/{svm.h,vmx.h,perf_regs.h} Export asm/{svm.h,vmx.h,perf_regs.h} so that they can be disintegrated. It looks from previous commits that the first two should have been exported, but the header-y lines weren't added to the Kbuild. I'm guessing that asm/perf_regs.h should be exported too. Signed-off-by: David Howells --- arch/x86/include/asm/Kbuild | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 66e5f0ef0523..79fd8a3418f9 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -12,6 +12,7 @@ header-y += mce.h header-y += msr-index.h header-y += msr.h header-y += mtrr.h +header-y += perf_regs.h header-y += posix_types_32.h header-y += posix_types_64.h header-y += posix_types_x32.h @@ -19,8 +20,10 @@ header-y += prctl.h header-y += processor-flags.h header-y += ptrace-abi.h header-y += sigcontext32.h +header-y += svm.h header-y += ucontext.h header-y += vm86.h +header-y += vmx.h header-y += vsyscall.h genhdr-y += unistd_32.h -- cgit v1.2.2 From f46f979fdac402c1a3decf420b82397cd93236b5 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 5 Nov 2012 12:34:47 +0000 Subject: arm64: perf: use architected event for CPU cycle counter We currently use a fake event encoding (0xFF) to indicate CPU cycles so that we don't waste an event counter and can target the hardware cycle counter instead. The problem with this approach is that the event space defined by the architecture permits an implementation to allocate 0xFF for some other event. This patch uses the architected cycle counter encoding (0x11) so that we avoid potentially clashing with event encodings on future CPU implementations. Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/kernel/perf_event.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index ecbf2d81ec5c..c76c7241125b 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -613,17 +613,11 @@ enum armv8_pmuv3_perf_types { ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19, ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A, ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D, - - /* - * This isn't an architected event. - * We detect this event number and use the cycle counter instead. - */ - ARMV8_PMUV3_PERFCTR_CPU_CYCLES = 0xFF, }; /* PMUv3 HW events mapping. */ static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = { - [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, + [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES, [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED, [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS, [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL, @@ -1106,7 +1100,7 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc, unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT; /* Always place a cycle counter into the cycle counter. */ - if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) { + if (evtype == ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES) { if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) return -EAGAIN; -- cgit v1.2.2 From 6ba1bc826d160fe4f32bcb188687dcca4bdfaf3d Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 6 Nov 2012 19:28:48 +0000 Subject: arm64: elf: fix core dumping definitions for GP and FP registers struct user_fp does not exist for arm64, so use struct user_fpsimd_state instead for the ELF core dumping definitions. Furthermore, since we use regset-based core dumping, we do not need definitions for dump_task_regs and dump_fpu. Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/elf.h | 5 +---- arch/arm64/include/asm/fpsimd.h | 5 ++--- arch/arm64/kernel/process.c | 18 ------------------ 3 files changed, 3 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index cf284649dfcb..07fea290d7c1 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -25,12 +25,10 @@ #include typedef unsigned long elf_greg_t; -typedef unsigned long elf_freg_t[3]; #define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef struct user_fp elf_fpregset_t; +typedef struct user_fpsimd_state elf_fpregset_t; #define EM_AARCH64 183 @@ -87,7 +85,6 @@ typedef struct user_fp elf_fpregset_t; #define R_AARCH64_MOVW_PREL_G2_NC 292 #define R_AARCH64_MOVW_PREL_G3 293 - /* * These are used to set parameters in the core dumps. */ diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index b42fab9f62a9..c43b4ac13008 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h @@ -25,9 +25,8 @@ * - FPSR and FPCR * - 32 128-bit data registers * - * Note that user_fp forms a prefix of this structure, which is relied - * upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must - * form a prefix of struct fpsimd_state. + * Note that user_fpsimd forms a prefix of this structure, which is + * relied upon in the ptrace FP/SIMD accessors. */ struct fpsimd_state { union { diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index f22965ea1cfc..e04cebdbb47f 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -309,24 +309,6 @@ struct task_struct *__switch_to(struct task_struct *prev, return last; } -/* - * Fill in the task's elfregs structure for a core dump. - */ -int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs) -{ - elf_core_copy_regs(elfregs, task_pt_regs(t)); - return 1; -} - -/* - * fill in the fpe structure for a core dump... - */ -int dump_fpu (struct pt_regs *regs, struct user_fp *fp) -{ - return 0; -} -EXPORT_SYMBOL(dump_fpu); - /* * Shuffle the argument into the correct register before calling the * thread function. x1 is the thread argument, x2 is the pointer to -- cgit v1.2.2 From 6212a512240f48d84090bc42a24d6dfb033754bc Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 7 Nov 2012 14:16:28 +0000 Subject: arm64: compat: select CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION Commit c1d7e01d7877 ("ipc: use Kconfig options for __ARCH_WANT_[COMPAT_]IPC_PARSE_VERSION") replaced the __ARCH_WANT_COMPAT_IPC_PARSE_VERSION token with a corresponding Kconfig option instead. This patch updates arm64 to use the latter, rather than #define an unused token. Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/Kconfig | 1 + arch/arm64/include/asm/unistd.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index ef54a59a9e89..15ac18a56c93 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1,6 +1,7 @@ config ARM64 def_bool y select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE + select ARCH_WANT_COMPAT_IPC_PARSE_VERSION select GENERIC_CLOCKEVENTS select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IOMAP diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h index 63f853f8b718..68aff2816e86 100644 --- a/arch/arm64/include/asm/unistd.h +++ b/arch/arm64/include/asm/unistd.h @@ -14,7 +14,6 @@ * along with this program. If not, see . */ #ifdef CONFIG_COMPAT -#define __ARCH_WANT_COMPAT_IPC_PARSE_VERSION #define __ARCH_WANT_COMPAT_STAT64 #define __ARCH_WANT_SYS_GETHOSTNAME #define __ARCH_WANT_SYS_PAUSE -- cgit v1.2.2 From b3770b3252589240e50f560197a19531979abba2 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 7 Nov 2012 17:00:05 +0000 Subject: arm64: smp: add missing completion for secondary boot Commit 149c24151e85 ("ARM: SMP: use a timing out completion for cpu hotplug") modified arm's CPU up path to use completions. It seems that we only got half of this patch for arm64, so add the missing call to complete. Reported-by: Jon Brawn Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/kernel/smp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 226b6bf6e9c2..538300f2273d 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -211,8 +211,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void) * before we continue. */ set_cpu_online(cpu, true); - while (!cpu_active(cpu)) - cpu_relax(); + complete(&cpu_running); /* * OK, it's off to the idle thread for us -- cgit v1.2.2 From f483a853b0b932a1d75eb27a1dcbd732862260db Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 8 Nov 2012 16:00:16 +0000 Subject: arm64: mm: fix booting on systems with no memory below 4GB Booting on a system with all of its memory above the 4GB boundary breaks for two reasons: (1) We still try to create a non-empty DMA32 zone (2) no-bootmem limits allocations to 0xffffffff This patch fixes these issues for ARM64. Tested-by: Marc Zyngier Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/processor.h | 2 ++ arch/arm64/mm/init.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 5d810044feda..77f696c14339 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -43,6 +43,8 @@ #else #define STACK_TOP STACK_TOP_MAX #endif /* CONFIG_COMPAT */ + +#define ARCH_LOW_ADDRESS_LIMIT PHYS_MASK #endif /* __KERNEL__ */ struct debug_info { diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index efbf7df05d3f..4cd28931dba9 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -80,7 +80,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) #ifdef CONFIG_ZONE_DMA32 /* 4GB maximum for 32-bit only capable devices */ max_dma32 = min(max, MAX_DMA32_PFN); - zone_size[ZONE_DMA32] = max_dma32 - min; + zone_size[ZONE_DMA32] = max(min, max_dma32) - min; #endif zone_size[ZONE_NORMAL] = max - max_dma32; -- cgit v1.2.2 From 6893f5675f54d6452aded27f9a1d5e86a3bddcbe Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Thu, 8 Nov 2012 15:53:41 -0800 Subject: h8300: add missing L1_CACHE_SHIFT Fix the build error lib/atomic64.c: In function 'lock_addr': lib/atomic64.c:40:11: error: 'L1_CACHE_SHIFT' undeclared (first use in this function) lib/atomic64.c:40:11: note: each undeclared identifier is reported only once for each function it appears in Signed-off-by: Fengguang Wu Cc: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/h8300/include/asm/cache.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/h8300/include/asm/cache.h b/arch/h8300/include/asm/cache.h index c6350283649d..05887a1d80e5 100644 --- a/arch/h8300/include/asm/cache.h +++ b/arch/h8300/include/asm/cache.h @@ -2,7 +2,8 @@ #define __ARCH_H8300_CACHE_H /* bytes per L1 cache line */ -#define L1_CACHE_BYTES 4 +#define L1_CACHE_SHIFT 2 +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) /* m68k-elf-gcc 2.95.2 doesn't like these */ -- cgit v1.2.2 From f3f09d5a4462929609342460d756fab2e8151421 Mon Sep 17 00:00:00 2001 From: Kautuk Consul Date: Sat, 31 Mar 2012 08:05:17 -0400 Subject: unicore32/mm/fault.c: Port OOM changes to do_pf Commit d065bd810b6deb67d4897a14bfe21f8eb526ba99 (mm: retry page fault when blocking on disk transfer) and commit 37b23e0525d393d48a7d59f870b3bc061a30ccdb (x86,mm: make pagefault killable) The above commits introduced changes into the x86 pagefault handler for making the page fault handler retryable as well as killable. These changes reduce the mmap_sem hold time, which is crucial during OOM killer invocation. Port these changes to unicore32. Signed-off-by: Kautuk Consul Acked-by: Guan Xuetao --- arch/unicore32/mm/fault.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c index 2eeb9c04cab0..f9b5c10bccee 100644 --- a/arch/unicore32/mm/fault.c +++ b/arch/unicore32/mm/fault.c @@ -168,7 +168,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma) } static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr, - struct task_struct *tsk) + unsigned int flags, struct task_struct *tsk) { struct vm_area_struct *vma; int fault; @@ -194,14 +194,7 @@ good_area: * If for any reason at all we couldn't handle the fault, make * sure we exit gracefully rather than endlessly redo the fault. */ - fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, - (!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); - if (unlikely(fault & VM_FAULT_ERROR)) - return fault; - if (fault & VM_FAULT_MAJOR) - tsk->maj_flt++; - else - tsk->min_flt++; + fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); return fault; check_stack: @@ -216,6 +209,8 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) struct task_struct *tsk; struct mm_struct *mm; int fault, sig, code; + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | + ((!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); tsk = current; mm = tsk->mm; @@ -236,6 +231,7 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (!user_mode(regs) && !search_exception_tables(regs->UCreg_pc)) goto no_context; +retry: down_read(&mm->mmap_sem); } else { /* @@ -251,7 +247,28 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) #endif } - fault = __do_pf(mm, addr, fsr, tsk); + fault = __do_pf(mm, addr, fsr, flags, tsk); + + /* If we need to retry but a fatal signal is pending, handle the + * signal first. We do not need to release the mmap_sem because + * it would already be released in __lock_page_or_retry in + * mm/filemap.c. */ + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) + return 0; + + if (!(fault & VM_FAULT_ERROR) && (flags & FAULT_FLAG_ALLOW_RETRY)) { + if (fault & VM_FAULT_MAJOR) + tsk->maj_flt++; + else + tsk->min_flt++; + if (fault & VM_FAULT_RETRY) { + /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk + * of starvation. */ + flags &= ~FAULT_FLAG_ALLOW_RETRY; + goto retry; + } + } + up_read(&mm->mmap_sem); /* -- cgit v1.2.2 From 446d141e1c84d34c70592b53443b06533703c324 Mon Sep 17 00:00:00 2001 From: Guan Xuetao Date: Thu, 12 Apr 2012 09:18:46 +0800 Subject: UniCore32 bugfix: add missed CONFIG_ZONE_DMA Because our PCI-bus handler confines dma zone into 128M, we should add CONFIG_ZONE_DMA for all boards. Otherwise, all memory bigger than 128M will be pushed into ZONE_MOVABLE. Cc: Arnd Bergmann Signed-off-by: Liu Guoli Signed-off-by: Guan Xuetao --- arch/unicore32/Kconfig | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index e5c5473e69ce..5b95ba4e0c70 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -64,6 +64,9 @@ config GENERIC_CALIBRATE_DELAY config ARCH_MAY_HAVE_PC_FDC bool +config ZONE_DMA + def_bool y + config NEED_DMA_MAP_STATE def_bool y -- cgit v1.2.2 From 195d4577d1d7ab1f0398b3190547c116b56f435f Mon Sep 17 00:00:00 2001 From: Guan Xuetao Date: Thu, 14 Jun 2012 15:39:48 +0800 Subject: UniCore32-bugfix: fix mismatch return value of __xchg_bad_pointer When disintegrate system.h, I left an error in asm/cmpxchg.h, which will result in following error: arch/unicore32/include/asm/cmpxchg.h: In function '__xchg': arch/unicore32/include/asm/cmpxchg.h:38: error: void value not ignored as it ought to be Signed-off-by: Guan Xuetao --- arch/unicore32/include/asm/cmpxchg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/unicore32/include/asm/cmpxchg.h b/arch/unicore32/include/asm/cmpxchg.h index df4d5acfd19f..8e797ad4fa24 100644 --- a/arch/unicore32/include/asm/cmpxchg.h +++ b/arch/unicore32/include/asm/cmpxchg.h @@ -35,7 +35,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, : "memory", "cc"); break; default: - ret = __xchg_bad_pointer(); + __xchg_bad_pointer(); } return ret; -- cgit v1.2.2 From 10e1e99e55378a65529c48753703c069aebce7af Mon Sep 17 00:00:00 2001 From: Guan Xuetao Date: Thu, 14 Jun 2012 11:38:25 +0800 Subject: UniCore32-bugfix: Remove definitions in asm/bug.h to solve difference between native and cross compiler For kernel/bound.c being compiled by native compiler, it will generate following errors in gcc 4.4.3: CC kernel/bounds.s In file included from include/linux/bug.h:4, from include/linux/page-flags.h:9, from kernel/bounds.c:9: arch/unicore32/include/asm/bug.h:22: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'void' arch/unicore32/include/asm/bug.h:23: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'void' So, we moved definitions in asm/bug.h to arch/unicore32/kernel/setup.h to solve the problem. Signed-off-by: Guan Xuetao --- arch/unicore32/include/asm/bug.h | 5 ----- arch/unicore32/kernel/setup.h | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/unicore32/include/asm/bug.h b/arch/unicore32/include/asm/bug.h index b1ff8cadb086..93a56f3e2344 100644 --- a/arch/unicore32/include/asm/bug.h +++ b/arch/unicore32/include/asm/bug.h @@ -19,9 +19,4 @@ extern void die(const char *msg, struct pt_regs *regs, int err); extern void uc32_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, unsigned long err, unsigned long trap); -extern asmlinkage void __backtrace(void); -extern asmlinkage void c_backtrace(unsigned long fp, int pmode); - -extern void __show_regs(struct pt_regs *); - #endif /* __UNICORE_BUG_H__ */ diff --git a/arch/unicore32/kernel/setup.h b/arch/unicore32/kernel/setup.h index f23955028a18..30f749da8f73 100644 --- a/arch/unicore32/kernel/setup.h +++ b/arch/unicore32/kernel/setup.h @@ -30,4 +30,10 @@ extern char __vectors_start[], __vectors_end[]; extern void kernel_thread_helper(void); extern void __init early_signal_init(void); + +extern asmlinkage void __backtrace(void); +extern asmlinkage void c_backtrace(unsigned long fp, int pmode); + +extern void __show_regs(struct pt_regs *); + #endif -- cgit v1.2.2 From e8ce15a6d7ecdbabd8d04d78e065a2706459194f Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 9 Oct 2012 09:47:48 +0100 Subject: UAPI: (Scripted) Disintegrate arch/unicore32/include/asm Signed-off-by: David Howells Acked-by: Arnd Bergmann Acked-by: Thomas Gleixner Acked-by: Michael Kerrisk Acked-by: Paul E. McKenney Acked-by: Dave Jones --- arch/unicore32/include/asm/Kbuild | 1 - arch/unicore32/include/asm/byteorder.h | 24 -------- arch/unicore32/include/asm/kvm_para.h | 1 - arch/unicore32/include/asm/ptrace.h | 76 +---------------------- arch/unicore32/include/asm/sigcontext.h | 29 --------- arch/unicore32/include/asm/unistd.h | 14 ----- arch/unicore32/include/uapi/asm/Kbuild | 5 ++ arch/unicore32/include/uapi/asm/byteorder.h | 24 ++++++++ arch/unicore32/include/uapi/asm/kvm_para.h | 1 + arch/unicore32/include/uapi/asm/ptrace.h | 90 ++++++++++++++++++++++++++++ arch/unicore32/include/uapi/asm/sigcontext.h | 29 +++++++++ arch/unicore32/include/uapi/asm/unistd.h | 14 +++++ 12 files changed, 164 insertions(+), 144 deletions(-) delete mode 100644 arch/unicore32/include/asm/byteorder.h delete mode 100644 arch/unicore32/include/asm/kvm_para.h delete mode 100644 arch/unicore32/include/asm/sigcontext.h delete mode 100644 arch/unicore32/include/asm/unistd.h create mode 100644 arch/unicore32/include/uapi/asm/byteorder.h create mode 100644 arch/unicore32/include/uapi/asm/kvm_para.h create mode 100644 arch/unicore32/include/uapi/asm/ptrace.h create mode 100644 arch/unicore32/include/uapi/asm/sigcontext.h create mode 100644 arch/unicore32/include/uapi/asm/unistd.h (limited to 'arch') diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild index c910c9857e11..601e92f18af6 100644 --- a/arch/unicore32/include/asm/Kbuild +++ b/arch/unicore32/include/asm/Kbuild @@ -1,4 +1,3 @@ -include include/asm-generic/Kbuild.asm generic-y += atomic.h generic-y += auxvec.h diff --git a/arch/unicore32/include/asm/byteorder.h b/arch/unicore32/include/asm/byteorder.h deleted file mode 100644 index ebe1b3fef3e3..000000000000 --- a/arch/unicore32/include/asm/byteorder.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * linux/arch/unicore32/include/asm/byteorder.h - * - * Code specific to PKUnity SoC and UniCore ISA - * - * Copyright (C) 2001-2010 GUAN Xue-tao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * UniCore ONLY support Little Endian mode, the data bus is connected such - * that byte accesses appear as: - * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31 - * and word accesses (data or instruction) appear as: - * d0...d31 - */ -#ifndef __UNICORE_BYTEORDER_H__ -#define __UNICORE_BYTEORDER_H__ - -#include - -#endif - diff --git a/arch/unicore32/include/asm/kvm_para.h b/arch/unicore32/include/asm/kvm_para.h deleted file mode 100644 index 14fab8f0b957..000000000000 --- a/arch/unicore32/include/asm/kvm_para.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/unicore32/include/asm/ptrace.h b/arch/unicore32/include/asm/ptrace.h index b9caf9b0997b..726749dab52f 100644 --- a/arch/unicore32/include/asm/ptrace.h +++ b/arch/unicore32/include/asm/ptrace.h @@ -12,80 +12,10 @@ #ifndef __UNICORE_PTRACE_H__ #define __UNICORE_PTRACE_H__ -#define PTRACE_GET_THREAD_AREA 22 - -/* - * PSR bits - */ -#define USER_MODE 0x00000010 -#define REAL_MODE 0x00000011 -#define INTR_MODE 0x00000012 -#define PRIV_MODE 0x00000013 -#define ABRT_MODE 0x00000017 -#define EXTN_MODE 0x0000001b -#define SUSR_MODE 0x0000001f -#define MODE_MASK 0x0000001f -#define PSR_R_BIT 0x00000040 -#define PSR_I_BIT 0x00000080 -#define PSR_V_BIT 0x10000000 -#define PSR_C_BIT 0x20000000 -#define PSR_Z_BIT 0x40000000 -#define PSR_S_BIT 0x80000000 - -/* - * Groups of PSR bits - */ -#define PSR_f 0xff000000 /* Flags */ -#define PSR_c 0x000000ff /* Control */ +#include #ifndef __ASSEMBLY__ -/* - * This struct defines the way the registers are stored on the - * stack during a system call. Note that sizeof(struct pt_regs) - * has to be a multiple of 8. - */ -struct pt_regs { - unsigned long uregs[34]; -}; - -#define UCreg_asr uregs[32] -#define UCreg_pc uregs[31] -#define UCreg_lr uregs[30] -#define UCreg_sp uregs[29] -#define UCreg_ip uregs[28] -#define UCreg_fp uregs[27] -#define UCreg_26 uregs[26] -#define UCreg_25 uregs[25] -#define UCreg_24 uregs[24] -#define UCreg_23 uregs[23] -#define UCreg_22 uregs[22] -#define UCreg_21 uregs[21] -#define UCreg_20 uregs[20] -#define UCreg_19 uregs[19] -#define UCreg_18 uregs[18] -#define UCreg_17 uregs[17] -#define UCreg_16 uregs[16] -#define UCreg_15 uregs[15] -#define UCreg_14 uregs[14] -#define UCreg_13 uregs[13] -#define UCreg_12 uregs[12] -#define UCreg_11 uregs[11] -#define UCreg_10 uregs[10] -#define UCreg_09 uregs[9] -#define UCreg_08 uregs[8] -#define UCreg_07 uregs[7] -#define UCreg_06 uregs[6] -#define UCreg_05 uregs[5] -#define UCreg_04 uregs[4] -#define UCreg_03 uregs[3] -#define UCreg_02 uregs[2] -#define UCreg_01 uregs[1] -#define UCreg_00 uregs[0] -#define UCreg_ORIG_00 uregs[33] - -#ifdef __KERNEL__ - #define user_mode(regs) \ (processor_mode(regs) == USER_MODE) @@ -125,9 +55,5 @@ static inline int valid_user_regs(struct pt_regs *regs) #define instruction_pointer(regs) ((regs)->UCreg_pc) -#endif /* __KERNEL__ */ - #endif /* __ASSEMBLY__ */ - #endif - diff --git a/arch/unicore32/include/asm/sigcontext.h b/arch/unicore32/include/asm/sigcontext.h deleted file mode 100644 index 6a2d7671c052..000000000000 --- a/arch/unicore32/include/asm/sigcontext.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * linux/arch/unicore32/include/asm/sigcontext.h - * - * Code specific to PKUnity SoC and UniCore ISA - * - * Copyright (C) 2001-2010 GUAN Xue-tao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __UNICORE_SIGCONTEXT_H__ -#define __UNICORE_SIGCONTEXT_H__ - -#include -/* - * Signal context structure - contains all info to do with the state - * before the signal handler was invoked. Note: only add new entries - * to the end of the structure. - */ -struct sigcontext { - unsigned long trap_no; - unsigned long error_code; - unsigned long oldmask; - unsigned long fault_address; - struct pt_regs regs; -}; - -#endif diff --git a/arch/unicore32/include/asm/unistd.h b/arch/unicore32/include/asm/unistd.h deleted file mode 100644 index 2abcf61c615d..000000000000 --- a/arch/unicore32/include/asm/unistd.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * linux/arch/unicore32/include/asm/unistd.h - * - * Code specific to PKUnity SoC and UniCore ISA - * - * Copyright (C) 2001-2010 GUAN Xue-tao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Use the standard ABI for syscalls. */ -#include diff --git a/arch/unicore32/include/uapi/asm/Kbuild b/arch/unicore32/include/uapi/asm/Kbuild index baebb3da1d44..a44b1c453d13 100644 --- a/arch/unicore32/include/uapi/asm/Kbuild +++ b/arch/unicore32/include/uapi/asm/Kbuild @@ -1,3 +1,8 @@ # UAPI Header export list include include/uapi/asm-generic/Kbuild.asm +header-y += byteorder.h +header-y += kvm_para.h +header-y += ptrace.h +header-y += sigcontext.h +header-y += unistd.h diff --git a/arch/unicore32/include/uapi/asm/byteorder.h b/arch/unicore32/include/uapi/asm/byteorder.h new file mode 100644 index 000000000000..ebe1b3fef3e3 --- /dev/null +++ b/arch/unicore32/include/uapi/asm/byteorder.h @@ -0,0 +1,24 @@ +/* + * linux/arch/unicore32/include/asm/byteorder.h + * + * Code specific to PKUnity SoC and UniCore ISA + * + * Copyright (C) 2001-2010 GUAN Xue-tao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * UniCore ONLY support Little Endian mode, the data bus is connected such + * that byte accesses appear as: + * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31 + * and word accesses (data or instruction) appear as: + * d0...d31 + */ +#ifndef __UNICORE_BYTEORDER_H__ +#define __UNICORE_BYTEORDER_H__ + +#include + +#endif + diff --git a/arch/unicore32/include/uapi/asm/kvm_para.h b/arch/unicore32/include/uapi/asm/kvm_para.h new file mode 100644 index 000000000000..14fab8f0b957 --- /dev/null +++ b/arch/unicore32/include/uapi/asm/kvm_para.h @@ -0,0 +1 @@ +#include diff --git a/arch/unicore32/include/uapi/asm/ptrace.h b/arch/unicore32/include/uapi/asm/ptrace.h new file mode 100644 index 000000000000..187aa2e98a53 --- /dev/null +++ b/arch/unicore32/include/uapi/asm/ptrace.h @@ -0,0 +1,90 @@ +/* + * linux/arch/unicore32/include/asm/ptrace.h + * + * Code specific to PKUnity SoC and UniCore ISA + * + * Copyright (C) 2001-2010 GUAN Xue-tao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef _UAPI__UNICORE_PTRACE_H__ +#define _UAPI__UNICORE_PTRACE_H__ + +#define PTRACE_GET_THREAD_AREA 22 + +/* + * PSR bits + */ +#define USER_MODE 0x00000010 +#define REAL_MODE 0x00000011 +#define INTR_MODE 0x00000012 +#define PRIV_MODE 0x00000013 +#define ABRT_MODE 0x00000017 +#define EXTN_MODE 0x0000001b +#define SUSR_MODE 0x0000001f +#define MODE_MASK 0x0000001f +#define PSR_R_BIT 0x00000040 +#define PSR_I_BIT 0x00000080 +#define PSR_V_BIT 0x10000000 +#define PSR_C_BIT 0x20000000 +#define PSR_Z_BIT 0x40000000 +#define PSR_S_BIT 0x80000000 + +/* + * Groups of PSR bits + */ +#define PSR_f 0xff000000 /* Flags */ +#define PSR_c 0x000000ff /* Control */ + +#ifndef __ASSEMBLY__ + +/* + * This struct defines the way the registers are stored on the + * stack during a system call. Note that sizeof(struct pt_regs) + * has to be a multiple of 8. + */ +struct pt_regs { + unsigned long uregs[34]; +}; + +#define UCreg_asr uregs[32] +#define UCreg_pc uregs[31] +#define UCreg_lr uregs[30] +#define UCreg_sp uregs[29] +#define UCreg_ip uregs[28] +#define UCreg_fp uregs[27] +#define UCreg_26 uregs[26] +#define UCreg_25 uregs[25] +#define UCreg_24 uregs[24] +#define UCreg_23 uregs[23] +#define UCreg_22 uregs[22] +#define UCreg_21 uregs[21] +#define UCreg_20 uregs[20] +#define UCreg_19 uregs[19] +#define UCreg_18 uregs[18] +#define UCreg_17 uregs[17] +#define UCreg_16 uregs[16] +#define UCreg_15 uregs[15] +#define UCreg_14 uregs[14] +#define UCreg_13 uregs[13] +#define UCreg_12 uregs[12] +#define UCreg_11 uregs[11] +#define UCreg_10 uregs[10] +#define UCreg_09 uregs[9] +#define UCreg_08 uregs[8] +#define UCreg_07 uregs[7] +#define UCreg_06 uregs[6] +#define UCreg_05 uregs[5] +#define UCreg_04 uregs[4] +#define UCreg_03 uregs[3] +#define UCreg_02 uregs[2] +#define UCreg_01 uregs[1] +#define UCreg_00 uregs[0] +#define UCreg_ORIG_00 uregs[33] + + +#endif /* __ASSEMBLY__ */ + +#endif /* _UAPI__UNICORE_PTRACE_H__ */ diff --git a/arch/unicore32/include/uapi/asm/sigcontext.h b/arch/unicore32/include/uapi/asm/sigcontext.h new file mode 100644 index 000000000000..6a2d7671c052 --- /dev/null +++ b/arch/unicore32/include/uapi/asm/sigcontext.h @@ -0,0 +1,29 @@ +/* + * linux/arch/unicore32/include/asm/sigcontext.h + * + * Code specific to PKUnity SoC and UniCore ISA + * + * Copyright (C) 2001-2010 GUAN Xue-tao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __UNICORE_SIGCONTEXT_H__ +#define __UNICORE_SIGCONTEXT_H__ + +#include +/* + * Signal context structure - contains all info to do with the state + * before the signal handler was invoked. Note: only add new entries + * to the end of the structure. + */ +struct sigcontext { + unsigned long trap_no; + unsigned long error_code; + unsigned long oldmask; + unsigned long fault_address; + struct pt_regs regs; +}; + +#endif diff --git a/arch/unicore32/include/uapi/asm/unistd.h b/arch/unicore32/include/uapi/asm/unistd.h new file mode 100644 index 000000000000..2abcf61c615d --- /dev/null +++ b/arch/unicore32/include/uapi/asm/unistd.h @@ -0,0 +1,14 @@ +/* + * linux/arch/unicore32/include/asm/unistd.h + * + * Code specific to PKUnity SoC and UniCore ISA + * + * Copyright (C) 2001-2010 GUAN Xue-tao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* Use the standard ABI for syscalls. */ +#include -- cgit v1.2.2 From ddd2d384b019d1733335c0fca7eccae3c29d2a14 Mon Sep 17 00:00:00 2001 From: Guan Xuetao Date: Mon, 15 Oct 2012 14:41:36 +0800 Subject: unicore32: Use Kbuild infrastructure for kvm_para.h All the headers but kvm_para.h use the Kbuild infrastructure to get to the asm-generic headers. Cc: linux-kbuild@vger.kernel.org Signed-off-by: Steven Rostedt Signed-off-by: Guan Xuetao --- arch/unicore32/include/uapi/asm/Kbuild | 2 ++ arch/unicore32/include/uapi/asm/kvm_para.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) delete mode 100644 arch/unicore32/include/uapi/asm/kvm_para.h (limited to 'arch') diff --git a/arch/unicore32/include/uapi/asm/Kbuild b/arch/unicore32/include/uapi/asm/Kbuild index a44b1c453d13..0514d7ad6855 100644 --- a/arch/unicore32/include/uapi/asm/Kbuild +++ b/arch/unicore32/include/uapi/asm/Kbuild @@ -6,3 +6,5 @@ header-y += kvm_para.h header-y += ptrace.h header-y += sigcontext.h header-y += unistd.h + +generic-y += kvm_para.h diff --git a/arch/unicore32/include/uapi/asm/kvm_para.h b/arch/unicore32/include/uapi/asm/kvm_para.h deleted file mode 100644 index 14fab8f0b957..000000000000 --- a/arch/unicore32/include/uapi/asm/kvm_para.h +++ /dev/null @@ -1 +0,0 @@ -#include -- cgit v1.2.2 From 38e993535edda089a6956bf12a1dde2602649de9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 13 Oct 2012 17:35:21 -0400 Subject: unicore32: switch to generic kernel_thread()/kernel_execve() Signed-off-by: Al Viro Acked-and-Tested-by: Guan Xuetao --- arch/unicore32/Kconfig | 2 ++ arch/unicore32/include/asm/processor.h | 5 --- arch/unicore32/kernel/entry.S | 15 ++++----- arch/unicore32/kernel/process.c | 58 ++++++++-------------------------- arch/unicore32/kernel/sys.c | 42 ------------------------ 5 files changed, 23 insertions(+), 99 deletions(-) (limited to 'arch') diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index 5b95ba4e0c70..fda37c941c10 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -16,6 +16,8 @@ config UNICORE32 select ARCH_WANT_FRAME_POINTERS select GENERIC_IOMAP select MODULES_USE_ELF_REL + select GENERIC_KERNEL_THREAD + select GENERIC_KERNEL_EXECVE help UniCore-32 is 32-bit Instruction Set Architecture, including a series of low-power-consumption RISC chip diff --git a/arch/unicore32/include/asm/processor.h b/arch/unicore32/include/asm/processor.h index 14382cb09657..4eaa42167667 100644 --- a/arch/unicore32/include/asm/processor.h +++ b/arch/unicore32/include/asm/processor.h @@ -72,11 +72,6 @@ unsigned long get_wchan(struct task_struct *p); #define cpu_relax() barrier() -/* - * Create a new kernel thread - */ -extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); - #define task_pt_regs(p) \ ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S index dcb87ab19ddd..32648c99483a 100644 --- a/arch/unicore32/kernel/entry.S +++ b/arch/unicore32/kernel/entry.S @@ -573,17 +573,16 @@ ENDPROC(ret_to_user) */ ENTRY(ret_from_fork) b.l schedule_tail - get_thread_info tsk - ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing - mov why, #1 - cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? - beq ret_slow_syscall - mov r1, sp - mov r0, #1 @ trace exit [IP = 1] - b.l syscall_trace b ret_slow_syscall ENDPROC(ret_from_fork) +ENTRY(ret_from_kernel_thread) + b.l schedule_tail + mov r0, r5 + adr lr, ret_slow_syscall + mov pc, r4 +ENDPROC(ret_from_kernel_thread) + /*============================================================================= * SWI handler *----------------------------------------------------------------------------- diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c index b008586dad75..a8fe265ce2c0 100644 --- a/arch/unicore32/kernel/process.c +++ b/arch/unicore32/kernel/process.c @@ -258,6 +258,7 @@ void release_thread(struct task_struct *dead_task) } asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); +asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread"); int copy_thread(unsigned long clone_flags, unsigned long stack_start, @@ -266,17 +267,22 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, struct thread_info *thread = task_thread_info(p); struct pt_regs *childregs = task_pt_regs(p); - *childregs = *regs; - childregs->UCreg_00 = 0; - childregs->UCreg_sp = stack_start; - memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); thread->cpu_context.sp = (unsigned long)childregs; - thread->cpu_context.pc = (unsigned long)ret_from_fork; - - if (clone_flags & CLONE_SETTLS) - childregs->UCreg_16 = regs->UCreg_03; + if (unlikely(!regs)) { + thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread; + thread->cpu_context.r4 = stack_start; + thread->cpu_context.r5 = stk_sz; + memset(childregs, 0, sizeof(struct pt_regs)); + } else { + thread->cpu_context.pc = (unsigned long)ret_from_fork; + *childregs = *regs; + childregs->UCreg_00 = 0; + childregs->UCreg_sp = stack_start; + if (clone_flags & CLONE_SETTLS) + childregs->UCreg_16 = regs->UCreg_03; + } return 0; } @@ -305,42 +311,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp) } EXPORT_SYMBOL(dump_fpu); -/* - * Shuffle the argument into the correct register before calling the - * thread function. r1 is the thread argument, r2 is the pointer to - * the thread function, and r3 points to the exit function. - */ -asm(".pushsection .text\n" -" .align\n" -" .type kernel_thread_helper, #function\n" -"kernel_thread_helper:\n" -" mov.a asr, r7\n" -" mov r0, r4\n" -" mov lr, r6\n" -" mov pc, r5\n" -" .size kernel_thread_helper, . - kernel_thread_helper\n" -" .popsection"); - -/* - * Create a kernel thread. - */ -pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) -{ - struct pt_regs regs; - - memset(®s, 0, sizeof(regs)); - - regs.UCreg_04 = (unsigned long)arg; - regs.UCreg_05 = (unsigned long)fn; - regs.UCreg_06 = (unsigned long)do_exit; - regs.UCreg_07 = PRIV_MODE; - regs.UCreg_pc = (unsigned long)kernel_thread_helper; - regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT; - - return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); -} -EXPORT_SYMBOL(kernel_thread); - unsigned long get_wchan(struct task_struct *p) { struct stackframe frame; diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c index fabdee96110b..8b6e4cc57393 100644 --- a/arch/unicore32/kernel/sys.c +++ b/arch/unicore32/kernel/sys.c @@ -63,48 +63,6 @@ out: return error; } -int kernel_execve(const char *filename, - const char *const argv[], - const char *const envp[]) -{ - struct pt_regs regs; - int ret; - - memset(®s, 0, sizeof(struct pt_regs)); - ret = do_execve(filename, - (const char __user *const __user *)argv, - (const char __user *const __user *)envp, ®s); - if (ret < 0) - goto out; - - /* - * Save argc to the register structure for userspace. - */ - regs.UCreg_00 = ret; - - /* - * We were successful. We won't be returning to our caller, but - * instead to user space by manipulating the kernel stack. - */ - asm("add r0, %0, %1\n\t" - "mov r1, %2\n\t" - "mov r2, %3\n\t" - "mov r22, #0\n\t" /* not a syscall */ - "mov r23, %0\n\t" /* thread structure */ - "b.l memmove\n\t" /* copy regs to top of stack */ - "mov sp, r0\n\t" /* reposition stack pointer */ - "b ret_to_user" - : - : "r" (current_thread_info()), - "Ir" (THREAD_START_SP - sizeof(regs)), - "r" (®s), - "Ir" (sizeof(regs)) - : "r0", "r1", "r2", "r3", "ip", "lr", "memory"); - - out: - return ret; -} - /* Note: used by the compat code even in 64-bit Linux. */ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, -- cgit v1.2.2 From 60541d778e536455970281de25b2476e01c03aef Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 13 Oct 2012 17:36:40 -0400 Subject: unicore32: switch to generic sys_execve() Signed-off-by: Al Viro Acked-and-Tested-by: Guan Xuetao --- arch/unicore32/include/uapi/asm/unistd.h | 1 + arch/unicore32/kernel/entry.S | 5 ----- arch/unicore32/kernel/sys.c | 21 --------------------- 3 files changed, 1 insertion(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/unicore32/include/uapi/asm/unistd.h b/arch/unicore32/include/uapi/asm/unistd.h index 2abcf61c615d..d18a3be89b38 100644 --- a/arch/unicore32/include/uapi/asm/unistd.h +++ b/arch/unicore32/include/uapi/asm/unistd.h @@ -12,3 +12,4 @@ /* Use the standard ABI for syscalls. */ #include +#define __ARCH_WANT_SYS_EXECVE diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S index 32648c99483a..7049350c790f 100644 --- a/arch/unicore32/kernel/entry.S +++ b/arch/unicore32/kernel/entry.S @@ -668,11 +668,6 @@ __cr_alignment: #endif .ltorg -ENTRY(sys_execve) - add r3, sp, #S_OFF - b __sys_execve -ENDPROC(sys_execve) - ENTRY(sys_clone) add ip, sp, #S_OFF stw ip, [sp+], #4 diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c index 8b6e4cc57393..9680134b31f0 100644 --- a/arch/unicore32/kernel/sys.c +++ b/arch/unicore32/kernel/sys.c @@ -42,27 +42,6 @@ asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp, parent_tid, child_tid); } -/* sys_execve() executes a new program. - * This is called indirectly via a small wrapper - */ -asmlinkage long __sys_execve(const char __user *filename, - const char __user *const __user *argv, - const char __user *const __user *envp, - struct pt_regs *regs) -{ - int error; - struct filename *fn; - - fn = getname(filename); - error = PTR_ERR(fn); - if (IS_ERR(fn)) - goto out; - error = do_execve(fn->name, argv, envp, regs); - putname(fn); -out: - return error; -} - /* Note: used by the compat code even in 64-bit Linux. */ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, -- cgit v1.2.2 From c284464658acab50c67ff65ff3dc9215a0231ad2 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 23 Oct 2012 13:01:43 -0700 Subject: arch/unicore32: remove CONFIG_EXPERIMENTAL This config item has not carried much meaning for a while now and is almost always enabled by default. As agreed during the Linux kernel summit, remove it. CC: Guan Xuetao Signed-off-by: Kees Cook Acked-by: Guan Xuetao --- arch/unicore32/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index fda37c941c10..c4fbb21e802b 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -221,7 +221,7 @@ config PUV3_GPIO bool depends on !ARCH_FPGA select GENERIC_GPIO - select GPIO_SYSFS if EXPERIMENTAL + select GPIO_SYSFS default y if PUV3_NB0916 -- cgit v1.2.2 From 4870639a754991a52fc8f4ba82f0d9c247c33659 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 7 Nov 2012 12:54:21 +0100 Subject: MIPS: compat: Fix use of TIF_32BIT_ADDR vs _TIF_32BIT_ADDR Signed-off-by: Ralf Baechle --- arch/mips/include/asm/thread_info.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 8debe9e91754..d8323ea9d5e8 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -115,7 +115,7 @@ register struct thread_info *__current_thread_info __asm__("$28"); #ifdef CONFIG_MIPS32_O32 #define TIF_32BIT TIF_32BIT_REGS #elif defined(CONFIG_MIPS32_N32) -#define TIF_32BIT _TIF_32BIT_ADDR +#define TIF_32BIT TIF_32BIT_ADDR #endif /* CONFIG_MIPS32_O32 */ #define _TIF_SYSCALL_TRACE (1< Date: Thu, 8 Nov 2012 23:59:31 +0100 Subject: MIPS: compat: Implement is_compat_task() by testing for 32-bit address space. So far is_compat_task() was testing for 32-bit registers if O32 support was enabled and if O32 support was disabled but N32 enabled it was testing for 32-bit address space. So if both O32 and N32 were enabled a N32 task was not considered a compat task, whops. This still leaves potential cases where O32 and N32 need different treatment unsolved. But that's another commit. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/compat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h index 58277e0e9cd4..3c5d1464b7bd 100644 --- a/arch/mips/include/asm/compat.h +++ b/arch/mips/include/asm/compat.h @@ -290,7 +290,7 @@ struct compat_shmid64_ds { static inline int is_compat_task(void) { - return test_thread_flag(TIF_32BIT); + return test_thread_flag(TIF_32BIT_ADDR); } #endif /* _ASM_COMPAT_H */ -- cgit v1.2.2 From 34d875d7b579baab2f2f6dfd8e8533602d9dbf33 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 9 Nov 2012 00:28:59 +0100 Subject: MIPS: compat: Delete now unused TIF_32BIT. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/thread_info.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'arch') diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index d8323ea9d5e8..18806a52061c 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -112,12 +112,6 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ -#ifdef CONFIG_MIPS32_O32 -#define TIF_32BIT TIF_32BIT_REGS -#elif defined(CONFIG_MIPS32_N32) -#define TIF_32BIT TIF_32BIT_ADDR -#endif /* CONFIG_MIPS32_O32 */ - #define _TIF_SYSCALL_TRACE (1< Date: Thu, 6 Sep 2012 11:36:54 -0400 Subject: MIPS: bitops.h: Change use of 'unsigned short' to 'int' [ralf@linux-mips.org: No functional change but it's consistent with how use types elsewhere in the code.] Signed-off-by: Jim Quinlan Cc: linux-mips@linux-mips.org Cc: David Daney Cc: Kevin Cernekee cernekee@gmail.com Cc: Jim Quinlan Patchwork: https://patchwork.linux-mips.org/patch/4319/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/bitops.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 82ad35ce2b45..455664cf5352 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h @@ -57,7 +57,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long temp; if (kernel_uses_llsc && R10000_LLSC_WAR) { @@ -118,7 +118,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long temp; if (kernel_uses_llsc && R10000_LLSC_WAR) { @@ -191,7 +191,7 @@ static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *ad */ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) { - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; if (kernel_uses_llsc && R10000_LLSC_WAR) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); @@ -244,7 +244,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) static inline int test_and_set_bit(unsigned long nr, volatile unsigned long *addr) { - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long res; smp_mb__before_llsc(); @@ -310,7 +310,7 @@ static inline int test_and_set_bit(unsigned long nr, static inline int test_and_set_bit_lock(unsigned long nr, volatile unsigned long *addr) { - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long res; if (kernel_uses_llsc && R10000_LLSC_WAR) { @@ -373,7 +373,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, static inline int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) { - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long res; smp_mb__before_llsc(); @@ -457,7 +457,7 @@ static inline int test_and_clear_bit(unsigned long nr, static inline int test_and_change_bit(unsigned long nr, volatile unsigned long *addr) { - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long res; smp_mb__before_llsc(); -- cgit v1.2.2 From 92d11594f688c8b55b51e80f2eac4417396237a4 Mon Sep 17 00:00:00 2001 From: Jim Quinlan Date: Thu, 6 Sep 2012 11:36:55 -0400 Subject: MIPS: Remove irqflags.h dependency from bitops.h The "else clause" of most functions in bitops.h invoked raw_local_irq_{save,restore}() and in doing so had a dependency on irqflags.h. This fix moves said code to bitops.c, removing the dependency. Signed-off-by: Jim Quinlan Cc: linux-mips@linux-mips.org Cc: David Daney Cc: Kevin Cernekee cernekee@gmail.com Cc: Jim Quinlan Patchwork: https://patchwork.linux-mips.org/patch/4320/ Signed-off-by: Ralf Baechle --- arch/mips/cavium-octeon/executive/cvmx-l2c.c | 1 + arch/mips/include/asm/bitops.h | 114 +++++------------ arch/mips/include/asm/io.h | 1 + arch/mips/lib/Makefile | 2 +- arch/mips/lib/bitops.c | 179 +++++++++++++++++++++++++++ 5 files changed, 214 insertions(+), 83 deletions(-) create mode 100644 arch/mips/lib/bitops.c (limited to 'arch') diff --git a/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/arch/mips/cavium-octeon/executive/cvmx-l2c.c index d38246e33ddb..9f883bf76953 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-l2c.c +++ b/arch/mips/cavium-octeon/executive/cvmx-l2c.c @@ -30,6 +30,7 @@ * measurement, and debugging facilities. */ +#include #include #include #include diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 455664cf5352..46ac73abd5ee 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h @@ -14,7 +14,6 @@ #endif #include -#include #include #include #include /* sigh ... */ @@ -44,6 +43,24 @@ #define smp_mb__before_clear_bit() smp_mb__before_llsc() #define smp_mb__after_clear_bit() smp_llsc_mb() + +/* + * These are the "slower" versions of the functions and are in bitops.c. + * These functions call raw_local_irq_{save,restore}(). + */ +void __mips_set_bit(unsigned long nr, volatile unsigned long *addr); +void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr); +void __mips_change_bit(unsigned long nr, volatile unsigned long *addr); +int __mips_test_and_set_bit(unsigned long nr, + volatile unsigned long *addr); +int __mips_test_and_set_bit_lock(unsigned long nr, + volatile unsigned long *addr); +int __mips_test_and_clear_bit(unsigned long nr, + volatile unsigned long *addr); +int __mips_test_and_change_bit(unsigned long nr, + volatile unsigned long *addr); + + /* * set_bit - Atomically set a bit in memory * @nr: the bit to set @@ -92,17 +109,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "+m" (*m) : "ir" (1UL << bit)); } while (unlikely(!temp)); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - *a |= mask; - raw_local_irq_restore(flags); - } + } else + __mips_set_bit(nr, addr); } /* @@ -153,17 +161,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "+m" (*m) : "ir" (~(1UL << bit))); } while (unlikely(!temp)); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - *a &= ~mask; - raw_local_irq_restore(flags); - } + } else + __mips_clear_bit(nr, addr); } /* @@ -220,17 +219,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "+m" (*m) : "ir" (1UL << bit)); } while (unlikely(!temp)); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - *a ^= mask; - raw_local_irq_restore(flags); - } + } else + __mips_change_bit(nr, addr); } /* @@ -281,18 +271,8 @@ static inline int test_and_set_bit(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a |= mask; - raw_local_irq_restore(flags); - } + } else + res = __mips_test_and_set_bit(nr, addr); smp_llsc_mb(); @@ -345,18 +325,8 @@ static inline int test_and_set_bit_lock(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a |= mask; - raw_local_irq_restore(flags); - } + } else + res = __mips_test_and_set_bit_lock(nr, addr); smp_llsc_mb(); @@ -428,18 +398,8 @@ static inline int test_and_clear_bit(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a &= ~mask; - raw_local_irq_restore(flags); - } + } else + res = __mips_test_and_clear_bit(nr, addr); smp_llsc_mb(); @@ -494,18 +454,8 @@ static inline int test_and_change_bit(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a ^= mask; - raw_local_irq_restore(flags); - } + } else + res = __mips_test_and_change_bit(nr, addr); smp_llsc_mb(); diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 29d9c23c20c7..ff2e0345e013 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index c4a82e841c73..a7b893714354 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for MIPS-specific library files.. # -lib-y += csum_partial.o delay.o memcpy.o memset.o \ +lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ strlen_user.o strncpy_user.o strnlen_user.o uncached.o obj-y += iomap.o diff --git a/arch/mips/lib/bitops.c b/arch/mips/lib/bitops.c new file mode 100644 index 000000000000..239a9c957b02 --- /dev/null +++ b/arch/mips/lib/bitops.c @@ -0,0 +1,179 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 1994-1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org) + * Copyright (c) 1999, 2000 Silicon Graphics, Inc. + */ +#include +#include +#include + + +/** + * __mips_set_bit - Atomically set a bit in memory. This is called by + * set_bit() if it cannot find a faster solution. + * @nr: the bit to set + * @addr: the address to start counting from + */ +void __mips_set_bit(unsigned long nr, volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + *a |= mask; + raw_local_irq_restore(flags); +} +EXPORT_SYMBOL(__mips_set_bit); + + +/** + * __mips_clear_bit - Clears a bit in memory. This is called by clear_bit() if + * it cannot find a faster solution. + * @nr: Bit to clear + * @addr: Address to start counting from + */ +void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + *a &= ~mask; + raw_local_irq_restore(flags); +} +EXPORT_SYMBOL(__mips_clear_bit); + + +/** + * __mips_change_bit - Toggle a bit in memory. This is called by change_bit() + * if it cannot find a faster solution. + * @nr: Bit to change + * @addr: Address to start counting from + */ +void __mips_change_bit(unsigned long nr, volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + *a ^= mask; + raw_local_irq_restore(flags); +} +EXPORT_SYMBOL(__mips_change_bit); + + +/** + * __mips_test_and_set_bit - Set a bit and return its old value. This is + * called by test_and_set_bit() if it cannot find a faster solution. + * @nr: Bit to set + * @addr: Address to count from + */ +int __mips_test_and_set_bit(unsigned long nr, + volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + unsigned long res; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a |= mask; + raw_local_irq_restore(flags); + return res; +} +EXPORT_SYMBOL(__mips_test_and_set_bit); + + +/** + * __mips_test_and_set_bit_lock - Set a bit and return its old value. This is + * called by test_and_set_bit_lock() if it cannot find a faster solution. + * @nr: Bit to set + * @addr: Address to count from + */ +int __mips_test_and_set_bit_lock(unsigned long nr, + volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + unsigned long res; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a |= mask; + raw_local_irq_restore(flags); + return res; +} +EXPORT_SYMBOL(__mips_test_and_set_bit_lock); + + +/** + * __mips_test_and_clear_bit - Clear a bit and return its old value. This is + * called by test_and_clear_bit() if it cannot find a faster solution. + * @nr: Bit to clear + * @addr: Address to count from + */ +int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + unsigned long res; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a &= ~mask; + raw_local_irq_restore(flags); + return res; +} +EXPORT_SYMBOL(__mips_test_and_clear_bit); + + +/** + * __mips_test_and_change_bit - Change a bit and return its old value. This is + * called by test_and_change_bit() if it cannot find a faster solution. + * @nr: Bit to change + * @addr: Address to count from + */ +int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + unsigned long res; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a ^= mask; + raw_local_irq_restore(flags); + return res; +} +EXPORT_SYMBOL(__mips_test_and_change_bit); -- cgit v1.2.2 From e97c5b609880d97313b13eb71830fca62cee50c2 Mon Sep 17 00:00:00 2001 From: Jim Quinlan Date: Thu, 6 Sep 2012 11:36:56 -0400 Subject: MIPS: Make irqflags.h functions preempt-safe for non-mipsr2 cpus For non MIPSr2 processors, such as the BMIPS 5000, calls to arch_local_irq_disable() and others may be preempted, and in doing so a stale value may be restored to c0_status. This fix disables preemption for such processors prior to the call and enables it after the call. Those functions that needed this fix have been "outlined" to mips-atomic.c, as they are no longer good candidates for inlining. This bug was observed in a BMIPS 5000, occuring once every few hours in a continuous reboot test. It was traced to the write_lock_irq() function which was being invoked in release_task() in exit.c. By placing a number of "nops" inbetween the mfc0/mtc0 pair in arch_local_irq_disable(), which is called by write_lock_irq(), we were able to greatly increase the occurance of this bug. Similarly, the application of this commit silenced the bug. Signed-off-by: Jim Quinlan Cc: linux-mips@linux-mips.org Cc: David Daney Cc: Kevin Cernekee cernekee@gmail.com Cc: Jim Quinlan Patchwork: https://patchwork.linux-mips.org/patch/4321/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/irqflags.h | 207 ++++++++++++++------------------------- arch/mips/lib/Makefile | 3 +- arch/mips/lib/mips-atomic.c | 176 +++++++++++++++++++++++++++++++++ 3 files changed, 253 insertions(+), 133 deletions(-) create mode 100644 arch/mips/lib/mips-atomic.c (limited to 'arch') diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h index 309cbcd6909c..9f3384c789d7 100644 --- a/arch/mips/include/asm/irqflags.h +++ b/arch/mips/include/asm/irqflags.h @@ -16,83 +16,13 @@ #include #include -__asm__( - " .macro arch_local_irq_enable \n" - " .set push \n" - " .set reorder \n" - " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" - " ori $1, 0x400 \n" - " xori $1, 0x400 \n" - " mtc0 $1, $2, 1 \n" -#elif defined(CONFIG_CPU_MIPSR2) - " ei \n" -#else - " mfc0 $1,$12 \n" - " ori $1,0x1f \n" - " xori $1,0x1e \n" - " mtc0 $1,$12 \n" -#endif - " irq_enable_hazard \n" - " .set pop \n" - " .endm"); +#if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) -extern void smtc_ipi_replay(void); - -static inline void arch_local_irq_enable(void) -{ -#ifdef CONFIG_MIPS_MT_SMTC - /* - * SMTC kernel needs to do a software replay of queued - * IPIs, at the cost of call overhead on each local_irq_enable() - */ - smtc_ipi_replay(); -#endif - __asm__ __volatile__( - "arch_local_irq_enable" - : /* no outputs */ - : /* no inputs */ - : "memory"); -} - - -/* - * For cli() we have to insert nops to make sure that the new value - * has actually arrived in the status register before the end of this - * macro. - * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs - * no nops at all. - */ -/* - * For TX49, operating only IE bit is not enough. - * - * If mfc0 $12 follows store and the mfc0 is last instruction of a - * page and fetching the next instruction causes TLB miss, the result - * of the mfc0 might wrongly contain EXL bit. - * - * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 - * - * Workaround: mask EXL bit of the result or place a nop before mfc0. - */ __asm__( " .macro arch_local_irq_disable\n" " .set push \n" " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 $1, $2, 1 \n" - " ori $1, 0x400 \n" - " .set noreorder \n" - " mtc0 $1, $2, 1 \n" -#elif defined(CONFIG_CPU_MIPSR2) " di \n" -#else - " mfc0 $1,$12 \n" - " ori $1,0x1f \n" - " xori $1,0x1f \n" - " .set noreorder \n" - " mtc0 $1,$12 \n" -#endif " irq_disable_hazard \n" " .set pop \n" " .endm \n"); @@ -106,46 +36,14 @@ static inline void arch_local_irq_disable(void) : "memory"); } -__asm__( - " .macro arch_local_save_flags flags \n" - " .set push \n" - " .set reorder \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 \\flags, $2, 1 \n" -#else - " mfc0 \\flags, $12 \n" -#endif - " .set pop \n" - " .endm \n"); - -static inline unsigned long arch_local_save_flags(void) -{ - unsigned long flags; - asm volatile("arch_local_save_flags %0" : "=r" (flags)); - return flags; -} __asm__( " .macro arch_local_irq_save result \n" " .set push \n" " .set reorder \n" " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 \\result, $2, 1 \n" - " ori $1, \\result, 0x400 \n" - " .set noreorder \n" - " mtc0 $1, $2, 1 \n" - " andi \\result, \\result, 0x400 \n" -#elif defined(CONFIG_CPU_MIPSR2) " di \\result \n" " andi \\result, 1 \n" -#else - " mfc0 \\result, $12 \n" - " ori $1, \\result, 0x1f \n" - " xori $1, 0x1f \n" - " .set noreorder \n" - " mtc0 $1, $12 \n" -#endif " irq_disable_hazard \n" " .set pop \n" " .endm \n"); @@ -160,61 +58,37 @@ static inline unsigned long arch_local_irq_save(void) return flags; } + __asm__( " .macro arch_local_irq_restore flags \n" " .set push \n" " .set noreorder \n" " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - "mfc0 $1, $2, 1 \n" - "andi \\flags, 0x400 \n" - "ori $1, 0x400 \n" - "xori $1, 0x400 \n" - "or \\flags, $1 \n" - "mtc0 \\flags, $2, 1 \n" -#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) +#if defined(CONFIG_IRQ_CPU) /* * Slow, but doesn't suffer from a relatively unlikely race * condition we're having since days 1. */ " beqz \\flags, 1f \n" - " di \n" + " di \n" " ei \n" "1: \n" -#elif defined(CONFIG_CPU_MIPSR2) +#else /* * Fast, dangerous. Life is fun, life is good. */ " mfc0 $1, $12 \n" " ins $1, \\flags, 0, 1 \n" " mtc0 $1, $12 \n" -#else - " mfc0 $1, $12 \n" - " andi \\flags, 1 \n" - " ori $1, 0x1f \n" - " xori $1, 0x1f \n" - " or \\flags, $1 \n" - " mtc0 \\flags, $12 \n" #endif " irq_disable_hazard \n" " .set pop \n" " .endm \n"); - static inline void arch_local_irq_restore(unsigned long flags) { unsigned long __tmp1; -#ifdef CONFIG_MIPS_MT_SMTC - /* - * SMTC kernel needs to do a software replay of queued - * IPIs, at the cost of branch and call overhead on each - * local_irq_restore() - */ - if (unlikely(!(flags & 0x0400))) - smtc_ipi_replay(); -#endif - __asm__ __volatile__( "arch_local_irq_restore\t%0" : "=r" (__tmp1) @@ -232,6 +106,75 @@ static inline void __arch_local_irq_restore(unsigned long flags) : "0" (flags) : "memory"); } +#else +/* Functions that require preempt_{dis,en}able() are in mips-atomic.c */ +void arch_local_irq_disable(void); +unsigned long arch_local_irq_save(void); +void arch_local_irq_restore(unsigned long flags); +void __arch_local_irq_restore(unsigned long flags); +#endif /* if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) */ + + +__asm__( + " .macro arch_local_irq_enable \n" + " .set push \n" + " .set reorder \n" + " .set noat \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" + " ori $1, 0x400 \n" + " xori $1, 0x400 \n" + " mtc0 $1, $2, 1 \n" +#elif defined(CONFIG_CPU_MIPSR2) + " ei \n" +#else + " mfc0 $1,$12 \n" + " ori $1,0x1f \n" + " xori $1,0x1e \n" + " mtc0 $1,$12 \n" +#endif + " irq_enable_hazard \n" + " .set pop \n" + " .endm"); + +extern void smtc_ipi_replay(void); + +static inline void arch_local_irq_enable(void) +{ +#ifdef CONFIG_MIPS_MT_SMTC + /* + * SMTC kernel needs to do a software replay of queued + * IPIs, at the cost of call overhead on each local_irq_enable() + */ + smtc_ipi_replay(); +#endif + __asm__ __volatile__( + "arch_local_irq_enable" + : /* no outputs */ + : /* no inputs */ + : "memory"); +} + + +__asm__( + " .macro arch_local_save_flags flags \n" + " .set push \n" + " .set reorder \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 \\flags, $2, 1 \n" +#else + " mfc0 \\flags, $12 \n" +#endif + " .set pop \n" + " .endm \n"); + +static inline unsigned long arch_local_save_flags(void) +{ + unsigned long flags; + asm volatile("arch_local_save_flags %0" : "=r" (flags)); + return flags; +} + static inline int arch_irqs_disabled_flags(unsigned long flags) { @@ -245,7 +188,7 @@ static inline int arch_irqs_disabled_flags(unsigned long flags) #endif } -#endif +#endif /* #ifndef __ASSEMBLY__ */ /* * Do the CPU's IRQ-state tracing from assembly code. diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index a7b893714354..eeddc58802e1 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -3,7 +3,8 @@ # lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ - strlen_user.o strncpy_user.o strnlen_user.o uncached.o + mips-atomic.o strlen_user.o strncpy_user.o \ + strnlen_user.o uncached.o obj-y += iomap.o obj-$(CONFIG_PCI) += iomap-pci.o diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c new file mode 100644 index 000000000000..e091430dbeb1 --- /dev/null +++ b/arch/mips/lib/mips-atomic.c @@ -0,0 +1,176 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle + * Copyright (C) 1996 by Paul M. Antoine + * Copyright (C) 1999 Silicon Graphics + * Copyright (C) 2000 MIPS Technologies, Inc. + */ +#include +#include +#include +#include +#include + +#if !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) + +/* + * For cli() we have to insert nops to make sure that the new value + * has actually arrived in the status register before the end of this + * macro. + * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs + * no nops at all. + */ +/* + * For TX49, operating only IE bit is not enough. + * + * If mfc0 $12 follows store and the mfc0 is last instruction of a + * page and fetching the next instruction causes TLB miss, the result + * of the mfc0 might wrongly contain EXL bit. + * + * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 + * + * Workaround: mask EXL bit of the result or place a nop before mfc0. + */ +__asm__( + " .macro arch_local_irq_disable\n" + " .set push \n" + " .set noat \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 $1, $2, 1 \n" + " ori $1, 0x400 \n" + " .set noreorder \n" + " mtc0 $1, $2, 1 \n" +#elif defined(CONFIG_CPU_MIPSR2) + /* see irqflags.h for inline function */ +#else + " mfc0 $1,$12 \n" + " ori $1,0x1f \n" + " xori $1,0x1f \n" + " .set noreorder \n" + " mtc0 $1,$12 \n" +#endif + " irq_disable_hazard \n" + " .set pop \n" + " .endm \n"); + +void arch_local_irq_disable(void) +{ + preempt_disable(); + __asm__ __volatile__( + "arch_local_irq_disable" + : /* no outputs */ + : /* no inputs */ + : "memory"); + preempt_enable(); +} +EXPORT_SYMBOL(arch_local_irq_disable); + + +__asm__( + " .macro arch_local_irq_save result \n" + " .set push \n" + " .set reorder \n" + " .set noat \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 \\result, $2, 1 \n" + " ori $1, \\result, 0x400 \n" + " .set noreorder \n" + " mtc0 $1, $2, 1 \n" + " andi \\result, \\result, 0x400 \n" +#elif defined(CONFIG_CPU_MIPSR2) + /* see irqflags.h for inline function */ +#else + " mfc0 \\result, $12 \n" + " ori $1, \\result, 0x1f \n" + " xori $1, 0x1f \n" + " .set noreorder \n" + " mtc0 $1, $12 \n" +#endif + " irq_disable_hazard \n" + " .set pop \n" + " .endm \n"); + +unsigned long arch_local_irq_save(void) +{ + unsigned long flags; + preempt_disable(); + asm volatile("arch_local_irq_save\t%0" + : "=r" (flags) + : /* no inputs */ + : "memory"); + preempt_enable(); + return flags; +} +EXPORT_SYMBOL(arch_local_irq_save); + + +__asm__( + " .macro arch_local_irq_restore flags \n" + " .set push \n" + " .set noreorder \n" + " .set noat \n" +#ifdef CONFIG_MIPS_MT_SMTC + "mfc0 $1, $2, 1 \n" + "andi \\flags, 0x400 \n" + "ori $1, 0x400 \n" + "xori $1, 0x400 \n" + "or \\flags, $1 \n" + "mtc0 \\flags, $2, 1 \n" +#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) + /* see irqflags.h for inline function */ +#elif defined(CONFIG_CPU_MIPSR2) + /* see irqflags.h for inline function */ +#else + " mfc0 $1, $12 \n" + " andi \\flags, 1 \n" + " ori $1, 0x1f \n" + " xori $1, 0x1f \n" + " or \\flags, $1 \n" + " mtc0 \\flags, $12 \n" +#endif + " irq_disable_hazard \n" + " .set pop \n" + " .endm \n"); + +void arch_local_irq_restore(unsigned long flags) +{ + unsigned long __tmp1; + +#ifdef CONFIG_MIPS_MT_SMTC + /* + * SMTC kernel needs to do a software replay of queued + * IPIs, at the cost of branch and call overhead on each + * local_irq_restore() + */ + if (unlikely(!(flags & 0x0400))) + smtc_ipi_replay(); +#endif + preempt_disable(); + __asm__ __volatile__( + "arch_local_irq_restore\t%0" + : "=r" (__tmp1) + : "0" (flags) + : "memory"); + preempt_enable(); +} +EXPORT_SYMBOL(arch_local_irq_restore); + + +void __arch_local_irq_restore(unsigned long flags) +{ + unsigned long __tmp1; + + preempt_disable(); + __asm__ __volatile__( + "arch_local_irq_restore\t%0" + : "=r" (__tmp1) + : "0" (flags) + : "memory"); + preempt_enable(); +} +EXPORT_SYMBOL(__arch_local_irq_restore); + +#endif /* !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) */ -- cgit v1.2.2 From ab277bbf662ef17ffb7fd8dd7a462a34e326e492 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Thu, 8 Nov 2012 15:58:55 +0000 Subject: xen/arm: Fix compile errors when drivers are compiled as modules (export more). The commit 911dec0db4de6ccc544178a8ddaf9cec0a11d533 "xen/arm: Fix compile errors when drivers are compiled as modules." exports the neccessary functions. But to guard ourselves against out-of-tree modules and future drivers hitting this, lets export all of the relevant hypercalls. Acked-by: Arnd Bergmann Signed-off-by: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk --- arch/arm/xen/enlighten.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 96d969da5335..f57609275449 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -170,4 +170,10 @@ EXPORT_SYMBOL_GPL(free_xenballooned_pages); /* In the hypervisor.S file. */ EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op); EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op); +EXPORT_SYMBOL_GPL(HYPERVISOR_xen_version); +EXPORT_SYMBOL_GPL(HYPERVISOR_console_io); +EXPORT_SYMBOL_GPL(HYPERVISOR_sched_op); +EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op); +EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op); +EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op); EXPORT_SYMBOL_GPL(privcmd_call); -- cgit v1.2.2 From 20424d85f8a07090fd32c6fad343f91b63c730b0 Mon Sep 17 00:00:00 2001 From: Andreas Larsson Date: Tue, 30 Oct 2012 00:09:46 +0000 Subject: sparc32, leon: Check for existent irq_map entry in leon_handle_ext_irq If an irq is being unlinked concurrently with leon_handle_ext_irq, irq_map[eirq] might be null in leon_handle_ext_irq. Make sure that this is not dereferenced. Signed-off-by: Andreas Larsson Acked-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/leon_kernel.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index f8b6eee40bde..87f60ee65433 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -56,11 +56,13 @@ static inline unsigned int leon_eirq_get(int cpu) static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) { unsigned int eirq; + struct irq_bucket *p; int cpu = sparc_leon3_cpuid(); eirq = leon_eirq_get(cpu); - if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */ - generic_handle_irq(irq_map[eirq]->irq); + p = irq_map[eirq]; + if ((eirq & 0x10) && p && p->irq) /* bit4 tells if IRQ happened */ + generic_handle_irq(p->irq); } /* The extended IRQ controller has been found, this function registers it */ -- cgit v1.2.2 From 0bce04be442cf4d6e4ba9dac2f0a4c5ee88af5c5 Mon Sep 17 00:00:00 2001 From: Andreas Larsson Date: Tue, 6 Nov 2012 00:12:03 +0000 Subject: of/address: sparc: Declare of_address_to_resource() as an extern function for sparc again This bug-fix makes sure that of_address_to_resource is defined extern for sparc so that the sparc-specific implementation of of_address_to_resource() is once again used when including include/linux/of_address.h in a sparc context. A number of drivers in mainline relies on this function working for sparc. The bug was introduced in a850a7554442f08d3e910c6eeb4ee216868dda1e, "of/address: add empty static inlines for !CONFIG_OF". Contrary to that commit title, the static inlines are added for !CONFIG_OF_ADDRESS, and CONFIG_OF_ADDRESS is never defined for sparc. This is good behavior for the other functions in include/linux/of_address.h, as the extern functions defined in drivers/of/address.c only gets linked when OF_ADDRESS is configured. However, for of_address_to_resource there exists a sparc-specific implementation in arch/sparc/arch/sparc/kernel/of_device_common.c Solution suggested by: Sam Ravnborg Signed-off-by: Andreas Larsson Acked-by: Rob Herring Signed-off-by: David S. Miller --- arch/sparc/include/asm/prom.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index c28765110706..f93003123bce 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -63,5 +63,10 @@ extern char *of_console_options; extern void irq_trans_init(struct device_node *dp); extern char *build_path_component(struct device_node *dp); +/* SPARC has a local implementation */ +extern int of_address_to_resource(struct device_node *dev, int index, + struct resource *r); +#define of_address_to_resource of_address_to_resource + #endif /* __KERNEL__ */ #endif /* _SPARC_PROM_H */ -- cgit v1.2.2 From 193d2aadc0ff5c687f6f0d5ef1d38c86ab511a14 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 9 Nov 2012 19:37:59 -0800 Subject: sparc: Support atomic64_dec_if_positive properly. Sparc32 already supported it, as a consequence of using the generic atomic64 implementation. And the sparc64 implementation is rather trivial. This allows us to set ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE for all of sparc, and avoid the annoying warning from lib/atomic64_test.c Signed-off-by: David S. Miller --- arch/sparc/Kconfig | 1 + arch/sparc/include/asm/atomic_64.h | 4 +++- arch/sparc/lib/atomic_64.S | 16 +++++++++++++++- arch/sparc/lib/ksyms.c | 1 + 4 files changed, 20 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index b6b442b0d793..9f2edb5c5551 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -20,6 +20,7 @@ config SPARC select HAVE_ARCH_TRACEHOOK select SYSCTL_EXCEPTION_TRACE select ARCH_WANT_OPTIONAL_GPIOLIB + select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select RTC_CLASS select RTC_DRV_M48T59 select HAVE_IRQ_WORK diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index ce35a1cf1a20..be56a244c9cf 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h @@ -1,7 +1,7 @@ /* atomic.h: Thankfully the V9 is at least reasonable for this * stuff. * - * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com) + * Copyright (C) 1996, 1997, 2000, 2012 David S. Miller (davem@redhat.com) */ #ifndef __ARCH_SPARC64_ATOMIC__ @@ -106,6 +106,8 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u) #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) +extern long atomic64_dec_if_positive(atomic64_t *v); + /* Atomic operations are already serializing */ #define smp_mb__before_atomic_dec() barrier() #define smp_mb__after_atomic_dec() barrier() diff --git a/arch/sparc/lib/atomic_64.S b/arch/sparc/lib/atomic_64.S index 4d502da3de78..85c233d0a340 100644 --- a/arch/sparc/lib/atomic_64.S +++ b/arch/sparc/lib/atomic_64.S @@ -1,6 +1,6 @@ /* atomic.S: These things are too big to do inline. * - * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 1999, 2007 2012 David S. Miller (davem@davemloft.net) */ #include @@ -117,3 +117,17 @@ ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ sub %g1, %o0, %o0 2: BACKOFF_SPIN(%o2, %o3, 1b) ENDPROC(atomic64_sub_ret) + +ENTRY(atomic64_dec_if_positive) /* %o0 = atomic_ptr */ + BACKOFF_SETUP(%o2) +1: ldx [%o0], %g1 + brlez,pn %g1, 3f + sub %g1, 1, %g7 + casx [%o0], %g1, %g7 + cmp %g1, %g7 + bne,pn %xcc, BACKOFF_LABEL(2f, 1b) + nop +3: retl + sub %g1, 1, %o0 +2: BACKOFF_SPIN(%o2, %o3, 1b) +ENDPROC(atomic64_dec_if_positive) diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c index ee31b884c61b..0c4e35e522fa 100644 --- a/arch/sparc/lib/ksyms.c +++ b/arch/sparc/lib/ksyms.c @@ -116,6 +116,7 @@ EXPORT_SYMBOL(atomic64_add); EXPORT_SYMBOL(atomic64_add_ret); EXPORT_SYMBOL(atomic64_sub); EXPORT_SYMBOL(atomic64_sub_ret); +EXPORT_SYMBOL(atomic64_dec_if_positive); /* Atomic bit operations. */ EXPORT_SYMBOL(test_and_set_bit); -- cgit v1.2.2 From 226f7cea949303a3e1911999a9a2c71b0a708e73 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 9 Nov 2012 20:53:32 -0800 Subject: sparc64: Fix build with mix of modular vs. non-modular crypto drivers. We tried linking in a single built object to hold the device table, but only works if all of the sparc64 crypto modules get built the same way (modular vs. non-modular). Just include the device ID stub into each driver source file so that the table gets compiled into the correct result in all cases. Reported-by: Meelis Roos Signed-off-by: David S. Miller --- arch/sparc/crypto/Makefile | 16 ++++++++-------- arch/sparc/crypto/aes_glue.c | 2 ++ arch/sparc/crypto/camellia_glue.c | 2 ++ arch/sparc/crypto/crc32c_glue.c | 2 ++ arch/sparc/crypto/des_glue.c | 2 ++ arch/sparc/crypto/md5_glue.c | 2 ++ arch/sparc/crypto/sha1_glue.c | 2 ++ arch/sparc/crypto/sha256_glue.c | 2 ++ arch/sparc/crypto/sha512_glue.c | 2 ++ 9 files changed, 24 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/sparc/crypto/Makefile b/arch/sparc/crypto/Makefile index 6ae1ad5e502b..5d469d81761f 100644 --- a/arch/sparc/crypto/Makefile +++ b/arch/sparc/crypto/Makefile @@ -13,13 +13,13 @@ obj-$(CONFIG_CRYPTO_DES_SPARC64) += camellia-sparc64.o obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o -sha1-sparc64-y := sha1_asm.o sha1_glue.o crop_devid.o -sha256-sparc64-y := sha256_asm.o sha256_glue.o crop_devid.o -sha512-sparc64-y := sha512_asm.o sha512_glue.o crop_devid.o -md5-sparc64-y := md5_asm.o md5_glue.o crop_devid.o +sha1-sparc64-y := sha1_asm.o sha1_glue.o +sha256-sparc64-y := sha256_asm.o sha256_glue.o +sha512-sparc64-y := sha512_asm.o sha512_glue.o +md5-sparc64-y := md5_asm.o md5_glue.o -aes-sparc64-y := aes_asm.o aes_glue.o crop_devid.o -des-sparc64-y := des_asm.o des_glue.o crop_devid.o -camellia-sparc64-y := camellia_asm.o camellia_glue.o crop_devid.o +aes-sparc64-y := aes_asm.o aes_glue.o +des-sparc64-y := des_asm.o des_glue.o +camellia-sparc64-y := camellia_asm.o camellia_glue.o -crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o crop_devid.o +crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o diff --git a/arch/sparc/crypto/aes_glue.c b/arch/sparc/crypto/aes_glue.c index 8f1c9980f637..3965d1d36dfa 100644 --- a/arch/sparc/crypto/aes_glue.c +++ b/arch/sparc/crypto/aes_glue.c @@ -475,3 +475,5 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated"); MODULE_ALIAS("aes"); + +#include "crop_devid.c" diff --git a/arch/sparc/crypto/camellia_glue.c b/arch/sparc/crypto/camellia_glue.c index 42905c084299..62c89af3fd3f 100644 --- a/arch/sparc/crypto/camellia_glue.c +++ b/arch/sparc/crypto/camellia_glue.c @@ -320,3 +320,5 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated"); MODULE_ALIAS("aes"); + +#include "crop_devid.c" diff --git a/arch/sparc/crypto/crc32c_glue.c b/arch/sparc/crypto/crc32c_glue.c index 0bd89cea8d8e..5162fad912ce 100644 --- a/arch/sparc/crypto/crc32c_glue.c +++ b/arch/sparc/crypto/crc32c_glue.c @@ -177,3 +177,5 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated"); MODULE_ALIAS("crc32c"); + +#include "crop_devid.c" diff --git a/arch/sparc/crypto/des_glue.c b/arch/sparc/crypto/des_glue.c index c4940c2d3073..41524cebcc49 100644 --- a/arch/sparc/crypto/des_glue.c +++ b/arch/sparc/crypto/des_glue.c @@ -527,3 +527,5 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated"); MODULE_ALIAS("des"); + +#include "crop_devid.c" diff --git a/arch/sparc/crypto/md5_glue.c b/arch/sparc/crypto/md5_glue.c index 603d723038ce..09a9ea1dfb69 100644 --- a/arch/sparc/crypto/md5_glue.c +++ b/arch/sparc/crypto/md5_glue.c @@ -186,3 +186,5 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated"); MODULE_ALIAS("md5"); + +#include "crop_devid.c" diff --git a/arch/sparc/crypto/sha1_glue.c b/arch/sparc/crypto/sha1_glue.c index 2bbb20bee9f1..6cd5f29e1e0d 100644 --- a/arch/sparc/crypto/sha1_glue.c +++ b/arch/sparc/crypto/sha1_glue.c @@ -181,3 +181,5 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated"); MODULE_ALIAS("sha1"); + +#include "crop_devid.c" diff --git a/arch/sparc/crypto/sha256_glue.c b/arch/sparc/crypto/sha256_glue.c index 591e656bd891..04f555ab2680 100644 --- a/arch/sparc/crypto/sha256_glue.c +++ b/arch/sparc/crypto/sha256_glue.c @@ -239,3 +239,5 @@ MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm, sparc64 sha256 op MODULE_ALIAS("sha224"); MODULE_ALIAS("sha256"); + +#include "crop_devid.c" diff --git a/arch/sparc/crypto/sha512_glue.c b/arch/sparc/crypto/sha512_glue.c index 486f0a2b7001..f04d1994d19a 100644 --- a/arch/sparc/crypto/sha512_glue.c +++ b/arch/sparc/crypto/sha512_glue.c @@ -224,3 +224,5 @@ MODULE_DESCRIPTION("SHA-384 and SHA-512 Secure Hash Algorithm, sparc64 sha512 op MODULE_ALIAS("sha384"); MODULE_ALIAS("sha512"); + +#include "crop_devid.c" -- cgit v1.2.2 From 6722df86ba92cce09fd5348ca23e7042b51d6013 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Sun, 4 Nov 2012 22:03:02 +0100 Subject: ARM: 7570/1: quiet down the non make -s output Commit edc88ceb0c7d285b9f58bc29a638cd8163b59989 silenced the make -s build, but inadvertently made louder the non-silent build. Fix by prepending '@' to each of the added $(kecho) statements. Build with edc88ceb0c7d285b9f58bc29a638cd8163b59989: CHK include/generated/compile.h echo ' Kernel: arch/arm/boot/Image is ready' Kernel: arch/arm/boot/Image is ready LD arch/arm/boot/compressed/vmlinux OBJCOPY arch/arm/boot/zImage echo ' Kernel: arch/arm/boot/zImage is ready' Kernel: arch/arm/boot/zImage is ready Build with this fix: CHK include/generated/compile.h Kernel: arch/arm/boot/Image is ready LD arch/arm/boot/compressed/vmlinux OBJCOPY arch/arm/boot/zImage Kernel: arch/arm/boot/zImage is ready Signed-off-by: Josh Cartwright Signed-off-by: Russell King --- arch/arm/boot/Makefile | 10 +++++----- arch/arm/tools/Makefile | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index f2aa09eb658e..9137df539b61 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -33,7 +33,7 @@ ifeq ($(CONFIG_XIP_KERNEL),y) $(obj)/xipImage: vmlinux FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' + @$(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' $(obj)/Image $(obj)/zImage: FORCE @echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)' @@ -48,14 +48,14 @@ $(obj)/xipImage: FORCE $(obj)/Image: vmlinux FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' $(obj)/compressed/vmlinux: $(obj)/Image FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed $@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' endif @@ -90,7 +90,7 @@ fi $(obj)/uImage: $(obj)/zImage FORCE @$(check_for_multiple_loadaddr) $(call if_changed,uimage) - $(kecho) ' Image $@ is ready' + @$(kecho) ' Image $@ is ready' $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE $(Q)$(MAKE) $(build)=$(obj)/bootp $@ @@ -98,7 +98,7 @@ $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE $(obj)/bootpImage: $(obj)/bootp/bootp FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' PHONY += initrd FORCE initrd: diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile index cd60a81163e9..32d05c8219dc 100644 --- a/arch/arm/tools/Makefile +++ b/arch/arm/tools/Makefile @@ -5,6 +5,6 @@ # include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types - $(kecho) ' Generating $@' + @$(kecho) ' Generating $@' @mkdir -p $(dir $@) $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } -- cgit v1.2.2 From 2b6e204f84cc8e324c5425ea98e378a2aeba3be0 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 7 Nov 2012 21:22:08 +0100 Subject: ARM: 7572/1: proc-v6.S: fix comment Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mm/proc-v6.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 86b8b480634f..09c5233f4dfc 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -89,7 +89,7 @@ ENTRY(cpu_v6_dcache_clean_area) mov pc, lr /* - * cpu_arm926_switch_mm(pgd_phys, tsk) + * cpu_v6_switch_mm(pgd_phys, tsk) * * Set the translation table base pointer to be pgd_phys * -- cgit v1.2.2 From fa968ee215c0ca91e4a9c3a69ac2405aae6e5d2f Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 7 Nov 2012 10:44:08 +0100 Subject: s390/signal: set correct address space control If user space is running in primary mode it can switch to secondary or access register mode, this is used e.g. in the clock_gettime code of the vdso. If a signal is delivered to the user space process while it has been running in access register mode the signal handler is executed in access register mode as well which will result in a crash most of the time. Set the address space control bits in the PSW to the default for the execution of the signal handler and make sure that the previous address space control is restored on signal return. Take care that user space can not switch to the kernel address space by modifying the registers in the signal frame. Cc: stable@vger.kernel.org Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/compat.h | 2 +- arch/s390/include/uapi/asm/ptrace.h | 4 ++-- arch/s390/kernel/compat_signal.c | 14 ++++++++++++-- arch/s390/kernel/signal.c | 14 ++++++++++++-- 4 files changed, 27 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index a34a9d612fc0..18cd6b592650 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -20,7 +20,7 @@ #define PSW32_MASK_CC 0x00003000UL #define PSW32_MASK_PM 0x00000f00UL -#define PSW32_MASK_USER 0x00003F00UL +#define PSW32_MASK_USER 0x0000FF00UL #define PSW32_ADDR_AMODE 0x80000000UL #define PSW32_ADDR_INSN 0x7FFFFFFFUL diff --git a/arch/s390/include/uapi/asm/ptrace.h b/arch/s390/include/uapi/asm/ptrace.h index 705588a16d70..a5ca214b34fd 100644 --- a/arch/s390/include/uapi/asm/ptrace.h +++ b/arch/s390/include/uapi/asm/ptrace.h @@ -239,7 +239,7 @@ typedef struct #define PSW_MASK_EA 0x00000000UL #define PSW_MASK_BA 0x00000000UL -#define PSW_MASK_USER 0x00003F00UL +#define PSW_MASK_USER 0x0000FF00UL #define PSW_ADDR_AMODE 0x80000000UL #define PSW_ADDR_INSN 0x7FFFFFFFUL @@ -269,7 +269,7 @@ typedef struct #define PSW_MASK_EA 0x0000000100000000UL #define PSW_MASK_BA 0x0000000080000000UL -#define PSW_MASK_USER 0x00003F8180000000UL +#define PSW_MASK_USER 0x0000FF8180000000UL #define PSW_ADDR_AMODE 0x0000000000000000UL #define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index a1e8a8694bb7..593fcc9253fc 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -309,6 +309,10 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | (__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 | (__u64)(regs32.psw.addr & PSW32_ADDR_AMODE); + /* Check for invalid user address space control. */ + if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) + regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN); for (i = 0; i < NUM_GPRS; i++) regs->gprs[i] = (__u64) regs32.gprs[i]; @@ -481,7 +485,10 @@ static int setup_frame32(int sig, struct k_sigaction *ka, /* Set up registers for signal handler */ regs->gprs[15] = (__force __u64) frame; - regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ + /* Force 31 bit amode and default user address space control. */ + regs->psw.mask = PSW_MASK_BA | + (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (__force __u64) ka->sa.sa_handler; regs->gprs[2] = map_signal(sig); @@ -549,7 +556,10 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up registers for signal handler */ regs->gprs[15] = (__force __u64) frame; - regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ + /* Force 31 bit amode and default user address space control. */ + regs->psw.mask = PSW_MASK_BA | + (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (__u64) ka->sa.sa_handler; regs->gprs[2] = map_signal(sig); diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index c13a2a37ef00..d1259d875074 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -136,6 +136,10 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) /* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */ regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | (user_sregs.regs.psw.mask & PSW_MASK_USER); + /* Check for invalid user address space control. */ + if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) + regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); /* Check for invalid amode */ if (regs->psw.mask & PSW_MASK_EA) regs->psw.mask |= PSW_MASK_BA; @@ -273,7 +277,10 @@ static int setup_frame(int sig, struct k_sigaction *ka, /* Set up registers for signal handler */ regs->gprs[15] = (unsigned long) frame; - regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ + /* Force default amode and default user address space control. */ + regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | + (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; regs->gprs[2] = map_signal(sig); @@ -346,7 +353,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up registers for signal handler */ regs->gprs[15] = (unsigned long) frame; - regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ + /* Force default amode and default user address space control. */ + regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | + (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; regs->gprs[2] = map_signal(sig); -- cgit v1.2.2 From 658e5ce705f2a09ab681eb61ca7c8619bb7a783d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sat, 10 Nov 2012 11:04:27 +0100 Subject: s390/topology: fix core id vs physical package id mix-up The current topology code confuses core id vs physical package id. In other words /sys/devices/system/cpu/cpuX/topology/core_id displays the physical_package_id (aka socket id) instead of the core id. The physical_package_id sysfs attribute always displays "-1" instead of the socket id. Fix this mix-up with a small patch which defines and initializes topology_physical_package_id correctly and fixes the broken core id handling. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/topology.h | 3 +++ arch/s390/kernel/topology.c | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index 9ca305383760..9935cbd6a46f 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h @@ -8,6 +8,9 @@ struct cpu; #ifdef CONFIG_SCHED_BOOK +extern unsigned char cpu_socket_id[NR_CPUS]; +#define topology_physical_package_id(cpu) (cpu_socket_id[cpu]) + extern unsigned char cpu_core_id[NR_CPUS]; extern cpumask_t cpu_core_map[NR_CPUS]; diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 54d93f4b6818..dd55f7c20104 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -40,6 +40,7 @@ static DEFINE_SPINLOCK(topology_lock); static struct mask_info core_info; cpumask_t cpu_core_map[NR_CPUS]; unsigned char cpu_core_id[NR_CPUS]; +unsigned char cpu_socket_id[NR_CPUS]; static struct mask_info book_info; cpumask_t cpu_book_map[NR_CPUS]; @@ -83,11 +84,12 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu, cpumask_set_cpu(lcpu, &book->mask); cpu_book_id[lcpu] = book->id; cpumask_set_cpu(lcpu, &core->mask); + cpu_core_id[lcpu] = rcpu; if (one_core_per_cpu) { - cpu_core_id[lcpu] = rcpu; + cpu_socket_id[lcpu] = rcpu; core = core->next; } else { - cpu_core_id[lcpu] = core->id; + cpu_socket_id[lcpu] = core->id; } smp_cpu_set_polarization(lcpu, tl_cpu->pp); } -- cgit v1.2.2 From 1ef43369c681bf30a980a4ba42df20514b15fdda Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 8 Nov 2012 11:08:50 -0800 Subject: ARM: OMAP4: TWL: mux sys_drm_msecure as output for PMIC On OMAP4 boards using the TWL6030 PMIC, the sys_drm_msecure is connected to the MSECURE input of the TWL6030 PMIC. This signal controls the secure-mode operation of the PMIC. If its not mux'd correctly, some functionality of the PMIC will not be accessible since the PMIC will be in secure mode. For example, if the TWL RTC is in secure mode, most of its registers are read-only, meaning (re)programming the RTC (e.g. for wakeup from suspend) will fail. To fix, ensure the signal is properly mux'd as output when TWL is intialized. This fix is required when using recent versions of u-boot (>= v2012.04.01) since u-boot is no longer setting the default mux for this pin. Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/twl-common.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 635e109f5ad3..96cae8bdfc25 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -73,6 +73,7 @@ void __init omap4_pmic_init(const char *pmic_type, { /* PMIC part*/ omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE); + omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT); omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data); /* Register additional devices on i2c1 bus if needed */ -- cgit v1.2.2 From 2d4d07b97c0b774ea9ce2a2105818208d3df7241 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 24 Oct 2012 16:37:28 -0200 Subject: ARM: boot: Fix usage of kecho Since commit edc88ceb0 (ARM: be really quiet when building with 'make -s') the following output is generated when building a kernel for ARM: echo ' Kernel: arch/arm/boot/Image is ready' Kernel: arch/arm/boot/Image is ready Building modules, stage 2. echo ' Kernel: arch/arm/boot/zImage is ready' Kernel: arch/arm/boot/zImage is ready As per Documentation/kbuild/makefiles.txt the correct way of using kecho is '@$(kecho)'. Make this change so no more unwanted 'echo' messages are displayed. Signed-off-by: Fabio Estevam Signed-off-by: Arnd Bergmann --- arch/arm/boot/Makefile | 10 +++++----- arch/arm/tools/Makefile | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index f2aa09eb658e..9137df539b61 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -33,7 +33,7 @@ ifeq ($(CONFIG_XIP_KERNEL),y) $(obj)/xipImage: vmlinux FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' + @$(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' $(obj)/Image $(obj)/zImage: FORCE @echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)' @@ -48,14 +48,14 @@ $(obj)/xipImage: FORCE $(obj)/Image: vmlinux FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' $(obj)/compressed/vmlinux: $(obj)/Image FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed $@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' endif @@ -90,7 +90,7 @@ fi $(obj)/uImage: $(obj)/zImage FORCE @$(check_for_multiple_loadaddr) $(call if_changed,uimage) - $(kecho) ' Image $@ is ready' + @$(kecho) ' Image $@ is ready' $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE $(Q)$(MAKE) $(build)=$(obj)/bootp $@ @@ -98,7 +98,7 @@ $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE $(obj)/bootpImage: $(obj)/bootp/bootp FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' PHONY += initrd FORCE initrd: diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile index cd60a81163e9..32d05c8219dc 100644 --- a/arch/arm/tools/Makefile +++ b/arch/arm/tools/Makefile @@ -5,6 +5,6 @@ # include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types - $(kecho) ' Generating $@' + @$(kecho) ' Generating $@' @mkdir -p $(dir $@) $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } -- cgit v1.2.2 From 6d1068b3a98519247d8ba4ec85cd40ac136dbdf9 Mon Sep 17 00:00:00 2001 From: Petr Matousek Date: Tue, 6 Nov 2012 19:24:07 +0100 Subject: KVM: x86: invalid opcode oops on SET_SREGS with OSXSAVE bit set (CVE-2012-4461) On hosts without the XSAVE support unprivileged local user can trigger oops similar to the one below by setting X86_CR4_OSXSAVE bit in guest cr4 register using KVM_SET_SREGS ioctl and later issuing KVM_RUN ioctl. invalid opcode: 0000 [#2] SMP Modules linked in: tun ip6table_filter ip6_tables ebtable_nat ebtables ... Pid: 24935, comm: zoog_kvm_monito Tainted: G D 3.2.0-3-686-pae EIP: 0060:[] EFLAGS: 00210246 CPU: 0 EIP is at kvm_arch_vcpu_ioctl_run+0x92a/0xd13 [kvm] EAX: 00000001 EBX: 000f387e ECX: 00000000 EDX: 00000000 ESI: 00000000 EDI: 00000000 EBP: ef5a0060 ESP: d7c63e70 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 Process zoog_kvm_monito (pid: 24935, ti=d7c62000 task=ed84a0c0 task.ti=d7c62000) Stack: 00000001 f70a1200 f8b940a9 ef5a0060 00000000 00200202 f8769009 00000000 ef5a0060 000f387e eda5c020 8722f9c8 00015bae 00000000 ed84a0c0 ed84a0c0 c12bf02d 0000ae80 ef7f8740 fffffffb f359b740 ef5a0060 f8b85dc1 0000ae80 Call Trace: [] ? kvm_arch_vcpu_ioctl_set_sregs+0x2fe/0x308 [kvm] ... [] ? syscall_call+0x7/0xb Code: 89 e8 e8 14 ee ff ff ba 00 00 04 00 89 e8 e8 98 48 ff ff 85 c0 74 1e 83 7d 48 00 75 18 8b 85 08 07 00 00 31 c9 8b 95 0c 07 00 00 <0f> 01 d1 c7 45 48 01 00 00 00 c7 45 1c 01 00 00 00 0f ae f0 89 EIP: [] kvm_arch_vcpu_ioctl_run+0x92a/0xd13 [kvm] SS:ESP 0068:d7c63e70 QEMU first retrieves the supported features via KVM_GET_SUPPORTED_CPUID and then sets them later. So guest's X86_FEATURE_XSAVE should be masked out on hosts without X86_FEATURE_XSAVE, making kvm_set_cr4 with X86_CR4_OSXSAVE fail. Userspaces that allow specifying guest cpuid with X86_FEATURE_XSAVE even on hosts that do not support it, might be susceptible to this attack from inside the guest as well. Allow setting X86_CR4_OSXSAVE bit only if host has XSAVE support. Signed-off-by: Petr Matousek Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/cpuid.h | 3 +++ arch/x86/kvm/x86.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index a10e46016851..58fc51488828 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -24,6 +24,9 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu) { struct kvm_cpuid_entry2 *best; + if (!static_cpu_has(X86_FEATURE_XSAVE)) + return 0; + best = kvm_find_cpuid_entry(vcpu, 1, 0); return best && (best->ecx & bit(X86_FEATURE_XSAVE)); } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 224a7e78cb6c..4f7641756be2 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5781,6 +5781,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, int pending_vec, max_bits, idx; struct desc_ptr dt; + if (!guest_cpuid_has_xsave(vcpu) && (sregs->cr4 & X86_CR4_OSXSAVE)) + return -EINVAL; + dt.size = sregs->idt.limit; dt.address = sregs->idt.base; kvm_x86_ops->set_idt(vcpu, &dt); -- cgit v1.2.2 From d55c4c613fc4d4ad2ba0fc6fa2b57176d420f7e4 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 22 Oct 2012 15:49:02 +0200 Subject: s390/gup: add missing TASK_SIZE check to get_user_pages_fast() When walking page tables we need to make sure that everything is within bounds of the ASCE limit of the task's address space. Otherwise we might calculate e.g. a pud pointer which is not within a pud and dereference it. So check against TASK_SIZE (which is the ASCE limit) before walking page tables. Reviewed-by: Gerald Schaefer Cc: stable@vger.kernel.org Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/mm/gup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 8b8285310b5a..16fb3c1615dc 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -229,7 +229,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, addr = start; len = (unsigned long) nr_pages << PAGE_SHIFT; end = start + len; - if (end < start) + if ((end < start) || (end > TASK_SIZE)) goto slow_irqon; /* -- cgit v1.2.2 From 516bad44b9f3bdcb0be6be0252b7557bf7a149e4 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 22 Oct 2012 15:58:26 +0200 Subject: s390/gup: fix access_ok() usage in __get_user_pages_fast() access_ok() returns always "true" on s390. Therefore all access_ok() invocations are rather pointless. However when walking page tables we need to make sure that everything is within bounds of the ASCE limit of the task's address space. So remove the access_ok() call and add the same check we have in get_user_pages_fast(). Reviewed-by: Gerald Schaefer Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/mm/gup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 16fb3c1615dc..1f5315d1215c 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -180,8 +180,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, addr = start; len = (unsigned long) nr_pages << PAGE_SHIFT; end = start + len; - if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, - (void __user *)start, len))) + if ((end < start) || (end > TASK_SIZE)) return 0; local_irq_save(flags); -- cgit v1.2.2 From 4bffbb3455372a26816e364fb4448810f7014452 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 8 Nov 2012 14:18:47 +0100 Subject: s390/mm: have 16 byte aligned struct pages Select HAVE_ALIGNED_STRUCT_PAGE on s390, so that the slub allocator can make use of compare and swap double for lockless updates. This increases the size of struct page to 64 bytes (instead of 56 bytes), however the performance gain justifies the increased size: - now excactly four struct pages fit into a single cache line; the case that accessing a struct page causes two cache line loads does not exist anymore. - calculating the offset of a struct page within the memmap array is only a simple shift instead of a more expensive multiplication. A "hackbench 200 process 200" run on a 32 cpu system did show an 8% runtime improvement. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 5dba755a43e6..d385f396dfee 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -96,6 +96,7 @@ config S390 select HAVE_MEMBLOCK_NODE_MAP select HAVE_CMPXCHG_LOCAL select HAVE_CMPXCHG_DOUBLE + select HAVE_ALIGNED_STRUCT_PAGE if SLUB select HAVE_VIRT_CPU_ACCOUNTING select VIRT_CPU_ACCOUNTING select ARCH_DISCARD_MEMBLOCK -- cgit v1.2.2 From 225ae5fd9a320e22841410049c3bdb6cf14a5841 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 13 Nov 2012 10:41:50 +0100 Subject: MIPS: Malta: Fix interupt number of CBUS UART. The CBUS UART's interrupt number was wrong conflicting with the interrupt being tied to the Intel PIIX4. Since the PIIX4's interrupt is registered before the CBUS UART which is not being used on most systems this would not be noticed. Attempts to open the ttyS2 CBUS UART would result in: genirq: Flags mismatch irq 18. 00000000 (serial) vs. 00010000 (XT-PIC cascade) serial_link_irq_chain: request failed: -16 for irq: 18 Qemu was written to match the kernel so will need to be fixed also. Signed-off-by: Ralf Baechle --- arch/mips/mti-malta/malta-platform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c index 80562b81f0f2..74732177851c 100644 --- a/arch/mips/mti-malta/malta-platform.c +++ b/arch/mips/mti-malta/malta-platform.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #define SMC_PORT(base, int) \ @@ -48,7 +49,7 @@ static struct plat_serial8250_port uart8250_data[] = { SMC_PORT(0x2F8, 3), { .mapbase = 0x1f000900, /* The CBUS UART */ - .irq = MIPS_CPU_IRQ_BASE + 2, + .irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2, .uartclk = 3686400, /* Twice the usual clk! */ .iotype = UPIO_MEM32, .flags = CBUS_UART_FLAGS, -- cgit v1.2.2 From 9aadd70aed60b47e367e7a1a6b9068daba04fe05 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 6 Nov 2012 16:31:32 +0000 Subject: Revert "ARM: OMAP: convert I2C driver to PM QoS for MPU latency constraints" This reverts commit 3db11feffc1ad2ab9dea27789e6b5b3032827adc (ARM: OMAP: convert I2C driver to PM QoS for MPU latency constraints). This commit causes I2C timeouts to appear on several OMAP3430/3530-based boards: http://marc.info/?l=linux-arm-kernel&m=135071372426971&w=2 http://marc.info/?l=linux-arm-kernel&m=135067558415214&w=2 http://marc.info/?l=linux-arm-kernel&m=135216013608196&w=2 and appears to have been sent for merging before one of its prerequisites was merged: http://marc.info/?l=linux-arm-kernel&m=135219411617621&w=2 Signed-off-by: Paul Walmsley Acked-by: Jean Pihet Signed-off-by: Wolfram Sang --- arch/arm/plat-omap/i2c.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'arch') diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index a5683a84c6ee..6013831a043e 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -26,12 +26,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include #define OMAP_I2C_SIZE 0x3f @@ -127,6 +129,16 @@ static inline int omap1_i2c_add_bus(int bus_id) #ifdef CONFIG_ARCH_OMAP2PLUS +/* + * XXX This function is a temporary compatibility wrapper - only + * needed until the I2C driver can be converted to call + * omap_pm_set_max_dev_wakeup_lat() and handle a return code. + */ +static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t) +{ + omap_pm_set_max_mpu_wakeup_lat(dev, t); +} + static inline int omap2_i2c_add_bus(int bus_id) { int l; @@ -158,6 +170,15 @@ static inline int omap2_i2c_add_bus(int bus_id) dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr; pdata->flags = dev_attr->flags; + /* + * When waiting for completion of a i2c transfer, we need to + * set a wake up latency constraint for the MPU. This is to + * ensure quick enough wakeup from idle, when transfer + * completes. + * Only omap3 has support for constraints + */ + if (cpu_is_omap34xx()) + pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(struct omap_i2c_bus_platform_data), NULL, 0, 0); -- cgit v1.2.2 From ddd32b4289a6feda9ad9e68b0d85641c389a72ba Mon Sep 17 00:00:00 2001 From: Joonsoo Kim Date: Tue, 13 Nov 2012 02:17:36 +0900 Subject: x86, mm: Correct vmflag test for checking VM_HUGETLB commit 611ae8e3f5204f7480b3b405993b3352cfa16662('enable tlb flush range support for x86') change flush_tlb_mm_range() considerably. After this, we test whether vmflag equal to VM_HUGETLB and it may be always failed, because vmflag usually has other flags simultaneously. Our intention is to check whether this vma is for hughtlb, so correct it according to this purpose. Signed-off-by: Joonsoo Kim Acked-by: Alex Shi Link: http://lkml.kernel.org/r/1352740656-19417-1-git-send-email-js1304@gmail.com Signed-off-by: H. Peter Anvin --- arch/x86/mm/tlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 0777f042e400..60f926cd8b0e 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -197,7 +197,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, } if (end == TLB_FLUSH_ALL || tlb_flushall_shift == -1 - || vmflag == VM_HUGETLB) { + || vmflag & VM_HUGETLB) { local_flush_tlb(); goto flush_all; } -- cgit v1.2.2 From 949a05d03490e39e773e8652ccab9157e6f595b4 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 2 Nov 2012 12:30:53 +0000 Subject: [PARISC] fix virtual aliasing issue in get_shared_area() On Thu, 2012-11-01 at 16:45 -0700, Michel Lespinasse wrote: > Looking at the arch/parisc/kernel/sys_parisc.c implementation of > get_shared_area(), I do have a concern though. The function basically > ignores the pgoff argument, so that if one creates a shared mapping of > pages 0-N of a file, and then a separate shared mapping of pages 1-N > of that same file, both will have the same cache offset for their > starting address. > > This looks like this would create obvious aliasing issues. Am I > misreading this ? I can't understand how this could work good enough > to be undetected, so there must be something I'm missing here ??? This turns out to be correct and we need to pay attention to the pgoff as well as the address when creating the virtual address for the area. Fortunately, the bug is rarely triggered as most applications which use pgoff tend to use large values (git being the primary one, and it uses pgoff in multiples of 16MB) which are larger than our cache coherency modulus, so the problem isn't often seen in practise. Reported-by: Michel Lespinasse Cc: Signed-off-by: James Bottomley --- arch/parisc/kernel/sys_parisc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 7426e40699bd..f76c10863c62 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -73,6 +73,8 @@ static unsigned long get_shared_area(struct address_space *mapping, struct vm_area_struct *vma; int offset = mapping ? get_offset(mapping) : 0; + offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000; + addr = DCACHE_ALIGN(addr - offset) + offset; for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { -- cgit v1.2.2 From 097965ee447e5ccec9776f9b075e64cf7607e5eb Mon Sep 17 00:00:00 2001 From: Nicolas Royer Date: Tue, 6 Nov 2012 17:31:03 +0100 Subject: ARM: at91/AT91SAM9G45: fix crypto peripherals irq issue due to sparse irq support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spare irq support introduced by commit 8fe82a5 (ARM: at91: sparse irq support) involves to add the NR_IRQS_LEGACY offset to irq number. Signed-off-by: Nicolas Royer Acked-by: Nicolas Ferre Acked-by: Eric Bénard Tested-by: Eric Bénard Cc: stable@vger.kernel.org # 3.6 --- arch/arm/mach-at91/at91sam9g45_devices.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index b1596072dcc2..fcd233cb33d2 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1841,8 +1841,8 @@ static struct resource sha_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91SAM9G45_ID_AESTDESSHA, - .end = AT91SAM9G45_ID_AESTDESSHA, + .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, + .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, .flags = IORESOURCE_IRQ, }, }; @@ -1874,8 +1874,8 @@ static struct resource tdes_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91SAM9G45_ID_AESTDESSHA, - .end = AT91SAM9G45_ID_AESTDESSHA, + .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, + .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, .flags = IORESOURCE_IRQ, }, }; @@ -1910,8 +1910,8 @@ static struct resource aes_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91SAM9G45_ID_AESTDESSHA, - .end = AT91SAM9G45_ID_AESTDESSHA, + .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, + .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, .flags = IORESOURCE_IRQ, }, }; -- cgit v1.2.2 From 641f3ce64b050961d454a0716bb6dbf528315aac Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 14 Nov 2012 12:18:17 +0100 Subject: ARM: at91/usbh: fix overcurrent gpio setup Use gpio_is_valid also for overcurrent pins (which are currently negative in many board files). Signed-off-by: Johan Hovold Acked-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/at91rm9200_devices.c | 2 +- arch/arm/mach-at91/at91sam9260_devices.c | 2 +- arch/arm/mach-at91/at91sam9261_devices.c | 2 +- arch/arm/mach-at91/at91sam9263_devices.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 1e122bcd7845..3cee0e6ea7c3 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -68,7 +68,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (data->overcurrent_pin[i]) + if (gpio_is_valid(data->overcurrent_pin[i])) at91_set_gpio_input(data->overcurrent_pin[i], 1); } diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index aa1e58729885..414bd855fb0c 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (data->overcurrent_pin[i]) + if (gpio_is_valid(data->overcurrent_pin[i])) at91_set_gpio_input(data->overcurrent_pin[i], 1); } diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index b9487696b7be..cd604aad8e96 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (data->overcurrent_pin[i]) + if (gpio_is_valid(data->overcurrent_pin[i])) at91_set_gpio_input(data->overcurrent_pin[i], 1); } diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index cb85da2eccea..9c61e59a2104 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -78,7 +78,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (data->overcurrent_pin[i]) + if (gpio_is_valid(data->overcurrent_pin[i])) at91_set_gpio_input(data->overcurrent_pin[i], 1); } -- cgit v1.2.2 From ecf026dc340f9700ed3c485344913a8a2b10e2e3 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 25 Oct 2012 23:02:18 +0800 Subject: ARM i.MX: fix error-valued pointer dereference in clk_register_gate2() The error-valued pointer clk is used for the arg of kfree, it should be kfree(gate) if clk_register() return ERR_PTR(). dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/clk-gate2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c index 3c1b8ff9a0a6..cc49c7ae186e 100644 --- a/arch/arm/mach-imx/clk-gate2.c +++ b/arch/arm/mach-imx/clk-gate2.c @@ -112,7 +112,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, clk = clk_register(dev, &gate->hw); if (IS_ERR(clk)) - kfree(clk); + kfree(gate); return clk; } -- cgit v1.2.2 From 3d5e2abe6e265acc5e1fda810301243e9bac92b2 Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Fri, 16 Nov 2012 15:39:24 +0100 Subject: ARM: imx: ehci: fix host power mask bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch sets HPM (Host power mask bit) to bit 16 according to i.MX Reference Manual. Falsely it was set to bit 8, but this controls pull-up Impedance. Reported-by: Michael Burkey Cc: Stable Signed-off-by: Christoph Fritz Acked-by: Eric Bénard Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/ehci-imx25.c | 2 +- arch/arm/mach-imx/ehci-imx35.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-imx/ehci-imx25.c b/arch/arm/mach-imx/ehci-imx25.c index 412c583a24b0..576af7446952 100644 --- a/arch/arm/mach-imx/ehci-imx25.c +++ b/arch/arm/mach-imx/ehci-imx25.c @@ -30,7 +30,7 @@ #define MX25_H1_SIC_SHIFT 21 #define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT) #define MX25_H1_PP_BIT (1 << 18) -#define MX25_H1_PM_BIT (1 << 8) +#define MX25_H1_PM_BIT (1 << 16) #define MX25_H1_IPPUE_UP_BIT (1 << 7) #define MX25_H1_IPPUE_DOWN_BIT (1 << 6) #define MX25_H1_TLL_BIT (1 << 5) diff --git a/arch/arm/mach-imx/ehci-imx35.c b/arch/arm/mach-imx/ehci-imx35.c index 779e16eb65cb..293397852e4e 100644 --- a/arch/arm/mach-imx/ehci-imx35.c +++ b/arch/arm/mach-imx/ehci-imx35.c @@ -30,7 +30,7 @@ #define MX35_H1_SIC_SHIFT 21 #define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT) #define MX35_H1_PP_BIT (1 << 18) -#define MX35_H1_PM_BIT (1 << 8) +#define MX35_H1_PM_BIT (1 << 16) #define MX35_H1_IPPUE_UP_BIT (1 << 7) #define MX35_H1_IPPUE_DOWN_BIT (1 << 6) #define MX35_H1_TLL_BIT (1 << 5) -- cgit v1.2.2 From 8e620b0476696e9428442d3551f3dad47df0e28f Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 15 Nov 2012 17:21:16 +0000 Subject: arm64: Distinguish between user and kernel XN bits On AArch64, the meaning of the XN bit has changed to UXN (user). The PXN (privileged) bit must be set to prevent kernel execution. Without the PXN bit set, the CPU may speculatively access device memory. This patch ensures that all the mappings that the kernel must not execute from (including user mappings) have the PXN bit set. Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/io.h | 2 +- arch/arm64/include/asm/pgtable-hwdef.h | 6 +++-- arch/arm64/include/asm/pgtable.h | 40 +++++++++++++++++----------------- 3 files changed, 25 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index 54f6116697f7..d2f05a608274 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h @@ -222,7 +222,7 @@ extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot extern void __iounmap(volatile void __iomem *addr); #define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY) -#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) +#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) #define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC)) #define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h index 0f3b4581d925..75fd13d289b9 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h @@ -38,7 +38,8 @@ #define PMD_SECT_S (_AT(pmdval_t, 3) << 8) #define PMD_SECT_AF (_AT(pmdval_t, 1) << 10) #define PMD_SECT_NG (_AT(pmdval_t, 1) << 11) -#define PMD_SECT_XN (_AT(pmdval_t, 1) << 54) +#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 53) +#define PMD_SECT_UXN (_AT(pmdval_t, 1) << 54) /* * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). @@ -57,7 +58,8 @@ #define PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ #define PTE_AF (_AT(pteval_t, 1) << 10) /* Access Flag */ #define PTE_NG (_AT(pteval_t, 1) << 11) /* nG */ -#define PTE_XN (_AT(pteval_t, 1) << 54) /* XN */ +#define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */ +#define PTE_UXN (_AT(pteval_t, 1) << 54) /* User XN */ /* * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 8960239be722..14aba2db6776 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -62,23 +62,23 @@ extern pgprot_t pgprot_default; #define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b)) -#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_XN | PTE_RDONLY) -#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN) -#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG) -#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) -#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY) -#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) -#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY) -#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_XN | PTE_DIRTY) -#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_DIRTY) - -#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_XN | PTE_RDONLY) -#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN) -#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG) -#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) -#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY) -#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) -#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY) +#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) +#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN) +#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) +#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) +#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY) +#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY) + +#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) +#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) +#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) +#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) #endif /* __ASSEMBLY__ */ @@ -130,10 +130,10 @@ extern struct page *empty_zero_page; #define pte_young(pte) (pte_val(pte) & PTE_AF) #define pte_special(pte) (pte_val(pte) & PTE_SPECIAL) #define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY)) -#define pte_exec(pte) (!(pte_val(pte) & PTE_XN)) +#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) #define pte_present_exec_user(pte) \ - ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_XN)) == \ + ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == \ (PTE_VALID | PTE_USER)) #define PTE_BIT_FUNC(fn,op) \ @@ -262,7 +262,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { - const pteval_t mask = PTE_USER | PTE_XN | PTE_RDONLY; + const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY; pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); return pte; } -- cgit v1.2.2 From 29282fde80d44e587f8c152b10049a56e61659f0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 9 Nov 2012 15:20:17 +0100 Subject: KVM: x86: Fix invalid secondary exec controls in vmx_cpuid_update() The commit [ad756a16: KVM: VMX: Implement PCID/INVPCID for guests with EPT] introduced the unconditional access to SECONDARY_VM_EXEC_CONTROL, and this triggers kernel warnings like below on old CPUs: vmwrite error: reg 401e value a0568000 (err 12) Pid: 13649, comm: qemu-kvm Not tainted 3.7.0-rc4-test2+ #154 Call Trace: [] vmwrite_error+0x27/0x29 [kvm_intel] [] vmcs_writel+0x1b/0x20 [kvm_intel] [] vmx_cpuid_update+0x74/0x170 [kvm_intel] [] kvm_vcpu_ioctl_set_cpuid2+0x76/0x90 [kvm] [] kvm_arch_vcpu_ioctl+0xc37/0xed0 [kvm] [] ? __vunmap+0x9c/0x110 [] ? vmx_vcpu_load+0x39/0x1a0 [kvm_intel] [] ? kvm_arch_vcpu_load+0x52/0x1a0 [kvm] [] ? vcpu_load+0x74/0xd0 [kvm] [] kvm_vcpu_ioctl+0x110/0x5e0 [kvm] [] ? kvm_dev_ioctl+0x4d/0x4a0 [kvm] [] do_vfs_ioctl+0x8f/0x530 [] ? remove_vma+0x56/0x60 [] ? do_munmap+0x328/0x400 [] ? fget_light+0x4c/0x100 [] sys_ioctl+0x91/0xb0 [] system_call_fastpath+0x1a/0x1f This patch adds a check for the availability of secondary exec control to avoid these warnings. Cc: [v3.6+] Signed-off-by: Takashi Iwai Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/vmx.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ad6b1dd06f8b..f85815945fc6 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -6549,19 +6549,22 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) } } - exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); /* Exposing INVPCID only when PCID is exposed */ best = kvm_find_cpuid_entry(vcpu, 0x7, 0); if (vmx_invpcid_supported() && best && (best->ebx & bit(X86_FEATURE_INVPCID)) && guest_cpuid_has_pcid(vcpu)) { + exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); exec_control |= SECONDARY_EXEC_ENABLE_INVPCID; vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control); } else { - exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; - vmcs_write32(SECONDARY_VM_EXEC_CONTROL, - exec_control); + if (cpu_has_secondary_exec_ctrls()) { + exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); + exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; + vmcs_write32(SECONDARY_VM_EXEC_CONTROL, + exec_control); + } if (best) best->ebx &= ~bit(X86_FEATURE_INVPCID); } -- cgit v1.2.2 From 18f694271b86ee279e88208550cc49fee206b544 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Fri, 16 Nov 2012 14:14:52 -0800 Subject: mips, arc: fix build failure Using a cross-compiler to fix another issue, the following build error occurred for mips defconfig: arch/mips/fw/arc/misc.c: In function 'ArcHalt': arch/mips/fw/arc/misc.c:25:2: error: implicit declaration of function 'local_irq_disable' Fix it up by including irqflags.h. Signed-off-by: David Rientjes Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/fw/arc/misc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/mips/fw/arc/misc.c b/arch/mips/fw/arc/misc.c index 7cf80ca2c1d2..f9f5307434c2 100644 --- a/arch/mips/fw/arc/misc.c +++ b/arch/mips/fw/arc/misc.c @@ -11,6 +11,7 @@ */ #include #include +#include #include -- cgit v1.2.2 From 5576646f3c1abd60d72d19829de6f5d8c2ca8ecf Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 16 Nov 2012 14:15:06 -0800 Subject: revert "mm: fix-up zone present pages" Revert commit 7f1290f2f2a4 ("mm: fix-up zone present pages") That patch tried to fix a issue when calculating zone->present_pages, but it caused a regression on 32bit systems with HIGHMEM. With that change, reset_zone_present_pages() resets all zone->present_pages to zero, and fixup_zone_present_pages() is called to recalculate zone->present_pages when the boot allocator frees core memory pages into buddy allocator. Because highmem pages are not freed by bootmem allocator, all highmem zones' present_pages becomes zero. Various options for improving the situation are being discussed but for now, let's return to the 3.6 code. Cc: Jianguo Wu Cc: Jiang Liu Cc: Petr Tesarik Cc: "Luck, Tony" Cc: Mel Gorman Cc: Yinghai Lu Cc: Minchan Kim Cc: Johannes Weiner Acked-by: David Rientjes Tested-by: Chris Clayton Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/mm/init.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index acd5b68e8871..082e383c1b6f 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -637,7 +637,6 @@ mem_init (void) high_memory = __va(max_low_pfn * PAGE_SIZE); - reset_zone_present_pages(); for_each_online_pgdat(pgdat) if (pgdat->bdata->node_bootmem_map) totalram_pages += free_all_bootmem_node(pgdat); -- cgit v1.2.2 From 34fa78b59c52d1db3513db4c1a999db26b2e9ac2 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Sat, 17 Nov 2012 22:27:04 +0100 Subject: m68k: fix sigset_t accessor functions The sigaddset/sigdelset/sigismember functions that are implemented with bitfield insn cannot allow the sigset argument to be placed in a data register since the sigset is wider than 32 bits. Remove the "d" constraint from the asm statements. The effect of the bug is that sending RT signals does not work, the signal number is truncated modulo 32. Signed-off-by: Andreas Schwab Signed-off-by: Geert Uytterhoeven Cc: stable@vger.kernel.org --- arch/m68k/include/asm/signal.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/m68k/include/asm/signal.h b/arch/m68k/include/asm/signal.h index 67e489d8d1bd..2df26b57c26a 100644 --- a/arch/m68k/include/asm/signal.h +++ b/arch/m68k/include/asm/signal.h @@ -41,7 +41,7 @@ struct k_sigaction { static inline void sigaddset(sigset_t *set, int _sig) { asm ("bfset %0{%1,#1}" - : "+od" (*set) + : "+o" (*set) : "id" ((_sig - 1) ^ 31) : "cc"); } @@ -49,7 +49,7 @@ static inline void sigaddset(sigset_t *set, int _sig) static inline void sigdelset(sigset_t *set, int _sig) { asm ("bfclr %0{%1,#1}" - : "+od" (*set) + : "+o" (*set) : "id" ((_sig - 1) ^ 31) : "cc"); } @@ -65,7 +65,7 @@ static inline int __gen_sigismember(sigset_t *set, int _sig) int ret; asm ("bfextu %1{%2,#1},%0" : "=d" (ret) - : "od" (*set), "id" ((_sig-1) ^ 31) + : "o" (*set), "id" ((_sig-1) ^ 31) : "cc"); return ret; } -- cgit v1.2.2 From fae2ae2a900a5c7bb385fe4075f343e7e2d5daa2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 18 Nov 2012 22:27:03 -0500 Subject: sparc64: not any error from do_sigaltstack() should fail rt_sigreturn() If a signal handler is executed on altstack and another signal comes, we will end up with rt_sigreturn() on return from the second handler getting -EPERM from do_sigaltstack(). It's perfectly OK, since we are not asking to change the settings; in fact, they couldn't have been changed during the second handler execution exactly because we'd been on altstack all along. 64bit sigreturn on sparc treats any error from do_sigaltstack() as "SIGSEGV now"; we need to switch to the same semantics we are using on other architectures. Cc: stable@vger.kernel.org Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/sparc/kernel/signal_64.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 867de2f8189c..689e1ba62809 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -295,9 +295,7 @@ void do_rt_sigreturn(struct pt_regs *regs) err |= restore_fpu_state(regs, fpu_save); err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); - err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf); - - if (err) + if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT) goto segv; err |= __get_user(rwin_save, &sf->rwin_save); -- cgit v1.2.2 From e37212aa5df1937bc19c0d0982d216675020a7ca Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Wed, 3 Oct 2012 12:05:00 +0530 Subject: ARM: davinci: dm644x: fix out range signal for ED Fix the video clock setting when custom timings are used with pclock <= 27MHz. Existing video clock selection uses PLL2 mode which results in a 54MHz clock whereas using the MXI mode results in a 27MHz clock (which is the one actually desired). This bug affects the Enhanced Definition (ED) support on DM644x. Without this patch, out-range signals errors are were observed on the TV when viewing ED. An out-of-range signal is often caused when the field rate is above the rate that the television will handle. Signed-off-by: Lad, Prabhakar Signed-off-by: Manjunath Hadli Cc: Sekhar Nori [nsekhar@ti.com: reword commit message based on on-list discussion] Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/dm644x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index cd0c8b1e1ecf..14e9947bad6e 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -713,8 +713,7 @@ static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type, break; case VPBE_ENC_CUSTOM_TIMINGS: if (pclock <= 27000000) { - v |= DM644X_VPSS_MUXSEL_PLL2_MODE | - DM644X_VPSS_DACCLKEN; + v |= DM644X_VPSS_DACCLKEN; writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); } else { /* -- cgit v1.2.2 From 91280e755a43fd2a6a20bfeab3a571321de68b76 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 20 Nov 2012 20:39:28 +0900 Subject: ARM: EXYNOS: PL330 MDMA1 fix for revision 0 of Exynos4210 SOC Commit 8214513 ("ARM: EXYNOS: fix address for EXYNOS4 MDMA1") changed EXYNOS specific setup of PL330 DMA engine to use 'non-secure' mdma1 address instead of 'secure' one (from 0x12840000 to 0x12850000) to fix issue with some Exynos4212 SOCs. Unfortunately it brakes PL330 setup for revision 0 of Exynos4210 SOC (mdma1 device cannot be found at 'non-secure' address): [ 0.566245] dma-pl330 dma-pl330.2: PERIPH_ID 0x0, PCELL_ID 0x0 ! [ 0.566278] dma-pl330: probe of dma-pl330.2 failed with error -22 Fix it by using 'secure' mdma1 address on Exynos4210 revision 0 SOC. Reviewed-by: Tomasz Figa Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Kyungmin Park Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/dma.c | 3 +++ arch/arm/mach-exynos/include/mach/map.h | 1 + 2 files changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c index 21d568b3b149..87e07d6fc615 100644 --- a/arch/arm/mach-exynos/dma.c +++ b/arch/arm/mach-exynos/dma.c @@ -275,6 +275,9 @@ static int __init exynos_dma_init(void) exynos_pdma1_pdata.nr_valid_peri = ARRAY_SIZE(exynos4210_pdma1_peri); exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri; + + if (samsung_rev() == EXYNOS4210_REV_0) + exynos_mdma1_device.res.start = EXYNOS4_PA_S_MDMA1; } else if (soc_is_exynos4212() || soc_is_exynos4412()) { exynos_pdma0_pdata.nr_valid_peri = ARRAY_SIZE(exynos4212_pdma0_peri); diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h index 8480849affb9..ed4da4544cd2 100644 --- a/arch/arm/mach-exynos/include/mach/map.h +++ b/arch/arm/mach-exynos/include/mach/map.h @@ -90,6 +90,7 @@ #define EXYNOS4_PA_MDMA0 0x10810000 #define EXYNOS4_PA_MDMA1 0x12850000 +#define EXYNOS4_PA_S_MDMA1 0x12840000 #define EXYNOS4_PA_PDMA0 0x12680000 #define EXYNOS4_PA_PDMA1 0x12690000 #define EXYNOS5_PA_MDMA0 0x10800000 -- cgit v1.2.2 From caaa8c6339ccefee6e834c4a8b0bec7e721e7357 Mon Sep 17 00:00:00 2001 From: Cesar Eduardo Barros Date: Sat, 27 Oct 2012 20:34:15 -0200 Subject: x86: remove dummy long from EFI stub Commit 2e064b1 (x86, efi: Fix issue of overlapping .reloc section for EFI_STUB) removed a dummy reloc added by commit 291f363 (x86, efi: EFI boot stub support), but forgot to remove the dummy long used by that reloc. Reviewed-by: Jordan Justen Tested-by: Lee G Rosenbaum Cc: "H. Peter Anvin" Cc: Thomas Gleixner Cc: Ingo Molnar Signed-off-by: Cesar Eduardo Barros Signed-off-by: Matt Fleming --- arch/x86/boot/header.S | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index 2a017441b8b2..8c132a625b94 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -476,6 +476,3 @@ die: setup_corrupt: .byte 7 .string "No setup signature found...\n" - - .data -dummy: .long 0 -- cgit v1.2.2 From 0f905a43ce955b638139bd84486194770a6a2c08 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Tue, 20 Nov 2012 13:07:46 +0000 Subject: x86, efi: Fix processor-specific memcpy() build error Building for Athlon/Duron/K7 results in the following build error, arch/x86/boot/compressed/eboot.o: In function `__constant_memcpy3d': eboot.c:(.text+0x385): undefined reference to `_mmx_memcpy' arch/x86/boot/compressed/eboot.o: In function `efi_main': eboot.c:(.text+0x1a22): undefined reference to `_mmx_memcpy' because the boot stub code doesn't link with the kernel proper, and therefore doesn't have access to the 3DNow version of memcpy. So, follow the example of misc.c and #undef memcpy so that we use the version provided by misc.c. See https://bugzilla.kernel.org/show_bug.cgi?id=50391 Reported-by: Al Viro Reported-by: Ryan Underwood Cc: H. Peter Anvin Cc: stable@vger.kernel.org Signed-off-by: Matt Fleming --- arch/x86/boot/compressed/eboot.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index c760e073963e..e87b0cac14b5 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -12,6 +12,8 @@ #include #include +#undef memcpy /* Use memcpy from misc.c */ + #include "eboot.h" static efi_system_table_t *sys_table; -- cgit v1.2.2 From 1022623842cb72ee4d0dbf02f6937f38c92c3f41 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Mon, 3 Sep 2012 20:54:48 +0200 Subject: x86-32: Fix invalid stack address while in softirq In 32 bit the stack address provided by kernel_stack_pointer() may point to an invalid range causing NULL pointer access or page faults while in NMI (see trace below). This happens if called in softirq context and if the stack is empty. The address at ®s->sp is then out of range. Fixing this by checking if regs and ®s->sp are in the same stack context. Otherwise return the previous stack pointer stored in struct thread_info. If that address is invalid too, return address of regs. BUG: unable to handle kernel NULL pointer dereference at 0000000a IP: [] print_context_stack+0x6e/0x8d *pde = 00000000 Oops: 0000 [#1] SMP Modules linked in: Pid: 4434, comm: perl Not tainted 3.6.0-rc3-oprofile-i386-standard-g4411a05 #4 Hewlett-Packard HP xw9400 Workstation/0A1Ch EIP: 0060:[] EFLAGS: 00010093 CPU: 0 EIP is at print_context_stack+0x6e/0x8d EAX: ffffe000 EBX: 0000000a ECX: f4435f94 EDX: 0000000a ESI: f4435f94 EDI: f4435f94 EBP: f5409ec0 ESP: f5409ea0 DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 CR0: 8005003b CR2: 0000000a CR3: 34ac9000 CR4: 000007d0 DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 DR6: ffff0ff0 DR7: 00000400 Process perl (pid: 4434, ti=f5408000 task=f5637850 task.ti=f4434000) Stack: 000003e8 ffffe000 00001ffc f4e39b00 00000000 0000000a f4435f94 c155198c f5409ef0 c1003723 c155198c f5409f04 00000000 f5409edc 00000000 00000000 f5409ee8 f4435f94 f5409fc4 00000001 f5409f1c c12dce1c 00000000 c155198c Call Trace: [] dump_trace+0x7b/0xa1 [] x86_backtrace+0x40/0x88 [] ? oprofile_add_sample+0x56/0x84 [] oprofile_add_sample+0x75/0x84 [] op_amd_check_ctrs+0x46/0x260 [] profile_exceptions_notify+0x23/0x4c [] nmi_handle+0x31/0x4a [] ? ftrace_define_fields_irq_handler_entry+0x45/0x45 [] do_nmi+0xa0/0x2ff [] ? ftrace_define_fields_irq_handler_entry+0x45/0x45 [] nmi_stack_correct+0x28/0x2d [] ? ftrace_define_fields_irq_handler_entry+0x45/0x45 [] ? do_softirq+0x4b/0x7f [] irq_exit+0x35/0x5b [] smp_apic_timer_interrupt+0x6c/0x7a [] apic_timer_interrupt+0x2a/0x30 Code: 89 fe eb 08 31 c9 8b 45 0c ff 55 ec 83 c3 04 83 7d 10 00 74 0c 3b 5d 10 73 26 3b 5d e4 73 0c eb 1f 3b 5d f0 76 1a 3b 5d e8 73 15 <8b> 13 89 d0 89 55 e0 e8 ad 42 03 00 85 c0 8b 55 e0 75 a6 eb cc EIP: [] print_context_stack+0x6e/0x8d SS:ESP 0068:f5409ea0 CR2: 000000000000000a ---[ end trace 62afee3481b00012 ]--- Kernel panic - not syncing: Fatal exception in interrupt V2: * add comments to kernel_stack_pointer() * always return a valid stack address by falling back to the address of regs Reported-by: Yang Wei Cc: Signed-off-by: Robert Richter Link: http://lkml.kernel.org/r/20120912135059.GZ8285@erda.amd.com Signed-off-by: H. Peter Anvin Cc: Jun Zhang --- arch/x86/include/asm/ptrace.h | 15 ++++----------- arch/x86/kernel/ptrace.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index dcfde52979c3..19f16ebaf4fa 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -205,21 +205,14 @@ static inline bool user_64bit_mode(struct pt_regs *regs) } #endif -/* - * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode - * when it traps. The previous stack will be directly underneath the saved - * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. - * - * This is valid only for kernel mode traps. - */ -static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) -{ #ifdef CONFIG_X86_32 - return (unsigned long)(®s->sp); +extern unsigned long kernel_stack_pointer(struct pt_regs *regs); #else +static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) +{ return regs->sp; -#endif } +#endif #define GET_IP(regs) ((regs)->ip) #define GET_FP(regs) ((regs)->bp) diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index b00b33a18390..2484e331a64d 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -166,6 +166,34 @@ static inline bool invalid_selector(u16 value) #define FLAG_MASK FLAG_MASK_32 +/* + * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode + * when it traps. The previous stack will be directly underneath the saved + * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. + * + * Now, if the stack is empty, '®s->sp' is out of range. In this + * case we try to take the previous stack. To always return a non-null + * stack pointer we fall back to regs as stack if no previous stack + * exists. + * + * This is valid only for kernel mode traps. + */ +unsigned long kernel_stack_pointer(struct pt_regs *regs) +{ + unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1); + unsigned long sp = (unsigned long)®s->sp; + struct thread_info *tinfo; + + if (context == (sp & ~(THREAD_SIZE - 1))) + return sp; + + tinfo = (struct thread_info *)context; + if (tinfo->previous_esp) + return tinfo->previous_esp; + + return (unsigned long)regs; +} + static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno) { BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0); -- cgit v1.2.2 From cb57a2b4cff7edf2a4e32c0163200e9434807e0a Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 20 Nov 2012 22:21:02 -0800 Subject: x86-32: Export kernel_stack_pointer() for modules Modules, in particular oprofile (and possibly other similar tools) need kernel_stack_pointer(), so export it using EXPORT_SYMBOL_GPL(). Cc: Yang Wei Cc: Robert Richter Cc: Jun Zhang Cc: Link: http://lkml.kernel.org/r/20120912135059.GZ8285@erda.amd.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/ptrace.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 2484e331a64d..5e0596b0632e 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -193,6 +194,7 @@ unsigned long kernel_stack_pointer(struct pt_regs *regs) return (unsigned long)regs; } +EXPORT_SYMBOL_GPL(kernel_stack_pointer); static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno) { -- cgit v1.2.2 From 36c46ca4f322a7bf89aad5462a3a1f61713edce7 Mon Sep 17 00:00:00 2001 From: Boris Ostrovsky Date: Thu, 15 Nov 2012 13:41:50 -0500 Subject: x86, microcode, AMD: Add support for family 16h processors Add valid patch size for family 16h processors. [ hpa: promoting to urgent/stable since it is hw enabling and trivial ] Signed-off-by: Boris Ostrovsky Acked-by: Andreas Herrmann Link: http://lkml.kernel.org/r/1353004910-2204-1-git-send-email-boris.ostrovsky@amd.com Signed-off-by: H. Peter Anvin Cc: --- arch/x86/kernel/microcode_amd.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index b3e67ba55b77..efdec7cd8e01 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c @@ -190,6 +190,7 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size, #define F1XH_MPB_MAX_SIZE 2048 #define F14H_MPB_MAX_SIZE 1824 #define F15H_MPB_MAX_SIZE 4096 +#define F16H_MPB_MAX_SIZE 3458 switch (c->x86) { case 0x14: @@ -198,6 +199,9 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size, case 0x15: max_size = F15H_MPB_MAX_SIZE; break; + case 0x16: + max_size = F16H_MPB_MAX_SIZE; + break; default: max_size = F1XH_MPB_MAX_SIZE; break; -- cgit v1.2.2 From ee4eb87be2c3f69c2c4d9f1c1d98e363a7ad18ab Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 2 Nov 2012 11:18:39 +0000 Subject: x86-64: Fix ordering of CFI directives and recent ASM_CLAC additions While these got added in the right place everywhere else, entry_64.S is the odd one where they ended up before the initial CFI directive(s). In order to cover the full code ranges, the CFI directive must be first, though. Signed-off-by: Jan Beulich Link: http://lkml.kernel.org/r/5093BA1F02000078000A600E@nat28.tlf.novell.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/entry_64.S | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index b51b2c7ee51f..1328fe49a3f1 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -995,8 +995,8 @@ END(interrupt) */ .p2align CONFIG_X86_L1_CACHE_SHIFT common_interrupt: - ASM_CLAC XCPT_FRAME + ASM_CLAC addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */ interrupt do_IRQ /* 0(%rsp): old_rsp-ARGOFFSET */ @@ -1135,8 +1135,8 @@ END(common_interrupt) */ .macro apicinterrupt num sym do_sym ENTRY(\sym) - ASM_CLAC INTR_FRAME + ASM_CLAC pushq_cfi $~(\num) .Lcommon_\sym: interrupt \do_sym @@ -1190,8 +1190,8 @@ apicinterrupt IRQ_WORK_VECTOR \ */ .macro zeroentry sym do_sym ENTRY(\sym) - ASM_CLAC INTR_FRAME + ASM_CLAC PARAVIRT_ADJUST_EXCEPTION_FRAME pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ subq $ORIG_RAX-R15, %rsp @@ -1208,8 +1208,8 @@ END(\sym) .macro paranoidzeroentry sym do_sym ENTRY(\sym) - ASM_CLAC INTR_FRAME + ASM_CLAC PARAVIRT_ADJUST_EXCEPTION_FRAME pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ subq $ORIG_RAX-R15, %rsp @@ -1227,8 +1227,8 @@ END(\sym) #define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8) .macro paranoidzeroentry_ist sym do_sym ist ENTRY(\sym) - ASM_CLAC INTR_FRAME + ASM_CLAC PARAVIRT_ADJUST_EXCEPTION_FRAME pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ subq $ORIG_RAX-R15, %rsp @@ -1247,8 +1247,8 @@ END(\sym) .macro errorentry sym do_sym ENTRY(\sym) - ASM_CLAC XCPT_FRAME + ASM_CLAC PARAVIRT_ADJUST_EXCEPTION_FRAME subq $ORIG_RAX-R15, %rsp CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 @@ -1266,8 +1266,8 @@ END(\sym) /* error code is on the stack already */ .macro paranoiderrorentry sym do_sym ENTRY(\sym) - ASM_CLAC XCPT_FRAME + ASM_CLAC PARAVIRT_ADJUST_EXCEPTION_FRAME subq $ORIG_RAX-R15, %rsp CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 -- cgit v1.2.2 From 70b9b24d4d240ff5f6087bca4013c6969af275ab Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 22 Nov 2012 00:11:09 +0900 Subject: ARM: S3C24XX: Fix potential NULL pointer dereference error chan->end is tested for being NULL. However in the event that it is NULL, the subsequent assignment statement would lead to NULL pointer dereference. Thus dereferencing it only when it is not NULL. Signed-off-by: Sachin Kamat Signed-off-by: Kukjin Kim --- arch/arm/plat-s3c24xx/dma.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index db98e7021f0d..0abd1c469887 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -473,12 +473,13 @@ int s3c2410_dma_enqueue(enum dma_ch channel, void *id, pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n", chan->number, __func__, buf); - if (chan->end == NULL) + if (chan->end == NULL) { pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n", chan->number, __func__, chan); - - chan->end->next = buf; - chan->end = buf; + } else { + chan->end->next = buf; + chan->end = buf; + } } /* if necessary, update the next buffer field */ -- cgit v1.2.2 From 5d3df935426271016b895aecaa247101b4bfa35e Mon Sep 17 00:00:00 2001 From: Russell King - ARM Linux Date: Sun, 18 Nov 2012 16:29:44 +0000 Subject: Dove: Attempt to fix PMU/RTC interrupts Fix the acknowledgement of PMU interrupts on Dove: some Dove hardware has not been sensibly designed so that interrupts can be handled in a race free manner. The PMU is one such instance. The pending (aka 'cause') register is a bunch of RW bits, meaning that these bits can be both cleared and set by software (confirmed on the Armada-510 on the cubox.) Hardware sets the appropriate bit when an interrupt is asserted, and software is required to clear the bits which are to be processed. If we write ~(1 << bit), then we end up asserting every other interrupt except the one we're processing. So, we need to do a read-modify-write cycle to clear the asserted bit. However, any interrupts which occur in the middle of this cycle will also be written back as zero, which will also clear the new interrupts. The upshot of this is: there is _no_ way to safely clear down interrupts in this register (and other similarly behaving interrupt pending registers on this device.) The patch below at least stops us creating new interrupts. Signed-off-by: Russell King Cc: stable@vger.kernel.org Signed-off-by: Jason Cooper --- arch/arm/mach-dove/irq.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c index 087711524e8a..bc4344aa1009 100644 --- a/arch/arm/mach-dove/irq.c +++ b/arch/arm/mach-dove/irq.c @@ -46,8 +46,20 @@ static void pmu_irq_ack(struct irq_data *d) int pin = irq_to_pmu(d->irq); u32 u; + /* + * The PMU mask register is not RW0C: it is RW. This means that + * the bits take whatever value is written to them; if you write + * a '1', you will set the interrupt. + * + * Unfortunately this means there is NO race free way to clear + * these interrupts. + * + * So, let's structure the code so that the window is as small as + * possible. + */ u = ~(1 << (pin & 31)); - writel(u, PMU_INTERRUPT_CAUSE); + u &= readl_relaxed(PMU_INTERRUPT_CAUSE); + writel_relaxed(u, PMU_INTERRUPT_CAUSE); } static struct irq_chip pmu_irq_chip = { -- cgit v1.2.2 From d356cf5a74afa32b40decca3c9dd88bc3cd63eb5 Mon Sep 17 00:00:00 2001 From: Russell King - ARM Linux Date: Sun, 18 Nov 2012 16:39:32 +0000 Subject: Dove: Fix irq_to_pmu() PMU interrupts start at IRQ_DOVE_PMU_START, not IRQ_DOVE_PMU_START + 1. Fix the condition. (It may have been less likely to occur had the code been written "if (irq >= IRQ_DOVE_PMU_START" which imho is the easier to understand notation, and matches the normal way of thinking about these things.) Signed-off-by: Russell King Cc: stable@vger.kernel.org Signed-off-by: Jason Cooper --- arch/arm/mach-dove/include/mach/pm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-dove/include/mach/pm.h b/arch/arm/mach-dove/include/mach/pm.h index 7bcd0dfce4b1..b47f75038686 100644 --- a/arch/arm/mach-dove/include/mach/pm.h +++ b/arch/arm/mach-dove/include/mach/pm.h @@ -63,7 +63,7 @@ static inline int pmu_to_irq(int pin) static inline int irq_to_pmu(int irq) { - if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS) + if (IRQ_DOVE_PMU_START <= irq && irq < NR_IRQS) return irq - IRQ_DOVE_PMU_START; return -EINVAL; -- cgit v1.2.2 From 1dc831bf53fddcc6443f74a39e72db5bcea4f15d Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Wed, 21 Nov 2012 00:19:06 -0700 Subject: ARM: Kirkwood: Update PCI-E fixup - The code relies on rc_pci_fixup being called, which only happens when CONFIG_PCI_QUIRKS is enabled, so add that to Kconfig. Omitting this causes a booting failure with a non-obvious cause. - Update rc_pci_fixup to set the class properly, copying the more modern style from other places - Correct the rc_pci_fixup comment Signed-off-by: Jason Gunthorpe Cc: stable@vger.kernel.org Signed-off-by: Jason Cooper --- arch/arm/Kconfig | 1 + arch/arm/mach-kirkwood/pcie.c | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ade7e924bef5..9759fec0b704 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -547,6 +547,7 @@ config ARCH_KIRKWOOD select CPU_FEROCEON select GENERIC_CLOCKEVENTS select PCI + select PCI_QUIRKS select PLAT_ORION_LEGACY help Support for the following Marvell Kirkwood series SoCs: diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index ec544918b12c..74fc5a074fc4 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c @@ -207,14 +207,19 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) return 1; } +/* + * The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it + * is operating as a root complex this needs to be switched to + * PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on + * the device. Decoding setup is handled by the orion code. + */ static void __devinit rc_pci_fixup(struct pci_dev *dev) { - /* - * Prevent enumeration of root complex. - */ if (dev->bus->parent == NULL && dev->devfn == 0) { int i; + dev->class &= 0xff; + dev->class |= PCI_CLASS_BRIDGE_HOST << 8; for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { dev->resource[i].start = 0; dev->resource[i].end = 0; -- cgit v1.2.2 From 0a0d62857366d8a6531e7fed1c3ccdd9a2b5b40b Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 20 Nov 2012 23:00:51 -0800 Subject: ARM - OMAP: ads7846: fix pendown debounce setting Commit 97ee9f01 (ARM: OMAP: fix the ads7846 init code) have enabled the pendown GPIO debounce time setting by the below sequence: gpio_request_one() gpio_set_debounce() gpio_free() It also revealed a bug in the OMAP GPIO handling code which prevented the GPIO debounce clock to be disabled and CORE transition to low power states. Commit c9c55d9 (gpio/omap: fix off-mode bug: clear debounce settings on free/reset) fixes the OMAP GPIO handling code by making sure that the GPIO debounce clock gets disabled if no GPIO is requested from current bank. While fixing the OMAP GPIO handling code (in the right way), the above commit makes the gpio_request->set_debounce->free sequence invalid as after freeing the GPIO, the debounce settings are lost. Fix the debounce settings by moving the debounce initialization to the actual GPIO requesting code - the ads7846 driver. Signed-off-by: Igor Grinberg Acked-by: Tony Lindgren Signed-off-by: Dmitry Torokhov --- arch/arm/mach-omap2/common-board-devices.c | 34 ++++++++++++++++++------------ 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c index 48daac2581b4..84551f205e46 100644 --- a/arch/arm/mach-omap2/common-board-devices.c +++ b/arch/arm/mach-omap2/common-board-devices.c @@ -64,30 +64,36 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce, struct spi_board_info *spi_bi = &ads7846_spi_board_info; int err; - err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); - if (err) { - pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); - return; - } + /* + * If a board defines get_pendown_state() function, request the pendown + * GPIO and set the GPIO debounce time. + * If a board does not define the get_pendown_state() function, then + * the ads7846 driver will setup the pendown GPIO itself. + */ + if (board_pdata && board_pdata->get_pendown_state) { + err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); + if (err) { + pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); + return; + } - if (gpio_debounce) - gpio_set_debounce(gpio_pendown, gpio_debounce); + if (gpio_debounce) + gpio_set_debounce(gpio_pendown, gpio_debounce); + + gpio_export(gpio_pendown, 0); + } spi_bi->bus_num = bus_num; spi_bi->irq = gpio_to_irq(gpio_pendown); + ads7846_config.gpio_pendown = gpio_pendown; + if (board_pdata) { board_pdata->gpio_pendown = gpio_pendown; + board_pdata->gpio_pendown_debounce = gpio_debounce; spi_bi->platform_data = board_pdata; - if (board_pdata->get_pendown_state) - gpio_export(gpio_pendown, 0); - } else { - ads7846_config.gpio_pendown = gpio_pendown; } - if (!board_pdata || (board_pdata && !board_pdata->get_pendown_state)) - gpio_free(gpio_pendown); - spi_register_board_info(&ads7846_spi_board_info, 1); } #else -- cgit v1.2.2 From 3043c5c8bf3511d76bbdcf27f56449549d4bb70c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Ha=C5=82asa?= Date: Sat, 1 Sep 2012 18:28:14 +0200 Subject: IXP4xx: Fix Goramo MultiLink platform compilation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Krzysztof Hałasa --- arch/arm/mach-ixp4xx/goramo_mlr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c index b800a031207c..f417632bc991 100644 --- a/arch/arm/mach-ixp4xx/goramo_mlr.c +++ b/arch/arm/mach-ixp4xx/goramo_mlr.c @@ -15,6 +15,7 @@ #include #include #include +#include #define SLOT_ETHA 0x0B /* IDSEL = AD21 */ #define SLOT_ETHB 0x0C /* IDSEL = AD20 */ -- cgit v1.2.2 From 87ba5c6a313b4da5639a18d7796e51483ededd17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Ha=C5=82asa?= Date: Sun, 2 Sep 2012 19:23:27 +0200 Subject: IXP4xx: Fix off-by-one bug in Goramo MultiLink platform. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Krzysztof Hałasa --- arch/arm/mach-ixp4xx/goramo_mlr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c index f417632bc991..53b8348dfcc2 100644 --- a/arch/arm/mach-ixp4xx/goramo_mlr.c +++ b/arch/arm/mach-ixp4xx/goramo_mlr.c @@ -330,7 +330,7 @@ static struct platform_device device_hss_tab[] = { }; -static struct platform_device *device_tab[6] __initdata = { +static struct platform_device *device_tab[7] __initdata = { &device_flash, /* index 0 */ }; -- cgit v1.2.2 From f203bc64e8b7d19ca52df89b142005c5552fef3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Ha=C5=82asa?= Date: Sun, 17 Apr 2011 21:06:06 +0200 Subject: IXP4xx: Remove time limit for PCI TRDY to enable use of slow devices. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Krzysztof Hałasa --- arch/arm/mach-ixp4xx/common-pci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 1694f01ce2b6..6d6bde3e15fa 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -410,6 +410,7 @@ void __init ixp4xx_pci_preinit(void) * Enable the IO window to be way up high, at 0xfffffc00 */ local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01); + local_write_config(0x40, 4, 0x000080FF); /* No TRDY time limit */ } else { printk("PCI: IXP4xx is target - No bus scan performed\n"); } -- cgit v1.2.2 From 05cd3db0df6f6ac3083a9e9671dd1662053604df Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Wed, 25 Jul 2012 12:33:06 -0600 Subject: ixp4xx: Declare MODULE_FIRMWARE usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Krzysztof Halasa Cc: Imre Kaloz Cc: Russell King Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Tim Gardner Signed-off-by: Krzysztof Hałasa --- arch/arm/mach-ixp4xx/ixp4xx_npe.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-ixp4xx/ixp4xx_npe.c b/arch/arm/mach-ixp4xx/ixp4xx_npe.c index a17ed79207a4..d4eb09a62863 100644 --- a/arch/arm/mach-ixp4xx/ixp4xx_npe.c +++ b/arch/arm/mach-ixp4xx/ixp4xx_npe.c @@ -116,7 +116,11 @@ /* NPE mailbox_status value for reset */ #define RESET_MBOX_STAT 0x0000F0F0 -const char *npe_names[] = { "NPE-A", "NPE-B", "NPE-C" }; +#define NPE_A_FIRMWARE "NPE-A" +#define NPE_B_FIRMWARE "NPE-B" +#define NPE_C_FIRMWARE "NPE-C" + +const char *npe_names[] = { NPE_A_FIRMWARE, NPE_B_FIRMWARE, NPE_C_FIRMWARE }; #define print_npe(pri, npe, fmt, ...) \ printk(pri "%s: " fmt, npe_name(npe), ## __VA_ARGS__) @@ -724,6 +728,9 @@ module_exit(npe_cleanup_module); MODULE_AUTHOR("Krzysztof Halasa"); MODULE_LICENSE("GPL v2"); +MODULE_FIRMWARE(NPE_A_FIRMWARE); +MODULE_FIRMWARE(NPE_B_FIRMWARE); +MODULE_FIRMWARE(NPE_C_FIRMWARE); EXPORT_SYMBOL(npe_names); EXPORT_SYMBOL(npe_running); -- cgit v1.2.2 From f0cdb153292635203b3a0921c901dacf85d4ef1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Ha=C5=82asa?= Date: Fri, 26 Mar 2010 16:38:52 +0100 Subject: IXP4xx: Always ioremap() Queue Manager MMIO region at boot. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It doesn't make much sense to map QMgr dynamically - we almost always need it and the static mapping will be needed for little-endian data-coherent operation (to make QMgr region value-coherent). Signed-off-by: Krzysztof Hałasa --- arch/arm/mach-ixp4xx/common.c | 5 +++++ arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h | 7 ++++--- arch/arm/mach-ixp4xx/include/mach/qmgr.h | 12 ++++++------ arch/arm/mach-ixp4xx/ixp4xx_qmgr.c | 14 ++------------ 4 files changed, 17 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index fdf91a160884..acc0584377fc 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -67,6 +67,11 @@ static struct map_desc ixp4xx_io_desc[] __initdata = { .pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS), .length = IXP4XX_PCI_CFG_REGION_SIZE, .type = MT_DEVICE + }, { /* Queue Manager */ + .virtual = (unsigned long)IXP4XX_QMGR_BASE_VIRT, + .pfn = __phys_to_pfn(IXP4XX_QMGR_BASE_PHYS), + .length = IXP4XX_QMGR_REGION_SIZE, + .type = MT_DEVICE }, #ifdef CONFIG_DEBUG_LL { /* Debug UART mapping */ diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h index eb68b61ce975..a24a8fe76604 100644 --- a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h +++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h @@ -30,19 +30,20 @@ * * 0x50000000 0x10000000 ioremap'd EXP BUS * - * 0x6000000 0x00004000 ioremap'd QMgr + * 0x60000000 0x00004000 0xffbe7000 QMgr * - * 0xC0000000 0x00001000 0xffbff000 PCI CFG + * 0xC8000000 0x00013000 0xffbeb000 On-Chip Peripherals * * 0xC4000000 0x00001000 0xffbfe000 EXP CFG * - * 0xC8000000 0x00013000 0xffbeb000 On-Chip Peripherals + * 0xC0000000 0x00001000 0xffbff000 PCI CFG */ /* * Queue Manager */ #define IXP4XX_QMGR_BASE_PHYS (0x60000000) +#define IXP4XX_QMGR_BASE_VIRT IOMEM(0xFFBE7000) #define IXP4XX_QMGR_REGION_SIZE (0x00004000) /* diff --git a/arch/arm/mach-ixp4xx/include/mach/qmgr.h b/arch/arm/mach-ixp4xx/include/mach/qmgr.h index 9e7cad2d54cb..0a88d3b8e806 100644 --- a/arch/arm/mach-ixp4xx/include/mach/qmgr.h +++ b/arch/arm/mach-ixp4xx/include/mach/qmgr.h @@ -86,7 +86,7 @@ void qmgr_release_queue(unsigned int queue); static inline void qmgr_put_entry(unsigned int queue, u32 val) { - extern struct qmgr_regs __iomem *qmgr_regs; + const struct qmgr_regs __iomem *qmgr_regs = (void __iomem *)IXP4XX_QMGR_BASE_VIRT; #if DEBUG_QMGR BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ @@ -99,7 +99,7 @@ static inline void qmgr_put_entry(unsigned int queue, u32 val) static inline u32 qmgr_get_entry(unsigned int queue) { u32 val; - extern struct qmgr_regs __iomem *qmgr_regs; + const struct qmgr_regs __iomem *qmgr_regs = (void __iomem *)IXP4XX_QMGR_BASE_VIRT; val = __raw_readl(&qmgr_regs->acc[queue][0]); #if DEBUG_QMGR BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ @@ -112,14 +112,14 @@ static inline u32 qmgr_get_entry(unsigned int queue) static inline int __qmgr_get_stat1(unsigned int queue) { - extern struct qmgr_regs __iomem *qmgr_regs; + const struct qmgr_regs __iomem *qmgr_regs = (void __iomem *)IXP4XX_QMGR_BASE_VIRT; return (__raw_readl(&qmgr_regs->stat1[queue >> 3]) >> ((queue & 7) << 2)) & 0xF; } static inline int __qmgr_get_stat2(unsigned int queue) { - extern struct qmgr_regs __iomem *qmgr_regs; + const struct qmgr_regs __iomem *qmgr_regs = (void __iomem *)IXP4XX_QMGR_BASE_VIRT; BUG_ON(queue >= HALF_QUEUES); return (__raw_readl(&qmgr_regs->stat2[queue >> 4]) >> ((queue & 0xF) << 1)) & 0x3; @@ -145,7 +145,7 @@ static inline int qmgr_stat_empty(unsigned int queue) */ static inline int qmgr_stat_below_low_watermark(unsigned int queue) { - extern struct qmgr_regs __iomem *qmgr_regs; + const struct qmgr_regs __iomem *qmgr_regs = (void __iomem *)IXP4XX_QMGR_BASE_VIRT; if (queue >= HALF_QUEUES) return (__raw_readl(&qmgr_regs->statne_h) >> (queue - HALF_QUEUES)) & 0x01; @@ -172,7 +172,7 @@ static inline int qmgr_stat_above_high_watermark(unsigned int queue) */ static inline int qmgr_stat_full(unsigned int queue) { - extern struct qmgr_regs __iomem *qmgr_regs; + const struct qmgr_regs __iomem *qmgr_regs = (void __iomem *)IXP4XX_QMGR_BASE_VIRT; if (queue >= HALF_QUEUES) return (__raw_readl(&qmgr_regs->statf_h) >> (queue - HALF_QUEUES)) & 0x01; diff --git a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c index 852f7c9f87d0..7c0584e0ab87 100644 --- a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c +++ b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c @@ -14,7 +14,7 @@ #include #include -struct qmgr_regs __iomem *qmgr_regs; +static const struct qmgr_regs __iomem *qmgr_regs = (void __iomem *)IXP4XX_QMGR_BASE_VIRT; static struct resource *mem_res; static spinlock_t qmgr_lock; static u32 used_sram_bitmap[4]; /* 128 16-dword pages */ @@ -32,7 +32,7 @@ void qmgr_set_irq(unsigned int queue, int src, spin_lock_irqsave(&qmgr_lock, flags); if (queue < HALF_QUEUES) { - u32 __iomem *reg; + const u32 __iomem *reg; int bit; BUG_ON(src > QUEUE_IRQ_SRC_NOT_FULL); reg = &qmgr_regs->irqsrc[queue >> 3]; /* 8 queues per u32 */ @@ -293,12 +293,6 @@ static int qmgr_init(void) if (mem_res == NULL) return -EBUSY; - qmgr_regs = ioremap(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); - if (qmgr_regs == NULL) { - err = -ENOMEM; - goto error_map; - } - /* reset qmgr registers */ for (i = 0; i < 4; i++) { __raw_writel(0x33333333, &qmgr_regs->stat1[i]); @@ -347,8 +341,6 @@ static int qmgr_init(void) error_irq2: free_irq(IRQ_IXP4XX_QM1, NULL); error_irq: - iounmap(qmgr_regs); -error_map: release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); return err; } @@ -359,7 +351,6 @@ static void qmgr_remove(void) free_irq(IRQ_IXP4XX_QM2, NULL); synchronize_irq(IRQ_IXP4XX_QM1); synchronize_irq(IRQ_IXP4XX_QM2); - iounmap(qmgr_regs); release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); } @@ -369,7 +360,6 @@ module_exit(qmgr_remove); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Krzysztof Halasa"); -EXPORT_SYMBOL(qmgr_regs); EXPORT_SYMBOL(qmgr_set_irq); EXPORT_SYMBOL(qmgr_enable_irq); EXPORT_SYMBOL(qmgr_disable_irq); -- cgit v1.2.2 From b7b23db72f9a79e6ed0bcfb75d73b29f8e03fe62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Ha=C5=82asa?= Date: Sun, 2 Sep 2012 00:50:39 +0200 Subject: IXP4xx: map CPU config registers within VMALLOC region. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Krzysztof Hałasa --- arch/arm/mach-ixp4xx/common.c | 8 ----- arch/arm/mach-ixp4xx/include/mach/debug-macro.S | 4 +-- arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h | 47 ++++++++++--------------- 3 files changed, 21 insertions(+), 38 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index acc0584377fc..8c0c0e2d0727 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -73,14 +73,6 @@ static struct map_desc ixp4xx_io_desc[] __initdata = { .length = IXP4XX_QMGR_REGION_SIZE, .type = MT_DEVICE }, -#ifdef CONFIG_DEBUG_LL - { /* Debug UART mapping */ - .virtual = (unsigned long)IXP4XX_DEBUG_UART_BASE_VIRT, - .pfn = __phys_to_pfn(IXP4XX_DEBUG_UART_BASE_PHYS), - .length = IXP4XX_DEBUG_UART_REGION_SIZE, - .type = MT_DEVICE - } -#endif }; void __init ixp4xx_map_io(void) diff --git a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S index 8c9f8d564492..ff686cbc5df4 100644 --- a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S +++ b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S @@ -17,8 +17,8 @@ #else mov \rp, #0 #endif - orr \rv, \rp, #0xff000000 @ virtual - orr \rv, \rv, #0x00b00000 + orr \rv, \rp, #0xfe000000 @ virtual + orr \rv, \rv, #0x00f00000 orr \rp, \rp, #0xc8000000 @ physical .endm diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h index a24a8fe76604..c5bae9c035d5 100644 --- a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h +++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h @@ -30,52 +30,43 @@ * * 0x50000000 0x10000000 ioremap'd EXP BUS * - * 0x60000000 0x00004000 0xffbe7000 QMgr + * 0xC8000000 0x00013000 0xFEF00000 On-Chip Peripherals * - * 0xC8000000 0x00013000 0xffbeb000 On-Chip Peripherals + * 0xC0000000 0x00001000 0xFEF13000 PCI CFG * - * 0xC4000000 0x00001000 0xffbfe000 EXP CFG + * 0xC4000000 0x00001000 0xFEF14000 EXP CFG * - * 0xC0000000 0x00001000 0xffbff000 PCI CFG + * 0x60000000 0x00004000 0xFEF15000 QMgr */ /* * Queue Manager */ -#define IXP4XX_QMGR_BASE_PHYS (0x60000000) -#define IXP4XX_QMGR_BASE_VIRT IOMEM(0xFFBE7000) -#define IXP4XX_QMGR_REGION_SIZE (0x00004000) +#define IXP4XX_QMGR_BASE_PHYS 0x60000000 +#define IXP4XX_QMGR_BASE_VIRT IOMEM(0xFEF15000) +#define IXP4XX_QMGR_REGION_SIZE 0x00004000 /* - * Expansion BUS Configuration registers + * Peripheral space, including debug UART. Must be section-aligned so that + * it can be used with the low-level debug code. */ -#define IXP4XX_EXP_CFG_BASE_PHYS (0xC4000000) -#define IXP4XX_EXP_CFG_BASE_VIRT IOMEM(0xFFBFE000) -#define IXP4XX_EXP_CFG_REGION_SIZE (0x00001000) +#define IXP4XX_PERIPHERAL_BASE_PHYS 0xC8000000 +#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFEF00000) +#define IXP4XX_PERIPHERAL_REGION_SIZE 0x00013000 /* * PCI Config registers */ -#define IXP4XX_PCI_CFG_BASE_PHYS (0xC0000000) -#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFFBFF000) -#define IXP4XX_PCI_CFG_REGION_SIZE (0x00001000) - -/* - * Peripheral space - */ -#define IXP4XX_PERIPHERAL_BASE_PHYS (0xC8000000) -#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFFBEB000) -#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000) +#define IXP4XX_PCI_CFG_BASE_PHYS 0xC0000000 +#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFEF13000) +#define IXP4XX_PCI_CFG_REGION_SIZE 0x00001000 /* - * Debug UART - * - * This is basically a remap of UART1 into a region that is section - * aligned so that it * can be used with the low-level debug code. + * Expansion BUS Configuration registers */ -#define IXP4XX_DEBUG_UART_BASE_PHYS (0xC8000000) -#define IXP4XX_DEBUG_UART_BASE_VIRT IOMEM(0xffb00000) -#define IXP4XX_DEBUG_UART_REGION_SIZE (0x00001000) +#define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000 +#define IXP4XX_EXP_CFG_BASE_VIRT 0xFEF14000 +#define IXP4XX_EXP_CFG_REGION_SIZE 0x00001000 #define IXP4XX_EXP_CS0_OFFSET 0x00 #define IXP4XX_EXP_CS1_OFFSET 0x04 -- cgit v1.2.2 From 0d2c9f0517e915ce03a04e91d3207827e0d274a8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 28 Sep 2012 23:36:10 +0200 Subject: IXP4xx: use __iomem for MMIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ixp4xx queue manager uses "const struct qmgr_regs __iomem *" as the type for a pointer that is passed to __raw_writel, which is not allowed because of the const-ness. Dropping the 'const' keyword fixes the problem. While we're here, let's also drop the useless type cast. Without this patch, building ixp4xx_defconfig results in: In file included from arch/arm/mach-ixp4xx/ixp4xx_qmgr.c:15:0: arch/arm/mach-ixp4xx/include/mach/qmgr.h: In function 'qmgr_put_entry': arch/arm/mach-ixp4xx/include/mach/qmgr.h:96:2: warning: passing argument 2 of '__raw_writel' discards 'const' qualifier from pointer target type [enabled by default] arch/arm/include/asm/io.h:88:91: note: expected 'volatile void *' but argument is of type 'const u32 *' In file included from drivers/net/ethernet/xscale/ixp4xx_eth.c:41:0: arch/arm/mach-ixp4xx/include/mach/qmgr.h: In function 'qmgr_put_entry': arch/arm/mach-ixp4xx/include/mach/qmgr.h:96:2: warning: passing argument 2 of '__raw_writel' discards 'const' qualifier from pointer target type [enabled by default] arch/arm/include/asm/io.h:88:91: note: expected 'volatile void *' but argument is of type 'const u32 *' arch/arm/mach-ixp4xx/ixp4xx_qmgr.c: In function 'qmgr_set_irq': arch/arm/mach-ixp4xx/ixp4xx_qmgr.c:41:9: warning: passing argument 2 of '__raw_writel' discards 'const' qualifier from pointer target type [enabled by default] arch/arm/include/asm/io.h:88:91: note: expected 'volatile void *' but argument is of type 'const u32 *' Signed-off-by: Arnd Bergmann Signed-off-by: Krzysztof Hałasa --- arch/arm/mach-ixp4xx/include/mach/qmgr.h | 12 ++++++------ arch/arm/mach-ixp4xx/ixp4xx_qmgr.c | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ixp4xx/include/mach/qmgr.h b/arch/arm/mach-ixp4xx/include/mach/qmgr.h index 0a88d3b8e806..4de8da536dbb 100644 --- a/arch/arm/mach-ixp4xx/include/mach/qmgr.h +++ b/arch/arm/mach-ixp4xx/include/mach/qmgr.h @@ -86,7 +86,7 @@ void qmgr_release_queue(unsigned int queue); static inline void qmgr_put_entry(unsigned int queue, u32 val) { - const struct qmgr_regs __iomem *qmgr_regs = (void __iomem *)IXP4XX_QMGR_BASE_VIRT; + struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; #if DEBUG_QMGR BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ @@ -99,7 +99,7 @@ static inline void qmgr_put_entry(unsigned int queue, u32 val) static inline u32 qmgr_get_entry(unsigned int queue) { u32 val; - const struct qmgr_regs __iomem *qmgr_regs = (void __iomem *)IXP4XX_QMGR_BASE_VIRT; + const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; val = __raw_readl(&qmgr_regs->acc[queue][0]); #if DEBUG_QMGR BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ @@ -112,14 +112,14 @@ static inline u32 qmgr_get_entry(unsigned int queue) static inline int __qmgr_get_stat1(unsigned int queue) { - const struct qmgr_regs __iomem *qmgr_regs = (void __iomem *)IXP4XX_QMGR_BASE_VIRT; + const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; return (__raw_readl(&qmgr_regs->stat1[queue >> 3]) >> ((queue & 7) << 2)) & 0xF; } static inline int __qmgr_get_stat2(unsigned int queue) { - const struct qmgr_regs __iomem *qmgr_regs = (void __iomem *)IXP4XX_QMGR_BASE_VIRT; + const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; BUG_ON(queue >= HALF_QUEUES); return (__raw_readl(&qmgr_regs->stat2[queue >> 4]) >> ((queue & 0xF) << 1)) & 0x3; @@ -145,7 +145,7 @@ static inline int qmgr_stat_empty(unsigned int queue) */ static inline int qmgr_stat_below_low_watermark(unsigned int queue) { - const struct qmgr_regs __iomem *qmgr_regs = (void __iomem *)IXP4XX_QMGR_BASE_VIRT; + const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; if (queue >= HALF_QUEUES) return (__raw_readl(&qmgr_regs->statne_h) >> (queue - HALF_QUEUES)) & 0x01; @@ -172,7 +172,7 @@ static inline int qmgr_stat_above_high_watermark(unsigned int queue) */ static inline int qmgr_stat_full(unsigned int queue) { - const struct qmgr_regs __iomem *qmgr_regs = (void __iomem *)IXP4XX_QMGR_BASE_VIRT; + const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; if (queue >= HALF_QUEUES) return (__raw_readl(&qmgr_regs->statf_h) >> (queue - HALF_QUEUES)) & 0x01; diff --git a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c index 7c0584e0ab87..9d1b6b7c394c 100644 --- a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c +++ b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c @@ -14,7 +14,7 @@ #include #include -static const struct qmgr_regs __iomem *qmgr_regs = (void __iomem *)IXP4XX_QMGR_BASE_VIRT; +static struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; static struct resource *mem_res; static spinlock_t qmgr_lock; static u32 used_sram_bitmap[4]; /* 128 16-dword pages */ @@ -32,7 +32,7 @@ void qmgr_set_irq(unsigned int queue, int src, spin_lock_irqsave(&qmgr_lock, flags); if (queue < HALF_QUEUES) { - const u32 __iomem *reg; + u32 __iomem *reg; int bit; BUG_ON(src > QUEUE_IRQ_SRC_NOT_FULL); reg = &qmgr_regs->irqsrc[queue >> 3]; /* 8 queues per u32 */ -- cgit v1.2.2 From 441a179dafc0f99fc8b3a8268eef66958621082e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 21 Nov 2012 19:27:23 +0000 Subject: [PARISC] fix user-triggerable panic on parisc int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, compat_sigset_t __user *oset, unsigned int sigsetsize) { sigset_t old_set, new_set; int ret; if (set && get_sigset32(set, &new_set, sigsetsize)) ... static int get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) { compat_sigset_t s; int r; if (sz != sizeof *set) panic("put_sigset32()"); In other words, rt_sigprocmask(69, (void *)69, 69) done by 32bit process will promptly panic the box. Signed-off-by: Al Viro Cc: Signed-off-by: James Bottomley --- arch/parisc/kernel/signal32.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index fd49aeda9eb8..5dede04f2f3e 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c @@ -65,7 +65,8 @@ put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) { compat_sigset_t s; - if (sz != sizeof *set) panic("put_sigset32()"); + if (sz != sizeof *set) + return -EINVAL; sigset_64to32(&s, set); return copy_to_user(up, &s, sizeof s); @@ -77,7 +78,8 @@ get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) compat_sigset_t s; int r; - if (sz != sizeof *set) panic("put_sigset32()"); + if (sz != sizeof *set) + return -EINVAL; if ((r = copy_from_user(&s, up, sz)) == 0) { sigset_32to64(set, &s); -- cgit v1.2.2 From bb4618823a3389086f157fafb2a0d97cade8d89f Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Fri, 23 Nov 2012 13:25:39 +1100 Subject: powerpc/pseries: Fix oops with MSIs when missing EEH PEs The new EEH code introduced a small regression, if the EEH PEs are missin (which happens currently in qemu for example), it will deref a NULL pointer in the MSI code. Signed-off-by: Alexey Kardashevskiy Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/msi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index d19f4977c834..e5b084723131 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -220,7 +220,8 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) /* Get the top level device in the PE */ edev = of_node_to_eeh_dev(dn); - edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); + if (edev->pe) + edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); dn = eeh_dev_to_of_node(edev); if (!dn) return NULL; -- cgit v1.2.2 From 5010192d5ae589002c4453d6c6e662e5e9acae59 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Thu, 22 Nov 2012 12:50:43 +0100 Subject: ARM: 7583/1: decompressor: Enable unaligned memory access for v6 and above Modern GCC can generate code which makes use of the CPU's native unaligned memory access capabilities. This is useful for the C decompressor implementations used for unpacking compressed kernels. This patch disables alignment faults and enables the v6 unaligned access model on CPUs which support these features (i.e., v6 and later), allowing full unaligned access support for C code in the decompressor. The decompressor C code must not be built to assume that unaligned access works if support for v5 or older platforms is included in the kernel. For correct code generation, C decompressor code must always use the get_unaligned and put_unaligned accessors when dealing with unaligned pointers, regardless of this patch. Signed-off-by: Dave Martin Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/boot/compressed/head.S | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 90275f036cd1..49ca86e37b8d 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -652,6 +652,15 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size mov pc, lr ENDPROC(__setup_mmu) +@ Enable unaligned access on v6, to allow better code generation +@ for the decompressor C code: +__armv6_mmu_cache_on: + mrc p15, 0, r0, c1, c0, 0 @ read SCTLR + bic r0, r0, #2 @ A (no unaligned access fault) + orr r0, r0, #1 << 22 @ U (v6 unaligned access model) + mcr p15, 0, r0, c1, c0, 0 @ write SCTLR + b __armv4_mmu_cache_on + __arm926ejs_mmu_cache_on: #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mov r0, #4 @ put dcache in WT mode @@ -694,6 +703,9 @@ __armv7_mmu_cache_on: bic r0, r0, #1 << 28 @ clear SCTLR.TRE orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement orr r0, r0, #0x003c @ write buffer + bic r0, r0, #2 @ A (no unaligned access fault) + orr r0, r0, #1 << 22 @ U (v6 unaligned access model) + @ (needed for ARM1176) #ifdef CONFIG_MMU #ifdef CONFIG_CPU_ENDIAN_BE8 orr r0, r0, #1 << 25 @ big-endian page tables @@ -914,7 +926,7 @@ proc_types: .word 0x0007b000 @ ARMv6 .word 0x000ff000 - W(b) __armv4_mmu_cache_on + W(b) __armv6_mmu_cache_on W(b) __armv4_mmu_cache_off W(b) __armv6_mmu_cache_flush -- cgit v1.2.2 From 0ec7ec75f674dbf48010081383263771f2611e72 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 15 Nov 2012 12:53:59 +0100 Subject: MIPS: Merge overlapping bootmem ranges Without this, we may end up with something like this in /proc/iomem: 01100000-014fffff : System RAM 01100000-013bf48f : Kernel code 013bf490-0149e01f : Kernel data 01500000-0c0fffff : System RAM but the two System RAM ranges should be one single range. This particular case will result in kexec failure on Octeon systems if the kernel being loaded by kexec is bigger than the already running kernel. Signed-off-by: Ralf Baechle --- arch/mips/kernel/setup.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index a53f8ec37aac..290dc6a1d7a3 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -79,7 +79,7 @@ static struct resource data_resource = { .name = "Kernel data", }; void __init add_memory_region(phys_t start, phys_t size, long type) { int x = boot_mem_map.nr_map; - struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1; + int i; /* Sanity check */ if (start + size < start) { @@ -88,15 +88,29 @@ void __init add_memory_region(phys_t start, phys_t size, long type) } /* - * Try to merge with previous entry if any. This is far less than - * perfect but is sufficient for most real world cases. + * Try to merge with existing entry, if any. */ - if (x && prev->addr + prev->size == start && prev->type == type) { - prev->size += size; + for (i = 0; i < boot_mem_map.nr_map; i++) { + struct boot_mem_map_entry *entry = boot_mem_map.map + i; + unsigned long top; + + if (entry->type != type) + continue; + + if (start + size < entry->addr) + continue; /* no overlap */ + + if (entry->addr + entry->size < start) + continue; /* no overlap */ + + top = max(entry->addr + entry->size, start + size); + entry->addr = min(entry->addr, start); + entry->size = top - entry->addr; + return; } - if (x == BOOT_MEM_MAP_MAX) { + if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) { pr_err("Ooops! Too many entries in the memory map!\n"); return; } -- cgit v1.2.2 From f93a1a00f2bd550f86fd1a9f83c493755aecd15f Mon Sep 17 00:00:00 2001 From: Al Cooper Date: Thu, 15 Nov 2012 18:16:14 -0500 Subject: MIPS: Fix crash that occurs when function tracing is enabled A recent patch changed some irq routines from inlines to functions. These routines are called by the tracer code. Now that they're functions, if they are compiled for function tracing they will call the tracer and crash the system due to infinite recursion. The fix disables tracing in these functions by using "notrace" in the function definition. Signed-off-by: Al Cooper Reviewed-by: David Daney Pathchwork: https://patchwork.linux-mips.org/patch/4564/ Signed-off-by: Ralf Baechle --- arch/mips/lib/mips-atomic.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c index e091430dbeb1..cd160be3ce4d 100644 --- a/arch/mips/lib/mips-atomic.c +++ b/arch/mips/lib/mips-atomic.c @@ -56,7 +56,7 @@ __asm__( " .set pop \n" " .endm \n"); -void arch_local_irq_disable(void) +notrace void arch_local_irq_disable(void) { preempt_disable(); __asm__ __volatile__( @@ -93,7 +93,7 @@ __asm__( " .set pop \n" " .endm \n"); -unsigned long arch_local_irq_save(void) +notrace unsigned long arch_local_irq_save(void) { unsigned long flags; preempt_disable(); @@ -135,7 +135,7 @@ __asm__( " .set pop \n" " .endm \n"); -void arch_local_irq_restore(unsigned long flags) +notrace void arch_local_irq_restore(unsigned long flags) { unsigned long __tmp1; @@ -159,7 +159,7 @@ void arch_local_irq_restore(unsigned long flags) EXPORT_SYMBOL(arch_local_irq_restore); -void __arch_local_irq_restore(unsigned long flags) +notrace void __arch_local_irq_restore(unsigned long flags) { unsigned long __tmp1; -- cgit v1.2.2 From 0e622d39197f0b64b9e043fe75ac3634bf9f3a05 Mon Sep 17 00:00:00 2001 From: Andreas Larsson Date: Fri, 23 Nov 2012 12:24:09 +0100 Subject: of/address: sparc: Declare of_iomap as an extern function for sparc again This bug-fix makes sure that of_iomap is defined extern for sparc so that the sparc-specific implementation of_iomap is once again used when including include/linux/of_address.h in a sparc context. OF_GPIO that is now available for sparc relies on this. The bug was inadvertently introduced in a850a75, "of/address: add empty static inlines for !CONFIG_OF", that added a static dummy inline for of_iomap when !CONFIG_OF_ADDRESS. However, CONFIG_OF_ADDRESS is never defined for sparc, but there is a sparc-specific implementation /arch/sparc/kernel/of_device_common.c. This fix takes the same approach as 0bce04b that solved the equivalent problem for of_address_to_resource. Signed-off-by: Andreas Larsson Acked-by: David Miller Signed-off-by: Grant Likely --- arch/sparc/include/asm/prom.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index f93003123bce..67c62578d170 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -63,10 +63,13 @@ extern char *of_console_options; extern void irq_trans_init(struct device_node *dp); extern char *build_path_component(struct device_node *dp); -/* SPARC has a local implementation */ +/* SPARC has local implementations */ extern int of_address_to_resource(struct device_node *dev, int index, struct resource *r); #define of_address_to_resource of_address_to_resource +void __iomem *of_iomap(struct device_node *node, int index); +#define of_iomap of_iomap + #endif /* __KERNEL__ */ #endif /* _SPARC_PROM_H */ -- cgit v1.2.2 From e716e014384688d1a50d1aa5213ee74748c6d4e0 Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Thu, 22 Nov 2012 21:58:26 +0000 Subject: powerpc/eeh: Do not invalidate PE properly While the EEH does recovery on the specific PE that has PCI errors, the PCI devices belonging to the PE will be removed and the PE will be marked as invalid since we still need the information stored in the PE. We only invalidate the PE when it doesn't have associated EEH devices and valid child PEs. However, the code used to check that is wrong. The patch fixes that. Signed-off-by: Gavin Shan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/eeh_pe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/eeh_pe.c b/arch/powerpc/platforms/pseries/eeh_pe.c index 797cd181dc3f..d16c8ded1084 100644 --- a/arch/powerpc/platforms/pseries/eeh_pe.c +++ b/arch/powerpc/platforms/pseries/eeh_pe.c @@ -449,7 +449,7 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe) if (list_empty(&pe->edevs)) { cnt = 0; list_for_each_entry(child, &pe->child_list, child) { - if (!(pe->type & EEH_PE_INVALID)) { + if (!(child->type & EEH_PE_INVALID)) { cnt++; break; } -- cgit v1.2.2 From 9d34340ebd00eaadbd414e02acc881c5fae903d3 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Mon, 26 Nov 2012 18:06:13 -0500 Subject: c6x: run do_notify_resume with interrupts enabled C6x was mistakenly running do_notify_resume with interrupts disabled. This would triggerlead to a warning in local_bh_enable() because interrupts were disabled: ------------[ cut here ]------------ WARNING: at /es/linux/linux-next/kernel/softirq.c:160 local_bh_enable+0x5c/0x10c() Modules linked in: e02f384d e002cda8 e02f3469 e02f384d 000000a0 e00363fc e01cce58 e5005c00 e0327986 00000000 e63c0aec 00000164 e00363fc 00000000 fffffffe e5005c00 e61fde00 e0268184 00000134 e01c91dc 00000001 fffffffe 00000000 10000100 e01c80e4 e5005c00 00000000 00000000 00000000 e63c0aec e526ce00 10000100 e628f920 e63c0a88 e6010410 e6449750 e5005c20 00000000 00000000 e63c0a80 e5005c20 e01c8590 e63c0a80 e5005c20 e63c0aec e00a0554 e009c758 e639e860 irq_spurious_proc_fops+0x6ad/0x3438 warn_slowpath_common+0x8c/0xb8 irq_spurious_proc_fops+0x2c9/0x3438 irq_spurious_proc_fops+0x6ad/0x3438 local_bh_enable+0x5c/0x10c sk_alloc+0x34/0xa4 local_bh_enable+0x5c/0x10c unix_release_sock+0x5c/0x2a0 sys_connect+0x94/0xd4 sock_release+0x38/0x104 sock_close+0x3c/0x54 __fput+0x154/0x2ec filp_close+0xc0/0xe4 task_work_run+0xdc/0x12c sys_close+0x2c/0x74 resume_userspace+0x0/0x30 ---[ end trace a70cbd610ae1f6b4 ]--- This patch enables interrupts before calling do_notify_resume(). Signed-off-by: Mark Salter --- arch/c6x/kernel/entry.S | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/c6x/kernel/entry.S b/arch/c6x/kernel/entry.S index 5449c36018fe..0c164c2c22be 100644 --- a/arch/c6x/kernel/entry.S +++ b/arch/c6x/kernel/entry.S @@ -277,6 +277,8 @@ work_rescheduled: [A1] BNOP .S1 work_resched,5 work_notifysig: + ;; enable interrupts for do_notify_resume() + UNMASK_INT B2 B .S2 do_notify_resume LDW .D2T1 *+SP(REGS__END+8),A6 ; syscall flag ADDKPC .S2 resume_userspace,B3,1 -- cgit v1.2.2 From 9c0603f487b6b0cfa0b2bbcab7f06333e78db652 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Mon, 26 Nov 2012 18:14:00 -0500 Subject: c6x: fix misleading comment A comment in entry.S incorrectly stated that interrupt vectors called __do_IRQ() and that int6 vector was used for syscalls. Both statements are incorrect for the current kernel, so this patch cleans up the wording to reflect current reality. Signed-off-by: Mark Salter --- arch/c6x/kernel/entry.S | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/c6x/kernel/entry.S b/arch/c6x/kernel/entry.S index 0c164c2c22be..0ed6157dd256 100644 --- a/arch/c6x/kernel/entry.S +++ b/arch/c6x/kernel/entry.S @@ -429,8 +429,7 @@ ENTRY(ret_from_kernel_execve) ENDPROC(ret_from_kernel_execve) ;; - ;; These are the interrupt handlers, responsible for calling __do_IRQ() - ;; int6 is used for syscalls (see _system_call entry) + ;; These are the interrupt handlers, responsible for calling c6x_do_IRQ() ;; .macro SAVE_ALL_INT SAVE_ALL IRP,ITSR -- cgit v1.2.2 From cb7cb2864e758a1b040040bc55e404c677c911cb Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 21 Nov 2012 14:41:21 -0800 Subject: x86, kvm: Remove incorrect redundant assembly constraint In __emulate_1op_rax_rdx, we use "+a" and "+d" which are input/output constraints, and *then* use "a" and "d" as input constraints. This is incorrect, but happens to work on some versions of gcc. However, it breaks gcc with -O0 and icc, and may break on future versions of gcc. Reported-and-tested-by: Melanie Blower Signed-off-by: H. Peter Anvin Link: http://lkml.kernel.org/r/B3584E72CFEBED439A3ECA9BCE67A4EF1B17AF90@FMSMSX107.amr.corp.intel.com Reviewed-by: Paolo Bonzini Acked-by: Marcelo Tosatti --- arch/x86/kvm/emulate.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 39171cb307ea..bba39bfa1c4b 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -426,8 +426,7 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt) _ASM_EXTABLE(1b, 3b) \ : "=m" ((ctxt)->eflags), "=&r" (_tmp), \ "+a" (*rax), "+d" (*rdx), "+qm"(_ex) \ - : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val), \ - "a" (*rax), "d" (*rdx)); \ + : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val)); \ } while (0) /* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */ -- cgit v1.2.2 From 6662c34fa9c60a48aaa5879cb229cd9a84de9c22 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 27 Nov 2012 08:54:36 -0800 Subject: x86-32: Unbreak booting on some 486 clones There appear to have been some 486 clones, including the "enhanced" version of Am486, which have CPUID but not CR4. These 486 clones had only the FPU flag, if any, unlike the Intel 486s with CPUID, which also had VME and therefore needed CR4. Therefore, look at the basic CPUID flags and require at least one bit other than bit 0 before we modify CR4. Thanks to Christian Ludloff of sandpile.org for confirming this as a problem. Signed-off-by: H. Peter Anvin --- arch/x86/kernel/head_32.S | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 957a47aec64e..4dac2f68ed4a 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -292,8 +292,8 @@ default_entry: * be using the global pages. * * NOTE! If we are on a 486 we may have no cr4 at all! - * Specifically, cr4 exists if and only if CPUID exists, - * which in turn exists if and only if EFLAGS.ID exists. + * Specifically, cr4 exists if and only if CPUID exists + * and has flags other than the FPU flag set. */ movl $X86_EFLAGS_ID,%ecx pushl %ecx @@ -308,6 +308,11 @@ default_entry: testl %ecx,%eax jz 6f # No ID flag = no CPUID = no CR4 + movl $1,%eax + cpuid + andl $~1,%edx # Ignore CPUID.FPU + jz 6f # No flags or only CPUID.FPU = no CR4 + movl pa(mmu_cr4_features),%eax movl %eax,%cr4 -- cgit v1.2.2 From ea3aacf5f22c1002cac97985354658072232e280 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 23 Nov 2012 18:55:30 +0100 Subject: ARM: 7586/1: sp804: set cpumask to cpu_possible_mask for clock event device The SP804 driver statically initialises the cpumask of the clock event device to be cpu_all_mask, which is derived from the compile-time constant NR_CPUS. This breaks SMP_ON_UP systems where the interrupt controller handling the sp804 doesn't have the irq_set_affinity callback on the irq_chip, because the common timer code fails to identify the device as cpu-local and ends up treating it as a broadcast device instead. This patch fixes the problem by using cpu_possible_mask at runtime, which will correctly represent the possible CPUs when SMP_ON_UP is being used. Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/common/timer-sp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c index df13a3ffff35..9d2d3ba339ff 100644 --- a/arch/arm/common/timer-sp.c +++ b/arch/arm/common/timer-sp.c @@ -162,7 +162,6 @@ static struct clock_event_device sp804_clockevent = { .set_mode = sp804_set_mode, .set_next_event = sp804_set_next_event, .rating = 300, - .cpumask = cpu_all_mask, }; static struct irqaction sp804_timer_irq = { @@ -185,6 +184,7 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq, clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ); evt->name = name; evt->irq = irq; + evt->cpumask = cpu_possible_mask; setup_irq(irq, &sp804_timer_irq); clockevents_config_and_register(evt, rate, 0xf, 0xffffffff); -- cgit v1.2.2 From de0eed2813ce42b8e0320a86cbe373266c904044 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Wed, 28 Nov 2012 14:16:05 -0500 Subject: c6x: remove internal kernel symbols from exported setup.h Some internal kernel symbols were referenced in the exported setup.h. This splits out the internal bits from the exported uapi bits. Signed-off-by: Mark Salter --- arch/c6x/include/asm/setup.h | 33 +++++++++++++++++++++++++++++++++ arch/c6x/include/uapi/asm/setup.h | 33 +++------------------------------ 2 files changed, 36 insertions(+), 30 deletions(-) create mode 100644 arch/c6x/include/asm/setup.h (limited to 'arch') diff --git a/arch/c6x/include/asm/setup.h b/arch/c6x/include/asm/setup.h new file mode 100644 index 000000000000..ecead15872a6 --- /dev/null +++ b/arch/c6x/include/asm/setup.h @@ -0,0 +1,33 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef _ASM_C6X_SETUP_H +#define _ASM_C6X_SETUP_H + +#include + +#ifndef __ASSEMBLY__ +extern char c6x_command_line[COMMAND_LINE_SIZE]; + +extern int c6x_add_memory(phys_addr_t start, unsigned long size); + +extern unsigned long ram_start; +extern unsigned long ram_end; + +extern int c6x_num_cores; +extern unsigned int c6x_silicon_rev; +extern unsigned int c6x_devstat; +extern unsigned char c6x_fuse_mac[6]; + +extern void machine_init(unsigned long dt_ptr); +extern void time_init(void); + +#endif /* !__ASSEMBLY__ */ +#endif /* _ASM_C6X_SETUP_H */ diff --git a/arch/c6x/include/uapi/asm/setup.h b/arch/c6x/include/uapi/asm/setup.h index a01e31896fa9..ad9ac97a8dad 100644 --- a/arch/c6x/include/uapi/asm/setup.h +++ b/arch/c6x/include/uapi/asm/setup.h @@ -1,33 +1,6 @@ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _ASM_C6X_SETUP_H -#define _ASM_C6X_SETUP_H +#ifndef _UAPI_ASM_C6X_SETUP_H +#define _UAPI_ASM_C6X_SETUP_H #define COMMAND_LINE_SIZE 1024 -#ifndef __ASSEMBLY__ -extern char c6x_command_line[COMMAND_LINE_SIZE]; - -extern int c6x_add_memory(phys_addr_t start, unsigned long size); - -extern unsigned long ram_start; -extern unsigned long ram_end; - -extern int c6x_num_cores; -extern unsigned int c6x_silicon_rev; -extern unsigned int c6x_devstat; -extern unsigned char c6x_fuse_mac[6]; - -extern void machine_init(unsigned long dt_ptr); -extern void time_init(void); - -#endif /* !__ASSEMBLY__ */ -#endif /* _ASM_C6X_SETUP_H */ +#endif /* _UAPI_ASM_C6X_SETUP_H */ -- cgit v1.2.2 From 93bbd0c087eb299e0fe11c59d340932180c082b5 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Wed, 28 Nov 2012 14:22:41 -0500 Subject: c6x: use generic kvm_para.h Signed-off-by: Mark Salter --- arch/c6x/include/uapi/asm/Kbuild | 2 ++ arch/c6x/include/uapi/asm/kvm_para.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) delete mode 100644 arch/c6x/include/uapi/asm/kvm_para.h (limited to 'arch') diff --git a/arch/c6x/include/uapi/asm/Kbuild b/arch/c6x/include/uapi/asm/Kbuild index c312b424c433..e9bc2b2b8147 100644 --- a/arch/c6x/include/uapi/asm/Kbuild +++ b/arch/c6x/include/uapi/asm/Kbuild @@ -1,6 +1,8 @@ # UAPI Header export list include include/uapi/asm-generic/Kbuild.asm +generic-y += kvm_para.h + header-y += byteorder.h header-y += kvm_para.h header-y += ptrace.h diff --git a/arch/c6x/include/uapi/asm/kvm_para.h b/arch/c6x/include/uapi/asm/kvm_para.h deleted file mode 100644 index 14fab8f0b957..000000000000 --- a/arch/c6x/include/uapi/asm/kvm_para.h +++ /dev/null @@ -1 +0,0 @@ -#include -- cgit v1.2.2 From 9436d5c32b1ac8d4efdbc933611b5e699908854e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 10 Nov 2012 01:15:42 -0500 Subject: um: get_safe_registers() should be done in flush_thread(), not start_thread() ... or we'll end up buggering the results of ELF_PLAT_INIT() Signed-off-by: Al Viro --- arch/um/kernel/exec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 3a8ece7d09ca..0d7103c9eff3 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -32,13 +32,14 @@ void flush_thread(void) "err = %d\n", ret); force_sig(SIGKILL, current); } + get_safe_registers(current_pt_regs()->regs.gp, + current_pt_regs()->regs.fp); __switch_mm(¤t->mm->context.id); } void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) { - get_safe_registers(regs->regs.gp, regs->regs.fp); PT_REGS_IP(regs) = eip; PT_REGS_SP(regs) = esp; current->ptrace &= ~PT_DTRACE; -- cgit v1.2.2 From d26654e5f9cd27815ab5bc8148c826f3b960396c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 20 Sep 2012 15:49:09 -0400 Subject: openrisk: fix altstack switching on sigreturn do_sigaltstack() expects _userland_ address, TYVM... Signed-off-by: Al Viro --- arch/openrisc/kernel/signal.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c index 30110297f4f9..ddedc8a77861 100644 --- a/arch/openrisc/kernel/signal.c +++ b/arch/openrisc/kernel/signal.c @@ -84,7 +84,6 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe *frame = (struct rt_sigframe __user *)regs->sp; sigset_t set; - stack_t st; /* * Since we stacked the signal on a dword boundary, @@ -104,11 +103,10 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs) if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; - if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) - goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - do_sigaltstack(&st, NULL, regs->sp); + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) + goto badframe; return regs->gpr[11]; -- cgit v1.2.2 From 9dc87c7b5b0a2db407e086f45cf08ca78208cc16 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 20 Sep 2012 16:38:34 -0400 Subject: sh64: fix altstack switching on sigreturn incidentally, declaring a local variable as __user (!) to make sparse STFU is really sick. Especially since sparse had been 100% right - it *is* a bug. Signed-off-by: Al Viro --- arch/sh/kernel/signal_64.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index 23853814bd17..d867cd95a622 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c @@ -347,7 +347,6 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, { struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (long) REF_REG_SP; sigset_t set; - stack_t __user st; long long ret; /* Always make any pending restarted system calls return -EINTR */ @@ -365,11 +364,10 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, goto badframe; regs->pc -= 4; - if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) - goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - do_sigaltstack(&st, NULL, REF_REG_SP); + if (do_sigaltstack(&frame->uc.uc_stack, NULL, REF_REG_SP) == -EFAULT) + goto badframe; return (int) ret; -- cgit v1.2.2 From afd3f96dc34357584763c2dc453192c78a9dbce0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 20 Nov 2012 10:36:17 -0500 Subject: score: do_sigaltstack() expects a userland pointer... Signed-off-by: Al Viro --- arch/score/kernel/signal.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c index c268bbf8b410..02353bde92d8 100644 --- a/arch/score/kernel/signal.c +++ b/arch/score/kernel/signal.c @@ -148,7 +148,6 @@ score_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe __user *frame; sigset_t set; - stack_t st; int sig; /* Always make any pending restarted system calls return -EINTR */ @@ -168,12 +167,10 @@ score_rt_sigreturn(struct pt_regs *regs) else if (sig) force_sig(sig, current); - if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st))) - goto badframe; - /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]); + if (do_sigaltstack(&frame->rs_uc.uc_stack, NULL, regs->regs[0]) == -EFAULT) + goto badframe; regs->is_syscall = 0; __asm__ __volatile__( -- cgit v1.2.2 From 02232f8d2b22708f0651dc515544f4a7ef1e0224 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 20 Nov 2012 10:41:11 -0500 Subject: microblaze: rt_sigreturn is too trigger-happy about sigaltstack errors Signed-off-by: Al Viro --- arch/microblaze/kernel/signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c index 3847e5b9c601..3903e3d11f5a 100644 --- a/arch/microblaze/kernel/signal.c +++ b/arch/microblaze/kernel/signal.c @@ -111,7 +111,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1)) + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1) == -EFAULT) goto badframe; return rval; -- cgit v1.2.2 From 644c154186386bb1fa6446bc5e037b9ed098db46 Mon Sep 17 00:00:00 2001 From: Vincent Palatin Date: Fri, 30 Nov 2012 12:15:32 -0800 Subject: x86, fpu: Avoid FPU lazy restore after suspend When a cpu enters S3 state, the FPU state is lost. After resuming for S3, if we try to lazy restore the FPU for a process running on the same CPU, this will result in a corrupted FPU context. Ensure that "fpu_owner_task" is properly invalided when (re-)initializing a CPU, so nobody will try to lazy restore a state which doesn't exist in the hardware. Tested with a 64-bit kernel on a 4-core Ivybridge CPU with eagerfpu=off, by doing thousands of suspend/resume cycles with 4 processes doing FPU operations running. Without the patch, a process is killed after a few hundreds cycles by a SIGFPE. Cc: Duncan Laurie Cc: Olof Johansson Cc: v3.4+ # for 3.4 need to replace this_cpu_write by percpu_write Signed-off-by: Vincent Palatin Link: http://lkml.kernel.org/r/1354306532-1014-1-git-send-email-vpalatin@chromium.org Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/fpu-internal.h | 15 +++++++++------ arch/x86/kernel/smpboot.c | 5 +++++ 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/fpu-internal.h b/arch/x86/include/asm/fpu-internal.h index 831dbb9c6c02..41ab26ea6564 100644 --- a/arch/x86/include/asm/fpu-internal.h +++ b/arch/x86/include/asm/fpu-internal.h @@ -399,14 +399,17 @@ static inline void drop_init_fpu(struct task_struct *tsk) typedef struct { int preload; } fpu_switch_t; /* - * FIXME! We could do a totally lazy restore, but we need to - * add a per-cpu "this was the task that last touched the FPU - * on this CPU" variable, and the task needs to have a "I last - * touched the FPU on this CPU" and check them. + * Must be run with preemption disabled: this clears the fpu_owner_task, + * on this CPU. * - * We don't do that yet, so "fpu_lazy_restore()" always returns - * false, but some day.. + * This will disable any lazy FPU state restore of the current FPU state, + * but if the current thread owns the FPU, it will still be saved by. */ +static inline void __cpu_disable_lazy_restore(unsigned int cpu) +{ + per_cpu(fpu_owner_task, cpu) = NULL; +} + static inline int fpu_lazy_restore(struct task_struct *new, unsigned int cpu) { return new == this_cpu_read_stable(fpu_owner_task) && diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index c80a33bc528b..f3e2ec878b8c 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -68,6 +68,8 @@ #include #include #include +#include +#include #include #include #include @@ -818,6 +820,9 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle) per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; + /* the FPU context is blank, nobody can own it */ + __cpu_disable_lazy_restore(cpu); + err = do_boot_cpu(apicid, cpu, tidle); if (err) { pr_debug("do_boot_cpu failed %d\n", err); -- cgit v1.2.2 From 9d73fc2d641f8831c9dc803177fe47c02120cc36 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 2 Dec 2012 17:55:07 +0000 Subject: open*(2) compat fixes (s390, arm64) The usual rules for open()/openat()/open_by_handle_at() are 1) native 32bit - don't force O_LARGEFILE in flags 2) native 64bit - force O_LARGEFILE in flags 3) compat on 64bit host - as for native 32bit 4) native 32bit ABI for 64bit system (mips/n32, x86/x32) - as for native 64bit There are only two exceptions - s390 compat has open() forcing O_LARGEFILE and arm64 compat has open_by_handle_at() doing the same thing. The same binaries on native host (s390/31 and arm resp.) will *not* force O_LARGEFILE, so IMO both are emulation bugs. Objections? The fix is obvious... Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/arm64/include/asm/unistd32.h | 2 +- arch/s390/kernel/compat_wrapper.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h index 6d909faebf28..656a6f291a35 100644 --- a/arch/arm64/include/asm/unistd32.h +++ b/arch/arm64/include/asm/unistd32.h @@ -392,7 +392,7 @@ __SYSCALL(367, sys_fanotify_init) __SYSCALL(368, compat_sys_fanotify_mark_wrapper) __SYSCALL(369, sys_prlimit64) __SYSCALL(370, sys_name_to_handle_at) -__SYSCALL(371, sys_open_by_handle_at) +__SYSCALL(371, compat_sys_open_by_handle_at) __SYSCALL(372, sys_clock_adjtime) __SYSCALL(373, sys_syncfs) diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index ad79b846535c..827e094a2f49 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -28,7 +28,7 @@ ENTRY(sys32_open_wrapper) llgtr %r2,%r2 # const char * lgfr %r3,%r3 # int lgfr %r4,%r4 # int - jg sys_open # branch to system call + jg compat_sys_open # branch to system call ENTRY(sys32_close_wrapper) llgfr %r2,%r2 # unsigned int -- cgit v1.2.2 From 25a3bc6bd1ca03ab504b8c55c98f8d0135644d53 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 3 Dec 2012 18:15:30 +0000 Subject: [parisc] open(2) compat bug In commit 9d73fc2d641f ("open*(2) compat fixes (s390, arm64)") I said: > > The usual rules for open()/openat()/open_by_handle_at() are > 1) native 32bit - don't force O_LARGEFILE in flags > 2) native 64bit - force O_LARGEFILE in flags > 3) compat on 64bit host - as for native 32bit > 4) native 32bit ABI for 64bit system (mips/n32, x86/x32) - as for native 64bit > > There are only two exceptions - s390 compat has open() forcing O_LARGEFILE and > arm64 compat has open_by_handle_at() doing the same thing. The same binaries > on native host (s390/31 and arm resp.) will *not* force O_LARGEFILE, so IMO > both are emulation bugs. Three exceptions, actually - parisc open() is another case like that. Native 32bit won't force O_LARGEFILE, the same binary on parisc64 will. Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/parisc/kernel/syscall_table.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 3735abd7f8f6..cbf5d59d5d6a 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -60,7 +60,7 @@ ENTRY_SAME(fork_wrapper) ENTRY_SAME(read) ENTRY_SAME(write) - ENTRY_SAME(open) /* 5 */ + ENTRY_COMP(open) /* 5 */ ENTRY_SAME(close) ENTRY_SAME(waitpid) ENTRY_SAME(creat) -- cgit v1.2.2 From de7531e8575ab383a0f5bb68b63e7891fce4765d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 3 Dec 2012 11:17:57 -0800 Subject: sparc64: exit_group should kill register windows just like plain exit. Reported-by: Al Viro Signed-off-by: David S. Miller --- arch/sparc/kernel/sys32.S | 2 +- arch/sparc/kernel/syscalls.S | 14 ++++++++++++-- arch/sparc/kernel/systbls_64.S | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S index 44025f4ba41f..8475a474273a 100644 --- a/arch/sparc/kernel/sys32.S +++ b/arch/sparc/kernel/sys32.S @@ -47,7 +47,7 @@ STUB: sra REG1, 0, REG1; \ sra REG4, 0, REG4 SIGN1(sys32_exit, sparc_exit, %o0) -SIGN1(sys32_exit_group, sys_exit_group, %o0) +SIGN1(sys32_exit_group, sparc_exit_group, %o0) SIGN1(sys32_wait4, compat_sys_wait4, %o2) SIGN1(sys32_creat, sys_creat, %o1) SIGN1(sys32_mknod, sys_mknod, %o1) diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index 7f5f65d0b3fd..bf2347794e33 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -118,10 +118,20 @@ ret_from_syscall: ba,pt %xcc, ret_sys_call ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0 + .globl sparc_exit_group + .type sparc_exit_group,#function +sparc_exit_group: + sethi %hi(sys_exit_group), %g7 + ba,pt %xcc, 1f + or %g7, %lo(sys_exit_group), %g7 + .size sparc_exit_group,.-sparc_exit_group + .globl sparc_exit .type sparc_exit,#function sparc_exit: - rdpr %pstate, %g2 + sethi %hi(sys_exit), %g7 + or %g7, %lo(sys_exit), %g7 +1: rdpr %pstate, %g2 wrpr %g2, PSTATE_IE, %pstate rdpr %otherwin, %g1 rdpr %cansave, %g3 @@ -129,7 +139,7 @@ sparc_exit: wrpr %g3, 0x0, %cansave wrpr %g0, 0x0, %otherwin wrpr %g2, 0x0, %pstate - ba,pt %xcc, sys_exit + jmpl %g7, %g0 stb %g0, [%g6 + TI_WSAVED] .size sparc_exit,.-sparc_exit diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 1c9af9fa38e9..017b74a63dcb 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -133,7 +133,7 @@ sys_call_table: /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall - .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname + .word sys_setpgid, sys_fremovexattr, sys_tkill, sparc_exit_group, sys_newuname /*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall -- cgit v1.2.2 From 0032c857454581510de1ca12615de5e38e543c92 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 3 Dec 2012 11:24:25 -0800 Subject: sparc: Fix piggyback with newer binutils. Newer versions of binutils mark '_end' as 'B' instead of 'A' for whatever reason. To be honest, the piggyback code doesn't actually care what kind of symbol _start and _end are, it just wants to find them and record the address. So remove the type from the match strings. Reported-by: Aaro Koskinen Signed-off-by: David S. Miller --- arch/sparc/boot/piggyback.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sparc/boot/piggyback.c b/arch/sparc/boot/piggyback.c index c0a798fcf030..bb7c95161d71 100644 --- a/arch/sparc/boot/piggyback.c +++ b/arch/sparc/boot/piggyback.c @@ -81,18 +81,18 @@ static void usage(void) static int start_line(const char *line) { - if (strcmp(line + 8, " T _start\n") == 0) + if (strcmp(line + 10, " _start\n") == 0) return 1; - else if (strcmp(line + 16, " T _start\n") == 0) + else if (strcmp(line + 18, " _start\n") == 0) return 1; return 0; } static int end_line(const char *line) { - if (strcmp(line + 8, " A _end\n") == 0) + if (strcmp(line + 10, " _end\n") == 0) return 1; - else if (strcmp (line + 16, " A _end\n") == 0) + else if (strcmp (line + 18, " _end\n") == 0) return 1; return 0; } @@ -100,8 +100,8 @@ static int end_line(const char *line) /* * Find address for start and end in System.map. * The file looks like this: - * f0004000 T _start - * f0379f79 A _end + * f0004000 ... _start + * f0379f79 ... _end * 1234567890123456 * ^coloumn 1 * There is support for 64 bit addresses too. -- cgit v1.2.2 From ac53c4fca42c394d8a06c7a470ae2d1d50503717 Mon Sep 17 00:00:00 2001 From: David Daney Date: Mon, 3 Dec 2012 12:44:26 -0800 Subject: MIPS: Avoid mcheck by flushing page range in huge_ptep_set_access_flags() Problem: 1) Huge page mapping of anonymous memory is initially invalid. Will be faulted in by copy-on-write mechanism. 2) Userspace attempts store at the end of the huge mapping. 3) TLB Refill exception handler fill TLB with a normal (4K sized) invalid page at the end of the huge mapping virtual address range. 4) Userspace restarted, and re-attempts the store at the end of the huge mapping. 5) Page from #3 is invalid, we get a fault and go to the hugepage fault handler. This tries to map a huge page and calls huge_ptep_set_access_flags() to install the mapping. 6) We just call the generic ptep_set_access_flags() to set up the page tables, but the flush there assumes a normal (4K sized) page and only tries to flush the first part of the huge page virtual address out of the TLB, since the existing entry from step #3 doesn't conflict, nothing is flushed. 7) We attempt to load the mapping into the TLB, but because it conflicts with the entry from step #3, we get a Machine Check exception. The fix: Flush the entire rage covered by the huge page in huge_ptep_set_access_flags(), and remove the optimization in local_flush_tlb_range() so that the flush actually does the correct thing. Signed-off-by: David Daney Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: Hillf Danton Patchwork: https://patchwork.linux-mips.org/patch/4661/ Signed-off-by: Ralf Baechle (cherry picked from commit dd617f258cc39d36be26afee9912624a2d23112c) --- arch/mips/include/asm/hugetlb.h | 12 +++++++++++- arch/mips/mm/tlb-r4k.c | 18 ++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h index bd94946a18f3..ef99db994c2f 100644 --- a/arch/mips/include/asm/hugetlb.h +++ b/arch/mips/include/asm/hugetlb.h @@ -95,7 +95,17 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep, pte_t pte, int dirty) { - return ptep_set_access_flags(vma, addr, ptep, pte, dirty); + int changed = !pte_same(*ptep, pte); + + if (changed) { + set_pte_at(vma->vm_mm, addr, ptep, pte); + /* + * There could be some standard sized pages in there, + * get them all. + */ + flush_tlb_range(vma, addr, addr + HPAGE_SIZE); + } + return changed; } static inline pte_t huge_ptep_get(pte_t *ptep) diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 4b9b935a070e..88e79ad6f811 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -120,18 +120,11 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, if (cpu_context(cpu, mm) != 0) { unsigned long size, flags; - int huge = is_vm_hugetlb_page(vma); ENTER_CRITICAL(flags); - if (huge) { - start = round_down(start, HPAGE_SIZE); - end = round_up(end, HPAGE_SIZE); - size = (end - start) >> HPAGE_SHIFT; - } else { - start = round_down(start, PAGE_SIZE << 1); - end = round_up(end, PAGE_SIZE << 1); - size = (end - start) >> (PAGE_SHIFT + 1); - } + start = round_down(start, PAGE_SIZE << 1); + end = round_up(end, PAGE_SIZE << 1); + size = (end - start) >> (PAGE_SHIFT + 1); if (size <= current_cpu_data.tlbsize/2) { int oldpid = read_c0_entryhi(); int newpid = cpu_asid(cpu, mm); @@ -140,10 +133,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, int idx; write_c0_entryhi(start | newpid); - if (huge) - start += HPAGE_SIZE; - else - start += (PAGE_SIZE << 1); + start += (PAGE_SIZE << 1); mtc0_tlbw_hazard(); tlb_probe(); tlb_probe_hazard(); -- cgit v1.2.2 From d5563715a30706b54ad9ec978b30b81d3fb320f3 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 4 Dec 2012 17:40:44 +0100 Subject: MIPS: N32: Fix preadv(2) and pwritev(2) entry points. By using the native syscall entry point the kernel was also expecting 64-bit iovec structures. This is broken since ddd9e91b71072b8ebe89311c3a44b077defa1756 [preadv/ pwritev: MIPS: Add preadv(2) and pwritev(2) syscalls.] which originally added these two syscalls. I walked through piles of code, including libc and couldn't find anything that would have worked around the issue so this change the API to what it should always have been. Noticed and patch suggested by Al Viro. Signed-off-by: Ralf Baechle --- arch/mips/kernel/scall64-n32.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index f6ba8381ee01..ad8b657f867e 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -403,8 +403,8 @@ EXPORT(sysn32_call_table) PTR sys_dup3 /* 6290 */ PTR sys_pipe2 PTR sys_inotify_init1 - PTR sys_preadv - PTR sys_pwritev + PTR compat_sys_preadv + PTR compat_sys_pwritev PTR compat_sys_rt_tgsigqueueinfo /* 6295 */ PTR sys_perf_event_open PTR sys_accept4 -- cgit v1.2.2 From 97daa768010296d393196cbcd77549ce436a4a54 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 4 Dec 2012 18:50:48 +0100 Subject: MIPS: N32: Fix signalfd4 syscall entry point This needs to use the compat entry point or it's going to fail on big endian systems. Noticed by Al Viro. Signed-off-by: Ralf Baechle --- arch/mips/kernel/scall64-n32.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index ad8b657f867e..86ec03f0e00c 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -397,7 +397,7 @@ EXPORT(sysn32_call_table) PTR sys_timerfd_create PTR compat_sys_timerfd_gettime /* 6285 */ PTR compat_sys_timerfd_settime - PTR sys_signalfd4 + PTR compat_sys_signalfd4 PTR sys_eventfd2 PTR sys_epoll_create1 PTR sys_dup3 /* 6290 */ -- cgit v1.2.2 From 2d33976fb395a5b9cb00f2c24132b3f272eb9a9d Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 8 Jun 2012 07:10:27 +0100 Subject: MIPS: R3000/R3081: Fix CPU detection. Broken since e05ea74fc56f347f872ef9946d27c53e8bf20864 (lmo) rsp. cea7e2dfdef53fe55f359d00da562a268be06fd2 (kernel.org) [MIPS: Sort out CPU type to name translation.] These CPUs are no longer very popular to say the least ... Signed-off-by: Ralf Baechle Reported-by: Murphy McCauley --- arch/mips/kernel/cpu-probe.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index b1fb7af3c350..cce3782c96c9 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -510,7 +510,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) c->cputype = CPU_R3000A; __cpu_name[cpu] = "R3000A"; } - break; } else { c->cputype = CPU_R3000; __cpu_name[cpu] = "R3000"; -- cgit v1.2.2 From c90e6fbb220d44988cb65af3707367c57cdb65a8 Mon Sep 17 00:00:00 2001 From: Dmitry Adamushko Date: Thu, 5 Apr 2012 20:37:34 +0200 Subject: MIPS: Fix endless loop when processing signals for kernel tasks The problem occurs [1] when a kernel-mode task returns from a system call with a pending signal. A real-life scenario is a child of 'khelper' returning from a failed kernel_execve() in ____call_usermodehelper() [ kernel/kmod.c ]. kernel_execve() fails due to a pending SIGKILL, which is the result of "kill -9 -1" (at least, busybox's init does it upon reboot). The loop is as follows: * syscall_exit_work: - work_pending: // start_of_the_loop - work_notifysig: - do_notify_resume() - do_signal() - if (!user_mode(regs)) return; - resume_userspace // TIF_SIGPENDING is still set - work_pending // so we call work_pending => goto // start_of_the_loop More information can be found in another LKML thread: http://www.serverphorums.com/read.php?12,457826 [1] The problem was also reproduced on !CONFIG_VM86 x86, and the following fix was accepted. http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=29a2e2836ff9ea65a603c89df217f4198973a74f Signed-off-by: Dmitry Adamushko Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3571/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/entry.S | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index a6c133212003..9b00362f32f6 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S @@ -36,6 +36,11 @@ FEXPORT(ret_from_exception) FEXPORT(ret_from_irq) LONG_S s0, TI_REGS($28) FEXPORT(__ret_from_irq) +/* + * We can be coming here from a syscall done in the kernel space, + * e.g. a failed kernel_execve(). + */ +resume_userspace_check: LONG_L t0, PT_STATUS(sp) # returning to kernel mode? andi t0, t0, KU_USER beqz t0, resume_kernel @@ -162,7 +167,7 @@ work_notifysig: # deal with pending signals and move a0, sp li a1, 0 jal do_notify_resume # a2 already loaded - j resume_userspace + j resume_userspace_check FEXPORT(syscall_exit_partial) local_irq_disable # make sure need_resched doesn't -- cgit v1.2.2