summaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/Kconfig152
-rw-r--r--arch/sparc64/Makefile1
-rw-r--r--arch/sparc64/defconfig145
-rw-r--r--arch/sparc64/kernel/Makefile17
-rw-r--r--arch/sparc64/kernel/audit.c6
-rw-r--r--arch/sparc64/kernel/binfmt_aout32.c419
-rw-r--r--arch/sparc64/kernel/cpu.c14
-rw-r--r--arch/sparc64/kernel/ds.c17
-rw-r--r--arch/sparc64/kernel/ebus.c1
-rw-r--r--arch/sparc64/kernel/entry.S128
-rw-r--r--arch/sparc64/kernel/entry.h195
-rw-r--r--arch/sparc64/kernel/etrap.S4
-rw-r--r--arch/sparc64/kernel/head.S8
-rw-r--r--arch/sparc64/kernel/hvtramp.S4
-rw-r--r--arch/sparc64/kernel/iommu.c56
-rw-r--r--arch/sparc64/kernel/iommu_common.h18
-rw-r--r--arch/sparc64/kernel/irq.c24
-rw-r--r--arch/sparc64/kernel/isa.c190
-rw-r--r--arch/sparc64/kernel/kprobes.c2
-rw-r--r--arch/sparc64/kernel/mdesc.c30
-rw-r--r--arch/sparc64/kernel/of_device.c18
-rw-r--r--arch/sparc64/kernel/pci.c14
-rw-r--r--arch/sparc64/kernel/pci_fire.c5
-rw-r--r--arch/sparc64/kernel/pci_impl.h4
-rw-r--r--arch/sparc64/kernel/pci_msi.c8
-rw-r--r--arch/sparc64/kernel/pci_psycho.c5
-rw-r--r--arch/sparc64/kernel/pci_sabre.c4
-rw-r--r--arch/sparc64/kernel/pci_schizo.c5
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c25
-rw-r--r--arch/sparc64/kernel/power.c3
-rw-r--r--arch/sparc64/kernel/process.c94
-rw-r--r--arch/sparc64/kernel/prom.c14
-rw-r--r--arch/sparc64/kernel/ptrace.c222
-rw-r--r--arch/sparc64/kernel/rtrap.S21
-rw-r--r--arch/sparc64/kernel/sbus.c3
-rw-r--r--arch/sparc64/kernel/semaphore.c254
-rw-r--r--arch/sparc64/kernel/setup.c8
-rw-r--r--arch/sparc64/kernel/signal.c39
-rw-r--r--arch/sparc64/kernel/signal32.c586
-rw-r--r--arch/sparc64/kernel/smp.c60
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c51
-rw-r--r--arch/sparc64/kernel/stacktrace.c20
-rw-r--r--arch/sparc64/kernel/sun4v_tlb_miss.S16
-rw-r--r--arch/sparc64/kernel/sunos_ioctl32.c275
-rw-r--r--arch/sparc64/kernel/sys_sparc.c56
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c15
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c1359
-rw-r--r--arch/sparc64/kernel/sysfs.c12
-rw-r--r--arch/sparc64/kernel/systbls.S122
-rw-r--r--arch/sparc64/kernel/systbls.h51
-rw-r--r--arch/sparc64/kernel/time.c66
-rw-r--r--arch/sparc64/kernel/trampoline.S192
-rw-r--r--arch/sparc64/kernel/traps.c70
-rw-r--r--arch/sparc64/kernel/tsb.S2
-rw-r--r--arch/sparc64/kernel/ttable.S14
-rw-r--r--arch/sparc64/kernel/winfixup.S12
-rw-r--r--arch/sparc64/mm/fault.c14
-rw-r--r--arch/sparc64/mm/init.c1051
-rw-r--r--arch/sparc64/mm/tlb.c6
-rw-r--r--arch/sparc64/mm/tsb.c3
-rw-r--r--arch/sparc64/mm/ultra.S4
-rw-r--r--arch/sparc64/solaris/Makefile10
-rw-r--r--arch/sparc64/solaris/conv.h38
-rw-r--r--arch/sparc64/solaris/entry64.S223
-rw-r--r--arch/sparc64/solaris/fs.c745
-rw-r--r--arch/sparc64/solaris/ioctl.c825
-rw-r--r--arch/sparc64/solaris/ipc.c126
-rw-r--r--arch/sparc64/solaris/misc.c786
-rw-r--r--arch/sparc64/solaris/signal.c429
-rw-r--r--arch/sparc64/solaris/signal.h108
-rw-r--r--arch/sparc64/solaris/socket.c461
-rw-r--r--arch/sparc64/solaris/socksys.c203
-rw-r--r--arch/sparc64/solaris/socksys.h208
-rw-r--r--arch/sparc64/solaris/systbl.S285
-rw-r--r--arch/sparc64/solaris/timod.c976
75 files changed, 1847 insertions, 9810 deletions
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 3af378ddb6ae..edbe71e3fab9 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -1,26 +1,18 @@
-# $Id: config.in,v 1.158 2002/01/24 22:14:44 davem Exp $
-# For a description of the syntax of this configuration file,
-# see the Configure script.
-#
-
-mainmenu "Linux/UltraSPARC Kernel Configuration"
+# sparc64 configuration
+mainmenu "Linux Kernel Configuration for 64-bit SPARC"
config SPARC
bool
default y
select HAVE_OPROFILE
select HAVE_KPROBES
+ select HAVE_KRETPROBES
config SPARC64
bool
default y
select HAVE_IDE
- help
- SPARC is a family of RISC microprocessors designed and marketed by
- Sun Microsystems, incorporated. This port covers the newer 64-bit
- UltraSPARC. The UltraLinux project maintains both the SPARC32 and
- SPARC64 ports; its web page is available at
- <http://www.ultralinux.org/>.
+ select HAVE_LMB
config GENERIC_TIME
bool
@@ -86,9 +78,6 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
bool
def_bool y
-config ARCH_SUPPORTS_AOUT
- def_bool y
-
choice
prompt "Kernel page size"
default SPARC64_PAGE_SIZE_8KB
@@ -98,7 +87,7 @@ config SPARC64_PAGE_SIZE_8KB
help
This lets you select the page size of the kernel.
- 8KB and 64KB work quite well, since Sparc ELF sections
+ 8KB and 64KB work quite well, since SPARC ELF sections
provide for up to 64KB alignment.
Therefore, 512KB and 4MB are for expert hackers only.
@@ -139,18 +128,13 @@ config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs"
depends on SMP
select HOTPLUG
- ---help---
+ help
Say Y here to experiment with turning CPUs off and on. CPUs
can be controlled through /sys/devices/system/cpu/cpu#.
Say N if you want to disable CPU hotplug.
source "init/Kconfig"
-config SYSVIPC_COMPAT
- bool
- depends on COMPAT && SYSVIPC
- default y
-
config GENERIC_HARDIRQS
bool
default y
@@ -161,23 +145,16 @@ source "kernel/time/Kconfig"
config SMP
bool "Symmetric multi-processing support"
- ---help---
+ help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, say N. If you have a system with more than
one CPU, say Y.
If you say N here, the kernel will run on single and multiprocessor
machines, but will use only one CPU of a multiprocessor machine. If
- you say Y here, the kernel will run on many, but not all,
- singleprocessor machines. On a singleprocessor machine, the kernel
- will run faster if you say N here.
-
- People using multiprocessor machines who say Y here should also say
- Y to "Enhanced Real Time Clock Support", below. The "Advanced Power
- Management" code will be disabled if you say Y here.
-
- See also <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO
- available at <http://www.tldp.org/docs.html#howto>.
+ you say Y here, the kernel will run on single-processor machines.
+ On a single-processor machine, the kernel will run faster if you say
+ N here.
If you don't know what to do here, say N.
@@ -256,6 +233,26 @@ endchoice
endmenu
+config NUMA
+ bool "NUMA support"
+
+config NODES_SHIFT
+ int
+ default "4"
+ depends on NEED_MULTIPLE_NODES
+
+# Some NUMA nodes have memory ranges that span
+# other nodes. Even though a pfn is valid and
+# between a node's start and end pfns, it may not
+# reside on that node. See memmap_init_zone()
+# for details.
+config NODES_SPAN_OTHER_NODES
+ def_bool y
+ depends on NEED_MULTIPLE_NODES
+
+config ARCH_POPULATES_NODE_MAP
+ def_bool y
+
config ARCH_SELECT_MEMORY_MODEL
def_bool y
@@ -270,50 +267,19 @@ source "mm/Kconfig"
config ISA
bool
- help
- Find out whether you have ISA slots on your motherboard. ISA is the
- name of a bus system, i.e. the way the CPU talks to the other stuff
- inside your box. Other bus systems are PCI, EISA, MicroChannel
- (MCA) or VESA. ISA is an older system, now being displaced by PCI;
- newer boards don't support it. If you have ISA, say Y, otherwise N.
config ISAPNP
bool
- help
- Say Y here if you would like support for ISA Plug and Play devices.
- Some information is in <file:Documentation/isapnp.txt>.
-
- To compile this driver as a module, choose M here: the
- module will be called isapnp.
-
- If unsure, say Y.
config EISA
bool
- ---help---
- The Extended Industry Standard Architecture (EISA) bus was
- developed as an open alternative to the IBM MicroChannel bus.
-
- The EISA bus provided some of the features of the IBM MicroChannel
- bus while maintaining backward compatibility with cards made for
- the older ISA bus. The EISA bus saw limited use between 1988 and
- 1995 when it was made obsolete by the PCI bus.
-
- Say Y here if you are building a kernel for an EISA-based machine.
-
- Otherwise, say N.
config MCA
bool
- help
- MicroChannel Architecture is found in some IBM PS/2 machines and
- laptops. It is a bus system similar to PCI or ISA. See
- <file:Documentation/mca.txt> (and especially the web page given
- there) before attempting to build an MCA bus kernel.
config PCMCIA
tristate
- ---help---
+ help
Say Y here if you want to attach PCMCIA- or PC-cards to your Linux
computer. These are credit-card size devices such as network cards,
modems or hard drives often used with laptops computers. There are
@@ -355,10 +321,10 @@ config PCI
bool "PCI support"
select ARCH_SUPPORTS_MSI
help
- Find out whether you have a PCI motherboard. PCI is the name of a
- bus system, i.e. the way the CPU talks to the other stuff inside
- your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
- VESA. If you have PCI, say Y, otherwise N.
+ Find out whether your system includes a PCI bus. PCI is the name of
+ a bus system, i.e. the way the CPU talks to the other stuff inside
+ your box. If you say Y here, the kernel will include drivers and
+ infrastructure code to support PCI bus devices.
config PCI_DOMAINS
def_bool PCI
@@ -378,49 +344,19 @@ config SUN_OPENPROMFS
To compile the /proc/openprom support as a module, choose M here: the
module will be called openpromfs. If unsure, choose M.
-config SPARC32_COMPAT
- bool "Kernel support for Linux/Sparc 32bit binary compatibility"
- help
- This allows you to run 32-bit binaries on your Ultra.
- Everybody wants this; say Y.
+menu "Executable file formats"
+
+source "fs/Kconfig.binfmt"
config COMPAT
bool
- depends on SPARC32_COMPAT
default y
select COMPAT_BINFMT_ELF
-config BINFMT_AOUT32
- bool "Kernel support for 32-bit (ie. SunOS) a.out binaries"
- depends on SPARC32_COMPAT && ARCH_SUPPORTS_AOUT
- help
- This allows you to run 32-bit a.out format binaries on your Ultra.
- If you want to run SunOS binaries (see SunOS binary emulation below)
- or other a.out binaries, say Y. If unsure, say N.
-
-menu "Executable file formats"
-
-source "fs/Kconfig.binfmt"
-
-config SUNOS_EMUL
- bool "SunOS binary emulation"
- depends on BINFMT_AOUT32
- help
- This allows you to run most SunOS binaries. If you want to do this,
- say Y here and place appropriate files in /usr/gnemul/sunos. See
- <http://www.ultralinux.org/faq.html> for more information. If you
- want to run SunOS binaries on an Ultra you must also say Y to
- "Kernel support for 32-bit a.out binaries" above.
-
-config SOLARIS_EMUL
- tristate "Solaris binary emulation (EXPERIMENTAL)"
- depends on SPARC32_COMPAT && NET && EXPERIMENTAL
- help
- This is experimental code which will enable you to run (many)
- Solaris binaries on your SPARC Linux machine.
-
- To compile this code as a module, choose M here: the
- module will be called solaris.
+config SYSVIPC_COMPAT
+ bool
+ depends on COMPAT && SYSVIPC
+ default y
endmenu
@@ -430,8 +366,8 @@ config SCHED_SMT
default y
help
SMT scheduler support improves the CPU scheduler's decision making
- when dealing with UltraSPARC cpus at a cost of slightly increased
- overhead in some places. If unsure say N here.
+ when dealing with SPARC cpus at a cost of slightly increased overhead
+ in some places. If unsure say N here.
config SCHED_MC
bool "Multi-core scheduler support"
diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile
index f0c22f826982..9cb75c852b45 100644
--- a/arch/sparc64/Makefile
+++ b/arch/sparc64/Makefile
@@ -27,7 +27,6 @@ endif
head-y := arch/sparc64/kernel/head.o arch/sparc64/kernel/init_task.o
core-y += arch/sparc64/kernel/ arch/sparc64/mm/
-core-$(CONFIG_SOLARIS_EMUL) += arch/sparc64/solaris/
core-y += arch/sparc64/math-emu/
libs-y += arch/sparc64/prom/ arch/sparc64/lib/
drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 250958d1e3cb..aff93c9d13f4 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25-rc1
-# Sun Feb 17 22:44:12 2008
+# Linux kernel version: 2.6.25
+# Sat Apr 26 03:11:06 2008
#
CONFIG_SPARC=y
CONFIG_SPARC64=y
@@ -22,7 +22,6 @@ CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_ARCH_NO_VIRT_TO_BUS=y
CONFIG_OF=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
CONFIG_SPARC64_PAGE_SIZE_8KB=y
# CONFIG_SPARC64_PAGE_SIZE_64KB is not set
# CONFIG_SPARC64_PAGE_SIZE_512KB is not set
@@ -55,10 +54,13 @@ CONFIG_POSIX_MQUEUE=y
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=18
# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
@@ -98,7 +100,9 @@ CONFIG_PROFILING=y
CONFIG_OPROFILE=m
CONFIG_HAVE_OPROFILE=y
CONFIG_KPROBES=y
+CONFIG_KRETPROBES=y
CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -129,8 +133,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
CONFIG_CLASSIC_RCU=y
-# CONFIG_PREEMPT_RCU is not set
-CONFIG_SYSVIPC_COMPAT=y
CONFIG_GENERIC_HARDIRQS=y
#
@@ -150,6 +152,10 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_HUGETLB_PAGE_SIZE_4MB=y
# CONFIG_HUGETLB_PAGE_SIZE_512K is not set
# CONFIG_HUGETLB_PAGE_SIZE_64K is not set
+CONFIG_NUMA=y
+CONFIG_NODES_SHIFT=4
+CONFIG_NODES_SPAN_OTHER_NODES=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
@@ -158,12 +164,14 @@ CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
+CONFIG_NEED_MULTIPLE_NODES=y
CONFIG_HAVE_MEMORY_PRESENT=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPARSEMEM_VMEMMAP=y
CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
CONFIG_RESOURCES_64BIT=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=1
@@ -180,9 +188,6 @@ CONFIG_PCI_MSI=y
# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
CONFIG_SUN_OPENPROMFS=m
-CONFIG_SPARC32_COMPAT=y
-CONFIG_COMPAT=y
-# CONFIG_BINFMT_AOUT32 is not set
#
# Executable file formats
@@ -190,13 +195,13 @@ CONFIG_COMPAT=y
CONFIG_BINFMT_ELF=y
CONFIG_COMPAT_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m
-CONFIG_SOLARIS_EMUL=y
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
CONFIG_SCHED_SMT=y
CONFIG_SCHED_MC=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
-# CONFIG_RCU_TRACE is not set
# CONFIG_CMDLINE_BOOL is not set
#
@@ -261,8 +266,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
CONFIG_INET6_XFRM_MODE_BEET=m
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
CONFIG_IPV6_TUNNEL=m
# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
CONFIG_IP_DCCP=m
@@ -366,7 +373,7 @@ CONFIG_IDE=y
CONFIG_BLK_DEV_IDE=y
#
-# Please see Documentation/ide.txt for help/info on IDE drives
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_BLK_DEV_IDEDISK=y
@@ -382,7 +389,6 @@ CONFIG_IDE_PROC_FS=y
#
# IDE chipset support/bugfixes
#
-CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_PLATFORM is not set
CONFIG_BLK_DEV_IDEDMA_SFF=y
@@ -420,7 +426,7 @@ CONFIG_BLK_DEV_ALI15X3=y
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_BLK_DEV_TC86C001 is not set
CONFIG_BLK_DEV_IDEDMA=y
-CONFIG_IDE_ARCH_OBSOLETE_INIT=y
+# CONFIG_BLK_DEV_HD_ONLY is not set
# CONFIG_BLK_DEV_HD is not set
#
@@ -482,6 +488,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_MVSAS is not set
# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
@@ -585,7 +592,6 @@ CONFIG_E1000_NAPI=y
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
CONFIG_TIGON3=m
CONFIG_BNX2=m
@@ -610,6 +616,7 @@ CONFIG_NIU=m
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
#
# USB Network Adapters
@@ -742,13 +749,7 @@ CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
# CONFIG_I2C_CHARDEV is not set
-
-#
-# I2C Algorithms
-#
CONFIG_I2C_ALGOBIT=y
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
#
# I2C Hardware Bus support
@@ -776,6 +777,7 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
#
# Miscellaneous I2C Chip support
@@ -785,7 +787,6 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_TPS65010 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -810,6 +811,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -866,6 +868,7 @@ CONFIG_SSB_POSSIBLE=y
# Multifunction device drivers
#
# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
#
# Multimedia devices
@@ -1021,6 +1024,7 @@ CONFIG_SND_ALI5451=m
# CONFIG_SND_AU8810 is not set
# CONFIG_SND_AU8820 is not set
# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AW2 is not set
# CONFIG_SND_AZT3328 is not set
# CONFIG_SND_BT87X is not set
# CONFIG_SND_CA0106 is not set
@@ -1092,10 +1096,6 @@ CONFIG_SND_SUN_CS4231=m
# CONFIG_SND_SOC is not set
#
-# SoC Audio support for SuperH
-#
-
-#
# ALSA SoC audio for Freescale SOCs
#
@@ -1216,10 +1216,6 @@ CONFIG_USB_STORAGE=m
# CONFIG_NEW_LEDS is not set
# CONFIG_INFINIBAND is not set
# CONFIG_RTC_CLASS is not set
-
-#
-# Userspace I/O
-#
# CONFIG_UIO is not set
#
@@ -1396,6 +1392,7 @@ CONFIG_SCHEDSTATS=y
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_BOOT_PRINTK_DELAY is not set
@@ -1422,53 +1419,82 @@ CONFIG_ASYNC_CORE=m
CONFIG_ASYNC_MEMCPY=m
CONFIG_ASYNC_XOR=m
CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_BLKCIPHER=y
-# CONFIG_CRYPTO_SEQIV is not set
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+
+#
+# Hash modes
+#
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=y
-CONFIG_CRYPTO_NULL=m
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_XTS=m
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_SEED=m
# CONFIG_CRYPTO_SALSA20 is not set
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_AUTHENC=m
# CONFIG_CRYPTO_LZO is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
@@ -1489,3 +1515,4 @@ CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index 1bf5b187de49..2bd0340b743d 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -10,31 +10,22 @@ extra-y := head.o init_task.o vmlinux.lds
obj-y := process.o setup.o cpu.o idprom.o \
traps.o auxio.o una_asm.o sysfs.o iommu.o \
irq.o ptrace.o time.o sys_sparc.o signal.o \
- unaligned.o central.o pci.o starfire.o semaphore.o \
+ unaligned.o central.o pci.o starfire.o \
power.o sbus.o sparc64_ksyms.o chmc.o \
visemul.o prom.o of_device.o hvapi.o sstate.o mdesc.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
-obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o \
+obj-$(CONFIG_PCI) += ebus.o pci_common.o \
pci_psycho.o pci_sabre.o pci_schizo.o \
pci_sun4v.o pci_sun4v_asm.o pci_fire.o
obj-$(CONFIG_PCI_MSI) += pci_msi.o
obj-$(CONFIG_SMP) += smp.o trampoline.o hvtramp.o
-obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o
-obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o
+obj-$(CONFIG_COMPAT) += sys32.o sys_sparc32.o signal32.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o
obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_SUN_LDOMS) += ldc.o vio.o viohs.o ds.o
obj-$(CONFIG_AUDIT) += audit.o
-obj-$(CONFIG_AUDIT)$(CONFIG_SPARC32_COMPAT) += compat_audit.o
+obj-$(CONFIG_AUDIT)$(CONFIG_COMPAT) += compat_audit.o
obj-y += $(obj-yy)
-
-ifdef CONFIG_SUNOS_EMUL
- obj-y += sys_sunos32.o sunos_ioctl32.o
-else
- ifdef CONFIG_SOLARIS_EMUL
- obj-y += sys_sunos32.o sunos_ioctl32.o
- endif
-endif
diff --git a/arch/sparc64/kernel/audit.c b/arch/sparc64/kernel/audit.c
index 24d7f4b4178a..8fff0ac63d56 100644
--- a/arch/sparc64/kernel/audit.c
+++ b/arch/sparc64/kernel/audit.c
@@ -30,7 +30,7 @@ static unsigned signal_class[] = {
int audit_classify_arch(int arch)
{
-#ifdef CONFIG_SPARC32_COMPAT
+#ifdef CONFIG_COMPAT
if (arch == AUDIT_ARCH_SPARC)
return 1;
#endif
@@ -39,7 +39,7 @@ int audit_classify_arch(int arch)
int audit_classify_syscall(int abi, unsigned syscall)
{
-#ifdef CONFIG_SPARC32_COMPAT
+#ifdef CONFIG_COMPAT
extern int sparc32_classify_syscall(unsigned);
if (abi == AUDIT_ARCH_SPARC)
return sparc32_classify_syscall(syscall);
@@ -60,7 +60,7 @@ int audit_classify_syscall(int abi, unsigned syscall)
static int __init audit_classes_init(void)
{
-#ifdef CONFIG_SPARC32_COMPAT
+#ifdef CONFIG_COMPAT
extern __u32 sparc32_dir_class[];
extern __u32 sparc32_write_class[];
extern __u32 sparc32_read_class[];
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
deleted file mode 100644
index 9877f2d7672d..000000000000
--- a/arch/sparc64/kernel/binfmt_aout32.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * linux/fs/binfmt_aout.c
- *
- * Copyright (C) 1991, 1992, 1996 Linus Torvalds
- *
- * Hacked a bit by DaveM to make it work with 32-bit SunOS
- * binaries on the sparc64 port.
- */
-
-#include <linux/module.h>
-
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-#include <linux/a.out.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/string.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/stat.h>
-#include <linux/fcntl.h>
-#include <linux/ptrace.h>
-#include <linux/user.h>
-#include <linux/slab.h>
-#include <linux/binfmts.h>
-#include <linux/personality.h>
-#include <linux/init.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
-#include <asm/mmu_context.h>
-#include <asm/a.out-core.h>
-
-static int load_aout32_binary(struct linux_binprm *, struct pt_regs * regs);
-static int load_aout32_library(struct file*);
-static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
-
-static struct linux_binfmt aout32_format = {
- .module = THIS_MODULE,
- .load_binary = load_aout32_binary,
- .load_shlib = load_aout32_library,
- .core_dump = aout32_core_dump,
- .min_coredump = PAGE_SIZE,
-};
-
-static void set_brk(unsigned long start, unsigned long end)
-{
- start = PAGE_ALIGN(start);
- end = PAGE_ALIGN(end);
- if (end <= start)
- return;
- down_write(&current->mm->mmap_sem);
- do_brk(start, end - start);
- up_write(&current->mm->mmap_sem);
-}
-
-/*
- * These are the only things you should do on a core-file: use only these
- * macros to write out all the necessary info.
- */
-
-static int dump_write(struct file *file, const void *addr, int nr)
-{
- return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
-}
-
-#define DUMP_WRITE(addr, nr) \
- if (!dump_write(file, (void *)(addr), (nr))) \
- goto end_coredump;
-
-#define DUMP_SEEK(offset) \
-if (file->f_op->llseek) { \
- if (file->f_op->llseek(file,(offset),0) != (offset)) \
- goto end_coredump; \
-} else file->f_pos = (offset)
-
-/*
- * Routine writes a core dump image in the current directory.
- * Currently only a stub-function.
- *
- * Note that setuid/setgid files won't make a core-dump if the uid/gid
- * changed due to the set[u|g]id. It's enforced by the "current->mm->dumpable"
- * field, which also makes sure the core-dumps won't be recursive if the
- * dumping of the process results in another error..
- */
-
-static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
-{
- mm_segment_t fs;
- int has_dumped = 0;
- unsigned long dump_start, dump_size;
- struct user dump;
-# define START_DATA(u) (u.u_tsize)
-# define START_STACK(u) ((regs->u_regs[UREG_FP]) & ~(PAGE_SIZE - 1))
-
- fs = get_fs();
- set_fs(KERNEL_DS);
- has_dumped = 1;
- current->flags |= PF_DUMPCORE;
- strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm));
- dump.signal = signr;
- aout_dump_thread(regs, &dump);
-
-/* If the size of the dump file exceeds the rlimit, then see what would happen
- if we wrote the stack, but not the data area. */
- if (dump.u_dsize + dump.u_ssize > limit)
- dump.u_dsize = 0;
-
-/* Make sure we have enough room to write the stack and data areas. */
- if (dump.u_ssize > limit)
- dump.u_ssize = 0;
-
-/* make sure we actually have a data and stack area to dump */
- set_fs(USER_DS);
- if (!access_ok(VERIFY_READ, (void __user *) START_DATA(dump), dump.u_dsize))
- dump.u_dsize = 0;
- if (!access_ok(VERIFY_READ, (void __user *) START_STACK(dump), dump.u_ssize))
- dump.u_ssize = 0;
-
- set_fs(KERNEL_DS);
-/* struct user */
- DUMP_WRITE(&dump,sizeof(dump));
-/* now we start writing out the user space info */
- set_fs(USER_DS);
-/* Dump the data area */
- if (dump.u_dsize != 0) {
- dump_start = START_DATA(dump);
- dump_size = dump.u_dsize;
- DUMP_WRITE(dump_start,dump_size);
- }
-/* Now prepare to dump the stack area */
- if (dump.u_ssize != 0) {
- dump_start = START_STACK(dump);
- dump_size = dump.u_ssize;
- DUMP_WRITE(dump_start,dump_size);
- }
-/* Finally dump the task struct. Not be used by gdb, but could be useful */
- set_fs(KERNEL_DS);
- DUMP_WRITE(current,sizeof(*current));
-end_coredump:
- set_fs(fs);
- return has_dumped;
-}
-
-/*
- * create_aout32_tables() parses the env- and arg-strings in new user
- * memory and creates the pointer tables from them, and puts their
- * addresses on the "stack", returning the new stack pointer value.
- */
-
-static u32 __user *create_aout32_tables(char __user *p, struct linux_binprm *bprm)
-{
- u32 __user *argv;
- u32 __user *envp;
- u32 __user *sp;
- int argc = bprm->argc;
- int envc = bprm->envc;
-
- sp = (u32 __user *)((-(unsigned long)sizeof(char *))&(unsigned long)p);
-
- /* This imposes the proper stack alignment for a new process. */
- sp = (u32 __user *) (((unsigned long) sp) & ~7);
- if ((envc+argc+3)&1)
- --sp;
-
- sp -= envc+1;
- envp = sp;
- sp -= argc+1;
- argv = sp;
- put_user(argc,--sp);
- current->mm->arg_start = (unsigned long) p;
- while (argc-->0) {
- char c;
- put_user(((u32)(unsigned long)(p)),argv++);
- do {
- get_user(c,p++);
- } while (c);
- }
- put_user(0,argv);
- current->mm->arg_end = current->mm->env_start = (unsigned long) p;
- while (envc-->0) {
- char c;
- put_user(((u32)(unsigned long)(p)),envp++);
- do {
- get_user(c,p++);
- } while (c);
- }
- put_user(0,envp);
- current->mm->env_end = (unsigned long) p;
- return sp;
-}
-
-/*
- * These are the functions used to load a.out style executables and shared
- * libraries. There is no binary dependent code anywhere else.
- */
-
-static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
-{
- struct exec ex;
- unsigned long error;
- unsigned long fd_offset;
- unsigned long rlim;
- unsigned long orig_thr_flags;
- int retval;
-
- ex = *((struct exec *) bprm->buf); /* exec-header */
- if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC &&
- N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) ||
- N_TRSIZE(ex) || N_DRSIZE(ex) ||
- bprm->file->f_path.dentry->d_inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
- return -ENOEXEC;
- }
-
- fd_offset = N_TXTOFF(ex);
-
- /* Check initial limits. This avoids letting people circumvent
- * size limits imposed on them by creating programs with large
- * arrays in the data or bss.
- */
- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
- if (rlim >= RLIM_INFINITY)
- rlim = ~0;
- if (ex.a_data + ex.a_bss > rlim)
- return -ENOMEM;
-
- /* Flush all traces of the currently running executable */
- retval = flush_old_exec(bprm);
- if (retval)
- return retval;
-
- /* OK, This is the point of no return */
- set_personality(PER_SUNOS);
-
- current->mm->end_code = ex.a_text +
- (current->mm->start_code = N_TXTADDR(ex));
- current->mm->end_data = ex.a_data +
- (current->mm->start_data = N_DATADDR(ex));
- current->mm->brk = ex.a_bss +
- (current->mm->start_brk = N_BSSADDR(ex));
- current->mm->free_area_cache = current->mm->mmap_base;
- current->mm->cached_hole_size = 0;
-
- current->mm->mmap = NULL;
- compute_creds(bprm);
- current->flags &= ~PF_FORKNOEXEC;
- if (N_MAGIC(ex) == NMAGIC) {
- loff_t pos = fd_offset;
- /* Fuck me plenty... */
- down_write(&current->mm->mmap_sem);
- error = do_brk(N_TXTADDR(ex), ex.a_text);
- up_write(&current->mm->mmap_sem);
- bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex),
- ex.a_text, &pos);
- down_write(&current->mm->mmap_sem);
- error = do_brk(N_DATADDR(ex), ex.a_data);
- up_write(&current->mm->mmap_sem);
- bprm->file->f_op->read(bprm->file, (char __user *)N_DATADDR(ex),
- ex.a_data, &pos);
- goto beyond_if;
- }
-
- if (N_MAGIC(ex) == OMAGIC) {
- loff_t pos = fd_offset;
- down_write(&current->mm->mmap_sem);
- do_brk(N_TXTADDR(ex) & PAGE_MASK,
- ex.a_text+ex.a_data + PAGE_SIZE - 1);
- up_write(&current->mm->mmap_sem);
- bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex),
- ex.a_text+ex.a_data, &pos);
- } else {
- static unsigned long error_time;
- if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
- (N_MAGIC(ex) != NMAGIC) && (jiffies-error_time) > 5*HZ)
- {
- printk(KERN_NOTICE "executable not page aligned\n");
- error_time = jiffies;
- }
-
- if (!bprm->file->f_op->mmap) {
- loff_t pos = fd_offset;
- down_write(&current->mm->mmap_sem);
- do_brk(0, ex.a_text+ex.a_data);
- up_write(&current->mm->mmap_sem);
- bprm->file->f_op->read(bprm->file,
- (char __user *)N_TXTADDR(ex),
- ex.a_text+ex.a_data, &pos);
- goto beyond_if;
- }
-
- down_write(&current->mm->mmap_sem);
- error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
- PROT_READ | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
- fd_offset);
- up_write(&current->mm->mmap_sem);
-
- if (error != N_TXTADDR(ex)) {
- send_sig(SIGKILL, current, 0);
- return error;
- }
-
- down_write(&current->mm->mmap_sem);
- error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
- fd_offset + ex.a_text);
- up_write(&current->mm->mmap_sem);
- if (error != N_DATADDR(ex)) {
- send_sig(SIGKILL, current, 0);
- return error;
- }
- }
-beyond_if:
- set_binfmt(&aout32_format);
-
- set_brk(current->mm->start_brk, current->mm->brk);
-
- /* Make sure STACK_TOP returns the right thing. */
- orig_thr_flags = current_thread_info()->flags;
- current_thread_info()->flags |= _TIF_32BIT;
-
- retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
- if (retval < 0) {
- current_thread_info()->flags = orig_thr_flags;
-
- /* Someone check-me: is this error path enough? */
- send_sig(SIGKILL, current, 0);
- return retval;
- }
-
- current->mm->start_stack =
- (unsigned long) create_aout32_tables((char __user *)bprm->p, bprm);
- tsb_context_switch(current->mm);
-
- start_thread32(regs, ex.a_entry, current->mm->start_stack);
- if (current->ptrace & PT_PTRACED)
- send_sig(SIGTRAP, current, 0);
- return 0;
-}
-
-/* N.B. Move to .h file and use code in fs/binfmt_aout.c? */
-static int load_aout32_library(struct file *file)
-{
- struct inode * inode;
- unsigned long bss, start_addr, len;
- unsigned long error;
- int retval;
- struct exec ex;
-
- inode = file->f_path.dentry->d_inode;
-
- retval = -ENOEXEC;
- error = kernel_read(file, 0, (char *) &ex, sizeof(ex));
- if (error != sizeof(ex))
- goto out;
-
- /* We come in here for the regular a.out style of shared libraries */
- if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) ||
- N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
- inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
- goto out;
- }
-
- if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) &&
- (N_TXTOFF(ex) < inode->i_sb->s_blocksize)) {
- printk("N_TXTOFF < BLOCK_SIZE. Please convert library\n");
- goto out;
- }
-
- if (N_FLAGS(ex))
- goto out;
-
- /* For QMAGIC, the starting address is 0x20 into the page. We mask
- this off to get the starting address for the page */
-
- start_addr = ex.a_entry & 0xfffff000;
-
- /* Now use mmap to map the library into memory. */
- down_write(&current->mm->mmap_sem);
- error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
- N_TXTOFF(ex));
- up_write(&current->mm->mmap_sem);
- retval = error;
- if (error != start_addr)
- goto out;
-
- len = PAGE_ALIGN(ex.a_text + ex.a_data);
- bss = ex.a_text + ex.a_data + ex.a_bss;
- if (bss > len) {
- down_write(&current->mm->mmap_sem);
- error = do_brk(start_addr + len, bss - len);
- up_write(&current->mm->mmap_sem);
- retval = error;
- if (error != start_addr + len)
- goto out;
- }
- retval = 0;
-out:
- return retval;
-}
-
-static int __init init_aout32_binfmt(void)
-{
- return register_binfmt(&aout32_format);
-}
-
-static void __exit exit_aout32_binfmt(void)
-{
- unregister_binfmt(&aout32_format);
-}
-
-module_init(init_aout32_binfmt);
-module_exit(exit_aout32_binfmt);
diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c
index e43db73f2b91..0097c08dc600 100644
--- a/arch/sparc64/kernel/cpu.c
+++ b/arch/sparc64/kernel/cpu.c
@@ -15,6 +15,8 @@
#include <asm/spitfire.h>
#include <asm/oplib.h>
+#include "entry.h"
+
DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 };
struct cpu_iu_info {
@@ -30,7 +32,7 @@ struct cpu_fp_info {
char* fp_name;
};
-struct cpu_fp_info linux_sparc_fpu[] = {
+static struct cpu_fp_info linux_sparc_fpu[] = {
{ 0x17, 0x10, 0, "UltraSparc I integrated FPU"},
{ 0x22, 0x10, 0, "UltraSparc I integrated FPU"},
{ 0x17, 0x11, 0, "UltraSparc II integrated FPU"},
@@ -46,7 +48,7 @@ struct cpu_fp_info linux_sparc_fpu[] = {
#define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu)
-struct cpu_iu_info linux_sparc_chips[] = {
+static struct cpu_iu_info linux_sparc_chips[] = {
{ 0x17, 0x10, "TI UltraSparc I (SpitFire)"},
{ 0x22, 0x10, "TI UltraSparc I (SpitFire)"},
{ 0x17, 0x11, "TI UltraSparc II (BlackBird)"},
@@ -65,8 +67,6 @@ struct cpu_iu_info linux_sparc_chips[] = {
char *sparc_cpu_type;
char *sparc_fpu_type;
-unsigned int fsr_storage;
-
static void __init sun4v_cpu_probe(void)
{
switch (sun4v_chip_type) {
@@ -94,8 +94,10 @@ void __init cpu_probe(void)
unsigned long ver, fpu_vers, manuf, impl, fprs;
int i;
- if (tlb_type == hypervisor)
- return sun4v_cpu_probe();
+ if (tlb_type == hypervisor) {
+ sun4v_cpu_probe();
+ return;
+ }
fprs = fprs_read();
fprs_write(FPRS_FEF);
diff --git a/arch/sparc64/kernel/ds.c b/arch/sparc64/kernel/ds.c
index eeb5a2fc788d..edb74f5a1186 100644
--- a/arch/sparc64/kernel/ds.c
+++ b/arch/sparc64/kernel/ds.c
@@ -525,10 +525,10 @@ static void dr_cpu_mark(struct ds_data *resp, int cpu, int ncpus,
}
}
-static int dr_cpu_configure(struct ds_info *dp,
- struct ds_cap_state *cp,
- u64 req_num,
- cpumask_t *mask)
+static int __cpuinit dr_cpu_configure(struct ds_info *dp,
+ struct ds_cap_state *cp,
+ u64 req_num,
+ cpumask_t *mask)
{
struct ds_data *resp;
int resp_len, ncpus, cpu;
@@ -623,9 +623,9 @@ static int dr_cpu_unconfigure(struct ds_info *dp,
return 0;
}
-static void dr_cpu_data(struct ds_info *dp,
- struct ds_cap_state *cp,
- void *buf, int len)
+static void __cpuinit dr_cpu_data(struct ds_info *dp,
+ struct ds_cap_state *cp,
+ void *buf, int len)
{
struct ds_data *data = buf;
struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1);
@@ -972,8 +972,7 @@ static void process_ds_work(void)
LIST_HEAD(todo);
spin_lock_irqsave(&ds_lock, flags);
- list_splice(&ds_work_list, &todo);
- INIT_LIST_HEAD(&ds_work_list);
+ list_splice_init(&ds_work_list, &todo);
spin_unlock_irqrestore(&ds_lock, flags);
list_for_each_entry_safe(qp, tmp, &todo, list) {
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c
index 04ab81cb4f48..bc2632274840 100644
--- a/arch/sparc64/kernel/ebus.c
+++ b/arch/sparc64/kernel/ebus.c
@@ -396,6 +396,7 @@ static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_de
sd->op = &dev->ofdev;
sd->iommu = dev->bus->ofdev.dev.parent->archdata.iommu;
sd->stc = dev->bus->ofdev.dev.parent->archdata.stc;
+ sd->numa_node = dev->bus->ofdev.dev.parent->archdata.numa_node;
dev->ofdev.node = dp;
dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 6be4d2d2904e..fd06e937ae1e 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -47,7 +47,7 @@ do_fpdis:
ba,pt %xcc, etrap
109: or %g7, %lo(109b), %g7
add %g0, %g0, %g0
- ba,a,pt %xcc, rtrap_clr_l6
+ ba,a,pt %xcc, rtrap
1: TRAP_LOAD_THREAD_REG(%g6, %g1)
ldub [%g6 + TI_FPSAVED], %g5
@@ -226,7 +226,7 @@ fp_other_bounce:
call do_fpother
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
- clr %l6
+ nop
.globl do_fpother_check_fitos
.align 32
@@ -489,7 +489,7 @@ utrap_trap: /* %g3=handler,%g4=level */
call bad_trap
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
- clr %l6
+ nop
invoke_utrap:
sllx %g3, 3, %g3
@@ -607,7 +607,7 @@ __spitfire_cee_trap_continue:
call spitfire_access_error
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
- clr %l6
+ nop
/* This is the trap handler entry point for ECC correctable
* errors. They are corrected, but we listen for the trap
@@ -686,7 +686,7 @@ __spitfire_data_access_exception_tl1:
call spitfire_data_access_exception_tl1
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
- clr %l6
+ nop
__spitfire_data_access_exception:
rdpr %pstate, %g4
@@ -705,7 +705,7 @@ __spitfire_data_access_exception:
call spitfire_data_access_exception
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
- clr %l6
+ nop
.globl __spitfire_insn_access_exception
.globl __spitfire_insn_access_exception_tl1
@@ -725,7 +725,7 @@ __spitfire_insn_access_exception_tl1:
call spitfire_insn_access_exception_tl1
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
- clr %l6
+ nop
__spitfire_insn_access_exception:
rdpr %pstate, %g4
@@ -743,7 +743,7 @@ __spitfire_insn_access_exception:
call spitfire_insn_access_exception
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
- clr %l6
+ nop
/* These get patched into the trap table at boot time
* once we know we have a cheetah processor.
@@ -937,7 +937,7 @@ do_dcpe_tl1_fatal:
call cheetah_plus_parity_error
add %sp, PTREGS_OFF, %o1
ba,pt %xcc, rtrap
- clr %l6
+ nop
do_icpe_tl1:
rdpr %tl, %g1 ! Save original trap level
@@ -979,7 +979,7 @@ do_icpe_tl1_fatal:
call cheetah_plus_parity_error
add %sp, PTREGS_OFF, %o1
ba,pt %xcc, rtrap
- clr %l6
+ nop
dcpe_icpe_tl1_common:
/* Flush D-cache, re-enable D/I caches in DCU and finally
@@ -1281,7 +1281,7 @@ __do_privact:
call do_privact
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
- clr %l6
+ nop
.globl do_mna
do_mna:
@@ -1308,7 +1308,7 @@ do_mna:
call mem_address_unaligned
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
- clr %l6
+ nop
.globl do_lddfmna
do_lddfmna:
@@ -1326,7 +1326,7 @@ do_lddfmna:
call handle_lddfmna
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
- clr %l6
+ nop
.globl do_stdfmna
do_stdfmna:
@@ -1344,7 +1344,7 @@ do_stdfmna:
call handle_stdfmna
add %sp, PTREGS_OFF, %o0
ba,pt %xcc, rtrap
- clr %l6
+ nop
.globl breakpoint_trap
breakpoint_trap:
@@ -1353,63 +1353,6 @@ breakpoint_trap:
ba,pt %xcc, rtrap
nop
-#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
- defined(CONFIG_SOLARIS_EMUL_MODULE)
- /* SunOS uses syscall zero as the 'indirect syscall' it looks
- * like indir_syscall(scall_num, arg0, arg1, arg2...); etc.
- * This is complete brain damage.
- */
- .globl sunos_indir
-sunos_indir:
- srl %o0, 0, %o0
- mov %o7, %l4
- cmp %o0, NR_SYSCALLS
- blu,a,pt %icc, 1f
- sll %o0, 0x2, %o0
- sethi %hi(sunos_nosys), %l6
- b,pt %xcc, 2f
- or %l6, %lo(sunos_nosys), %l6
-1: sethi %hi(sunos_sys_table), %l7
- or %l7, %lo(sunos_sys_table), %l7
- lduw [%l7 + %o0], %l6
-2: mov %o1, %o0
- mov %o2, %o1
- mov %o3, %o2
- mov %o4, %o3
- mov %o5, %o4
- call %l6
- mov %l4, %o7
-
- .globl sunos_getpid
-sunos_getpid:
- call sys_getppid
- nop
- call sys_getpid
- stx %o0, [%sp + PTREGS_OFF + PT_V9_I1]
- b,pt %xcc, ret_sys_call
- stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
-
- /* SunOS getuid() returns uid in %o0 and euid in %o1 */
- .globl sunos_getuid
-sunos_getuid:
- call sys32_geteuid16
- nop
- call sys32_getuid16
- stx %o0, [%sp + PTREGS_OFF + PT_V9_I1]
- b,pt %xcc, ret_sys_call
- stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
-
- /* SunOS getgid() returns gid in %o0 and egid in %o1 */
- .globl sunos_getgid
-sunos_getgid:
- call sys32_getegid16
- nop
- call sys32_getgid16
- stx %o0, [%sp + PTREGS_OFF + PT_V9_I1]
- b,pt %xcc, ret_sys_call
- stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
-#endif
-
/* SunOS's execv() call only specifies the argv argument, the
* environment settings are the same as the calling processes.
*/
@@ -1481,13 +1424,13 @@ sys32_rt_sigreturn:
1: ldx [%curptr + TI_FLAGS], %l5
andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
be,pt %icc, rtrap
- clr %l6
+ nop
add %sp, PTREGS_OFF, %o0
call syscall_trace
mov 1, %o1
ba,pt %xcc, rtrap
- clr %l6
+ nop
/* This is how fork() was meant to be done, 8 instruction entry.
*
@@ -1591,7 +1534,7 @@ linux_syscall_trace:
mov %i4, %o4
- /* Linux 32-bit and SunOS system calls enter here... */
+ /* Linux 32-bit system calls enter here... */
.align 32
.globl linux_sparc_syscall32
linux_sparc_syscall32:
@@ -1614,9 +1557,9 @@ linux_sparc_syscall32:
srl %i3, 0, %o3 ! IEU0
ba,a,pt %xcc, 3f
- /* Linux native and SunOS system calls enter here... */
+ /* Linux native system calls enter here... */
.align 32
- .globl linux_sparc_syscall, ret_sys_call
+ .globl linux_sparc_syscall
linux_sparc_syscall:
/* Direct access to user regs, much faster. */
cmp %g1, NR_SYSCALLS ! IEU1 Group
@@ -1662,7 +1605,7 @@ ret_sys_call:
bne,pn %icc, linux_syscall_trace2
add %l1, 0x4, %l2 ! npc = npc+4
stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
- ba,pt %xcc, rtrap_clr_l6
+ ba,pt %xcc, rtrap
stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
1:
@@ -1673,7 +1616,6 @@ ret_sys_call:
sub %g0, %o0, %o0
or %g3, %g2, %g3
stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
- mov 1, %l6
stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
bne,pn %icc, linux_syscall_trace2
add %l1, 0x4, %l2 ! npc = npc+4
@@ -1705,6 +1647,36 @@ __flushw_user:
2: retl
nop
+ /* Flush %fp and %i7 to the stack for all register
+ * windows active inside of the cpu. This allows
+ * show_stack_trace() to avoid using an expensive
+ * 'flushw'.
+ */
+ .globl stack_trace_flush
+ .type stack_trace_flush,#function
+stack_trace_flush:
+ rdpr %pstate, %o0
+ wrpr %o0, PSTATE_IE, %pstate
+
+ rdpr %cwp, %g1
+ rdpr %canrestore, %g2
+ sub %g1, 1, %g3
+
+1: brz,pn %g2, 2f
+ sub %g2, 1, %g2
+ wrpr %g3, %cwp
+ stx %fp, [%sp + STACK_BIAS + RW_V9_I6]
+ stx %i7, [%sp + STACK_BIAS + RW_V9_I7]
+ ba,pt %xcc, 1b
+ sub %g3, 1, %g3
+
+2: wrpr %g1, %cwp
+ wrpr %o0, %pstate
+
+ retl
+ nop
+ .size stack_trace_flush,.-stack_trace_flush
+
#ifdef CONFIG_SMP
.globl hard_smp_processor_id
hard_smp_processor_id:
diff --git a/arch/sparc64/kernel/entry.h b/arch/sparc64/kernel/entry.h
new file mode 100644
index 000000000000..32fbab620852
--- /dev/null
+++ b/arch/sparc64/kernel/entry.h
@@ -0,0 +1,195 @@
+#ifndef _ENTRY_H
+#define _ENTRY_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+
+extern char *sparc_cpu_type;
+extern char *sparc_fpu_type;
+
+extern void __init per_cpu_patch(void);
+extern void __init sun4v_patch(void);
+extern void __init boot_cpu_id_too_large(int cpu);
+extern unsigned int dcache_parity_tl1_occurred;
+extern unsigned int icache_parity_tl1_occurred;
+
+extern asmlinkage void update_perfctrs(void);
+extern asmlinkage void sparc_breakpoint(struct pt_regs *regs);
+extern void timer_interrupt(int irq, struct pt_regs *regs);
+
+extern void do_notify_resume(struct pt_regs *regs,
+ unsigned long orig_i0,
+ unsigned long thread_info_flags);
+
+extern asmlinkage void syscall_trace(struct pt_regs *regs,
+ int syscall_exit_p);
+
+extern void bad_trap_tl1(struct pt_regs *regs, long lvl);
+
+extern void do_fpe_common(struct pt_regs *regs);
+extern void do_fpieee(struct pt_regs *regs);
+extern void do_fpother(struct pt_regs *regs);
+extern void do_tof(struct pt_regs *regs);
+extern void do_div0(struct pt_regs *regs);
+extern void do_illegal_instruction(struct pt_regs *regs);
+extern void mem_address_unaligned(struct pt_regs *regs,
+ unsigned long sfar,
+ unsigned long sfsr);
+extern void sun4v_do_mna(struct pt_regs *regs,
+ unsigned long addr,
+ unsigned long type_ctx);
+extern void do_privop(struct pt_regs *regs);
+extern void do_privact(struct pt_regs *regs);
+extern void do_cee(struct pt_regs *regs);
+extern void do_cee_tl1(struct pt_regs *regs);
+extern void do_dae_tl1(struct pt_regs *regs);
+extern void do_iae_tl1(struct pt_regs *regs);
+extern void do_div0_tl1(struct pt_regs *regs);
+extern void do_fpdis_tl1(struct pt_regs *regs);
+extern void do_fpieee_tl1(struct pt_regs *regs);
+extern void do_fpother_tl1(struct pt_regs *regs);
+extern void do_ill_tl1(struct pt_regs *regs);
+extern void do_irq_tl1(struct pt_regs *regs);
+extern void do_lddfmna_tl1(struct pt_regs *regs);
+extern void do_stdfmna_tl1(struct pt_regs *regs);
+extern void do_paw(struct pt_regs *regs);
+extern void do_paw_tl1(struct pt_regs *regs);
+extern void do_vaw(struct pt_regs *regs);
+extern void do_vaw_tl1(struct pt_regs *regs);
+extern void do_tof_tl1(struct pt_regs *regs);
+extern void do_getpsr(struct pt_regs *regs);
+
+extern void spitfire_insn_access_exception(struct pt_regs *regs,
+ unsigned long sfsr,
+ unsigned long sfar);
+extern void spitfire_insn_access_exception_tl1(struct pt_regs *regs,
+ unsigned long sfsr,
+ unsigned long sfar);
+extern void spitfire_data_access_exception(struct pt_regs *regs,
+ unsigned long sfsr,
+ unsigned long sfar);
+extern void spitfire_data_access_exception_tl1(struct pt_regs *regs,
+ unsigned long sfsr,
+ unsigned long sfar);
+extern void spitfire_access_error(struct pt_regs *regs,
+ unsigned long status_encoded,
+ unsigned long afar);
+
+extern void cheetah_fecc_handler(struct pt_regs *regs,
+ unsigned long afsr,
+ unsigned long afar);
+extern void cheetah_cee_handler(struct pt_regs *regs,
+ unsigned long afsr,
+ unsigned long afar);
+extern void cheetah_deferred_handler(struct pt_regs *regs,
+ unsigned long afsr,
+ unsigned long afar);
+extern void cheetah_plus_parity_error(int type, struct pt_regs *regs);
+
+extern void sun4v_insn_access_exception(struct pt_regs *regs,
+ unsigned long addr,
+ unsigned long type_ctx);
+extern void sun4v_insn_access_exception_tl1(struct pt_regs *regs,
+ unsigned long addr,
+ unsigned long type_ctx);
+extern void sun4v_data_access_exception(struct pt_regs *regs,
+ unsigned long addr,
+ unsigned long type_ctx);
+extern void sun4v_data_access_exception_tl1(struct pt_regs *regs,
+ unsigned long addr,
+ unsigned long type_ctx);
+extern void sun4v_resum_error(struct pt_regs *regs,
+ unsigned long offset);
+extern void sun4v_resum_overflow(struct pt_regs *regs);
+extern void sun4v_nonresum_error(struct pt_regs *regs,
+ unsigned long offset);
+extern void sun4v_nonresum_overflow(struct pt_regs *regs);
+
+extern unsigned long sun4v_err_itlb_vaddr;
+extern unsigned long sun4v_err_itlb_ctx;
+extern unsigned long sun4v_err_itlb_pte;
+extern unsigned long sun4v_err_itlb_error;
+
+extern void sun4v_itlb_error_report(struct pt_regs *regs, int tl);
+
+extern unsigned long sun4v_err_dtlb_vaddr;
+extern unsigned long sun4v_err_dtlb_ctx;
+extern unsigned long sun4v_err_dtlb_pte;
+extern unsigned long sun4v_err_dtlb_error;
+
+extern void sun4v_dtlb_error_report(struct pt_regs *regs, int tl);
+extern void hypervisor_tlbop_error(unsigned long err,
+ unsigned long op);
+extern void hypervisor_tlbop_error_xcall(unsigned long err,
+ unsigned long op);
+
+/* WARNING: The error trap handlers in assembly know the precise
+ * layout of the following structure.
+ *
+ * C-level handlers in traps.c use this information to log the
+ * error and then determine how to recover (if possible).
+ */
+struct cheetah_err_info {
+/*0x00*/u64 afsr;
+/*0x08*/u64 afar;
+
+ /* D-cache state */
+/*0x10*/u64 dcache_data[4]; /* The actual data */
+/*0x30*/u64 dcache_index; /* D-cache index */
+/*0x38*/u64 dcache_tag; /* D-cache tag/valid */
+/*0x40*/u64 dcache_utag; /* D-cache microtag */
+/*0x48*/u64 dcache_stag; /* D-cache snooptag */
+
+ /* I-cache state */
+/*0x50*/u64 icache_data[8]; /* The actual insns + predecode */
+/*0x90*/u64 icache_index; /* I-cache index */
+/*0x98*/u64 icache_tag; /* I-cache phys tag */
+/*0xa0*/u64 icache_utag; /* I-cache microtag */
+/*0xa8*/u64 icache_stag; /* I-cache snooptag */
+/*0xb0*/u64 icache_upper; /* I-cache upper-tag */
+/*0xb8*/u64 icache_lower; /* I-cache lower-tag */
+
+ /* E-cache state */
+/*0xc0*/u64 ecache_data[4]; /* 32 bytes from staging registers */
+/*0xe0*/u64 ecache_index; /* E-cache index */
+/*0xe8*/u64 ecache_tag; /* E-cache tag/state */
+
+/*0xf0*/u64 __pad[32 - 30];
+};
+#define CHAFSR_INVALID ((u64)-1L)
+
+/* This is allocated at boot time based upon the largest hardware
+ * cpu ID in the system. We allocate two entries per cpu, one for
+ * TL==0 logging and one for TL >= 1 logging.
+ */
+extern struct cheetah_err_info *cheetah_error_log;
+
+/* UPA nodes send interrupt packet to UltraSparc with first data reg
+ * value low 5 (7 on Starfire) bits holding the IRQ identifier being
+ * delivered. We must translate this into a non-vector IRQ so we can
+ * set the softint on this cpu.
+ *
+ * To make processing these packets efficient and race free we use
+ * an array of irq buckets below. The interrupt vector handler in
+ * entry.S feeds incoming packets into per-cpu pil-indexed lists.
+ *
+ * If you make changes to ino_bucket, please update hand coded assembler
+ * of the vectored interrupt trap handler(s) in entry.S and sun4v_ivec.S
+ */
+struct ino_bucket {
+/*0x00*/unsigned long __irq_chain_pa;
+
+ /* Virtual interrupt number assigned to this INO. */
+/*0x08*/unsigned int __virt_irq;
+/*0x0c*/unsigned int __pad;
+};
+
+extern struct ino_bucket *ivector_table;
+extern unsigned long ivector_table_pa;
+
+extern void handler_irq(int irq, struct pt_regs *regs);
+extern void init_irqwork_curcpu(void);
+extern void __cpuinit sun4v_register_mondo_queues(int this_cpu);
+
+#endif /* _ENTRY_H */
diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S
index 4b2bf9eb447a..b49d3b60bc0c 100644
--- a/arch/sparc64/kernel/etrap.S
+++ b/arch/sparc64/kernel/etrap.S
@@ -53,7 +53,11 @@ etrap_irq:
stx %g3, [%g2 + STACKFRAME_SZ + PT_V9_TPC]
rd %y, %g3
stx %g1, [%g2 + STACKFRAME_SZ + PT_V9_TNPC]
+ rdpr %tt, %g1
st %g3, [%g2 + STACKFRAME_SZ + PT_V9_Y]
+ sethi %hi(PT_REGS_MAGIC), %g3
+ or %g3, %g1, %g1
+ st %g1, [%g2 + STACKFRAME_SZ + PT_V9_MAGIC]
rdpr %cansave, %g1
brnz,pt %g1, etrap_save
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index 44b105c04dd3..34f8ff57c56b 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -288,8 +288,12 @@ sun4v_chip_type:
/* Leave arg2 as-is, prom_mmu_ihandle_cache */
mov -1, %l3
stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: mode (-1 default)
- sethi %hi(8 * 1024 * 1024), %l3
- stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4: size (8MB)
+ /* 4MB align the kernel image size. */
+ set (_end - KERNBASE), %l3
+ set ((4 * 1024 * 1024) - 1), %l4
+ add %l3, %l4, %l3
+ andn %l3, %l4, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4: roundup(ksize, 4MB)
sethi %hi(KERNBASE), %l3
stx %l3, [%sp + 2047 + 128 + 0x38] ! arg5: vaddr (KERNBASE)
stx %g0, [%sp + 2047 + 128 + 0x40] ! arg6: empty
diff --git a/arch/sparc64/kernel/hvtramp.S b/arch/sparc64/kernel/hvtramp.S
index b692e044a463..0236c43772fa 100644
--- a/arch/sparc64/kernel/hvtramp.S
+++ b/arch/sparc64/kernel/hvtramp.S
@@ -3,6 +3,8 @@
* Copyright (C) 2007 David S. Miller <davem@davemloft.net>
*/
+#include <linux/init.h>
+
#include <asm/thread_info.h>
#include <asm/hypervisor.h>
#include <asm/scratchpad.h>
@@ -13,7 +15,7 @@
#include <asm/head.h>
#include <asm/asi.h>
- .text
+ __CPUINIT
.align 8
.globl hv_cpu_startup, hv_cpu_startup_end
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index 0e347ff812a3..2a37a6ca2a16 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -134,7 +134,8 @@ unsigned long iommu_range_alloc(struct device *dev,
else
boundary_size = ALIGN(1UL << 32, 1 << IO_PAGE_SHIFT);
- n = iommu_area_alloc(arena->map, limit, start, npages, 0,
+ n = iommu_area_alloc(arena->map, limit, start, npages,
+ iommu->page_table_map_base >> IO_PAGE_SHIFT,
boundary_size >> IO_PAGE_SHIFT, 0);
if (n == -1) {
if (likely(pass < 1)) {
@@ -172,9 +173,11 @@ void iommu_range_free(struct iommu *iommu, dma_addr_t dma_addr, unsigned long np
}
int iommu_table_init(struct iommu *iommu, int tsbsize,
- u32 dma_offset, u32 dma_addr_mask)
+ u32 dma_offset, u32 dma_addr_mask,
+ int numa_node)
{
- unsigned long i, tsbbase, order, sz, num_tsb_entries;
+ unsigned long i, order, sz, num_tsb_entries;
+ struct page *page;
num_tsb_entries = tsbsize / sizeof(iopte_t);
@@ -187,11 +190,12 @@ int iommu_table_init(struct iommu *iommu, int tsbsize,
/* Allocate and initialize the free area map. */
sz = num_tsb_entries / 8;
sz = (sz + 7UL) & ~7UL;
- iommu->arena.map = kzalloc(sz, GFP_KERNEL);
+ iommu->arena.map = kmalloc_node(sz, GFP_KERNEL, numa_node);
if (!iommu->arena.map) {
printk(KERN_ERR "IOMMU: Error, kmalloc(arena.map) failed.\n");
return -ENOMEM;
}
+ memset(iommu->arena.map, 0, sz);
iommu->arena.limit = num_tsb_entries;
if (tlb_type != hypervisor)
@@ -200,21 +204,23 @@ int iommu_table_init(struct iommu *iommu, int tsbsize,
/* Allocate and initialize the dummy page which we
* set inactive IO PTEs to point to.
*/
- iommu->dummy_page = get_zeroed_page(GFP_KERNEL);
- if (!iommu->dummy_page) {
+ page = alloc_pages_node(numa_node, GFP_KERNEL, 0);
+ if (!page) {
printk(KERN_ERR "IOMMU: Error, gfp(dummy_page) failed.\n");
goto out_free_map;
}
+ iommu->dummy_page = (unsigned long) page_address(page);
+ memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
/* Now allocate and setup the IOMMU page table itself. */
order = get_order(tsbsize);
- tsbbase = __get_free_pages(GFP_KERNEL, order);
- if (!tsbbase) {
+ page = alloc_pages_node(numa_node, GFP_KERNEL, order);
+ if (!page) {
printk(KERN_ERR "IOMMU: Error, gfp(tsb) failed.\n");
goto out_free_dummy_page;
}
- iommu->page_table = (iopte_t *)tsbbase;
+ iommu->page_table = (iopte_t *)page_address(page);
for (i = 0; i < num_tsb_entries; i++)
iopte_make_dummy(iommu, &iommu->page_table[i]);
@@ -275,20 +281,24 @@ static inline void iommu_free_ctx(struct iommu *iommu, int ctx)
static void *dma_4u_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_addrp, gfp_t gfp)
{
+ unsigned long flags, order, first_page;
struct iommu *iommu;
+ struct page *page;
+ int npages, nid;
iopte_t *iopte;
- unsigned long flags, order, first_page;
void *ret;
- int npages;
size = IO_PAGE_ALIGN(size);
order = get_order(size);
if (order >= 10)
return NULL;
- first_page = __get_free_pages(gfp, order);
- if (first_page == 0UL)
+ nid = dev->archdata.numa_node;
+ page = alloc_pages_node(nid, gfp, order);
+ if (unlikely(!page))
return NULL;
+
+ first_page = (unsigned long) page_address(page);
memset((char *)first_page, 0, PAGE_SIZE << order);
iommu = dev->archdata.iommu;
@@ -515,9 +525,11 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
unsigned long flags, handle, prot, ctx;
dma_addr_t dma_next = 0, dma_addr;
unsigned int max_seg_size;
+ unsigned long seg_boundary_size;
int outcount, incount, i;
struct strbuf *strbuf;
struct iommu *iommu;
+ unsigned long base_shift;
BUG_ON(direction == DMA_NONE);
@@ -548,8 +560,11 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
outs->dma_length = 0;
max_seg_size = dma_get_max_seg_size(dev);
+ seg_boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
+ IO_PAGE_SIZE) >> IO_PAGE_SHIFT;
+ base_shift = iommu->page_table_map_base >> IO_PAGE_SHIFT;
for_each_sg(sglist, s, nelems, i) {
- unsigned long paddr, npages, entry, slen;
+ unsigned long paddr, npages, entry, out_entry = 0, slen;
iopte_t *base;
slen = s->length;
@@ -592,7 +607,9 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
* - allocated dma_addr isn't contiguous to previous allocation
*/
if ((dma_addr != dma_next) ||
- (outs->dma_length + s->length > max_seg_size)) {
+ (outs->dma_length + s->length > max_seg_size) ||
+ (is_span_boundary(out_entry, base_shift,
+ seg_boundary_size, outs, s))) {
/* Can't merge: create a new segment */
segstart = s;
outcount++;
@@ -606,6 +623,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
/* This is a new segment, fill entries */
outs->dma_address = dma_addr;
outs->dma_length = slen;
+ out_entry = entry;
}
/* Calculate next page pointer for contiguous check */
@@ -625,7 +643,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
iommu_map_failed:
for_each_sg(sglist, s, nelems, i) {
if (s->dma_length != 0) {
- unsigned long vaddr, npages, entry, i;
+ unsigned long vaddr, npages, entry, j;
iopte_t *base;
vaddr = s->dma_address & IO_PAGE_MASK;
@@ -636,8 +654,8 @@ iommu_map_failed:
>> IO_PAGE_SHIFT;
base = iommu->page_table + entry;
- for (i = 0; i < npages; i++)
- iopte_make_dummy(iommu, base + i);
+ for (j = 0; j < npages; j++)
+ iopte_make_dummy(iommu, base + j);
s->dma_address = DMA_ERROR_CODE;
s->dma_length = 0;
@@ -802,7 +820,7 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev,
spin_unlock_irqrestore(&iommu->lock, flags);
}
-const struct dma_ops sun4u_dma_ops = {
+static const struct dma_ops sun4u_dma_ops = {
.alloc_coherent = dma_4u_alloc_coherent,
.free_coherent = dma_4u_free_coherent,
.map_single = dma_4u_map_single,
diff --git a/arch/sparc64/kernel/iommu_common.h b/arch/sparc64/kernel/iommu_common.h
index 0713bd58499c..f3575a614fa2 100644
--- a/arch/sparc64/kernel/iommu_common.h
+++ b/arch/sparc64/kernel/iommu_common.h
@@ -12,6 +12,7 @@
#include <linux/mm.h>
#include <linux/scatterlist.h>
#include <linux/device.h>
+#include <linux/iommu-helper.h>
#include <asm/iommu.h>
#include <asm/scatterlist.h>
@@ -45,17 +46,16 @@ static inline unsigned long iommu_num_pages(unsigned long vaddr,
return npages;
}
-static inline unsigned long calc_npages(struct scatterlist *sglist, int nelems)
+static inline int is_span_boundary(unsigned long entry,
+ unsigned long shift,
+ unsigned long boundary_size,
+ struct scatterlist *outs,
+ struct scatterlist *sg)
{
- unsigned long i, npages = 0;
- struct scatterlist *sg;
+ unsigned long paddr = SG_ENT_PHYS_ADDRESS(outs);
+ int nr = iommu_num_pages(paddr, outs->dma_length + sg->length);
- for_each_sg(sglist, sg, nelems, i) {
- unsigned long paddr = SG_ENT_PHYS_ADDRESS(sg);
- npages += iommu_num_pages(paddr, sg->length);
- }
-
- return npages;
+ return iommu_is_span_boundary(entry, nr, shift, boundary_size);
}
extern unsigned long iommu_range_alloc(struct device *dev,
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 5ec06c8c7fea..b441a26b73b0 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -1,6 +1,6 @@
/* irq.c: UltraSparc IRQ handling/init/registry.
*
- * Copyright (C) 1997, 2007 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1997, 2007, 2008 David S. Miller (davem@davemloft.net)
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
* Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
*/
@@ -44,27 +44,10 @@
#include <asm/hypervisor.h>
#include <asm/cacheflush.h>
-/* UPA nodes send interrupt packet to UltraSparc with first data reg
- * value low 5 (7 on Starfire) bits holding the IRQ identifier being
- * delivered. We must translate this into a non-vector IRQ so we can
- * set the softint on this cpu.
- *
- * To make processing these packets efficient and race free we use
- * an array of irq buckets below. The interrupt vector handler in
- * entry.S feeds incoming packets into per-cpu pil-indexed lists.
- *
- * If you make changes to ino_bucket, please update hand coded assembler
- * of the vectored interrupt trap handler(s) in entry.S and sun4v_ivec.S
- */
-struct ino_bucket {
-/*0x00*/unsigned long __irq_chain_pa;
-
- /* Virtual interrupt number assigned to this INO. */
-/*0x08*/unsigned int __virt_irq;
-/*0x0c*/unsigned int __pad;
-};
+#include "entry.h"
#define NUM_IVECS (IMAP_INR + 1)
+
struct ino_bucket *ivector_table;
unsigned long ivector_table_pa;
@@ -325,6 +308,7 @@ static void sun4u_irq_enable(unsigned int virt_irq)
IMAP_AID_SAFARI | IMAP_NID_SAFARI);
val |= tid | IMAP_VALID;
upa_writeq(val, imap);
+ upa_writeq(ICLR_IDLE, data->iclr);
}
}
diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c
deleted file mode 100644
index b5f7b354084f..000000000000
--- a/arch/sparc64/kernel/isa.c
+++ /dev/null
@@ -1,190 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <asm/oplib.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
-#include <asm/isa.h>
-
-struct sparc_isa_bridge *isa_chain;
-
-static void __init fatal_err(const char *reason)
-{
- prom_printf("ISA: fatal error, %s.\n", reason);
-}
-
-static void __init report_dev(struct sparc_isa_device *isa_dev, int child)
-{
- if (child)
- printk(" (%s)", isa_dev->prom_node->name);
- else
- printk(" [%s", isa_dev->prom_node->name);
-}
-
-static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev)
-{
- struct of_device *op = of_find_device_by_node(isa_dev->prom_node);
-
- memcpy(&isa_dev->resource, &op->resource[0], sizeof(struct resource));
-}
-
-static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev)
-{
- struct of_device *op = of_find_device_by_node(isa_dev->prom_node);
-
- if (!op || !op->num_irqs) {
- isa_dev->irq = PCI_IRQ_NONE;
- } else {
- isa_dev->irq = op->irqs[0];
- }
-}
-
-static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
-{
- struct device_node *dp = parent_isa_dev->prom_node->child;
-
- if (!dp)
- return;
-
- printk(" ->");
- while (dp) {
- struct sparc_isa_device *isa_dev;
-
- isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL);
- if (!isa_dev) {
- fatal_err("cannot allocate child isa_dev");
- prom_halt();
- }
-
- /* Link it in to parent. */
- isa_dev->next = parent_isa_dev->child;
- parent_isa_dev->child = isa_dev;
-
- isa_dev->bus = parent_isa_dev->bus;
- isa_dev->prom_node = dp;
-
- isa_dev_get_resource(isa_dev);
- isa_dev_get_irq(isa_dev);
-
- report_dev(isa_dev, 1);
-
- dp = dp->sibling;
- }
-}
-
-static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
-{
- struct device_node *dp = isa_br->prom_node->child;
-
- while (dp) {
- struct sparc_isa_device *isa_dev;
- struct dev_archdata *sd;
-
- isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL);
- if (!isa_dev) {
- printk(KERN_DEBUG "ISA: cannot allocate isa_dev");
- return;
- }
-
- sd = &isa_dev->ofdev.dev.archdata;
- sd->prom_node = dp;
- sd->op = &isa_dev->ofdev;
- sd->iommu = isa_br->ofdev.dev.parent->archdata.iommu;
- sd->stc = isa_br->ofdev.dev.parent->archdata.stc;
-
- isa_dev->ofdev.node = dp;
- isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev;
- isa_dev->ofdev.dev.bus = &isa_bus_type;
- sprintf(isa_dev->ofdev.dev.bus_id, "isa[%08x]", dp->node);
-
- /* Register with core */
- if (of_device_register(&isa_dev->ofdev) != 0) {
- printk(KERN_DEBUG "isa: device registration error for %s!\n",
- dp->path_component_name);
- kfree(isa_dev);
- goto next_sibling;
- }
-
- /* Link it in. */
- isa_dev->next = NULL;
- if (isa_br->devices == NULL) {
- isa_br->devices = isa_dev;
- } else {
- struct sparc_isa_device *tmp = isa_br->devices;
-
- while (tmp->next)
- tmp = tmp->next;
-
- tmp->next = isa_dev;
- }
-
- isa_dev->bus = isa_br;
- isa_dev->prom_node = dp;
-
- isa_dev_get_resource(isa_dev);
- isa_dev_get_irq(isa_dev);
-
- report_dev(isa_dev, 0);
-
- isa_fill_children(isa_dev);
-
- printk("]");
-
- next_sibling:
- dp = dp->sibling;
- }
-}
-
-void __init isa_init(void)
-{
- struct pci_dev *pdev;
- unsigned short vendor, device;
- int index = 0;
-
- vendor = PCI_VENDOR_ID_AL;
- device = PCI_DEVICE_ID_AL_M1533;
-
- pdev = NULL;
- while ((pdev = pci_get_device(vendor, device, pdev)) != NULL) {
- struct sparc_isa_bridge *isa_br;
- struct device_node *dp;
-
- dp = pci_device_to_OF_node(pdev);
-
- isa_br = kzalloc(sizeof(*isa_br), GFP_KERNEL);
- if (!isa_br) {
- printk(KERN_DEBUG "isa: cannot allocate sparc_isa_bridge");
- pci_dev_put(pdev);
- return;
- }
-
- isa_br->ofdev.node = dp;
- isa_br->ofdev.dev.parent = &pdev->dev;
- isa_br->ofdev.dev.bus = &isa_bus_type;
- sprintf(isa_br->ofdev.dev.bus_id, "isa%d", index);
-
- /* Register with core */
- if (of_device_register(&isa_br->ofdev) != 0) {
- printk(KERN_DEBUG "isa: device registration error for %s!\n",
- dp->path_component_name);
- kfree(isa_br);
- pci_dev_put(pdev);
- return;
- }
-
- /* Link it in. */
- isa_br->next = isa_chain;
- isa_chain = isa_br;
-
- isa_br->self = pdev;
- isa_br->index = index++;
- isa_br->prom_node = dp;
-
- printk("isa%d:", isa_br->index);
-
- isa_fill_devices(isa_br);
-
- printk("\n");
- }
-}
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index 34fc3ddd5002..f43b5d755354 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -465,8 +465,6 @@ void __kprobes jprobe_return(void)
extern void jprobe_return_trap_instruction(void);
-extern void __show_regs(struct pt_regs * regs);
-
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
{
u32 *addr = (u32 *) regs->tpc;
diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c
index 856659bb1311..dde52bcf5c64 100644
--- a/arch/sparc64/kernel/mdesc.c
+++ b/arch/sparc64/kernel/mdesc.c
@@ -1,10 +1,10 @@
/* mdesc.c: Sun4V machine description handling.
*
- * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
*/
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/bootmem.h>
+#include <linux/lmb.h>
#include <linux/log2.h>
#include <linux/list.h>
#include <linux/slab.h>
@@ -84,24 +84,28 @@ static void mdesc_handle_init(struct mdesc_handle *hp,
hp->handle_size = handle_size;
}
-static struct mdesc_handle * __init mdesc_bootmem_alloc(unsigned int mdesc_size)
+static struct mdesc_handle * __init mdesc_lmb_alloc(unsigned int mdesc_size)
{
- struct mdesc_handle *hp;
unsigned int handle_size, alloc_size;
+ struct mdesc_handle *hp;
+ unsigned long paddr;
handle_size = (sizeof(struct mdesc_handle) -
sizeof(struct mdesc_hdr) +
mdesc_size);
alloc_size = PAGE_ALIGN(handle_size);
- hp = __alloc_bootmem(alloc_size, PAGE_SIZE, 0UL);
- if (hp)
- mdesc_handle_init(hp, handle_size, hp);
+ paddr = lmb_alloc(alloc_size, PAGE_SIZE);
+ hp = NULL;
+ if (paddr) {
+ hp = __va(paddr);
+ mdesc_handle_init(hp, handle_size, hp);
+ }
return hp;
}
-static void mdesc_bootmem_free(struct mdesc_handle *hp)
+static void mdesc_lmb_free(struct mdesc_handle *hp)
{
unsigned int alloc_size, handle_size = hp->handle_size;
unsigned long start, end;
@@ -124,9 +128,9 @@ static void mdesc_bootmem_free(struct mdesc_handle *hp)
}
}
-static struct mdesc_mem_ops bootmem_mdesc_ops = {
- .alloc = mdesc_bootmem_alloc,
- .free = mdesc_bootmem_free,
+static struct mdesc_mem_ops lmb_mdesc_ops = {
+ .alloc = mdesc_lmb_alloc,
+ .free = mdesc_lmb_free,
};
static struct mdesc_handle *mdesc_kmalloc(unsigned int mdesc_size)
@@ -758,7 +762,7 @@ static void __devinit get_mondo_data(struct mdesc_handle *hp, u64 mp,
get_one_mondo_bits(val, &tb->nonresum_qmask, 2);
}
-void __devinit mdesc_fill_in_cpu_data(cpumask_t mask)
+void __cpuinit mdesc_fill_in_cpu_data(cpumask_t mask)
{
struct mdesc_handle *hp = mdesc_grab();
u64 mp;
@@ -888,7 +892,7 @@ void __init sun4v_mdesc_init(void)
printk("MDESC: Size is %lu bytes.\n", len);
- hp = mdesc_alloc(len, &bootmem_mdesc_ops);
+ hp = mdesc_alloc(len, &lmb_mdesc_ops);
if (hp == NULL) {
prom_printf("MDESC: alloc of %lu bytes failed.\n", len);
prom_halt();
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index 0fd9db95b896..d569f60c24b8 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -6,6 +6,7 @@
#include <linux/mod_devicetable.h>
#include <linux/slab.h>
#include <linux/errno.h>
+#include <linux/irq.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
@@ -411,12 +412,6 @@ static int __init build_one_resource(struct device_node *parent,
static int __init use_1to1_mapping(struct device_node *pp)
{
- /* If this is on the PMU bus, don't try to translate it even
- * if a ranges property exists.
- */
- if (!strcmp(pp->name, "pmu"))
- return 1;
-
/* If we have a ranges property in the parent, use it. */
if (of_find_property(pp, "ranges", NULL) != NULL)
return 0;
@@ -660,6 +655,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op,
struct device_node *dp = op->node;
struct device_node *pp, *ip;
unsigned int orig_irq = irq;
+ int nid;
if (irq == 0xffffffff)
return irq;
@@ -672,7 +668,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op,
printk("%s: direct translate %x --> %x\n",
dp->full_name, orig_irq, irq);
- return irq;
+ goto out;
}
/* Something more complicated. Walk up to the root, applying
@@ -744,6 +740,14 @@ static unsigned int __init build_one_device_irq(struct of_device *op,
printk("%s: Apply IRQ trans [%s] %x --> %x\n",
op->node->full_name, ip->full_name, orig_irq, irq);
+out:
+ nid = of_node_to_nid(dp);
+ if (nid != -1) {
+ cpumask_t numa_mask = node_to_cpumask(nid);
+
+ irq_set_affinity(irq, numa_mask);
+ }
+
return irq;
}
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 545356b00e2e..dbf2fc2f4d87 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -23,7 +23,6 @@
#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/ebus.h>
-#include <asm/isa.h>
#include <asm/prom.h>
#include <asm/apb.h>
@@ -369,10 +368,12 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
sd->host_controller = pbm;
sd->prom_node = node;
sd->op = of_find_device_by_node(node);
+ sd->numa_node = pbm->numa_node;
sd = &sd->op->dev.archdata;
sd->iommu = pbm->iommu;
sd->stc = &pbm->stc;
+ sd->numa_node = pbm->numa_node;
type = of_get_property(node, "device_type", NULL);
if (type == NULL)
@@ -883,7 +884,6 @@ static int __init pcibios_init(void)
pci_scan_each_controller_bus();
- isa_init();
ebus_init();
power_init();
@@ -1159,6 +1159,16 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
return 0;
}
+#ifdef CONFIG_NUMA
+int pcibus_to_node(struct pci_bus *pbus)
+{
+ struct pci_pbm_info *pbm = pbus->sysdata;
+
+ return pbm->numa_node;
+}
+EXPORT_SYMBOL(pcibus_to_node);
+#endif
+
/* Return the domain nuber for this pci bus */
int pci_domain_nr(struct pci_bus *pbus)
diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c
index 7571ed563147..d23bb6f53cda 100644
--- a/arch/sparc64/kernel/pci_fire.c
+++ b/arch/sparc64/kernel/pci_fire.c
@@ -71,7 +71,8 @@ static int pci_fire_pbm_iommu_init(struct pci_pbm_info *pbm)
*/
fire_write(iommu->iommu_flushinv, ~(u64)0);
- err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask);
+ err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask,
+ pbm->numa_node);
if (err)
return err;
@@ -449,6 +450,8 @@ static int __init pci_fire_pbm_init(struct pci_controller_info *p,
pbm->next = pci_pbm_root;
pci_pbm_root = pbm;
+ pbm->numa_node = -1;
+
pbm->scan_bus = pci_fire_scan_bus;
pbm->pci_ops = &sun4u_pci_ops;
pbm->config_space_reg_bits = 12;
diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h
index 4a50da13ce48..218bac4ff79b 100644
--- a/arch/sparc64/kernel/pci_impl.h
+++ b/arch/sparc64/kernel/pci_impl.h
@@ -148,6 +148,8 @@ struct pci_pbm_info {
struct pci_bus *pci_bus;
void (*scan_bus)(struct pci_pbm_info *);
struct pci_ops *pci_ops;
+
+ int numa_node;
};
struct pci_controller_info {
@@ -161,8 +163,6 @@ extern struct pci_pbm_info *pci_pbm_root;
extern int pci_num_pbms;
/* PCI bus scanning and fixup support. */
-extern void pci_iommu_table_init(struct iommu *iommu, int tsbsize,
- u32 dma_offset, u32 dma_addr_mask);
extern void pci_get_pbm_props(struct pci_pbm_info *pbm);
extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm);
extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm);
diff --git a/arch/sparc64/kernel/pci_msi.c b/arch/sparc64/kernel/pci_msi.c
index d6d64b44af63..db5e8fd8f674 100644
--- a/arch/sparc64/kernel/pci_msi.c
+++ b/arch/sparc64/kernel/pci_msi.c
@@ -279,11 +279,17 @@ static int bringup_one_msi_queue(struct pci_pbm_info *pbm,
unsigned long devino)
{
int irq = ops->msiq_build_irq(pbm, msiqid, devino);
- int err;
+ int err, nid;
if (irq < 0)
return irq;
+ nid = pbm->numa_node;
+ if (nid != -1) {
+ cpumask_t numa_mask = node_to_cpumask(nid);
+
+ irq_set_affinity(irq, numa_mask);
+ }
err = request_irq(irq, sparc64_msiq_interrupt, 0,
"MSIQ",
&pbm->msiq_irq_cookies[msiqid - pbm->msiq_first]);
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 0bad96e5d184..994dbe0603da 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -848,7 +848,8 @@ static int psycho_iommu_init(struct pci_pbm_info *pbm)
/* Leave diag mode enabled for full-flushing done
* in pci_iommu.c
*/
- err = iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff);
+ err = iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff,
+ pbm->numa_node);
if (err)
return err;
@@ -979,6 +980,8 @@ static void __init psycho_pbm_init(struct pci_controller_info *p,
pbm->next = pci_pbm_root;
pci_pbm_root = pbm;
+ pbm->numa_node = -1;
+
pbm->scan_bus = psycho_scan_bus;
pbm->pci_ops = &sun4u_pci_ops;
pbm->config_space_reg_bits = 8;
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index 1c5f5fa2339f..4c34195baf37 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -704,7 +704,7 @@ static int sabre_iommu_init(struct pci_pbm_info *pbm,
* in pci_iommu.c
*/
err = iommu_table_init(iommu, tsbsize * 1024 * 8,
- dvma_offset, dma_mask);
+ dvma_offset, dma_mask, pbm->numa_node);
if (err)
return err;
@@ -737,6 +737,8 @@ static void __init sabre_pbm_init(struct pci_controller_info *p,
pbm->name = dp->full_name;
printk("%s: SABRE PCI Bus Module\n", pbm->name);
+ pbm->numa_node = -1;
+
pbm->scan_bus = sabre_scan_bus;
pbm->pci_ops = &sun4u_pci_ops;
pbm->config_space_reg_bits = 8;
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index e30609362322..615edd9c8e2a 100644
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -1220,7 +1220,8 @@ static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
/* Leave diag mode enabled for full-flushing done
* in pci_iommu.c
*/
- err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask);
+ err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask,
+ pbm->numa_node);
if (err)
return err;
@@ -1379,6 +1380,8 @@ static int __init schizo_pbm_init(struct pci_controller_info *p,
pbm->next = pci_pbm_root;
pci_pbm_root = pbm;
+ pbm->numa_node = -1;
+
pbm->scan_bus = schizo_scan_bus;
pbm->pci_ops = &sun4u_pci_ops;
pbm->config_space_reg_bits = 8;
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index ddca6c6c0b49..e2bb9790039c 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -127,10 +127,12 @@ static inline long iommu_batch_end(void)
static void *dma_4v_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_addrp, gfp_t gfp)
{
- struct iommu *iommu;
unsigned long flags, order, first_page, npages, n;
+ struct iommu *iommu;
+ struct page *page;
void *ret;
long entry;
+ int nid;
size = IO_PAGE_ALIGN(size);
order = get_order(size);
@@ -139,10 +141,12 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size,
npages = size >> IO_PAGE_SHIFT;
- first_page = __get_free_pages(gfp, order);
- if (unlikely(first_page == 0UL))
+ nid = dev->archdata.numa_node;
+ page = alloc_pages_node(nid, gfp, order);
+ if (unlikely(!page))
return NULL;
+ first_page = (unsigned long) page_address(page);
memset((char *)first_page, 0, PAGE_SIZE << order);
iommu = dev->archdata.iommu;
@@ -335,8 +339,10 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
unsigned long flags, handle, prot;
dma_addr_t dma_next = 0, dma_addr;
unsigned int max_seg_size;
+ unsigned long seg_boundary_size;
int outcount, incount, i;
struct iommu *iommu;
+ unsigned long base_shift;
long err;
BUG_ON(direction == DMA_NONE);
@@ -362,8 +368,11 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
iommu_batch_start(dev, prot, ~0UL);
max_seg_size = dma_get_max_seg_size(dev);
+ seg_boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
+ IO_PAGE_SIZE) >> IO_PAGE_SHIFT;
+ base_shift = iommu->page_table_map_base >> IO_PAGE_SHIFT;
for_each_sg(sglist, s, nelems, i) {
- unsigned long paddr, npages, entry, slen;
+ unsigned long paddr, npages, entry, out_entry = 0, slen;
slen = s->length;
/* Sanity check */
@@ -406,7 +415,9 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
* - allocated dma_addr isn't contiguous to previous allocation
*/
if ((dma_addr != dma_next) ||
- (outs->dma_length + s->length > max_seg_size)) {
+ (outs->dma_length + s->length > max_seg_size) ||
+ (is_span_boundary(out_entry, base_shift,
+ seg_boundary_size, outs, s))) {
/* Can't merge: create a new segment */
segstart = s;
outcount++;
@@ -420,6 +431,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
/* This is a new segment, fill entries */
outs->dma_address = dma_addr;
outs->dma_length = slen;
+ out_entry = entry;
}
/* Calculate next page pointer for contiguous check */
@@ -891,6 +903,8 @@ static void __init pci_sun4v_pbm_init(struct pci_controller_info *p,
pbm->next = pci_pbm_root;
pci_pbm_root = pbm;
+ pbm->numa_node = of_node_to_nid(dp);
+
pbm->scan_bus = pci_sun4v_scan_bus;
pbm->pci_ops = &sun4v_pci_ops;
pbm->config_space_reg_bits = 12;
@@ -905,6 +919,7 @@ static void __init pci_sun4v_pbm_init(struct pci_controller_info *p,
pbm->name = dp->full_name;
printk("%s: SUN4V PCI Bus Module\n", pbm->name);
+ printk("%s: On NUMA node %d\n", pbm->name, pbm->numa_node);
pci_determine_mem_io_space(pbm);
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index 850cdffdd69c..eae8ca2a6ba5 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -20,6 +20,7 @@
#include <asm/of_device.h>
#include <asm/io.h>
#include <asm/sstate.h>
+#include <asm/reboot.h>
#include <linux/unistd.h>
@@ -39,8 +40,6 @@ static irqreturn_t power_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-extern void machine_halt(void);
-extern void machine_alt_power_off(void);
static void (*poweroff_method)(void) = machine_alt_power_off;
void machine_power_off(void)
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 6eceac51ae62..056013749157 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -1,5 +1,4 @@
-/* $Id: process.c,v 1.131 2002/02/09 19:49:30 davem Exp $
- * arch/sparc64/kernel/process.c
+/* arch/sparc64/kernel/process.c
*
* Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
@@ -30,6 +29,7 @@
#include <linux/tick.h>
#include <linux/init.h>
#include <linux/cpu.h>
+#include <linux/elfcore.h>
#include <asm/oplib.h>
#include <asm/uaccess.h>
@@ -47,6 +47,8 @@
#include <asm/unistd.h>
#include <asm/hypervisor.h>
#include <asm/sstate.h>
+#include <asm/reboot.h>
+#include <asm/syscalls.h>
/* #define VERBOSE_SHOWREGS */
@@ -111,8 +113,6 @@ void cpu_idle(void)
}
}
-extern char reboot_command [];
-
void machine_halt(void)
{
sstate_halt();
@@ -211,62 +211,6 @@ static void show_regwindow(struct pt_regs *regs)
print_symbol("I7: <%s>\n", rwk->ins[7]);
}
-void show_stackframe(struct sparc_stackf *sf)
-{
- unsigned long size;
- unsigned long *stk;
- int i;
-
- printk("l0: %016lx l1: %016lx l2: %016lx l3: %016lx\n"
- "l4: %016lx l5: %016lx l6: %016lx l7: %016lx\n",
- sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3],
- sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]);
- printk("i0: %016lx i1: %016lx i2: %016lx i3: %016lx\n"
- "i4: %016lx i5: %016lx fp: %016lx ret_pc: %016lx\n",
- sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3],
- sf->ins[4], sf->ins[5], (unsigned long)sf->fp, sf->callers_pc);
- printk("sp: %016lx x0: %016lx x1: %016lx x2: %016lx\n"
- "x3: %016lx x4: %016lx x5: %016lx xx: %016lx\n",
- (unsigned long)sf->structptr, sf->xargs[0], sf->xargs[1],
- sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5],
- sf->xxargs[0]);
- size = ((unsigned long)sf->fp) - ((unsigned long)sf);
- size -= STACKFRAME_SZ;
- stk = (unsigned long *)((unsigned long)sf + STACKFRAME_SZ);
- i = 0;
- do {
- printk("s%d: %016lx\n", i++, *stk++);
- } while ((size -= sizeof(unsigned long)));
-}
-
-void show_stackframe32(struct sparc_stackf32 *sf)
-{
- unsigned long size;
- unsigned *stk;
- int i;
-
- printk("l0: %08x l1: %08x l2: %08x l3: %08x\n",
- sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3]);
- printk("l4: %08x l5: %08x l6: %08x l7: %08x\n",
- sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]);
- printk("i0: %08x i1: %08x i2: %08x i3: %08x\n",
- sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3]);
- printk("i4: %08x i5: %08x fp: %08x ret_pc: %08x\n",
- sf->ins[4], sf->ins[5], sf->fp, sf->callers_pc);
- printk("sp: %08x x0: %08x x1: %08x x2: %08x\n"
- "x3: %08x x4: %08x x5: %08x xx: %08x\n",
- sf->structptr, sf->xargs[0], sf->xargs[1],
- sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5],
- sf->xxargs[0]);
- size = ((unsigned long)sf->fp) - ((unsigned long)sf);
- size -= STACKFRAME32_SZ;
- stk = (unsigned *)((unsigned long)sf + STACKFRAME32_SZ);
- i = 0;
- do {
- printk("s%d: %08x\n", i++, *stk++);
- } while ((size -= sizeof(unsigned)));
-}
-
#ifdef CONFIG_SMP
static DEFINE_SPINLOCK(regdump_lock);
#endif
@@ -354,24 +298,6 @@ void show_regs(struct pt_regs *regs)
#endif
}
-void show_regs32(struct pt_regs32 *regs)
-{
- printk("PSR: %08x PC: %08x NPC: %08x Y: %08x %s\n", regs->psr,
- regs->pc, regs->npc, regs->y, print_tainted());
- printk("g0: %08x g1: %08x g2: %08x g3: %08x ",
- regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
- regs->u_regs[3]);
- printk("g4: %08x g5: %08x g6: %08x g7: %08x\n",
- regs->u_regs[4], regs->u_regs[5], regs->u_regs[6],
- regs->u_regs[7]);
- printk("o0: %08x o1: %08x o2: %08x o3: %08x ",
- regs->u_regs[8], regs->u_regs[9], regs->u_regs[10],
- regs->u_regs[11]);
- printk("o4: %08x o5: %08x sp: %08x ret_pc: %08x\n",
- regs->u_regs[12], regs->u_regs[13], regs->u_regs[14],
- regs->u_regs[15]);
-}
-
unsigned long thread_saved_pc(struct task_struct *tsk)
{
struct thread_info *ti = task_thread_info(tsk);
@@ -441,9 +367,6 @@ void flush_thread(void)
if (get_thread_current_ds() != ASI_AIUS)
set_fs(USER_DS);
-
- /* Init new signal delivery disposition. */
- clear_thread_flag(TIF_NEWSIGNALS);
}
/* It's a bit more tricky when 64-bit tasks are involved... */
@@ -668,6 +591,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
if (clone_flags & CLONE_SETTLS)
t->kregs->u_regs[UREG_G7] = regs->u_regs[UREG_I3];
+ /* We do not want to accidently trigger system call restart
+ * handling in the new thread. Therefore, clear out the trap
+ * type, which will make pt_regs_regs_is_syscall() return false.
+ */
+ pt_regs_clear_trap_type(t->kregs);
+
return 0;
}
@@ -804,9 +733,6 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
current_thread_info()->xfsr[0] = 0;
current_thread_info()->fpsaved[0] = 0;
regs->tstate &= ~TSTATE_PEF;
- task_lock(current);
- current->ptrace &= ~PT_DTRACE;
- task_unlock(current);
}
out:
return error;
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index 68964ddcde1e..ed03a18d3b36 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -19,8 +19,8 @@
#include <linux/types.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/bootmem.h>
#include <linux/module.h>
+#include <linux/lmb.h>
#include <asm/prom.h>
#include <asm/of_device.h>
@@ -122,16 +122,20 @@ int of_find_in_proplist(const char *list, const char *match, int len)
}
EXPORT_SYMBOL(of_find_in_proplist);
-static unsigned int prom_early_allocated;
+static unsigned int prom_early_allocated __initdata;
static void * __init prom_early_alloc(unsigned long size)
{
+ unsigned long paddr = lmb_alloc(size, SMP_CACHE_BYTES);
void *ret;
- ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL);
- if (ret != NULL)
- memset(ret, 0, size);
+ if (!paddr) {
+ prom_printf("prom_early_alloc(%lu) failed\n");
+ prom_halt();
+ }
+ ret = __va(paddr);
+ memset(ret, 0, size);
prom_early_allocated += size;
return ret;
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index 9a1ba1fe859d..e9fc0aa2da38 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -35,6 +35,9 @@
#include <asm/spitfire.h>
#include <asm/page.h>
#include <asm/cpudata.h>
+#include <asm/cacheflush.h>
+
+#include "entry.h"
/* #define ALLOW_INIT_TRACING */
@@ -67,6 +70,8 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
if (tlb_type == hypervisor)
return;
+ preempt_disable();
+
#ifdef DCACHE_ALIASING_POSSIBLE
/* If bit 13 of the kernel address we used to access the
* user page is the same as the virtual address that page
@@ -105,6 +110,87 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
for (; start < end; start += icache_line_size)
flushi(start);
}
+
+ preempt_enable();
+}
+
+static int get_from_target(struct task_struct *target, unsigned long uaddr,
+ void *kbuf, int len)
+{
+ if (target == current) {
+ if (copy_from_user(kbuf, (void __user *) uaddr, len))
+ return -EFAULT;
+ } else {
+ int len2 = access_process_vm(target, uaddr, kbuf, len, 0);
+ if (len2 != len)
+ return -EFAULT;
+ }
+ return 0;
+}
+
+static int set_to_target(struct task_struct *target, unsigned long uaddr,
+ void *kbuf, int len)
+{
+ if (target == current) {
+ if (copy_to_user((void __user *) uaddr, kbuf, len))
+ return -EFAULT;
+ } else {
+ int len2 = access_process_vm(target, uaddr, kbuf, len, 1);
+ if (len2 != len)
+ return -EFAULT;
+ }
+ return 0;
+}
+
+static int regwindow64_get(struct task_struct *target,
+ const struct pt_regs *regs,
+ struct reg_window *wbuf)
+{
+ unsigned long rw_addr = regs->u_regs[UREG_I6];
+
+ if (test_tsk_thread_flag(current, TIF_32BIT)) {
+ struct reg_window32 win32;
+ int i;
+
+ if (get_from_target(target, rw_addr, &win32, sizeof(win32)))
+ return -EFAULT;
+ for (i = 0; i < 8; i++)
+ wbuf->locals[i] = win32.locals[i];
+ for (i = 0; i < 8; i++)
+ wbuf->ins[i] = win32.ins[i];
+ } else {
+ rw_addr += STACK_BIAS;
+ if (get_from_target(target, rw_addr, wbuf, sizeof(*wbuf)))
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int regwindow64_set(struct task_struct *target,
+ const struct pt_regs *regs,
+ struct reg_window *wbuf)
+{
+ unsigned long rw_addr = regs->u_regs[UREG_I6];
+
+ if (test_tsk_thread_flag(current, TIF_32BIT)) {
+ struct reg_window32 win32;
+ int i;
+
+ for (i = 0; i < 8; i++)
+ win32.locals[i] = wbuf->locals[i];
+ for (i = 0; i < 8; i++)
+ win32.ins[i] = wbuf->ins[i];
+
+ if (set_to_target(target, rw_addr, &win32, sizeof(win32)))
+ return -EFAULT;
+ } else {
+ rw_addr += STACK_BIAS;
+ if (set_to_target(target, rw_addr, wbuf, sizeof(*wbuf)))
+ return -EFAULT;
+ }
+
+ return 0;
}
enum sparc_regset {
@@ -126,16 +212,13 @@ static int genregs64_get(struct task_struct *target,
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
regs->u_regs,
0, 16 * sizeof(u64));
- if (!ret) {
- unsigned long __user *reg_window = (unsigned long __user *)
- (regs->u_regs[UREG_I6] + STACK_BIAS);
- unsigned long window[16];
+ if (!ret && count && pos < (32 * sizeof(u64))) {
+ struct reg_window window;
- if (copy_from_user(window, reg_window, sizeof(window)))
+ if (regwindow64_get(target, regs, &window))
return -EFAULT;
-
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- window,
+ &window,
16 * sizeof(u64),
32 * sizeof(u64));
}
@@ -157,10 +240,11 @@ static int genregs64_get(struct task_struct *target,
36 * sizeof(u64));
}
- if (!ret)
+ if (!ret) {
ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
36 * sizeof(u64), -1);
+ }
return ret;
}
@@ -178,20 +262,19 @@ static int genregs64_set(struct task_struct *target,
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
regs->u_regs,
0, 16 * sizeof(u64));
- if (!ret && count > 0) {
- unsigned long __user *reg_window = (unsigned long __user *)
- (regs->u_regs[UREG_I6] + STACK_BIAS);
- unsigned long window[16];
+ if (!ret && count && pos < (32 * sizeof(u64))) {
+ struct reg_window window;
- if (copy_from_user(window, reg_window, sizeof(window)))
+ if (regwindow64_get(target, regs, &window))
return -EFAULT;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- window,
+ &window,
16 * sizeof(u64),
32 * sizeof(u64));
+
if (!ret &&
- copy_to_user(reg_window, window, sizeof(window)))
+ regwindow64_set(target, regs, &window))
return -EFAULT;
}
@@ -382,6 +465,7 @@ static const struct user_regset_view user_sparc64_view = {
.regsets = sparc64_regsets, .n = ARRAY_SIZE(sparc64_regsets)
};
+#ifdef CONFIG_COMPAT
static int genregs32_get(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
@@ -404,9 +488,22 @@ static int genregs32_get(struct task_struct *target,
*k++ = regs->u_regs[pos++];
reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
- for (; count > 0 && pos < 32; count--) {
- if (get_user(*k++, &reg_window[pos++]))
- return -EFAULT;
+ if (target == current) {
+ for (; count > 0 && pos < 32; count--) {
+ if (get_user(*k++, &reg_window[pos++]))
+ return -EFAULT;
+ }
+ } else {
+ for (; count > 0 && pos < 32; count--) {
+ if (access_process_vm(target,
+ (unsigned long)
+ &reg_window[pos],
+ k, sizeof(*k), 0)
+ != sizeof(*k))
+ return -EFAULT;
+ k++;
+ pos++;
+ }
}
} else {
for (; count > 0 && pos < 16; count--) {
@@ -415,10 +512,28 @@ static int genregs32_get(struct task_struct *target,
}
reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
- for (; count > 0 && pos < 32; count--) {
- if (get_user(reg, &reg_window[pos++]) ||
- put_user(reg, u++))
- return -EFAULT;
+ if (target == current) {
+ for (; count > 0 && pos < 32; count--) {
+ if (get_user(reg, &reg_window[pos++]) ||
+ put_user(reg, u++))
+ return -EFAULT;
+ }
+ } else {
+ for (; count > 0 && pos < 32; count--) {
+ if (access_process_vm(target,
+ (unsigned long)
+ &reg_window[pos],
+ &reg, sizeof(reg), 0)
+ != sizeof(reg))
+ return -EFAULT;
+ if (access_process_vm(target,
+ (unsigned long) u,
+ &reg, sizeof(reg), 1)
+ != sizeof(reg))
+ return -EFAULT;
+ pos++;
+ u++;
+ }
}
}
while (count > 0) {
@@ -480,9 +595,23 @@ static int genregs32_set(struct task_struct *target,
regs->u_regs[pos++] = *k++;
reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
- for (; count > 0 && pos < 32; count--) {
- if (put_user(*k++, &reg_window[pos++]))
- return -EFAULT;
+ if (target == current) {
+ for (; count > 0 && pos < 32; count--) {
+ if (put_user(*k++, &reg_window[pos++]))
+ return -EFAULT;
+ }
+ } else {
+ for (; count > 0 && pos < 32; count--) {
+ if (access_process_vm(target,
+ (unsigned long)
+ &reg_window[pos],
+ (void *) k,
+ sizeof(*k), 1)
+ != sizeof(*k))
+ return -EFAULT;
+ k++;
+ pos++;
+ }
}
} else {
for (; count > 0 && pos < 16; count--) {
@@ -492,10 +621,29 @@ static int genregs32_set(struct task_struct *target,
}
reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
- for (; count > 0 && pos < 32; count--) {
- if (get_user(reg, u++) ||
- put_user(reg, &reg_window[pos++]))
- return -EFAULT;
+ if (target == current) {
+ for (; count > 0 && pos < 32; count--) {
+ if (get_user(reg, u++) ||
+ put_user(reg, &reg_window[pos++]))
+ return -EFAULT;
+ }
+ } else {
+ for (; count > 0 && pos < 32; count--) {
+ if (access_process_vm(target,
+ (unsigned long)
+ u,
+ &reg, sizeof(reg), 0)
+ != sizeof(reg))
+ return -EFAULT;
+ if (access_process_vm(target,
+ (unsigned long)
+ &reg_window[pos],
+ &reg, sizeof(reg), 1)
+ != sizeof(reg))
+ return -EFAULT;
+ pos++;
+ u++;
+ }
}
}
while (count > 0) {
@@ -676,14 +824,18 @@ static const struct user_regset_view user_sparc32_view = {
.name = "sparc", .e_machine = EM_SPARC,
.regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets)
};
+#endif /* CONFIG_COMPAT */
const struct user_regset_view *task_user_regset_view(struct task_struct *task)
{
+#ifdef CONFIG_COMPAT
if (test_tsk_thread_flag(task, TIF_32BIT))
return &user_sparc32_view;
+#endif
return &user_sparc64_view;
}
+#ifdef CONFIG_COMPAT
struct compat_fps {
unsigned int regs[32];
unsigned int fsr;
@@ -699,7 +851,7 @@ struct compat_fps {
long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
compat_ulong_t caddr, compat_ulong_t cdata)
{
- const struct user_regset_view *view = task_user_regset_view(child);
+ const struct user_regset_view *view = task_user_regset_view(current);
compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4];
struct pt_regs32 __user *pregs;
struct compat_fps __user *fps;
@@ -798,6 +950,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
return ret;
}
+#endif /* CONFIG_COMPAT */
struct fps {
unsigned int regs[64];
@@ -806,12 +959,15 @@ struct fps {
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- const struct user_regset_view *view = task_user_regset_view(child);
- struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
+ const struct user_regset_view *view = task_user_regset_view(current);
unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4];
- struct fps __user *fps = (struct fps __user *) addr;
+ struct pt_regs __user *pregs;
+ struct fps __user *fps;
int ret;
+ pregs = (struct pt_regs __user *) (unsigned long) addr;
+ fps = (struct fps __user *) (unsigned long) addr;
+
switch (request) {
case PTRACE_PEEKUSR:
ret = (addr != 0) ? -EIO : 0;
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index 079d18a11d24..ecf6753b204a 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -18,12 +18,6 @@
#define RTRAP_PSTATE_IRQOFF (PSTATE_RMO|PSTATE_PEF|PSTATE_PRIV)
#define RTRAP_PSTATE_AG_IRQOFF (PSTATE_RMO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)
- /* Register %l6 keeps track of whether we are returning
- * from a system call or not. It is cleared if we call
- * do_notify_resume, and it must not be otherwise modified
- * until we fully commit to returning to userspace.
- */
-
.text
.align 32
__handle_softirq:
@@ -56,14 +50,12 @@ __handle_user_windows:
be,pt %xcc, __handle_user_windows_continue
nop
mov %l5, %o1
- mov %l6, %o2
add %sp, PTREGS_OFF, %o0
- mov %l0, %o3
+ mov %l0, %o2
call do_notify_resume
wrpr %g0, RTRAP_PSTATE, %pstate
wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
- clr %l6
/* Signal delivery can modify pt_regs tstate, so we must
* reload it.
*/
@@ -99,14 +91,12 @@ __handle_perfctrs:
be,pt %xcc, __handle_perfctrs_continue
sethi %hi(TSTATE_PEF), %o0
mov %l5, %o1
- mov %l6, %o2
add %sp, PTREGS_OFF, %o0
- mov %l0, %o3
+ mov %l0, %o2
call do_notify_resume
wrpr %g0, RTRAP_PSTATE, %pstate
wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
- clr %l6
/* Signal delivery can modify pt_regs tstate, so we must
* reload it.
*/
@@ -127,13 +117,11 @@ __handle_userfpu:
__handle_signal:
mov %l5, %o1
- mov %l6, %o2
add %sp, PTREGS_OFF, %o0
- mov %l0, %o3
+ mov %l0, %o2
call do_notify_resume
wrpr %g0, RTRAP_PSTATE, %pstate
wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
- clr %l6
/* Signal delivery can modify pt_regs tstate, so we must
* reload it.
@@ -145,9 +133,8 @@ __handle_signal:
andn %l1, %l4, %l1
.align 64
- .globl rtrap_irq, rtrap_clr_l6, rtrap, irqsz_patchme, rtrap_xcall
+ .globl rtrap_irq, rtrap, irqsz_patchme, rtrap_xcall
rtrap_irq:
-rtrap_clr_l6: clr %l6
rtrap:
#ifndef CONFIG_SMP
sethi %hi(per_cpu____cpu_data), %l0
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index d1fb13ba02b5..fa2827c4a3ad 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -544,6 +544,7 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus)
sbus->ofdev.dev.archdata.iommu = iommu;
sbus->ofdev.dev.archdata.stc = strbuf;
+ sbus->ofdev.dev.archdata.numa_node = -1;
reg_base = regs + SYSIO_IOMMUREG_BASE;
iommu->iommu_control = reg_base + IOMMU_CONTROL;
@@ -575,7 +576,7 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus)
sbus->portid, regs);
/* Setup for TSB_SIZE=7, TBW_SIZE=0, MMU_DE=1, MMU_EN=1 */
- if (iommu_table_init(iommu, IO_TSB_SIZE, MAP_BASE, 0xffffffff))
+ if (iommu_table_init(iommu, IO_TSB_SIZE, MAP_BASE, 0xffffffff, -1))
goto fatal_memory_error;
control = upa_readq(iommu->iommu_control);
diff --git a/arch/sparc64/kernel/semaphore.c b/arch/sparc64/kernel/semaphore.c
deleted file mode 100644
index 9974a6899551..000000000000
--- a/arch/sparc64/kernel/semaphore.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/* semaphore.c: Sparc64 semaphore implementation.
- *
- * This is basically the PPC semaphore scheme ported to use
- * the sparc64 atomic instructions, so see the PPC code for
- * credits.
- */
-
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-
-/*
- * Atomically update sem->count.
- * This does the equivalent of the following:
- *
- * old_count = sem->count;
- * tmp = MAX(old_count, 0) + incr;
- * sem->count = tmp;
- * return old_count;
- */
-static inline int __sem_update_count(struct semaphore *sem, int incr)
-{
- int old_count, tmp;
-
- __asm__ __volatile__("\n"
-" ! __sem_update_count old_count(%0) tmp(%1) incr(%4) &sem->count(%3)\n"
-"1: ldsw [%3], %0\n"
-" mov %0, %1\n"
-" cmp %0, 0\n"
-" movl %%icc, 0, %1\n"
-" add %1, %4, %1\n"
-" cas [%3], %0, %1\n"
-" cmp %0, %1\n"
-" membar #StoreLoad | #StoreStore\n"
-" bne,pn %%icc, 1b\n"
-" nop\n"
- : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
- : "r" (&sem->count), "r" (incr), "m" (sem->count)
- : "cc");
-
- return old_count;
-}
-
-static void __up(struct semaphore *sem)
-{
- __sem_update_count(sem, 1);
- wake_up(&sem->wait);
-}
-
-void up(struct semaphore *sem)
-{
- /* This atomically does:
- * old_val = sem->count;
- * new_val = sem->count + 1;
- * sem->count = new_val;
- * if (old_val < 0)
- * __up(sem);
- *
- * The (old_val < 0) test is equivalent to
- * the more straightforward (new_val <= 0),
- * but it is easier to test the former because
- * of how the CAS instruction works.
- */
-
- __asm__ __volatile__("\n"
-" ! up sem(%0)\n"
-" membar #StoreLoad | #LoadLoad\n"
-"1: lduw [%0], %%g1\n"
-" add %%g1, 1, %%g7\n"
-" cas [%0], %%g1, %%g7\n"
-" cmp %%g1, %%g7\n"
-" bne,pn %%icc, 1b\n"
-" addcc %%g7, 1, %%g0\n"
-" membar #StoreLoad | #StoreStore\n"
-" ble,pn %%icc, 3f\n"
-" nop\n"
-"2:\n"
-" .subsection 2\n"
-"3: mov %0, %%g1\n"
-" save %%sp, -160, %%sp\n"
-" call %1\n"
-" mov %%g1, %%o0\n"
-" ba,pt %%xcc, 2b\n"
-" restore\n"
-" .previous\n"
- : : "r" (sem), "i" (__up)
- : "g1", "g2", "g3", "g7", "memory", "cc");
-}
-
-static void __sched __down(struct semaphore * sem)
-{
- struct task_struct *tsk = current;
- DECLARE_WAITQUEUE(wait, tsk);
-
- tsk->state = TASK_UNINTERRUPTIBLE;
- add_wait_queue_exclusive(&sem->wait, &wait);
-
- while (__sem_update_count(sem, -1) <= 0) {
- schedule();
- tsk->state = TASK_UNINTERRUPTIBLE;
- }
- remove_wait_queue(&sem->wait, &wait);
- tsk->state = TASK_RUNNING;
-
- wake_up(&sem->wait);
-}
-
-void __sched down(struct semaphore *sem)
-{
- might_sleep();
- /* This atomically does:
- * old_val = sem->count;
- * new_val = sem->count - 1;
- * sem->count = new_val;
- * if (old_val < 1)
- * __down(sem);
- *
- * The (old_val < 1) test is equivalent to
- * the more straightforward (new_val < 0),
- * but it is easier to test the former because
- * of how the CAS instruction works.
- */
-
- __asm__ __volatile__("\n"
-" ! down sem(%0)\n"
-"1: lduw [%0], %%g1\n"
-" sub %%g1, 1, %%g7\n"
-" cas [%0], %%g1, %%g7\n"
-" cmp %%g1, %%g7\n"
-" bne,pn %%icc, 1b\n"
-" cmp %%g7, 1\n"
-" membar #StoreLoad | #StoreStore\n"
-" bl,pn %%icc, 3f\n"
-" nop\n"
-"2:\n"
-" .subsection 2\n"
-"3: mov %0, %%g1\n"
-" save %%sp, -160, %%sp\n"
-" call %1\n"
-" mov %%g1, %%o0\n"
-" ba,pt %%xcc, 2b\n"
-" restore\n"
-" .previous\n"
- : : "r" (sem), "i" (__down)
- : "g1", "g2", "g3", "g7", "memory", "cc");
-}
-
-int down_trylock(struct semaphore *sem)
-{
- int ret;
-
- /* This atomically does:
- * old_val = sem->count;
- * new_val = sem->count - 1;
- * if (old_val < 1) {
- * ret = 1;
- * } else {
- * sem->count = new_val;
- * ret = 0;
- * }
- *
- * The (old_val < 1) test is equivalent to
- * the more straightforward (new_val < 0),
- * but it is easier to test the former because
- * of how the CAS instruction works.
- */
-
- __asm__ __volatile__("\n"
-" ! down_trylock sem(%1) ret(%0)\n"
-"1: lduw [%1], %%g1\n"
-" sub %%g1, 1, %%g7\n"
-" cmp %%g1, 1\n"
-" bl,pn %%icc, 2f\n"
-" mov 1, %0\n"
-" cas [%1], %%g1, %%g7\n"
-" cmp %%g1, %%g7\n"
-" bne,pn %%icc, 1b\n"
-" mov 0, %0\n"
-" membar #StoreLoad | #StoreStore\n"
-"2:\n"
- : "=&r" (ret)
- : "r" (sem)
- : "g1", "g7", "memory", "cc");
-
- return ret;
-}
-
-static int __sched __down_interruptible(struct semaphore * sem)
-{
- int retval = 0;
- struct task_struct *tsk = current;
- DECLARE_WAITQUEUE(wait, tsk);
-
- tsk->state = TASK_INTERRUPTIBLE;
- add_wait_queue_exclusive(&sem->wait, &wait);
-
- while (__sem_update_count(sem, -1) <= 0) {
- if (signal_pending(current)) {
- __sem_update_count(sem, 0);
- retval = -EINTR;
- break;
- }
- schedule();
- tsk->state = TASK_INTERRUPTIBLE;
- }
- tsk->state = TASK_RUNNING;
- remove_wait_queue(&sem->wait, &wait);
- wake_up(&sem->wait);
- return retval;
-}
-
-int __sched down_interruptible(struct semaphore *sem)
-{
- int ret = 0;
-
- might_sleep();
- /* This atomically does:
- * old_val = sem->count;
- * new_val = sem->count - 1;
- * sem->count = new_val;
- * if (old_val < 1)
- * ret = __down_interruptible(sem);
- *
- * The (old_val < 1) test is equivalent to
- * the more straightforward (new_val < 0),
- * but it is easier to test the former because
- * of how the CAS instruction works.
- */
-
- __asm__ __volatile__("\n"
-" ! down_interruptible sem(%2) ret(%0)\n"
-"1: lduw [%2], %%g1\n"
-" sub %%g1, 1, %%g7\n"
-" cas [%2], %%g1, %%g7\n"
-" cmp %%g1, %%g7\n"
-" bne,pn %%icc, 1b\n"
-" cmp %%g7, 1\n"
-" membar #StoreLoad | #StoreStore\n"
-" bl,pn %%icc, 3f\n"
-" nop\n"
-"2:\n"
-" .subsection 2\n"
-"3: mov %2, %%g1\n"
-" save %%sp, -160, %%sp\n"
-" call %3\n"
-" mov %%g1, %%o0\n"
-" ba,pt %%xcc, 2b\n"
-" restore\n"
-" .previous\n"
- : "=r" (ret)
- : "0" (ret), "r" (sem), "i" (__down_interruptible)
- : "g1", "g2", "g3", "g7", "memory", "cc");
- return ret;
-}
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index d036dbe72864..da5e6ee0c661 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -51,6 +51,8 @@
#include <net/ipconfig.h>
#endif
+#include "entry.h"
+
/* Used to synchronize accesses to NatSemi SUPER I/O chip configure
* operations in asm/ns87303.h
*/
@@ -80,7 +82,7 @@ unsigned long cmdline_memory_size = 0;
static struct console prom_early_console = {
.name = "earlyprom",
.write = prom_console_write,
- .flags = CON_PRINTBUFFER | CON_BOOT,
+ .flags = CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME,
.index = -1,
};
@@ -279,6 +281,7 @@ void __init setup_arch(char **cmdline_p)
/* Initialize PROM console and command line. */
*cmdline_p = prom_getbootargs();
strcpy(boot_command_line, *cmdline_p);
+ parse_early_param();
boot_flags_init(*cmdline_p);
register_console(&prom_early_console);
@@ -335,9 +338,6 @@ void __init setup_arch(char **cmdline_p)
/* BUFFER is PAGE_SIZE bytes long. */
-extern char *sparc_cpu_type;
-extern char *sparc_fpu_type;
-
extern void smp_info(struct seq_file *);
extern void smp_bogo(struct seq_file *);
extern void mmu_info(struct seq_file *);
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index fb13775b3682..f2d88d8f7a42 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -8,7 +8,7 @@
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
*/
-#ifdef CONFIG_SPARC32_COMPAT
+#ifdef CONFIG_COMPAT
#include <linux/compat.h> /* for compat_old_sigset_t */
#endif
#include <linux/sched.h>
@@ -25,13 +25,15 @@
#include <asm/uaccess.h>
#include <asm/ptrace.h>
-#include <asm/svr4.h>
#include <asm/pgtable.h>
#include <asm/fpumacro.h>
#include <asm/uctx.h>
#include <asm/siginfo.h>
#include <asm/visasm.h>
+#include "entry.h"
+#include "systbls.h"
+
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
/* {set, get}context() needed for 64-bit SparcLinux userland. */
@@ -234,9 +236,6 @@ struct rt_signal_frame {
__siginfo_fpu_t fpu_state;
};
-/* Align macros */
-#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
-
static long _sigpause_common(old_sigset_t set)
{
set &= _BLOCKABLE;
@@ -354,7 +353,7 @@ static int invalid_frame_pointer(void __user *fp, int fplen)
static inline int
save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
{
- unsigned long *fpregs = (unsigned long *)(regs+1);
+ unsigned long *fpregs = current_thread_info()->fpregs;
unsigned long fprs;
int err = 0;
@@ -398,7 +397,7 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
synchronize_user_stack();
save_and_clear_fpu();
- sigframe_size = RT_ALIGNEDSZ;
+ sigframe_size = sizeof(struct rt_signal_frame);
if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
sigframe_size -= sizeof(__siginfo_fpu_t);
@@ -508,15 +507,19 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
*/
-static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall)
+static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
{
- siginfo_t info;
struct signal_deliver_cookie cookie;
struct k_sigaction ka;
- int signr;
sigset_t *oldset;
+ siginfo_t info;
+ int signr;
- cookie.restart_syscall = restart_syscall;
+ if (pt_regs_is_syscall(regs)) {
+ pt_regs_clear_trap_type(regs);
+ cookie.restart_syscall = 1;
+ } else
+ cookie.restart_syscall = 0;
cookie.orig_i0 = orig_i0;
if (test_thread_flag(TIF_RESTORE_SIGMASK))
@@ -524,12 +527,11 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_s
else
oldset = &current->blocked;
-#ifdef CONFIG_SPARC32_COMPAT
+#ifdef CONFIG_COMPAT
if (test_thread_flag(TIF_32BIT)) {
extern void do_signal32(sigset_t *, struct pt_regs *,
- unsigned long, int);
- do_signal32(oldset, regs, orig_i0,
- cookie.restart_syscall);
+ struct signal_deliver_cookie *);
+ do_signal32(oldset, regs, &cookie);
return;
}
#endif
@@ -537,7 +539,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_s
signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
if (signr > 0) {
if (cookie.restart_syscall)
- syscall_restart(orig_i0, regs, &ka.sa);
+ syscall_restart(cookie.orig_i0, regs, &ka.sa);
handle_signal(signr, &ka, &info, oldset, regs);
/* a signal was successfully delivered; the saved
@@ -574,11 +576,10 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_s
}
}
-void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall,
- unsigned long thread_info_flags)
+void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags)
{
if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
- do_signal(regs, orig_i0, restart_syscall);
+ do_signal(regs, orig_i0);
}
void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 8c1c121330fb..91f8d0826db1 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -1,5 +1,4 @@
-/* $Id: signal32.c,v 1.74 2002/02/09 19:49:30 davem Exp $
- * arch/sparc64/kernel/signal32.c
+/* arch/sparc64/kernel/signal32.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -23,7 +22,6 @@
#include <asm/uaccess.h>
#include <asm/ptrace.h>
-#include <asm/svr4.h>
#include <asm/pgtable.h>
#include <asm/psrcompat.h>
#include <asm/fpumacro.h>
@@ -32,30 +30,6 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-/* Signal frames: the original one (compatible with SunOS):
- *
- * Set up a signal frame... Make the stack look the way SunOS
- * expects it to look which is basically:
- *
- * ---------------------------------- <-- %sp at signal time
- * Struct sigcontext
- * Signal address
- * Ptr to sigcontext area above
- * Signal code
- * The signal number itself
- * One register window
- * ---------------------------------- <-- New %sp
- */
-struct signal_sframe32 {
- struct reg_window32 sig_window;
- int sig_num;
- int sig_code;
- /* struct sigcontext32 * */ u32 sig_scptr;
- int sig_address;
- struct sigcontext32 sig_context;
- unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
-};
-
/* This magic should be in g_upper[0] for all upper parts
* to be valid.
*/
@@ -66,12 +40,7 @@ typedef struct {
unsigned int asi;
} siginfo_extra_v8plus_t;
-/*
- * And the new one, intended to be used for Linux applications only
- * (we have enough in there to work with clone).
- * All the interesting bits are in the info field.
- */
-struct new_signal_frame32 {
+struct signal_frame32 {
struct sparc_stackf32 ss;
__siginfo32_t info;
/* __siginfo_fpu32_t * */ u32 fpu_save;
@@ -150,8 +119,7 @@ struct rt_signal_frame32 {
};
/* Align macros */
-#define SF_ALIGNEDSZ (((sizeof(struct signal_sframe32) + 7) & (~7)))
-#define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame32) + 7) & (~7)))
+#define SF_ALIGNEDSZ (((sizeof(struct signal_frame32) + 7) & (~7)))
#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 7) & (~7)))
int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
@@ -242,17 +210,22 @@ static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu
return err;
}
-void do_new_sigreturn32(struct pt_regs *regs)
+void do_sigreturn32(struct pt_regs *regs)
{
- struct new_signal_frame32 __user *sf;
+ struct signal_frame32 __user *sf;
unsigned int psr;
unsigned pc, npc, fpu_save;
sigset_t set;
unsigned seta[_COMPAT_NSIG_WORDS];
int err, i;
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+ synchronize_user_stack();
+
regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
- sf = (struct new_signal_frame32 __user *) regs->u_regs[UREG_FP];
+ sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
/* 1. Make sure we are not getting garbage from the user */
if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
@@ -320,76 +293,6 @@ segv:
force_sig(SIGSEGV, current);
}
-asmlinkage void do_sigreturn32(struct pt_regs *regs)
-{
- struct sigcontext32 __user *scptr;
- unsigned int pc, npc, psr;
- sigset_t set;
- unsigned int seta[_COMPAT_NSIG_WORDS];
- int err;
-
- /* Always make any pending restarted system calls return -EINTR */
- current_thread_info()->restart_block.fn = do_no_restart_syscall;
-
- synchronize_user_stack();
- if (test_thread_flag(TIF_NEWSIGNALS)) {
- do_new_sigreturn32(regs);
- return;
- }
-
- scptr = (struct sigcontext32 __user *)
- (regs->u_regs[UREG_I0] & 0x00000000ffffffffUL);
- /* Check sanity of the user arg. */
- if (!access_ok(VERIFY_READ, scptr, sizeof(struct sigcontext32)) ||
- (((unsigned long) scptr) & 3))
- goto segv;
-
- err = __get_user(pc, &scptr->sigc_pc);
- err |= __get_user(npc, &scptr->sigc_npc);
-
- if ((pc | npc) & 3)
- goto segv; /* Nice try. */
-
- err |= __get_user(seta[0], &scptr->sigc_mask);
- /* Note that scptr + 1 points to extramask */
- err |= copy_from_user(seta+1, scptr + 1,
- (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
- if (err)
- goto segv;
- switch (_NSIG_WORDS) {
- case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32);
- case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32);
- case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32);
- case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
- }
- sigdelsetmask(&set, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- current->blocked = set;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- if (test_thread_flag(TIF_32BIT)) {
- pc &= 0xffffffff;
- npc &= 0xffffffff;
- }
- regs->tpc = pc;
- regs->tnpc = npc;
- err = __get_user(regs->u_regs[UREG_FP], &scptr->sigc_sp);
- err |= __get_user(regs->u_regs[UREG_I0], &scptr->sigc_o0);
- err |= __get_user(regs->u_regs[UREG_G1], &scptr->sigc_g1);
-
- /* User can only change condition codes in %tstate. */
- err |= __get_user(psr, &scptr->sigc_psr);
- if (err)
- goto segv;
- regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
- regs->tstate |= psr_to_tstate_icc(psr);
- return;
-
-segv:
- force_sig(SIGSEGV, current);
-}
-
asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
{
struct rt_signal_frame32 __user *sf;
@@ -505,145 +408,6 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns
return (void __user *)(sp - framesize);
}
-static void
-setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *oldset, siginfo_t *info)
-{
- struct signal_sframe32 __user *sframep;
- struct sigcontext32 __user *sc;
- unsigned int seta[_COMPAT_NSIG_WORDS];
- int err = 0;
- void __user *sig_address;
- int sig_code;
- unsigned long pc = regs->tpc;
- unsigned long npc = regs->tnpc;
- unsigned int psr;
-
- if (test_thread_flag(TIF_32BIT)) {
- pc &= 0xffffffff;
- npc &= 0xffffffff;
- }
-
- synchronize_user_stack();
- save_and_clear_fpu();
-
- sframep = (struct signal_sframe32 __user *)
- get_sigframe(sa, regs, SF_ALIGNEDSZ);
- if (invalid_frame_pointer(sframep, sizeof(*sframep))){
- /* Don't change signal code and address, so that
- * post mortem debuggers can have a look.
- */
- do_exit(SIGILL);
- }
-
- sc = &sframep->sig_context;
-
- /* We've already made sure frame pointer isn't in kernel space... */
- err = __put_user((sas_ss_flags(regs->u_regs[UREG_FP]) == SS_ONSTACK),
- &sc->sigc_onstack);
-
- switch (_NSIG_WORDS) {
- case 4: seta[7] = (oldset->sig[3] >> 32);
- seta[6] = oldset->sig[3];
- case 3: seta[5] = (oldset->sig[2] >> 32);
- seta[4] = oldset->sig[2];
- case 2: seta[3] = (oldset->sig[1] >> 32);
- seta[2] = oldset->sig[1];
- case 1: seta[1] = (oldset->sig[0] >> 32);
- seta[0] = oldset->sig[0];
- }
- err |= __put_user(seta[0], &sc->sigc_mask);
- err |= __copy_to_user(sframep->extramask, seta + 1,
- (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
- err |= __put_user(regs->u_regs[UREG_FP], &sc->sigc_sp);
- err |= __put_user(pc, &sc->sigc_pc);
- err |= __put_user(npc, &sc->sigc_npc);
- psr = tstate_to_psr(regs->tstate);
- if (current_thread_info()->fpsaved[0] & FPRS_FEF)
- psr |= PSR_EF;
- err |= __put_user(psr, &sc->sigc_psr);
- err |= __put_user(regs->u_regs[UREG_G1], &sc->sigc_g1);
- err |= __put_user(regs->u_regs[UREG_I0], &sc->sigc_o0);
- err |= __put_user(get_thread_wsaved(), &sc->sigc_oswins);
-
- err |= copy_in_user((u32 __user *)sframep,
- (u32 __user *)(regs->u_regs[UREG_FP]),
- sizeof(struct reg_window32));
-
- set_thread_wsaved(0); /* So process is allowed to execute. */
- err |= __put_user(signr, &sframep->sig_num);
- sig_address = NULL;
- sig_code = 0;
- if (SI_FROMKERNEL (info) && (info->si_code & __SI_MASK) == __SI_FAULT) {
- sig_address = info->si_addr;
- switch (signr) {
- case SIGSEGV:
- switch (info->si_code) {
- case SEGV_MAPERR: sig_code = SUBSIG_NOMAPPING; break;
- default: sig_code = SUBSIG_PROTECTION; break;
- }
- break;
- case SIGILL:
- switch (info->si_code) {
- case ILL_ILLOPC: sig_code = SUBSIG_ILLINST; break;
- case ILL_PRVOPC: sig_code = SUBSIG_PRIVINST; break;
- case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP(info->si_trapno); break;
- default: sig_code = SUBSIG_STACK; break;
- }
- break;
- case SIGFPE:
- switch (info->si_code) {
- case FPE_INTDIV: sig_code = SUBSIG_IDIVZERO; break;
- case FPE_INTOVF: sig_code = SUBSIG_FPINTOVFL; break;
- case FPE_FLTDIV: sig_code = SUBSIG_FPDIVZERO; break;
- case FPE_FLTOVF: sig_code = SUBSIG_FPOVFLOW; break;
- case FPE_FLTUND: sig_code = SUBSIG_FPUNFLOW; break;
- case FPE_FLTRES: sig_code = SUBSIG_FPINEXACT; break;
- case FPE_FLTINV: sig_code = SUBSIG_FPOPERROR; break;
- default: sig_code = SUBSIG_FPERROR; break;
- }
- break;
- case SIGBUS:
- switch (info->si_code) {
- case BUS_ADRALN: sig_code = SUBSIG_ALIGNMENT; break;
- case BUS_ADRERR: sig_code = SUBSIG_MISCERROR; break;
- default: sig_code = SUBSIG_BUSTIMEOUT; break;
- }
- break;
- case SIGEMT:
- switch (info->si_code) {
- case EMT_TAGOVF: sig_code = SUBSIG_TAG; break;
- }
- break;
- case SIGSYS:
- if (info->si_code == (__SI_FAULT|0x100)) {
- /* See sys_sunos32.c */
- sig_code = info->si_trapno;
- break;
- }
- default:
- sig_address = NULL;
- }
- }
- err |= __put_user(ptr_to_compat(sig_address), &sframep->sig_address);
- err |= __put_user(sig_code, &sframep->sig_code);
- err |= __put_user(ptr_to_compat(sc), &sframep->sig_scptr);
- if (err)
- goto sigsegv;
-
- regs->u_regs[UREG_FP] = (unsigned long) sframep;
- regs->tpc = (unsigned long) sa->sa_handler;
- regs->tnpc = (regs->tpc + 4);
- if (test_thread_flag(TIF_32BIT)) {
- regs->tpc &= 0xffffffff;
- regs->tnpc &= 0xffffffff;
- }
- return;
-
-sigsegv:
- force_sigsegv(signr, current);
-}
-
-
static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
{
unsigned long *fpregs = current_thread_info()->fpregs;
@@ -664,10 +428,10 @@ static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
return err;
}
-static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
- int signo, sigset_t *oldset)
+static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
+ int signo, sigset_t *oldset)
{
- struct new_signal_frame32 __user *sf;
+ struct signal_frame32 __user *sf;
int sigframe_size;
u32 psr;
int i, err;
@@ -677,11 +441,11 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
synchronize_user_stack();
save_and_clear_fpu();
- sigframe_size = NF_ALIGNEDSZ;
+ sigframe_size = SF_ALIGNEDSZ;
if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
sigframe_size -= sizeof(__siginfo_fpu_t);
- sf = (struct new_signal_frame32 __user *)
+ sf = (struct signal_frame32 __user *)
get_sigframe(&ka->sa, regs, sigframe_size);
if (invalid_frame_pointer(sf, sigframe_size))
@@ -798,281 +562,6 @@ sigsegv:
force_sigsegv(signo, current);
}
-/* Setup a Solaris stack frame */
-static void
-setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
- struct pt_regs *regs, int signr, sigset_t *oldset)
-{
- svr4_signal_frame_t __user *sfp;
- svr4_gregset_t __user *gr;
- svr4_siginfo_t __user *si;
- svr4_mcontext_t __user *mc;
- svr4_gwindows_t __user *gw;
- svr4_ucontext_t __user *uc;
- svr4_sigset_t setv;
- unsigned int psr;
- int i, err;
-
- synchronize_user_stack();
- save_and_clear_fpu();
-
- regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
- sfp = (svr4_signal_frame_t __user *)
- get_sigframe(sa, regs,
- sizeof(struct reg_window32) + SVR4_SF_ALIGNED);
-
- if (invalid_frame_pointer(sfp, sizeof(*sfp)))
- do_exit(SIGILL);
-
- /* Start with a clean frame pointer and fill it */
- err = clear_user(sfp, sizeof(*sfp));
-
- /* Setup convenience variables */
- si = &sfp->si;
- uc = &sfp->uc;
- gw = &sfp->gw;
- mc = &uc->mcontext;
- gr = &mc->greg;
-
- /* FIXME: where am I supposed to put this?
- * sc->sigc_onstack = old_status;
- * anyways, it does not look like it is used for anything at all.
- */
- setv.sigbits[0] = oldset->sig[0];
- setv.sigbits[1] = (oldset->sig[0] >> 32);
- if (_NSIG_WORDS >= 2) {
- setv.sigbits[2] = oldset->sig[1];
- setv.sigbits[3] = (oldset->sig[1] >> 32);
- err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
- } else
- err |= __copy_to_user(&uc->sigmask, &setv,
- 2 * sizeof(unsigned int));
-
- /* Store registers */
- if (test_thread_flag(TIF_32BIT)) {
- regs->tpc &= 0xffffffff;
- regs->tnpc &= 0xffffffff;
- }
- err |= __put_user(regs->tpc, &((*gr)[SVR4_PC]));
- err |= __put_user(regs->tnpc, &((*gr)[SVR4_NPC]));
- psr = tstate_to_psr(regs->tstate);
- if (current_thread_info()->fpsaved[0] & FPRS_FEF)
- psr |= PSR_EF;
- err |= __put_user(psr, &((*gr)[SVR4_PSR]));
- err |= __put_user(regs->y, &((*gr)[SVR4_Y]));
-
- /* Copy g[1..7] and o[0..7] registers */
- for (i = 0; i < 7; i++)
- err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
- for (i = 0; i < 8; i++)
- err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
-
- /* Setup sigaltstack */
- err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
- err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
- err |= __put_user(current->sas_ss_size, &uc->stack.size);
-
- /* Save the currently window file: */
-
- /* 1. Link sfp->uc->gwins to our windows */
- err |= __put_user(ptr_to_compat(gw), &mc->gwin);
-
- /* 2. Number of windows to restore at setcontext (): */
- err |= __put_user(get_thread_wsaved(), &gw->count);
-
- /* 3. We just pay attention to the gw->count field on setcontext */
- set_thread_wsaved(0); /* So process is allowed to execute. */
-
- /* Setup the signal information. Solaris expects a bunch of
- * information to be passed to the signal handler, we don't provide
- * that much currently, should use siginfo.
- */
- err |= __put_user(signr, &si->siginfo.signo);
- err |= __put_user(SVR4_SINOINFO, &si->siginfo.code);
- if (err)
- goto sigsegv;
-
- regs->u_regs[UREG_FP] = (unsigned long) sfp;
- regs->tpc = (unsigned long) sa->sa_handler;
- regs->tnpc = (regs->tpc + 4);
- if (test_thread_flag(TIF_32BIT)) {
- regs->tpc &= 0xffffffff;
- regs->tnpc &= 0xffffffff;
- }
-
- /* Arguments passed to signal handler */
- if (regs->u_regs[14]){
- struct reg_window32 __user *rw = (struct reg_window32 __user *)
- (regs->u_regs[14] & 0x00000000ffffffffUL);
-
- err |= __put_user(signr, &rw->ins[0]);
- err |= __put_user((u64)si, &rw->ins[1]);
- err |= __put_user((u64)uc, &rw->ins[2]);
- err |= __put_user((u64)sfp, &rw->ins[6]); /* frame pointer */
- if (err)
- goto sigsegv;
-
- regs->u_regs[UREG_I0] = signr;
- regs->u_regs[UREG_I1] = (u32)(u64) si;
- regs->u_regs[UREG_I2] = (u32)(u64) uc;
- }
- return;
-
-sigsegv:
- force_sigsegv(signr, current);
-}
-
-asmlinkage int
-svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs)
-{
- svr4_gregset_t __user *gr;
- svr4_mcontext_t __user *mc;
- svr4_sigset_t setv;
- int i, err;
- u32 psr;
-
- synchronize_user_stack();
- save_and_clear_fpu();
-
- if (get_thread_wsaved())
- do_exit(SIGSEGV);
-
- err = clear_user(uc, sizeof(*uc));
-
- /* Setup convenience variables */
- mc = &uc->mcontext;
- gr = &mc->greg;
-
- setv.sigbits[0] = current->blocked.sig[0];
- setv.sigbits[1] = (current->blocked.sig[0] >> 32);
- if (_NSIG_WORDS >= 2) {
- setv.sigbits[2] = current->blocked.sig[1];
- setv.sigbits[3] = (current->blocked.sig[1] >> 32);
- err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
- } else
- err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
-
- /* Store registers */
- if (test_thread_flag(TIF_32BIT)) {
- regs->tpc &= 0xffffffff;
- regs->tnpc &= 0xffffffff;
- }
- err |= __put_user(regs->tpc, &uc->mcontext.greg[SVR4_PC]);
- err |= __put_user(regs->tnpc, &uc->mcontext.greg[SVR4_NPC]);
-
- psr = tstate_to_psr(regs->tstate) & ~PSR_EF;
- if (current_thread_info()->fpsaved[0] & FPRS_FEF)
- psr |= PSR_EF;
- err |= __put_user(psr, &uc->mcontext.greg[SVR4_PSR]);
-
- err |= __put_user(regs->y, &uc->mcontext.greg[SVR4_Y]);
-
- /* Copy g[1..7] and o[0..7] registers */
- for (i = 0; i < 7; i++)
- err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
- for (i = 0; i < 8; i++)
- err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
-
- /* Setup sigaltstack */
- err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
- err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
- err |= __put_user(current->sas_ss_size, &uc->stack.size);
-
- /* The register file is not saved
- * we have already stuffed all of it with sync_user_stack
- */
- return (err ? -EFAULT : 0);
-}
-
-
-/* Set the context for a svr4 application, this is Solaris way to sigreturn */
-asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs)
-{
- svr4_gregset_t __user *gr;
- mm_segment_t old_fs;
- u32 pc, npc, psr, u_ss_sp;
- sigset_t set;
- svr4_sigset_t setv;
- int i, err;
- stack_t st;
-
- /* Fixme: restore windows, or is this already taken care of in
- * svr4_setup_frame when sync_user_windows is done?
- */
- flush_user_windows();
-
- if (get_thread_wsaved())
- goto sigsegv;
-
- if (((unsigned long) c) & 3){
- printk("Unaligned structure passed\n");
- goto sigsegv;
- }
-
- if (!__access_ok(c, sizeof(*c))) {
- /* Miguel, add nice debugging msg _here_. ;-) */
- goto sigsegv;
- }
-
- /* Check for valid PC and nPC */
- gr = &c->mcontext.greg;
- err = __get_user(pc, &((*gr)[SVR4_PC]));
- err |= __get_user(npc, &((*gr)[SVR4_NPC]));
- if ((pc | npc) & 3)
- goto sigsegv;
-
- /* Retrieve information from passed ucontext */
- /* note that nPC is ored a 1, this is used to inform entry.S */
- /* that we don't want it to mess with our PC and nPC */
-
- err |= copy_from_user(&setv, &c->sigmask, sizeof(svr4_sigset_t));
- set.sig[0] = setv.sigbits[0] | (((long)setv.sigbits[1]) << 32);
- if (_NSIG_WORDS >= 2)
- set.sig[1] = setv.sigbits[2] | (((long)setv.sigbits[3]) << 32);
-
- err |= __get_user(u_ss_sp, &c->stack.sp);
- st.ss_sp = compat_ptr(u_ss_sp);
- err |= __get_user(st.ss_flags, &c->stack.flags);
- err |= __get_user(st.ss_size, &c->stack.size);
- if (err)
- goto sigsegv;
-
- /* It is more difficult to avoid calling this function than to
- call it and ignore errors. */
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- do_sigaltstack((stack_t __user *) &st, NULL, regs->u_regs[UREG_I6]);
- set_fs(old_fs);
-
- sigdelsetmask(&set, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- current->blocked = set;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
- regs->tpc = pc;
- regs->tnpc = npc | 1;
- if (test_thread_flag(TIF_32BIT)) {
- regs->tpc &= 0xffffffff;
- regs->tnpc &= 0xffffffff;
- }
- err |= __get_user(regs->y, &((*gr)[SVR4_Y]));
- err |= __get_user(psr, &((*gr)[SVR4_PSR]));
- regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
- regs->tstate |= psr_to_tstate_icc(psr);
-
- /* Restore g[1..7] and o[0..7] registers */
- for (i = 0; i < 7; i++)
- err |= __get_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
- for (i = 0; i < 8; i++)
- err |= __get_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
- if (err)
- goto sigsegv;
-
- return -EINTR;
-sigsegv:
- return -EFAULT;
-}
-
static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
unsigned long signr, sigset_t *oldset,
siginfo_t *info)
@@ -1216,20 +705,13 @@ sigsegv:
static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info,
- sigset_t *oldset, struct pt_regs *regs,
- int svr4_signal)
+ sigset_t *oldset, struct pt_regs *regs)
{
- if (svr4_signal)
- setup_svr4_frame32(&ka->sa, regs->tpc, regs->tnpc,
- regs, signr, oldset);
- else {
- if (ka->sa.sa_flags & SA_SIGINFO)
- setup_rt_frame32(ka, regs, signr, oldset, info);
- else if (test_thread_flag(TIF_NEWSIGNALS))
- new_setup_frame32(ka, regs, signr, oldset);
- else
- setup_frame32(&ka->sa, regs, signr, oldset, info);
- }
+ if (ka->sa.sa_flags & SA_SIGINFO)
+ setup_rt_frame32(ka, regs, signr, oldset, info);
+ else
+ setup_frame32(ka, regs, signr, oldset);
+
spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NOMASK))
@@ -1264,23 +746,17 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
* mistake.
*/
void do_signal32(sigset_t *oldset, struct pt_regs * regs,
- unsigned long orig_i0, int restart_syscall)
+ struct signal_deliver_cookie *cookie)
{
- siginfo_t info;
- struct signal_deliver_cookie cookie;
struct k_sigaction ka;
+ siginfo_t info;
int signr;
- int svr4_signal = current->personality == PER_SVR4;
- cookie.restart_syscall = restart_syscall;
- cookie.orig_i0 = orig_i0;
-
- signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
+ signr = get_signal_to_deliver(&info, &ka, regs, cookie);
if (signr > 0) {
- if (cookie.restart_syscall)
- syscall_restart32(orig_i0, regs, &ka.sa);
- handle_signal32(signr, &ka, &info, oldset,
- regs, svr4_signal);
+ if (cookie->restart_syscall)
+ syscall_restart32(cookie->orig_i0, regs, &ka.sa);
+ handle_signal32(signr, &ka, &info, oldset, regs);
/* a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
@@ -1291,16 +767,16 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
clear_thread_flag(TIF_RESTORE_SIGMASK);
return;
}
- if (cookie.restart_syscall &&
+ if (cookie->restart_syscall &&
(regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
regs->u_regs[UREG_I0] == ERESTARTSYS ||
regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
/* replay the system call when we are done */
- regs->u_regs[UREG_I0] = cookie.orig_i0;
+ regs->u_regs[UREG_I0] = cookie->orig_i0;
regs->tpc -= 4;
regs->tnpc -= 4;
}
- if (cookie.restart_syscall &&
+ if (cookie->restart_syscall &&
regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
regs->u_regs[UREG_G1] = __NR_restart_syscall;
regs->tpc -= 4;
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index a8052b76df41..409dd71f2738 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -1,6 +1,6 @@
/* smp.c: Sparc64 SMP support.
*
- * Copyright (C) 1997, 2007 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1997, 2007, 2008 David S. Miller (davem@davemloft.net)
*/
#include <linux/module.h>
@@ -20,7 +20,7 @@
#include <linux/cache.h>
#include <linux/jiffies.h>
#include <linux/profile.h>
-#include <linux/bootmem.h>
+#include <linux/lmb.h>
#include <asm/head.h>
#include <asm/ptrace.h>
@@ -30,6 +30,7 @@
#include <asm/cpudata.h>
#include <asm/hvtramp.h>
#include <asm/io.h>
+#include <asm/timer.h>
#include <asm/irq.h>
#include <asm/irq_regs.h>
@@ -86,7 +87,7 @@ extern void setup_sparc64_timer(void);
static volatile unsigned long callin_flag = 0;
-void __devinit smp_callin(void)
+void __cpuinit smp_callin(void)
{
int cpuid = hard_smp_processor_id();
@@ -284,14 +285,17 @@ static void ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg)
{
extern unsigned long sparc64_ttable_tl0;
extern unsigned long kern_locked_tte_data;
- extern int bigkernel;
struct hvtramp_descr *hdesc;
unsigned long trampoline_ra;
struct trap_per_cpu *tb;
u64 tte_vaddr, tte_data;
unsigned long hv_err;
+ int i;
- hdesc = kzalloc(sizeof(*hdesc), GFP_KERNEL);
+ hdesc = kzalloc(sizeof(*hdesc) +
+ (sizeof(struct hvtramp_mapping) *
+ num_kernel_image_mappings - 1),
+ GFP_KERNEL);
if (!hdesc) {
printk(KERN_ERR "ldom_startcpu_cpuid: Cannot allocate "
"hvtramp_descr.\n");
@@ -299,7 +303,7 @@ static void ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg)
}
hdesc->cpu = cpu;
- hdesc->num_mappings = (bigkernel ? 2 : 1);
+ hdesc->num_mappings = num_kernel_image_mappings;
tb = &trap_block[cpu];
tb->hdesc = hdesc;
@@ -312,13 +316,11 @@ static void ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg)
tte_vaddr = (unsigned long) KERNBASE;
tte_data = kern_locked_tte_data;
- hdesc->maps[0].vaddr = tte_vaddr;
- hdesc->maps[0].tte = tte_data;
- if (bigkernel) {
+ for (i = 0; i < hdesc->num_mappings; i++) {
+ hdesc->maps[i].vaddr = tte_vaddr;
+ hdesc->maps[i].tte = tte_data;
tte_vaddr += 0x400000;
tte_data += 0x400000;
- hdesc->maps[1].vaddr = tte_vaddr;
- hdesc->maps[1].tte = tte_data;
}
trampoline_ra = kimage_addr_to_ra(hv_cpu_startup);
@@ -864,14 +866,21 @@ void smp_call_function_client(int irq, struct pt_regs *regs)
void *info = call_data->info;
clear_softint(1 << irq);
+
+ irq_enter();
+
+ if (!call_data->wait) {
+ /* let initiator proceed after getting data */
+ atomic_inc(&call_data->finished);
+ }
+
+ func(info);
+
+ irq_exit();
+
if (call_data->wait) {
/* let initiator proceed only after completion */
- func(info);
atomic_inc(&call_data->finished);
- } else {
- /* let initiator proceed after getting data */
- atomic_inc(&call_data->finished);
- func(info);
}
}
@@ -1030,7 +1039,9 @@ void smp_receive_signal(int cpu)
void smp_receive_signal_client(int irq, struct pt_regs *regs)
{
+ irq_enter();
clear_softint(1 << irq);
+ irq_exit();
}
void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
@@ -1038,6 +1049,8 @@ void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
struct mm_struct *mm;
unsigned long flags;
+ irq_enter();
+
clear_softint(1 << irq);
/* See if we need to allocate a new TLB context because
@@ -1057,6 +1070,8 @@ void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
load_secondary_context(mm);
__flush_tlb_mm(CTX_HWBITS(mm->context),
SECONDARY_CONTEXT);
+
+ irq_exit();
}
void smp_new_mmu_context_version(void)
@@ -1215,6 +1230,8 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs)
{
clear_softint(1 << irq);
+ irq_enter();
+
preempt_disable();
__asm__ __volatile__("flushw");
@@ -1227,6 +1244,8 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs)
prom_world(0);
preempt_enable();
+
+ irq_exit();
}
/* /proc/profile writes can call this, don't __init it please. */
@@ -1429,7 +1448,7 @@ EXPORT_SYMBOL(__per_cpu_shift);
void __init real_setup_per_cpu_areas(void)
{
- unsigned long goal, size, i;
+ unsigned long paddr, goal, size, i;
char *ptr;
/* Copy section for each CPU (we discard the original) */
@@ -1439,8 +1458,13 @@ void __init real_setup_per_cpu_areas(void)
for (size = PAGE_SIZE; size < goal; size <<= 1UL)
__per_cpu_shift++;
- ptr = alloc_bootmem_pages(size * NR_CPUS);
+ paddr = lmb_alloc(size * NR_CPUS, PAGE_SIZE);
+ if (!paddr) {
+ prom_printf("Cannot allocate per-cpu memory.\n");
+ prom_halt();
+ }
+ ptr = __va(paddr);
__per_cpu_base = ptr - __per_cpu_start;
for (i = 0; i < NR_CPUS; i++, ptr += size)
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index 51fa773f38c9..8ac0b99f2c55 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -33,13 +33,11 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/idprom.h>
-#include <asm/svr4.h>
#include <asm/elf.h>
#include <asm/head.h>
#include <asm/smp.h>
#include <asm/mostek.h>
#include <asm/ptrace.h>
-#include <asm/user.h>
#include <asm/uaccess.h>
#include <asm/checksum.h>
#include <asm/fpumacro.h>
@@ -51,7 +49,6 @@
#endif
#ifdef CONFIG_PCI
#include <asm/ebus.h>
-#include <asm/isa.h>
#endif
#include <asm/ns87303.h>
#include <asm/timer.h>
@@ -70,16 +67,9 @@ extern void *__memscan_zero(void *, size_t);
extern void *__memscan_generic(void *, int, size_t);
extern int __memcmp(const void *, const void *, __kernel_size_t);
extern __kernel_size_t strlen(const char *);
-extern void linux_sparc_syscall(void);
-extern void rtrap(void);
extern void show_regs(struct pt_regs *);
-extern void solaris_syscall(void);
extern void syscall_trace(struct pt_regs *, int);
-extern u32 sunos_sys_table[], sys_call_table32[];
-extern void tl0_solaris(void);
extern void sys_sigsuspend(void);
-extern int svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs);
-extern int svr4_setcontext(svr4_ucontext_t *uc, struct pt_regs *regs);
extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *);
extern long sparc32_open(const char __user * filename, int flags, int mode);
@@ -90,8 +80,6 @@ extern int __ashrdi3(int, int);
extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs);
-extern unsigned int sys_call_table[];
-
extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *);
extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *,
unsigned long *);
@@ -130,12 +118,6 @@ EXPORT_SYMBOL(_mcount);
EXPORT_SYMBOL(sparc64_get_clock_tick);
-/* semaphores */
-EXPORT_SYMBOL(down);
-EXPORT_SYMBOL(down_trylock);
-EXPORT_SYMBOL(down_interruptible);
-EXPORT_SYMBOL(up);
-
/* RW semaphores */
EXPORT_SYMBOL(__down_read);
EXPORT_SYMBOL(__down_read_trylock);
@@ -204,7 +186,6 @@ EXPORT_SYMBOL(insw);
EXPORT_SYMBOL(insl);
#ifdef CONFIG_PCI
EXPORT_SYMBOL(ebus_chain);
-EXPORT_SYMBOL(isa_chain);
EXPORT_SYMBOL(pci_alloc_consistent);
EXPORT_SYMBOL(pci_free_consistent);
EXPORT_SYMBOL(pci_map_single);
@@ -219,11 +200,6 @@ EXPORT_SYMBOL(pci_dma_supported);
/* I/O device mmaping on Sparc64. */
EXPORT_SYMBOL(io_remap_pfn_range);
-#if defined(CONFIG_COMPAT) && defined(CONFIG_NET)
-/* Solaris/SunOS binary compatibility */
-EXPORT_SYMBOL(verify_compat_iovec);
-#endif
-
EXPORT_SYMBOL(dump_fpu);
EXPORT_SYMBOL(put_fs_struct);
@@ -260,30 +236,6 @@ EXPORT_SYMBOL(strlen);
EXPORT_SYMBOL(__strlen_user);
EXPORT_SYMBOL(__strnlen_user);
-#ifdef CONFIG_SOLARIS_EMUL_MODULE
-EXPORT_SYMBOL(linux_sparc_syscall);
-EXPORT_SYMBOL(rtrap);
-EXPORT_SYMBOL(show_regs);
-EXPORT_SYMBOL(solaris_syscall);
-EXPORT_SYMBOL(syscall_trace);
-EXPORT_SYMBOL(sunos_sys_table);
-EXPORT_SYMBOL(sys_call_table32);
-EXPORT_SYMBOL(tl0_solaris);
-EXPORT_SYMBOL(sys_sigsuspend);
-EXPORT_SYMBOL(sys_getppid);
-EXPORT_SYMBOL(sys_getpid);
-EXPORT_SYMBOL(sys_geteuid);
-EXPORT_SYMBOL(sys_getuid);
-EXPORT_SYMBOL(sys_getegid);
-EXPORT_SYMBOL(sysctl_nr_open);
-EXPORT_SYMBOL(sys_getgid);
-EXPORT_SYMBOL(svr4_getcontext);
-EXPORT_SYMBOL(svr4_setcontext);
-EXPORT_SYMBOL(compat_sys_ioctl);
-EXPORT_SYMBOL(sys_ioctl);
-EXPORT_SYMBOL(sparc32_open);
-#endif
-
/* Special internal versions of library functions. */
EXPORT_SYMBOL(_clear_page);
EXPORT_SYMBOL(clear_user_page);
@@ -340,9 +292,6 @@ EXPORT_SYMBOL(do_BUG);
/* for ns8703 */
EXPORT_SYMBOL(ns87303_lock);
-/* for solaris compat module */
-EXPORT_SYMBOL_GPL(sys_call_table);
-
EXPORT_SYMBOL(tick_ops);
EXPORT_SYMBOL(xor_vis_2);
diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c
index 47f92a59be18..01b52f561af4 100644
--- a/arch/sparc64/kernel/stacktrace.c
+++ b/arch/sparc64/kernel/stacktrace.c
@@ -2,13 +2,15 @@
#include <linux/stacktrace.h>
#include <linux/thread_info.h>
#include <asm/ptrace.h>
+#include <asm/stacktrace.h>
void save_stack_trace(struct stack_trace *trace)
{
unsigned long ksp, fp, thread_base;
struct thread_info *tp = task_thread_info(current);
- flushw_all();
+ stack_trace_flush();
+
__asm__ __volatile__(
"mov %%fp, %0"
: "=r" (ksp)
@@ -18,6 +20,8 @@ void save_stack_trace(struct stack_trace *trace)
thread_base = (unsigned long) tp;
do {
struct reg_window *rw;
+ struct pt_regs *regs;
+ unsigned long pc;
/* Bogus frame pointer? */
if (fp < (thread_base + sizeof(struct thread_info)) ||
@@ -25,11 +29,19 @@ void save_stack_trace(struct stack_trace *trace)
break;
rw = (struct reg_window *) fp;
+ regs = (struct pt_regs *) (rw + 1);
+
+ if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) {
+ pc = regs->tpc;
+ fp = regs->u_regs[UREG_I6] + STACK_BIAS;
+ } else {
+ pc = rw->ins[7];
+ fp = rw->ins[6] + STACK_BIAS;
+ }
+
if (trace->skip > 0)
trace->skip--;
else
- trace->entries[trace->nr_entries++] = rw->ins[7];
-
- fp = rw->ins[6] + STACK_BIAS;
+ trace->entries[trace->nr_entries++] = pc;
} while (trace->nr_entries < trace->max_entries);
}
diff --git a/arch/sparc64/kernel/sun4v_tlb_miss.S b/arch/sparc64/kernel/sun4v_tlb_miss.S
index fd9430562e0b..e1fbf8c75787 100644
--- a/arch/sparc64/kernel/sun4v_tlb_miss.S
+++ b/arch/sparc64/kernel/sun4v_tlb_miss.S
@@ -262,7 +262,7 @@ sun4v_iacc:
mov %l5, %o2
call sun4v_insn_access_exception
add %sp, PTREGS_OFF, %o0
- ba,a,pt %xcc, rtrap_clr_l6
+ ba,a,pt %xcc, rtrap
/* Instruction Access Exception, tl1. */
sun4v_iacc_tl1:
@@ -278,7 +278,7 @@ sun4v_iacc_tl1:
mov %l5, %o2
call sun4v_insn_access_exception_tl1
add %sp, PTREGS_OFF, %o0
- ba,a,pt %xcc, rtrap_clr_l6
+ ba,a,pt %xcc, rtrap
/* Data Access Exception, tl0. */
sun4v_dacc:
@@ -294,7 +294,7 @@ sun4v_dacc:
mov %l5, %o2
call sun4v_data_access_exception
add %sp, PTREGS_OFF, %o0
- ba,a,pt %xcc, rtrap_clr_l6
+ ba,a,pt %xcc, rtrap
/* Data Access Exception, tl1. */
sun4v_dacc_tl1:
@@ -310,7 +310,7 @@ sun4v_dacc_tl1:
mov %l5, %o2
call sun4v_data_access_exception_tl1
add %sp, PTREGS_OFF, %o0
- ba,a,pt %xcc, rtrap_clr_l6
+ ba,a,pt %xcc, rtrap
/* Memory Address Unaligned. */
sun4v_mna:
@@ -344,7 +344,7 @@ sun4v_mna:
mov %l5, %o2
call sun4v_do_mna
add %sp, PTREGS_OFF, %o0
- ba,a,pt %xcc, rtrap_clr_l6
+ ba,a,pt %xcc, rtrap
/* Privileged Action. */
sun4v_privact:
@@ -352,7 +352,7 @@ sun4v_privact:
rd %pc, %g7
call do_privact
add %sp, PTREGS_OFF, %o0
- ba,a,pt %xcc, rtrap_clr_l6
+ ba,a,pt %xcc, rtrap
/* Unaligned ldd float, tl0. */
sun4v_lddfmna:
@@ -368,7 +368,7 @@ sun4v_lddfmna:
mov %l5, %o2
call handle_lddfmna
add %sp, PTREGS_OFF, %o0
- ba,a,pt %xcc, rtrap_clr_l6
+ ba,a,pt %xcc, rtrap
/* Unaligned std float, tl0. */
sun4v_stdfmna:
@@ -384,7 +384,7 @@ sun4v_stdfmna:
mov %l5, %o2
call handle_stdfmna
add %sp, PTREGS_OFF, %o0
- ba,a,pt %xcc, rtrap_clr_l6
+ ba,a,pt %xcc, rtrap
#define BRANCH_ALWAYS 0x10680000
#define NOP 0x01000000
diff --git a/arch/sparc64/kernel/sunos_ioctl32.c b/arch/sparc64/kernel/sunos_ioctl32.c
deleted file mode 100644
index 75d2bad49839..000000000000
--- a/arch/sparc64/kernel/sunos_ioctl32.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/* $Id: sunos_ioctl32.c,v 1.11 2000/07/30 23:12:24 davem Exp $
- * sunos_ioctl32.c: SunOS ioctl compatibility on sparc64.
- *
- * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
- * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#include <asm/uaccess.h>
-
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/termios.h>
-#include <linux/tty.h>
-#include <linux/ioctl.h>
-#include <linux/route.h>
-#include <linux/sockios.h>
-#include <linux/if.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/syscalls.h>
-#include <linux/compat.h>
-
-#define SUNOS_NR_OPEN 256
-
-struct rtentry32 {
- u32 rt_pad1;
- struct sockaddr rt_dst; /* target address */
- struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */
- struct sockaddr rt_genmask; /* target network mask (IP) */
- unsigned short rt_flags;
- short rt_pad2;
- u32 rt_pad3;
- unsigned char rt_tos;
- unsigned char rt_class;
- short rt_pad4;
- short rt_metric; /* +1 for binary compatibility! */
- /* char * */ u32 rt_dev; /* forcing the device at add */
- u32 rt_mtu; /* per route MTU/Window */
- u32 rt_window; /* Window clamping */
- unsigned short rt_irtt; /* Initial RTT */
-
-};
-
-struct ifmap32 {
- u32 mem_start;
- u32 mem_end;
- unsigned short base_addr;
- unsigned char irq;
- unsigned char dma;
- unsigned char port;
-};
-
-struct ifreq32 {
-#define IFHWADDRLEN 6
-#define IFNAMSIZ 16
- union {
- char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
- } ifr_ifrn;
- union {
- struct sockaddr ifru_addr;
- struct sockaddr ifru_dstaddr;
- struct sockaddr ifru_broadaddr;
- struct sockaddr ifru_netmask;
- struct sockaddr ifru_hwaddr;
- short ifru_flags;
- int ifru_ivalue;
- int ifru_mtu;
- struct ifmap32 ifru_map;
- char ifru_slave[IFNAMSIZ]; /* Just fits the size */
- compat_caddr_t ifru_data;
- } ifr_ifru;
-};
-
-struct ifconf32 {
- int ifc_len; /* size of buffer */
- compat_caddr_t ifcbuf;
-};
-
-extern asmlinkage int compat_sys_ioctl(unsigned int, unsigned int, u32);
-
-asmlinkage int sunos_ioctl (int fd, u32 cmd, u32 arg)
-{
- int ret = -EBADF;
-
- if(fd >= SUNOS_NR_OPEN)
- goto out;
- if(!fcheck(fd))
- goto out;
-
- if(cmd == TIOCSETD) {
- mm_segment_t old_fs = get_fs();
- int __user *p;
- int ntty = N_TTY;
- int tmp;
-
- p = (int __user *) (unsigned long) arg;
- ret = -EFAULT;
- if(get_user(tmp, p))
- goto out;
- if(tmp == 2) {
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, cmd, (unsigned long) &ntty);
- set_fs(old_fs);
- ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
- goto out;
- }
- }
- if(cmd == TIOCNOTTY) {
- ret = sys_setsid();
- goto out;
- }
- switch(cmd) {
- case _IOW('r', 10, struct rtentry32):
- ret = compat_sys_ioctl(fd, SIOCADDRT, arg);
- goto out;
- case _IOW('r', 11, struct rtentry32):
- ret = compat_sys_ioctl(fd, SIOCDELRT, arg);
- goto out;
-
- case _IOW('i', 12, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCSIFADDR, arg);
- goto out;
- case _IOWR('i', 13, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCGIFADDR, arg);
- goto out;
- case _IOW('i', 14, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCSIFDSTADDR, arg);
- goto out;
- case _IOWR('i', 15, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCGIFDSTADDR, arg);
- goto out;
- case _IOW('i', 16, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCSIFFLAGS, arg);
- goto out;
- case _IOWR('i', 17, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCGIFFLAGS, arg);
- goto out;
- case _IOW('i', 18, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCSIFMEM, arg);
- goto out;
- case _IOWR('i', 19, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCGIFMEM, arg);
- goto out;
-
- case _IOWR('i', 20, struct ifconf32):
- ret = compat_sys_ioctl(fd, SIOCGIFCONF, arg);
- goto out;
-
- case _IOW('i', 21, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCSIFMTU, arg);
- goto out;
-
- case _IOWR('i', 22, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCGIFMTU, arg);
- goto out;
-
- case _IOWR('i', 23, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCGIFBRDADDR, arg);
- goto out;
- case _IOW('i', 24, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCSIFBRDADDR, arg);
- goto out;
- case _IOWR('i', 25, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCGIFNETMASK, arg);
- goto out;
- case _IOW('i', 26, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCSIFNETMASK, arg);
- goto out;
- case _IOWR('i', 27, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCGIFMETRIC, arg);
- goto out;
- case _IOW('i', 28, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCSIFMETRIC, arg);
- goto out;
-
- case _IOW('i', 30, struct arpreq):
- ret = compat_sys_ioctl(fd, SIOCSARP, arg);
- goto out;
- case _IOWR('i', 31, struct arpreq):
- ret = compat_sys_ioctl(fd, SIOCGARP, arg);
- goto out;
- case _IOW('i', 32, struct arpreq):
- ret = compat_sys_ioctl(fd, SIOCDARP, arg);
- goto out;
-
- case _IOW('i', 40, struct ifreq32): /* SIOCUPPER */
- case _IOW('i', 41, struct ifreq32): /* SIOCLOWER */
- case _IOW('i', 44, struct ifreq32): /* SIOCSETSYNC */
- case _IOW('i', 45, struct ifreq32): /* SIOCGETSYNC */
- case _IOW('i', 46, struct ifreq32): /* SIOCSSDSTATS */
- case _IOW('i', 47, struct ifreq32): /* SIOCSSESTATS */
- case _IOW('i', 48, struct ifreq32): /* SIOCSPROMISC */
- ret = -EOPNOTSUPP;
- goto out;
-
- case _IOW('i', 49, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCADDMULTI, arg);
- goto out;
- case _IOW('i', 50, struct ifreq32):
- ret = compat_sys_ioctl(fd, SIOCDELMULTI, arg);
- goto out;
-
- /* FDDI interface ioctls, unsupported. */
-
- case _IOW('i', 51, struct ifreq32): /* SIOCFDRESET */
- case _IOW('i', 52, struct ifreq32): /* SIOCFDSLEEP */
- case _IOW('i', 53, struct ifreq32): /* SIOCSTRTFMWAR */
- case _IOW('i', 54, struct ifreq32): /* SIOCLDNSTRTFW */
- case _IOW('i', 55, struct ifreq32): /* SIOCGETFDSTAT */
- case _IOW('i', 56, struct ifreq32): /* SIOCFDNMIINT */
- case _IOW('i', 57, struct ifreq32): /* SIOCFDEXUSER */
- case _IOW('i', 58, struct ifreq32): /* SIOCFDGNETMAP */
- case _IOW('i', 59, struct ifreq32): /* SIOCFDGIOCTL */
- printk("FDDI ioctl, returning EOPNOTSUPP\n");
- ret = -EOPNOTSUPP;
- goto out;
-
- case _IOW('t', 125, int):
- /* More stupid tty sunos ioctls, just
- * say it worked.
- */
- ret = 0;
- goto out;
-
- /* Non posix grp */
- case _IOW('t', 118, int): {
- int oldval, newval, __user *ptr;
-
- cmd = TIOCSPGRP;
- ptr = (int __user *) (unsigned long) arg;
- ret = -EFAULT;
- if(get_user(oldval, ptr))
- goto out;
- ret = compat_sys_ioctl(fd, cmd, arg);
- __get_user(newval, ptr);
- if(newval == -1) {
- __put_user(oldval, ptr);
- ret = -EIO;
- }
- if(ret == -ENOTTY)
- ret = -EIO;
- goto out;
- }
-
- case _IOR('t', 119, int): {
- int oldval, newval, __user *ptr;
-
- cmd = TIOCGPGRP;
- ptr = (int __user *) (unsigned long) arg;
- ret = -EFAULT;
- if(get_user(oldval, ptr))
- goto out;
- ret = compat_sys_ioctl(fd, cmd, arg);
- __get_user(newval, ptr);
- if(newval == -1) {
- __put_user(oldval, ptr);
- ret = -EIO;
- }
- if(ret == -ENOTTY)
- ret = -EIO;
- goto out;
- }
- };
-
- ret = compat_sys_ioctl(fd, cmd, arg);
- /* so stupid... */
- ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
-out:
- return ret;
-}
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index 134d801579f9..8d4761f15fa9 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -1,5 +1,4 @@
-/* $Id: sys_sparc.c,v 1.57 2002/02/09 19:49:30 davem Exp $
- * linux/arch/sparc64/kernel/sys_sparc.c
+/* linux/arch/sparc64/kernel/sys_sparc.c
*
* This file contains various random system calls that
* have a non-standard calling sequence on the Linux/sparc
@@ -30,6 +29,9 @@
#include <asm/perfctr.h>
#include <asm/unistd.h>
+#include "entry.h"
+#include "systbls.h"
+
/* #define DEBUG_UNIMP_SYSCALL */
asmlinkage unsigned long sys_getpagesize(void)
@@ -445,14 +447,15 @@ asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second,
goto out;
case SEMTIMEDOP:
err = sys_semtimedop(first, ptr, (unsigned)second,
- (const struct timespec __user *) fifth);
+ (const struct timespec __user *)
+ (unsigned long) fifth);
goto out;
case SEMGET:
err = sys_semget(first, (int)second, (int)third);
goto out;
case SEMCTL: {
- err = sys_semctl(first, third,
- (int)second | IPC_64,
+ err = sys_semctl(first, second,
+ (int)third | IPC_64,
(union semun) ptr);
goto out;
}
@@ -717,44 +720,6 @@ out:
return err;
}
-asmlinkage long solaris_syscall(struct pt_regs *regs)
-{
- static int count;
-
- regs->tpc = regs->tnpc;
- regs->tnpc += 4;
- if (test_thread_flag(TIF_32BIT)) {
- regs->tpc &= 0xffffffff;
- regs->tnpc &= 0xffffffff;
- }
- if (++count <= 5) {
- printk ("For Solaris binary emulation you need solaris module loaded\n");
- show_regs (regs);
- }
- send_sig(SIGSEGV, current, 1);
-
- return -ENOSYS;
-}
-
-#ifndef CONFIG_SUNOS_EMUL
-asmlinkage long sunos_syscall(struct pt_regs *regs)
-{
- static int count;
-
- regs->tpc = regs->tnpc;
- regs->tnpc += 4;
- if (test_thread_flag(TIF_32BIT)) {
- regs->tpc &= 0xffffffff;
- regs->tnpc &= 0xffffffff;
- }
- if (++count <= 20)
- printk ("SunOS binary emulation not compiled in\n");
- force_sig(SIGSEGV, current);
-
- return -ENOSYS;
-}
-#endif
-
asmlinkage long sys_utrap_install(utrap_entry_t type,
utrap_handler_t new_p,
utrap_handler_t new_d,
@@ -788,7 +753,7 @@ asmlinkage long sys_utrap_install(utrap_entry_t type,
} else {
if ((utrap_handler_t)current_thread_info()->utraps[type] != new_p &&
current_thread_info()->utraps[0] > 1) {
- long *p = current_thread_info()->utraps;
+ unsigned long *p = current_thread_info()->utraps;
current_thread_info()->utraps =
kmalloc((UT_TRAP_INSTRUCTION_31+1)*sizeof(long),
@@ -816,7 +781,8 @@ asmlinkage long sys_utrap_install(utrap_entry_t type,
return 0;
}
-long sparc_memory_ordering(unsigned long model, struct pt_regs *regs)
+asmlinkage long sparc_memory_ordering(unsigned long model,
+ struct pt_regs *regs)
{
if (model >= 3)
return -EINVAL;
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index deaba2bd0535..161ce4710fe7 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -55,7 +55,6 @@
#include <asm/types.h>
#include <asm/uaccess.h>
#include <asm/fpumacro.h>
-#include <asm/semaphore.h>
#include <asm/mmu_context.h>
#include <asm/compat_signal.h>
@@ -555,10 +554,8 @@ asmlinkage long compat_sys_sigaction(int sig, struct old_sigaction32 __user *act
struct k_sigaction new_ka, old_ka;
int ret;
- if (sig < 0) {
- set_thread_flag(TIF_NEWSIGNALS);
- sig = -sig;
- }
+ WARN_ON_ONCE(sig >= 0);
+ sig = -sig;
if (act) {
compat_old_sigset_t mask;
@@ -602,11 +599,6 @@ asmlinkage long compat_sys_rt_sigaction(int sig,
if (sigsetsize != sizeof(compat_sigset_t))
return -EINVAL;
- /* All tasks which use RT signals (effectively) use
- * new style signals.
- */
- set_thread_flag(TIF_NEWSIGNALS);
-
if (act) {
u32 u_handler, u_restorer;
@@ -678,9 +670,6 @@ asmlinkage long sparc32_execve(struct pt_regs *regs)
current_thread_info()->xfsr[0] = 0;
current_thread_info()->fpsaved[0] = 0;
regs->tstate &= ~TSTATE_PEF;
- task_lock(current);
- current->ptrace &= ~PT_DTRACE;
- task_unlock(current);
}
out:
return error;
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
deleted file mode 100644
index cfc22d3fe54c..000000000000
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ /dev/null
@@ -1,1359 +0,0 @@
-/* $Id: sys_sunos32.c,v 1.64 2002/02/09 19:49:31 davem Exp $
- * sys_sunos32.c: SunOS binary compatibility layer on sparc64.
- *
- * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
- *
- * Based upon preliminary work which is:
- *
- * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/capability.h>
-#include <linux/compat.h>
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/resource.h>
-#include <linux/ipc.h>
-#include <linux/shm.h>
-#include <linux/msg.h>
-#include <linux/sem.h>
-#include <linux/signal.h>
-#include <linux/uio.h>
-#include <linux/utsname.h>
-#include <linux/major.h>
-#include <linux/stat.h>
-#include <linux/slab.h>
-#include <linux/pagemap.h>
-#include <linux/errno.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/syscalls.h>
-
-#include <asm/uaccess.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/pconf.h>
-#include <asm/idprom.h> /* for gethostid() */
-#include <asm/unistd.h>
-#include <asm/system.h>
-#include <asm/compat_signal.h>
-
-/* For the nfs mount emulation */
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/nfs.h>
-#include <linux/nfs2.h>
-#include <linux/nfs_mount.h>
-
-/* for sunos_select */
-#include <linux/time.h>
-#include <linux/personality.h>
-
-/* For SOCKET_I */
-#include <net/sock.h>
-#include <net/compat.h>
-
-#define SUNOS_NR_OPEN 256
-
-asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off)
-{
- struct file *file = NULL;
- unsigned long retval, ret_type;
-
- if (flags & MAP_NORESERVE) {
- static int cnt;
- if (cnt++ < 10)
- printk("%s: unimplemented SunOS MAP_NORESERVE mmap() flag\n",
- current->comm);
- flags &= ~MAP_NORESERVE;
- }
- retval = -EBADF;
- if (!(flags & MAP_ANONYMOUS)) {
- struct inode * inode;
- if (fd >= SUNOS_NR_OPEN)
- goto out;
- file = fget(fd);
- if (!file)
- goto out;
- inode = file->f_path.dentry->d_inode;
- if (imajor(inode) == MEM_MAJOR && iminor(inode) == 5) {
- flags |= MAP_ANONYMOUS;
- fput(file);
- file = NULL;
- }
- }
-
- retval = -EINVAL;
- if (!(flags & MAP_FIXED))
- addr = 0;
- else if (len > 0xf0000000 || addr > 0xf0000000 - len)
- goto out_putf;
- ret_type = flags & _MAP_NEW;
- flags &= ~_MAP_NEW;
-
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- down_write(&current->mm->mmap_sem);
- retval = do_mmap(file,
- (unsigned long) addr, (unsigned long) len,
- (unsigned long) prot, (unsigned long) flags,
- (unsigned long) off);
- up_write(&current->mm->mmap_sem);
- if (!ret_type)
- retval = ((retval < 0xf0000000) ? 0 : retval);
-out_putf:
- if (file)
- fput(file);
-out:
- return (u32) retval;
-}
-
-asmlinkage int sunos_mctl(u32 addr, u32 len, int function, u32 arg)
-{
- return 0;
-}
-
-asmlinkage int sunos_brk(u32 baddr)
-{
- int freepages, retval = -ENOMEM;
- unsigned long rlim;
- unsigned long newbrk, oldbrk, brk = (unsigned long) baddr;
-
- down_write(&current->mm->mmap_sem);
- if (brk < current->mm->end_code)
- goto out;
- newbrk = PAGE_ALIGN(brk);
- oldbrk = PAGE_ALIGN(current->mm->brk);
- retval = 0;
- if (oldbrk == newbrk) {
- current->mm->brk = brk;
- goto out;
- }
- /* Always allow shrinking brk. */
- if (brk <= current->mm->brk) {
- current->mm->brk = brk;
- do_munmap(current->mm, newbrk, oldbrk-newbrk);
- goto out;
- }
- /* Check against rlimit and stack.. */
- retval = -ENOMEM;
- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
- if (rlim >= RLIM_INFINITY)
- rlim = ~0;
- if (brk - current->mm->end_code > rlim)
- goto out;
- /* Check against existing mmap mappings. */
- if (find_vma_intersection(current->mm, oldbrk, newbrk+PAGE_SIZE))
- goto out;
- /* stupid algorithm to decide if we have enough memory: while
- * simple, it hopefully works in most obvious cases.. Easy to
- * fool it, but this should catch most mistakes.
- */
- freepages = global_page_state(NR_FILE_PAGES);
- freepages >>= 1;
- freepages += nr_free_pages();
- freepages += nr_swap_pages;
- freepages -= num_physpages >> 4;
- freepages -= (newbrk-oldbrk) >> PAGE_SHIFT;
- if (freepages < 0)
- goto out;
- /* Ok, we have probably got enough memory - let it rip. */
- current->mm->brk = brk;
- do_brk(oldbrk, newbrk-oldbrk);
- retval = 0;
-out:
- up_write(&current->mm->mmap_sem);
- return retval;
-}
-
-asmlinkage u32 sunos_sbrk(int increment)
-{
- int error, oldbrk;
-
- /* This should do it hopefully... */
- oldbrk = (int)current->mm->brk;
- error = sunos_brk(((int) current->mm->brk) + increment);
- if (!error)
- error = oldbrk;
- return error;
-}
-
-asmlinkage u32 sunos_sstk(int increment)
-{
- printk("%s: Call to sunos_sstk(increment<%d>) is unsupported\n",
- current->comm, increment);
-
- return (u32)-1;
-}
-
-/* Give hints to the kernel as to what paging strategy to use...
- * Completely bogus, don't remind me.
- */
-#define VA_NORMAL 0 /* Normal vm usage expected */
-#define VA_ABNORMAL 1 /* Abnormal/random vm usage probable */
-#define VA_SEQUENTIAL 2 /* Accesses will be of a sequential nature */
-#define VA_INVALIDATE 3 /* Page table entries should be flushed ??? */
-static char *vstrings[] = {
- "VA_NORMAL",
- "VA_ABNORMAL",
- "VA_SEQUENTIAL",
- "VA_INVALIDATE",
-};
-
-asmlinkage void sunos_vadvise(u32 strategy)
-{
- static int count;
-
- /* I wanna see who uses this... */
- if (count++ < 5)
- printk("%s: Advises us to use %s paging strategy\n",
- current->comm,
- strategy <= 3 ? vstrings[strategy] : "BOGUS");
-}
-
-/* This just wants the soft limit (ie. rlim_cur element) of the RLIMIT_NOFILE
- * resource limit and is for backwards compatibility with older sunos
- * revs.
- */
-asmlinkage int sunos_getdtablesize(void)
-{
- return SUNOS_NR_OPEN;
-}
-
-
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
-asmlinkage u32 sunos_sigblock(u32 blk_mask)
-{
- u32 old;
-
- spin_lock_irq(&current->sighand->siglock);
- old = (u32) current->blocked.sig[0];
- current->blocked.sig[0] |= (blk_mask & _BLOCKABLE);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
- return old;
-}
-
-asmlinkage u32 sunos_sigsetmask(u32 newmask)
-{
- u32 retval;
-
- spin_lock_irq(&current->sighand->siglock);
- retval = (u32) current->blocked.sig[0];
- current->blocked.sig[0] = (newmask & _BLOCKABLE);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
- return retval;
-}
-
-/* SunOS getdents is very similar to the newer Linux (iBCS2 compliant) */
-/* getdents system call, the format of the structure just has a different */
-/* layout (d_off+d_ino instead of d_ino+d_off) */
-struct sunos_dirent {
- s32 d_off;
- u32 d_ino;
- u16 d_reclen;
- u16 d_namlen;
- char d_name[1];
-};
-
-struct sunos_dirent_callback {
- struct sunos_dirent __user *curr;
- struct sunos_dirent __user *previous;
- int count;
- int error;
-};
-
-#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
-#define ROUND_UP(x) (((x)+sizeof(s32)-1) & ~(sizeof(s32)-1))
-
-static int sunos_filldir(void * __buf, const char * name, int namlen,
- loff_t offset, ino_t ino, unsigned int d_type)
-{
- struct sunos_dirent __user *dirent;
- struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf;
- int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
- u32 d_ino;
-
- buf->error = -EINVAL; /* only used if we fail.. */
- if (reclen > buf->count)
- return -EINVAL;
- d_ino = ino;
- if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
- return -EOVERFLOW;
- dirent = buf->previous;
- if (dirent)
- put_user(offset, &dirent->d_off);
- dirent = buf->curr;
- buf->previous = dirent;
- put_user(d_ino, &dirent->d_ino);
- put_user(namlen, &dirent->d_namlen);
- put_user(reclen, &dirent->d_reclen);
- if (copy_to_user(dirent->d_name, name, namlen))
- return -EFAULT;
- put_user(0, dirent->d_name + namlen);
- dirent = (void __user *) dirent + reclen;
- buf->curr = dirent;
- buf->count -= reclen;
- return 0;
-}
-
-asmlinkage int sunos_getdents(unsigned int fd, void __user *dirent, int cnt)
-{
- struct file * file;
- struct sunos_dirent __user *lastdirent;
- struct sunos_dirent_callback buf;
- int error = -EBADF;
-
- if (fd >= SUNOS_NR_OPEN)
- goto out;
-
- file = fget(fd);
- if (!file)
- goto out;
-
- error = -EINVAL;
- if (cnt < (sizeof(struct sunos_dirent) + 255))
- goto out_putf;
-
- buf.curr = (struct sunos_dirent __user *) dirent;
- buf.previous = NULL;
- buf.count = cnt;
- buf.error = 0;
-
- error = vfs_readdir(file, sunos_filldir, &buf);
- if (error < 0)
- goto out_putf;
-
- lastdirent = buf.previous;
- error = buf.error;
- if (lastdirent) {
- put_user(file->f_pos, &lastdirent->d_off);
- error = cnt - buf.count;
- }
-
-out_putf:
- fput(file);
-out:
- return error;
-}
-
-/* Old sunos getdirentries, severely broken compatibility stuff here. */
-struct sunos_direntry {
- u32 d_ino;
- u16 d_reclen;
- u16 d_namlen;
- char d_name[1];
-};
-
-struct sunos_direntry_callback {
- struct sunos_direntry __user *curr;
- struct sunos_direntry __user *previous;
- int count;
- int error;
-};
-
-static int sunos_filldirentry(void * __buf, const char * name, int namlen,
- loff_t offset, ino_t ino, unsigned int d_type)
-{
- struct sunos_direntry __user *dirent;
- struct sunos_direntry_callback * buf =
- (struct sunos_direntry_callback *) __buf;
- int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
- u32 d_ino;
-
- buf->error = -EINVAL; /* only used if we fail.. */
- if (reclen > buf->count)
- return -EINVAL;
- d_ino = ino;
- if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
- return -EOVERFLOW;
- dirent = buf->previous;
- dirent = buf->curr;
- buf->previous = dirent;
- put_user(d_ino, &dirent->d_ino);
- put_user(namlen, &dirent->d_namlen);
- put_user(reclen, &dirent->d_reclen);
- if (copy_to_user(dirent->d_name, name, namlen))
- return -EFAULT;
- put_user(0, dirent->d_name + namlen);
- dirent = (void __user *) dirent + reclen;
- buf->curr = dirent;
- buf->count -= reclen;
- return 0;
-}
-
-asmlinkage int sunos_getdirentries(unsigned int fd,
- void __user *dirent,
- int cnt,
- unsigned int __user *basep)
-{
- struct file * file;
- struct sunos_direntry __user *lastdirent;
- int error = -EBADF;
- struct sunos_direntry_callback buf;
-
- if (fd >= SUNOS_NR_OPEN)
- goto out;
-
- file = fget(fd);
- if (!file)
- goto out;
-
- error = -EINVAL;
- if (cnt < (sizeof(struct sunos_direntry) + 255))
- goto out_putf;
-
- buf.curr = (struct sunos_direntry __user *) dirent;
- buf.previous = NULL;
- buf.count = cnt;
- buf.error = 0;
-
- error = vfs_readdir(file, sunos_filldirentry, &buf);
- if (error < 0)
- goto out_putf;
-
- lastdirent = buf.previous;
- error = buf.error;
- if (lastdirent) {
- put_user(file->f_pos, basep);
- error = cnt - buf.count;
- }
-
-out_putf:
- fput(file);
-out:
- return error;
-}
-
-struct sunos_utsname {
- char sname[9];
- char nname[9];
- char nnext[56];
- char rel[9];
- char ver[9];
- char mach[9];
-};
-
-asmlinkage int sunos_uname(struct sunos_utsname __user *name)
-{
- int ret;
-
- down_read(&uts_sem);
- ret = copy_to_user(&name->sname[0], &utsname()->sysname[0],
- sizeof(name->sname) - 1);
- ret |= copy_to_user(&name->nname[0], &utsname()->nodename[0],
- sizeof(name->nname) - 1);
- ret |= put_user('\0', &name->nname[8]);
- ret |= copy_to_user(&name->rel[0], &utsname()->release[0],
- sizeof(name->rel) - 1);
- ret |= copy_to_user(&name->ver[0], &utsname()->version[0],
- sizeof(name->ver) - 1);
- ret |= copy_to_user(&name->mach[0], &utsname()->machine[0],
- sizeof(name->mach) - 1);
- up_read(&uts_sem);
- return (ret ? -EFAULT : 0);
-}
-
-asmlinkage int sunos_nosys(void)
-{
- struct pt_regs *regs;
- siginfo_t info;
- static int cnt;
-
- regs = current_thread_info()->kregs;
- if (test_thread_flag(TIF_32BIT)) {
- regs->tpc &= 0xffffffff;
- regs->tnpc &= 0xffffffff;
- }
- info.si_signo = SIGSYS;
- info.si_errno = 0;
- info.si_code = __SI_FAULT|0x100;
- info.si_addr = (void __user *)regs->tpc;
- info.si_trapno = regs->u_regs[UREG_G1];
- send_sig_info(SIGSYS, &info, current);
- if (cnt++ < 4) {
- printk("Process makes ni_syscall number %d, register dump:\n",
- (int) regs->u_regs[UREG_G1]);
- show_regs(regs);
- }
- return -ENOSYS;
-}
-
-/* This is not a real and complete implementation yet, just to keep
- * the easy SunOS binaries happy.
- */
-asmlinkage int sunos_fpathconf(int fd, int name)
-{
- int ret;
-
- switch(name) {
- case _PCONF_LINK:
- ret = LINK_MAX;
- break;
- case _PCONF_CANON:
- ret = MAX_CANON;
- break;
- case _PCONF_INPUT:
- ret = MAX_INPUT;
- break;
- case _PCONF_NAME:
- ret = NAME_MAX;
- break;
- case _PCONF_PATH:
- ret = PATH_MAX;
- break;
- case _PCONF_PIPE:
- ret = PIPE_BUF;
- break;
- case _PCONF_CHRESTRICT: /* XXX Investigate XXX */
- ret = 1;
- break;
- case _PCONF_NOTRUNC: /* XXX Investigate XXX */
- case _PCONF_VDISABLE:
- ret = 0;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
-asmlinkage int sunos_pathconf(u32 u_path, int name)
-{
- int ret;
-
- ret = sunos_fpathconf(0, name); /* XXX cheese XXX */
- return ret;
-}
-
-asmlinkage int sunos_select(int width, u32 inp, u32 outp, u32 exp, u32 tvp_x)
-{
- int ret;
-
- /* SunOS binaries expect that select won't change the tvp contents */
- ret = compat_sys_select(width, compat_ptr(inp), compat_ptr(outp),
- compat_ptr(exp), compat_ptr(tvp_x));
- if (ret == -EINTR && tvp_x) {
- struct compat_timeval __user *tvp = compat_ptr(tvp_x);
- time_t sec, usec;
-
- __get_user(sec, &tvp->tv_sec);
- __get_user(usec, &tvp->tv_usec);
- if (sec == 0 && usec == 0)
- ret = 0;
- }
- return ret;
-}
-
-asmlinkage void sunos_nop(void)
-{
- return;
-}
-
-#if 0 /* This code doesn't translate user pointers correctly,
- * disable for now. -DaveM
- */
-
-/* XXXXXXXXXX SunOS mount/umount. XXXXXXXXXXX */
-#define SMNT_RDONLY 1
-#define SMNT_NOSUID 2
-#define SMNT_NEWTYPE 4
-#define SMNT_GRPID 8
-#define SMNT_REMOUNT 16
-#define SMNT_NOSUB 32
-#define SMNT_MULTI 64
-#define SMNT_SYS5 128
-
-struct sunos_fh_t {
- char fh_data [NFS_FHSIZE];
-};
-
-struct sunos_nfs_mount_args {
- struct sockaddr_in *addr; /* file server address */
- struct nfs_fh *fh; /* File handle to be mounted */
- int flags; /* flags */
- int wsize; /* write size in bytes */
- int rsize; /* read size in bytes */
- int timeo; /* initial timeout in .1 secs */
- int retrans; /* times to retry send */
- char *hostname; /* server's hostname */
- int acregmin; /* attr cache file min secs */
- int acregmax; /* attr cache file max secs */
- int acdirmin; /* attr cache dir min secs */
- int acdirmax; /* attr cache dir max secs */
- char *netname; /* server's netname */
-};
-
-
-/* Bind the socket on a local reserved port and connect it to the
- * remote server. This on Linux/i386 is done by the mount program,
- * not by the kernel.
- */
-/* XXXXXXXXXXXXXXXXXXXX */
-static int
-sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr)
-{
- struct sockaddr_in local;
- struct sockaddr_in server;
- int try_port;
- int ret;
- struct socket *socket;
- struct inode *inode;
- struct file *file;
-
- file = fget(fd);
- if (!file)
- return 0;
-
- inode = file->f_path.dentry->d_inode;
-
- socket = SOCKET_I(inode);
- local.sin_family = AF_INET;
- local.sin_addr.s_addr = INADDR_ANY;
-
- /* IPPORT_RESERVED = 1024, can't find the definition in the kernel */
- try_port = 1024;
- do {
- local.sin_port = htons (--try_port);
- ret = socket->ops->bind(socket, (struct sockaddr*)&local,
- sizeof(local));
- } while (ret && try_port > (1024 / 2));
-
- if (ret) {
- fput(file);
- return 0;
- }
-
- server.sin_family = AF_INET;
- server.sin_addr = addr->sin_addr;
- server.sin_port = NFS_PORT;
-
- /* Call sys_connect */
- ret = socket->ops->connect (socket, (struct sockaddr *) &server,
- sizeof (server), file->f_flags);
- fput(file);
- if (ret < 0)
- return 0;
- return 1;
-}
-
-/* XXXXXXXXXXXXXXXXXXXX */
-static int get_default (int value, int def_value)
-{
- if (value)
- return value;
- else
- return def_value;
-}
-
-/* XXXXXXXXXXXXXXXXXXXX */
-static int sunos_nfs_mount(char *dir_name, int linux_flags, void __user *data)
-{
- int server_fd, err;
- char *the_name, *mount_page;
- struct nfs_mount_data linux_nfs_mount;
- struct sunos_nfs_mount_args sunos_mount;
-
- /* Ok, here comes the fun part: Linux's nfs mount needs a
- * socket connection to the server, but SunOS mount does not
- * require this, so we use the information on the destination
- * address to create a socket and bind it to a reserved
- * port on this system
- */
- if (copy_from_user(&sunos_mount, data, sizeof(sunos_mount)))
- return -EFAULT;
-
- server_fd = sys_socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (server_fd < 0)
- return -ENXIO;
-
- if (copy_from_user(&linux_nfs_mount.addr, sunos_mount.addr,
- sizeof(*sunos_mount.addr)) ||
- copy_from_user(&linux_nfs_mount.root, sunos_mount.fh,
- sizeof(*sunos_mount.fh))) {
- sys_close (server_fd);
- return -EFAULT;
- }
-
- if (!sunos_nfs_get_server_fd (server_fd, &linux_nfs_mount.addr)){
- sys_close (server_fd);
- return -ENXIO;
- }
-
- /* Now, bind it to a locally reserved port */
- linux_nfs_mount.version = NFS_MOUNT_VERSION;
- linux_nfs_mount.flags = sunos_mount.flags;
- linux_nfs_mount.fd = server_fd;
-
- linux_nfs_mount.rsize = get_default (sunos_mount.rsize, 8192);
- linux_nfs_mount.wsize = get_default (sunos_mount.wsize, 8192);
- linux_nfs_mount.timeo = get_default (sunos_mount.timeo, 10);
- linux_nfs_mount.retrans = sunos_mount.retrans;
-
- linux_nfs_mount.acregmin = sunos_mount.acregmin;
- linux_nfs_mount.acregmax = sunos_mount.acregmax;
- linux_nfs_mount.acdirmin = sunos_mount.acdirmin;
- linux_nfs_mount.acdirmax = sunos_mount.acdirmax;
-
- the_name = getname(sunos_mount.hostname);
- if (IS_ERR(the_name))
- return PTR_ERR(the_name);
-
- strlcpy(linux_nfs_mount.hostname, the_name,
- sizeof(linux_nfs_mount.hostname));
- putname (the_name);
-
- mount_page = (char *) get_zeroed_page(GFP_KERNEL);
- if (!mount_page)
- return -ENOMEM;
-
- memcpy(mount_page, &linux_nfs_mount, sizeof(linux_nfs_mount));
-
- err = do_mount("", dir_name, "nfs", linux_flags, mount_page);
-
- free_page((unsigned long) mount_page);
- return err;
-}
-
-/* XXXXXXXXXXXXXXXXXXXX */
-asmlinkage int
-sunos_mount(char *type, char *dir, int flags, void *data)
-{
- int linux_flags = 0;
- int ret = -EINVAL;
- char *dev_fname = 0;
- char *dir_page, *type_page;
-
- if (!capable (CAP_SYS_ADMIN))
- return -EPERM;
-
- /* We don't handle the integer fs type */
- if ((flags & SMNT_NEWTYPE) == 0)
- goto out;
-
- /* Do not allow for those flags we don't support */
- if (flags & (SMNT_GRPID|SMNT_NOSUB|SMNT_MULTI|SMNT_SYS5))
- goto out;
-
- if (flags & SMNT_REMOUNT)
- linux_flags |= MS_REMOUNT;
- if (flags & SMNT_RDONLY)
- linux_flags |= MS_RDONLY;
- if (flags & SMNT_NOSUID)
- linux_flags |= MS_NOSUID;
-
- dir_page = getname(dir);
- ret = PTR_ERR(dir_page);
- if (IS_ERR(dir_page))
- goto out;
-
- type_page = getname(type);
- ret = PTR_ERR(type_page);
- if (IS_ERR(type_page))
- goto out1;
-
- if (strcmp(type_page, "ext2") == 0) {
- dev_fname = getname(data);
- } else if (strcmp(type_page, "iso9660") == 0) {
- dev_fname = getname(data);
- } else if (strcmp(type_page, "minix") == 0) {
- dev_fname = getname(data);
- } else if (strcmp(type_page, "nfs") == 0) {
- ret = sunos_nfs_mount (dir_page, flags, data);
- goto out2;
- } else if (strcmp(type_page, "ufs") == 0) {
- printk("Warning: UFS filesystem mounts unsupported.\n");
- ret = -ENODEV;
- goto out2;
- } else if (strcmp(type_page, "proc")) {
- ret = -ENODEV;
- goto out2;
- }
- ret = PTR_ERR(dev_fname);
- if (IS_ERR(dev_fname))
- goto out2;
- lock_kernel();
- ret = do_mount(dev_fname, dir_page, type_page, linux_flags, NULL);
- unlock_kernel();
- if (dev_fname)
- putname(dev_fname);
-out2:
- putname(type_page);
-out1:
- putname(dir_page);
-out:
- return ret;
-}
-#endif
-
-asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid)
-{
- int ret;
-
- /* So stupid... */
- if ((!pid || pid == current->pid) &&
- !pgid) {
- sys_setsid();
- ret = 0;
- } else {
- ret = sys_setpgid(pid, pgid);
- }
- return ret;
-}
-
-/* So stupid... */
-extern long compat_sys_wait4(compat_pid_t, compat_uint_t __user *, int,
- struct compat_rusage __user *);
-
-asmlinkage int sunos_wait4(compat_pid_t pid, compat_uint_t __user *stat_addr, int options, struct compat_rusage __user *ru)
-{
- int ret;
-
- ret = compat_sys_wait4((pid ? pid : ((compat_pid_t)-1)),
- stat_addr, options, ru);
- return ret;
-}
-
-asmlinkage int sunos_killpg(int pgrp, int sig)
-{
- int ret;
-
- rcu_read_lock();
- ret = -EINVAL;
- if (pgrp > 0)
- ret = kill_pgrp(find_vpid(pgrp), sig, 0);
- rcu_read_unlock();
-
- return ret;
-}
-
-asmlinkage int sunos_audit(void)
-{
- printk ("sys_audit\n");
- return -1;
-}
-
-asmlinkage u32 sunos_gethostid(void)
-{
- u32 ret;
-
- ret = (((u32)idprom->id_machtype << 24) | ((u32)idprom->id_sernum));
-
- return ret;
-}
-
-/* sysconf options, for SunOS compatibility */
-#define _SC_ARG_MAX 1
-#define _SC_CHILD_MAX 2
-#define _SC_CLK_TCK 3
-#define _SC_NGROUPS_MAX 4
-#define _SC_OPEN_MAX 5
-#define _SC_JOB_CONTROL 6
-#define _SC_SAVED_IDS 7
-#define _SC_VERSION 8
-
-asmlinkage s32 sunos_sysconf (int name)
-{
- s32 ret;
-
- switch (name){
- case _SC_ARG_MAX:
- ret = ARG_MAX;
- break;
- case _SC_CHILD_MAX:
- ret = current->signal->rlim[RLIMIT_NPROC].rlim_cur;
- break;
- case _SC_CLK_TCK:
- ret = HZ;
- break;
- case _SC_NGROUPS_MAX:
- ret = NGROUPS_MAX;
- break;
- case _SC_OPEN_MAX:
- ret = current->signal->rlim[RLIMIT_NOFILE].rlim_cur;
- break;
- case _SC_JOB_CONTROL:
- ret = 1; /* yes, we do support job control */
- break;
- case _SC_SAVED_IDS:
- ret = 1; /* yes, we do support saved uids */
- break;
- case _SC_VERSION:
- /* mhm, POSIX_VERSION is in /usr/include/unistd.h
- * should it go on /usr/include/linux?
- */
- ret = 199009;
- break;
- default:
- ret = -1;
- break;
- };
- return ret;
-}
-
-asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, void __user *ptr)
-{
- union semun arg4;
- int ret;
-
- switch (op) {
- case 0:
- /* Most arguments match on a 1:1 basis but cmd doesn't */
- switch(arg3) {
- case 4:
- arg3=GETPID; break;
- case 5:
- arg3=GETVAL; break;
- case 6:
- arg3=GETALL; break;
- case 3:
- arg3=GETNCNT; break;
- case 7:
- arg3=GETZCNT; break;
- case 8:
- arg3=SETVAL; break;
- case 9:
- arg3=SETALL; break;
- }
- /* sys_semctl(): */
- /* value to modify semaphore to */
- arg4.__pad = ptr;
- ret = sys_semctl((int)arg1, (int)arg2, (int)arg3, arg4);
- break;
- case 1:
- /* sys_semget(): */
- ret = sys_semget((key_t)arg1, (int)arg2, (int)arg3);
- break;
- case 2:
- /* sys_semop(): */
- ret = sys_semop((int)arg1, (struct sembuf __user *)(unsigned long)arg2,
- (unsigned int) arg3);
- break;
- default:
- ret = -EINVAL;
- break;
- };
- return ret;
-}
-
-struct msgbuf32 {
- s32 mtype;
- char mtext[1];
-};
-
-struct ipc_perm32
-{
- key_t key;
- compat_uid_t uid;
- compat_gid_t gid;
- compat_uid_t cuid;
- compat_gid_t cgid;
- compat_mode_t mode;
- unsigned short seq;
-};
-
-struct msqid_ds32
-{
- struct ipc_perm32 msg_perm;
- u32 msg_first;
- u32 msg_last;
- compat_time_t msg_stime;
- compat_time_t msg_rtime;
- compat_time_t msg_ctime;
- u32 wwait;
- u32 rwait;
- unsigned short msg_cbytes;
- unsigned short msg_qnum;
- unsigned short msg_qbytes;
- compat_ipc_pid_t msg_lspid;
- compat_ipc_pid_t msg_lrpid;
-};
-
-static inline int sunos_msqid_get(struct msqid_ds32 __user *user,
- struct msqid_ds *kern)
-{
- if (get_user(kern->msg_perm.key, &user->msg_perm.key) ||
- __get_user(kern->msg_perm.uid, &user->msg_perm.uid) ||
- __get_user(kern->msg_perm.gid, &user->msg_perm.gid) ||
- __get_user(kern->msg_perm.cuid, &user->msg_perm.cuid) ||
- __get_user(kern->msg_perm.cgid, &user->msg_perm.cgid) ||
- __get_user(kern->msg_stime, &user->msg_stime) ||
- __get_user(kern->msg_rtime, &user->msg_rtime) ||
- __get_user(kern->msg_ctime, &user->msg_ctime) ||
- __get_user(kern->msg_ctime, &user->msg_cbytes) ||
- __get_user(kern->msg_ctime, &user->msg_qnum) ||
- __get_user(kern->msg_ctime, &user->msg_qbytes) ||
- __get_user(kern->msg_ctime, &user->msg_lspid) ||
- __get_user(kern->msg_ctime, &user->msg_lrpid))
- return -EFAULT;
- return 0;
-}
-
-static inline int sunos_msqid_put(struct msqid_ds32 __user *user,
- struct msqid_ds *kern)
-{
- if (put_user(kern->msg_perm.key, &user->msg_perm.key) ||
- __put_user(kern->msg_perm.uid, &user->msg_perm.uid) ||
- __put_user(kern->msg_perm.gid, &user->msg_perm.gid) ||
- __put_user(kern->msg_perm.cuid, &user->msg_perm.cuid) ||
- __put_user(kern->msg_perm.cgid, &user->msg_perm.cgid) ||
- __put_user(kern->msg_stime, &user->msg_stime) ||
- __put_user(kern->msg_rtime, &user->msg_rtime) ||
- __put_user(kern->msg_ctime, &user->msg_ctime) ||
- __put_user(kern->msg_ctime, &user->msg_cbytes) ||
- __put_user(kern->msg_ctime, &user->msg_qnum) ||
- __put_user(kern->msg_ctime, &user->msg_qbytes) ||
- __put_user(kern->msg_ctime, &user->msg_lspid) ||
- __put_user(kern->msg_ctime, &user->msg_lrpid))
- return -EFAULT;
- return 0;
-}
-
-static inline int sunos_msgbuf_get(struct msgbuf32 __user *user, struct msgbuf *kern, int len)
-{
- if (get_user(kern->mtype, &user->mtype) ||
- __copy_from_user(kern->mtext, &user->mtext, len))
- return -EFAULT;
- return 0;
-}
-
-static inline int sunos_msgbuf_put(struct msgbuf32 __user *user, struct msgbuf *kern, int len)
-{
- if (put_user(kern->mtype, &user->mtype) ||
- __copy_to_user(user->mtext, kern->mtext, len))
- return -EFAULT;
- return 0;
-}
-
-asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
-{
- struct sparc_stackf32 __user *sp;
- struct msqid_ds kds;
- struct msgbuf *kmbuf;
- mm_segment_t old_fs = get_fs();
- u32 arg5;
- int rval;
-
- switch(op) {
- case 0:
- rval = sys_msgget((key_t)arg1, (int)arg2);
- break;
- case 1:
- if (!sunos_msqid_get((struct msqid_ds32 __user *)(unsigned long)arg3, &kds)) {
- set_fs(KERNEL_DS);
- rval = sys_msgctl((int)arg1, (int)arg2,
- (struct msqid_ds __user *)(unsigned long)arg3);
- set_fs(old_fs);
- if (!rval)
- rval = sunos_msqid_put((struct msqid_ds32 __user *)(unsigned long)arg3,
- &kds);
- } else
- rval = -EFAULT;
- break;
- case 2:
- rval = -EFAULT;
- kmbuf = kmalloc(sizeof(struct msgbuf) + arg3,
- GFP_KERNEL);
- if (!kmbuf)
- break;
- sp = (struct sparc_stackf32 __user *)
- (current_thread_info()->kregs->u_regs[UREG_FP] & 0xffffffffUL);
- if (get_user(arg5, &sp->xxargs[0])) {
- rval = -EFAULT;
- kfree(kmbuf);
- break;
- }
- set_fs(KERNEL_DS);
- rval = sys_msgrcv((int)arg1, (struct msgbuf __user *) kmbuf,
- (size_t)arg3,
- (long)arg4, (int)arg5);
- set_fs(old_fs);
- if (!rval)
- rval = sunos_msgbuf_put((struct msgbuf32 __user *)(unsigned long)arg2,
- kmbuf, arg3);
- kfree(kmbuf);
- break;
- case 3:
- rval = -EFAULT;
- kmbuf = kmalloc(sizeof(struct msgbuf) + arg3,
- GFP_KERNEL);
- if (!kmbuf || sunos_msgbuf_get((struct msgbuf32 __user *)(unsigned long)arg2,
- kmbuf, arg3))
- break;
- set_fs(KERNEL_DS);
- rval = sys_msgsnd((int)arg1, (struct msgbuf __user *) kmbuf,
- (size_t)arg3, (int)arg4);
- set_fs(old_fs);
- kfree(kmbuf);
- break;
- default:
- rval = -EINVAL;
- break;
- }
- return rval;
-}
-
-struct shmid_ds32 {
- struct ipc_perm32 shm_perm;
- int shm_segsz;
- compat_time_t shm_atime;
- compat_time_t shm_dtime;
- compat_time_t shm_ctime;
- compat_ipc_pid_t shm_cpid;
- compat_ipc_pid_t shm_lpid;
- unsigned short shm_nattch;
-};
-
-static inline int sunos_shmid_get(struct shmid_ds32 __user *user,
- struct shmid_ds *kern)
-{
- if (get_user(kern->shm_perm.key, &user->shm_perm.key) ||
- __get_user(kern->shm_perm.uid, &user->shm_perm.uid) ||
- __get_user(kern->shm_perm.gid, &user->shm_perm.gid) ||
- __get_user(kern->shm_perm.cuid, &user->shm_perm.cuid) ||
- __get_user(kern->shm_perm.cgid, &user->shm_perm.cgid) ||
- __get_user(kern->shm_segsz, &user->shm_segsz) ||
- __get_user(kern->shm_atime, &user->shm_atime) ||
- __get_user(kern->shm_dtime, &user->shm_dtime) ||
- __get_user(kern->shm_ctime, &user->shm_ctime) ||
- __get_user(kern->shm_cpid, &user->shm_cpid) ||
- __get_user(kern->shm_lpid, &user->shm_lpid) ||
- __get_user(kern->shm_nattch, &user->shm_nattch))
- return -EFAULT;
- return 0;
-}
-
-static inline int sunos_shmid_put(struct shmid_ds32 __user *user,
- struct shmid_ds *kern)
-{
- if (put_user(kern->shm_perm.key, &user->shm_perm.key) ||
- __put_user(kern->shm_perm.uid, &user->shm_perm.uid) ||
- __put_user(kern->shm_perm.gid, &user->shm_perm.gid) ||
- __put_user(kern->shm_perm.cuid, &user->shm_perm.cuid) ||
- __put_user(kern->shm_perm.cgid, &user->shm_perm.cgid) ||
- __put_user(kern->shm_segsz, &user->shm_segsz) ||
- __put_user(kern->shm_atime, &user->shm_atime) ||
- __put_user(kern->shm_dtime, &user->shm_dtime) ||
- __put_user(kern->shm_ctime, &user->shm_ctime) ||
- __put_user(kern->shm_cpid, &user->shm_cpid) ||
- __put_user(kern->shm_lpid, &user->shm_lpid) ||
- __put_user(kern->shm_nattch, &user->shm_nattch))
- return -EFAULT;
- return 0;
-}
-
-asmlinkage int sunos_shmsys(int op, u32 arg1, u32 arg2, u32 arg3)
-{
- struct shmid_ds ksds;
- unsigned long raddr;
- mm_segment_t old_fs = get_fs();
- int rval;
-
- switch(op) {
- case 0:
- /* do_shmat(): attach a shared memory area */
- rval = do_shmat((int)arg1,(char __user *)(unsigned long)arg2,(int)arg3,&raddr);
- if (!rval)
- rval = (int) raddr;
- break;
- case 1:
- /* sys_shmctl(): modify shared memory area attr. */
- if (!sunos_shmid_get((struct shmid_ds32 __user *)(unsigned long)arg3, &ksds)) {
- set_fs(KERNEL_DS);
- rval = sys_shmctl((int) arg1,(int) arg2,
- (struct shmid_ds __user *) &ksds);
- set_fs(old_fs);
- if (!rval)
- rval = sunos_shmid_put((struct shmid_ds32 __user *)(unsigned long)arg3,
- &ksds);
- } else
- rval = -EFAULT;
- break;
- case 2:
- /* sys_shmdt(): detach a shared memory area */
- rval = sys_shmdt((char __user *)(unsigned long)arg1);
- break;
- case 3:
- /* sys_shmget(): get a shared memory area */
- rval = sys_shmget((key_t)arg1,(int)arg2,(int)arg3);
- break;
- default:
- rval = -EINVAL;
- break;
- };
- return rval;
-}
-
-extern asmlinkage long sparc32_open(const char __user * filename, int flags, int mode);
-
-asmlinkage int sunos_open(u32 fname, int flags, int mode)
-{
- const char __user *filename = compat_ptr(fname);
-
- return sparc32_open(filename, flags, mode);
-}
-
-#define SUNOS_EWOULDBLOCK 35
-
-/* see the sunos man page read(2v) for an explanation
- of this garbage. We use O_NDELAY to mark
- file descriptors that have been set non-blocking
- using 4.2BSD style calls. (tridge) */
-
-static inline int check_nonblock(int ret, int fd)
-{
- if (ret == -EAGAIN) {
- struct file * file = fget(fd);
- if (file) {
- if (file->f_flags & O_NDELAY)
- ret = -SUNOS_EWOULDBLOCK;
- fput(file);
- }
- }
- return ret;
-}
-
-asmlinkage int sunos_read(unsigned int fd, char __user *buf, u32 count)
-{
- int ret;
-
- ret = check_nonblock(sys_read(fd, buf, count), fd);
- return ret;
-}
-
-asmlinkage int sunos_readv(u32 fd, void __user *vector, s32 count)
-{
- int ret;
-
- ret = check_nonblock(compat_sys_readv(fd, vector, count), fd);
- return ret;
-}
-
-asmlinkage int sunos_write(unsigned int fd, char __user *buf, u32 count)
-{
- int ret;
-
- ret = check_nonblock(sys_write(fd, buf, count), fd);
- return ret;
-}
-
-asmlinkage int sunos_writev(u32 fd, void __user *vector, s32 count)
-{
- int ret;
-
- ret = check_nonblock(compat_sys_writev(fd, vector, count), fd);
- return ret;
-}
-
-asmlinkage int sunos_recv(u32 __fd, void __user *ubuf, int size, unsigned flags)
-{
- int ret, fd = (int) __fd;
-
- ret = check_nonblock(sys_recv(fd, ubuf, size, flags), fd);
- return ret;
-}
-
-asmlinkage int sunos_send(u32 __fd, void __user *buff, int len, unsigned flags)
-{
- int ret, fd = (int) __fd;
-
- ret = check_nonblock(sys_send(fd, buff, len, flags), fd);
- return ret;
-}
-
-asmlinkage int sunos_accept(u32 __fd, struct sockaddr __user *sa, int __user *addrlen)
-{
- int ret, fd = (int) __fd;
-
- while (1) {
- ret = check_nonblock(sys_accept(fd, sa, addrlen), fd);
- if (ret != -ENETUNREACH && ret != -EHOSTUNREACH)
- break;
- }
- return ret;
-}
-
-#define SUNOS_SV_INTERRUPT 2
-
-asmlinkage int sunos_sigaction (int sig,
- struct old_sigaction32 __user *act,
- struct old_sigaction32 __user *oact)
-{
- struct k_sigaction new_ka, old_ka;
- int ret;
-
- if (act) {
- compat_old_sigset_t mask;
- u32 u_handler;
-
- if (get_user(u_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_flags, &act->sa_flags))
- return -EFAULT;
- new_ka.sa.sa_handler = compat_ptr(u_handler);
- __get_user(mask, &act->sa_mask);
- new_ka.sa.sa_restorer = NULL;
- new_ka.ka_restorer = NULL;
- siginitset(&new_ka.sa.sa_mask, mask);
- new_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT;
- }
-
- ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
-
- if (!ret && oact) {
- old_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT;
- if (put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
- return -EFAULT;
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
- }
-
- return ret;
-}
-
-asmlinkage int sunos_setsockopt(u32 __fd, u32 __level, u32 __optname,
- char __user *optval, u32 __optlen)
-{
- int fd = (int) __fd;
- int level = (int) __level;
- int optname = (int) __optname;
- int optlen = (int) __optlen;
- int tr_opt = optname;
- int ret;
-
- if (level == SOL_IP) {
- /* Multicast socketopts (ttl, membership) */
- if (tr_opt >=2 && tr_opt <= 6)
- tr_opt += 30;
- }
- ret = sys_setsockopt(fd, level, tr_opt,
- optval, optlen);
- return ret;
-}
-
-asmlinkage int sunos_getsockopt(u32 __fd, u32 __level, u32 __optname,
- char __user *optval, int __user *optlen)
-{
- int fd = (int) __fd;
- int level = (int) __level;
- int optname = (int) __optname;
- int tr_opt = optname;
- int ret;
-
- if (level == SOL_IP) {
- /* Multicast socketopts (ttl, membership) */
- if (tr_opt >=2 && tr_opt <= 6)
- tr_opt += 30;
- }
- ret = compat_sys_getsockopt(fd, level, tr_opt,
- optval, optlen);
- return ret;
-}
diff --git a/arch/sparc64/kernel/sysfs.c b/arch/sparc64/kernel/sysfs.c
index 52816c7be0b9..e885034a6b73 100644
--- a/arch/sparc64/kernel/sysfs.c
+++ b/arch/sparc64/kernel/sysfs.c
@@ -273,10 +273,22 @@ static void __init check_mmu_stats(void)
mmu_stats_supported = 1;
}
+static void register_nodes(void)
+{
+#ifdef CONFIG_NUMA
+ int i;
+
+ for (i = 0; i < MAX_NUMNODES; i++)
+ register_one_node(i);
+#endif
+}
+
static int __init topology_init(void)
{
int cpu;
+ register_nodes();
+
check_mmu_stats();
register_cpu_notifier(&sysfs_cpu_nb);
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 6b9b718e24af..a4fef2ba1ae1 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -155,125 +155,3 @@ sys_call_table:
.word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait
/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
.word sys_timerfd_settime, sys_timerfd_gettime
-
-#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
- defined(CONFIG_SOLARIS_EMUL_MODULE)
- /* Now the 32-bit SunOS syscall table. */
-
- .align 4
- .globl sunos_sys_table
-sunos_sys_table:
-/*0*/ .word sunos_indir, sys32_exit, sys_fork
- .word sunos_read, sunos_write, sunos_open
- .word sys_close, sunos_wait4, sys_creat
- .word sys_link, sys_unlink, sunos_execv
- .word sys_chdir, sunos_nosys, sys32_mknod
- .word sys_chmod, sys32_lchown16, sunos_brk
- .word sunos_nosys, sys32_lseek, sunos_getpid
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_getuid, sunos_nosys, sys_ptrace
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sys_access, sunos_nosys, sunos_nosys
- .word sys_sync, sys_kill, compat_sys_newstat
- .word sunos_nosys, compat_sys_newlstat, sys_dup
- .word sys_pipe, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_getgid
- .word sunos_nosys, sunos_nosys
-/*50*/ .word sunos_nosys, sys_acct, sunos_nosys
- .word sunos_mctl, sunos_ioctl, sys_reboot
- .word sunos_nosys, sys_symlink, sys_readlink
- .word sys32_execve, sys_umask, sys_chroot
- .word compat_sys_newfstat, sunos_nosys, sys_getpagesize
- .word sys_msync, sys_vfork, sunos_nosys
- .word sunos_nosys, sunos_sbrk, sunos_sstk
- .word sunos_mmap, sunos_vadvise, sys_munmap
- .word sys_mprotect, sys_madvise, sys_vhangup
- .word sunos_nosys, sys_mincore, sys32_getgroups16
- .word sys32_setgroups16, sys_getpgrp, sunos_setpgrp
- .word compat_sys_setitimer, sunos_nosys, sys_swapon
- .word compat_sys_getitimer, sys_gethostname, sys_sethostname
- .word sunos_getdtablesize, sys_dup2, sunos_nop
- .word compat_sys_fcntl, sunos_select, sunos_nop
- .word sys_fsync, sys32_setpriority, sys32_socket
- .word sys32_connect, sunos_accept
-/*100*/ .word sys_getpriority, sunos_send, sunos_recv
- .word sunos_nosys, sys32_bind, sunos_setsockopt
- .word sys32_listen, sunos_nosys, sunos_sigaction
- .word sunos_sigblock, sunos_sigsetmask, sys_sigpause
- .word sys32_sigstack, sys32_recvmsg, sys32_sendmsg
- .word sunos_nosys, sys32_gettimeofday, compat_sys_getrusage
- .word sunos_getsockopt, sunos_nosys, sunos_readv
- .word sunos_writev, sys32_settimeofday, sys32_fchown16
- .word sys_fchmod, sys32_recvfrom, sys32_setreuid16
- .word sys32_setregid16, sys_rename, sys_truncate
- .word sys_ftruncate, sys_flock, sunos_nosys
- .word sys32_sendto, sys32_shutdown, sys32_socketpair
- .word sys_mkdir, sys_rmdir, sys32_utimes
- .word sys32_sigreturn, sunos_nosys, sys32_getpeername
- .word sunos_gethostid, sunos_nosys, compat_sys_getrlimit
- .word compat_sys_setrlimit, sunos_killpg, sunos_nosys
- .word sunos_nosys, sunos_nosys
-/*150*/ .word sys32_getsockname, sunos_nosys, sunos_nosys
- .word sys_poll, sunos_nosys, sunos_nosys
- .word sunos_getdirentries, compat_sys_statfs, compat_sys_fstatfs
- .word sys_oldumount, sunos_nosys, sunos_nosys
- .word sys_getdomainname, sys_setdomainname
- .word sunos_nosys, sys_quotactl, sunos_nosys
- .word sunos_nosys, sys_ustat, sunos_semsys
- .word sunos_nosys, sunos_shmsys, sunos_audit
- .word sunos_nosys, sunos_getdents, sys_setsid
- .word sys_fchdir, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, compat_sys_sigpending, sunos_nosys
- .word sys_setpgid, sunos_pathconf, sunos_fpathconf
- .word sunos_sysconf, sunos_uname, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
-/*200*/ .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys
-/*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys
-/*260*/ .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys
-/*270*/ .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys
-/*280*/ .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys
-/*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys
-/*300*/ .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys
-/*310*/ .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys, sunos_nosys, sunos_nosys
- .word sunos_nosys
-
-#endif
diff --git a/arch/sparc64/kernel/systbls.h b/arch/sparc64/kernel/systbls.h
new file mode 100644
index 000000000000..bc9f5dac4069
--- /dev/null
+++ b/arch/sparc64/kernel/systbls.h
@@ -0,0 +1,51 @@
+#ifndef _SYSTBLS_H
+#define _SYSTBLS_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/utsname.h>
+#include <asm/utrap.h>
+#include <asm/signal.h>
+
+extern asmlinkage unsigned long sys_getpagesize(void);
+extern asmlinkage unsigned long sparc_brk(unsigned long brk);
+extern asmlinkage long sparc_pipe(struct pt_regs *regs);
+extern asmlinkage long sys_ipc(unsigned int call, int first,
+ unsigned long second,
+ unsigned long third,
+ void __user *ptr, long fifth);
+extern asmlinkage long sparc64_newuname(struct new_utsname __user *name);
+extern asmlinkage long sparc64_personality(unsigned long personality);
+extern asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long off);
+extern asmlinkage long sys64_munmap(unsigned long addr, size_t len);
+extern asmlinkage unsigned long sys64_mremap(unsigned long addr,
+ unsigned long old_len,
+ unsigned long new_len,
+ unsigned long flags,
+ unsigned long new_addr);
+extern asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs);
+extern asmlinkage long sys_getdomainname(char __user *name, int len);
+extern asmlinkage long sys_utrap_install(utrap_entry_t type,
+ utrap_handler_t new_p,
+ utrap_handler_t new_d,
+ utrap_handler_t __user *old_p,
+ utrap_handler_t __user *old_d);
+extern asmlinkage long sparc_memory_ordering(unsigned long model,
+ struct pt_regs *regs);
+extern asmlinkage long sys_rt_sigaction(int sig,
+ const struct sigaction __user *act,
+ struct sigaction __user *oact,
+ void __user *restorer,
+ size_t sigsetsize);
+extern asmlinkage long sys_perfctr(int opcode, unsigned long arg0,
+ unsigned long arg1, unsigned long arg2);
+
+extern asmlinkage void sparc64_set_context(struct pt_regs *regs);
+extern asmlinkage void sparc64_get_context(struct pt_regs *regs);
+extern asmlinkage long sys_sigpause(unsigned int set);
+extern asmlinkage long sys_sigsuspend(old_sigset_t set);
+extern void do_rt_sigreturn(struct pt_regs *regs);
+
+#endif /* _SYSTBLS_H */
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index d204f1ab1d4c..e5d238970c7e 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -1,7 +1,6 @@
-/* $Id: time.c,v 1.42 2002/01/23 14:33:55 davem Exp $
- * time.c: UltraSparc timer and TOD clock support.
+/* time.c: UltraSparc timer and TOD clock support.
*
- * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1997, 2008 David S. Miller (davem@davemloft.net)
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
*
* Based largely on code which is:
@@ -48,6 +47,8 @@
#include <asm/uaccess.h>
#include <asm/irq_regs.h>
+#include "entry.h"
+
DEFINE_SPINLOCK(mostek_lock);
DEFINE_SPINLOCK(rtc_lock);
void __iomem *mstk48t02_regs = NULL;
@@ -508,6 +509,37 @@ static int __init has_low_battery(void)
return (data1 == data2); /* Was the write blocked? */
}
+static void __init mostek_set_system_time(void __iomem *mregs)
+{
+ unsigned int year, mon, day, hour, min, sec;
+ u8 tmp;
+
+ spin_lock_irq(&mostek_lock);
+
+ /* Traditional Mostek chip. */
+ tmp = mostek_read(mregs + MOSTEK_CREG);
+ tmp |= MSTK_CREG_READ;
+ mostek_write(mregs + MOSTEK_CREG, tmp);
+
+ sec = MSTK_REG_SEC(mregs);
+ min = MSTK_REG_MIN(mregs);
+ hour = MSTK_REG_HOUR(mregs);
+ day = MSTK_REG_DOM(mregs);
+ mon = MSTK_REG_MONTH(mregs);
+ year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
+
+ xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+ xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
+ set_normalized_timespec(&wall_to_monotonic,
+ -xtime.tv_sec, -xtime.tv_nsec);
+
+ tmp = mostek_read(mregs + MOSTEK_CREG);
+ tmp &= ~MSTK_CREG_READ;
+ mostek_write(mregs + MOSTEK_CREG, tmp);
+
+ spin_unlock_irq(&mostek_lock);
+}
+
/* Probe for the real time clock chip. */
static void __init set_system_time(void)
{
@@ -520,7 +552,6 @@ static void __init set_system_time(void)
unsigned long dregs = 0UL;
void __iomem *bregs = 0UL;
#endif
- u8 tmp;
if (!mregs && !dregs && !bregs) {
prom_printf("Something wrong, clock regs not mapped yet.\n");
@@ -528,20 +559,11 @@ static void __init set_system_time(void)
}
if (mregs) {
- spin_lock_irq(&mostek_lock);
-
- /* Traditional Mostek chip. */
- tmp = mostek_read(mregs + MOSTEK_CREG);
- tmp |= MSTK_CREG_READ;
- mostek_write(mregs + MOSTEK_CREG, tmp);
+ mostek_set_system_time(mregs);
+ return;
+ }
- sec = MSTK_REG_SEC(mregs);
- min = MSTK_REG_MIN(mregs);
- hour = MSTK_REG_HOUR(mregs);
- day = MSTK_REG_DOM(mregs);
- mon = MSTK_REG_MONTH(mregs);
- year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
- } else if (bregs) {
+ if (bregs) {
unsigned char val = readb(bregs + 0x0e);
unsigned int century;
@@ -596,14 +618,6 @@ static void __init set_system_time(void)
xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
set_normalized_timespec(&wall_to_monotonic,
-xtime.tv_sec, -xtime.tv_nsec);
-
- if (mregs) {
- tmp = mostek_read(mregs + MOSTEK_CREG);
- tmp &= ~MSTK_CREG_READ;
- mostek_write(mregs + MOSTEK_CREG, tmp);
-
- spin_unlock_irq(&mostek_lock);
- }
}
/* davem suggests we keep this within the 4M locked kernel image */
@@ -1027,7 +1041,7 @@ void __init time_init(void)
setup_clockevent_multiplier(clock);
sparc64_clockevent.max_delta_ns =
- clockevent_delta2ns(0x7fffffffffffffff, &sparc64_clockevent);
+ clockevent_delta2ns(0x7fffffffffffffffUL, &sparc64_clockevent);
sparc64_clockevent.min_delta_ns =
clockevent_delta2ns(0xF, &sparc64_clockevent);
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S
index 04e81dda13d0..56ff55211341 100644
--- a/arch/sparc64/kernel/trampoline.S
+++ b/arch/sparc64/kernel/trampoline.S
@@ -4,6 +4,8 @@
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
*/
+#include <linux/init.h>
+
#include <asm/head.h>
#include <asm/asi.h>
#include <asm/lsu.h>
@@ -36,7 +38,7 @@ dtlb_load:
tramp_stack:
.skip TRAMP_STACK_SIZE
- .text
+ __CPUINIT
.align 8
.globl sparc64_cpu_startup, sparc64_cpu_startup_end
sparc64_cpu_startup:
@@ -103,7 +105,7 @@ startup_continue:
wr %g2, 0, %tick_cmpr
/* Call OBP by hand to lock KERNBASE into i/d tlbs.
- * We lock 2 consequetive entries if we are 'bigkernel'.
+ * We lock 'num_kernel_image_mappings' consequetive entries.
*/
sethi %hi(prom_entry_lock), %g2
1: ldstub [%g2 + %lo(prom_entry_lock)], %g1
@@ -117,6 +119,29 @@ startup_continue:
add %l2, -(192 + 128), %sp
flushw
+ /* Setup the loop variables:
+ * %l3: VADDR base
+ * %l4: TTE base
+ * %l5: Loop iterator, iterates from 0 to 'num_kernel_image_mappings'
+ * %l6: Number of TTE entries to map
+ * %l7: Highest TTE entry number, we count down
+ */
+ sethi %hi(KERNBASE), %l3
+ sethi %hi(kern_locked_tte_data), %l4
+ ldx [%l4 + %lo(kern_locked_tte_data)], %l4
+ clr %l5
+ sethi %hi(num_kernel_image_mappings), %l6
+ lduw [%l6 + %lo(num_kernel_image_mappings)], %l6
+ add %l6, 1, %l6
+
+ mov 15, %l7
+ BRANCH_IF_ANY_CHEETAH(g1,g5,2f)
+
+ mov 63, %l7
+2:
+
+3:
+ /* Lock into I-MMU */
sethi %hi(call_method), %g2
or %g2, %lo(call_method), %g2
stx %g2, [%sp + 2047 + 128 + 0x00]
@@ -130,63 +155,26 @@ startup_continue:
sethi %hi(prom_mmu_ihandle_cache), %g2
lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
stx %g2, [%sp + 2047 + 128 + 0x20]
- sethi %hi(KERNBASE), %g2
- stx %g2, [%sp + 2047 + 128 + 0x28]
- sethi %hi(kern_locked_tte_data), %g2
- ldx [%g2 + %lo(kern_locked_tte_data)], %g2
- stx %g2, [%sp + 2047 + 128 + 0x30]
- mov 15, %g2
- BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
-
- mov 63, %g2
-1:
- stx %g2, [%sp + 2047 + 128 + 0x38]
- sethi %hi(p1275buf), %g2
- or %g2, %lo(p1275buf), %g2
- ldx [%g2 + 0x08], %o1
- call %o1
- add %sp, (2047 + 128), %o0
+ /* Each TTE maps 4MB, convert index to offset. */
+ sllx %l5, 22, %g1
- sethi %hi(bigkernel), %g2
- lduw [%g2 + %lo(bigkernel)], %g2
- brz,pt %g2, do_dtlb
- nop
+ add %l3, %g1, %g2
+ stx %g2, [%sp + 2047 + 128 + 0x28] ! VADDR
+ add %l4, %g1, %g2
+ stx %g2, [%sp + 2047 + 128 + 0x30] ! TTE
- sethi %hi(call_method), %g2
- or %g2, %lo(call_method), %g2
- stx %g2, [%sp + 2047 + 128 + 0x00]
- mov 5, %g2
- stx %g2, [%sp + 2047 + 128 + 0x08]
- mov 1, %g2
- stx %g2, [%sp + 2047 + 128 + 0x10]
- sethi %hi(itlb_load), %g2
- or %g2, %lo(itlb_load), %g2
- stx %g2, [%sp + 2047 + 128 + 0x18]
- sethi %hi(prom_mmu_ihandle_cache), %g2
- lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
- stx %g2, [%sp + 2047 + 128 + 0x20]
- sethi %hi(KERNBASE + 0x400000), %g2
- stx %g2, [%sp + 2047 + 128 + 0x28]
- sethi %hi(kern_locked_tte_data), %g2
- ldx [%g2 + %lo(kern_locked_tte_data)], %g2
- sethi %hi(0x400000), %g1
- add %g2, %g1, %g2
- stx %g2, [%sp + 2047 + 128 + 0x30]
-
- mov 14, %g2
- BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
-
- mov 62, %g2
-1:
+ /* TTE index is highest minus loop index. */
+ sub %l7, %l5, %g2
stx %g2, [%sp + 2047 + 128 + 0x38]
+
sethi %hi(p1275buf), %g2
or %g2, %lo(p1275buf), %g2
ldx [%g2 + 0x08], %o1
call %o1
add %sp, (2047 + 128), %o0
-do_dtlb:
+ /* Lock into D-MMU */
sethi %hi(call_method), %g2
or %g2, %lo(call_method), %g2
stx %g2, [%sp + 2047 + 128 + 0x00]
@@ -200,65 +188,30 @@ do_dtlb:
sethi %hi(prom_mmu_ihandle_cache), %g2
lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
stx %g2, [%sp + 2047 + 128 + 0x20]
- sethi %hi(KERNBASE), %g2
- stx %g2, [%sp + 2047 + 128 + 0x28]
- sethi %hi(kern_locked_tte_data), %g2
- ldx [%g2 + %lo(kern_locked_tte_data)], %g2
- stx %g2, [%sp + 2047 + 128 + 0x30]
- mov 15, %g2
- BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
+ /* Each TTE maps 4MB, convert index to offset. */
+ sllx %l5, 22, %g1
- mov 63, %g2
-1:
+ add %l3, %g1, %g2
+ stx %g2, [%sp + 2047 + 128 + 0x28] ! VADDR
+ add %l4, %g1, %g2
+ stx %g2, [%sp + 2047 + 128 + 0x30] ! TTE
+ /* TTE index is highest minus loop index. */
+ sub %l7, %l5, %g2
stx %g2, [%sp + 2047 + 128 + 0x38]
+
sethi %hi(p1275buf), %g2
or %g2, %lo(p1275buf), %g2
ldx [%g2 + 0x08], %o1
call %o1
add %sp, (2047 + 128), %o0
- sethi %hi(bigkernel), %g2
- lduw [%g2 + %lo(bigkernel)], %g2
- brz,pt %g2, do_unlock
+ add %l5, 1, %l5
+ cmp %l5, %l6
+ bne,pt %xcc, 3b
nop
- sethi %hi(call_method), %g2
- or %g2, %lo(call_method), %g2
- stx %g2, [%sp + 2047 + 128 + 0x00]
- mov 5, %g2
- stx %g2, [%sp + 2047 + 128 + 0x08]
- mov 1, %g2
- stx %g2, [%sp + 2047 + 128 + 0x10]
- sethi %hi(dtlb_load), %g2
- or %g2, %lo(dtlb_load), %g2
- stx %g2, [%sp + 2047 + 128 + 0x18]
- sethi %hi(prom_mmu_ihandle_cache), %g2
- lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
- stx %g2, [%sp + 2047 + 128 + 0x20]
- sethi %hi(KERNBASE + 0x400000), %g2
- stx %g2, [%sp + 2047 + 128 + 0x28]
- sethi %hi(kern_locked_tte_data), %g2
- ldx [%g2 + %lo(kern_locked_tte_data)], %g2
- sethi %hi(0x400000), %g1
- add %g2, %g1, %g2
- stx %g2, [%sp + 2047 + 128 + 0x30]
-
- mov 14, %g2
- BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
-
- mov 62, %g2
-1:
-
- stx %g2, [%sp + 2047 + 128 + 0x38]
- sethi %hi(p1275buf), %g2
- or %g2, %lo(p1275buf), %g2
- ldx [%g2 + 0x08], %o1
- call %o1
- add %sp, (2047 + 128), %o0
-
-do_unlock:
sethi %hi(prom_entry_lock), %g2
stb %g0, [%g2 + %lo(prom_entry_lock)]
membar #StoreStore | #StoreLoad
@@ -267,47 +220,36 @@ do_unlock:
nop
niagara_lock_tlb:
+ sethi %hi(KERNBASE), %l3
+ sethi %hi(kern_locked_tte_data), %l4
+ ldx [%l4 + %lo(kern_locked_tte_data)], %l4
+ clr %l5
+ sethi %hi(num_kernel_image_mappings), %l6
+ lduw [%l6 + %lo(num_kernel_image_mappings)], %l6
+ add %l6, 1, %l6
+
+1:
mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
- sethi %hi(KERNBASE), %o0
+ sllx %l5, 22, %g2
+ add %l3, %g2, %o0
clr %o1
- sethi %hi(kern_locked_tte_data), %o2
- ldx [%o2 + %lo(kern_locked_tte_data)], %o2
+ add %l4, %g2, %o2
mov HV_MMU_IMMU, %o3
ta HV_FAST_TRAP
mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
- sethi %hi(KERNBASE), %o0
+ sllx %l5, 22, %g2
+ add %l3, %g2, %o0
clr %o1
- sethi %hi(kern_locked_tte_data), %o2
- ldx [%o2 + %lo(kern_locked_tte_data)], %o2
+ add %l4, %g2, %o2
mov HV_MMU_DMMU, %o3
ta HV_FAST_TRAP
- sethi %hi(bigkernel), %g2
- lduw [%g2 + %lo(bigkernel)], %g2
- brz,pt %g2, after_lock_tlb
+ add %l5, 1, %l5
+ cmp %l5, %l6
+ bne,pt %xcc, 1b
nop
- mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
- sethi %hi(KERNBASE + 0x400000), %o0
- clr %o1
- sethi %hi(kern_locked_tte_data), %o2
- ldx [%o2 + %lo(kern_locked_tte_data)], %o2
- sethi %hi(0x400000), %o3
- add %o2, %o3, %o2
- mov HV_MMU_IMMU, %o3
- ta HV_FAST_TRAP
-
- mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
- sethi %hi(KERNBASE + 0x400000), %o0
- clr %o1
- sethi %hi(kern_locked_tte_data), %o2
- ldx [%o2 + %lo(kern_locked_tte_data)], %o2
- sethi %hi(0x400000), %o3
- add %o2, %o3, %o2
- mov HV_MMU_DMMU, %o3
- ta HV_FAST_TRAP
-
after_lock_tlb:
wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate
wr %g0, 0, %fprs
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 2b6abf633343..d9b8d46707d1 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -42,6 +42,7 @@
#endif
#include <asm/prom.h>
+#include "entry.h"
/* When an irrecoverable trap occurs at tl > 0, the trap entry
* code logs the trap state registers at every level in the trap
@@ -77,11 +78,6 @@ static void dump_tl1_traplog(struct tl1_traplog *p)
}
}
-void do_call_debug(struct pt_regs *regs)
-{
- notify_die(DIE_CALL, "debug call", regs, 0, 255, SIGINT);
-}
-
void bad_trap(struct pt_regs *regs, long lvl)
{
char buffer[32];
@@ -550,41 +546,6 @@ static unsigned long ecache_flush_physbase;
static unsigned long ecache_flush_linesize;
static unsigned long ecache_flush_size;
-/* WARNING: The error trap handlers in assembly know the precise
- * layout of the following structure.
- *
- * C-level handlers below use this information to log the error
- * and then determine how to recover (if possible).
- */
-struct cheetah_err_info {
-/*0x00*/u64 afsr;
-/*0x08*/u64 afar;
-
- /* D-cache state */
-/*0x10*/u64 dcache_data[4]; /* The actual data */
-/*0x30*/u64 dcache_index; /* D-cache index */
-/*0x38*/u64 dcache_tag; /* D-cache tag/valid */
-/*0x40*/u64 dcache_utag; /* D-cache microtag */
-/*0x48*/u64 dcache_stag; /* D-cache snooptag */
-
- /* I-cache state */
-/*0x50*/u64 icache_data[8]; /* The actual insns + predecode */
-/*0x90*/u64 icache_index; /* I-cache index */
-/*0x98*/u64 icache_tag; /* I-cache phys tag */
-/*0xa0*/u64 icache_utag; /* I-cache microtag */
-/*0xa8*/u64 icache_stag; /* I-cache snooptag */
-/*0xb0*/u64 icache_upper; /* I-cache upper-tag */
-/*0xb8*/u64 icache_lower; /* I-cache lower-tag */
-
- /* E-cache state */
-/*0xc0*/u64 ecache_data[4]; /* 32 bytes from staging registers */
-/*0xe0*/u64 ecache_index; /* E-cache index */
-/*0xe8*/u64 ecache_tag; /* E-cache tag/state */
-
-/*0xf0*/u64 __pad[32 - 30];
-};
-#define CHAFSR_INVALID ((u64)-1L)
-
/* This table is ordered in priority of errors and matches the
* AFAR overwrite policy as well.
*/
@@ -758,10 +719,6 @@ static struct afsr_error_table __jalapeno_error_table[] = {
static struct afsr_error_table *cheetah_error_table;
static unsigned long cheetah_afsr_errors;
-/* This is allocated at boot time based upon the largest hardware
- * cpu ID in the system. We allocate two entries per cpu, one for
- * TL==0 logging and one for TL >= 1 logging.
- */
struct cheetah_err_info *cheetah_error_log;
static inline struct cheetah_err_info *cheetah_get_error_log(unsigned long afsr)
@@ -1791,8 +1748,6 @@ static const char *sun4v_err_type_to_str(u32 type)
};
}
-extern void __show_regs(struct pt_regs * regs);
-
static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt)
{
int cnt;
@@ -2104,7 +2059,7 @@ void do_div0(struct pt_regs *regs)
force_sig_info(SIGFPE, &info, current);
}
-void instruction_dump (unsigned int *pc)
+static void instruction_dump(unsigned int *pc)
{
int i;
@@ -2117,7 +2072,7 @@ void instruction_dump (unsigned int *pc)
printk("\n");
}
-static void user_instruction_dump (unsigned int __user *pc)
+static void user_instruction_dump(unsigned int __user *pc)
{
int i;
unsigned int buf[9];
@@ -2136,9 +2091,8 @@ static void user_instruction_dump (unsigned int __user *pc)
void show_stack(struct task_struct *tsk, unsigned long *_ksp)
{
- unsigned long pc, fp, thread_base, ksp;
+ unsigned long fp, thread_base, ksp;
struct thread_info *tp;
- struct reg_window *rw;
int count = 0;
ksp = (unsigned long) _ksp;
@@ -2162,15 +2116,27 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp)
printk("\n");
#endif
do {
+ struct reg_window *rw;
+ struct pt_regs *regs;
+ unsigned long pc;
+
/* Bogus frame pointer? */
if (fp < (thread_base + sizeof(struct thread_info)) ||
fp >= (thread_base + THREAD_SIZE))
break;
rw = (struct reg_window *)fp;
- pc = rw->ins[7];
+ regs = (struct pt_regs *) (rw + 1);
+
+ if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) {
+ pc = regs->tpc;
+ fp = regs->u_regs[UREG_I6] + STACK_BIAS;
+ } else {
+ pc = rw->ins[7];
+ fp = rw->ins[6] + STACK_BIAS;
+ }
+
printk(" [%016lx] ", pc);
print_symbol("%s\n", pc);
- fp = rw->ins[6] + STACK_BIAS;
} while (++count < 16);
#ifndef CONFIG_KALLSYMS
printk("\n");
diff --git a/arch/sparc64/kernel/tsb.S b/arch/sparc64/kernel/tsb.S
index 10adb2fb8ffe..c499214b501d 100644
--- a/arch/sparc64/kernel/tsb.S
+++ b/arch/sparc64/kernel/tsb.S
@@ -275,7 +275,7 @@ sparc64_realfault_common:
stx %l5, [%g6 + TI_FAULT_ADDR] ! Save fault address
call do_sparc64_fault ! Call fault handler
add %sp, PTREGS_OFF, %o0 ! Compute pt_regs arg
- ba,pt %xcc, rtrap_clr_l6 ! Restore cpu state
+ ba,pt %xcc, rtrap ! Restore cpu state
nop ! Delay slot (fill me)
winfix_trampoline:
diff --git a/arch/sparc64/kernel/ttable.S b/arch/sparc64/kernel/ttable.S
index 7575aa371da8..b0de4c00b11a 100644
--- a/arch/sparc64/kernel/ttable.S
+++ b/arch/sparc64/kernel/ttable.S
@@ -117,16 +117,13 @@ tl0_f4o: FILL_4_OTHER
tl0_f5o: FILL_5_OTHER
tl0_f6o: FILL_6_OTHER
tl0_f7o: FILL_7_OTHER
-tl0_sunos: SUNOS_SYSCALL_TRAP
+tl0_resv100: BTRAP(0x100)
tl0_bkpt: BREAKPOINT_TRAP
tl0_divz: TRAP(do_div0)
tl0_flushw: FLUSH_WINDOW_TRAP
-tl0_resv104: BTRAP(0x104) BTRAP(0x105) BTRAP(0x106) BTRAP(0x107)
- .globl tl0_solaris
-tl0_solaris: SOLARIS_SYSCALL_TRAP
-tl0_resv109: BTRAP(0x109)
-tl0_resv10a: BTRAP(0x10a) BTRAP(0x10b) BTRAP(0x10c) BTRAP(0x10d) BTRAP(0x10e)
-tl0_resv10f: BTRAP(0x10f)
+tl0_resv104: BTRAP(0x104) BTRAP(0x105) BTRAP(0x106) BTRAP(0x107) BTRAP(0x108)
+tl0_resv109: BTRAP(0x109) BTRAP(0x10a) BTRAP(0x10b) BTRAP(0x10c) BTRAP(0x10d)
+tl0_resv10e: BTRAP(0x10e) BTRAP(0x10f)
tl0_linux32: LINUX_32BIT_SYSCALL_TRAP
tl0_oldlinux64: LINUX_64BIT_SYSCALL_TRAP
tl0_resv112: TRAP_UTRAP(UT_TRAP_INSTRUCTION_18,0x112) TRAP_UTRAP(UT_TRAP_INSTRUCTION_19,0x113)
@@ -139,8 +136,7 @@ tl0_resv11e: TRAP_UTRAP(UT_TRAP_INSTRUCTION_30,0x11e) TRAP_UTRAP(UT_TRAP_INSTRUC
tl0_getcc: GETCC_TRAP
tl0_setcc: SETCC_TRAP
tl0_getpsr: TRAP(do_getpsr)
-tl0_resv123: BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126)
-tl0_solindir: INDIRECT_SOLARIS_SYSCALL(156)
+tl0_resv123: BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126) BTRAP(0x127)
tl0_resv128: BTRAP(0x128) BTRAP(0x129) BTRAP(0x12a) BTRAP(0x12b) BTRAP(0x12c)
tl0_resv12d: BTRAP(0x12d) BTRAP(0x12e) BTRAP(0x12f) BTRAP(0x130) BTRAP(0x131)
tl0_resv132: BTRAP(0x132) BTRAP(0x133) BTRAP(0x134) BTRAP(0x135) BTRAP(0x136)
diff --git a/arch/sparc64/kernel/winfixup.S b/arch/sparc64/kernel/winfixup.S
index c4aa110a10e5..a6b0863c27df 100644
--- a/arch/sparc64/kernel/winfixup.S
+++ b/arch/sparc64/kernel/winfixup.S
@@ -32,7 +32,7 @@ fill_fixup:
rd %pc, %g7
call do_sparc64_fault
add %sp, PTREGS_OFF, %o0
- ba,pt %xcc, rtrap_clr_l6
+ ba,pt %xcc, rtrap
nop
/* Be very careful about usage of the trap globals here.
@@ -100,7 +100,7 @@ spill_fixup_dax:
rd %pc, %g7
call do_sparc64_fault
add %sp, PTREGS_OFF, %o0
- ba,a,pt %xcc, rtrap_clr_l6
+ ba,a,pt %xcc, rtrap
winfix_mna:
andn %g3, 0x7f, %g3
@@ -122,12 +122,12 @@ fill_fixup_mna:
mov %l4, %o2
call sun4v_do_mna
mov %l5, %o1
- ba,a,pt %xcc, rtrap_clr_l6
+ ba,a,pt %xcc, rtrap
1: mov %l4, %o1
mov %l5, %o2
call mem_address_unaligned
nop
- ba,a,pt %xcc, rtrap_clr_l6
+ ba,a,pt %xcc, rtrap
winfix_dax:
andn %g3, 0x7f, %g3
@@ -150,7 +150,7 @@ fill_fixup_dax:
add %sp, PTREGS_OFF, %o0
call sun4v_data_access_exception
nop
- ba,a,pt %xcc, rtrap_clr_l6
+ ba,a,pt %xcc, rtrap
1: call spitfire_data_access_exception
nop
- ba,a,pt %xcc, rtrap_clr_l6
+ ba,a,pt %xcc, rtrap
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index e2027f27c0fe..2650d0d33ac2 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -244,16 +244,8 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
if (regs->tstate & TSTATE_PRIV) {
const struct exception_table_entry *entry;
- if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) {
- if (insn & 0x2000)
- asi = (regs->tstate >> 24);
- else
- asi = (insn >> 5);
- }
-
- /* Look in asi.h: All _S asis have LS bit set */
- if ((asi & 0x1) &&
- (entry = search_exception_tables(regs->tpc))) {
+ entry = search_exception_tables(regs->tpc);
+ if (entry) {
regs->tpc = entry->fixup;
regs->tnpc = regs->tpc + 4;
return;
@@ -294,7 +286,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
unsigned long tpc = regs->tpc;
/* Sanity check the PC. */
- if ((tpc >= KERNBASE && tpc < (unsigned long) _etext) ||
+ if ((tpc >= KERNBASE && tpc < (unsigned long) __init_end) ||
(tpc >= MODULES_VADDR && tpc < MODULES_END)) {
/* Valid, no problems... */
} else {
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index 9e6bca266d88..8c2b50e8abc6 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -24,6 +24,8 @@
#include <linux/cache.h>
#include <linux/sort.h>
#include <linux/percpu.h>
+#include <linux/lmb.h>
+#include <linux/mmzone.h>
#include <asm/head.h>
#include <asm/system.h>
@@ -46,6 +48,7 @@
#include <asm/prom.h>
#include <asm/sstate.h>
#include <asm/mdesc.h>
+#include <asm/cpudata.h>
#define MAX_PHYS_ADDRESS (1UL << 42UL)
#define KPTE_BITMAP_CHUNK_SZ (256UL * 1024UL * 1024UL)
@@ -71,9 +74,7 @@ extern struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES];
#define MAX_BANKS 32
static struct linux_prom64_registers pavail[MAX_BANKS] __initdata;
-static struct linux_prom64_registers pavail_rescan[MAX_BANKS] __initdata;
static int pavail_ents __initdata;
-static int pavail_rescan_ents __initdata;
static int cmp_p64(const void *a, const void *b)
{
@@ -166,7 +167,7 @@ unsigned long sparc64_kern_pri_context __read_mostly;
unsigned long sparc64_kern_pri_nuc_bits __read_mostly;
unsigned long sparc64_kern_sec_context __read_mostly;
-int bigkernel = 0;
+int num_kernel_image_mappings;
#ifdef CONFIG_DEBUG_DCFLUSH
atomic_t dcpage_flushes = ATOMIC_INIT(0);
@@ -572,7 +573,7 @@ static unsigned long kern_large_tte(unsigned long paddr);
static void __init remap_kernel(void)
{
unsigned long phys_page, tte_vaddr, tte_data;
- int tlb_ent = sparc64_highest_locked_tlbent();
+ int i, tlb_ent = sparc64_highest_locked_tlbent();
tte_vaddr = (unsigned long) KERNBASE;
phys_page = (prom_boot_mapping_phys_low >> 22UL) << 22UL;
@@ -582,27 +583,20 @@ static void __init remap_kernel(void)
/* Now lock us into the TLBs via Hypervisor or OBP. */
if (tlb_type == hypervisor) {
- hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_DMMU);
- hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_IMMU);
- if (bigkernel) {
- tte_vaddr += 0x400000;
- tte_data += 0x400000;
+ for (i = 0; i < num_kernel_image_mappings; i++) {
hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_DMMU);
hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_IMMU);
+ tte_vaddr += 0x400000;
+ tte_data += 0x400000;
}
} else {
- prom_dtlb_load(tlb_ent, tte_data, tte_vaddr);
- prom_itlb_load(tlb_ent, tte_data, tte_vaddr);
- if (bigkernel) {
- tlb_ent -= 1;
- prom_dtlb_load(tlb_ent,
- tte_data + 0x400000,
- tte_vaddr + 0x400000);
- prom_itlb_load(tlb_ent,
- tte_data + 0x400000,
- tte_vaddr + 0x400000);
+ for (i = 0; i < num_kernel_image_mappings; i++) {
+ prom_dtlb_load(tlb_ent - i, tte_data, tte_vaddr);
+ prom_itlb_load(tlb_ent - i, tte_data, tte_vaddr);
+ tte_vaddr += 0x400000;
+ tte_data += 0x400000;
}
- sparc64_highest_unlocked_tlb_ent = tlb_ent - 1;
+ sparc64_highest_unlocked_tlb_ent = tlb_ent - i;
}
if (tlb_type == cheetah_plus) {
sparc64_kern_pri_context = (CTX_CHEETAH_PLUS_CTX0 |
@@ -721,285 +715,684 @@ out:
smp_new_mmu_context_version();
}
-/* Find a free area for the bootmem map, avoiding the kernel image
- * and the initial ramdisk.
- */
-static unsigned long __init choose_bootmap_pfn(unsigned long start_pfn,
- unsigned long end_pfn)
+static int numa_enabled = 1;
+static int numa_debug;
+
+static int __init early_numa(char *p)
{
- unsigned long avoid_start, avoid_end, bootmap_size;
- int i;
+ if (!p)
+ return 0;
- bootmap_size = bootmem_bootmap_pages(end_pfn - start_pfn);
- bootmap_size <<= PAGE_SHIFT;
+ if (strstr(p, "off"))
+ numa_enabled = 0;
- avoid_start = avoid_end = 0;
+ if (strstr(p, "debug"))
+ numa_debug = 1;
+
+ return 0;
+}
+early_param("numa", early_numa);
+
+#define numadbg(f, a...) \
+do { if (numa_debug) \
+ printk(KERN_INFO f, ## a); \
+} while (0)
+
+static void __init find_ramdisk(unsigned long phys_base)
+{
#ifdef CONFIG_BLK_DEV_INITRD
- avoid_start = initrd_start;
- avoid_end = PAGE_ALIGN(initrd_end);
+ if (sparc_ramdisk_image || sparc_ramdisk_image64) {
+ unsigned long ramdisk_image;
+
+ /* Older versions of the bootloader only supported a
+ * 32-bit physical address for the ramdisk image
+ * location, stored at sparc_ramdisk_image. Newer
+ * SILO versions set sparc_ramdisk_image to zero and
+ * provide a full 64-bit physical address at
+ * sparc_ramdisk_image64.
+ */
+ ramdisk_image = sparc_ramdisk_image;
+ if (!ramdisk_image)
+ ramdisk_image = sparc_ramdisk_image64;
+
+ /* Another bootloader quirk. The bootloader normalizes
+ * the physical address to KERNBASE, so we have to
+ * factor that back out and add in the lowest valid
+ * physical page address to get the true physical address.
+ */
+ ramdisk_image -= KERNBASE;
+ ramdisk_image += phys_base;
+
+ numadbg("Found ramdisk at physical address 0x%lx, size %u\n",
+ ramdisk_image, sparc_ramdisk_size);
+
+ initrd_start = ramdisk_image;
+ initrd_end = ramdisk_image + sparc_ramdisk_size;
+
+ lmb_reserve(initrd_start, initrd_end);
+ }
#endif
+}
- for (i = 0; i < pavail_ents; i++) {
- unsigned long start, end;
+struct node_mem_mask {
+ unsigned long mask;
+ unsigned long val;
+ unsigned long bootmem_paddr;
+};
+static struct node_mem_mask node_masks[MAX_NUMNODES];
+static int num_node_masks;
- start = pavail[i].phys_addr;
- end = start + pavail[i].reg_size;
+int numa_cpu_lookup_table[NR_CPUS];
+cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES];
- while (start < end) {
- if (start >= kern_base &&
- start < PAGE_ALIGN(kern_base + kern_size)) {
- start = PAGE_ALIGN(kern_base + kern_size);
- continue;
- }
- if (start >= avoid_start && start < avoid_end) {
- start = avoid_end;
- continue;
- }
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+static bootmem_data_t plat_node_bdata[MAX_NUMNODES];
- if ((end - start) < bootmap_size)
- break;
+struct mdesc_mblock {
+ u64 base;
+ u64 size;
+ u64 offset; /* RA-to-PA */
+};
+static struct mdesc_mblock *mblocks;
+static int num_mblocks;
- if (start < kern_base &&
- (start + bootmap_size) > kern_base) {
- start = PAGE_ALIGN(kern_base + kern_size);
- continue;
- }
+static unsigned long ra_to_pa(unsigned long addr)
+{
+ int i;
- if (start < avoid_start &&
- (start + bootmap_size) > avoid_start) {
- start = avoid_end;
- continue;
- }
+ for (i = 0; i < num_mblocks; i++) {
+ struct mdesc_mblock *m = &mblocks[i];
- /* OK, it doesn't overlap anything, use it. */
- return start >> PAGE_SHIFT;
+ if (addr >= m->base &&
+ addr < (m->base + m->size)) {
+ addr += m->offset;
+ break;
}
}
-
- prom_printf("Cannot find free area for bootmap, aborting.\n");
- prom_halt();
+ return addr;
}
-static void __init trim_pavail(unsigned long *cur_size_p,
- unsigned long *end_of_phys_p)
+static int find_node(unsigned long addr)
{
- unsigned long to_trim = *cur_size_p - cmdline_memory_size;
- unsigned long avoid_start, avoid_end;
int i;
- to_trim = PAGE_ALIGN(to_trim);
+ addr = ra_to_pa(addr);
+ for (i = 0; i < num_node_masks; i++) {
+ struct node_mem_mask *p = &node_masks[i];
- avoid_start = avoid_end = 0;
-#ifdef CONFIG_BLK_DEV_INITRD
- avoid_start = initrd_start;
- avoid_end = PAGE_ALIGN(initrd_end);
+ if ((addr & p->mask) == p->val)
+ return i;
+ }
+ return -1;
+}
+
+static unsigned long nid_range(unsigned long start, unsigned long end,
+ int *nid)
+{
+ *nid = find_node(start);
+ start += PAGE_SIZE;
+ while (start < end) {
+ int n = find_node(start);
+
+ if (n != *nid)
+ break;
+ start += PAGE_SIZE;
+ }
+
+ return start;
+}
+#else
+static unsigned long nid_range(unsigned long start, unsigned long end,
+ int *nid)
+{
+ *nid = 0;
+ return end;
+}
#endif
- /* Trim some pavail[] entries in order to satisfy the
- * requested "mem=xxx" kernel command line specification.
- *
- * We must not trim off the kernel image area nor the
- * initial ramdisk range (if any). Also, we must not trim
- * any pavail[] entry down to zero in order to preserve
- * the invariant that all pavail[] entries have a non-zero
- * size which is assumed by all of the code in here.
- */
- for (i = 0; i < pavail_ents; i++) {
- unsigned long start, end, kern_end;
- unsigned long trim_low, trim_high, n;
+/* This must be invoked after performing all of the necessary
+ * add_active_range() calls for 'nid'. We need to be able to get
+ * correct data from get_pfn_range_for_nid().
+ */
+static void __init allocate_node_data(int nid)
+{
+ unsigned long paddr, num_pages, start_pfn, end_pfn;
+ struct pglist_data *p;
+
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+ paddr = lmb_alloc_nid(sizeof(struct pglist_data),
+ SMP_CACHE_BYTES, nid, nid_range);
+ if (!paddr) {
+ prom_printf("Cannot allocate pglist_data for nid[%d]\n", nid);
+ prom_halt();
+ }
+ NODE_DATA(nid) = __va(paddr);
+ memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
- kern_end = PAGE_ALIGN(kern_base + kern_size);
+ NODE_DATA(nid)->bdata = &plat_node_bdata[nid];
+#endif
- trim_low = start = pavail[i].phys_addr;
- trim_high = end = start + pavail[i].reg_size;
+ p = NODE_DATA(nid);
- if (kern_base >= start &&
- kern_base < end) {
- trim_low = kern_base;
- if (kern_end >= end)
- continue;
- }
- if (kern_end >= start &&
- kern_end < end) {
- trim_high = kern_end;
- }
- if (avoid_start &&
- avoid_start >= start &&
- avoid_start < end) {
- if (trim_low > avoid_start)
- trim_low = avoid_start;
- if (avoid_end >= end)
- continue;
- }
- if (avoid_end &&
- avoid_end >= start &&
- avoid_end < end) {
- if (trim_high < avoid_end)
- trim_high = avoid_end;
+ get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
+ p->node_start_pfn = start_pfn;
+ p->node_spanned_pages = end_pfn - start_pfn;
+
+ if (p->node_spanned_pages) {
+ num_pages = bootmem_bootmap_pages(p->node_spanned_pages);
+
+ paddr = lmb_alloc_nid(num_pages << PAGE_SHIFT, PAGE_SIZE, nid,
+ nid_range);
+ if (!paddr) {
+ prom_printf("Cannot allocate bootmap for nid[%d]\n",
+ nid);
+ prom_halt();
}
+ node_masks[nid].bootmem_paddr = paddr;
+ }
+}
+
+static void init_node_masks_nonnuma(void)
+{
+ int i;
+
+ numadbg("Initializing tables for non-numa.\n");
+
+ node_masks[0].mask = node_masks[0].val = 0;
+ num_node_masks = 1;
+
+ for (i = 0; i < NR_CPUS; i++)
+ numa_cpu_lookup_table[i] = 0;
+
+ numa_cpumask_lookup_table[0] = CPU_MASK_ALL;
+}
+
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+struct pglist_data *node_data[MAX_NUMNODES];
+
+EXPORT_SYMBOL(numa_cpu_lookup_table);
+EXPORT_SYMBOL(numa_cpumask_lookup_table);
+EXPORT_SYMBOL(node_data);
+
+struct mdesc_mlgroup {
+ u64 node;
+ u64 latency;
+ u64 match;
+ u64 mask;
+};
+static struct mdesc_mlgroup *mlgroups;
+static int num_mlgroups;
- if (trim_high <= trim_low)
+static int scan_pio_for_cfg_handle(struct mdesc_handle *md, u64 pio,
+ u32 cfg_handle)
+{
+ u64 arc;
+
+ mdesc_for_each_arc(arc, md, pio, MDESC_ARC_TYPE_FWD) {
+ u64 target = mdesc_arc_target(md, arc);
+ const u64 *val;
+
+ val = mdesc_get_property(md, target,
+ "cfg-handle", NULL);
+ if (val && *val == cfg_handle)
+ return 0;
+ }
+ return -ENODEV;
+}
+
+static int scan_arcs_for_cfg_handle(struct mdesc_handle *md, u64 grp,
+ u32 cfg_handle)
+{
+ u64 arc, candidate, best_latency = ~(u64)0;
+
+ candidate = MDESC_NODE_NULL;
+ mdesc_for_each_arc(arc, md, grp, MDESC_ARC_TYPE_FWD) {
+ u64 target = mdesc_arc_target(md, arc);
+ const char *name = mdesc_node_name(md, target);
+ const u64 *val;
+
+ if (strcmp(name, "pio-latency-group"))
continue;
- if (trim_low == start && trim_high == end) {
- /* Whole chunk is available for trimming.
- * Trim all except one page, in order to keep
- * entry non-empty.
- */
- n = (end - start) - PAGE_SIZE;
- if (n > to_trim)
- n = to_trim;
-
- if (n) {
- pavail[i].phys_addr += n;
- pavail[i].reg_size -= n;
- to_trim -= n;
- }
- } else {
- n = (trim_low - start);
- if (n > to_trim)
- n = to_trim;
-
- if (n) {
- pavail[i].phys_addr += n;
- pavail[i].reg_size -= n;
- to_trim -= n;
- }
- if (to_trim) {
- n = end - trim_high;
- if (n > to_trim)
- n = to_trim;
- if (n) {
- pavail[i].reg_size -= n;
- to_trim -= n;
- }
- }
+ val = mdesc_get_property(md, target, "latency", NULL);
+ if (!val)
+ continue;
+
+ if (*val < best_latency) {
+ candidate = target;
+ best_latency = *val;
}
+ }
+
+ if (candidate == MDESC_NODE_NULL)
+ return -ENODEV;
+
+ return scan_pio_for_cfg_handle(md, candidate, cfg_handle);
+}
+
+int of_node_to_nid(struct device_node *dp)
+{
+ const struct linux_prom64_registers *regs;
+ struct mdesc_handle *md;
+ u32 cfg_handle;
+ int count, nid;
+ u64 grp;
+
+ if (!mlgroups)
+ return -1;
+
+ regs = of_get_property(dp, "reg", NULL);
+ if (!regs)
+ return -1;
+
+ cfg_handle = (regs->phys_addr >> 32UL) & 0x0fffffff;
- if (!to_trim)
+ md = mdesc_grab();
+
+ count = 0;
+ nid = -1;
+ mdesc_for_each_node_by_name(md, grp, "group") {
+ if (!scan_arcs_for_cfg_handle(md, grp, cfg_handle)) {
+ nid = count;
break;
+ }
+ count++;
}
- /* Recalculate. */
- *cur_size_p = 0UL;
- for (i = 0; i < pavail_ents; i++) {
- *end_of_phys_p = pavail[i].phys_addr +
- pavail[i].reg_size;
- *cur_size_p += pavail[i].reg_size;
- }
+ mdesc_release(md);
+
+ return nid;
}
-/* About pages_avail, this is the value we will use to calculate
- * the zholes_size[] argument given to free_area_init_node(). The
- * page allocator uses this to calculate nr_kernel_pages,
- * nr_all_pages and zone->present_pages. On NUMA it is used
- * to calculate zone->min_unmapped_pages and zone->min_slab_pages.
- *
- * So this number should really be set to what the page allocator
- * actually ends up with. This means:
- * 1) It should include bootmem map pages, we'll release those.
- * 2) It should not include the kernel image, except for the
- * __init sections which we will also release.
- * 3) It should include the initrd image, since we'll release
- * that too.
- */
-static unsigned long __init bootmem_init(unsigned long *pages_avail,
- unsigned long phys_base)
+static void add_node_ranges(void)
{
- unsigned long bootmap_size, end_pfn;
- unsigned long end_of_phys_memory = 0UL;
- unsigned long bootmap_pfn, bytes_avail, size;
int i;
- bytes_avail = 0UL;
- for (i = 0; i < pavail_ents; i++) {
- end_of_phys_memory = pavail[i].phys_addr +
- pavail[i].reg_size;
- bytes_avail += pavail[i].reg_size;
+ for (i = 0; i < lmb.memory.cnt; i++) {
+ unsigned long size = lmb_size_bytes(&lmb.memory, i);
+ unsigned long start, end;
+
+ start = lmb.memory.region[i].base;
+ end = start + size;
+ while (start < end) {
+ unsigned long this_end;
+ int nid;
+
+ this_end = nid_range(start, end, &nid);
+
+ numadbg("Adding active range nid[%d] "
+ "start[%lx] end[%lx]\n",
+ nid, start, this_end);
+
+ add_active_range(nid,
+ start >> PAGE_SHIFT,
+ this_end >> PAGE_SHIFT);
+
+ start = this_end;
+ }
}
+}
- /* Determine the location of the initial ramdisk before trying
- * to honor the "mem=xxx" command line argument. We must know
- * where the kernel image and the ramdisk image are so that we
- * do not trim those two areas from the physical memory map.
- */
+static int __init grab_mlgroups(struct mdesc_handle *md)
+{
+ unsigned long paddr;
+ int count = 0;
+ u64 node;
+
+ mdesc_for_each_node_by_name(md, node, "memory-latency-group")
+ count++;
+ if (!count)
+ return -ENOENT;
+
+ paddr = lmb_alloc(count * sizeof(struct mdesc_mlgroup),
+ SMP_CACHE_BYTES);
+ if (!paddr)
+ return -ENOMEM;
+
+ mlgroups = __va(paddr);
+ num_mlgroups = count;
+
+ count = 0;
+ mdesc_for_each_node_by_name(md, node, "memory-latency-group") {
+ struct mdesc_mlgroup *m = &mlgroups[count++];
+ const u64 *val;
+
+ m->node = node;
+
+ val = mdesc_get_property(md, node, "latency", NULL);
+ m->latency = *val;
+ val = mdesc_get_property(md, node, "address-match", NULL);
+ m->match = *val;
+ val = mdesc_get_property(md, node, "address-mask", NULL);
+ m->mask = *val;
+
+ numadbg("MLGROUP[%d]: node[%lx] latency[%lx] "
+ "match[%lx] mask[%lx]\n",
+ count - 1, m->node, m->latency, m->match, m->mask);
+ }
-#ifdef CONFIG_BLK_DEV_INITRD
- /* Now have to check initial ramdisk, so that bootmap does not overwrite it */
- if (sparc_ramdisk_image || sparc_ramdisk_image64) {
- unsigned long ramdisk_image = sparc_ramdisk_image ?
- sparc_ramdisk_image : sparc_ramdisk_image64;
- ramdisk_image -= KERNBASE;
- initrd_start = ramdisk_image + phys_base;
- initrd_end = initrd_start + sparc_ramdisk_size;
- if (initrd_end > end_of_phys_memory) {
- printk(KERN_CRIT "initrd extends beyond end of memory "
- "(0x%016lx > 0x%016lx)\ndisabling initrd\n",
- initrd_end, end_of_phys_memory);
- initrd_start = 0;
- initrd_end = 0;
+ return 0;
+}
+
+static int __init grab_mblocks(struct mdesc_handle *md)
+{
+ unsigned long paddr;
+ int count = 0;
+ u64 node;
+
+ mdesc_for_each_node_by_name(md, node, "mblock")
+ count++;
+ if (!count)
+ return -ENOENT;
+
+ paddr = lmb_alloc(count * sizeof(struct mdesc_mblock),
+ SMP_CACHE_BYTES);
+ if (!paddr)
+ return -ENOMEM;
+
+ mblocks = __va(paddr);
+ num_mblocks = count;
+
+ count = 0;
+ mdesc_for_each_node_by_name(md, node, "mblock") {
+ struct mdesc_mblock *m = &mblocks[count++];
+ const u64 *val;
+
+ val = mdesc_get_property(md, node, "base", NULL);
+ m->base = *val;
+ val = mdesc_get_property(md, node, "size", NULL);
+ m->size = *val;
+ val = mdesc_get_property(md, node,
+ "address-congruence-offset", NULL);
+ m->offset = *val;
+
+ numadbg("MBLOCK[%d]: base[%lx] size[%lx] offset[%lx]\n",
+ count - 1, m->base, m->size, m->offset);
+ }
+
+ return 0;
+}
+
+static void __init numa_parse_mdesc_group_cpus(struct mdesc_handle *md,
+ u64 grp, cpumask_t *mask)
+{
+ u64 arc;
+
+ cpus_clear(*mask);
+
+ mdesc_for_each_arc(arc, md, grp, MDESC_ARC_TYPE_BACK) {
+ u64 target = mdesc_arc_target(md, arc);
+ const char *name = mdesc_node_name(md, target);
+ const u64 *id;
+
+ if (strcmp(name, "cpu"))
+ continue;
+ id = mdesc_get_property(md, target, "id", NULL);
+ if (*id < NR_CPUS)
+ cpu_set(*id, *mask);
+ }
+}
+
+static struct mdesc_mlgroup * __init find_mlgroup(u64 node)
+{
+ int i;
+
+ for (i = 0; i < num_mlgroups; i++) {
+ struct mdesc_mlgroup *m = &mlgroups[i];
+ if (m->node == node)
+ return m;
+ }
+ return NULL;
+}
+
+static int __init numa_attach_mlgroup(struct mdesc_handle *md, u64 grp,
+ int index)
+{
+ struct mdesc_mlgroup *candidate = NULL;
+ u64 arc, best_latency = ~(u64)0;
+ struct node_mem_mask *n;
+
+ mdesc_for_each_arc(arc, md, grp, MDESC_ARC_TYPE_FWD) {
+ u64 target = mdesc_arc_target(md, arc);
+ struct mdesc_mlgroup *m = find_mlgroup(target);
+ if (!m)
+ continue;
+ if (m->latency < best_latency) {
+ candidate = m;
+ best_latency = m->latency;
}
}
-#endif
+ if (!candidate)
+ return -ENOENT;
+
+ if (num_node_masks != index) {
+ printk(KERN_ERR "Inconsistent NUMA state, "
+ "index[%d] != num_node_masks[%d]\n",
+ index, num_node_masks);
+ return -EINVAL;
+ }
- if (cmdline_memory_size &&
- bytes_avail > cmdline_memory_size)
- trim_pavail(&bytes_avail,
- &end_of_phys_memory);
+ n = &node_masks[num_node_masks++];
- *pages_avail = bytes_avail >> PAGE_SHIFT;
+ n->mask = candidate->mask;
+ n->val = candidate->match;
- end_pfn = end_of_phys_memory >> PAGE_SHIFT;
+ numadbg("NUMA NODE[%d]: mask[%lx] val[%lx] (latency[%lx])\n",
+ index, n->mask, n->val, candidate->latency);
- /* Initialize the boot-time allocator. */
- max_pfn = max_low_pfn = end_pfn;
- min_low_pfn = (phys_base >> PAGE_SHIFT);
+ return 0;
+}
- bootmap_pfn = choose_bootmap_pfn(min_low_pfn, end_pfn);
+static int __init numa_parse_mdesc_group(struct mdesc_handle *md, u64 grp,
+ int index)
+{
+ cpumask_t mask;
+ int cpu;
- bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn,
- min_low_pfn, end_pfn);
+ numa_parse_mdesc_group_cpus(md, grp, &mask);
- /* Now register the available physical memory with the
- * allocator.
- */
- for (i = 0; i < pavail_ents; i++)
- free_bootmem(pavail[i].phys_addr, pavail[i].reg_size);
+ for_each_cpu_mask(cpu, mask)
+ numa_cpu_lookup_table[cpu] = index;
+ numa_cpumask_lookup_table[index] = mask;
-#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start) {
- size = initrd_end - initrd_start;
+ if (numa_debug) {
+ printk(KERN_INFO "NUMA GROUP[%d]: cpus [ ", index);
+ for_each_cpu_mask(cpu, mask)
+ printk("%d ", cpu);
+ printk("]\n");
+ }
+
+ return numa_attach_mlgroup(md, grp, index);
+}
+
+static int __init numa_parse_mdesc(void)
+{
+ struct mdesc_handle *md = mdesc_grab();
+ int i, err, count;
+ u64 node;
+
+ node = mdesc_node_by_name(md, MDESC_NODE_NULL, "latency-groups");
+ if (node == MDESC_NODE_NULL) {
+ mdesc_release(md);
+ return -ENOENT;
+ }
+
+ err = grab_mblocks(md);
+ if (err < 0)
+ goto out;
+
+ err = grab_mlgroups(md);
+ if (err < 0)
+ goto out;
+
+ count = 0;
+ mdesc_for_each_node_by_name(md, node, "group") {
+ err = numa_parse_mdesc_group(md, node, count);
+ if (err < 0)
+ break;
+ count++;
+ }
+
+ add_node_ranges();
+
+ for (i = 0; i < num_node_masks; i++) {
+ allocate_node_data(i);
+ node_set_online(i);
+ }
+
+ err = 0;
+out:
+ mdesc_release(md);
+ return err;
+}
+
+static int __init numa_parse_sun4u(void)
+{
+ return -1;
+}
+
+static int __init bootmem_init_numa(void)
+{
+ int err = -1;
- /* Reserve the initrd image area. */
- reserve_bootmem(initrd_start, size, BOOTMEM_DEFAULT);
+ numadbg("bootmem_init_numa()\n");
- initrd_start += PAGE_OFFSET;
- initrd_end += PAGE_OFFSET;
+ if (numa_enabled) {
+ if (tlb_type == hypervisor)
+ err = numa_parse_mdesc();
+ else
+ err = numa_parse_sun4u();
}
+ return err;
+}
+
+#else
+
+static int bootmem_init_numa(void)
+{
+ return -1;
+}
+
#endif
- /* Reserve the kernel text/data/bss. */
- reserve_bootmem(kern_base, kern_size, BOOTMEM_DEFAULT);
- *pages_avail -= PAGE_ALIGN(kern_size) >> PAGE_SHIFT;
-
- /* Add back in the initmem pages. */
- size = ((unsigned long)(__init_end) & PAGE_MASK) -
- PAGE_ALIGN((unsigned long)__init_begin);
- *pages_avail += size >> PAGE_SHIFT;
-
- /* Reserve the bootmem map. We do not account for it
- * in pages_avail because we will release that memory
- * in free_all_bootmem.
- */
- size = bootmap_size;
- reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size, BOOTMEM_DEFAULT);
- for (i = 0; i < pavail_ents; i++) {
+static void __init bootmem_init_nonnuma(void)
+{
+ unsigned long top_of_ram = lmb_end_of_DRAM();
+ unsigned long total_ram = lmb_phys_mem_size();
+ unsigned int i;
+
+ numadbg("bootmem_init_nonnuma()\n");
+
+ printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
+ top_of_ram, total_ram);
+ printk(KERN_INFO "Memory hole size: %ldMB\n",
+ (top_of_ram - total_ram) >> 20);
+
+ init_node_masks_nonnuma();
+
+ for (i = 0; i < lmb.memory.cnt; i++) {
+ unsigned long size = lmb_size_bytes(&lmb.memory, i);
unsigned long start_pfn, end_pfn;
- start_pfn = pavail[i].phys_addr >> PAGE_SHIFT;
- end_pfn = (start_pfn + (pavail[i].reg_size >> PAGE_SHIFT));
- memory_present(0, start_pfn, end_pfn);
+ if (!size)
+ continue;
+
+ start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
+ end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
+ add_active_range(0, start_pfn, end_pfn);
+ }
+
+ allocate_node_data(0);
+
+ node_set_online(0);
+}
+
+static void __init reserve_range_in_node(int nid, unsigned long start,
+ unsigned long end)
+{
+ numadbg(" reserve_range_in_node(nid[%d],start[%lx],end[%lx]\n",
+ nid, start, end);
+ while (start < end) {
+ unsigned long this_end;
+ int n;
+
+ this_end = nid_range(start, end, &n);
+ if (n == nid) {
+ numadbg(" MATCH reserving range [%lx:%lx]\n",
+ start, this_end);
+ reserve_bootmem_node(NODE_DATA(nid), start,
+ (this_end - start), BOOTMEM_DEFAULT);
+ } else
+ numadbg(" NO MATCH, advancing start to %lx\n",
+ this_end);
+
+ start = this_end;
+ }
+}
+
+static void __init trim_reserved_in_node(int nid)
+{
+ int i;
+
+ numadbg(" trim_reserved_in_node(%d)\n", nid);
+
+ for (i = 0; i < lmb.reserved.cnt; i++) {
+ unsigned long start = lmb.reserved.region[i].base;
+ unsigned long size = lmb_size_bytes(&lmb.reserved, i);
+ unsigned long end = start + size;
+
+ reserve_range_in_node(nid, start, end);
+ }
+}
+
+static void __init bootmem_init_one_node(int nid)
+{
+ struct pglist_data *p;
+
+ numadbg("bootmem_init_one_node(%d)\n", nid);
+
+ p = NODE_DATA(nid);
+
+ if (p->node_spanned_pages) {
+ unsigned long paddr = node_masks[nid].bootmem_paddr;
+ unsigned long end_pfn;
+
+ end_pfn = p->node_start_pfn + p->node_spanned_pages;
+
+ numadbg(" init_bootmem_node(%d, %lx, %lx, %lx)\n",
+ nid, paddr >> PAGE_SHIFT, p->node_start_pfn, end_pfn);
+
+ init_bootmem_node(p, paddr >> PAGE_SHIFT,
+ p->node_start_pfn, end_pfn);
+
+ numadbg(" free_bootmem_with_active_regions(%d, %lx)\n",
+ nid, end_pfn);
+ free_bootmem_with_active_regions(nid, end_pfn);
+
+ trim_reserved_in_node(nid);
+
+ numadbg(" sparse_memory_present_with_active_regions(%d)\n",
+ nid);
+ sparse_memory_present_with_active_regions(nid);
}
+}
+
+static unsigned long __init bootmem_init(unsigned long phys_base)
+{
+ unsigned long end_pfn;
+ int nid;
+
+ end_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT;
+ max_pfn = max_low_pfn = end_pfn;
+ min_low_pfn = (phys_base >> PAGE_SHIFT);
+
+ if (bootmem_init_numa() < 0)
+ bootmem_init_nonnuma();
+
+ /* XXX cpu notifier XXX */
+
+ for_each_online_node(nid)
+ bootmem_init_one_node(nid);
sparse_init();
@@ -1010,7 +1403,8 @@ static struct linux_prom64_registers pall[MAX_BANKS] __initdata;
static int pall_ents __initdata;
#ifdef CONFIG_DEBUG_PAGEALLOC
-static unsigned long kernel_map_range(unsigned long pstart, unsigned long pend, pgprot_t prot)
+static unsigned long __ref kernel_map_range(unsigned long pstart,
+ unsigned long pend, pgprot_t prot)
{
unsigned long vstart = PAGE_OFFSET + pstart;
unsigned long vend = PAGE_OFFSET + pend;
@@ -1279,10 +1673,6 @@ void __cpuinit sun4v_ktsb_register(void)
/* paging_init() sets up the page tables */
-extern void cheetah_ecache_flush_init(void);
-extern void sun4v_patch_tlb_handlers(void);
-
-extern void cpu_probe(void);
extern void central_probe(void);
static unsigned long last_valid_pfn;
@@ -1298,7 +1688,7 @@ void __init setup_per_cpu_areas(void)
void __init paging_init(void)
{
- unsigned long end_pfn, pages_avail, shift, phys_base;
+ unsigned long end_pfn, shift, phys_base;
unsigned long real_end, i;
/* These build time checkes make sure that the dcache_dirty_cpu()
@@ -1309,9 +1699,21 @@ void __init paging_init(void)
* functions like clear_dcache_dirty_cpu use the cpu mask
* in 13-bit signed-immediate instruction fields.
*/
- BUILD_BUG_ON(FLAGS_RESERVED != 32);
+
+ /*
+ * Page flags must not reach into upper 32 bits that are used
+ * for the cpu number
+ */
+ BUILD_BUG_ON(NR_PAGEFLAGS > 32);
+
+ /*
+ * The bit fields placed in the high range must not reach below
+ * the 32 bit boundary. Otherwise we cannot place the cpu field
+ * at the 32 bit boundary.
+ */
BUILD_BUG_ON(SECTIONS_WIDTH + NODES_WIDTH + ZONES_WIDTH +
- ilog2(roundup_pow_of_two(NR_CPUS)) > FLAGS_RESERVED);
+ ilog2(roundup_pow_of_two(NR_CPUS)) > 32);
+
BUILD_BUG_ON(NR_CPUS > 4096);
kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL;
@@ -1339,24 +1741,35 @@ void __init paging_init(void)
sun4v_ktsb_init();
}
+ lmb_init();
+
/* Find available physical memory... */
read_obp_memory("available", &pavail[0], &pavail_ents);
phys_base = 0xffffffffffffffffUL;
- for (i = 0; i < pavail_ents; i++)
+ for (i = 0; i < pavail_ents; i++) {
phys_base = min(phys_base, pavail[i].phys_addr);
+ lmb_add(pavail[i].phys_addr, pavail[i].reg_size);
+ }
+
+ lmb_reserve(kern_base, kern_size);
+
+ find_ramdisk(phys_base);
+
+ if (cmdline_memory_size)
+ lmb_enforce_memory_limit(phys_base + cmdline_memory_size);
+
+ lmb_analyze();
+ lmb_dump_all();
set_bit(0, mmu_context_bmap);
shift = kern_base + PAGE_OFFSET - ((unsigned long)KERNBASE);
real_end = (unsigned long)_end;
- if ((real_end > ((unsigned long)KERNBASE + 0x400000)))
- bigkernel = 1;
- if ((real_end > ((unsigned long)KERNBASE + 0x800000))) {
- prom_printf("paging_init: Kernel > 8MB, too large.\n");
- prom_halt();
- }
+ num_kernel_image_mappings = DIV_ROUND_UP(real_end - KERNBASE, 1 << 22);
+ printk("Kernel: Using %d locked TLB entries for main kernel image.\n",
+ num_kernel_image_mappings);
/* Set kernel pgd to upper alias so physical page computations
* work.
@@ -1383,14 +1796,10 @@ void __init paging_init(void)
if (tlb_type == hypervisor)
sun4v_ktsb_register();
- /* Setup bootmem... */
- pages_avail = 0;
- last_valid_pfn = end_pfn = bootmem_init(&pages_avail, phys_base);
-
- max_mapnr = last_valid_pfn;
-
- kernel_physical_mapping_init();
-
+ /* We must setup the per-cpu areas before we pull in the
+ * PROM and the MDESC. The code there fills in cpu and
+ * other information into per-cpu data structures.
+ */
real_setup_per_cpu_areas();
prom_build_devicetree();
@@ -1398,20 +1807,22 @@ void __init paging_init(void)
if (tlb_type == hypervisor)
sun4v_mdesc_init();
+ /* Setup bootmem... */
+ last_valid_pfn = end_pfn = bootmem_init(phys_base);
+
+#ifndef CONFIG_NEED_MULTIPLE_NODES
+ max_mapnr = last_valid_pfn;
+#endif
+ kernel_physical_mapping_init();
+
{
- unsigned long zones_size[MAX_NR_ZONES];
- unsigned long zholes_size[MAX_NR_ZONES];
- int znum;
+ unsigned long max_zone_pfns[MAX_NR_ZONES];
- for (znum = 0; znum < MAX_NR_ZONES; znum++)
- zones_size[znum] = zholes_size[znum] = 0;
+ memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
- zones_size[ZONE_NORMAL] = end_pfn;
- zholes_size[ZONE_NORMAL] = end_pfn - pages_avail;
+ max_zone_pfns[ZONE_NORMAL] = end_pfn;
- free_area_init_node(0, &contig_page_data, zones_size,
- __pa(PAGE_OFFSET) >> PAGE_SHIFT,
- zholes_size);
+ free_area_init_nodes(max_zone_pfns);
}
printk("Booting Linux...\n");
@@ -1420,21 +1831,52 @@ void __init paging_init(void)
cpu_probe();
}
-static void __init taint_real_pages(void)
+int __init page_in_phys_avail(unsigned long paddr)
+{
+ int i;
+
+ paddr &= PAGE_MASK;
+
+ for (i = 0; i < pavail_ents; i++) {
+ unsigned long start, end;
+
+ start = pavail[i].phys_addr;
+ end = start + pavail[i].reg_size;
+
+ if (paddr >= start && paddr < end)
+ return 1;
+ }
+ if (paddr >= kern_base && paddr < (kern_base + kern_size))
+ return 1;
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (paddr >= __pa(initrd_start) &&
+ paddr < __pa(PAGE_ALIGN(initrd_end)))
+ return 1;
+#endif
+
+ return 0;
+}
+
+static struct linux_prom64_registers pavail_rescan[MAX_BANKS] __initdata;
+static int pavail_rescan_ents __initdata;
+
+/* Certain OBP calls, such as fetching "available" properties, can
+ * claim physical memory. So, along with initializing the valid
+ * address bitmap, what we do here is refetch the physical available
+ * memory list again, and make sure it provides at least as much
+ * memory as 'pavail' does.
+ */
+static void setup_valid_addr_bitmap_from_pavail(void)
{
int i;
read_obp_memory("available", &pavail_rescan[0], &pavail_rescan_ents);
- /* Find changes discovered in the physmem available rescan and
- * reserve the lost portions in the bootmem maps.
- */
for (i = 0; i < pavail_ents; i++) {
unsigned long old_start, old_end;
old_start = pavail[i].phys_addr;
- old_end = old_start +
- pavail[i].reg_size;
+ old_end = old_start + pavail[i].reg_size;
while (old_start < old_end) {
int n;
@@ -1452,7 +1894,16 @@ static void __init taint_real_pages(void)
goto do_next_page;
}
}
- reserve_bootmem(old_start, PAGE_SIZE, BOOTMEM_DEFAULT);
+
+ prom_printf("mem_init: Lost memory in pavail\n");
+ prom_printf("mem_init: OLD start[%lx] size[%lx]\n",
+ pavail[i].phys_addr,
+ pavail[i].reg_size);
+ prom_printf("mem_init: NEW start[%lx] size[%lx]\n",
+ pavail_rescan[i].phys_addr,
+ pavail_rescan[i].reg_size);
+ prom_printf("mem_init: Cannot continue, aborting.\n");
+ prom_halt();
do_next_page:
old_start += PAGE_SIZE;
@@ -1460,32 +1911,6 @@ static void __init taint_real_pages(void)
}
}
-int __init page_in_phys_avail(unsigned long paddr)
-{
- int i;
-
- paddr &= PAGE_MASK;
-
- for (i = 0; i < pavail_rescan_ents; i++) {
- unsigned long start, end;
-
- start = pavail_rescan[i].phys_addr;
- end = start + pavail_rescan[i].reg_size;
-
- if (paddr >= start && paddr < end)
- return 1;
- }
- if (paddr >= kern_base && paddr < (kern_base + kern_size))
- return 1;
-#ifdef CONFIG_BLK_DEV_INITRD
- if (paddr >= __pa(initrd_start) &&
- paddr < __pa(PAGE_ALIGN(initrd_end)))
- return 1;
-#endif
-
- return 0;
-}
-
void __init mem_init(void)
{
unsigned long codepages, datapages, initpages;
@@ -1508,14 +1933,26 @@ void __init mem_init(void)
addr += PAGE_SIZE;
}
- taint_real_pages();
+ setup_valid_addr_bitmap_from_pavail();
high_memory = __va(last_valid_pfn << PAGE_SHIFT);
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+ for_each_online_node(i) {
+ if (NODE_DATA(i)->node_spanned_pages != 0) {
+ totalram_pages +=
+ free_all_bootmem_node(NODE_DATA(i));
+ }
+ }
+#else
+ totalram_pages = free_all_bootmem();
+#endif
+
/* We subtract one to account for the mem_map_zero page
* allocated below.
*/
- totalram_pages = num_physpages = free_all_bootmem() - 1;
+ totalram_pages -= 1;
+ num_physpages = totalram_pages;
/*
* Set up the zero page, mark it reserved, so that page count
diff --git a/arch/sparc64/mm/tlb.c b/arch/sparc64/mm/tlb.c
index 3f10fc921b00..ae24919cba7c 100644
--- a/arch/sparc64/mm/tlb.c
+++ b/arch/sparc64/mm/tlb.c
@@ -23,9 +23,7 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers) = { 0, };
void flush_tlb_pending(void)
{
- struct mmu_gather *mp = &__get_cpu_var(mmu_gathers);
-
- preempt_disable();
+ struct mmu_gather *mp = &get_cpu_var(mmu_gathers);
if (mp->tlb_nr) {
flush_tsb_user(mp);
@@ -42,7 +40,7 @@ void flush_tlb_pending(void)
mp->tlb_nr = 0;
}
- preempt_enable();
+ put_cpu_var(mmu_gathers);
}
void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t orig)
diff --git a/arch/sparc64/mm/tsb.c b/arch/sparc64/mm/tsb.c
index a3e6e4b635b3..fe70c8a557b5 100644
--- a/arch/sparc64/mm/tsb.c
+++ b/arch/sparc64/mm/tsb.c
@@ -321,7 +321,8 @@ retry_tsb_alloc:
if (new_size > (PAGE_SIZE * 2))
gfp_flags = __GFP_NOWARN | __GFP_NORETRY;
- new_tsb = kmem_cache_alloc(tsb_caches[new_cache_index], gfp_flags);
+ new_tsb = kmem_cache_alloc_node(tsb_caches[new_cache_index],
+ gfp_flags, numa_node_id());
if (unlikely(!new_tsb)) {
/* Not being able to fork due to a high-order TSB
* allocation failure is very bad behavior. Just back
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S
index 2865c105b6a4..e686a67561af 100644
--- a/arch/sparc64/mm/ultra.S
+++ b/arch/sparc64/mm/ultra.S
@@ -476,7 +476,6 @@ xcall_sync_tick:
#endif
call smp_synchronize_tick_client
nop
- clr %l6
b rtrap_xcall
ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
@@ -511,7 +510,6 @@ xcall_report_regs:
#endif
call __show_regs
add %sp, PTREGS_OFF, %o0
- clr %l6
/* Has to be a non-v9 branch due to the large distance. */
b rtrap_xcall
ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
@@ -576,7 +574,7 @@ __hypervisor_tlb_xcall_error:
mov %l4, %o0
call hypervisor_tlbop_error_xcall
mov %l5, %o1
- ba,a,pt %xcc, rtrap_clr_l6
+ ba,a,pt %xcc, rtrap
.globl __hypervisor_xcall_flush_tlb_mm
__hypervisor_xcall_flush_tlb_mm: /* 21 insns */
diff --git a/arch/sparc64/solaris/Makefile b/arch/sparc64/solaris/Makefile
deleted file mode 100644
index 8c8663033bfb..000000000000
--- a/arch/sparc64/solaris/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for the Solaris binary emulation.
-#
-
-EXTRA_AFLAGS := -ansi
-
-solaris-objs := entry64.o fs.o misc.o signal.o systbl.o socket.o \
- ioctl.o ipc.o socksys.o timod.o
-
-obj-$(CONFIG_SOLARIS_EMUL) += solaris.o
diff --git a/arch/sparc64/solaris/conv.h b/arch/sparc64/solaris/conv.h
deleted file mode 100644
index 5faf59a9de39..000000000000
--- a/arch/sparc64/solaris/conv.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* $Id: conv.h,v 1.4 1998/08/15 20:42:51 davem Exp $
- * conv.h: Utility macros for Solaris emulation
- *
- * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-/* #define DEBUG_SOLARIS */
-#define DEBUG_SOLARIS_KMALLOC
-
-#ifndef __ASSEMBLY__
-
-#include <asm/unistd.h>
-
-/* Use this to get at 32-bit user passed pointers. */
-#define A(__x) \
-({ unsigned long __ret; \
- __asm__ ("srl %0, 0, %0" \
- : "=r" (__ret) \
- : "0" (__x)); \
- (void __user *)__ret; \
-})
-
-extern unsigned sys_call_table[];
-extern unsigned sys_call_table32[];
-extern unsigned sunos_sys_table[];
-
-#define SYS(name) ((long)sys_call_table[__NR_##name])
-#define SUNOS(x) ((long)sunos_sys_table[x])
-
-#ifdef DEBUG_SOLARIS
-#define SOLD(s) printk("%s,%d,%s(): %s\n",__FILE__,__LINE__,__FUNCTION__,(s))
-#define SOLDD(s) printk("solaris: "); printk s
-#else
-#define SOLD(s)
-#define SOLDD(s)
-#endif
-
-#endif /* __ASSEMBLY__ */
diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S
deleted file mode 100644
index f170324e8bf2..000000000000
--- a/arch/sparc64/solaris/entry64.S
+++ /dev/null
@@ -1,223 +0,0 @@
-/* $Id: entry64.S,v 1.7 2002/02/09 19:49:31 davem Exp $
- * entry64.S: Solaris syscall emulation entry point.
- *
- * Copyright (C) 1996,1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
- */
-
-#include <linux/errno.h>
-
-#include <asm/head.h>
-#include <asm/asi.h>
-#include <asm/smp.h>
-#include <asm/ptrace.h>
-#include <asm/page.h>
-#include <asm/signal.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/thread_info.h>
-
-#include "conv.h"
-
-#define NR_SYSCALLS 256
-
- .text
-solaris_syscall_trace:
- add %sp, PTREGS_OFF, %o0
- call syscall_trace
- mov 0, %o1
- srl %i0, 0, %o0
- mov %i4, %o4
- srl %i1, 0, %o1
- mov %i5, %o5
- andcc %l3, 1, %g0
- be,pt %icc, 2f
- srl %i2, 0, %o2
- b,pt %xcc, 2f
- add %sp, PTREGS_OFF, %o0
-
-solaris_sucks:
-/* Solaris is a big system which needs to be able to do all the things
- * in Inf+1 different ways */
- add %i6, 0x5c, %o0
- mov %i0, %g1
- mov %i1, %i0
- mov %i2, %i1
- srl %o0, 0, %o0
- mov %i3, %i2
- movrz %g1, 256, %g1 /* Ensure we don't loop forever */
- mov %i4, %i3
- mov %i5, %i4
- ba,pt %xcc, solaris_sparc_syscall
-exen: lduwa [%o0] ASI_S, %i5
-
-exenf: ba,pt %xcc, solaris_sparc_syscall
- clr %i5
-
-/* For shared binaries, binfmt_elf32 already sets up personality
- and exec_domain. This is to handle static binaries as well */
-solaris_reg:
- call solaris_register
- nop
- ba,pt %xcc, 1f
- mov %i4, %o4
-
-linux_syscall_for_solaris:
- sethi %hi(sys_call_table32), %l6
- or %l6, %lo(sys_call_table32), %l6
- sll %l3, 2, %l4
- ba,pt %xcc, 10f
- lduw [%l6 + %l4], %l3
-
- /* Solaris system calls enter here... */
- .align 32
- .globl solaris_sparc_syscall, entry64_personality_patch
-solaris_sparc_syscall:
-entry64_personality_patch:
- ldub [%g4 + 0x0], %l0
- cmp %g1, 255
- bg,pn %icc, solaris_unimplemented
- srl %g1, 0, %g1
- sethi %hi(solaris_sys_table), %l7
- or %l7, %lo(solaris_sys_table), %l7
- brz,pn %g1, solaris_sucks
- mov %i4, %o4
- sll %g1, 2, %l4
- cmp %l0, 1
- bne,pn %icc, solaris_reg
-1: srl %i0, 0, %o0
- lduw [%l7 + %l4], %l3
- srl %i1, 0, %o1
- ldx [%g6 + TI_FLAGS], %l5
- cmp %l3, NR_SYSCALLS
- bleu,a,pn %xcc, linux_syscall_for_solaris
- nop
- andcc %l3, 1, %g0
- bne,a,pn %icc, 10f
- add %sp, PTREGS_OFF, %o0
-10: srl %i2, 0, %o2
- mov %i5, %o5
- andn %l3, 3, %l7
- andcc %l5, _TIF_SYSCALL_TRACE, %g0
- bne,pn %icc, solaris_syscall_trace
- mov %i0, %l5
-2: call %l7
- srl %i3, 0, %o3
-ret_from_solaris:
- stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
- ldx [%g6 + TI_FLAGS], %l6
- sra %o0, 0, %o0
- mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2
- ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3
- cmp %o0, -ERESTART_RESTARTBLOCK
- sllx %g2, 32, %g2
- bgeu,pn %xcc, 1f
- andcc %l6, _TIF_SYSCALL_TRACE, %l6
-
- /* System call success, clear Carry condition code. */
- andn %g3, %g2, %g3
- stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
- bne,pn %icc, solaris_syscall_trace2
- ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1
- andcc %l1, 1, %g0
- bne,pn %icc, 2f
- clr %l6
- add %l1, 0x4, %l2
- stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ! pc = npc
- call rtrap
- stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc+4
-
- /* When tnpc & 1, this comes from setcontext and we don't want to advance pc */
-2: andn %l1, 3, %l1
- call rtrap
- stx %l1, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc&~3
-
-1:
- /* System call failure, set Carry condition code.
- * Also, get abs(errno) to return to the process.
- */
- sub %g0, %o0, %o0
- or %g3, %g2, %g3
- cmp %o0, ERANGE /* 0-ERANGE are identity mapped */
- bleu,pt %icc, 1f
- cmp %o0, EMEDIUMTYPE
- bgu,pn %icc, 1f
- sethi %hi(solaris_err_table), %l6
- sll %o0, 2, %o0
- or %l6, %lo(solaris_err_table), %l6
- ldsw [%l6 + %o0], %o0
-1: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
- mov 1, %l6
- stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
- bne,pn %icc, solaris_syscall_trace2
- ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1
- andcc %l1, 1, %g0
- bne,pn %icc, 2b
- add %l1, 0x4, %l2
- stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ! pc = npc
- call rtrap
- stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc+4
-
-solaris_syscall_trace2:
- add %sp, PTREGS_OFF, %o0
- call syscall_trace
- mov 1, %o1
- add %l1, 0x4, %l2 /* npc = npc+4 */
- andcc %l1, 1, %g0
- bne,pn %icc, 2b
- nop
- stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
- call rtrap
- stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
-
- /* This one is tricky, so that's why we do it in assembly */
- .globl solaris_sigsuspend
-solaris_sigsuspend:
- call do_sol_sigsuspend
- nop
- brlz,pn %o0, ret_from_solaris
- nop
- call sys_sigsuspend
- stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
- b,pt %xcc, ret_from_solaris
- nop
-
- .globl solaris_getpid
-solaris_getpid:
- call sys_getppid
- nop
- call sys_getpid
- stx %o0, [%sp + PTREGS_OFF + PT_V9_I1]
- b,pt %xcc, ret_from_solaris
- nop
-
- .globl solaris_getuid
-solaris_getuid:
- call sys_geteuid
- nop
- call sys_getuid
- stx %o1, [%sp + PTREGS_OFF + PT_V9_I1]
- b,pt %xcc, ret_from_solaris
- nop
-
- .globl solaris_getgid
-solaris_getgid:
- call sys_getegid
- nop
- call sys_getgid
- stx %o1, [%sp + PTREGS_OFF + PT_V9_I1]
- b,pt %xcc, ret_from_solaris
- nop
-
- .globl solaris_unimplemented
-solaris_unimplemented:
- call do_sol_unimplemented
- add %sp, PTREGS_OFF, %o0
- ba,pt %xcc, ret_from_solaris
- nop
-
- .section __ex_table,"a"
- .align 4
- .word exen, exenf
-
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
deleted file mode 100644
index 7d035f0d3ae1..000000000000
--- a/arch/sparc64/solaris/fs.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/* $Id: fs.c,v 1.27 2002/02/08 03:57:14 davem Exp $
- * fs.c: fs related syscall emulation for Solaris
- *
- * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- *
- * 1999-08-19 Implemented solaris F_FREESP (truncate)
- * fcntl, by Jason Rappleye (rappleye@ccr.buffalo.edu)
- */
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/capability.h>
-#include <linux/fs.h>
-#include <linux/namei.h>
-#include <linux/mm.h>
-#include <linux/file.h>
-#include <linux/stat.h>
-#include <linux/smp_lock.h>
-#include <linux/limits.h>
-#include <linux/resource.h>
-#include <linux/quotaops.h>
-#include <linux/mount.h>
-#include <linux/vfs.h>
-
-#include <asm/uaccess.h>
-#include <asm/string.h>
-#include <asm/ptrace.h>
-
-#include "conv.h"
-
-#define R3_VERSION 1
-#define R4_VERSION 2
-
-typedef struct {
- s32 tv_sec;
- s32 tv_nsec;
-} timestruct_t;
-
-struct sol_stat {
- u32 st_dev;
- s32 st_pad1[3]; /* network id */
- u32 st_ino;
- u32 st_mode;
- u32 st_nlink;
- u32 st_uid;
- u32 st_gid;
- u32 st_rdev;
- s32 st_pad2[2];
- s32 st_size;
- s32 st_pad3; /* st_size, off_t expansion */
- timestruct_t st_atime;
- timestruct_t st_mtime;
- timestruct_t st_ctime;
- s32 st_blksize;
- s32 st_blocks;
- char st_fstype[16];
- s32 st_pad4[8]; /* expansion area */
-};
-
-struct sol_stat64 {
- u32 st_dev;
- s32 st_pad1[3]; /* network id */
- u64 st_ino;
- u32 st_mode;
- u32 st_nlink;
- u32 st_uid;
- u32 st_gid;
- u32 st_rdev;
- s32 st_pad2[2];
- s64 st_size;
- timestruct_t st_atime;
- timestruct_t st_mtime;
- timestruct_t st_ctime;
- s64 st_blksize;
- s32 st_blocks;
- char st_fstype[16];
- s32 st_pad4[4]; /* expansion area */
-};
-
-#define UFSMAGIC (((unsigned)'u'<<24)||((unsigned)'f'<<16)||((unsigned)'s'<<8))
-
-static inline int putstat(struct sol_stat __user *ubuf, struct kstat *kbuf)
-{
- u32 ino;
-
- if (kbuf->size > MAX_NON_LFS ||
- !sysv_valid_dev(kbuf->dev) ||
- !sysv_valid_dev(kbuf->rdev))
- return -EOVERFLOW;
- ino = kbuf->ino;
- if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
- return -EOVERFLOW;
- if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) ||
- __put_user (ino, &ubuf->st_ino) ||
- __put_user (kbuf->mode, &ubuf->st_mode) ||
- __put_user (kbuf->nlink, &ubuf->st_nlink) ||
- __put_user (kbuf->uid, &ubuf->st_uid) ||
- __put_user (kbuf->gid, &ubuf->st_gid) ||
- __put_user (sysv_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
- __put_user (kbuf->size, &ubuf->st_size) ||
- __put_user (kbuf->atime.tv_sec, &ubuf->st_atime.tv_sec) ||
- __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime.tv_nsec) ||
- __put_user (kbuf->mtime.tv_sec, &ubuf->st_mtime.tv_sec) ||
- __put_user (kbuf->mtime.tv_nsec, &ubuf->st_mtime.tv_nsec) ||
- __put_user (kbuf->ctime.tv_sec, &ubuf->st_ctime.tv_sec) ||
- __put_user (kbuf->ctime.tv_nsec, &ubuf->st_ctime.tv_nsec) ||
- __put_user (kbuf->blksize, &ubuf->st_blksize) ||
- __put_user (kbuf->blocks, &ubuf->st_blocks) ||
- __put_user (UFSMAGIC, (unsigned __user *)ubuf->st_fstype))
- return -EFAULT;
- return 0;
-}
-
-static inline int putstat64(struct sol_stat64 __user *ubuf, struct kstat *kbuf)
-{
- if (!sysv_valid_dev(kbuf->dev) || !sysv_valid_dev(kbuf->rdev))
- return -EOVERFLOW;
- if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) ||
- __put_user (kbuf->ino, &ubuf->st_ino) ||
- __put_user (kbuf->mode, &ubuf->st_mode) ||
- __put_user (kbuf->nlink, &ubuf->st_nlink) ||
- __put_user (kbuf->uid, &ubuf->st_uid) ||
- __put_user (kbuf->gid, &ubuf->st_gid) ||
- __put_user (sysv_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
- __put_user (kbuf->size, &ubuf->st_size) ||
- __put_user (kbuf->atime.tv_sec, &ubuf->st_atime.tv_sec) ||
- __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime.tv_nsec) ||
- __put_user (kbuf->mtime.tv_sec, &ubuf->st_mtime.tv_sec) ||
- __put_user (kbuf->mtime.tv_nsec, &ubuf->st_mtime.tv_nsec) ||
- __put_user (kbuf->ctime.tv_sec, &ubuf->st_ctime.tv_sec) ||
- __put_user (kbuf->ctime.tv_nsec, &ubuf->st_ctime.tv_nsec) ||
- __put_user (kbuf->blksize, &ubuf->st_blksize) ||
- __put_user (kbuf->blocks, &ubuf->st_blocks) ||
- __put_user (UFSMAGIC, (unsigned __user *)ubuf->st_fstype))
- return -EFAULT;
- return 0;
-}
-
-asmlinkage int solaris_stat(u32 filename, u32 statbuf)
-{
- struct kstat s;
- int ret = vfs_stat(A(filename), &s);
- if (!ret)
- return putstat(A(statbuf), &s);
- return ret;
-}
-
-asmlinkage int solaris_xstat(int vers, u32 filename, u32 statbuf)
-{
- /* Solaris doesn't bother with looking at vers, so we do neither */
- return solaris_stat(filename, statbuf);
-}
-
-asmlinkage int solaris_stat64(u32 filename, u32 statbuf)
-{
- struct kstat s;
- int ret = vfs_stat(A(filename), &s);
- if (!ret)
- return putstat64(A(statbuf), &s);
- return ret;
-}
-
-asmlinkage int solaris_lstat(u32 filename, u32 statbuf)
-{
- struct kstat s;
- int ret = vfs_lstat(A(filename), &s);
- if (!ret)
- return putstat(A(statbuf), &s);
- return ret;
-}
-
-asmlinkage int solaris_lxstat(int vers, u32 filename, u32 statbuf)
-{
- return solaris_lstat(filename, statbuf);
-}
-
-asmlinkage int solaris_lstat64(u32 filename, u32 statbuf)
-{
- struct kstat s;
- int ret = vfs_lstat(A(filename), &s);
- if (!ret)
- return putstat64(A(statbuf), &s);
- return ret;
-}
-
-asmlinkage int solaris_fstat(unsigned int fd, u32 statbuf)
-{
- struct kstat s;
- int ret = vfs_fstat(fd, &s);
- if (!ret)
- return putstat(A(statbuf), &s);
- return ret;
-}
-
-asmlinkage int solaris_fxstat(int vers, u32 fd, u32 statbuf)
-{
- return solaris_fstat(fd, statbuf);
-}
-
-asmlinkage int solaris_fstat64(unsigned int fd, u32 statbuf)
-{
- struct kstat s;
- int ret = vfs_fstat(fd, &s);
- if (!ret)
- return putstat64(A(statbuf), &s);
- return ret;
-}
-
-asmlinkage int solaris_mknod(u32 path, u32 mode, s32 dev)
-{
- int (*sys_mknod)(const char __user *,int,unsigned) =
- (int (*)(const char __user *,int,unsigned))SYS(mknod);
- int major = sysv_major(dev);
- int minor = sysv_minor(dev);
-
- /* minor is guaranteed to be OK for MKDEV, major might be not */
- if (major > 0xfff)
- return -EINVAL;
- return sys_mknod(A(path), mode, new_encode_dev(MKDEV(major,minor)));
-}
-
-asmlinkage int solaris_xmknod(int vers, u32 path, u32 mode, s32 dev)
-{
- return solaris_mknod(path, mode, dev);
-}
-
-asmlinkage int solaris_getdents64(unsigned int fd, void __user *dirent, unsigned int count)
-{
- int (*sys_getdents)(unsigned int, void __user *, unsigned int) =
- (int (*)(unsigned int, void __user *, unsigned int))SYS(getdents);
-
- return sys_getdents(fd, dirent, count);
-}
-
-/* This statfs thingie probably will go in the near future, but... */
-
-struct sol_statfs {
- short f_type;
- s32 f_bsize;
- s32 f_frsize;
- s32 f_blocks;
- s32 f_bfree;
- u32 f_files;
- u32 f_ffree;
- char f_fname[6];
- char f_fpack[6];
-};
-
-asmlinkage int solaris_statfs(u32 path, u32 buf, int len, int fstype)
-{
- int ret;
- struct statfs s;
- mm_segment_t old_fs = get_fs();
- int (*sys_statfs)(const char __user *,struct statfs __user *) =
- (int (*)(const char __user *,struct statfs __user *))SYS(statfs);
- struct sol_statfs __user *ss = A(buf);
-
- if (len != sizeof(struct sol_statfs)) return -EINVAL;
- if (!fstype) {
- /* FIXME: mixing userland and kernel pointers */
- set_fs (KERNEL_DS);
- ret = sys_statfs(A(path), &s);
- set_fs (old_fs);
- if (!ret) {
- if (put_user (s.f_type, &ss->f_type) ||
- __put_user (s.f_bsize, &ss->f_bsize) ||
- __put_user (0, &ss->f_frsize) ||
- __put_user (s.f_blocks, &ss->f_blocks) ||
- __put_user (s.f_bfree, &ss->f_bfree) ||
- __put_user (s.f_files, &ss->f_files) ||
- __put_user (s.f_ffree, &ss->f_ffree) ||
- __clear_user (&ss->f_fname, 12))
- return -EFAULT;
- }
- return ret;
- }
-/* Linux can't stat unmounted filesystems so we
- * simply lie and claim 100MB of 1GB is free. Sorry.
- */
- if (put_user (fstype, &ss->f_type) ||
- __put_user (1024, &ss->f_bsize) ||
- __put_user (0, &ss->f_frsize) ||
- __put_user (1024*1024, &ss->f_blocks) ||
- __put_user (100*1024, &ss->f_bfree) ||
- __put_user (60000, &ss->f_files) ||
- __put_user (50000, &ss->f_ffree) ||
- __clear_user (&ss->f_fname, 12))
- return -EFAULT;
- return 0;
-}
-
-asmlinkage int solaris_fstatfs(u32 fd, u32 buf, int len, int fstype)
-{
- int ret;
- struct statfs s;
- mm_segment_t old_fs = get_fs();
- int (*sys_fstatfs)(unsigned,struct statfs __user *) =
- (int (*)(unsigned,struct statfs __user *))SYS(fstatfs);
- struct sol_statfs __user *ss = A(buf);
-
- if (len != sizeof(struct sol_statfs)) return -EINVAL;
- if (!fstype) {
- set_fs (KERNEL_DS);
- ret = sys_fstatfs(fd, &s);
- set_fs (old_fs);
- if (!ret) {
- if (put_user (s.f_type, &ss->f_type) ||
- __put_user (s.f_bsize, &ss->f_bsize) ||
- __put_user (0, &ss->f_frsize) ||
- __put_user (s.f_blocks, &ss->f_blocks) ||
- __put_user (s.f_bfree, &ss->f_bfree) ||
- __put_user (s.f_files, &ss->f_files) ||
- __put_user (s.f_ffree, &ss->f_ffree) ||
- __clear_user (&ss->f_fname, 12))
- return -EFAULT;
- }
- return ret;
- }
- /* Otherwise fstatfs is the same as statfs */
- return solaris_statfs(0, buf, len, fstype);
-}
-
-struct sol_statvfs {
- u32 f_bsize;
- u32 f_frsize;
- u32 f_blocks;
- u32 f_bfree;
- u32 f_bavail;
- u32 f_files;
- u32 f_ffree;
- u32 f_favail;
- u32 f_fsid;
- char f_basetype[16];
- u32 f_flag;
- u32 f_namemax;
- char f_fstr[32];
- u32 f_filler[16];
-};
-
-struct sol_statvfs64 {
- u32 f_bsize;
- u32 f_frsize;
- u64 f_blocks;
- u64 f_bfree;
- u64 f_bavail;
- u64 f_files;
- u64 f_ffree;
- u64 f_favail;
- u32 f_fsid;
- char f_basetype[16];
- u32 f_flag;
- u32 f_namemax;
- char f_fstr[32];
- u32 f_filler[16];
-};
-
-static int report_statvfs(struct vfsmount *mnt, struct inode *inode, u32 buf)
-{
- struct kstatfs s;
- int error;
- struct sol_statvfs __user *ss = A(buf);
-
- error = vfs_statfs(mnt->mnt_root, &s);
- if (!error) {
- const char *p = mnt->mnt_sb->s_type->name;
- int i = 0;
- int j = strlen (p);
-
- if (j > 15) j = 15;
- if (IS_RDONLY(inode)) i = 1;
- if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
- if (!sysv_valid_dev(inode->i_sb->s_dev))
- return -EOVERFLOW;
- if (put_user (s.f_bsize, &ss->f_bsize) ||
- __put_user (0, &ss->f_frsize) ||
- __put_user (s.f_blocks, &ss->f_blocks) ||
- __put_user (s.f_bfree, &ss->f_bfree) ||
- __put_user (s.f_bavail, &ss->f_bavail) ||
- __put_user (s.f_files, &ss->f_files) ||
- __put_user (s.f_ffree, &ss->f_ffree) ||
- __put_user (s.f_ffree, &ss->f_favail) ||
- __put_user (sysv_encode_dev(inode->i_sb->s_dev), &ss->f_fsid) ||
- __copy_to_user (ss->f_basetype,p,j) ||
- __put_user (0, (char __user *)&ss->f_basetype[j]) ||
- __put_user (s.f_namelen, &ss->f_namemax) ||
- __put_user (i, &ss->f_flag) ||
- __clear_user (&ss->f_fstr, 32))
- return -EFAULT;
- }
- return error;
-}
-
-static int report_statvfs64(struct vfsmount *mnt, struct inode *inode, u32 buf)
-{
- struct kstatfs s;
- int error;
- struct sol_statvfs64 __user *ss = A(buf);
-
- error = vfs_statfs(mnt->mnt_root, &s);
- if (!error) {
- const char *p = mnt->mnt_sb->s_type->name;
- int i = 0;
- int j = strlen (p);
-
- if (j > 15) j = 15;
- if (IS_RDONLY(inode)) i = 1;
- if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
- if (!sysv_valid_dev(inode->i_sb->s_dev))
- return -EOVERFLOW;
- if (put_user (s.f_bsize, &ss->f_bsize) ||
- __put_user (0, &ss->f_frsize) ||
- __put_user (s.f_blocks, &ss->f_blocks) ||
- __put_user (s.f_bfree, &ss->f_bfree) ||
- __put_user (s.f_bavail, &ss->f_bavail) ||
- __put_user (s.f_files, &ss->f_files) ||
- __put_user (s.f_ffree, &ss->f_ffree) ||
- __put_user (s.f_ffree, &ss->f_favail) ||
- __put_user (sysv_encode_dev(inode->i_sb->s_dev), &ss->f_fsid) ||
- __copy_to_user (ss->f_basetype,p,j) ||
- __put_user (0, (char __user *)&ss->f_basetype[j]) ||
- __put_user (s.f_namelen, &ss->f_namemax) ||
- __put_user (i, &ss->f_flag) ||
- __clear_user (&ss->f_fstr, 32))
- return -EFAULT;
- }
- return error;
-}
-
-asmlinkage int solaris_statvfs(u32 path, u32 buf)
-{
- struct nameidata nd;
- int error;
-
- error = user_path_walk(A(path),&nd);
- if (!error) {
- struct inode *inode = nd.path.dentry->d_inode;
- error = report_statvfs(nd.path.mnt, inode, buf);
- path_put(&nd.path);
- }
- return error;
-}
-
-asmlinkage int solaris_fstatvfs(unsigned int fd, u32 buf)
-{
- struct file * file;
- int error;
-
- error = -EBADF;
- file = fget(fd);
- if (file) {
- error = report_statvfs(file->f_path.mnt, file->f_path.dentry->d_inode, buf);
- fput(file);
- }
-
- return error;
-}
-
-asmlinkage int solaris_statvfs64(u32 path, u32 buf)
-{
- struct nameidata nd;
- int error;
-
- lock_kernel();
- error = user_path_walk(A(path), &nd);
- if (!error) {
- struct inode *inode = nd.path.dentry->d_inode;
- error = report_statvfs64(nd.path.mnt, inode, buf);
- path_put(&nd.path);
- }
- unlock_kernel();
- return error;
-}
-
-asmlinkage int solaris_fstatvfs64(unsigned int fd, u32 buf)
-{
- struct file * file;
- int error;
-
- error = -EBADF;
- file = fget(fd);
- if (file) {
- lock_kernel();
- error = report_statvfs64(file->f_path.mnt, file->f_path.dentry->d_inode, buf);
- unlock_kernel();
- fput(file);
- }
- return error;
-}
-
-extern asmlinkage long sparc32_open(const char * filename, int flags, int mode);
-
-asmlinkage int solaris_open(u32 fname, int flags, u32 mode)
-{
- const char *filename = (const char *)(long)fname;
- int fl = flags & 0xf;
-
- /* Translate flags first. */
- if (flags & 0x2000) fl |= O_LARGEFILE;
- if (flags & 0x8050) fl |= O_SYNC;
- if (flags & 0x80) fl |= O_NONBLOCK;
- if (flags & 0x100) fl |= O_CREAT;
- if (flags & 0x200) fl |= O_TRUNC;
- if (flags & 0x400) fl |= O_EXCL;
- if (flags & 0x800) fl |= O_NOCTTY;
- flags = fl;
-
- return sparc32_open(filename, flags, mode);
-}
-
-#define SOL_F_SETLK 6
-#define SOL_F_SETLKW 7
-#define SOL_F_FREESP 11
-#define SOL_F_ISSTREAM 13
-#define SOL_F_GETLK 14
-#define SOL_F_PRIV 15
-#define SOL_F_NPRIV 16
-#define SOL_F_QUOTACTL 17
-#define SOL_F_BLOCKS 18
-#define SOL_F_BLKSIZE 19
-#define SOL_F_GETOWN 23
-#define SOL_F_SETOWN 24
-
-struct sol_flock {
- short l_type;
- short l_whence;
- u32 l_start;
- u32 l_len;
- s32 l_sysid;
- s32 l_pid;
- s32 l_pad[4];
-};
-
-asmlinkage int solaris_fcntl(unsigned fd, unsigned cmd, u32 arg)
-{
- int (*sys_fcntl)(unsigned,unsigned,unsigned long) =
- (int (*)(unsigned,unsigned,unsigned long))SYS(fcntl);
- int ret, flags;
-
- switch (cmd) {
- case F_DUPFD:
- case F_GETFD:
- case F_SETFD: return sys_fcntl(fd, cmd, (unsigned long)arg);
- case F_GETFL:
- flags = sys_fcntl(fd, cmd, 0);
- ret = flags & 0xf;
- if (flags & O_SYNC) ret |= 0x8050;
- if (flags & O_NONBLOCK) ret |= 0x80;
- return ret;
- case F_SETFL:
- flags = arg & 0xf;
- if (arg & 0x8050) flags |= O_SYNC;
- if (arg & 0x80) flags |= O_NONBLOCK;
- return sys_fcntl(fd, cmd, (long)flags);
- case SOL_F_GETLK:
- case SOL_F_SETLK:
- case SOL_F_SETLKW:
- {
- struct flock f;
- struct sol_flock __user *p = A(arg);
- mm_segment_t old_fs = get_fs();
-
- switch (cmd) {
- case SOL_F_GETLK: cmd = F_GETLK; break;
- case SOL_F_SETLK: cmd = F_SETLK; break;
- case SOL_F_SETLKW: cmd = F_SETLKW; break;
- }
-
- if (get_user (f.l_type, &p->l_type) ||
- __get_user (f.l_whence, &p->l_whence) ||
- __get_user (f.l_start, &p->l_start) ||
- __get_user (f.l_len, &p->l_len) ||
- __get_user (f.l_pid, &p->l_sysid))
- return -EFAULT;
-
- set_fs(KERNEL_DS);
- ret = sys_fcntl(fd, cmd, (unsigned long)&f);
- set_fs(old_fs);
-
- if (__put_user (f.l_type, &p->l_type) ||
- __put_user (f.l_whence, &p->l_whence) ||
- __put_user (f.l_start, &p->l_start) ||
- __put_user (f.l_len, &p->l_len) ||
- __put_user (f.l_pid, &p->l_pid) ||
- __put_user (0, &p->l_sysid))
- return -EFAULT;
-
- return ret;
- }
- case SOL_F_FREESP:
- {
- int length;
- int (*sys_newftruncate)(unsigned int, unsigned long)=
- (int (*)(unsigned int, unsigned long))SYS(ftruncate);
-
- if (get_user(length, &((struct sol_flock __user *)A(arg))->l_start))
- return -EFAULT;
-
- return sys_newftruncate(fd, length);
- }
- };
- return -EINVAL;
-}
-
-asmlinkage int solaris_ulimit(int cmd, int val)
-{
- switch (cmd) {
- case 1: /* UL_GETFSIZE - in 512B chunks */
- return current->signal->rlim[RLIMIT_FSIZE].rlim_cur >> 9;
- case 2: /* UL_SETFSIZE */
- if ((unsigned long)val > (LONG_MAX>>9)) return -ERANGE;
- val <<= 9;
- task_lock(current->group_leader);
- if (val > current->signal->rlim[RLIMIT_FSIZE].rlim_max) {
- if (!capable(CAP_SYS_RESOURCE)) {
- task_unlock(current->group_leader);
- return -EPERM;
- }
- current->signal->rlim[RLIMIT_FSIZE].rlim_max = val;
- }
- current->signal->rlim[RLIMIT_FSIZE].rlim_cur = val;
- task_unlock(current->group_leader);
- return 0;
- case 3: /* UL_GMEMLIM */
- return current->signal->rlim[RLIMIT_DATA].rlim_cur;
- case 4: /* UL_GDESLIM */
- return sysctl_nr_open;
- }
- return -EINVAL;
-}
-
-/* At least at the time I'm writing this, Linux doesn't have ACLs, so we
- just fake this */
-asmlinkage int solaris_acl(u32 filename, int cmd, int nentries, u32 aclbufp)
-{
- return -ENOSYS;
-}
-
-asmlinkage int solaris_facl(unsigned int fd, int cmd, int nentries, u32 aclbufp)
-{
- return -ENOSYS;
-}
-
-asmlinkage int solaris_pread(unsigned int fd, char __user *buf, u32 count, u32 pos)
-{
- ssize_t (*sys_pread64)(unsigned int, char __user *, size_t, loff_t) =
- (ssize_t (*)(unsigned int, char __user *, size_t, loff_t))SYS(pread64);
-
- return sys_pread64(fd, buf, count, (loff_t)pos);
-}
-
-asmlinkage int solaris_pwrite(unsigned int fd, char __user *buf, u32 count, u32 pos)
-{
- ssize_t (*sys_pwrite64)(unsigned int, char __user *, size_t, loff_t) =
- (ssize_t (*)(unsigned int, char __user *, size_t, loff_t))SYS(pwrite64);
-
- return sys_pwrite64(fd, buf, count, (loff_t)pos);
-}
-
-/* POSIX.1 names */
-#define _PC_LINK_MAX 1
-#define _PC_MAX_CANON 2
-#define _PC_MAX_INPUT 3
-#define _PC_NAME_MAX 4
-#define _PC_PATH_MAX 5
-#define _PC_PIPE_BUF 6
-#define _PC_NO_TRUNC 7
-#define _PC_VDISABLE 8
-#define _PC_CHOWN_RESTRICTED 9
-/* POSIX.4 names */
-#define _PC_ASYNC_IO 10
-#define _PC_PRIO_IO 11
-#define _PC_SYNC_IO 12
-#define _PC_LAST 12
-
-/* This is not a real and complete implementation yet, just to keep
- * the easy Solaris binaries happy.
- */
-asmlinkage int solaris_fpathconf(int fd, int name)
-{
- int ret;
-
- switch(name) {
- case _PC_LINK_MAX:
- ret = LINK_MAX;
- break;
- case _PC_MAX_CANON:
- ret = MAX_CANON;
- break;
- case _PC_MAX_INPUT:
- ret = MAX_INPUT;
- break;
- case _PC_NAME_MAX:
- ret = NAME_MAX;
- break;
- case _PC_PATH_MAX:
- ret = PATH_MAX;
- break;
- case _PC_PIPE_BUF:
- ret = PIPE_BUF;
- break;
- case _PC_CHOWN_RESTRICTED:
- ret = 1;
- break;
- case _PC_NO_TRUNC:
- case _PC_VDISABLE:
- ret = 0;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
-asmlinkage int solaris_pathconf(u32 path, int name)
-{
- return solaris_fpathconf(0, name);
-}
-
-/* solaris_llseek returns long long - quite difficult */
-asmlinkage long solaris_llseek(struct pt_regs *regs, u32 off_hi, u32 off_lo, int whence)
-{
- int (*sys_llseek)(unsigned int, unsigned long, unsigned long, loff_t __user *, unsigned int) =
- (int (*)(unsigned int, unsigned long, unsigned long, loff_t __user *, unsigned int))SYS(_llseek);
- int ret;
- mm_segment_t old_fs = get_fs();
- loff_t retval;
-
- set_fs(KERNEL_DS);
- ret = sys_llseek((unsigned int)regs->u_regs[UREG_I0], off_hi, off_lo, &retval, whence);
- set_fs(old_fs);
- if (ret < 0) return ret;
- regs->u_regs[UREG_I1] = (u32)retval;
- return (retval >> 32);
-}
-
-/* Have to mask out all but lower 3 bits */
-asmlinkage int solaris_access(u32 filename, long mode)
-{
- int (*sys_access)(const char __user *, int) =
- (int (*)(const char __user *, int))SYS(access);
-
- return sys_access(A(filename), mode & 7);
-}
diff --git a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c
deleted file mode 100644
index 8ad10a6d993b..000000000000
--- a/arch/sparc64/solaris/ioctl.c
+++ /dev/null
@@ -1,825 +0,0 @@
-/* $Id: ioctl.c,v 1.17 2002/02/08 03:57:14 davem Exp $
- * ioctl.c: Solaris ioctl emulation.
- *
- * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 1997,1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
- *
- * Streams & timod emulation based on code
- * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
- *
- * 1999-08-19 Implemented solaris 'm' (mag tape) and
- * 'O' (openprom) ioctls, by Jason Rappleye
- * (rappleye@ccr.buffalo.edu)
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/syscalls.h>
-#include <linux/ioctl.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/netdevice.h>
-#include <linux/mtio.h>
-#include <linux/time.h>
-#include <linux/rcupdate.h>
-#include <linux/compat.h>
-
-#include <net/sock.h>
-#include <net/net_namespace.h>
-
-#include <asm/uaccess.h>
-#include <asm/termios.h>
-#include <asm/openpromio.h>
-
-#include "conv.h"
-#include "socksys.h"
-
-extern asmlinkage int compat_sys_ioctl(unsigned int fd, unsigned int cmd,
- u32 arg);
-asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
-
-extern int timod_putmsg(unsigned int fd, char __user *ctl_buf, int ctl_len,
- char __user *data_buf, int data_len, int flags);
-extern int timod_getmsg(unsigned int fd, char __user *ctl_buf, int ctl_maxlen, int __user *ctl_len,
- char __user *data_buf, int data_maxlen, int __user *data_len, int *flags);
-
-/* termio* stuff {{{ */
-
-struct solaris_termios {
- u32 c_iflag;
- u32 c_oflag;
- u32 c_cflag;
- u32 c_lflag;
- u8 c_cc[19];
-};
-
-struct solaris_termio {
- u16 c_iflag;
- u16 c_oflag;
- u16 c_cflag;
- u16 c_lflag;
- s8 c_line;
- u8 c_cc[8];
-};
-
-struct solaris_termiox {
- u16 x_hflag;
- u16 x_cflag;
- u16 x_rflag[5];
- u16 x_sflag;
-};
-
-static u32 solaris_to_linux_cflag(u32 cflag)
-{
- cflag &= 0x7fdff000;
- if (cflag & 0x200000) {
- int baud = cflag & 0xf;
- cflag &= ~0x20000f;
- switch (baud) {
- case 0: baud = B57600; break;
- case 1: baud = B76800; break;
- case 2: baud = B115200; break;
- case 3: baud = B153600; break;
- case 4: baud = B230400; break;
- case 5: baud = B307200; break;
- case 6: baud = B460800; break;
- }
- cflag |= CBAUDEX | baud;
- }
- return cflag;
-}
-
-static u32 linux_to_solaris_cflag(u32 cflag)
-{
- cflag &= ~(CMSPAR | CIBAUD);
- if (cflag & CBAUDEX) {
- int baud = cflag & CBAUD;
- cflag &= ~CBAUD;
- switch (baud) {
- case B57600: baud = 0; break;
- case B76800: baud = 1; break;
- case B115200: baud = 2; break;
- case B153600: baud = 3; break;
- case B230400: baud = 4; break;
- case B307200: baud = 5; break;
- case B460800: baud = 6; break;
- case B614400: baud = 7; break;
- case B921600: baud = 8; break;
-#if 0
- case B1843200: baud = 9; break;
-#endif
- }
- cflag |= 0x200000 | baud;
- }
- return cflag;
-}
-
-static inline int linux_to_solaris_termio(unsigned int fd, unsigned int cmd, u32 arg)
-{
- struct solaris_termio __user *p = A(arg);
- int ret;
-
- ret = sys_ioctl(fd, cmd, (unsigned long)p);
- if (!ret) {
- u32 cflag;
-
- if (__get_user (cflag, &p->c_cflag))
- return -EFAULT;
- cflag = linux_to_solaris_cflag(cflag);
- if (__put_user (cflag, &p->c_cflag))
- return -EFAULT;
- }
- return ret;
-}
-
-static int solaris_to_linux_termio(unsigned int fd, unsigned int cmd, u32 arg)
-{
- int ret;
- struct solaris_termio s;
- mm_segment_t old_fs = get_fs();
-
- if (copy_from_user (&s, (struct solaris_termio __user *)A(arg), sizeof(struct solaris_termio)))
- return -EFAULT;
- s.c_cflag = solaris_to_linux_cflag(s.c_cflag);
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, cmd, (unsigned long)&s);
- set_fs(old_fs);
- return ret;
-}
-
-static inline int linux_to_solaris_termios(unsigned int fd, unsigned int cmd, u32 arg)
-{
- int ret;
- struct solaris_termios s;
- mm_segment_t old_fs = get_fs();
-
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, cmd, (unsigned long)&s);
- set_fs(old_fs);
- if (!ret) {
- struct solaris_termios __user *p = A(arg);
- if (put_user (s.c_iflag, &p->c_iflag) ||
- __put_user (s.c_oflag, &p->c_oflag) ||
- __put_user (linux_to_solaris_cflag(s.c_cflag), &p->c_cflag) ||
- __put_user (s.c_lflag, &p->c_lflag) ||
- __copy_to_user (p->c_cc, s.c_cc, 16) ||
- __clear_user (p->c_cc + 16, 2))
- return -EFAULT;
- }
- return ret;
-}
-
-static int solaris_to_linux_termios(unsigned int fd, unsigned int cmd, u32 arg)
-{
- int ret;
- struct solaris_termios s;
- struct solaris_termios __user *p = A(arg);
- mm_segment_t old_fs = get_fs();
-
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, TCGETS, (unsigned long)&s);
- set_fs(old_fs);
- if (ret) return ret;
- if (put_user (s.c_iflag, &p->c_iflag) ||
- __put_user (s.c_oflag, &p->c_oflag) ||
- __put_user (s.c_cflag, &p->c_cflag) ||
- __put_user (s.c_lflag, &p->c_lflag) ||
- __copy_from_user (s.c_cc, p->c_cc, 16))
- return -EFAULT;
- s.c_cflag = solaris_to_linux_cflag(s.c_cflag);
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, cmd, (unsigned long)&s);
- set_fs(old_fs);
- return ret;
-}
-
-static inline int solaris_T(unsigned int fd, unsigned int cmd, u32 arg)
-{
- switch (cmd & 0xff) {
- case 1: /* TCGETA */
- return linux_to_solaris_termio(fd, TCGETA, arg);
- case 2: /* TCSETA */
- return solaris_to_linux_termio(fd, TCSETA, arg);
- case 3: /* TCSETAW */
- return solaris_to_linux_termio(fd, TCSETAW, arg);
- case 4: /* TCSETAF */
- return solaris_to_linux_termio(fd, TCSETAF, arg);
- case 5: /* TCSBRK */
- return sys_ioctl(fd, TCSBRK, arg);
- case 6: /* TCXONC */
- return sys_ioctl(fd, TCXONC, arg);
- case 7: /* TCFLSH */
- return sys_ioctl(fd, TCFLSH, arg);
- case 13: /* TCGETS */
- return linux_to_solaris_termios(fd, TCGETS, arg);
- case 14: /* TCSETS */
- return solaris_to_linux_termios(fd, TCSETS, arg);
- case 15: /* TCSETSW */
- return solaris_to_linux_termios(fd, TCSETSW, arg);
- case 16: /* TCSETSF */
- return solaris_to_linux_termios(fd, TCSETSF, arg);
- case 103: /* TIOCSWINSZ */
- return sys_ioctl(fd, TIOCSWINSZ, arg);
- case 104: /* TIOCGWINSZ */
- return sys_ioctl(fd, TIOCGWINSZ, arg);
- }
- return -ENOSYS;
-}
-
-static inline int solaris_t(unsigned int fd, unsigned int cmd, u32 arg)
-{
- switch (cmd & 0xff) {
- case 20: /* TIOCGPGRP */
- return sys_ioctl(fd, TIOCGPGRP, arg);
- case 21: /* TIOCSPGRP */
- return sys_ioctl(fd, TIOCSPGRP, arg);
- }
- return -ENOSYS;
-}
-
-/* }}} */
-
-/* A pseudo STREAMS support {{{ */
-
-struct strioctl {
- int cmd, timeout, len;
- u32 data;
-};
-
-struct solaris_si_sockparams {
- int sp_family;
- int sp_type;
- int sp_protocol;
-};
-
-struct solaris_o_si_udata {
- int tidusize;
- int addrsize;
- int optsize;
- int etsdusize;
- int servtype;
- int so_state;
- int so_options;
- int tsdusize;
-};
-
-struct solaris_si_udata {
- int tidusize;
- int addrsize;
- int optsize;
- int etsdusize;
- int servtype;
- int so_state;
- int so_options;
- int tsdusize;
- struct solaris_si_sockparams sockparams;
-};
-
-#define SOLARIS_MODULE_TIMOD 0
-#define SOLARIS_MODULE_SOCKMOD 1
-#define SOLARIS_MODULE_MAX 2
-
-static struct module_info {
- const char *name;
- /* can be expanded further if needed */
-} module_table[ SOLARIS_MODULE_MAX + 1 ] = {
- /* the ordering here must match the module numbers above! */
- { "timod" },
- { "sockmod" },
- { NULL }
-};
-
-static inline int solaris_sockmod(unsigned int fd, unsigned int cmd, u32 arg)
-{
- struct inode *ino;
- struct fdtable *fdt;
- /* I wonder which of these tests are superfluous... --patrik */
- rcu_read_lock();
- fdt = files_fdtable(current->files);
- if (! fdt->fd[fd] ||
- ! fdt->fd[fd]->f_path.dentry ||
- ! (ino = fdt->fd[fd]->f_path.dentry->d_inode) ||
- ! S_ISSOCK(ino->i_mode)) {
- rcu_read_unlock();
- return TBADF;
- }
- rcu_read_unlock();
-
- switch (cmd & 0xff) {
- case 109: /* SI_SOCKPARAMS */
- {
- struct solaris_si_sockparams si;
- if (copy_from_user (&si, A(arg), sizeof(si)))
- return (EFAULT << 8) | TSYSERR;
-
- /* Should we modify socket ino->socket_i.ops and type? */
- return 0;
- }
- case 110: /* SI_GETUDATA */
- {
- int etsdusize, servtype;
- struct solaris_si_udata __user *p = A(arg);
- switch (SOCKET_I(ino)->type) {
- case SOCK_STREAM:
- etsdusize = 1;
- servtype = 2;
- break;
- default:
- etsdusize = -2;
- servtype = 3;
- break;
- }
- if (put_user(16384, &p->tidusize) ||
- __put_user(sizeof(struct sockaddr), &p->addrsize) ||
- __put_user(-1, &p->optsize) ||
- __put_user(etsdusize, &p->etsdusize) ||
- __put_user(servtype, &p->servtype) ||
- __put_user(0, &p->so_state) ||
- __put_user(0, &p->so_options) ||
- __put_user(16384, &p->tsdusize) ||
- __put_user(SOCKET_I(ino)->ops->family, &p->sockparams.sp_family) ||
- __put_user(SOCKET_I(ino)->type, &p->sockparams.sp_type) ||
- __put_user(SOCKET_I(ino)->ops->family, &p->sockparams.sp_protocol))
- return (EFAULT << 8) | TSYSERR;
- return 0;
- }
- case 101: /* O_SI_GETUDATA */
- {
- int etsdusize, servtype;
- struct solaris_o_si_udata __user *p = A(arg);
- switch (SOCKET_I(ino)->type) {
- case SOCK_STREAM:
- etsdusize = 1;
- servtype = 2;
- break;
- default:
- etsdusize = -2;
- servtype = 3;
- break;
- }
- if (put_user(16384, &p->tidusize) ||
- __put_user(sizeof(struct sockaddr), &p->addrsize) ||
- __put_user(-1, &p->optsize) ||
- __put_user(etsdusize, &p->etsdusize) ||
- __put_user(servtype, &p->servtype) ||
- __put_user(0, &p->so_state) ||
- __put_user(0, &p->so_options) ||
- __put_user(16384, &p->tsdusize))
- return (EFAULT << 8) | TSYSERR;
- return 0;
- }
- case 102: /* SI_SHUTDOWN */
- case 103: /* SI_LISTEN */
- case 104: /* SI_SETMYNAME */
- case 105: /* SI_SETPEERNAME */
- case 106: /* SI_GETINTRANSIT */
- case 107: /* SI_TCL_LINK */
- case 108: /* SI_TCL_UNLINK */
- ;
- }
- return TNOTSUPPORT;
-}
-
-static inline int solaris_timod(unsigned int fd, unsigned int cmd, u32 arg,
- int len, int __user *len_p)
-{
- int ret;
-
- switch (cmd & 0xff) {
- case 141: /* TI_OPTMGMT */
- {
- int i;
- u32 prim;
- SOLD("TI_OPMGMT entry");
- ret = timod_putmsg(fd, A(arg), len, NULL, -1, 0);
- SOLD("timod_putmsg() returned");
- if (ret)
- return (-ret << 8) | TSYSERR;
- i = MSG_HIPRI;
- SOLD("calling timod_getmsg()");
- ret = timod_getmsg(fd, A(arg), len, len_p, NULL, -1, NULL, &i);
- SOLD("timod_getmsg() returned");
- if (ret)
- return (-ret << 8) | TSYSERR;
- SOLD("ret ok");
- if (get_user(prim, (u32 __user *)A(arg)))
- return (EFAULT << 8) | TSYSERR;
- SOLD("got prim");
- if (prim == T_ERROR_ACK) {
- u32 tmp, tmp2;
- SOLD("prim is T_ERROR_ACK");
- if (get_user(tmp, (u32 __user *)A(arg)+3) ||
- get_user(tmp2, (u32 __user *)A(arg)+2))
- return (EFAULT << 8) | TSYSERR;
- return (tmp2 << 8) | tmp;
- }
- SOLD("TI_OPMGMT return 0");
- return 0;
- }
- case 142: /* TI_BIND */
- {
- int i;
- u32 prim;
- SOLD("TI_BIND entry");
- ret = timod_putmsg(fd, A(arg), len, NULL, -1, 0);
- SOLD("timod_putmsg() returned");
- if (ret)
- return (-ret << 8) | TSYSERR;
- len = 1024; /* Solaris allows arbitrary return size */
- i = MSG_HIPRI;
- SOLD("calling timod_getmsg()");
- ret = timod_getmsg(fd, A(arg), len, len_p, NULL, -1, NULL, &i);
- SOLD("timod_getmsg() returned");
- if (ret)
- return (-ret << 8) | TSYSERR;
- SOLD("ret ok");
- if (get_user(prim, (u32 __user *)A(arg)))
- return (EFAULT << 8) | TSYSERR;
- SOLD("got prim");
- if (prim == T_ERROR_ACK) {
- u32 tmp, tmp2;
- SOLD("prim is T_ERROR_ACK");
- if (get_user(tmp, (u32 __user *)A(arg)+3) ||
- get_user(tmp2, (u32 __user *)A(arg)+2))
- return (EFAULT << 8) | TSYSERR;
- return (tmp2 << 8) | tmp;
- }
- SOLD("no ERROR_ACK requested");
- if (prim != T_OK_ACK)
- return TBADSEQ;
- SOLD("OK_ACK requested");
- i = MSG_HIPRI;
- SOLD("calling timod_getmsg()");
- ret = timod_getmsg(fd, A(arg), len, len_p, NULL, -1, NULL, &i);
- SOLD("timod_getmsg() returned");
- if (ret)
- return (-ret << 8) | TSYSERR;
- SOLD("TI_BIND return ok");
- return 0;
- }
- case 140: /* TI_GETINFO */
- case 143: /* TI_UNBIND */
- case 144: /* TI_GETMYNAME */
- case 145: /* TI_GETPEERNAME */
- case 146: /* TI_SETMYNAME */
- case 147: /* TI_SETPEERNAME */
- ;
- }
- return TNOTSUPPORT;
-}
-
-static inline int solaris_S(struct file *filp, unsigned int fd, unsigned int cmd, u32 arg)
-{
- char *p;
- int ret;
- mm_segment_t old_fs;
- struct strioctl si;
- struct inode *ino;
- struct sol_socket_struct *sock;
- struct module_info *mi;
-
- ino = filp->f_path.dentry->d_inode;
- if (!S_ISSOCK(ino->i_mode))
- return -EBADF;
- sock = filp->private_data;
- if (! sock) {
- printk("solaris_S: NULL private_data\n");
- return -EBADF;
- }
- if (sock->magic != SOLARIS_SOCKET_MAGIC) {
- printk("solaris_S: invalid magic\n");
- return -EBADF;
- }
-
-
- switch (cmd & 0xff) {
- case 1: /* I_NREAD */
- return -ENOSYS;
- case 2: /* I_PUSH */
- {
- p = getname (A(arg));
- if (IS_ERR (p))
- return PTR_ERR(p);
- ret = -EINVAL;
- for (mi = module_table; mi->name; mi++) {
- if (strcmp(mi->name, p) == 0) {
- sol_module m;
- if (sock->modcount >= MAX_NR_STREAM_MODULES) {
- ret = -ENXIO;
- break;
- }
- m = (sol_module) (mi - module_table);
- sock->module[sock->modcount++] = m;
- ret = 0;
- break;
- }
- }
- putname (p);
- return ret;
- }
- case 3: /* I_POP */
- if (sock->modcount <= 0) return -EINVAL;
- sock->modcount--;
- return 0;
- case 4: /* I_LOOK */
- {
- const char *p;
- if (sock->modcount <= 0) return -EINVAL;
- p = module_table[(unsigned)sock->module[sock->modcount]].name;
- if (copy_to_user (A(arg), p, strlen(p)))
- return -EFAULT;
- return 0;
- }
- case 5: /* I_FLUSH */
- return 0;
- case 8: /* I_STR */
- if (copy_from_user(&si, A(arg), sizeof(struct strioctl)))
- return -EFAULT;
- /* We ignore what module is actually at the top of stack. */
- switch ((si.cmd >> 8) & 0xff) {
- case 'I':
- return solaris_sockmod(fd, si.cmd, si.data);
- case 'T':
- return solaris_timod(fd, si.cmd, si.data, si.len,
- &((struct strioctl __user *)A(arg))->len);
- default:
- return solaris_ioctl(fd, si.cmd, si.data);
- }
- case 9: /* I_SETSIG */
- return sys_ioctl(fd, FIOSETOWN, current->pid);
- case 10: /* I_GETSIG */
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- sys_ioctl(fd, FIOGETOWN, (unsigned long)&ret);
- set_fs(old_fs);
- if (ret == current->pid) return 0x3ff;
- else return -EINVAL;
- case 11: /* I_FIND */
- {
- int i;
- p = getname (A(arg));
- if (IS_ERR (p))
- return PTR_ERR(p);
- ret = 0;
- for (i = 0; i < sock->modcount; i++) {
- unsigned m = sock->module[i];
- if (strcmp(module_table[m].name, p) == 0) {
- ret = 1;
- break;
- }
- }
- putname (p);
- return ret;
- }
- case 19: /* I_SWROPT */
- case 32: /* I_SETCLTIME */
- return 0; /* Lie */
- }
- return -ENOSYS;
-}
-
-static inline int solaris_s(unsigned int fd, unsigned int cmd, u32 arg)
-{
- switch (cmd & 0xff) {
- case 0: /* SIOCSHIWAT */
- case 2: /* SIOCSLOWAT */
- return 0; /* We don't support them */
- case 1: /* SIOCGHIWAT */
- case 3: /* SIOCGLOWAT */
- if (put_user (0, (u32 __user *)A(arg)))
- return -EFAULT;
- return 0; /* Lie */
- case 7: /* SIOCATMARK */
- return sys_ioctl(fd, SIOCATMARK, arg);
- case 8: /* SIOCSPGRP */
- return sys_ioctl(fd, SIOCSPGRP, arg);
- case 9: /* SIOCGPGRP */
- return sys_ioctl(fd, SIOCGPGRP, arg);
- }
- return -ENOSYS;
-}
-
-static inline int solaris_r(unsigned int fd, unsigned int cmd, u32 arg)
-{
- switch (cmd & 0xff) {
- case 10: /* SIOCADDRT */
- return compat_sys_ioctl(fd, SIOCADDRT, arg);
- case 11: /* SIOCDELRT */
- return compat_sys_ioctl(fd, SIOCDELRT, arg);
- }
- return -ENOSYS;
-}
-
-static inline int solaris_i(unsigned int fd, unsigned int cmd, u32 arg)
-{
- switch (cmd & 0xff) {
- case 12: /* SIOCSIFADDR */
- return compat_sys_ioctl(fd, SIOCSIFADDR, arg);
- case 13: /* SIOCGIFADDR */
- return compat_sys_ioctl(fd, SIOCGIFADDR, arg);
- case 14: /* SIOCSIFDSTADDR */
- return compat_sys_ioctl(fd, SIOCSIFDSTADDR, arg);
- case 15: /* SIOCGIFDSTADDR */
- return compat_sys_ioctl(fd, SIOCGIFDSTADDR, arg);
- case 16: /* SIOCSIFFLAGS */
- return compat_sys_ioctl(fd, SIOCSIFFLAGS, arg);
- case 17: /* SIOCGIFFLAGS */
- return compat_sys_ioctl(fd, SIOCGIFFLAGS, arg);
- case 18: /* SIOCSIFMEM */
- return compat_sys_ioctl(fd, SIOCSIFMEM, arg);
- case 19: /* SIOCGIFMEM */
- return compat_sys_ioctl(fd, SIOCGIFMEM, arg);
- case 20: /* SIOCGIFCONF */
- return compat_sys_ioctl(fd, SIOCGIFCONF, arg);
- case 21: /* SIOCSIFMTU */
- return compat_sys_ioctl(fd, SIOCSIFMTU, arg);
- case 22: /* SIOCGIFMTU */
- return compat_sys_ioctl(fd, SIOCGIFMTU, arg);
- case 23: /* SIOCGIFBRDADDR */
- return compat_sys_ioctl(fd, SIOCGIFBRDADDR, arg);
- case 24: /* SIOCSIFBRDADDR */
- return compat_sys_ioctl(fd, SIOCSIFBRDADDR, arg);
- case 25: /* SIOCGIFNETMASK */
- return compat_sys_ioctl(fd, SIOCGIFNETMASK, arg);
- case 26: /* SIOCSIFNETMASK */
- return compat_sys_ioctl(fd, SIOCSIFNETMASK, arg);
- case 27: /* SIOCGIFMETRIC */
- return compat_sys_ioctl(fd, SIOCGIFMETRIC, arg);
- case 28: /* SIOCSIFMETRIC */
- return compat_sys_ioctl(fd, SIOCSIFMETRIC, arg);
- case 30: /* SIOCSARP */
- return compat_sys_ioctl(fd, SIOCSARP, arg);
- case 31: /* SIOCGARP */
- return compat_sys_ioctl(fd, SIOCGARP, arg);
- case 32: /* SIOCDARP */
- return compat_sys_ioctl(fd, SIOCDARP, arg);
- case 52: /* SIOCGETNAME */
- case 53: /* SIOCGETPEER */
- {
- struct sockaddr uaddr;
- int uaddr_len = sizeof(struct sockaddr), ret;
- long args[3];
- mm_segment_t old_fs = get_fs();
- int (*sys_socketcall)(int, unsigned long *) =
- (int (*)(int, unsigned long *))SYS(socketcall);
-
- args[0] = fd; args[1] = (long)&uaddr; args[2] = (long)&uaddr_len;
- set_fs(KERNEL_DS);
- ret = sys_socketcall(((cmd & 0xff) == 52) ? SYS_GETSOCKNAME : SYS_GETPEERNAME,
- args);
- set_fs(old_fs);
- if (ret >= 0) {
- if (copy_to_user(A(arg), &uaddr, uaddr_len))
- return -EFAULT;
- }
- return ret;
- }
-#if 0
- case 86: /* SIOCSOCKSYS */
- return socksys_syscall(fd, arg);
-#endif
- case 87: /* SIOCGIFNUM */
- {
- struct net_device *d;
- int i = 0;
-
- read_lock_bh(&dev_base_lock);
- for_each_netdev(&init_net, d)
- i++;
- read_unlock_bh(&dev_base_lock);
-
- if (put_user (i, (int __user *)A(arg)))
- return -EFAULT;
- return 0;
- }
- }
- return -ENOSYS;
-}
-
-static int solaris_m(unsigned int fd, unsigned int cmd, u32 arg)
-{
- int ret;
-
- switch (cmd & 0xff) {
- case 1: /* MTIOCTOP */
- ret = sys_ioctl(fd, MTIOCTOP, (unsigned long)&arg);
- break;
- case 2: /* MTIOCGET */
- ret = sys_ioctl(fd, MTIOCGET, (unsigned long)&arg);
- break;
- case 3: /* MTIOCGETDRIVETYPE */
- case 4: /* MTIOCPERSISTENT */
- case 5: /* MTIOCPERSISTENTSTATUS */
- case 6: /* MTIOCLRERR */
- case 7: /* MTIOCGUARANTEEDORDER */
- case 8: /* MTIOCRESERVE */
- case 9: /* MTIOCRELEASE */
- case 10: /* MTIOCFORCERESERVE */
- case 13: /* MTIOCSTATE */
- case 14: /* MTIOCREADIGNOREILI */
- case 15: /* MTIOCREADIGNOREEOFS */
- case 16: /* MTIOCSHORTFMK */
- default:
- ret = -ENOSYS; /* linux doesn't support these */
- break;
- };
-
- return ret;
-}
-
-static int solaris_O(unsigned int fd, unsigned int cmd, u32 arg)
-{
- int ret = -EINVAL;
-
- switch (cmd & 0xff) {
- case 1: /* OPROMGETOPT */
- ret = sys_ioctl(fd, OPROMGETOPT, arg);
- break;
- case 2: /* OPROMSETOPT */
- ret = sys_ioctl(fd, OPROMSETOPT, arg);
- break;
- case 3: /* OPROMNXTOPT */
- ret = sys_ioctl(fd, OPROMNXTOPT, arg);
- break;
- case 4: /* OPROMSETOPT2 */
- ret = sys_ioctl(fd, OPROMSETOPT2, arg);
- break;
- case 5: /* OPROMNEXT */
- ret = sys_ioctl(fd, OPROMNEXT, arg);
- break;
- case 6: /* OPROMCHILD */
- ret = sys_ioctl(fd, OPROMCHILD, arg);
- break;
- case 7: /* OPROMGETPROP */
- ret = sys_ioctl(fd, OPROMGETPROP, arg);
- break;
- case 8: /* OPROMNXTPROP */
- ret = sys_ioctl(fd, OPROMNXTPROP, arg);
- break;
- case 9: /* OPROMU2P */
- ret = sys_ioctl(fd, OPROMU2P, arg);
- break;
- case 10: /* OPROMGETCONS */
- ret = sys_ioctl(fd, OPROMGETCONS, arg);
- break;
- case 11: /* OPROMGETFBNAME */
- ret = sys_ioctl(fd, OPROMGETFBNAME, arg);
- break;
- case 12: /* OPROMGETBOOTARGS */
- ret = sys_ioctl(fd, OPROMGETBOOTARGS, arg);
- break;
- case 13: /* OPROMGETVERSION */
- case 14: /* OPROMPATH2DRV */
- case 15: /* OPROMDEV2PROMNAME */
- case 16: /* OPROMPROM2DEVNAME */
- case 17: /* OPROMGETPROPLEN */
- default:
- ret = -EINVAL;
- break;
- };
- return ret;
-}
-
-/* }}} */
-
-asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg)
-{
- struct file *filp;
- int error = -EBADF;
-
- filp = fget(fd);
- if (!filp)
- goto out;
-
- lock_kernel();
- error = -EFAULT;
- switch ((cmd >> 8) & 0xff) {
- case 'S': error = solaris_S(filp, fd, cmd, arg); break;
- case 'T': error = solaris_T(fd, cmd, arg); break;
- case 'i': error = solaris_i(fd, cmd, arg); break;
- case 'r': error = solaris_r(fd, cmd, arg); break;
- case 's': error = solaris_s(fd, cmd, arg); break;
- case 't': error = solaris_t(fd, cmd, arg); break;
- case 'f': error = sys_ioctl(fd, cmd, arg); break;
- case 'm': error = solaris_m(fd, cmd, arg); break;
- case 'O': error = solaris_O(fd, cmd, arg); break;
- default:
- error = -ENOSYS;
- break;
- }
- unlock_kernel();
- fput(filp);
-out:
- if (error == -ENOSYS) {
- unsigned char c = cmd>>8;
-
- if (c < ' ' || c > 126) c = '.';
- printk("solaris_ioctl: Unknown cmd fd(%d) cmd(%08x '%c') arg(%08x)\n",
- (int)fd, (unsigned int)cmd, c, (unsigned int)arg);
- error = -EINVAL;
- }
- return error;
-}
diff --git a/arch/sparc64/solaris/ipc.c b/arch/sparc64/solaris/ipc.c
deleted file mode 100644
index 499135fa7060..000000000000
--- a/arch/sparc64/solaris/ipc.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/* $Id: ipc.c,v 1.5 1999/12/09 00:41:00 davem Exp $
- * ipc.c: Solaris IPC emulation
- *
- * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <linux/mm.h>
-#include <linux/shm.h>
-#include <linux/sem.h>
-#include <linux/msg.h>
-#include <linux/ipc.h>
-
-#include <asm/uaccess.h>
-#include <asm/string.h>
-
-#include "conv.h"
-
-struct solaris_ipc_perm {
- s32 uid;
- s32 gid;
- s32 cuid;
- s32 cgid;
- u32 mode;
- u32 seq;
- int key;
- s32 pad[4];
-};
-
-struct solaris_shmid_ds {
- struct solaris_ipc_perm shm_perm;
- int shm_segsz;
- u32 shm_amp;
- unsigned short shm_lkcnt;
- char __padxx[2];
- s32 shm_lpid;
- s32 shm_cpid;
- u32 shm_nattch;
- u32 shm_cnattch;
- s32 shm_atime;
- s32 shm_pad1;
- s32 shm_dtime;
- s32 shm_pad2;
- s32 shm_ctime;
- s32 shm_pad3;
- unsigned short shm_cv;
- char shm_pad4[2];
- u32 shm_sptas;
- s32 shm_pad5[2];
-};
-
-asmlinkage long solaris_shmsys(int cmd, u32 arg1, u32 arg2, u32 arg3)
-{
- int (*sys_ipc)(unsigned,int,int,unsigned long,void __user *,long) =
- (int (*)(unsigned,int,int,unsigned long,void __user *,long))SYS(ipc);
- mm_segment_t old_fs;
- unsigned long raddr;
- int ret;
-
- switch (cmd) {
- case 0: /* shmat */
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ipc(SHMAT, arg1, arg3 & ~0x4000, (unsigned long)&raddr, A(arg2), 0);
- set_fs(old_fs);
- if (ret >= 0) return (u32)raddr;
- else return ret;
- case 1: /* shmctl */
- switch (arg2) {
- case 3: /* SHM_LOCK */
- case 4: /* SHM_UNLOCK */
- return sys_ipc(SHMCTL, arg1, (arg2 == 3) ? SHM_LOCK : SHM_UNLOCK, 0, NULL, 0);
- case 10: /* IPC_RMID */
- return sys_ipc(SHMCTL, arg1, IPC_RMID, 0, NULL, 0);
- case 11: /* IPC_SET */
- {
- struct shmid_ds s;
- struct solaris_shmid_ds __user *p = A(arg3);
-
- if (get_user (s.shm_perm.uid, &p->shm_perm.uid) ||
- __get_user (s.shm_perm.gid, &p->shm_perm.gid) ||
- __get_user (s.shm_perm.mode, &p->shm_perm.mode))
- return -EFAULT;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ipc(SHMCTL, arg1, IPC_SET, 0, &s, 0);
- set_fs(old_fs);
- return ret;
- }
- case 12: /* IPC_STAT */
- {
- struct shmid_ds s;
- struct solaris_shmid_ds __user *p = A(arg3);
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ipc(SHMCTL, arg1, IPC_SET, 0, &s, 0);
- set_fs(old_fs);
- if (put_user (s.shm_perm.uid, &(p->shm_perm.uid)) ||
- __put_user (s.shm_perm.gid, &(p->shm_perm.gid)) ||
- __put_user (s.shm_perm.cuid, &(p->shm_perm.cuid)) ||
- __put_user (s.shm_perm.cgid, &(p->shm_perm.cgid)) ||
- __put_user (s.shm_perm.mode, &(p->shm_perm.mode)) ||
- __put_user (s.shm_perm.seq, &(p->shm_perm.seq)) ||
- __put_user (s.shm_perm.key, &(p->shm_perm.key)) ||
- __put_user (s.shm_segsz, &(p->shm_segsz)) ||
- __put_user (s.shm_lpid, &(p->shm_lpid)) ||
- __put_user (s.shm_cpid, &(p->shm_cpid)) ||
- __put_user (s.shm_nattch, &(p->shm_nattch)) ||
- __put_user (s.shm_atime, &(p->shm_atime)) ||
- __put_user (s.shm_dtime, &(p->shm_dtime)) ||
- __put_user (s.shm_ctime, &(p->shm_ctime)))
- return -EFAULT;
- return ret;
- }
- default: return -EINVAL;
- }
- case 2: /* shmdt */
- return sys_ipc(SHMDT, 0, 0, 0, A(arg1), 0);
- case 3: /* shmget */
- return sys_ipc(SHMGET, arg1, arg2, arg3, NULL, 0);
- }
- return -EINVAL;
-}
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
deleted file mode 100644
index d3e48e9701bf..000000000000
--- a/arch/sparc64/solaris/misc.c
+++ /dev/null
@@ -1,786 +0,0 @@
-/* $Id: misc.c,v 1.36 2002/02/09 19:49:31 davem Exp $
- * misc.c: Miscellaneous syscall emulation for Solaris
- *
- * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/utsname.h>
-#include <linux/limits.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/tty.h>
-#include <linux/mman.h>
-#include <linux/file.h>
-#include <linux/timex.h>
-#include <linux/major.h>
-#include <linux/compat.h>
-
-#include <asm/uaccess.h>
-#include <asm/string.h>
-#include <asm/oplib.h>
-#include <asm/idprom.h>
-#include <asm/smp.h>
-#include <asm/prom.h>
-
-#include "conv.h"
-
-/* Conversion from Linux to Solaris errnos. 0-34 are identity mapped.
- Some Linux errnos (EPROCLIM, EDOTDOT, ERREMOTE, EUCLEAN, ENOTNAM,
- ENAVAIL, EISNAM, EREMOTEIO, ENOMEDIUM, EMEDIUMTYPE) have no Solaris
- equivalents. I return EINVAL in that case, which is very wrong. If
- someone suggest a better value for them, you're welcomed.
- On the other side, Solaris ECANCELED and ENOTSUP have no Linux equivalents,
- but that doesn't matter here. --jj */
-int solaris_err_table[] = {
-/* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
-/* 10 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
-/* 20 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
-/* 30 */ 30, 31, 32, 33, 34, 22, 150, 149, 95, 96,
-/* 40 */ 97, 98, 99, 120, 121, 122, 123, 124, 125, 126,
-/* 50 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144,
-/* 60 */ 145, 146, 90, 78, 147, 148, 93, 22, 94, 49,
-/* 70 */ 151, 66, 60, 62, 63, 35, 77, 36, 45, 46,
-/* 80 */ 64, 22, 67, 68, 69, 70, 71, 74, 22, 82,
-/* 90 */ 89, 92, 79, 81, 37, 38, 39, 40, 41, 42,
-/* 100 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57,
-/* 110 */ 87, 61, 84, 65, 83, 80, 91, 22, 22, 22,
-/* 120 */ 22, 22, 88, 86, 85, 22, 22,
-};
-
-#define SOLARIS_NR_OPEN 256
-
-static u32 do_solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u64 off)
-{
- struct file *file = NULL;
- unsigned long retval, ret_type;
-
- /* Do we need it here? */
- set_personality(PER_SVR4);
- if (flags & MAP_NORESERVE) {
- static int cnt;
-
- if (cnt < 5) {
- printk("%s: unimplemented Solaris MAP_NORESERVE mmap() flag\n",
- current->comm);
- cnt++;
- }
- flags &= ~MAP_NORESERVE;
- }
- retval = -EBADF;
- if(!(flags & MAP_ANONYMOUS)) {
- if(fd >= SOLARIS_NR_OPEN)
- goto out;
- file = fget(fd);
- if (!file)
- goto out;
- else {
- struct inode * inode = file->f_path.dentry->d_inode;
- if(imajor(inode) == MEM_MAJOR &&
- iminor(inode) == 5) {
- flags |= MAP_ANONYMOUS;
- fput(file);
- file = NULL;
- }
- }
- }
-
- retval = -EINVAL;
- len = PAGE_ALIGN(len);
- if(!(flags & MAP_FIXED))
- addr = 0;
- else if (len > STACK_TOP32 || addr > STACK_TOP32 - len)
- goto out_putf;
- ret_type = flags & _MAP_NEW;
- flags &= ~_MAP_NEW;
-
- down_write(&current->mm->mmap_sem);
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- retval = do_mmap(file,
- (unsigned long) addr, (unsigned long) len,
- (unsigned long) prot, (unsigned long) flags, off);
- up_write(&current->mm->mmap_sem);
- if(!ret_type)
- retval = ((retval < STACK_TOP32) ? 0 : retval);
-
-out_putf:
- if (file)
- fput(file);
-out:
- return (u32) retval;
-}
-
-asmlinkage u32 solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off)
-{
- return do_solaris_mmap(addr, len, prot, flags, fd, (u64) off);
-}
-
-asmlinkage u32 solaris_mmap64(struct pt_regs *regs, u32 len, u32 prot, u32 flags, u32 fd, u32 offhi)
-{
- u32 offlo;
-
- if (regs->u_regs[UREG_G1]) {
- if (get_user (offlo, (u32 __user *)(long)((u32)regs->u_regs[UREG_I6] + 0x5c)))
- return -EFAULT;
- } else {
- if (get_user (offlo, (u32 __user *)(long)((u32)regs->u_regs[UREG_I6] + 0x60)))
- return -EFAULT;
- }
- return do_solaris_mmap((u32)regs->u_regs[UREG_I0], len, prot, flags, fd, (((u64)offhi)<<32)|offlo);
-}
-
-asmlinkage int solaris_brk(u32 brk)
-{
- int (*sunos_brk)(u32) = (int (*)(u32))SUNOS(17);
-
- return sunos_brk(brk);
-}
-
-static int __set_utsfield(char __user *to, int to_size,
- const char *from, int from_size,
- int dotchop, int countfrom)
-{
- int len = countfrom ? (to_size > from_size ?
- from_size : to_size) : to_size;
- int off;
-
- if (copy_to_user(to, from, len))
- return -EFAULT;
-
- off = len < to_size? len: len - 1;
- if (dotchop) {
- const char *p = strnchr(from, len, '.');
- if (p) off = p - from;
- }
-
- if (__put_user('\0', to + off))
- return -EFAULT;
-
- return 0;
-}
-
-#define set_utsfield(to, from, dotchop, countfrom) \
- __set_utsfield((to), sizeof(to), \
- (from), sizeof(from), \
- (dotchop), (countfrom))
-
-struct sol_uname {
- char sysname[9];
- char nodename[9];
- char release[9];
- char version[9];
- char machine[9];
-};
-
-struct sol_utsname {
- char sysname[257];
- char nodename[257];
- char release[257];
- char version[257];
- char machine[257];
-};
-
-static char *machine(void)
-{
- switch (sparc_cpu_model) {
- case sun4: return "sun4";
- case sun4c: return "sun4c";
- case sun4e: return "sun4e";
- case sun4m: return "sun4m";
- case sun4d: return "sun4d";
- case sun4u: return "sun4u";
- default: return "sparc";
- }
-}
-
-static char *platform(char *buffer, int sz)
-{
- struct device_node *dp = of_find_node_by_path("/");
- int len;
-
- *buffer = 0;
- len = strlen(dp->name);
- if (len > sz)
- len = sz;
- memcpy(buffer, dp->name, len);
- buffer[len] = 0;
- if (*buffer) {
- char *p;
-
- for (p = buffer; *p; p++)
- if (*p == '/' || *p == ' ') *p = '_';
- return buffer;
- }
-
- return "sun4u";
-}
-
-static char *serial(char *buffer, int sz)
-{
- struct device_node *dp = of_find_node_by_path("/options");
- int len;
-
- *buffer = 0;
- if (dp) {
- const char *val =
- of_get_property(dp, "system-board-serial#", &len);
-
- if (val && len > 0) {
- if (len > sz)
- len = sz;
- memcpy(buffer, val, len);
- buffer[len] = 0;
- }
- }
- if (!*buffer)
- return "4512348717234";
- else
- return buffer;
-}
-
-asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2)
-{
- struct sol_uname __user *v = A(buf);
- int err;
-
- switch (which) {
- case 0: /* old uname */
- /* Let's cheat */
- err = set_utsfield(v->sysname, "SunOS", 1, 0);
- down_read(&uts_sem);
- err |= set_utsfield(v->nodename, utsname()->nodename,
- 1, 1);
- up_read(&uts_sem);
- err |= set_utsfield(v->release, "2.6", 0, 0);
- err |= set_utsfield(v->version, "Generic", 0, 0);
- err |= set_utsfield(v->machine, machine(), 0, 0);
- return (err ? -EFAULT : 0);
- case 2: /* ustat */
- return -ENOSYS;
- case 3: /* fusers */
- return -ENOSYS;
- default:
- return -ENOSYS;
- }
-}
-
-asmlinkage int solaris_utsname(u32 buf)
-{
- struct sol_utsname __user *v = A(buf);
- int err;
-
- /* Why should we not lie a bit? */
- down_read(&uts_sem);
- err = set_utsfield(v->sysname, "SunOS", 0, 0);
- err |= set_utsfield(v->nodename, utsname()->nodename, 1, 1);
- err |= set_utsfield(v->release, "5.6", 0, 0);
- err |= set_utsfield(v->version, "Generic", 0, 0);
- err |= set_utsfield(v->machine, machine(), 0, 0);
- up_read(&uts_sem);
-
- return (err ? -EFAULT : 0);
-}
-
-#define SI_SYSNAME 1 /* return name of operating system */
-#define SI_HOSTNAME 2 /* return name of node */
-#define SI_RELEASE 3 /* return release of operating system */
-#define SI_VERSION 4 /* return version field of utsname */
-#define SI_MACHINE 5 /* return kind of machine */
-#define SI_ARCHITECTURE 6 /* return instruction set arch */
-#define SI_HW_SERIAL 7 /* return hardware serial number */
-#define SI_HW_PROVIDER 8 /* return hardware manufacturer */
-#define SI_SRPC_DOMAIN 9 /* return secure RPC domain */
-#define SI_PLATFORM 513 /* return platform identifier */
-
-asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count)
-{
- char *p, *q, *r;
- char buffer[256];
- int len;
-
- /* Again, we cheat :)) */
- switch (cmd) {
- case SI_SYSNAME: r = "SunOS"; break;
- case SI_HOSTNAME:
- r = buffer + 256;
- down_read(&uts_sem);
- for (p = utsname()->nodename, q = buffer;
- q < r && *p && *p != '.'; *q++ = *p++);
- up_read(&uts_sem);
- *q = 0;
- r = buffer;
- break;
- case SI_RELEASE: r = "5.6"; break;
- case SI_MACHINE: r = machine(); break;
- case SI_ARCHITECTURE: r = "sparc"; break;
- case SI_HW_PROVIDER: r = "Sun_Microsystems"; break;
- case SI_HW_SERIAL: r = serial(buffer, sizeof(buffer)); break;
- case SI_PLATFORM: r = platform(buffer, sizeof(buffer)); break;
- case SI_SRPC_DOMAIN: r = ""; break;
- case SI_VERSION: r = "Generic"; break;
- default: return -EINVAL;
- }
- len = strlen(r) + 1;
- if (count < len) {
- if (copy_to_user(A(buf), r, count - 1) ||
- __put_user(0, (char __user *)A(buf) + count - 1))
- return -EFAULT;
- } else {
- if (copy_to_user(A(buf), r, len))
- return -EFAULT;
- }
- return len;
-}
-
-#define SOLARIS_CONFIG_NGROUPS 2
-#define SOLARIS_CONFIG_CHILD_MAX 3
-#define SOLARIS_CONFIG_OPEN_FILES 4
-#define SOLARIS_CONFIG_POSIX_VER 5
-#define SOLARIS_CONFIG_PAGESIZE 6
-#define SOLARIS_CONFIG_CLK_TCK 7
-#define SOLARIS_CONFIG_XOPEN_VER 8
-#define SOLARIS_CONFIG_PROF_TCK 10
-#define SOLARIS_CONFIG_NPROC_CONF 11
-#define SOLARIS_CONFIG_NPROC_ONLN 12
-#define SOLARIS_CONFIG_AIO_LISTIO_MAX 13
-#define SOLARIS_CONFIG_AIO_MAX 14
-#define SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX 15
-#define SOLARIS_CONFIG_DELAYTIMER_MAX 16
-#define SOLARIS_CONFIG_MQ_OPEN_MAX 17
-#define SOLARIS_CONFIG_MQ_PRIO_MAX 18
-#define SOLARIS_CONFIG_RTSIG_MAX 19
-#define SOLARIS_CONFIG_SEM_NSEMS_MAX 20
-#define SOLARIS_CONFIG_SEM_VALUE_MAX 21
-#define SOLARIS_CONFIG_SIGQUEUE_MAX 22
-#define SOLARIS_CONFIG_SIGRT_MIN 23
-#define SOLARIS_CONFIG_SIGRT_MAX 24
-#define SOLARIS_CONFIG_TIMER_MAX 25
-#define SOLARIS_CONFIG_PHYS_PAGES 26
-#define SOLARIS_CONFIG_AVPHYS_PAGES 27
-
-asmlinkage int solaris_sysconf(int id)
-{
- switch (id) {
- case SOLARIS_CONFIG_NGROUPS: return NGROUPS_MAX;
- case SOLARIS_CONFIG_CHILD_MAX:
- return current->signal->rlim[RLIMIT_NPROC].rlim_cur;
- case SOLARIS_CONFIG_OPEN_FILES:
- return current->signal->rlim[RLIMIT_NOFILE].rlim_cur;
- case SOLARIS_CONFIG_POSIX_VER: return 199309;
- case SOLARIS_CONFIG_PAGESIZE: return PAGE_SIZE;
- case SOLARIS_CONFIG_XOPEN_VER: return 3;
- case SOLARIS_CONFIG_CLK_TCK:
- case SOLARIS_CONFIG_PROF_TCK:
- return sparc64_get_clock_tick(smp_processor_id());
-#ifdef CONFIG_SMP
- case SOLARIS_CONFIG_NPROC_CONF: return NR_CPUS;
- case SOLARIS_CONFIG_NPROC_ONLN: return num_online_cpus();
-#else
- case SOLARIS_CONFIG_NPROC_CONF: return 1;
- case SOLARIS_CONFIG_NPROC_ONLN: return 1;
-#endif
- case SOLARIS_CONFIG_SIGRT_MIN: return 37;
- case SOLARIS_CONFIG_SIGRT_MAX: return 44;
- case SOLARIS_CONFIG_PHYS_PAGES:
- case SOLARIS_CONFIG_AVPHYS_PAGES:
- {
- struct sysinfo s;
-
- si_meminfo(&s);
- if (id == SOLARIS_CONFIG_PHYS_PAGES)
- return s.totalram >>= PAGE_SHIFT;
- else
- return s.freeram >>= PAGE_SHIFT;
- }
- /* XXX support these as well -jj */
- case SOLARIS_CONFIG_AIO_LISTIO_MAX: return -EINVAL;
- case SOLARIS_CONFIG_AIO_MAX: return -EINVAL;
- case SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX: return -EINVAL;
- case SOLARIS_CONFIG_DELAYTIMER_MAX: return -EINVAL;
- case SOLARIS_CONFIG_MQ_OPEN_MAX: return -EINVAL;
- case SOLARIS_CONFIG_MQ_PRIO_MAX: return -EINVAL;
- case SOLARIS_CONFIG_RTSIG_MAX: return -EINVAL;
- case SOLARIS_CONFIG_SEM_NSEMS_MAX: return -EINVAL;
- case SOLARIS_CONFIG_SEM_VALUE_MAX: return -EINVAL;
- case SOLARIS_CONFIG_SIGQUEUE_MAX: return -EINVAL;
- case SOLARIS_CONFIG_TIMER_MAX: return -EINVAL;
- default: return -EINVAL;
- }
-}
-
-asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
-{
- int ret;
-
- switch (cmd) {
- case 0: /* getpgrp */
- return task_pgrp_vnr(current);
- case 1: /* setpgrp */
- {
- int (*sys_setpgid)(pid_t,pid_t) =
- (int (*)(pid_t,pid_t))SYS(setpgid);
-
- /* can anyone explain me the difference between
- Solaris setpgrp and setsid? */
- ret = sys_setpgid(0, 0);
- if (ret) return ret;
- proc_clear_tty(current);
- return task_pgrp_vnr(current);
- }
- case 2: /* getsid */
- {
- int (*sys_getsid)(pid_t) = (int (*)(pid_t))SYS(getsid);
- return sys_getsid(pid);
- }
- case 3: /* setsid */
- {
- int (*sys_setsid)(void) = (int (*)(void))SYS(setsid);
- return sys_setsid();
- }
- case 4: /* getpgid */
- {
- int (*sys_getpgid)(pid_t) = (int (*)(pid_t))SYS(getpgid);
- return sys_getpgid(pid);
- }
- case 5: /* setpgid */
- {
- int (*sys_setpgid)(pid_t,pid_t) =
- (int (*)(pid_t,pid_t))SYS(setpgid);
- return sys_setpgid(pid,pgid);
- }
- }
- return -EINVAL;
-}
-
-asmlinkage int solaris_gettimeofday(u32 tim)
-{
- int (*sys_gettimeofday)(struct timeval *, struct timezone *) =
- (int (*)(struct timeval *, struct timezone *))SYS(gettimeofday);
-
- return sys_gettimeofday((struct timeval *)(u64)tim, NULL);
-}
-
-#define RLIM_SOL_INFINITY32 0x7fffffff
-#define RLIM_SOL_SAVED_MAX32 0x7ffffffe
-#define RLIM_SOL_SAVED_CUR32 0x7ffffffd
-#define RLIM_SOL_INFINITY ((u64)-3)
-#define RLIM_SOL_SAVED_MAX ((u64)-2)
-#define RLIM_SOL_SAVED_CUR ((u64)-1)
-#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
-#define RLIMIT_SOL_NOFILE 5
-#define RLIMIT_SOL_VMEM 6
-
-struct rlimit32 {
- u32 rlim_cur;
- u32 rlim_max;
-};
-
-asmlinkage int solaris_getrlimit(unsigned int resource, struct rlimit32 __user *rlim)
-{
- struct rlimit r;
- int ret;
- mm_segment_t old_fs = get_fs ();
- int (*sys_getrlimit)(unsigned int, struct rlimit *) =
- (int (*)(unsigned int, struct rlimit *))SYS(getrlimit);
-
- if (resource > RLIMIT_SOL_VMEM)
- return -EINVAL;
- switch (resource) {
- case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
- case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
- default: break;
- }
- set_fs (KERNEL_DS);
- ret = sys_getrlimit(resource, &r);
- set_fs (old_fs);
- if (!ret) {
- if (r.rlim_cur == RLIM_INFINITY)
- r.rlim_cur = RLIM_SOL_INFINITY32;
- else if ((u64)r.rlim_cur > RLIM_SOL_INFINITY32)
- r.rlim_cur = RLIM_SOL_SAVED_CUR32;
- if (r.rlim_max == RLIM_INFINITY)
- r.rlim_max = RLIM_SOL_INFINITY32;
- else if ((u64)r.rlim_max > RLIM_SOL_INFINITY32)
- r.rlim_max = RLIM_SOL_SAVED_MAX32;
- ret = put_user (r.rlim_cur, &rlim->rlim_cur);
- ret |= __put_user (r.rlim_max, &rlim->rlim_max);
- }
- return ret;
-}
-
-asmlinkage int solaris_setrlimit(unsigned int resource, struct rlimit32 __user *rlim)
-{
- struct rlimit r, rold;
- int ret;
- mm_segment_t old_fs = get_fs ();
- int (*sys_getrlimit)(unsigned int, struct rlimit __user *) =
- (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit);
- int (*sys_setrlimit)(unsigned int, struct rlimit __user *) =
- (int (*)(unsigned int, struct rlimit __user *))SYS(setrlimit);
-
- if (resource > RLIMIT_SOL_VMEM)
- return -EINVAL;
- switch (resource) {
- case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
- case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
- default: break;
- }
- if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
- __get_user (r.rlim_max, &rlim->rlim_max))
- return -EFAULT;
- set_fs (KERNEL_DS);
- ret = sys_getrlimit(resource, &rold);
- if (!ret) {
- if (r.rlim_cur == RLIM_SOL_INFINITY32)
- r.rlim_cur = RLIM_INFINITY;
- else if (r.rlim_cur == RLIM_SOL_SAVED_CUR32)
- r.rlim_cur = rold.rlim_cur;
- else if (r.rlim_cur == RLIM_SOL_SAVED_MAX32)
- r.rlim_cur = rold.rlim_max;
- if (r.rlim_max == RLIM_SOL_INFINITY32)
- r.rlim_max = RLIM_INFINITY;
- else if (r.rlim_max == RLIM_SOL_SAVED_CUR32)
- r.rlim_max = rold.rlim_cur;
- else if (r.rlim_max == RLIM_SOL_SAVED_MAX32)
- r.rlim_max = rold.rlim_max;
- ret = sys_setrlimit(resource, &r);
- }
- set_fs (old_fs);
- return ret;
-}
-
-asmlinkage int solaris_getrlimit64(unsigned int resource, struct rlimit __user *rlim)
-{
- struct rlimit r;
- int ret;
- mm_segment_t old_fs = get_fs ();
- int (*sys_getrlimit)(unsigned int, struct rlimit __user *) =
- (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit);
-
- if (resource > RLIMIT_SOL_VMEM)
- return -EINVAL;
- switch (resource) {
- case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
- case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
- default: break;
- }
- set_fs (KERNEL_DS);
- ret = sys_getrlimit(resource, &r);
- set_fs (old_fs);
- if (!ret) {
- if (r.rlim_cur == RLIM_INFINITY)
- r.rlim_cur = RLIM_SOL_INFINITY;
- if (r.rlim_max == RLIM_INFINITY)
- r.rlim_max = RLIM_SOL_INFINITY;
- ret = put_user (r.rlim_cur, &rlim->rlim_cur);
- ret |= __put_user (r.rlim_max, &rlim->rlim_max);
- }
- return ret;
-}
-
-asmlinkage int solaris_setrlimit64(unsigned int resource, struct rlimit __user *rlim)
-{
- struct rlimit r, rold;
- int ret;
- mm_segment_t old_fs = get_fs ();
- int (*sys_getrlimit)(unsigned int, struct rlimit __user *) =
- (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit);
- int (*sys_setrlimit)(unsigned int, struct rlimit __user *) =
- (int (*)(unsigned int, struct rlimit __user *))SYS(setrlimit);
-
- if (resource > RLIMIT_SOL_VMEM)
- return -EINVAL;
- switch (resource) {
- case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
- case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
- default: break;
- }
- if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
- __get_user (r.rlim_max, &rlim->rlim_max))
- return -EFAULT;
- set_fs (KERNEL_DS);
- ret = sys_getrlimit(resource, &rold);
- if (!ret) {
- if (r.rlim_cur == RLIM_SOL_INFINITY)
- r.rlim_cur = RLIM_INFINITY;
- else if (r.rlim_cur == RLIM_SOL_SAVED_CUR)
- r.rlim_cur = rold.rlim_cur;
- else if (r.rlim_cur == RLIM_SOL_SAVED_MAX)
- r.rlim_cur = rold.rlim_max;
- if (r.rlim_max == RLIM_SOL_INFINITY)
- r.rlim_max = RLIM_INFINITY;
- else if (r.rlim_max == RLIM_SOL_SAVED_CUR)
- r.rlim_max = rold.rlim_cur;
- else if (r.rlim_max == RLIM_SOL_SAVED_MAX)
- r.rlim_max = rold.rlim_max;
- ret = sys_setrlimit(resource, &r);
- }
- set_fs (old_fs);
- return ret;
-}
-
-struct sol_ntptimeval {
- struct compat_timeval time;
- s32 maxerror;
- s32 esterror;
-};
-
-struct sol_timex {
- u32 modes;
- s32 offset;
- s32 freq;
- s32 maxerror;
- s32 esterror;
- s32 status;
- s32 constant;
- s32 precision;
- s32 tolerance;
- s32 ppsfreq;
- s32 jitter;
- s32 shift;
- s32 stabil;
- s32 jitcnt;
- s32 calcnt;
- s32 errcnt;
- s32 stbcnt;
-};
-
-asmlinkage int solaris_ntp_gettime(struct sol_ntptimeval __user *ntp)
-{
- int (*sys_adjtimex)(struct timex __user *) =
- (int (*)(struct timex __user *))SYS(adjtimex);
- struct timex t;
- int ret;
- mm_segment_t old_fs = get_fs();
-
- set_fs(KERNEL_DS);
- t.modes = 0;
- ret = sys_adjtimex(&t);
- set_fs(old_fs);
- if (ret < 0)
- return ret;
- ret = put_user (t.time.tv_sec, &ntp->time.tv_sec);
- ret |= __put_user (t.time.tv_usec, &ntp->time.tv_usec);
- ret |= __put_user (t.maxerror, &ntp->maxerror);
- ret |= __put_user (t.esterror, &ntp->esterror);
- return ret;
-}
-
-asmlinkage int solaris_ntp_adjtime(struct sol_timex __user *txp)
-{
- int (*sys_adjtimex)(struct timex __user *) =
- (int (*)(struct timex __user *))SYS(adjtimex);
- struct timex t;
- int ret, err;
- mm_segment_t old_fs = get_fs();
-
- ret = get_user (t.modes, &txp->modes);
- ret |= __get_user (t.offset, &txp->offset);
- ret |= __get_user (t.freq, &txp->freq);
- ret |= __get_user (t.maxerror, &txp->maxerror);
- ret |= __get_user (t.esterror, &txp->esterror);
- ret |= __get_user (t.status, &txp->status);
- ret |= __get_user (t.constant, &txp->constant);
- set_fs(KERNEL_DS);
- ret = sys_adjtimex(&t);
- set_fs(old_fs);
- if (ret < 0)
- return ret;
- err = put_user (t.offset, &txp->offset);
- err |= __put_user (t.freq, &txp->freq);
- err |= __put_user (t.maxerror, &txp->maxerror);
- err |= __put_user (t.esterror, &txp->esterror);
- err |= __put_user (t.status, &txp->status);
- err |= __put_user (t.constant, &txp->constant);
- err |= __put_user (t.precision, &txp->precision);
- err |= __put_user (t.tolerance, &txp->tolerance);
- err |= __put_user (t.ppsfreq, &txp->ppsfreq);
- err |= __put_user (t.jitter, &txp->jitter);
- err |= __put_user (t.shift, &txp->shift);
- err |= __put_user (t.stabil, &txp->stabil);
- err |= __put_user (t.jitcnt, &txp->jitcnt);
- err |= __put_user (t.calcnt, &txp->calcnt);
- err |= __put_user (t.errcnt, &txp->errcnt);
- err |= __put_user (t.stbcnt, &txp->stbcnt);
- if (err)
- return -EFAULT;
- return ret;
-}
-
-asmlinkage int do_sol_unimplemented(struct pt_regs *regs)
-{
- printk ("Unimplemented Solaris syscall %d %08x %08x %08x %08x\n",
- (int)regs->u_regs[UREG_G1],
- (int)regs->u_regs[UREG_I0],
- (int)regs->u_regs[UREG_I1],
- (int)regs->u_regs[UREG_I2],
- (int)regs->u_regs[UREG_I3]);
- return -ENOSYS;
-}
-
-asmlinkage void solaris_register(void)
-{
- set_personality(PER_SVR4);
-}
-
-extern long solaris_to_linux_signals[], linux_to_solaris_signals[];
-
-struct exec_domain solaris_exec_domain = {
- .name = "Solaris",
- .handler = NULL,
- .pers_low = 1, /* PER_SVR4 personality */
- .pers_high = 1,
- .signal_map = solaris_to_linux_signals,
- .signal_invmap =linux_to_solaris_signals,
- .module = THIS_MODULE,
- .next = NULL
-};
-
-extern int init_socksys(void);
-
-MODULE_AUTHOR("Jakub Jelinek (jj@ultra.linux.cz), Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)");
-MODULE_DESCRIPTION("Solaris binary emulation module");
-MODULE_LICENSE("GPL");
-
-extern u32 tl0_solaris[8];
-#define update_ttable(x) \
- tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000; \
- wmb(); \
- __asm__ __volatile__ ("flush %0" : : "r" (&tl0_solaris[3]))
-
-extern u32 solaris_sparc_syscall[];
-extern u32 solaris_syscall[];
-extern void cleanup_socksys(void);
-
-extern u32 entry64_personality_patch;
-
-static int __init solaris_init(void)
-{
- int ret;
-
- SOLDD(("Solaris module at %p\n", solaris_sparc_syscall));
- register_exec_domain(&solaris_exec_domain);
- if ((ret = init_socksys())) {
- unregister_exec_domain(&solaris_exec_domain);
- return ret;
- }
- update_ttable(solaris_sparc_syscall);
- entry64_personality_patch |=
- (offsetof(struct task_struct, personality) +
- (sizeof(unsigned long) - 1));
- wmb();
- __asm__ __volatile__("flush %0"
- : : "r" (&entry64_personality_patch));
- return 0;
-}
-
-static void __exit solaris_exit(void)
-{
- update_ttable(solaris_syscall);
- cleanup_socksys();
- unregister_exec_domain(&solaris_exec_domain);
-}
-
-module_init(solaris_init);
-module_exit(solaris_exit);
diff --git a/arch/sparc64/solaris/signal.c b/arch/sparc64/solaris/signal.c
deleted file mode 100644
index de10c9716cfb..000000000000
--- a/arch/sparc64/solaris/signal.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/* $Id: signal.c,v 1.7 2000/09/05 21:44:54 davem Exp $
- * signal.c: Signal emulation for Solaris
- *
- * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#include <linux/types.h>
-#include <linux/errno.h>
-
-#include <asm/uaccess.h>
-#include <asm/svr4.h>
-#include <asm/string.h>
-
-#include "conv.h"
-#include "signal.h"
-
-#define _S(nr) (1L<<((nr)-1))
-
-#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
-
-long linux_to_solaris_signals[] = {
- 0,
- SOLARIS_SIGHUP, SOLARIS_SIGINT,
- SOLARIS_SIGQUIT, SOLARIS_SIGILL,
- SOLARIS_SIGTRAP, SOLARIS_SIGIOT,
- SOLARIS_SIGEMT, SOLARIS_SIGFPE,
- SOLARIS_SIGKILL, SOLARIS_SIGBUS,
- SOLARIS_SIGSEGV, SOLARIS_SIGSYS,
- SOLARIS_SIGPIPE, SOLARIS_SIGALRM,
- SOLARIS_SIGTERM, SOLARIS_SIGURG,
- SOLARIS_SIGSTOP, SOLARIS_SIGTSTP,
- SOLARIS_SIGCONT, SOLARIS_SIGCLD,
- SOLARIS_SIGTTIN, SOLARIS_SIGTTOU,
- SOLARIS_SIGPOLL, SOLARIS_SIGXCPU,
- SOLARIS_SIGXFSZ, SOLARIS_SIGVTALRM,
- SOLARIS_SIGPROF, SOLARIS_SIGWINCH,
- SOLARIS_SIGUSR1, SOLARIS_SIGUSR1,
- SOLARIS_SIGUSR2, -1,
-};
-
-long solaris_to_linux_signals[] = {
- 0,
- SIGHUP, SIGINT, SIGQUIT, SIGILL,
- SIGTRAP, SIGIOT, SIGEMT, SIGFPE,
- SIGKILL, SIGBUS, SIGSEGV, SIGSYS,
- SIGPIPE, SIGALRM, SIGTERM, SIGUSR1,
- SIGUSR2, SIGCHLD, -1, SIGWINCH,
- SIGURG, SIGPOLL, SIGSTOP, SIGTSTP,
- SIGCONT, SIGTTIN, SIGTTOU, SIGVTALRM,
- SIGPROF, SIGXCPU, SIGXFSZ, -1,
- -1, -1, -1, -1,
- -1, -1, -1, -1,
- -1, -1, -1, -1,
-};
-
-static inline long mapsig(long sig)
-{
- if ((unsigned long)sig > SOLARIS_NSIGNALS)
- return -EINVAL;
- return solaris_to_linux_signals[sig];
-}
-
-asmlinkage int solaris_kill(int pid, int sig)
-{
- int (*sys_kill)(int,int) =
- (int (*)(int,int))SYS(kill);
- int s = mapsig(sig);
-
- if (s < 0) return s;
- return sys_kill(pid, s);
-}
-
-static long sig_handler(int sig, u32 arg, int one_shot)
-{
- struct sigaction sa, old;
- int ret;
- mm_segment_t old_fs = get_fs();
- int (*sys_sigaction)(int,struct sigaction __user *,struct sigaction __user *) =
- (int (*)(int,struct sigaction __user *,struct sigaction __user *))SYS(sigaction);
-
- sigemptyset(&sa.sa_mask);
- sa.sa_restorer = NULL;
- sa.sa_handler = (__sighandler_t)A(arg);
- sa.sa_flags = 0;
- if (one_shot) sa.sa_flags = SA_ONESHOT | SA_NOMASK;
- set_fs (KERNEL_DS);
- ret = sys_sigaction(sig, (void __user *)&sa, (void __user *)&old);
- set_fs (old_fs);
- if (ret < 0) return ret;
- return (u32)(unsigned long)old.sa_handler;
-}
-
-static inline long solaris_signal(int sig, u32 arg)
-{
- return sig_handler (sig, arg, 1);
-}
-
-static long solaris_sigset(int sig, u32 arg)
-{
- if (arg != 2) /* HOLD */ {
- spin_lock_irq(&current->sighand->siglock);
- sigdelsetmask(&current->blocked, _S(sig));
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
- return sig_handler (sig, arg, 0);
- } else {
- spin_lock_irq(&current->sighand->siglock);
- sigaddsetmask(&current->blocked, (_S(sig) & ~_BLOCKABLE));
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
- return 0;
- }
-}
-
-static inline long solaris_sighold(int sig)
-{
- return solaris_sigset(sig, 2);
-}
-
-static inline long solaris_sigrelse(int sig)
-{
- spin_lock_irq(&current->sighand->siglock);
- sigdelsetmask(&current->blocked, _S(sig));
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
- return 0;
-}
-
-static inline long solaris_sigignore(int sig)
-{
- return sig_handler(sig, (u32)(unsigned long)SIG_IGN, 0);
-}
-
-static inline long solaris_sigpause(int sig)
-{
- printk ("Need to support solaris sigpause\n");
- return -ENOSYS;
-}
-
-asmlinkage long solaris_sigfunc(int sig, u32 arg)
-{
- int func = sig & ~0xff;
-
- sig = mapsig(sig & 0xff);
- if (sig < 0) return sig;
- switch (func) {
- case 0: return solaris_signal(sig, arg);
- case 0x100: return solaris_sigset(sig, arg);
- case 0x200: return solaris_sighold(sig);
- case 0x400: return solaris_sigrelse(sig);
- case 0x800: return solaris_sigignore(sig);
- case 0x1000: return solaris_sigpause(sig);
- }
- return -EINVAL;
-}
-
-typedef struct {
- u32 __sigbits[4];
-} sol_sigset_t;
-
-static inline int mapin(u32 *p, sigset_t *q)
-{
- int i;
- u32 x;
- int sig;
-
- sigemptyset(q);
- x = p[0];
- for (i = 1; i <= SOLARIS_NSIGNALS; i++) {
- if (x & 1) {
- sig = solaris_to_linux_signals[i];
- if (sig == -1)
- return -EINVAL;
- sigaddsetmask(q, (1L << (sig - 1)));
- }
- x >>= 1;
- if (i == 32)
- x = p[1];
- }
- return 0;
-}
-
-static inline int mapout(sigset_t *q, u32 *p)
-{
- int i;
- int sig;
-
- p[0] = 0;
- p[1] = 0;
- for (i = 1; i <= 32; i++) {
- if (sigismember(q, sigmask(i))) {
- sig = linux_to_solaris_signals[i];
- if (sig == -1)
- return -EINVAL;
- if (sig > 32)
- p[1] |= 1L << (sig - 33);
- else
- p[0] |= 1L << (sig - 1);
- }
- }
- return 0;
-}
-
-asmlinkage int solaris_sigprocmask(int how, u32 in, u32 out)
-{
- sigset_t in_s, *ins, out_s, *outs;
- mm_segment_t old_fs = get_fs();
- int ret;
- int (*sys_sigprocmask)(int,sigset_t __user *,sigset_t __user *) =
- (int (*)(int,sigset_t __user *,sigset_t __user *))SYS(sigprocmask);
-
- ins = NULL; outs = NULL;
- if (in) {
- u32 tmp[2];
-
- if (copy_from_user (tmp, (void __user *)A(in), 2*sizeof(u32)))
- return -EFAULT;
- ins = &in_s;
- if (mapin (tmp, ins)) return -EINVAL;
- }
- if (out) outs = &out_s;
- set_fs (KERNEL_DS);
- ret = sys_sigprocmask((how == 3) ? SIG_SETMASK : how,
- (void __user *)ins, (void __user *)outs);
- set_fs (old_fs);
- if (ret) return ret;
- if (out) {
- u32 tmp[4];
-
- tmp[2] = 0; tmp[3] = 0;
- if (mapout (outs, tmp)) return -EINVAL;
- if (copy_to_user((void __user *)A(out), tmp, 4*sizeof(u32)))
- return -EFAULT;
- }
- return 0;
-}
-
-asmlinkage long do_sol_sigsuspend(u32 mask)
-{
- sigset_t s;
- u32 tmp[2];
-
- if (copy_from_user (tmp, (sol_sigset_t __user *)A(mask), 2*sizeof(u32)))
- return -EFAULT;
- if (mapin (tmp, &s)) return -EINVAL;
- return (long)s.sig[0];
-}
-
-struct sol_sigaction {
- int sa_flags;
- u32 sa_handler;
- u32 sa_mask[4];
- int sa_resv[2];
-};
-
-asmlinkage int solaris_sigaction(int sig, u32 act, u32 old)
-{
- u32 tmp, tmp2[4];
- struct sigaction s, s2;
- int ret;
- mm_segment_t old_fs = get_fs();
- struct sol_sigaction __user *p = (void __user *)A(old);
- int (*sys_sigaction)(int,struct sigaction __user *,struct sigaction __user *) =
- (int (*)(int,struct sigaction __user *,struct sigaction __user *))SYS(sigaction);
-
- sig = mapsig(sig);
- if (sig < 0) {
- /* We cheat a little bit for Solaris only signals */
- if (old && clear_user(p, sizeof(struct sol_sigaction)))
- return -EFAULT;
- return 0;
- }
- if (act) {
- if (get_user (tmp, &p->sa_flags))
- return -EFAULT;
- s.sa_flags = 0;
- if (tmp & SOLARIS_SA_ONSTACK) s.sa_flags |= SA_STACK;
- if (tmp & SOLARIS_SA_RESTART) s.sa_flags |= SA_RESTART;
- if (tmp & SOLARIS_SA_NODEFER) s.sa_flags |= SA_NOMASK;
- if (tmp & SOLARIS_SA_RESETHAND) s.sa_flags |= SA_ONESHOT;
- if (tmp & SOLARIS_SA_NOCLDSTOP) s.sa_flags |= SA_NOCLDSTOP;
- if (get_user (tmp, &p->sa_handler) ||
- copy_from_user (tmp2, &p->sa_mask, 2*sizeof(u32)))
- return -EFAULT;
- s.sa_handler = (__sighandler_t)A(tmp);
- if (mapin (tmp2, &s.sa_mask)) return -EINVAL;
- s.sa_restorer = NULL;
- }
- set_fs(KERNEL_DS);
- ret = sys_sigaction(sig, act ? (void __user *)&s : NULL,
- old ? (void __user *)&s2 : NULL);
- set_fs(old_fs);
- if (ret) return ret;
- if (old) {
- if (mapout (&s2.sa_mask, tmp2)) return -EINVAL;
- tmp = 0; tmp2[2] = 0; tmp2[3] = 0;
- if (s2.sa_flags & SA_STACK) tmp |= SOLARIS_SA_ONSTACK;
- if (s2.sa_flags & SA_RESTART) tmp |= SOLARIS_SA_RESTART;
- if (s2.sa_flags & SA_NOMASK) tmp |= SOLARIS_SA_NODEFER;
- if (s2.sa_flags & SA_ONESHOT) tmp |= SOLARIS_SA_RESETHAND;
- if (s2.sa_flags & SA_NOCLDSTOP) tmp |= SOLARIS_SA_NOCLDSTOP;
- if (put_user (tmp, &p->sa_flags) ||
- __put_user ((u32)(unsigned long)s2.sa_handler, &p->sa_handler) ||
- copy_to_user (&p->sa_mask, tmp2, 4*sizeof(u32)))
- return -EFAULT;
- }
- return 0;
-}
-
-asmlinkage int solaris_sigpending(int which, u32 set)
-{
- sigset_t s;
- u32 tmp[4];
- switch (which) {
- case 1: /* sigpending */
- spin_lock_irq(&current->sighand->siglock);
- sigandsets(&s, &current->blocked, &current->pending.signal);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
- break;
- case 2: /* sigfillset - I just set signals which have linux equivalents */
- sigfillset(&s);
- break;
- default: return -EINVAL;
- }
- if (mapout (&s, tmp)) return -EINVAL;
- tmp[2] = 0; tmp[3] = 0;
- if (copy_to_user ((u32 __user *)A(set), tmp, sizeof(tmp)))
- return -EFAULT;
- return 0;
-}
-
-asmlinkage int solaris_wait(u32 stat_loc)
-{
- unsigned __user *p = (unsigned __user *)A(stat_loc);
- int (*sys_wait4)(pid_t,unsigned __user *, int, struct rusage __user *) =
- (int (*)(pid_t,unsigned __user *, int, struct rusage __user *))SYS(wait4);
- int ret, status;
-
- ret = sys_wait4(-1, p, WUNTRACED, NULL);
- if (ret >= 0 && stat_loc) {
- if (get_user (status, p))
- return -EFAULT;
- if (((status - 1) & 0xffff) < 0xff)
- status = linux_to_solaris_signals[status & 0x7f] & 0x7f;
- else if ((status & 0xff) == 0x7f)
- status = (linux_to_solaris_signals[(status >> 8) & 0xff] << 8) | 0x7f;
- if (__put_user (status, p))
- return -EFAULT;
- }
- return ret;
-}
-
-asmlinkage int solaris_waitid(int idtype, s32 pid, u32 info, int options)
-{
- int (*sys_wait4)(pid_t,unsigned __user *, int, struct rusage __user *) =
- (int (*)(pid_t,unsigned __user *, int, struct rusage __user *))SYS(wait4);
- int opts, status, ret;
-
- switch (idtype) {
- case 0: /* P_PID */ break;
- case 1: /* P_PGID */ pid = -pid; break;
- case 7: /* P_ALL */ pid = -1; break;
- default: return -EINVAL;
- }
- opts = 0;
- if (options & SOLARIS_WUNTRACED) opts |= WUNTRACED;
- if (options & SOLARIS_WNOHANG) opts |= WNOHANG;
- current->state = TASK_RUNNING;
- ret = sys_wait4(pid, (unsigned int __user *)A(info), opts, NULL);
- if (ret < 0) return ret;
- if (info) {
- struct sol_siginfo __user *s = (void __user *)A(info);
-
- if (get_user (status, (unsigned int __user *)A(info)))
- return -EFAULT;
-
- if (__put_user (SOLARIS_SIGCLD, &s->si_signo) ||
- __put_user (ret, &s->_data._proc._pid))
- return -EFAULT;
-
- switch (status & 0xff) {
- case 0: ret = SOLARIS_CLD_EXITED;
- status = (status >> 8) & 0xff;
- break;
- case 0x7f:
- status = (status >> 8) & 0xff;
- switch (status) {
- case SIGSTOP:
- case SIGTSTP: ret = SOLARIS_CLD_STOPPED;
- default: ret = SOLARIS_CLD_EXITED;
- }
- status = linux_to_solaris_signals[status];
- break;
- default:
- if (status & 0x80) ret = SOLARIS_CLD_DUMPED;
- else ret = SOLARIS_CLD_KILLED;
- status = linux_to_solaris_signals[status & 0x7f];
- break;
- }
-
- if (__put_user (ret, &s->si_code) ||
- __put_user (status, &s->_data._proc._pdata._cld._status))
- return -EFAULT;
- }
- return 0;
-}
-
-extern int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs);
-extern int svr4_getcontext(svr4_ucontext_t *c, struct pt_regs *regs);
-
-asmlinkage int solaris_context(struct pt_regs *regs)
-{
- switch ((unsigned)regs->u_regs[UREG_I0]) {
- case 0: /* getcontext */
- return svr4_getcontext((svr4_ucontext_t *)(long)(u32)regs->u_regs[UREG_I1], regs);
- case 1: /* setcontext */
- return svr4_setcontext((svr4_ucontext_t *)(long)(u32)regs->u_regs[UREG_I1], regs);
- default:
- return -EINVAL;
-
- }
-}
-
-asmlinkage int solaris_sigaltstack(u32 ss, u32 oss)
-{
-/* XXX Implement this soon */
- return 0;
-}
diff --git a/arch/sparc64/solaris/signal.h b/arch/sparc64/solaris/signal.h
deleted file mode 100644
index e91570803050..000000000000
--- a/arch/sparc64/solaris/signal.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* $Id: signal.h,v 1.3 1998/04/12 06:20:33 davem Exp $
- * signal.h: Signal emulation for Solaris
- *
- * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#define SOLARIS_SIGHUP 1
-#define SOLARIS_SIGINT 2
-#define SOLARIS_SIGQUIT 3
-#define SOLARIS_SIGILL 4
-#define SOLARIS_SIGTRAP 5
-#define SOLARIS_SIGIOT 6
-#define SOLARIS_SIGEMT 7
-#define SOLARIS_SIGFPE 8
-#define SOLARIS_SIGKILL 9
-#define SOLARIS_SIGBUS 10
-#define SOLARIS_SIGSEGV 11
-#define SOLARIS_SIGSYS 12
-#define SOLARIS_SIGPIPE 13
-#define SOLARIS_SIGALRM 14
-#define SOLARIS_SIGTERM 15
-#define SOLARIS_SIGUSR1 16
-#define SOLARIS_SIGUSR2 17
-#define SOLARIS_SIGCLD 18
-#define SOLARIS_SIGPWR 19
-#define SOLARIS_SIGWINCH 20
-#define SOLARIS_SIGURG 21
-#define SOLARIS_SIGPOLL 22
-#define SOLARIS_SIGSTOP 23
-#define SOLARIS_SIGTSTP 24
-#define SOLARIS_SIGCONT 25
-#define SOLARIS_SIGTTIN 26
-#define SOLARIS_SIGTTOU 27
-#define SOLARIS_SIGVTALRM 28
-#define SOLARIS_SIGPROF 29
-#define SOLARIS_SIGXCPU 30
-#define SOLARIS_SIGXFSZ 31
-#define SOLARIS_SIGWAITING 32
-#define SOLARIS_SIGLWP 33
-#define SOLARIS_SIGFREEZE 34
-#define SOLARIS_SIGTHAW 35
-#define SOLARIS_SIGCANCEL 36
-#define SOLARIS_SIGRTMIN 37
-#define SOLARIS_SIGRTMAX 44
-#define SOLARIS_NSIGNALS 44
-
-
-#define SOLARIS_SA_ONSTACK 1
-#define SOLARIS_SA_RESETHAND 2
-#define SOLARIS_SA_RESTART 4
-#define SOLARIS_SA_SIGINFO 8
-#define SOLARIS_SA_NODEFER 16
-#define SOLARIS_SA_NOCLDWAIT 0x10000
-#define SOLARIS_SA_NOCLDSTOP 0x20000
-
-struct sol_siginfo {
- int si_signo;
- int si_code;
- int si_errno;
- union {
- char pad[128-3*sizeof(int)];
- struct {
- s32 _pid;
- union {
- struct {
- s32 _uid;
- s32 _value;
- } _kill;
- struct {
- s32 _utime;
- int _status;
- s32 _stime;
- } _cld;
- } _pdata;
- } _proc;
- struct { /* SIGSEGV, SIGBUS, SIGILL and SIGFPE */
- u32 _addr;
- int _trapno;
- } _fault;
- struct { /* SIGPOLL, SIGXFSZ */
- int _fd;
- s32 _band;
- } _file;
- } _data;
-};
-
-#define SOLARIS_WUNTRACED 0x04
-#define SOLARIS_WNOHANG 0x40
-#define SOLARIS_WEXITED 0x01
-#define SOLARIS_WTRAPPED 0x02
-#define SOLARIS_WSTOPPED WUNTRACED
-#define SOLARIS_WCONTINUED 0x08
-#define SOLARIS_WNOWAIT 0x80
-
-#define SOLARIS_TRAP_BRKPT 1
-#define SOLARIS_TRAP_TRACE 2
-#define SOLARIS_CLD_EXITED 1
-#define SOLARIS_CLD_KILLED 2
-#define SOLARIS_CLD_DUMPED 3
-#define SOLARIS_CLD_TRAPPED 4
-#define SOLARIS_CLD_STOPPED 5
-#define SOLARIS_CLD_CONTINUED 6
-#define SOLARIS_POLL_IN 1
-#define SOLARIS_POLL_OUT 2
-#define SOLARIS_POLL_MSG 3
-#define SOLARIS_POLL_ERR 4
-#define SOLARIS_POLL_PRI 5
-#define SOLARIS_POLL_HUP 6
diff --git a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c
deleted file mode 100644
index cc69847cf240..000000000000
--- a/arch/sparc64/solaris/socket.c
+++ /dev/null
@@ -1,461 +0,0 @@
-/* $Id: socket.c,v 1.6 2002/02/08 03:57:14 davem Exp $
- * socket.c: Socket syscall emulation for Solaris 2.6+
- *
- * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
- *
- * 1999-08-19 Fixed socketpair code
- * Jason Rappleye (rappleye@ccr.buffalo.edu)
- */
-
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/socket.h>
-#include <linux/file.h>
-#include <linux/net.h>
-#include <linux/compat.h>
-#include <net/compat.h>
-#include <net/sock.h>
-
-#include <asm/uaccess.h>
-#include <asm/string.h>
-#include <asm/oplib.h>
-#include <asm/idprom.h>
-
-#include "conv.h"
-
-#define SOCK_SOL_STREAM 2
-#define SOCK_SOL_DGRAM 1
-#define SOCK_SOL_RAW 4
-#define SOCK_SOL_RDM 5
-#define SOCK_SOL_SEQPACKET 6
-
-#define SOL_SO_SNDLOWAT 0x1003
-#define SOL_SO_RCVLOWAT 0x1004
-#define SOL_SO_SNDTIMEO 0x1005
-#define SOL_SO_RCVTIMEO 0x1006
-#define SOL_SO_STATE 0x2000
-
-#define SOL_SS_NDELAY 0x040
-#define SOL_SS_NONBLOCK 0x080
-#define SOL_SS_ASYNC 0x100
-
-#define SO_STATE 0x000e
-
-static int socket_check(int family, int type)
-{
- if (family != PF_UNIX && family != PF_INET)
- return -ESOCKTNOSUPPORT;
- switch (type) {
- case SOCK_SOL_STREAM: type = SOCK_STREAM; break;
- case SOCK_SOL_DGRAM: type = SOCK_DGRAM; break;
- case SOCK_SOL_RAW: type = SOCK_RAW; break;
- case SOCK_SOL_RDM: type = SOCK_RDM; break;
- case SOCK_SOL_SEQPACKET: type = SOCK_SEQPACKET; break;
- default: return -EINVAL;
- }
- return type;
-}
-
-static int solaris_to_linux_sockopt(int optname)
-{
- switch (optname) {
- case SOL_SO_SNDLOWAT: optname = SO_SNDLOWAT; break;
- case SOL_SO_RCVLOWAT: optname = SO_RCVLOWAT; break;
- case SOL_SO_SNDTIMEO: optname = SO_SNDTIMEO; break;
- case SOL_SO_RCVTIMEO: optname = SO_RCVTIMEO; break;
- case SOL_SO_STATE: optname = SO_STATE; break;
- };
-
- return optname;
-}
-
-asmlinkage int solaris_socket(int family, int type, int protocol)
-{
- int (*sys_socket)(int, int, int) =
- (int (*)(int, int, int))SYS(socket);
-
- type = socket_check (family, type);
- if (type < 0) return type;
- return sys_socket(family, type, protocol);
-}
-
-asmlinkage int solaris_socketpair(int *usockvec)
-{
- int (*sys_socketpair)(int, int, int, int *) =
- (int (*)(int, int, int, int *))SYS(socketpair);
-
- /* solaris socketpair really only takes one arg at the syscall
- * level, int * usockvec. The libs apparently take care of
- * making sure that family==AF_UNIX and type==SOCK_STREAM. The
- * pointer we really want ends up residing in the first (and
- * supposedly only) argument.
- */
-
- return sys_socketpair(AF_UNIX, SOCK_STREAM, 0, (int *)usockvec);
-}
-
-asmlinkage int solaris_bind(int fd, struct sockaddr *addr, int addrlen)
-{
- int (*sys_bind)(int, struct sockaddr *, int) =
- (int (*)(int, struct sockaddr *, int))SUNOS(104);
-
- return sys_bind(fd, addr, addrlen);
-}
-
-asmlinkage int solaris_setsockopt(int fd, int level, int optname, u32 optval, int optlen)
-{
- int (*sunos_setsockopt)(int, int, int, u32, int) =
- (int (*)(int, int, int, u32, int))SUNOS(105);
-
- optname = solaris_to_linux_sockopt(optname);
- if (optname < 0)
- return optname;
- if (optname == SO_STATE)
- return 0;
-
- return sunos_setsockopt(fd, level, optname, optval, optlen);
-}
-
-asmlinkage int solaris_getsockopt(int fd, int level, int optname, u32 optval, u32 optlen)
-{
- int (*sunos_getsockopt)(int, int, int, u32, u32) =
- (int (*)(int, int, int, u32, u32))SUNOS(118);
-
- optname = solaris_to_linux_sockopt(optname);
- if (optname < 0)
- return optname;
-
- if (optname == SO_STATE)
- optname = SOL_SO_STATE;
-
- return sunos_getsockopt(fd, level, optname, optval, optlen);
-}
-
-asmlinkage int solaris_connect(int fd, struct sockaddr __user *addr, int addrlen)
-{
- int (*sys_connect)(int, struct sockaddr __user *, int) =
- (int (*)(int, struct sockaddr __user *, int))SYS(connect);
-
- return sys_connect(fd, addr, addrlen);
-}
-
-asmlinkage int solaris_accept(int fd, struct sockaddr __user *addr, int __user *addrlen)
-{
- int (*sys_accept)(int, struct sockaddr __user *, int __user *) =
- (int (*)(int, struct sockaddr __user *, int __user *))SYS(accept);
-
- return sys_accept(fd, addr, addrlen);
-}
-
-asmlinkage int solaris_listen(int fd, int backlog)
-{
- int (*sys_listen)(int, int) =
- (int (*)(int, int))SUNOS(106);
-
- return sys_listen(fd, backlog);
-}
-
-asmlinkage int solaris_shutdown(int fd, int how)
-{
- int (*sys_shutdown)(int, int) =
- (int (*)(int, int))SYS(shutdown);
-
- return sys_shutdown(fd, how);
-}
-
-#define MSG_SOL_OOB 0x1
-#define MSG_SOL_PEEK 0x2
-#define MSG_SOL_DONTROUTE 0x4
-#define MSG_SOL_EOR 0x8
-#define MSG_SOL_CTRUNC 0x10
-#define MSG_SOL_TRUNC 0x20
-#define MSG_SOL_WAITALL 0x40
-#define MSG_SOL_DONTWAIT 0x80
-
-static int solaris_to_linux_msgflags(int flags)
-{
- int fl = flags & (MSG_OOB|MSG_PEEK|MSG_DONTROUTE);
-
- if (flags & MSG_SOL_EOR) fl |= MSG_EOR;
- if (flags & MSG_SOL_CTRUNC) fl |= MSG_CTRUNC;
- if (flags & MSG_SOL_TRUNC) fl |= MSG_TRUNC;
- if (flags & MSG_SOL_WAITALL) fl |= MSG_WAITALL;
- if (flags & MSG_SOL_DONTWAIT) fl |= MSG_DONTWAIT;
- return fl;
-}
-
-static int linux_to_solaris_msgflags(int flags)
-{
- int fl = flags & (MSG_OOB|MSG_PEEK|MSG_DONTROUTE);
-
- if (flags & MSG_EOR) fl |= MSG_SOL_EOR;
- if (flags & MSG_CTRUNC) fl |= MSG_SOL_CTRUNC;
- if (flags & MSG_TRUNC) fl |= MSG_SOL_TRUNC;
- if (flags & MSG_WAITALL) fl |= MSG_SOL_WAITALL;
- if (flags & MSG_DONTWAIT) fl |= MSG_SOL_DONTWAIT;
- return fl;
-}
-
-asmlinkage int solaris_recvfrom(int s, char __user *buf, int len, int flags, u32 from, u32 fromlen)
-{
- int (*sys_recvfrom)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *) =
- (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(recvfrom);
-
- return sys_recvfrom(s, buf, len, solaris_to_linux_msgflags(flags), A(from), A(fromlen));
-}
-
-asmlinkage int solaris_recv(int s, char __user *buf, int len, int flags)
-{
- int (*sys_recvfrom)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *) =
- (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(recvfrom);
-
- return sys_recvfrom(s, buf, len, solaris_to_linux_msgflags(flags), NULL, NULL);
-}
-
-asmlinkage int solaris_sendto(int s, char __user *buf, int len, int flags, u32 to, u32 tolen)
-{
- int (*sys_sendto)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *) =
- (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(sendto);
-
- return sys_sendto(s, buf, len, solaris_to_linux_msgflags(flags), A(to), A(tolen));
-}
-
-asmlinkage int solaris_send(int s, char *buf, int len, int flags)
-{
- int (*sys_sendto)(int, void *, size_t, unsigned, struct sockaddr *, int *) =
- (int (*)(int, void *, size_t, unsigned, struct sockaddr *, int *))SYS(sendto);
-
- return sys_sendto(s, buf, len, solaris_to_linux_msgflags(flags), NULL, NULL);
-}
-
-asmlinkage int solaris_getpeername(int fd, struct sockaddr *addr, int *addrlen)
-{
- int (*sys_getpeername)(int, struct sockaddr *, int *) =
- (int (*)(int, struct sockaddr *, int *))SYS(getpeername);
-
- return sys_getpeername(fd, addr, addrlen);
-}
-
-asmlinkage int solaris_getsockname(int fd, struct sockaddr *addr, int *addrlen)
-{
- int (*sys_getsockname)(int, struct sockaddr *, int *) =
- (int (*)(int, struct sockaddr *, int *))SYS(getsockname);
-
- return sys_getsockname(fd, addr, addrlen);
-}
-
-/* XXX This really belongs in some header file... -DaveM */
-#define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
- 16 for IP, 16 for IPX,
- 24 for IPv6,
- about 80 for AX.25 */
-
-struct sol_nmsghdr {
- u32 msg_name;
- int msg_namelen;
- u32 msg_iov;
- u32 msg_iovlen;
- u32 msg_control;
- u32 msg_controllen;
- u32 msg_flags;
-};
-
-struct sol_cmsghdr {
- u32 cmsg_len;
- int cmsg_level;
- int cmsg_type;
- unsigned char cmsg_data[0];
-};
-
-static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
- struct sol_nmsghdr __user *umsg)
-{
- u32 tmp1, tmp2, tmp3;
- int err;
-
- err = get_user(tmp1, &umsg->msg_name);
- err |= __get_user(tmp2, &umsg->msg_iov);
- err |= __get_user(tmp3, &umsg->msg_control);
- if (err)
- return -EFAULT;
-
- kmsg->msg_name = A(tmp1);
- kmsg->msg_iov = A(tmp2);
- kmsg->msg_control = A(tmp3);
-
- err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
- err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
- err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
-
- kmsg->msg_flags = solaris_to_linux_msgflags(kmsg->msg_flags);
-
- return err;
-}
-
-asmlinkage int solaris_sendmsg(int fd, struct sol_nmsghdr __user *user_msg, unsigned user_flags)
-{
- struct socket *sock;
- char address[MAX_SOCK_ADDR];
- struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
- unsigned char ctl[sizeof(struct cmsghdr) + 20];
- unsigned char *ctl_buf = ctl;
- struct msghdr msg_sys;
- int err, ctl_len, iov_size, total_len;
-
- err = -EFAULT;
- if (msghdr_from_user32_to_kern(&msg_sys, user_msg))
- goto out;
-
- sock = sockfd_lookup(fd, &err);
- if (!sock)
- goto out;
-
- /* do not move before msg_sys is valid */
- err = -EMSGSIZE;
- if (msg_sys.msg_iovlen > UIO_MAXIOV)
- goto out_put;
-
- /* Check whether to allocate the iovec area*/
- err = -ENOMEM;
- iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
- if (msg_sys.msg_iovlen > UIO_FASTIOV) {
- iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
- if (!iov)
- goto out_put;
- }
-
- err = verify_compat_iovec(&msg_sys, iov, address, VERIFY_READ);
- if (err < 0)
- goto out_freeiov;
- total_len = err;
-
- err = -ENOBUFS;
- if (msg_sys.msg_controllen > INT_MAX)
- goto out_freeiov;
-
- ctl_len = msg_sys.msg_controllen;
- if (ctl_len) {
- struct sol_cmsghdr __user *ucmsg = msg_sys.msg_control;
- unsigned long *kcmsg;
- compat_size_t cmlen;
-
- err = -EINVAL;
- if (ctl_len <= sizeof(compat_size_t))
- goto out_freeiov;
-
- if (ctl_len > sizeof(ctl)) {
- err = -ENOBUFS;
- ctl_buf = kmalloc(ctl_len, GFP_KERNEL);
- if (!ctl_buf)
- goto out_freeiov;
- }
- __get_user(cmlen, &ucmsg->cmsg_len);
- kcmsg = (unsigned long *) ctl_buf;
- *kcmsg++ = (unsigned long)cmlen;
- err = -EFAULT;
- if (copy_from_user(kcmsg, &ucmsg->cmsg_level,
- ctl_len - sizeof(compat_size_t)))
- goto out_freectl;
- msg_sys.msg_control = ctl_buf;
- }
- msg_sys.msg_flags = solaris_to_linux_msgflags(user_flags);
-
- if (sock->file->f_flags & O_NONBLOCK)
- msg_sys.msg_flags |= MSG_DONTWAIT;
- err = sock_sendmsg(sock, &msg_sys, total_len);
-
-out_freectl:
- if (ctl_buf != ctl)
- sock_kfree_s(sock->sk, ctl_buf, ctl_len);
-out_freeiov:
- if (iov != iovstack)
- sock_kfree_s(sock->sk, iov, iov_size);
-out_put:
- sockfd_put(sock);
-out:
- return err;
-}
-
-asmlinkage int solaris_recvmsg(int fd, struct sol_nmsghdr __user *user_msg, unsigned int user_flags)
-{
- struct socket *sock;
- struct iovec iovstack[UIO_FASTIOV];
- struct iovec *iov = iovstack;
- struct msghdr msg_sys;
- unsigned long cmsg_ptr;
- int err, iov_size, total_len, len;
-
- /* kernel mode address */
- char addr[MAX_SOCK_ADDR];
-
- /* user mode address pointers */
- struct sockaddr __user *uaddr;
- int __user *uaddr_len;
-
- if (msghdr_from_user32_to_kern(&msg_sys, user_msg))
- return -EFAULT;
-
- sock = sockfd_lookup(fd, &err);
- if (!sock)
- goto out;
-
- err = -EMSGSIZE;
- if (msg_sys.msg_iovlen > UIO_MAXIOV)
- goto out_put;
-
- /* Check whether to allocate the iovec area*/
- err = -ENOMEM;
- iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
- if (msg_sys.msg_iovlen > UIO_FASTIOV) {
- iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
- if (!iov)
- goto out_put;
- }
-
- /*
- * Save the user-mode address (verify_iovec will change the
- * kernel msghdr to use the kernel address space)
- */
-
- uaddr = (void __user *) msg_sys.msg_name;
- uaddr_len = &user_msg->msg_namelen;
- err = verify_compat_iovec(&msg_sys, iov, addr, VERIFY_WRITE);
- if (err < 0)
- goto out_freeiov;
- total_len = err;
-
- cmsg_ptr = (unsigned long) msg_sys.msg_control;
- msg_sys.msg_flags = MSG_CMSG_COMPAT;
-
- if (sock->file->f_flags & O_NONBLOCK)
- user_flags |= MSG_DONTWAIT;
-
- err = sock_recvmsg(sock, &msg_sys, total_len, user_flags);
- if(err < 0)
- goto out_freeiov;
-
- len = err;
-
- if (uaddr != NULL) {
- err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len);
- if (err < 0)
- goto out_freeiov;
- }
- err = __put_user(linux_to_solaris_msgflags(msg_sys.msg_flags), &user_msg->msg_flags);
- if (err)
- goto out_freeiov;
- err = __put_user((unsigned long)msg_sys.msg_control - cmsg_ptr,
- &user_msg->msg_controllen);
- if (err)
- goto out_freeiov;
- err = len;
-
-out_freeiov:
- if (iov != iovstack)
- sock_kfree_s(sock->sk, iov, iov_size);
-out_put:
- sockfd_put(sock);
-out:
- return err;
-}
diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c
deleted file mode 100644
index 7736411f244f..000000000000
--- a/arch/sparc64/solaris/socksys.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* $Id: socksys.c,v 1.21 2002/02/08 03:57:14 davem Exp $
- * socksys.c: /dev/inet/ stuff for Solaris emulation.
- *
- * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 1997, 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
- * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
- */
-
-/*
- * Dave, _please_ give me specifications on this fscking mess so that I
- * could at least get it into the state when it wouldn't screw the rest of
- * the kernel over. socksys.c and timod.c _stink_ and we are not talking
- * H2S here, it's isopropilmercaptan in concentrations way over LD50. -- AV
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/ioctl.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/slab.h>
-#include <linux/syscalls.h>
-#include <linux/in.h>
-
-#include <net/sock.h>
-
-#include <asm/uaccess.h>
-#include <asm/termios.h>
-
-#include "conv.h"
-#include "socksys.h"
-
-static int af_inet_protocols[] = {
-IPPROTO_ICMP, IPPROTO_ICMP, IPPROTO_IGMP, IPPROTO_IPIP, IPPROTO_TCP,
-IPPROTO_EGP, IPPROTO_PUP, IPPROTO_UDP, IPPROTO_IDP, IPPROTO_RAW,
-0, 0, 0, 0, 0, 0,
-};
-
-#ifndef DEBUG_SOLARIS_KMALLOC
-
-#define mykmalloc kmalloc
-#define mykfree kfree
-
-#else
-
-extern void * mykmalloc(size_t s, gfp_t gfp);
-extern void mykfree(void *);
-
-#endif
-
-static unsigned int (*sock_poll)(struct file *, poll_table *);
-
-static struct file_operations socksys_file_ops = {
- /* Currently empty */
-};
-
-static int socksys_open(struct inode * inode, struct file * filp)
-{
- int family, type, protocol, fd;
- struct dentry *dentry;
- int (*sys_socket)(int,int,int) =
- (int (*)(int,int,int))SUNOS(97);
- struct sol_socket_struct * sock;
-
- family = ((iminor(inode) >> 4) & 0xf);
- switch (family) {
- case AF_UNIX:
- type = SOCK_STREAM;
- protocol = 0;
- break;
- case AF_INET:
- protocol = af_inet_protocols[iminor(inode) & 0xf];
- switch (protocol) {
- case IPPROTO_TCP: type = SOCK_STREAM; break;
- case IPPROTO_UDP: type = SOCK_DGRAM; break;
- default: type = SOCK_RAW; break;
- }
- break;
- default:
- type = SOCK_RAW;
- protocol = 0;
- break;
- }
-
- fd = sys_socket(family, type, protocol);
- if (fd < 0)
- return fd;
- /*
- * N.B. The following operations are not legal!
- *
- * No shit. WTF is it supposed to do, anyway?
- *
- * Try instead:
- * d_delete(filp->f_path.dentry), then d_instantiate with sock inode
- */
- dentry = filp->f_path.dentry;
- filp->f_path.dentry = dget(fcheck(fd)->f_path.dentry);
- filp->f_path.dentry->d_inode->i_rdev = inode->i_rdev;
- filp->f_path.dentry->d_inode->i_flock = inode->i_flock;
- SOCKET_I(filp->f_path.dentry->d_inode)->file = filp;
- filp->f_op = &socksys_file_ops;
- sock = (struct sol_socket_struct*)
- mykmalloc(sizeof(struct sol_socket_struct), GFP_KERNEL);
- if (!sock) return -ENOMEM;
- SOLDD(("sock=%016lx(%016lx)\n", sock, filp));
- sock->magic = SOLARIS_SOCKET_MAGIC;
- sock->modcount = 0;
- sock->state = TS_UNBND;
- sock->offset = 0;
- sock->pfirst = sock->plast = NULL;
- filp->private_data = sock;
- SOLDD(("filp->private_data %016lx\n", filp->private_data));
-
- sys_close(fd);
- dput(dentry);
- return 0;
-}
-
-static int socksys_release(struct inode * inode, struct file * filp)
-{
- struct sol_socket_struct * sock;
- struct T_primsg *it;
-
- /* XXX: check this */
- sock = (struct sol_socket_struct *)filp->private_data;
- SOLDD(("sock release %016lx(%016lx)\n", sock, filp));
- it = sock->pfirst;
- while (it) {
- struct T_primsg *next = it->next;
-
- SOLDD(("socksys_release %016lx->%016lx\n", it, next));
- mykfree((char*)it);
- it = next;
- }
- filp->private_data = NULL;
- SOLDD(("socksys_release %016lx\n", sock));
- mykfree((char*)sock);
- return 0;
-}
-
-static unsigned int socksys_poll(struct file * filp, poll_table * wait)
-{
- struct inode *ino;
- unsigned int mask = 0;
-
- ino=filp->f_path.dentry->d_inode;
- if (ino && S_ISSOCK(ino->i_mode)) {
- struct sol_socket_struct *sock;
- sock = (struct sol_socket_struct*)filp->private_data;
- if (sock && sock->pfirst) {
- mask |= POLLIN | POLLRDNORM;
- if (sock->pfirst->pri == MSG_HIPRI)
- mask |= POLLPRI;
- }
- }
- if (sock_poll)
- mask |= (*sock_poll)(filp, wait);
- return mask;
-}
-
-static const struct file_operations socksys_fops = {
- .open = socksys_open,
- .release = socksys_release,
-};
-
-int __init init_socksys(void)
-{
- int ret;
- struct file * file;
- int (*sys_socket)(int,int,int) =
- (int (*)(int,int,int))SUNOS(97);
- int (*sys_close)(unsigned int) =
- (int (*)(unsigned int))SYS(close);
-
- ret = register_chrdev (30, "socksys", &socksys_fops);
- if (ret < 0) {
- printk ("Couldn't register socksys character device\n");
- return ret;
- }
- ret = sys_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (ret < 0) {
- printk ("Couldn't create socket\n");
- return ret;
- }
-
- file = fcheck(ret);
- /* N.B. Is this valid? Suppose the f_ops are in a module ... */
- socksys_file_ops = *file->f_op;
- sys_close(ret);
- sock_poll = socksys_file_ops.poll;
- socksys_file_ops.poll = socksys_poll;
- socksys_file_ops.release = socksys_release;
- return 0;
-}
-
-void __exit cleanup_socksys(void)
-{
- unregister_chrdev(30, "socksys");
-}
diff --git a/arch/sparc64/solaris/socksys.h b/arch/sparc64/solaris/socksys.h
deleted file mode 100644
index 5d1b78ec1600..000000000000
--- a/arch/sparc64/solaris/socksys.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/* $Id: socksys.h,v 1.2 1998/03/26 08:46:07 jj Exp $
- * socksys.h: Definitions for STREAMS modules emulation code.
- *
- * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
- */
-
-#define MSG_HIPRI 0x01
-#define MSG_ANY 0x02
-#define MSG_BAND 0x04
-
-#define MORECTL 1
-#define MOREDATA 2
-
-#define TBADADDR 1
-#define TBADOPT 2
-#define TACCES 3
-#define TBADF 4
-#define TNOADDR 5
-#define TOUTSTATE 6
-#define TBADSEQ 7
-#define TSYSERR 8
-#define TLOOK 9
-#define TBADDATA 10
-#define TBUFOVFLW 11
-#define TFLOW 12
-#define TNODATA 13
-#define TNODIS 14
-#define TNOUDERR 15
-#define TBADFLAG 16
-#define TNOREL 17
-#define TNOTSUPPORT 18
-#define TSTATECHNG 19
-
-#define T_CONN_REQ 0
-#define T_CONN_RES 1
-#define T_DISCON_REQ 2
-#define T_DATA_REQ 3
-#define T_EXDATA_REQ 4
-#define T_INFO_REQ 5
-#define T_BIND_REQ 6
-#define T_UNBIND_REQ 7
-#define T_UNITDATA_REQ 8
-#define T_OPTMGMT_REQ 9
-#define T_ORDREL_REQ 10
-
-#define T_CONN_IND 11
-#define T_CONN_CON 12
-#define T_DISCON_IND 13
-#define T_DATA_IND 14
-#define T_EXDATA_IND 15
-#define T_INFO_ACK 16
-#define T_BIND_ACK 17
-#define T_ERROR_ACK 18
-#define T_OK_ACK 19
-#define T_UNITDATA_IND 20
-#define T_UDERROR_IND 21
-#define T_OPTMGMT_ACK 22
-#define T_ORDREL_IND 23
-
-#define T_NEGOTIATE 0x0004
-#define T_FAILURE 0x0040
-
-#define TS_UNBND 0 /* unbound */
-#define TS_WACK_BREQ 1 /* waiting for T_BIND_REQ ack */
-#define TS_WACK_UREQ 2 /* waiting for T_UNBIND_REQ ack */
-#define TS_IDLE 3 /* idle */
-#define TS_WACK_OPTREQ 4 /* waiting for T_OPTMGMT_REQ ack */
-#define TS_WACK_CREQ 5 /* waiting for T_CONN_REQ ack */
-#define TS_WCON_CREQ 6 /* waiting for T_CONN_REQ confirmation */
-#define TS_WRES_CIND 7 /* waiting for T_CONN_IND */
-#define TS_WACK_CRES 8 /* waiting for T_CONN_RES ack */
-#define TS_DATA_XFER 9 /* data transfer */
-#define TS_WIND_ORDREL 10 /* releasing read but not write */
-#define TS_WREQ_ORDREL 11 /* wait to release write but not read */
-#define TS_WACK_DREQ6 12 /* waiting for T_DISCON_REQ ack */
-#define TS_WACK_DREQ7 13 /* waiting for T_DISCON_REQ ack */
-#define TS_WACK_DREQ9 14 /* waiting for T_DISCON_REQ ack */
-#define TS_WACK_DREQ10 15 /* waiting for T_DISCON_REQ ack */
-#define TS_WACK_DREQ11 16 /* waiting for T_DISCON_REQ ack */
-#define TS_NOSTATES 17
-
-struct T_conn_req {
- s32 PRIM_type;
- s32 DEST_length;
- s32 DEST_offset;
- s32 OPT_length;
- s32 OPT_offset;
-};
-
-struct T_bind_req {
- s32 PRIM_type;
- s32 ADDR_length;
- s32 ADDR_offset;
- u32 CONIND_number;
-};
-
-struct T_unitdata_req {
- s32 PRIM_type;
- s32 DEST_length;
- s32 DEST_offset;
- s32 OPT_length;
- s32 OPT_offset;
-};
-
-struct T_optmgmt_req {
- s32 PRIM_type;
- s32 OPT_length;
- s32 OPT_offset;
- s32 MGMT_flags;
-};
-
-struct T_bind_ack {
- s32 PRIM_type;
- s32 ADDR_length;
- s32 ADDR_offset;
- u32 CONIND_number;
-};
-
-struct T_error_ack {
- s32 PRIM_type;
- s32 ERROR_prim;
- s32 TLI_error;
- s32 UNIX_error;
-};
-
-struct T_ok_ack {
- s32 PRIM_type;
- s32 CORRECT_prim;
-};
-
-struct T_conn_ind {
- s32 PRIM_type;
- s32 SRC_length;
- s32 SRC_offset;
- s32 OPT_length;
- s32 OPT_offset;
- s32 SEQ_number;
-};
-
-struct T_conn_con {
- s32 PRIM_type;
- s32 RES_length;
- s32 RES_offset;
- s32 OPT_length;
- s32 OPT_offset;
-};
-
-struct T_discon_ind {
- s32 PRIM_type;
- s32 DISCON_reason;
- s32 SEQ_number;
-};
-
-struct T_unitdata_ind {
- s32 PRIM_type;
- s32 SRC_length;
- s32 SRC_offset;
- s32 OPT_length;
- s32 OPT_offset;
-};
-
-struct T_optmgmt_ack {
- s32 PRIM_type;
- s32 OPT_length;
- s32 OPT_offset;
- s32 MGMT_flags;
-};
-
-struct opthdr {
- s32 level;
- s32 name;
- s32 len;
- char value[0];
-};
-
-struct T_primsg {
- struct T_primsg *next;
- unsigned char pri;
- unsigned char band;
- int length;
- s32 type;
-};
-
-struct strbuf {
- s32 maxlen;
- s32 len;
- u32 buf;
-} ;
-
-/* Constants used by STREAMS modules emulation code */
-
-typedef char sol_module;
-
-#define MAX_NR_STREAM_MODULES 16
-
-/* Private data structure assigned to sockets. */
-
-struct sol_socket_struct {
- int magic;
- int modcount;
- sol_module module[MAX_NR_STREAM_MODULES];
- long state;
- int offset;
- struct T_primsg *pfirst, *plast;
-};
-
-#define SOLARIS_SOCKET_MAGIC 0xADDED
-
diff --git a/arch/sparc64/solaris/systbl.S b/arch/sparc64/solaris/systbl.S
deleted file mode 100644
index 7043ca18caf9..000000000000
--- a/arch/sparc64/solaris/systbl.S
+++ /dev/null
@@ -1,285 +0,0 @@
-/* $Id: systbl.S,v 1.11 2000/03/13 21:57:35 davem Exp $
- * systbl.S: System call entry point table for Solaris compatibility.
- *
- * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
- */
-
-#include <asm/unistd.h>
-
-/* Fall back to sys_call_table32 entry */
-#define CHAIN(name) __NR_##name
-
-/* Pass pt_regs pointer as first argument */
-#define REGS(name) name+1
-
-/* Hack till all be implemented */
-#define solaris_getpmsg solaris_unimplemented
-#define solaris_hrtsys solaris_unimplemented
-#define solaris_msgsys solaris_unimplemented
-#define solaris_putpmsg solaris_unimplemented
-#define solaris_semsys solaris_unimplemented
-
- .data
- .globl solaris_sys_table
-solaris_sys_table:
- .word solaris_unimplemented /* nosys 0 */
- .word CHAIN(exit) /* exit d 1 */
- .word CHAIN(fork) /* fork 2 */
- .word CHAIN(read) /* read dpd 3 */
- .word CHAIN(write) /* write dpd 4 */
- .word solaris_open /* open soo 5 */
- .word CHAIN(close) /* close d 6 */
- .word solaris_wait /* wait xxx 7 */
- .word CHAIN(creat) /* creat so 8 */
- .word CHAIN(link) /* link ss 9 */
- .word CHAIN(unlink) /* unlink s 10 */
- .word solaris_unimplemented /* exec sxx 11 */
- .word CHAIN(chdir) /* chdir s 12 */
- .word CHAIN(time) /* time 13 */
- .word solaris_mknod /* mknod sox 14 */
- .word CHAIN(chmod) /* chmod so 15 */
- .word CHAIN(chown) /* chown sdd 16 */
- .word solaris_brk /* brk/break x 17 */
- .word solaris_stat /* stat sp 18 */
- .word CHAIN(lseek) /* seek/lseek ddd 19 */
- .word solaris_getpid /* getpid 20 */
- .word solaris_unimplemented /* mount 21 */
- .word CHAIN(umount) /* umount s 22 */
- .word CHAIN(setuid) /* setuid d 23 */
- .word solaris_getuid /* getuid 24 */
- .word CHAIN(stime) /* stime d 25 */
-#if 0
- .word solaris_ptrace /* ptrace xdxx 26 */
-#else
- .word CHAIN(ptrace) /* ptrace xdxx 26 */
-#endif
- .word CHAIN(alarm) /* alarm d 27 */
- .word solaris_fstat /* fstat dp 28 */
- .word CHAIN(pause) /* pause 29 */
- .word CHAIN(utime) /* utime xx 30 */
- .word solaris_unimplemented /* stty 31 */
- .word solaris_unimplemented /* gtty 32 */
- .word solaris_access /* access so 33 */
- .word CHAIN(nice) /* nice d 34 */
- .word solaris_statfs /* statfs spdd 35 */
- .word CHAIN(sync) /* sync 36 */
- .word solaris_kill /* kill dd 37 */
- .word solaris_fstatfs /* fstatfs dpdd 38 */
- .word solaris_procids /* pgrpsys ddd 39 */
- .word solaris_unimplemented /* xenix 40 */
- .word CHAIN(dup) /* dup d 41 */
- .word CHAIN(pipe) /* pipe 42 */
- .word CHAIN(times) /* times p 43 */
- .word 44 /*CHAIN(profil)*/ /* prof xxxx 44 */
- .word solaris_unimplemented /* lock/plock 45 */
- .word CHAIN(setgid) /* setgid d 46 */
- .word solaris_getgid /* getgid 47 */
- .word solaris_sigfunc /* sigfunc xx 48 */
- .word REGS(solaris_msgsys) /* msgsys dxddd 49 */
- .word solaris_unimplemented /* syssun/3b 50 */
- .word CHAIN(acct) /* acct/sysacct x 51 */
- .word solaris_shmsys /* shmsys ddxo 52 */
- .word REGS(solaris_semsys) /* semsys dddx 53 */
- .word solaris_ioctl /* ioctl dxx 54 */
- .word solaris_unimplemented /* uadmin xxx 55 */
- .word solaris_unimplemented /* reserved:exch 56 */
- .word solaris_utssys /* utssys x 57 */
- .word CHAIN(fsync) /* fsync d 58 */
- .word CHAIN(execve) /* execv spp 59 */
- .word CHAIN(umask) /* umask o 60 */
- .word CHAIN(chroot) /* chroot s 61 */
- .word solaris_fcntl /* fcntl dxx 62 */
- .word solaris_ulimit /* ulimit xx 63 */
- .word solaris_unimplemented /* ? 64 */
- .word solaris_unimplemented /* ? 65 */
- .word solaris_unimplemented /* ? 66 */
- .word solaris_unimplemented /* ? 67 */
- .word solaris_unimplemented /* ? 68 */
- .word solaris_unimplemented /* ? 69 */
- .word solaris_unimplemented /* advfs 70 */
- .word solaris_unimplemented /* unadvfs 71 */
- .word solaris_unimplemented /* rmount 72 */
- .word solaris_unimplemented /* rumount 73 */
- .word solaris_unimplemented /* rfstart 74 */
- .word solaris_unimplemented /* ? 75 */
- .word solaris_unimplemented /* rdebug 76 */
- .word solaris_unimplemented /* rfstop 77 */
- .word solaris_unimplemented /* rfsys 78 */
- .word CHAIN(rmdir) /* rmdir s 79 */
- .word CHAIN(mkdir) /* mkdir so 80 */
- .word CHAIN(getdents) /* getdents dxd 81 */
- .word solaris_unimplemented /* libattach 82 */
- .word solaris_unimplemented /* libdetach 83 */
- .word CHAIN(sysfs) /* sysfs dxx 84 */
- .word solaris_getmsg /* getmsg dxxx 85 */
- .word solaris_putmsg /* putmsg dxxd 86 */
- .word CHAIN(poll) /* poll xdd 87 */
- .word solaris_lstat /* lstat sp 88 */
- .word CHAIN(symlink) /* symlink ss 89 */
- .word CHAIN(readlink) /* readlink spd 90 */
- .word CHAIN(setgroups) /* setgroups dp 91 */
- .word CHAIN(getgroups) /* getgroups dp 92 */
- .word CHAIN(fchmod) /* fchmod do 93 */
- .word CHAIN(fchown) /* fchown ddd 94 */
- .word solaris_sigprocmask /* sigprocmask dxx 95 */
- .word solaris_sigsuspend /* sigsuspend x 96 */
- .word solaris_sigaltstack /* sigaltstack xx 97 */
- .word solaris_sigaction /* sigaction dxx 98 */
- .word solaris_sigpending /* sigpending dd 99 */
- .word REGS(solaris_context) /* context 100 */
- .word solaris_unimplemented /* evsys 101 */
- .word solaris_unimplemented /* evtrapret 102 */
- .word solaris_statvfs /* statvfs sp 103 */
- .word solaris_fstatvfs /* fstatvfs dp 104 */
- .word solaris_unimplemented /* unknown 105 */
- .word solaris_unimplemented /* nfssys 106 */
- .word solaris_waitid /* waitid ddxd 107 */
- .word solaris_unimplemented /* sigsendsys ddd 108 */
- .word REGS(solaris_hrtsys) /* hrtsys xxx 109 */
- .word solaris_unimplemented /* acancel dxd 110 */
- .word solaris_unimplemented /* async 111 */
- .word solaris_unimplemented /* priocntlsys 112 */
- .word solaris_pathconf /* pathconf sd 113 */
- .word CHAIN(mincore) /* mincore d 114 */
- .word solaris_mmap /* mmap xxxxdx 115 */
- .word CHAIN(mprotect) /* mprotect xdx 116 */
- .word CHAIN(munmap) /* munmap xd 117 */
- .word solaris_fpathconf /* fpathconf dd 118 */
- .word CHAIN(fork) /* fork 119 */
- .word solaris_unimplemented /* fchdir d 120 */
- .word CHAIN(readv) /* readv dxd 121 */
- .word CHAIN(writev) /* writev dxd 122 */
- .word solaris_xstat /* xstat dsx 123 */
- .word solaris_lxstat /* lxstat dsx 124 */
- .word solaris_fxstat /* fxstat ddx 125 */
- .word solaris_xmknod /* xmknod dsox 126 */
- .word solaris_unimplemented /* syslocal d 127 */
- .word solaris_setrlimit /* setrlimit dp 128 */
- .word solaris_getrlimit /* getrlimit dp 129 */
- .word CHAIN(chown) /* lchown sdd 130 */
- .word solaris_unimplemented /* memcntl 131 */
- .word solaris_getpmsg /* getpmsg dxxxx 132 */
- .word solaris_putpmsg /* putpmsg dxxdd 133 */
- .word CHAIN(rename) /* rename ss 134 */
- .word solaris_utsname /* uname x 135 */
- .word solaris_unimplemented /* setegid 136 */
- .word solaris_sysconf /* sysconfig d 137 */
- .word solaris_unimplemented /* adjtime 138 */
- .word solaris_sysinfo /* systeminfo dsd 139 */
- .word solaris_unimplemented /* ? 140 */
- .word solaris_unimplemented /* seteuid 141 */
- .word solaris_unimplemented /* ? 142 */
- .word solaris_unimplemented /* ? 143 */
- .word solaris_unimplemented /* secsys dx 144 */
- .word solaris_unimplemented /* filepriv sdxd 145 */
- .word solaris_unimplemented /* procpriv dxd 146 */
- .word solaris_unimplemented /* devstat sdx 147 */
- .word solaris_unimplemented /* aclipc ddddx 148 */
- .word solaris_unimplemented /* fdevstat ddx 149 */
- .word solaris_unimplemented /* flvlfile ddx 150 */
- .word solaris_unimplemented /* lvlfile sdx 151 */
- .word solaris_unimplemented /* ? 152 */
- .word solaris_unimplemented /* fchroot d 153 */
- .word solaris_unimplemented /* lvlproc dx 154 */
- .word solaris_unimplemented /* ? 155 */
- .word solaris_gettimeofday /* gettimeofday x 156 */
- .word CHAIN(getitimer) /* getitimer dx 157 */
- .word CHAIN(setitimer) /* setitimer dxx 158 */
- .word solaris_unimplemented /* lwp-xxx 159 */
- .word solaris_unimplemented /* lwp-xxx 160 */
- .word solaris_unimplemented /* lwp-xxx 161 */
- .word solaris_unimplemented /* lwp-xxx 162 */
- .word solaris_unimplemented /* lwp-xxx 163 */
- .word solaris_unimplemented /* lwp-xxx 164 */
- .word solaris_unimplemented /* lwp-xxx 165 */
- .word solaris_unimplemented /* lwp-xxx 166 */
- .word solaris_unimplemented /* lwp-xxx 167 */
- .word solaris_unimplemented /* lwp-xxx 168 */
- .word solaris_unimplemented /* lwp-xxx 169 */
- .word solaris_unimplemented /* lwp-xxx 170 */
- .word solaris_unimplemented /* lwp-xxx 171 */
- .word solaris_unimplemented /* lwp-xxx 172 */
- .word solaris_pread /* pread dpdd 173 */
- .word solaris_pwrite /* pwrite dpdd 174 */
- .word REGS(solaris_llseek) /* llseek dLd 175 */
- .word solaris_unimplemented /* lwpself 176 */
- .word solaris_unimplemented /* lwpinfo 177 */
- .word solaris_unimplemented /* lwpprivate 178 */
- .word solaris_unimplemented /* processorbind 179 */
- .word solaris_unimplemented /* processorexbind 180 */
- .word solaris_unimplemented /* 181 */
- .word solaris_unimplemented /* sync_mailbox 182 */
- .word solaris_unimplemented /* prepblock 183 */
- .word solaris_unimplemented /* block 184 */
- .word solaris_acl /* acl sddp 185 */
- .word solaris_unimplemented /* unblock 186 */
- .word solaris_unimplemented /* cancelblock 187 */
- .word solaris_unimplemented /* ? 188 */
- .word solaris_unimplemented /* xxxxx 189 */
- .word solaris_unimplemented /* xxxxxe 190 */
- .word solaris_unimplemented /* 191 */
- .word solaris_unimplemented /* 192 */
- .word solaris_unimplemented /* 193 */
- .word solaris_unimplemented /* 194 */
- .word solaris_unimplemented /* 195 */
- .word solaris_unimplemented /* 196 */
- .word solaris_unimplemented /* 197 */
- .word solaris_unimplemented /* 198 */
- .word CHAIN(nanosleep) /* nanosleep dd 199 */
- .word solaris_facl /* facl dddp 200 */
- .word solaris_unimplemented /* 201 */
- .word CHAIN(setreuid) /* setreuid dd 202 */
- .word CHAIN(setregid) /* setregid dd 203 */
- .word solaris_unimplemented /* 204 */
- .word solaris_unimplemented /* 205 */
- .word solaris_unimplemented /* 206 */
- .word solaris_unimplemented /* 207 */
- .word solaris_unimplemented /* 208 */
- .word solaris_unimplemented /* 209 */
- .word solaris_unimplemented /* 210 */
- .word solaris_unimplemented /* 211 */
- .word solaris_unimplemented /* 212 */
- .word solaris_getdents64 /* getdents64 dpd 213 */
- .word REGS(solaris_mmap64) /* mmap64 xxxxdX 214 */
- .word solaris_stat64 /* stat64 sP 215 */
- .word solaris_lstat64 /* lstat64 sP 216 */
- .word solaris_fstat64 /* fstat64 dP 217 */
- .word solaris_statvfs64 /* statvfs64 sP 218 */
- .word solaris_fstatvfs64 /* fstatvfs64 dP 219 */
- .word solaris_setrlimit64 /* setrlimit64 dP 220 */
- .word solaris_getrlimit64 /* getrlimit64 dP 221 */
- .word CHAIN(pread64) /* pread64 dpdD 222 */
- .word CHAIN(pwrite64) /* pwrite64 dpdD 223 */
- .word CHAIN(creat) /* creat64 so 224 */
- .word solaris_open /* open64 soo 225 */
- .word solaris_unimplemented /* 226 */
- .word solaris_unimplemented /* 227 */
- .word solaris_unimplemented /* 228 */
- .word solaris_unimplemented /* 229 */
- .word solaris_socket /* socket ddd 230 */
- .word solaris_socketpair /* socketpair dddp 231 */
- .word solaris_bind /* bind dpd 232 */
- .word solaris_listen /* listen dd 233 */
- .word solaris_accept /* accept dpp 234 */
- .word solaris_connect /* connect dpd 235 */
- .word solaris_shutdown /* shutdown dd 236 */
- .word solaris_recv /* recv dpdd 237 */
- .word solaris_recvfrom /* recvfrom dpddpp 238 */
- .word solaris_recvmsg /* recvmsg dpd 239 */
- .word solaris_send /* send dpdd 240 */
- .word solaris_sendmsg /* sendmsg dpd 241 */
- .word solaris_sendto /* sendto dpddpd 242 */
- .word solaris_getpeername /* getpeername dpp 243 */
- .word solaris_getsockname /* getsockname dpp 244 */
- .word solaris_getsockopt /* getsockopt dddpp 245 */
- .word solaris_setsockopt /* setsockopt dddpp 246 */
- .word solaris_unimplemented /* 247 */
- .word solaris_ntp_gettime /* ntp_gettime p 248 */
- .word solaris_ntp_adjtime /* ntp_adjtime p 249 */
- .word solaris_unimplemented /* 250 */
- .word solaris_unimplemented /* 251 */
- .word solaris_unimplemented /* 252 */
- .word solaris_unimplemented /* 253 */
- .word solaris_unimplemented /* 254 */
- .word solaris_unimplemented /* 255 */
diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c
deleted file mode 100644
index f53123c02c2b..000000000000
--- a/arch/sparc64/solaris/timod.c
+++ /dev/null
@@ -1,976 +0,0 @@
-/* $Id: timod.c,v 1.19 2002/02/08 03:57:14 davem Exp $
- * timod.c: timod emulation.
- *
- * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
- *
- * Streams & timod emulation based on code
- * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
- *
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/ioctl.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/netdevice.h>
-#include <linux/poll.h>
-
-#include <net/sock.h>
-
-#include <asm/uaccess.h>
-#include <asm/termios.h>
-
-#include "conv.h"
-#include "socksys.h"
-
-asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
-
-static DEFINE_SPINLOCK(timod_pagelock);
-static char * page = NULL ;
-
-#ifndef DEBUG_SOLARIS_KMALLOC
-
-#define mykmalloc kmalloc
-#define mykfree kfree
-
-#else
-
-void * mykmalloc(size_t s, gfp_t gfp)
-{
- static char * page;
- static size_t free;
- void * r;
- s = ((s + 63) & ~63);
- if( s > PAGE_SIZE ) {
- SOLD("too big size, calling real kmalloc");
- return kmalloc(s, gfp);
- }
- if( s > free ) {
- /* we are wasting memory, but we don't care */
- page = (char *)__get_free_page(gfp);
- free = PAGE_SIZE;
- }
- r = page;
- page += s;
- free -= s;
- return r;
-}
-
-void mykfree(void *p)
-{
-}
-
-#endif
-
-#ifndef DEBUG_SOLARIS
-
-#define BUF_SIZE PAGE_SIZE
-#define PUT_MAGIC(a,m)
-#define SCHECK_MAGIC(a,m)
-#define BUF_OFFSET 0
-#define MKCTL_TRAILER 0
-
-#else
-
-#define BUF_SIZE (PAGE_SIZE-2*sizeof(u64))
-#define BUFPAGE_MAGIC 0xBADC0DEDDEADBABEL
-#define MKCTL_MAGIC 0xDEADBABEBADC0DEDL
-#define PUT_MAGIC(a,m) do{(*(u64*)(a))=(m);}while(0)
-#define SCHECK_MAGIC(a,m) do{if((*(u64*)(a))!=(m))printk("%s,%u,%s(): magic %08x at %p corrupted!\n",\
- __FILE__,__LINE__,__FUNCTION__,(m),(a));}while(0)
-#define BUF_OFFSET sizeof(u64)
-#define MKCTL_TRAILER sizeof(u64)
-
-#endif
-
-static char *getpage( void )
-{
- char *r;
- SOLD("getting page");
- spin_lock(&timod_pagelock);
- if (page) {
- r = page;
- page = NULL;
- spin_unlock(&timod_pagelock);
- SOLD("got cached");
- return r + BUF_OFFSET;
- }
- spin_unlock(&timod_pagelock);
- SOLD("getting new");
- r = (char *)__get_free_page(GFP_KERNEL);
- PUT_MAGIC(r,BUFPAGE_MAGIC);
- PUT_MAGIC(r+PAGE_SIZE-sizeof(u64),BUFPAGE_MAGIC);
- return r + BUF_OFFSET;
-}
-
-static void putpage(char *p)
-{
- SOLD("putting page");
- p = p - BUF_OFFSET;
- SCHECK_MAGIC(p,BUFPAGE_MAGIC);
- SCHECK_MAGIC(p+PAGE_SIZE-sizeof(u64),BUFPAGE_MAGIC);
- spin_lock(&timod_pagelock);
- if (page) {
- spin_unlock(&timod_pagelock);
- free_page((unsigned long)p);
- SOLD("freed it");
- } else {
- page = p;
- spin_unlock(&timod_pagelock);
- SOLD("cached it");
- }
-}
-
-static struct T_primsg *timod_mkctl(int size)
-{
- struct T_primsg *it;
-
- SOLD("creating primsg");
- it = (struct T_primsg *)mykmalloc(size+sizeof(*it)-sizeof(s32)+2*MKCTL_TRAILER, GFP_KERNEL);
- if (it) {
- SOLD("got it");
- it->pri = MSG_HIPRI;
- it->length = size;
- PUT_MAGIC((char*)((u64)(((char *)&it->type)+size+7)&~7),MKCTL_MAGIC);
- }
- return it;
-}
-
-static void timod_wake_socket(unsigned int fd)
-{
- struct socket *sock;
- struct fdtable *fdt;
-
- SOLD("wakeing socket");
- fdt = files_fdtable(current->files);
- sock = SOCKET_I(fdt->fd[fd]->f_path.dentry->d_inode);
- wake_up_interruptible(&sock->wait);
- read_lock(&sock->sk->sk_callback_lock);
- if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
- __kill_fasync(sock->fasync_list, SIGIO, POLL_IN);
- read_unlock(&sock->sk->sk_callback_lock);
- SOLD("done");
-}
-
-static void timod_queue(unsigned int fd, struct T_primsg *it)
-{
- struct sol_socket_struct *sock;
- struct fdtable *fdt;
-
- SOLD("queuing primsg");
- fdt = files_fdtable(current->files);
- sock = (struct sol_socket_struct *)fdt->fd[fd]->private_data;
- it->next = sock->pfirst;
- sock->pfirst = it;
- if (!sock->plast)
- sock->plast = it;
- timod_wake_socket(fd);
- SOLD("done");
-}
-
-static void timod_queue_end(unsigned int fd, struct T_primsg *it)
-{
- struct sol_socket_struct *sock;
- struct fdtable *fdt;
-
- SOLD("queuing primsg at end");
- fdt = files_fdtable(current->files);
- sock = (struct sol_socket_struct *)fdt->fd[fd]->private_data;
- it->next = NULL;
- if (sock->plast)
- sock->plast->next = it;
- else
- sock->pfirst = it;
- sock->plast = it;
- SOLD("done");
-}
-
-static void timod_error(unsigned int fd, int prim, int terr, int uerr)
-{
- struct T_primsg *it;
-
- SOLD("making error");
- it = timod_mkctl(sizeof(struct T_error_ack));
- if (it) {
- struct T_error_ack *err = (struct T_error_ack *)&it->type;
-
- SOLD("got it");
- err->PRIM_type = T_ERROR_ACK;
- err->ERROR_prim = prim;
- err->TLI_error = terr;
- err->UNIX_error = uerr; /* FIXME: convert this */
- timod_queue(fd, it);
- }
- SOLD("done");
-}
-
-static void timod_ok(unsigned int fd, int prim)
-{
- struct T_primsg *it;
- struct T_ok_ack *ok;
-
- SOLD("creating ok ack");
- it = timod_mkctl(sizeof(*ok));
- if (it) {
- SOLD("got it");
- ok = (struct T_ok_ack *)&it->type;
- ok->PRIM_type = T_OK_ACK;
- ok->CORRECT_prim = prim;
- timod_queue(fd, it);
- }
- SOLD("done");
-}
-
-static int timod_optmgmt(unsigned int fd, int flag, char __user *opt_buf, int opt_len, int do_ret)
-{
- int error, failed;
- int ret_space, ret_len;
- long args[5];
- char *ret_pos,*ret_buf;
- int (*sys_socketcall)(int, unsigned long *) =
- (int (*)(int, unsigned long *))SYS(socketcall);
- mm_segment_t old_fs = get_fs();
-
- SOLD("entry");
- SOLDD(("fd %u flg %u buf %p len %u doret %u",fd,flag,opt_buf,opt_len,do_ret));
- if (!do_ret && (!opt_buf || opt_len <= 0))
- return 0;
- SOLD("getting page");
- ret_pos = ret_buf = getpage();
- ret_space = BUF_SIZE;
- ret_len = 0;
-
- error = failed = 0;
- SOLD("looping");
- while(opt_len >= sizeof(struct opthdr)) {
- struct opthdr *opt;
- int orig_opt_len;
- SOLD("loop start");
- opt = (struct opthdr *)ret_pos;
- if (ret_space < sizeof(struct opthdr)) {
- failed = TSYSERR;
- break;
- }
- SOLD("getting opthdr");
- if (copy_from_user(opt, opt_buf, sizeof(struct opthdr)) ||
- opt->len > opt_len) {
- failed = TBADOPT;
- break;
- }
- SOLD("got opthdr");
- if (flag == T_NEGOTIATE) {
- char *buf;
-
- SOLD("handling T_NEGOTIATE");
- buf = ret_pos + sizeof(struct opthdr);
- if (ret_space < opt->len + sizeof(struct opthdr) ||
- copy_from_user(buf, opt_buf+sizeof(struct opthdr), opt->len)) {
- failed = TSYSERR;
- break;
- }
- SOLD("got optdata");
- args[0] = fd;
- args[1] = opt->level;
- args[2] = opt->name;
- args[3] = (long)buf;
- args[4] = opt->len;
- SOLD("calling SETSOCKOPT");
- set_fs(KERNEL_DS);
- error = sys_socketcall(SYS_SETSOCKOPT, args);
- set_fs(old_fs);
- if (error) {
- failed = TBADOPT;
- break;
- }
- SOLD("SETSOCKOPT ok");
- }
- orig_opt_len = opt->len;
- opt->len = ret_space - sizeof(struct opthdr);
- if (opt->len < 0) {
- failed = TSYSERR;
- break;
- }
- args[0] = fd;
- args[1] = opt->level;
- args[2] = opt->name;
- args[3] = (long)(ret_pos+sizeof(struct opthdr));
- args[4] = (long)&opt->len;
- SOLD("calling GETSOCKOPT");
- set_fs(KERNEL_DS);
- error = sys_socketcall(SYS_GETSOCKOPT, args);
- set_fs(old_fs);
- if (error) {
- failed = TBADOPT;
- break;
- }
- SOLD("GETSOCKOPT ok");
- ret_space -= sizeof(struct opthdr) + opt->len;
- ret_len += sizeof(struct opthdr) + opt->len;
- ret_pos += sizeof(struct opthdr) + opt->len;
- opt_len -= sizeof(struct opthdr) + orig_opt_len;
- opt_buf += sizeof(struct opthdr) + orig_opt_len;
- SOLD("loop end");
- }
- SOLD("loop done");
- if (do_ret) {
- SOLD("generating ret msg");
- if (failed)
- timod_error(fd, T_OPTMGMT_REQ, failed, -error);
- else {
- struct T_primsg *it;
- it = timod_mkctl(sizeof(struct T_optmgmt_ack) + ret_len);
- if (it) {
- struct T_optmgmt_ack *ack =
- (struct T_optmgmt_ack *)&it->type;
- SOLD("got primsg");
- ack->PRIM_type = T_OPTMGMT_ACK;
- ack->OPT_length = ret_len;
- ack->OPT_offset = sizeof(struct T_optmgmt_ack);
- ack->MGMT_flags = (failed ? T_FAILURE : flag);
- memcpy(((char*)ack)+sizeof(struct T_optmgmt_ack),
- ret_buf, ret_len);
- timod_queue(fd, it);
- }
- }
- }
- SOLDD(("put_page %p\n", ret_buf));
- putpage(ret_buf);
- SOLD("done");
- return 0;
-}
-
-int timod_putmsg(unsigned int fd, char __user *ctl_buf, int ctl_len,
- char __user *data_buf, int data_len, int flags)
-{
- int ret, error, terror;
- char *buf;
- struct file *filp;
- struct inode *ino;
- struct fdtable *fdt;
- struct sol_socket_struct *sock;
- mm_segment_t old_fs = get_fs();
- long args[6];
- int (*sys_socketcall)(int, unsigned long __user *) =
- (int (*)(int, unsigned long __user *))SYS(socketcall);
- int (*sys_sendto)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int) =
- (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int))SYS(sendto);
-
- fdt = files_fdtable(current->files);
- filp = fdt->fd[fd];
- ino = filp->f_path.dentry->d_inode;
- sock = (struct sol_socket_struct *)filp->private_data;
- SOLD("entry");
- if (get_user(ret, (int __user *)A(ctl_buf)))
- return -EFAULT;
- switch (ret) {
- case T_BIND_REQ:
- {
- struct T_bind_req req;
-
- SOLDD(("bind %016lx(%016lx)\n", sock, filp));
- SOLD("T_BIND_REQ");
- if (sock->state != TS_UNBND) {
- timod_error(fd, T_BIND_REQ, TOUTSTATE, 0);
- return 0;
- }
- SOLD("state ok");
- if (copy_from_user(&req, ctl_buf, sizeof(req))) {
- timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT);
- return 0;
- }
- SOLD("got ctl req");
- if (req.ADDR_offset && req.ADDR_length) {
- if (req.ADDR_length > BUF_SIZE) {
- timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT);
- return 0;
- }
- SOLD("req size ok");
- buf = getpage();
- if (copy_from_user(buf, ctl_buf + req.ADDR_offset, req.ADDR_length)) {
- timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT);
- putpage(buf);
- return 0;
- }
- SOLD("got ctl data");
- args[0] = fd;
- args[1] = (long)buf;
- args[2] = req.ADDR_length;
- SOLD("calling BIND");
- set_fs(KERNEL_DS);
- error = sys_socketcall(SYS_BIND, args);
- set_fs(old_fs);
- putpage(buf);
- SOLD("BIND returned");
- } else
- error = 0;
- if (!error) {
- struct T_primsg *it;
- if (req.CONIND_number) {
- args[0] = fd;
- args[1] = req.CONIND_number;
- SOLD("calling LISTEN");
- set_fs(KERNEL_DS);
- error = sys_socketcall(SYS_LISTEN, args);
- set_fs(old_fs);
- SOLD("LISTEN done");
- }
- it = timod_mkctl(sizeof(struct T_bind_ack)+sizeof(struct sockaddr));
- if (it) {
- struct T_bind_ack *ack;
-
- ack = (struct T_bind_ack *)&it->type;
- ack->PRIM_type = T_BIND_ACK;
- ack->ADDR_offset = sizeof(*ack);
- ack->ADDR_length = sizeof(struct sockaddr);
- ack->CONIND_number = req.CONIND_number;
- args[0] = fd;
- args[1] = (long)(ack+sizeof(*ack));
- args[2] = (long)&ack->ADDR_length;
- set_fs(KERNEL_DS);
- sys_socketcall(SYS_GETSOCKNAME,args);
- set_fs(old_fs);
- sock->state = TS_IDLE;
- timod_ok(fd, T_BIND_REQ);
- timod_queue_end(fd, it);
- SOLD("BIND done");
- return 0;
- }
- }
- SOLD("some error");
- switch (error) {
- case -EINVAL:
- terror = TOUTSTATE;
- error = 0;
- break;
- case -EACCES:
- terror = TACCES;
- error = 0;
- break;
- case -EADDRNOTAVAIL:
- case -EADDRINUSE:
- terror = TNOADDR;
- error = 0;
- break;
- default:
- terror = TSYSERR;
- break;
- }
- timod_error(fd, T_BIND_REQ, terror, -error);
- SOLD("BIND done");
- return 0;
- }
- case T_CONN_REQ:
- {
- struct T_conn_req req;
- unsigned short oldflags;
- struct T_primsg *it;
- SOLD("T_CONN_REQ");
- if (sock->state != TS_UNBND && sock->state != TS_IDLE) {
- timod_error(fd, T_CONN_REQ, TOUTSTATE, 0);
- return 0;
- }
- SOLD("state ok");
- if (copy_from_user(&req, ctl_buf, sizeof(req))) {
- timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
- return 0;
- }
- SOLD("got ctl req");
- if (ctl_len > BUF_SIZE) {
- timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
- return 0;
- }
- SOLD("req size ok");
- buf = getpage();
- if (copy_from_user(buf, ctl_buf, ctl_len)) {
- timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
- putpage(buf);
- return 0;
- }
-#ifdef DEBUG_SOLARIS
- {
- char * ptr = buf;
- int len = ctl_len;
- printk("returned data (%d bytes): ",len);
- while( len-- ) {
- if (!(len & 7))
- printk(" ");
- printk("%02x",(unsigned char)*ptr++);
- }
- printk("\n");
- }
-#endif
- SOLD("got ctl data");
- args[0] = fd;
- args[1] = (long)buf+req.DEST_offset;
- args[2] = req.DEST_length;
- oldflags = filp->f_flags;
- filp->f_flags &= ~O_NONBLOCK;
- SOLD("calling CONNECT");
- set_fs(KERNEL_DS);
- error = sys_socketcall(SYS_CONNECT, args);
- set_fs(old_fs);
- filp->f_flags = oldflags;
- SOLD("CONNECT done");
- if (!error) {
- struct T_conn_con *con;
- SOLD("no error");
- it = timod_mkctl(ctl_len);
- if (!it) {
- putpage(buf);
- return -ENOMEM;
- }
- con = (struct T_conn_con *)&it->type;
-#ifdef DEBUG_SOLARIS
- {
- char * ptr = buf;
- int len = ctl_len;
- printk("returned data (%d bytes): ",len);
- while( len-- ) {
- if (!(len & 7))
- printk(" ");
- printk("%02x",(unsigned char)*ptr++);
- }
- printk("\n");
- }
-#endif
- memcpy(con, buf, ctl_len);
- SOLD("copied ctl_buf");
- con->PRIM_type = T_CONN_CON;
- sock->state = TS_DATA_XFER;
- } else {
- struct T_discon_ind *dis;
- SOLD("some error");
- it = timod_mkctl(sizeof(*dis));
- if (!it) {
- putpage(buf);
- return -ENOMEM;
- }
- SOLD("got primsg");
- dis = (struct T_discon_ind *)&it->type;
- dis->PRIM_type = T_DISCON_IND;
- dis->DISCON_reason = -error; /* FIXME: convert this as in iABI_errors() */
- dis->SEQ_number = 0;
- }
- putpage(buf);
- timod_ok(fd, T_CONN_REQ);
- it->pri = 0;
- timod_queue_end(fd, it);
- SOLD("CONNECT done");
- return 0;
- }
- case T_OPTMGMT_REQ:
- {
- struct T_optmgmt_req req;
- SOLD("OPTMGMT_REQ");
- if (copy_from_user(&req, ctl_buf, sizeof(req)))
- return -EFAULT;
- SOLD("got req");
- return timod_optmgmt(fd, req.MGMT_flags,
- req.OPT_offset > 0 ? ctl_buf + req.OPT_offset : NULL,
- req.OPT_length, 1);
- }
- case T_UNITDATA_REQ:
- {
- struct T_unitdata_req req;
-
- int err;
- SOLD("T_UNITDATA_REQ");
- if (sock->state != TS_IDLE && sock->state != TS_DATA_XFER) {
- timod_error(fd, T_CONN_REQ, TOUTSTATE, 0);
- return 0;
- }
- SOLD("state ok");
- if (copy_from_user(&req, ctl_buf, sizeof(req))) {
- timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
- return 0;
- }
- SOLD("got ctl req");
-#ifdef DEBUG_SOLARIS
- {
- char * ptr = ctl_buf+req.DEST_offset;
- int len = req.DEST_length;
- printk("socket address (%d bytes): ",len);
- while( len-- ) {
- char c;
- if (get_user(c,ptr))
- printk("??");
- else
- printk("%02x",(unsigned char)c);
- ptr++;
- }
- printk("\n");
- }
-#endif
- err = sys_sendto(fd, data_buf, data_len, 0, req.DEST_length > 0 ? (struct sockaddr __user *)(ctl_buf+req.DEST_offset) : NULL, req.DEST_length);
- if (err == data_len)
- return 0;
- if(err >= 0) {
- printk("timod: sendto failed to send all the data\n");
- return 0;
- }
- timod_error(fd, T_CONN_REQ, TSYSERR, -err);
- return 0;
- }
- default:
- printk(KERN_INFO "timod_putmsg: unsupported command %u.\n", ret);
- break;
- }
- return -EINVAL;
-}
-
-int timod_getmsg(unsigned int fd, char __user *ctl_buf, int ctl_maxlen, s32 __user *ctl_len,
- char __user *data_buf, int data_maxlen, s32 __user *data_len, int *flags_p)
-{
- int error;
- int oldflags;
- struct file *filp;
- struct inode *ino;
- struct fdtable *fdt;
- struct sol_socket_struct *sock;
- struct T_unitdata_ind udi;
- mm_segment_t old_fs = get_fs();
- long args[6];
- char __user *tmpbuf;
- int tmplen;
- int (*sys_socketcall)(int, unsigned long __user *) =
- (int (*)(int, unsigned long __user *))SYS(socketcall);
- int (*sys_recvfrom)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *);
-
- SOLD("entry");
- SOLDD(("%u %p %d %p %p %d %p %d\n", fd, ctl_buf, ctl_maxlen, ctl_len, data_buf, data_maxlen, data_len, *flags_p));
- fdt = files_fdtable(current->files);
- filp = fdt->fd[fd];
- ino = filp->f_path.dentry->d_inode;
- sock = (struct sol_socket_struct *)filp->private_data;
- SOLDD(("%p %p\n", sock->pfirst, sock->pfirst ? sock->pfirst->next : NULL));
- if ( ctl_maxlen > 0 && !sock->pfirst && SOCKET_I(ino)->type == SOCK_STREAM
- && sock->state == TS_IDLE) {
- SOLD("calling LISTEN");
- args[0] = fd;
- args[1] = -1;
- set_fs(KERNEL_DS);
- sys_socketcall(SYS_LISTEN, args);
- set_fs(old_fs);
- SOLD("LISTEN done");
- }
- if (!(filp->f_flags & O_NONBLOCK)) {
- struct poll_wqueues wait_table;
- poll_table *wait;
-
- poll_initwait(&wait_table);
- wait = &wait_table.pt;
- for(;;) {
- SOLD("loop");
- set_current_state(TASK_INTERRUPTIBLE);
- /* ! ( l<0 || ( l>=0 && ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */
- /* ( ! l<0 && ! ( l>=0 && ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */
- /* ( l>=0 && ( ! l>=0 || ! ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */
- /* ( l>=0 && ( l<0 || ( pfirst && ! (flags == HIPRI && pri != HIPRI) ) ) ) */
- /* ( l>=0 && ( l<0 || ( pfirst && (flags != HIPRI || pri == HIPRI) ) ) ) */
- /* ( l>=0 && ( pfirst && (flags != HIPRI || pri == HIPRI) ) ) */
- if (ctl_maxlen >= 0 && sock->pfirst && (*flags_p != MSG_HIPRI || sock->pfirst->pri == MSG_HIPRI))
- break;
- SOLD("cond 1 passed");
- if (
- #if 1
- *flags_p != MSG_HIPRI &&
- #endif
- ((filp->f_op->poll(filp, wait) & POLLIN) ||
- (filp->f_op->poll(filp, NULL) & POLLIN) ||
- signal_pending(current))
- ) {
- break;
- }
- if( *flags_p == MSG_HIPRI ) {
- SOLD("avoiding lockup");
- break ;
- }
- if(wait_table.error) {
- SOLD("wait-table error");
- poll_freewait(&wait_table);
- return wait_table.error;
- }
- SOLD("scheduling");
- schedule();
- }
- SOLD("loop done");
- current->state = TASK_RUNNING;
- poll_freewait(&wait_table);
- if (signal_pending(current)) {
- SOLD("signal pending");
- return -EINTR;
- }
- }
- if (ctl_maxlen >= 0 && sock->pfirst) {
- struct T_primsg *it = sock->pfirst;
- int l = min_t(int, ctl_maxlen, it->length);
- SCHECK_MAGIC((char*)((u64)(((char *)&it->type)+sock->offset+it->length+7)&~7),MKCTL_MAGIC);
- SOLD("purting ctl data");
- if(copy_to_user(ctl_buf,
- (char*)&it->type + sock->offset, l))
- return -EFAULT;
- SOLD("pur it");
- if(put_user(l, ctl_len))
- return -EFAULT;
- SOLD("set ctl_len");
- *flags_p = it->pri;
- it->length -= l;
- if (it->length) {
- SOLD("more ctl");
- sock->offset += l;
- return MORECTL;
- } else {
- SOLD("removing message");
- sock->pfirst = it->next;
- if (!sock->pfirst)
- sock->plast = NULL;
- SOLDD(("getmsg kfree %016lx->%016lx\n", it, sock->pfirst));
- mykfree(it);
- sock->offset = 0;
- SOLD("ctl done");
- return 0;
- }
- }
- *flags_p = 0;
- if (ctl_maxlen >= 0) {
- SOLD("ACCEPT perhaps?");
- if (SOCKET_I(ino)->type == SOCK_STREAM && sock->state == TS_IDLE) {
- struct T_conn_ind ind;
- char *buf = getpage();
- int len = BUF_SIZE;
-
- SOLD("trying ACCEPT");
- if (put_user(ctl_maxlen - sizeof(ind), ctl_len))
- return -EFAULT;
- args[0] = fd;
- args[1] = (long)buf;
- args[2] = (long)&len;
- oldflags = filp->f_flags;
- filp->f_flags |= O_NONBLOCK;
- SOLD("calling ACCEPT");
- set_fs(KERNEL_DS);
- error = sys_socketcall(SYS_ACCEPT, args);
- set_fs(old_fs);
- filp->f_flags = oldflags;
- if (error < 0) {
- SOLD("some error");
- putpage(buf);
- return error;
- }
- if (error) {
- SOLD("connect");
- putpage(buf);
- if (sizeof(ind) > ctl_maxlen) {
- SOLD("generating CONN_IND");
- ind.PRIM_type = T_CONN_IND;
- ind.SRC_length = len;
- ind.SRC_offset = sizeof(ind);
- ind.OPT_length = ind.OPT_offset = 0;
- ind.SEQ_number = error;
- if(copy_to_user(ctl_buf, &ind, sizeof(ind))||
- put_user(sizeof(ind)+ind.SRC_length,ctl_len))
- return -EFAULT;
- SOLD("CONN_IND created");
- }
- if (data_maxlen >= 0)
- put_user(0, data_len);
- SOLD("CONN_IND done");
- return 0;
- }
- if (len>ctl_maxlen) {
- SOLD("data don't fit");
- putpage(buf);
- return -EFAULT; /* XXX - is this ok ? */
- }
- if(copy_to_user(ctl_buf,buf,len) || put_user(len,ctl_len)){
- SOLD("can't copy data");
- putpage(buf);
- return -EFAULT;
- }
- SOLD("ACCEPT done");
- putpage(buf);
- }
- }
- SOLD("checking data req");
- if (data_maxlen <= 0) {
- if (data_maxlen == 0)
- put_user(0, data_len);
- if (ctl_maxlen >= 0)
- put_user(0, ctl_len);
- return -EAGAIN;
- }
- SOLD("wants data");
- if (ctl_maxlen > sizeof(udi) && sock->state == TS_IDLE) {
- SOLD("udi fits");
- tmpbuf = ctl_buf + sizeof(udi);
- tmplen = ctl_maxlen - sizeof(udi);
- } else {
- SOLD("udi does not fit");
- tmpbuf = NULL;
- tmplen = 0;
- }
- if (put_user(tmplen, ctl_len))
- return -EFAULT;
- SOLD("set ctl_len");
- oldflags = filp->f_flags;
- filp->f_flags |= O_NONBLOCK;
- SOLD("calling recvfrom");
- sys_recvfrom = (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(recvfrom);
- error = sys_recvfrom(fd, data_buf, data_maxlen, 0, (struct sockaddr __user *)tmpbuf, ctl_len);
- filp->f_flags = oldflags;
- if (error < 0)
- return error;
- SOLD("error >= 0" ) ;
- if (error && ctl_maxlen > sizeof(udi) && sock->state == TS_IDLE) {
- SOLD("generating udi");
- udi.PRIM_type = T_UNITDATA_IND;
- if (get_user(udi.SRC_length, ctl_len))
- return -EFAULT;
- udi.SRC_offset = sizeof(udi);
- udi.OPT_length = udi.OPT_offset = 0;
- if (copy_to_user(ctl_buf, &udi, sizeof(udi)) ||
- put_user(sizeof(udi)+udi.SRC_length, ctl_len))
- return -EFAULT;
- SOLD("udi done");
- } else {
- if (put_user(0, ctl_len))
- return -EFAULT;
- }
- put_user(error, data_len);
- SOLD("done");
- return 0;
-}
-
-asmlinkage int solaris_getmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
-{
- struct file *filp;
- struct inode *ino;
- struct strbuf __user *ctlptr;
- struct strbuf __user *datptr;
- struct strbuf ctl, dat;
- int __user *flgptr;
- int flags;
- int error = -EBADF;
- struct fdtable *fdt;
-
- SOLD("entry");
- lock_kernel();
- if (fd >= sysctl_nr_open)
- goto out;
-
- fdt = files_fdtable(current->files);
- filp = fdt->fd[fd];
- if(!filp) goto out;
-
- ino = filp->f_path.dentry->d_inode;
- if (!ino || !S_ISSOCK(ino->i_mode))
- goto out;
-
- ctlptr = (struct strbuf __user *)A(arg1);
- datptr = (struct strbuf __user *)A(arg2);
- flgptr = (int __user *)A(arg3);
-
- error = -EFAULT;
-
- if (ctlptr) {
- if (copy_from_user(&ctl,ctlptr,sizeof(struct strbuf)) ||
- put_user(-1,&ctlptr->len))
- goto out;
- } else
- ctl.maxlen = -1;
-
- if (datptr) {
- if (copy_from_user(&dat,datptr,sizeof(struct strbuf)) ||
- put_user(-1,&datptr->len))
- goto out;
- } else
- dat.maxlen = -1;
-
- if (get_user(flags,flgptr))
- goto out;
-
- switch (flags) {
- case 0:
- case MSG_HIPRI:
- case MSG_ANY:
- case MSG_BAND:
- break;
- default:
- error = -EINVAL;
- goto out;
- }
-
- error = timod_getmsg(fd,A(ctl.buf),ctl.maxlen,&ctlptr->len,
- A(dat.buf),dat.maxlen,&datptr->len,&flags);
-
- if (!error && put_user(flags,flgptr))
- error = -EFAULT;
-out:
- unlock_kernel();
- SOLD("done");
- return error;
-}
-
-asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
-{
- struct file *filp;
- struct inode *ino;
- struct strbuf __user *ctlptr;
- struct strbuf __user *datptr;
- struct strbuf ctl, dat;
- int flags = (int) arg3;
- int error = -EBADF;
- struct fdtable *fdt;
-
- SOLD("entry");
- lock_kernel();
- if (fd >= sysctl_nr_open)
- goto out;
-
- fdt = files_fdtable(current->files);
- filp = fdt->fd[fd];
- if(!filp) goto out;
-
- ino = filp->f_path.dentry->d_inode;
- if (!ino) goto out;
-
- if (!S_ISSOCK(ino->i_mode) &&
- (imajor(ino) != 30 || iminor(ino) != 1))
- goto out;
-
- ctlptr = A(arg1);
- datptr = A(arg2);
-
- error = -EFAULT;
-
- if (ctlptr) {
- if (copy_from_user(&ctl,ctlptr,sizeof(ctl)))
- goto out;
- if (ctl.len < 0 && flags) {
- error = -EINVAL;
- goto out;
- }
- } else {
- ctl.len = 0;
- ctl.buf = 0;
- }
-
- if (datptr) {
- if (copy_from_user(&dat,datptr,sizeof(dat)))
- goto out;
- } else {
- dat.len = 0;
- dat.buf = 0;
- }
-
- error = timod_putmsg(fd,A(ctl.buf),ctl.len,
- A(dat.buf),dat.len,flags);
-out:
- unlock_kernel();
- SOLD("done");
- return error;
-}