summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2002-10-18 06:19:39 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2002-10-18 06:19:39 -0700
commit76dd2761f3527e958e287bf4e83ddea04b92c2cf (patch)
tree7df06b326c08ca27c17c60cc1f405a4b132d7068
parent1e215a63539c42fb4b4c936551b04ea44621b390 (diff)
parent1a19232d88b8f4545aca468056b924d58b01991b (diff)
Merge home.transmeta.com:/home/torvalds/v2.5/x86-64
into home.transmeta.com:/home/torvalds/v2.5/linux
-rw-r--r--arch/x86_64/Config.help43
-rw-r--r--arch/x86_64/Makefile47
-rw-r--r--arch/x86_64/boot/compressed/misc.c11
-rw-r--r--arch/x86_64/config.in29
-rw-r--r--arch/x86_64/defconfig420
-rw-r--r--arch/x86_64/ia32/ia32_binfmt.c26
-rw-r--r--arch/x86_64/ia32/ia32_ioctl.c1477
-rw-r--r--arch/x86_64/ia32/ia32_signal.c39
-rw-r--r--arch/x86_64/ia32/ia32entry.S17
-rw-r--r--arch/x86_64/ia32/ipc32.c5
-rw-r--r--arch/x86_64/ia32/sys_ia32.c190
-rw-r--r--arch/x86_64/kernel/Makefile2
-rw-r--r--arch/x86_64/kernel/apic.c16
-rw-r--r--arch/x86_64/kernel/mpparse.c2
-rw-r--r--arch/x86_64/kernel/mtrr.c2
-rw-r--r--arch/x86_64/kernel/nmi.c42
-rw-r--r--arch/x86_64/kernel/process.c1
-rw-r--r--arch/x86_64/kernel/profile.c45
-rw-r--r--arch/x86_64/kernel/reboot.c1
-rw-r--r--arch/x86_64/kernel/setup.c11
-rw-r--r--arch/x86_64/kernel/traps.c3
-rw-r--r--arch/x86_64/mm/Makefile10
-rw-r--r--arch/x86_64/mm/fault.c24
-rw-r--r--arch/x86_64/mm/init.c38
-rw-r--r--arch/x86_64/mm/ioremap.c65
-rw-r--r--arch/x86_64/mm/modutil.c72
-rw-r--r--arch/x86_64/mm/pageattr.c210
-rw-r--r--include/asm-x86_64/hw_irq.h32
-rw-r--r--include/asm-x86_64/ia32.h5
-rw-r--r--include/asm-x86_64/ide.h2
-rw-r--r--include/asm-x86_64/io_apic.h9
-rw-r--r--include/asm-x86_64/ioctl32.h1
-rw-r--r--include/asm-x86_64/ipc.h4
-rw-r--r--include/asm-x86_64/ipcbuf.h8
-rw-r--r--include/asm-x86_64/namei.h6
-rw-r--r--include/asm-x86_64/nmi.h49
-rw-r--r--include/asm-x86_64/param.h2
-rw-r--r--include/asm-x86_64/proto.h1
-rw-r--r--include/asm-x86_64/softirq.h2
-rw-r--r--include/asm-x86_64/unistd.h5
-rw-r--r--include/linux/ioctl32.h23
41 files changed, 2389 insertions, 608 deletions
diff --git a/arch/x86_64/Config.help b/arch/x86_64/Config.help
index 4bc75426d7b7..1f0a6e48a1fe 100644
--- a/arch/x86_64/Config.help
+++ b/arch/x86_64/Config.help
@@ -435,6 +435,14 @@ CONFIG_X86_CPUID
with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
/dev/cpu/31/cpuid.
+CONFIG_NR_CPUS
+ This allows you to specify the maximum number of CPUs which this
+ kernel will support. The maximum supported value is 32 and the
+ minimum value which makes sense is 2.
+
+ This is purely to save memory - each supported CPU adds
+ approximately eight kilobytes to the kernel image.
+
CONFIG_PREEMPT
This option reduces the latency of the kernel when reacting to
real-time or interactive events by allowing a low priority process to
@@ -487,10 +495,6 @@ CONFIG_CHECKING
Enables some internal consistency checks for kernel debugging.
You should normally say N.
-CONFIG_SIMNOW
- Disable some time consuming optional things for slow CPU simulators.
- Say N unless you're running on a slow simulator like Simics or SimNow.
-
CONFIG_EARLY_PRINTK
Write kernel log output directly into the VGA buffer. This is useful
for kernel debugging when your machine crashes very early before
@@ -499,13 +503,26 @@ CONFIG_EARLY_PRINTK
klogd/syslogd or the X server.You should normally N here, unless
you want to debug such a crash.
-CONFIG_X86_MCE_NONFATAL
- Enabling this feature starts a timer that triggers every 5 seconds which
- will look at the machine check registers to see if anything happened.
- Non-fatal problems automatically get corrected (but still logged).
- Disable this if you don't want to see these messages.
- Seeing the messages this option prints out may be indicative of dying hardware,
- or out-of-spec (ie, overclocked) hardware.
- This option only does something on hardware with Intel P6 style MCE.
- (Pentium Pro and above, AMD Athlon/Duron)
+CONFIG_KALLSYMS
+ Say Y here to let the kernel print out symbolic crash information and
+ symbolic stack backtraces. This increases the size of the kernel
+ somewhat, as all symbols have to be loaded into the kernel image.
+
+CONFIG_INIT_DEBUG
+ Fill __init and __initdata at the end of boot. This is only for debugging.
+
+CONFIG_IA32_EMULATION
+ Include code to run 32bit programs under an 64bit kernel. You should likely
+ turn this on, unless you're 100% sure that you don't have any 32bit programs
+ left.
+
+CONFIG_GART_IOMMU
+ Support the K8 IOMMU. Needed to run systems with more than 4GB of memory
+ properly with 32bit devices. You should probably turn this on.
+ The iommu can be turned off at runtime with the iommu=off parameter.
+
+CONFIG_DUMMY_IOMMU
+ Don't use IOMMU code. This will cause problems when you have more than 4GB
+ of memory and any 32bit devices. Don't turn on unless you know what you
+ are doing.
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index 07650a3a0ce1..382b3a091704 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -33,7 +33,7 @@ IA32_CPP := $(CROSS_COMPILE)gcc -m32 -E
export IA32_CC IA32_LD IA32_AS IA32_OBJCOPY IA32_CPP
-LD=$(CROSS_COMPILE)ld -m elf_x86_64
+LDFLAGS := -m elf_x86_64
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
LDFLAGS_vmlinux := -e stext
@@ -47,52 +47,39 @@ CFLAGS += -finline-limit=2000
HEAD := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o
-SUBDIRS += arch/x86_64/kernel arch/x86_64/mm arch/x86_64/lib
-CORE_FILES := arch/x86_64/kernel/kernel.o $(CORE_FILES)
-CORE_FILES += arch/x86_64/mm/mm.o
-LIBS := $(TOPDIR)/arch/x86_64/lib/lib.a $(LIBS)
-
-ifdef CONFIG_IA32_EMULATION
-SUBDIRS += arch/x86_64/ia32
-CORE_FILES += arch/x86_64/ia32/ia32.o
-endif
-
-ifdef CONFIG_PCI
-SUBDIRS += arch/x86_64/pci
-DRIVERS += arch/x86_64/pci/pci.o
-endif
-
-CORE_FILES += $(core-y)
+libs-y += arch/x86_64/lib/
+core-y += arch/x86_64/kernel/ arch/x86_64/mm/
+core-$(CONFIG_IA32_EMULATION) += arch/x86_64/ia32/
+drivers-$(CONFIG_PCI) += arch/x86_64/pci/
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+makeboot = $(call descend,arch/x86_64/boot,$(1))
.PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install \
clean archclean archmrproper
-bzImage: vmlinux
- @$(MAKEBOOT) bzImage
+BOOTIMAGE=arch/x86_64/boot/bzImage
+zImage zlilo zdisk: BOOTIMAGE=arch/x86_64/boot/zImage
-bzImage-padded: vmlinux
- @$(MAKEBOOT) bzImage-padded
+zImage bzImage: vmlinux
+ +@$(call makeboot,$(BOOTIMAGE))
-tmp:
- @$(MAKEBOOT) BOOTIMAGE=bzImage zlilo
+compressed: zImage
-bzlilo: vmlinux
- @$(MAKEBOOT) BOOTIMAGE=bzImage zlilo
+zlilo bzlilo: vmlinux
+ +@$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) zlilo)
-bzdisk: vmlinux
- @$(MAKEBOOT) BOOTIMAGE=bzImage zdisk
+zdisk bzdisk: vmlinux
+ +@$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) zdisk)
install: vmlinux
- @$(MAKEBOOT) BOOTIMAGE=bzImage install
+ +@$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) install)
archclean:
- @$(MAKEBOOT) clean
+ +@$(call makeboot,clean)
archmrproper:
-
prepare: include/asm-$(ARCH)/offset.h
arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
diff --git a/arch/x86_64/boot/compressed/misc.c b/arch/x86_64/boot/compressed/misc.c
index 8c674582130e..cc5d85df42fe 100644
--- a/arch/x86_64/boot/compressed/misc.c
+++ b/arch/x86_64/boot/compressed/misc.c
@@ -190,7 +190,7 @@ static void puts(const char *s)
outb_p(0xff & (pos >> 1), vidport+1);
}
-void* memset(void* s, int c, size_t n)
+void* memset(void* s, int c, unsigned n)
{
int i;
char *ss = (char*)s;
@@ -199,14 +199,13 @@ void* memset(void* s, int c, size_t n)
return s;
}
-void* memcpy(void* __dest, __const void* __src,
- size_t __n)
+void* memcpy(void* dest, const void* src, unsigned n)
{
int i;
- char *d = (char *)__dest, *s = (char *)__src;
+ char *d = (char *)dest, *s = (char *)src;
- for (i=0;i<__n;i++) d[i] = s[i];
- return __dest;
+ for (i=0;i<n;i++) d[i] = s[i];
+ return dest;
}
/* ===========================================================================
diff --git a/arch/x86_64/config.in b/arch/x86_64/config.in
index 6c41e4e22b1d..95a1393387e8 100644
--- a/arch/x86_64/config.in
+++ b/arch/x86_64/config.in
@@ -21,6 +21,7 @@ define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
define_bool CONFIG_X86_CMPXCHG y
define_bool CONFIG_EARLY_PRINTK y
+define_bool CONFIG_GENERIC_ISA_DMA y
source init/Config.in
@@ -54,11 +55,17 @@ if [ "$CONFIG_SMP" = "n" ]; then
fi
if [ "$CONFIG_SMP" = "y" ]; then
define_bool CONFIG_HAVE_DEC_LOCK y
+ # actually 64 maximum, but you need to fix the APIC code first
+ # to use clustered mode or whatever your big iron needs
int 'Maximum number of CPUs (2-8)' CONFIG_NR_CPUS 8
fi
+bool 'IOMMU support' CONFIG_GART_IOMMU
+if [ "$CONFIG_GART_IOMMU" != "y" ]; then
+ define_bool CONFIG_DUMMY_IOMMU y
+fi
+
define_bool CONFIG_X86_MCE y
-bool 'Check for non-fatal machine check errors' CONFIG_X86_MCE_NONFATAL $CONFIG_X86_MCE
endmenu
@@ -108,22 +115,20 @@ tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
bool 'IA32 Emulation' CONFIG_IA32_EMULATION
+
+
endmenu
source drivers/mtd/Config.in
source drivers/parport/Config.in
-#source drivers/pnp/Config.in
-
source drivers/block/Config.in
-source drivers/md/Config.in
-
mainmenu_option next_comment
comment 'ATA/ATAPI/MFM/RLL support'
-tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE
+tristate 'ATA/ATAPI/MFM/RLL device support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
@@ -133,15 +138,19 @@ fi
endmenu
mainmenu_option next_comment
-comment 'SCSI support'
+comment 'SCSI device support'
-tristate 'SCSI support' CONFIG_SCSI
+tristate 'SCSI device support' CONFIG_SCSI
if [ "$CONFIG_SCSI" != "n" ]; then
source drivers/scsi/Config.in
fi
endmenu
+source drivers/md/Config.in
+
+source drivers/telephony/Config.in
+
source drivers/message/fusion/Config.in
source drivers/ieee1394/Config.in
@@ -172,8 +181,6 @@ source net/irda/Config.in
source drivers/isdn/Config.in
-source drivers/telephony/Config.in
-
# no support for non IDE/SCSI cdroms as they were all ISA only
#
@@ -224,6 +231,8 @@ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK
bool ' Additional run-time checks' CONFIG_CHECKING
bool ' Debug __init statements' CONFIG_INIT_DEBUG
+ bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK
+ bool ' Load all symbols for debugging/kksymoops' CONFIG_KALLSYMS
fi
endmenu
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index 6651cfc904a3..57a53ec3cc0f 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -1,5 +1,5 @@
#
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
#
CONFIG_X86_64=y
CONFIG_X86=y
@@ -10,6 +10,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_X86_CMPXCHG=y
CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_ISA_DMA=y
#
# Code maturity level options
@@ -47,11 +48,12 @@ CONFIG_X86_CPUID=y
# CONFIG_EISA is not set
CONFIG_X86_IO_APIC=y
CONFIG_X86_LOCAL_APIC=y
+CONFIG_MTRR=y
CONFIG_SMP=y
CONFIG_HAVE_DEC_LOCK=y
-CONFIG_X86_MCE=y
-# CONFIG_X86_MCE_NONFATAL is not set
CONFIG_NR_CPUS=8
+CONFIG_GART_IOMMU=y
+CONFIG_X86_MCE=y
#
# Power management options
@@ -61,7 +63,25 @@ CONFIG_NR_CPUS=8
#
# ACPI Support
#
-# CONFIG_ACPI is not set
+CONFIG_ACPI=y
+# CONFIG_ACPI_HT_ONLY is not set
+CONFIG_ACPI_BOOT=y
+# CONFIG_ACPI_SLEEP is not set
+CONFIG_ACPI_AC=y
+CONFIG_ACPI_BATTERY=y
+CONFIG_ACPI_BUTTON=y
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_TOSHIBA=y
+CONFIG_ACPI_DEBUG=y
+CONFIG_ACPI_BOOT=y
+CONFIG_ACPI_BUS=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_PCI=y
+CONFIG_ACPI_SYSTEM=y
#
# Bus options (PCI etc.)
@@ -106,81 +126,21 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
+CONFIG_LBD=y
#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-# CONFIG_NETFILTER is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_IPV6 is not set
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
+# ATA/ATAPI/MFM/RLL support
#
-# CONFIG_NET_SCHED is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-# CONFIG_PHONE_IXJ is not set
-# CONFIG_PHONE_IXJ_PCMCIA is not set
+CONFIG_IDE=y
#
-# ATA/IDE/MFM/RLL support
+# IDE, ATA and ATAPI Block devices
#
-CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
#
-# ATA and ATAPI Block devices
+# Please see Documentation/ide.txt for help/info on IDE drives
#
-CONFIG_BLK_DEV_IDE=y
# CONFIG_BLK_DEV_HD_IDE is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_BLK_DEV_IDEDISK=y
@@ -188,27 +148,35 @@ CONFIG_IDEDISK_MULTI_MODE=y
# CONFIG_IDEDISK_STROKE is not set
# CONFIG_BLK_DEV_IDECS is not set
CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_BLK_DEV_GENERIC is not set
# CONFIG_IDEPCI_SHARE_IRQ is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_IDEDMA_PCI_AUTO is not set
-# CONFIG_IDEDMA_ONLYDISK is not set
-CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_BLK_DEV_IDE_TCQ is not set
# CONFIG_BLK_DEV_IDE_TCQ_DEFAULT is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+CONFIG_BLK_DEV_ADMA=y
# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_AEC6280_BURST is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_WDC_ALI15X3 is not set
CONFIG_BLK_DEV_AMD74XX=y
+# CONFIG_AMD74XX_OVERRIDE is not set
# CONFIG_BLK_DEV_CMD64X is not set
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5530 is not set
@@ -216,88 +184,58 @@ CONFIG_BLK_DEV_AMD74XX=y
# CONFIG_HPT34X_AUTODMA is not set
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_NFORCE is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_PDC202XX_BURST is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
# CONFIG_IDE_CHIPSETS is not set
+CONFIG_IDEDMA_AUTO=y
# CONFIG_IDEDMA_IVB is not set
-CONFIG_ATAPI=y
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SD_EXTRA_DEVS=40
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_REPORT_LUNS is not set
-CONFIG_SCSI_CONSTANTS=y
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-CONFIG_SCSI_AIC7XXX=y
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
-CONFIG_AIC7XXX_RESET_DELAY_MS=15000
-# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_NCR53C8XX is not set
-# CONFIG_SCSI_SYM53C8XX is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_DEBUG is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
#
# Fusion MPT device support
#
# CONFIG_FUSION is not set
+# CONFIG_FUSION_BOOT is not set
+# CONFIG_FUSION_ISENSE is not set
+# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION_LAN is not set
#
# IEEE 1394 (FireWire) support (EXPERIMENTAL)
@@ -305,6 +243,53 @@ CONFIG_AIC7XXX_RESET_DELAY_MS=15000
# CONFIG_IEEE1394 is not set
#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
+# CONFIG_NETFILTER is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_LLC is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
# Network device support
#
CONFIG_NETDEVICES=y
@@ -339,6 +324,11 @@ CONFIG_VORTEX=y
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
# CONFIG_NET_PCI is not set
@@ -350,6 +340,7 @@ CONFIG_VORTEX=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
+# CONFIG_E1000_NAPI is not set
# CONFIG_MYRI_SBUS is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
@@ -381,11 +372,6 @@ CONFIG_TIGON3=y
# CONFIG_WAN is not set
#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-
-#
# Amateur Radio support
#
# CONFIG_HAMRADIO is not set
@@ -403,31 +389,106 @@ CONFIG_TIGON3=y
#
# Input device support
#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
# CONFIG_GAMEPORT is not set
CONFIG_SOUND_GAMEPORT=y
# CONFIG_GAMEPORT_NS558 is not set
# CONFIG_GAMEPORT_L4 is not set
-# CONFIG_INPUT_EMU10K1 is not set
-# CONFIG_GAMEPORT_PCIGAME is not set
+# CONFIG_GAMEPORT_EMU10K1 is not set
+# CONFIG_GAMEPORT_VORTEX is not set
# CONFIG_GAMEPORT_FM801 is not set
# CONFIG_GAMEPORT_CS461x is not set
-# CONFIG_SERIO is not set
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+CONFIG_INPUT_JOYSTICK=y
+# CONFIG_JOYSTICK_ANALOG is not set
+# CONFIG_JOYSTICK_A3D is not set
+# CONFIG_JOYSTICK_ADI is not set
+# CONFIG_JOYSTICK_COBRA is not set
+# CONFIG_JOYSTICK_GF2K is not set
+# CONFIG_JOYSTICK_GRIP is not set
+# CONFIG_JOYSTICK_GRIP_MP is not set
+# CONFIG_JOYSTICK_GUILLEMOT is not set
+# CONFIG_JOYSTICK_INTERACT is not set
+# CONFIG_JOYSTICK_SIDEWINDER is not set
+# CONFIG_JOYSTICK_TMDC is not set
+# CONFIG_JOYSTICK_IFORCE is not set
+# CONFIG_JOYSTICK_WARRIOR is not set
+# CONFIG_JOYSTICK_MAGELLAN is not set
+# CONFIG_JOYSTICK_SPACEORB is not set
+# CONFIG_JOYSTICK_SPACEBALL is not set
+# CONFIG_JOYSTICK_STINGER is not set
+# CONFIG_JOYSTICK_TWIDDLER is not set
+# CONFIG_JOYSTICK_DB9 is not set
+# CONFIG_JOYSTICK_GAMECON is not set
+# CONFIG_JOYSTICK_TURBOGRAFX is not set
+# CONFIG_INPUT_JOYDUMP is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_INPUT_MISC is not set
+# CONFIG_INPUT_PCSPKR is not set
+# CONFIG_INPUT_UINPUT is not set
#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_HW_CONSOLE=y
# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_CS is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
@@ -440,10 +501,6 @@ CONFIG_UNIX98_PTY_COUNT=256
# Mice
#
# CONFIG_BUSMOUSE is not set
-CONFIG_MOUSE=y
-CONFIG_PSMOUSE=y
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
# CONFIG_QIC02_TAPE is not set
#
@@ -451,6 +508,7 @@ CONFIG_PSMOUSE=y
#
# CONFIG_WATCHDOG is not set
# CONFIG_INTEL_RNG is not set
+# CONFIG_AMD_RNG is not set
# CONFIG_NVRAM is not set
CONFIG_RTC=y
# CONFIG_DTLK is not set
@@ -462,9 +520,18 @@ CONFIG_RTC=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
+CONFIG_AGP=y
+# CONFIG_AGP_INTEL is not set
+# CONFIG_AGP_I810 is not set
+# CONFIG_AGP_VIA is not set
+# CONFIG_AGP_AMD is not set
+# CONFIG_AGP_SIS is not set
+# CONFIG_AGP_ALI is not set
+# CONFIG_AGP_SWORKS is not set
# CONFIG_DRM is not set
# CONFIG_MWAVE is not set
+# CONFIG_SCx200_GPIO is not set
+CONFIG_RAW_DRIVER=y
#
# Misc devices
@@ -504,7 +571,7 @@ CONFIG_JBD=y
# CONFIG_CRAMFS is not set
CONFIG_TMPFS=y
CONFIG_RAMFS=y
-# CONFIG_ISO9660_FS is not set
+CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
# CONFIG_ZISOFS is not set
# CONFIG_JFS_FS is not set
@@ -530,6 +597,9 @@ CONFIG_EXT2_FS=y
# CONFIG_UDF_RW is not set
# CONFIG_UFS_FS is not set
# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_QUOTA is not set
#
# Network File Systems
@@ -537,14 +607,18 @@ CONFIG_EXT2_FS=y
# CONFIG_CODA_FS is not set
# CONFIG_INTERMEZZO_FS is not set
CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
# CONFIG_ROOT_NFS is not set
CONFIG_NFSD=y
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+# CONFIG_CIFS is not set
# CONFIG_SMB_FS is not set
# CONFIG_NCP_FS is not set
# CONFIG_NCPFS_PACKET_SIGNING is not set
@@ -555,6 +629,7 @@ CONFIG_EXPORTFS=y
# CONFIG_NCPFS_SMALLDOS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_AFS_FS is not set
# CONFIG_ZISOFS_FS is not set
#
@@ -599,8 +674,15 @@ CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SLAB is not set
CONFIG_MAGIC_SYSRQ=y
# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_CHECKING is not set
+CONFIG_CHECKING=y
# CONFIG_INIT_DEBUG is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_KALLSYMS is not set
+
+#
+# Security options
+#
+CONFIG_SECURITY_CAPABILITIES=y
#
# Library routines
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c
index 32fd068146e5..557d4f5e7575 100644
--- a/arch/x86_64/ia32/ia32_binfmt.c
+++ b/arch/x86_64/ia32/ia32_binfmt.c
@@ -25,7 +25,7 @@ struct elf_phdr;
#define IA32_EMULATOR 1
-#define IA32_PAGE_OFFSET 0xE0000000
+#define IA32_PAGE_OFFSET 0xffff0000
#define IA32_STACK_TOP IA32_PAGE_OFFSET
#define ELF_ET_DYN_BASE (IA32_PAGE_OFFSET/3 + 0x1000000)
@@ -216,13 +216,15 @@ static void elf32_init(struct pt_regs *regs)
extern void put_dirty_page(struct task_struct * tsk, struct page *page, unsigned long address);
-int ia32_setup_arg_pages(struct linux_binprm *bprm)
+int setup_arg_pages(struct linux_binprm *bprm)
{
unsigned long stack_base;
struct vm_area_struct *mpnt;
+ struct mm_struct *mm = current->mm;
int i;
- stack_base = IA32_STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE;
+ stack_base = IA32_STACK_TOP - MAX_ARG_PAGES * PAGE_SIZE;
+ mm->arg_start = bprm->p + stack_base;
bprm->p += stack_base;
if (bprm->loader)
@@ -233,9 +235,14 @@ int ia32_setup_arg_pages(struct linux_binprm *bprm)
if (!mpnt)
return -ENOMEM;
- down_write(&current->mm->mmap_sem);
+ if (!vm_enough_memory((IA32_STACK_TOP - (PAGE_MASK & (unsigned long) bprm->p))>>PAGE_SHIFT)) {
+ kmem_cache_free(vm_area_cachep, mpnt);
+ return -ENOMEM;
+ }
+
+ down_write(&mm->mmap_sem);
{
- mpnt->vm_mm = current->mm;
+ mpnt->vm_mm = mm;
mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
mpnt->vm_end = IA32_STACK_TOP;
mpnt->vm_page_prot = PAGE_COPY;
@@ -243,24 +250,25 @@ int ia32_setup_arg_pages(struct linux_binprm *bprm)
mpnt->vm_ops = NULL;
mpnt->vm_pgoff = 0;
mpnt->vm_file = NULL;
+ INIT_LIST_HEAD(&mpnt->shared);
mpnt->vm_private_data = (void *) 0;
- insert_vm_struct(current->mm, mpnt);
- current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
+ insert_vm_struct(mm, mpnt);
+ mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
}
for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
struct page *page = bprm->page[i];
if (page) {
bprm->page[i] = NULL;
- current->mm->rss++;
put_dirty_page(current,page,stack_base);
}
stack_base += PAGE_SIZE;
}
- up_write(&current->mm->mmap_sem);
+ up_write(&mm->mmap_sem);
return 0;
}
+
static unsigned long
elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
{
diff --git a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
index 42fc19f33e41..8a84ef80c15b 100644
--- a/arch/x86_64/ia32/ia32_ioctl.c
+++ b/arch/x86_64/ia32/ia32_ioctl.c
@@ -1,4 +1,4 @@
-/* $Id: ia32_ioctl.c,v 1.11 2002/04/18 14:36:37 ak Exp $
+/* $Id: ia32_ioctl.c,v 1.25 2002/10/11 07:17:06 ak Exp $
* ioctl32.c: Conversion between 32bit and 64bit native ioctls.
*
* Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
@@ -21,6 +21,7 @@
#include <linux/hdreg.h>
#include <linux/raid/md.h>
#include <linux/kd.h>
+#include <linux/dirent.h>
#include <linux/route.h>
#include <linux/in6.h>
#include <linux/ipv6_route.h>
@@ -55,7 +56,9 @@
#include <linux/module.h>
#include <linux/serial.h>
#include <linux/reiserfs_fs.h>
+#include <linux/if_tun.h>
#include <linux/dirent.h>
+#include <linux/ctype.h>
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
/* Ugh. This header really is not clean */
#define min min
@@ -74,8 +77,14 @@
#include <asm/ia32.h>
#include <asm/uaccess.h>
#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/if_bonding.h>
+#include <linux/watchdog.h>
+
#include <asm/module.h>
+#include <asm/ioctl32.h>
#include <linux/soundcard.h>
+#include <linux/lp.h>
#include <linux/atm.h>
#include <linux/atmarp.h>
@@ -88,6 +97,19 @@
#include <linux/atm_tcp.h>
#include <linux/sonet.h>
#include <linux/atm_suni.h>
+#include <linux/mtd/mtd.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci.h>
+
+#include <linux/usb.h>
+#include <linux/usbdevice_fs.h>
+#include <linux/nbd.h>
+#include <linux/random.h>
+#include <linux/filter.h>
+
+#include <asm/mtrr.h>
+
#define A(__x) ((void *)(unsigned long)(__x))
#define AA(__x) A(__x)
@@ -114,7 +136,6 @@ static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
return err;
}
-#if 0
static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
{
mm_segment_t old_fs = get_fs();
@@ -130,7 +151,6 @@ static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
return -EFAULT;
return err;
}
-#endif
static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
@@ -443,6 +463,7 @@ struct ifconf32 {
__kernel_caddr_t32 ifcbuf;
};
+#ifdef CONFIG_NET
static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct net_device *dev;
@@ -458,10 +479,12 @@ static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
strncpy(ifr32.ifr_name, dev->name, sizeof(ifr32.ifr_name)-1);
ifr32.ifr_name[sizeof(ifr32.ifr_name)-1] = 0;
+ dev_put(dev);
err = copy_to_user((struct ifreq32 *)arg, &ifr32, sizeof(struct ifreq32));
return (err ? -EFAULT : 0);
}
+#endif
static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
{
@@ -558,9 +581,25 @@ static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
}
switch (ethcmd) {
case ETHTOOL_GDRVINFO: len = sizeof(struct ethtool_drvinfo); break;
+ case ETHTOOL_GMSGLVL:
+ case ETHTOOL_SMSGLVL:
+ case ETHTOOL_GLINK:
+ case ETHTOOL_NWAY_RST: len = sizeof(struct ethtool_value); break;
+ case ETHTOOL_GREGS: {
+ struct ethtool_regs *regaddr = (struct ethtool_regs *)A(data);
+ /* darned variable size arguments */
+ if (get_user(len, (u32 *)&regaddr->len)) {
+ err = -EFAULT;
+ goto out;
+ }
+ len += sizeof(struct ethtool_regs);
+ break;
+ }
case ETHTOOL_GSET:
- case ETHTOOL_SSET:
- default: len = sizeof(struct ethtool_cmd); break;
+ case ETHTOOL_SSET: len = sizeof(struct ethtool_cmd); break;
+ default:
+ err = -EOPNOTSUPP;
+ goto out;
}
if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
@@ -586,6 +625,91 @@ out:
return err;
}
+
+static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg)
+{
+ struct ifreq ifr;
+ mm_segment_t old_fs;
+ int err, len;
+ u32 data;
+
+ if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
+ return -EFAULT;
+ ifr.ifr_data = (__kernel_caddr_t)get_zeroed_page(GFP_KERNEL);
+ if (!ifr.ifr_data)
+ return -EAGAIN;
+
+ switch (cmd) {
+ case SIOCBONDENSLAVE:
+ case SIOCBONDRELEASE:
+ case SIOCBONDSETHWADDR:
+ case SIOCBONDCHANGEACTIVE:
+ len = IFNAMSIZ * sizeof(char);
+ break;
+ case SIOCBONDSLAVEINFOQUERY:
+ len = sizeof(struct ifslave);
+ break;
+ case SIOCBONDINFOQUERY:
+ len = sizeof(struct ifbond);
+ break;
+ default:
+ err = -EINVAL;
+ goto out;
+ };
+
+ __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
+ if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
+ err = -EFAULT;
+ goto out;
+ }
+
+ old_fs = get_fs();
+ set_fs (KERNEL_DS);
+ err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
+ set_fs (old_fs);
+ if (!err) {
+ len = copy_to_user((char *)A(data), ifr.ifr_data, len);
+ if (len)
+ err = -EFAULT;
+ }
+
+out:
+ free_page((unsigned long)ifr.ifr_data);
+ return err;
+}
+
+static __inline__ void *alloc_user_space(long len)
+{
+ struct pt_regs *regs = (void *)current->thread.rsp0 - sizeof(struct pt_regs);
+ return (void *)regs->rsp - len;
+}
+
+static int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ struct ifreq *u_ifreq64;
+ struct ifreq32 *u_ifreq32 = (struct ifreq32 *) arg;
+ char tmp_buf[IFNAMSIZ];
+ void *data64;
+ u32 data32;
+
+ if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]),
+ IFNAMSIZ))
+ return -EFAULT;
+ if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
+ return -EFAULT;
+ data64 = (void *) A(data32);
+
+ u_ifreq64 = alloc_user_space(sizeof(*u_ifreq64));
+
+ /* Don't check these user accesses, just let that get trapped
+ * in the ioctl handler instead.
+ */
+ copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0], IFNAMSIZ);
+ __put_user(data64, &u_ifreq64->ifr_ifru.ifru_data);
+
+ return sys_ioctl(fd, cmd, (unsigned long) u_ifreq64);
+}
+
static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct ifreq ifr;
@@ -604,15 +728,6 @@ static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
if (err)
return -EFAULT;
break;
- case SIOCGPPPSTATS:
- case SIOCGPPPCSTATS:
- case SIOCGPPPVER:
- if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
- return -EFAULT;
- ifr.ifr_data = (__kernel_caddr_t)get_zeroed_page(GFP_KERNEL);
- if (!ifr.ifr_data)
- return -EAGAIN;
- break;
default:
if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
return -EFAULT;
@@ -638,27 +753,6 @@ static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32)))
return -EFAULT;
break;
- case SIOCGPPPSTATS:
- case SIOCGPPPCSTATS:
- case SIOCGPPPVER:
- {
- u32 data;
- int len;
-
- __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
- if(cmd == SIOCGPPPVER)
- len = strlen((char *)ifr.ifr_data) + 1;
- else if(cmd == SIOCGPPPCSTATS)
- len = sizeof(struct ppp_comp_stats);
- else
- len = sizeof(struct ppp_stats);
-
- len = copy_to_user((char *)A(data), ifr.ifr_data, len);
- free_page((unsigned long)ifr.ifr_data);
- if(len)
- return -EFAULT;
- break;
- }
case SIOCGIFMAP:
err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name));
err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
@@ -671,14 +765,6 @@ static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
err = -EFAULT;
break;
}
- } else {
- switch (cmd) {
- case SIOCGPPPSTATS:
- case SIOCGPPPCSTATS:
- case SIOCGPPPVER:
- free_page((unsigned long)ifr.ifr_data);
- break;
- }
}
return err;
}
@@ -792,14 +878,6 @@ static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
return err ? -EFAULT : 0;
}
-struct fbcmap32 {
- int index; /* first element (0 origin) */
- int count;
- u32 red;
- u32 green;
- u32 blue;
-};
-
struct fb_fix_screeninfo32 {
char id[16];
__kernel_caddr_t32 smem_start;
@@ -883,7 +961,7 @@ static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
break;
default:
do {
- static int count = 0;
+ static int count;
if (++count <= 20)
printk("%s: Unknown fb ioctl cmd fd(%d) "
"cmd(%08x) arg(%08lx)\n",
@@ -1262,6 +1340,269 @@ out: if (karg) kfree(karg);
return err;
}
+
+typedef struct sg_io_hdr32 {
+ s32 interface_id; /* [i] 'S' for SCSI generic (required) */
+ s32 dxfer_direction; /* [i] data transfer direction */
+ u8 cmd_len; /* [i] SCSI command length ( <= 16 bytes) */
+ u8 mx_sb_len; /* [i] max length to write to sbp */
+ u16 iovec_count; /* [i] 0 implies no scatter gather */
+ u32 dxfer_len; /* [i] byte count of data transfer */
+ u32 dxferp; /* [i], [*io] points to data transfer memory
+ or scatter gather list */
+ u32 cmdp; /* [i], [*i] points to command to perform */
+ u32 sbp; /* [i], [*o] points to sense_buffer memory */
+ u32 timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */
+ u32 flags; /* [i] 0 -> default, see SG_FLAG... */
+ s32 pack_id; /* [i->o] unused internally (normally) */
+ u32 usr_ptr; /* [i->o] unused internally */
+ u8 status; /* [o] scsi status */
+ u8 masked_status; /* [o] shifted, masked scsi status */
+ u8 msg_status; /* [o] messaging level data (optional) */
+ u8 sb_len_wr; /* [o] byte count actually written to sbp */
+ u16 host_status; /* [o] errors from host adapter */
+ u16 driver_status; /* [o] errors from software driver */
+ s32 resid; /* [o] dxfer_len - actual_transferred */
+ u32 duration; /* [o] time taken by cmd (unit: millisec) */
+ u32 info; /* [o] auxiliary information */
+} sg_io_hdr32_t; /* 64 bytes long (on sparc32) */
+
+typedef struct sg_iovec32 {
+ u32 iov_base;
+ u32 iov_len;
+} sg_iovec32_t;
+
+static int alloc_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
+{
+ sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);
+ sg_iovec_t *kiov;
+ int i;
+
+ sgp->dxferp = kmalloc(sgp->iovec_count *
+ sizeof(sg_iovec_t), GFP_KERNEL);
+ if (!sgp->dxferp)
+ return -ENOMEM;
+ memset(sgp->dxferp, 0,
+ sgp->iovec_count * sizeof(sg_iovec_t));
+
+ kiov = (sg_iovec_t *) sgp->dxferp;
+ for (i = 0; i < sgp->iovec_count; i++) {
+ u32 iov_base32;
+ if (__get_user(iov_base32, &uiov->iov_base) ||
+ __get_user(kiov->iov_len, &uiov->iov_len))
+ return -EFAULT;
+
+ kiov->iov_base = kmalloc(kiov->iov_len, GFP_KERNEL);
+ if (!kiov->iov_base)
+ return -ENOMEM;
+ if (copy_from_user(kiov->iov_base,
+ (void *) A(iov_base32),
+ kiov->iov_len))
+ return -EFAULT;
+
+ uiov++;
+ kiov++;
+ }
+
+ return 0;
+}
+
+static int copy_back_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
+{
+ sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);
+ sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
+ int i;
+
+ for (i = 0; i < sgp->iovec_count; i++) {
+ u32 iov_base32;
+
+ if (__get_user(iov_base32, &uiov->iov_base))
+ return -EFAULT;
+
+ if (copy_to_user((void *) A(iov_base32),
+ kiov->iov_base,
+ kiov->iov_len))
+ return -EFAULT;
+
+ uiov++;
+ kiov++;
+ }
+
+ return 0;
+}
+
+static void free_sg_iovec(sg_io_hdr_t *sgp)
+{
+ sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
+ int i;
+
+ for (i = 0; i < sgp->iovec_count; i++) {
+ if (kiov->iov_base) {
+ kfree(kiov->iov_base);
+ kiov->iov_base = NULL;
+ }
+ kiov++;
+ }
+ kfree(sgp->dxferp);
+ sgp->dxferp = NULL;
+}
+
+static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ sg_io_hdr32_t *sg_io32;
+ sg_io_hdr_t sg_io64;
+ u32 dxferp32, cmdp32, sbp32;
+ mm_segment_t old_fs;
+ int err = 0;
+
+ sg_io32 = (sg_io_hdr32_t *)arg;
+ err = __get_user(sg_io64.interface_id, &sg_io32->interface_id);
+ err |= __get_user(sg_io64.dxfer_direction, &sg_io32->dxfer_direction);
+ err |= __get_user(sg_io64.cmd_len, &sg_io32->cmd_len);
+ err |= __get_user(sg_io64.mx_sb_len, &sg_io32->mx_sb_len);
+ err |= __get_user(sg_io64.iovec_count, &sg_io32->iovec_count);
+ err |= __get_user(sg_io64.dxfer_len, &sg_io32->dxfer_len);
+ err |= __get_user(sg_io64.timeout, &sg_io32->timeout);
+ err |= __get_user(sg_io64.flags, &sg_io32->flags);
+ err |= __get_user(sg_io64.pack_id, &sg_io32->pack_id);
+
+ sg_io64.dxferp = NULL;
+ sg_io64.cmdp = NULL;
+ sg_io64.sbp = NULL;
+
+ err |= __get_user(cmdp32, &sg_io32->cmdp);
+ sg_io64.cmdp = kmalloc(sg_io64.cmd_len, GFP_KERNEL);
+ if (!sg_io64.cmdp) {
+ err = -ENOMEM;
+ goto out;
+ }
+ if (copy_from_user(sg_io64.cmdp,
+ (void *) A(cmdp32),
+ sg_io64.cmd_len)) {
+ err = -EFAULT;
+ goto out;
+ }
+
+ err |= __get_user(sbp32, &sg_io32->sbp);
+ sg_io64.sbp = kmalloc(sg_io64.mx_sb_len, GFP_KERNEL);
+ if (!sg_io64.sbp) {
+ err = -ENOMEM;
+ goto out;
+ }
+ if (copy_from_user(sg_io64.sbp,
+ (void *) A(sbp32),
+ sg_io64.mx_sb_len)) {
+ err = -EFAULT;
+ goto out;
+ }
+
+ err |= __get_user(dxferp32, &sg_io32->dxferp);
+ if (sg_io64.iovec_count) {
+ int ret;
+
+ if ((ret = alloc_sg_iovec(&sg_io64, dxferp32))) {
+ err = ret;
+ goto out;
+ }
+ } else {
+ sg_io64.dxferp = kmalloc(sg_io64.dxfer_len, GFP_KERNEL);
+ if (!sg_io64.dxferp) {
+ err = -ENOMEM;
+ goto out;
+ }
+ if (copy_from_user(sg_io64.dxferp,
+ (void *) A(dxferp32),
+ sg_io64.dxfer_len)) {
+ err = -EFAULT;
+ goto out;
+ }
+ }
+
+ /* Unused internally, do not even bother to copy it over. */
+ sg_io64.usr_ptr = NULL;
+
+ if (err)
+ return -EFAULT;
+
+ old_fs = get_fs();
+ set_fs (KERNEL_DS);
+ err = sys_ioctl (fd, cmd, (unsigned long) &sg_io64);
+ set_fs (old_fs);
+
+ if (err < 0)
+ goto out;
+
+ err = __put_user(sg_io64.pack_id, &sg_io32->pack_id);
+ err |= __put_user(sg_io64.status, &sg_io32->status);
+ err |= __put_user(sg_io64.masked_status, &sg_io32->masked_status);
+ err |= __put_user(sg_io64.msg_status, &sg_io32->msg_status);
+ err |= __put_user(sg_io64.sb_len_wr, &sg_io32->sb_len_wr);
+ err |= __put_user(sg_io64.host_status, &sg_io32->host_status);
+ err |= __put_user(sg_io64.driver_status, &sg_io32->driver_status);
+ err |= __put_user(sg_io64.resid, &sg_io32->resid);
+ err |= __put_user(sg_io64.duration, &sg_io32->duration);
+ err |= __put_user(sg_io64.info, &sg_io32->info);
+ err |= copy_to_user((void *)A(sbp32), sg_io64.sbp, sg_io64.mx_sb_len);
+ if (sg_io64.dxferp) {
+ if (sg_io64.iovec_count)
+ err |= copy_back_sg_iovec(&sg_io64, dxferp32);
+ else
+ err |= copy_to_user((void *)A(dxferp32),
+ sg_io64.dxferp,
+ sg_io64.dxfer_len);
+ }
+ if (err)
+ err = -EFAULT;
+
+out:
+ if (sg_io64.cmdp)
+ kfree(sg_io64.cmdp);
+ if (sg_io64.sbp)
+ kfree(sg_io64.sbp);
+ if (sg_io64.dxferp) {
+ if (sg_io64.iovec_count) {
+ free_sg_iovec(&sg_io64);
+ } else {
+ kfree(sg_io64.dxferp);
+ }
+ }
+ return err;
+}
+
+struct sock_fprog32 {
+ __u16 len;
+ __u32 filter;
+};
+
+#define PPPIOCSPASS32 _IOW('t', 71, struct sock_fprog32)
+#define PPPIOCSACTIVE32 _IOW('t', 70, struct sock_fprog32)
+
+static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ struct sock_fprog32 *u_fprog32 = (struct sock_fprog32 *) arg;
+ struct sock_fprog *u_fprog64 = alloc_user_space(sizeof(struct sock_fprog));
+ void *fptr64;
+ u32 fptr32;
+ u16 flen;
+
+ if (get_user(flen, &u_fprog32->len) ||
+ get_user(fptr32, &u_fprog32->filter))
+ return -EFAULT;
+
+ fptr64 = (void *) A(fptr32);
+
+ if (put_user(flen, &u_fprog64->len) ||
+ put_user(fptr64, &u_fprog64->filter))
+ return -EFAULT;
+
+ if (cmd == PPPIOCSPASS32)
+ cmd = PPPIOCSPASS;
+ else
+ cmd = PPPIOCSACTIVE;
+
+ return sys_ioctl(fd, cmd, (unsigned long) u_fprog64);
+}
+
struct ppp_option_data32 {
__kernel_caddr_t32 ptr;
__u32 length;
@@ -1308,7 +1649,7 @@ static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
break;
default:
do {
- static int count = 0;
+ static int count;
if (++count <= 20)
printk("ppp_ioctl: Unknown cmd fd(%d) "
"cmd(%08x) arg(%08x)\n",
@@ -1418,7 +1759,7 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
break;
default:
do {
- static int count = 0;
+ static int count;
if (++count <= 20)
printk("mt_ioctl: Unknown cmd fd(%d) "
"cmd(%08x) arg(%08x)\n",
@@ -1536,7 +1877,7 @@ static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long ar
break;
default:
do {
- static int count = 0;
+ static int count;
if (++count <= 20)
printk("cdrom_ioctl: Unknown cmd fd(%d) "
"cmd(%08x) arg(%08x)\n",
@@ -1623,7 +1964,7 @@ static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
}
break;
default: {
- static int count = 0;
+ static int count;
if (++count <= 20)
printk("%s: Unknown loop ioctl cmd, fd(%d) "
"cmd(%08x) arg(%08lx)\n",
@@ -1652,9 +1993,9 @@ static int vt_check(struct file *file)
/*
* To have permissions to do most of the vt ioctls, we either have
- * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
+ * to be the owner of the tty, or super-user.
*/
- if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
+ if (current->tty == tty || capable(CAP_SYS_ADMIN))
return 1;
return 0;
}
@@ -2024,6 +2365,7 @@ typedef struct {
u32 pv[ABS_MAX_PV + 1];
u32 lv[ABS_MAX_LV + 1];
uint8_t vg_uuid[UUID_LEN+1]; /* volume group UUID */
+ uint8_t dummy1[200];
} vg32_t;
typedef struct {
@@ -2138,7 +2480,8 @@ static lv_t *get_lv_t(u32 p, int *errp)
lv_block_exception32_t *lbe32;
lv_block_exception_t *lbe;
lv32_t *ul = (lv32_t *)A(p);
- lv_t *l = (lv_t *)kmalloc(sizeof(lv_t), GFP_KERNEL);
+ lv_t *l = (lv_t *) kmalloc(sizeof(lv_t), GFP_KERNEL);
+
if (!l) {
*errp = -ENOMEM;
return NULL;
@@ -2173,7 +2516,6 @@ static lv_t *get_lv_t(u32 p, int *errp)
err |= __get_user(lbe->rdev_org, &lbe32->rdev_org);
err |= __get_user(lbe->rsector_new, &lbe32->rsector_new);
err |= __get_user(lbe->rdev_new, &lbe32->rdev_new);
-
}
}
}
@@ -2211,7 +2553,7 @@ static int copy_lv_t(u32 ptr, lv_t *l)
static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
- vg_t *v;
+ vg_t *v = NULL;
union {
lv_req_t lv_req;
le_remap_req_t le_remap;
@@ -2229,17 +2571,22 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
switch (cmd) {
case VG_STATUS:
v = kmalloc(sizeof(vg_t), GFP_KERNEL);
- if (!v) return -ENOMEM;
+ if (!v)
+ return -ENOMEM;
karg = v;
break;
+
+ case VG_CREATE_OLD:
case VG_CREATE:
v = kmalloc(sizeof(vg_t), GFP_KERNEL);
- if (!v) return -ENOMEM;
- if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc) ||
- __get_user(v->proc, &((vg32_t *)arg)->proc)) {
+ if (!v)
+ return -ENOMEM;
+ if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc)) {
kfree(v);
return -EFAULT;
}
+ /* 'proc' field is unused, just NULL it out. */
+ v->proc = NULL;
if (copy_from_user(v->vg_uuid, ((vg32_t *)arg)->vg_uuid, UUID_LEN+1)) {
kfree(v);
return -EFAULT;
@@ -2251,94 +2598,117 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
return -EPERM;
for (i = 0; i < v->pv_max; i++) {
err = __get_user(ptr, &((vg32_t *)arg)->pv[i]);
- if (err) break;
+ if (err)
+ break;
if (ptr) {
v->pv[i] = kmalloc(sizeof(pv_t), GFP_KERNEL);
if (!v->pv[i]) {
err = -ENOMEM;
break;
}
- err = copy_from_user(v->pv[i], (void *)A(ptr), sizeof(pv32_t) - 8 - UUID_LEN+1);
+ err = copy_from_user(v->pv[i], (void *)A(ptr),
+ sizeof(pv32_t) - 8 - UUID_LEN+1);
if (err) {
err = -EFAULT;
break;
}
- err = copy_from_user(v->pv[i]->pv_uuid, ((pv32_t *)A(ptr))->pv_uuid, UUID_LEN+1);
+ err = copy_from_user(v->pv[i]->pv_uuid,
+ ((pv32_t *)A(ptr))->pv_uuid,
+ UUID_LEN+1);
if (err) {
err = -EFAULT;
break;
}
-
- v->pv[i]->pe = NULL; v->pv[i]->inode = NULL;
+ v->pv[i]->pe = NULL;
+ v->pv[i]->bd = NULL;
}
}
if (!err) {
for (i = 0; i < v->lv_max; i++) {
err = __get_user(ptr, &((vg32_t *)arg)->lv[i]);
- if (err) break;
+ if (err)
+ break;
if (ptr) {
v->lv[i] = get_lv_t(ptr, &err);
- if (err) break;
+ if (err)
+ break;
}
}
}
break;
+
case LV_CREATE:
case LV_EXTEND:
case LV_REDUCE:
case LV_REMOVE:
case LV_RENAME:
case LV_STATUS_BYNAME:
- err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name));
- if (err) return -EFAULT;
+ err = copy_from_user(&u.pv_status, (void*)arg, sizeof(u.pv_status.pv_name));
+ if (err)
+ return -EFAULT;
if (cmd != LV_REMOVE) {
err = __get_user(ptr, &((lv_req32_t *)arg)->lv);
- if (err) return err;
+ if (err)
+ return err;
u.lv_req.lv = get_lv_t(ptr, &err);
} else
u.lv_req.lv = NULL;
break;
-
case LV_STATUS_BYINDEX:
- err = get_user(u.lv_byindex.lv_index, &((lv_status_byindex_req32_t *)arg)->lv_index);
+ err = get_user(u.lv_byindex.lv_index,
+ &((lv_status_byindex_req32_t *)arg)->lv_index);
err |= __get_user(ptr, &((lv_status_byindex_req32_t *)arg)->lv);
- if (err) return err;
+ if (err)
+ return err;
u.lv_byindex.lv = get_lv_t(ptr, &err);
break;
+
case LV_STATUS_BYDEV:
err = get_user(u.lv_bydev.dev, &((lv_status_bydev_req32_t *)arg)->dev);
+ err |= __get_user(ptr, &((lv_status_bydev_req32_t *)arg)->lv);
+ if (err)
+ return err;
u.lv_bydev.lv = get_lv_t(ptr, &err);
- if (err) return err;
- u.lv_bydev.lv = &p;
- p.pe = NULL; p.inode = NULL;
break;
+
case VG_EXTEND:
err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8 - UUID_LEN+1);
- if (err) return -EFAULT;
+ if (err)
+ return -EFAULT;
err = copy_from_user(p.pv_uuid, ((pv32_t *)arg)->pv_uuid, UUID_LEN+1);
- if (err) return -EFAULT;
- p.pe = NULL; p.inode = NULL;
+ if (err)
+ return -EFAULT;
+ p.pe = NULL;
+ p.bd = NULL;
karg = &p;
break;
+
case PV_CHANGE:
case PV_STATUS:
- err = copy_from_user(&u.pv_status, arg, sizeof(u.lv_req.lv_name));
- if (err) return -EFAULT;
+ err = copy_from_user(&u.pv_status, (void*)arg, sizeof(u.lv_req.lv_name));
+ if (err)
+ return -EFAULT;
err = __get_user(ptr, &((pv_status_req32_t *)arg)->pv);
- if (err) return err;
+ if (err)
+ return err;
u.pv_status.pv = &p;
if (cmd == PV_CHANGE) {
- err = copy_from_user(&p, (void *)A(ptr), sizeof(pv32_t) - 8 - UUID_LEN+1);
- if (err) return -EFAULT;
- p.pe = NULL; p.inode = NULL;
+ err = copy_from_user(&p, (void *)A(ptr),
+ sizeof(pv32_t) - 8 - UUID_LEN+1);
+ if (err)
+ return -EFAULT;
+ p.pe = NULL;
+ p.bd = NULL;
}
break;
- }
+ };
+
old_fs = get_fs(); set_fs (KERNEL_DS);
err = sys_ioctl (fd, cmd, (unsigned long)karg);
set_fs (old_fs);
+
switch (cmd) {
case VG_STATUS:
if (!err) {
@@ -2351,42 +2721,60 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
}
kfree(v);
break;
+
+ case VG_CREATE_OLD:
case VG_CREATE:
- for (i = 0; i < v->pv_max; i++)
- if (v->pv[i]) kfree(v->pv[i]);
- for (i = 0; i < v->lv_max; i++)
- if (v->lv[i]) put_lv_t(v->lv[i]);
+ for (i = 0; i < v->pv_max; i++) {
+ if (v->pv[i])
+ kfree(v->pv[i]);
+ }
+ for (i = 0; i < v->lv_max; i++) {
+ if (v->lv[i])
+ put_lv_t(v->lv[i]);
+ }
kfree(v);
break;
+
case LV_STATUS_BYNAME:
- if (!err && u.lv_req.lv) err = copy_lv_t(ptr, u.lv_req.lv);
+ if (!err && u.lv_req.lv)
+ err = copy_lv_t(ptr, u.lv_req.lv);
/* Fall through */
+
case LV_CREATE:
case LV_EXTEND:
case LV_REDUCE:
- if (u.lv_req.lv) put_lv_t(u.lv_req.lv);
+ if (u.lv_req.lv)
+ put_lv_t(u.lv_req.lv);
break;
+
case LV_STATUS_BYINDEX:
if (u.lv_byindex.lv) {
- if (!err) err = copy_lv_t(ptr, u.lv_byindex.lv);
+ if (!err)
+ err = copy_lv_t(ptr, u.lv_byindex.lv);
put_lv_t(u.lv_byindex.lv);
}
break;
- case PV_STATUS:
- if (!err) {
- err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1);
- if (err) return -EFAULT;
- err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1);
- if (err) return -EFAULT;
- }
- break;
+
case LV_STATUS_BYDEV:
- if (!err) {
- if (!err) err = copy_lv_t(ptr, u.lv_bydev.lv);
+ if (u.lv_bydev.lv) {
+ if (!err)
+ err = copy_lv_t(ptr, u.lv_bydev.lv);
put_lv_t(u.lv_byindex.lv);
}
break;
+
+ case PV_STATUS:
+ if (!err) {
+ err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1);
+ if (err)
+ return -EFAULT;
+ err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1);
+ if (err)
+ return -EFAULT;
}
+ break;
+ };
+
return err;
}
#endif
@@ -2976,7 +3364,11 @@ static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioc
return err;
}
-/* SuSE extension */
+static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
+}
+
#ifndef TIOCGDEV
#define TIOCGDEV _IOR('T',0x32, unsigned int)
#endif
@@ -3088,6 +3480,15 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, void *ptr)
}
+#define REISERFS_IOC_UNPACK32 _IOW(0xCD,1,int)
+
+static int reiserfs_ioctl32(unsigned fd, unsigned cmd, unsigned long ptr)
+{
+ if (cmd == REISERFS_IOC_UNPACK32)
+ cmd = REISERFS_IOC_UNPACK;
+ return sys_ioctl(fd,cmd,ptr);
+}
+
struct dirent32 {
unsigned int d_ino;
__kernel_off_t32 d_off;
@@ -3125,32 +3526,6 @@ static int vfat_ioctl32(unsigned fd, unsigned cmd, void *ptr)
return ret;
}
-
-
-#define REISERFS_IOC_UNPACK32 _IOW(0xCD,1,int)
-
-static int reiserfs_ioctl32(unsigned fd, unsigned cmd, unsigned long ptr)
-{
- if (cmd == REISERFS_IOC_UNPACK32)
- cmd = REISERFS_IOC_UNPACK;
- return sys_ioctl(fd,cmd,ptr);
-}
-
-#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
-
-static int autofs_ioctl32(unsigned fd, unsigned cmd, unsigned long ptr)
-{
- int ret;
- unsigned long val;
- mm_segment_t oldfs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, AUTOFS_IOC_SETTIMEOUT32, (unsigned long)&val);
- set_fs(oldfs);
- if (!ret)
- ret = put_user(val, (int *) ptr);
- return ret;
-}
-
#define RTC_IRQP_READ32 _IOR('p', 0x0b, unsigned int) /* Read IRQ rate */
#define RTC_IRQP_SET32 _IOW('p', 0x0c, unsigned int) /* Set IRQ rate */
#define RTC_EPOCH_READ32 _IOR('p', 0x0d, unsigned) /* Read epoch */
@@ -3190,6 +3565,572 @@ static int rtc32_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
return sys_ioctl(fd,cmd,arg);
}
+/* Fix sizeof(sizeof()) breakage */
+#define BLKELVGET_32 _IOR(0x12,106,int)
+#define BLKELVSET_32 _IOW(0x12,107,int)
+#define BLKBSZGET_32 _IOR(0x12,112,int)
+#define BLKBSZSET_32 _IOW(0x12,113,int)
+#define BLKGETSIZE64_32 _IOR(0x12,114,int)
+
+static int do_blkelvget(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ return sys_ioctl(fd, BLKELVGET, arg);
+}
+
+static int do_blkelvset(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ return sys_ioctl(fd, BLKELVSET, arg);
+}
+
+static int do_blkbszget(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ return sys_ioctl(fd, BLKBSZGET, arg);
+}
+
+static int do_blkbszset(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ return sys_ioctl(fd, BLKBSZSET, arg);
+}
+
+static int do_blkgetsize64(unsigned int fd, unsigned int cmd,
+ unsigned long arg)
+{
+ return sys_ioctl(fd, BLKGETSIZE64, arg);
+}
+
+
+
+struct usbdevfs_ctrltransfer32 {
+ __u8 bRequestType;
+ __u8 bRequest;
+ __u16 wValue;
+ __u16 wIndex;
+ __u16 wLength;
+ __u32 timeout; /* in milliseconds */
+ __u32 data;
+};
+
+#define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
+
+static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ struct usbdevfs_ctrltransfer kctrl;
+ struct usbdevfs_ctrltransfer32 *uctrl;
+ mm_segment_t old_fs;
+ __u32 udata;
+ void *uptr, *kptr;
+ int err;
+
+ uctrl = (struct usbdevfs_ctrltransfer32 *) arg;
+
+ if (copy_from_user(&kctrl, uctrl,
+ (sizeof(struct usbdevfs_ctrltransfer) -
+ sizeof(void *))))
+ return -EFAULT;
+
+ if (get_user(udata, &uctrl->data))
+ return -EFAULT;
+ uptr = (void *) A(udata);
+
+ /* In usbdevice_fs, it limits the control buffer to a page,
+ * for simplicity so do we.
+ */
+ if (!uptr || kctrl.wLength > PAGE_SIZE)
+ return -EINVAL;
+
+ kptr = (void *)__get_free_page(GFP_KERNEL);
+
+ if ((kctrl.bRequestType & 0x80) == 0) {
+ err = -EFAULT;
+ if (copy_from_user(kptr, uptr, kctrl.wLength))
+ goto out;
+ }
+
+ kctrl.data = kptr;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_ioctl(fd, USBDEVFS_CONTROL, (unsigned long)&kctrl);
+ set_fs(old_fs);
+
+ if (err >= 0 &&
+ ((kctrl.bRequestType & 0x80) != 0)) {
+ if (copy_to_user(uptr, kptr, kctrl.wLength))
+ err = -EFAULT;
+ }
+
+out:
+ free_page((unsigned long) kptr);
+ return err;
+}
+
+struct usbdevfs_bulktransfer32 {
+ unsigned int ep;
+ unsigned int len;
+ unsigned int timeout; /* in milliseconds */
+ __u32 data;
+};
+
+#define USBDEVFS_BULK32 _IOWR('U', 2, struct usbdevfs_bulktransfer32)
+
+static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ struct usbdevfs_bulktransfer kbulk;
+ struct usbdevfs_bulktransfer32 *ubulk;
+ mm_segment_t old_fs;
+ __u32 udata;
+ void *uptr, *kptr;
+ int err;
+
+ ubulk = (struct usbdevfs_bulktransfer32 *) arg;
+
+ if (get_user(kbulk.ep, &ubulk->ep) ||
+ get_user(kbulk.len, &ubulk->len) ||
+ get_user(kbulk.timeout, &ubulk->timeout) ||
+ get_user(udata, &ubulk->data))
+ return -EFAULT;
+
+ uptr = (void *) A(udata);
+
+ /* In usbdevice_fs, it limits the control buffer to a page,
+ * for simplicity so do we.
+ */
+ if (!uptr || kbulk.len > PAGE_SIZE)
+ return -EINVAL;
+
+ kptr = (void *) __get_free_page(GFP_KERNEL);
+
+ if ((kbulk.ep & 0x80) == 0) {
+ err = -EFAULT;
+ if (copy_from_user(kptr, uptr, kbulk.len))
+ goto out;
+ }
+
+ kbulk.data = kptr;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_ioctl(fd, USBDEVFS_BULK, (unsigned long) &kbulk);
+ set_fs(old_fs);
+
+ if (err >= 0 &&
+ ((kbulk.ep & 0x80) != 0)) {
+ if (copy_to_user(uptr, kptr, kbulk.len))
+ err = -EFAULT;
+ }
+
+out:
+ free_page((unsigned long) kptr);
+ return err;
+}
+
+/* This needs more work before we can enable it. Unfortunately
+ * because of the fancy asynchronous way URB status/error is written
+ * back to userspace, we'll need to fiddle with USB devio internals
+ * and/or reimplement entirely the frontend of it ourselves. -DaveM
+ *
+ * The issue is:
+ *
+ * When an URB is submitted via usbdevicefs it is put onto an
+ * asynchronous queue. When the URB completes, it may be reaped
+ * via another ioctl. During this reaping the status is written
+ * back to userspace along with the length of the transfer.
+ *
+ * We must translate into 64-bit kernel types so we pass in a kernel
+ * space copy of the usbdevfs_urb structure. This would mean that we
+ * must do something to deal with the async entry reaping. First we
+ * have to deal somehow with this transitory memory we've allocated.
+ * This is problematic since there are many call sites from which the
+ * async entries can be destroyed (and thus when we'd need to free up
+ * this kernel memory). One of which is the close() op of usbdevicefs.
+ * To handle that we'd need to make our own file_operations struct which
+ * overrides usbdevicefs's release op with our own which runs usbdevicefs's
+ * real release op then frees up the kernel memory.
+ *
+ * But how to keep track of these kernel buffers? We'd need to either
+ * keep track of them in some table _or_ know about usbdevicefs internals
+ * (ie. the exact layout of it's file private, which is actually defined
+ * in linux/usbdevice_fs.h, the layout of the async queues are private to
+ * devio.c)
+ *
+ * There is one possible other solution I considered, also involving knowledge
+ * of usbdevicefs internals:
+ *
+ * After an URB is submitted, we "fix up" the address back to the user
+ * space one. This would work if the status/length fields written back
+ * by the async URB completion lines up perfectly in the 32-bit type with
+ * the 64-bit kernel type. Unfortunately, it does not because the iso
+ * frame descriptors, at the end of the struct, can be written back.
+ *
+ * I think we'll just need to simply duplicate the devio URB engine here.
+ */
+#if 0
+struct usbdevfs_urb32 {
+ __u8 type;
+ __u8 endpoint;
+ __s32 status;
+ __u32 flags;
+ __u32 buffer;
+ __s32 buffer_length;
+ __s32 actual_length;
+ __s32 start_frame;
+ __s32 number_of_packets;
+ __s32 error_count;
+ __u32 signr;
+ __u32 usercontext; /* unused */
+ struct usbdevfs_iso_packet_desc iso_frame_desc[0];
+};
+
+#define USBDEVFS_SUBMITURB32 _IOR('U', 10, struct usbdevfs_urb32)
+
+static int get_urb32(struct usbdevfs_urb *kurb,
+ struct usbdevfs_urb32 *uurb)
+{
+ if (get_user(kurb->type, &uurb->type) ||
+ __get_user(kurb->endpoint, &uurb->endpoint) ||
+ __get_user(kurb->status, &uurb->status) ||
+ __get_user(kurb->flags, &uurb->flags) ||
+ __get_user(kurb->buffer_length, &uurb->buffer_length) ||
+ __get_user(kurb->actual_length, &uurb->actual_length) ||
+ __get_user(kurb->start_frame, &uurb->start_frame) ||
+ __get_user(kurb->number_of_packets, &uurb->number_of_packets) ||
+ __get_user(kurb->error_count, &uurb->error_count) ||
+ __get_user(kurb->signr, &uurb->signr))
+ return -EFAULT;
+
+ kurb->usercontext = 0; /* unused currently */
+
+ return 0;
+}
+
+/* Just put back the values which usbdevfs actually changes. */
+static int put_urb32(struct usbdevfs_urb *kurb,
+ struct usbdevfs_urb32 *uurb)
+{
+ if (put_user(kurb->status, &uurb->status) ||
+ __put_user(kurb->actual_length, &uurb->actual_length) ||
+ __put_user(kurb->error_count, &uurb->error_count))
+ return -EFAULT;
+
+ if (kurb->number_of_packets != 0) {
+ int i;
+
+ for (i = 0; i < kurb->number_of_packets; i++) {
+ if (__put_user(kurb->iso_frame_desc[i].actual_length,
+ &uurb->iso_frame_desc[i].actual_length) ||
+ __put_user(kurb->iso_frame_desc[i].status,
+ &uurb->iso_frame_desc[i].status))
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
+static int get_urb32_isoframes(struct usbdevfs_urb *kurb,
+ struct usbdevfs_urb32 *uurb)
+{
+ unsigned int totlen;
+ int i;
+
+ if (kurb->type != USBDEVFS_URB_TYPE_ISO) {
+ kurb->number_of_packets = 0;
+ return 0;
+ }
+
+ if (kurb->number_of_packets < 1 ||
+ kurb->number_of_packets > 128)
+ return -EINVAL;
+
+ if (copy_from_user(&kurb->iso_frame_desc[0],
+ &uurb->iso_frame_desc[0],
+ sizeof(struct usbdevfs_iso_packet_desc) *
+ kurb->number_of_packets))
+ return -EFAULT;
+
+ totlen = 0;
+ for (i = 0; i < kurb->number_of_packets; i++) {
+ unsigned int this_len;
+
+ this_len = kurb->iso_frame_desc[i].length;
+ if (this_len > 1023)
+ return -EINVAL;
+
+ totlen += this_len;
+ }
+
+ if (totlen > 32768)
+ return -EINVAL;
+
+ kurb->buffer_length = totlen;
+
+ return 0;
+}
+
+static int do_usbdevfs_urb(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ struct usbdevfs_urb *kurb;
+ struct usbdevfs_urb32 *uurb;
+ mm_segment_t old_fs;
+ __u32 udata;
+ void *uptr, *kptr;
+ unsigned int buflen;
+ int err;
+
+ uurb = (struct usbdevfs_urb32 *) arg;
+
+ err = -ENOMEM;
+ kurb = kmalloc(sizeof(struct usbdevfs_urb) +
+ (sizeof(struct usbdevfs_iso_packet_desc) * 128),
+ GFP_KERNEL);
+ if (!kurb)
+ goto out;
+
+ err = -EFAULT;
+ if (get_urb32(kurb, uurb))
+ goto out;
+
+ err = get_urb32_isoframes(kurb, uurb);
+ if (err)
+ goto out;
+
+ err = -EFAULT;
+ if (__get_user(udata, &uurb->buffer))
+ goto out;
+ uptr = (void *) A(udata);
+
+ err = -ENOMEM;
+ buflen = kurb->buffer_length;
+ kptr = kmalloc(buflen, GFP_KERNEL);
+ if (!kptr)
+ goto out;
+
+ kurb->buffer = kptr;
+
+ err = -EFAULT;
+ if (copy_from_user(kptr, uptr, buflen))
+ goto out_kptr;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_ioctl(fd, USBDEVFS_SUBMITURB, (unsigned long) kurb);
+ set_fs(old_fs);
+
+ if (err >= 0) {
+ /* RED-PEN Shit, this doesn't work for async URBs :-( XXX */
+ if (put_urb32(kurb, uurb)) {
+ err = -EFAULT;
+ } else if ((kurb->endpoint & USB_DIR_IN) != 0) {
+ if (copy_to_user(uptr, kptr, buflen))
+ err = -EFAULT;
+ }
+ }
+
+out_kptr:
+ kfree(kptr);
+
+out:
+ kfree(kurb);
+ return err;
+}
+#endif
+
+#define USBDEVFS_REAPURB32 _IOW('U', 12, u32)
+#define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, u32)
+
+static int do_usbdevfs_reapurb(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ mm_segment_t old_fs;
+ void *kptr;
+ int err;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_ioctl(fd,
+ (cmd == USBDEVFS_REAPURB32 ?
+ USBDEVFS_REAPURB :
+ USBDEVFS_REAPURBNDELAY),
+ (unsigned long) &kptr);
+ set_fs(old_fs);
+
+ if (err >= 0 &&
+ put_user(((u32)(long)kptr), (u32 *) A(arg)))
+ err = -EFAULT;
+
+ return err;
+}
+
+struct usbdevfs_disconnectsignal32 {
+ unsigned int signr;
+ u32 context;
+};
+
+#define USBDEVFS_DISCSIGNAL32 _IOR('U', 14, struct usbdevfs_disconnectsignal32)
+
+static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ struct usbdevfs_disconnectsignal kdis;
+ struct usbdevfs_disconnectsignal32 *udis;
+ mm_segment_t old_fs;
+ u32 uctx;
+ int err;
+
+ udis = (struct usbdevfs_disconnectsignal32 *) arg;
+
+ if (get_user(kdis.signr, &udis->signr) ||
+ __get_user(uctx, &udis->context))
+ return -EFAULT;
+
+ kdis.context = (void *) (long)uctx;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_ioctl(fd, USBDEVFS_DISCSIGNAL, (unsigned long) &kdis);
+ set_fs(old_fs);
+
+ return err;
+}
+
+struct mtd_oob_buf32 {
+ u32 start;
+ u32 length;
+ u32 ptr; /* unsigned char* */
+};
+
+#define MEMWRITEOOB32 _IOWR('M',3,struct mtd_oob_buf32)
+#define MEMREADOOB32 _IOWR('M',4,struct mtd_oob_buf32)
+
+static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ mm_segment_t old_fs = get_fs();
+ struct mtd_oob_buf32 *uarg = (struct mtd_oob_buf32 *)arg;
+ struct mtd_oob_buf karg;
+ u32 tmp;
+ char *ptr;
+ int ret;
+
+ if (get_user(karg.start, &uarg->start) ||
+ get_user(karg.length, &uarg->length) ||
+ get_user(tmp, &uarg->ptr))
+ return -EFAULT;
+
+ ptr = (char *)A(tmp);
+ if (0 >= karg.length)
+ return -EINVAL;
+
+ karg.ptr = kmalloc(karg.length, GFP_KERNEL);
+ if (NULL == karg.ptr)
+ return -ENOMEM;
+
+ if (copy_from_user(karg.ptr, ptr, karg.length)) {
+ kfree(karg.ptr);
+ return -EFAULT;
+ }
+
+ set_fs(KERNEL_DS);
+ if (MEMREADOOB32 == cmd)
+ ret = sys_ioctl(fd, MEMREADOOB, (unsigned long)&karg);
+ else if (MEMWRITEOOB32 == cmd)
+ ret = sys_ioctl(fd, MEMWRITEOOB, (unsigned long)&karg);
+ else
+ ret = -EINVAL;
+ set_fs(old_fs);
+
+ if (0 == ret && cmd == MEMREADOOB32) {
+ ret = copy_to_user(ptr, karg.ptr, karg.length);
+ ret |= put_user(karg.start, &uarg->start);
+ ret |= put_user(karg.length, &uarg->length);
+ }
+
+ kfree(karg.ptr);
+ return ((0 == ret) ? 0 : -EFAULT);
+}
+
+/* /proc/mtrr ioctls */
+
+
+struct mtrr_sentry32
+{
+ unsigned int base; /* Base address */
+ unsigned int size; /* Size of region */
+ unsigned int type; /* Type of region */
+};
+
+struct mtrr_gentry32
+{
+ unsigned int regnum; /* Register number */
+ unsigned int base; /* Base address */
+ unsigned int size; /* Size of region */
+ unsigned int type; /* Type of region */
+};
+
+#define MTRR_IOCTL_BASE 'M'
+
+#define MTRRIOC32_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry32)
+#define MTRRIOC32_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry32)
+#define MTRRIOC32_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry32)
+#define MTRRIOC32_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32)
+#define MTRRIOC32_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry32)
+#define MTRRIOC32_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry32)
+#define MTRRIOC32_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry32)
+#define MTRRIOC32_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry32)
+#define MTRRIOC32_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32)
+#define MTRRIOC32_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry32)
+
+
+static int mtrr_ioctl32(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ struct mtrr_gentry g;
+ struct mtrr_sentry s;
+ int get = 0, err = 0;
+ struct mtrr_gentry32 *g32 = (struct mtrr_gentry32 *)arg;
+ mm_segment_t oldfs = get_fs();
+
+ switch (cmd) {
+#define SET(x) case MTRRIOC32_ ## x ## _ENTRY: cmd = MTRRIOC_ ## x ## _ENTRY; break
+#define GET(x) case MTRRIOC32_ ## x ## _ENTRY: cmd = MTRRIOC_ ## x ## _ENTRY; get=1; break
+ SET(ADD);
+ SET(SET);
+ SET(DEL);
+ GET(GET);
+ SET(KILL);
+ SET(ADD_PAGE);
+ SET(SET_PAGE);
+ SET(DEL_PAGE);
+ GET(GET_PAGE);
+ SET(KILL_PAGE);
+ }
+
+ if (get) {
+ err = get_user(g.regnum, &g32->regnum);
+ err |= get_user(g.base, &g32->base);
+ err |= get_user(g.size, &g32->size);
+ err |= get_user(g.type, &g32->type);
+
+ arg = (unsigned long)&g;
+ } else {
+ struct mtrr_sentry32 *s32 = (struct mtrr_sentry32 *)arg;
+ err = get_user(s.base, &s32->base);
+ err |= get_user(s.size, &s32->size);
+ err |= get_user(s.type, &s32->type);
+
+ arg = (unsigned long)&s;
+ }
+ if (err) return err;
+
+ set_fs(KERNEL_DS);
+ err = sys_ioctl(fd, cmd, arg);
+ set_fs(oldfs);
+
+ if (!err && get) {
+ err = put_user(g.base, &g32->base);
+ err |= put_user(g.size, &g32->size);
+ err |= put_user(g.regnum, &g32->regnum);
+ err |= put_user(g.type, &g32->type);
+ }
+ return err;
+}
+
struct ioctl_trans {
unsigned long cmd;
int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
@@ -3220,7 +4161,6 @@ COMPATIBLE_IOCTL(TCSETS)
COMPATIBLE_IOCTL(TCSETSW)
COMPATIBLE_IOCTL(TCSETSF)
COMPATIBLE_IOCTL(TIOCLINUX)
-HANDLE_IOCTL(TIOCGDEV, tiocgdev)
/* Little t */
COMPATIBLE_IOCTL(TIOCGETD)
COMPATIBLE_IOCTL(TIOCSETD)
@@ -3245,6 +4185,7 @@ COMPATIBLE_IOCTL(TIOCSCTTY)
COMPATIBLE_IOCTL(TIOCGPTN)
COMPATIBLE_IOCTL(TIOCSPTLCK)
COMPATIBLE_IOCTL(TIOCSERGETLSR)
+/* Big F */
COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO)
COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
COMPATIBLE_IOCTL(FBIOPAN_DISPLAY)
@@ -3269,12 +4210,14 @@ COMPATIBLE_IOCTL(FIGETBSZ)
*/
COMPATIBLE_IOCTL(HDIO_GET_IDENTITY)
COMPATIBLE_IOCTL(HDIO_SET_DMA)
+COMPATIBLE_IOCTL(HDIO_SET_KEEPSETTINGS)
COMPATIBLE_IOCTL(HDIO_SET_UNMASKINTR)
COMPATIBLE_IOCTL(HDIO_SET_NOWERR)
COMPATIBLE_IOCTL(HDIO_SET_32BIT)
COMPATIBLE_IOCTL(HDIO_SET_MULTCOUNT)
COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE)
+COMPATIBLE_IOCTL(HDIO_SCAN_HWIF)
COMPATIBLE_IOCTL(HDIO_SET_NICE)
/* 0x02 -- Floppy ioctls */
COMPATIBLE_IOCTL(FDMSGON)
@@ -3302,7 +4245,6 @@ COMPATIBLE_IOCTL(BLKRASET)
COMPATIBLE_IOCTL(BLKFRASET)
COMPATIBLE_IOCTL(BLKSECTSET)
COMPATIBLE_IOCTL(BLKSSZGET)
-
/* RAID */
COMPATIBLE_IOCTL(RAID_VERSION)
COMPATIBLE_IOCTL(GET_ARRAY_INFO)
@@ -3323,7 +4265,6 @@ COMPATIBLE_IOCTL(START_ARRAY)
COMPATIBLE_IOCTL(STOP_ARRAY)
COMPATIBLE_IOCTL(STOP_ARRAY_RO)
COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
-
/* Big K */
COMPATIBLE_IOCTL(PIO_FONT)
COMPATIBLE_IOCTL(GIO_FONT)
@@ -3345,6 +4286,7 @@ COMPATIBLE_IOCTL(KDGKBSENT)
COMPATIBLE_IOCTL(KDSKBSENT)
COMPATIBLE_IOCTL(KDGKBDIACR)
COMPATIBLE_IOCTL(KDSKBDIACR)
+COMPATIBLE_IOCTL(KDKBDREP)
COMPATIBLE_IOCTL(KDGKBLED)
COMPATIBLE_IOCTL(KDSKBLED)
COMPATIBLE_IOCTL(KDGETLED)
@@ -3364,6 +4306,14 @@ COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_ENABLE)
COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_DISABLE)
COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER)
COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
+COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST)
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI)
+/* Big T */
+COMPATIBLE_IOCTL(TUNSETNOCSUM)
+COMPATIBLE_IOCTL(TUNSETDEBUG)
+COMPATIBLE_IOCTL(TUNSETIFF)
+COMPATIBLE_IOCTL(TUNSETPERSIST)
+COMPATIBLE_IOCTL(TUNSETOWNER)
/* Big V */
COMPATIBLE_IOCTL(VT_SETMODE)
COMPATIBLE_IOCTL(VT_GETMODE)
@@ -3377,7 +4327,8 @@ COMPATIBLE_IOCTL(VT_RESIZE)
COMPATIBLE_IOCTL(VT_RESIZEX)
COMPATIBLE_IOCTL(VT_LOCKSWITCH)
COMPATIBLE_IOCTL(VT_UNLOCKSWITCH)
-/* Little v, the video4linux ioctls */
+/* Little v */
+/* Little v, the video4linux ioctls (conflict?) */
COMPATIBLE_IOCTL(VIDIOCGCAP)
COMPATIBLE_IOCTL(VIDIOCGCHAN)
COMPATIBLE_IOCTL(VIDIOCSCHAN)
@@ -3417,10 +4368,6 @@ COMPATIBLE_IOCTL(RTC_RD_TIME)
COMPATIBLE_IOCTL(RTC_SET_TIME)
COMPATIBLE_IOCTL(RTC_WKALM_SET)
COMPATIBLE_IOCTL(RTC_WKALM_RD)
-HANDLE_IOCTL(RTC_IRQP_READ32,rtc32_ioctl)
-HANDLE_IOCTL(RTC_IRQP_SET32,rtc32_ioctl)
-HANDLE_IOCTL(RTC_EPOCH_READ32, rtc32_ioctl)
-HANDLE_IOCTL(RTC_EPOCH_SET32, rtc32_ioctl)
/* Little m */
COMPATIBLE_IOCTL(MTIOCTOP)
/* Socket level stuff */
@@ -3442,6 +4389,11 @@ COMPATIBLE_IOCTL(SIOCGRARP)
COMPATIBLE_IOCTL(SIOCDRARP)
COMPATIBLE_IOCTL(SIOCADDDLCI)
COMPATIBLE_IOCTL(SIOCDELDLCI)
+COMPATIBLE_IOCTL(SIOCGMIIPHY)
+COMPATIBLE_IOCTL(SIOCGMIIREG)
+COMPATIBLE_IOCTL(SIOCSMIIREG)
+COMPATIBLE_IOCTL(SIOCGIFVLAN)
+COMPATIBLE_IOCTL(SIOCSIFVLAN)
/* SG stuff */
COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
@@ -3463,7 +4415,6 @@ COMPATIBLE_IOCTL(SG_SET_COMMAND_Q)
COMPATIBLE_IOCTL(SG_GET_VERSION_NUM)
COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN)
COMPATIBLE_IOCTL(SG_SCSI_RESET)
-COMPATIBLE_IOCTL(SG_IO)
COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)
COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN)
COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN)
@@ -3481,10 +4432,14 @@ COMPATIBLE_IOCTL(PPPIOCSMAXCID)
COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP)
COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP)
COMPATIBLE_IOCTL(PPPIOCXFERUNIT)
+/* PPPIOCSCOMPRESS is translated */
COMPATIBLE_IOCTL(PPPIOCGNPMODE)
COMPATIBLE_IOCTL(PPPIOCSNPMODE)
COMPATIBLE_IOCTL(PPPIOCGDEBUG)
COMPATIBLE_IOCTL(PPPIOCSDEBUG)
+/* PPPIOCSPASS is translated */
+/* PPPIOCSACTIVE is translated */
+/* PPPIOCGIDLE is translated */
COMPATIBLE_IOCTL(PPPIOCNEWUNIT)
COMPATIBLE_IOCTL(PPPIOCATTACH)
COMPATIBLE_IOCTL(PPPIOCDETACH)
@@ -3494,8 +4449,10 @@ COMPATIBLE_IOCTL(PPPIOCDISCONN)
COMPATIBLE_IOCTL(PPPIOCATTCHAN)
COMPATIBLE_IOCTL(PPPIOCGCHAN)
/* PPPOX */
-COMPATIBLE_IOCTL(PPPOEIOCSFWD);
-COMPATIBLE_IOCTL(PPPOEIOCDFWD);
+COMPATIBLE_IOCTL(PPPOEIOCSFWD)
+COMPATIBLE_IOCTL(PPPOEIOCDFWD)
+/* LP */
+COMPATIBLE_IOCTL(LPGETSTATUS)
/* CDROM stuff */
COMPATIBLE_IOCTL(CDROMPAUSE)
COMPATIBLE_IOCTL(CDROMRESUME)
@@ -3527,9 +4484,15 @@ COMPATIBLE_IOCTL(CDROM_CHANGER_NSLOTS)
COMPATIBLE_IOCTL(CDROM_LOCKDOOR)
COMPATIBLE_IOCTL(CDROM_DEBUG)
COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY)
+/* DVD ioctls */
+COMPATIBLE_IOCTL(DVD_READ_STRUCT)
+COMPATIBLE_IOCTL(DVD_WRITE_STRUCT)
+COMPATIBLE_IOCTL(DVD_AUTH)
/* Big L */
COMPATIBLE_IOCTL(LOOP_SET_FD)
COMPATIBLE_IOCTL(LOOP_CLR_FD)
+/* Big A */
+/* sparc only */
/* Big Q for sound/OSS */
COMPATIBLE_IOCTL(SNDCTL_SEQ_RESET)
COMPATIBLE_IOCTL(SNDCTL_SEQ_SYNC)
@@ -3688,7 +4651,6 @@ COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL)
COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
-HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, autofs_ioctl32);
/* DEVFS */
COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV)
COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK)
@@ -3755,15 +4717,68 @@ COMPATIBLE_IOCTL(DRM_IOCTL_LOCK)
COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK)
COMPATIBLE_IOCTL(DRM_IOCTL_FINISH)
#endif /* DRM */
-HANDLE_IOCTL(REISERFS_IOC_UNPACK32, reiserfs_ioctl32);
-HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32);
-HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32);
-/* serial driver */
-HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl);
-HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl);
-/* elevator */
-COMPATIBLE_IOCTL(BLKELVGET)
-COMPATIBLE_IOCTL(BLKELVSET)
+#ifdef CONFIG_AUTOFS_FS
+COMPATIBLE_IOCTL(AUTOFS_IOC_READY)
+COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL)
+COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
+COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
+COMPATIBLE_IOCTL(AUTOFS_IOC_SETTIMEOUT)
+COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
+#endif
+#ifdef CONFIG_RTC
+COMPATIBLE_IOCTL(RTC_AIE_ON)
+COMPATIBLE_IOCTL(RTC_AIE_OFF)
+COMPATIBLE_IOCTL(RTC_UIE_ON)
+COMPATIBLE_IOCTL(RTC_UIE_OFF)
+COMPATIBLE_IOCTL(RTC_PIE_ON)
+COMPATIBLE_IOCTL(RTC_PIE_OFF)
+COMPATIBLE_IOCTL(RTC_WIE_ON)
+COMPATIBLE_IOCTL(RTC_WIE_OFF)
+COMPATIBLE_IOCTL(RTC_ALM_SET)
+COMPATIBLE_IOCTL(RTC_ALM_READ)
+COMPATIBLE_IOCTL(RTC_RD_TIME)
+COMPATIBLE_IOCTL(RTC_SET_TIME)
+COMPATIBLE_IOCTL(RTC_WKALM_SET)
+COMPATIBLE_IOCTL(RTC_WKALM_RD)
+#endif
+/* Big W */
+/* WIOC_GETSUPPORT not yet implemented -E */
+COMPATIBLE_IOCTL(WDIOC_GETSTATUS)
+COMPATIBLE_IOCTL(WDIOC_GETBOOTSTATUS)
+COMPATIBLE_IOCTL(WDIOC_GETTEMP)
+COMPATIBLE_IOCTL(WDIOC_SETOPTIONS)
+COMPATIBLE_IOCTL(WDIOC_KEEPALIVE)
+#if 0 /* sparc only ? */
+COMPATIBLE_IOCTL(WIOCSTART)
+COMPATIBLE_IOCTL(WIOCSTOP)
+COMPATIBLE_IOCTL(WIOCGSTAT)
+#endif
+/* Big R */
+COMPATIBLE_IOCTL(RNDGETENTCNT)
+COMPATIBLE_IOCTL(RNDADDTOENTCNT)
+COMPATIBLE_IOCTL(RNDGETPOOL)
+COMPATIBLE_IOCTL(RNDADDENTROPY)
+COMPATIBLE_IOCTL(RNDZAPENTCNT)
+COMPATIBLE_IOCTL(RNDCLEARPOOL)
+/* Bluetooth ioctls */
+COMPATIBLE_IOCTL(HCIDEVUP)
+COMPATIBLE_IOCTL(HCIDEVDOWN)
+COMPATIBLE_IOCTL(HCIDEVRESET)
+COMPATIBLE_IOCTL(HCIDEVRESTAT)
+COMPATIBLE_IOCTL(HCIGETDEVLIST)
+COMPATIBLE_IOCTL(HCIGETDEVINFO)
+COMPATIBLE_IOCTL(HCIGETCONNLIST)
+COMPATIBLE_IOCTL(HCIGETCONNINFO)
+COMPATIBLE_IOCTL(HCISETRAW)
+COMPATIBLE_IOCTL(HCISETSCAN)
+COMPATIBLE_IOCTL(HCISETAUTH)
+COMPATIBLE_IOCTL(HCISETENCRYPT)
+COMPATIBLE_IOCTL(HCISETPTYPE)
+COMPATIBLE_IOCTL(HCISETLINKPOL)
+COMPATIBLE_IOCTL(HCISETLINKMODE)
+COMPATIBLE_IOCTL(HCISETACLMTU)
+COMPATIBLE_IOCTL(HCISETSCOMTU)
+COMPATIBLE_IOCTL(HCIINQUIRY)
/* Misc. */
COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */
COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */
@@ -3771,8 +4786,46 @@ COMPATIBLE_IOCTL(PCIIOC_CONTROLLER)
COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO)
COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM)
COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE)
+COMPATIBLE_IOCTL(0x4B50); /* KDGHWCLK - not in the kernel, but don't complain */
+COMPATIBLE_IOCTL(0x4B51); /* KDSHWCLK - not in the kernel, but don't complain */
+/* USB */
+COMPATIBLE_IOCTL(USBDEVFS_RESETEP)
+COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE)
+COMPATIBLE_IOCTL(USBDEVFS_SETCONFIGURATION)
+COMPATIBLE_IOCTL(USBDEVFS_GETDRIVER)
+COMPATIBLE_IOCTL(USBDEVFS_DISCARDURB)
+COMPATIBLE_IOCTL(USBDEVFS_CLAIMINTERFACE)
+COMPATIBLE_IOCTL(USBDEVFS_RELEASEINTERFACE)
+COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO)
+COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO)
+COMPATIBLE_IOCTL(USBDEVFS_RESET)
+COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT)
+/* MTD */
+COMPATIBLE_IOCTL(MEMGETINFO)
+COMPATIBLE_IOCTL(MEMERASE)
+COMPATIBLE_IOCTL(MEMLOCK)
+COMPATIBLE_IOCTL(MEMUNLOCK)
+COMPATIBLE_IOCTL(MEMGETREGIONCOUNT)
+COMPATIBLE_IOCTL(MEMGETREGIONINFO)
+/* NBD */
+COMPATIBLE_IOCTL(NBD_SET_SOCK)
+COMPATIBLE_IOCTL(NBD_SET_BLKSIZE)
+COMPATIBLE_IOCTL(NBD_SET_SIZE)
+COMPATIBLE_IOCTL(NBD_DO_IT)
+COMPATIBLE_IOCTL(NBD_CLEAR_SOCK)
+COMPATIBLE_IOCTL(NBD_CLEAR_QUE)
+COMPATIBLE_IOCTL(NBD_PRINT_DEBUG)
+COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS)
+COMPATIBLE_IOCTL(NBD_DISCONNECT)
/* And these ioctls need translation */
+HANDLE_IOCTL(TIOCGDEV, tiocgdev)
+HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl)
+HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl)
+HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob)
+HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob)
+#ifdef CONFIG_NET
HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32)
+#endif
HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf)
HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc)
HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc)
@@ -3799,26 +4852,42 @@ HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc)
HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc)
HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc)
HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc)
-HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc)
-HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
-HANDLE_IOCTL(SIOCGPPPVER, dev_ifsioc)
HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc)
HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc)
HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl)
+HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl)
+HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl)
+HANDLE_IOCTL(SIOCBONDSETHWADDR, bond_ioctl)
+HANDLE_IOCTL(SIOCBONDSLAVEINFOQUERY, bond_ioctl)
+HANDLE_IOCTL(SIOCBONDINFOQUERY, bond_ioctl)
+HANDLE_IOCTL(SIOCBONDCHANGEACTIVE, bond_ioctl)
HANDLE_IOCTL(SIOCADDRT, routing_ioctl)
HANDLE_IOCTL(SIOCDELRT, routing_ioctl)
+/* realtime device */
+HANDLE_IOCTL(RTC_IRQP_READ, rtc32_ioctl)
+HANDLE_IOCTL(RTC_IRQP_READ32,rtc32_ioctl)
+HANDLE_IOCTL(RTC_IRQP_SET32, rtc32_ioctl)
+HANDLE_IOCTL(RTC_EPOCH_READ32, rtc32_ioctl)
+HANDLE_IOCTL(RTC_EPOCH_SET32, rtc32_ioctl)
+HANDLE_IOCTL(REISERFS_IOC_UNPACK32, reiserfs_ioctl32)
+HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)
+HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32)
/* Raw devices */
HANDLE_IOCTL(RAW_SETBIND, raw_ioctl)
/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
HANDLE_IOCTL(SIOCRTMSG, ret_einval)
HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp)
HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo)
+HANDLE_IOCTL(BLKRAGET, w_long)
HANDLE_IOCTL(BLKGETSIZE, w_long)
HANDLE_IOCTL(0x1260, broken_blkgetsize)
+HANDLE_IOCTL(BLKFRAGET, w_long)
HANDLE_IOCTL(BLKSECTGET, w_long)
+HANDLE_IOCTL(FBIOGET_FSCREENINFO, fb_ioctl_trans)
HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans)
HANDLE_IOCTL(FBIOGETCMAP, fb_ioctl_trans)
HANDLE_IOCTL(FBIOPUTCMAP, fb_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans)
HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans)
HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans)
HANDLE_IOCTL(HDIO_GET_32BIT, hdio_ioctl_trans)
@@ -3834,8 +4903,11 @@ HANDLE_IOCTL(FDGETDRVSTAT32, fd_ioctl_trans)
HANDLE_IOCTL(FDPOLLDRVSTAT32, fd_ioctl_trans)
HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans)
HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans)
+HANDLE_IOCTL(SG_IO,sg_ioctl_trans)
HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans)
HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans)
+HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans)
+HANDLE_IOCTL(PPPIOCSACTIVE32, ppp_sock_fprog_ioctl_trans)
HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans)
HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans)
HANDLE_IOCTL(MTIOCGETCONFIG32, mt_ioctl_trans)
@@ -3849,6 +4921,8 @@ HANDLE_IOCTL(CDROMREADALL, cdrom_ioctl_trans)
HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans)
HANDLE_IOCTL(LOOP_SET_STATUS, loop_status)
HANDLE_IOCTL(LOOP_GET_STATUS, loop_status)
+#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
+HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout)
HANDLE_IOCTL(PIO_FONTX, do_fontx_ioctl)
HANDLE_IOCTL(GIO_FONTX, do_fontx_ioctl)
HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl)
@@ -3907,18 +4981,48 @@ HANDLE_IOCTL(LV_STATUS_BYNAME, do_lvm_ioctl)
HANDLE_IOCTL(LV_STATUS_BYINDEX, do_lvm_ioctl)
HANDLE_IOCTL(PV_CHANGE, do_lvm_ioctl)
HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl)
+HANDLE_IOCTL(VG_CREATE_OLD, do_lvm_ioctl)
+HANDLE_IOCTL(LV_STATUS_BYDEV, do_lvm_ioctl)
#endif /* LVM */
#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version);
-HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique);
-HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique);
-HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap);
-HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma);
-HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx);
+HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version)
+HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique)
+HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique)
+HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap)
+HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs)
+HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs)
+HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs)
+HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma)
+HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx)
#endif /* DRM */
+/* VFAT */
+HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)
+HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32)
+HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
+HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
+/*HANDLE_IOCTL(USBDEVFS_SUBMITURB32, do_usbdevfs_urb)*/
+HANDLE_IOCTL(USBDEVFS_REAPURB32, do_usbdevfs_reapurb)
+HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb)
+HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
+/* take care of sizeof(sizeof()) breakage */
+/* elevator */
+HANDLE_IOCTL(BLKELVGET_32, do_blkelvget)
+HANDLE_IOCTL(BLKELVSET_32, do_blkelvset)
+/* block stuff */
+HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget)
+HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset)
+HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64)
+/* mtrr */
+HANDLE_IOCTL(MTRRIOC32_ADD_ENTRY, mtrr_ioctl32)
+HANDLE_IOCTL(MTRRIOC32_SET_ENTRY, mtrr_ioctl32)
+HANDLE_IOCTL(MTRRIOC32_DEL_ENTRY, mtrr_ioctl32)
+HANDLE_IOCTL(MTRRIOC32_GET_ENTRY, mtrr_ioctl32)
+HANDLE_IOCTL(MTRRIOC32_KILL_ENTRY, mtrr_ioctl32)
+HANDLE_IOCTL(MTRRIOC32_ADD_PAGE_ENTRY, mtrr_ioctl32)
+HANDLE_IOCTL(MTRRIOC32_SET_PAGE_ENTRY, mtrr_ioctl32)
+HANDLE_IOCTL(MTRRIOC32_DEL_PAGE_ENTRY, mtrr_ioctl32)
+HANDLE_IOCTL(MTRRIOC32_GET_PAGE_ENTRY, mtrr_ioctl32)
+HANDLE_IOCTL(MTRRIOC32_KILL_PAGE_ENTRY, mtrr_ioctl32)
IOCTL_TABLE_END
#define IOCTL_HASHSIZE 256
@@ -3926,6 +5030,8 @@ struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE];
extern struct ioctl_trans ioctl_start[], ioctl_end[];
+extern struct ioctl_trans ioctl_start[], ioctl_end[];
+
static inline unsigned long ioctl32_hash(unsigned long cmd)
{
return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE;
@@ -4022,7 +5128,7 @@ static inline int builtin_ioctl(struct ioctl_trans *t)
/* Problem:
This function cannot unregister duplicate ioctls, because they are not
unique.
- When they happen we need to extend the prototype to pass handler too. */
+ When they happen we need to extend the prototype to pass the handler too. */
int unregister_ioctl32_conversion(unsigned int cmd)
{
@@ -4096,13 +5202,35 @@ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
if (t) {
handler = t->handler;
error = handler(fd, cmd, arg, filp);
+ } else if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
+ error = siocdevprivate_ioctl(fd, cmd, arg);
} else {
- static int count = 0;
- if (++count <= 50)
- printk("sys32_ioctl(%s:%d): Unknown cmd fd(%d) "
- "cmd(%08x) arg(%08x)\n",
+ static int count;
+ if (++count <= 50) {
+ char buf[10];
+ char *path = (char *)__get_free_page(GFP_KERNEL), *fn = "?";
+
+ /* find the name of the device. */
+ if (path) {
+ struct file *f = fget(fd);
+ if (f) {
+ fn = d_path(f->f_dentry, f->f_vfsmnt,
+ path, PAGE_SIZE);
+ fput(f);
+ }
+ }
+
+ sprintf(buf,"'%c'", (cmd>>24) & 0x3f);
+ if (!isprint(buf[1]))
+ sprintf(buf, "%02x", buf[1]);
+ printk("ioctl32(%s:%d): Unknown cmd fd(%d) "
+ "cmd(%08x){%s} arg(%08x) on %s\n",
current->comm, current->pid,
- (int)fd, (unsigned int)cmd, (unsigned int)arg);
+ (int)fd, (unsigned int)cmd, buf, (unsigned int)arg,
+ fn);
+ if (path)
+ free_page((unsigned long)path);
+ }
error = -EINVAL;
}
out:
@@ -4110,3 +5238,4 @@ out:
out2:
return error;
}
+
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
index 5274839f0e34..782e6144eedf 100644
--- a/arch/x86_64/ia32/ia32_signal.c
+++ b/arch/x86_64/ia32/ia32_signal.c
@@ -7,7 +7,7 @@
* 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes
* 2000-12-* x86-64 compatibility mode signal handling by Andi Kleen
*
- * $Id: ia32_signal.c,v 1.17 2002/03/21 14:16:32 ak Exp $
+ * $Id: ia32_signal.c,v 1.22 2002/07/29 10:34:03 ak Exp $
*/
#include <linux/sched.h>
@@ -39,6 +39,7 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
+void signal_fault(struct pt_regs *regs, void *frame, char *where);
static int ia32_copy_siginfo_to_user(siginfo_t32 *to, siginfo_t *from)
{
@@ -163,32 +164,38 @@ ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsign
regs->r ## x = reg; \
}
-#define RELOAD_SEG(seg) \
+#define RELOAD_SEG(seg,mask) \
{ unsigned int cur; \
unsigned short pre; \
err |= __get_user(pre, &sc->seg); \
asm volatile("movl %%" #seg ",%0" : "=r" (cur)); \
+ pre |= mask; \
if (pre != cur) loadsegment(seg,pre); }
- /* Reload fs and gs if they have changed in the signal handler. */
+ /* Reload fs and gs if they have changed in the signal handler.
+ This does not handle long fs/gs base changes in the handler, but
+ does not clobber them at least in the normal case. */
{
- unsigned short gs;
+ unsigned gs, oldgs;
err |= __get_user(gs, &sc->gs);
+ gs |= 3;
+ asm("movl %%gs,%0" : "=r" (oldgs));
+ if (gs != oldgs)
load_gs_index(gs);
}
- RELOAD_SEG(fs);
- RELOAD_SEG(ds);
- RELOAD_SEG(es);
+ RELOAD_SEG(fs,3);
+ RELOAD_SEG(ds,3);
+ RELOAD_SEG(es,3);
COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
COPY(dx); COPY(cx); COPY(ip);
/* Don't touch extended registers */
err |= __get_user(regs->cs, &sc->cs);
- regs->cs |= 2;
+ regs->cs |= 3;
err |= __get_user(regs->ss, &sc->ss);
- regs->ss |= 2;
+ regs->ss |= 3;
{
unsigned int tmpflags;
@@ -284,7 +291,7 @@ asmlinkage int sys32_rt_sigreturn(struct pt_regs regs)
return eax;
badframe:
- signal_fault(&regs, frame, "32bit rt sigreturn");
+ signal_fault(&regs,frame,"32bit rt sigreturn");
return 0;
}
@@ -377,8 +384,9 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka,
{
struct exec_domain *ed = current_thread_info()->exec_domain;
-
- err |= __put_user((ed && ed->signal_invmap && sig < 32
+ err |= __put_user((ed
+ && ed->signal_invmap
+ && sig < 32
? ed->signal_invmap[sig]
: sig),
&frame->sig);
@@ -435,7 +443,7 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka,
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
- signal_fault(regs,frame,"32bit signal setup");
+ signal_fault(regs,frame,"32bit signal deliver");
}
void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
@@ -449,9 +457,12 @@ void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
+
{
struct exec_domain *ed = current_thread_info()->exec_domain;
- err |= __put_user((ed && ed->signal_invmap && sig < 32
+ err |= __put_user((ed
+ && ed->signal_invmap
+ && sig < 32
? ed->signal_invmap[sig]
: sig),
&frame->sig);
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index 406e6ddb2dac..df4e6d13ec3d 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -27,7 +27,7 @@
*/
ENTRY(ia32_cstar_target)
movq $-ENOSYS,%rax
- sysret
+ sysretl
/*
* Emulated IA32 system calls via int 0x80.
@@ -77,6 +77,7 @@ ia32_tracesys:
jmp ia32_do_syscall
ia32_badsys:
+ movq $0,ORIG_RAX-ARGOFFSET(%rsp)
movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
jmp int_ret_from_sys_call
@@ -84,6 +85,10 @@ ni_syscall:
movq %rax,%rdi
jmp sys32_ni_syscall
+quiet_ni_syscall:
+ movq $-ENOSYS,%rax
+ ret
+
.macro PTREGSCALL label, func
.globl \label
\label:
@@ -229,7 +234,7 @@ ia32_sys_call_table:
.quad stub32_iopl /* 110 */
.quad sys_vhangup
.quad ni_syscall /* old "idle" system call */
- .quad ni_syscall /* vm86old */
+ .quad sys32_vm86_warning /* vm86old */
.quad sys32_wait4
.quad sys_swapoff /* 115 */
.quad sys32_sysinfo
@@ -238,7 +243,7 @@ ia32_sys_call_table:
.quad stub32_sigreturn
.quad stub32_clone /* 120 */
.quad sys_setdomainname
- .quad sys32_newuname
+ .quad sys_uname
.quad sys_modify_ldt
.quad sys32_adjtimex
.quad sys32_mprotect /* 125 */
@@ -282,8 +287,8 @@ ia32_sys_call_table:
.quad sys_mremap
.quad sys_setresuid16
.quad sys_getresuid16 /* 165 */
- .quad ni_syscall /* vm86 */
- .quad ni_syscall /* query_module */
+ .quad sys32_vm86_warning /* vm86 */
+ .quad quiet_ni_syscall /* query_module */
.quad sys_poll
.quad sys32_nfsservctl
.quad sys_setresgid16 /* 170 */
@@ -368,7 +373,7 @@ ia32_sys_call_table:
.quad sys_io_cancel
.quad sys_ni_syscall /* 250 alloc_huge_pages */
.quad sys_ni_syscall /* free_huge_pages */
- .quad sys_ni_syscall /* exit_group */
+ .quad sys_exit_group /* exit_group */
ia32_syscall_end:
.rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
.quad ni_syscall
diff --git a/arch/x86_64/ia32/ipc32.c b/arch/x86_64/ia32/ipc32.c
index e441f93a3f98..d8e7eebcfc22 100644
--- a/arch/x86_64/ia32/ipc32.c
+++ b/arch/x86_64/ia32/ipc32.c
@@ -264,6 +264,9 @@ semctl32 (int first, int second, int third, void *uptr)
if (err2)
err = -EFAULT;
break;
+ default:
+ err = -EINVAL;
+ break;
}
return err;
}
@@ -284,7 +287,7 @@ do_sys32_msgsnd (int first, int second, int third, void *uptr)
if (!p)
return -ENOMEM;
err = get_user(p->mtype, &up->mtype);
- err |= copy_from_user(p->mtext, &up->mtext, second);
+ err |= (copy_from_user(p->mtext, &up->mtext, second) ? -EFAULT : 0);
if (err)
goto out;
old_fs = get_fs();
diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
index d56ddadce445..6039be04e21e 100644
--- a/arch/x86_64/ia32/sys_ia32.c
+++ b/arch/x86_64/ia32/sys_ia32.c
@@ -35,7 +35,6 @@
#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
-#include <linux/binfmts.h>
#include <linux/mm.h>
#include <linux/shm.h>
#include <linux/slab.h>
@@ -56,6 +55,7 @@
#include <linux/stat.h>
#include <linux/ipc.h>
#include <linux/rwsem.h>
+#include <linux/binfmts.h>
#include <linux/init.h>
#include <linux/aio_abi.h>
#include <asm/mman.h>
@@ -264,8 +264,11 @@ sys32_mmap(struct mmap_arg_struct *arg)
if (!file)
return -EBADF;
}
+
+#if 0 /* reenable when noexec works */
if (a.prot & PROT_READ)
a.prot |= PROT_EXEC;
+#endif
a.flags |= MAP_32BIT;
@@ -275,8 +278,8 @@ sys32_mmap(struct mmap_arg_struct *arg)
if (file)
fput(file);
- /* Should not happen */
- if (retval >= 0xFFFFFFFF && (long)retval > 0) {
+ /* Cannot wrap */
+ if (retval+a.len >= 0xFFFFFFFF && (long)retval > 0) {
do_munmap(mm, retval, a.len);
retval = -ENOMEM;
}
@@ -964,22 +967,24 @@ sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
asmlinkage ssize_t sys_readv(unsigned long,const struct iovec *,unsigned long);
asmlinkage ssize_t sys_writev(unsigned long,const struct iovec *,unsigned long);
-struct iovec *
-get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type)
+static struct iovec *
+get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type, int *errp)
{
int i;
u32 buf, len;
struct iovec *ivp, *iov;
+ unsigned long totlen;
/* Get the "struct iovec" from user memory */
if (!count)
return 0;
- if(verify_area(VERIFY_READ, iov32, sizeof(struct iovec32)*count))
- return(struct iovec *)0;
if (count > UIO_MAXIOV)
return(struct iovec *)0;
+ if(verify_area(VERIFY_READ, iov32, sizeof(struct iovec32)*count))
+ return(struct iovec *)0;
if (count > UIO_FASTIOV) {
+ *errp = -ENOMEM;
iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
if (!iov)
return((struct iovec *)0);
@@ -987,24 +992,33 @@ get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type)
iov = iov_buf;
ivp = iov;
+ totlen = 0;
for (i = 0; i < count; i++) {
- if (__get_user(len, &iov32->iov_len) ||
- __get_user(buf, &iov32->iov_base)) {
- if (iov != iov_buf)
- kfree(iov);
- return((struct iovec *)0);
- }
- if (verify_area(type, (void *)A(buf), len)) {
- if (iov != iov_buf)
- kfree(iov);
- return((struct iovec *)0);
- }
+ *errp = __get_user(len, &iov32->iov_len) |
+ __get_user(buf, &iov32->iov_base);
+ if (*errp)
+ goto error;
+ *errp = verify_area(type, (void *)A(buf), len);
+ if (*errp)
+ goto error;
+ /* SuS checks: */
+ *errp = -EINVAL;
+ if ((int)len < 0)
+ goto error;
+ if ((totlen += len) >= 0x7fffffff)
+ goto error;
ivp->iov_base = (void *)A(buf);
ivp->iov_len = (__kernel_size_t)len;
iov32++;
ivp++;
}
+ *errp = 0;
return(iov);
+
+error:
+ if (iov != iov_buf)
+ kfree(iov);
+ return NULL;
}
asmlinkage long
@@ -1015,8 +1029,8 @@ sys32_readv(int fd, struct iovec32 *vector, u32 count)
int ret;
mm_segment_t old_fs = get_fs();
- if ((iov = get_iovec32(vector, iovstack, count, VERIFY_WRITE)) == (struct iovec *)0)
- return -EFAULT;
+ if ((iov = get_iovec32(vector, iovstack, count, VERIFY_WRITE, &ret)) == NULL)
+ return ret;
set_fs(KERNEL_DS);
ret = sys_readv(fd, iov, count);
set_fs(old_fs);
@@ -1033,8 +1047,8 @@ sys32_writev(int fd, struct iovec32 *vector, u32 count)
int ret;
mm_segment_t old_fs = get_fs();
- if ((iov = get_iovec32(vector, iovstack, count, VERIFY_READ)) == (struct iovec *)0)
- return -EFAULT;
+ if ((iov = get_iovec32(vector, iovstack, count, VERIFY_READ, &ret)) == NULL)
+ return ret;
set_fs(KERNEL_DS);
ret = sys_writev(fd, iov, count);
set_fs(old_fs);
@@ -1121,7 +1135,7 @@ sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
/*
* sys_time() can be implemented in user-level using
- * sys_gettimeofday(). IA64 did this but i386 Linux did not
+ * sys_gettimeofday(). x86-64 did this but i386 Linux did not
* so we have to implement this system call here.
*/
asmlinkage long sys32_time(int * tloc)
@@ -1288,6 +1302,39 @@ static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
}
extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
+asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg);
+
+
+asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ switch (cmd) {
+ case F_GETLK:
+ case F_SETLK:
+ case F_SETLKW:
+ {
+ struct flock f;
+ mm_segment_t old_fs;
+ long ret;
+
+ if (get_flock(&f, (struct flock32 *)arg))
+ return -EFAULT;
+ old_fs = get_fs(); set_fs (KERNEL_DS);
+ ret = sys_fcntl(fd, cmd, (unsigned long)&f);
+ set_fs (old_fs);
+ if (ret) return ret;
+ if (put_flock(&f, (struct flock32 *)arg))
+ return -EFAULT;
+ return 0;
+ }
+ case F_GETLK64:
+ case F_SETLK64:
+ case F_SETLKW64:
+ return sys32_fcntl64(fd,cmd,arg);
+
+ default:
+ return sys_fcntl(fd, cmd, (unsigned long)arg);
+ }
+}
static inline int get_flock64(struct ia32_flock64 *fl32, struct flock *fl64)
{
@@ -1319,40 +1366,34 @@ asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long a
{
struct flock fl64;
mm_segment_t oldfs = get_fs();
- int ret = 0, origcmd;
- unsigned long origarg;
+ int ret = 0;
+ int oldcmd = cmd;
+ unsigned long oldarg = arg;
- origcmd = cmd;
- origarg = arg;
switch (cmd) {
- case F_GETLK:
- case F_SETLK:
- case F_SETLKW:
- ret = get_flock(&fl64, (struct flock32 *)arg);
- arg = (unsigned long) &fl64;
- set_fs(KERNEL_DS);
- break;
case F_GETLK64:
cmd = F_GETLK;
- goto cnv64;
+ goto cnv;
case F_SETLK64:
cmd = F_SETLK;
- goto cnv64;
+ goto cnv;
case F_SETLKW64:
cmd = F_SETLKW;
- cnv64:
+ cnv:
ret = get_flock64((struct ia32_flock64 *)arg, &fl64);
arg = (unsigned long)&fl64;
set_fs(KERNEL_DS);
break;
+ case F_GETLK:
+ case F_SETLK:
+ case F_SETLKW:
+ return sys32_fcntl(fd,cmd,arg);
}
if (!ret)
ret = sys_fcntl(fd, cmd, arg);
set_fs(oldfs);
- if (origcmd == F_GETLK && !ret)
- ret = put_flock(&fl64, (struct flock32 *)origarg);
- else if (cmd == F_GETLK && !ret)
- ret = put_flock64((struct ia32_flock64 *)origarg, &fl64);
+ if (oldcmd == F_GETLK64 && !ret)
+ ret = put_flock64((struct ia32_flock64 *)oldarg, &fl64);
return ret;
}
@@ -1804,19 +1845,6 @@ sys32_sysctl(struct sysctl_ia32 *args32)
#endif
}
-extern asmlinkage long sys_newuname(struct new_utsname * name);
-
-asmlinkage long
-sys32_newuname(struct new_utsname * name)
-{
- int ret = sys_newuname(name);
-
- if (current->personality == PER_LINUX32 && !ret) {
- ret = copy_to_user(name->machine, "i686\0\0", 6);
- }
- return ret;
-}
-
extern asmlinkage ssize_t sys_pread64(unsigned int fd, char * buf,
size_t count, loff_t pos);
@@ -1825,7 +1853,8 @@ extern asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char * buf,
typedef __kernel_ssize_t32 ssize_t32;
-/* warning. next two assume LE */
+
+/* warning: next two assume little endian */
asmlinkage ssize_t32
sys32_pread(unsigned int fd, char *ubuf, __kernel_size_t32 count,
u32 poslo, u32 poshi)
@@ -1849,7 +1878,8 @@ asmlinkage long
sys32_personality(unsigned long personality)
{
int ret;
- if (current->personality == PER_LINUX32 && personality == PER_LINUX)
+ if (personality(current->personality) == PER_LINUX32 &&
+ personality == PER_LINUX)
personality = PER_LINUX32;
ret = sys_personality(personality);
if (ret == PER_LINUX32)
@@ -1956,42 +1986,39 @@ sys32_adjtimex(struct timex32 *utp)
return ret;
}
-
-/* common code for old and new mmaps */
-static inline long do_mmap2(
- unsigned long addr, unsigned long len,
+asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
- int error = -EBADF;
+ struct mm_struct *mm = current->mm;
+ unsigned long error;
struct file * file = NULL;
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
if (!(flags & MAP_ANONYMOUS)) {
file = fget(fd);
if (!file)
- goto out;
+ return -EBADF;
}
- down_write(&current->mm->mmap_sem);
- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up_write(&current->mm->mmap_sem);
+ /* later add PROT_EXEC for PROT_READ here */
+
+ down_write(&mm->mmap_sem);
+ error = do_mmap_pgoff(file, addr, len, prot, flags|MAP_32BIT, pgoff);
+ up_write(&mm->mmap_sem);
+
+ /* cannot wrap */
+ if (error+len >= 0xFFFFFFFF && (long)error >= 0) {
+ do_munmap(mm, error, len);
+ error = -ENOMEM;
+ }
if (file)
fput(file);
-out:
return error;
}
-asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff)
-{
- return do_mmap2(addr, len, prot, flags, fd, pgoff);
-}
-
-
-asmlinkage int sys32_olduname(struct oldold_utsname * name)
+asmlinkage long sys32_olduname(struct oldold_utsname * name)
{
int error;
@@ -2581,6 +2608,19 @@ long sys32_io_setup(unsigned nr_reqs, u32 *ctx32p)
return ret;
}
+
+int sys32_vm86_warning(void)
+{
+ static long warn_time = -(60*HZ);
+ if (time_before(warn_time + 60*HZ,jiffies)) {
+ printk(KERN_INFO "%s: vm86 mode not supported on 64 bit kernel\n",
+ current->comm);
+ warn_time = jiffies;
+ }
+ return -ENOSYS ;
+}
+
+
struct exec_domain ia32_exec_domain = {
.name = "linux/x86",
.pers_low = PER_LINUX32,
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index f4fde633c039..606bb3f46405 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -9,7 +9,7 @@ export-objs := mtrr.o x8664_ksyms.o pci-gart.o
obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \
ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \
pci-dma.o x8664_ksyms.o i387.o syscall.o vsyscall.o \
- setup64.o bluesmoke.o bootflag.o e820.o reboot.o
+ setup64.o bluesmoke.o bootflag.o e820.o reboot.o profile.o
obj-$(CONFIG_MTRR) += mtrr.o
obj-$(CONFIG_X86_MSR) += msr.o
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 6d6905297e00..6bc56ac417bf 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -897,17 +897,9 @@ int setup_profiling_timer(unsigned int multiplier)
inline void smp_local_timer_interrupt(struct pt_regs *regs)
{
- int user = user_mode(regs);
int cpu = smp_processor_id();
- /*
- * The profiling function is SMP safe. (nothing can mess
- * around with "current", and the profiling counters are
- * updated with atomic operations). This is especially
- * useful with a profiling multiplier != 1
- */
- if (!user)
- x86_do_profile(regs->rip);
+ x86_do_profile(regs);
if (--prof_counter[cpu] <= 0) {
/*
@@ -925,7 +917,7 @@ inline void smp_local_timer_interrupt(struct pt_regs *regs)
}
#ifdef CONFIG_SMP
- update_process_times(user);
+ update_process_times(user_mode(regs));
#endif
}
@@ -951,8 +943,6 @@ inline void smp_local_timer_interrupt(struct pt_regs *regs)
*/
void smp_apic_timer_interrupt(struct pt_regs *regs)
{
- int cpu = smp_processor_id();
-
/*
* the NMI deadlock-detector uses this.
*/
@@ -1084,11 +1074,13 @@ int __init APIC_init_uniprocessor (void)
static __init int setup_disableapic(char *str)
{
disable_apic = 1;
+ return 0;
}
static __init int setup_noapictimer(char *str)
{
disable_apic_timer = 1;
+ return 0;
}
__setup("disableapic", setup_disableapic);
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index 0b397c901511..92ca3b015fc8 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -785,7 +785,7 @@ void __init mp_register_ioapic (
mp_ioapic_routing[idx].irq_end = irq_base +
io_apic_get_redir_entries(idx);
- printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, "
+ printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
"IRQ %d-%d\n", idx, mp_ioapics[idx].mpc_apicid,
mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr,
mp_ioapic_routing[idx].irq_start,
diff --git a/arch/x86_64/kernel/mtrr.c b/arch/x86_64/kernel/mtrr.c
index 9d478fa81f6b..26325a4a579c 100644
--- a/arch/x86_64/kernel/mtrr.c
+++ b/arch/x86_64/kernel/mtrr.c
@@ -646,7 +646,7 @@ int mtrr_add_page (u64 base, u32 size, unsigned int type, char increment)
}
if (base & (size_or_mask>>PAGE_SHIFT)) {
- printk (KERN_WARNING "mtrr: base(%lx) exceeds the MTRR width(%lx)\n",
+ printk (KERN_WARNING "mtrr: base(%Lx) exceeds the MTRR width(%Lx)\n",
(unsigned long) base,
(unsigned long) (size_or_mask>>PAGE_SHIFT));
return -EINVAL;
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index ddc060329c9a..e6d6b251367f 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -23,6 +23,7 @@
#include <asm/smp.h>
#include <asm/mtrr.h>
#include <asm/mpspec.h>
+#include <asm/nmi.h>
unsigned int nmi_watchdog = NMI_LOCAL_APIC;
static unsigned int nmi_hz = HZ;
@@ -137,6 +138,18 @@ static int nmi_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
return 0;
}
+struct pm_dev * set_nmi_pm_callback(pm_callback callback)
+{
+ apic_pm_unregister(nmi_pmdev);
+ return apic_pm_register(PM_SYS_DEV, 0, callback);
+}
+
+void unset_nmi_pm_callback(struct pm_dev * dev)
+{
+ apic_pm_unregister(dev);
+ nmi_pmdev = apic_pm_register(PM_SYS_DEV, 0, nmi_pm_callback);
+}
+
static void nmi_pm_init(void)
{
if (!nmi_pmdev)
@@ -178,7 +191,7 @@ static void __pminit setup_k7_watchdog(void)
| K7_NMI_EVENT;
wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
- printk(KERN_INFO "watchdog: setting K7_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000));
+ printk(KERN_INFO "watchdog: setting K7_PERFCTR0 to %08x\n", -(cpu_khz/nmi_hz*1000));
wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/nmi_hz*1000), -1);
apic_write(APIC_LVTPC, APIC_DM_NMI);
evntsel |= K7_EVNTSEL_ENABLE;
@@ -275,3 +288,30 @@ void nmi_watchdog_tick (struct pt_regs * regs)
if (nmi_perfctr_msr)
wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1);
}
+
+static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
+{
+ return 0;
+}
+
+static nmi_callback_t nmi_callback = dummy_nmi_callback;
+
+asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
+{
+ int cpu = smp_processor_id();
+
+ add_pda(__nmi_count,1);
+
+ if (!nmi_callback(regs, cpu))
+ default_do_nmi(regs);
+}
+
+void set_nmi_callback(nmi_callback_t callback)
+{
+ nmi_callback = callback;
+}
+
+void unset_nmi_callback(void)
+{
+ nmi_callback = dummy_nmi_callback;
+}
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 2113d078275a..0dbfe91c9c9c 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -32,6 +32,7 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/user.h>
+#include <linux/module.h>
#include <linux/a.out.h>
#include <linux/interrupt.h>
#include <linux/config.h>
diff --git a/arch/x86_64/kernel/profile.c b/arch/x86_64/kernel/profile.c
new file mode 100644
index 000000000000..334af20585cb
--- /dev/null
+++ b/arch/x86_64/kernel/profile.c
@@ -0,0 +1,45 @@
+/*
+ * linux/arch/i386/kernel/profile.c
+ *
+ * (C) 2002 John Levon <levon@movementarian.org>
+ *
+ */
+
+#include <linux/profile.h>
+#include <linux/spinlock.h>
+#include <linux/notifier.h>
+#include <linux/irq.h>
+#include <asm/hw_irq.h>
+
+static struct notifier_block * profile_listeners;
+static rwlock_t profile_lock = RW_LOCK_UNLOCKED;
+
+int register_profile_notifier(struct notifier_block * nb)
+{
+ int err;
+ write_lock_irq(&profile_lock);
+ err = notifier_chain_register(&profile_listeners, nb);
+ write_unlock_irq(&profile_lock);
+ return err;
+}
+
+
+int unregister_profile_notifier(struct notifier_block * nb)
+{
+ int err;
+ write_lock_irq(&profile_lock);
+ err = notifier_chain_unregister(&profile_listeners, nb);
+ write_unlock_irq(&profile_lock);
+ return err;
+}
+
+
+void x86_profile_hook(struct pt_regs * regs)
+{
+ /* we would not even need this lock if
+ * we had a global cli() on register/unregister
+ */
+ read_lock(&profile_lock);
+ notifier_call_chain(&profile_listeners, 0, regs);
+ read_unlock(&profile_lock);
+}
diff --git a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c
index a08766e0d67d..a260d52f756c 100644
--- a/arch/x86_64/kernel/reboot.c
+++ b/arch/x86_64/kernel/reboot.c
@@ -8,6 +8,7 @@
#include <asm/io.h>
#include <asm/kdebug.h>
#include <asm/delay.h>
+#include <asm/hw_irq.h>
/*
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 7564e806e5c1..26368cee8ec0 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -234,7 +234,6 @@ static void __init contig_initmem_init(void)
void __init setup_arch(char **cmdline_p)
{
- unsigned long bootmap_size, low_mem_size;
int i;
ROOT_DEV = ORIG_ROOT_DEV;
@@ -284,14 +283,8 @@ void __init setup_arch(char **cmdline_p)
contig_initmem_init();
- /*
- * Reserve the bootmem bitmap itself as well. We do this in two
- * steps (first step was init_bootmem()) because this catches
- * the (very unlikely) case of us accidentally initializing the
- * bootmem allocator with an invalid RAM area.
- */
- reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) +
- bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY));
+ /* reserve kernel */
+ reserve_bootmem(HIGH_MEMORY, PFN_PHYS(start_pfn) - HIGH_MEMORY);
/*
* reserve physical page 0 - it's a special BIOS page on many boxes,
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 53b2b002c491..61ba37b6f4a1 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -559,11 +559,10 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
printk("Do you have a strange power saving mode enabled?\n");
}
-asmlinkage void do_nmi(struct pt_regs * regs)
+asmlinkage void default_do_nmi(struct pt_regs * regs)
{
unsigned char reason = inb(0x61);
- add_pda(__nmi_count,1);
if (!(reason & 0xc0)) {
#if CONFIG_X86_LOCAL_APIC
/*
diff --git a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile
index 9dbb65684d90..d95a85e2d0d5 100644
--- a/arch/x86_64/mm/Makefile
+++ b/arch/x86_64/mm/Makefile
@@ -1,13 +1,9 @@
#
# Makefile for the linux i386-specific parts of the memory manager.
#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definition is now in the main makefile...
-O_TARGET := mm.o
-obj-y := init.o fault.o ioremap.o extable.o modutil.o
+export-objs := pageattr.o
+
+obj-y := init.o fault.o ioremap.o extable.o modutil.o pageattr.o
include $(TOPDIR)/Rules.make
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index b222113c97c3..8faa403b596a 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -32,18 +32,14 @@
extern void die(const char *,struct pt_regs *,long);
-extern spinlock_t console_lock, timerlist_lock;
+extern spinlock_t console_lock;
void bust_spinlocks(int yes)
{
- spin_lock_init(&timerlist_lock);
+ int loglevel_save = console_loglevel;
if (yes) {
oops_in_progress = 1;
-#ifdef CONFIG_SMP
- global_irq_lock = 0; /* Many serial drivers do __global_cli() */
-#endif
} else {
- int loglevel_save = console_loglevel;
#ifdef CONFIG_VT
unblank_screen();
#endif
@@ -108,6 +104,18 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
int write;
siginfo_t info;
+#ifdef CONFIG_CHECKING
+ {
+ unsigned long gs;
+ struct x8664_pda *pda = cpu_pda + stack_smp_processor_id();
+ rdmsrl(MSR_GS_BASE, gs);
+ if (gs != (unsigned long)pda) {
+ wrmsrl(MSR_GS_BASE, pda);
+ printk("page_fault: wrong gs %lx expected %p\n", gs, pda);
+ }
+ }
+#endif
+
/* get the address */
__asm__("movq %%cr2,%0":"=r" (address));
@@ -129,7 +137,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
* If we're in an interrupt or have no user
* context, we must not take the fault..
*/
- if (in_interrupt() || !mm)
+ if (in_atomic() || !mm)
goto no_context;
again:
@@ -223,7 +231,7 @@ no_context:
/* Are we prepared to handle this kernel fault? */
if ((fixup = search_exception_table(regs->rip)) != 0) {
regs->rip = fixup;
- if (exception_trace)
+ if (0 && exception_trace)
printk(KERN_ERR
"%s: fixed kernel exception at %lx address %lx err:%ld\n",
current->comm, regs->rip, address, error_code);
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index 0c5b3b0e1e49..f9af1cde89a0 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -37,6 +37,8 @@
#include <asm/tlb.h>
#include <asm/mmu_context.h>
+unsigned long start_pfn, end_pfn;
+
mmu_gather_t mmu_gathers[NR_CPUS];
/*
@@ -49,19 +51,24 @@ void show_mem(void)
{
int i, total = 0, reserved = 0;
int shared = 0, cached = 0;
+ pg_data_t *pgdat;
+ struct page *page;
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
- i = max_mapnr;
- while (i-- > 0) {
+
+ for_each_pgdat(pgdat) {
+ for (i = 0; i < pgdat->node_size; ++i) {
+ page = pgdat->node_mem_map + i;
total++;
- if (PageReserved(mem_map+i))
+ if (PageReserved(page))
reserved++;
- else if (PageSwapCache(mem_map+i))
+ else if (PageSwapCache(page))
cached++;
- else if (page_count(mem_map+i))
- shared += page_count(mem_map+i) - 1;
+ else if (page_count(page))
+ shared += page_count(page) - 1;
+ }
}
printk("%d pages of RAM\n", total);
printk("%d reserved pages\n",reserved);
@@ -264,16 +271,15 @@ void __init paging_init(void)
{
{
unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
- unsigned int max_dma, low;
+ unsigned int max_dma;
max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
- low = max_low_pfn;
- if (low < max_dma)
- zones_size[ZONE_DMA] = low;
+ if (end_pfn < max_dma)
+ zones_size[ZONE_DMA] = end_pfn;
else {
zones_size[ZONE_DMA] = max_dma;
- zones_size[ZONE_NORMAL] = low - max_dma;
+ zones_size[ZONE_NORMAL] = end_pfn - max_dma;
}
free_area_init(zones_size);
}
@@ -308,11 +314,15 @@ void __init mem_init(void)
int codesize, reservedpages, datasize, initsize;
int tmp;
+ printk("mem_init\n");
+
if (!mem_map)
BUG();
- max_mapnr = num_physpages = max_low_pfn;
- high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
+ max_low_pfn = end_pfn;
+ max_pfn = end_pfn;
+ max_mapnr = num_physpages = end_pfn;
+ high_memory = (void *) __va(end_pfn * PAGE_SIZE);
/* clear the zero-page */
memset(empty_zero_page, 0, PAGE_SIZE);
@@ -323,7 +333,7 @@ void __init mem_init(void)
after_bootmem = 1;
reservedpages = 0;
- for (tmp = 0; tmp < max_low_pfn; tmp++)
+ for (tmp = 0; tmp < end_pfn; tmp++)
/*
* Only count reserved RAM pages
*/
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
index 4f2c33115ef5..c095886d9b16 100644
--- a/arch/x86_64/mm/ioremap.c
+++ b/arch/x86_64/mm/ioremap.c
@@ -10,6 +10,7 @@
#include <linux/vmalloc.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <asm/pgalloc.h>
#include <asm/fixmap.h>
@@ -157,14 +158,72 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag
return NULL;
addr = area->addr;
if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
- vfree(addr);
+ vunmap(addr);
return NULL;
}
return (void *) (offset + (char *)addr);
}
+/**
+ * ioremap_nocache - map bus memory into CPU space
+ * @offset: bus address of the memory
+ * @size: size of the resource to map
+ *
+ * ioremap_nocache performs a platform specific sequence of operations to
+ * make bus memory CPU accessible via the readb/readw/readl/writeb/
+ * writew/writel functions and the other mmio helpers. The returned
+ * address is not guaranteed to be usable directly as a virtual
+ * address.
+ *
+ * This version of ioremap ensures that the memory is marked uncachable
+ * on the CPU as well as honouring existing caching rules from things like
+ * the PCI bus. Note that there are other caches and buffers on many
+ * busses. In particular driver authors should read up on PCI writes
+ *
+ * It's useful if some control registers are in such an area and
+ * write combining or read caching is not desirable:
+ *
+ * Must be freed with iounmap.
+ */
+
+void *ioremap_nocache (unsigned long phys_addr, unsigned long size)
+{
+ void *p = __ioremap(phys_addr, size, _PAGE_PCD);
+ if (!p)
+ return p;
+
+ if (phys_addr + size < virt_to_phys(high_memory)) {
+ struct page *ppage = virt_to_page(__va(phys_addr));
+ unsigned long npages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+ BUG_ON(phys_addr+size > (unsigned long)high_memory);
+ BUG_ON(phys_addr + size < phys_addr);
+
+ if (change_page_attr(ppage, npages, PAGE_KERNEL_NOCACHE) < 0) {
+ iounmap(p);
+ p = NULL;
+ }
+ }
+
+ return p;
+}
+
void iounmap(void *addr)
{
- if (addr > high_memory)
- vfree((void *) (PAGE_MASK & (unsigned long) addr));
+ struct vm_struct *p;
+ if (addr <= high_memory)
+ return;
+ p = remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr));
+ if (!p) {
+ printk("__iounmap: bad address %p\n", addr);
+ return;
+ }
+
+ unmap_vm_area(p);
+ if (p->flags && p->phys_addr < virt_to_phys(high_memory)) {
+ change_page_attr(virt_to_page(__va(p->phys_addr)),
+ p->size >> PAGE_SHIFT,
+ PAGE_KERNEL);
+ }
+ kfree(p);
}
diff --git a/arch/x86_64/mm/modutil.c b/arch/x86_64/mm/modutil.c
index 52751604fd7a..5a5827166a04 100644
--- a/arch/x86_64/mm/modutil.c
+++ b/arch/x86_64/mm/modutil.c
@@ -13,12 +13,15 @@
#include <asm/uaccess.h>
#include <asm/system.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
static struct vm_struct * modvmlist = NULL;
void module_unmap (void * addr)
{
struct vm_struct **p, *tmp;
+ int i;
if (!addr)
return;
@@ -29,21 +32,33 @@ void module_unmap (void * addr)
for (p = &modvmlist ; (tmp = *p) ; p = &tmp->next) {
if (tmp->addr == addr) {
*p = tmp->next;
- vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), tmp->size);
- kfree(tmp);
- return;
+ goto found;
}
}
printk("Trying to unmap nonexistent module vm area (%p)\n", addr);
+ return;
+ found:
+ unmap_vm_area(tmp);
+ for (i = 0; i < tmp->nr_pages; i++) {
+ if (unlikely(!tmp->pages[i]))
+ BUG();
+ __free_page(tmp->pages[i]);
+ }
+
+ kfree(tmp->pages);
+ kfree(tmp);
}
void * module_map (unsigned long size)
{
- void * addr;
struct vm_struct **p, *tmp, *area;
+ struct page **pages;
+ void * addr;
+ unsigned int nr_pages, array_size, i;
size = PAGE_ALIGN(size);
- if (!size || size > MODULES_LEN) return NULL;
+ if (!size || size > MODULES_LEN)
+ return NULL;
addr = (void *) MODULES_VADDR;
for (p = &modvmlist; (tmp = *p) ; p = &tmp->next) {
@@ -51,18 +66,53 @@ void * module_map (unsigned long size)
break;
addr = (void *) (tmp->size + (unsigned long) tmp->addr);
}
- if ((unsigned long) addr + size >= MODULES_END) return NULL;
+ if ((unsigned long) addr + size >= MODULES_END)
+ return NULL;
area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
- if (!area) return NULL;
+ if (!area)
+ return NULL;
area->size = size + PAGE_SIZE;
area->addr = addr;
area->next = *p;
+ area->pages = NULL;
+ area->nr_pages = 0;
+ area->phys_addr = 0;
*p = area;
- if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size, GFP_KERNEL, PAGE_KERNEL)) {
- module_unmap(addr);
- return NULL;
+ nr_pages = size >> PAGE_SHIFT;
+ array_size = (nr_pages * sizeof(struct page *));
+
+ area->nr_pages = nr_pages;
+ area->pages = pages = kmalloc(array_size, GFP_KERNEL);
+ if (!area->pages)
+ goto fail;
+
+ memset(area->pages, 0, array_size);
+
+ for (i = 0; i < area->nr_pages; i++) {
+ area->pages[i] = alloc_page(GFP_KERNEL);
+ if (unlikely(!area->pages[i]))
+ goto fail;
+ }
+
+ if (map_vm_area(area, PAGE_KERNEL, &pages)) {
+ unmap_vm_area(area);
+ goto fail;
}
- return addr;
+
+ return area->addr;
+
+fail:
+ if (area->pages) {
+ for (i = 0; i < area->nr_pages; i++) {
+ if (area->pages[i])
+ __free_page(area->pages[i]);
+ }
+ kfree(area->pages);
+ }
+ kfree(area);
+
+ return NULL;
}
+
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
new file mode 100644
index 000000000000..3d9e3498d2cc
--- /dev/null
+++ b/arch/x86_64/mm/pageattr.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2002 Andi Kleen, SuSE Labs.
+ * Thanks to Ben LaHaise for precious feedback.
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+#include <asm/processor.h>
+#include <asm/tlbflush.h>
+#include <asm/io.h>
+
+static inline pte_t *lookup_address(unsigned long address)
+{
+ pgd_t *pgd = pgd_offset_k(address);
+ pmd_t *pmd;
+ pte_t *pte;
+ if (!pgd || !pgd_present(*pgd))
+ return NULL;
+ pmd = pmd_offset(pgd, address);
+ if (!pmd_present(*pmd))
+ return NULL;
+ if (pmd_large(*pmd))
+ return (pte_t *)pmd;
+ pte = pte_offset_kernel(pmd, address);
+ if (pte && !pte_present(*pte))
+ pte = NULL;
+ return pte;
+}
+
+static struct page *split_large_page(unsigned long address, pgprot_t prot)
+{
+ int i;
+ unsigned long addr;
+ struct page *base = alloc_pages(GFP_KERNEL, 0);
+ pte_t *pbase;
+ if (!base)
+ return NULL;
+ address = __pa(address);
+ addr = address & LARGE_PAGE_MASK;
+ pbase = (pte_t *)page_address(base);
+ for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
+ pbase[i] = pfn_pte(addr >> PAGE_SHIFT,
+ addr == address ? prot : PAGE_KERNEL);
+ }
+ return base;
+}
+
+
+static void flush_kernel_map(void *address)
+{
+ if (address && cpu_has_clflush) {
+ /* is this worth it? */
+ int i;
+ for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
+ asm volatile("clflush %0" :: "m" (address + i));
+ } else
+ asm volatile("wbinvd":::"memory");
+ __flush_tlb_one(address);
+}
+
+/*
+ * No more special protections in this 2/4MB area - revert to a
+ * large page again.
+ */
+static inline void revert_page(struct page *kpte_page, unsigned long address)
+{
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t large_pte;
+
+ pgd = pgd_offset_k(address);
+ if (!pgd) BUG();
+ pmd = pmd_offset(pgd, address);
+ if (!pmd) BUG();
+ if ((pmd_val(*pmd) & _PAGE_GLOBAL) == 0) BUG();
+
+ large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, PAGE_KERNEL_LARGE);
+ set_pte((pte_t *)pmd, large_pte);
+}
+
+static int
+__change_page_attr(unsigned long address, struct page *page, pgprot_t prot,
+ struct page **oldpage)
+{
+ pte_t *kpte;
+ struct page *kpte_page;
+ unsigned kpte_flags;
+
+ kpte = lookup_address(address);
+ if (!kpte) return 0;
+ kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
+ kpte_flags = pte_val(*kpte);
+ if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) {
+ if ((kpte_flags & _PAGE_PSE) == 0) {
+ pte_t old = *kpte;
+ pte_t standard = mk_pte(page, PAGE_KERNEL);
+
+ set_pte(kpte, mk_pte(page, prot));
+ if (pte_same(old,standard))
+ atomic_inc(&kpte_page->count);
+ } else {
+ struct page *split = split_large_page(address, prot);
+ if (!split)
+ return -ENOMEM;
+ set_pte(kpte,mk_pte(split, PAGE_KERNEL));
+ }
+ } else if ((kpte_flags & _PAGE_PSE) == 0) {
+ set_pte(kpte, mk_pte(page, PAGE_KERNEL));
+ atomic_dec(&kpte_page->count);
+ }
+
+ if (atomic_read(&kpte_page->count) == 1) {
+ *oldpage = kpte_page;
+ revert_page(kpte_page, address);
+ }
+ return 0;
+}
+
+static inline void flush_map(unsigned long address)
+{
+#ifdef CONFIG_SMP
+ smp_call_function(flush_kernel_map, (void *)address, 1, 1);
+#endif
+ flush_kernel_map((void *)address);
+}
+
+struct deferred_page {
+ struct deferred_page *next;
+ struct page *fpage;
+ unsigned long address;
+};
+static struct deferred_page *df_list; /* protected by init_mm.mmap_sem */
+
+static inline void save_page(unsigned long address, struct page *fpage)
+{
+ struct deferred_page *df;
+ df = kmalloc(sizeof(struct deferred_page), GFP_KERNEL);
+ if (!df) {
+ flush_map(address);
+ __free_page(fpage);
+ } else {
+ df->next = df_list;
+ df->fpage = fpage;
+ df->address = address;
+ df_list = df;
+ }
+}
+
+/*
+ * Change the page attributes of an page in the linear mapping.
+ *
+ * This should be used when a page is mapped with a different caching policy
+ * than write-back somewhere - some CPUs do not like it when mappings with
+ * different caching policies exist. This changes the page attributes of the
+ * in kernel linear mapping too.
+ *
+ * The caller needs to ensure that there are no conflicting mappings elsewhere.
+ * This function only deals with the kernel linear map.
+ *
+ * Caller must call global_flush_tlb() after this.
+ */
+int change_page_attr(struct page *page, int numpages, pgprot_t prot)
+{
+ int err = 0;
+ struct page *fpage, *fpage2;
+ int i;
+
+ down_write(&init_mm.mmap_sem);
+ for (i = 0; i < numpages; i++, page++) {
+ unsigned long address = (unsigned long)page_address(page);
+ fpage = NULL;
+ err = __change_page_attr(address, page, prot, &fpage);
+ /* Handle kernel mapping too which aliases part of the lowmem */
+ if (!err && page_to_phys(page) < KERNEL_TEXT_SIZE) {
+ unsigned long addr2 = __START_KERNEL_map + page_to_phys(page);
+ fpage2 = NULL;
+ err = __change_page_attr(addr2, page, prot, &fpage2);
+ if (fpage2)
+ save_page(addr2, fpage2);
+ }
+ if (fpage)
+ save_page(address, fpage);
+ }
+ up_write(&init_mm.mmap_sem);
+ return err;
+}
+
+void global_flush_tlb(void)
+{
+ struct deferred_page *df, *next_df;
+
+ down_read(&init_mm.mmap_sem);
+ df = xchg(&df_list, NULL);
+ up_read(&init_mm.mmap_sem);
+ flush_map((df && !df->next) ? df->address : 0);
+ for (; df; df = next_df) {
+ next_df = df->next;
+ if (df->fpage)
+ __free_page(df->fpage);
+ kfree(df);
+ }
+}
+
+EXPORT_SYMBOL(change_page_attr);
+EXPORT_SYMBOL(global_flush_tlb);
diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h
index 811c69f8743d..9d7d039d5222 100644
--- a/include/asm-x86_64/hw_irq.h
+++ b/include/asm-x86_64/hw_irq.h
@@ -20,6 +20,10 @@
#include <linux/config.h>
#include <asm/atomic.h>
#include <asm/irq.h>
+#include <linux/profile.h>
+#include <linux/smp.h>
+
+struct hw_interrupt_type;
#endif
/*
@@ -126,20 +130,23 @@ __asm__( \
"push $" #nr "-256 ; " \
"jmp common_interrupt");
-extern unsigned long prof_cpu_mask;
-extern unsigned int * prof_buffer;
-extern unsigned long prof_len;
-extern unsigned long prof_shift;
-
-/*
- * x86 profiling function, SMP safe. We might want to do this in
- * assembly totally?
- */
-static inline void x86_do_profile (unsigned long rip)
+static inline void x86_do_profile (struct pt_regs *regs)
{
+ unsigned long rip;
+ extern unsigned long prof_cpu_mask;
+ extern char _stext;
+#ifdef CONFIG_PROFILING
+ extern void x86_profile_hook(struct pt_regs *);
+
+ x86_profile_hook(regs);
+#endif
+ if (user_mode(regs))
+ return;
if (!prof_buffer)
return;
+ rip = regs->rip;
+
/*
* Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
* (default is all CPUs.)
@@ -159,6 +166,11 @@ static inline void x86_do_profile (unsigned long rip)
atomic_inc((atomic_t *)&prof_buffer[rip]);
}
+struct notifier_block;
+
+int register_profile_notifier(struct notifier_block * nb);
+int unregister_profile_notifier(struct notifier_block * nb);
+
#ifdef CONFIG_SMP /*more of this file should probably be ifdefed SMP */
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
if (IO_APIC_IRQ(i))
diff --git a/include/asm-x86_64/ia32.h b/include/asm-x86_64/ia32.h
index 7830bf40cfd4..23be4a85e415 100644
--- a/include/asm-x86_64/ia32.h
+++ b/include/asm-x86_64/ia32.h
@@ -235,11 +235,6 @@ struct iovec32 {
};
-#ifdef __KERNEL__
-struct iovec *get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type);
-#endif
-
-
#endif /* !CONFIG_IA32_SUPPORT */
#endif
diff --git a/include/asm-x86_64/ide.h b/include/asm-x86_64/ide.h
index 8e0ad03131b3..ac0d00e0d535 100644
--- a/include/asm-x86_64/ide.h
+++ b/include/asm-x86_64/ide.h
@@ -5,7 +5,7 @@
*/
/*
- * This file contains the i386 architecture specific IDE code.
+ * This file contains the x86_64 architecture specific IDE code.
*/
#ifndef __ASMx86_64_IDE_H
diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h
index 6a460b5f5340..8cee542f40f4 100644
--- a/include/asm-x86_64/io_apic.h
+++ b/include/asm-x86_64/io_apic.h
@@ -148,9 +148,18 @@ extern int io_apic_get_redir_entries (int ioapic);
extern int io_apic_set_pci_routing (int ioapic, int pin, int irq);
#endif
+#ifdef CONFIG_ACPI_BOOT
+extern int io_apic_get_unique_id (int ioapic, int apic_id);
+extern int io_apic_get_version (int ioapic);
+extern int io_apic_get_redir_entries (int ioapic);
+extern int io_apic_set_pci_routing (int ioapic, int pin, int irq);
+#endif
+
#else /* !CONFIG_X86_IO_APIC */
#define io_apic_assign_pci_irqs 0
#endif
+void enable_NMI_through_LVT0 (void * dummy);
+
#endif
diff --git a/include/asm-x86_64/ioctl32.h b/include/asm-x86_64/ioctl32.h
new file mode 100644
index 000000000000..d0d227f45e05
--- /dev/null
+++ b/include/asm-x86_64/ioctl32.h
@@ -0,0 +1 @@
+#include <linux/ioctl32.h>
diff --git a/include/asm-x86_64/ipc.h b/include/asm-x86_64/ipc.h
index c6f281e673ff..8736ba68c118 100644
--- a/include/asm-x86_64/ipc.h
+++ b/include/asm-x86_64/ipc.h
@@ -1,5 +1,5 @@
-#ifndef __x86_64_IPC_H__
-#define __x86_64_IPC_H__
+#ifndef __x8664_IPC_H__
+#define __x8664_IPC_H__
/* dummy */
diff --git a/include/asm-x86_64/ipcbuf.h b/include/asm-x86_64/ipcbuf.h
index 0dcad4f84c2a..470cf85e3ba8 100644
--- a/include/asm-x86_64/ipcbuf.h
+++ b/include/asm-x86_64/ipcbuf.h
@@ -1,8 +1,8 @@
-#ifndef __i386_IPCBUF_H__
-#define __i386_IPCBUF_H__
+#ifndef __x86_64_IPCBUF_H__
+#define __x86_64_IPCBUF_H__
/*
- * The ipc64_perm structure for i386 architecture.
+ * The ipc64_perm structure for x86_64 architecture.
* Note extra padding because this structure is passed back and forth
* between kernel and user space.
*
@@ -26,4 +26,4 @@ struct ipc64_perm
unsigned long __unused2;
};
-#endif /* __i386_IPCBUF_H__ */
+#endif /* __x86_64_IPCBUF_H__ */
diff --git a/include/asm-x86_64/namei.h b/include/asm-x86_64/namei.h
index c6f90b5cf0af..bef239f5318f 100644
--- a/include/asm-x86_64/namei.h
+++ b/include/asm-x86_64/namei.h
@@ -1,9 +1,3 @@
-/* $Id: namei.h,v 1.2 2001/07/04 09:08:13 ak Exp $
- * linux/include/asm-i386/namei.h
- *
- * Included from linux/fs/namei.c
- */
-
#ifndef __X8664_NAMEI_H
#define __X8664_NAMEI_H
diff --git a/include/asm-x86_64/nmi.h b/include/asm-x86_64/nmi.h
new file mode 100644
index 000000000000..d20f0fb9ad2b
--- /dev/null
+++ b/include/asm-x86_64/nmi.h
@@ -0,0 +1,49 @@
+/*
+ * linux/include/asm-i386/nmi.h
+ */
+#ifndef ASM_NMI_H
+#define ASM_NMI_H
+
+#include <linux/pm.h>
+
+struct pt_regs;
+
+typedef int (*nmi_callback_t)(struct pt_regs * regs, int cpu);
+
+/**
+ * set_nmi_callback
+ *
+ * Set a handler for an NMI. Only one handler may be
+ * set. Return 1 if the NMI was handled.
+ */
+void set_nmi_callback(nmi_callback_t callback);
+
+/**
+ * unset_nmi_callback
+ *
+ * Remove the handler previously set.
+ */
+void unset_nmi_callback(void);
+
+#ifdef CONFIG_PM
+
+/** Replace the PM callback routine for NMI. */
+struct pm_dev * set_nmi_pm_callback(pm_callback callback);
+
+/** Unset the PM callback routine back to the default. */
+void unset_nmi_pm_callback(struct pm_dev * dev);
+
+#else
+
+static inline struct pm_dev * set_nmi_pm_callback(pm_callback callback)
+{
+ return 0;
+}
+
+static inline void unset_nmi_pm_callback(struct pm_dev * dev)
+{
+}
+
+#endif /* CONFIG_PM */
+
+#endif /* ASM_NMI_H */
diff --git a/include/asm-x86_64/param.h b/include/asm-x86_64/param.h
index 3921e50c76b2..ef316e2cb5e2 100644
--- a/include/asm-x86_64/param.h
+++ b/include/asm-x86_64/param.h
@@ -2,7 +2,7 @@
#define _ASMx86_64_PARAM_H
#ifdef __KERNEL__
-# define HZ 100 /* Internal kernel timer frequency */
+# define HZ 1000 /* Internal kernel timer frequency */
# define USER_HZ 100 /* .. some user interfaces are in "ticks */
#define CLOCKS_PER_SEC (USER_HZ) /* like times() */
#endif
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
index b580f59b7649..aee29a94ba84 100644
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -42,6 +42,7 @@ extern void exception_table_check(void);
extern void acpi_boot_init(char *);
+int iommu_setup(char *opt);
#define round_up(x,y) (((x) + (y) - 1) & ~((y)-1))
#define round_down(x,y) ((x) & ~((y)-1))
diff --git a/include/asm-x86_64/softirq.h b/include/asm-x86_64/softirq.h
index 23fa952e98e4..436bdc869980 100644
--- a/include/asm-x86_64/softirq.h
+++ b/include/asm-x86_64/softirq.h
@@ -9,6 +9,8 @@
#define __local_bh_enable() \
do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0)
+void do_softirq(void);
+
#define local_bh_enable() \
do { \
__local_bh_enable(); \
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index 3faf01e59d61..50fa45bc8d9c 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -482,8 +482,10 @@ __SYSCALL(__NR_io_submit, sys_io_submit)
__SYSCALL(__NR_io_cancel, sys_io_cancel)
#define __NR_get_thread_area 211
__SYSCALL(__NR_get_thread_area, sys_get_thread_area)
+#define __NR_lookup_dcookie 212
+__SYSCALL(__NR_lookup_dcookie, sys_lookup_dcookie)
-#define __NR_syscall_max __NR_get_thread_area
+#define __NR_syscall_max __NR_lookup_dcookie
#ifndef __NO_STUBS
/* user-visible error numbers are in the range -1 - -4095 */
@@ -503,7 +505,6 @@ do { \
#define __syscall "syscall"
-/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
#define _syscall0(type,name) \
type name(void) \
{ \
diff --git a/include/linux/ioctl32.h b/include/linux/ioctl32.h
new file mode 100644
index 000000000000..b7abfe6eae10
--- /dev/null
+++ b/include/linux/ioctl32.h
@@ -0,0 +1,23 @@
+#ifndef IOCTL32_H
+#define IOCTL32_H 1
+
+struct file;
+
+int sys_ioctl(unsigned int, unsigned int, unsigned long);
+
+/*
+ * Register an 32bit ioctl translation handler for ioctl cmd.
+ *
+ * handler == NULL: use 64bit ioctl handler.
+ * arguments to handler: fd: file descriptor
+ * cmd: ioctl command.
+ * arg: ioctl argument
+ * struct file *file: file descriptor pointer.
+ */
+
+extern int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *));
+
+extern int unregister_ioctl32_conversion(unsigned int cmd);
+
+
+#endif