Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile

* git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile: (26 commits)
  arch/tile: prefer "tilepro" as the name of the 32-bit architecture
  compat: include aio_abi.h for aio_context_t
  arch/tile: cleanups for tilegx compat mode
  arch/tile: allocate PCI IRQs later in boot
  arch/tile: support signal "exception-trace" hook
  arch/tile: use better definitions of xchg() and cmpxchg()
  include/linux/compat.h: coding-style fixes
  tile: add an RTC driver for the Tilera hypervisor
  arch/tile: finish enabling support for TILE-Gx 64-bit chip
  compat: fixes to allow working with tile arch
  arch/tile: update defconfig file to something more useful
  tile: do_hardwall_trap: do not play with task->sighand
  tile: replace mm->cpu_vm_mask with mm_cpumask()
  tile,mn10300: add device parameter to dma_cache_sync()
  audit: support the "standard" <asm-generic/unistd.h>
  arch/tile: clarify flush_buffer()/finv_buffer() function names
  arch/tile: kernel-related cleanups from removing static page size
  arch/tile: various header improvements for building drivers
  arch/tile: disable GX prefetcher during cache flush
  arch/tile: tolerate disabling CONFIG_BLK_DEV_INITRD
  ...
This commit is contained in:
Linus Torvalds 2011-05-25 15:35:32 -07:00
commit 0798b1dbfb
92 changed files with 11825 additions and 2060 deletions

View File

@ -220,6 +220,14 @@ ifeq ($(ARCH),sh64)
SRCARCH := sh
endif
# Additional ARCH settings for tile
ifeq ($(ARCH),tilepro)
SRCARCH := tile
endif
ifeq ($(ARCH),tilegx)
SRCARCH := tile
endif
# Where to locate arch specific headers
hdr-arch := $(SRCARCH)

View File

@ -339,6 +339,14 @@ config NO_IOPORT
source "drivers/pci/Kconfig"
config HOTPLUG
bool "Support for hot-pluggable devices"
---help---
Say Y here if you want to plug devices into your computer while
the system is running, and be able to use them quickly. In many
cases, the devices can likewise be unplugged at any time too.
One well-known example of this is USB.
source "drivers/pci/hotplug/Kconfig"
endmenu

View File

@ -1,71 +0,0 @@
CONFIG_EXPERIMENTAL=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="usr/contents.txt"
CONFIG_EXPERT=y
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_HZ_100=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
CONFIG_IPV6=y
# CONFIG_WIRELESS is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_NETDEVICES=y
CONFIG_TUN=y
# CONFIG_NETDEV_10000 is not set
# CONFIG_WLAN is not set
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_NOWAYOUT=y
# CONFIG_HID_SUPPORT is not set
CONFIG_RTC_CLASS=y
# CONFIG_RTC_INTF_SYSFS is not set
# CONFIG_RTC_INTF_PROC is not set
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_FUSE_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=m
CONFIG_TMPFS=y
CONFIG_HUGETLBFS=y
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_FRAME_WARN=2048
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_VM=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_DEBUG_EXTRA_FLAGS="-femit-struct-debug-baseonly"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,258 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/*
* @file
* Global header file.
* This header file specifies defines for TILE-Gx.
*/
#ifndef __ARCH_CHIP_H__
#define __ARCH_CHIP_H__
/** Specify chip version.
* When possible, prefer the CHIP_xxx symbols below for future-proofing.
* This is intended for cross-compiling; native compilation should
* use the predefined __tile_chip__ symbol.
*/
#define TILE_CHIP 10
/** Specify chip revision.
* This provides for the case of a respin of a particular chip type;
* the normal value for this symbol is "0".
* This is intended for cross-compiling; native compilation should
* use the predefined __tile_chip_rev__ symbol.
*/
#define TILE_CHIP_REV 0
/** The name of this architecture. */
#define CHIP_ARCH_NAME "tilegx"
/** The ELF e_machine type for binaries for this chip. */
#define CHIP_ELF_TYPE() EM_TILEGX
/** The alternate ELF e_machine type for binaries for this chip. */
#define CHIP_COMPAT_ELF_TYPE() 0x2597
/** What is the native word size of the machine? */
#define CHIP_WORD_SIZE() 64
/** How many bits of a virtual address are used. Extra bits must be
* the sign extension of the low bits.
*/
#define CHIP_VA_WIDTH() 42
/** How many bits are in a physical address? */
#define CHIP_PA_WIDTH() 40
/** Size of the L2 cache, in bytes. */
#define CHIP_L2_CACHE_SIZE() 262144
/** Log size of an L2 cache line in bytes. */
#define CHIP_L2_LOG_LINE_SIZE() 6
/** Size of an L2 cache line, in bytes. */
#define CHIP_L2_LINE_SIZE() (1 << CHIP_L2_LOG_LINE_SIZE())
/** Associativity of the L2 cache. */
#define CHIP_L2_ASSOC() 8
/** Size of the L1 data cache, in bytes. */
#define CHIP_L1D_CACHE_SIZE() 32768
/** Log size of an L1 data cache line in bytes. */
#define CHIP_L1D_LOG_LINE_SIZE() 6
/** Size of an L1 data cache line, in bytes. */
#define CHIP_L1D_LINE_SIZE() (1 << CHIP_L1D_LOG_LINE_SIZE())
/** Associativity of the L1 data cache. */
#define CHIP_L1D_ASSOC() 2
/** Size of the L1 instruction cache, in bytes. */
#define CHIP_L1I_CACHE_SIZE() 32768
/** Log size of an L1 instruction cache line in bytes. */
#define CHIP_L1I_LOG_LINE_SIZE() 6
/** Size of an L1 instruction cache line, in bytes. */
#define CHIP_L1I_LINE_SIZE() (1 << CHIP_L1I_LOG_LINE_SIZE())
/** Associativity of the L1 instruction cache. */
#define CHIP_L1I_ASSOC() 2
/** Stride with which flush instructions must be issued. */
#define CHIP_FLUSH_STRIDE() CHIP_L2_LINE_SIZE()
/** Stride with which inv instructions must be issued. */
#define CHIP_INV_STRIDE() CHIP_L2_LINE_SIZE()
/** Stride with which finv instructions must be issued. */
#define CHIP_FINV_STRIDE() CHIP_L2_LINE_SIZE()
/** Can the local cache coherently cache data that is homed elsewhere? */
#define CHIP_HAS_COHERENT_LOCAL_CACHE() 1
/** How many simultaneous outstanding victims can the L2 cache have? */
#define CHIP_MAX_OUTSTANDING_VICTIMS() 128
/** Does the TLB support the NC and NOALLOC bits? */
#define CHIP_HAS_NC_AND_NOALLOC_BITS() 1
/** Does the chip support hash-for-home caching? */
#define CHIP_HAS_CBOX_HOME_MAP() 1
/** Number of entries in the chip's home map tables. */
#define CHIP_CBOX_HOME_MAP_SIZE() 128
/** Do uncacheable requests miss in the cache regardless of whether
* there is matching data? */
#define CHIP_HAS_ENFORCED_UNCACHEABLE_REQUESTS() 1
/** Does the mf instruction wait for victims? */
#define CHIP_HAS_MF_WAITS_FOR_VICTIMS() 0
/** Does the chip have an "inv" instruction that doesn't also flush? */
#define CHIP_HAS_INV() 1
/** Does the chip have a "wh64" instruction? */
#define CHIP_HAS_WH64() 1
/** Does this chip have a 'dword_align' instruction? */
#define CHIP_HAS_DWORD_ALIGN() 0
/** Number of performance counters. */
#define CHIP_PERFORMANCE_COUNTERS() 4
/** Does this chip have auxiliary performance counters? */
#define CHIP_HAS_AUX_PERF_COUNTERS() 1
/** Is the CBOX_MSR1 SPR supported? */
#define CHIP_HAS_CBOX_MSR1() 0
/** Is the TILE_RTF_HWM SPR supported? */
#define CHIP_HAS_TILE_RTF_HWM() 1
/** Is the TILE_WRITE_PENDING SPR supported? */
#define CHIP_HAS_TILE_WRITE_PENDING() 0
/** Is the PROC_STATUS SPR supported? */
#define CHIP_HAS_PROC_STATUS_SPR() 1
/** Is the DSTREAM_PF SPR supported? */
#define CHIP_HAS_DSTREAM_PF() 1
/** Log of the number of mshims we have. */
#define CHIP_LOG_NUM_MSHIMS() 2
/** Are the bases of the interrupt vector areas fixed? */
#define CHIP_HAS_FIXED_INTVEC_BASE() 0
/** Are the interrupt masks split up into 2 SPRs? */
#define CHIP_HAS_SPLIT_INTR_MASK() 0
/** Is the cycle count split up into 2 SPRs? */
#define CHIP_HAS_SPLIT_CYCLE() 0
/** Does the chip have a static network? */
#define CHIP_HAS_SN() 0
/** Does the chip have a static network processor? */
#define CHIP_HAS_SN_PROC() 0
/** Size of the L1 static network processor instruction cache, in bytes. */
/* #define CHIP_L1SNI_CACHE_SIZE() -- does not apply to chip 10 */
/** Does the chip have DMA support in each tile? */
#define CHIP_HAS_TILE_DMA() 0
/** Does the chip have the second revision of the directly accessible
* dynamic networks? This encapsulates a number of characteristics,
* including the absence of the catch-all, the absence of inline message
* tags, the absence of support for network context-switching, and so on.
*/
#define CHIP_HAS_REV1_XDN() 1
/** Does the chip have cmpexch and similar (fetchadd, exch, etc.)? */
#define CHIP_HAS_CMPEXCH() 1
/** Does the chip have memory-mapped I/O support? */
#define CHIP_HAS_MMIO() 1
/** Does the chip have post-completion interrupts? */
#define CHIP_HAS_POST_COMPLETION_INTERRUPTS() 1
/** Does the chip have native single step support? */
#define CHIP_HAS_SINGLE_STEP() 1
#ifndef __OPEN_SOURCE__ /* features only relevant to hypervisor-level code */
/** How many entries are present in the instruction TLB? */
#define CHIP_ITLB_ENTRIES() 16
/** How many entries are present in the data TLB? */
#define CHIP_DTLB_ENTRIES() 32
/** How many MAF entries does the XAUI shim have? */
#define CHIP_XAUI_MAF_ENTRIES() 32
/** Does the memory shim have a source-id table? */
#define CHIP_HAS_MSHIM_SRCID_TABLE() 0
/** Does the L1 instruction cache clear on reset? */
#define CHIP_HAS_L1I_CLEAR_ON_RESET() 1
/** Does the chip come out of reset with valid coordinates on all tiles?
* Note that if defined, this also implies that the upper left is 1,1.
*/
#define CHIP_HAS_VALID_TILE_COORD_RESET() 1
/** Does the chip have unified packet formats? */
#define CHIP_HAS_UNIFIED_PACKET_FORMATS() 1
/** Does the chip support write reordering? */
#define CHIP_HAS_WRITE_REORDERING() 1
/** Does the chip support Y-X routing as well as X-Y? */
#define CHIP_HAS_Y_X_ROUTING() 1
/** Is INTCTRL_3 managed with the correct MPL? */
#define CHIP_HAS_INTCTRL_3_STATUS_FIX() 1
/** Is it possible to configure the chip to be big-endian? */
#define CHIP_HAS_BIG_ENDIAN_CONFIG() 1
/** Is the CACHE_RED_WAY_OVERRIDDEN SPR supported? */
#define CHIP_HAS_CACHE_RED_WAY_OVERRIDDEN() 0
/** Is the DIAG_TRACE_WAY SPR supported? */
#define CHIP_HAS_DIAG_TRACE_WAY() 0
/** Is the MEM_STRIPE_CONFIG SPR supported? */
#define CHIP_HAS_MEM_STRIPE_CONFIG() 1
/** Are the TLB_PERF SPRs supported? */
#define CHIP_HAS_TLB_PERF() 1
/** Is the VDN_SNOOP_SHIM_CTL SPR supported? */
#define CHIP_HAS_VDN_SNOOP_SHIM_CTL() 0
/** Does the chip support rev1 DMA packets? */
#define CHIP_HAS_REV1_DMA_PACKETS() 1
/** Does the chip have an IPI shim? */
#define CHIP_HAS_IPI() 1
#endif /* !__OPEN_SOURCE__ */
#endif /* __ARCH_CHIP_H__ */

View File

@ -16,7 +16,7 @@
/**
* @file
*
* Support for invalidating bytes in the instruction
* Support for invalidating bytes in the instruction cache.
*/
#ifndef __ARCH_ICACHE_H__
@ -30,11 +30,10 @@
*
* @param addr The start of memory to be invalidated.
* @param size The number of bytes to be invalidated.
* @param page_size The system's page size, typically the PAGE_SIZE constant
* in sys/page.h. This value must be a power of two no larger
* than the page containing the code to be invalidated. If the value
* is smaller than the actual page size, this function will still
* work, but may run slower than necessary.
* @param page_size The system's page size, e.g. getpagesize() in userspace.
* This value must be a power of two no larger than the page containing
* the code to be invalidated. If the value is smaller than the actual page
* size, this function will still work, but may run slower than necessary.
*/
static __inline void
invalidate_icache(const void* addr, unsigned long size,

View File

@ -0,0 +1,276 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#ifndef __ARCH_INTERRUPTS_H__
#define __ARCH_INTERRUPTS_H__
/** Mask for an interrupt. */
#ifdef __ASSEMBLER__
/* Note: must handle breaking interrupts into high and low words manually. */
#define INT_MASK(intno) (1 << (intno))
#else
#define INT_MASK(intno) (1ULL << (intno))
#endif
/** Where a given interrupt executes */
#define INTERRUPT_VECTOR(i, pl) (0xFC000000 + ((pl) << 24) + ((i) << 8))
/** Where to store a vector for a given interrupt. */
#define USER_INTERRUPT_VECTOR(i) INTERRUPT_VECTOR(i, 0)
/** The base address of user-level interrupts. */
#define USER_INTERRUPT_VECTOR_BASE INTERRUPT_VECTOR(0, 0)
/** Additional synthetic interrupt. */
#define INT_BREAKPOINT (63)
#define INT_MEM_ERROR 0
#define INT_SINGLE_STEP_3 1
#define INT_SINGLE_STEP_2 2
#define INT_SINGLE_STEP_1 3
#define INT_SINGLE_STEP_0 4
#define INT_IDN_COMPLETE 5
#define INT_UDN_COMPLETE 6
#define INT_ITLB_MISS 7
#define INT_ILL 8
#define INT_GPV 9
#define INT_IDN_ACCESS 10
#define INT_UDN_ACCESS 11
#define INT_SWINT_3 12
#define INT_SWINT_2 13
#define INT_SWINT_1 14
#define INT_SWINT_0 15
#define INT_ILL_TRANS 16
#define INT_UNALIGN_DATA 17
#define INT_DTLB_MISS 18
#define INT_DTLB_ACCESS 19
#define INT_IDN_FIREWALL 20
#define INT_UDN_FIREWALL 21
#define INT_TILE_TIMER 22
#define INT_AUX_TILE_TIMER 23
#define INT_IDN_TIMER 24
#define INT_UDN_TIMER 25
#define INT_IDN_AVAIL 26
#define INT_UDN_AVAIL 27
#define INT_IPI_3 28
#define INT_IPI_2 29
#define INT_IPI_1 30
#define INT_IPI_0 31
#define INT_PERF_COUNT 32
#define INT_AUX_PERF_COUNT 33
#define INT_INTCTRL_3 34
#define INT_INTCTRL_2 35
#define INT_INTCTRL_1 36
#define INT_INTCTRL_0 37
#define INT_BOOT_ACCESS 38
#define INT_WORLD_ACCESS 39
#define INT_I_ASID 40
#define INT_D_ASID 41
#define INT_DOUBLE_FAULT 42
#define NUM_INTERRUPTS 43
#ifndef __ASSEMBLER__
#define QUEUED_INTERRUPTS ( \
INT_MASK(INT_MEM_ERROR) | \
INT_MASK(INT_IDN_COMPLETE) | \
INT_MASK(INT_UDN_COMPLETE) | \
INT_MASK(INT_IDN_FIREWALL) | \
INT_MASK(INT_UDN_FIREWALL) | \
INT_MASK(INT_TILE_TIMER) | \
INT_MASK(INT_AUX_TILE_TIMER) | \
INT_MASK(INT_IDN_TIMER) | \
INT_MASK(INT_UDN_TIMER) | \
INT_MASK(INT_IDN_AVAIL) | \
INT_MASK(INT_UDN_AVAIL) | \
INT_MASK(INT_IPI_3) | \
INT_MASK(INT_IPI_2) | \
INT_MASK(INT_IPI_1) | \
INT_MASK(INT_IPI_0) | \
INT_MASK(INT_PERF_COUNT) | \
INT_MASK(INT_AUX_PERF_COUNT) | \
INT_MASK(INT_INTCTRL_3) | \
INT_MASK(INT_INTCTRL_2) | \
INT_MASK(INT_INTCTRL_1) | \
INT_MASK(INT_INTCTRL_0) | \
INT_MASK(INT_BOOT_ACCESS) | \
INT_MASK(INT_WORLD_ACCESS) | \
INT_MASK(INT_I_ASID) | \
INT_MASK(INT_D_ASID) | \
INT_MASK(INT_DOUBLE_FAULT) | \
0)
#define NONQUEUED_INTERRUPTS ( \
INT_MASK(INT_SINGLE_STEP_3) | \
INT_MASK(INT_SINGLE_STEP_2) | \
INT_MASK(INT_SINGLE_STEP_1) | \
INT_MASK(INT_SINGLE_STEP_0) | \
INT_MASK(INT_ITLB_MISS) | \
INT_MASK(INT_ILL) | \
INT_MASK(INT_GPV) | \
INT_MASK(INT_IDN_ACCESS) | \
INT_MASK(INT_UDN_ACCESS) | \
INT_MASK(INT_SWINT_3) | \
INT_MASK(INT_SWINT_2) | \
INT_MASK(INT_SWINT_1) | \
INT_MASK(INT_SWINT_0) | \
INT_MASK(INT_ILL_TRANS) | \
INT_MASK(INT_UNALIGN_DATA) | \
INT_MASK(INT_DTLB_MISS) | \
INT_MASK(INT_DTLB_ACCESS) | \
0)
#define CRITICAL_MASKED_INTERRUPTS ( \
INT_MASK(INT_MEM_ERROR) | \
INT_MASK(INT_SINGLE_STEP_3) | \
INT_MASK(INT_SINGLE_STEP_2) | \
INT_MASK(INT_SINGLE_STEP_1) | \
INT_MASK(INT_SINGLE_STEP_0) | \
INT_MASK(INT_IDN_COMPLETE) | \
INT_MASK(INT_UDN_COMPLETE) | \
INT_MASK(INT_IDN_FIREWALL) | \
INT_MASK(INT_UDN_FIREWALL) | \
INT_MASK(INT_TILE_TIMER) | \
INT_MASK(INT_AUX_TILE_TIMER) | \
INT_MASK(INT_IDN_TIMER) | \
INT_MASK(INT_UDN_TIMER) | \
INT_MASK(INT_IDN_AVAIL) | \
INT_MASK(INT_UDN_AVAIL) | \
INT_MASK(INT_IPI_3) | \
INT_MASK(INT_IPI_2) | \
INT_MASK(INT_IPI_1) | \
INT_MASK(INT_IPI_0) | \
INT_MASK(INT_PERF_COUNT) | \
INT_MASK(INT_AUX_PERF_COUNT) | \
INT_MASK(INT_INTCTRL_3) | \
INT_MASK(INT_INTCTRL_2) | \
INT_MASK(INT_INTCTRL_1) | \
INT_MASK(INT_INTCTRL_0) | \
0)
#define CRITICAL_UNMASKED_INTERRUPTS ( \
INT_MASK(INT_ITLB_MISS) | \
INT_MASK(INT_ILL) | \
INT_MASK(INT_GPV) | \
INT_MASK(INT_IDN_ACCESS) | \
INT_MASK(INT_UDN_ACCESS) | \
INT_MASK(INT_SWINT_3) | \
INT_MASK(INT_SWINT_2) | \
INT_MASK(INT_SWINT_1) | \
INT_MASK(INT_SWINT_0) | \
INT_MASK(INT_ILL_TRANS) | \
INT_MASK(INT_UNALIGN_DATA) | \
INT_MASK(INT_DTLB_MISS) | \
INT_MASK(INT_DTLB_ACCESS) | \
INT_MASK(INT_BOOT_ACCESS) | \
INT_MASK(INT_WORLD_ACCESS) | \
INT_MASK(INT_I_ASID) | \
INT_MASK(INT_D_ASID) | \
INT_MASK(INT_DOUBLE_FAULT) | \
0)
#define MASKABLE_INTERRUPTS ( \
INT_MASK(INT_MEM_ERROR) | \
INT_MASK(INT_SINGLE_STEP_3) | \
INT_MASK(INT_SINGLE_STEP_2) | \
INT_MASK(INT_SINGLE_STEP_1) | \
INT_MASK(INT_SINGLE_STEP_0) | \
INT_MASK(INT_IDN_COMPLETE) | \
INT_MASK(INT_UDN_COMPLETE) | \
INT_MASK(INT_IDN_FIREWALL) | \
INT_MASK(INT_UDN_FIREWALL) | \
INT_MASK(INT_TILE_TIMER) | \
INT_MASK(INT_AUX_TILE_TIMER) | \
INT_MASK(INT_IDN_TIMER) | \
INT_MASK(INT_UDN_TIMER) | \
INT_MASK(INT_IDN_AVAIL) | \
INT_MASK(INT_UDN_AVAIL) | \
INT_MASK(INT_IPI_3) | \
INT_MASK(INT_IPI_2) | \
INT_MASK(INT_IPI_1) | \
INT_MASK(INT_IPI_0) | \
INT_MASK(INT_PERF_COUNT) | \
INT_MASK(INT_AUX_PERF_COUNT) | \
INT_MASK(INT_INTCTRL_3) | \
INT_MASK(INT_INTCTRL_2) | \
INT_MASK(INT_INTCTRL_1) | \
INT_MASK(INT_INTCTRL_0) | \
0)
#define UNMASKABLE_INTERRUPTS ( \
INT_MASK(INT_ITLB_MISS) | \
INT_MASK(INT_ILL) | \
INT_MASK(INT_GPV) | \
INT_MASK(INT_IDN_ACCESS) | \
INT_MASK(INT_UDN_ACCESS) | \
INT_MASK(INT_SWINT_3) | \
INT_MASK(INT_SWINT_2) | \
INT_MASK(INT_SWINT_1) | \
INT_MASK(INT_SWINT_0) | \
INT_MASK(INT_ILL_TRANS) | \
INT_MASK(INT_UNALIGN_DATA) | \
INT_MASK(INT_DTLB_MISS) | \
INT_MASK(INT_DTLB_ACCESS) | \
INT_MASK(INT_BOOT_ACCESS) | \
INT_MASK(INT_WORLD_ACCESS) | \
INT_MASK(INT_I_ASID) | \
INT_MASK(INT_D_ASID) | \
INT_MASK(INT_DOUBLE_FAULT) | \
0)
#define SYNC_INTERRUPTS ( \
INT_MASK(INT_SINGLE_STEP_3) | \
INT_MASK(INT_SINGLE_STEP_2) | \
INT_MASK(INT_SINGLE_STEP_1) | \
INT_MASK(INT_SINGLE_STEP_0) | \
INT_MASK(INT_IDN_COMPLETE) | \
INT_MASK(INT_UDN_COMPLETE) | \
INT_MASK(INT_ITLB_MISS) | \
INT_MASK(INT_ILL) | \
INT_MASK(INT_GPV) | \
INT_MASK(INT_IDN_ACCESS) | \
INT_MASK(INT_UDN_ACCESS) | \
INT_MASK(INT_SWINT_3) | \
INT_MASK(INT_SWINT_2) | \
INT_MASK(INT_SWINT_1) | \
INT_MASK(INT_SWINT_0) | \
INT_MASK(INT_ILL_TRANS) | \
INT_MASK(INT_UNALIGN_DATA) | \
INT_MASK(INT_DTLB_MISS) | \
INT_MASK(INT_DTLB_ACCESS) | \
0)
#define NON_SYNC_INTERRUPTS ( \
INT_MASK(INT_MEM_ERROR) | \
INT_MASK(INT_IDN_FIREWALL) | \
INT_MASK(INT_UDN_FIREWALL) | \
INT_MASK(INT_TILE_TIMER) | \
INT_MASK(INT_AUX_TILE_TIMER) | \
INT_MASK(INT_IDN_TIMER) | \
INT_MASK(INT_UDN_TIMER) | \
INT_MASK(INT_IDN_AVAIL) | \
INT_MASK(INT_UDN_AVAIL) | \
INT_MASK(INT_IPI_3) | \
INT_MASK(INT_IPI_2) | \
INT_MASK(INT_IPI_1) | \
INT_MASK(INT_IPI_0) | \
INT_MASK(INT_PERF_COUNT) | \
INT_MASK(INT_AUX_PERF_COUNT) | \
INT_MASK(INT_INTCTRL_3) | \
INT_MASK(INT_INTCTRL_2) | \
INT_MASK(INT_INTCTRL_1) | \
INT_MASK(INT_INTCTRL_0) | \
INT_MASK(INT_BOOT_ACCESS) | \
INT_MASK(INT_WORLD_ACCESS) | \
INT_MASK(INT_I_ASID) | \
INT_MASK(INT_D_ASID) | \
INT_MASK(INT_DOUBLE_FAULT) | \
0)
#endif /* !__ASSEMBLER__ */
#endif /* !__ARCH_INTERRUPTS_H__ */

View File

@ -12,6 +12,15 @@
* more details.
*/
/* Include the proper base SPR definition file. */
#ifdef __tilegx__
#include <arch/spr_def_64.h>
#else
#include <arch/spr_def_32.h>
#endif
#ifdef __KERNEL__
/*
* In addition to including the proper base SPR definition file, depending
* on machine architecture, this file defines several macros which allow
@ -29,7 +38,6 @@
#define _concat4(a, b, c, d) __concat4(a, b, c, d)
#ifdef __tilegx__
#include <arch/spr_def_64.h>
/* TILE-Gx dependent, protection-level dependent SPRs. */
@ -65,7 +73,6 @@
_concat4(INT_SINGLE_STEP_, CONFIG_KERNEL_PL,,)
#else
#include <arch/spr_def_32.h>
/* TILEPro dependent, protection-level dependent SPRs. */
@ -102,3 +109,5 @@
_concat4(SPR_INTCTRL_, CONFIG_KERNEL_PL, _STATUS,)
#define INT_INTCTRL_K \
_concat4(INT_INTCTRL_, CONFIG_KERNEL_PL,,)
#endif /* __KERNEL__ */

View File

@ -0,0 +1,173 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#ifndef __DOXYGEN__
#ifndef __ARCH_SPR_DEF_H__
#define __ARCH_SPR_DEF_H__
#define SPR_AUX_PERF_COUNT_0 0x2105
#define SPR_AUX_PERF_COUNT_1 0x2106
#define SPR_AUX_PERF_COUNT_CTL 0x2107
#define SPR_AUX_PERF_COUNT_STS 0x2108
#define SPR_CMPEXCH_VALUE 0x2780
#define SPR_CYCLE 0x2781
#define SPR_DONE 0x2705
#define SPR_DSTREAM_PF 0x2706
#define SPR_EVENT_BEGIN 0x2782
#define SPR_EVENT_END 0x2783
#define SPR_EX_CONTEXT_0_0 0x2580
#define SPR_EX_CONTEXT_0_1 0x2581
#define SPR_EX_CONTEXT_0_1__PL_SHIFT 0
#define SPR_EX_CONTEXT_0_1__PL_RMASK 0x3
#define SPR_EX_CONTEXT_0_1__PL_MASK 0x3
#define SPR_EX_CONTEXT_0_1__ICS_SHIFT 2
#define SPR_EX_CONTEXT_0_1__ICS_RMASK 0x1
#define SPR_EX_CONTEXT_0_1__ICS_MASK 0x4
#define SPR_EX_CONTEXT_1_0 0x2480
#define SPR_EX_CONTEXT_1_1 0x2481
#define SPR_EX_CONTEXT_1_1__PL_SHIFT 0
#define SPR_EX_CONTEXT_1_1__PL_RMASK 0x3
#define SPR_EX_CONTEXT_1_1__PL_MASK 0x3
#define SPR_EX_CONTEXT_1_1__ICS_SHIFT 2
#define SPR_EX_CONTEXT_1_1__ICS_RMASK 0x1
#define SPR_EX_CONTEXT_1_1__ICS_MASK 0x4
#define SPR_EX_CONTEXT_2_0 0x2380
#define SPR_EX_CONTEXT_2_1 0x2381
#define SPR_EX_CONTEXT_2_1__PL_SHIFT 0
#define SPR_EX_CONTEXT_2_1__PL_RMASK 0x3
#define SPR_EX_CONTEXT_2_1__PL_MASK 0x3
#define SPR_EX_CONTEXT_2_1__ICS_SHIFT 2
#define SPR_EX_CONTEXT_2_1__ICS_RMASK 0x1
#define SPR_EX_CONTEXT_2_1__ICS_MASK 0x4
#define SPR_FAIL 0x2707
#define SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK 0x1
#define SPR_INTCTRL_0_STATUS 0x2505
#define SPR_INTCTRL_1_STATUS 0x2405
#define SPR_INTCTRL_2_STATUS 0x2305
#define SPR_INTERRUPT_CRITICAL_SECTION 0x2708
#define SPR_INTERRUPT_MASK_0 0x2506
#define SPR_INTERRUPT_MASK_1 0x2406
#define SPR_INTERRUPT_MASK_2 0x2306
#define SPR_INTERRUPT_MASK_RESET_0 0x2507
#define SPR_INTERRUPT_MASK_RESET_1 0x2407
#define SPR_INTERRUPT_MASK_RESET_2 0x2307
#define SPR_INTERRUPT_MASK_SET_0 0x2508
#define SPR_INTERRUPT_MASK_SET_1 0x2408
#define SPR_INTERRUPT_MASK_SET_2 0x2308
#define SPR_INTERRUPT_VECTOR_BASE_0 0x2509
#define SPR_INTERRUPT_VECTOR_BASE_1 0x2409
#define SPR_INTERRUPT_VECTOR_BASE_2 0x2309
#define SPR_INTERRUPT_VECTOR_BASE_3 0x2209
#define SPR_IPI_EVENT_0 0x1f05
#define SPR_IPI_EVENT_1 0x1e05
#define SPR_IPI_EVENT_2 0x1d05
#define SPR_IPI_EVENT_RESET_0 0x1f06
#define SPR_IPI_EVENT_RESET_1 0x1e06
#define SPR_IPI_EVENT_RESET_2 0x1d06
#define SPR_IPI_EVENT_SET_0 0x1f07
#define SPR_IPI_EVENT_SET_1 0x1e07
#define SPR_IPI_EVENT_SET_2 0x1d07
#define SPR_IPI_MASK_0 0x1f08
#define SPR_IPI_MASK_1 0x1e08
#define SPR_IPI_MASK_2 0x1d08
#define SPR_IPI_MASK_RESET_0 0x1f09
#define SPR_IPI_MASK_RESET_1 0x1e09
#define SPR_IPI_MASK_RESET_2 0x1d09
#define SPR_IPI_MASK_SET_0 0x1f0a
#define SPR_IPI_MASK_SET_1 0x1e0a
#define SPR_IPI_MASK_SET_2 0x1d0a
#define SPR_MPL_AUX_TILE_TIMER_SET_0 0x1700
#define SPR_MPL_AUX_TILE_TIMER_SET_1 0x1701
#define SPR_MPL_AUX_TILE_TIMER_SET_2 0x1702
#define SPR_MPL_INTCTRL_0_SET_0 0x2500
#define SPR_MPL_INTCTRL_0_SET_1 0x2501
#define SPR_MPL_INTCTRL_0_SET_2 0x2502
#define SPR_MPL_INTCTRL_1_SET_0 0x2400
#define SPR_MPL_INTCTRL_1_SET_1 0x2401
#define SPR_MPL_INTCTRL_1_SET_2 0x2402
#define SPR_MPL_INTCTRL_2_SET_0 0x2300
#define SPR_MPL_INTCTRL_2_SET_1 0x2301
#define SPR_MPL_INTCTRL_2_SET_2 0x2302
#define SPR_MPL_UDN_ACCESS_SET_0 0x0b00
#define SPR_MPL_UDN_ACCESS_SET_1 0x0b01
#define SPR_MPL_UDN_ACCESS_SET_2 0x0b02
#define SPR_MPL_UDN_AVAIL_SET_0 0x1b00
#define SPR_MPL_UDN_AVAIL_SET_1 0x1b01
#define SPR_MPL_UDN_AVAIL_SET_2 0x1b02
#define SPR_MPL_UDN_COMPLETE_SET_0 0x0600
#define SPR_MPL_UDN_COMPLETE_SET_1 0x0601
#define SPR_MPL_UDN_COMPLETE_SET_2 0x0602
#define SPR_MPL_UDN_FIREWALL_SET_0 0x1500
#define SPR_MPL_UDN_FIREWALL_SET_1 0x1501
#define SPR_MPL_UDN_FIREWALL_SET_2 0x1502
#define SPR_MPL_UDN_TIMER_SET_0 0x1900
#define SPR_MPL_UDN_TIMER_SET_1 0x1901
#define SPR_MPL_UDN_TIMER_SET_2 0x1902
#define SPR_MPL_WORLD_ACCESS_SET_0 0x2700
#define SPR_MPL_WORLD_ACCESS_SET_1 0x2701
#define SPR_MPL_WORLD_ACCESS_SET_2 0x2702
#define SPR_PASS 0x2709
#define SPR_PERF_COUNT_0 0x2005
#define SPR_PERF_COUNT_1 0x2006
#define SPR_PERF_COUNT_CTL 0x2007
#define SPR_PERF_COUNT_DN_CTL 0x2008
#define SPR_PERF_COUNT_STS 0x2009
#define SPR_PROC_STATUS 0x2784
#define SPR_SIM_CONTROL 0x2785
#define SPR_SINGLE_STEP_CONTROL_0 0x0405
#define SPR_SINGLE_STEP_CONTROL_0__CANCELED_MASK 0x1
#define SPR_SINGLE_STEP_CONTROL_0__INHIBIT_MASK 0x2
#define SPR_SINGLE_STEP_CONTROL_1 0x0305
#define SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK 0x1
#define SPR_SINGLE_STEP_CONTROL_1__INHIBIT_MASK 0x2
#define SPR_SINGLE_STEP_CONTROL_2 0x0205
#define SPR_SINGLE_STEP_CONTROL_2__CANCELED_MASK 0x1
#define SPR_SINGLE_STEP_CONTROL_2__INHIBIT_MASK 0x2
#define SPR_SINGLE_STEP_EN_0_0 0x250a
#define SPR_SINGLE_STEP_EN_0_1 0x240a
#define SPR_SINGLE_STEP_EN_0_2 0x230a
#define SPR_SINGLE_STEP_EN_1_0 0x250b
#define SPR_SINGLE_STEP_EN_1_1 0x240b
#define SPR_SINGLE_STEP_EN_1_2 0x230b
#define SPR_SINGLE_STEP_EN_2_0 0x250c
#define SPR_SINGLE_STEP_EN_2_1 0x240c
#define SPR_SINGLE_STEP_EN_2_2 0x230c
#define SPR_SYSTEM_SAVE_0_0 0x2582
#define SPR_SYSTEM_SAVE_0_1 0x2583
#define SPR_SYSTEM_SAVE_0_2 0x2584
#define SPR_SYSTEM_SAVE_0_3 0x2585
#define SPR_SYSTEM_SAVE_1_0 0x2482
#define SPR_SYSTEM_SAVE_1_1 0x2483
#define SPR_SYSTEM_SAVE_1_2 0x2484
#define SPR_SYSTEM_SAVE_1_3 0x2485
#define SPR_SYSTEM_SAVE_2_0 0x2382
#define SPR_SYSTEM_SAVE_2_1 0x2383
#define SPR_SYSTEM_SAVE_2_2 0x2384
#define SPR_SYSTEM_SAVE_2_3 0x2385
#define SPR_TILE_COORD 0x270b
#define SPR_TILE_RTF_HWM 0x270c
#define SPR_TILE_TIMER_CONTROL 0x1605
#define SPR_UDN_AVAIL_EN 0x1b05
#define SPR_UDN_DATA_AVAIL 0x0b80
#define SPR_UDN_DEADLOCK_TIMEOUT 0x1906
#define SPR_UDN_DEMUX_COUNT_0 0x0b05
#define SPR_UDN_DEMUX_COUNT_1 0x0b06
#define SPR_UDN_DEMUX_COUNT_2 0x0b07
#define SPR_UDN_DEMUX_COUNT_3 0x0b08
#define SPR_UDN_DIRECTION_PROTECT 0x1505
#endif /* !defined(__ARCH_SPR_DEF_H__) */
#endif /* !defined(__DOXYGEN__) */

View File

@ -130,17 +130,52 @@ static inline int atomic_read(const atomic_t *v)
*/
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
/*
* We define xchg() and cmpxchg() in the included headers.
* Note that we do not define __HAVE_ARCH_CMPXCHG, since that would imply
* that cmpxchg() is an efficient operation, which is not particularly true.
*/
/* Nonexistent functions intended to cause link errors. */
extern unsigned long __xchg_called_with_bad_pointer(void);
extern unsigned long __cmpxchg_called_with_bad_pointer(void);
#define xchg(ptr, x) \
({ \
typeof(*(ptr)) __x; \
switch (sizeof(*(ptr))) { \
case 4: \
__x = (typeof(__x))(typeof(__x-__x))atomic_xchg( \
(atomic_t *)(ptr), \
(u32)(typeof((x)-(x)))(x)); \
break; \
case 8: \
__x = (typeof(__x))(typeof(__x-__x))atomic64_xchg( \
(atomic64_t *)(ptr), \
(u64)(typeof((x)-(x)))(x)); \
break; \
default: \
__xchg_called_with_bad_pointer(); \
} \
__x; \
})
#define cmpxchg(ptr, o, n) \
({ \
typeof(*(ptr)) __x; \
switch (sizeof(*(ptr))) { \
case 4: \
__x = (typeof(__x))(typeof(__x-__x))atomic_cmpxchg( \
(atomic_t *)(ptr), \
(u32)(typeof((o)-(o)))(o), \
(u32)(typeof((n)-(n)))(n)); \
break; \
case 8: \
__x = (typeof(__x))(typeof(__x-__x))atomic64_cmpxchg( \
(atomic64_t *)(ptr), \
(u64)(typeof((o)-(o)))(o), \
(u64)(typeof((n)-(n)))(n)); \
break; \
default: \
__cmpxchg_called_with_bad_pointer(); \
} \
__x; \
})
#define tas(ptr) (xchg((ptr), 1))
#endif /* __ASSEMBLY__ */

View File

