Commit 0707ad30 authored by Chris Metcalf's avatar Chris Metcalf

arch/tile: Miscellaneous cleanup changes.

This commit is primarily changes caused by reviewing "sparse"
and "checkpatch" output on our sources, so is somewhat noisy, since
things like "printk() -> pr_err()" (or whatever) throughout the
codebase tend to get tedious to read.  Rather than trying to tease
apart precisely which things changed due to which type of code
review, this commit includes various cleanups in the code:

- sparse: Add declarations in headers for globals.
- sparse: Fix __user annotations.
- sparse: Using gfp_t consistently instead of int.
- sparse: removing functions not actually used.
- checkpatch: Clean up printk() warnings by using pr_info(), etc.;
  also avoid partial-line printks except in bootup code.
  - checkpatch: Use exposed structs rather than typedefs.
  - checkpatch: Change some C99 comments to C89 comments.

In addition, a couple of minor other changes are rolled in
to this commit:

- Add support for a "raise" instruction to cause SIGFPE, etc., to be raised.
- Remove some compat code that is unnecessary when we fully eliminate
  some of the deprecated syscalls from the generic syscall ABI.
- Update the tile_defconfig to reflect current config contents.
Signed-off-by: default avatarChris Metcalf <cmetcalf@tilera.com>
Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
parent c78095bd
# #
# Automatically generated make config: don't edit # Automatically generated make config: don't edit
# Linux kernel version: 2.6.34 # Linux kernel version: 2.6.34
# Fri May 28 17:51:43 2010 # Thu Jun 3 13:20:05 2010
# #
CONFIG_MMU=y CONFIG_MMU=y
CONFIG_GENERIC_CSUM=y CONFIG_GENERIC_CSUM=y
...@@ -9,16 +9,13 @@ CONFIG_GENERIC_HARDIRQS=y ...@@ -9,16 +9,13 @@ CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_PENDING_IRQ=y CONFIG_GENERIC_PENDING_IRQ=y
CONFIG_ZONE_DMA=y
CONFIG_SEMAPHORE_SLEEPERS=y CONFIG_SEMAPHORE_SLEEPERS=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_HAVE_ARCH_ALLOC_REMAP=y CONFIG_HAVE_ARCH_ALLOC_REMAP=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_HUGETLBFS=y
CONFIG_GENERIC_TIME=y CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_DEFAULT_MIGRATION_COST=10000000 CONFIG_DEFAULT_MIGRATION_COST=10000000
CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
...@@ -32,7 +29,6 @@ CONFIG_STRICT_DEVMEM=y ...@@ -32,7 +29,6 @@ CONFIG_STRICT_DEVMEM=y
CONFIG_SMP=y CONFIG_SMP=y
CONFIG_WERROR=y CONFIG_WERROR=y
# CONFIG_DEBUG_COPY_FROM_USER is not set # CONFIG_DEBUG_COPY_FROM_USER is not set
CONFIG_SERIAL_CONSOLE=y
CONFIG_HVC_TILE=y CONFIG_HVC_TILE=y
CONFIG_TILE=y CONFIG_TILE=y
# CONFIG_TILEGX is not set # CONFIG_TILEGX is not set
...@@ -86,6 +82,7 @@ CONFIG_INITRAMFS_COMPRESSION_NONE=y ...@@ -86,6 +82,7 @@ CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set # CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set # CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
# CONFIG_INITRAMFS_COMPRESSION_LZO is not set # CONFIG_INITRAMFS_COMPRESSION_LZO is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y CONFIG_EMBEDDED=y
...@@ -220,7 +217,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y ...@@ -220,7 +217,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_MIGRATION=y CONFIG_MIGRATION=y
CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=1 CONFIG_ZONE_DMA_FLAG=0
CONFIG_BOUNCE=y CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y CONFIG_VIRT_TO_BUS=y
# CONFIG_KSM is not set # CONFIG_KSM is not set
...@@ -232,10 +229,11 @@ CONFIG_FEEDBACK_USE="" ...@@ -232,10 +229,11 @@ CONFIG_FEEDBACK_USE=""
CONFIG_VMALLOC_RESERVE=0x1000000 CONFIG_VMALLOC_RESERVE=0x1000000
CONFIG_HARDWALL=y CONFIG_HARDWALL=y
CONFIG_MEMPROF=y CONFIG_MEMPROF=y
CONFIG_XGBE_MAIN=y CONFIG_XGBE=y
CONFIG_NET_TILE=y CONFIG_NET_TILE=y
CONFIG_PSEUDO_NAPI=y CONFIG_PSEUDO_NAPI=y
CONFIG_TILEPCI_ENDP=y CONFIG_TILEPCI_ENDP=y
CONFIG_TILEPCI_HOST_SUBSET=m
CONFIG_TILE_IDE_GPIO=y CONFIG_TILE_IDE_GPIO=y
CONFIG_TILE_SOFTUART=y CONFIG_TILE_SOFTUART=y
...@@ -244,6 +242,8 @@ CONFIG_TILE_SOFTUART=y ...@@ -244,6 +242,8 @@ CONFIG_TILE_SOFTUART=y
# #
CONFIG_PCI=y CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y CONFIG_PCI_DOMAINS=y
# CONFIG_NO_IOMEM is not set
# CONFIG_NO_IOPORT is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_DEBUG=y CONFIG_PCI_DEBUG=y
# CONFIG_PCI_STUB is not set # CONFIG_PCI_STUB is not set
...@@ -742,6 +742,7 @@ CONFIG_HVC_DRIVER=y ...@@ -742,6 +742,7 @@ CONFIG_HVC_DRIVER=y
# #
# CONFIG_RAW_DRIVER is not set # CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set # CONFIG_TCG_TPM is not set
CONFIG_DEVPORT=y
CONFIG_I2C=y CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_COMPAT=y CONFIG_I2C_COMPAT=y
......
// Copyright 2010 Tilera Corporation. All Rights Reserved. /*
// * Copyright 2010 Tilera Corporation. All Rights Reserved.
// This program is free software; you can redistribute it and/or *
// modify it under the terms of the GNU General Public License * This program is free software; you can redistribute it and/or
// as published by the Free Software Foundation, version 2. * modify it under the terms of the GNU General Public License
// * as published by the Free Software Foundation, version 2.
// This program is distributed in the hope that it will be useful, but *
// WITHOUT ANY WARRANTY; without even the implied warranty of * This program is distributed in the hope that it will be useful, but
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or * WITHOUT ANY WARRANTY; without even the implied warranty of
// NON INFRINGEMENT. See the GNU General Public License for * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
// more details. * NON INFRINGEMENT. See the GNU General Public License for
* more details.
//! @file */
//!
//! ABI-related register definitions helpful when writing assembly code. /**
//! * @file
*
* ABI-related register definitions helpful when writing assembly code.
*/
#ifndef __ARCH_ABI_H__ #ifndef __ARCH_ABI_H__
#define __ARCH_ABI_H__ #define __ARCH_ABI_H__
#include <arch/chip.h> #include <arch/chip.h>
// Registers 0 - 55 are "normal", but some perform special roles. /* Registers 0 - 55 are "normal", but some perform special roles. */
#define TREG_FP 52 /**< Frame pointer. */ #define TREG_FP 52 /**< Frame pointer. */
#define TREG_TP 53 /**< Thread pointer. */ #define TREG_TP 53 /**< Thread pointer. */
...@@ -30,7 +33,7 @@ ...@@ -30,7 +33,7 @@
/** Index of last normal general-purpose register. */ /** Index of last normal general-purpose register. */
#define TREG_LAST_GPR 55 #define TREG_LAST_GPR 55
// Registers 56 - 62 are "special" network registers. /* Registers 56 - 62 are "special" network registers. */
#define TREG_SN 56 /**< Static network access. */ #define TREG_SN 56 /**< Static network access. */
#define TREG_IDN0 57 /**< IDN demux 0 access. */ #define TREG_IDN0 57 /**< IDN demux 0 access. */
...@@ -40,7 +43,7 @@ ...@@ -40,7 +43,7 @@
#define TREG_UDN2 61 /**< UDN demux 2 access. */ #define TREG_UDN2 61 /**< UDN demux 2 access. */
#define TREG_UDN3 62 /**< UDN demux 3 access. */ #define TREG_UDN3 62 /**< UDN demux 3 access. */
// Register 63 is the "special" zero register. /* Register 63 is the "special" zero register. */
#define TREG_ZERO 63 /**< "Zero" register; always reads as "0". */ #define TREG_ZERO 63 /**< "Zero" register; always reads as "0". */
...@@ -52,42 +55,44 @@ ...@@ -52,42 +55,44 @@
#define TREG_SYSCALL_NR_NAME r10 #define TREG_SYSCALL_NR_NAME r10
//! The ABI requires callers to allocate a caller state save area of /**
//! this many bytes at the bottom of each stack frame. * The ABI requires callers to allocate a caller state save area of
//! * this many bytes at the bottom of each stack frame.
*/
#ifdef __tile__ #ifdef __tile__
#define C_ABI_SAVE_AREA_SIZE (2 * __SIZEOF_POINTER__) #define C_ABI_SAVE_AREA_SIZE (2 * __SIZEOF_POINTER__)
#endif #endif
//! The operand to an 'info' opcode directing the backtracer to not /**
//! try to find the calling frame. * The operand to an 'info' opcode directing the backtracer to not
//! * try to find the calling frame.
*/
#define INFO_OP_CANNOT_BACKTRACE 2 #define INFO_OP_CANNOT_BACKTRACE 2
#ifndef __ASSEMBLER__ #ifndef __ASSEMBLER__
#if CHIP_WORD_SIZE() > 32 #if CHIP_WORD_SIZE() > 32
//! Unsigned type that can hold a register. /** Unsigned type that can hold a register. */
typedef unsigned long long uint_reg_t; typedef unsigned long long uint_reg_t;
//! Signed type that can hold a register. /** Signed type that can hold a register. */
typedef long long int_reg_t; typedef long long int_reg_t;
//! String prefix to use for printf(). /** String prefix to use for printf(). */
#define INT_REG_FMT "ll" #define INT_REG_FMT "ll"
#elif !defined(__LP64__) /* avoid confusion with LP64 cross-build tools */ #elif !defined(__LP64__) /* avoid confusion with LP64 cross-build tools */
//! Unsigned type that can hold a register. /** Unsigned type that can hold a register. */
typedef unsigned long uint_reg_t; typedef unsigned long uint_reg_t;
//! Signed type that can hold a register. /** Signed type that can hold a register. */
typedef long int_reg_t; typedef long int_reg_t;
//! String prefix to use for printf(). /** String prefix to use for printf(). */
#define INT_REG_FMT "l" #define INT_REG_FMT "l"
#endif #endif
#endif /* __ASSEMBLER__ */ #endif /* __ASSEMBLER__ */
#endif // !__ARCH_ABI_H__ #endif /* !__ARCH_ABI_H__ */
...@@ -301,4 +301,4 @@ ...@@ -301,4 +301,4 @@
INT_MASK(INT_DOUBLE_FAULT) | \ INT_MASK(INT_DOUBLE_FAULT) | \
INT_MASK(INT_AUX_PERF_COUNT) | \ INT_MASK(INT_AUX_PERF_COUNT) | \
0) 0)
#endif // !__ARCH_INTERRUPTS_H__ #endif /* !__ARCH_INTERRUPTS_H__ */
...@@ -348,6 +348,23 @@ void __init_atomic_per_cpu(void); ...@@ -348,6 +348,23 @@ void __init_atomic_per_cpu(void);
/* Support releasing the atomic lock in do_page_fault_ics(). */ /* Support releasing the atomic lock in do_page_fault_ics(). */
void __atomic_fault_unlock(int *lock_ptr); void __atomic_fault_unlock(int *lock_ptr);
#endif #endif
/* Private helper routines in lib/atomic_asm_32.S */
extern struct __get_user __atomic_cmpxchg(volatile int *p,
int *lock, int o, int n);
extern struct __get_user __atomic_xchg(volatile int *p, int *lock, int n);
extern struct __get_user __atomic_xchg_add(volatile int *p, int *lock, int n);
extern struct __get_user __atomic_xchg_add_unless(volatile int *p,
int *lock, int o, int n);
extern struct __get_user __atomic_or(volatile int *p, int *lock, int n);
extern struct __get_user __atomic_andn(volatile int *p, int *lock, int n);
extern struct __get_user __atomic_xor(volatile int *p, int *lock, int n);
extern u64 __atomic64_cmpxchg(volatile u64 *p, int *lock, u64 o, u64 n);
extern u64 __atomic64_xchg(volatile u64 *p, int *lock, u64 n);
extern u64 __atomic64_xchg_add(volatile u64 *p, int *lock, u64 n);
extern u64 __atomic64_xchg_add_unless(volatile u64 *p,
int *lock, u64 o, u64 n);
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#endif /* _ASM_TILE_ATOMIC_32_H */ #endif /* _ASM_TILE_ATOMIC_32_H */
...@@ -70,48 +70,7 @@ struct compat_timeval { ...@@ -70,48 +70,7 @@ struct compat_timeval {
s32 tv_usec; s32 tv_usec;
}; };
struct compat_stat { #define compat_stat stat
unsigned int st_dev;
unsigned int st_ino;
unsigned int st_mode;
unsigned int st_nlink;
unsigned int st_uid;
unsigned int st_gid;
unsigned int st_rdev;
unsigned int __pad1;
int st_size;
int st_blksize;
int __pad2;
int st_blocks;
int st_atime;
unsigned int st_atime_nsec;
int st_mtime;
unsigned int st_mtime_nsec;
int st_ctime;
unsigned int st_ctime_nsec;
unsigned int __unused[2];
};
struct compat_stat64 {
unsigned long st_dev;
unsigned long st_ino;
unsigned int st_mode;
unsigned int st_nlink;
unsigned int st_uid;
unsigned int st_gid;
unsigned long st_rdev;
long st_size;
unsigned int st_blksize;
unsigned long st_blocks __attribute__((packed));
unsigned int st_atime;
unsigned int st_atime_nsec;
unsigned int st_mtime;
unsigned int st_mtime_nsec;
unsigned int st_ctime;
unsigned int st_ctime_nsec;
unsigned int __unused8;
};
#define compat_statfs statfs #define compat_statfs statfs
struct compat_sysctl { struct compat_sysctl {
...@@ -233,7 +192,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) ...@@ -233,7 +192,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
/* Sign-extend when storing a kernel pointer to a user's ptregs. */ /* Sign-extend when storing a kernel pointer to a user's ptregs. */
static inline unsigned long ptr_to_compat_reg(void __user *uptr) static inline unsigned long ptr_to_compat_reg(void __user *uptr)
{ {
return (long)(int)(long)uptr; return (long)(int)(long __force)uptr;
} }
static inline void __user *compat_alloc_user_space(long len) static inline void __user *compat_alloc_user_space(long len)
...@@ -278,17 +237,8 @@ long compat_sys_sync_file_range2(int fd, unsigned int flags, ...@@ -278,17 +237,8 @@ long compat_sys_sync_file_range2(int fd, unsigned int flags,
long compat_sys_fallocate(int fd, int mode, long compat_sys_fallocate(int fd, int mode,
u32 offset_lo, u32 offset_hi, u32 offset_lo, u32 offset_hi,
u32 len_lo, u32 len_hi); u32 len_lo, u32 len_hi);
long compat_sys_stat64(char __user *filename,
struct compat_stat64 __user *statbuf);
long compat_sys_lstat64(char __user *filename,
struct compat_stat64 __user *statbuf);
long compat_sys_fstat64(unsigned int fd, struct compat_stat64 __user *statbuf);
long compat_sys_fstatat64(int dfd, char __user *filename,
struct compat_stat64 __user *statbuf, int flag);
long compat_sys_sched_rr_get_interval(compat_pid_t pid, long compat_sys_sched_rr_get_interval(compat_pid_t pid,
struct compat_timespec __user *interval); struct compat_timespec __user *interval);
ssize_t compat_sys_sendfile(int out_fd, int in_fd, compat_off_t __user *offset,
size_t count);
/* Versions of compat functions that differ from generic Linux. */ /* Versions of compat functions that differ from generic Linux. */
struct compat_msgbuf; struct compat_msgbuf;
...@@ -302,7 +252,6 @@ long tile_compat_sys_ptrace(compat_long_t request, compat_long_t pid, ...@@ -302,7 +252,6 @@ long tile_compat_sys_ptrace(compat_long_t request, compat_long_t pid,
compat_long_t addr, compat_long_t data); compat_long_t addr, compat_long_t data);
/* Tilera Linux syscalls that don't have "compat" versions. */ /* Tilera Linux syscalls that don't have "compat" versions. */
#define compat_sys_raise_fpe sys_raise_fpe
#define compat_sys_flush_cache sys_flush_cache #define compat_sys_flush_cache sys_flush_cache
#endif /* _ASM_TILE_COMPAT_H */ #endif /* _ASM_TILE_COMPAT_H */
...@@ -59,8 +59,7 @@ enum { ELF_ARCH = CHIP_ELF_TYPE() }; ...@@ -59,8 +59,7 @@ enum { ELF_ARCH = CHIP_ELF_TYPE() };
*/ */
#define elf_check_arch(x) \ #define elf_check_arch(x) \
((x)->e_ident[EI_CLASS] == ELF_CLASS && \ ((x)->e_ident[EI_CLASS] == ELF_CLASS && \
((x)->e_machine == CHIP_ELF_TYPE() || \ (x)->e_machine == CHIP_ELF_TYPE())
(x)->e_machine == CHIP_COMPAT_ELF_TYPE()))
/* The module loader only handles a few relocation types. */ /* The module loader only handles a few relocation types. */
#ifndef __tilegx__ #ifndef __tilegx__
...@@ -139,8 +138,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm, ...@@ -139,8 +138,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
*/ */
#define compat_elf_check_arch(x) \ #define compat_elf_check_arch(x) \
((x)->e_ident[EI_CLASS] == ELFCLASS32 && \ ((x)->e_ident[EI_CLASS] == ELFCLASS32 && \
((x)->e_machine == CHIP_ELF_TYPE() || \ (x)->e_machine == CHIP_ELF_TYPE())
(x)->e_machine == CHIP_COMPAT_ELF_TYPE()))
#define compat_start_thread(regs, ip, usp) do { \ #define compat_start_thread(regs, ip, usp) do { \
regs->pc = ptr_to_compat_reg((void *)(ip)); \ regs->pc = ptr_to_compat_reg((void *)(ip)); \
......
...@@ -29,14 +29,14 @@ ...@@ -29,14 +29,14 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/errno.h> #include <linux/errno.h>
extern struct __get_user futex_set(int *v, int i); extern struct __get_user futex_set(int __user *v, int i);
extern struct __get_user futex_add(int *v, int n); extern struct __get_user futex_add(int __user *v, int n);
extern struct __get_user futex_or(int *v, int n); extern struct __get_user futex_or(int __user *v, int n);
extern struct __get_user futex_andn(int *v, int n); extern struct __get_user futex_andn(int __user *v, int n);
extern struct __get_user futex_cmpxchg(int *v, int o, int n); extern struct __get_user futex_cmpxchg(int __user *v, int o, int n);
#ifndef __tilegx__ #ifndef __tilegx__
extern struct __get_user futex_xor(int *v, int n); extern struct __get_user futex_xor(int __user *v, int n);
#else #else
static inline struct __get_user futex_xor(int __user *uaddr, int n) static inline struct __get_user futex_xor(int __user *uaddr, int n)
{ {
...@@ -131,6 +131,11 @@ static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, ...@@ -131,6 +131,11 @@ static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
return asm_ret.err ? asm_ret.err : asm_ret.val; return asm_ret.err ? asm_ret.err : asm_ret.val;
} }
#ifndef __tilegx__
/* Return failure from the atomic wrappers. */
struct __get_user __atomic_bad_address(int __user *addr);
#endif
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#endif /* _ASM_TILE_FUTEX_H */ #endif /* _ASM_TILE_FUTEX_H */
...@@ -16,8 +16,6 @@ ...@@ -16,8 +16,6 @@
#define _ASM_TILE_PAGE_H #define _ASM_TILE_PAGE_H
#include <linux/const.h> #include <linux/const.h>
#include <hv/hypervisor.h>
#include <arch/chip.h>
/* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */ /* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */
#define PAGE_SHIFT 16 #define PAGE_SHIFT 16
...@@ -29,6 +27,11 @@ ...@@ -29,6 +27,11 @@
#define PAGE_MASK (~(PAGE_SIZE - 1)) #define PAGE_MASK (~(PAGE_SIZE - 1))
#define HPAGE_MASK (~(HPAGE_SIZE - 1)) #define HPAGE_MASK (~(HPAGE_SIZE - 1))
#ifdef __KERNEL__
#include <hv/hypervisor.h>
#include <arch/chip.h>
/* /*
* The {,H}PAGE_SHIFT values must match the HV_LOG2_PAGE_SIZE_xxx * The {,H}PAGE_SHIFT values must match the HV_LOG2_PAGE_SIZE_xxx
* definitions in <hv/hypervisor.h>. We validate this at build time * definitions in <hv/hypervisor.h>. We validate this at build time
...@@ -331,4 +334,6 @@ extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr); ...@@ -331,4 +334,6 @@ extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
#include <asm-generic/memory_model.h> #include <asm-generic/memory_model.h>
#include <asm-generic/getorder.h> #include <asm-generic/getorder.h>
#endif /* __KERNEL__ */
#endif /* _ASM_TILE_PAGE_H */ #endif /* _ASM_TILE_PAGE_H */
...@@ -229,9 +229,9 @@ static inline void __pte_clear(pte_t *ptep) ...@@ -229,9 +229,9 @@ static inline void __pte_clear(pte_t *ptep)
#define pte_donemigrate(x) hv_pte_set_present(hv_pte_clear_migrating(x)) #define pte_donemigrate(x) hv_pte_set_present(hv_pte_clear_migrating(x))
#define pte_ERROR(e) \ #define pte_ERROR(e) \
printk("%s:%d: bad pte 0x%016llx.\n", __FILE__, __LINE__, pte_val(e)) pr_err("%s:%d: bad pte 0x%016llx.\n", __FILE__, __LINE__, pte_val(e))
#define pgd_ERROR(e) \ #define pgd_ERROR(e) \
printk("%s:%d: bad pgd 0x%016llx.\n", __FILE__, __LINE__, pgd_val(e)) pr_err("%s:%d: bad pgd 0x%016llx.\n", __FILE__, __LINE__, pgd_val(e))
/* /*
* set_pte_order() sets the given PTE and also sanity-checks the * set_pte_order() sets the given PTE and also sanity-checks the
...@@ -470,6 +470,11 @@ static inline int pmd_huge_page(pmd_t pmd) ...@@ -470,6 +470,11 @@ static inline int pmd_huge_page(pmd_t pmd)
#include <asm-generic/pgtable.h> #include <asm-generic/pgtable.h>
/* Support /proc/NN/pgtable API. */
struct seq_file;
int arch_proc_pgtable_show(struct seq_file *m, struct mm_struct *mm,
unsigned long vaddr, pte_t *ptep, void **datap);
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#endif /* _ASM_TILE_PGTABLE_H */ #endif /* _ASM_TILE_PGTABLE_H */
...@@ -89,15 +89,27 @@ static inline int pgd_addr_invalid(unsigned long addr) ...@@ -89,15 +89,27 @@ static inline int pgd_addr_invalid(unsigned long addr)
/* /*
* Provide versions of these routines that can be used safely when * Provide versions of these routines that can be used safely when
* the hypervisor may be asynchronously modifying dirty/accessed bits. * the hypervisor may be asynchronously modifying dirty/accessed bits.
* ptep_get_and_clear() matches the generic one but we provide it to
* be parallel with the 64-bit code.
*/ */
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
#define __HAVE_ARCH_PTEP_SET_WRPROTECT #define __HAVE_ARCH_PTEP_SET_WRPROTECT
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
extern int ptep_test_and_clear_young(struct vm_area_struct *, extern int ptep_test_and_clear_young(struct vm_area_struct *,
unsigned long addr, pte_t *); unsigned long addr, pte_t *);
extern void ptep_set_wrprotect(struct mm_struct *, extern void ptep_set_wrprotect(struct mm_struct *,
unsigned long addr, pte_t *); unsigned long addr, pte_t *);
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
pte_t pte = *ptep;
pte_clear(_mm, addr, ptep);
return pte;
}
/* Create a pmd from a PTFN. */ /* Create a pmd from a PTFN. */
static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot) static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot)
{ {
......
...@@ -112,6 +112,9 @@ struct pt_regs { ...@@ -112,6 +112,9 @@ struct pt_regs {
/* Fill in a struct pt_regs with the current kernel registers. */ /* Fill in a struct pt_regs with the current kernel registers. */
struct pt_regs *get_pt_regs(struct pt_regs *); struct pt_regs *get_pt_regs(struct pt_regs *);
/* Trace the current syscall. */
extern void do_syscall_trace(void);
extern void show_regs(struct pt_regs *); extern void show_regs(struct pt_regs *);
#define arch_has_single_step() (1) #define arch_has_single_step() (1)
...@@ -123,7 +126,7 @@ extern void show_regs(struct pt_regs *); ...@@ -123,7 +126,7 @@ extern void show_regs(struct pt_regs *);
*/ */
struct single_step_state { struct single_step_state {
/* the page to which we will write hacked-up bundles */ /* the page to which we will write hacked-up bundles */
void *buffer; void __user *buffer;
union { union {
int flags; int flags;
......
...@@ -25,7 +25,14 @@ extern char _sinitdata[], _einitdata[]; ...@@ -25,7 +25,14 @@ extern char _sinitdata[], _einitdata[];
/* Write-once data is writable only till the end of initialization. */ /* Write-once data is writable only till the end of initialization. */
extern char __w1data_begin[], __w1data_end[]; extern char __w1data_begin[], __w1data_end[];
extern char __feedback_section_start[], __feedback_section_end[];
/* Not exactly sections, but PC comparison points in the code. */
extern char __rt_sigreturn[], __rt_sigreturn_end[];
#ifndef __tilegx__
extern char sys_cmpxchg[], __sys_cmpxchg_end[];
extern char __sys_cmpxchg_grab_lock[];
extern char __start_atomic_asm_code[], __end_atomic_asm_code[];
#endif
/* Handle the discontiguity between _sdata and _stext. */ /* Handle the discontiguity between _sdata and _stext. */
static inline int arch_is_kernel_data(unsigned long addr) static inline int arch_is_kernel_data(unsigned long addr)
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#if defined(__KERNEL__) && !defined(__ASSEMBLY__) #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *); int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *);
int setup_sigcontext(struct sigcontext __user *, struct pt_regs *); int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
void do_signal(struct pt_regs *regs);
#endif #endif
#endif /* _ASM_TILE_SIGNAL_H */ #endif /* _ASM_TILE_SIGNAL_H */
...@@ -134,9 +134,8 @@ static inline int arch_read_trylock(arch_rwlock_t *rwlock) ...@@ -134,9 +134,8 @@ static inline int arch_read_trylock(arch_rwlock_t *rwlock)
{ {
int locked; int locked;
u32 val = __insn_tns((int *)&rwlock->lock); u32 val = __insn_tns((int *)&rwlock->lock);
if (unlikely(val & 1)) { if (unlikely(val & 1))
return arch_read_trylock_slow(rwlock); return arch_read_trylock_slow(rwlock);
}
locked = (val << _RD_COUNT_WIDTH) == 0; locked = (val << _RD_COUNT_WIDTH) == 0;
rwlock->lock = val + (locked << _RD_COUNT_SHIFT); rwlock->lock = val + (locked << _RD_COUNT_SHIFT);
return locked; return locked;
......
...@@ -48,6 +48,10 @@ extern void KBacktraceIterator_init(struct KBacktraceIterator *kbt, ...@@ -48,6 +48,10 @@ extern void KBacktraceIterator_init(struct KBacktraceIterator *kbt,
/* Initialize iterator based on current stack. */ /* Initialize iterator based on current stack. */
extern void KBacktraceIterator_init_current(struct KBacktraceIterator *kbt); extern void KBacktraceIterator_init_current(struct KBacktraceIterator *kbt);
/* Helper method for above. */
extern void _KBacktraceIterator_init_current(struct KBacktraceIterator *kbt,
ulong pc, ulong lr, ulong sp, ulong r52);
/* No more frames? */ /* No more frames? */
extern int KBacktraceIterator_end(struct KBacktraceIterator *kbt); extern int KBacktraceIterator_end(struct KBacktraceIterator *kbt);
...@@ -64,5 +68,7 @@ extern void tile_show_stack(struct KBacktraceIterator *, int headers); ...@@ -64,5 +68,7 @@ extern void tile_show_stack(struct KBacktraceIterator *, int headers);
/* Dump stack of current process, with registers to seed the backtrace. */ /* Dump stack of current process, with registers to seed the backtrace. */
extern void dump_stack_regs(struct pt_regs *); extern void dump_stack_regs(struct pt_regs *);
/* Helper method for assembly dump_stack(). */
extern void _dump_stack(int dummy, ulong pc, ulong lr, ulong sp, ulong r52);
#endif /* _ASM_TILE_STACK_H */ #endif /* _ASM_TILE_STACK_H */
...@@ -22,7 +22,19 @@ ...@@ -22,7 +22,19 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/types.h> #include <linux/types.h>
#include <asm-generic/syscalls.h> #include <linux/compat.h>
/* The array of function pointers for syscalls. */
extern void *sys_call_table[];
#ifdef CONFIG_COMPAT
extern void *compat_sys_call_table[];
#endif
/*
* Note that by convention, any syscall which requires the current
* register set takes an additional "struct pt_regs *" pointer; the
* sys_xxx() function just adds the pointer and tail-calls to _sys_xxx().
*/
/* kernel/sys.c */ /* kernel/sys.c */
ssize_t sys32_readahead(int fd, u32 offset_lo, u32 offset_hi, u32 count); ssize_t sys32_readahead(int fd, u32 offset_lo, u32 offset_hi, u32 count);
...@@ -31,10 +43,66 @@ long sys32_fadvise64(int fd, u32 offset_lo, u32 offset_hi, ...@@ -31,10 +43,66 @@ long sys32_fadvise64(int fd, u32 offset_lo, u32 offset_hi,
int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi, int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi,
u32 len_lo, u32 len_hi, int advice); u32 len_lo, u32 len_hi, int advice);
long sys_flush_cache(void); long sys_flush_cache(void);
long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
#ifdef __tilegx__
long sys_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, off_t pgoff);
#endif
/* kernel/process.c */
long sys_clone(unsigned long clone_flags, unsigned long newsp,
void __user *parent_tid, void __user *child_tid);
long _sys_clone(unsigned long clone_flags, unsigned long newsp,
void __user *parent_tid, void __user *child_tid,
struct pt_regs *regs);
long sys_fork(void);
long _sys_fork(struct pt_regs *regs);
long sys_vfork(void);
long _sys_vfork(struct pt_regs *regs);
long sys_execve(char __user *filename, char __user * __user *argv,
char __user * __user *envp);
long _sys_execve(char __user *filename, char __user * __user *argv,
char __user * __user *envp, struct pt_regs *regs);
/* kernel/signal.c */
long sys_sigaltstack(const stack_t __user *, stack_t __user *);
long _sys_sigaltstack(const stack_t __user *, stack_t __user *,
struct pt_regs *);
long sys_rt_sigreturn(void);
long _sys_rt_sigreturn(struct pt_regs *regs);
/* platform-independent functions */
long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize);
long sys_rt_sigaction(int sig, const struct sigaction __user *act,
struct sigaction __user *oact, size_t sigsetsize);
#ifndef __tilegx__ #ifndef __tilegx__
/* mm/fault.c */ /* mm/fault.c */
int sys_cmpxchg_badaddr(unsigned long address, struct pt_regs *); int sys_cmpxchg_badaddr(unsigned long address);
int _sys_cmpxchg_badaddr(unsigned long address, struct pt_regs *);
#endif
#ifdef CONFIG_COMPAT
long compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
compat_uptr_t __user *envp);
long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
compat_uptr_t __user *envp, struct pt_regs *regs);
long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
struct compat_sigaltstack __user *uoss_ptr);
long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
struct compat_sigaltstack __user *uoss_ptr,
struct pt_regs *regs);
long compat_sys_rt_sigreturn(void);
long _compat_sys_rt_sigreturn(struct pt_regs *regs);
/* These four are not defined for 64-bit, but serve as "compat" syscalls. */
long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg);
long sys_fstat64(unsigned long fd, struct stat64 __user *statbuf);
long sys_truncate64(const char __user *path, loff_t length);
long sys_ftruncate64(unsigned int fd, loff_t length);
#endif #endif
#endif /* _ASM_TILE_SYSCALLS_H */ #endif /* _ASM_TILE_SYSCALLS_H */
...@@ -160,6 +160,14 @@ struct task_struct; ...@@ -160,6 +160,14 @@ struct task_struct;
extern struct task_struct *_switch_to(struct task_struct *prev, extern struct task_struct *_switch_to(struct task_struct *prev,
struct task_struct *next); struct task_struct *next);
/* Helper function for _switch_to(). */
extern struct task_struct *__switch_to(struct task_struct *prev,
struct task_struct *next,
unsigned long new_system_save_1_0);
/* Address that switched-away from tasks are at. */
extern unsigned long get_switch_to_pc(void);
/* /*
* On SMP systems, when the scheduler does migration-cost autodetection, * On SMP systems, when the scheduler does migration-cost autodetection,
* it needs a way to flush as much of the CPU's caches as possible: * it needs a way to flush as much of the CPU's caches as possible:
...@@ -187,10 +195,26 @@ extern int unaligned_printk; ...@@ -187,10 +195,26 @@ extern int unaligned_printk;
/* Number of unaligned fixups performed */ /* Number of unaligned fixups performed */
extern unsigned int unaligned_fixup_count; extern unsigned int unaligned_fixup_count;
/* Init-time routine to do tile-specific per-cpu setup. */
void setup_cpu(int boot);
/* User-level DMA management functions */ /* User-level DMA management functions */
void grant_dma_mpls(void); void grant_dma_mpls(void);
void restrict_dma_mpls(void); void restrict_dma_mpls(void);
#ifdef CONFIG_HARDWALL
/* User-level network management functions */
void reset_network_state(void);
void grant_network_mpls(void);
void restrict_network_mpls(void);
int hardwall_deactivate(struct task_struct *task);
/* Hook hardwall code into changes in affinity. */
#define arch_set_cpus_allowed(p, new_mask) do { \
if (p->thread.hardwall && !cpumask_equal(&p->cpus_allowed, new_mask)) \
hardwall_deactivate(p); \
} while (0)
#endif
/* Invoke the simulator "syscall" mechanism (see arch/tile/kernel/entry.S). */ /* Invoke the simulator "syscall" mechanism (see arch/tile/kernel/entry.S). */
extern int _sim_syscall(int syscall_num, ...); extern int _sim_syscall(int syscall_num, ...);
...@@ -215,6 +239,12 @@ extern int _sim_syscall(int syscall_num, ...); ...@@ -215,6 +239,12 @@ extern int _sim_syscall(int syscall_num, ...);
homecache_migrate_kthread(); \ homecache_migrate_kthread(); \
} while (0) } while (0)
/* Support function for forking a new task. */
void ret_from_fork(void);
/* Called from ret_from_fork() when a new process starts up. */
struct task_struct *sim_notify_fork(struct task_struct *prev);
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#endif /* _ASM_TILE_SYSTEM_H */ #endif /* _ASM_TILE_SYSTEM_H */
...@@ -55,7 +55,7 @@ struct thread_info { ...@@ -55,7 +55,7 @@ struct thread_info {
.restart_block = { \ .restart_block = { \
.fn = do_no_restart_syscall, \ .fn = do_no_restart_syscall, \
}, \ }, \
.step_state = 0, \ .step_state = NULL, \
} }
#define init_thread_info (init_thread_union.thread_info) #define init_thread_info (init_thread_union.thread_info)
...@@ -86,6 +86,12 @@ register unsigned long stack_pointer __asm__("sp"); ...@@ -86,6 +86,12 @@ register unsigned long stack_pointer __asm__("sp");
extern struct thread_info *alloc_thread_info(struct task_struct *task); extern struct thread_info *alloc_thread_info(struct task_struct *task);
extern void free_thread_info(struct thread_info *info); extern void free_thread_info(struct thread_info *info);
/* Sit on a nap instruction until interrupted. */
extern void smp_nap(void);
/* Enable interrupts racelessly and nap forever: helper for cpu_idle(). */
extern void _cpu_idle(void);
/* Switch boot idle thread to a freshly-allocated stack and free old stack. */ /* Switch boot idle thread to a freshly-allocated stack and free old stack. */
extern void cpu_idle_on_new_stack(struct thread_info *old_ti, extern void cpu_idle_on_new_stack(struct thread_info *old_ti,
unsigned long new_sp, unsigned long new_sp,
......
...@@ -18,9 +18,28 @@ ...@@ -18,9 +18,28 @@
/* mm/fault.c */ /* mm/fault.c */
void do_page_fault(struct pt_regs *, int fault_num, void do_page_fault(struct pt_regs *, int fault_num,
unsigned long address, unsigned long write); unsigned long address, unsigned long write);
void do_async_page_fault(struct pt_regs *);
#ifndef __tilegx__
/*
* We return this structure in registers to avoid having to write
* additional save/restore code in the intvec.S caller.
*/
struct intvec_state {
void *handler;
unsigned long vecnum;
unsigned long fault_num;
unsigned long info;
unsigned long retval;
};
struct intvec_state do_page_fault_ics(struct pt_regs *regs, int fault_num,
unsigned long address,
unsigned long info);
#endif
/* kernel/traps.c */ /* kernel/traps.c */
void do_trap(struct pt_regs *, int fault_num, unsigned long reason); void do_trap(struct pt_regs *, int fault_num, unsigned long reason);
void kernel_double_fault(int dummy, ulong pc, ulong lr, ulong sp, ulong r52);
/* kernel/time.c */ /* kernel/time.c */
void do_timer_interrupt(struct pt_regs *, int fault_num); void do_timer_interrupt(struct pt_regs *, int fault_num);
...@@ -31,6 +50,13 @@ void hv_message_intr(struct pt_regs *, int intnum); ...@@ -31,6 +50,13 @@ void hv_message_intr(struct pt_regs *, int intnum);
/* kernel/irq.c */ /* kernel/irq.c */
void tile_dev_intr(struct pt_regs *, int intnum); void tile_dev_intr(struct pt_regs *, int intnum);
#ifdef CONFIG_HARDWALL
/* kernel/hardwall.c */
void do_hardwall_trap(struct pt_regs *, int fault_num);
#endif
/* kernel/ptrace.c */
void do_breakpoint(struct pt_regs *, int fault_num);
#endif /* _ASM_TILE_SYSCALLS_H */ #endif /* _ASM_TILE_SYSCALLS_H */
...@@ -89,8 +89,10 @@ int __range_ok(unsigned long addr, unsigned long size); ...@@ -89,8 +89,10 @@ int __range_ok(unsigned long addr, unsigned long size);
* checks that the pointer is in the user space range - after calling * checks that the pointer is in the user space range - after calling
* this function, memory access functions may still return -EFAULT. * this function, memory access functions may still return -EFAULT.
*/ */
#define access_ok(type, addr, size) \ #define access_ok(type, addr, size) ({ \
(likely(__range_ok((unsigned long)addr, size) == 0)) __chk_user_ptr(addr); \
likely(__range_ok((unsigned long)(addr), (size)) == 0); \
})
/* /*
* The exception table consists of pairs of addresses: the first is the * The exception table consists of pairs of addresses: the first is the
...@@ -134,14 +136,14 @@ struct __get_user { ...@@ -134,14 +136,14 @@ struct __get_user {
* such extended assembler routines, though we will have to use a * such extended assembler routines, though we will have to use a
* different return code in that case (1, 2, or 4, rather than -EFAULT). * different return code in that case (1, 2, or 4, rather than -EFAULT).
*/ */
extern struct __get_user __get_user_1(const void *); extern struct __get_user __get_user_1(const void __user *);
extern struct __get_user __get_user_2(const void *); extern struct __get_user __get_user_2(const void __user *);
extern struct __get_user __get_user_4(const void *); extern struct __get_user __get_user_4(const void __user *);
extern struct __get_user __get_user_8(const void *); extern struct __get_user __get_user_8(const void __user *);
extern int __put_user_1(long, void *); extern int __put_user_1(long, void __user *);
extern int __put_user_2(long, void *); extern int __put_user_2(long, void __user *);
extern int __put_user_4(long, void *); extern int __put_user_4(long, void __user *);
extern int __put_user_8(long long, void *); extern int __put_user_8(long long, void __user *);
/* Unimplemented routines to cause linker failures */ /* Unimplemented routines to cause linker failures */
extern struct __get_user __get_user_bad(void); extern struct __get_user __get_user_bad(void);
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#if !defined(_ASM_TILE_UNISTD_H) || defined(__SYSCALL) #if !defined(_ASM_TILE_UNISTD_H) || defined(__SYSCALL)
#define _ASM_TILE_UNISTD_H #define _ASM_TILE_UNISTD_H
#ifndef __LP64__ #ifndef __LP64__
/* Use the flavor of this syscall that matches the 32-bit API better. */ /* Use the flavor of this syscall that matches the 32-bit API better. */
#define __ARCH_WANT_SYNC_FILE_RANGE2 #define __ARCH_WANT_SYNC_FILE_RANGE2
...@@ -24,6 +23,10 @@ ...@@ -24,6 +23,10 @@
/* Use the standard ABI for syscalls. */ /* Use the standard ABI for syscalls. */
#include <asm-generic/unistd.h> #include <asm-generic/unistd.h>
/* Additional Tilera-specific syscalls. */
#define __NR_flush_cache (__NR_arch_specific_syscall + 1)
__SYSCALL(__NR_flush_cache, sys_flush_cache)
#ifndef __tilegx__ #ifndef __tilegx__
/* "Fast" syscalls provide atomic support for 32-bit chips. */ /* "Fast" syscalls provide atomic support for 32-bit chips. */
#define __NR_FAST_cmpxchg -1 #define __NR_FAST_cmpxchg -1
...@@ -33,10 +36,6 @@ ...@@ -33,10 +36,6 @@
__SYSCALL(__NR_cmpxchg_badaddr, sys_cmpxchg_badaddr) __SYSCALL(__NR_cmpxchg_badaddr, sys_cmpxchg_badaddr)
#endif #endif
/* Additional Tilera-specific syscalls. */
#define __NR_flush_cache (__NR_arch_specific_syscall + 1)
__SYSCALL(__NR_flush_cache, sys_flush_cache)
#ifdef __KERNEL__ #ifdef __KERNEL__
/* In compat mode, we use sys_llseek() for compat_sys_llseek(). */ /* In compat mode, we use sys_llseek() for compat_sys_llseek(). */
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
......
...@@ -30,18 +30,18 @@ ...@@ -30,18 +30,18 @@
/** A decoded bundle used for backtracer analysis. */ /** A decoded bundle used for backtracer analysis. */
typedef struct { struct BacktraceBundle {
tile_bundle_bits bits; tile_bundle_bits bits;
int num_insns; int num_insns;
struct tile_decoded_instruction struct tile_decoded_instruction
insns[TILE_MAX_INSTRUCTIONS_PER_BUNDLE]; insns[TILE_MAX_INSTRUCTIONS_PER_BUNDLE];
} BacktraceBundle; };
/* This implementation only makes sense for native tools. */ /* This implementation only makes sense for native tools. */
/** Default function to read memory. */ /** Default function to read memory. */
static bool static bool bt_read_memory(void *result, VirtualAddress addr,
bt_read_memory(void *result, VirtualAddress addr, size_t size, void *extra) size_t size, void *extra)
{ {
/* FIXME: this should do some horrible signal stuff to catch /* FIXME: this should do some horrible signal stuff to catch
* SEGV cleanly and fail. * SEGV cleanly and fail.
...@@ -58,11 +58,11 @@ bt_read_memory(void *result, VirtualAddress addr, size_t size, void *extra) ...@@ -58,11 +58,11 @@ bt_read_memory(void *result, VirtualAddress addr, size_t size, void *extra)
* has the specified mnemonic, and whose first 'num_operands_to_match' * has the specified mnemonic, and whose first 'num_operands_to_match'
* operands exactly match those in 'operand_values'. * operands exactly match those in 'operand_values'.
*/ */
static const struct tile_decoded_instruction* static const struct tile_decoded_instruction *find_matching_insn(
find_matching_insn(const BacktraceBundle *bundle, const struct BacktraceBundle *bundle,
tile_mnemonic mnemonic, tile_mnemonic mnemonic,
const int *operand_values, const int *operand_values,
int num_operands_to_match) int num_operands_to_match)
{ {
int i, j; int i, j;
bool match; bool match;
...@@ -90,8 +90,7 @@ find_matching_insn(const BacktraceBundle *bundle, ...@@ -90,8 +90,7 @@ find_matching_insn(const BacktraceBundle *bundle,
} }
/** Does this bundle contain an 'iret' instruction? */ /** Does this bundle contain an 'iret' instruction? */
static inline bool static inline bool bt_has_iret(const struct BacktraceBundle *bundle)
bt_has_iret(const BacktraceBundle *bundle)
{ {
return find_matching_insn(bundle, TILE_OPC_IRET, NULL, 0) != NULL; return find_matching_insn(bundle, TILE_OPC_IRET, NULL, 0) != NULL;
} }
...@@ -99,8 +98,7 @@ bt_has_iret(const BacktraceBundle *bundle) ...@@ -99,8 +98,7 @@ bt_has_iret(const BacktraceBundle *bundle)
/** Does this bundle contain an 'addi sp, sp, OFFSET' or /** Does this bundle contain an 'addi sp, sp, OFFSET' or
* 'addli sp, sp, OFFSET' instruction, and if so, what is OFFSET? * 'addli sp, sp, OFFSET' instruction, and if so, what is OFFSET?
*/ */
static bool static bool bt_has_addi_sp(const struct BacktraceBundle *bundle, int *adjust)
bt_has_addi_sp(const BacktraceBundle *bundle, int *adjust)
{ {
static const int vals[2] = { TREG_SP, TREG_SP }; static const int vals[2] = { TREG_SP, TREG_SP };
...@@ -120,8 +118,7 @@ bt_has_addi_sp(const BacktraceBundle *bundle, int *adjust) ...@@ -120,8 +118,7 @@ bt_has_addi_sp(const BacktraceBundle *bundle, int *adjust)
* as an unsigned value by this code since that's what the caller wants. * as an unsigned value by this code since that's what the caller wants.
* Returns the number of info ops found. * Returns the number of info ops found.
*/ */
static int static int bt_get_info_ops(const struct BacktraceBundle *bundle,
bt_get_info_ops(const BacktraceBundle *bundle,
int operands[MAX_INFO_OPS_PER_BUNDLE]) int operands[MAX_INFO_OPS_PER_BUNDLE])
{ {
int num_ops = 0; int num_ops = 0;
...@@ -143,8 +140,7 @@ bt_get_info_ops(const BacktraceBundle *bundle, ...@@ -143,8 +140,7 @@ bt_get_info_ops(const BacktraceBundle *bundle,
/** Does this bundle contain a jrp instruction, and if so, to which /** Does this bundle contain a jrp instruction, and if so, to which
* register is it jumping? * register is it jumping?
*/ */
static bool static bool bt_has_jrp(const struct BacktraceBundle *bundle, int *target_reg)
bt_has_jrp(const BacktraceBundle *bundle, int *target_reg)
{ {
const struct tile_decoded_instruction *insn = const struct tile_decoded_instruction *insn =
find_matching_insn(bundle, TILE_OPC_JRP, NULL, 0); find_matching_insn(bundle, TILE_OPC_JRP, NULL, 0);
...@@ -156,8 +152,7 @@ bt_has_jrp(const BacktraceBundle *bundle, int *target_reg) ...@@ -156,8 +152,7 @@ bt_has_jrp(const BacktraceBundle *bundle, int *target_reg)
} }
/** Does this bundle modify the specified register in any way? */ /** Does this bundle modify the specified register in any way? */
static bool static bool bt_modifies_reg(const struct BacktraceBundle *bundle, int reg)
bt_modifies_reg(const BacktraceBundle *bundle, int reg)
{ {
int i, j; int i, j;
for (i = 0; i < bundle->num_insns; i++) { for (i = 0; i < bundle->num_insns; i++) {
...@@ -177,30 +172,26 @@ bt_modifies_reg(const BacktraceBundle *bundle, int reg) ...@@ -177,30 +172,26 @@ bt_modifies_reg(const BacktraceBundle *bundle, int reg)
} }
/** Does this bundle modify sp? */ /** Does this bundle modify sp? */
static inline bool static inline bool bt_modifies_sp(const struct BacktraceBundle *bundle)
bt_modifies_sp(const BacktraceBundle *bundle)
{ {
return bt_modifies_reg(bundle, TREG_SP); return bt_modifies_reg(bundle, TREG_SP);
} }
/** Does this bundle modify lr? */ /** Does this bundle modify lr? */
static inline bool static inline bool bt_modifies_lr(const struct BacktraceBundle *bundle)
bt_modifies_lr(const BacktraceBundle *bundle)
{ {
return bt_modifies_reg(bundle, TREG_LR); return bt_modifies_reg(bundle, TREG_LR);
} }
/** Does this bundle contain the instruction 'move fp, sp'? */ /** Does this bundle contain the instruction 'move fp, sp'? */
static inline bool static inline bool bt_has_move_r52_sp(const struct BacktraceBundle *bundle)
bt_has_move_r52_sp(const BacktraceBundle *bundle)
{ {
static const int vals[2] = { 52, TREG_SP }; static const int vals[2] = { 52, TREG_SP };
return find_matching_insn(bundle, TILE_OPC_MOVE, vals, 2) != NULL; return find_matching_insn(bundle, TILE_OPC_MOVE, vals, 2) != NULL;
} }
/** Does this bundle contain the instruction 'sw sp, lr'? */ /** Does this bundle contain the instruction 'sw sp, lr'? */
static inline bool static inline bool bt_has_sw_sp_lr(const struct BacktraceBundle *bundle)
bt_has_sw_sp_lr(const BacktraceBundle *bundle)
{ {
static const int vals[2] = { TREG_SP, TREG_LR }; static const int vals[2] = { TREG_SP, TREG_LR };
return find_matching_insn(bundle, TILE_OPC_SW, vals, 2) != NULL; return find_matching_insn(bundle, TILE_OPC_SW, vals, 2) != NULL;
...@@ -209,11 +200,10 @@ bt_has_sw_sp_lr(const BacktraceBundle *bundle) ...@@ -209,11 +200,10 @@ bt_has_sw_sp_lr(const BacktraceBundle *bundle)
/** Locates the caller's PC and SP for a program starting at the /** Locates the caller's PC and SP for a program starting at the
* given address. * given address.
*/ */
static void static void find_caller_pc_and_caller_sp(CallerLocation *location,
find_caller_pc_and_caller_sp(CallerLocation *location, const VirtualAddress start_pc,
const VirtualAddress start_pc, BacktraceMemoryReader read_memory_func,
BacktraceMemoryReader read_memory_func, void *read_memory_func_extra)
void *read_memory_func_extra)
{ {
/* Have we explicitly decided what the sp is, /* Have we explicitly decided what the sp is,
* rather than just the default? * rather than just the default?
...@@ -253,7 +243,7 @@ find_caller_pc_and_caller_sp(CallerLocation *location, ...@@ -253,7 +243,7 @@ find_caller_pc_and_caller_sp(CallerLocation *location,
for (pc = start_pc;; pc += sizeof(tile_bundle_bits)) { for (pc = start_pc;; pc += sizeof(tile_bundle_bits)) {
BacktraceBundle bundle; struct BacktraceBundle bundle;
int num_info_ops, info_operands[MAX_INFO_OPS_PER_BUNDLE]; int num_info_ops, info_operands[MAX_INFO_OPS_PER_BUNDLE];
int one_ago, jrp_reg; int one_ago, jrp_reg;
bool has_jrp; bool has_jrp;
...@@ -475,12 +465,11 @@ find_caller_pc_and_caller_sp(CallerLocation *location, ...@@ -475,12 +465,11 @@ find_caller_pc_and_caller_sp(CallerLocation *location,
} }
} }
void void backtrace_init(BacktraceIterator *state,
backtrace_init(BacktraceIterator *state, BacktraceMemoryReader read_memory_func,
BacktraceMemoryReader read_memory_func, void *read_memory_func_extra,
void *read_memory_func_extra, VirtualAddress pc, VirtualAddress lr,
VirtualAddress pc, VirtualAddress lr, VirtualAddress sp, VirtualAddress r52)
VirtualAddress sp, VirtualAddress r52)
{ {
CallerLocation location; CallerLocation location;
VirtualAddress fp, initial_frame_caller_pc; VirtualAddress fp, initial_frame_caller_pc;
...@@ -558,8 +547,7 @@ backtrace_init(BacktraceIterator *state, ...@@ -558,8 +547,7 @@ backtrace_init(BacktraceIterator *state,
state->read_memory_func_extra = read_memory_func_extra; state->read_memory_func_extra = read_memory_func_extra;
} }
bool bool backtrace_next(BacktraceIterator *state)
backtrace_next(BacktraceIterator *state)
{ {
VirtualAddress next_fp, next_pc, next_frame[2]; VirtualAddress next_fp, next_pc, next_frame[2];
...@@ -614,12 +602,11 @@ backtrace_next(BacktraceIterator *state) ...@@ -614,12 +602,11 @@ backtrace_next(BacktraceIterator *state)
#else /* TILE_CHIP < 10 */ #else /* TILE_CHIP < 10 */
void void backtrace_init(BacktraceIterator *state,
backtrace_init(BacktraceIterator *state, BacktraceMemoryReader read_memory_func,
BacktraceMemoryReader read_memory_func, void *read_memory_func_extra,
void *read_memory_func_extra, VirtualAddress pc, VirtualAddress lr,
VirtualAddress pc, VirtualAddress lr, VirtualAddress sp, VirtualAddress r52)
VirtualAddress sp, VirtualAddress r52)
{ {
state->pc = pc; state->pc = pc;
state->sp = sp; state->sp = sp;
......
...@@ -88,34 +88,14 @@ long compat_sys_sched_rr_get_interval(compat_pid_t pid, ...@@ -88,34 +88,14 @@ long compat_sys_sched_rr_get_interval(compat_pid_t pid,
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t); ret = sys_sched_rr_get_interval(pid,
(struct timespec __force __user *)&t);
set_fs(old_fs); set_fs(old_fs);
if (put_compat_timespec(&t, interval)) if (put_compat_timespec(&t, interval))
return -EFAULT; return -EFAULT;
return ret; return ret;
} }
ssize_t compat_sys_sendfile(int out_fd, int in_fd, compat_off_t __user *offset,
size_t count)
{
mm_segment_t old_fs = get_fs();
int ret;
off_t of;
if (offset && get_user(of, offset))
return -EFAULT;
set_fs(KERNEL_DS);
ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL,
count);
set_fs(old_fs);
if (offset && put_user(of, offset))
return -EFAULT;
return ret;
}
/* /*
* The usual compat_sys_msgsnd() and _msgrcv() seem to be assuming * The usual compat_sys_msgsnd() and _msgrcv() seem to be assuming
* some different calling convention than our normal 32-bit tile code. * some different calling convention than our normal 32-bit tile code.
...@@ -177,6 +157,10 @@ long tile_compat_sys_msgrcv(int msqid, ...@@ -177,6 +157,10 @@ long tile_compat_sys_msgrcv(int msqid,
/* Pass full 64-bit values through ptrace. */ /* Pass full 64-bit values through ptrace. */
#define compat_sys_ptrace tile_compat_sys_ptrace #define compat_sys_ptrace tile_compat_sys_ptrace
/*
* Note that we can't include <linux/unistd.h> here since the header
* guard will defeat us; <asm/unistd.h> checks for __SYSCALL as well.
*/
void *compat_sys_call_table[__NR_syscalls] = { void *compat_sys_call_table[__NR_syscalls] = {
[0 ... __NR_syscalls-1] = sys_ni_syscall, [0 ... __NR_syscalls-1] = sys_ni_syscall,
#include <asm/unistd.h> #include <asm/unistd.h>
......
...@@ -32,13 +32,14 @@ ...@@ -32,13 +32,14 @@
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/ucontext.h> #include <asm/ucontext.h>
#include <asm/sigframe.h> #include <asm/sigframe.h>
#include <asm/syscalls.h>
#include <arch/interrupts.h> #include <arch/interrupts.h>
struct compat_sigaction { struct compat_sigaction {
compat_uptr_t sa_handler; compat_uptr_t sa_handler;
compat_ulong_t sa_flags; compat_ulong_t sa_flags;
compat_uptr_t sa_restorer; compat_uptr_t sa_restorer;
sigset_t sa_mask; /* mask last for extensibility */ sigset_t sa_mask __packed;
}; };
struct compat_sigaltstack { struct compat_sigaltstack {
...@@ -170,7 +171,7 @@ long compat_sys_rt_sigqueueinfo(int pid, int sig, ...@@ -170,7 +171,7 @@ long compat_sys_rt_sigqueueinfo(int pid, int sig,
if (copy_siginfo_from_user32(&info, uinfo)) if (copy_siginfo_from_user32(&info, uinfo))
return -EFAULT; return -EFAULT;
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info); ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __force __user *)&info);
set_fs(old_fs); set_fs(old_fs);
return ret; return ret;
} }
...@@ -274,7 +275,8 @@ long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, ...@@ -274,7 +275,8 @@ long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
} }
seg = get_fs(); seg = get_fs();
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, ret = do_sigaltstack(uss_ptr ? (stack_t __user __force *)&uss : NULL,
(stack_t __user __force *)&uoss,
(unsigned long)compat_ptr(regs->sp)); (unsigned long)compat_ptr(regs->sp));
set_fs(seg); set_fs(seg);
if (ret >= 0 && uoss_ptr) { if (ret >= 0 && uoss_ptr) {
...@@ -336,7 +338,7 @@ static inline void __user *compat_get_sigframe(struct k_sigaction *ka, ...@@ -336,7 +338,7 @@ static inline void __user *compat_get_sigframe(struct k_sigaction *ka,
* will die with SIGSEGV. * will die with SIGSEGV.
*/ */
if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
return (void __user *) -1L; return (void __user __force *)-1UL;
/* This is the X/Open sanctioned signal stack switching. */ /* This is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) { if (ka->sa.sa_flags & SA_ONSTACK) {
......
...@@ -32,7 +32,7 @@ static struct console early_hv_console = { ...@@ -32,7 +32,7 @@ static struct console early_hv_console = {
}; };
/* Direct interface for emergencies */ /* Direct interface for emergencies */
struct console *early_console = &early_hv_console; static struct console *early_console = &early_hv_console;
static int early_console_initialized; static int early_console_initialized;
static int early_console_complete; static int early_console_complete;
......
...@@ -13,9 +13,9 @@ ...@@ -13,9 +13,9 @@
*/ */
#include <linux/linkage.h> #include <linux/linkage.h>
#include <arch/abi.h> #include <linux/unistd.h>
#include <asm/unistd.h>
#include <asm/irqflags.h> #include <asm/irqflags.h>
#include <arch/abi.h>
#ifdef __tilegx__ #ifdef __tilegx__
#define bnzt bnezt #define bnzt bnezt
......
...@@ -75,13 +75,13 @@ void machine_crash_shutdown(struct pt_regs *regs) ...@@ -75,13 +75,13 @@ void machine_crash_shutdown(struct pt_regs *regs)
int machine_kexec_prepare(struct kimage *image) int machine_kexec_prepare(struct kimage *image)
{ {
if (num_online_cpus() > 1) { if (num_online_cpus() > 1) {
printk(KERN_WARNING "%s: detected attempt to kexec " pr_warning("%s: detected attempt to kexec "
"with num_online_cpus() > 1\n", "with num_online_cpus() > 1\n",
__func__); __func__);
return -ENOSYS; return -ENOSYS;
} }
if (image->type != KEXEC_TYPE_DEFAULT) { if (image->type != KEXEC_TYPE_DEFAULT) {
printk(KERN_WARNING "%s: detected attempt to kexec " pr_warning("%s: detected attempt to kexec "
"with unsupported type: %d\n", "with unsupported type: %d\n",
__func__, __func__,
image->type); image->type);
...@@ -124,22 +124,13 @@ static unsigned char *kexec_bn2cl(void *pg) ...@@ -124,22 +124,13 @@ static unsigned char *kexec_bn2cl(void *pg)
return 0; return 0;
/* /*
* If we get a checksum mismatch, it's possible that this is * If we get a checksum mismatch, warn with the checksum
* just a false positive, but relatively unlikely. We dump * so we can diagnose better.
* out the contents of the section so we can diagnose better.
*/ */
csum = ip_compute_csum(pg, bhdrp->b_size); csum = ip_compute_csum(pg, bhdrp->b_size);
if (csum != 0) { if (csum != 0) {
int i; pr_warning("%s: bad checksum %#x (size %d)\n",
unsigned char *p = pg; __func__, csum, bhdrp->b_size);
int nbytes = min((Elf32_Word)1000, bhdrp->b_size);
printk(KERN_INFO "%s: bad checksum %#x\n", __func__, csum);
printk(KERN_INFO "bytes (%d):", bhdrp->b_size);
for (i = 0; i < nbytes; ++i)
printk(" %02x", p[i]);
if (bhdrp->b_size != nbytes)
printk(" ...");
printk("\n");
return 0; return 0;
} }
...@@ -156,7 +147,7 @@ static unsigned char *kexec_bn2cl(void *pg) ...@@ -156,7 +147,7 @@ static unsigned char *kexec_bn2cl(void *pg)
if ((unsigned char *) (nhdrp + 1) > if ((unsigned char *) (nhdrp + 1) >
((unsigned char *) pg) + bhdrp->b_size) { ((unsigned char *) pg) + bhdrp->b_size) {
printk(KERN_INFO "%s: out of bounds\n", __func__); pr_info("%s: out of bounds\n", __func__);
return 0; return 0;
} }
} }
...@@ -167,7 +158,7 @@ static unsigned char *kexec_bn2cl(void *pg) ...@@ -167,7 +158,7 @@ static unsigned char *kexec_bn2cl(void *pg)
while (*desc != '\0') { while (*desc != '\0') {
desc++; desc++;
if (((unsigned long)desc & PAGE_MASK) != (unsigned long)pg) { if (((unsigned long)desc & PAGE_MASK) != (unsigned long)pg) {
printk(KERN_INFO "%s: ran off end of page\n", pr_info("%s: ran off end of page\n",
__func__); __func__);
return 0; return 0;
} }
...@@ -202,23 +193,20 @@ static void kexec_find_and_set_command_line(struct kimage *image) ...@@ -202,23 +193,20 @@ static void kexec_find_and_set_command_line(struct kimage *image)
} }
if (command_line != 0) { if (command_line != 0) {
printk(KERN_INFO "setting new command line to \"%s\"\n", pr_info("setting new command line to \"%s\"\n",
command_line); command_line);
hverr = hv_set_command_line( hverr = hv_set_command_line(
(HV_VirtAddr) command_line, strlen(command_line)); (HV_VirtAddr) command_line, strlen(command_line));
kunmap_atomic(command_line, KM_USER0); kunmap_atomic(command_line, KM_USER0);
} else { } else {
printk(KERN_INFO "%s: no command line found; making empty\n", pr_info("%s: no command line found; making empty\n",
__func__); __func__);
hverr = hv_set_command_line((HV_VirtAddr) command_line, 0); hverr = hv_set_command_line((HV_VirtAddr) command_line, 0);
} }
if (hverr) { if (hverr)
printk(KERN_WARNING pr_warning("%s: hv_set_command_line returned error: %d\n",
"%s: call to hv_set_command_line returned error: %d\n", __func__, hverr);
__func__, hverr);
}
} }
/* /*
......
...@@ -18,13 +18,14 @@ ...@@ -18,13 +18,14 @@
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <asm/hv_driver.h> #include <asm/hv_driver.h>
#include <asm/irq_regs.h> #include <asm/irq_regs.h>
#include <asm/traps.h>
#include <hv/hypervisor.h> #include <hv/hypervisor.h>
#include <arch/interrupts.h> #include <arch/interrupts.h>
/* All messages are stored here */ /* All messages are stored here */
static DEFINE_PER_CPU(HV_MsgState, msg_state); static DEFINE_PER_CPU(HV_MsgState, msg_state);
void __cpuinit init_messaging() void __cpuinit init_messaging(void)
{ {
/* Allocate storage for messages in kernel space */ /* Allocate storage for messages in kernel space */
HV_MsgState *state = &__get_cpu_var(msg_state); HV_MsgState *state = &__get_cpu_var(msg_state);
...@@ -58,7 +59,7 @@ void hv_message_intr(struct pt_regs *regs, int intnum) ...@@ -58,7 +59,7 @@ void hv_message_intr(struct pt_regs *regs, int intnum)
{ {
long sp = stack_pointer - (long) current_thread_info(); long sp = stack_pointer - (long) current_thread_info();
if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) { if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
printk(KERN_EMERG "hv_message_intr: " pr_emerg("hv_message_intr: "
"stack overflow: %ld\n", "stack overflow: %ld\n",
sp - sizeof(struct thread_info)); sp - sizeof(struct thread_info));
dump_stack(); dump_stack();
......
...@@ -107,7 +107,7 @@ int apply_relocate(Elf_Shdr *sechdrs, ...@@ -107,7 +107,7 @@ int apply_relocate(Elf_Shdr *sechdrs,
unsigned int relsec, unsigned int relsec,
struct module *me) struct module *me)
{ {
printk(KERN_ERR "module %s: .rel relocation unsupported\n", me->name); pr_err("module %s: .rel relocation unsupported\n", me->name);
return -ENOEXEC; return -ENOEXEC;
} }
...@@ -119,8 +119,8 @@ int apply_relocate(Elf_Shdr *sechdrs, ...@@ -119,8 +119,8 @@ int apply_relocate(Elf_Shdr *sechdrs,
static int validate_hw2_last(long value, struct module *me) static int validate_hw2_last(long value, struct module *me)
{ {
if (((value << 16) >> 16) != value) { if (((value << 16) >> 16) != value) {
printk("module %s: Out of range HW2_LAST value %#lx\n", pr_warning("module %s: Out of range HW2_LAST value %#lx\n",
me->name, value); me->name, value);
return 0; return 0;
} }
return 1; return 1;
...@@ -223,10 +223,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, ...@@ -223,10 +223,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
value -= (unsigned long) location; /* pc-relative */ value -= (unsigned long) location; /* pc-relative */
value = (long) value >> 3; /* count by instrs */ value = (long) value >> 3; /* count by instrs */
if (!validate_jumpoff(value)) { if (!validate_jumpoff(value)) {
printk("module %s: Out of range jump to" pr_warning("module %s: Out of range jump to"
" %#llx at %#llx (%p)\n", me->name, " %#llx at %#llx (%p)\n", me->name,
sym->st_value + rel[i].r_addend, sym->st_value + rel[i].r_addend,
rel[i].r_offset, location); rel[i].r_offset, location);
return -ENOEXEC; return -ENOEXEC;
} }
MUNGE(create_JumpOff_X1); MUNGE(create_JumpOff_X1);
...@@ -236,7 +236,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, ...@@ -236,7 +236,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
#undef MUNGE #undef MUNGE
default: default:
printk(KERN_ERR "module %s: Unknown relocation: %d\n", pr_err("module %s: Unknown relocation: %d\n",
me->name, (int) ELF_R_TYPE(rel[i].r_info)); me->name, (int) ELF_R_TYPE(rel[i].r_info));
return -ENOEXEC; return -ENOEXEC;
} }
......
...@@ -24,9 +24,14 @@ ...@@ -24,9 +24,14 @@
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/hardirq.h> #include <linux/hardirq.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <linux/kernel.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/stack.h> #include <asm/stack.h>
#include <asm/homecache.h> #include <asm/homecache.h>
#include <asm/syscalls.h>
#ifdef CONFIG_HARDWALL
#include <asm/hardwall.h>
#endif
#include <arch/chip.h> #include <arch/chip.h>
#include <arch/abi.h> #include <arch/abi.h>
...@@ -43,7 +48,7 @@ static int __init idle_setup(char *str) ...@@ -43,7 +48,7 @@ static int __init idle_setup(char *str)
return -EINVAL; return -EINVAL;
if (!strcmp(str, "poll")) { if (!strcmp(str, "poll")) {
printk("using polling idle threads.\n"); pr_info("using polling idle threads.\n");
no_idle_nap = 1; no_idle_nap = 1;
} else if (!strcmp(str, "halt")) } else if (!strcmp(str, "halt"))
no_idle_nap = 0; no_idle_nap = 0;
...@@ -62,7 +67,6 @@ early_param("idle", idle_setup); ...@@ -62,7 +67,6 @@ early_param("idle", idle_setup);
*/ */
void cpu_idle(void) void cpu_idle(void)
{ {
extern void _cpu_idle(void);
int cpu = smp_processor_id(); int cpu = smp_processor_id();
...@@ -108,7 +112,7 @@ void cpu_idle(void) ...@@ -108,7 +112,7 @@ void cpu_idle(void)
struct thread_info *alloc_thread_info(struct task_struct *task) struct thread_info *alloc_thread_info(struct task_struct *task)
{ {
struct page *page; struct page *page;
int flags = GFP_KERNEL; gfp_t flags = GFP_KERNEL;
#ifdef CONFIG_DEBUG_STACK_USAGE #ifdef CONFIG_DEBUG_STACK_USAGE
flags |= __GFP_ZERO; flags |= __GFP_ZERO;
...@@ -116,7 +120,7 @@ struct thread_info *alloc_thread_info(struct task_struct *task) ...@@ -116,7 +120,7 @@ struct thread_info *alloc_thread_info(struct task_struct *task)
page = alloc_pages(flags, THREAD_SIZE_ORDER); page = alloc_pages(flags, THREAD_SIZE_ORDER);
if (!page) if (!page)
return 0; return NULL;
return (struct thread_info *)page_address(page); return (struct thread_info *)page_address(page);
} }
...@@ -129,6 +133,18 @@ void free_thread_info(struct thread_info *info) ...@@ -129,6 +133,18 @@ void free_thread_info(struct thread_info *info)
{ {
struct single_step_state *step_state = info->step_state; struct single_step_state *step_state = info->step_state;
#ifdef CONFIG_HARDWALL
/*
* We free a thread_info from the context of the task that has
* been scheduled next, so the original task is already dead.
* Calling deactivate here just frees up the data structures.
* If the task we're freeing held the last reference to a
* hardwall fd, it would have been released prior to this point
* anyway via exit_files(), and "hardwall" would be NULL by now.
*/
if (info->task->thread.hardwall)
hardwall_deactivate(info->task);
#endif
if (step_state) { if (step_state) {
...@@ -154,8 +170,6 @@ void free_thread_info(struct thread_info *info) ...@@ -154,8 +170,6 @@ void free_thread_info(struct thread_info *info)
static void save_arch_state(struct thread_struct *t); static void save_arch_state(struct thread_struct *t);
extern void ret_from_fork(void);
int copy_thread(unsigned long clone_flags, unsigned long sp, int copy_thread(unsigned long clone_flags, unsigned long sp,
unsigned long stack_size, unsigned long stack_size,
struct task_struct *p, struct pt_regs *regs) struct task_struct *p, struct pt_regs *regs)
...@@ -235,6 +249,10 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, ...@@ -235,6 +249,10 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
p->thread.proc_status = 0; p->thread.proc_status = 0;
#endif #endif
#ifdef CONFIG_HARDWALL
/* New thread does not own any networks. */
p->thread.hardwall = NULL;
#endif
/* /*
...@@ -257,7 +275,7 @@ struct task_struct *validate_current(void) ...@@ -257,7 +275,7 @@ struct task_struct *validate_current(void)
if (unlikely((unsigned long)tsk < PAGE_OFFSET || if (unlikely((unsigned long)tsk < PAGE_OFFSET ||
(void *)tsk > high_memory || (void *)tsk > high_memory ||
((unsigned long)tsk & (__alignof__(*tsk) - 1)) != 0)) { ((unsigned long)tsk & (__alignof__(*tsk) - 1)) != 0)) {
printk("Corrupt 'current' %p (sp %#lx)\n", tsk, stack_pointer); pr_err("Corrupt 'current' %p (sp %#lx)\n", tsk, stack_pointer);
tsk = &corrupt; tsk = &corrupt;
} }
return tsk; return tsk;
...@@ -447,10 +465,6 @@ void _prepare_arch_switch(struct task_struct *next) ...@@ -447,10 +465,6 @@ void _prepare_arch_switch(struct task_struct *next)
} }
extern struct task_struct *__switch_to(struct task_struct *prev,
struct task_struct *next,
unsigned long new_system_save_1_0);
struct task_struct *__sched _switch_to(struct task_struct *prev, struct task_struct *__sched _switch_to(struct task_struct *prev,
struct task_struct *next) struct task_struct *next)
{ {
...@@ -486,6 +500,15 @@ struct task_struct *__sched _switch_to(struct task_struct *prev, ...@@ -486,6 +500,15 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
} }
#endif #endif
#ifdef CONFIG_HARDWALL
/* Enable or disable access to the network registers appropriately. */
if (prev->thread.hardwall != NULL) {
if (next->thread.hardwall == NULL)
restrict_network_mpls();
} else if (next->thread.hardwall != NULL) {
grant_network_mpls();
}
#endif
/* /*
* Switch kernel SP, PC, and callee-saved registers. * Switch kernel SP, PC, and callee-saved registers.
...@@ -496,14 +519,14 @@ struct task_struct *__sched _switch_to(struct task_struct *prev, ...@@ -496,14 +519,14 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
return __switch_to(prev, next, next_current_ksp0(next)); return __switch_to(prev, next, next_current_ksp0(next));
} }
int _sys_fork(struct pt_regs *regs) long _sys_fork(struct pt_regs *regs)
{ {
return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL); return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
} }
int _sys_clone(unsigned long clone_flags, unsigned long newsp, long _sys_clone(unsigned long clone_flags, unsigned long newsp,
void __user *parent_tidptr, void __user *child_tidptr, void __user *parent_tidptr, void __user *child_tidptr,
struct pt_regs *regs) struct pt_regs *regs)
{ {
if (!newsp) if (!newsp)
newsp = regs->sp; newsp = regs->sp;
...@@ -511,7 +534,7 @@ int _sys_clone(unsigned long clone_flags, unsigned long newsp, ...@@ -511,7 +534,7 @@ int _sys_clone(unsigned long clone_flags, unsigned long newsp,
parent_tidptr, child_tidptr); parent_tidptr, child_tidptr);
} }
int _sys_vfork(struct pt_regs *regs) long _sys_vfork(struct pt_regs *regs)
{ {
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp,
regs, 0, NULL, NULL); regs, 0, NULL, NULL);
...@@ -520,10 +543,10 @@ int _sys_vfork(struct pt_regs *regs) ...@@ -520,10 +543,10 @@ int _sys_vfork(struct pt_regs *regs)
/* /*
* sys_execve() executes a new program. * sys_execve() executes a new program.
*/ */
int _sys_execve(char __user *path, char __user *__user *argv, long _sys_execve(char __user *path, char __user *__user *argv,
char __user *__user *envp, struct pt_regs *regs) char __user *__user *envp, struct pt_regs *regs)
{ {
int error; long error;
char *filename; char *filename;
filename = getname(path); filename = getname(path);
...@@ -537,10 +560,10 @@ int _sys_execve(char __user *path, char __user *__user *argv, ...@@ -537,10 +560,10 @@ int _sys_execve(char __user *path, char __user *__user *argv,
} }
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
int _compat_sys_execve(char __user *path, compat_uptr_t __user *argv, long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
compat_uptr_t __user *envp, struct pt_regs *regs) compat_uptr_t __user *envp, struct pt_regs *regs)
{ {
int error; long error;
char *filename; char *filename;
filename = getname(path); filename = getname(path);
...@@ -616,31 +639,32 @@ void exit_thread(void) ...@@ -616,31 +639,32 @@ void exit_thread(void)
/* Nothing */ /* Nothing */
} }
#ifdef __tilegx__
# define LINECOUNT 3
# define EXTRA_NL "\n"
#else
# define LINECOUNT 4
# define EXTRA_NL ""
#endif
void show_regs(struct pt_regs *regs) void show_regs(struct pt_regs *regs)
{ {
struct task_struct *tsk = validate_current(); struct task_struct *tsk = validate_current();
int i, linebreak; int i;
printk("\n");
printk(" Pid: %d, comm: %20s, CPU: %d\n", pr_err("\n");
pr_err(" Pid: %d, comm: %20s, CPU: %d\n",
tsk->pid, tsk->comm, smp_processor_id()); tsk->pid, tsk->comm, smp_processor_id());
for (i = linebreak = 0; i < 53; ++i) { #ifdef __tilegx__
printk(" r%-2d: "REGFMT, i, regs->regs[i]); for (i = 0; i < 51; i += 3)
if (++linebreak == LINECOUNT) { pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT" r%-2d: "REGFMT"\n",
linebreak = 0; i, regs->regs[i], i+1, regs->regs[i+1],
printk("\n"); i+2, regs->regs[i+2]);
} pr_err(" r51: "REGFMT" r52: "REGFMT" tp : "REGFMT"\n",
} regs->regs[51], regs->regs[52], regs->tp);
printk(" tp : "REGFMT EXTRA_NL " sp : "REGFMT" lr : "REGFMT"\n", pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr);
regs->tp, regs->sp, regs->lr); #else
printk(" pc : "REGFMT" ex1: %ld faultnum: %ld\n", for (i = 0; i < 52; i += 3)
pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT
" r%-2d: "REGFMT" r%-2d: "REGFMT"\n",
i, regs->regs[i], i+1, regs->regs[i+1],
i+2, regs->regs[i+2], i+3, regs->regs[i+3]);
pr_err(" r52: "REGFMT" tp : "REGFMT" sp : "REGFMT" lr : "REGFMT"\n",
regs->regs[52], regs->tp, regs->sp, regs->lr);
#endif
pr_err(" pc : "REGFMT" ex1: %ld faultnum: %ld\n",
regs->pc, regs->ex1, regs->faultnum); regs->pc, regs->ex1, regs->faultnum);
dump_stack_regs(regs); dump_stack_regs(regs);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/kprobes.h> #include <linux/kprobes.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/traps.h>
void user_enable_single_step(struct task_struct *child) void user_enable_single_step(struct task_struct *child)
{ {
...@@ -76,7 +77,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -76,7 +77,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
if (task_thread_info(child)->status & TS_COMPAT) if (task_thread_info(child)->status & TS_COMPAT)
addr = (u32)addr; addr = (u32)addr;
#endif #endif
datap = (unsigned long __user *)data; datap = (unsigned long __user __force *)data;
switch (request) { switch (request) {
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/pm.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <hv/hypervisor.h> #include <hv/hypervisor.h>
...@@ -46,7 +47,5 @@ void machine_restart(char *cmd) ...@@ -46,7 +47,5 @@ void machine_restart(char *cmd)
hv_restart((HV_VirtAddr) "vmlinux", (HV_VirtAddr) cmd); hv_restart((HV_VirtAddr) "vmlinux", (HV_VirtAddr) cmd);
} }
/* /* No interesting distinction to be made here. */
* Power off function, if any void (*pm_power_off)(void) = NULL;
*/
void (*pm_power_off)(void) = machine_power_off;
This diff is collapsed.
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/ucontext.h> #include <asm/ucontext.h>
#include <asm/sigframe.h> #include <asm/sigframe.h>
#include <asm/syscalls.h>
#include <arch/interrupts.h> #include <arch/interrupts.h>
#define DEBUG_SIG 0 #define DEBUG_SIG 0
...@@ -40,11 +41,8 @@ ...@@ -40,11 +41,8 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
/* Caller before callee in this file; other callee is in assembler */
void do_signal(struct pt_regs *regs);
long _sys_sigaltstack(const stack_t __user *uss, long _sys_sigaltstack(const stack_t __user *uss,
stack_t __user *uoss, struct pt_regs *regs) stack_t __user *uoss, struct pt_regs *regs)
{ {
return do_sigaltstack(uss, uoss, regs->sp); return do_sigaltstack(uss, uoss, regs->sp);
} }
...@@ -65,7 +63,7 @@ int restore_sigcontext(struct pt_regs *regs, ...@@ -65,7 +63,7 @@ int restore_sigcontext(struct pt_regs *regs,
for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
err |= __get_user(((long *)regs)[i], err |= __get_user(((long *)regs)[i],
&((long *)(&sc->regs))[i]); &((long __user *)(&sc->regs))[i]);
regs->faultnum = INT_SWINT_1_SIGRETURN; regs->faultnum = INT_SWINT_1_SIGRETURN;
...@@ -73,7 +71,8 @@ int restore_sigcontext(struct pt_regs *regs, ...@@ -73,7 +71,8 @@ int restore_sigcontext(struct pt_regs *regs,
return err; return err;
} }
int _sys_rt_sigreturn(struct pt_regs *regs) /* sigreturn() returns long since it restores r0 in the interrupted code. */
long _sys_rt_sigreturn(struct pt_regs *regs)
{ {
struct rt_sigframe __user *frame = struct rt_sigframe __user *frame =
(struct rt_sigframe __user *)(regs->sp); (struct rt_sigframe __user *)(regs->sp);
...@@ -114,7 +113,7 @@ int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs) ...@@ -114,7 +113,7 @@ int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
err |= __put_user(((long *)regs)[i], err |= __put_user(((long *)regs)[i],
&((long *)(&sc->regs))[i]); &((long __user *)(&sc->regs))[i]);
return err; return err;
} }
...@@ -137,7 +136,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, ...@@ -137,7 +136,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
* will die with SIGSEGV. * will die with SIGSEGV.
*/ */
if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
return (void __user *) -1L; return (void __user __force *)-1UL;
/* This is the X/Open sanctioned signal stack switching. */ /* This is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) { if (ka->sa.sa_flags & SA_ONSTACK) {
...@@ -185,8 +184,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -185,8 +184,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Create the ucontext. */ /* Create the ucontext. */
err |= __clear_user(&frame->save_area, sizeof(frame->save_area)); err |= __clear_user(&frame->save_area, sizeof(frame->save_area));
err |= __put_user(0, &frame->uc.uc_flags); err |= __put_user(0, &frame->uc.uc_flags);
err |= __put_user(0, &frame->uc.uc_link); err |= __put_user(NULL, &frame->uc.uc_link);
err |= __put_user((void *)(current->sas_ss_sp), err |= __put_user((void __user *)(current->sas_ss_sp),
&frame->uc.uc_stack.ss_sp); &frame->uc.uc_stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->sp), err |= __put_user(sas_ss_flags(regs->sp),
&frame->uc.uc_stack.ss_flags); &frame->uc.uc_stack.ss_flags);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/mman.h> #include <linux/mman.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/err.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/opcode-tile.h> #include <asm/opcode-tile.h>
#include <asm/opcode_constants.h> #include <asm/opcode_constants.h>
...@@ -39,8 +40,8 @@ static int __init setup_unaligned_printk(char *str) ...@@ -39,8 +40,8 @@ static int __init setup_unaligned_printk(char *str)
if (strict_strtol(str, 0, &val) != 0) if (strict_strtol(str, 0, &val) != 0)
return 0; return 0;
unaligned_printk = val; unaligned_printk = val;
printk("Printk for each unaligned data accesses is %s\n", pr_info("Printk for each unaligned data accesses is %s\n",
unaligned_printk ? "enabled" : "disabled"); unaligned_printk ? "enabled" : "disabled");
return 1; return 1;
} }
__setup("unaligned_printk=", setup_unaligned_printk); __setup("unaligned_printk=", setup_unaligned_printk);
...@@ -113,7 +114,7 @@ static tile_bundle_bits rewrite_load_store_unaligned( ...@@ -113,7 +114,7 @@ static tile_bundle_bits rewrite_load_store_unaligned(
enum mem_op mem_op, enum mem_op mem_op,
int size, int sign_ext) int size, int sign_ext)
{ {
unsigned char *addr; unsigned char __user *addr;
int val_reg, addr_reg, err, val; int val_reg, addr_reg, err, val;
/* Get address and value registers */ /* Get address and value registers */
...@@ -148,7 +149,7 @@ static tile_bundle_bits rewrite_load_store_unaligned( ...@@ -148,7 +149,7 @@ static tile_bundle_bits rewrite_load_store_unaligned(
return bundle; return bundle;
/* If it's aligned, don't handle it specially */ /* If it's aligned, don't handle it specially */
addr = (void *)regs->regs[addr_reg]; addr = (void __user *)regs->regs[addr_reg];
if (((unsigned long)addr % size) == 0) if (((unsigned long)addr % size) == 0)
return bundle; return bundle;
...@@ -183,7 +184,7 @@ static tile_bundle_bits rewrite_load_store_unaligned( ...@@ -183,7 +184,7 @@ static tile_bundle_bits rewrite_load_store_unaligned(
siginfo_t info = { siginfo_t info = {
.si_signo = SIGSEGV, .si_signo = SIGSEGV,
.si_code = SEGV_MAPERR, .si_code = SEGV_MAPERR,
.si_addr = (void __user *)addr .si_addr = addr
}; };
force_sig_info(info.si_signo, &info, current); force_sig_info(info.si_signo, &info, current);
return (tile_bundle_bits) 0; return (tile_bundle_bits) 0;
...@@ -193,30 +194,33 @@ static tile_bundle_bits rewrite_load_store_unaligned( ...@@ -193,30 +194,33 @@ static tile_bundle_bits rewrite_load_store_unaligned(
siginfo_t info = { siginfo_t info = {
.si_signo = SIGBUS, .si_signo = SIGBUS,
.si_code = BUS_ADRALN, .si_code = BUS_ADRALN,
.si_addr = (void __user *)addr .si_addr = addr
}; };
force_sig_info(info.si_signo, &info, current); force_sig_info(info.si_signo, &info, current);
return (tile_bundle_bits) 0; return (tile_bundle_bits) 0;
} }
if (unaligned_printk || unaligned_fixup_count == 0) { if (unaligned_printk || unaligned_fixup_count == 0) {
printk("Process %d/%s: PC %#lx: Fixup of" pr_info("Process %d/%s: PC %#lx: Fixup of"
" unaligned %s at %#lx.\n", " unaligned %s at %#lx.\n",
current->pid, current->comm, regs->pc, current->pid, current->comm, regs->pc,
(mem_op == MEMOP_LOAD || mem_op == MEMOP_LOAD_POSTINCR) ? (mem_op == MEMOP_LOAD ||
"load" : "store", mem_op == MEMOP_LOAD_POSTINCR) ?
(unsigned long)addr); "load" : "store",
(unsigned long)addr);
if (!unaligned_printk) { if (!unaligned_printk) {
printk("\n" #define P pr_info
"Unaligned fixups in the kernel will slow your application considerably.\n" P("\n");
"You can find them by writing \"1\" to /proc/sys/tile/unaligned_fixup/printk,\n" P("Unaligned fixups in the kernel will slow your application considerably.\n");
"which requests the kernel show all unaligned fixups, or writing a \"0\"\n" P("To find them, write a \"1\" to /proc/sys/tile/unaligned_fixup/printk,\n");
"to /proc/sys/tile/unaligned_fixup/enabled, in which case each unaligned\n" P("which requests the kernel show all unaligned fixups, or write a \"0\"\n");
"access will become a SIGBUS you can debug. No further warnings will be\n" P("to /proc/sys/tile/unaligned_fixup/enabled, in which case each unaligned\n");
"shown so as to avoid additional slowdown, but you can track the number\n" P("access will become a SIGBUS you can debug. No further warnings will be\n");
"of fixups performed via /proc/sys/tile/unaligned_fixup/count.\n" P("shown so as to avoid additional slowdown, but you can track the number\n");
"Use the tile-addr2line command (see \"info addr2line\") to decode PCs.\n" P("of fixups performed via /proc/sys/tile/unaligned_fixup/count.\n");
"\n"); P("Use the tile-addr2line command (see \"info addr2line\") to decode PCs.\n");
P("\n");
#undef P
} }
} }
++unaligned_fixup_count; ++unaligned_fixup_count;
...@@ -276,7 +280,7 @@ void single_step_once(struct pt_regs *regs) ...@@ -276,7 +280,7 @@ void single_step_once(struct pt_regs *regs)
struct thread_info *info = (void *)current_thread_info(); struct thread_info *info = (void *)current_thread_info();
struct single_step_state *state = info->step_state; struct single_step_state *state = info->step_state;
int is_single_step = test_ti_thread_flag(info, TIF_SINGLESTEP); int is_single_step = test_ti_thread_flag(info, TIF_SINGLESTEP);
tile_bundle_bits *buffer, *pc; tile_bundle_bits __user *buffer, *pc;
tile_bundle_bits bundle; tile_bundle_bits bundle;
int temp_reg; int temp_reg;
int target_reg = TREG_LR; int target_reg = TREG_LR;
...@@ -306,21 +310,21 @@ void single_step_once(struct pt_regs *regs) ...@@ -306,21 +310,21 @@ void single_step_once(struct pt_regs *regs)
/* allocate a page of writable, executable memory */ /* allocate a page of writable, executable memory */
state = kmalloc(sizeof(struct single_step_state), GFP_KERNEL); state = kmalloc(sizeof(struct single_step_state), GFP_KERNEL);
if (state == NULL) { if (state == NULL) {
printk("Out of kernel memory trying to single-step\n"); pr_err("Out of kernel memory trying to single-step\n");
return; return;
} }
/* allocate a cache line of writable, executable memory */ /* allocate a cache line of writable, executable memory */
down_write(&current->mm->mmap_sem); down_write(&current->mm->mmap_sem);
buffer = (void *) do_mmap(0, 0, 64, buffer = (void __user *) do_mmap(NULL, 0, 64,
PROT_EXEC | PROT_READ | PROT_WRITE, PROT_EXEC | PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, MAP_PRIVATE | MAP_ANONYMOUS,
0); 0);
up_write(&current->mm->mmap_sem); up_write(&current->mm->mmap_sem);
if ((int)buffer < 0 && (int)buffer > -PAGE_SIZE) { if (IS_ERR((void __force *)buffer)) {
kfree(state); kfree(state);
printk("Out of kernel pages trying to single-step\n"); pr_err("Out of kernel pages trying to single-step\n");
return; return;
} }
...@@ -349,11 +353,14 @@ void single_step_once(struct pt_regs *regs) ...@@ -349,11 +353,14 @@ void single_step_once(struct pt_regs *regs)
if (regs->faultnum == INT_SWINT_1) if (regs->faultnum == INT_SWINT_1)
regs->pc -= 8; regs->pc -= 8;
pc = (tile_bundle_bits *)(regs->pc); pc = (tile_bundle_bits __user *)(regs->pc);
bundle = pc[0]; if (get_user(bundle, pc) != 0) {
pr_err("Couldn't read instruction at %p trying to step\n", pc);
return;
}
/* We'll follow the instruction with 2 ill op bundles */ /* We'll follow the instruction with 2 ill op bundles */
state->orig_pc = (unsigned long) pc; state->orig_pc = (unsigned long)pc;
state->next_pc = (unsigned long)(pc + 1); state->next_pc = (unsigned long)(pc + 1);
state->branch_next_pc = 0; state->branch_next_pc = 0;
state->update = 0; state->update = 0;
...@@ -633,7 +640,7 @@ void single_step_once(struct pt_regs *regs) ...@@ -633,7 +640,7 @@ void single_step_once(struct pt_regs *regs)
} }
if (err) { if (err) {
printk("Fault when writing to single-step buffer\n"); pr_err("Fault when writing to single-step buffer\n");
return; return;
} }
...@@ -641,12 +648,12 @@ void single_step_once(struct pt_regs *regs) ...@@ -641,12 +648,12 @@ void single_step_once(struct pt_regs *regs)
* Flush the buffer. * Flush the buffer.
* We do a local flush only, since this is a thread-specific buffer. * We do a local flush only, since this is a thread-specific buffer.
*/ */
__flush_icache_range((unsigned long) state->buffer, __flush_icache_range((unsigned long)state->buffer,
(unsigned long) buffer); (unsigned long)buffer);
/* Indicate enabled */ /* Indicate enabled */
state->is_enabled = is_single_step; state->is_enabled = is_single_step;
regs->pc = (unsigned long) state->buffer; regs->pc = (unsigned long)state->buffer;
/* Fault immediately if we are coming back from a syscall. */ /* Fault immediately if we are coming back from a syscall. */
if (regs->faultnum == INT_SWINT_1) if (regs->faultnum == INT_SWINT_1)
......
...@@ -25,19 +25,13 @@ ...@@ -25,19 +25,13 @@
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/irq.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/sections.h> #include <asm/sections.h>
/*
* This assembly function is provided in entry.S.
* When called, it loops on a nap instruction forever.
* FIXME: should be in a header somewhere.
*/
extern void smp_nap(void);
/* State of each CPU. */ /* State of each CPU. */
DEFINE_PER_CPU(int, cpu_state) = { 0 }; static DEFINE_PER_CPU(int, cpu_state) = { 0 };
/* The messaging code jumps to this pointer during boot-up */ /* The messaging code jumps to this pointer during boot-up */
unsigned long start_cpu_function_addr; unsigned long start_cpu_function_addr;
...@@ -74,7 +68,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -74,7 +68,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
*/ */
rc = sched_setaffinity(current->pid, cpumask_of(boot_cpu)); rc = sched_setaffinity(current->pid, cpumask_of(boot_cpu));
if (rc != 0) if (rc != 0)
printk("Couldn't set init affinity to boot cpu (%ld)\n", rc); pr_err("Couldn't set init affinity to boot cpu (%ld)\n", rc);
/* Print information about disabled and dataplane cpus. */ /* Print information about disabled and dataplane cpus. */
print_disabled_cpus(); print_disabled_cpus();
...@@ -134,13 +128,13 @@ static __init int reset_init_affinity(void) ...@@ -134,13 +128,13 @@ static __init int reset_init_affinity(void)
{ {
long rc = sched_setaffinity(current->pid, &init_affinity); long rc = sched_setaffinity(current->pid, &init_affinity);
if (rc != 0) if (rc != 0)
printk(KERN_WARNING "couldn't reset init affinity (%ld)\n", pr_warning("couldn't reset init affinity (%ld)\n",
rc); rc);
return 0; return 0;
} }
late_initcall(reset_init_affinity); late_initcall(reset_init_affinity);
struct cpumask cpu_started __cpuinitdata; static struct cpumask cpu_started __cpuinitdata;
/* /*
* Activate a secondary processor. Very minimal; don't add anything * Activate a secondary processor. Very minimal; don't add anything
...@@ -172,9 +166,6 @@ static void __cpuinit start_secondary(void) ...@@ -172,9 +166,6 @@ static void __cpuinit start_secondary(void)
BUG(); BUG();
enter_lazy_tlb(&init_mm, current); enter_lazy_tlb(&init_mm, current);
/* Enable IRQs. */
init_per_tile_IRQs();
/* Allow hypervisor messages to be received */ /* Allow hypervisor messages to be received */
init_messaging(); init_messaging();
local_irq_enable(); local_irq_enable();
...@@ -182,7 +173,7 @@ static void __cpuinit start_secondary(void) ...@@ -182,7 +173,7 @@ static void __cpuinit start_secondary(void)
/* Indicate that we're ready to come up. */ /* Indicate that we're ready to come up. */
/* Must not do this before we're ready to receive messages */ /* Must not do this before we're ready to receive messages */
if (cpumask_test_and_set_cpu(cpuid, &cpu_started)) { if (cpumask_test_and_set_cpu(cpuid, &cpu_started)) {
printk(KERN_WARNING "CPU#%d already started!\n", cpuid); pr_warning("CPU#%d already started!\n", cpuid);
for (;;) for (;;)
local_irq_enable(); local_irq_enable();
} }
...@@ -190,13 +181,10 @@ static void __cpuinit start_secondary(void) ...@@ -190,13 +181,10 @@ static void __cpuinit start_secondary(void)
smp_nap(); smp_nap();
} }
void setup_mpls(void); /* from kernel/setup.c */
void store_permanent_mappings(void);
/* /*
* Bring a secondary processor online. * Bring a secondary processor online.
*/ */
void __cpuinit online_secondary() void __cpuinit online_secondary(void)
{ {
/* /*
* low-memory mappings have been cleared, flush them from * low-memory mappings have been cleared, flush them from
...@@ -222,17 +210,14 @@ void __cpuinit online_secondary() ...@@ -222,17 +210,14 @@ void __cpuinit online_secondary()
ipi_call_unlock(); ipi_call_unlock();
__get_cpu_var(cpu_state) = CPU_ONLINE; __get_cpu_var(cpu_state) = CPU_ONLINE;
/* Set up MPLs for this processor */ /* Set up tile-specific state for this cpu. */
setup_mpls(); setup_cpu(0);
/* Set up tile-timer clock-event device on this cpu */ /* Set up tile-timer clock-event device on this cpu */
setup_tile_timer(); setup_tile_timer();
preempt_enable(); preempt_enable();
store_permanent_mappings();
cpu_idle(); cpu_idle();
} }
...@@ -242,7 +227,7 @@ int __cpuinit __cpu_up(unsigned int cpu) ...@@ -242,7 +227,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
static int timeout; static int timeout;
for (; !cpumask_test_cpu(cpu, &cpu_started); timeout++) { for (; !cpumask_test_cpu(cpu, &cpu_started); timeout++) {
if (timeout >= 50000) { if (timeout >= 50000) {
printk(KERN_INFO "skipping unresponsive cpu%d\n", cpu); pr_info("skipping unresponsive cpu%d\n", cpu);
local_irq_enable(); local_irq_enable();
return -EIO; return -EIO;
} }
...@@ -289,5 +274,5 @@ void __init smp_cpus_done(unsigned int max_cpus) ...@@ -289,5 +274,5 @@ void __init smp_cpus_done(unsigned int max_cpus)
; ;
rc = sched_setaffinity(current->pid, cpumask_of(cpu)); rc = sched_setaffinity(current->pid, cpumask_of(cpu));
if (rc != 0) if (rc != 0)
printk("Couldn't set init affinity to cpu %d (%d)\n", cpu, rc); pr_err("Couldn't set init affinity to cpu %d (%d)\n", cpu, rc);
} }
...@@ -56,13 +56,16 @@ static int valid_address(struct KBacktraceIterator *kbt, VirtualAddress address) ...@@ -56,13 +56,16 @@ static int valid_address(struct KBacktraceIterator *kbt, VirtualAddress address)
HV_PTE pte; HV_PTE pte;
struct page *page; struct page *page;
if (l1_pgtable == NULL)
return 0; /* can't read user space in other tasks */
pte = l1_pgtable[HV_L1_INDEX(address)]; pte = l1_pgtable[HV_L1_INDEX(address)];
if (!hv_pte_get_present(pte)) if (!hv_pte_get_present(pte))
return 0; return 0;
pfn = hv_pte_get_pfn(pte); pfn = hv_pte_get_pfn(pte);
if (pte_huge(pte)) { if (pte_huge(pte)) {
if (!pfn_valid(pfn)) { if (!pfn_valid(pfn)) {
printk(KERN_ERR "huge page has bad pfn %#lx\n", pfn); pr_err("huge page has bad pfn %#lx\n", pfn);
return 0; return 0;
} }
return hv_pte_get_present(pte) && hv_pte_get_readable(pte); return hv_pte_get_present(pte) && hv_pte_get_readable(pte);
...@@ -70,7 +73,7 @@ static int valid_address(struct KBacktraceIterator *kbt, VirtualAddress address) ...@@ -70,7 +73,7 @@ static int valid_address(struct KBacktraceIterator *kbt, VirtualAddress address)
page = pfn_to_page(pfn); page = pfn_to_page(pfn);
if (PageHighMem(page)) { if (PageHighMem(page)) {
printk(KERN_ERR "L2 page table not in LOWMEM (%#llx)\n", pr_err("L2 page table not in LOWMEM (%#llx)\n",
HV_PFN_TO_CPA(pfn)); HV_PFN_TO_CPA(pfn));
return 0; return 0;
} }
...@@ -91,13 +94,12 @@ static bool read_memory_func(void *result, VirtualAddress address, ...@@ -91,13 +94,12 @@ static bool read_memory_func(void *result, VirtualAddress address,
/* We only tolerate kernel-space reads of this task's stack */ /* We only tolerate kernel-space reads of this task's stack */
if (!in_kernel_stack(kbt, address)) if (!in_kernel_stack(kbt, address))
return 0; return 0;
} else if (kbt->pgtable == NULL) {
return 0; /* can't read user space in other tasks */
} else if (!valid_address(kbt, address)) { } else if (!valid_address(kbt, address)) {
return 0; /* invalid user-space address */ return 0; /* invalid user-space address */
} }
pagefault_disable(); pagefault_disable();
retval = __copy_from_user_inatomic(result, (const void *)address, retval = __copy_from_user_inatomic(result,
(void __user __force *)address,
size); size);
pagefault_enable(); pagefault_enable();
return (retval == 0); return (retval == 0);
...@@ -131,14 +133,14 @@ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt) ...@@ -131,14 +133,14 @@ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt)
in_kernel_stack(kbt, p->sp) && in_kernel_stack(kbt, p->sp) &&
p->sp >= sp) { p->sp >= sp) {
if (kbt->verbose) if (kbt->verbose)
printk(KERN_ERR " <%s while in kernel mode>\n", fault); pr_err(" <%s while in kernel mode>\n", fault);
} else if (EX1_PL(p->ex1) == USER_PL && } else if (EX1_PL(p->ex1) == USER_PL &&
p->pc < PAGE_OFFSET && p->pc < PAGE_OFFSET &&
p->sp < PAGE_OFFSET) { p->sp < PAGE_OFFSET) {
if (kbt->verbose) if (kbt->verbose)
printk(KERN_ERR " <%s while in user mode>\n", fault); pr_err(" <%s while in user mode>\n", fault);
} else if (kbt->verbose) { } else if (kbt->verbose) {
printk(KERN_ERR " (odd fault: pc %#lx, sp %#lx, ex1 %#lx?)\n", pr_err(" (odd fault: pc %#lx, sp %#lx, ex1 %#lx?)\n",
p->pc, p->sp, p->ex1); p->pc, p->sp, p->ex1);
p = NULL; p = NULL;
} }
...@@ -166,13 +168,13 @@ static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt) ...@@ -166,13 +168,13 @@ static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt)
if (!valid_address(kbt, b->sp) || if (!valid_address(kbt, b->sp) ||
!valid_address(kbt, sigframe_top)) { !valid_address(kbt, sigframe_top)) {
if (kbt->verbose) if (kbt->verbose)
printk(" (odd signal: sp %#lx?)\n", pr_err(" (odd signal: sp %#lx?)\n",
(unsigned long)(b->sp)); (unsigned long)(b->sp));
return NULL; return NULL;
} }
frame = (struct rt_sigframe *)b->sp; frame = (struct rt_sigframe *)b->sp;
if (kbt->verbose) { if (kbt->verbose) {
printk(KERN_ERR " <received signal %d>\n", pr_err(" <received signal %d>\n",
frame->info.si_signo); frame->info.si_signo);
} }
return &frame->uc.uc_mcontext.regs; return &frame->uc.uc_mcontext.regs;
...@@ -180,7 +182,7 @@ static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt) ...@@ -180,7 +182,7 @@ static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt)
return NULL; return NULL;
} }
int KBacktraceIterator_is_sigreturn(struct KBacktraceIterator *kbt) static int KBacktraceIterator_is_sigreturn(struct KBacktraceIterator *kbt)
{ {
return is_sigreturn(kbt->it.pc); return is_sigreturn(kbt->it.pc);
} }
...@@ -231,13 +233,13 @@ static void validate_stack(struct pt_regs *regs) ...@@ -231,13 +233,13 @@ static void validate_stack(struct pt_regs *regs)
unsigned long sp = stack_pointer; unsigned long sp = stack_pointer;
if (EX1_PL(regs->ex1) == KERNEL_PL && regs->sp >= ksp0) { if (EX1_PL(regs->ex1) == KERNEL_PL && regs->sp >= ksp0) {
printk("WARNING: cpu %d: kernel stack page %#lx underrun!\n" pr_err("WARNING: cpu %d: kernel stack page %#lx underrun!\n"
" sp %#lx (%#lx in caller), caller pc %#lx, lr %#lx\n", " sp %#lx (%#lx in caller), caller pc %#lx, lr %#lx\n",
cpu, ksp0_base, sp, regs->sp, regs->pc, regs->lr); cpu, ksp0_base, sp, regs->sp, regs->pc, regs->lr);
} }
else if (sp < ksp0_base + sizeof(struct thread_info)) { else if (sp < ksp0_base + sizeof(struct thread_info)) {
printk("WARNING: cpu %d: kernel stack page %#lx overrun!\n" pr_err("WARNING: cpu %d: kernel stack page %#lx overrun!\n"
" sp %#lx (%#lx in caller), caller pc %#lx, lr %#lx\n", " sp %#lx (%#lx in caller), caller pc %#lx, lr %#lx\n",
cpu, ksp0_base, sp, regs->sp, regs->pc, regs->lr); cpu, ksp0_base, sp, regs->sp, regs->pc, regs->lr);
} }
...@@ -280,7 +282,7 @@ void KBacktraceIterator_init(struct KBacktraceIterator *kbt, ...@@ -280,7 +282,7 @@ void KBacktraceIterator_init(struct KBacktraceIterator *kbt,
if (!PageHighMem(page)) if (!PageHighMem(page))
kbt->pgtable = __va(pgdir_pa); kbt->pgtable = __va(pgdir_pa);
else else
printk(KERN_ERR "page table not in LOWMEM" pr_err("page table not in LOWMEM"
" (%#llx)\n", pgdir_pa); " (%#llx)\n", pgdir_pa);
} }
local_flush_tlb_all(); local_flush_tlb_all();
...@@ -288,13 +290,12 @@ void KBacktraceIterator_init(struct KBacktraceIterator *kbt, ...@@ -288,13 +290,12 @@ void KBacktraceIterator_init(struct KBacktraceIterator *kbt,
} }
if (regs == NULL) { if (regs == NULL) {
extern const void *get_switch_to_pc(void);
if (is_current || t->state == TASK_RUNNING) { if (is_current || t->state == TASK_RUNNING) {
/* Can't do this; we need registers */ /* Can't do this; we need registers */
kbt->end = 1; kbt->end = 1;
return; return;
} }
pc = (ulong) get_switch_to_pc(); pc = get_switch_to_pc();
lr = t->thread.pc; lr = t->thread.pc;
sp = t->thread.ksp; sp = t->thread.ksp;
r52 = 0; r52 = 0;
...@@ -344,8 +345,8 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers) ...@@ -344,8 +345,8 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers)
* then bust_spinlocks() spit out a space in front of us * then bust_spinlocks() spit out a space in front of us
* and it will mess up our KERN_ERR. * and it will mess up our KERN_ERR.
*/ */
printk("\n"); pr_err("\n");
printk(KERN_ERR "Starting stack dump of tid %d, pid %d (%s)" pr_err("Starting stack dump of tid %d, pid %d (%s)"
" on cpu %d at cycle %lld\n", " on cpu %d at cycle %lld\n",
kbt->task->pid, kbt->task->tgid, kbt->task->comm, kbt->task->pid, kbt->task->tgid, kbt->task->comm,
smp_processor_id(), get_cycles()); smp_processor_id(), get_cycles());
...@@ -385,17 +386,17 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers) ...@@ -385,17 +386,17 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers)
namebuf[sizeof(namebuf)-1] = '\0'; namebuf[sizeof(namebuf)-1] = '\0';
} }
printk(KERN_ERR " frame %d: 0x%lx %s(sp 0x%lx)\n", pr_err(" frame %d: 0x%lx %s(sp 0x%lx)\n",
i++, address, namebuf, (unsigned long)(kbt->it.sp)); i++, address, namebuf, (unsigned long)(kbt->it.sp));
if (i >= 100) { if (i >= 100) {
printk(KERN_ERR "Stack dump truncated" pr_err("Stack dump truncated"
" (%d frames)\n", i); " (%d frames)\n", i);
break; break;
} }
} }
if (headers) if (headers)
printk(KERN_ERR "Stack dump complete\n"); pr_err("Stack dump complete\n");
} }
EXPORT_SYMBOL(tile_show_stack); EXPORT_SYMBOL(tile_show_stack);
......
...@@ -27,11 +27,10 @@ ...@@ -27,11 +27,10 @@
#include <linux/mempolicy.h> #include <linux/mempolicy.h>
#include <linux/binfmts.h> #include <linux/binfmts.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/syscalls.h> #include <linux/compat.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <asm/syscalls.h> #include <asm/syscalls.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/homecache.h> #include <asm/homecache.h>
#include <arch/chip.h> #include <arch/chip.h>
...@@ -74,10 +73,7 @@ int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi, ...@@ -74,10 +73,7 @@ int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi,
#endif /* 32-bit syscall wrappers */ #endif /* 32-bit syscall wrappers */
/* /* Note: used by the compat code even in 64-bit Linux. */
* This API uses a 4KB-page-count offset into the file descriptor.
* It is likely not the right API to use on a 64-bit platform.
*/
SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags, unsigned long, prot, unsigned long, flags,
unsigned long, fd, unsigned long, off_4k) unsigned long, fd, unsigned long, off_4k)
...@@ -89,10 +85,7 @@ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, ...@@ -89,10 +85,7 @@ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
off_4k >> PAGE_ADJUST); off_4k >> PAGE_ADJUST);
} }
/* #ifdef __tilegx__
* This API uses a byte offset into the file descriptor.
* It is likely not the right API to use on a 32-bit platform.
*/
SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags, unsigned long, prot, unsigned long, flags,
unsigned long, fd, off_t, offset) unsigned long, fd, off_t, offset)
...@@ -102,6 +95,7 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, ...@@ -102,6 +95,7 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
return sys_mmap_pgoff(addr, len, prot, flags, fd, return sys_mmap_pgoff(addr, len, prot, flags, fd,
offset >> PAGE_SHIFT); offset >> PAGE_SHIFT);
} }
#endif
/* Provide the actual syscall number to call mapping. */ /* Provide the actual syscall number to call mapping. */
...@@ -116,6 +110,10 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, ...@@ -116,6 +110,10 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
#define sys_sync_file_range sys_sync_file_range2 #define sys_sync_file_range sys_sync_file_range2
#endif #endif
/*
* Note that we can't include <linux/unistd.h> here since the header
* guard will defeat us; <asm/unistd.h> checks for __SYSCALL as well.
*/
void *sys_call_table[__NR_syscalls] = { void *sys_call_table[__NR_syscalls] = {
[0 ... __NR_syscalls-1] = sys_ni_syscall, [0 ... __NR_syscalls-1] = sys_ni_syscall,
#include <asm/unistd.h> #include <asm/unistd.h>
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <asm/irq_regs.h> #include <asm/irq_regs.h>
#include <asm/traps.h>
#include <hv/hypervisor.h> #include <hv/hypervisor.h>
#include <arch/interrupts.h> #include <arch/interrupts.h>
#include <arch/spr_def.h> #include <arch/spr_def.h>
...@@ -45,13 +46,13 @@ static cycles_t cycles_per_sec __write_once; ...@@ -45,13 +46,13 @@ static cycles_t cycles_per_sec __write_once;
*/ */
#define TILE_MINSEC 5 #define TILE_MINSEC 5
cycles_t get_clock_rate() cycles_t get_clock_rate(void)
{ {
return cycles_per_sec; return cycles_per_sec;
} }
#if CHIP_HAS_SPLIT_CYCLE() #if CHIP_HAS_SPLIT_CYCLE()
cycles_t get_cycles() cycles_t get_cycles(void)
{ {
unsigned int high = __insn_mfspr(SPR_CYCLE_HIGH); unsigned int high = __insn_mfspr(SPR_CYCLE_HIGH);
unsigned int low = __insn_mfspr(SPR_CYCLE_LOW); unsigned int low = __insn_mfspr(SPR_CYCLE_LOW);
...@@ -67,7 +68,7 @@ cycles_t get_cycles() ...@@ -67,7 +68,7 @@ cycles_t get_cycles()
} }
#endif #endif
cycles_t clocksource_get_cycles(struct clocksource *cs) static cycles_t clocksource_get_cycles(struct clocksource *cs)
{ {
return get_cycles(); return get_cycles();
} }
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <asm/opcode-tile.h> #include <asm/opcode-tile.h>
#include <asm/opcode_constants.h>
#include <asm/stack.h>
#include <asm/traps.h>
#include <arch/interrupts.h> #include <arch/interrupts.h>
#include <arch/spr_def.h> #include <arch/spr_def.h>
...@@ -42,7 +45,7 @@ static int __init setup_unaligned_fixup(char *str) ...@@ -42,7 +45,7 @@ static int __init setup_unaligned_fixup(char *str)
if (strict_strtol(str, 0, &val) != 0) if (strict_strtol(str, 0, &val) != 0)
return 0; return 0;
unaligned_fixup = val; unaligned_fixup = val;
printk("Fixups for unaligned data accesses are %s\n", pr_info("Fixups for unaligned data accesses are %s\n",
unaligned_fixup >= 0 ? unaligned_fixup >= 0 ?
(unaligned_fixup ? "enabled" : "disabled") : (unaligned_fixup ? "enabled" : "disabled") :
"completely disabled"); "completely disabled");
...@@ -56,7 +59,7 @@ static int dma_disabled; ...@@ -56,7 +59,7 @@ static int dma_disabled;
static int __init nodma(char *str) static int __init nodma(char *str)
{ {
printk("User-space DMA is disabled\n"); pr_info("User-space DMA is disabled\n");
dma_disabled = 1; dma_disabled = 1;
return 1; return 1;
} }
...@@ -97,20 +100,106 @@ static int retry_gpv(unsigned int gpv_reason) ...@@ -97,20 +100,106 @@ static int retry_gpv(unsigned int gpv_reason)
#endif /* CHIP_HAS_TILE_DMA() */ #endif /* CHIP_HAS_TILE_DMA() */
/* Defined inside do_trap(), below. */
#ifdef __tilegx__ #ifdef __tilegx__
extern tilegx_bundle_bits bpt_code; #define bundle_bits tilegx_bundle_bits
#else #else
extern tile_bundle_bits bpt_code; #define bundle_bits tile_bundle_bits
#endif #endif
extern bundle_bits bpt_code;
asm(".pushsection .rodata.bpt_code,\"a\";"
".align 8;"
"bpt_code: bpt;"
".size bpt_code,.-bpt_code;"
".popsection");
static int special_ill(bundle_bits bundle, int *sigp, int *codep)
{
int sig, code, maxcode;
if (bundle == bpt_code) {
*sigp = SIGTRAP;
*codep = TRAP_BRKPT;
return 1;
}
/* If it's a "raise" bundle, then "ill" must be in pipe X1. */
#ifdef __tilegx__
if ((bundle & TILEGX_BUNDLE_MODE_MASK) != 0)
return 0;
if (get_Opcode_X1(bundle) != UNARY_OPCODE_X1)
return 0;
if (get_UnaryOpcodeExtension_X1(bundle) != ILL_UNARY_OPCODE_X1)
return 0;
#else
if (bundle & TILE_BUNDLE_Y_ENCODING_MASK)
return 0;
if (get_Opcode_X1(bundle) != SHUN_0_OPCODE_X1)
return 0;
if (get_UnShOpcodeExtension_X1(bundle) != UN_0_SHUN_0_OPCODE_X1)
return 0;
if (get_UnOpcodeExtension_X1(bundle) != ILL_UN_0_SHUN_0_OPCODE_X1)
return 0;
#endif
/* Check that the magic distinguishers are set to mean "raise". */
if (get_Dest_X1(bundle) != 29 || get_SrcA_X1(bundle) != 37)
return 0;
/* There must be an "addli zero, zero, VAL" in X0. */
if (get_Opcode_X0(bundle) != ADDLI_OPCODE_X0)
return 0;
if (get_Dest_X0(bundle) != TREG_ZERO)
return 0;
if (get_SrcA_X0(bundle) != TREG_ZERO)
return 0;
/*
* Validate the proposed signal number and si_code value.
* Note that we embed these in the static instruction itself
* so that we perturb the register state as little as possible
* at the time of the actual fault; it's unlikely you'd ever
* need to dynamically choose which kind of fault to raise
* from user space.
*/
sig = get_Imm16_X0(bundle) & 0x3f;
switch (sig) {
case SIGILL:
maxcode = NSIGILL;
break;
case SIGFPE:
maxcode = NSIGFPE;
break;
case SIGSEGV:
maxcode = NSIGSEGV;
break;
case SIGBUS:
maxcode = NSIGBUS;
break;
case SIGTRAP:
maxcode = NSIGTRAP;
break;
default:
return 0;
}
code = (get_Imm16_X0(bundle) >> 6) & 0xf;
if (code <= 0 || code > maxcode)
return 0;
/* Make it the requested signal. */
*sigp = sig;
*codep = code | __SI_FAULT;
return 1;
}
void __kprobes do_trap(struct pt_regs *regs, int fault_num, void __kprobes do_trap(struct pt_regs *regs, int fault_num,
unsigned long reason) unsigned long reason)
{ {
siginfo_t info = { 0 }; siginfo_t info = { 0 };
int signo, code; int signo, code;
unsigned long address; unsigned long address;
__typeof__(bpt_code) instr; bundle_bits instr;
/* Re-enable interrupts. */ /* Re-enable interrupts. */
local_irq_enable(); local_irq_enable();
...@@ -122,10 +211,10 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, ...@@ -122,10 +211,10 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
if (!user_mode(regs)) { if (!user_mode(regs)) {
if (fixup_exception(regs)) /* only UNALIGN_DATA in practice */ if (fixup_exception(regs)) /* only UNALIGN_DATA in practice */
return; return;
printk(KERN_ALERT "Kernel took bad trap %d at PC %#lx\n", pr_alert("Kernel took bad trap %d at PC %#lx\n",
fault_num, regs->pc); fault_num, regs->pc);
if (fault_num == INT_GPV) if (fault_num == INT_GPV)
printk(KERN_ALERT "GPV_REASON is %#lx\n", reason); pr_alert("GPV_REASON is %#lx\n", reason);
show_regs(regs); show_regs(regs);
do_exit(SIGKILL); /* FIXME: implement i386 die() */ do_exit(SIGKILL); /* FIXME: implement i386 die() */
return; return;
...@@ -133,22 +222,14 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, ...@@ -133,22 +222,14 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
switch (fault_num) { switch (fault_num) {
case INT_ILL: case INT_ILL:
asm(".pushsection .rodata.bpt_code,\"a\";" if (copy_from_user(&instr, (void __user *)regs->pc,
".align 8;" sizeof(instr))) {
"bpt_code: bpt;" pr_err("Unreadable instruction for INT_ILL:"
".size bpt_code,.-bpt_code;"
".popsection");
if (copy_from_user(&instr, (void *)regs->pc, sizeof(instr))) {
printk(KERN_ERR "Unreadable instruction for INT_ILL:"
" %#lx\n", regs->pc); " %#lx\n", regs->pc);
do_exit(SIGKILL); do_exit(SIGKILL);
return; return;
} }
if (instr == bpt_code) { if (!special_ill(instr, &signo, &code)) {
signo = SIGTRAP;
code = TRAP_BRKPT;
} else {
signo = SIGILL; signo = SIGILL;
code = ILL_ILLOPC; code = ILL_ILLOPC;
} }
...@@ -181,7 +262,8 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, ...@@ -181,7 +262,8 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
if (unaligned_fixup >= 0) { if (unaligned_fixup >= 0) {
struct single_step_state *state = struct single_step_state *state =
current_thread_info()->step_state; current_thread_info()->step_state;
if (!state || (void *)(regs->pc) != state->buffer) { if (!state ||
(void __user *)(regs->pc) != state->buffer) {
single_step_once(regs); single_step_once(regs);
return; return;
} }
...@@ -221,17 +303,15 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, ...@@ -221,17 +303,15 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
info.si_signo = signo; info.si_signo = signo;
info.si_code = code; info.si_code = code;
info.si_addr = (void *)address; info.si_addr = (void __user *)address;
if (signo == SIGILL) if (signo == SIGILL)
info.si_trapno = fault_num; info.si_trapno = fault_num;
force_sig_info(signo, &info, current); force_sig_info(signo, &info, current);
} }
extern void _dump_stack(int dummy, ulong pc, ulong lr, ulong sp, ulong r52);
void kernel_double_fault(int dummy, ulong pc, ulong lr, ulong sp, ulong r52) void kernel_double_fault(int dummy, ulong pc, ulong lr, ulong sp, ulong r52)
{ {
_dump_stack(dummy, pc, lr, sp, r52); _dump_stack(dummy, pc, lr, sp, r52);
printk("Double fault: exiting\n"); pr_emerg("Double fault: exiting\n");
machine_halt(); machine_halt();
} }
...@@ -36,8 +36,8 @@ SECTIONS ...@@ -36,8 +36,8 @@ SECTIONS
/* Now the real code */ /* Now the real code */
. = ALIGN(0x20000); . = ALIGN(0x20000);
HEAD_TEXT_SECTION :text =0
.text : AT (ADDR(.text) - LOAD_OFFSET) { .text : AT (ADDR(.text) - LOAD_OFFSET) {
HEAD_TEXT
SCHED_TEXT SCHED_TEXT
LOCK_TEXT LOCK_TEXT
__fix_text_end = .; /* tile-cpack won't rearrange before this */ __fix_text_end = .; /* tile-cpack won't rearrange before this */
...@@ -46,7 +46,7 @@ SECTIONS ...@@ -46,7 +46,7 @@ SECTIONS
*(.coldtext*) *(.coldtext*)
*(.fixup) *(.fixup)
*(.gnu.warning) *(.gnu.warning)
} } :text =0
_etext = .; _etext = .;
/* "Init" is divided into two areas with very different virtual addresses. */ /* "Init" is divided into two areas with very different virtual addresses. */
......
...@@ -18,27 +18,10 @@ ...@@ -18,27 +18,10 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/futex.h>
#include <arch/chip.h> #include <arch/chip.h>
/* The routines in atomic_asm.S are private, so we only declare them here. */ /* See <asm/atomic_32.h> */
extern struct __get_user __atomic_cmpxchg(volatile int *p,
int *lock, int o, int n);
extern struct __get_user __atomic_xchg(volatile int *p, int *lock, int n);
extern struct __get_user __atomic_xchg_add(volatile int *p, int *lock, int n);
extern struct __get_user __atomic_xchg_add_unless(volatile int *p,
int *lock, int o, int n);
extern struct __get_user __atomic_or(volatile int *p, int *lock, int n);
extern struct __get_user __atomic_andn(volatile int *p, int *lock, int n);
extern struct __get_user __atomic_xor(volatile int *p, int *lock, int n);
extern u64 __atomic64_cmpxchg(volatile u64 *p, int *lock, u64 o, u64 n);
extern u64 __atomic64_xchg(volatile u64 *p, int *lock, u64 n);
extern u64 __atomic64_xchg_add(volatile u64 *p, int *lock, u64 n);
extern u64 __atomic64_xchg_add_unless(volatile u64 *p,
int *lock, u64 o, u64 n);
/* See <asm/atomic.h> */
#if ATOMIC_LOCKS_FOUND_VIA_TABLE() #if ATOMIC_LOCKS_FOUND_VIA_TABLE()
/* /*
...@@ -209,7 +192,7 @@ u64 _atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n) ...@@ -209,7 +192,7 @@ u64 _atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n)
EXPORT_SYMBOL(_atomic64_cmpxchg); EXPORT_SYMBOL(_atomic64_cmpxchg);
static inline int *__futex_setup(__user int *v) static inline int *__futex_setup(int __user *v)
{ {
/* /*
* Issue a prefetch to the counter to bring it into cache. * Issue a prefetch to the counter to bring it into cache.
...@@ -217,37 +200,37 @@ static inline int *__futex_setup(__user int *v) ...@@ -217,37 +200,37 @@ static inline int *__futex_setup(__user int *v)
* since it might fault; instead we do a prefetch into the L2. * since it might fault; instead we do a prefetch into the L2.
*/ */
__insn_prefetch(v); __insn_prefetch(v);
return __atomic_hashed_lock(v); return __atomic_hashed_lock((int __force *)v);
} }
struct __get_user futex_set(int *v, int i) struct __get_user futex_set(int __user *v, int i)
{ {
return __atomic_xchg(v, __futex_setup(v), i); return __atomic_xchg((int __force *)v, __futex_setup(v), i);
} }
struct __get_user futex_add(int *v, int n) struct __get_user futex_add(int __user *v, int n)
{ {
return __atomic_xchg_add(v, __futex_setup(v), n); return __atomic_xchg_add((int __force *)v, __futex_setup(v), n);
} }
struct __get_user futex_or(int *v, int n) struct __get_user futex_or(int __user *v, int n)
{ {
return __atomic_or(v, __futex_setup(v), n); return __atomic_or((int __force *)v, __futex_setup(v), n);
} }
struct __get_user futex_andn(int *v, int n) struct __get_user futex_andn(int __user *v, int n)
{ {
return __atomic_andn(v, __futex_setup(v), n); return __atomic_andn((int __force *)v, __futex_setup(v), n);
} }
struct __get_user futex_xor(int *v, int n) struct __get_user futex_xor(int __user *v, int n)
{ {
return __atomic_xor(v, __futex_setup(v), n); return __atomic_xor((int __force *)v, __futex_setup(v), n);
} }
struct __get_user futex_cmpxchg(int *v, int o, int n) struct __get_user futex_cmpxchg(int __user *v, int o, int n)
{ {
return __atomic_cmpxchg(v, __futex_setup(v), o, n); return __atomic_cmpxchg((int __force *)v, __futex_setup(v), o, n);
} }
/* /*
...@@ -260,7 +243,7 @@ struct __get_user futex_cmpxchg(int *v, int o, int n) ...@@ -260,7 +243,7 @@ struct __get_user futex_cmpxchg(int *v, int o, int n)
* invoked in is the context of the "_atomic_xxx()" routines called * invoked in is the context of the "_atomic_xxx()" routines called
* by the functions in this file. * by the functions in this file.
*/ */
struct __get_user __atomic_bad_address(int *addr) struct __get_user __atomic_bad_address(int __user *addr)
{ {
if (unlikely(!access_ok(VERIFY_WRITE, addr, sizeof(int)))) if (unlikely(!access_ok(VERIFY_WRITE, addr, sizeof(int))))
panic("Bad address used for kernel atomic op: %p\n", addr); panic("Bad address used for kernel atomic op: %p\n", addr);
...@@ -271,7 +254,7 @@ struct __get_user __atomic_bad_address(int *addr) ...@@ -271,7 +254,7 @@ struct __get_user __atomic_bad_address(int *addr)
#if CHIP_HAS_CBOX_HOME_MAP() #if CHIP_HAS_CBOX_HOME_MAP()
static int __init noatomichash(char *str) static int __init noatomichash(char *str)
{ {
printk("noatomichash is deprecated.\n"); pr_warning("noatomichash is deprecated.\n");
return 1; return 1;
} }
__setup("noatomichash", noatomichash); __setup("noatomichash", noatomichash);
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/smp.h>
/* /*
* Allow cropping out bits beyond the end of the array. * Allow cropping out bits beyond the end of the array.
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
EXPORT_SYMBOL(__get_user_1); EXPORT_SYMBOL(__get_user_1);
EXPORT_SYMBOL(__get_user_2); EXPORT_SYMBOL(__get_user_2);
EXPORT_SYMBOL(__get_user_4); EXPORT_SYMBOL(__get_user_4);
EXPORT_SYMBOL(__get_user_8);
EXPORT_SYMBOL(__put_user_1); EXPORT_SYMBOL(__put_user_1);
EXPORT_SYMBOL(__put_user_2); EXPORT_SYMBOL(__put_user_2);
EXPORT_SYMBOL(__put_user_4); EXPORT_SYMBOL(__put_user_4);
......
...@@ -60,8 +60,8 @@ typedef unsigned long (*memcpy_t)(void *, const void *, unsigned long); ...@@ -60,8 +60,8 @@ typedef unsigned long (*memcpy_t)(void *, const void *, unsigned long);
static void memcpy_multicache(void *dest, const void *source, static void memcpy_multicache(void *dest, const void *source,
pte_t dst_pte, pte_t src_pte, int len) pte_t dst_pte, pte_t src_pte, int len)
{ {
int idx, i; int idx;
unsigned long flags, newsrc, newdst, endsrc; unsigned long flags, newsrc, newdst;
pmd_t *pmdp; pmd_t *pmdp;
pte_t *ptep; pte_t *ptep;
int cpu = get_cpu(); int cpu = get_cpu();
...@@ -121,7 +121,7 @@ static void memcpy_multicache(void *dest, const void *source, ...@@ -121,7 +121,7 @@ static void memcpy_multicache(void *dest, const void *source,
*/ */
sim_allow_multiple_caching(0); sim_allow_multiple_caching(0);
local_irq_restore(flags); local_irq_restore(flags);
put_cpu_no_resched(); put_cpu();
} }
/* /*
......
...@@ -42,7 +42,7 @@ void *memmove(void *dest, const void *src, size_t n) ...@@ -42,7 +42,7 @@ void *memmove(void *dest, const void *src, size_t n)
in = (const uint8_t *)src; in = (const uint8_t *)src;
out = (uint8_t *)dest; out = (uint8_t *)dest;
stride = 1; stride = 1;
} }
/* Manually software-pipeline this loop. */ /* Manually software-pipeline this loop. */
x = *in; x = *in;
......
...@@ -245,7 +245,8 @@ void *memset(void *s, int c, size_t n) ...@@ -245,7 +245,8 @@ void *memset(void *s, int c, size_t n)
wh += CACHE_LINE_SIZE_IN_WORDS; wh += CACHE_LINE_SIZE_IN_WORDS;
} while (--i); } while (--i);
for (j = x * (CACHE_LINE_SIZE_IN_WORDS / 4); j != 0; j--) { for (j = x * (CACHE_LINE_SIZE_IN_WORDS / 4);
j != 0; j--) {
*out32++ = v32; *out32++ = v32;
*out32++ = v32; *out32++ = v32;
*out32++ = v32; *out32++ = v32;
......
...@@ -35,7 +35,7 @@ relax(int iterations) ...@@ -35,7 +35,7 @@ relax(int iterations)
} }
/* Perform bounded exponential backoff.*/ /* Perform bounded exponential backoff.*/
void delay_backoff(int iterations) static void delay_backoff(int iterations)
{ {
u32 exponent, loops; u32 exponent, loops;
......
...@@ -18,14 +18,15 @@ ...@@ -18,14 +18,15 @@
int __range_ok(unsigned long addr, unsigned long size) int __range_ok(unsigned long addr, unsigned long size)
{ {
unsigned long limit = current_thread_info()->addr_limit.seg; unsigned long limit = current_thread_info()->addr_limit.seg;
__chk_user_ptr(addr);
return !((addr < limit && size <= limit - addr) || return !((addr < limit && size <= limit - addr) ||
is_arch_mappable_range(addr, size)); is_arch_mappable_range(addr, size));
} }
EXPORT_SYMBOL(__range_ok); EXPORT_SYMBOL(__range_ok);
#ifdef CONFIG_DEBUG_COPY_FROM_USER
void copy_from_user_overflow(void) void copy_from_user_overflow(void)
{ {
WARN(1, "Buffer overflow detected!\n"); WARN(1, "Buffer overflow detected!\n");
} }
EXPORT_SYMBOL(copy_from_user_overflow); EXPORT_SYMBOL(copy_from_user_overflow);
#endif
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/elf.h> #include <linux/elf.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/sections.h>
/* Notify a running simulator, if any, that an exec just occurred. */ /* Notify a running simulator, if any, that an exec just occurred. */
static void sim_notify_exec(const char *binary_name) static void sim_notify_exec(const char *binary_name)
...@@ -77,9 +78,8 @@ static void *vdso_page; ...@@ -77,9 +78,8 @@ static void *vdso_page;
/* One-entry array used for install_special_mapping. */ /* One-entry array used for install_special_mapping. */
static struct page *vdso_pages[1]; static struct page *vdso_pages[1];
int __init vdso_setup(void) static int __init vdso_setup(void)
{ {
extern char __rt_sigreturn[], __rt_sigreturn_end[];
vdso_page = (void *)get_zeroed_page(GFP_ATOMIC); vdso_page = (void *)get_zeroed_page(GFP_ATOMIC);
memcpy(vdso_page, __rt_sigreturn, __rt_sigreturn_end - __rt_sigreturn); memcpy(vdso_page, __rt_sigreturn, __rt_sigreturn_end - __rt_sigreturn);
vdso_pages[0] = virt_to_page(vdso_page); vdso_pages[0] = virt_to_page(vdso_page);
......
...@@ -39,32 +39,11 @@ ...@@ -39,32 +39,11 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/traps.h>
#include <asm/syscalls.h>
#include <arch/interrupts.h> #include <arch/interrupts.h>
/*
* Unlock any spinlocks which will prevent us from getting the
* message out
*/
void bust_spinlocks(int yes)
{
int loglevel_save = console_loglevel;
if (yes) {
oops_in_progress = 1;
return;
}
oops_in_progress = 0;
/*
* OK, the message is on the console. Now we call printk()
* without oops_in_progress set so that printk will give klogd
* a poke. Hold onto your hats...
*/
console_loglevel = 15; /* NMI oopser may have shut the console up */
printk(" ");
console_loglevel = loglevel_save;
}
static noinline void force_sig_info_fault(int si_signo, int si_code, static noinline void force_sig_info_fault(int si_signo, int si_code,
unsigned long address, int fault_num, struct task_struct *tsk) unsigned long address, int fault_num, struct task_struct *tsk)
{ {
...@@ -301,10 +280,10 @@ static int handle_page_fault(struct pt_regs *regs, ...@@ -301,10 +280,10 @@ static int handle_page_fault(struct pt_regs *regs,
*/ */
stack_offset = stack_pointer & (THREAD_SIZE-1); stack_offset = stack_pointer & (THREAD_SIZE-1);
if (stack_offset < THREAD_SIZE / 8) { if (stack_offset < THREAD_SIZE / 8) {
printk(KERN_ALERT "Potential stack overrun: sp %#lx\n", pr_alert("Potential stack overrun: sp %#lx\n",
stack_pointer); stack_pointer);
show_regs(regs); show_regs(regs);
printk(KERN_ALERT "Killing current process %d/%s\n", pr_alert("Killing current process %d/%s\n",
tsk->pid, tsk->comm); tsk->pid, tsk->comm);
do_group_exit(SIGKILL); do_group_exit(SIGKILL);
} }
...@@ -422,7 +401,7 @@ static int handle_page_fault(struct pt_regs *regs, ...@@ -422,7 +401,7 @@ static int handle_page_fault(struct pt_regs *regs,
} else if (write) { } else if (write) {
#ifdef TEST_VERIFY_AREA #ifdef TEST_VERIFY_AREA
if (!is_page_fault && regs->cs == KERNEL_CS) if (!is_page_fault && regs->cs == KERNEL_CS)
printk("WP fault at "REGFMT"\n", regs->eip); pr_err("WP fault at "REGFMT"\n", regs->eip);
#endif #endif
if (!(vma->vm_flags & VM_WRITE)) if (!(vma->vm_flags & VM_WRITE))
goto bad_area; goto bad_area;
...@@ -450,6 +429,7 @@ static int handle_page_fault(struct pt_regs *regs, ...@@ -450,6 +429,7 @@ static int handle_page_fault(struct pt_regs *regs,
else else
tsk->min_flt++; tsk->min_flt++;
#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
/* /*
* If this was an asynchronous fault, * If this was an asynchronous fault,
* restart the appropriate engine. * restart the appropriate engine.
...@@ -472,6 +452,7 @@ static int handle_page_fault(struct pt_regs *regs, ...@@ -472,6 +452,7 @@ static int handle_page_fault(struct pt_regs *regs,
break; break;
#endif #endif
} }
#endif
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
return 1; return 1;
...@@ -514,17 +495,17 @@ static int handle_page_fault(struct pt_regs *regs, ...@@ -514,17 +495,17 @@ static int handle_page_fault(struct pt_regs *regs,
pte_t *pte = lookup_address(address); pte_t *pte = lookup_address(address);
if (pte && pte_present(*pte) && !pte_exec_kernel(*pte)) if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
printk(KERN_CRIT "kernel tried to execute" pr_crit("kernel tried to execute"
" non-executable page - exploit attempt?" " non-executable page - exploit attempt?"
" (uid: %d)\n", current->uid); " (uid: %d)\n", current->uid);
} }
#endif #endif
if (address < PAGE_SIZE) if (address < PAGE_SIZE)
printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference\n"); pr_alert("Unable to handle kernel NULL pointer dereference\n");
else else
printk(KERN_ALERT "Unable to handle kernel paging request\n"); pr_alert("Unable to handle kernel paging request\n");
printk(" at virtual address "REGFMT", pc "REGFMT"\n", pr_alert(" at virtual address "REGFMT", pc "REGFMT"\n",
address, regs->pc); address, regs->pc);
show_regs(regs); show_regs(regs);
...@@ -555,7 +536,7 @@ static int handle_page_fault(struct pt_regs *regs, ...@@ -555,7 +536,7 @@ static int handle_page_fault(struct pt_regs *regs,
down_read(&mm->mmap_sem); down_read(&mm->mmap_sem);
goto survive; goto survive;
} }
printk("VM: killing process %s\n", tsk->comm); pr_alert("VM: killing process %s\n", tsk->comm);
if (!is_kernel_mode) if (!is_kernel_mode)
do_group_exit(SIGKILL); do_group_exit(SIGKILL);
goto no_context; goto no_context;
...@@ -573,31 +554,12 @@ static int handle_page_fault(struct pt_regs *regs, ...@@ -573,31 +554,12 @@ static int handle_page_fault(struct pt_regs *regs,
#ifndef __tilegx__ #ifndef __tilegx__
extern char sys_cmpxchg[], __sys_cmpxchg_end[];
extern char __sys_cmpxchg_grab_lock[];
extern char __start_atomic_asm_code[], __end_atomic_asm_code[];
/*
* We return this structure in registers to avoid having to write
* additional save/restore code in the intvec.S caller.
*/
struct intvec_state {
void *handler;
unsigned long vecnum;
unsigned long fault_num;
unsigned long info;
unsigned long retval;
};
/* We must release ICS before panicking or we won't get anywhere. */ /* We must release ICS before panicking or we won't get anywhere. */
#define ics_panic(fmt, ...) do { \ #define ics_panic(fmt, ...) do { \
__insn_mtspr(SPR_INTERRUPT_CRITICAL_SECTION, 0); \ __insn_mtspr(SPR_INTERRUPT_CRITICAL_SECTION, 0); \
panic(fmt, __VA_ARGS__); \ panic(fmt, __VA_ARGS__); \
} while (0) } while (0)
void do_page_fault(struct pt_regs *regs, int fault_num,
unsigned long address, unsigned long write);
/* /*
* When we take an ITLB or DTLB fault or access violation in the * When we take an ITLB or DTLB fault or access violation in the
* supervisor while the critical section bit is set, the hypervisor is * supervisor while the critical section bit is set, the hypervisor is
......
...@@ -121,7 +121,7 @@ static struct list_head amp_list = LIST_HEAD_INIT(amp_list); ...@@ -121,7 +121,7 @@ static struct list_head amp_list = LIST_HEAD_INIT(amp_list);
struct kmap_amps { struct kmap_amps {
struct atomic_mapped_page per_type[KM_TYPE_NR]; struct atomic_mapped_page per_type[KM_TYPE_NR];
}; };
DEFINE_PER_CPU(struct kmap_amps, amps); static DEFINE_PER_CPU(struct kmap_amps, amps);
/* /*
* Add a page and va, on this cpu, to the list of kmap_atomic pages, * Add a page and va, on this cpu, to the list of kmap_atomic pages,
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
* locally from a remote home. There's no point in using it if we * locally from a remote home. There's no point in using it if we
* don't have coherent local caching, though. * don't have coherent local caching, though.
*/ */
int __write_once noallocl2; static int __write_once noallocl2;
static int __init set_noallocl2(char *str) static int __init set_noallocl2(char *str)
{ {
noallocl2 = 1; noallocl2 = 1;
...@@ -60,15 +60,11 @@ early_param("noallocl2", set_noallocl2); ...@@ -60,15 +60,11 @@ early_param("noallocl2", set_noallocl2);
#endif #endif
/* Provide no-op versions of these routines to keep flush_remote() cleaner. */ /* Provide no-op versions of these routines to keep flush_remote() cleaner. */
#define mark_caches_evicted_start() 0 #define mark_caches_evicted_start() 0
#define mark_caches_evicted_finish(mask, timestamp) do {} while (0) #define mark_caches_evicted_finish(mask, timestamp) do {} while (0)
/* /*
* Update the irq_stat for cpus that we are going to interrupt * Update the irq_stat for cpus that we are going to interrupt
* with TLB or cache flushes. Also handle removing dataplane cpus * with TLB or cache flushes. Also handle removing dataplane cpus
...@@ -171,20 +167,12 @@ void flush_remote(unsigned long cache_pfn, unsigned long cache_control, ...@@ -171,20 +167,12 @@ void flush_remote(unsigned long cache_pfn, unsigned long cache_control,
cpumask_scnprintf(cache_buf, sizeof(cache_buf), &cache_cpumask_copy); cpumask_scnprintf(cache_buf, sizeof(cache_buf), &cache_cpumask_copy);
cpumask_scnprintf(tlb_buf, sizeof(tlb_buf), &tlb_cpumask_copy); cpumask_scnprintf(tlb_buf, sizeof(tlb_buf), &tlb_cpumask_copy);
printk("hv_flush_remote(%#llx, %#lx, %p [%s]," pr_err("hv_flush_remote(%#llx, %#lx, %p [%s],"
" %#lx, %#lx, %#lx, %p [%s], %p, %d) = %d\n", " %#lx, %#lx, %#lx, %p [%s], %p, %d) = %d\n",
cache_pa, cache_control, cache_cpumask, cache_buf, cache_pa, cache_control, cache_cpumask, cache_buf,
(unsigned long)tlb_va, tlb_length, tlb_pgsize, (unsigned long)tlb_va, tlb_length, tlb_pgsize,
tlb_cpumask, tlb_buf, tlb_cpumask, tlb_buf,
asids, asidcount, rc); asids, asidcount, rc);
if (asidcount > 0) {
int i;
printk(" asids:");
for (i = 0; i < asidcount; ++i)
printk(" %d,%d,%d",
asids[i].x, asids[i].y, asids[i].asid);
printk("\n");
}
panic("Unsafe to continue."); panic("Unsafe to continue.");
} }
...@@ -293,7 +281,7 @@ pte_t pte_set_home(pte_t pte, int home) ...@@ -293,7 +281,7 @@ pte_t pte_set_home(pte_t pte, int home)
*/ */
if (hv_pte_get_nc(pte) && home != PAGE_HOME_IMMUTABLE) { if (hv_pte_get_nc(pte) && home != PAGE_HOME_IMMUTABLE) {
pte = hv_pte_clear_nc(pte); pte = hv_pte_clear_nc(pte);
printk("non-immutable page incoherently referenced: %#llx\n", pr_err("non-immutable page incoherently referenced: %#llx\n",
pte.val); pte.val);
} }
......
...@@ -332,7 +332,7 @@ static __init int setup_hugepagesz(char *opt) ...@@ -332,7 +332,7 @@ static __init int setup_hugepagesz(char *opt)
} else if (ps == PUD_SIZE) { } else if (ps == PUD_SIZE) {
hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
} else { } else {
printk(KERN_ERR "hugepagesz: Unsupported page size %lu M\n", pr_err("hugepagesz: Unsupported page size %lu M\n",
ps >> 20); ps >> 20);
return 0; return 0;
} }
......
...@@ -67,7 +67,9 @@ ...@@ -67,7 +67,9 @@
#define clear_pgd(pmdptr) (*(pmdptr) = hv_pte(0)) #define clear_pgd(pmdptr) (*(pmdptr) = hv_pte(0))
#ifndef __tilegx__
unsigned long VMALLOC_RESERVE = CONFIG_VMALLOC_RESERVE; unsigned long VMALLOC_RESERVE = CONFIG_VMALLOC_RESERVE;
#endif
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
...@@ -282,9 +284,9 @@ static pgprot_t __init init_pgprot(ulong address) ...@@ -282,9 +284,9 @@ static pgprot_t __init init_pgprot(ulong address)
/* /*
* Everything else that isn't data or bss is heap, so mark it * Everything else that isn't data or bss is heap, so mark it
* with the initial heap home (hash-for-home, or this cpu). This * with the initial heap home (hash-for-home, or this cpu). This
* includes any addresses after the loaded image; any address before * includes any addresses after the loaded image and any address before
* _einittext (since we already captured the case of text before * _einitdata, since we already captured the case of text before
* _sinittext); and any init-data pages. * _sinittext, and __pa(einittext) is approximately __pa(sinitdata).
* *
* All the LOWMEM pages that we mark this way will get their * All the LOWMEM pages that we mark this way will get their
* struct page homecache properly marked later, in set_page_homes(). * struct page homecache properly marked later, in set_page_homes().
...@@ -292,9 +294,7 @@ static pgprot_t __init init_pgprot(ulong address) ...@@ -292,9 +294,7 @@ static pgprot_t __init init_pgprot(ulong address)
* homes, but with a zero free_time we don't have to actually * homes, but with a zero free_time we don't have to actually
* do a flush action the first time we use them, either. * do a flush action the first time we use them, either.
*/ */
if (address >= (ulong) _end || address < (ulong) _sdata || if (address >= (ulong) _end || address < (ulong) _einitdata)
(address >= (ulong) _sinitdata &&
address < (ulong) _einitdata))
return construct_pgprot(PAGE_KERNEL, initial_heap_home()); return construct_pgprot(PAGE_KERNEL, initial_heap_home());
#if CHIP_HAS_CBOX_HOME_MAP() #if CHIP_HAS_CBOX_HOME_MAP()
...@@ -303,6 +303,14 @@ static pgprot_t __init init_pgprot(ulong address) ...@@ -303,6 +303,14 @@ static pgprot_t __init init_pgprot(ulong address)
return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH); return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH);
#endif #endif
/*
* Make the w1data homed like heap to start with, to avoid
* making it part of the page-striped data area when we're just
* going to convert it to read-only soon anyway.
*/
if (address >= (ulong)__w1data_begin && address < (ulong)__w1data_end)
return construct_pgprot(PAGE_KERNEL, initial_heap_home());
/* /*
* Otherwise we just hand out consecutive cpus. To avoid * Otherwise we just hand out consecutive cpus. To avoid
* requiring this function to hold state, we just walk forward from * requiring this function to hold state, we just walk forward from
...@@ -310,29 +318,24 @@ static pgprot_t __init init_pgprot(ulong address) ...@@ -310,29 +318,24 @@ static pgprot_t __init init_pgprot(ulong address)
* the requested address, while walking cpu home around kdata_mask. * the requested address, while walking cpu home around kdata_mask.
* This is typically no more than a dozen or so iterations. * This is typically no more than a dozen or so iterations.
*/ */
BUG_ON(_einitdata != __bss_start); page = (((ulong)__w1data_end) + PAGE_SIZE - 1) & PAGE_MASK;
for (page = (ulong)_sdata, cpu = NR_CPUS; ; ) { BUG_ON(address < page || address >= (ulong)_end);
cpu = cpumask_next(cpu, &kdata_mask); cpu = cpumask_first(&kdata_mask);
if (cpu == NR_CPUS) for (; page < address; page += PAGE_SIZE) {
cpu = cpumask_first(&kdata_mask); if (page >= (ulong)&init_thread_union &&
if (page >= address) page < (ulong)&init_thread_union + THREAD_SIZE)
break; continue;
page += PAGE_SIZE;
if (page == (ulong)__start_rodata)
page = (ulong)__end_rodata;
if (page == (ulong)&init_thread_union)
page += THREAD_SIZE;
if (page == (ulong)_sinitdata)
page = (ulong)_einitdata;
if (page == (ulong)empty_zero_page) if (page == (ulong)empty_zero_page)
page += PAGE_SIZE; continue;
#ifndef __tilegx__ #ifndef __tilegx__
#if !ATOMIC_LOCKS_FOUND_VIA_TABLE() #if !ATOMIC_LOCKS_FOUND_VIA_TABLE()
if (page == (ulong)atomic_locks) if (page == (ulong)atomic_locks)
page += PAGE_SIZE; continue;
#endif #endif
#endif #endif
cpu = cpumask_next(cpu, &kdata_mask);
if (cpu == NR_CPUS)
cpu = cpumask_first(&kdata_mask);
} }
return construct_pgprot(PAGE_KERNEL, cpu); return construct_pgprot(PAGE_KERNEL, cpu);
} }
...@@ -362,7 +365,7 @@ static int __init setup_ktext(char *str) ...@@ -362,7 +365,7 @@ static int __init setup_ktext(char *str)
/* If you have a leading "nocache", turn off ktext caching */ /* If you have a leading "nocache", turn off ktext caching */
if (strncmp(str, "nocache", 7) == 0) { if (strncmp(str, "nocache", 7) == 0) {
ktext_nocache = 1; ktext_nocache = 1;
printk("ktext: disabling local caching of kernel text\n"); pr_info("ktext: disabling local caching of kernel text\n");
str += 7; str += 7;
if (*str == ',') if (*str == ',')
++str; ++str;
...@@ -374,20 +377,20 @@ static int __init setup_ktext(char *str) ...@@ -374,20 +377,20 @@ static int __init setup_ktext(char *str)
/* Default setting on Tile64: use a huge page */ /* Default setting on Tile64: use a huge page */
if (strcmp(str, "huge") == 0) if (strcmp(str, "huge") == 0)
printk("ktext: using one huge locally cached page\n"); pr_info("ktext: using one huge locally cached page\n");
/* Pay TLB cost but get no cache benefit: cache small pages locally */ /* Pay TLB cost but get no cache benefit: cache small pages locally */
else if (strcmp(str, "local") == 0) { else if (strcmp(str, "local") == 0) {
ktext_small = 1; ktext_small = 1;
ktext_local = 1; ktext_local = 1;
printk("ktext: using small pages with local caching\n"); pr_info("ktext: using small pages with local caching\n");
} }
/* Neighborhood cache ktext pages on all cpus. */ /* Neighborhood cache ktext pages on all cpus. */
else if (strcmp(str, "all") == 0) { else if (strcmp(str, "all") == 0) {
ktext_small = 1; ktext_small = 1;
ktext_all = 1; ktext_all = 1;
printk("ktext: using maximal caching neighborhood\n"); pr_info("ktext: using maximal caching neighborhood\n");
} }
...@@ -397,10 +400,10 @@ static int __init setup_ktext(char *str) ...@@ -397,10 +400,10 @@ static int __init setup_ktext(char *str)
cpulist_scnprintf(buf, sizeof(buf), &ktext_mask); cpulist_scnprintf(buf, sizeof(buf), &ktext_mask);
if (cpumask_weight(&ktext_mask) > 1) { if (cpumask_weight(&ktext_mask) > 1) {
ktext_small = 1; ktext_small = 1;
printk("ktext: using caching neighborhood %s " pr_info("ktext: using caching neighborhood %s "
"with small pages\n", buf); "with small pages\n", buf);
} else { } else {
printk("ktext: caching on cpu %s with one huge page\n", pr_info("ktext: caching on cpu %s with one huge page\n",
buf); buf);
} }
} }
...@@ -470,19 +473,19 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base) ...@@ -470,19 +473,19 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
#if CHIP_HAS_CBOX_HOME_MAP() #if CHIP_HAS_CBOX_HOME_MAP()
if (ktext_arg_seen && ktext_hash) { if (ktext_arg_seen && ktext_hash) {
printk("warning: \"ktext\" boot argument ignored" pr_warning("warning: \"ktext\" boot argument ignored"
" if \"kcache_hash\" sets up text hash-for-home\n"); " if \"kcache_hash\" sets up text hash-for-home\n");
ktext_small = 0; ktext_small = 0;
} }
if (kdata_arg_seen && kdata_hash) { if (kdata_arg_seen && kdata_hash) {
printk("warning: \"kdata\" boot argument ignored" pr_warning("warning: \"kdata\" boot argument ignored"
" if \"kcache_hash\" sets up data hash-for-home\n"); " if \"kcache_hash\" sets up data hash-for-home\n");
} }
if (kdata_huge && !hash_default) { if (kdata_huge && !hash_default) {
printk("warning: disabling \"kdata=huge\"; requires" pr_warning("warning: disabling \"kdata=huge\"; requires"
" kcache_hash=all or =allbutstack\n"); " kcache_hash=all or =allbutstack\n");
kdata_huge = 0; kdata_huge = 0;
} }
#endif #endif
...@@ -556,11 +559,11 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base) ...@@ -556,11 +559,11 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
if (!cpumask_empty(&bad)) { if (!cpumask_empty(&bad)) {
char buf[NR_CPUS * 5]; char buf[NR_CPUS * 5];
cpulist_scnprintf(buf, sizeof(buf), &bad); cpulist_scnprintf(buf, sizeof(buf), &bad);
printk("ktext: not using unavailable cpus %s\n", buf); pr_info("ktext: not using unavailable cpus %s\n", buf);
} }
if (cpumask_empty(&ktext_mask)) { if (cpumask_empty(&ktext_mask)) {
printk("ktext: no valid cpus; caching on %d.\n", pr_warning("ktext: no valid cpus; caching on %d.\n",
smp_processor_id()); smp_processor_id());
cpumask_copy(&ktext_mask, cpumask_copy(&ktext_mask,
cpumask_of(smp_processor_id())); cpumask_of(smp_processor_id()));
} }
...@@ -737,17 +740,18 @@ static void __init set_non_bootmem_pages_init(void) ...@@ -737,17 +740,18 @@ static void __init set_non_bootmem_pages_init(void)
for_each_zone(z) { for_each_zone(z) {
unsigned long start, end; unsigned long start, end;
int nid = z->zone_pgdat->node_id; int nid = z->zone_pgdat->node_id;
int idx = zone_idx(z);
start = z->zone_start_pfn; start = z->zone_start_pfn;
if (start == 0) if (start == 0)
continue; /* bootmem */ continue; /* bootmem */
end = start + z->spanned_pages; end = start + z->spanned_pages;
if (zone_idx(z) == ZONE_NORMAL) { if (idx == ZONE_NORMAL) {
BUG_ON(start != node_start_pfn[nid]); BUG_ON(start != node_start_pfn[nid]);
start = node_free_pfn[nid]; start = node_free_pfn[nid];
} }
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM
if (zone_idx(z) == ZONE_HIGHMEM) if (idx == ZONE_HIGHMEM)
totalhigh_pages += z->spanned_pages; totalhigh_pages += z->spanned_pages;
#endif #endif
if (kdata_huge) { if (kdata_huge) {
...@@ -841,9 +845,9 @@ void __init mem_init(void) ...@@ -841,9 +845,9 @@ void __init mem_init(void)
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM
/* check that fixmap and pkmap do not overlap */ /* check that fixmap and pkmap do not overlap */
if (PKMAP_ADDR(LAST_PKMAP-1) >= FIXADDR_START) { if (PKMAP_ADDR(LAST_PKMAP-1) >= FIXADDR_START) {
printk(KERN_ERR "fixmap and kmap areas overlap" pr_err("fixmap and kmap areas overlap"
" - this will crash\n"); " - this will crash\n");
printk(KERN_ERR "pkstart: %lxh pkend: %lxh fixstart %lxh\n", pr_err("pkstart: %lxh pkend: %lxh fixstart %lxh\n",
PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP-1), PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP-1),
FIXADDR_START); FIXADDR_START);
BUG(); BUG();
...@@ -863,7 +867,7 @@ void __init mem_init(void) ...@@ -863,7 +867,7 @@ void __init mem_init(void)
initsize = (unsigned long)&_einittext - (unsigned long)&_sinittext; initsize = (unsigned long)&_einittext - (unsigned long)&_sinittext;
initsize += (unsigned long)&_einitdata - (unsigned long)&_sinitdata; initsize += (unsigned long)&_einitdata - (unsigned long)&_sinitdata;
printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n", pr_info("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10), (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
num_physpages << (PAGE_SHIFT-10), num_physpages << (PAGE_SHIFT-10),
codesize >> 10, codesize >> 10,
...@@ -968,7 +972,6 @@ static void mark_w1data_ro(void) ...@@ -968,7 +972,6 @@ static void mark_w1data_ro(void)
BUG_ON((addr & (PAGE_SIZE-1)) != 0); BUG_ON((addr & (PAGE_SIZE-1)) != 0);
for (; addr <= (unsigned long)__w1data_end - 1; addr += PAGE_SIZE) { for (; addr <= (unsigned long)__w1data_end - 1; addr += PAGE_SIZE) {
unsigned long pfn = kaddr_to_pfn((void *)addr); unsigned long pfn = kaddr_to_pfn((void *)addr);
struct page *page = pfn_to_page(pfn);
pte_t *ptep = virt_to_pte(NULL, addr); pte_t *ptep = virt_to_pte(NULL, addr);
BUG_ON(pte_huge(*ptep)); /* not relevant for kdata_huge */ BUG_ON(pte_huge(*ptep)); /* not relevant for kdata_huge */
set_pte_at(&init_mm, addr, ptep, pfn_pte(pfn, PAGE_KERNEL_RO)); set_pte_at(&init_mm, addr, ptep, pfn_pte(pfn, PAGE_KERNEL_RO));
...@@ -986,7 +989,7 @@ static long __write_once initfree = 1; ...@@ -986,7 +989,7 @@ static long __write_once initfree = 1;
static int __init set_initfree(char *str) static int __init set_initfree(char *str)
{ {
strict_strtol(str, 0, &initfree); strict_strtol(str, 0, &initfree);
printk("initfree: %s free init pages\n", initfree ? "will" : "won't"); pr_info("initfree: %s free init pages\n", initfree ? "will" : "won't");
return 1; return 1;
} }
__setup("initfree=", set_initfree); __setup("initfree=", set_initfree);
...@@ -996,8 +999,8 @@ static void free_init_pages(char *what, unsigned long begin, unsigned long end) ...@@ -996,8 +999,8 @@ static void free_init_pages(char *what, unsigned long begin, unsigned long end)
unsigned long addr = (unsigned long) begin; unsigned long addr = (unsigned long) begin;
if (kdata_huge && !initfree) { if (kdata_huge && !initfree) {
printk("Warning: ignoring initfree=0:" pr_warning("Warning: ignoring initfree=0:"
" incompatible with kdata=huge\n"); " incompatible with kdata=huge\n");
initfree = 1; initfree = 1;
} }
end = (end + PAGE_SIZE - 1) & PAGE_MASK; end = (end + PAGE_SIZE - 1) & PAGE_MASK;
...@@ -1033,7 +1036,7 @@ static void free_init_pages(char *what, unsigned long begin, unsigned long end) ...@@ -1033,7 +1036,7 @@ static void free_init_pages(char *what, unsigned long begin, unsigned long end)
free_page(addr); free_page(addr);
totalram_pages++; totalram_pages++;
} }
printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); pr_info("Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
} }
void free_initmem(void) void free_initmem(void)
......
...@@ -46,7 +46,7 @@ void show_mem(void) ...@@ -46,7 +46,7 @@ void show_mem(void)
{ {
struct zone *zone; struct zone *zone;
printk("Active:%lu inactive:%lu dirty:%lu writeback:%lu unstable:%lu" pr_err("Active:%lu inactive:%lu dirty:%lu writeback:%lu unstable:%lu"
" free:%lu\n slab:%lu mapped:%lu pagetables:%lu bounce:%lu" " free:%lu\n slab:%lu mapped:%lu pagetables:%lu bounce:%lu"
" pagecache:%lu swap:%lu\n", " pagecache:%lu swap:%lu\n",
(global_page_state(NR_ACTIVE_ANON) + (global_page_state(NR_ACTIVE_ANON) +
...@@ -71,7 +71,6 @@ void show_mem(void) ...@@ -71,7 +71,6 @@ void show_mem(void)
if (!populated_zone(zone)) if (!populated_zone(zone))
continue; continue;
printk("Node %d %7s: ", zone_to_nid(zone), zone->name);
spin_lock_irqsave(&zone->lock, flags); spin_lock_irqsave(&zone->lock, flags);
for (order = 0; order < MAX_ORDER; order++) { for (order = 0; order < MAX_ORDER; order++) {
int nr = zone->free_area[order].nr_free; int nr = zone->free_area[order].nr_free;
...@@ -80,7 +79,8 @@ void show_mem(void) ...@@ -80,7 +79,8 @@ void show_mem(void)
largest_order = order; largest_order = order;
} }
spin_unlock_irqrestore(&zone->lock, flags); spin_unlock_irqrestore(&zone->lock, flags);
printk("%lukB (largest %luKb)\n", pr_err("Node %d %7s: %lukB (largest %luKb)\n",
zone_to_nid(zone), zone->name,
K(total), largest_order ? K(1UL) << largest_order : 0); K(total), largest_order ? K(1UL) << largest_order : 0);
} }
} }
...@@ -123,42 +123,6 @@ static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) ...@@ -123,42 +123,6 @@ static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
local_flush_tlb_page(NULL, vaddr, PAGE_SIZE); local_flush_tlb_page(NULL, vaddr, PAGE_SIZE);
} }
/*
* Associate a huge virtual page frame with a given physical page frame
* and protection flags for that frame. pfn is for the base of the page,
* vaddr is what the page gets mapped to - both must be properly aligned.
* The pmd must already be instantiated.
*/
void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
if (vaddr & (PMD_SIZE-1)) { /* vaddr is misaligned */
printk(KERN_WARNING "set_pmd_pfn: vaddr misaligned\n");
return; /* BUG(); */
}
if (pfn & (PTRS_PER_PTE-1)) { /* pfn is misaligned */
printk(KERN_WARNING "set_pmd_pfn: pfn misaligned\n");
return; /* BUG(); */
}
pgd = swapper_pg_dir + pgd_index(vaddr);
if (pgd_none(*pgd)) {
printk(KERN_WARNING "set_pmd_pfn: pgd_none\n");
return; /* BUG(); */
}
pud = pud_offset(pgd, vaddr);
pmd = pmd_offset(pud, vaddr);
set_pmd(pmd, ptfn_pmd(HV_PFN_TO_PTFN(pfn), flags));
/*
* It's enough to flush this one mapping.
* We flush both small and huge TSBs to be sure.
*/
local_flush_tlb_page(NULL, vaddr, HPAGE_SIZE);
local_flush_tlb_pages(NULL, vaddr, PAGE_SIZE, HPAGE_SIZE);
}
void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags) void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
{ {
unsigned long address = __fix_to_virt(idx); unsigned long address = __fix_to_virt(idx);
...@@ -257,7 +221,7 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd) ...@@ -257,7 +221,7 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
{ {
int flags = GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO|__GFP_COMP; gfp_t flags = GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO|__GFP_COMP;
struct page *p; struct page *p;
#ifdef CONFIG_HIGHPTE #ifdef CONFIG_HIGHPTE
...@@ -550,7 +514,7 @@ void iounmap(volatile void __iomem *addr_in) ...@@ -550,7 +514,7 @@ void iounmap(volatile void __iomem *addr_in)
read_unlock(&vmlist_lock); read_unlock(&vmlist_lock);
if (!p) { if (!p) {
printk("iounmap: bad address %p\n", addr); pr_err("iounmap: bad address %p\n", addr);
dump_stack(); dump_stack();
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment