From fb1b79d88b88370a8177aefcd446b1b3d323e4c8 Mon Sep 17 00:00:00 2001 From: Chengguang Xu Date: Sun, 5 May 2019 22:26:06 +0800 Subject: xtensa: fix incorrect fd close in error case of simdisk_setup() dev->fd is opened in attach operation, so should not close dev->fd in error case of simdisk_setup(). Signed-off-by: Chengguang Xu Message-Id: <1557066367-4783-1-git-send-email-cgxu519@gmail.com> Signed-off-by: Max Filippov --- arch/xtensa/platforms/iss/simdisk.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c index 026211e7ab09..5fac8b781453 100644 --- a/arch/xtensa/platforms/iss/simdisk.c +++ b/arch/xtensa/platforms/iss/simdisk.c @@ -297,7 +297,6 @@ out_alloc_disk: blk_cleanup_queue(dev->queue); dev->queue = NULL; out_alloc_queue: - simc_close(dev->fd); return -EIO; } -- cgit v1.2.3 From fd58015ca9fed04fd52009e2dbcb7aef6940f734 Mon Sep 17 00:00:00 2001 From: Chengguang Xu Date: Sun, 5 May 2019 22:26:07 +0800 Subject: xtensa: set proper error code for simdisk_setup() Change error code to -ENOMEM from -EIO because the error is related to memory allocating. Signed-off-by: Chengguang Xu Message-Id: <1557066367-4783-2-git-send-email-cgxu519@gmail.com> Signed-off-by: Max Filippov --- arch/xtensa/platforms/iss/simdisk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c index 5fac8b781453..f9cd45860bee 100644 --- a/arch/xtensa/platforms/iss/simdisk.c +++ b/arch/xtensa/platforms/iss/simdisk.c @@ -297,7 +297,7 @@ out_alloc_disk: blk_cleanup_queue(dev->queue); dev->queue = NULL; out_alloc_queue: - return -EIO; + return -ENOMEM; } static int __init simdisk_init(void) -- cgit v1.2.3 From 8e65986dcae8c49501c1920064dc192e704248bb Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 6 May 2019 13:07:26 -0700 Subject: xtensa: drop ifdef __KERNEL__ from kernel-only headers These headers are not exported to userspace, so they're never used without __KERNEL__ defined. Drop these ifdef statements. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/atomic.h | 4 ---- arch/xtensa/include/asm/bitops.h | 4 ---- arch/xtensa/include/asm/futex.h | 3 --- arch/xtensa/include/asm/io.h | 3 --- arch/xtensa/include/asm/pci-bridge.h | 3 --- arch/xtensa/include/asm/pci.h | 4 ---- arch/xtensa/include/asm/pgalloc.h | 3 --- 7 files changed, 24 deletions(-) diff --git a/arch/xtensa/include/asm/atomic.h b/arch/xtensa/include/asm/atomic.h index 7de0149e1cf7..4e7311f58ae8 100644 --- a/arch/xtensa/include/asm/atomic.h +++ b/arch/xtensa/include/asm/atomic.h @@ -15,8 +15,6 @@ #include #include - -#ifdef __KERNEL__ #include #include #include @@ -200,6 +198,4 @@ ATOMIC_OPS(xor) #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) -#endif /* __KERNEL__ */ - #endif /* _XTENSA_ATOMIC_H */ diff --git a/arch/xtensa/include/asm/bitops.h b/arch/xtensa/include/asm/bitops.h index d3490189792b..345d28aead65 100644 --- a/arch/xtensa/include/asm/bitops.h +++ b/arch/xtensa/include/asm/bitops.h @@ -13,8 +13,6 @@ #ifndef _XTENSA_BITOPS_H #define _XTENSA_BITOPS_H -#ifdef __KERNEL__ - #ifndef _LINUX_BITOPS_H #error only can be included directly #endif @@ -232,6 +230,4 @@ test_and_change_bit(unsigned int bit, volatile unsigned long *p) #include #include -#endif /* __KERNEL__ */ - #endif /* _XTENSA_BITOPS_H */ diff --git a/arch/xtensa/include/asm/futex.h b/arch/xtensa/include/asm/futex.h index 505d09eff184..0fd58b7521aa 100644 --- a/arch/xtensa/include/asm/futex.h +++ b/arch/xtensa/include/asm/futex.h @@ -15,8 +15,6 @@ #ifndef _ASM_XTENSA_FUTEX_H #define _ASM_XTENSA_FUTEX_H -#ifdef __KERNEL__ - #include #include #include @@ -123,5 +121,4 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return ret; } -#endif /* __KERNEL__ */ #endif /* _ASM_XTENSA_FUTEX_H */ diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h index acc5bb2cf1c7..da3e783f896b 100644 --- a/arch/xtensa/include/asm/io.h +++ b/arch/xtensa/include/asm/io.h @@ -11,7 +11,6 @@ #ifndef _XTENSA_IO_H #define _XTENSA_IO_H -#ifdef __KERNEL__ #include #include #include @@ -78,8 +77,6 @@ static inline void iounmap(volatile void __iomem *addr) #endif /* CONFIG_MMU */ -#endif /* __KERNEL__ */ - #include #endif /* _XTENSA_IO_H */ diff --git a/arch/xtensa/include/asm/pci-bridge.h b/arch/xtensa/include/asm/pci-bridge.h index 0b68c76ec1e6..405526912d9a 100644 --- a/arch/xtensa/include/asm/pci-bridge.h +++ b/arch/xtensa/include/asm/pci-bridge.h @@ -11,8 +11,6 @@ #ifndef _XTENSA_PCI_BRIDGE_H #define _XTENSA_PCI_BRIDGE_H -#ifdef __KERNEL__ - struct device_node; struct pci_controller; @@ -84,5 +82,4 @@ int early_write_config_byte(struct pci_controller*, int, int, int, u8); int early_write_config_word(struct pci_controller*, int, int, int, u16); int early_write_config_dword(struct pci_controller*, int, int, int, u32); -#endif /* __KERNEL__ */ #endif /* _XTENSA_PCI_BRIDGE_H */ diff --git a/arch/xtensa/include/asm/pci.h b/arch/xtensa/include/asm/pci.h index 883024054b05..8e2b48a268db 100644 --- a/arch/xtensa/include/asm/pci.h +++ b/arch/xtensa/include/asm/pci.h @@ -11,8 +11,6 @@ #ifndef _XTENSA_PCI_H #define _XTENSA_PCI_H -#ifdef __KERNEL__ - /* Can be used to override the logic in pci_scan_bus for skipping * already-configured bus numbers - to be used for buggy BIOSes * or architectures with incomplete PCI setup by the loader @@ -45,8 +43,6 @@ #define ARCH_GENERIC_PCI_MMAP_RESOURCE 1 #define arch_can_pci_mmap_io() 1 -#endif /* __KERNEL__ */ - /* Generic PCI */ #include diff --git a/arch/xtensa/include/asm/pgalloc.h b/arch/xtensa/include/asm/pgalloc.h index b3b388ff2f01..368284c972e7 100644 --- a/arch/xtensa/include/asm/pgalloc.h +++ b/arch/xtensa/include/asm/pgalloc.h @@ -11,8 +11,6 @@ #ifndef _XTENSA_PGALLOC_H #define _XTENSA_PGALLOC_H -#ifdef __KERNEL__ - #include #include @@ -79,5 +77,4 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte) } #define pmd_pgtable(pmd) pmd_page(pmd) -#endif /* __KERNEL__ */ #endif /* _XTENSA_PGALLOC_H */ -- cgit v1.2.3 From 8f8d5745bb520c76b81abef4a2cb3023d0313bfd Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 1 Jan 2019 19:41:55 -0800 Subject: xtensa: replace variant/core.h with asm/core.h Introduce the header arch/xtensa/include/asm/core.h that provides definitions for XCHAL macros missing in older xtensa releases. Use this header instead of variant/core.h Signed-off-by: Max Filippov --- arch/xtensa/boot/boot-redboot/bootstrap.S | 2 +- arch/xtensa/include/asm/asmmacro.h | 2 +- arch/xtensa/include/asm/cache.h | 2 +- arch/xtensa/include/asm/checksum.h | 2 +- arch/xtensa/include/asm/coprocessor.h | 2 +- arch/xtensa/include/asm/core.h | 13 +++++++++++++ arch/xtensa/include/asm/initialize_mmu.h | 4 ---- arch/xtensa/include/asm/irq.h | 2 +- arch/xtensa/include/asm/processor.h | 2 +- arch/xtensa/include/asm/ptrace.h | 2 +- arch/xtensa/include/asm/vectors.h | 2 +- arch/xtensa/kernel/hw_breakpoint.c | 2 +- arch/xtensa/kernel/vmlinux.lds.S | 2 +- arch/xtensa/lib/checksum.S | 2 +- arch/xtensa/lib/memcopy.S | 2 +- arch/xtensa/lib/memset.S | 2 +- arch/xtensa/lib/strncpy_user.S | 2 +- arch/xtensa/lib/strnlen_user.S | 2 +- arch/xtensa/lib/usercopy.S | 2 +- arch/xtensa/platforms/xt2000/include/platform/hardware.h | 2 +- arch/xtensa/platforms/xt2000/include/platform/serial.h | 2 +- 21 files changed, 32 insertions(+), 23 deletions(-) create mode 100644 arch/xtensa/include/asm/core.h diff --git a/arch/xtensa/boot/boot-redboot/bootstrap.S b/arch/xtensa/boot/boot-redboot/bootstrap.S index bbf3b4b080cd..48ba5a232d94 100644 --- a/arch/xtensa/boot/boot-redboot/bootstrap.S +++ b/arch/xtensa/boot/boot-redboot/bootstrap.S @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#include +#include #include #include #include diff --git a/arch/xtensa/include/asm/asmmacro.h b/arch/xtensa/include/asm/asmmacro.h index 7f2ae5872151..8308a9c3abb2 100644 --- a/arch/xtensa/include/asm/asmmacro.h +++ b/arch/xtensa/include/asm/asmmacro.h @@ -11,7 +11,7 @@ #ifndef _XTENSA_ASMMACRO_H #define _XTENSA_ASMMACRO_H -#include +#include /* * Some little helpers for loops. Use zero-overhead-loops diff --git a/arch/xtensa/include/asm/cache.h b/arch/xtensa/include/asm/cache.h index d2fd932fdb4d..b21fd133ff62 100644 --- a/arch/xtensa/include/asm/cache.h +++ b/arch/xtensa/include/asm/cache.h @@ -11,7 +11,7 @@ #ifndef _XTENSA_CACHE_H #define _XTENSA_CACHE_H -#include +#include #define L1_CACHE_SHIFT XCHAL_DCACHE_LINEWIDTH #define L1_CACHE_BYTES XCHAL_DCACHE_LINESIZE diff --git a/arch/xtensa/include/asm/checksum.h b/arch/xtensa/include/asm/checksum.h index f302ef57973a..8b687176ad72 100644 --- a/arch/xtensa/include/asm/checksum.h +++ b/arch/xtensa/include/asm/checksum.h @@ -13,7 +13,7 @@ #include #include -#include +#include /* * computes the checksum of a memory block at buff, length len, diff --git a/arch/xtensa/include/asm/coprocessor.h b/arch/xtensa/include/asm/coprocessor.h index 6712929a27c9..0fbe2a740b8d 100644 --- a/arch/xtensa/include/asm/coprocessor.h +++ b/arch/xtensa/include/asm/coprocessor.h @@ -12,8 +12,8 @@ #ifndef _XTENSA_COPROCESSOR_H #define _XTENSA_COPROCESSOR_H -#include #include +#include #include #ifdef __ASSEMBLY__ diff --git a/arch/xtensa/include/asm/core.h b/arch/xtensa/include/asm/core.h new file mode 100644 index 000000000000..b1f57519df49 --- /dev/null +++ b/arch/xtensa/include/asm/core.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2019 Cadence Design Systems Inc. */ + +#ifndef _ASM_XTENSA_CORE_H +#define _ASM_XTENSA_CORE_H + +#include + +#ifndef XCHAL_SPANNING_WAY +#define XCHAL_SPANNING_WAY 0 +#endif + +#endif diff --git a/arch/xtensa/include/asm/initialize_mmu.h b/arch/xtensa/include/asm/initialize_mmu.h index 10e9852b2fb4..d719785e54f7 100644 --- a/arch/xtensa/include/asm/initialize_mmu.h +++ b/arch/xtensa/include/asm/initialize_mmu.h @@ -33,10 +33,6 @@ #define CA_WRITEBACK (0x4) #endif -#ifndef XCHAL_SPANNING_WAY -#define XCHAL_SPANNING_WAY 0 -#endif - #ifdef __ASSEMBLY__ #define XTENSA_HWVERSION_RC_2009_0 230000 diff --git a/arch/xtensa/include/asm/irq.h b/arch/xtensa/include/asm/irq.h index 6c6ed23e0c79..0f71a51dab25 100644 --- a/arch/xtensa/include/asm/irq.h +++ b/arch/xtensa/include/asm/irq.h @@ -12,7 +12,7 @@ #define _XTENSA_IRQ_H #include -#include +#include #ifdef CONFIG_PLATFORM_NR_IRQS # define PLATFORM_NR_IRQS CONFIG_PLATFORM_NR_IRQS diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index 0c14018d1c26..19f6b54e358b 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h @@ -10,7 +10,7 @@ #ifndef _XTENSA_PROCESSOR_H #define _XTENSA_PROCESSOR_H -#include +#include #include #include diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h index 62a58d2567e9..b109416dc07e 100644 --- a/arch/xtensa/include/asm/ptrace.h +++ b/arch/xtensa/include/asm/ptrace.h @@ -80,7 +80,7 @@ struct pt_regs { unsigned long areg[16]; }; -#include +#include # define arch_has_single_step() (1) # define task_pt_regs(tsk) ((struct pt_regs*) \ diff --git a/arch/xtensa/include/asm/vectors.h b/arch/xtensa/include/asm/vectors.h index 7111280c8842..79fe3007919e 100644 --- a/arch/xtensa/include/asm/vectors.h +++ b/arch/xtensa/include/asm/vectors.h @@ -18,7 +18,7 @@ #ifndef _XTENSA_VECTORS_H #define _XTENSA_VECTORS_H -#include +#include #include #if XCHAL_HAVE_PTP_MMU diff --git a/arch/xtensa/kernel/hw_breakpoint.c b/arch/xtensa/kernel/hw_breakpoint.c index 4f20416061fb..285fb2942b06 100644 --- a/arch/xtensa/kernel/hw_breakpoint.c +++ b/arch/xtensa/kernel/hw_breakpoint.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include /* Breakpoint currently in use for each IBREAKA. */ static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[XCHAL_NUM_IBREAK]); diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index b80a430453b1..943f10639a93 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -18,8 +18,8 @@ #include #include +#include #include -#include OUTPUT_ARCH(xtensa) ENTRY(_start) diff --git a/arch/xtensa/lib/checksum.S b/arch/xtensa/lib/checksum.S index 528fe0dd9339..d82c20c1fb7a 100644 --- a/arch/xtensa/lib/checksum.S +++ b/arch/xtensa/lib/checksum.S @@ -16,8 +16,8 @@ #include #include -#include #include +#include /* * computes a partial checksum, e.g. for TCP/UDP fragments diff --git a/arch/xtensa/lib/memcopy.S b/arch/xtensa/lib/memcopy.S index c0f6981719d6..efecfd7ed8cc 100644 --- a/arch/xtensa/lib/memcopy.S +++ b/arch/xtensa/lib/memcopy.S @@ -10,8 +10,8 @@ */ #include -#include #include +#include /* * void *memcpy(void *dst, const void *src, size_t len); diff --git a/arch/xtensa/lib/memset.S b/arch/xtensa/lib/memset.S index 276747dec300..8632eacbdc80 100644 --- a/arch/xtensa/lib/memset.S +++ b/arch/xtensa/lib/memset.S @@ -12,8 +12,8 @@ */ #include -#include #include +#include /* * void *memset(void *dst, int c, size_t length) diff --git a/arch/xtensa/lib/strncpy_user.S b/arch/xtensa/lib/strncpy_user.S index 5fce16b67dca..c4c6c8578d59 100644 --- a/arch/xtensa/lib/strncpy_user.S +++ b/arch/xtensa/lib/strncpy_user.S @@ -13,8 +13,8 @@ #include #include -#include #include +#include /* * char *__strncpy_user(char *dst, const char *src, size_t len) diff --git a/arch/xtensa/lib/strnlen_user.S b/arch/xtensa/lib/strnlen_user.S index 0b956ce7f386..1f2ca2bb2ab3 100644 --- a/arch/xtensa/lib/strnlen_user.S +++ b/arch/xtensa/lib/strnlen_user.S @@ -12,8 +12,8 @@ */ #include -#include #include +#include /* * size_t __strnlen_user(const char *s, size_t len) diff --git a/arch/xtensa/lib/usercopy.S b/arch/xtensa/lib/usercopy.S index 64ab1971324f..228607e30bc2 100644 --- a/arch/xtensa/lib/usercopy.S +++ b/arch/xtensa/lib/usercopy.S @@ -54,8 +54,8 @@ */ #include -#include #include +#include .text ENTRY(__xtensa_copy_user) diff --git a/arch/xtensa/platforms/xt2000/include/platform/hardware.h b/arch/xtensa/platforms/xt2000/include/platform/hardware.h index 8e5e0d6a81ec..9f213f573330 100644 --- a/arch/xtensa/platforms/xt2000/include/platform/hardware.h +++ b/arch/xtensa/platforms/xt2000/include/platform/hardware.h @@ -15,7 +15,7 @@ #ifndef _XTENSA_XT2000_HARDWARE_H #define _XTENSA_XT2000_HARDWARE_H -#include +#include /* * On-board components. diff --git a/arch/xtensa/platforms/xt2000/include/platform/serial.h b/arch/xtensa/platforms/xt2000/include/platform/serial.h index 7226cf732b47..cde804827626 100644 --- a/arch/xtensa/platforms/xt2000/include/platform/serial.h +++ b/arch/xtensa/platforms/xt2000/include/platform/serial.h @@ -11,7 +11,7 @@ #ifndef _XTENSA_XT2000_SERIAL_H #define _XTENSA_XT2000_SERIAL_H -#include +#include #include /* National-Semi PC16552D DUART: */ -- cgit v1.2.3 From d065fcf12c21348cbc125460f75332f467518fb1 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 6 May 2019 12:02:26 -0700 Subject: xtensa: clean up inline assembly in futex.h Replace numeric inline assembly parameters with named parameters. Drop unused parameters from the futex_atomic_cmpxchg_inatomic. Use new temporary variable to hold target address in the fixup code in futex_atomic_cmpxchg_inatomic. Conditionalize function bodies so that only 'return -ENOSYS' is left in configurations without futex support. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/futex.h | 80 +++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/arch/xtensa/include/asm/futex.h b/arch/xtensa/include/asm/futex.h index 0fd58b7521aa..a67f801aa303 100644 --- a/arch/xtensa/include/asm/futex.h +++ b/arch/xtensa/include/asm/futex.h @@ -19,59 +19,58 @@ #include #include -#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ +#define __futex_atomic_op(insn, ret, old, uaddr, arg) \ __asm__ __volatile( \ - "1: l32i %0, %2, 0\n" \ + "1: l32i %[oldval], %[addr], 0\n" \ insn "\n" \ - " wsr %0, scompare1\n" \ - "2: s32c1i %1, %2, 0\n" \ - " bne %1, %0, 1b\n" \ - " movi %1, 0\n" \ + " wsr %[oldval], scompare1\n" \ + "2: s32c1i %[newval], %[addr], 0\n" \ + " bne %[newval], %[oldval], 1b\n" \ + " movi %[newval], 0\n" \ "3:\n" \ " .section .fixup,\"ax\"\n" \ " .align 4\n" \ " .literal_position\n" \ - "5: movi %0, 3b\n" \ - " movi %1, %3\n" \ - " jx %0\n" \ + "5: movi %[oldval], 3b\n" \ + " movi %[newval], %[fault]\n" \ + " jx %[oldval]\n" \ " .previous\n" \ " .section __ex_table,\"a\"\n" \ - " .long 1b,5b,2b,5b\n" \ + " .long 1b, 5b, 2b, 5b\n" \ " .previous\n" \ - : "=&r" (oldval), "=&r" (ret) \ - : "r" (uaddr), "I" (-EFAULT), "r" (oparg) \ + : [oldval] "=&r" (old), [newval] "=&r" (ret) \ + : [addr] "r" (uaddr), [oparg] "r" (arg), \ + [fault] "I" (-EFAULT) \ : "memory") static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { +#if XCHAL_HAVE_S32C1I int oldval = 0, ret; -#if !XCHAL_HAVE_S32C1I - return -ENOSYS; -#endif - pagefault_disable(); switch (op) { case FUTEX_OP_SET: - __futex_atomic_op("mov %1, %4", ret, oldval, uaddr, oparg); + __futex_atomic_op("mov %[newval], %[oparg]", + ret, oldval, uaddr, oparg); break; case FUTEX_OP_ADD: - __futex_atomic_op("add %1, %0, %4", ret, oldval, uaddr, - oparg); + __futex_atomic_op("add %[newval], %[oldval], %[oparg]", + ret, oldval, uaddr, oparg); break; case FUTEX_OP_OR: - __futex_atomic_op("or %1, %0, %4", ret, oldval, uaddr, - oparg); + __futex_atomic_op("or %[newval], %[oldval], %[oparg]", + ret, oldval, uaddr, oparg); break; case FUTEX_OP_ANDN: - __futex_atomic_op("and %1, %0, %4", ret, oldval, uaddr, - ~oparg); + __futex_atomic_op("and %[newval], %[oldval], %[oparg]", + ret, oldval, uaddr, ~oparg); break; case FUTEX_OP_XOR: - __futex_atomic_op("xor %1, %0, %4", ret, oldval, uaddr, - oparg); + __futex_atomic_op("xor %[newval], %[oldval], %[oparg]", + ret, oldval, uaddr, oparg); break; default: ret = -ENOSYS; @@ -83,42 +82,47 @@ static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, *oval = oldval; return ret; +#else + return -ENOSYS; +#endif } static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newval) { +#if XCHAL_HAVE_S32C1I + unsigned long tmp; int ret = 0; if (!access_ok(uaddr, sizeof(u32))) return -EFAULT; -#if !XCHAL_HAVE_S32C1I - return -ENOSYS; -#endif - __asm__ __volatile__ ( " # futex_atomic_cmpxchg_inatomic\n" - " wsr %5, scompare1\n" - "1: s32c1i %1, %4, 0\n" - " s32i %1, %6, 0\n" + " wsr %[oldval], scompare1\n" + "1: s32c1i %[newval], %[addr], 0\n" + " s32i %[newval], %[uval], 0\n" "2:\n" " .section .fixup,\"ax\"\n" " .align 4\n" " .literal_position\n" - "4: movi %1, 2b\n" - " movi %0, %7\n" - " jx %1\n" + "4: movi %[tmp], 2b\n" + " movi %[ret], %[fault]\n" + " jx %[tmp]\n" " .previous\n" " .section __ex_table,\"a\"\n" - " .long 1b,4b\n" + " .long 1b, 4b\n" " .previous\n" - : "+r" (ret), "+r" (newval), "+m" (*uaddr), "+m" (*uval) - : "r" (uaddr), "r" (oldval), "r" (uval), "I" (-EFAULT) + : [ret] "+r" (ret), [newval] "+r" (newval), [tmp] "=&r" (tmp) + : [addr] "r" (uaddr), [oldval] "r" (oldval), [uval] "r" (uval), + [fault] "I" (-EFAULT) : "memory"); return ret; +#else + return -ENOSYS; +#endif } #endif /* _ASM_XTENSA_FUTEX_H */ -- cgit v1.2.3 From f7c34874f04a80d6c39a32f08da2529e59602d3c Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 20 Dec 2018 17:18:12 -0800 Subject: xtensa: add exclusive atomics support Implement atomic primitives using exclusive access opcodes available in the recent xtensa cores. Since l32ex/s32ex don't have any memory ordering guarantees don't define __smp_mb__before_atomic/__smp_mb__after_atomic to make them use memw. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/atomic.h | 62 ++++++++++++++++++- arch/xtensa/include/asm/barrier.h | 4 ++ arch/xtensa/include/asm/bitops.h | 121 +++++++++++++++++++++++++++++++++++++- arch/xtensa/include/asm/cmpxchg.h | 36 +++++++++++- arch/xtensa/include/asm/core.h | 4 ++ arch/xtensa/include/asm/futex.h | 43 +++++++++++++- arch/xtensa/kernel/setup.c | 3 + 7 files changed, 267 insertions(+), 6 deletions(-) diff --git a/arch/xtensa/include/asm/atomic.h b/arch/xtensa/include/asm/atomic.h index 4e7311f58ae8..7b00d26f472e 100644 --- a/arch/xtensa/include/asm/atomic.h +++ b/arch/xtensa/include/asm/atomic.h @@ -56,7 +56,67 @@ */ #define atomic_set(v,i) WRITE_ONCE((v)->counter, (i)) -#if XCHAL_HAVE_S32C1I +#if XCHAL_HAVE_EXCLUSIVE +#define ATOMIC_OP(op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + unsigned long tmp; \ + int result; \ + \ + __asm__ __volatile__( \ + "1: l32ex %1, %3\n" \ + " " #op " %0, %1, %2\n" \ + " s32ex %0, %3\n" \ + " getex %0\n" \ + " beqz %0, 1b\n" \ + : "=&a" (result), "=&a" (tmp) \ + : "a" (i), "a" (v) \ + : "memory" \ + ); \ +} \ + +#define ATOMIC_OP_RETURN(op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + unsigned long tmp; \ + int result; \ + \ + __asm__ __volatile__( \ + "1: l32ex %1, %3\n" \ + " " #op " %0, %1, %2\n" \ + " s32ex %0, %3\n" \ + " getex %0\n" \ + " beqz %0, 1b\n" \ + " " #op " %0, %1, %2\n" \ + : "=&a" (result), "=&a" (tmp) \ + : "a" (i), "a" (v) \ + : "memory" \ + ); \ + \ + return result; \ +} + +#define ATOMIC_FETCH_OP(op) \ +static inline int atomic_fetch_##op(int i, atomic_t *v) \ +{ \ + unsigned long tmp; \ + int result; \ + \ + __asm__ __volatile__( \ + "1: l32ex %1, %3\n" \ + " " #op " %0, %1, %2\n" \ + " s32ex %0, %3\n" \ + " getex %0\n" \ + " beqz %0, 1b\n" \ + : "=&a" (result), "=&a" (tmp) \ + : "a" (i), "a" (v) \ + : "memory" \ + ); \ + \ + return tmp; \ +} + +#elif XCHAL_HAVE_S32C1I #define ATOMIC_OP(op) \ static inline void atomic_##op(int i, atomic_t * v) \ { \ diff --git a/arch/xtensa/include/asm/barrier.h b/arch/xtensa/include/asm/barrier.h index 956596e4d437..d6f8d4ddc2bc 100644 --- a/arch/xtensa/include/asm/barrier.h +++ b/arch/xtensa/include/asm/barrier.h @@ -9,12 +9,16 @@ #ifndef _XTENSA_SYSTEM_H #define _XTENSA_SYSTEM_H +#include + #define mb() ({ __asm__ __volatile__("memw" : : : "memory"); }) #define rmb() barrier() #define wmb() mb() +#if XCHAL_HAVE_S32C1I #define __smp_mb__before_atomic() barrier() #define __smp_mb__after_atomic() barrier() +#endif #include diff --git a/arch/xtensa/include/asm/bitops.h b/arch/xtensa/include/asm/bitops.h index 345d28aead65..aeb15f4c755b 100644 --- a/arch/xtensa/include/asm/bitops.h +++ b/arch/xtensa/include/asm/bitops.h @@ -96,7 +96,126 @@ static inline unsigned long __fls(unsigned long word) #include -#if XCHAL_HAVE_S32C1I +#if XCHAL_HAVE_EXCLUSIVE + +static inline void set_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long tmp; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + __asm__ __volatile__( + "1: l32ex %0, %2\n" + " or %0, %0, %1\n" + " s32ex %0, %2\n" + " getex %0\n" + " beqz %0, 1b\n" + : "=&a" (tmp) + : "a" (mask), "a" (p) + : "memory"); +} + +static inline void clear_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long tmp; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + __asm__ __volatile__( + "1: l32ex %0, %2\n" + " and %0, %0, %1\n" + " s32ex %0, %2\n" + " getex %0\n" + " beqz %0, 1b\n" + : "=&a" (tmp) + : "a" (~mask), "a" (p) + : "memory"); +} + +static inline void change_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long tmp; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + __asm__ __volatile__( + "1: l32ex %0, %2\n" + " xor %0, %0, %1\n" + " s32ex %0, %2\n" + " getex %0\n" + " beqz %0, 1b\n" + : "=&a" (tmp) + : "a" (~mask), "a" (p) + : "memory"); +} + +static inline int +test_and_set_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long tmp, value; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + __asm__ __volatile__( + "1: l32ex %1, %3\n" + " or %0, %1, %2\n" + " s32ex %0, %3\n" + " getex %0\n" + " beqz %0, 1b\n" + : "=&a" (tmp), "=&a" (value) + : "a" (mask), "a" (p) + : "memory"); + + return value & mask; +} + +static inline int +test_and_clear_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long tmp, value; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + __asm__ __volatile__( + "1: l32ex %1, %3\n" + " and %0, %1, %2\n" + " s32ex %0, %3\n" + " getex %0\n" + " beqz %0, 1b\n" + : "=&a" (tmp), "=&a" (value) + : "a" (~mask), "a" (p) + : "memory"); + + return value & mask; +} + +static inline int +test_and_change_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long tmp, value; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + __asm__ __volatile__( + "1: l32ex %1, %3\n" + " xor %0, %1, %2\n" + " s32ex %0, %3\n" + " getex %0\n" + " beqz %0, 1b\n" + : "=&a" (tmp), "=&a" (value) + : "a" (mask), "a" (p) + : "memory"); + + return value & mask; +} + +#elif XCHAL_HAVE_S32C1I static inline void set_bit(unsigned int bit, volatile unsigned long *p) { diff --git a/arch/xtensa/include/asm/cmpxchg.h b/arch/xtensa/include/asm/cmpxchg.h index 22a10c715c1f..7ccc5cbf441b 100644 --- a/arch/xtensa/include/asm/cmpxchg.h +++ b/arch/xtensa/include/asm/cmpxchg.h @@ -23,7 +23,24 @@ static inline unsigned long __cmpxchg_u32(volatile int *p, int old, int new) { -#if XCHAL_HAVE_S32C1I +#if XCHAL_HAVE_EXCLUSIVE + unsigned long tmp, result; + + __asm__ __volatile__( + "1: l32ex %0, %3\n" + " bne %0, %4, 2f\n" + " mov %1, %2\n" + " s32ex %1, %3\n" + " getex %1\n" + " beqz %1, 1b\n" + "2:\n" + : "=&a" (result), "=&a" (tmp) + : "a" (new), "a" (p), "a" (old) + : "memory" + ); + + return result; +#elif XCHAL_HAVE_S32C1I __asm__ __volatile__( " wsr %2, scompare1\n" " s32c1i %0, %1, 0\n" @@ -108,7 +125,22 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, static inline unsigned long xchg_u32(volatile int * m, unsigned long val) { -#if XCHAL_HAVE_S32C1I +#if XCHAL_HAVE_EXCLUSIVE + unsigned long tmp, result; + + __asm__ __volatile__( + "1: l32ex %0, %3\n" + " mov %1, %2\n" + " s32ex %1, %3\n" + " getex %1\n" + " beqz %1, 1b\n" + : "=&a" (result), "=&a" (tmp) + : "a" (val), "a" (m) + : "memory" + ); + + return result; +#elif XCHAL_HAVE_S32C1I unsigned long tmp, result; __asm__ __volatile__( "1: l32i %1, %2, 0\n" diff --git a/arch/xtensa/include/asm/core.h b/arch/xtensa/include/asm/core.h index b1f57519df49..ee02e164b673 100644 --- a/arch/xtensa/include/asm/core.h +++ b/arch/xtensa/include/asm/core.h @@ -6,6 +6,10 @@ #include +#ifndef XCHAL_HAVE_EXCLUSIVE +#define XCHAL_HAVE_EXCLUSIVE 0 +#endif + #ifndef XCHAL_SPANNING_WAY #define XCHAL_SPANNING_WAY 0 #endif diff --git a/arch/xtensa/include/asm/futex.h b/arch/xtensa/include/asm/futex.h index a67f801aa303..9538b0f7953c 100644 --- a/arch/xtensa/include/asm/futex.h +++ b/arch/xtensa/include/asm/futex.h @@ -19,6 +19,31 @@ #include #include +#if XCHAL_HAVE_EXCLUSIVE +#define __futex_atomic_op(insn, ret, old, uaddr, arg) \ + __asm__ __volatile( \ + "1: l32ex %[oldval], %[addr]\n" \ + insn "\n" \ + "2: s32ex %[newval], %[addr]\n" \ + " getex %[newval]\n" \ + " beqz %[newval], 1b\n" \ + " movi %[newval], 0\n" \ + "3:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 4\n" \ + " .literal_position\n" \ + "5: movi %[oldval], 3b\n" \ + " movi %[newval], %[fault]\n" \ + " jx %[oldval]\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .long 1b, 5b, 2b, 5b\n" \ + " .previous\n" \ + : [oldval] "=&r" (old), [newval] "=&r" (ret) \ + : [addr] "r" (uaddr), [oparg] "r" (arg), \ + [fault] "I" (-EFAULT) \ + : "memory") +#elif XCHAL_HAVE_S32C1I #define __futex_atomic_op(insn, ret, old, uaddr, arg) \ __asm__ __volatile( \ "1: l32i %[oldval], %[addr], 0\n" \ @@ -42,11 +67,12 @@ : [addr] "r" (uaddr), [oparg] "r" (arg), \ [fault] "I" (-EFAULT) \ : "memory") +#endif static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { -#if XCHAL_HAVE_S32C1I +#if XCHAL_HAVE_S32C1I || XCHAL_HAVE_EXCLUSIVE int oldval = 0, ret; pagefault_disable(); @@ -91,7 +117,7 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newval) { -#if XCHAL_HAVE_S32C1I +#if XCHAL_HAVE_S32C1I || XCHAL_HAVE_EXCLUSIVE unsigned long tmp; int ret = 0; @@ -100,9 +126,19 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, __asm__ __volatile__ ( " # futex_atomic_cmpxchg_inatomic\n" +#if XCHAL_HAVE_EXCLUSIVE + "1: l32ex %[tmp], %[addr]\n" + " s32i %[tmp], %[uval], 0\n" + " bne %[tmp], %[oldval], 2f\n" + " mov %[tmp], %[newval]\n" + "3: s32ex %[tmp], %[addr]\n" + " getex %[tmp]\n" + " beqz %[tmp], 1b\n" +#elif XCHAL_HAVE_S32C1I " wsr %[oldval], scompare1\n" "1: s32c1i %[newval], %[addr], 0\n" " s32i %[newval], %[uval], 0\n" +#endif "2:\n" " .section .fixup,\"ax\"\n" " .align 4\n" @@ -113,6 +149,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, " .previous\n" " .section __ex_table,\"a\"\n" " .long 1b, 4b\n" +#if XCHAL_HAVE_EXCLUSIVE + " .long 3b, 4b\n" +#endif " .previous\n" : [ret] "+r" (ret), [newval] "+r" (newval), [tmp] "=&r" (tmp) : [addr] "r" (uaddr), [oldval] "r" (oldval), [uval] "r" (uval), diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 4ec6fbb696bf..c0ec24349421 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -650,6 +650,9 @@ c_show(struct seq_file *f, void *slot) #endif #if XCHAL_HAVE_S32C1I "s32c1i " +#endif +#if XCHAL_HAVE_EXCLUSIVE + "exclusive " #endif "\n"); -- cgit v1.2.3 From a5944195d00a359e28d6e093593609bcee37ed5e Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 6 May 2019 16:47:41 -0700 Subject: xtensa: implement initialize_cacheattr for MPU cores Use CONFIG_MEMMAP_CACHEATTR to initialize MPU as described in the Xtensa LSP RM document. Coalesce adjacent regions with the same cacheattr. Update Kconfig help text. Signed-off-by: Max Filippov --- arch/xtensa/Kconfig | 26 ++++++++++++++++++------ arch/xtensa/include/asm/core.h | 4 ++++ arch/xtensa/include/asm/initialize_mmu.h | 34 +++++++++++++++++++++++++++++++- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 4b9aafe766c5..f081751db229 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -256,12 +256,26 @@ config MEMMAP_CACHEATTR region: bits 0..3 -- for addresses 0x00000000..0x1fffffff, bits 4..7 -- for addresses 0x20000000..0x3fffffff, and so on. - Cache attribute values are specific for the MMU type, so e.g. - for region protection MMUs: 2 is cache bypass, 4 is WB cached, - 1 is WT cached, f is illegal. For ful MMU: bit 0 makes it executable, - bit 1 makes it writable, bits 2..3 meaning is 0: cache bypass, - 1: WB cache, 2: WT cache, 3: special (c and e are illegal, f is - reserved). + Cache attribute values are specific for the MMU type. + For region protection MMUs: + 1: WT cached, + 2: cache bypass, + 4: WB cached, + f: illegal. + For ful MMU: + bit 0: executable, + bit 1: writable, + bits 2..3: + 0: cache bypass, + 1: WB cache, + 2: WT cache, + 3: special (c and e are illegal, f is reserved). + For MPU: + 0: illegal, + 1: WB cache, + 2: WB, no-write-allocate cache, + 3: WT cache, + 4: cache bypass. config KSEG_PADDR hex "Physical address of the KSEG mapping" diff --git a/arch/xtensa/include/asm/core.h b/arch/xtensa/include/asm/core.h index ee02e164b673..5b4acb7d1c07 100644 --- a/arch/xtensa/include/asm/core.h +++ b/arch/xtensa/include/asm/core.h @@ -10,6 +10,10 @@ #define XCHAL_HAVE_EXCLUSIVE 0 #endif +#ifndef XCHAL_HAVE_MPU +#define XCHAL_HAVE_MPU 0 +#endif + #ifndef XCHAL_SPANNING_WAY #define XCHAL_SPANNING_WAY 0 #endif diff --git a/arch/xtensa/include/asm/initialize_mmu.h b/arch/xtensa/include/asm/initialize_mmu.h index d719785e54f7..323d05789159 100644 --- a/arch/xtensa/include/asm/initialize_mmu.h +++ b/arch/xtensa/include/asm/initialize_mmu.h @@ -177,11 +177,42 @@ .macro initialize_cacheattr -#if !defined(CONFIG_MMU) && XCHAL_HAVE_TLBS +#if !defined(CONFIG_MMU) && (XCHAL_HAVE_TLBS || XCHAL_HAVE_MPU) #if CONFIG_MEMMAP_CACHEATTR == 0x22222222 && XCHAL_HAVE_PTP_MMU #error Default MEMMAP_CACHEATTR of 0x22222222 does not work with full MMU. #endif +#if XCHAL_HAVE_MPU + .data + .align 4 +.Lattribute_table: + .long 0x000000, 0x1fff00, 0x1ddf00, 0x1eef00 + .long 0x006600, 0x000000, 0x000000, 0x000000 + .long 0x000000, 0x000000, 0x000000, 0x000000 + .long 0x000000, 0x000000, 0x000000, 0x000000 + .previous + + movi a3, .Lattribute_table + movi a4, CONFIG_MEMMAP_CACHEATTR + movi a5, 1 + movi a6, XCHAL_MPU_ENTRIES + movi a10, 0x20000000 + movi a11, -1 +1: + sub a5, a5, a10 + extui a8, a4, 28, 4 + beq a8, a11, 2f + addi a6, a6, -1 + mov a11, a8 +2: + addx4 a9, a8, a3 + l32i a9, a9, 0 + or a9, a9, a6 + wptlb a9, a5 + slli a4, a4, 4 + bgeu a5, a10, 1b + +#else movi a5, XCHAL_SPANNING_WAY movi a6, ~_PAGE_ATTRIB_MASK movi a4, CONFIG_MEMMAP_CACHEATTR @@ -203,6 +234,7 @@ bgeu a5, a8, 1b isync +#endif #endif .endm -- cgit v1.2.3