@ -110,16 +110,6 @@ static inline void atomic_set(atomic_t *v, int n)
_atomic_xchg(v, n);
}
#define xchg(ptr, x) ((typeof(*(ptr))) \
((sizeof(*(ptr)) == sizeof(atomic_t)) ? \
atomic_xchg((atomic_t *)(ptr), (long)(x)) : \
__xchg_called_with_bad_pointer()))
#define cmpxchg(ptr, o, n) ((typeof(*(ptr))) \
((sizeof(*(ptr)) == sizeof(atomic_t)) ? \
atomic_cmpxchg((atomic_t *)(ptr), (long)(o), (long)(n)) : \
__cmpxchg_called_with_bad_pointer()))
/* A 64bit atomic type */
typedef struct {

View File

@ -0,0 +1,156 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*
* Do not include directly; use <asm/atomic.h>.
*/
#ifndef _ASM_TILE_ATOMIC_64_H
#define _ASM_TILE_ATOMIC_64_H
#ifndef __ASSEMBLY__
#include <arch/spr_def.h>
/* First, the 32-bit atomic ops that are "real" on our 64-bit platform. */
#define atomic_set(v, i) ((v)->counter = (i))
/*
* The smp_mb() operations throughout are to support the fact that
* Linux requires memory barriers before and after the operation,
* on any routine which updates memory and returns a value.
*/
static inline int atomic_cmpxchg(atomic_t *v, int o, int n)
{
int val;
__insn_mtspr(SPR_CMPEXCH_VALUE, o);
smp_mb(); /* barrier for proper semantics */
val = __insn_cmpexch4((void *)&v->counter, n);
smp_mb(); /* barrier for proper semantics */
return val;
}
static inline int atomic_xchg(atomic_t *v, int n)
{
int val;
smp_mb(); /* barrier for proper semantics */
val = __insn_exch4((void *)&v->counter, n);
smp_mb(); /* barrier for proper semantics */
return val;
}
static inline void atomic_add(int i, atomic_t *v)
{
__insn_fetchadd4((void *)&v->counter, i);
}
static inline int atomic_add_return(int i, atomic_t *v)
{
int val;
smp_mb(); /* barrier for proper semantics */
val = __insn_fetchadd4((void *)&v->counter, i) + i;
barrier(); /* the "+ i" above will wait on memory */
return val;
}
static inline int atomic_add_unless(atomic_t *v, int a, int u)
{
int guess, oldval = v->counter;
do {
if (oldval == u)
break;
guess = oldval;
oldval = atomic_cmpxchg(v, guess, guess + a);
} while (guess != oldval);
return oldval != u;
}
/* Now the true 64-bit operations. */
#define ATOMIC64_INIT(i) { (i) }
#define atomic64_read(v) ((v)->counter)
#define atomic64_set(v, i) ((v)->counter = (i))
static inline long atomic64_cmpxchg(atomic64_t *v, long o, long n)
{
long val;
smp_mb(); /* barrier for proper semantics */
__insn_mtspr(SPR_CMPEXCH_VALUE, o);
val = __insn_cmpexch((void *)&v->counter, n);
smp_mb(); /* barrier for proper semantics */
return val;
}
static inline long atomic64_xchg(atomic64_t *v, long n)
{
long val;
smp_mb(); /* barrier for proper semantics */
val = __insn_exch((void *)&v->counter, n);
smp_mb(); /* barrier for proper semantics */
return val;
}
static inline void atomic64_add(long i, atomic64_t *v)
{
__insn_fetchadd((void *)&v->counter, i);
}
static inline long atomic64_add_return(long i, atomic64_t *v)
{
int val;
smp_mb(); /* barrier for proper semantics */
val = __insn_fetchadd((void *)&v->counter, i) + i;
barrier(); /* the "+ i" above will wait on memory */
return val;
}
static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
{
long guess, oldval = v->counter;
do {
if (oldval == u)
break;
guess = oldval;
oldval = atomic64_cmpxchg(v, guess, guess + a);
} while (guess != oldval);
return oldval != u;
}
#define atomic64_sub_return(i, v) atomic64_add_return(-(i), (v))
#define atomic64_sub(i, v) atomic64_add(-(i), (v))
#define atomic64_inc_return(v) atomic64_add_return(1, (v))
#define atomic64_dec_return(v) atomic64_sub_return(1, (v))
#define atomic64_inc(v) atomic64_add(1, (v))
#define atomic64_dec(v) atomic64_sub(1, (v))
#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
#define atomic64_dec_and_test(v) (atomic64_dec_return(v) == 0)
#define atomic64_sub_and_test(i, v) (atomic64_sub_return((i), (v)) == 0)
#define atomic64_add_negative(i, v) (atomic64_add_return((i), (v)) < 0)
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
/* Atomic dec and inc don't implement barrier, so provide them if needed. */
#define smp_mb__before_atomic_dec() smp_mb()
#define smp_mb__after_atomic_dec() smp_mb()
#define smp_mb__before_atomic_inc() smp_mb()
#define smp_mb__after_atomic_inc() smp_mb()
/* Define this to indicate that cmpxchg is an efficient operation. */
#define __HAVE_ARCH_CMPXCHG
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_TILE_ATOMIC_64_H */

View File

@ -12,80 +12,41 @@
* more details.
*/
#ifndef _TILE_BACKTRACE_H
#define _TILE_BACKTRACE_H
#ifndef _ASM_TILE_BACKTRACE_H
#define _ASM_TILE_BACKTRACE_H
#include <linux/types.h>
#include <arch/chip.h>
#if defined(__tile__)
typedef unsigned long VirtualAddress;
#elif CHIP_VA_WIDTH() > 32
typedef unsigned long long VirtualAddress;
#else
typedef unsigned int VirtualAddress;
#endif
/** Reads 'size' bytes from 'address' and writes the data to 'result'.
/* Reads 'size' bytes from 'address' and writes the data to 'result'.
* Returns true if successful, else false (e.g. memory not readable).
*/
typedef bool (*BacktraceMemoryReader)(void *result,
VirtualAddress address,
unsigned long address,
unsigned int size,
void *extra);
typedef struct {
/** Current PC. */
VirtualAddress pc;
/* Current PC. */
unsigned long pc;
/** Current stack pointer value. */
VirtualAddress sp;
/* Current stack pointer value. */
unsigned long sp;
/** Current frame pointer value (i.e. caller's stack pointer) */
VirtualAddress fp;
/* Current frame pointer value (i.e. caller's stack pointer) */
unsigned long fp;
/** Internal use only: caller's PC for first frame. */
VirtualAddress initial_frame_caller_pc;
/* Internal use only: caller's PC for first frame. */
unsigned long initial_frame_caller_pc;
/** Internal use only: callback to read memory. */
/* Internal use only: callback to read memory. */
BacktraceMemoryReader read_memory_func;
/** Internal use only: arbitrary argument to read_memory_func. */
/* Internal use only: arbitrary argument to read_memory_func. */
void *read_memory_func_extra;
} BacktraceIterator;
/** Initializes a backtracer to start from the given location.
*
* If the frame pointer cannot be determined it is set to -1.
*
* @param state The state to be filled in.
* @param read_memory_func A callback that reads memory. If NULL, a default
* value is provided.
* @param read_memory_func_extra An arbitrary argument to read_memory_func.
* @param pc The current PC.
* @param lr The current value of the 'lr' register.
* @param sp The current value of the 'sp' register.
* @param r52 The current value of the 'r52' register.
*/
extern void backtrace_init(BacktraceIterator *state,
BacktraceMemoryReader read_memory_func,
void *read_memory_func_extra,
VirtualAddress pc, VirtualAddress lr,
VirtualAddress sp, VirtualAddress r52);
/** Advances the backtracing state to the calling frame, returning
* true iff successful.
*/
extern bool backtrace_next(BacktraceIterator *state);
typedef enum {
/* We have no idea what the caller's pc is. */
@ -138,7 +99,7 @@ enum {
};
/** Internal constants used to define 'info' operands. */
/* Internal constants used to define 'info' operands. */
enum {
/* 0 and 1 are reserved, as are all negative numbers. */
@ -147,13 +108,10 @@ enum {
CALLER_SP_IN_R52_BASE = 4,
CALLER_SP_OFFSET_BASE = 8,
/* Marks the entry point of certain functions. */
ENTRY_POINT_INFO_OP = 16
};
/** Current backtracer state describing where it thinks the caller is. */
/* Current backtracer state describing where it thinks the caller is. */
typedef struct {
/*
* Public fields
@ -192,7 +150,13 @@ typedef struct {
} CallerLocation;
extern void backtrace_init(BacktraceIterator *state,
BacktraceMemoryReader read_memory_func,
void *read_memory_func_extra,
unsigned long pc, unsigned long lr,
unsigned long sp, unsigned long r52);
extern bool backtrace_next(BacktraceIterator *state);
#endif /* _TILE_BACKTRACE_H */
#endif /* _ASM_TILE_BACKTRACE_H */

View File

@ -122,6 +122,7 @@ static inline unsigned long __arch_hweight64(__u64 w)
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/non-atomic.h>
#include <asm-generic/bitops/le.h>
#endif /* _ASM_TILE_BITOPS_H */

View File

@ -126,7 +126,6 @@ static inline int test_and_change_bit(unsigned nr,
#define smp_mb__before_clear_bit() smp_mb()
#define smp_mb__after_clear_bit() do {} while (0)
#include <asm-generic/bitops/non-atomic.h>
#include <asm-generic/bitops/ext2-atomic.h>
#endif /* _ASM_TILE_BITOPS_32_H */

View File

@ -0,0 +1,105 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#ifndef _ASM_TILE_BITOPS_64_H
#define _ASM_TILE_BITOPS_64_H
#include <linux/compiler.h>
#include <asm/atomic.h>
#include <asm/system.h>
/* See <asm/bitops.h> for API comments. */
static inline void set_bit(unsigned nr, volatile unsigned long *addr)
{
unsigned long mask = (1UL << (nr % BITS_PER_LONG));
__insn_fetchor((void *)(addr + nr / BITS_PER_LONG), mask);
}
static inline void clear_bit(unsigned nr, volatile unsigned long *addr)
{
unsigned long mask = (1UL << (nr % BITS_PER_LONG));
__insn_fetchand((void *)(addr + nr / BITS_PER_LONG), ~mask);
}
#define smp_mb__before_clear_bit() smp_mb()
#define smp_mb__after_clear_bit() smp_mb()
static inline void change_bit(unsigned nr, volatile unsigned long *addr)
{
unsigned long old, mask = (1UL << (nr % BITS_PER_LONG));
long guess, oldval;
addr += nr / BITS_PER_LONG;
old = *addr;
do {
guess = oldval;
oldval = atomic64_cmpxchg((atomic64_t *)addr,
guess, guess ^ mask);
} while (guess != oldval);
}
/*
* The test_and_xxx_bit() routines require a memory fence before we
* start the operation, and after the operation completes. We use
* smp_mb() before, and rely on the "!= 0" comparison, plus a compiler
* barrier(), to block until the atomic op is complete.
*/
static inline int test_and_set_bit(unsigned nr, volatile unsigned long *addr)
{
int val;
unsigned long mask = (1UL << (nr % BITS_PER_LONG));
smp_mb(); /* barrier for proper semantics */
val = (__insn_fetchor((void *)(addr + nr / BITS_PER_LONG), mask)
& mask) != 0;
barrier();
return val;
}
static inline int test_and_clear_bit(unsigned nr, volatile unsigned long *addr)
{
int val;
unsigned long mask = (1UL << (nr % BITS_PER_LONG));
smp_mb(); /* barrier for proper semantics */
val = (__insn_fetchand((void *)(addr + nr / BITS_PER_LONG), ~mask)
& mask) != 0;
barrier();
return val;
}
static inline int test_and_change_bit(unsigned nr,
volatile unsigned long *addr)
{
unsigned long mask = (1UL << (nr % BITS_PER_LONG));
long guess, oldval = *addr;
addr += nr / BITS_PER_LONG;
oldval = *addr;
do {
guess = oldval;
oldval = atomic64_cmpxchg((atomic64_t *)addr,
guess, guess ^ mask);
} while (guess != oldval);
return (oldval & mask) != 0;
}
#define ext2_set_bit_atomic(lock, nr, addr) \
test_and_set_bit((nr), (unsigned long *)(addr))
#define ext2_clear_bit_atomic(lock, nr, addr) \
test_and_clear_bit((nr), (unsigned long *)(addr))
#endif /* _ASM_TILE_BITOPS_64_H */

View File

@ -116,22 +116,28 @@ static inline void __finv_buffer(void *buffer, size_t size)
}
/* Invalidate a VA range, then memory fence. */
/* Invalidate a VA range and wait for it to be complete. */
static inline void inv_buffer(void *buffer, size_t size)
{
__inv_buffer(buffer, size);
mb_incoherent();
mb();
}
/* Flush a VA range, then memory fence. */
static inline void flush_buffer(void *buffer, size_t size)
/*
* Flush a locally-homecached VA range and wait for the evicted
* cachelines to hit memory.
*/
static inline void flush_buffer_local(void *buffer, size_t size)
{
__flush_buffer(buffer, size);
mb_incoherent();
}
/* Flush & invalidate a VA range, then memory fence. */
static inline void finv_buffer(void *buffer, size_t size)
/*
* Flush and invalidate a locally-homecached VA range and wait for the
* evicted cachelines to hit memory.
*/
static inline void finv_buffer_local(void *buffer, size_t size)
{
__finv_buffer(buffer, size);
mb_incoherent();

View File

@ -215,8 +215,8 @@ struct compat_sigaction;
struct compat_siginfo;
struct compat_sigaltstack;
long compat_sys_execve(const char __user *path,
const compat_uptr_t __user *argv,
const compat_uptr_t __user *envp, struct pt_regs *);
compat_uptr_t __user *argv,
compat_uptr_t __user *envp, struct pt_regs *);
long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
struct compat_sigaction __user *oact,
size_t sigsetsize);

View File

@ -65,7 +65,8 @@ extern void dma_sync_single_range_for_cpu(struct device *, dma_addr_t,
extern void dma_sync_single_range_for_device(struct device *, dma_addr_t,
unsigned long offset, size_t,
enum dma_data_direction);
extern void dma_cache_sync(void *vaddr, size_t, enum dma_data_direction);
extern void dma_cache_sync(struct device *dev, void *vaddr, size_t,
enum dma_data_direction);
static inline int
dma_mapping_error(struct device *dev, dma_addr_t dma_addr)

View File

@ -0,0 +1 @@
#include <asm-generic/fb.h>

View File

@ -52,6 +52,7 @@ extern void iounmap(volatile void __iomem *addr);
#endif
#define ioremap_nocache(physaddr, size) ioremap(physaddr, size)
#define ioremap_wc(physaddr, size) ioremap(physaddr, size)
#define ioremap_writethrough(physaddr, size) ioremap(physaddr, size)
#define ioremap_fullcache(physaddr, size) ioremap(physaddr, size)
@ -161,6 +162,15 @@ static inline void _tile_writeq(u64 val, unsigned long addr)
#define iowrite32 writel
#define iowrite64 writeq
static inline void memset_io(void *dst, int val, size_t len)
{
int x;
BUG_ON((unsigned long)dst & 0x3);
val = (val & 0xff) * 0x01010101;
for (x = 0; x < len; x += 4)
writel(val, dst + x);
}
static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
size_t len)
{
@ -269,6 +279,11 @@ static inline void outsl(unsigned long addr, const void *buffer, int count)
ioport_panic();
}
#define ioread16be(addr) be16_to_cpu(ioread16(addr))
#define ioread32be(addr) be32_to_cpu(ioread32(addr))
#define iowrite16be(v, addr) iowrite16(be16_to_cpu(v), (addr))
#define iowrite32be(v, addr) iowrite32(be32_to_cpu(v), (addr))
#define ioread8_rep(p, dst, count) \
insb((unsigned long) (p), (dst), (count))
#define ioread16_rep(p, dst, count) \
@ -283,4 +298,7 @@ static inline void outsl(unsigned long addr, const void *buffer, int count)
#define iowrite32_rep(p, src, count) \
outsl((unsigned long) (p), (src), (count))
#define virt_to_bus virt_to_phys
#define bus_to_virt phys_to_virt
#endif /* _ASM_TILE_IO_H */

View File

@ -23,6 +23,8 @@
/* IRQ numbers used for linux IPIs. */
#define IRQ_RESCHEDULE 1
#define irq_canonicalize(irq) (irq)
void ack_bad_irq(unsigned int irq);
/*

View File

@ -100,8 +100,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
__get_cpu_var(current_asid) = asid;
/* Clear cpu from the old mm, and set it in the new one. */
cpumask_clear_cpu(cpu, &prev->cpu_vm_mask);
cpumask_set_cpu(cpu, &next->cpu_vm_mask);
cpumask_clear_cpu(cpu, mm_cpumask(prev));
cpumask_set_cpu(cpu, mm_cpumask(next));
/* Re-load page tables */
install_page_table(next->pgd, asid);

View File

@ -1502,5 +1502,12 @@ extern int parse_insn_tile(tile_bundle_bits bits,
decoded[TILE_MAX_INSTRUCTIONS_PER_BUNDLE]);
/* Given a set of bundle bits and a specific pipe, returns which
* instruction the bundle contains in that pipe.
*/
extern const struct tile_opcode *
find_opcode(tile_bundle_bits bits, tile_pipeline pipe);
#endif /* opcode_tile_h */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,8 @@
#define _ASM_TILE_PAGE_H
#include <linux/const.h>
#include <hv/pagesize.h>
#include <hv/hypervisor.h>
#include <arch/chip.h>
/* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */
#define PAGE_SHIFT HV_LOG2_PAGE_SIZE_SMALL
@ -28,8 +29,6 @@
#define PAGE_MASK (~(PAGE_SIZE - 1))
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
#ifdef __KERNEL__
/*
* If the Kconfig doesn't specify, set a maximum zone order that
* is enough so that we can create huge pages from small pages given
@ -39,9 +38,6 @@
#define CONFIG_FORCE_MAX_ZONEORDER (HPAGE_SHIFT - PAGE_SHIFT + 1)
#endif
#include <hv/hypervisor.h>
#include <arch/chip.h>
#ifndef __ASSEMBLY__
#include <linux/types.h>
@ -91,6 +87,10 @@ typedef struct page *pgtable_t;
/* Must be a macro since it is used to create constants. */
#define __pgprot(val) hv_pte(val)
/* Rarely-used initializers, typically with a "zero" value. */
#define __pte(x) hv_pte(x)
#define __pgd(x) hv_pte(x)
static inline u64 pgprot_val(pgprot_t pgprot)
{
return hv_pte_val(pgprot);
@ -110,6 +110,8 @@ static inline u64 pgd_val(pgd_t pgd)
typedef HV_PTE pmd_t;
#define __pmd(x) hv_pte(x)
static inline u64 pmd_val(pmd_t pmd)
{
return hv_pte_val(pmd);
@ -318,7 +320,7 @@ static inline int pfn_valid(unsigned long pfn)
/* Provide as macros since these require some other headers included. */
#define page_to_pa(page) ((phys_addr_t)(page_to_pfn(page)) << PAGE_SHIFT)
#define virt_to_page(kaddr) pfn_to_page(kaddr_to_pfn(kaddr))
#define virt_to_page(kaddr) pfn_to_page(kaddr_to_pfn((void *)(kaddr)))
#define page_to_virt(page) pfn_to_kaddr(page_to_pfn(page))
struct mm_struct;
@ -331,6 +333,4 @@ extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
#include <asm-generic/memory_model.h>
#endif /* __KERNEL__ */
#endif /* _ASM_TILE_PAGE_H */

View File

@ -0,0 +1 @@
#include <asm-generic/parport.h>

View File

@ -46,7 +46,8 @@ struct pci_controller {
*/
#define PCI_DMA_BUS_IS_PHYS 1
int __init tile_pci_init(void);
int __devinit tile_pci_init(void);
int __devinit pcibios_init(void);
void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}

View File

@ -0,0 +1,175 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*
*/
#ifndef _ASM_TILE_PGTABLE_64_H
#define _ASM_TILE_PGTABLE_64_H
/* The level-0 page table breaks the address space into 32-bit chunks. */
#define PGDIR_SHIFT HV_LOG2_L1_SPAN
#define PGDIR_SIZE HV_L1_SPAN
#define PGDIR_MASK (~(PGDIR_SIZE-1))
#define PTRS_PER_PGD HV_L0_ENTRIES
#define SIZEOF_PGD (PTRS_PER_PGD * sizeof(pgd_t))
/*
* The level-1 index is defined by the huge page size. A PMD is composed
* of PTRS_PER_PMD pgd_t's and is the middle level of the page table.
*/
#define PMD_SHIFT HV_LOG2_PAGE_SIZE_LARGE
#define PMD_SIZE HV_PAGE_SIZE_LARGE
#define PMD_MASK (~(PMD_SIZE-1))
#define PTRS_PER_PMD (1 << (PGDIR_SHIFT - PMD_SHIFT))
#define SIZEOF_PMD (PTRS_PER_PMD * sizeof(pmd_t))
/*
* The level-2 index is defined by the difference between the huge
* page size and the normal page size. A PTE is composed of
* PTRS_PER_PTE pte_t's and is the bottom level of the page table.
* Note that the hypervisor docs use PTE for what we call pte_t, so
* this nomenclature is somewhat confusing.
*/
#define PTRS_PER_PTE (1 << (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL))
#define SIZEOF_PTE (PTRS_PER_PTE * sizeof(pte_t))
/*
* Align the vmalloc area to an L2 page table, and leave a guard page
* at the beginning and end. The vmalloc code also puts in an internal
* guard page between each allocation.
*/
#define _VMALLOC_END HUGE_VMAP_BASE
#define VMALLOC_END (_VMALLOC_END - PAGE_SIZE)
#define VMALLOC_START (_VMALLOC_START + PAGE_SIZE)
#define HUGE_VMAP_END (HUGE_VMAP_BASE + PGDIR_SIZE)
#ifndef __ASSEMBLY__
/* We have no pud since we are a three-level page table. */
#include <asm-generic/pgtable-nopud.h>
static inline int pud_none(pud_t pud)
{
return pud_val(pud) == 0;
}
static inline int pud_present(pud_t pud)
{
return pud_val(pud) & _PAGE_PRESENT;
}
#define pmd_ERROR(e) \
pr_err("%s:%d: bad pmd 0x%016llx.\n", __FILE__, __LINE__, pmd_val(e))
static inline void pud_clear(pud_t *pudp)
{
__pte_clear(&pudp->pgd);
}
static inline int pud_bad(pud_t pud)
{
return ((pud_val(pud) & _PAGE_ALL) != _PAGE_TABLE);
}
/* Return the page-table frame number (ptfn) that a pud_t points at. */
#define pud_ptfn(pud) hv_pte_get_ptfn((pud).pgd)
/*
* A given kernel pud_t maps to a kernel pmd_t table at a specific
* virtual address. Since kernel pmd_t tables can be aligned at
* sub-page granularity, this macro can return non-page-aligned
* pointers, despite its name.
*/
#define pud_page_vaddr(pud) \
(__va((phys_addr_t)pud_ptfn(pud) << HV_LOG2_PAGE_TABLE_ALIGN))
/*
* A pud_t points to a pmd_t array. Since we can have multiple per
* page, we don't have a one-to-one mapping of pud_t's to pages.
*/
#define pud_page(pud) pfn_to_page(HV_PTFN_TO_PFN(pud_ptfn(pud)))
static inline unsigned long pud_index(unsigned long address)
{
return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1);
}
#define pmd_offset(pud, address) \
((pmd_t *)pud_page_vaddr(*(pud)) + pmd_index(address))
static inline void __set_pmd(pmd_t *pmdp, pmd_t pmdval)
{
set_pte(pmdp, pmdval);
}
/* Create a pmd from a PTFN and pgprot. */
static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot)
{
return hv_pte_set_ptfn(prot, ptfn);
}
/* Return the page-table frame number (ptfn) that a pmd_t points at. */
static inline unsigned long pmd_ptfn(pmd_t pmd)
{
return hv_pte_get_ptfn(pmd);
}
static inline void pmd_clear(pmd_t *pmdp)
{
__pte_clear(pmdp);
}
/* Normalize an address to having the correct high bits set. */
#define pgd_addr_normalize pgd_addr_normalize
static inline unsigned long pgd_addr_normalize(unsigned long addr)
{
return ((long)addr << (CHIP_WORD_SIZE() - CHIP_VA_WIDTH())) >>
(CHIP_WORD_SIZE() - CHIP_VA_WIDTH());
}
/* We don't define any pgds for these addresses. */
static inline int pgd_addr_invalid(unsigned long addr)
{
return addr >= MEM_HV_START ||
(addr > MEM_LOW_END && addr < MEM_HIGH_START);
}
/*
* Use atomic instructions to provide atomicity against the hypervisor.
*/
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep)
{
return (__insn_fetchand(&ptep->val, ~HV_PTE_ACCESSED) >>
HV_PTE_INDEX_ACCESSED) & 0x1;
}
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
static inline void ptep_set_wrprotect(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
__insn_fetchand(&ptep->val, ~HV_PTE_WRITABLE);
}
#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)
{
return hv_pte(__insn_exch(&ptep->val, 0UL));
}
#endif /* __ASSEMBLY__ */
#endif /* _ASM_TILE_PGTABLE_64_H */

View File

@ -215,6 +215,8 @@ static inline void release_thread(struct task_struct *dead_task)
extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
extern int do_work_pending(struct pt_regs *regs, u32 flags);
/*
* Return saved (kernel) PC of a blocked thread.
@ -255,10 +257,6 @@ static inline void cpu_relax(void)
barrier();
}
struct siginfo;
extern void arch_coredump_signal(struct siginfo *, struct pt_regs *);
#define arch_coredump_signal arch_coredump_signal
/* Info on this processor (see fs/proc/cpuinfo.c) */
struct seq_operations;
extern const struct seq_operations cpuinfo_op;
@ -269,9 +267,6 @@ extern char chip_model[64];
/* Data on which physical memory controller corresponds to which NUMA node. */
extern int node_controller[];
/* Do we dump information to the console when a user application crashes? */
extern int show_crashinfo;
#if CHIP_HAS_CBOX_HOME_MAP()
/* Does the heap allocator return hash-for-home pages by default? */
extern int hash_default;

View File

@ -0,0 +1 @@
#include <asm-generic/serial.h>

View File

@ -28,6 +28,10 @@ struct pt_regs;
int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
void do_signal(struct pt_regs *regs);
void signal_fault(const char *type, struct pt_regs *,
void __user *frame, int sig);
void trace_unhandled_signal(const char *type, struct pt_regs *regs,
unsigned long address, int signo);
#endif
#endif /* _ASM_TILE_SIGNAL_H */

View File

@ -0,0 +1,161 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*
* 64-bit SMP ticket spinlocks, allowing only a single CPU anywhere
* (the type definitions are in asm/spinlock_types.h)
*/
#ifndef _ASM_TILE_SPINLOCK_64_H
#define _ASM_TILE_SPINLOCK_64_H
/* Shifts and masks for the various fields in "lock". */
#define __ARCH_SPIN_CURRENT_SHIFT 17
#define __ARCH_SPIN_NEXT_MASK 0x7fff
#define __ARCH_SPIN_NEXT_OVERFLOW 0x8000
/*
* Return the "current" portion of a ticket lock value,
* i.e. the number that currently owns the lock.
*/
static inline int arch_spin_current(u32 val)
{
return val >> __ARCH_SPIN_CURRENT_SHIFT;
}
/*
* Return the "next" portion of a ticket lock value,
* i.e. the number that the next task to try to acquire the lock will get.
*/
static inline int arch_spin_next(u32 val)
{
return val & __ARCH_SPIN_NEXT_MASK;
}
/* The lock is locked if a task would have to wait to get it. */
static inline int arch_spin_is_locked(arch_spinlock_t *lock)
{
u32 val = lock->lock;
return arch_spin_current(val) != arch_spin_next(val);
}
/* Bump the current ticket so the next task owns the lock. */
static inline void arch_spin_unlock(arch_spinlock_t *lock)
{
wmb(); /* guarantee anything modified under the lock is visible */
__insn_fetchadd4(&lock->lock, 1U << __ARCH_SPIN_CURRENT_SHIFT);
}
void arch_spin_unlock_wait(arch_spinlock_t *lock);
void arch_spin_lock_slow(arch_spinlock_t *lock, u32 val);
/* Grab the "next" ticket number and bump it atomically.
* If the current ticket is not ours, go to the slow path.
* We also take the slow path if the "next" value overflows.
*/
static inline void arch_spin_lock(arch_spinlock_t *lock)
{
u32 val = __insn_fetchadd4(&lock->lock, 1);
u32 ticket = val & (__ARCH_SPIN_NEXT_MASK | __ARCH_SPIN_NEXT_OVERFLOW);
if (unlikely(arch_spin_current(val) != ticket))
arch_spin_lock_slow(lock, ticket);
}
/* Try to get the lock, and return whether we succeeded. */
int arch_spin_trylock(arch_spinlock_t *lock);
/* We cannot take an interrupt after getting a ticket, so don't enable them. */
#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
/*
* Read-write spinlocks, allowing multiple readers
* but only one writer.
*
* We use fetchadd() for readers, and fetchor() with the sign bit
* for writers.
*/
#define __WRITE_LOCK_BIT (1 << 31)
static inline int arch_write_val_locked(int val)
{
return val < 0; /* Optimize "val & __WRITE_LOCK_BIT". */
}
/**
* read_can_lock - would read_trylock() succeed?
* @lock: the rwlock in question.
*/
static inline int arch_read_can_lock(arch_rwlock_t *rw)
{
return !arch_write_val_locked(rw->lock);
}
/**
* write_can_lock - would write_trylock() succeed?
* @lock: the rwlock in question.
*/
static inline int arch_write_can_lock(arch_rwlock_t *rw)
{
return rw->lock == 0;
}
extern void __read_lock_failed(arch_rwlock_t *rw);
static inline void arch_read_lock(arch_rwlock_t *rw)
{
u32 val = __insn_fetchaddgez4(&rw->lock, 1);
if (unlikely(arch_write_val_locked(val)))
__read_lock_failed(rw);
}
extern void __write_lock_failed(arch_rwlock_t *rw, u32 val);
static inline void arch_write_lock(arch_rwlock_t *rw)
{
u32 val = __insn_fetchor4(&rw->lock, __WRITE_LOCK_BIT);
if (unlikely(val != 0))
__write_lock_failed(rw, val);
}
static inline void arch_read_unlock(arch_rwlock_t *rw)
{
__insn_mf();
__insn_fetchadd4(&rw->lock, -1);
}
static inline void arch_write_unlock(arch_rwlock_t *rw)
{
__insn_mf();
rw->lock = 0;
}
static inline int arch_read_trylock(arch_rwlock_t *rw)
{
return !arch_write_val_locked(__insn_fetchaddgez4(&rw->lock, 1));
}
static inline int arch_write_trylock(arch_rwlock_t *rw)
{
u32 val = __insn_fetchor4(&rw->lock, __WRITE_LOCK_BIT);
if (likely(val == 0))
return 1;
if (!arch_write_val_locked(val))
__insn_fetchand4(&rw->lock, ~__WRITE_LOCK_BIT);
return 0;
}
#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
#endif /* _ASM_TILE_SPINLOCK_64_H */

View File

@ -1,4 +1,4 @@
#ifdef CONFIG_COMPAT
#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
#define __ARCH_WANT_STAT64 /* Used for compat_sys_stat64() etc. */
#endif
#include <asm-generic/stat.h>

View File

@ -18,12 +18,6 @@
/* Tile gcc is always >= 4.3.0, so we use __builtin_bswap. */
#define __arch_swab32(x) __builtin_bswap32(x)
#define __arch_swab64(x) __builtin_bswap64(x)
/* Use the variant that is natural for the wordsize. */
#ifdef CONFIG_64BIT
#define __arch_swab16(x) (__builtin_bswap64(x) >> 48)
#else
#define __arch_swab16(x) (__builtin_bswap32(x) >> 16)
#endif
#endif /* _ASM_TILE_SWAB_H */

View File

@ -125,6 +125,7 @@ extern void cpu_idle_on_new_stack(struct thread_info *old_ti,
#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
#define TIF_SECCOMP 6 /* secure computing */
#define TIF_MEMDIE 7 /* OOM killer at work */
#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
@ -134,10 +135,12 @@ extern void cpu_idle_on_new_stack(struct thread_info *old_ti,
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_MEMDIE (1<<TIF_MEMDIE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
/* Work to do on any return to user space. */
#define _TIF_ALLWORK_MASK \
(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SINGLESTEP|_TIF_ASYNC_TLB)
(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SINGLESTEP|\
_TIF_ASYNC_TLB|_TIF_NOTIFY_RESUME)
/*
* Thread-synchronous status.

View File

@ -44,25 +44,64 @@ static inline const struct cpumask *cpumask_of_node(int node)
/* For now, use numa node -1 for global allocation. */
#define pcibus_to_node(bus) ((void)(bus), -1)
/*
* TILE architecture has many cores integrated in one processor, so we need
* setup bigger balance_interval for both CPU/NODE scheduling domains to
* reduce process scheduling costs.
*/
/* sched_domains SD_CPU_INIT for TILE architecture */
#define SD_CPU_INIT (struct sched_domain) { \
.min_interval = 4, \
.max_interval = 128, \
.busy_factor = 64, \
.imbalance_pct = 125, \
.cache_nice_tries = 1, \
.busy_idx = 2, \
.idle_idx = 1, \
.newidle_idx = 0, \
.wake_idx = 0, \
.forkexec_idx = 0, \
\
.flags = 1*SD_LOAD_BALANCE \
| 1*SD_BALANCE_NEWIDLE \
| 1*SD_BALANCE_EXEC \
| 1*SD_BALANCE_FORK \
| 0*SD_BALANCE_WAKE \
| 0*SD_WAKE_AFFINE \
| 0*SD_PREFER_LOCAL \
| 0*SD_SHARE_CPUPOWER \
| 0*SD_SHARE_PKG_RESOURCES \
| 0*SD_SERIALIZE \
, \
.last_balance = jiffies, \
.balance_interval = 32, \
}
/* sched_domains SD_NODE_INIT for TILE architecture */
#define SD_NODE_INIT (struct sched_domain) { \
.min_interval = 8, \
.max_interval = 32, \
.busy_factor = 32, \
.imbalance_pct = 125, \
.cache_nice_tries = 1, \
.busy_idx = 3, \
.idle_idx = 1, \
.newidle_idx = 2, \
.wake_idx = 1, \
.flags = SD_LOAD_BALANCE \
| SD_BALANCE_NEWIDLE \
| SD_BALANCE_EXEC \
| SD_BALANCE_FORK \
| SD_WAKE_AFFINE \
| SD_SERIALIZE, \
.last_balance = jiffies, \
.balance_interval = 1, \
#define SD_NODE_INIT (struct sched_domain) { \
.min_interval = 16, \
.max_interval = 512, \
.busy_factor = 32, \
.imbalance_pct = 125, \
.cache_nice_tries = 1, \
.busy_idx = 3, \
.idle_idx = 1, \
.newidle_idx = 2, \
.wake_idx = 1, \
.flags = 1*SD_LOAD_BALANCE \
| 1*SD_BALANCE_NEWIDLE \
| 1*SD_BALANCE_EXEC \
| 1*SD_BALANCE_FORK \
| 0*SD_BALANCE_WAKE \
| 0*SD_WAKE_AFFINE \
| 0*SD_PREFER_LOCAL \
| 0*SD_SHARE_CPUPOWER \
| 0*SD_SHARE_PKG_RESOURCES \
| 1*SD_SERIALIZE \
, \
.last_balance = jiffies, \
.balance_interval = 128, \
}
/* By definition, we create nodes based on online memory. */

View File

@ -15,10 +15,14 @@
#ifndef _ASM_TILE_TRAPS_H
#define _ASM_TILE_TRAPS_H
#include <arch/chip.h>
/* mm/fault.c */
void do_page_fault(struct pt_regs *, int fault_num,
unsigned long address, unsigned long write);
#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
void do_async_page_fault(struct pt_regs *);
#endif
#ifndef __tilegx__
/*

View File

@ -15,7 +15,7 @@
#if !defined(_ASM_TILE_UNISTD_H) || defined(__SYSCALL)
#define _ASM_TILE_UNISTD_H
#ifndef __LP64__
#if !defined(__LP64__) || defined(__SYSCALL_COMPAT)
/* Use the flavor of this syscall that matches the 32-bit API better. */
#define __ARCH_WANT_SYNC_FILE_RANGE2
#endif

View File

@ -10,23 +10,30 @@
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*
* Access to VGA videoram.
*/
/**
* @file pagesize.h
*/
#ifndef _ASM_TILE_VGA_H
#define _ASM_TILE_VGA_H
#ifndef _HV_PAGESIZE_H
#define _HV_PAGESIZE_H
#include <asm/io.h>
/** The log2 of the size of small pages, in bytes. This value should
* be verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
*/
#define HV_LOG2_PAGE_SIZE_SMALL 16
#define VT_BUF_HAVE_RW
/** The log2 of the size of large pages, in bytes. This value should be
* verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
*/
#define HV_LOG2_PAGE_SIZE_LARGE 24
static inline void scr_writew(u16 val, volatile u16 *addr)
{
__raw_writew(val, (volatile u16 __iomem *) addr);
}
#endif /* _HV_PAGESIZE_H */
static inline u16 scr_readw(volatile const u16 *addr)
{
return __raw_readw((volatile const u16 __iomem *) addr);
}
#define vga_readb(a) readb((u8 __iomem *)(a))
#define vga_writeb(v,a) writeb(v, (u8 __iomem *)(a))
#define VGA_MAP_MEM(x,s) ((unsigned long) ioremap(x, s))
#endif

View File

@ -22,8 +22,6 @@
#include <arch/chip.h>
#include <hv/pagesize.h>
/* Linux builds want unsigned long constants, but assembler wants numbers */
#ifdef __ASSEMBLER__
/** One, for assembler */
@ -44,11 +42,21 @@
*/
#define HV_L1_SPAN (__HV_SIZE_ONE << HV_LOG2_L1_SPAN)
/** The log2 of the size of small pages, in bytes. This value should
* be verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
*/
#define HV_LOG2_PAGE_SIZE_SMALL 16
/** The size of small pages, in bytes. This value should be verified
* at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
*/
#define HV_PAGE_SIZE_SMALL (__HV_SIZE_ONE << HV_LOG2_PAGE_SIZE_SMALL)
/** The log2 of the size of large pages, in bytes. This value should be
* verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
*/
#define HV_LOG2_PAGE_SIZE_LARGE 24
/** The size of large pages, in bytes. This value should be verified
* at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
*/

View File

@ -14,19 +14,11 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <asm/backtrace.h>
#include <arch/chip.h>
#include <asm/opcode-tile.h>
#include <arch/abi.h>
#define TREG_SP 54
#define TREG_LR 55
#if TILE_CHIP >= 10
#ifdef __tilegx__
#define tile_bundle_bits tilegx_bundle_bits
#define TILE_MAX_INSTRUCTIONS_PER_BUNDLE TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE
#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES
@ -47,7 +39,7 @@ typedef long long bt_int_reg_t;
typedef int bt_int_reg_t;
#endif
/** A decoded bundle used for backtracer analysis. */
/* A decoded bundle used for backtracer analysis. */
struct BacktraceBundle {
tile_bundle_bits bits;
int num_insns;
@ -56,23 +48,7 @@ struct BacktraceBundle {
};
/* This implementation only makes sense for native tools. */
/** Default function to read memory. */
static bool bt_read_memory(void *result, VirtualAddress addr,
unsigned int size, void *extra)
{
/* FIXME: this should do some horrible signal stuff to catch
* SEGV cleanly and fail.
*
* Or else the caller should do the setjmp for efficiency.
*/
memcpy(result, (const void *)addr, size);
return true;
}
/** Locates an instruction inside the given bundle that
/* Locates an instruction inside the given bundle that
* has the specified mnemonic, and whose first 'num_operands_to_match'
* operands exactly match those in 'operand_values'.
*/
@ -107,13 +83,13 @@ static const struct tile_decoded_instruction *find_matching_insn(
return NULL;
}
/** Does this bundle contain an 'iret' instruction? */
/* Does this bundle contain an 'iret' instruction? */
static inline bool bt_has_iret(const struct BacktraceBundle *bundle)
{
return find_matching_insn(bundle, TILE_OPC_IRET, NULL, 0) != NULL;
}
/** 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?
*/
static bool bt_has_addi_sp(const struct BacktraceBundle *bundle, int *adjust)
@ -124,7 +100,7 @@ static bool bt_has_addi_sp(const struct BacktraceBundle *bundle, int *adjust)
find_matching_insn(bundle, TILE_OPC_ADDI, vals, 2);
if (insn == NULL)
insn = find_matching_insn(bundle, TILE_OPC_ADDLI, vals, 2);
#if TILE_CHIP >= 10
#ifdef __tilegx__
if (insn == NULL)
insn = find_matching_insn(bundle, TILEGX_OPC_ADDXLI, vals, 2);
if (insn == NULL)
@ -137,7 +113,7 @@ static bool bt_has_addi_sp(const struct BacktraceBundle *bundle, int *adjust)
return true;
}
/** Does this bundle contain any 'info OP' or 'infol OP'
/* Does this bundle contain any 'info OP' or 'infol OP'
* instruction, and if so, what are their OP? Note that OP is interpreted
* as an unsigned value by this code since that's what the caller wants.
* Returns the number of info ops found.
@ -161,7 +137,7 @@ static int bt_get_info_ops(const struct BacktraceBundle *bundle,
return num_ops;
}
/** 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?
*/
static bool bt_has_jrp(const struct BacktraceBundle *bundle, int *target_reg)
@ -175,7 +151,7 @@ static bool bt_has_jrp(const struct BacktraceBundle *bundle, int *target_reg)
return true;
}
/** Does this bundle modify the specified register in any way? */
/* Does this bundle modify the specified register in any way? */
static bool bt_modifies_reg(const struct BacktraceBundle *bundle, int reg)
{
int i, j;
@ -195,34 +171,34 @@ static bool bt_modifies_reg(const struct BacktraceBundle *bundle, int reg)
return false;
}
/** Does this bundle modify sp? */
/* Does this bundle modify sp? */
static inline bool bt_modifies_sp(const struct BacktraceBundle *bundle)
{
return bt_modifies_reg(bundle, TREG_SP);
}
/** Does this bundle modify lr? */
/* Does this bundle modify lr? */
static inline bool bt_modifies_lr(const struct BacktraceBundle *bundle)
{
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 bt_has_move_r52_sp(const struct BacktraceBundle *bundle)
{
static const int vals[2] = { 52, TREG_SP };
return find_matching_insn(bundle, TILE_OPC_MOVE, vals, 2) != NULL;
}
/** Does this bundle contain a store of lr to sp? */
/* Does this bundle contain a store of lr to sp? */
static inline bool bt_has_sw_sp_lr(const struct BacktraceBundle *bundle)
{
static const int vals[2] = { TREG_SP, TREG_LR };
return find_matching_insn(bundle, OPCODE_STORE, vals, 2) != NULL;
}
#if TILE_CHIP >= 10
/** Track moveli values placed into registers. */
#ifdef __tilegx__
/* Track moveli values placed into registers. */
static inline void bt_update_moveli(const struct BacktraceBundle *bundle,
int moveli_args[])
{
@ -238,7 +214,7 @@ static inline void bt_update_moveli(const struct BacktraceBundle *bundle,
}
}
/** Does this bundle contain an 'add sp, sp, reg' instruction
/* Does this bundle contain an 'add sp, sp, reg' instruction
* from a register that we saw a moveli into, and if so, what
* is the value in the register?
*/
@ -260,11 +236,11 @@ static bool bt_has_add_sp(const struct BacktraceBundle *bundle, int *adjust,
}
#endif
/** 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.
*/
static void find_caller_pc_and_caller_sp(CallerLocation *location,
const VirtualAddress start_pc,
const unsigned long start_pc,
BacktraceMemoryReader read_memory_func,
void *read_memory_func_extra)
{
@ -288,9 +264,9 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location,
tile_bundle_bits prefetched_bundles[32];
int num_bundles_prefetched = 0;
int next_bundle = 0;
VirtualAddress pc;
unsigned long pc;
#if TILE_CHIP >= 10
#ifdef __tilegx__
/* Naively try to track moveli values to support addx for -m32. */
int moveli_args[TILEGX_NUM_REGISTERS] = { 0 };
#endif
@ -369,10 +345,6 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location,
/* Weird; reserved value, ignore it. */
continue;
}
if (info_operand & ENTRY_POINT_INFO_OP) {
/* This info op is ignored by the backtracer. */
continue;
}
/* Skip info ops which are not in the
* "one_ago" mode we want right now.
@ -453,7 +425,7 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location,
if (!sp_determined) {
int adjust;
if (bt_has_addi_sp(&bundle, &adjust)
#if TILE_CHIP >= 10
#ifdef __tilegx__
|| bt_has_add_sp(&bundle, &adjust, moveli_args)
#endif
) {
@ -504,7 +476,7 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location,
}
}
#if TILE_CHIP >= 10
#ifdef __tilegx__
/* Track moveli arguments for -m32 mode. */
bt_update_moveli(&bundle, moveli_args);
#endif
@ -546,18 +518,26 @@ static void find_caller_pc_and_caller_sp(CallerLocation *location,
}
}
/* Initializes a backtracer to start from the given location.
*
* If the frame pointer cannot be determined it is set to -1.
*
* state: The state to be filled in.
* read_memory_func: A callback that reads memory.
* read_memory_func_extra: An arbitrary argument to read_memory_func.
* pc: The current PC.
* lr: The current value of the 'lr' register.
* sp: The current value of the 'sp' register.
* r52: The current value of the 'r52' register.
*/
void backtrace_init(BacktraceIterator *state,
BacktraceMemoryReader read_memory_func,
void *read_memory_func_extra,
VirtualAddress pc, VirtualAddress lr,
VirtualAddress sp, VirtualAddress r52)
unsigned long pc, unsigned long lr,
unsigned long sp, unsigned long r52)
{
CallerLocation location;
VirtualAddress fp, initial_frame_caller_pc;
if (read_memory_func == NULL) {
read_memory_func = bt_read_memory;
}
unsigned long fp, initial_frame_caller_pc;
/* Find out where we are in the initial frame. */
find_caller_pc_and_caller_sp(&location, pc,
@ -630,12 +610,15 @@ void backtrace_init(BacktraceIterator *state,
/* Handle the case where the register holds more bits than the VA. */
static bool valid_addr_reg(bt_int_reg_t reg)
{
return ((VirtualAddress)reg == reg);
return ((unsigned long)reg == reg);
}
/* Advances the backtracing state to the calling frame, returning
* true iff successful.
*/
bool backtrace_next(BacktraceIterator *state)
{
VirtualAddress next_fp, next_pc;
unsigned long next_fp, next_pc;
bt_int_reg_t next_frame[2];
if (state->fp == -1) {

View File

@ -135,26 +135,15 @@ long tile_compat_sys_msgrcv(int msqid,
/* Provide the compat syscall number to call mapping. */
#undef __SYSCALL
#define __SYSCALL(nr, call) [nr] = (compat_##call),
#define __SYSCALL(nr, call) [nr] = (call),
/* The generic versions of these don't work for Tile. */
#define compat_sys_msgrcv tile_compat_sys_msgrcv
#define compat_sys_msgsnd tile_compat_sys_msgsnd
/* See comments in sys.c */
#define compat_sys_fadvise64 sys32_fadvise64
#define compat_sys_fadvise64_64 sys32_fadvise64_64
#define compat_sys_readahead sys32_readahead
#define compat_sys_sync_file_range compat_sys_sync_file_range2
/* We leverage the "struct stat64" type for 32-bit time_t/nsec. */
#define compat_sys_stat64 sys_stat64
#define compat_sys_lstat64 sys_lstat64
#define compat_sys_fstat64 sys_fstat64
#define compat_sys_fstatat64 sys_fstatat64
/* The native sys_ptrace dynamically handles compat binaries. */
#define compat_sys_ptrace sys_ptrace
/* Call the trampolines to manage pt_regs where necessary. */
#define compat_sys_execve _compat_sys_execve

View File

@ -317,7 +317,7 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs)
return 0;
badframe:
force_sig(SIGSEGV, current);
signal_fault("bad sigreturn frame", regs, frame, 0);
return 0;
}
@ -431,6 +431,6 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
return 0;
give_sigsegv:
force_sigsegv(sig, current);
signal_fault("bad setup frame", regs, frame, sig);
return -EFAULT;
}

View File

@ -0,0 +1,55 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*
* Atomically access user memory, but use MMU to avoid propagating
* kernel exceptions.
*/
#include <linux/linkage.h>
#include <asm/errno.h>
#include <asm/futex.h>
#include <asm/page.h>
#include <asm/processor.h>
/*
* Provide a set of atomic memory operations supporting <asm/futex.h>.
*
* r0: user address to manipulate
* r1: new value to write, or for cmpxchg, old value to compare against
* r2: (cmpxchg only) new value to write
*
* Return __get_user struct, r0 with value, r1 with error.
*/
#define FUTEX_OP(name, ...) \
STD_ENTRY(futex_##name) \
__VA_ARGS__; \
{ \
move r1, zero; \
jrp lr \
}; \
STD_ENDPROC(futex_##name); \
.pushsection __ex_table,"a"; \
.quad 1b, get_user_fault; \
.popsection
.pushsection .fixup,"ax"
get_user_fault:
{ movei r1, -EFAULT; jrp lr }
ENDPROC(get_user_fault)
.popsection
FUTEX_OP(cmpxchg, mtspr CMPEXCH_VALUE, r1; 1: cmpexch4 r0, r0, r2)
FUTEX_OP(set, 1: exch4 r0, r0, r1)
FUTEX_OP(add, 1: fetchadd4 r0, r0, r1)
FUTEX_OP(or, 1: fetchor4 r0, r0, r1)
FUTEX_OP(andn, nor r1, r1, zero; 1: fetchand4 r0, r0, r1)

View File

@ -268,12 +268,10 @@ void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num)
found_processes = 0;
list_for_each_entry(p, &rect->task_head, thread.hardwall_list) {
BUG_ON(p->thread.hardwall != rect);
if (p->sighand) {
if (!(p->flags & PF_EXITING)) {
found_processes = 1;
pr_notice("hardwall: killing %d\n", p->pid);
spin_lock(&p->sighand->siglock);
__group_send_sig_info(info.si_signo, &info, p);
spin_unlock(&p->sighand->siglock);
do_send_sig_info(info.si_signo, &info, p, false);
}
}
if (!found_processes)

269
arch/tile/kernel/head_64.S Normal file
View File

@ -0,0 +1,269 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*
* TILE startup code.
*/
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/thread_info.h>
#include <asm/processor.h>
#include <asm/asm-offsets.h>
#include <hv/hypervisor.h>
#include <arch/chip.h>
#include <arch/spr_def.h>
/*
* This module contains the entry code for kernel images. It performs the
* minimal setup needed to call the generic C routines.
*/
__HEAD
ENTRY(_start)
/* Notify the hypervisor of what version of the API we want */
{
movei r1, TILE_CHIP
movei r2, TILE_CHIP_REV
}
{
moveli r0, _HV_VERSION
jal hv_init
}
/* Get a reasonable default ASID in r0 */
{
move r0, zero
jal hv_inquire_asid
}
/*
* Install the default page table. The relocation required to
* statically define the table is a bit too complex, so we have
* to plug in the pointer from the L0 to the L1 table by hand.
* We only do this on the first cpu to boot, though, since the
* other CPUs should see a properly-constructed page table.
*/
{
v4int_l r2, zero, r0 /* ASID for hv_install_context */
moveli r4, hw1_last(swapper_pgprot - PAGE_OFFSET)
}
{
shl16insli r4, r4, hw0(swapper_pgprot - PAGE_OFFSET)
}
{
ld r1, r4 /* access_pte for hv_install_context */
}
{
moveli r0, hw1_last(.Lsv_data_pmd - PAGE_OFFSET)
moveli r6, hw1_last(temp_data_pmd - PAGE_OFFSET)
}
{
/* After initializing swapper_pgprot, HV_PTE_GLOBAL is set. */
bfextu r7, r1, HV_PTE_INDEX_GLOBAL, HV_PTE_INDEX_GLOBAL
inv r4
}
bnez r7, .Lno_write
{
shl16insli r0, r0, hw0(.Lsv_data_pmd - PAGE_OFFSET)
shl16insli r6, r6, hw0(temp_data_pmd - PAGE_OFFSET)
}
{
/* Cut off the low bits of the PT address. */
shrui r6, r6, HV_LOG2_PAGE_TABLE_ALIGN
/* Start with our access pte. */
move r5, r1
}
{
/* Stuff the address into the page table pointer slot of the PTE. */
bfins r5, r6, HV_PTE_INDEX_PTFN, \
HV_PTE_INDEX_PTFN + HV_PTE_PTFN_BITS - 1
}
{
/* Store the L0 data PTE. */
st r0, r5
addli r6, r6, (temp_code_pmd - temp_data_pmd) >> \
HV_LOG2_PAGE_TABLE_ALIGN
}
{
addli r0, r0, .Lsv_code_pmd - .Lsv_data_pmd
bfins r5, r6, HV_PTE_INDEX_PTFN, \
HV_PTE_INDEX_PTFN + HV_PTE_PTFN_BITS - 1
}
/* Store the L0 code PTE. */
st r0, r5
.Lno_write:
moveli lr, hw2_last(1f)
{
shl16insli lr, lr, hw1(1f)
moveli r0, hw1_last(swapper_pg_dir - PAGE_OFFSET)
}
{
shl16insli lr, lr, hw0(1f)
shl16insli r0, r0, hw0(swapper_pg_dir - PAGE_OFFSET)
}
{
move r3, zero
j hv_install_context
}
1:
/* Install the interrupt base. */
moveli r0, hw2_last(MEM_SV_START)
shl16insli r0, r0, hw1(MEM_SV_START)
shl16insli r0, r0, hw0(MEM_SV_START)
mtspr SPR_INTERRUPT_VECTOR_BASE_K, r0
/*
* Get our processor number and save it away in SAVE_K_0.
* Extract stuff from the topology structure: r4 = y, r6 = x,
* r5 = width. FIXME: consider whether we want to just make these
* 64-bit values (and if so fix smp_topology write below, too).
*/
jal hv_inquire_topology
{
v4int_l r5, zero, r1 /* r5 = width */
shrui r4, r0, 32 /* r4 = y */
}
{
v4int_l r6, zero, r0 /* r6 = x */
mul_lu_lu r4, r4, r5
}
{
add r4, r4, r6 /* r4 == cpu == y*width + x */
}
#ifdef CONFIG_SMP
/*
* Load up our per-cpu offset. When the first (master) tile
* boots, this value is still zero, so we will load boot_pc
* with start_kernel, and boot_sp with init_stack + THREAD_SIZE.
* The master tile initializes the per-cpu offset array, so that
* when subsequent (secondary) tiles boot, they will instead load
* from their per-cpu versions of boot_sp and boot_pc.
*/
moveli r5, hw2_last(__per_cpu_offset)
shl16insli r5, r5, hw1(__per_cpu_offset)
shl16insli r5, r5, hw0(__per_cpu_offset)
shl3add r5, r4, r5
ld r5, r5
bnez r5, 1f
/*
* Save the width and height to the smp_topology variable
* for later use.
*/
moveli r0, hw2_last(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
shl16insli r0, r0, hw1(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
shl16insli r0, r0, hw0(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
st r0, r1
1:
#else
move r5, zero
#endif
/* Load and go with the correct pc and sp. */
{
moveli r1, hw2_last(boot_sp)
moveli r0, hw2_last(boot_pc)
}
{
shl16insli r1, r1, hw1(boot_sp)
shl16insli r0, r0, hw1(boot_pc)
}
{
shl16insli r1, r1, hw0(boot_sp)
shl16insli r0, r0, hw0(boot_pc)
}
{
add r1, r1, r5
add r0, r0, r5
}
ld r0, r0
ld sp, r1
or r4, sp, r4
mtspr SPR_SYSTEM_SAVE_K_0, r4 /* save ksp0 + cpu */
addi sp, sp, -STACK_TOP_DELTA
{
move lr, zero /* stop backtraces in the called function */
jr r0
}
ENDPROC(_start)
__PAGE_ALIGNED_BSS
.align PAGE_SIZE
ENTRY(empty_zero_page)
.fill PAGE_SIZE,1,0
END(empty_zero_page)
.macro PTE cpa, bits1
.quad HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED |\
HV_PTE_GLOBAL | (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE) |\
(\bits1) | (HV_CPA_TO_PFN(\cpa) << HV_PTE_INDEX_PFN)
.endm
__PAGE_ALIGNED_DATA
.align PAGE_SIZE
ENTRY(swapper_pg_dir)
.org swapper_pg_dir + HV_L0_INDEX(PAGE_OFFSET) * HV_PTE_SIZE
.Lsv_data_pmd:
.quad 0 /* PTE temp_data_pmd - PAGE_OFFSET, 0 */
.org swapper_pg_dir + HV_L0_INDEX(MEM_SV_START) * HV_PTE_SIZE
.Lsv_code_pmd:
.quad 0 /* PTE temp_code_pmd - PAGE_OFFSET, 0 */
.org swapper_pg_dir + HV_L0_SIZE
END(swapper_pg_dir)
.align HV_PAGE_TABLE_ALIGN
ENTRY(temp_data_pmd)
/*
* We fill the PAGE_OFFSET pmd with huge pages with
* VA = PA + PAGE_OFFSET. We remap things with more precise access
* permissions later.
*/
.set addr, 0
.rept HV_L1_ENTRIES
PTE addr, HV_PTE_READABLE | HV_PTE_WRITABLE
.set addr, addr + HV_PAGE_SIZE_LARGE
.endr
.org temp_data_pmd + HV_L1_SIZE
END(temp_data_pmd)
.align HV_PAGE_TABLE_ALIGN
ENTRY(temp_code_pmd)
/*
* We fill the MEM_SV_START pmd with huge pages with
* VA = PA + PAGE_OFFSET. We remap things with more precise access
* permissions later.
*/
.set addr, 0
.rept HV_L1_ENTRIES
PTE addr, HV_PTE_READABLE | HV_PTE_EXECUTABLE
.set addr, addr + HV_PAGE_SIZE_LARGE
.endr
.org temp_code_pmd + HV_L1_SIZE
END(temp_code_pmd)
/*
* Isolate swapper_pgprot to its own cache line, since each cpu
* starting up will read it using VA-is-PA and local homing.
* This would otherwise likely conflict with other data on the cache
* line, once we have set its permanent home in the page tables.
*/
__INITDATA
.align CHIP_L2_LINE_SIZE()
ENTRY(swapper_pgprot)
.quad HV_PTE_PRESENT | (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE)
.align CHIP_L2_LINE_SIZE()
END(swapper_pgprot)

View File

@ -851,14 +851,27 @@ STD_ENTRY(interrupt_return)
/* Check to see if there is any work to do before returning to user. */
{
addi r29, r32, THREAD_INFO_FLAGS_OFFSET
moveli r28, lo16(_TIF_ALLWORK_MASK)
moveli r1, lo16(_TIF_ALLWORK_MASK)
}
{
lw r29, r29
auli r28, r28, ha16(_TIF_ALLWORK_MASK)
auli r1, r1, ha16(_TIF_ALLWORK_MASK)
}
and r28, r29, r28
bnz r28, .Lwork_pending
and r1, r29, r1
bzt r1, .Lrestore_all
/*
* Make sure we have all the registers saved for signal
* handling or single-step. Call out to C code to figure out
* exactly what we need to do for each flag bit, then if
* necessary, reload the flags and recheck.
*/
push_extra_callee_saves r0
{
PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
jal do_work_pending
}
bnz r0, .Lresume_userspace
/*
* In the NMI case we
@ -1099,99 +1112,6 @@ STD_ENTRY(interrupt_return)
pop_reg r50
pop_reg r51, sp, PTREGS_OFFSET_REG(29) - PTREGS_OFFSET_REG(51)
j .Lcontinue_restore_regs
.Lwork_pending:
/* Mask the reschedule flag */
andi r28, r29, _TIF_NEED_RESCHED
{
/*
* If the NEED_RESCHED flag is called, we call schedule(), which
* may drop this context right here and go do something else.
* On return, jump back to .Lresume_userspace and recheck.
*/
bz r28, .Lasync_tlb
/* Mask the async-tlb flag */
andi r28, r29, _TIF_ASYNC_TLB
}
jal schedule
FEEDBACK_REENTER(interrupt_return)
/* Reload the flags and check again */
j .Lresume_userspace
.Lasync_tlb:
{
bz r28, .Lneed_sigpending
/* Mask the sigpending flag */
andi r28, r29, _TIF_SIGPENDING
}
PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
jal do_async_page_fault
FEEDBACK_REENTER(interrupt_return)
/*
* Go restart the "resume userspace" process. We may have
* fired a signal, and we need to disable interrupts again.
*/
j .Lresume_userspace
.Lneed_sigpending:
/*
* At this point we are either doing signal handling or single-step,
* so either way make sure we have all the registers saved.
*/
push_extra_callee_saves r0
{
/* If no signal pending, skip to singlestep check */
bz r28, .Lneed_singlestep
/* Mask the singlestep flag */
andi r28, r29, _TIF_SINGLESTEP
}
jal do_signal
FEEDBACK_REENTER(interrupt_return)
/* Reload the flags and check again */
j .Lresume_userspace
.Lneed_singlestep:
{
/* Get a pointer to the EX1 field */
PTREGS_PTR(r29, PTREGS_OFFSET_EX1)
/* If we get here, our bit must be set. */
bz r28, .Lwork_confusion
}
/* If we are in priv mode, don't single step */
lw r28, r29
andi r28, r28, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */
bnz r28, .Lrestore_all
/* Allow interrupts within the single step code */
TRACE_IRQS_ON /* Note: clobbers registers r0-r29 */
IRQ_ENABLE(r20, r21)
/* try to single-step the current instruction */
PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
jal single_step_once
FEEDBACK_REENTER(interrupt_return)
/* Re-disable interrupts. TRACE_IRQS_OFF in .Lrestore_all. */
IRQ_DISABLE(r20,r21)
j .Lrestore_all
.Lwork_confusion:
move r0, r28
panic "thread_info allwork flags unhandled on userspace resume: %#x"
STD_ENDPROC(interrupt_return)
/*
@ -1550,7 +1470,10 @@ STD_ENTRY(_sys_clone)
* We place it in the __HEAD section to ensure it is relatively
* near to the intvec_SWINT_1 code (reachable by a conditional branch).
*
* Must match register usage in do_page_fault().
* Our use of ATOMIC_LOCK_REG here must match do_page_fault_ics().
*
* As we do in lib/atomic_asm_32.S, we bypass a store if the value we
* would store is the same as the value we just loaded.
*/
__HEAD
.align 64
@ -1611,17 +1534,7 @@ ENTRY(sys_cmpxchg)
{
shri r20, r25, 32 - ATOMIC_HASH_L1_SHIFT
slt_u r23, r0, r23
/*
* Ensure that the TLB is loaded before we take out the lock.
* On TILEPro, this will start fetching the value all the way
* into our L1 as well (and if it gets modified before we
* grab the lock, it will be invalidated from our cache
* before we reload it). On tile64, we'll start fetching it
* into our L1 if we're the home, and if we're not, we'll
* still at least start fetching it into the home's L2.
*/
lw r26, r0
lw r26, r0 /* see comment in the "#else" for the "lw r26". */
}
{
s2a r21, r20, r21
@ -1637,18 +1550,9 @@ ENTRY(sys_cmpxchg)
bbs r23, .Lcmpxchg64
andi r23, r0, 7 /* Precompute alignment for cmpxchg64. */
}
{
/*
* We very carefully align the code that actually runs with
* the lock held (nine bundles) so that we know it is all in
* the icache when we start. This instruction (the jump) is
* at the start of the first cache line, address zero mod 64;
* we jump to somewhere in the second cache line to issue the
* tns, then jump back to finish up.
*/
s2a ATOMIC_LOCK_REG_NAME, r25, r21
j .Lcmpxchg32_tns
j .Lcmpxchg32_tns /* see comment in the #else for the jump. */
}
#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
@ -1713,24 +1617,25 @@ ENTRY(sys_cmpxchg)
{
/*
* We very carefully align the code that actually runs with
* the lock held (nine bundles) so that we know it is all in
* the lock held (twelve bundles) so that we know it is all in
* the icache when we start. This instruction (the jump) is
* at the start of the first cache line, address zero mod 64;
* we jump to somewhere in the second cache line to issue the
* tns, then jump back to finish up.
* we jump to the very end of the second cache line to get that
* line loaded in the icache, then fall through to issue the tns
* in the third cache line, at which point it's all cached.
* Note that is for performance, not correctness.
*/
j .Lcmpxchg32_tns
}
#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
ENTRY(__sys_cmpxchg_grab_lock)
/* Symbol for do_page_fault_ics() to use to compare against the PC. */
.global __sys_cmpxchg_grab_lock
__sys_cmpxchg_grab_lock:
/*
* Perform the actual cmpxchg or atomic_update.
* Note that the system <arch/atomic.h> header relies on
* atomic_update() to always perform an "mf", so don't make
* it optional or conditional without modifying that code.
*/
.Ldo_cmpxchg32:
{
@ -1748,10 +1653,13 @@ ENTRY(sys_cmpxchg)
}
{
mvnz r24, r23, r25 /* Use atomic_update value if appropriate. */
bbns r22, .Lcmpxchg32_mismatch
bbns r22, .Lcmpxchg32_nostore
}
seq r22, r24, r21 /* Are we storing the value we loaded? */
bbs r22, .Lcmpxchg32_nostore
sw r0, r24
/* The following instruction is the start of the second cache line. */
/* Do slow mtspr here so the following "mf" waits less. */
{
move sp, r27
@ -1759,7 +1667,6 @@ ENTRY(sys_cmpxchg)
}
mf
/* The following instruction is the start of the second cache line. */
{
move r0, r21
sw ATOMIC_LOCK_REG_NAME, zero
@ -1767,7 +1674,7 @@ ENTRY(sys_cmpxchg)
iret
/* Duplicated code here in the case where we don't overlap "mf" */
.Lcmpxchg32_mismatch:
.Lcmpxchg32_nostore:
{
move r0, r21
sw ATOMIC_LOCK_REG_NAME, zero
@ -1783,8 +1690,6 @@ ENTRY(sys_cmpxchg)
* and for 64-bit cmpxchg. We provide it as a macro and put
* it into both versions. We can't share the code literally
* since it depends on having the right branch-back address.
* Note that the first few instructions should share the cache
* line with the second half of the actual locked code.
*/
.macro cmpxchg_lock, bitwidth
@ -1810,7 +1715,7 @@ ENTRY(sys_cmpxchg)
}
/*
* The preceding instruction is the last thing that must be
* on the second cache line.
* hot in the icache before we do the "tns" above.
*/
#ifdef CONFIG_SMP
@ -1841,6 +1746,12 @@ ENTRY(sys_cmpxchg)
.endm
.Lcmpxchg32_tns:
/*
* This is the last instruction on the second cache line.
* The nop here loads the second line, then we fall through
* to the tns to load the third line before we take the lock.
*/
nop
cmpxchg_lock 32
/*

1231
arch/tile/kernel/intvec_64.S Normal file

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <asm/opcode-tile.h>
#include <asm/pgtable.h>
#include <asm/homecache.h>
#ifdef __tilegx__
# define Elf_Rela Elf64_Rela
@ -86,8 +87,13 @@ error:
void module_free(struct module *mod, void *module_region)
{
vfree(module_region);
/* Globally flush the L1 icache. */
flush_remote(0, HV_FLUSH_EVICT_L1I, cpu_online_mask,
0, 0, 0, NULL, NULL, 0);
/*
* FIXME: If module_region == mod->init_region, trim exception
* FIXME: If module_region == mod->module_init, trim exception
* table entries.
*/
}

View File

@ -244,7 +244,7 @@ EXPORT_SYMBOL(dma_sync_single_range_for_device);
* dma_alloc_noncoherent() returns non-cacheable memory, so there's no
* need to do any flushing here.
*/
void dma_cache_sync(void *vaddr, size_t size,
void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)
{
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2010 Tilera Corporation. All Rights Reserved.
* Copyright 2011 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
@ -59,6 +59,7 @@ int __write_once tile_plx_gen1;
static struct pci_controller controllers[TILE_NUM_PCIE];
static int num_controllers;
static int pci_scan_flags[TILE_NUM_PCIE];
static struct pci_ops tile_cfg_ops;
@ -79,7 +80,7 @@ EXPORT_SYMBOL(pcibios_align_resource);
* controller_id is the controller number, config type is 0 or 1 for
* config0 or config1 operations.
*/
static int __init tile_pcie_open(int controller_id, int config_type)
static int __devinit tile_pcie_open(int controller_id, int config_type)
{
char filename[32];
int fd;
@ -95,7 +96,7 @@ static int __init tile_pcie_open(int controller_id, int config_type)
/*
* Get the IRQ numbers from the HV and set up the handlers for them.
*/
static int __init tile_init_irqs(int controller_id,
static int __devinit tile_init_irqs(int controller_id,
struct pci_controller *controller)
{
char filename[32];
@ -139,71 +140,74 @@ static int __init tile_init_irqs(int controller_id,
*
* Returns the number of controllers discovered.
*/
int __init tile_pci_init(void)
int __devinit tile_pci_init(void)
{
int i;
pr_info("PCI: Searching for controllers...\n");
/* Re-init number of PCIe controllers to support hot-plug feature. */
num_controllers = 0;
/* Do any configuration we need before using the PCIe */
for (i = 0; i < TILE_NUM_PCIE; i++) {
int hv_cfg_fd0 = -1;
int hv_cfg_fd1 = -1;
int hv_mem_fd = -1;
char name[32];
struct pci_controller *controller;
/*
* Open the fd to the HV. If it fails then this
* device doesn't exist.
* To see whether we need a real config op based on
* the results of pcibios_init(), to support PCIe hot-plug.
*/
hv_cfg_fd0 = tile_pcie_open(i, 0);
if (hv_cfg_fd0 < 0)
if (pci_scan_flags[i] == 0) {
int hv_cfg_fd0 = -1;
int hv_cfg_fd1 = -1;
int hv_mem_fd = -1;
char name[32];
struct pci_controller *controller;
/*
* Open the fd to the HV. If it fails then this
* device doesn't exist.
*/
hv_cfg_fd0 = tile_pcie_open(i, 0);
if (hv_cfg_fd0 < 0)
continue;
hv_cfg_fd1 = tile_pcie_open(i, 1);
if (hv_cfg_fd1 < 0) {
pr_err("PCI: Couldn't open config fd to HV "
"for controller %d\n", i);
goto err_cont;
}
sprintf(name, "pcie/%d/mem", i);
hv_mem_fd = hv_dev_open((HV_VirtAddr)name, 0);
if (hv_mem_fd < 0) {
pr_err("PCI: Could not open mem fd to HV!\n");
goto err_cont;
}
pr_info("PCI: Found PCI controller #%d\n", i);
controller = &controllers[i];
controller->index = i;
controller->hv_cfg_fd[0] = hv_cfg_fd0;
controller->hv_cfg_fd[1] = hv_cfg_fd1;
controller->hv_mem_fd = hv_mem_fd;
controller->first_busno = 0;
controller->last_busno = 0xff;
controller->ops = &tile_cfg_ops;
num_controllers++;
continue;
hv_cfg_fd1 = tile_pcie_open(i, 1);
if (hv_cfg_fd1 < 0) {
pr_err("PCI: Couldn't open config fd to HV "
"for controller %d\n", i);
goto err_cont;
}
sprintf(name, "pcie/%d/mem", i);
hv_mem_fd = hv_dev_open((HV_VirtAddr)name, 0);
if (hv_mem_fd < 0) {
pr_err("PCI: Could not open mem fd to HV!\n");
goto err_cont;
}
pr_info("PCI: Found PCI controller #%d\n", i);
controller = &controllers[num_controllers];
if (tile_init_irqs(i, controller)) {
pr_err("PCI: Could not initialize "
"IRQs, aborting.\n");
goto err_cont;
}
controller->index = num_controllers;
controller->hv_cfg_fd[0] = hv_cfg_fd0;
controller->hv_cfg_fd[1] = hv_cfg_fd1;
controller->hv_mem_fd = hv_mem_fd;
controller->first_busno = 0;
controller->last_busno = 0xff;
controller->ops = &tile_cfg_ops;
num_controllers++;
continue;
err_cont:
if (hv_cfg_fd0 >= 0)
hv_dev_close(hv_cfg_fd0);
if (hv_cfg_fd1 >= 0)
hv_dev_close(hv_cfg_fd1);
if (hv_mem_fd >= 0)
hv_dev_close(hv_mem_fd);
continue;
if (hv_cfg_fd0 >= 0)
hv_dev_close(hv_cfg_fd0);
if (hv_cfg_fd1 >= 0)
hv_dev_close(hv_cfg_fd1);
if (hv_mem_fd >= 0)
hv_dev_close(hv_mem_fd);
continue;
}
}
/*
@ -232,7 +236,7 @@ static int tile_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
}
static void __init fixup_read_and_payload_sizes(void)
static void __devinit fixup_read_and_payload_sizes(void)
{
struct pci_dev *dev = NULL;
int smallest_max_payload = 0x1; /* Tile maxes out at 256 bytes. */
@ -282,7 +286,7 @@ static void __init fixup_read_and_payload_sizes(void)
* The controllers have been set up by the time we get here, by a call to
* tile_pci_init.
*/
static int __init pcibios_init(void)
int __devinit pcibios_init(void)
{
int i;
@ -296,25 +300,36 @@ static int __init pcibios_init(void)
mdelay(250);
/* Scan all of the recorded PCI controllers. */
for (i = 0; i < num_controllers; i++) {
struct pci_controller *controller = &controllers[i];
struct pci_bus *bus;
pr_info("PCI: initializing controller #%d\n", i);
for (i = 0; i < TILE_NUM_PCIE; i++) {
/*
* This comes from the generic Linux PCI driver.
*
* It reads the PCI tree for this bus into the Linux
* data structures.
*
* This is inlined in linux/pci.h and calls into
* pci_scan_bus_parented() in probe.c.
* Do real pcibios init ops if the controller is initialized
* by tile_pci_init() successfully and not initialized by
* pcibios_init() yet to support PCIe hot-plug.
*/
bus = pci_scan_bus(0, controller->ops, controller);
controller->root_bus = bus;
controller->last_busno = bus->subordinate;
if (pci_scan_flags[i] == 0 && controllers[i].ops != NULL) {
struct pci_controller *controller = &controllers[i];
struct pci_bus *bus;
if (tile_init_irqs(i, controller)) {
pr_err("PCI: Could not initialize IRQs\n");
continue;
}
pr_info("PCI: initializing controller #%d\n", i);
/*
* This comes from the generic Linux PCI driver.
*
* It reads the PCI tree for this bus into the Linux
* data structures.
*
* This is inlined in linux/pci.h and calls into
* pci_scan_bus_parented() in probe.c.
*/
bus = pci_scan_bus(0, controller->ops, controller);
controller->root_bus = bus;
controller->last_busno = bus->subordinate;
}
}
/* Do machine dependent PCI interrupt routing */
@ -326,34 +341,45 @@ static int __init pcibios_init(void)
* It allocates all of the resources (I/O memory, etc)
* associated with the devices read in above.
*/
pci_assign_unassigned_resources();
/* Configure the max_read_size and max_payload_size values. */
fixup_read_and_payload_sizes();
/* Record the I/O resources in the PCI controller structure. */
for (i = 0; i < num_controllers; i++) {
struct pci_bus *root_bus = controllers[i].root_bus;
struct pci_bus *next_bus;
struct pci_dev *dev;
for (i = 0; i < TILE_NUM_PCIE; i++) {
/*
* Do real pcibios init ops if the controller is initialized
* by tile_pci_init() successfully and not initialized by
* pcibios_init() yet to support PCIe hot-plug.
*/
if (pci_scan_flags[i] == 0 && controllers[i].ops != NULL) {
struct pci_bus *root_bus = controllers[i].root_bus;
struct pci_bus *next_bus;
struct pci_dev *dev;
list_for_each_entry(dev, &root_bus->devices, bus_list) {
/* Find the PCI host controller, ie. the 1st bridge. */
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
(PCI_SLOT(dev->devfn) == 0)) {
next_bus = dev->subordinate;
controllers[i].mem_resources[0] =
*next_bus->resource[0];
controllers[i].mem_resources[1] =
*next_bus->resource[1];
controllers[i].mem_resources[2] =
*next_bus->resource[2];
list_for_each_entry(dev, &root_bus->devices, bus_list) {
/*
* Find the PCI host controller, ie. the 1st
* bridge.
*/
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
(PCI_SLOT(dev->devfn) == 0)) {
next_bus = dev->subordinate;
controllers[i].mem_resources[0] =
*next_bus->resource[0];
controllers[i].mem_resources[1] =
*next_bus->resource[1];
controllers[i].mem_resources[2] =
*next_bus->resource[2];
break;
/* Setup flags. */
pci_scan_flags[i] = 1;
break;
}
}
}
}
return 0;
@ -381,7 +407,7 @@ char __devinit *pcibios_setup(char *str)
/*
* This is called from the generic Linux layer.
*/
void __init pcibios_update_irq(struct pci_dev *dev, int irq)
void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
{
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
}

View File

@ -25,10 +25,13 @@
#include <linux/hardirq.h>
#include <linux/syscalls.h>
#include <linux/kernel.h>
#include <linux/tracehook.h>
#include <linux/signal.h>
#include <asm/system.h>
#include <asm/stack.h>
#include <asm/homecache.h>
#include <asm/syscalls.h>
#include <asm/traps.h>
#ifdef CONFIG_HARDWALL
#include <asm/hardwall.h>
#endif
@ -546,6 +549,51 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
return __switch_to(prev, next, next_current_ksp0(next));
}
/*
* This routine is called on return from interrupt if any of the
* TIF_WORK_MASK flags are set in thread_info->flags. It is
* entered with interrupts disabled so we don't miss an event
* that modified the thread_info flags. If any flag is set, we
* handle it and return, and the calling assembly code will
* re-disable interrupts, reload the thread flags, and call back
* if more flags need to be handled.
*
* We return whether we need to check the thread_info flags again
* or not. Note that we don't clear TIF_SINGLESTEP here, so it's
* important that it be tested last, and then claim that we don't
* need to recheck the flags.
*/
int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
{
if (thread_info_flags & _TIF_NEED_RESCHED) {
schedule();
return 1;
}
#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
if (thread_info_flags & _TIF_ASYNC_TLB) {
do_async_page_fault(regs);
return 1;
}
#endif
if (thread_info_flags & _TIF_SIGPENDING) {
do_signal(regs);
return 1;
}
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
clear_thread_flag(TIF_NOTIFY_RESUME);
tracehook_notify_resume(regs);
if (current->replacement_session_keyring)
key_replace_session_keyring();
return 1;
}
if (thread_info_flags & _TIF_SINGLESTEP) {
if ((regs->ex1 & SPR_EX_CONTEXT_1_1__PL_MASK) == 0)
single_step_once(regs);
return 0;
}
panic("work_pending: bad flags %#x\n", thread_info_flags);
}
/* Note there is an implicit fifth argument if (clone_flags & CLONE_SETTLS). */
SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
void __user *, parent_tidptr, void __user *, child_tidptr,
@ -582,8 +630,8 @@ out:
#ifdef CONFIG_COMPAT
long compat_sys_execve(const char __user *path,
const compat_uptr_t __user *argv,
const compat_uptr_t __user *envp,
compat_uptr_t __user *argv,
compat_uptr_t __user *envp,
struct pt_regs *regs)
{
long error;

145
arch/tile/kernel/regs_64.S Normal file
View File

@ -0,0 +1,145 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#include <linux/linkage.h>
#include <asm/system.h>
#include <asm/ptrace.h>
#include <asm/asm-offsets.h>
#include <arch/spr_def.h>
#include <asm/processor.h>
/*
* See <asm/system.h>; called with prev and next task_struct pointers.
* "prev" is returned in r0 for _switch_to and also for ret_from_fork.
*
* We want to save pc/sp in "prev", and get the new pc/sp from "next".
* We also need to save all the callee-saved registers on the stack.
*
* Intel enables/disables access to the hardware cycle counter in
* seccomp (secure computing) environments if necessary, based on
* has_secure_computing(). We might want to do this at some point,
* though it would require virtualizing the other SPRs under WORLD_ACCESS.
*
* Since we're saving to the stack, we omit sp from this list.
* And for parallels with other architectures, we save lr separately,
* in the thread_struct itself (as the "pc" field).
*
* This code also needs to be aligned with process.c copy_thread()
*/
#if CALLEE_SAVED_REGS_COUNT != 24
# error Mismatch between <asm/system.h> and kernel/entry.S
#endif
#define FRAME_SIZE ((2 + CALLEE_SAVED_REGS_COUNT) * 8)
#define SAVE_REG(r) { st r12, r; addi r12, r12, 8 }
#define LOAD_REG(r) { ld r, r12; addi r12, r12, 8 }
#define FOR_EACH_CALLEE_SAVED_REG(f) \
f(r30); f(r31); \
f(r32); f(r33); f(r34); f(r35); f(r36); f(r37); f(r38); f(r39); \
f(r40); f(r41); f(r42); f(r43); f(r44); f(r45); f(r46); f(r47); \
f(r48); f(r49); f(r50); f(r51); f(r52);
STD_ENTRY_SECTION(__switch_to, .sched.text)
{
move r10, sp
st sp, lr
}
{
addli r11, sp, -FRAME_SIZE + 8
addli sp, sp, -FRAME_SIZE
}
{
st r11, r10
addli r4, r1, TASK_STRUCT_THREAD_KSP_OFFSET
}
{
ld r13, r4 /* Load new sp to a temp register early. */
addi r12, sp, 16
}
FOR_EACH_CALLEE_SAVED_REG(SAVE_REG)
addli r3, r0, TASK_STRUCT_THREAD_KSP_OFFSET
{
st r3, sp
addli r3, r0, TASK_STRUCT_THREAD_PC_OFFSET
}
{
st r3, lr
addli r4, r1, TASK_STRUCT_THREAD_PC_OFFSET
}
{
ld lr, r4
addi r12, r13, 16
}
{
/* Update sp and ksp0 simultaneously to avoid backtracer warnings. */
move sp, r13
mtspr SPR_SYSTEM_SAVE_K_0, r2
}
FOR_EACH_CALLEE_SAVED_REG(LOAD_REG)
.L__switch_to_pc:
{
addli sp, sp, FRAME_SIZE
jrp lr /* r0 is still valid here, so return it */
}
STD_ENDPROC(__switch_to)
/* Return a suitable address for the backtracer for suspended threads */
STD_ENTRY_SECTION(get_switch_to_pc, .sched.text)
lnk r0
{
addli r0, r0, .L__switch_to_pc - .
jrp lr
}
STD_ENDPROC(get_switch_to_pc)
STD_ENTRY(get_pt_regs)
.irp reg, r0, r1, r2, r3, r4, r5, r6, r7, \
r8, r9, r10, r11, r12, r13, r14, r15, \
r16, r17, r18, r19, r20, r21, r22, r23, \
r24, r25, r26, r27, r28, r29, r30, r31, \
r32, r33, r34, r35, r36, r37, r38, r39, \
r40, r41, r42, r43, r44, r45, r46, r47, \
r48, r49, r50, r51, r52, tp, sp
{
st r0, \reg
addi r0, r0, 8
}
.endr
{
st r0, lr
addi r0, r0, PTREGS_OFFSET_PC - PTREGS_OFFSET_LR
}
lnk r1
{
st r0, r1
addi r0, r0, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC
}
mfspr r1, INTERRUPT_CRITICAL_SECTION
shli r1, r1, SPR_EX_CONTEXT_1_1__ICS_SHIFT
ori r1, r1, KERNEL_PL
{
st r0, r1
addi r0, r0, PTREGS_OFFSET_FAULTNUM - PTREGS_OFFSET_EX1
}
{
st r0, zero /* clear faultnum */
addi r0, r0, PTREGS_OFFSET_ORIG_R0 - PTREGS_OFFSET_FAULTNUM
}
{
st r0, zero /* clear orig_r0 */
addli r0, r0, -PTREGS_OFFSET_ORIG_R0 /* restore r0 to base */
}
jrp lr
STD_ENDPROC(get_pt_regs)

View File

@ -912,6 +912,8 @@ void __cpuinit setup_cpu(int boot)
#endif
}
#ifdef CONFIG_BLK_DEV_INITRD
static int __initdata set_initramfs_file;
static char __initdata initramfs_file[128] = "initramfs.cpio.gz";
@ -969,6 +971,10 @@ void __init free_initrd_mem(unsigned long begin, unsigned long end)
free_bootmem(__pa(begin), end - begin);
}
#else
static inline void load_hv_initrd(void) {}
#endif /* CONFIG_BLK_DEV_INITRD */
static void __init validate_hv(void)
{
/*

View File

@ -39,7 +39,6 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss,
stack_t __user *, uoss, struct pt_regs *, regs)
{
@ -78,6 +77,13 @@ int restore_sigcontext(struct pt_regs *regs,
return err;
}
void signal_fault(const char *type, struct pt_regs *regs,
void __user *frame, int sig)
{
trace_unhandled_signal(type, regs, (unsigned long)frame, SIGSEGV);
force_sigsegv(sig, current);
}
/* The assembly shim for this function arranges to ignore the return value. */
SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
{
@ -105,7 +111,7 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
return 0;
badframe:
force_sig(SIGSEGV, current);
signal_fault("bad sigreturn frame", regs, frame, 0);
return 0;
}
@ -231,7 +237,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
return 0;
give_sigsegv:
force_sigsegv(sig, current);
signal_fault("bad setup frame", regs, frame, sig);
return -EFAULT;
}
@ -245,7 +251,6 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
{
int ret;
/* Are we from a system call? */
if (regs->faultnum == INT_SWINT_1) {
/* If so, check system call restarting.. */
@ -363,3 +368,118 @@ done:
/* Avoid double syscall restart if there are nested signals. */
regs->faultnum = INT_SWINT_1_SIGRETURN;
}
int show_unhandled_signals = 1;
static int __init crashinfo(char *str)
{
unsigned long val;
const char *word;
if (*str == '\0')
val = 2;
else if (*str != '=' || strict_strtoul(++str, 0, &val) != 0)
return 0;
show_unhandled_signals = val;
switch (show_unhandled_signals) {
case 0:
word = "No";
break;
case 1:
word = "One-line";
break;
default:
word = "Detailed";
break;
}
pr_info("%s crash reports will be generated on the console\n", word);
return 1;
}
__setup("crashinfo", crashinfo);
static void dump_mem(void __user *address)
{
void __user *addr;
enum { region_size = 256, bytes_per_line = 16 };
int i, j, k;
int found_readable_mem = 0;
pr_err("\n");
if (!access_ok(VERIFY_READ, address, 1)) {
pr_err("Not dumping at address 0x%lx (kernel address)\n",
(unsigned long)address);
return;
}
addr = (void __user *)
(((unsigned long)address & -bytes_per_line) - region_size/2);
if (addr > address)
addr = NULL;
for (i = 0; i < region_size;
addr += bytes_per_line, i += bytes_per_line) {
unsigned char buf[bytes_per_line];
char line[100];
if (copy_from_user(buf, addr, bytes_per_line))
continue;
if (!found_readable_mem) {
pr_err("Dumping memory around address 0x%lx:\n",
(unsigned long)address);
found_readable_mem = 1;
}
j = sprintf(line, REGFMT":", (unsigned long)addr);
for (k = 0; k < bytes_per_line; ++k)
j += sprintf(&line[j], " %02x", buf[k]);
pr_err("%s\n", line);
}
if (!found_readable_mem)
pr_err("No readable memory around address 0x%lx\n",
(unsigned long)address);
}
void trace_unhandled_signal(const char *type, struct pt_regs *regs,
unsigned long address, int sig)
{
struct task_struct *tsk = current;
if (show_unhandled_signals == 0)
return;
/* If the signal is handled, don't show it here. */
if (!is_global_init(tsk)) {
void __user *handler =
tsk->sighand->action[sig-1].sa.sa_handler;
if (handler != SIG_IGN && handler != SIG_DFL)
return;
}
/* Rate-limit the one-line output, not the detailed output. */
if (show_unhandled_signals <= 1 && !printk_ratelimit())
return;
printk("%s%s[%d]: %s at %lx pc "REGFMT" signal %d",
task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
tsk->comm, task_pid_nr(tsk), type, address, regs->pc, sig);
print_vma_addr(KERN_CONT " in ", regs->pc);
printk(KERN_CONT "\n");
if (show_unhandled_signals > 1) {
switch (sig) {
case SIGILL:
case SIGFPE:
case SIGSEGV:
case SIGBUS:
pr_err("User crash: signal %d,"
" trap %ld, address 0x%lx\n",
sig, regs->faultnum, address);
show_regs(regs);
dump_mem((void __user *)address);
break;
default:
pr_err("User crash: signal %d, trap %ld\n",
sig, regs->faultnum);
break;
}
}
}

View File

@ -186,6 +186,8 @@ static tile_bundle_bits rewrite_load_store_unaligned(
.si_code = SEGV_MAPERR,
.si_addr = addr
};
trace_unhandled_signal("segfault", regs,
(unsigned long)addr, SIGSEGV);
force_sig_info(info.si_signo, &info, current);
return (tile_bundle_bits) 0;
}
@ -196,6 +198,8 @@ static tile_bundle_bits rewrite_load_store_unaligned(
.si_code = BUS_ADRALN,
.si_addr = addr
};
trace_unhandled_signal("unaligned trap", regs,
(unsigned long)addr, SIGBUS);
force_sig_info(info.si_signo, &info, current);
return (tile_bundle_bits) 0;
}
@ -318,6 +322,14 @@ void single_step_once(struct pt_regs *regs)
" .popsection\n"
);
/*
* Enable interrupts here to allow touching userspace and the like.
* The callers expect this: do_trap() already has interrupts
* enabled, and do_work_pending() handles functions that enable
* interrupts internally.
*/
local_irq_enable();
if (state == NULL) {
/* allocate a page of writable, executable memory */
state = kmalloc(sizeof(struct single_step_state), GFP_KERNEL);

View File

@ -36,7 +36,7 @@
#define KBT_LOOP 3 /* Backtrace entered a loop */
/* Is address on the specified kernel stack? */
static int in_kernel_stack(struct KBacktraceIterator *kbt, VirtualAddress sp)
static int in_kernel_stack(struct KBacktraceIterator *kbt, unsigned long sp)
{
ulong kstack_base = (ulong) kbt->task->stack;
if (kstack_base == 0) /* corrupt task pointer; just follow stack... */
@ -45,7 +45,7 @@ static int in_kernel_stack(struct KBacktraceIterator *kbt, VirtualAddress sp)
}
/* Is address valid for reading? */
static int valid_address(struct KBacktraceIterator *kbt, VirtualAddress address)
static int valid_address(struct KBacktraceIterator *kbt, unsigned long address)
{
HV_PTE *l1_pgtable = kbt->pgtable;
HV_PTE *l2_pgtable;
@ -97,7 +97,7 @@ static int valid_address(struct KBacktraceIterator *kbt, VirtualAddress address)
}
/* Callback for backtracer; basically a glorified memcpy */
static bool read_memory_func(void *result, VirtualAddress address,
static bool read_memory_func(void *result, unsigned long address,
unsigned int size, void *vkbt)
{
int retval;
@ -124,7 +124,7 @@ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt)
{
const char *fault = NULL; /* happy compiler */
char fault_buf[64];
VirtualAddress sp = kbt->it.sp;
unsigned long sp = kbt->it.sp;
struct pt_regs *p;
if (!in_kernel_stack(kbt, sp))
@ -163,7 +163,7 @@ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt)
}
/* Is the pc pointing to a sigreturn trampoline? */
static int is_sigreturn(VirtualAddress pc)
static int is_sigreturn(unsigned long pc)
{
return (pc == VDSO_BASE);
}
@ -260,7 +260,7 @@ static void validate_stack(struct pt_regs *regs)
void KBacktraceIterator_init(struct KBacktraceIterator *kbt,
struct task_struct *t, struct pt_regs *regs)
{
VirtualAddress pc, lr, sp, r52;
unsigned long pc, lr, sp, r52;
int is_current;
/*
@ -331,7 +331,7 @@ EXPORT_SYMBOL(KBacktraceIterator_end);
void KBacktraceIterator_next(struct KBacktraceIterator *kbt)
{
VirtualAddress old_pc = kbt->it.pc, old_sp = kbt->it.sp;
unsigned long old_pc = kbt->it.pc, old_sp = kbt->it.sp;
kbt->new_context = 0;
if (!backtrace_next(&kbt->it) && !KBacktraceIterator_restart(kbt)) {
kbt->end = KBT_DONE;

View File

@ -56,13 +56,6 @@ ssize_t sys32_readahead(int fd, u32 offset_lo, u32 offset_hi, u32 count)
return sys_readahead(fd, ((loff_t)offset_hi << 32) | offset_lo, count);
}
long sys32_fadvise64(int fd, u32 offset_lo, u32 offset_hi,
u32 len, int advice)
{
return sys_fadvise64_64(fd, ((loff_t)offset_hi << 32) | offset_lo,
len, advice);
}
int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi,
u32 len_lo, u32 len_hi, int advice)
{
@ -103,10 +96,8 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
#ifndef __tilegx__
/* See comments at the top of the file. */
#define sys_fadvise64 sys32_fadvise64
#define sys_fadvise64_64 sys32_fadvise64_64
#define sys_readahead sys32_readahead
#define sys_sync_file_range sys_sync_file_range2
#endif
/* Call the trampolines to manage pt_regs where necessary. */

View File

@ -2413,12 +2413,13 @@ const struct tile_operand tile_operands[43] =
/* Given a set of bundle bits and the lookup FSM for a specific pipe,
* returns which instruction the bundle contains in that pipe.
/* Given a set of bundle bits and a specific pipe, returns which
* instruction the bundle contains in that pipe.
*/
static const struct tile_opcode *
find_opcode(tile_bundle_bits bits, const unsigned short *table)
const struct tile_opcode *
find_opcode(tile_bundle_bits bits, tile_pipeline pipe)
{
const unsigned short *table = tile_bundle_decoder_fsms[pipe];
int index = 0;
while (1)
@ -2465,7 +2466,7 @@ parse_insn_tile(tile_bundle_bits bits,
int i;
d = &decoded[num_instructions++];
opc = find_opcode (bits, tile_bundle_decoder_fsms[pipe]);
opc = find_opcode (bits, (tile_pipeline)pipe);
d->opcode = opc;
/* Decode each operand, sign extending, etc. as appropriate. */

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <asm/irq_regs.h>
#include <asm/traps.h>
#include <hv/hypervisor.h>
@ -56,6 +57,7 @@ cycles_t get_cycles(void)
return (((cycles_t)high) << 32) | low;
}
EXPORT_SYMBOL(get_cycles);
#endif
/*

View File

@ -34,13 +34,13 @@ void flush_tlb_mm(struct mm_struct *mm)
{
HV_Remote_ASID asids[NR_CPUS];
int i = 0, cpu;
for_each_cpu(cpu, &mm->cpu_vm_mask) {
for_each_cpu(cpu, mm_cpumask(mm)) {
HV_Remote_ASID *asid = &asids[i++];
asid->y = cpu / smp_topology.width;
asid->x = cpu % smp_topology.width;
asid->asid = per_cpu(current_asid, cpu);
}
flush_remote(0, HV_FLUSH_EVICT_L1I, &mm->cpu_vm_mask,
flush_remote(0, HV_FLUSH_EVICT_L1I, mm_cpumask(mm),
0, 0, 0, NULL, asids, i);
}
@ -54,8 +54,8 @@ void flush_tlb_page_mm(const struct vm_area_struct *vma, struct mm_struct *mm,
{
unsigned long size = hv_page_size(vma);
int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0;
flush_remote(0, cache, &mm->cpu_vm_mask,
va, size, size, &mm->cpu_vm_mask, NULL, 0);
flush_remote(0, cache, mm_cpumask(mm),
va, size, size, mm_cpumask(mm), NULL, 0);
}
void flush_tlb_page(const struct vm_area_struct *vma, unsigned long va)
@ -70,8 +70,8 @@ void flush_tlb_range(const struct vm_area_struct *vma,
unsigned long size = hv_page_size(vma);
struct mm_struct *mm = vma->vm_mm;
int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0;
flush_remote(0, cache, &mm->cpu_vm_mask, start, end - start, size,
&mm->cpu_vm_mask, NULL, 0);
flush_remote(0, cache, mm_cpumask(mm), start, end - start, size,
mm_cpumask(mm), NULL, 0);
}
void flush_tlb_all(void)

View File

@ -308,6 +308,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
info.si_addr = (void __user *)address;
if (signo == SIGILL)
info.si_trapno = fault_num;
trace_unhandled_signal("trap", regs, address, signo);
force_sig_info(signo, &info, current);
}

View File

@ -59,7 +59,7 @@
* bad kernel addresses).
*
* Note that if the value we would store is the same as what we
* loaded, we bypass the load. Other platforms with true atomics can
* loaded, we bypass the store. Other platforms with true atomics can
* make the guarantee that a non-atomic __clear_bit(), for example,
* can safely race with an atomic test_and_set_bit(); this example is
* from bit_spinlock.h in slub_lock() / slub_unlock(). We can't do

View File

@ -15,6 +15,7 @@
#include <asm/page.h>
#include <asm/cacheflush.h>
#include <arch/icache.h>
#include <arch/spr_def.h>
void __flush_icache_range(unsigned long start, unsigned long end)
@ -39,6 +40,18 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh)
char *p, *base;
size_t step_size, load_count;
const unsigned long STRIPE_WIDTH = 8192;
#ifdef __tilegx__
/*
* On TILE-Gx, we must disable the dstream prefetcher before doing
* a cache flush; otherwise, we could end up with data in the cache
* that we don't want there. Note that normally we'd do an mf
* after the SPR write to disabling the prefetcher, but we do one
* below, before any further loads, so there's no need to do it
* here.
*/
uint_reg_t old_dstream_pf = __insn_mfspr(SPR_DSTREAM_PF);
__insn_mtspr(SPR_DSTREAM_PF, 0);
#endif
/*
* Flush and invalidate the buffer out of the local L1/L2
@ -122,4 +135,9 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh)
/* Wait for the load+inv's (and thus finvs) to have completed. */
__insn_mf();
#ifdef __tilegx__
/* Reenable the prefetcher. */
__insn_mtspr(SPR_DSTREAM_PF, old_dstream_pf);
#endif
}

71
arch/tile/lib/memchr_64.c Normal file
View File

@ -0,0 +1,71 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#include <linux/types.h>
#include <linux/string.h>
#include <linux/module.h>
void *memchr(const void *s, int c, size_t n)
{
const uint64_t *last_word_ptr;
const uint64_t *p;
const char *last_byte_ptr;
uintptr_t s_int;
uint64_t goal, before_mask, v, bits;
char *ret;
if (__builtin_expect(n == 0, 0)) {
/* Don't dereference any memory if the array is empty. */
return NULL;
}
/* Get an aligned pointer. */
s_int = (uintptr_t) s;
p = (const uint64_t *)(s_int & -8);
/* Create eight copies of the byte for which we are looking. */
goal = 0x0101010101010101ULL * (uint8_t) c;
/* Read the first word, but munge it so that bytes before the array
* will not match goal.
*
* Note that this shift count expression works because we know
* shift counts are taken mod 64.
*/
before_mask = (1ULL << (s_int << 3)) - 1;
v = (*p | before_mask) ^ (goal & before_mask);
/* Compute the address of the last byte. */
last_byte_ptr = (const char *)s + n - 1;
/* Compute the address of the word containing the last byte. */
last_word_ptr = (const uint64_t *)((uintptr_t) last_byte_ptr & -8);
while ((bits = __insn_v1cmpeq(v, goal)) == 0) {
if (__builtin_expect(p == last_word_ptr, 0)) {
/* We already read the last word in the array,
* so give up.
*/
return NULL;
}
v = *++p;
}
/* We found a match, but it might be in a byte past the end
* of the array.
*/
ret = ((char *)p) + (__insn_ctz(bits) >> 3);
return (ret <= last_byte_ptr) ? ret : NULL;
}
EXPORT_SYMBOL(memchr);

220
arch/tile/lib/memcpy_64.c Normal file
View File

@ -0,0 +1,220 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#include <linux/types.h>
#include <linux/string.h>
#include <linux/module.h>
#define __memcpy memcpy
/* EXPORT_SYMBOL() is in arch/tile/lib/exports.c since this should be asm. */
/* Must be 8 bytes in size. */
#define word_t uint64_t
#if CHIP_L2_LINE_SIZE() != 64 && CHIP_L2_LINE_SIZE() != 128
#error "Assumes 64 or 128 byte line size"
#endif
/* How many cache lines ahead should we prefetch? */
#define PREFETCH_LINES_AHEAD 3
/*
* Provide "base versions" of load and store for the normal code path.
* The kernel provides other versions for userspace copies.
*/
#define ST(p, v) (*(p) = (v))
#define LD(p) (*(p))
#ifndef USERCOPY_FUNC
#define ST1 ST
#define ST2 ST
#define ST4 ST
#define ST8 ST
#define LD1 LD
#define LD2 LD
#define LD4 LD
#define LD8 LD
#define RETVAL dstv
void *memcpy(void *__restrict dstv, const void *__restrict srcv, size_t n)
#else
/*
* Special kernel version will provide implementation of the LDn/STn
* macros to return a count of uncopied bytes due to mm fault.
*/
#define RETVAL 0
int USERCOPY_FUNC(void *__restrict dstv, const void *__restrict srcv, size_t n)
#endif
{
char *__restrict dst1 = (char *)dstv;
const char *__restrict src1 = (const char *)srcv;
const char *__restrict src1_end;
const char *__restrict prefetch;
word_t *__restrict dst8; /* 8-byte pointer to destination memory. */
word_t final; /* Final bytes to write to trailing word, if any */
long i;
if (n < 16) {
for (; n; n--)
ST1(dst1++, LD1(src1++));
return RETVAL;
}
/*
* Locate the end of source memory we will copy. Don't
* prefetch past this.
*/
src1_end = src1 + n - 1;
/* Prefetch ahead a few cache lines, but not past the end. */
prefetch = src1;
for (i = 0; i < PREFETCH_LINES_AHEAD; i++) {
__insn_prefetch(prefetch);
prefetch += CHIP_L2_LINE_SIZE();
prefetch = (prefetch > src1_end) ? prefetch : src1;
}
/* Copy bytes until dst is word-aligned. */
for (; (uintptr_t)dst1 & (sizeof(word_t) - 1); n--)
ST1(dst1++, LD1(src1++));
/* 8-byte pointer to destination memory. */
dst8 = (word_t *)dst1;
if (__builtin_expect((uintptr_t)src1 & (sizeof(word_t) - 1), 0)) {
/*
* Misaligned copy. Copy 8 bytes at a time, but don't
* bother with other fanciness.
*
* TODO: Consider prefetching and using wh64 as well.
*/
/* Create an aligned src8. */
const word_t *__restrict src8 =
(const word_t *)((uintptr_t)src1 & -sizeof(word_t));
word_t b;
word_t a = LD8(src8++);
for (; n >= sizeof(word_t); n -= sizeof(word_t)) {
b = LD8(src8++);
a = __insn_dblalign(a, b, src1);
ST8(dst8++, a);
a = b;
}
if (n == 0)
return RETVAL;
b = ((const char *)src8 <= src1_end) ? *src8 : 0;
/*
* Final source bytes to write to trailing partial
* word, if any.
*/
final = __insn_dblalign(a, b, src1);
} else {
/* Aligned copy. */
const word_t* __restrict src8 = (const word_t *)src1;
/* src8 and dst8 are both word-aligned. */
if (n >= CHIP_L2_LINE_SIZE()) {
/* Copy until 'dst' is cache-line-aligned. */
for (; (uintptr_t)dst8 & (CHIP_L2_LINE_SIZE() - 1);
n -= sizeof(word_t))
ST8(dst8++, LD8(src8++));
for (; n >= CHIP_L2_LINE_SIZE(); ) {
__insn_wh64(dst8);
/*
* Prefetch and advance to next line
* to prefetch, but don't go past the end
*/
__insn_prefetch(prefetch);
prefetch += CHIP_L2_LINE_SIZE();
prefetch = (prefetch > src1_end) ? prefetch :
(const char *)src8;
/*
* Copy an entire cache line. Manually
* unrolled to avoid idiosyncracies of
* compiler unrolling.
*/
#define COPY_WORD(offset) ({ ST8(dst8+offset, LD8(src8+offset)); n -= 8; })
COPY_WORD(0);
COPY_WORD(1);
COPY_WORD(2);
COPY_WORD(3);
COPY_WORD(4);
COPY_WORD(5);
COPY_WORD(6);
COPY_WORD(7);
#if CHIP_L2_LINE_SIZE() == 128
COPY_WORD(8);
COPY_WORD(9);
COPY_WORD(10);
COPY_WORD(11);
COPY_WORD(12);
COPY_WORD(13);
COPY_WORD(14);
COPY_WORD(15);
#elif CHIP_L2_LINE_SIZE() != 64
# error Fix code that assumes particular L2 cache line sizes
#endif
dst8 += CHIP_L2_LINE_SIZE() / sizeof(word_t);
src8 += CHIP_L2_LINE_SIZE() / sizeof(word_t);
}
}
for (; n >= sizeof(word_t); n -= sizeof(word_t))
ST8(dst8++, LD8(src8++));
if (__builtin_expect(n == 0, 1))
return RETVAL;
final = LD8(src8);
}
/* n != 0 if we get here. Write out any trailing bytes. */
dst1 = (char *)dst8;
if (n & 4) {
ST4((uint32_t *)dst1, final);
dst1 += 4;
final >>= 32;
n &= 3;
}
if (n & 2) {
ST2((uint16_t *)dst1, final);
dst1 += 2;
final >>= 16;
n &= 1;
}
if (n)
ST1((uint8_t *)dst1, final);
return RETVAL;
}
#ifdef USERCOPY_FUNC
#undef ST1
#undef ST2
#undef ST4
#undef ST8
#undef LD1
#undef LD2
#undef LD4
#undef LD8
#undef USERCOPY_FUNC
#endif

View File

@ -0,0 +1,86 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*
* Do memcpy(), but trap and return "n" when a load or store faults.
*
* Note: this idiom only works when memcpy() compiles to a leaf function.
* If "sp" is updated during memcpy, the "jrp lr" will be incorrect.
*
* Also note that we are capturing "n" from the containing scope here.
*/
#define _ST(p, inst, v) \
({ \
asm("1: " #inst " %0, %1;" \
".pushsection .coldtext.memcpy,\"ax\";" \
"2: { move r0, %2; jrp lr };" \
".section __ex_table,\"a\";" \
".quad 1b, 2b;" \
".popsection" \
: "=m" (*(p)) : "r" (v), "r" (n)); \
})
#define _LD(p, inst) \
({ \
unsigned long __v; \
asm("1: " #inst " %0, %1;" \
".pushsection .coldtext.memcpy,\"ax\";" \
"2: { move r0, %2; jrp lr };" \
".section __ex_table,\"a\";" \
".quad 1b, 2b;" \
".popsection" \
: "=r" (__v) : "m" (*(p)), "r" (n)); \
__v; \
})
#define USERCOPY_FUNC __copy_to_user_inatomic
#define ST1(p, v) _ST((p), st1, (v))
#define ST2(p, v) _ST((p), st2, (v))
#define ST4(p, v) _ST((p), st4, (v))
#define ST8(p, v) _ST((p), st, (v))
#define LD1 LD
#define LD2 LD
#define LD4 LD
#define LD8 LD
#include "memcpy_64.c"
#define USERCOPY_FUNC __copy_from_user_inatomic
#define ST1 ST
#define ST2 ST
#define ST4 ST
#define ST8 ST
#define LD1(p) _LD((p), ld1u)
#define LD2(p) _LD((p), ld2u)
#define LD4(p) _LD((p), ld4u)
#define LD8(p) _LD((p), ld)
#include "memcpy_64.c"
#define USERCOPY_FUNC __copy_in_user_inatomic
#define ST1(p, v) _ST((p), st1, (v))
#define ST2(p, v) _ST((p), st2, (v))
#define ST4(p, v) _ST((p), st4, (v))
#define ST8(p, v) _ST((p), st, (v))
#define LD1(p) _LD((p), ld1u)
#define LD2(p) _LD((p), ld2u)
#define LD4(p) _LD((p), ld4u)
#define LD8(p) _LD((p), ld)
#include "memcpy_64.c"
unsigned long __copy_from_user_zeroing(void *to, const void __user *from,
unsigned long n)
{
unsigned long rc = __copy_from_user_inatomic(to, from, n);
if (unlikely(rc))
memset(to + n - rc, 0, rc);
return rc;
}

145
arch/tile/lib/memset_64.c Normal file
View File

@ -0,0 +1,145 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#include <arch/chip.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/module.h>
#undef memset
void *memset(void *s, int c, size_t n)
{
uint64_t *out64;
int n64, to_align64;
uint64_t v64;
uint8_t *out8 = s;
/* Experimentation shows that a trivial tight loop is a win up until
* around a size of 20, where writing a word at a time starts to win.
*/
#define BYTE_CUTOFF 20
#if BYTE_CUTOFF < 7
/* This must be at least at least this big, or some code later
* on doesn't work.
*/
#error "BYTE_CUTOFF is too small"
#endif
if (n < BYTE_CUTOFF) {
/* Strangely, this turns out to be the tightest way to
* write this loop.
*/
if (n != 0) {
do {
/* Strangely, combining these into one line
* performs worse.
*/
*out8 = c;
out8++;
} while (--n != 0);
}
return s;
}
/* Align 'out8'. We know n >= 7 so this won't write past the end. */
while (((uintptr_t) out8 & 7) != 0) {
*out8++ = c;
--n;
}
/* Align 'n'. */
while (n & 7)
out8[--n] = c;
out64 = (uint64_t *) out8;
n64 = n >> 3;
/* Tile input byte out to 64 bits. */
/* KLUDGE */
v64 = 0x0101010101010101ULL * (uint8_t)c;
/* This must be at least 8 or the following loop doesn't work. */
#define CACHE_LINE_SIZE_IN_DOUBLEWORDS (CHIP_L2_LINE_SIZE() / 8)
/* Determine how many words we need to emit before the 'out32'
* pointer becomes aligned modulo the cache line size.
*/
to_align64 = (-((uintptr_t)out64 >> 3)) &
(CACHE_LINE_SIZE_IN_DOUBLEWORDS - 1);
/* Only bother aligning and using wh64 if there is at least
* one full cache line to process. This check also prevents
* overrunning the end of the buffer with alignment words.
*/
if (to_align64 <= n64 - CACHE_LINE_SIZE_IN_DOUBLEWORDS) {
int lines_left;
/* Align out64 mod the cache line size so we can use wh64. */
n64 -= to_align64;
for (; to_align64 != 0; to_align64--) {
*out64 = v64;
out64++;
}
/* Use unsigned divide to turn this into a right shift. */
lines_left = (unsigned)n64 / CACHE_LINE_SIZE_IN_DOUBLEWORDS;
do {
/* Only wh64 a few lines at a time, so we don't
* exceed the maximum number of victim lines.
*/
int x = ((lines_left < CHIP_MAX_OUTSTANDING_VICTIMS())
? lines_left
: CHIP_MAX_OUTSTANDING_VICTIMS());
uint64_t *wh = out64;
int i = x;
int j;
lines_left -= x;
do {
__insn_wh64(wh);
wh += CACHE_LINE_SIZE_IN_DOUBLEWORDS;
} while (--i);
for (j = x * (CACHE_LINE_SIZE_IN_DOUBLEWORDS / 4);
j != 0; j--) {
*out64++ = v64;
*out64++ = v64;
*out64++ = v64;
*out64++ = v64;
}
} while (lines_left != 0);
/* We processed all full lines above, so only this many
* words remain to be processed.
*/
n64 &= CACHE_LINE_SIZE_IN_DOUBLEWORDS - 1;
}
/* Now handle any leftover values. */
if (n64 != 0) {
do {
*out64 = v64;
out64++;
} while (--n64 != 0);
}
return s;
}
EXPORT_SYMBOL(memset);

104
arch/tile/lib/spinlock_64.c Normal file
View File

@ -0,0 +1,104 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#include <linux/spinlock.h>
#include <linux/module.h>
#include <asm/processor.h>
#include "spinlock_common.h"
/*
* Read the spinlock value without allocating in our cache and without
* causing an invalidation to another cpu with a copy of the cacheline.
* This is important when we are spinning waiting for the lock.
*/
static inline u32 arch_spin_read_noalloc(void *lock)
{
return atomic_cmpxchg((atomic_t *)lock, -1, -1);
}
/*
* Wait until the high bits (current) match my ticket.
* If we notice the overflow bit set on entry, we clear it.
*/
void arch_spin_lock_slow(arch_spinlock_t *lock, u32 my_ticket)
{
if (unlikely(my_ticket & __ARCH_SPIN_NEXT_OVERFLOW)) {
__insn_fetchand4(&lock->lock, ~__ARCH_SPIN_NEXT_OVERFLOW);
my_ticket &= ~__ARCH_SPIN_NEXT_OVERFLOW;
}
for (;;) {
u32 val = arch_spin_read_noalloc(lock);
u32 delta = my_ticket - arch_spin_current(val);
if (delta == 0)
return;
relax((128 / CYCLES_PER_RELAX_LOOP) * delta);
}
}
EXPORT_SYMBOL(arch_spin_lock_slow);
/*
* Check the lock to see if it is plausible, and try to get it with cmpxchg().
*/
int arch_spin_trylock(arch_spinlock_t *lock)
{
u32 val = arch_spin_read_noalloc(lock);
if (unlikely(arch_spin_current(val) != arch_spin_next(val)))
return 0;
return cmpxchg(&lock->lock, val, (val + 1) & ~__ARCH_SPIN_NEXT_OVERFLOW)
== val;
}
EXPORT_SYMBOL(arch_spin_trylock);
void arch_spin_unlock_wait(arch_spinlock_t *lock)
{
u32 iterations = 0;
while (arch_spin_is_locked(lock))
delay_backoff(iterations++);
}
EXPORT_SYMBOL(arch_spin_unlock_wait);
/*
* If the read lock fails due to a writer, we retry periodically
* until the value is positive and we write our incremented reader count.
*/
void __read_lock_failed(arch_rwlock_t *rw)
{
u32 val;
int iterations = 0;
do {
delay_backoff(iterations++);
val = __insn_fetchaddgez4(&rw->lock, 1);
} while (unlikely(arch_write_val_locked(val)));
}
EXPORT_SYMBOL(__read_lock_failed);
/*
* If we failed because there were readers, clear the "writer" bit
* so we don't block additional readers. Otherwise, there was another
* writer anyway, so our "fetchor" made no difference. Then wait,
* issuing periodic fetchor instructions, till we get the lock.
*/
void __write_lock_failed(arch_rwlock_t *rw, u32 val)
{
int iterations = 0;
do {
if (!arch_write_val_locked(val))
val = __insn_fetchand4(&rw->lock, ~__WRITE_LOCK_BIT);
delay_backoff(iterations++);
val = __insn_fetchor4(&rw->lock, __WRITE_LOCK_BIT);
} while (val != 0);
}
EXPORT_SYMBOL(__write_lock_failed);

67
arch/tile/lib/strchr_64.c Normal file
View File

@ -0,0 +1,67 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#include <linux/types.h>
#include <linux/string.h>
#include <linux/module.h>
#undef strchr
char *strchr(const char *s, int c)
{
int z, g;
/* Get an aligned pointer. */
const uintptr_t s_int = (uintptr_t) s;
const uint64_t *p = (const uint64_t *)(s_int & -8);
/* Create eight copies of the byte for which we are looking. */
const uint64_t goal = 0x0101010101010101ULL * (uint8_t) c;
/* Read the first aligned word, but force bytes before the string to
* match neither zero nor goal (we make sure the high bit of each
* byte is 1, and the low 7 bits are all the opposite of the goal
* byte).
*
* Note that this shift count expression works because we know shift
* counts are taken mod 64.
*/
const uint64_t before_mask = (1ULL << (s_int << 3)) - 1;
uint64_t v = (*p | before_mask) ^
(goal & __insn_v1shrsi(before_mask, 1));
uint64_t zero_matches, goal_matches;
while (1) {
/* Look for a terminating '\0'. */
zero_matches = __insn_v1cmpeqi(v, 0);
/* Look for the goal byte. */
goal_matches = __insn_v1cmpeq(v, goal);
if (__builtin_expect((zero_matches | goal_matches) != 0, 0))
break;
v = *++p;
}
z = __insn_ctz(zero_matches);
g = __insn_ctz(goal_matches);
/* If we found c before '\0' we got a match. Note that if c == '\0'
* then g == z, and we correctly return the address of the '\0'
* rather than NULL.
*/
return (g <= z) ? ((char *)p) + (g >> 3) : NULL;
}
EXPORT_SYMBOL(strchr);

38
arch/tile/lib/strlen_64.c Normal file
View File

@ -0,0 +1,38 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#include <linux/types.h>
#include <linux/string.h>
#include <linux/module.h>
#undef strlen
size_t strlen(const char *s)
{
/* Get an aligned pointer. */
const uintptr_t s_int = (uintptr_t) s;
const uint64_t *p = (const uint64_t *)(s_int & -8);
/* Read the first word, but force bytes before the string to be nonzero.
* This expression works because we know shift counts are taken mod 64.
*/
uint64_t v = *p | ((1ULL << (s_int << 3)) - 1);
uint64_t bits;
while ((bits = __insn_v1cmpeqi(v, 0)) == 0)
v = *++p;
return ((const char *)p) + (__insn_ctz(bits) >> 3) - s;
}
EXPORT_SYMBOL(strlen);

196
arch/tile/lib/usercopy_64.S Normal file
View File

@ -0,0 +1,196 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#include <linux/linkage.h>
#include <asm/errno.h>
#include <asm/cache.h>
#include <arch/chip.h>
/* Access user memory, but use MMU to avoid propagating kernel exceptions. */
.pushsection .fixup,"ax"
get_user_fault:
{ movei r1, -EFAULT; move r0, zero }
jrp lr
ENDPROC(get_user_fault)
put_user_fault:
{ movei r0, -EFAULT; jrp lr }
ENDPROC(put_user_fault)
.popsection
/*
* __get_user_N functions take a pointer in r0, and return 0 in r1
* on success, with the value in r0; or else -EFAULT in r1.
*/
#define __get_user_N(bytes, LOAD) \
STD_ENTRY(__get_user_##bytes); \
1: { LOAD r0, r0; move r1, zero }; \
jrp lr; \
STD_ENDPROC(__get_user_##bytes); \
.pushsection __ex_table,"a"; \
.quad 1b, get_user_fault; \
.popsection
__get_user_N(1, ld1u)
__get_user_N(2, ld2u)
__get_user_N(4, ld4u)
__get_user_N(8, ld)
/*
* __put_user_N functions take a value in r0 and a pointer in r1,
* and return 0 in r0 on success or -EFAULT on failure.
*/
#define __put_user_N(bytes, STORE) \
STD_ENTRY(__put_user_##bytes); \
1: { STORE r1, r0; move r0, zero }; \
jrp lr; \
STD_ENDPROC(__put_user_##bytes); \
.pushsection __ex_table,"a"; \
.quad 1b, put_user_fault; \
.popsection
__put_user_N(1, st1)
__put_user_N(2, st2)
__put_user_N(4, st4)
__put_user_N(8, st)
/*
* strnlen_user_asm takes the pointer in r0, and the length bound in r1.
* It returns the length, including the terminating NUL, or zero on exception.
* If length is greater than the bound, returns one plus the bound.
*/
STD_ENTRY(strnlen_user_asm)
{ beqz r1, 2f; addi r3, r0, -1 } /* bias down to include NUL */
1: { ld1u r4, r0; addi r1, r1, -1 }
beqz r4, 2f
{ bnezt r1, 1b; addi r0, r0, 1 }
2: { sub r0, r0, r3; jrp lr }
STD_ENDPROC(strnlen_user_asm)
.pushsection .fixup,"ax"
strnlen_user_fault:
{ move r0, zero; jrp lr }
ENDPROC(strnlen_user_fault)
.section __ex_table,"a"
.quad 1b, strnlen_user_fault
.popsection
/*
* strncpy_from_user_asm takes the kernel target pointer in r0,
* the userspace source pointer in r1, and the length bound (including
* the trailing NUL) in r2. On success, it returns the string length
* (not including the trailing NUL), or -EFAULT on failure.
*/
STD_ENTRY(strncpy_from_user_asm)
{ beqz r2, 2f; move r3, r0 }
1: { ld1u r4, r1; addi r1, r1, 1; addi r2, r2, -1 }
{ st1 r0, r4; addi r0, r0, 1 }
beqz r2, 2f
bnezt r4, 1b
addi r0, r0, -1 /* don't count the trailing NUL */
2: { sub r0, r0, r3; jrp lr }
STD_ENDPROC(strncpy_from_user_asm)
.pushsection .fixup,"ax"
strncpy_from_user_fault:
{ movei r0, -EFAULT; jrp lr }
ENDPROC(strncpy_from_user_fault)
.section __ex_table,"a"
.quad 1b, strncpy_from_user_fault
.popsection
/*
* clear_user_asm takes the user target address in r0 and the
* number of bytes to zero in r1.
* It returns the number of uncopiable bytes (hopefully zero) in r0.
* Note that we don't use a separate .fixup section here since we fall
* through into the "fixup" code as the last straight-line bundle anyway.
*/
STD_ENTRY(clear_user_asm)
{ beqz r1, 2f; or r2, r0, r1 }
andi r2, r2, 7
beqzt r2, .Lclear_aligned_user_asm
1: { st1 r0, zero; addi r0, r0, 1; addi r1, r1, -1 }
bnezt r1, 1b
2: { move r0, r1; jrp lr }
.pushsection __ex_table,"a"
.quad 1b, 2b
.popsection
.Lclear_aligned_user_asm:
1: { st r0, zero; addi r0, r0, 8; addi r1, r1, -8 }
bnezt r1, 1b
2: { move r0, r1; jrp lr }
STD_ENDPROC(clear_user_asm)
.pushsection __ex_table,"a"
.quad 1b, 2b
.popsection
/*
* flush_user_asm takes the user target address in r0 and the
* number of bytes to flush in r1.
* It returns the number of unflushable bytes (hopefully zero) in r0.
*/
STD_ENTRY(flush_user_asm)
beqz r1, 2f
{ movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
{ sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
{ and r0, r0, r2; and r1, r1, r2 }
{ sub r1, r1, r0 }
1: { flush r0; addi r1, r1, -CHIP_FLUSH_STRIDE() }
{ addi r0, r0, CHIP_FLUSH_STRIDE(); bnezt r1, 1b }
2: { move r0, r1; jrp lr }
STD_ENDPROC(flush_user_asm)
.pushsection __ex_table,"a"
.quad 1b, 2b
.popsection
/*
* inv_user_asm takes the user target address in r0 and the
* number of bytes to invalidate in r1.
* It returns the number of not inv'able bytes (hopefully zero) in r0.
*/
STD_ENTRY(inv_user_asm)
beqz r1, 2f
{ movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
{ sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
{ and r0, r0, r2; and r1, r1, r2 }
{ sub r1, r1, r0 }
1: { inv r0; addi r1, r1, -CHIP_INV_STRIDE() }
{ addi r0, r0, CHIP_INV_STRIDE(); bnezt r1, 1b }
2: { move r0, r1; jrp lr }
STD_ENDPROC(inv_user_asm)
.pushsection __ex_table,"a"
.quad 1b, 2b
.popsection
/*
* finv_user_asm takes the user target address in r0 and the
* number of bytes to flush-invalidate in r1.
* It returns the number of not finv'able bytes (hopefully zero) in r0.
*/
STD_ENTRY(finv_user_asm)
beqz r1, 2f
{ movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
{ sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
{ and r0, r0, r2; and r1, r1, r2 }
{ sub r1, r1, r0 }
1: { finv r0; addi r1, r1, -CHIP_FINV_STRIDE() }
{ addi r0, r0, CHIP_FINV_STRIDE(); bnezt r1, 1b }
2: { move r0, r1; jrp lr }
STD_ENDPROC(finv_user_asm)
.pushsection __ex_table,"a"
.quad 1b, 2b
.popsection

View File

@ -43,8 +43,11 @@
#include <arch/interrupts.h>
static noinline void force_sig_info_fault(int si_signo, int si_code,
unsigned long address, int fault_num, struct task_struct *tsk)
static noinline void force_sig_info_fault(const char *type, int si_signo,
int si_code, unsigned long address,
int fault_num,
struct task_struct *tsk,
struct pt_regs *regs)
{
siginfo_t info;
@ -59,6 +62,7 @@ static noinline void force_sig_info_fault(int si_signo, int si_code,
info.si_code = si_code;
info.si_addr = (void __user *)address;
info.si_trapno = fault_num;
trace_unhandled_signal(type, regs, address, si_signo);
force_sig_info(si_signo, &info, tsk);
}
@ -71,11 +75,12 @@ SYSCALL_DEFINE2(cmpxchg_badaddr, unsigned long, address,
struct pt_regs *, regs)
{
if (address >= PAGE_OFFSET)
force_sig_info_fault(SIGSEGV, SEGV_MAPERR, address,
INT_DTLB_MISS, current);
force_sig_info_fault("atomic segfault", SIGSEGV, SEGV_MAPERR,
address, INT_DTLB_MISS, current, regs);
else
force_sig_info_fault(SIGBUS, BUS_ADRALN, address,
INT_UNALIGN_DATA, current);
force_sig_info_fault("atomic alignment fault", SIGBUS,
BUS_ADRALN, address,
INT_UNALIGN_DATA, current, regs);
/*
* Adjust pc to point at the actual instruction, which is unusual
@ -471,8 +476,8 @@ bad_area_nosemaphore:
*/
local_irq_enable();
force_sig_info_fault(SIGSEGV, si_code, address,
fault_num, tsk);
force_sig_info_fault("segfault", SIGSEGV, si_code, address,
fault_num, tsk, regs);
return 0;
}
@ -547,7 +552,8 @@ do_sigbus:
if (is_kernel_mode)
goto no_context;
force_sig_info_fault(SIGBUS, BUS_ADRERR, address, fault_num, tsk);
force_sig_info_fault("bus error", SIGBUS, BUS_ADRERR, address,
fault_num, tsk, regs);
return 0;
}
@ -732,6 +738,7 @@ void do_page_fault(struct pt_regs *regs, int fault_num,
panic("Bad fault number %d in do_page_fault", fault_num);
}
#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
if (EX1_PL(regs->ex1) != USER_PL) {
struct async_tlb *async;
switch (fault_num) {
@ -775,6 +782,7 @@ void do_page_fault(struct pt_regs *regs, int fault_num,
return;
}
}
#endif
handle_page_fault(regs, fault_num, is_page_fault, address, write);
}
@ -801,8 +809,6 @@ static void handle_async_page_fault(struct pt_regs *regs,
async->address, async->is_write);
}
}
#endif /* CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() */
/*
* This routine effectively re-issues asynchronous page faults
@ -824,6 +830,8 @@ void do_async_page_fault(struct pt_regs *regs)
handle_async_page_fault(regs, &current->thread.sn_async_tlb);
#endif
}
#endif /* CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() */
void vmalloc_sync_all(void)
{

187
arch/tile/mm/migrate_64.S Normal file
View File

@ -0,0 +1,187 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*
* This routine is a helper for migrating the home of a set of pages to
* a new cpu. See the documentation in homecache.c for more information.
*/
#include <linux/linkage.h>
#include <linux/threads.h>
#include <asm/page.h>
#include <asm/thread_info.h>
#include <asm/types.h>
#include <asm/asm-offsets.h>
#include <hv/hypervisor.h>
.text
/*
* First, some definitions that apply to all the code in the file.
*/
/* Locals (caller-save) */
#define r_tmp r10
#define r_save_sp r11
/* What we save where in the stack frame; must include all callee-saves. */
#define FRAME_SP 8
#define FRAME_R30 16
#define FRAME_R31 24
#define FRAME_R32 32
#define FRAME_R33 40
#define FRAME_SIZE 48
/*
* On entry:
*
* r0 the new context PA to install (moved to r_context)
* r1 PTE to use for context access (moved to r_access)
* r2 ASID to use for new context (moved to r_asid)
* r3 pointer to cpumask with just this cpu set in it (r_my_cpumask)
*/
/* Arguments (caller-save) */
#define r_context_in r0
#define r_access_in r1
#define r_asid_in r2
#define r_my_cpumask r3
/* Locals (callee-save); must not be more than FRAME_xxx above. */
#define r_save_ics r30
#define r_context r31
#define r_access r32
#define r_asid r33
/*
* Caller-save locals and frame constants are the same as
* for homecache_migrate_stack_and_flush.
*/
STD_ENTRY(flush_and_install_context)
/*
* Create a stack frame; we can't touch it once we flush the
* cache until we install the new page table and flush the TLB.
*/
{
move r_save_sp, sp
st sp, lr
addi sp, sp, -FRAME_SIZE
}
addi r_tmp, sp, FRAME_SP
{
st r_tmp, r_save_sp
addi r_tmp, sp, FRAME_R30
}
{
st r_tmp, r30
addi r_tmp, sp, FRAME_R31
}
{
st r_tmp, r31
addi r_tmp, sp, FRAME_R32
}
{
st r_tmp, r32
addi r_tmp, sp, FRAME_R33
}
st r_tmp, r33
/* Move some arguments to callee-save registers. */
{
move r_context, r_context_in
move r_access, r_access_in
}
move r_asid, r_asid_in
/* Disable interrupts, since we can't use our stack. */
{
mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION
movei r_tmp, 1
}
mtspr INTERRUPT_CRITICAL_SECTION, r_tmp
/* First, flush our L2 cache. */
{
move r0, zero /* cache_pa */
moveli r1, hw2_last(HV_FLUSH_EVICT_L2) /* cache_control */
}
{
shl16insli r1, r1, hw1(HV_FLUSH_EVICT_L2)
move r2, r_my_cpumask /* cache_cpumask */
}
{
shl16insli r1, r1, hw0(HV_FLUSH_EVICT_L2)
move r3, zero /* tlb_va */
}
{
move r4, zero /* tlb_length */
move r5, zero /* tlb_pgsize */
}
{
move r6, zero /* tlb_cpumask */
move r7, zero /* asids */
}
{
move r8, zero /* asidcount */
jal hv_flush_remote
}
bnez r0, 1f
/* Now install the new page table. */
{
move r0, r_context
move r1, r_access
}
{
move r2, r_asid
movei r3, HV_CTX_DIRECTIO
}
jal hv_install_context
bnez r0, 1f
/* Finally, flush the TLB. */
{
movei r0, 0 /* preserve_global */
jal hv_flush_all
}
1: /* Reset interrupts back how they were before. */
mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics
/* Restore the callee-saved registers and return. */
addli lr, sp, FRAME_SIZE
{
ld lr, lr
addli r_tmp, sp, FRAME_R30
}
{
ld r30, r_tmp
addli r_tmp, sp, FRAME_R31
}
{
ld r31, r_tmp
addli r_tmp, sp, FRAME_R32
}
{
ld r32, r_tmp
addli r_tmp, sp, FRAME_R33
}
{
ld r33, r_tmp
addi sp, sp, FRAME_SIZE
}
jrp lr
STD_ENDPROC(flush_and_install_context)

View File

@ -19,7 +19,7 @@
/* Note to the author of this code: did it ever occur to
you why the ifdefs are needed? Think about it again. -AK */
#ifdef CONFIG_X86_64
#if defined(CONFIG_X86_64) || defined(CONFIG_TILE)
# define INPUT_COMPAT_TEST is_compat_task()
#elif defined(CONFIG_S390)
# define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT)

View File

@ -1658,11 +1658,9 @@ static int tile_net_stop(struct net_device *dev)
while (tile_net_lepp_free_comps(dev, true))
/* loop */;
/* Wipe the EPP queue. */
/* Wipe the EPP queue, and wait till the stores hit the EPP. */
memset(priv->eq, 0, sizeof(lepp_queue_t));
/* Evict the EPP queue. */
finv_buffer(priv->eq, EQ_SIZE);
mb();
return 0;
}
@ -2398,7 +2396,7 @@ static void tile_net_cleanup(void)
struct net_device *dev = tile_net_devs[i];
struct tile_net_priv *priv = netdev_priv(dev);
unregister_netdev(dev);
finv_buffer(priv->eq, EQ_SIZE);
finv_buffer_remote(priv->eq, EQ_SIZE, 0);
__free_pages(priv->eq_pages, EQ_ORDER);
free_netdev(dev);
}

View File

@ -992,4 +992,11 @@ config RTC_DRV_TEGRA
This drive can also be built as a module. If so, the module
will be called rtc-tegra.
config RTC_DRV_TILE
tristate "Tilera hypervisor RTC support"
depends on TILE
help
Enable support for the Linux driver side of the Tilera
hypervisor's real-time clock interface.
endif # RTC_CLASS

View File

@ -93,6 +93,7 @@ obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o
obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o
obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o
obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o
obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o
obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o
obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o

162
drivers/rtc/rtc-tile.c Normal file
View File

@ -0,0 +1,162 @@
/*
* Copyright 2011 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
* 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
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*
* Tilera-specific RTC driver.
*/
#include <linux/module.h>
#include <linux/device.h>
#include <linux/rtc.h>
#include <linux/platform_device.h>
/* Platform device pointer. */
static struct platform_device *tile_rtc_platform_device;
/*
* RTC read routine. Gets time info from RTC chip via hypervisor syscall.
*/
static int read_rtc_time(struct device *dev, struct rtc_time *tm)
{
HV_RTCTime hvtm = hv_get_rtc();
tm->tm_sec = hvtm.tm_sec;
tm->tm_min = hvtm.tm_min;
tm->tm_hour = hvtm.tm_hour;
tm->tm_mday = hvtm.tm_mday;
tm->tm_mon = hvtm.tm_mon;
tm->tm_year = hvtm.tm_year;
tm->tm_wday = 0;
tm->tm_yday = 0;
tm->tm_isdst = 0;
if (rtc_valid_tm(tm) < 0)
dev_warn(dev, "Read invalid date/time from RTC\n");
return 0;
}
/*
* RTC write routine. Sends time info to hypervisor via syscall, to be
* written to RTC chip.
*/
static int set_rtc_time(struct device *dev, struct rtc_time *tm)
{
HV_RTCTime hvtm;
hvtm.tm_sec = tm->tm_sec;
hvtm.tm_min = tm->tm_min;
hvtm.tm_hour = tm->tm_hour;
hvtm.tm_mday = tm->tm_mday;
hvtm.tm_mon = tm->tm_mon;
hvtm.tm_year = tm->tm_year;
hv_set_rtc(hvtm);
return 0;
}
/*
* RTC read/write ops.
*/
static const struct rtc_class_ops tile_rtc_ops = {
.read_time = read_rtc_time,
.set_time = set_rtc_time,
};
/*
* Device probe routine.
*/
static int __devinit tile_rtc_probe(struct platform_device *dev)
{
struct rtc_device *rtc;
rtc = rtc_device_register("tile",
&dev->dev, &tile_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
platform_set_drvdata(dev, rtc);
return 0;
}
/*
* Device cleanup routine.
*/
static int __devexit tile_rtc_remove(struct platform_device *dev)
{
struct rtc_device *rtc = platform_get_drvdata(dev);
if (rtc)
rtc_device_unregister(rtc);
platform_set_drvdata(dev, NULL);
return 0;
}
static struct platform_driver tile_rtc_platform_driver = {
.driver = {
.name = "rtc-tile",
.owner = THIS_MODULE,
},
.probe = tile_rtc_probe,
.remove = __devexit_p(tile_rtc_remove),
};
/*
* Driver init routine.
*/
static int __init tile_rtc_driver_init(void)
{
int err;
err = platform_driver_register(&tile_rtc_platform_driver);
if (err)
return err;
tile_rtc_platform_device = platform_device_alloc("rtc-tile", 0);
if (tile_rtc_platform_device == NULL) {
err = -ENOMEM;
goto exit_driver_unregister;
}
err = platform_device_add(tile_rtc_platform_device);
if (err)
goto exit_device_put;
return 0;
exit_device_put:
platform_device_put(tile_rtc_platform_device);
exit_driver_unregister:
platform_driver_unregister(&tile_rtc_platform_driver);
return err;
}
/*
* Driver cleanup routine.
*/
static void __exit tile_rtc_driver_exit(void)
{
platform_driver_unregister(&tile_rtc_platform_driver);
}
module_init(tile_rtc_driver_init);
module_exit(tile_rtc_driver_exit);
MODULE_DESCRIPTION("Tilera-specific Real Time Clock Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:rtc-tile");

View File

@ -1,4 +1,6 @@
#ifdef __NR_chmod
__NR_chmod,
#endif
__NR_fchmod,
#ifdef __NR_chown
__NR_chown,
@ -20,7 +22,9 @@ __NR_chown32,
__NR_fchown32,
__NR_lchown32,
#endif
#ifdef __NR_link
__NR_link,
#endif
#ifdef __NR_linkat
__NR_linkat,
#endif

View File

@ -1,13 +1,27 @@
#ifdef __NR_rename
__NR_rename,
#endif
#ifdef __NR_mkdir
__NR_mkdir,
#endif
#ifdef __NR_rmdir
__NR_rmdir,
#endif
#ifdef __NR_creat
__NR_creat,
#endif
#ifdef __NR_link
__NR_link,
#endif
#ifdef __NR_unlink
__NR_unlink,
#endif
#ifdef __NR_symlink
__NR_symlink,
#endif
#ifdef __NR_mknod
__NR_mknod,
#endif
#ifdef __NR_mkdirat
__NR_mkdirat,
__NR_mknodat,

View File

@ -1,4 +1,6 @@
#ifdef __NR_readlink
__NR_readlink,
#endif
__NR_quotactl,
__NR_listxattr,
__NR_llistxattr,
@ -6,3 +8,6 @@ __NR_flistxattr,
__NR_getxattr,
__NR_lgetxattr,
__NR_fgetxattr,
#ifdef __NR_readlinkat
__NR_readlinkat,
#endif

View File

@ -4,7 +4,9 @@ __NR_acct,
__NR_swapon,
#endif
__NR_quotactl,
#ifdef __NR_truncate
__NR_truncate,
#endif
#ifdef __NR_truncate64
__NR_truncate64,
#endif

View File

@ -24,16 +24,24 @@
#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64)
#endif
#ifdef __SYSCALL_COMPAT
#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _comp)
#define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp)
#else
#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _sys)
#define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
#endif
#define __NR_io_setup 0
__SYSCALL(__NR_io_setup, sys_io_setup)
__SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)
#define __NR_io_destroy 1
__SYSCALL(__NR_io_destroy, sys_io_destroy)
#define __NR_io_submit 2
__SYSCALL(__NR_io_submit, sys_io_submit)
__SC_COMP(__NR_io_submit, sys_io_submit, compat_sys_io_submit)
#define __NR_io_cancel 3
__SYSCALL(__NR_io_cancel, sys_io_cancel)
#define __NR_io_getevents 4
__SYSCALL(__NR_io_getevents, sys_io_getevents)
__SC_COMP(__NR_io_getevents, sys_io_getevents, compat_sys_io_getevents)
/* fs/xattr.c */
#define __NR_setxattr 5
@ -67,7 +75,7 @@ __SYSCALL(__NR_getcwd, sys_getcwd)
/* fs/cookies.c */
#define __NR_lookup_dcookie 18
__SYSCALL(__NR_lookup_dcookie, sys_lookup_dcookie)
__SC_COMP(__NR_lookup_dcookie, sys_lookup_dcookie, compat_sys_lookup_dcookie)
/* fs/eventfd.c */
#define __NR_eventfd2 19
@ -79,7 +87,7 @@ __SYSCALL(__NR_epoll_create1, sys_epoll_create1)
#define __NR_epoll_ctl 21
__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
#define __NR_epoll_pwait 22
__SYSCALL(__NR_epoll_pwait, sys_epoll_pwait)
__SC_COMP(__NR_epoll_pwait, sys_epoll_pwait, compat_sys_epoll_pwait)
/* fs/fcntl.c */
#define __NR_dup 23
@ -87,7 +95,7 @@ __SYSCALL(__NR_dup, sys_dup)
#define __NR_dup3 24
__SYSCALL(__NR_dup3, sys_dup3)
#define __NR3264_fcntl 25
__SC_3264(__NR3264_fcntl, sys_fcntl64, sys_fcntl)
__SC_COMP_3264(__NR3264_fcntl, sys_fcntl64, sys_fcntl, compat_sys_fcntl64)
/* fs/inotify_user.c */
#define __NR_inotify_init1 26
@ -99,7 +107,7 @@ __SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
/* fs/ioctl.c */
#define __NR_ioctl 29
__SYSCALL(__NR_ioctl, sys_ioctl)
__SC_COMP(__NR_ioctl, sys_ioctl, compat_sys_ioctl)
/* fs/ioprio.c */
#define __NR_ioprio_set 30
@ -129,26 +137,30 @@ __SYSCALL(__NR_renameat, sys_renameat)
#define __NR_umount2 39
__SYSCALL(__NR_umount2, sys_umount)
#define __NR_mount 40
__SYSCALL(__NR_mount, sys_mount)
__SC_COMP(__NR_mount, sys_mount, compat_sys_mount)
#define __NR_pivot_root 41
__SYSCALL(__NR_pivot_root, sys_pivot_root)
/* fs/nfsctl.c */
#define __NR_nfsservctl 42
__SYSCALL(__NR_nfsservctl, sys_nfsservctl)
__SC_COMP(__NR_nfsservctl, sys_nfsservctl, compat_sys_nfsservctl)
/* fs/open.c */
#define __NR3264_statfs 43
__SC_3264(__NR3264_statfs, sys_statfs64, sys_statfs)
__SC_COMP_3264(__NR3264_statfs, sys_statfs64, sys_statfs, \
compat_sys_statfs64)
#define __NR3264_fstatfs 44
__SC_3264(__NR3264_fstatfs, sys_fstatfs64, sys_fstatfs)
__SC_COMP_3264(__NR3264_fstatfs, sys_fstatfs64, sys_fstatfs, \
compat_sys_fstatfs64)
#define __NR3264_truncate 45
__SC_3264(__NR3264_truncate, sys_truncate64, sys_truncate)
__SC_COMP_3264(__NR3264_truncate, sys_truncate64, sys_truncate, \
compat_sys_truncate64)
#define __NR3264_ftruncate 46
__SC_3264(__NR3264_ftruncate, sys_ftruncate64, sys_ftruncate)
__SC_COMP_3264(__NR3264_ftruncate, sys_ftruncate64, sys_ftruncate, \
compat_sys_ftruncate64)
#define __NR_fallocate 47
__SYSCALL(__NR_fallocate, sys_fallocate)
__SC_COMP(__NR_fallocate, sys_fallocate, compat_sys_fallocate)
#define __NR_faccessat 48
__SYSCALL(__NR_faccessat, sys_faccessat)
#define __NR_chdir 49
@ -166,7 +178,7 @@ __SYSCALL(__NR_fchownat, sys_fchownat)
#define __NR_fchown 55
__SYSCALL(__NR_fchown, sys_fchown)
#define __NR_openat 56
__SYSCALL(__NR_openat, sys_openat)
__SC_COMP(__NR_openat, sys_openat, compat_sys_openat)
#define __NR_close 57
__SYSCALL(__NR_close, sys_close)
#define __NR_vhangup 58
@ -182,7 +194,7 @@ __SYSCALL(__NR_quotactl, sys_quotactl)
/* fs/readdir.c */
#define __NR_getdents64 61
__SYSCALL(__NR_getdents64, sys_getdents64)
__SC_COMP(__NR_getdents64, sys_getdents64, compat_sys_getdents64)
/* fs/read_write.c */
#define __NR3264_lseek 62
@ -192,17 +204,17 @@ __SYSCALL(__NR_read, sys_read)
#define __NR_write 64
__SYSCALL(__NR_write, sys_write)
#define __NR_readv 65
__SYSCALL(__NR_readv, sys_readv)
__SC_COMP(__NR_readv, sys_readv, compat_sys_readv)
#define __NR_writev 66
__SYSCALL(__NR_writev, sys_writev)
__SC_COMP(__NR_writev, sys_writev, compat_sys_writev)
#define __NR_pread64 67
__SYSCALL(__NR_pread64, sys_pread64)
__SC_COMP(__NR_pread64, sys_pread64, compat_sys_pread64)
#define __NR_pwrite64 68
__SYSCALL(__NR_pwrite64, sys_pwrite64)
__SC_COMP(__NR_pwrite64, sys_pwrite64, compat_sys_pwrite64)
#define __NR_preadv 69
__SYSCALL(__NR_preadv, sys_preadv)
__SC_COMP(__NR_preadv, sys_preadv, compat_sys_preadv)
#define __NR_pwritev 70
__SYSCALL(__NR_pwritev, sys_pwritev)
__SC_COMP(__NR_pwritev, sys_pwritev, compat_sys_pwritev)
/* fs/sendfile.c */
#define __NR3264_sendfile 71
@ -210,17 +222,17 @@ __SC_3264(__NR3264_sendfile, sys_sendfile64, sys_sendfile)
/* fs/select.c */
#define __NR_pselect6 72
__SYSCALL(__NR_pselect6, sys_pselect6)
__SC_COMP(__NR_pselect6, sys_pselect6, compat_sys_pselect6)
#define __NR_ppoll 73
__SYSCALL(__NR_ppoll, sys_ppoll)
__SC_COMP(__NR_ppoll, sys_ppoll, compat_sys_ppoll)
/* fs/signalfd.c */
#define __NR_signalfd4 74
__SYSCALL(__NR_signalfd4, sys_signalfd4)
__SC_COMP(__NR_signalfd4, sys_signalfd4, compat_sys_signalfd4)
/* fs/splice.c */
#define __NR_vmsplice 75
__SYSCALL(__NR_vmsplice, sys_vmsplice)
__SC_COMP(__NR_vmsplice, sys_vmsplice, compat_sys_vmsplice)
#define __NR_splice 76
__SYSCALL(__NR_splice, sys_splice)
#define __NR_tee 77
@ -243,23 +255,27 @@ __SYSCALL(__NR_fsync, sys_fsync)
__SYSCALL(__NR_fdatasync, sys_fdatasync)
#ifdef __ARCH_WANT_SYNC_FILE_RANGE2
#define __NR_sync_file_range2 84
__SYSCALL(__NR_sync_file_range2, sys_sync_file_range2)
__SC_COMP(__NR_sync_file_range2, sys_sync_file_range2, \
compat_sys_sync_file_range2)
#else
#define __NR_sync_file_range 84
__SYSCALL(__NR_sync_file_range, sys_sync_file_range)
__SC_COMP(__NR_sync_file_range, sys_sync_file_range, \
compat_sys_sync_file_range)
#endif
/* fs/timerfd.c */
#define __NR_timerfd_create 85
__SYSCALL(__NR_timerfd_create, sys_timerfd_create)
#define __NR_timerfd_settime 86
__SYSCALL(__NR_timerfd_settime, sys_timerfd_settime)
__SC_COMP(__NR_timerfd_settime, sys_timerfd_settime, \
compat_sys_timerfd_settime)
#define __NR_timerfd_gettime 87
__SYSCALL(__NR_timerfd_gettime, sys_timerfd_gettime)
__SC_COMP(__NR_timerfd_gettime, sys_timerfd_gettime, \
compat_sys_timerfd_gettime)
/* fs/utimes.c */
#define __NR_utimensat 88
__SYSCALL(__NR_utimensat, sys_utimensat)
__SC_COMP(__NR_utimensat, sys_utimensat, compat_sys_utimensat)
/* kernel/acct.c */
#define __NR_acct 89
@ -281,7 +297,7 @@ __SYSCALL(__NR_exit, sys_exit)
#define __NR_exit_group 94
__SYSCALL(__NR_exit_group, sys_exit_group)
#define __NR_waitid 95
__SYSCALL(__NR_waitid, sys_waitid)
__SC_COMP(__NR_waitid, sys_waitid, compat_sys_waitid)
/* kernel/fork.c */
#define __NR_set_tid_address 96
@ -291,25 +307,27 @@ __SYSCALL(__NR_unshare, sys_unshare)
/* kernel/futex.c */
#define __NR_futex 98
__SYSCALL(__NR_futex, sys_futex)
__SC_COMP(__NR_futex, sys_futex, compat_sys_futex)
#define __NR_set_robust_list 99
__SYSCALL(__NR_set_robust_list, sys_set_robust_list)
__SC_COMP(__NR_set_robust_list, sys_set_robust_list, \
compat_sys_set_robust_list)
#define __NR_get_robust_list 100
__SYSCALL(__NR_get_robust_list, sys_get_robust_list)
__SC_COMP(__NR_get_robust_list, sys_get_robust_list, \
compat_sys_get_robust_list)
/* kernel/hrtimer.c */
#define __NR_nanosleep 101
__SYSCALL(__NR_nanosleep, sys_nanosleep)
__SC_COMP(__NR_nanosleep, sys_nanosleep, compat_sys_nanosleep)
/* kernel/itimer.c */
#define __NR_getitimer 102
__SYSCALL(__NR_getitimer, sys_getitimer)
__SC_COMP(__NR_getitimer, sys_getitimer, compat_sys_getitimer)
#define __NR_setitimer 103
__SYSCALL(__NR_setitimer, sys_setitimer)
__SC_COMP(__NR_setitimer, sys_setitimer, compat_sys_setitimer)
/* kernel/kexec.c */
#define __NR_kexec_load 104
__SYSCALL(__NR_kexec_load, sys_kexec_load)
__SC_COMP(__NR_kexec_load, sys_kexec_load, compat_sys_kexec_load)
/* kernel/module.c */
#define __NR_init_module 105
@ -319,23 +337,24 @@ __SYSCALL(__NR_delete_module, sys_delete_module)
/* kernel/posix-timers.c */
#define __NR_timer_create 107
__SYSCALL(__NR_timer_create, sys_timer_create)
__SC_COMP(__NR_timer_create, sys_timer_create, compat_sys_timer_create)
#define __NR_timer_gettime 108
__SYSCALL(__NR_timer_gettime, sys_timer_gettime)
__SC_COMP(__NR_timer_gettime, sys_timer_gettime, compat_sys_timer_gettime)
#define __NR_timer_getoverrun 109
__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun)
#define __NR_timer_settime 110
__SYSCALL(__NR_timer_settime, sys_timer_settime)
__SC_COMP(__NR_timer_settime, sys_timer_settime, compat_sys_timer_settime)
#define __NR_timer_delete 111
__SYSCALL(__NR_timer_delete, sys_timer_delete)
#define __NR_clock_settime 112
__SYSCALL(__NR_clock_settime, sys_clock_settime)
__SC_COMP(__NR_clock_settime, sys_clock_settime, compat_sys_clock_settime)
#define __NR_clock_gettime 113
__SYSCALL(__NR_clock_gettime, sys_clock_gettime)
__SC_COMP(__NR_clock_gettime, sys_clock_gettime, compat_sys_clock_gettime)
#define __NR_clock_getres 114
__SYSCALL(__NR_clock_getres, sys_clock_getres)
__SC_COMP(__NR_clock_getres, sys_clock_getres, compat_sys_clock_getres)
#define __NR_clock_nanosleep 115
__SYSCALL(__NR_clock_nanosleep, sys_clock_nanosleep)
__SC_COMP(__NR_clock_nanosleep, sys_clock_nanosleep, \
compat_sys_clock_nanosleep)
/* kernel/printk.c */
#define __NR_syslog 116
@ -355,9 +374,11 @@ __SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler)
#define __NR_sched_getparam 121
__SYSCALL(__NR_sched_getparam, sys_sched_getparam)
#define __NR_sched_setaffinity 122
__SYSCALL(__NR_sched_setaffinity, sys_sched_setaffinity)
__SC_COMP(__NR_sched_setaffinity, sys_sched_setaffinity, \
compat_sys_sched_setaffinity)
#define __NR_sched_getaffinity 123
__SYSCALL(__NR_sched_getaffinity, sys_sched_getaffinity)
__SC_COMP(__NR_sched_getaffinity, sys_sched_getaffinity, \
compat_sys_sched_getaffinity)
#define __NR_sched_yield 124
__SYSCALL(__NR_sched_yield, sys_sched_yield)
#define __NR_sched_get_priority_max 125
@ -365,7 +386,8 @@ __SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max)
#define __NR_sched_get_priority_min 126
__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min)
#define __NR_sched_rr_get_interval 127
__SYSCALL(__NR_sched_rr_get_interval, sys_sched_rr_get_interval)
__SC_COMP(__NR_sched_rr_get_interval, sys_sched_rr_get_interval, \
compat_sys_sched_rr_get_interval)
/* kernel/signal.c */
#define __NR_restart_syscall 128
@ -377,21 +399,23 @@ __SYSCALL(__NR_tkill, sys_tkill)
#define __NR_tgkill 131
__SYSCALL(__NR_tgkill, sys_tgkill)
#define __NR_sigaltstack 132
__SYSCALL(__NR_sigaltstack, sys_sigaltstack)
__SC_COMP(__NR_sigaltstack, sys_sigaltstack, compat_sys_sigaltstack)
#define __NR_rt_sigsuspend 133
__SYSCALL(__NR_rt_sigsuspend, sys_rt_sigsuspend) /* __ARCH_WANT_SYS_RT_SIGSUSPEND */
__SC_COMP(__NR_rt_sigsuspend, sys_rt_sigsuspend, compat_sys_rt_sigsuspend)
#define __NR_rt_sigaction 134
__SYSCALL(__NR_rt_sigaction, sys_rt_sigaction) /* __ARCH_WANT_SYS_RT_SIGACTION */
__SC_COMP(__NR_rt_sigaction, sys_rt_sigaction, compat_sys_rt_sigaction)
#define __NR_rt_sigprocmask 135
__SYSCALL(__NR_rt_sigprocmask, sys_rt_sigprocmask)
#define __NR_rt_sigpending 136
__SYSCALL(__NR_rt_sigpending, sys_rt_sigpending)
#define __NR_rt_sigtimedwait 137
__SYSCALL(__NR_rt_sigtimedwait, sys_rt_sigtimedwait)
__SC_COMP(__NR_rt_sigtimedwait, sys_rt_sigtimedwait, \
compat_sys_rt_sigtimedwait)
#define __NR_rt_sigqueueinfo 138
__SYSCALL(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo)
__SC_COMP(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo, \
compat_sys_rt_sigqueueinfo)
#define __NR_rt_sigreturn 139
__SYSCALL(__NR_rt_sigreturn, sys_rt_sigreturn) /* sys_rt_sigreturn_wrapper, */
__SC_COMP(__NR_rt_sigreturn, sys_rt_sigreturn, compat_sys_rt_sigreturn)
/* kernel/sys.c */
#define __NR_setpriority 140
@ -421,7 +445,7 @@ __SYSCALL(__NR_setfsuid, sys_setfsuid)
#define __NR_setfsgid 152
__SYSCALL(__NR_setfsgid, sys_setfsgid)
#define __NR_times 153
__SYSCALL(__NR_times, sys_times)
__SC_COMP(__NR_times, sys_times, compat_sys_times)
#define __NR_setpgid 154
__SYSCALL(__NR_setpgid, sys_setpgid)
#define __NR_getpgid 155
@ -441,11 +465,11 @@ __SYSCALL(__NR_sethostname, sys_sethostname)
#define __NR_setdomainname 162
__SYSCALL(__NR_setdomainname, sys_setdomainname)
#define __NR_getrlimit 163
__SYSCALL(__NR_getrlimit, sys_getrlimit)
__SC_COMP(__NR_getrlimit, sys_getrlimit, compat_sys_getrlimit)
#define __NR_setrlimit 164
__SYSCALL(__NR_setrlimit, sys_setrlimit)
__SC_COMP(__NR_setrlimit, sys_setrlimit, compat_sys_setrlimit)
#define __NR_getrusage 165
__SYSCALL(__NR_getrusage, sys_getrusage)
__SC_COMP(__NR_getrusage, sys_getrusage, compat_sys_getrusage)
#define __NR_umask 166
__SYSCALL(__NR_umask, sys_umask)
#define __NR_prctl 167
@ -455,11 +479,11 @@ __SYSCALL(__NR_getcpu, sys_getcpu)
/* kernel/time.c */
#define __NR_gettimeofday 169
__SYSCALL(__NR_gettimeofday, sys_gettimeofday)
__SC_COMP(__NR_gettimeofday, sys_gettimeofday, compat_sys_gettimeofday)
#define __NR_settimeofday 170
__SYSCALL(__NR_settimeofday, sys_settimeofday)
__SC_COMP(__NR_settimeofday, sys_settimeofday, compat_sys_settimeofday)
#define __NR_adjtimex 171
__SYSCALL(__NR_adjtimex, sys_adjtimex)
__SC_COMP(__NR_adjtimex, sys_adjtimex, compat_sys_adjtimex)
/* kernel/timer.c */
#define __NR_getpid 172
@ -477,39 +501,40 @@ __SYSCALL(__NR_getegid, sys_getegid)
#define __NR_gettid 178
__SYSCALL(__NR_gettid, sys_gettid)
#define __NR_sysinfo 179
__SYSCALL(__NR_sysinfo, sys_sysinfo)
__SC_COMP(__NR_sysinfo, sys_sysinfo, compat_sys_sysinfo)
/* ipc/mqueue.c */
#define __NR_mq_open 180
__SYSCALL(__NR_mq_open, sys_mq_open)
__SC_COMP(__NR_mq_open, sys_mq_open, compat_sys_mq_open)
#define __NR_mq_unlink 181
__SYSCALL(__NR_mq_unlink, sys_mq_unlink)
#define __NR_mq_timedsend 182
__SYSCALL(__NR_mq_timedsend, sys_mq_timedsend)
__SC_COMP(__NR_mq_timedsend, sys_mq_timedsend, compat_sys_mq_timedsend)
#define __NR_mq_timedreceive 183
__SYSCALL(__NR_mq_timedreceive, sys_mq_timedreceive)
__SC_COMP(__NR_mq_timedreceive, sys_mq_timedreceive, \
compat_sys_mq_timedreceive)
#define __NR_mq_notify 184
__SYSCALL(__NR_mq_notify, sys_mq_notify)
__SC_COMP(__NR_mq_notify, sys_mq_notify, compat_sys_mq_notify)
#define __NR_mq_getsetattr 185
__SYSCALL(__NR_mq_getsetattr, sys_mq_getsetattr)
__SC_COMP(__NR_mq_getsetattr, sys_mq_getsetattr, compat_sys_mq_getsetattr)
/* ipc/msg.c */
#define __NR_msgget 186
__SYSCALL(__NR_msgget, sys_msgget)
#define __NR_msgctl 187
__SYSCALL(__NR_msgctl, sys_msgctl)
__SC_COMP(__NR_msgctl, sys_msgctl, compat_sys_msgctl)
#define __NR_msgrcv 188
__SYSCALL(__NR_msgrcv, sys_msgrcv)
__SC_COMP(__NR_msgrcv, sys_msgrcv, compat_sys_msgrcv)
#define __NR_msgsnd 189
__SYSCALL(__NR_msgsnd, sys_msgsnd)
__SC_COMP(__NR_msgsnd, sys_msgsnd, compat_sys_msgsnd)
/* ipc/sem.c */
#define __NR_semget 190
__SYSCALL(__NR_semget, sys_semget)
#define __NR_semctl 191
__SYSCALL(__NR_semctl, sys_semctl)
__SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl)
#define __NR_semtimedop 192
__SYSCALL(__NR_semtimedop, sys_semtimedop)
__SC_COMP(__NR_semtimedop, sys_semtimedop, compat_sys_semtimedop)
#define __NR_semop 193
__SYSCALL(__NR_semop, sys_semop)
@ -517,9 +542,9 @@ __SYSCALL(__NR_semop, sys_semop)
#define __NR_shmget 194
__SYSCALL(__NR_shmget, sys_shmget)
#define __NR_shmctl 195
__SYSCALL(__NR_shmctl, sys_shmctl)
__SC_COMP(__NR_shmctl, sys_shmctl, compat_sys_shmctl)
#define __NR_shmat 196
__SYSCALL(__NR_shmat, sys_shmat)
__SC_COMP(__NR_shmat, sys_shmat, compat_sys_shmat)
#define __NR_shmdt 197
__SYSCALL(__NR_shmdt, sys_shmdt)
@ -543,21 +568,21 @@ __SYSCALL(__NR_getpeername, sys_getpeername)
#define __NR_sendto 206
__SYSCALL(__NR_sendto, sys_sendto)
#define __NR_recvfrom 207
__SYSCALL(__NR_recvfrom, sys_recvfrom)
__SC_COMP(__NR_recvfrom, sys_recvfrom, compat_sys_recvfrom)
#define __NR_setsockopt 208
__SYSCALL(__NR_setsockopt, sys_setsockopt)
__SC_COMP(__NR_setsockopt, sys_setsockopt, compat_sys_setsockopt)
#define __NR_getsockopt 209
__SYSCALL(__NR_getsockopt, sys_getsockopt)
__SC_COMP(__NR_getsockopt, sys_getsockopt, compat_sys_getsockopt)
#define __NR_shutdown 210
__SYSCALL(__NR_shutdown, sys_shutdown)
#define __NR_sendmsg 211
__SYSCALL(__NR_sendmsg, sys_sendmsg)
__SC_COMP(__NR_sendmsg, sys_sendmsg, compat_sys_sendmsg)
#define __NR_recvmsg 212
__SYSCALL(__NR_recvmsg, sys_recvmsg)
__SC_COMP(__NR_recvmsg, sys_recvmsg, compat_sys_recvmsg)
/* mm/filemap.c */
#define __NR_readahead 213
__SYSCALL(__NR_readahead, sys_readahead)
__SC_COMP(__NR_readahead, sys_readahead, compat_sys_readahead)
/* mm/nommu.c, also with MMU */
#define __NR_brk 214
@ -573,19 +598,19 @@ __SYSCALL(__NR_add_key, sys_add_key)
#define __NR_request_key 218
__SYSCALL(__NR_request_key, sys_request_key)
#define __NR_keyctl 219
__SYSCALL(__NR_keyctl, sys_keyctl)
__SC_COMP(__NR_keyctl, sys_keyctl, compat_sys_keyctl)
/* arch/example/kernel/sys_example.c */
#define __NR_clone 220
__SYSCALL(__NR_clone, sys_clone) /* .long sys_clone_wrapper */
__SYSCALL(__NR_clone, sys_clone)
#define __NR_execve 221
__SYSCALL(__NR_execve, sys_execve) /* .long sys_execve_wrapper */
__SC_COMP(__NR_execve, sys_execve, compat_sys_execve)
#define __NR3264_mmap 222
__SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap)
/* mm/fadvise.c */
#define __NR3264_fadvise64 223
__SYSCALL(__NR3264_fadvise64, sys_fadvise64_64)
__SC_COMP(__NR3264_fadvise64, sys_fadvise64_64, compat_sys_fadvise64_64)
/* mm/, CONFIG_MMU only */
#ifndef __ARCH_NOMMU
@ -612,25 +637,26 @@ __SYSCALL(__NR_madvise, sys_madvise)
#define __NR_remap_file_pages 234
__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages)
#define __NR_mbind 235
__SYSCALL(__NR_mbind, sys_mbind)
__SC_COMP(__NR_mbind, sys_mbind, compat_sys_mbind)
#define __NR_get_mempolicy 236
__SYSCALL(__NR_get_mempolicy, sys_get_mempolicy)
__SC_COMP(__NR_get_mempolicy, sys_get_mempolicy, compat_sys_get_mempolicy)
#define __NR_set_mempolicy 237
__SYSCALL(__NR_set_mempolicy, sys_set_mempolicy)
__SC_COMP(__NR_set_mempolicy, sys_set_mempolicy, compat_sys_set_mempolicy)
#define __NR_migrate_pages 238
__SYSCALL(__NR_migrate_pages, sys_migrate_pages)
__SC_COMP(__NR_migrate_pages, sys_migrate_pages, compat_sys_migrate_pages)
#define __NR_move_pages 239
__SYSCALL(__NR_move_pages, sys_move_pages)
__SC_COMP(__NR_move_pages, sys_move_pages, compat_sys_move_pages)
#endif
#define __NR_rt_tgsigqueueinfo 240
__SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo)
__SC_COMP(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, \
compat_sys_rt_tgsigqueueinfo)
#define __NR_perf_event_open 241
__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
#define __NR_accept4 242
__SYSCALL(__NR_accept4, sys_accept4)
#define __NR_recvmmsg 243
__SYSCALL(__NR_recvmmsg, sys_recvmmsg)
__SC_COMP(__NR_recvmmsg, sys_recvmmsg, compat_sys_recvmmsg)
/*
* Architectures may provide up to 16 syscalls of their own
@ -639,19 +665,20 @@ __SYSCALL(__NR_recvmmsg, sys_recvmmsg)
#define __NR_arch_specific_syscall 244
#define __NR_wait4 260
__SYSCALL(__NR_wait4, sys_wait4)
__SC_COMP(__NR_wait4, sys_wait4, compat_sys_wait4)
#define __NR_prlimit64 261
__SYSCALL(__NR_prlimit64, sys_prlimit64)
#define __NR_fanotify_init 262
__SYSCALL(__NR_fanotify_init, sys_fanotify_init)
#define __NR_fanotify_mark 263
__SYSCALL(__NR_fanotify_mark, sys_fanotify_mark)
#define __NR_name_to_handle_at 264
#define __NR_name_to_handle_at 264
__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
#define __NR_open_by_handle_at 265
__SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at)
#define __NR_open_by_handle_at 265
__SC_COMP(__NR_open_by_handle_at, sys_open_by_handle_at, \
compat_sys_open_by_handle_at)
#define __NR_clock_adjtime 266
__SYSCALL(__NR_clock_adjtime, sys_clock_adjtime)
__SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime)
#define __NR_syncfs 267
__SYSCALL(__NR_syncfs, sys_syncfs)

View File

@ -12,6 +12,8 @@
#include <linux/sem.h>
#include <linux/socket.h>
#include <linux/if.h>
#include <linux/fs.h>
#include <linux/aio_abi.h> /* for aio_context_t */
#include <asm/compat.h>
#include <asm/siginfo.h>
@ -26,7 +28,7 @@ typedef __compat_gid32_t compat_gid_t;
struct compat_sel_arg_struct;
struct rusage;
struct compat_itimerspec {
struct compat_itimerspec {
struct compat_timespec it_interval;
struct compat_timespec it_value;
};
@ -70,9 +72,9 @@ struct compat_timex {
compat_long_t stbcnt;
compat_int_t tai;
compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32;
compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32;
compat_int_t :32; compat_int_t :32; compat_int_t :32;
compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32;
compat_int_t:32; compat_int_t:32; compat_int_t:32; compat_int_t:32;
compat_int_t:32; compat_int_t:32; compat_int_t:32;
};
#define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW)
@ -81,8 +83,10 @@ typedef struct {
compat_sigset_word sig[_COMPAT_NSIG_WORDS];
} compat_sigset_t;
extern int get_compat_timespec(struct timespec *, const struct compat_timespec __user *);
extern int put_compat_timespec(const struct timespec *, struct compat_timespec __user *);
extern int get_compat_timespec(struct timespec *,
const struct compat_timespec __user *);
extern int put_compat_timespec(const struct timespec *,
struct compat_timespec __user *);
struct compat_iovec {
compat_uptr_t iov_base;
@ -113,7 +117,8 @@ struct compat_rusage {
compat_long_t ru_nivcsw;
};
extern int put_compat_rusage(const struct rusage *, struct compat_rusage __user *);
extern int put_compat_rusage(const struct rusage *,
struct compat_rusage __user *);
struct compat_siginfo;
@ -166,8 +171,7 @@ struct compat_ifmap {
unsigned char port;
};
struct compat_if_settings
{
struct compat_if_settings {
unsigned int type; /* Type of physical device or protocol */
unsigned int size; /* Size of the data allocated by the caller */
compat_uptr_t ifs_ifsu; /* union of pointers */
@ -195,8 +199,8 @@ struct compat_ifreq {
};
struct compat_ifconf {
compat_int_t ifc_len; /* size of buffer */
compat_caddr_t ifcbuf;
compat_int_t ifc_len; /* size of buffer */
compat_caddr_t ifcbuf;
};
struct compat_robust_list {
@ -209,6 +213,18 @@ struct compat_robust_list_head {
compat_uptr_t list_op_pending;
};
struct compat_statfs;
struct compat_statfs64;
struct compat_old_linux_dirent;
struct compat_linux_dirent;
struct linux_dirent64;
struct compat_msghdr;
struct compat_mmsghdr;
struct compat_sysinfo;
struct compat_sysctl_args;
struct compat_kexec_segment;
struct compat_mq_attr;
extern void compat_exit_robust_list(struct task_struct *curr);
asmlinkage long
@ -243,8 +259,8 @@ asmlinkage ssize_t compat_sys_pwritev(unsigned long fd,
const struct compat_iovec __user *vec,
unsigned long vlen, u32 pos_low, u32 pos_high);
int compat_do_execve(char * filename, compat_uptr_t __user *argv,
compat_uptr_t __user *envp, struct pt_regs * regs);
int compat_do_execve(char *filename, compat_uptr_t __user *argv,
compat_uptr_t __user *envp, struct pt_regs *regs);
asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
@ -331,12 +347,18 @@ asmlinkage long compat_sys_epoll_pwait(int epfd,
const compat_sigset_t __user *sigmask,
compat_size_t sigsetsize);
asmlinkage long compat_sys_utimensat(unsigned int dfd, const char __user *filename,
struct compat_timespec __user *t, int flags);
asmlinkage long compat_sys_utime(const char __user *filename,
struct compat_utimbuf __user *t);
asmlinkage long compat_sys_utimensat(unsigned int dfd,
const char __user *filename,
struct compat_timespec __user *t,
int flags);
asmlinkage long compat_sys_time(compat_time_t __user *tloc);
asmlinkage long compat_sys_stime(compat_time_t __user *tptr);
asmlinkage long compat_sys_signalfd(int ufd,
const compat_sigset_t __user *sigmask,
compat_size_t sigsetsize);
const compat_sigset_t __user *sigmask,
compat_size_t sigsetsize);
asmlinkage long compat_sys_timerfd_settime(int ufd, int flags,
const struct compat_itimerspec __user *utmr,
struct compat_itimerspec __user *otmr);
@ -348,16 +370,190 @@ asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page,
const int __user *nodes,
int __user *status,
int flags);
asmlinkage long compat_sys_futimesat(unsigned int dfd, const char __user *filename,
asmlinkage long compat_sys_futimesat(unsigned int dfd,
const char __user *filename,
struct compat_timeval __user *t);
asmlinkage long compat_sys_newfstatat(unsigned int dfd, const char __user * filename,
asmlinkage long compat_sys_utimes(const char __user *filename,
struct compat_timeval __user *t);
asmlinkage long compat_sys_newstat(const char __user *filename,
struct compat_stat __user *statbuf);
asmlinkage long compat_sys_newlstat(const char __user *filename,
struct compat_stat __user *statbuf);
asmlinkage long compat_sys_newfstatat(unsigned int dfd,
const char __user *filename,
struct compat_stat __user *statbuf,
int flag);
asmlinkage long compat_sys_newfstat(unsigned int fd,
struct compat_stat __user *statbuf);
asmlinkage long compat_sys_statfs(const char __user *pathname,
struct compat_statfs __user *buf);
asmlinkage long compat_sys_fstatfs(unsigned int fd,
struct compat_statfs __user *buf);
asmlinkage long compat_sys_statfs64(const char __user *pathname,
compat_size_t sz,
struct compat_statfs64 __user *buf);
asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz,
struct compat_statfs64 __user *buf);
asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
unsigned long arg);
asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd,
unsigned long arg);
asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p);
asmlinkage long compat_sys_io_getevents(aio_context_t ctx_id,
unsigned long min_nr,
unsigned long nr,
struct io_event __user *events,
struct compat_timespec __user *timeout);
asmlinkage long compat_sys_io_submit(aio_context_t ctx_id, int nr,
u32 __user *iocb);
asmlinkage long compat_sys_mount(const char __user *dev_name,
const char __user *dir_name,
const char __user *type, unsigned long flags,
const void __user *data);
asmlinkage long compat_sys_old_readdir(unsigned int fd,
struct compat_old_linux_dirent __user *,
unsigned int count);
asmlinkage long compat_sys_getdents(unsigned int fd,
struct compat_linux_dirent __user *dirent,
unsigned int count);
asmlinkage long compat_sys_getdents64(unsigned int fd,
struct linux_dirent64 __user *dirent,
unsigned int count);
asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *,
unsigned int nr_segs, unsigned int flags);
asmlinkage long compat_sys_open(const char __user *filename, int flags,
int mode);
asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename,
int flags, int mode);
asmlinkage long compat_sys_open_by_handle_at(int mountdirfd,
struct file_handle __user *handle,
int flags);
asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp,
compat_ulong_t __user *outp,
compat_ulong_t __user *exp,
struct compat_timespec __user *tsp,
void __user *sig);
asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
unsigned int nfds,
struct compat_timespec __user *tsp,
const compat_sigset_t __user *sigmask,
compat_size_t sigsetsize);
#if (defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)) && \
!defined(CONFIG_NFSD_DEPRECATED)
union compat_nfsctl_res;
struct compat_nfsctl_arg;
asmlinkage long compat_sys_nfsservctl(int cmd,
struct compat_nfsctl_arg __user *arg,
union compat_nfsctl_res __user *res);
#else
asmlinkage long compat_sys_nfsservctl(int cmd, void *notused, void *notused2);
#endif
asmlinkage long compat_sys_signalfd4(int ufd,
const compat_sigset_t __user *sigmask,
compat_size_t sigsetsize, int flags);
asmlinkage long compat_sys_get_mempolicy(int __user *policy,
compat_ulong_t __user *nmask,
compat_ulong_t maxnode,
compat_ulong_t addr,
compat_ulong_t flags);
asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask,
compat_ulong_t maxnode);
asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len,
compat_ulong_t mode,
compat_ulong_t __user *nmask,
compat_ulong_t maxnode, compat_ulong_t flags);
asmlinkage long compat_sys_setsockopt(int fd, int level, int optname,
char __user *optval, unsigned int optlen);
asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg,
unsigned flags);
asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg,
unsigned int flags);
asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len,
unsigned flags);
asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, size_t len,
unsigned flags, struct sockaddr __user *addr,
int __user *addrlen);
asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
unsigned vlen, unsigned int flags,
struct compat_timespec __user *timeout);
asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp,
struct compat_timespec __user *rmtp);
asmlinkage long compat_sys_getitimer(int which,
struct compat_itimerval __user *it);
asmlinkage long compat_sys_setitimer(int which,
struct compat_itimerval __user *in,
struct compat_itimerval __user *out);
asmlinkage long compat_sys_times(struct compat_tms __user *tbuf);
asmlinkage long compat_sys_setrlimit(unsigned int resource,
struct compat_rlimit __user *rlim);
asmlinkage long compat_sys_getrlimit(unsigned int resource,
struct compat_rlimit __user *rlim);
asmlinkage long compat_sys_getrusage(int who, struct compat_rusage __user *ru);
asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid,
unsigned int len,
compat_ulong_t __user *user_mask_ptr);
asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid,
unsigned int len,
compat_ulong_t __user *user_mask_ptr);
asmlinkage long compat_sys_timer_create(clockid_t which_clock,
struct compat_sigevent __user *timer_event_spec,
timer_t __user *created_timer_id);
asmlinkage long compat_sys_timer_settime(timer_t timer_id, int flags,
struct compat_itimerspec __user *new,
struct compat_itimerspec __user *old);
asmlinkage long compat_sys_timer_gettime(timer_t timer_id,
struct compat_itimerspec __user *setting);
asmlinkage long compat_sys_clock_settime(clockid_t which_clock,
struct compat_timespec __user *tp);
asmlinkage long compat_sys_clock_gettime(clockid_t which_clock,
struct compat_timespec __user *tp);
asmlinkage long compat_sys_clock_adjtime(clockid_t which_clock,
struct compat_timex __user *tp);
asmlinkage long compat_sys_clock_getres(clockid_t which_clock,
struct compat_timespec __user *tp);
asmlinkage long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
struct compat_timespec __user *rqtp,
struct compat_timespec __user *rmtp);
asmlinkage long compat_sys_rt_sigtimedwait(compat_sigset_t __user *uthese,
struct compat_siginfo __user *uinfo,
struct compat_timespec __user *uts, compat_size_t sigsetsize);
asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset,
compat_size_t sigsetsize);
asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
unsigned long arg);
asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
struct compat_timespec __user *utime, u32 __user *uaddr2,
u32 val3);
asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
char __user *optval, int __user *optlen);
asmlinkage long compat_sys_kexec_load(unsigned long entry,
unsigned long nr_segments,
struct compat_kexec_segment __user *,
unsigned long flags);
asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes,
const struct compat_mq_attr __user *u_mqstat,
struct compat_mq_attr __user *u_omqstat);
asmlinkage long compat_sys_mq_notify(mqd_t mqdes,
const struct compat_sigevent __user *u_notification);
asmlinkage long compat_sys_mq_open(const char __user *u_name,
int oflag, compat_mode_t mode,
struct compat_mq_attr __user *u_attr);
asmlinkage long compat_sys_mq_timedsend(mqd_t mqdes,
const char __user *u_msg_ptr,
size_t msg_len, unsigned int msg_prio,
const struct compat_timespec __user *u_abs_timeout);
asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes,
char __user *u_msg_ptr,
size_t msg_len, unsigned int __user *u_msg_prio,
const struct compat_timespec __user *u_abs_timeout);
asmlinkage long compat_sys_socketcall(int call, u32 __user *args);
asmlinkage long compat_sys_sysctl(struct compat_sysctl_args __user *args);
extern ssize_t compat_rw_copy_check_uvector(int type,
const struct compat_iovec __user *uvector, unsigned long nr_segs,
const struct compat_iovec __user *uvector,
unsigned long nr_segs,
unsigned long fast_segs, struct iovec *fast_pointer,
struct iovec **ret_pointer);

View File

@ -293,6 +293,8 @@ asmlinkage long compat_sys_times(struct compat_tms __user *tbuf)
return compat_jiffies_to_clock_t(jiffies);
}
#ifdef __ARCH_WANT_SYS_SIGPENDING
/*
* Assumption: old_sigset_t and compat_old_sigset_t are both
* types that can be passed to put_user()/get_user().
@ -312,6 +314,10 @@ asmlinkage long compat_sys_sigpending(compat_old_sigset_t __user *set)
return ret;
}
#endif
#ifdef __ARCH_WANT_SYS_SIGPROCMASK
asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set,
compat_old_sigset_t __user *oset)
{
@ -333,6 +339,8 @@ asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set,
return ret;
}
#endif
asmlinkage long compat_sys_setrlimit(unsigned int resource,
struct compat_rlimit __user *rlim)
{

View File

@ -1506,7 +1506,7 @@ static struct ctl_table fs_table[] = {
static struct ctl_table debug_table[] = {
#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) || \
defined(CONFIG_S390)
defined(CONFIG_S390) || defined(CONFIG_TILE)
{
.procname = "exception-trace",
.data = &show_unhandled_signals,

View File

@ -36,8 +36,10 @@ int audit_classify_arch(int arch)
int audit_classify_syscall(int abi, unsigned syscall)
{
switch(syscall) {
#ifdef __NR_open
case __NR_open:
return 2;
#endif
#ifdef __NR_openat
case __NR_openat:
return 3;